From 23ee318c43af1a034f2819f2486bdd18cfe2bfe7 Mon Sep 17 00:00:00 2001 From: Slyghtning Date: Wed, 9 Jul 2025 15:21:12 +0200 Subject: [PATCH 01/12] sweepbatcher: consider change in unsigned batch tx Optional change of a swap is encoded in its sweeps as a pointer to the same change output. This change is taken into account when constructing the unsigned batch transaction when it comes to tx weight and outputs. --- sweepbatcher/sweep_batch.go | 54 +++++++++++++++++++++++++++----- sweepbatcher/sweep_batch_test.go | 9 ++++-- 2 files changed, 54 insertions(+), 9 deletions(-) diff --git a/sweepbatcher/sweep_batch.go b/sweepbatcher/sweep_batch.go index 933077fcf..85e54bc63 100644 --- a/sweepbatcher/sweep_batch.go +++ b/sweepbatcher/sweep_batch.go @@ -125,6 +125,9 @@ type sweep struct { // presigned is set, if the sweep should be handled in presigned mode. presigned bool + + // change is the optional change output of the sweep. + change *wire.TxOut } // batchState is the state of the batch. @@ -1238,6 +1241,7 @@ func (b *batch) createPsbt(unsignedTx *wire.MsgTx, sweeps []sweep) ([]byte, // constructUnsignedTx creates unsigned tx from the sweeps, paying to the addr. // It also returns absolute fee (from weight and clamped). func constructUnsignedTx(sweeps []sweep, address btcutil.Address, + changeOutputs map[*wire.TxOut]btcutil.Address, currentHeight int32, feeRate chainfee.SatPerKWeight) (*wire.MsgTx, lntypes.WeightUnit, btcutil.Amount, btcutil.Amount, error) { @@ -1297,6 +1301,20 @@ func constructUnsignedTx(sweeps []sweep, address btcutil.Address, "failed: %w", err) } + // Add the optional change outputs to weight estimates. + if len(changeOutputs) > 0 { + for _, addr := range changeOutputs { + // Add the output to weight estimates. + err = sweeppkg.AddOutputEstimate( + &weightEstimate, addr, + ) + if err != nil { + return nil, 0, 0, 0, fmt.Errorf("sweep."+ + "AddOutputEstimate failed: %w", err) + } + } + } + // Keep track of the total amount this batch is sweeping back. batchAmt := btcutil.Amount(0) for _, sweep := range sweeps { @@ -1318,11 +1336,29 @@ func constructUnsignedTx(sweeps []sweep, address btcutil.Address, fee := clampBatchFee(feeForWeight, batchAmt) // Add the batch transaction output, which excludes the fees paid to - // miners. - batchTx.AddTxOut(&wire.TxOut{ - PkScript: batchPkScript, - Value: int64(batchAmt - fee), - }) + // miners. Reduce the amount by the sum of change outputs, if any. + if len(changeOutputs) == 0 { + batchTx.AddTxOut(&wire.TxOut{ + PkScript: batchPkScript, + Value: int64(batchAmt - fee), + }) + } else if len(changeOutputs) > 0 { + // Reduce the batch output by the sum of change outputs. + var sumChange int64 + for change := range changeOutputs { + sumChange += change.Value + } + batchTx.AddTxOut(&wire.TxOut{ + PkScript: batchPkScript, + Value: int64(batchAmt-fee) - sumChange, + }) + for txOut := range changeOutputs { + batchTx.AddTxOut(&wire.TxOut{ + PkScript: txOut.PkScript, + Value: txOut.Value, + }) + } + } return batchTx, weight, feeForWeight, fee, nil } @@ -1396,9 +1432,13 @@ func (b *batch) publishMixedBatch(ctx context.Context) (btcutil.Amount, error, attempt) // Construct unsigned batch transaction. - var err error + var ( + err error + changeOutputs map[*wire.TxOut]btcutil.Address + ) tx, weight, feeForWeight, fee, err = constructUnsignedTx( - sweeps, address, b.currentHeight, b.rbfCache.FeeRate, + sweeps, address, changeOutputs, b.currentHeight, + b.rbfCache.FeeRate, ) if err != nil { return 0, fmt.Errorf("failed to construct tx: %w", err), diff --git a/sweepbatcher/sweep_batch_test.go b/sweepbatcher/sweep_batch_test.go index 570565b0d..6e7b7fbf2 100644 --- a/sweepbatcher/sweep_batch_test.go +++ b/sweepbatcher/sweep_batch_test.go @@ -338,9 +338,14 @@ func TestConstructUnsignedTx(t *testing.T) { for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { + changeOutputs, err := getChangeOutputs( + tc.sweeps, &chaincfg.RegressionNetParams, + ) + require.NoError(t, err) + tx, weight, feeForW, fee, err := constructUnsignedTx( - tc.sweeps, tc.address, tc.currentHeight, - tc.feeRate, + tc.sweeps, tc.address, changeOutputs, + tc.currentHeight, tc.feeRate, ) if tc.wantErr != "" { require.Error(t, err) From 4874081d9911d61f23773ad1e45313b3b9a0b8f0 Mon Sep 17 00:00:00 2001 From: Slyghtning Date: Wed, 9 Jul 2025 15:27:24 +0200 Subject: [PATCH 02/12] sweepbatcher: consider change when presigning Presigning sweeps takes change outputs into account. Each sweep belonging to the same sweep group points to the same change output, if existent. sweepbatcher.presign scans all passed sweeps for change outputs and passes them to constructUnsignedTx. --- sweepbatcher/presigned.go | 100 +++++++++++++++++++++----- sweepbatcher/presigned_test.go | 128 ++++++++++++++++++++++++++++++++- 2 files changed, 207 insertions(+), 21 deletions(-) diff --git a/sweepbatcher/presigned.go b/sweepbatcher/presigned.go index 385f34cf9..9057e78f4 100644 --- a/sweepbatcher/presigned.go +++ b/sweepbatcher/presigned.go @@ -51,6 +51,7 @@ func ensurePresigned(ctx context.Context, newSweeps []*sweep, outpoint: s.outpoint, value: s.value, presigned: s.presigned, + change: s.change, } } @@ -66,6 +67,12 @@ func ensurePresigned(ctx context.Context, newSweeps []*sweep, return fmt.Errorf("failed to find destination address: %w", err) } + // Get the change outputs for each sweep group. + changeOutputs, err := getChangeOutputs(sweeps, chainParams) + if err != nil { + return fmt.Errorf("failed to get change outputs: %w", err) + } + // Set LockTime to 0. It is not critical. const currentHeight = 0 @@ -73,7 +80,7 @@ func ensurePresigned(ctx context.Context, newSweeps []*sweep, const feeRate = chainfee.FeePerKwFloor tx, _, _, _, err := constructUnsignedTx( - sweeps, destAddr, currentHeight, feeRate, + sweeps, destAddr, changeOutputs, currentHeight, feeRate, ) if err != nil { return fmt.Errorf("failed to construct unsigned tx "+ @@ -257,7 +264,7 @@ func (b *batch) presign(ctx context.Context, newSweeps []*sweep) error { err = presign( ctx, b.cfg.presignedHelper, destAddr, primarySweepID, - sweeps, nextBlockFeeRate, + sweeps, nextBlockFeeRate, b.cfg.chainParams, ) if err != nil { return fmt.Errorf("failed to presign a transaction "+ @@ -299,7 +306,8 @@ type presigner interface { // 10x of the current next block feerate. func presign(ctx context.Context, presigner presigner, destAddr btcutil.Address, primarySweepID wire.OutPoint, sweeps []sweep, - nextBlockFeeRate chainfee.SatPerKWeight) error { + nextBlockFeeRate chainfee.SatPerKWeight, + chainParams *chaincfg.Params) error { if presigner == nil { return fmt.Errorf("presigner is not installed") @@ -328,6 +336,12 @@ func presign(ctx context.Context, presigner presigner, destAddr btcutil.Address, return fmt.Errorf("timeout is invalid: %d", timeout) } + // Get the change outputs of each sweep group. + changeOutputs, err := getChangeOutputs(sweeps, chainParams) + if err != nil { + return fmt.Errorf("failed to get change outputs: %w", err) + } + // Go from the floor (1.01 sat/vbyte) to 2k sat/vbyte with step of 1.2x. const ( start = chainfee.FeePerKwFloor @@ -353,7 +367,7 @@ func presign(ctx context.Context, presigner presigner, destAddr btcutil.Address, for fr := start; fr <= stop; fr = (fr * factorPPM) / 1_000_000 { // Construct an unsigned transaction for this fee rate. tx, _, feeForWeight, fee, err := constructUnsignedTx( - sweeps, destAddr, currentHeight, fr, + sweeps, destAddr, changeOutputs, currentHeight, fr, ) if err != nil { return fmt.Errorf("failed to construct unsigned tx "+ @@ -438,9 +452,15 @@ func (b *batch) publishPresigned(ctx context.Context) (btcutil.Amount, error, err), false } + changeOutputs, err := getChangeOutputs(sweeps, b.cfg.chainParams) + if err != nil { + return 0, fmt.Errorf("failed to get change outputs: %w", err), + false + } + // Construct unsigned batch transaction. tx, weight, _, fee, err := constructUnsignedTx( - sweeps, address, currentHeight, feeRate, + sweeps, address, changeOutputs, currentHeight, feeRate, ) if err != nil { return 0, fmt.Errorf("failed to construct tx: %w", err), @@ -493,10 +513,12 @@ func (b *batch) publishPresigned(ctx context.Context) (btcutil.Amount, error, signedFeeRate := chainfee.NewSatPerKWeight(fee, realWeight) numSweeps := len(tx.TxIn) + numChange := len(tx.TxOut) - 1 b.Infof("attempting to publish custom signed tx=%v, desiredFeerate=%v,"+ - " signedFeeRate=%v, weight=%v, fee=%v, sweeps=%d, destAddr=%s", + " signedFeeRate=%v, weight=%v, fee=%v, sweeps=%d, "+ + "changeOutputs=%d, destAddr=%s", txHash, feeRate, signedFeeRate, realWeight, fee, numSweeps, - address) + numChange, address) b.debugLogTx("serialized batch", tx) // Publish the transaction. @@ -557,6 +579,46 @@ func getPresignedSweepsDestAddr(ctx context.Context, helper destPkScripter, return address, nil } +// getChangeOutputs retrieves the change output references of each sweep and +// de-duplicates them. The function must be used in presigned mode only. +func getChangeOutputs(sweeps []sweep, chainParams *chaincfg.Params) ( + map[*wire.TxOut]btcutil.Address, error) { + + changeOutputs := make(map[*wire.TxOut]btcutil.Address) + for _, sweep := range sweeps { + // If the sweep has a change output, add it to the changeOutputs + // map to avoid duplicates. + if sweep.change != nil { + // If the change output is already in the map, skip it. + if _, exists := changeOutputs[sweep.change]; exists { + continue + } + + // Convert the change output's pkScript to an + // address. + changePkScript, err := txscript.ParsePkScript( + sweep.change.PkScript, + ) + if err != nil { + return nil, fmt.Errorf("failed to parse "+ + "change output pkScript: %w", err) + } + + address, err := changePkScript.Address(chainParams) + if err != nil { + return nil, fmt.Errorf("pkScript.Address "+ + "failed for pkScript %x returned for "+ + "change output: %w", + sweep.change.PkScript, err) + } + + changeOutputs[sweep.change] = address + } + } + + return changeOutputs, nil +} + // CheckSignedTx makes sure that signedTx matches the unsignedTx. It checks // according to criteria specified in the description of PresignedHelper.SignTx. func CheckSignedTx(unsignedTx, signedTx *wire.MsgTx, inputAmt btcutil.Amount, @@ -593,23 +655,23 @@ func CheckSignedTx(unsignedTx, signedTx *wire.MsgTx, inputAmt btcutil.Amount, } // Compare outputs. - if len(unsignedTx.TxOut) != 1 { - return fmt.Errorf("unsigned tx has %d outputs, want 1", - len(unsignedTx.TxOut)) - } - if len(signedTx.TxOut) != 1 { - return fmt.Errorf("the signed tx has %d outputs, want 1", + if len(unsignedTx.TxOut) != len(signedTx.TxOut) { + return fmt.Errorf("unsigned tx has %d outputs, signed tx has "+ + "%d outputs, should be equal", len(unsignedTx.TxOut), len(signedTx.TxOut)) } - unsignedOut := unsignedTx.TxOut[0] - signedOut := signedTx.TxOut[0] - if !bytes.Equal(unsignedOut.PkScript, signedOut.PkScript) { - return fmt.Errorf("mismatch of output pkScript: %x, %x", - unsignedOut.PkScript, signedOut.PkScript) + for i, o := range unsignedTx.TxOut { + if !bytes.Equal(o.PkScript, signedTx.TxOut[i].PkScript) { + return fmt.Errorf("mismatch of output pkScript: %x, %x", + o.PkScript, signedTx.TxOut[i].PkScript) + } } + // The first output is always the batch output. + batchOutput := signedTx.TxOut[0] + // Find the feerate of signedTx. - fee := inputAmt - btcutil.Amount(signedOut.Value) + fee := inputAmt - btcutil.Amount(batchOutput.Value) weight := lntypes.WeightUnit( blockchain.GetTransactionWeight(btcutil.NewTx(signedTx)), ) diff --git a/sweepbatcher/presigned_test.go b/sweepbatcher/presigned_test.go index 629ff1de4..cb84d49a5 100644 --- a/sweepbatcher/presigned_test.go +++ b/sweepbatcher/presigned_test.go @@ -1011,6 +1011,7 @@ func TestPresign(t *testing.T) { ctx, tc.presigner, tc.destAddr, tc.primarySweepID, tc.sweeps, tc.nextBlockFeeRate, + &chaincfg.RegressionNetParams, ) if tc.wantErr != "" { require.Error(t, err) @@ -1460,7 +1461,8 @@ func TestCheckSignedTx(t *testing.T) { }, inputAmt: 3_000_000, minRelayFee: 253, - wantErr: "unsigned tx has 2 outputs, want 1", + wantErr: "unsigned tx has 2 outputs, signed tx " + + "has 1 outputs, should be equal", }, { @@ -1517,7 +1519,8 @@ func TestCheckSignedTx(t *testing.T) { }, inputAmt: 3_000_000, minRelayFee: 253, - wantErr: "the signed tx has 2 outputs, want 1", + wantErr: "unsigned tx has 1 outputs, signed tx " + + "has 2 outputs, should be equal", }, { @@ -1642,3 +1645,124 @@ func TestCheckSignedTx(t *testing.T) { }) } } + +// TestGetChangeOutputs tests that the change aggregation across sweeps works as +// intended. Each sweep of a sweep group should have a pointer to the same +// change output which is aggregated in getChangeOutput. +func TestGetChangeOutputs(t *testing.T) { + // Prepare the necessary data for test cases. + op1 := wire.OutPoint{ + Hash: chainhash.Hash{1, 1, 1}, + Index: 1, + } + op2 := wire.OutPoint{ + Hash: chainhash.Hash{2, 2, 2}, + Index: 2, + } + op3 := wire.OutPoint{ + Hash: chainhash.Hash{3, 3, 3}, + Index: 3, + } + + batchPkScript, err := txscript.PayToAddrScript(destAddr) + require.NoError(t, err) + + changeOutput1 := &wire.TxOut{ + Value: 100_000, + PkScript: batchPkScript, + } + changeOutput2 := &wire.TxOut{ + Value: 200_000, + PkScript: batchPkScript, + } + + cases := []struct { + name string + sweeps []sweep + wantOutputs map[*wire.TxOut]btcutil.Address + wantErr string + }{ + { + name: "no change", + sweeps: []sweep{ + { + outpoint: op1, + value: 1_000_000, + change: nil, + }, + }, + wantOutputs: map[*wire.TxOut]btcutil.Address{}, + }, + { + name: "single sweep, single change", + sweeps: []sweep{ + { + outpoint: op1, + value: 1_000_000, + change: changeOutput1, + }, + }, + wantOutputs: map[*wire.TxOut]btcutil.Address{ + changeOutput1: destAddr, + }, + }, + { + name: "double sweep, single change", + sweeps: []sweep{ + { + outpoint: op1, + value: 1_000_000, + change: changeOutput1, + }, + { + outpoint: op2, + value: 1_000_000, + change: changeOutput1, + }, + }, + wantOutputs: map[*wire.TxOut]btcutil.Address{ + changeOutput1: destAddr, + }, + }, + { + name: "double sweep, double change", + sweeps: []sweep{ + { + outpoint: op1, + value: 1_000_000, + change: changeOutput1, + }, + { + outpoint: op2, + value: 1_000_000, + change: changeOutput1, + }, + { + outpoint: op3, + value: 1_000_000, + change: changeOutput2, + }, + }, + wantOutputs: map[*wire.TxOut]btcutil.Address{ + changeOutput1: destAddr, + changeOutput2: destAddr, + }, + }, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + changeOutputs, err := getChangeOutputs( + tc.sweeps, &chaincfg.RegressionNetParams, + ) + if tc.wantErr != "" { + require.Error(t, err) + require.ErrorContains(t, err, tc.wantErr) + } else { + require.NoError(t, err) + } + + require.Equal(t, tc.wantOutputs, changeOutputs) + }) + } +} From c7091de8cf68c3bc7dd3c71faf07878a6104351a Mon Sep 17 00:00:00 2001 From: Slyghtning Date: Wed, 9 Jul 2025 15:30:07 +0200 Subject: [PATCH 03/12] sweepbatcher: add change to PresignSweepsGroup The batcher now presigns sweep groups including an optional change output. Change is usually leftover from the client's swap amount which is returned to the client. --- sweepbatcher/sweep_batcher.go | 10 +++- sweepbatcher/sweep_batcher_presigned_test.go | 60 +++++++++++--------- 2 files changed, 42 insertions(+), 28 deletions(-) diff --git a/sweepbatcher/sweep_batcher.go b/sweepbatcher/sweep_batcher.go index 6bab035e7..7633c20b8 100644 --- a/sweepbatcher/sweep_batcher.go +++ b/sweepbatcher/sweep_batcher.go @@ -125,6 +125,9 @@ type SweepInfo struct { // value should be stable for a sweep. Currently presigned and // non-presigned sweeps never appear in the same batch. IsPresigned bool + + // Change is an optional change output of the sweep. + Change *wire.TxOut } // SweepFetcher is used to get details of a sweep. @@ -713,7 +716,8 @@ func (b *Batcher) Run(ctx context.Context) error { // swap. The order of sweeps is important. The first sweep serves as // primarySweepID if the group starts a new batch. func (b *Batcher) PresignSweepsGroup(ctx context.Context, inputs []Input, - sweepTimeout int32, destAddress btcutil.Address) error { + sweepTimeout int32, destAddress btcutil.Address, + changeOutput *wire.TxOut) error { if len(inputs) == 0 { return fmt.Errorf("no inputs passed to PresignSweepsGroup") @@ -742,6 +746,7 @@ func (b *Batcher) PresignSweepsGroup(ctx context.Context, inputs []Input, outpoint: input.Outpoint, value: input.Value, timeout: sweepTimeout, + change: changeOutput, } } @@ -751,7 +756,7 @@ func (b *Batcher) PresignSweepsGroup(ctx context.Context, inputs []Input, return presign( ctx, b.presignedHelper, destAddress, primarySweepID, sweeps, - nextBlockFeeRate, + nextBlockFeeRate, b.chainParams, ) } @@ -1564,6 +1569,7 @@ func (b *Batcher) loadSweep(ctx context.Context, swapHash lntypes.Hash, minFeeRate: minFeeRate, nonCoopHint: s.NonCoopHint, presigned: s.IsPresigned, + change: s.Change, }, nil } diff --git a/sweepbatcher/sweep_batcher_presigned_test.go b/sweepbatcher/sweep_batcher_presigned_test.go index 36f11f750..76d14b2b2 100644 --- a/sweepbatcher/sweep_batcher_presigned_test.go +++ b/sweepbatcher/sweep_batcher_presigned_test.go @@ -113,7 +113,7 @@ func (h *mockPresignedHelper) DestPkScript(ctx context.Context, } // SignTx tries to sign the transaction. If all the inputs are online, it signs -// the exact transaction passed and adds it to presignedBatches. Otherwise it +// the exact transaction passed and adds it to presignedBatches. Otherwise, it // looks for a transaction in presignedBatches satisfying the criteria. func (h *mockPresignedHelper) SignTx(ctx context.Context, primarySweepID wire.OutPoint, tx *wire.MsgTx, inputAmt btcutil.Amount, @@ -273,7 +273,7 @@ func testPresigned_forgotten_presign(t *testing.T, presignedHelper.SetOutpointOnline(op1, false) err := batcher.PresignSweepsGroup( ctx, []Input{{Outpoint: op1, Value: 1_000_000}}, - sweepTimeout, destAddr, + sweepTimeout, destAddr, nil, ) require.Error(t, err) require.ErrorContains(t, err, "offline") @@ -350,7 +350,7 @@ func testPresigned_input1_offline_then_input2(t *testing.T, presignedHelper.SetOutpointOnline(op1, true) err = batcher.PresignSweepsGroup( ctx, []Input{{Outpoint: op1, Value: 1_000_000}}, - sweepTimeout, destAddr, + sweepTimeout, destAddr, nil, ) require.NoError(t, err) @@ -413,7 +413,7 @@ func testPresigned_input1_offline_then_input2(t *testing.T, presignedHelper.SetOutpointOnline(op2, true) err = batcher.PresignSweepsGroup( ctx, []Input{{Outpoint: op2, Value: 2_000_000}}, - sweepTimeout, destAddr, + sweepTimeout, destAddr, nil, ) require.NoError(t, err) @@ -520,7 +520,7 @@ func testPresigned_min_relay_fee(t *testing.T, presignedHelper.SetOutpointOnline(op1, true) err := batcher.PresignSweepsGroup( ctx, []Input{{Outpoint: op1, Value: inputAmt}}, - sweepTimeout, destAddr, + sweepTimeout, destAddr, nil, ) require.NoError(t, err) @@ -644,7 +644,7 @@ func testPresigned_two_inputs_one_goes_offline(t *testing.T, presignedHelper.SetOutpointOnline(op1, true) err = batcher.PresignSweepsGroup( ctx, []Input{{Outpoint: op1, Value: 1_000_000}}, - sweepTimeout, destAddr, + sweepTimeout, destAddr, nil, ) require.NoError(t, err) require.NoError(t, batcher.AddSweep(ctx, &sweepReq1)) @@ -670,7 +670,7 @@ func testPresigned_two_inputs_one_goes_offline(t *testing.T, presignedHelper.SetOutpointOnline(op2, true) err = batcher.PresignSweepsGroup( ctx, []Input{{Outpoint: op2, Value: 2_000_000}}, - sweepTimeout, destAddr, + sweepTimeout, destAddr, nil, ) require.NoError(t, err) require.NoError(t, batcher.AddSweep(ctx, &sweepReq2)) @@ -780,7 +780,7 @@ func testPresigned_first_publish_fails(t *testing.T, presignedHelper.SetOutpointOnline(op1, true) err = batcher.PresignSweepsGroup( ctx, []Input{{Outpoint: op1, Value: 1_000_000}}, - sweepTimeout, destAddr, + sweepTimeout, destAddr, nil, ) require.NoError(t, err) presignedHelper.SetOutpointOnline(op1, false) @@ -903,7 +903,7 @@ func testPresigned_locktime(t *testing.T, presignedHelper.SetOutpointOnline(op1, true) err = batcher.PresignSweepsGroup( ctx, []Input{{Outpoint: op1, Value: 1_000_000}}, - sweepTimeout, destAddr, + sweepTimeout, destAddr, nil, ) require.NoError(t, err) presignedHelper.SetOutpointOnline(op1, false) @@ -994,14 +994,18 @@ func testPresigned_presigned_group(t *testing.T, presignedHelper.SetOutpointOnline(op2, false) // An attempt to presign must fail. - err = batcher.PresignSweepsGroup(ctx, group1, sweepTimeout, destAddr) + err = batcher.PresignSweepsGroup( + ctx, group1, sweepTimeout, destAddr, nil, + ) require.ErrorContains(t, err, "some outpoint is offline") // Enable both outpoints. presignedHelper.SetOutpointOnline(op2, true) // An attempt to presign must succeed. - err = batcher.PresignSweepsGroup(ctx, group1, sweepTimeout, destAddr) + err = batcher.PresignSweepsGroup( + ctx, group1, sweepTimeout, destAddr, nil, + ) require.NoError(t, err) // Add the sweep, triggering the publish attempt. @@ -1053,7 +1057,9 @@ func testPresigned_presigned_group(t *testing.T, presignedHelper.SetOutpointOnline(op4, true) // An attempt to presign must succeed. - err = batcher.PresignSweepsGroup(ctx, group2, sweepTimeout, destAddr) + err = batcher.PresignSweepsGroup( + ctx, group2, sweepTimeout, destAddr, nil, + ) require.NoError(t, err) // Add the sweep. It should go to the same batch. @@ -1107,7 +1113,9 @@ func testPresigned_presigned_group(t *testing.T, presignedHelper.SetOutpointOnline(op6, true) // An attempt to presign must succeed. - err = batcher.PresignSweepsGroup(ctx, group3, sweepTimeout, destAddr) + err = batcher.PresignSweepsGroup( + ctx, group3, sweepTimeout, destAddr, nil, + ) require.NoError(t, err) // Add the sweep. It should go to the same batch. @@ -1215,9 +1223,9 @@ func testPresigned_presigned_and_regular_sweeps(t *testing.T, store testStore, setFeeRate(feeRateLow) - ///////////////////////////////////// + // /////////////////////////////////// // Create the first regular sweep. // - ///////////////////////////////////// + // /////////////////////////////////// swapHash1 := lntypes.Hash{1, 1, 1} op1 := wire.OutPoint{ Hash: chainhash.Hash{1, 1}, @@ -1264,9 +1272,9 @@ func testPresigned_presigned_and_regular_sweeps(t *testing.T, store testStore, require.Len(t, tx1.TxIn, 1) require.Len(t, tx1.TxOut, 1) - /////////////////////////////////////// + // ///////////////////////////////////// // Create the first presigned sweep. // - /////////////////////////////////////// + // ///////////////////////////////////// swapHash2 := lntypes.Hash{2, 2, 2} op2 := wire.OutPoint{ Hash: chainhash.Hash{2, 2}, @@ -1304,7 +1312,7 @@ func testPresigned_presigned_and_regular_sweeps(t *testing.T, store testStore, presignedHelper.SetOutpointOnline(op2, true) err = batcher.PresignSweepsGroup( ctx, []Input{{Outpoint: op2, Value: 2_000_000}}, - sweepTimeout, destAddr, + sweepTimeout, destAddr, nil, ) require.NoError(t, err) require.NoError(t, batcher.AddSweep(ctx, &sweepReq2)) @@ -1319,9 +1327,9 @@ func testPresigned_presigned_and_regular_sweeps(t *testing.T, store testStore, require.Len(t, tx2.TxOut, 1) require.Equal(t, op2, tx2.TxIn[0].PreviousOutPoint) - ////////////////////////////////////// + // //////////////////////////////////// // Create the second regular sweep. // - ////////////////////////////////////// + // //////////////////////////////////// swapHash3 := lntypes.Hash{3, 3, 3} op3 := wire.OutPoint{ Hash: chainhash.Hash{3, 3}, @@ -1359,9 +1367,9 @@ func testPresigned_presigned_and_regular_sweeps(t *testing.T, store testStore, // Deliver sweep request to batcher. require.NoError(t, batcher.AddSweep(ctx, &sweepReq3)) - //////////////////////////////////////// + // ////////////////////////////////////// // Create the second presigned sweep. // - //////////////////////////////////////// + // ////////////////////////////////////// swapHash4 := lntypes.Hash{4, 4, 4} op4 := wire.OutPoint{ Hash: chainhash.Hash{4, 4}, @@ -1399,7 +1407,7 @@ func testPresigned_presigned_and_regular_sweeps(t *testing.T, store testStore, presignedHelper.SetOutpointOnline(op4, true) err = batcher.PresignSweepsGroup( ctx, []Input{{Outpoint: op4, Value: 3_000_000}}, - sweepTimeout, destAddr, + sweepTimeout, destAddr, nil, ) require.NoError(t, err) require.NoError(t, batcher.AddSweep(ctx, &sweepReq4)) @@ -1520,7 +1528,7 @@ func testPresigned_purging(t *testing.T, numSwaps, numConfirmedSwaps int, // An attempt to presign must succeed. err := batcher.PresignSweepsGroup( - ctx, group, sweepTimeout, destAddr, + ctx, group, sweepTimeout, destAddr, nil, ) require.NoError(t, err) @@ -1584,11 +1592,11 @@ func testPresigned_purging(t *testing.T, numSwaps, numConfirmedSwaps int, // An attempt to presign must succeed. err := batcher.PresignSweepsGroup( - ctx, group, sweepTimeout, destAddr, + ctx, group, sweepTimeout, destAddr, nil, ) require.NoError(t, err) - // Add the sweep, triggering the publish attempt. + // Add the sweep, triggering the publishing attempt. require.NoError(t, batcher.AddSweep(ctx, &SweepRequest{ SwapHash: swapHash, Inputs: group, From eb909ac48bf837c10e501d2dd77ee8d4fce25a04 Mon Sep 17 00:00:00 2001 From: Slyghtning Date: Wed, 11 Jun 2025 14:56:04 +0200 Subject: [PATCH 04/12] swapserverrpc: arbitrary static swap amount --- swapserverrpc/staticaddr.pb.go | 264 ++++++++++++++++++--------------- swapserverrpc/staticaddr.proto | 15 +- 2 files changed, 155 insertions(+), 124 deletions(-) diff --git a/swapserverrpc/staticaddr.pb.go b/swapserverrpc/staticaddr.pb.go index 4f5cd4134..0deaf1252 100644 --- a/swapserverrpc/staticaddr.pb.go +++ b/swapserverrpc/staticaddr.pb.go @@ -398,7 +398,9 @@ type ServerStaticAddressLoopInRequest struct { // The hashed swap invoice preimage of the swap. SwapHash []byte `protobuf:"bytes,2,opt,name=swap_hash,json=swapHash,proto3" json:"swap_hash,omitempty"` // The deposit outpoints the client wishes to loop in. They implicitly state - // the swap amount. + // the swap amount if the amount field is not specified. If the amount field + // is specified, the server will use the total amount of the deposit + // outpoints minus the amount as the change amount. DepositOutpoints []string `protobuf:"bytes,3,rep,name=deposit_outpoints,json=depositOutpoints,proto3" json:"deposit_outpoints,omitempty"` // The swap invoice that the client wants the server to pay. SwapInvoice string `protobuf:"bytes,4,opt,name=swap_invoice,json=swapInvoice,proto3" json:"swap_invoice,omitempty"` @@ -424,6 +426,14 @@ type ServerStaticAddressLoopInRequest struct { // swap payment. If the timeout is reached the swap will be aborted on the // server side and the client can retry the swap with different parameters. PaymentTimeoutSeconds uint32 `protobuf:"varint,8,opt,name=payment_timeout_seconds,json=paymentTimeoutSeconds,proto3" json:"payment_timeout_seconds,omitempty"` + // The optional swap amount the client is attempting to swap. If specified the + // server will take out this amount from the total value of provided + // deposit_outpoints and will send the change back to the static address. If + // this results in dust change the server will reject the swap request. If the + // amount is not specified the server will use the total amount of the + // deposit_outpoints as swap amount without providing an additional flag - this + // is to maintain backwards compatibility. + Amount uint64 `protobuf:"varint,9,opt,name=amount,proto3" json:"amount,omitempty"` } func (x *ServerStaticAddressLoopInRequest) Reset() { @@ -514,6 +524,13 @@ func (x *ServerStaticAddressLoopInRequest) GetPaymentTimeoutSeconds() uint32 { return 0 } +func (x *ServerStaticAddressLoopInRequest) GetAmount() uint64 { + if x != nil { + return x.Amount + } + return 0 +} + type ServerStaticAddressLoopInResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1050,7 +1067,7 @@ var file_staticaddr_proto_rawDesc = []byte{ 0x52, 0x0f, 0x6d, 0x75, 0x73, 0x69, 0x67, 0x32, 0x53, 0x77, 0x65, 0x65, 0x70, 0x53, 0x69, 0x67, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x22, 0x82, 0x03, 0x0a, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x22, 0x9a, 0x03, 0x0a, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x13, 0x68, 0x74, 0x6c, 0x63, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x75, 0x62, 0x5f, 0x6b, @@ -1074,129 +1091,130 @@ var file_staticaddr_proto_rawDesc = []byte{ 0x65, 0x6e, 0x74, 0x12, 0x36, 0x0a, 0x17, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x15, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, - 0x65, 0x6f, 0x75, 0x74, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0xe1, 0x02, 0x0a, 0x21, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x2d, 0x0a, 0x13, 0x68, 0x74, 0x6c, 0x63, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x5f, 0x70, 0x75, 0x62, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, - 0x68, 0x74, 0x6c, 0x63, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, - 0x12, 0x1f, 0x0a, 0x0b, 0x68, 0x74, 0x6c, 0x63, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x68, 0x74, 0x6c, 0x63, 0x45, 0x78, 0x70, 0x69, 0x72, - 0x79, 0x12, 0x4c, 0x0a, 0x12, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x5f, 0x68, 0x74, - 0x6c, 0x63, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, - 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x48, 0x74, - 0x6c, 0x63, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x10, 0x73, - 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x48, 0x74, 0x6c, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x12, - 0x4b, 0x0a, 0x12, 0x68, 0x69, 0x67, 0x68, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x68, 0x74, 0x6c, 0x63, - 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6c, 0x6f, - 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x48, 0x74, 0x6c, 0x63, - 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x68, 0x69, 0x67, - 0x68, 0x46, 0x65, 0x65, 0x48, 0x74, 0x6c, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x51, 0x0a, 0x15, - 0x65, 0x78, 0x74, 0x72, 0x65, 0x6d, 0x65, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x68, 0x74, 0x6c, 0x63, - 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6c, 0x6f, - 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x48, 0x74, 0x6c, 0x63, - 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x12, 0x65, 0x78, 0x74, - 0x72, 0x65, 0x6d, 0x65, 0x46, 0x65, 0x65, 0x48, 0x74, 0x6c, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x22, - 0x4a, 0x0a, 0x15, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x48, 0x74, 0x6c, 0x63, 0x53, 0x69, 0x67, - 0x6e, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, 0x6e, 0x63, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, - 0x12, 0x19, 0x0a, 0x08, 0x66, 0x65, 0x65, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x07, 0x66, 0x65, 0x65, 0x52, 0x61, 0x74, 0x65, 0x22, 0xad, 0x02, 0x0a, 0x20, + 0x65, 0x6f, 0x75, 0x74, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x61, + 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x22, 0xe1, 0x02, 0x0a, 0x21, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, + 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x13, 0x68, 0x74, 0x6c, + 0x63, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x70, 0x75, 0x62, 0x5f, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x68, 0x74, 0x6c, 0x63, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x68, 0x74, 0x6c, 0x63, + 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x68, + 0x74, 0x6c, 0x63, 0x45, 0x78, 0x70, 0x69, 0x72, 0x79, 0x12, 0x4c, 0x0a, 0x12, 0x73, 0x74, 0x61, + 0x6e, 0x64, 0x61, 0x72, 0x64, 0x5f, 0x68, 0x74, 0x6c, 0x63, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x48, 0x74, 0x6c, 0x63, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, + 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x10, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x48, + 0x74, 0x6c, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x4b, 0x0a, 0x12, 0x68, 0x69, 0x67, 0x68, 0x5f, + 0x66, 0x65, 0x65, 0x5f, 0x68, 0x74, 0x6c, 0x63, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x48, 0x74, 0x6c, 0x63, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x68, 0x69, 0x67, 0x68, 0x46, 0x65, 0x65, 0x48, 0x74, 0x6c, 0x63, + 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x51, 0x0a, 0x15, 0x65, 0x78, 0x74, 0x72, 0x65, 0x6d, 0x65, 0x5f, + 0x66, 0x65, 0x65, 0x5f, 0x68, 0x74, 0x6c, 0x63, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x48, 0x74, 0x6c, 0x63, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x12, 0x65, 0x78, 0x74, 0x72, 0x65, 0x6d, 0x65, 0x46, 0x65, 0x65, 0x48, + 0x74, 0x6c, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x4a, 0x0a, 0x15, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x48, 0x74, 0x6c, 0x63, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, + 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, + 0x52, 0x06, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x65, 0x65, 0x5f, + 0x72, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x66, 0x65, 0x65, 0x52, + 0x61, 0x74, 0x65, 0x22, 0xad, 0x02, 0x0a, 0x20, 0x50, 0x75, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, + 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, 0x74, 0x6c, 0x63, 0x53, 0x69, 0x67, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x77, 0x61, 0x70, + 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x77, 0x61, + 0x70, 0x48, 0x61, 0x73, 0x68, 0x12, 0x4c, 0x0a, 0x12, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, + 0x64, 0x5f, 0x68, 0x74, 0x6c, 0x63, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1e, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x48, 0x74, 0x6c, 0x63, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x10, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x48, 0x74, 0x6c, 0x63, 0x49, + 0x6e, 0x66, 0x6f, 0x12, 0x4b, 0x0a, 0x12, 0x68, 0x69, 0x67, 0x68, 0x5f, 0x66, 0x65, 0x65, 0x5f, + 0x68, 0x74, 0x6c, 0x63, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1e, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x48, 0x74, 0x6c, 0x63, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x0f, 0x68, 0x69, 0x67, 0x68, 0x46, 0x65, 0x65, 0x48, 0x74, 0x6c, 0x63, 0x49, 0x6e, 0x66, 0x6f, + 0x12, 0x51, 0x0a, 0x15, 0x65, 0x78, 0x74, 0x72, 0x65, 0x6d, 0x65, 0x5f, 0x66, 0x65, 0x65, 0x5f, + 0x68, 0x74, 0x6c, 0x63, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1e, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x48, 0x74, 0x6c, 0x63, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x12, 0x65, 0x78, 0x74, 0x72, 0x65, 0x6d, 0x65, 0x46, 0x65, 0x65, 0x48, 0x74, 0x6c, 0x63, 0x49, + 0x6e, 0x66, 0x6f, 0x22, 0x43, 0x0a, 0x15, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x48, 0x74, 0x6c, + 0x63, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x0a, 0x06, + 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, + 0x6e, 0x63, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0c, 0x52, 0x04, 0x73, 0x69, 0x67, 0x73, 0x22, 0x23, 0x0a, 0x21, 0x50, 0x75, 0x73, 0x68, + 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, 0x74, 0x6c, + 0x63, 0x53, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xc6, 0x02, + 0x0a, 0x25, 0x50, 0x75, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x53, 0x77, 0x65, 0x65, 0x70, 0x6c, 0x65, 0x73, 0x73, 0x53, 0x69, 0x67, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x77, 0x61, 0x70, 0x5f, + 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x77, 0x61, 0x70, + 0x48, 0x61, 0x73, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x78, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x04, 0x74, 0x78, 0x69, 0x64, 0x12, 0x62, 0x0a, 0x0c, 0x73, 0x69, 0x67, 0x6e, + 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3f, + 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x53, 0x74, 0x61, + 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x77, 0x65, 0x65, 0x70, 0x6c, + 0x65, 0x73, 0x73, 0x53, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x53, + 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x23, 0x0a, 0x0d, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x1a, 0x63, 0x0a, 0x10, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x39, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, + 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x77, 0x65, 0x65, 0x70, 0x6c, 0x65, 0x73, 0x73, + 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x44, 0x0a, 0x1a, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x53, 0x77, 0x65, 0x65, 0x70, 0x6c, 0x65, 0x73, 0x73, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, + 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, + 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x69, 0x67, 0x22, 0x28, 0x0a, 0x26, 0x50, 0x75, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x48, 0x74, 0x6c, 0x63, 0x53, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x77, 0x61, 0x70, 0x48, 0x61, 0x73, 0x68, 0x12, 0x4c, 0x0a, - 0x12, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x5f, 0x68, 0x74, 0x6c, 0x63, 0x5f, 0x69, - 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, - 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x48, 0x74, 0x6c, 0x63, 0x53, 0x69, - 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x10, 0x73, 0x74, 0x61, 0x6e, 0x64, - 0x61, 0x72, 0x64, 0x48, 0x74, 0x6c, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x4b, 0x0a, 0x12, 0x68, - 0x69, 0x67, 0x68, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x68, 0x74, 0x6c, 0x63, 0x5f, 0x69, 0x6e, 0x66, - 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, - 0x63, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x48, 0x74, 0x6c, 0x63, 0x53, 0x69, 0x67, 0x6e, - 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x68, 0x69, 0x67, 0x68, 0x46, 0x65, 0x65, - 0x48, 0x74, 0x6c, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x51, 0x0a, 0x15, 0x65, 0x78, 0x74, 0x72, - 0x65, 0x6d, 0x65, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x68, 0x74, 0x6c, 0x63, 0x5f, 0x69, 0x6e, 0x66, - 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, - 0x63, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x48, 0x74, 0x6c, 0x63, 0x53, 0x69, 0x67, 0x6e, - 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x12, 0x65, 0x78, 0x74, 0x72, 0x65, 0x6d, 0x65, - 0x46, 0x65, 0x65, 0x48, 0x74, 0x6c, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x43, 0x0a, 0x15, 0x43, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x48, 0x74, 0x6c, 0x63, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, - 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, - 0x73, 0x69, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x04, 0x73, 0x69, 0x67, 0x73, - 0x22, 0x23, 0x0a, 0x21, 0x50, 0x75, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, 0x74, 0x6c, 0x63, 0x53, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xc6, 0x02, 0x0a, 0x25, 0x50, 0x75, 0x73, 0x68, 0x53, 0x74, - 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x77, 0x65, 0x65, 0x70, - 0x6c, 0x65, 0x73, 0x73, 0x53, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x1b, 0x0a, 0x09, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x08, 0x73, 0x77, 0x61, 0x70, 0x48, 0x61, 0x73, 0x68, 0x12, 0x12, 0x0a, 0x04, - 0x74, 0x78, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x74, 0x78, 0x69, 0x64, - 0x12, 0x62, 0x0a, 0x0c, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x6e, 0x66, 0x6f, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, + 0x73, 0x53, 0x77, 0x65, 0x65, 0x70, 0x6c, 0x65, 0x73, 0x73, 0x53, 0x69, 0x67, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x26, 0x0a, 0x1c, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x06, 0x0a, 0x02, 0x56, 0x30, 0x10, 0x00, 0x32, 0xb5, + 0x04, 0x0a, 0x13, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x57, 0x0a, 0x10, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, + 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x65, 0x77, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6c, + 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x65, 0x77, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x59, 0x0a, 0x16, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, + 0x77, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x12, 0x1e, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, + 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, + 0x61, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, + 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, + 0x61, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, 0x19, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x12, 0x29, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, + 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, + 0x0a, 0x19, 0x50, 0x75, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x48, 0x74, 0x6c, 0x63, 0x53, 0x69, 0x67, 0x73, 0x12, 0x29, 0x2e, 0x6c, 0x6f, + 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, 0x74, 0x6c, 0x63, 0x53, 0x69, 0x67, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x53, 0x77, 0x65, 0x65, 0x70, 0x6c, 0x65, 0x73, 0x73, 0x53, 0x69, 0x67, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x49, 0x6e, - 0x66, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, - 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x63, 0x0a, 0x10, 0x53, 0x69, 0x67, - 0x6e, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, - 0x39, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, - 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, - 0x77, 0x65, 0x65, 0x70, 0x6c, 0x65, 0x73, 0x73, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x49, - 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x44, - 0x0a, 0x1a, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x77, 0x65, 0x65, 0x70, 0x6c, 0x65, 0x73, - 0x73, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x14, 0x0a, 0x05, - 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x6e, 0x6f, 0x6e, - 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x03, 0x73, 0x69, 0x67, 0x22, 0x28, 0x0a, 0x26, 0x50, 0x75, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, - 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x77, 0x65, 0x65, 0x70, 0x6c, 0x65, - 0x73, 0x73, 0x53, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x26, - 0x0a, 0x1c, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x06, - 0x0a, 0x02, 0x56, 0x30, 0x10, 0x00, 0x32, 0xb5, 0x04, 0x0a, 0x13, 0x53, 0x74, 0x61, 0x74, 0x69, - 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x57, - 0x0a, 0x10, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x12, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x16, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x73, 0x12, 0x1e, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1f, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x72, 0x0a, 0x19, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, - 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x12, - 0x29, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x6f, - 0x70, 0x49, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x6c, 0x6f, 0x6f, - 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x69, - 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, 0x19, 0x50, 0x75, 0x73, 0x68, 0x53, 0x74, - 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, 0x74, 0x6c, 0x63, 0x53, - 0x69, 0x67, 0x73, 0x12, 0x29, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x75, - 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, - 0x74, 0x6c, 0x63, 0x53, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, - 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x53, 0x74, 0x61, - 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, 0x74, 0x6c, 0x63, 0x53, 0x69, - 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x81, 0x01, 0x0a, 0x1e, 0x50, - 0x75, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x53, 0x77, 0x65, 0x65, 0x70, 0x6c, 0x65, 0x73, 0x73, 0x53, 0x69, 0x67, 0x73, 0x12, 0x2e, 0x2e, - 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, - 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x77, 0x65, 0x65, 0x70, 0x6c, 0x65, - 0x73, 0x73, 0x53, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, - 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, - 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x77, 0x65, 0x65, 0x70, 0x6c, 0x65, - 0x73, 0x73, 0x53, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x2d, - 0x5a, 0x2b, 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, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, - 0x73, 0x77, 0x61, 0x70, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x73, 0x48, 0x74, 0x6c, 0x63, 0x53, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x81, 0x01, 0x0a, 0x1e, 0x50, 0x75, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x69, + 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x77, 0x65, 0x65, 0x70, 0x6c, 0x65, 0x73, + 0x73, 0x53, 0x69, 0x67, 0x73, 0x12, 0x2e, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, + 0x50, 0x75, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x53, 0x77, 0x65, 0x65, 0x70, 0x6c, 0x65, 0x73, 0x73, 0x53, 0x69, 0x67, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, + 0x50, 0x75, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x53, 0x77, 0x65, 0x65, 0x70, 0x6c, 0x65, 0x73, 0x73, 0x53, 0x69, 0x67, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x2d, 0x5a, 0x2b, 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, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x73, 0x77, 0x61, 0x70, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/swapserverrpc/staticaddr.proto b/swapserverrpc/staticaddr.proto index 9aceefb3b..ce6890a28 100644 --- a/swapserverrpc/staticaddr.proto +++ b/swapserverrpc/staticaddr.proto @@ -107,7 +107,9 @@ message ServerStaticAddressLoopInRequest { bytes swap_hash = 2; // The deposit outpoints the client wishes to loop in. They implicitly state - // the swap amount. + // the swap amount if the amount field is not specified. If the amount field + // is specified, the server will use the total amount of the deposit + // outpoints minus the amount as the change amount. repeated string deposit_outpoints = 3; // The swap invoice that the client wants the server to pay. @@ -135,6 +137,17 @@ message ServerStaticAddressLoopInRequest { // swap payment. If the timeout is reached the swap will be aborted on the // server side and the client can retry the swap with different parameters. uint32 payment_timeout_seconds = 8; + + /* + The optional swap amount the client is attempting to swap. If specified the + server will take out this amount from the total value of provided + deposit_outpoints and will send the change back to the static address. If + this results in dust change the server will reject the swap request. If the + amount is not specified the server will use the total amount of the + deposit_outpoints as swap amount without providing an additional flag - this + is to maintain backwards compatibility. + */ + uint64 amount = 9; } message ServerStaticAddressLoopInResponse { From 6a26ea35a645de25b8da5bbf2211a1ef01b2f280 Mon Sep 17 00:00:00 2001 From: Slyghtning Date: Wed, 2 Apr 2025 14:29:48 +0200 Subject: [PATCH 05/12] staticaddr: method to fetch deposits by outpoints --- loopdb/sqlc/querier.go | 1 + .../sqlc/queries/static_address_deposits.sql | 10 +++++ loopdb/sqlc/static_address_deposits.sql.go | 33 +++++++++++++++ staticaddr/deposit/interface.go | 4 ++ staticaddr/deposit/manager.go | 33 +++++++++++++++ staticaddr/deposit/manager_test.go | 7 ++++ staticaddr/deposit/sql_store.go | 42 +++++++++++++++++++ staticaddr/loopin/interface.go | 5 +++ 8 files changed, 135 insertions(+) diff --git a/loopdb/sqlc/querier.go b/loopdb/sqlc/querier.go index 15b2e388f..26e4c0554 100644 --- a/loopdb/sqlc/querier.go +++ b/loopdb/sqlc/querier.go @@ -18,6 +18,7 @@ type Querier interface { CreateStaticAddress(ctx context.Context, arg CreateStaticAddressParams) error CreateWithdrawal(ctx context.Context, arg CreateWithdrawalParams) error CreateWithdrawalDeposit(ctx context.Context, arg CreateWithdrawalDepositParams) error + DepositForOutpoint(ctx context.Context, arg DepositForOutpointParams) (Deposit, error) FetchLiquidityParams(ctx context.Context) ([]byte, error) GetAllWithdrawals(ctx context.Context) ([]Withdrawal, error) GetBatchSweeps(ctx context.Context, batchID int32) ([]Sweep, error) diff --git a/loopdb/sqlc/queries/static_address_deposits.sql b/loopdb/sqlc/queries/static_address_deposits.sql index bc782bbb2..2987e469e 100644 --- a/loopdb/sqlc/queries/static_address_deposits.sql +++ b/loopdb/sqlc/queries/static_address_deposits.sql @@ -49,6 +49,16 @@ FROM WHERE deposit_id = $1; +-- name: DepositForOutpoint :one +SELECT + * +FROM + deposits +WHERE + tx_hash = $1 +AND + out_index = $2; + -- name: AllDeposits :many SELECT * diff --git a/loopdb/sqlc/static_address_deposits.sql.go b/loopdb/sqlc/static_address_deposits.sql.go index 75645c8e1..3a5c8076b 100644 --- a/loopdb/sqlc/static_address_deposits.sql.go +++ b/loopdb/sqlc/static_address_deposits.sql.go @@ -100,6 +100,39 @@ func (q *Queries) CreateDeposit(ctx context.Context, arg CreateDepositParams) er return err } +const depositForOutpoint = `-- name: DepositForOutpoint :one +SELECT + id, deposit_id, tx_hash, out_index, amount, confirmation_height, timeout_sweep_pk_script, expiry_sweep_txid, finalized_withdrawal_tx +FROM + deposits +WHERE + tx_hash = $1 +AND + out_index = $2 +` + +type DepositForOutpointParams struct { + TxHash []byte + OutIndex int32 +} + +func (q *Queries) DepositForOutpoint(ctx context.Context, arg DepositForOutpointParams) (Deposit, error) { + row := q.db.QueryRowContext(ctx, depositForOutpoint, arg.TxHash, arg.OutIndex) + var i Deposit + err := row.Scan( + &i.ID, + &i.DepositID, + &i.TxHash, + &i.OutIndex, + &i.Amount, + &i.ConfirmationHeight, + &i.TimeoutSweepPkScript, + &i.ExpirySweepTxid, + &i.FinalizedWithdrawalTx, + ) + return i, err +} + const getDeposit = `-- name: GetDeposit :one SELECT id, deposit_id, tx_hash, out_index, amount, confirmation_height, timeout_sweep_pk_script, expiry_sweep_txid, finalized_withdrawal_tx diff --git a/staticaddr/deposit/interface.go b/staticaddr/deposit/interface.go index d38cfbaac..c18011bc3 100644 --- a/staticaddr/deposit/interface.go +++ b/staticaddr/deposit/interface.go @@ -26,6 +26,10 @@ type Store interface { // GetDeposit retrieves a deposit with depositID from the database. GetDeposit(ctx context.Context, depositID ID) (*Deposit, error) + // DepositForOutpoint retrieves the deposit with the given outpoint. + DepositForOutpoint(ctx context.Context, outpoint string) (*Deposit, + error) + // AllDeposits retrieves all deposits from the store. AllDeposits(ctx context.Context) ([]*Deposit, error) } diff --git a/staticaddr/deposit/manager.go b/staticaddr/deposit/manager.go index 44ca40d2c..cdea4949a 100644 --- a/staticaddr/deposit/manager.go +++ b/staticaddr/deposit/manager.go @@ -572,3 +572,36 @@ func (m *Manager) toActiveDeposits(outpoints *[]wire.OutPoint) ([]*FSM, return fsms, deposits } + +// DepositsForOutpoints returns all deposits that are behind the given +// outpoints. +func (m *Manager) DepositsForOutpoints(ctx context.Context, + outpoints []string) ([]*Deposit, error) { + + // Check for duplicates. + existingOutpoints := make(map[string]struct{}, len(outpoints)) + for i, o := range outpoints { + if _, ok := existingOutpoints[o]; ok { + return nil, fmt.Errorf("duplicate outpoint %s "+ + "at index %d", o, i) + } + existingOutpoints[o] = struct{}{} + } + + deposits := make([]*Deposit, 0, len(outpoints)) + for _, o := range outpoints { + op, err := wire.NewOutPointFromString(o) + if err != nil { + return nil, err + } + + deposit, err := m.cfg.Store.DepositForOutpoint(ctx, op.String()) + if err != nil { + return nil, err + } + + deposits = append(deposits, deposit) + } + + return deposits, nil +} diff --git a/staticaddr/deposit/manager_test.go b/staticaddr/deposit/manager_test.go index 007414c2c..74a361eb2 100644 --- a/staticaddr/deposit/manager_test.go +++ b/staticaddr/deposit/manager_test.go @@ -165,6 +165,13 @@ func (s *mockStore) GetDeposit(ctx context.Context, depositID ID) (*Deposit, return args.Get(0).(*Deposit), args.Error(1) } +func (s *mockStore) DepositForOutpoint(ctx context.Context, + outpoint string) (*Deposit, error) { + + args := s.Called(ctx, outpoint) + return args.Get(0).(*Deposit), args.Error(1) +} + func (s *mockStore) AllDeposits(ctx context.Context) ([]*Deposit, error) { args := s.Called(ctx) return args.Get(0).([]*Deposit), args.Error(1) diff --git a/staticaddr/deposit/sql_store.go b/staticaddr/deposit/sql_store.go index 6a52ae282..1303c6a70 100644 --- a/staticaddr/deposit/sql_store.go +++ b/staticaddr/deposit/sql_store.go @@ -149,6 +149,48 @@ func (s *SqlStore) GetDeposit(ctx context.Context, id ID) (*Deposit, error) { return deposit, nil } +// DepositForOutpoint retrieves the deposit with the given outpoint from the +// database. +func (s *SqlStore) DepositForOutpoint(ctx context.Context, + outpoint string) (*Deposit, error) { + + var deposit *Deposit + err := s.baseDB.ExecTx(ctx, loopdb.NewSqlReadOpts(), + func(q *sqlc.Queries) error { + op, err := wire.NewOutPointFromString(outpoint) + if err != nil { + return err + } + params := sqlc.DepositForOutpointParams{ + TxHash: op.Hash[:], + OutIndex: int32(op.Index), + } + row, err := q.DepositForOutpoint(ctx, params) + if err != nil { + return err + } + + latestUpdate, err := q.GetLatestDepositUpdate( + ctx, row.DepositID, + ) + if err != nil { + return err + } + + deposit, err = s.toDeposit(row, latestUpdate) + if err != nil { + return err + } + + return nil + }) + if err != nil { + return nil, err + } + + return deposit, nil +} + // AllDeposits retrieves all known deposits to our static address. func (s *SqlStore) AllDeposits(ctx context.Context) ([]*Deposit, error) { var allDeposits []*Deposit diff --git a/staticaddr/loopin/interface.go b/staticaddr/loopin/interface.go index e4e73862c..cf95f838b 100644 --- a/staticaddr/loopin/interface.go +++ b/staticaddr/loopin/interface.go @@ -48,6 +48,11 @@ type DepositManager interface { // invalid. TransitionDeposits(ctx context.Context, deposits []*deposit.Deposit, event fsm.EventType, expectedFinalState fsm.StateType) error + + // DepositsForOutpoints returns all deposits that behind the given + // outpoints. + DepositsForOutpoints(ctx context.Context, outpoints []string) ( + []*deposit.Deposit, error) } // StaticAddressLoopInStore provides access to the static address loop-in DB. From 38c90d9d549155518681d5bbab2de7b136f5a4c8 Mon Sep 17 00:00:00 2001 From: Slyghtning Date: Thu, 20 Feb 2025 15:40:07 +0100 Subject: [PATCH 06/12] sqlc: add amount column to static swaps --- .../000017_static_selected_amount.down.sql | 3 +++ .../000017_static_selected_amount.up.sql | 4 ++++ loopdb/sqlc/models.go | 1 + loopdb/sqlc/queries/static_address_loopin.sql | 4 +++- loopdb/sqlc/static_address_loopin.sql.go | 14 +++++++++++--- 5 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 loopdb/sqlc/migrations/000017_static_selected_amount.down.sql create mode 100644 loopdb/sqlc/migrations/000017_static_selected_amount.up.sql diff --git a/loopdb/sqlc/migrations/000017_static_selected_amount.down.sql b/loopdb/sqlc/migrations/000017_static_selected_amount.down.sql new file mode 100644 index 000000000..ae6852fc2 --- /dev/null +++ b/loopdb/sqlc/migrations/000017_static_selected_amount.down.sql @@ -0,0 +1,3 @@ +-- selected_amount is a fractional amount amongst selected deposits of a static +-- address loop-in swap. +ALTER TABLE static_address_swaps DROP COLUMN selected_amount; diff --git a/loopdb/sqlc/migrations/000017_static_selected_amount.up.sql b/loopdb/sqlc/migrations/000017_static_selected_amount.up.sql new file mode 100644 index 000000000..52027e30b --- /dev/null +++ b/loopdb/sqlc/migrations/000017_static_selected_amount.up.sql @@ -0,0 +1,4 @@ +-- selected_amount is a fractional amount amongst selected deposits of a static +-- address loop-in swap. A selected amount of 0 indicates that the total amount +-- of deposits is selected for the swap. +ALTER TABLE static_address_swaps ADD selected_amount BIGINT NOT NULL DEFAULT 0; diff --git a/loopdb/sqlc/models.go b/loopdb/sqlc/models.go index 6728bb420..281c795d4 100644 --- a/loopdb/sqlc/models.go +++ b/loopdb/sqlc/models.go @@ -146,6 +146,7 @@ type StaticAddressSwap struct { HtlcTxFeeRateSatKw int64 HtlcTimeoutSweepTxID sql.NullString HtlcTimeoutSweepAddress string + SelectedAmount int64 } type StaticAddressSwapUpdate struct { diff --git a/loopdb/sqlc/queries/static_address_loopin.sql b/loopdb/sqlc/queries/static_address_loopin.sql index ea4344b75..16fa9ab3a 100644 --- a/loopdb/sqlc/queries/static_address_loopin.sql +++ b/loopdb/sqlc/queries/static_address_loopin.sql @@ -6,6 +6,7 @@ INSERT INTO static_address_swaps ( payment_timeout_seconds, quoted_swap_fee_satoshis, deposit_outpoints, + selected_amount, htlc_tx_fee_rate_sat_kw, htlc_timeout_sweep_tx_id, htlc_timeout_sweep_address @@ -18,7 +19,8 @@ INSERT INTO static_address_swaps ( $6, $7, $8, - $9 + $9, + $10 ); -- name: UpdateStaticAddressLoopIn :exec diff --git a/loopdb/sqlc/static_address_loopin.sql.go b/loopdb/sqlc/static_address_loopin.sql.go index 22ee6438a..d18496912 100644 --- a/loopdb/sqlc/static_address_loopin.sql.go +++ b/loopdb/sqlc/static_address_loopin.sql.go @@ -51,7 +51,7 @@ func (q *Queries) GetLoopInSwapUpdates(ctx context.Context, swapHash []byte) ([] const getStaticAddressLoopInSwap = `-- name: GetStaticAddressLoopInSwap :one SELECT swaps.id, swaps.swap_hash, swaps.preimage, swaps.initiation_time, swaps.amount_requested, swaps.cltv_expiry, swaps.max_miner_fee, swaps.max_swap_fee, swaps.initiation_height, swaps.protocol_version, swaps.label, - static_address_swaps.id, static_address_swaps.swap_hash, static_address_swaps.swap_invoice, static_address_swaps.last_hop, static_address_swaps.payment_timeout_seconds, static_address_swaps.quoted_swap_fee_satoshis, static_address_swaps.deposit_outpoints, static_address_swaps.htlc_tx_fee_rate_sat_kw, static_address_swaps.htlc_timeout_sweep_tx_id, static_address_swaps.htlc_timeout_sweep_address, + static_address_swaps.id, static_address_swaps.swap_hash, static_address_swaps.swap_invoice, static_address_swaps.last_hop, static_address_swaps.payment_timeout_seconds, static_address_swaps.quoted_swap_fee_satoshis, static_address_swaps.deposit_outpoints, static_address_swaps.htlc_tx_fee_rate_sat_kw, static_address_swaps.htlc_timeout_sweep_tx_id, static_address_swaps.htlc_timeout_sweep_address, static_address_swaps.selected_amount, htlc_keys.swap_hash, htlc_keys.sender_script_pubkey, htlc_keys.receiver_script_pubkey, htlc_keys.sender_internal_pubkey, htlc_keys.receiver_internal_pubkey, htlc_keys.client_key_family, htlc_keys.client_key_index FROM swaps @@ -85,6 +85,7 @@ type GetStaticAddressLoopInSwapRow struct { HtlcTxFeeRateSatKw int64 HtlcTimeoutSweepTxID sql.NullString HtlcTimeoutSweepAddress string + SelectedAmount int64 SwapHash_3 []byte SenderScriptPubkey []byte ReceiverScriptPubkey []byte @@ -119,6 +120,7 @@ func (q *Queries) GetStaticAddressLoopInSwap(ctx context.Context, swapHash []byt &i.HtlcTxFeeRateSatKw, &i.HtlcTimeoutSweepTxID, &i.HtlcTimeoutSweepAddress, + &i.SelectedAmount, &i.SwapHash_3, &i.SenderScriptPubkey, &i.ReceiverScriptPubkey, @@ -133,7 +135,7 @@ func (q *Queries) GetStaticAddressLoopInSwap(ctx context.Context, swapHash []byt const getStaticAddressLoopInSwapsByStates = `-- name: GetStaticAddressLoopInSwapsByStates :many SELECT swaps.id, swaps.swap_hash, swaps.preimage, swaps.initiation_time, swaps.amount_requested, swaps.cltv_expiry, swaps.max_miner_fee, swaps.max_swap_fee, swaps.initiation_height, swaps.protocol_version, swaps.label, - static_address_swaps.id, static_address_swaps.swap_hash, static_address_swaps.swap_invoice, static_address_swaps.last_hop, static_address_swaps.payment_timeout_seconds, static_address_swaps.quoted_swap_fee_satoshis, static_address_swaps.deposit_outpoints, static_address_swaps.htlc_tx_fee_rate_sat_kw, static_address_swaps.htlc_timeout_sweep_tx_id, static_address_swaps.htlc_timeout_sweep_address, + static_address_swaps.id, static_address_swaps.swap_hash, static_address_swaps.swap_invoice, static_address_swaps.last_hop, static_address_swaps.payment_timeout_seconds, static_address_swaps.quoted_swap_fee_satoshis, static_address_swaps.deposit_outpoints, static_address_swaps.htlc_tx_fee_rate_sat_kw, static_address_swaps.htlc_timeout_sweep_tx_id, static_address_swaps.htlc_timeout_sweep_address, static_address_swaps.selected_amount, htlc_keys.swap_hash, htlc_keys.sender_script_pubkey, htlc_keys.receiver_script_pubkey, htlc_keys.sender_internal_pubkey, htlc_keys.receiver_internal_pubkey, htlc_keys.client_key_family, htlc_keys.client_key_index FROM swaps @@ -178,6 +180,7 @@ type GetStaticAddressLoopInSwapsByStatesRow struct { HtlcTxFeeRateSatKw int64 HtlcTimeoutSweepTxID sql.NullString HtlcTimeoutSweepAddress string + SelectedAmount int64 SwapHash_3 []byte SenderScriptPubkey []byte ReceiverScriptPubkey []byte @@ -218,6 +221,7 @@ func (q *Queries) GetStaticAddressLoopInSwapsByStates(ctx context.Context, dolla &i.HtlcTxFeeRateSatKw, &i.HtlcTimeoutSweepTxID, &i.HtlcTimeoutSweepAddress, + &i.SelectedAmount, &i.SwapHash_3, &i.SenderScriptPubkey, &i.ReceiverScriptPubkey, @@ -247,6 +251,7 @@ INSERT INTO static_address_swaps ( payment_timeout_seconds, quoted_swap_fee_satoshis, deposit_outpoints, + selected_amount, htlc_tx_fee_rate_sat_kw, htlc_timeout_sweep_tx_id, htlc_timeout_sweep_address @@ -259,7 +264,8 @@ INSERT INTO static_address_swaps ( $6, $7, $8, - $9 + $9, + $10 ) ` @@ -270,6 +276,7 @@ type InsertStaticAddressLoopInParams struct { PaymentTimeoutSeconds int32 QuotedSwapFeeSatoshis int64 DepositOutpoints string + SelectedAmount int64 HtlcTxFeeRateSatKw int64 HtlcTimeoutSweepTxID sql.NullString HtlcTimeoutSweepAddress string @@ -283,6 +290,7 @@ func (q *Queries) InsertStaticAddressLoopIn(ctx context.Context, arg InsertStati arg.PaymentTimeoutSeconds, arg.QuotedSwapFeeSatoshis, arg.DepositOutpoints, + arg.SelectedAmount, arg.HtlcTxFeeRateSatKw, arg.HtlcTimeoutSweepTxID, arg.HtlcTimeoutSweepAddress, From 23a3f23ddb74a03d5c939f5903edcdf105c3629d Mon Sep 17 00:00:00 2001 From: Slyghtning Date: Thu, 20 Feb 2025 15:40:58 +0100 Subject: [PATCH 07/12] looprpc: fractional amount for static address loop-ins The QuoteRequest adds a field select_deposits to signal that the specified quote amount should be coin-selected from the client's deposits in order to determine the number of deposits to quote for. The StaticAddressLoopInRequest gets a new amount field that either indicates that the swap amount should be allocated from the passed deposits or coin-selected from all available deposits. --- looprpc/client.pb.go | 1707 ++++++++++++++++++----------------- looprpc/client.proto | 33 +- looprpc/client.swagger.json | 22 +- 3 files changed, 921 insertions(+), 841 deletions(-) diff --git a/looprpc/client.pb.go b/looprpc/client.pb.go index d341a0592..31af0d7ec 100644 --- a/looprpc/client.pb.go +++ b/looprpc/client.pb.go @@ -1890,7 +1890,10 @@ type QuoteRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The amount to swap in satoshis. + // The amount to swap in satoshis. In the loop-in case this can either be taken + // from the connected lnd wallet or coin-selected from static address deposits. + // This is controlled by the select_deposits flag. If deposit_outpoints are + // specified, the coins are taken out of that. Amt int64 `protobuf:"varint,1,opt,name=amt,proto3" json:"amt,omitempty"` // The confirmation target that should be used either for the sweep of the // on-chain HTLC broadcast by the swap server in the case of a Loop Out, or for @@ -1917,12 +1920,18 @@ type QuoteRequest struct { // probing and payment. Private bool `protobuf:"varint,7,opt,name=private,proto3" json:"private,omitempty"` // Static address deposit outpoints that will be quoted for. This option only - // pertains to loop in swaps. Either this or the amt parameter can be set at - // the same time. + // pertains to loop in swaps. If the amt field is set as well the respective + // partial amount will be swapped. Cannot be used in conjunction with + // select_deposits. DepositOutpoints []string `protobuf:"bytes,8,rep,name=deposit_outpoints,json=depositOutpoints,proto3" json:"deposit_outpoints,omitempty"` // The optional asset information to use for the swap. If set, the quote will // be returned in the specified asset. AssetInfo *AssetLoopOutRequest `protobuf:"bytes,9,opt,name=asset_info,json=assetInfo,proto3" json:"asset_info,omitempty"` + // This field indicates whether the swap amount should be covered by our lnd + // wallet or by static address deposits. If set to true, the swap amount + // will be selected from the static address deposits. This field cannot be used + // in conjunction with deposit_outpoints. + SelectDeposits bool `protobuf:"varint,10,opt,name=select_deposits,json=selectDeposits,proto3" json:"select_deposits,omitempty"` } func (x *QuoteRequest) Reset() { @@ -2020,6 +2029,13 @@ func (x *QuoteRequest) GetAssetInfo() *AssetLoopOutRequest { return nil } +func (x *QuoteRequest) GetSelectDeposits() bool { + if x != nil { + return x.SelectDeposits + } + return false +} + type InQuoteResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -5566,6 +5582,18 @@ type StaticAddressLoopInRequest struct { // payment. If the timeout is reached the swap will be aborted on the server // side and the client can retry the swap with different parameters. PaymentTimeoutSeconds uint32 `protobuf:"varint,8,opt,name=payment_timeout_seconds,json=paymentTimeoutSeconds,proto3" json:"payment_timeout_seconds,omitempty"` + // The optional swap amount the client is attempting to swap. It can be + // provided in combination with the outpoints or separately. If provided with + // outpoints the client takes out this amount from the sum of provided + // outpoints and sends the change back to the static address. If the amount is + // provided without outpoints, the client will select deposits automatically. + // The coin selection strategy is simplified by sorting all available deposits + // in descending order by amount, and equal amounts in ascending order of + // blocks until expiry, and then selecting the largest deposits first until the + // amount is reached. The change will be sent back to the static address. If a + // subset of outpoints suffice to cover the specified amount the swap will be + // canceled to allow the user to safe on transaction fees. + Amount int64 `protobuf:"varint,9,opt,name=amount,proto3" json:"amount,omitempty"` } func (x *StaticAddressLoopInRequest) Reset() { @@ -5656,6 +5684,13 @@ func (x *StaticAddressLoopInRequest) GetPaymentTimeoutSeconds() uint32 { return 0 } +func (x *StaticAddressLoopInRequest) GetAmount() int64 { + if x != nil { + return x.Amount + } + return 0 +} + type StaticAddressLoopInResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -6337,7 +6372,7 @@ var file_client_proto_rawDesc = []byte{ 0x74, 0x61, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x43, 0x6c, 0x74, 0x76, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x4a, 0x04, - 0x08, 0x07, 0x10, 0x08, 0x22, 0x92, 0x03, 0x0a, 0x0c, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, + 0x08, 0x07, 0x10, 0x08, 0x22, 0xbb, 0x03, 0x0a, 0x0c, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6d, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x61, 0x6d, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x63, 0x6f, @@ -6362,842 +6397,846 @@ var file_client_proto_rawDesc = []byte{ 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x09, - 0x61, 0x73, 0x73, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0xb0, 0x01, 0x0a, 0x0f, 0x49, 0x6e, - 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, - 0x0c, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x73, 0x61, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x0a, 0x73, 0x77, 0x61, 0x70, 0x46, 0x65, 0x65, 0x53, 0x61, 0x74, 0x12, - 0x2f, 0x0a, 0x14, 0x68, 0x74, 0x6c, 0x63, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x5f, - 0x66, 0x65, 0x65, 0x5f, 0x73, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x68, - 0x74, 0x6c, 0x63, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x46, 0x65, 0x65, 0x53, 0x61, 0x74, - 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6c, 0x74, 0x76, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x63, 0x6c, 0x74, 0x76, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x12, - 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, 0xb0, 0x02, 0x0a, - 0x10, 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x20, 0x0a, 0x0c, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x73, 0x61, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x73, 0x77, 0x61, 0x70, 0x46, 0x65, 0x65, - 0x53, 0x61, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x72, 0x65, 0x70, 0x61, 0x79, 0x5f, 0x61, 0x6d, - 0x74, 0x5f, 0x73, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x70, 0x72, 0x65, - 0x70, 0x61, 0x79, 0x41, 0x6d, 0x74, 0x53, 0x61, 0x74, 0x12, 0x2b, 0x0a, 0x12, 0x68, 0x74, 0x6c, - 0x63, 0x5f, 0x73, 0x77, 0x65, 0x65, 0x70, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x73, 0x61, 0x74, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x68, 0x74, 0x6c, 0x63, 0x53, 0x77, 0x65, 0x65, 0x70, - 0x46, 0x65, 0x65, 0x53, 0x61, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x70, - 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x64, 0x65, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x0f, 0x73, 0x77, 0x61, 0x70, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, - 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6c, 0x74, 0x76, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x63, 0x6c, 0x74, 0x76, 0x44, 0x65, 0x6c, 0x74, - 0x61, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x54, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x12, 0x3b, 0x0a, 0x0e, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x72, 0x66, 0x71, 0x5f, - 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, - 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x66, 0x71, 0x49, 0x6e, 0x66, - 0x6f, 0x52, 0x0c, 0x61, 0x73, 0x73, 0x65, 0x74, 0x52, 0x66, 0x71, 0x49, 0x6e, 0x66, 0x6f, 0x22, - 0x70, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x10, 0x0a, 0x03, 0x61, 0x6d, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x61, 0x6d, - 0x74, 0x12, 0x19, 0x0a, 0x08, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x68, 0x6f, 0x70, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6c, 0x61, 0x73, 0x74, 0x48, 0x6f, 0x70, 0x12, 0x33, 0x0a, 0x0b, - 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x68, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x12, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x6f, 0x75, 0x74, - 0x65, 0x48, 0x69, 0x6e, 0x74, 0x52, 0x0a, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x48, 0x69, 0x6e, 0x74, - 0x73, 0x22, 0x0f, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x0f, 0x0a, 0x0d, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x22, 0x3c, 0x0a, 0x0e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, - 0x4c, 0x34, 0x30, 0x32, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x73, 0x22, 0x17, 0x0a, 0x15, 0x46, 0x65, 0x74, 0x63, 0x68, 0x4c, 0x34, 0x30, 0x32, 0x54, 0x6f, - 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x18, 0x0a, 0x16, 0x46, 0x65, - 0x74, 0x63, 0x68, 0x4c, 0x34, 0x30, 0x32, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xcb, 0x02, 0x0a, 0x09, 0x4c, 0x34, 0x30, 0x32, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x6d, 0x61, 0x63, 0x61, 0x72, - 0x6f, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x62, 0x61, 0x73, 0x65, 0x4d, - 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x61, 0x79, 0x6d, 0x65, - 0x6e, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x70, - 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x29, 0x0a, 0x10, 0x70, 0x61, - 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x72, 0x65, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x65, - 0x69, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, - 0x70, 0x61, 0x69, 0x64, 0x5f, 0x6d, 0x73, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x0e, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x61, 0x69, 0x64, 0x4d, 0x73, 0x61, 0x74, 0x12, - 0x31, 0x0a, 0x15, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x70, - 0x61, 0x69, 0x64, 0x5f, 0x6d, 0x73, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, - 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x46, 0x65, 0x65, 0x50, 0x61, 0x69, 0x64, 0x4d, 0x73, - 0x61, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x64, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x64, 0x12, - 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, - 0x69, 0x64, 0x22, 0xc8, 0x01, 0x0a, 0x09, 0x4c, 0x6f, 0x6f, 0x70, 0x53, 0x74, 0x61, 0x74, 0x73, - 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, - 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x73, 0x75, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x66, 0x61, - 0x69, 0x6c, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, - 0x66, 0x61, 0x69, 0x6c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x75, 0x6d, - 0x5f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x6d, 0x74, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x0d, 0x73, 0x75, 0x6d, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x41, 0x6d, - 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x73, 0x75, 0x6d, 0x5f, 0x73, 0x75, 0x63, 0x63, 0x65, 0x65, 0x64, - 0x65, 0x64, 0x5f, 0x61, 0x6d, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x73, 0x75, - 0x6d, 0x53, 0x75, 0x63, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, 0x41, 0x6d, 0x74, 0x22, 0x10, 0x0a, - 0x0e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, - 0xe1, 0x02, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, - 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x70, 0x63, 0x5f, 0x6c, - 0x69, 0x73, 0x74, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x70, 0x63, - 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x74, 0x5f, 0x6c, - 0x69, 0x73, 0x74, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, - 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x61, 0x63, 0x61, 0x72, - 0x6f, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, - 0x6d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x50, 0x61, 0x74, 0x68, 0x12, 0x22, 0x0a, 0x0d, - 0x74, 0x6c, 0x73, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x6c, 0x73, 0x43, 0x65, 0x72, 0x74, 0x50, 0x61, 0x74, 0x68, - 0x12, 0x38, 0x0a, 0x0e, 0x6c, 0x6f, 0x6f, 0x70, 0x5f, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x74, 0x61, - 0x74, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, - 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x6f, 0x70, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x0c, 0x6c, 0x6f, - 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x36, 0x0a, 0x0d, 0x6c, 0x6f, - 0x6f, 0x70, 0x5f, 0x69, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x61, 0x73, 0x73, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x5f, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x18, 0x0a, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x73, 0x22, 0xb0, 0x01, 0x0a, 0x0f, 0x49, 0x6e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0c, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x66, + 0x65, 0x65, 0x5f, 0x73, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x73, 0x77, + 0x61, 0x70, 0x46, 0x65, 0x65, 0x53, 0x61, 0x74, 0x12, 0x2f, 0x0a, 0x14, 0x68, 0x74, 0x6c, 0x63, + 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x73, 0x61, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x68, 0x74, 0x6c, 0x63, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x73, 0x68, 0x46, 0x65, 0x65, 0x53, 0x61, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6c, 0x74, + 0x76, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x63, + 0x6c, 0x74, 0x76, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, + 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x63, + 0x6f, 0x6e, 0x66, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, + 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, 0xb0, 0x02, 0x0a, 0x10, 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, + 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0c, 0x73, 0x77, + 0x61, 0x70, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x73, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x0a, 0x73, 0x77, 0x61, 0x70, 0x46, 0x65, 0x65, 0x53, 0x61, 0x74, 0x12, 0x24, 0x0a, 0x0e, + 0x70, 0x72, 0x65, 0x70, 0x61, 0x79, 0x5f, 0x61, 0x6d, 0x74, 0x5f, 0x73, 0x61, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x70, 0x72, 0x65, 0x70, 0x61, 0x79, 0x41, 0x6d, 0x74, 0x53, + 0x61, 0x74, 0x12, 0x2b, 0x0a, 0x12, 0x68, 0x74, 0x6c, 0x63, 0x5f, 0x73, 0x77, 0x65, 0x65, 0x70, + 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x73, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, + 0x68, 0x74, 0x6c, 0x63, 0x53, 0x77, 0x65, 0x65, 0x70, 0x46, 0x65, 0x65, 0x53, 0x61, 0x74, 0x12, + 0x2a, 0x0a, 0x11, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, + 0x64, 0x65, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x73, 0x77, 0x61, 0x70, + 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, + 0x6c, 0x74, 0x76, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x09, 0x63, 0x6c, 0x74, 0x76, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, + 0x6e, 0x66, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x3b, 0x0a, 0x0e, 0x61, + 0x73, 0x73, 0x65, 0x74, 0x5f, 0x72, 0x66, 0x71, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x73, + 0x73, 0x65, 0x74, 0x52, 0x66, 0x71, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0c, 0x61, 0x73, 0x73, 0x65, + 0x74, 0x52, 0x66, 0x71, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x70, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x62, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6d, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x61, 0x6d, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x6c, 0x61, + 0x73, 0x74, 0x5f, 0x68, 0x6f, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6c, 0x61, + 0x73, 0x74, 0x48, 0x6f, 0x70, 0x12, 0x33, 0x0a, 0x0b, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x68, + 0x69, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6c, 0x6f, 0x6f, + 0x70, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x48, 0x69, 0x6e, 0x74, 0x52, 0x0a, + 0x72, 0x6f, 0x75, 0x74, 0x65, 0x48, 0x69, 0x6e, 0x74, 0x73, 0x22, 0x0f, 0x0a, 0x0d, 0x50, 0x72, + 0x6f, 0x62, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x0f, 0x0a, 0x0d, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3c, 0x0a, 0x0e, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, + 0x0a, 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, + 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x34, 0x30, 0x32, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x52, 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22, 0x17, 0x0a, 0x15, 0x46, 0x65, + 0x74, 0x63, 0x68, 0x4c, 0x34, 0x30, 0x32, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x22, 0x18, 0x0a, 0x16, 0x46, 0x65, 0x74, 0x63, 0x68, 0x4c, 0x34, 0x30, 0x32, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xcb, 0x02, + 0x0a, 0x09, 0x4c, 0x34, 0x30, 0x32, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x62, + 0x61, 0x73, 0x65, 0x5f, 0x6d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x0c, 0x62, 0x61, 0x73, 0x65, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, + 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x48, + 0x61, 0x73, 0x68, 0x12, 0x29, 0x0a, 0x10, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x70, + 0x72, 0x65, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x70, + 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x65, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x28, + 0x0a, 0x10, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x69, 0x64, 0x5f, 0x6d, 0x73, + 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x50, 0x61, 0x69, 0x64, 0x4d, 0x73, 0x61, 0x74, 0x12, 0x31, 0x0a, 0x15, 0x72, 0x6f, 0x75, 0x74, + 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x70, 0x61, 0x69, 0x64, 0x5f, 0x6d, 0x73, 0x61, + 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, + 0x46, 0x65, 0x65, 0x50, 0x61, 0x69, 0x64, 0x4d, 0x73, 0x61, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x74, + 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x12, 0x18, + 0x0a, 0x07, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x07, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x6f, 0x72, + 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0xc8, 0x01, 0x0a, 0x09, + 0x4c, 0x6f, 0x6f, 0x70, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x65, 0x6e, + 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x0c, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x23, + 0x0a, 0x0d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x66, 0x61, 0x69, 0x6c, 0x5f, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x66, 0x61, 0x69, 0x6c, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x75, 0x6d, 0x5f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, + 0x67, 0x5f, 0x61, 0x6d, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x73, 0x75, 0x6d, + 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x41, 0x6d, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x73, 0x75, + 0x6d, 0x5f, 0x73, 0x75, 0x63, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, 0x5f, 0x61, 0x6d, 0x74, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x73, 0x75, 0x6d, 0x53, 0x75, 0x63, 0x63, 0x65, 0x65, + 0x64, 0x65, 0x64, 0x41, 0x6d, 0x74, 0x22, 0x10, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xe1, 0x02, 0x0a, 0x0f, 0x47, 0x65, 0x74, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, + 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, + 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x70, 0x63, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x70, 0x63, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x12, + 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, + 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x74, + 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, + 0x6e, 0x50, 0x61, 0x74, 0x68, 0x12, 0x22, 0x0a, 0x0d, 0x74, 0x6c, 0x73, 0x5f, 0x63, 0x65, 0x72, + 0x74, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x6c, + 0x73, 0x43, 0x65, 0x72, 0x74, 0x50, 0x61, 0x74, 0x68, 0x12, 0x38, 0x0a, 0x0e, 0x6c, 0x6f, 0x6f, + 0x70, 0x5f, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x6f, 0x70, - 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x0b, 0x6c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x53, 0x74, 0x61, - 0x74, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x68, 0x61, 0x73, - 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x48, - 0x61, 0x73, 0x68, 0x22, 0x1b, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, - 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x22, 0x8d, 0x0b, 0x0a, 0x13, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, - 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x2c, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, - 0x63, 0x2e, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x52, - 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x65, 0x65, 0x5f, 0x70, 0x70, - 0x6d, 0x18, 0x10, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x66, 0x65, 0x65, 0x50, 0x70, 0x6d, 0x12, - 0x3d, 0x0a, 0x1c, 0x73, 0x77, 0x65, 0x65, 0x70, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x72, 0x61, 0x74, - 0x65, 0x5f, 0x73, 0x61, 0x74, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x76, 0x62, 0x79, 0x74, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x17, 0x73, 0x77, 0x65, 0x65, 0x70, 0x46, 0x65, 0x65, 0x52, - 0x61, 0x74, 0x65, 0x53, 0x61, 0x74, 0x50, 0x65, 0x72, 0x56, 0x62, 0x79, 0x74, 0x65, 0x12, 0x27, - 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x70, - 0x70, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x53, 0x77, 0x61, - 0x70, 0x46, 0x65, 0x65, 0x50, 0x70, 0x6d, 0x12, 0x2d, 0x0a, 0x13, 0x6d, 0x61, 0x78, 0x5f, 0x72, - 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x70, 0x70, 0x6d, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, - 0x46, 0x65, 0x65, 0x50, 0x70, 0x6d, 0x12, 0x3a, 0x0a, 0x1a, 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x72, - 0x65, 0x70, 0x61, 0x79, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x65, 0x65, - 0x5f, 0x70, 0x70, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x16, 0x6d, 0x61, 0x78, 0x50, - 0x72, 0x65, 0x70, 0x61, 0x79, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x46, 0x65, 0x65, 0x50, - 0x70, 0x6d, 0x12, 0x24, 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x72, 0x65, 0x70, 0x61, 0x79, - 0x5f, 0x73, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x50, - 0x72, 0x65, 0x70, 0x61, 0x79, 0x53, 0x61, 0x74, 0x12, 0x29, 0x0a, 0x11, 0x6d, 0x61, 0x78, 0x5f, - 0x6d, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x73, 0x61, 0x74, 0x18, 0x07, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x0e, 0x6d, 0x61, 0x78, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x46, 0x65, 0x65, - 0x53, 0x61, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x73, 0x77, 0x65, 0x65, 0x70, 0x5f, 0x63, 0x6f, 0x6e, - 0x66, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, - 0x73, 0x77, 0x65, 0x65, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, - 0x2e, 0x0a, 0x13, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x6f, - 0x66, 0x66, 0x5f, 0x73, 0x65, 0x63, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x66, 0x61, - 0x69, 0x6c, 0x75, 0x72, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x53, 0x65, 0x63, 0x12, - 0x1a, 0x0a, 0x08, 0x61, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x18, 0x0a, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x08, 0x61, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x12, 0x2e, 0x0a, 0x13, 0x61, - 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x5f, 0x62, 0x75, 0x64, 0x67, 0x65, 0x74, 0x5f, 0x73, - 0x61, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x61, 0x75, 0x74, 0x6f, 0x6c, 0x6f, - 0x6f, 0x70, 0x42, 0x75, 0x64, 0x67, 0x65, 0x74, 0x53, 0x61, 0x74, 0x12, 0x3d, 0x0a, 0x19, 0x61, - 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x5f, 0x62, 0x75, 0x64, 0x67, 0x65, 0x74, 0x5f, 0x73, - 0x74, 0x61, 0x72, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x04, 0x42, 0x02, - 0x18, 0x01, 0x52, 0x16, 0x61, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x42, 0x75, 0x64, 0x67, - 0x65, 0x74, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x65, 0x63, 0x12, 0x2b, 0x0a, 0x12, 0x61, 0x75, - 0x74, 0x6f, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x69, 0x6e, 0x5f, 0x66, 0x6c, 0x69, 0x67, 0x68, 0x74, - 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x61, 0x75, 0x74, 0x6f, 0x4d, 0x61, 0x78, 0x49, - 0x6e, 0x46, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x69, 0x6e, 0x5f, 0x73, - 0x77, 0x61, 0x70, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x0d, 0x6d, 0x69, 0x6e, 0x53, 0x77, 0x61, 0x70, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, - 0x26, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x61, 0x6d, 0x6f, 0x75, - 0x6e, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x53, 0x77, 0x61, - 0x70, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x68, 0x74, 0x6c, 0x63, 0x5f, - 0x63, 0x6f, 0x6e, 0x66, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x0e, 0x68, 0x74, 0x6c, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x54, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x12, 0x32, 0x0a, 0x15, 0x61, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x5f, 0x64, 0x65, - 0x73, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x13, 0x61, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x44, 0x65, 0x73, 0x74, 0x41, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x4a, 0x0a, 0x22, 0x61, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, - 0x70, 0x5f, 0x62, 0x75, 0x64, 0x67, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, - 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x5f, 0x73, 0x65, 0x63, 0x18, 0x13, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x1e, 0x61, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x42, 0x75, 0x64, 0x67, 0x65, - 0x74, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x53, 0x65, - 0x63, 0x12, 0x3f, 0x0a, 0x1c, 0x61, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x5f, 0x62, 0x75, - 0x64, 0x67, 0x65, 0x74, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, - 0x68, 0x18, 0x14, 0x20, 0x01, 0x28, 0x04, 0x52, 0x19, 0x61, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, - 0x70, 0x42, 0x75, 0x64, 0x67, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x52, 0x65, 0x66, 0x72, 0x65, - 0x73, 0x68, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x61, 0x73, 0x79, 0x5f, 0x61, 0x75, 0x74, 0x6f, 0x6c, - 0x6f, 0x6f, 0x70, 0x18, 0x15, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x65, 0x61, 0x73, 0x79, 0x41, - 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x12, 0x42, 0x0a, 0x1e, 0x65, 0x61, 0x73, 0x79, 0x5f, - 0x61, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x74, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x61, 0x74, 0x18, 0x16, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x1a, 0x65, 0x61, 0x73, 0x79, 0x41, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x4c, 0x6f, 0x63, - 0x61, 0x6c, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x61, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x61, - 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x17, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x63, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x40, 0x0a, 0x11, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x5f, 0x61, 0x64, 0x64, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x14, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, - 0x64, 0x64, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x5d, 0x0a, 0x11, 0x65, 0x61, 0x73, 0x79, 0x5f, - 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x19, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x71, - 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, - 0x2e, 0x45, 0x61, 0x73, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, 0x65, 0x61, 0x73, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, - 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x73, - 0x77, 0x61, 0x70, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x1a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x66, 0x61, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x50, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x64, 0x0a, 0x14, 0x45, 0x61, - 0x73, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 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, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x45, 0x61, - 0x73, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x41, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x50, - 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x22, 0x68, 0x0a, 0x17, 0x45, 0x61, 0x73, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x41, 0x75, 0x74, - 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x65, - 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, - 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x33, 0x0a, 0x16, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x74, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x61, 0x6d, 0x74, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x54, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x41, 0x73, 0x73, 0x65, 0x74, 0x41, 0x6d, 0x74, 0x22, 0x84, 0x02, 0x0a, 0x0d, 0x4c, - 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x1d, 0x0a, 0x0a, - 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x09, 0x73, - 0x77, 0x61, 0x70, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, - 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x54, 0x79, 0x70, - 0x65, 0x52, 0x08, 0x73, 0x77, 0x61, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, - 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x75, 0x62, - 0x6b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x1a, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x71, 0x75, - 0x69, 0x64, 0x69, 0x74, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x12, 0x2d, 0x0a, 0x12, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x5f, - 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x11, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, - 0x6c, 0x64, 0x12, 0x2d, 0x0a, 0x12, 0x6f, 0x75, 0x74, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x5f, 0x74, - 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, - 0x6f, 0x75, 0x74, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, - 0x64, 0x22, 0x59, 0x0a, 0x19, 0x53, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, - 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3c, - 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x71, - 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, - 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x22, 0x1c, 0x0a, 0x1a, - 0x53, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, - 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x15, 0x0a, 0x13, 0x53, 0x75, - 0x67, 0x67, 0x65, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x22, 0x72, 0x0a, 0x0c, 0x44, 0x69, 0x73, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x66, 0x69, 0x65, - 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x64, - 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x2b, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, - 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, - 0x70, 0x63, 0x2e, 0x41, 0x75, 0x74, 0x6f, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x52, 0x06, 0x72, - 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0xb6, 0x01, 0x0a, 0x14, 0x53, 0x75, 0x67, 0x67, 0x65, 0x73, - 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, - 0x0a, 0x08, 0x6c, 0x6f, 0x6f, 0x70, 0x5f, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, - 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x6c, 0x6f, 0x6f, 0x70, 0x4f, - 0x75, 0x74, 0x12, 0x2f, 0x0a, 0x07, 0x6c, 0x6f, 0x6f, 0x70, 0x5f, 0x69, 0x6e, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, - 0x6f, 0x70, 0x49, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x06, 0x6c, 0x6f, 0x6f, - 0x70, 0x49, 0x6e, 0x12, 0x39, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x66, - 0x69, 0x65, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, - 0x72, 0x70, 0x63, 0x2e, 0x44, 0x69, 0x73, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, - 0x52, 0x0c, 0x64, 0x69, 0x73, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x22, 0x57, - 0x0a, 0x12, 0x41, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x53, 0x77, 0x61, 0x70, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x31, 0x0a, 0x16, 0x69, 0x5f, 0x6b, 0x6e, 0x6f, 0x77, 0x5f, 0x77, - 0x68, 0x61, 0x74, 0x5f, 0x69, 0x5f, 0x61, 0x6d, 0x5f, 0x64, 0x6f, 0x69, 0x6e, 0x67, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x69, 0x4b, 0x6e, 0x6f, 0x77, 0x57, 0x68, 0x61, 0x74, 0x49, - 0x41, 0x6d, 0x44, 0x6f, 0x69, 0x6e, 0x67, 0x22, 0x15, 0x0a, 0x13, 0x41, 0x62, 0x61, 0x6e, 0x64, - 0x6f, 0x6e, 0x53, 0x77, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x19, - 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x5a, 0x0a, 0x18, 0x4c, 0x69, 0x73, - 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0c, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6c, 0x6f, - 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x65, - 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xa9, 0x01, 0x0a, 0x11, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x72, - 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, - 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, - 0x12, 0x13, 0x0a, 0x05, 0x74, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x74, 0x78, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x76, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x04, 0x76, 0x6f, 0x75, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x70, - 0x69, 0x72, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, - 0x79, 0x22, 0x85, 0x01, 0x0a, 0x11, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x73, 0x65, 0x72, - 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, - 0x52, 0x0e, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, - 0x12, 0x2a, 0x0a, 0x11, 0x6f, 0x75, 0x74, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x68, 0x61, - 0x6e, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x04, 0x52, 0x0f, 0x6f, 0x75, 0x74, - 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x43, 0x68, 0x61, 0x6e, 0x53, 0x65, 0x74, 0x12, 0x1b, 0x0a, 0x09, - 0x64, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x64, 0x65, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, 0x22, 0x74, 0x0a, 0x12, 0x49, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x28, 0x0a, 0x10, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x5f, 0x6f, 0x75, 0x74, 0x5f, 0x68, - 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1e, 0x0a, 0x0b, 0x73, 0x77, 0x65, - 0x65, 0x70, 0x5f, 0x74, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x73, 0x77, 0x65, 0x65, 0x70, 0x54, 0x78, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, - 0x82, 0x01, 0x0a, 0x16, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x51, 0x75, - 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6d, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x61, 0x6d, 0x74, 0x12, 0x2d, 0x0a, 0x10, - 0x6e, 0x75, 0x6d, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0f, 0x6e, 0x75, 0x6d, 0x52, - 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x72, - 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x49, 0x64, 0x73, 0x22, 0x65, 0x0a, 0x17, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, - 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x26, 0x0a, 0x0f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x73, - 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x46, 0x65, 0x65, 0x53, 0x61, 0x74, 0x12, 0x22, 0x0a, 0x0d, 0x73, 0x77, 0x65, 0x65, 0x70, - 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x73, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, - 0x73, 0x77, 0x65, 0x65, 0x70, 0x46, 0x65, 0x65, 0x53, 0x61, 0x74, 0x22, 0x18, 0x0a, 0x16, 0x4c, - 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x44, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x29, 0x0a, 0x05, 0x73, 0x77, 0x61, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x13, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x74, 0x4f, 0x75, 0x74, 0x52, 0x05, 0x73, 0x77, 0x61, 0x70, 0x73, 0x22, 0xa0, 0x01, 0x0a, 0x0a, - 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x77, - 0x61, 0x70, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, - 0x77, 0x61, 0x70, 0x48, 0x61, 0x73, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, - 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, - 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0e, - 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x1e, - 0x0a, 0x0b, 0x73, 0x77, 0x65, 0x65, 0x70, 0x5f, 0x74, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x77, 0x65, 0x65, 0x70, 0x54, 0x78, 0x49, 0x64, 0x22, 0x38, - 0x0a, 0x17, 0x4e, 0x65, 0x77, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x22, 0x4c, 0x0a, 0x18, 0x4e, 0x65, 0x77, 0x53, - 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, - 0x0a, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, - 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x22, 0x56, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x6e, - 0x73, 0x70, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, - 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x6d, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, - 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x73, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x66, 0x73, 0x22, 0x42, - 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, - 0x05, 0x75, 0x74, 0x78, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6c, - 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x74, 0x78, 0x6f, 0x52, 0x05, 0x75, 0x74, 0x78, - 0x6f, 0x73, 0x22, 0x8e, 0x01, 0x0a, 0x04, 0x55, 0x74, 0x78, 0x6f, 0x12, 0x25, 0x0a, 0x0e, 0x73, - 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x73, 0x61, 0x74, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x61, - 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x24, 0x0a, - 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x22, 0xb5, 0x01, 0x0a, 0x17, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, - 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x2f, 0x0a, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, 0x74, - 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, - 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6c, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61, - 0x6c, 0x6c, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, 0x12, - 0x22, 0x0a, 0x0d, 0x73, 0x61, 0x74, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x76, 0x62, 0x79, 0x74, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x73, 0x61, 0x74, 0x50, 0x65, 0x72, 0x56, 0x62, - 0x79, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x62, 0x0a, 0x18, 0x57, - 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x77, 0x69, 0x74, 0x68, 0x64, - 0x72, 0x61, 0x77, 0x61, 0x6c, 0x5f, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x10, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x54, - 0x78, 0x48, 0x61, 0x73, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, - 0x67, 0x0a, 0x08, 0x4f, 0x75, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x74, - 0x78, 0x69, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x09, 0x74, 0x78, 0x69, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x78, - 0x69, 0x64, 0x5f, 0x73, 0x74, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x78, - 0x69, 0x64, 0x53, 0x74, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, - 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x7a, 0x0a, 0x20, 0x4c, 0x69, 0x73, 0x74, - 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x44, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0b, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, - 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x6f, - 0x69, 0x6e, 0x74, 0x73, 0x22, 0x62, 0x0a, 0x21, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, - 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x11, 0x66, 0x69, 0x6c, - 0x74, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x44, - 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x52, 0x10, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, - 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x22, 0x24, 0x0a, 0x22, 0x4c, 0x69, 0x73, 0x74, - 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x57, 0x69, 0x74, - 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x69, - 0x0a, 0x23, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x0b, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, - 0x77, 0x61, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, - 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x0b, 0x77, 0x69, - 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x73, 0x22, 0x1f, 0x0a, 0x1d, 0x4c, 0x69, 0x73, - 0x74, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x77, - 0x61, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x58, 0x0a, 0x1e, 0x4c, 0x69, - 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, - 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x05, - 0x73, 0x77, 0x61, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6c, 0x6f, - 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x53, 0x77, 0x61, 0x70, 0x52, 0x05, 0x73, - 0x77, 0x61, 0x70, 0x73, 0x22, 0x1d, 0x0a, 0x1b, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x22, 0x96, 0x04, 0x0a, 0x1c, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x61, + 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x0c, 0x6c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x53, 0x74, + 0x61, 0x74, 0x73, 0x12, 0x36, 0x0a, 0x0d, 0x6c, 0x6f, 0x6f, 0x70, 0x5f, 0x69, 0x6e, 0x5f, 0x73, + 0x74, 0x61, 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6c, 0x6f, 0x6f, + 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x6f, 0x70, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x0b, + 0x6c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x63, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x48, 0x61, 0x73, 0x68, 0x22, 0x1b, 0x0a, 0x19, + 0x47, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, + 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x8d, 0x0b, 0x0a, 0x13, 0x4c, 0x69, + 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, + 0x73, 0x12, 0x2c, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x16, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x71, 0x75, 0x69, + 0x64, 0x69, 0x74, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x12, + 0x17, 0x0a, 0x07, 0x66, 0x65, 0x65, 0x5f, 0x70, 0x70, 0x6d, 0x18, 0x10, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x06, 0x66, 0x65, 0x65, 0x50, 0x70, 0x6d, 0x12, 0x3d, 0x0a, 0x1c, 0x73, 0x77, 0x65, 0x65, + 0x70, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x61, 0x74, 0x5f, 0x70, + 0x65, 0x72, 0x5f, 0x76, 0x62, 0x79, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x17, + 0x73, 0x77, 0x65, 0x65, 0x70, 0x46, 0x65, 0x65, 0x52, 0x61, 0x74, 0x65, 0x53, 0x61, 0x74, 0x50, + 0x65, 0x72, 0x56, 0x62, 0x79, 0x74, 0x65, 0x12, 0x27, 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x5f, 0x73, + 0x77, 0x61, 0x70, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x70, 0x70, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x53, 0x77, 0x61, 0x70, 0x46, 0x65, 0x65, 0x50, 0x70, 0x6d, + 0x12, 0x2d, 0x0a, 0x13, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, + 0x66, 0x65, 0x65, 0x5f, 0x70, 0x70, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x6d, + 0x61, 0x78, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x46, 0x65, 0x65, 0x50, 0x70, 0x6d, 0x12, + 0x3a, 0x0a, 0x1a, 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x72, 0x65, 0x70, 0x61, 0x79, 0x5f, 0x72, 0x6f, + 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x70, 0x70, 0x6d, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x16, 0x6d, 0x61, 0x78, 0x50, 0x72, 0x65, 0x70, 0x61, 0x79, 0x52, 0x6f, + 0x75, 0x74, 0x69, 0x6e, 0x67, 0x46, 0x65, 0x65, 0x50, 0x70, 0x6d, 0x12, 0x24, 0x0a, 0x0e, 0x6d, + 0x61, 0x78, 0x5f, 0x70, 0x72, 0x65, 0x70, 0x61, 0x79, 0x5f, 0x73, 0x61, 0x74, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x50, 0x72, 0x65, 0x70, 0x61, 0x79, 0x53, 0x61, + 0x74, 0x12, 0x29, 0x0a, 0x11, 0x6d, 0x61, 0x78, 0x5f, 0x6d, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x66, + 0x65, 0x65, 0x5f, 0x73, 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x6d, 0x61, + 0x78, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x46, 0x65, 0x65, 0x53, 0x61, 0x74, 0x12, 0x2a, 0x0a, 0x11, + 0x73, 0x77, 0x65, 0x65, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x73, 0x77, 0x65, 0x65, 0x70, 0x43, 0x6f, + 0x6e, 0x66, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x2e, 0x0a, 0x13, 0x66, 0x61, 0x69, 0x6c, + 0x75, 0x72, 0x65, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x5f, 0x73, 0x65, 0x63, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x42, 0x61, + 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x53, 0x65, 0x63, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x75, 0x74, 0x6f, + 0x6c, 0x6f, 0x6f, 0x70, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x61, 0x75, 0x74, 0x6f, + 0x6c, 0x6f, 0x6f, 0x70, 0x12, 0x2e, 0x0a, 0x13, 0x61, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, + 0x5f, 0x62, 0x75, 0x64, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x61, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x11, 0x61, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x42, 0x75, 0x64, 0x67, 0x65, + 0x74, 0x53, 0x61, 0x74, 0x12, 0x3d, 0x0a, 0x19, 0x61, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, + 0x5f, 0x62, 0x75, 0x64, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x73, 0x65, + 0x63, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x04, 0x42, 0x02, 0x18, 0x01, 0x52, 0x16, 0x61, 0x75, 0x74, + 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x42, 0x75, 0x64, 0x67, 0x65, 0x74, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x53, 0x65, 0x63, 0x12, 0x2b, 0x0a, 0x12, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x6d, 0x61, 0x78, 0x5f, + 0x69, 0x6e, 0x5f, 0x66, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x0f, 0x61, 0x75, 0x74, 0x6f, 0x4d, 0x61, 0x78, 0x49, 0x6e, 0x46, 0x6c, 0x69, 0x67, 0x68, 0x74, + 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x69, 0x6e, 0x5f, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x61, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x6d, 0x69, 0x6e, 0x53, 0x77, + 0x61, 0x70, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, + 0x73, 0x77, 0x61, 0x70, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x53, 0x77, 0x61, 0x70, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x12, 0x28, 0x0a, 0x10, 0x68, 0x74, 0x6c, 0x63, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x5f, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x68, 0x74, 0x6c, 0x63, + 0x43, 0x6f, 0x6e, 0x66, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x32, 0x0a, 0x15, 0x61, 0x75, + 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x5f, 0x64, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x61, 0x75, 0x74, 0x6f, 0x6c, + 0x6f, 0x6f, 0x70, 0x44, 0x65, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x4a, + 0x0a, 0x22, 0x61, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x5f, 0x62, 0x75, 0x64, 0x67, 0x65, + 0x74, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, + 0x5f, 0x73, 0x65, 0x63, 0x18, 0x13, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1e, 0x61, 0x75, 0x74, 0x6f, + 0x6c, 0x6f, 0x6f, 0x70, 0x42, 0x75, 0x64, 0x67, 0x65, 0x74, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, + 0x68, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x53, 0x65, 0x63, 0x12, 0x3f, 0x0a, 0x1c, 0x61, 0x75, + 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x5f, 0x62, 0x75, 0x64, 0x67, 0x65, 0x74, 0x5f, 0x6c, 0x61, + 0x73, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x18, 0x14, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x19, 0x61, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x42, 0x75, 0x64, 0x67, 0x65, 0x74, + 0x4c, 0x61, 0x73, 0x74, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x12, 0x23, 0x0a, 0x0d, 0x65, + 0x61, 0x73, 0x79, 0x5f, 0x61, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x18, 0x15, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0c, 0x65, 0x61, 0x73, 0x79, 0x41, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, + 0x12, 0x42, 0x0a, 0x1e, 0x65, 0x61, 0x73, 0x79, 0x5f, 0x61, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, + 0x70, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x73, + 0x61, 0x74, 0x18, 0x16, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1a, 0x65, 0x61, 0x73, 0x79, 0x41, 0x75, + 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x54, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x53, 0x61, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x17, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x40, + 0x0a, 0x11, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, + 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, + 0x0f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x5d, 0x0a, 0x11, 0x65, 0x61, 0x73, 0x79, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x19, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x6c, 0x6f, + 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x45, 0x61, 0x73, 0x79, 0x41, 0x73, + 0x73, 0x65, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, + 0x65, 0x61, 0x73, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, + 0x32, 0x0a, 0x15, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x70, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, + 0x66, 0x61, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x1a, 0x64, 0x0a, 0x14, 0x45, 0x61, 0x73, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, + 0x50, 0x61, 0x72, 0x61, 0x6d, 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, 0x36, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6c, + 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x45, 0x61, 0x73, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, + 0x41, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x68, 0x0a, 0x17, 0x45, 0x61, 0x73, + 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x41, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x33, + 0x0a, 0x16, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x61, + 0x73, 0x73, 0x65, 0x74, 0x5f, 0x61, 0x6d, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x41, 0x73, 0x73, 0x65, 0x74, + 0x41, 0x6d, 0x74, 0x22, 0x84, 0x02, 0x0a, 0x0d, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, + 0x79, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x6e, + 0x65, 0x6c, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x09, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, + 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x73, 0x77, 0x61, 0x70, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x04, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x6c, 0x6f, 0x6f, + 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x52, 0x75, + 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x2d, 0x0a, 0x12, + 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, + 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x69, + 0x6e, 0x67, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x2d, 0x0a, 0x12, 0x6f, + 0x75, 0x74, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, + 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x6f, 0x75, 0x74, 0x67, 0x6f, 0x69, 0x6e, + 0x67, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x22, 0x59, 0x0a, 0x19, 0x53, 0x65, + 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6c, 0x6f, + 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x73, 0x22, 0x1c, 0x0a, 0x1a, 0x53, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, + 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x15, 0x0a, 0x13, 0x53, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x53, 0x77, + 0x61, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x72, 0x0a, 0x0c, 0x44, 0x69, + 0x73, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x68, + 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, + 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, + 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, + 0x79, 0x12, 0x2b, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x13, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x75, 0x74, 0x6f, + 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0xb6, + 0x01, 0x0a, 0x14, 0x53, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x6c, 0x6f, 0x6f, 0x70, 0x5f, + 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, + 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x52, 0x07, 0x6c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x12, 0x2f, 0x0a, 0x07, 0x6c, + 0x6f, 0x6f, 0x70, 0x5f, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6c, + 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x52, 0x06, 0x6c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x12, 0x39, 0x0a, 0x0c, + 0x64, 0x69, 0x73, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x69, 0x73, + 0x71, 0x75, 0x61, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x52, 0x0c, 0x64, 0x69, 0x73, 0x71, 0x75, + 0x61, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x22, 0x57, 0x0a, 0x12, 0x41, 0x62, 0x61, 0x6e, 0x64, + 0x6f, 0x6e, 0x53, 0x77, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x31, 0x0a, + 0x16, 0x69, 0x5f, 0x6b, 0x6e, 0x6f, 0x77, 0x5f, 0x77, 0x68, 0x61, 0x74, 0x5f, 0x69, 0x5f, 0x61, + 0x6d, 0x5f, 0x64, 0x6f, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x69, + 0x4b, 0x6e, 0x6f, 0x77, 0x57, 0x68, 0x61, 0x74, 0x49, 0x41, 0x6d, 0x44, 0x6f, 0x69, 0x6e, 0x67, + 0x22, 0x15, 0x0a, 0x13, 0x41, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x53, 0x77, 0x61, 0x70, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x19, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x22, 0x5a, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, + 0x0a, 0x0c, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x43, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x0c, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xa9, + 0x01, 0x0a, 0x11, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x72, 0x65, + 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x13, 0x0a, 0x05, 0x74, 0x78, 0x5f, + 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x78, 0x49, 0x64, 0x12, 0x12, + 0x0a, 0x04, 0x76, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x76, 0x6f, + 0x75, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x22, 0x85, 0x01, 0x0a, 0x11, 0x49, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x65, 0x72, + 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x6f, 0x75, 0x74, + 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x04, 0x52, 0x0f, 0x6f, 0x75, 0x74, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x43, 0x68, + 0x61, 0x6e, 0x53, 0x65, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x64, + 0x64, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, 0x73, 0x74, 0x41, 0x64, + 0x64, 0x72, 0x22, 0x74, 0x0a, 0x12, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x74, 0x5f, 0x6f, 0x75, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x0e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x48, 0x61, + 0x73, 0x68, 0x12, 0x1e, 0x0a, 0x0b, 0x73, 0x77, 0x65, 0x65, 0x70, 0x5f, 0x74, 0x78, 0x5f, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x77, 0x65, 0x65, 0x70, 0x54, 0x78, + 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x82, 0x01, 0x0a, 0x16, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6d, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x03, 0x61, 0x6d, 0x74, 0x12, 0x2d, 0x0a, 0x10, 0x6e, 0x75, 0x6d, 0x5f, 0x72, 0x65, 0x73, + 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x42, + 0x02, 0x18, 0x01, 0x52, 0x0f, 0x6e, 0x75, 0x6d, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0e, 0x72, + 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x22, 0x65, 0x0a, + 0x17, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x73, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x0d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x46, 0x65, 0x65, 0x53, 0x61, 0x74, + 0x12, 0x22, 0x0a, 0x0d, 0x73, 0x77, 0x65, 0x65, 0x70, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x73, 0x61, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x73, 0x77, 0x65, 0x65, 0x70, 0x46, 0x65, + 0x65, 0x53, 0x61, 0x74, 0x22, 0x18, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x44, + 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x05, 0x73, 0x77, 0x61, + 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, + 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x52, 0x05, 0x73, + 0x77, 0x61, 0x70, 0x73, 0x22, 0xa0, 0x01, 0x0a, 0x0a, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, + 0x4f, 0x75, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x68, 0x61, 0x73, 0x68, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x77, 0x61, 0x70, 0x48, 0x61, 0x73, 0x68, + 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x27, + 0x0a, 0x0f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, + 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x1e, 0x0a, 0x0b, 0x73, 0x77, 0x65, 0x65, 0x70, + 0x5f, 0x74, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x77, + 0x65, 0x65, 0x70, 0x54, 0x78, 0x49, 0x64, 0x22, 0x38, 0x0a, 0x17, 0x4e, 0x65, 0x77, 0x53, 0x74, + 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4b, 0x65, + 0x79, 0x22, 0x4c, 0x0a, 0x18, 0x4e, 0x65, 0x77, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, + 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x22, + 0x56, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x44, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, + 0x09, 0x6d, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x08, 0x6d, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, + 0x78, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x6d, + 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x66, 0x73, 0x22, 0x42, 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x55, + 0x6e, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x75, 0x74, 0x78, 0x6f, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, + 0x55, 0x74, 0x78, 0x6f, 0x52, 0x05, 0x75, 0x74, 0x78, 0x6f, 0x73, 0x22, 0x8e, 0x01, 0x0a, 0x04, + 0x55, 0x74, 0x78, 0x6f, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x74, - 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x72, - 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x5f, 0x62, - 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x14, 0x72, 0x65, 0x6c, - 0x61, 0x74, 0x69, 0x76, 0x65, 0x45, 0x78, 0x70, 0x69, 0x72, 0x79, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6e, 0x75, 0x6d, 0x5f, 0x64, - 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x74, - 0x6f, 0x74, 0x61, 0x6c, 0x4e, 0x75, 0x6d, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x12, - 0x3c, 0x0a, 0x1a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x75, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x72, 0x6d, 0x65, 0x64, 0x5f, 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x18, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x55, 0x6e, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x72, 0x6d, 0x65, 0x64, 0x53, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x12, 0x38, 0x0a, - 0x18, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x64, - 0x5f, 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x16, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x64, 0x53, - 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, - 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x14, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x78, - 0x70, 0x69, 0x72, 0x65, 0x64, 0x53, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x12, 0x38, 0x0a, - 0x18, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x6e, - 0x5f, 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x16, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x6e, 0x53, - 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x12, 0x37, 0x0a, 0x18, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x5f, 0x6c, 0x6f, 0x6f, 0x70, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x5f, 0x73, 0x61, 0x74, 0x6f, 0x73, - 0x68, 0x69, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x4c, 0x6f, 0x6f, 0x70, 0x65, 0x64, 0x49, 0x6e, 0x53, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, - 0x12, 0x4a, 0x0a, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x68, 0x74, 0x6c, 0x63, 0x5f, 0x74, - 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x77, 0x65, 0x65, 0x70, 0x73, 0x5f, 0x73, 0x61, - 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1e, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x48, 0x74, 0x6c, 0x63, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x53, 0x77, - 0x65, 0x65, 0x70, 0x73, 0x53, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x22, 0xd9, 0x01, 0x0a, - 0x07, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2b, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, - 0x63, 0x2e, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, - 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, - 0x74, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2f, 0x0a, 0x13, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x2e, 0x0a, 0x13, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x73, 0x5f, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x55, 0x6e, 0x74, - 0x69, 0x6c, 0x45, 0x78, 0x70, 0x69, 0x72, 0x79, 0x22, 0xc2, 0x02, 0x0a, 0x17, 0x53, 0x74, 0x61, - 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, - 0x61, 0x77, 0x61, 0x6c, 0x12, 0x13, 0x0a, 0x05, 0x74, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x78, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x08, 0x64, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6c, 0x6f, - 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x52, 0x08, 0x64, - 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x12, 0x41, 0x0a, 0x1d, 0x74, 0x6f, 0x74, 0x61, 0x6c, - 0x5f, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, - 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1a, - 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x41, 0x6d, 0x6f, 0x75, - 0x6e, 0x74, 0x53, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x12, 0x3a, 0x0a, 0x19, 0x77, 0x69, - 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x6e, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x73, - 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, 0x77, - 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x6e, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x61, - 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, + 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x73, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x09, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x61, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x75, + 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x75, + 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, + 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xb5, 0x01, 0x0a, + 0x17, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x09, 0x6f, 0x75, 0x74, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6c, 0x6f, + 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x09, + 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6c, 0x6c, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61, 0x6c, 0x6c, 0x12, 0x1b, 0x0a, 0x09, 0x64, + 0x65, 0x73, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x64, 0x65, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, 0x12, 0x22, 0x0a, 0x0d, 0x73, 0x61, 0x74, 0x5f, + 0x70, 0x65, 0x72, 0x5f, 0x76, 0x62, 0x79, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x0b, 0x73, 0x61, 0x74, 0x50, 0x65, 0x72, 0x56, 0x62, 0x79, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, + 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x61, 0x6d, + 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x62, 0x0a, 0x18, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, + 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x2c, 0x0a, 0x12, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x5f, 0x74, + 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x77, 0x69, + 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x54, 0x78, 0x48, 0x61, 0x73, 0x68, 0x12, 0x18, + 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x67, 0x0a, 0x08, 0x4f, 0x75, 0x74, 0x50, + 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x78, 0x69, 0x64, 0x5f, 0x62, 0x79, 0x74, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x74, 0x78, 0x69, 0x64, 0x42, 0x79, + 0x74, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x78, 0x69, 0x64, 0x5f, 0x73, 0x74, 0x72, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x78, 0x69, 0x64, 0x53, 0x74, 0x72, 0x12, 0x21, + 0x0a, 0x0c, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x49, 0x6e, 0x64, 0x65, + 0x78, 0x22, 0x7a, 0x0a, 0x20, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x66, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x6c, 0x6f, + 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x52, 0x0b, 0x73, 0x74, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, + 0x1c, 0x0a, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x22, 0x62, 0x0a, + 0x21, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x11, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x64, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, + 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x52, + 0x10, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x73, 0x22, 0x24, 0x0a, 0x22, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x69, 0x0a, 0x23, 0x4c, 0x69, 0x73, 0x74, 0x53, + 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x57, 0x69, 0x74, 0x68, + 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, + 0x0a, 0x0b, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, + 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x57, 0x69, 0x74, 0x68, 0x64, + 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x0b, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, + 0x6c, 0x73, 0x22, 0x1f, 0x0a, 0x1d, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x22, 0x58, 0x0a, 0x1e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x69, + 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x05, 0x73, 0x77, 0x61, 0x70, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, + 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x6f, 0x70, + 0x49, 0x6e, 0x53, 0x77, 0x61, 0x70, 0x52, 0x05, 0x73, 0x77, 0x61, 0x70, 0x73, 0x22, 0x1d, 0x0a, + 0x1b, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x75, + 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x96, 0x04, 0x0a, + 0x1c, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x75, + 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, + 0x0e, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, + 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x14, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x45, 0x78, + 0x70, 0x69, 0x72, 0x79, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x74, 0x6f, + 0x74, 0x61, 0x6c, 0x5f, 0x6e, 0x75, 0x6d, 0x5f, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4e, 0x75, 0x6d, + 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x12, 0x3c, 0x0a, 0x1a, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x5f, 0x75, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x5f, 0x73, 0x61, + 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x18, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x55, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x53, 0x61, + 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x12, 0x38, 0x0a, 0x18, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, + 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, + 0x69, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x16, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x44, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x64, 0x53, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, + 0x12, 0x34, 0x0a, 0x16, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, + 0x64, 0x5f, 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x14, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x64, 0x53, 0x61, + 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x12, 0x38, 0x0a, 0x18, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, + 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x6e, 0x5f, 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, + 0x69, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x16, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x57, + 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x6e, 0x53, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, + 0x12, 0x37, 0x0a, 0x18, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x6c, 0x6f, 0x6f, 0x70, 0x65, 0x64, + 0x5f, 0x69, 0x6e, 0x5f, 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x15, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4c, 0x6f, 0x6f, 0x70, 0x65, 0x64, 0x49, + 0x6e, 0x53, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x12, 0x4a, 0x0a, 0x22, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x5f, 0x68, 0x74, 0x6c, 0x63, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, + 0x73, 0x77, 0x65, 0x65, 0x70, 0x73, 0x5f, 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x48, 0x74, 0x6c, 0x63, + 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x53, 0x77, 0x65, 0x65, 0x70, 0x73, 0x53, 0x61, 0x74, + 0x6f, 0x73, 0x68, 0x69, 0x73, 0x22, 0xd9, 0x01, 0x0a, 0x07, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x2b, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1a, + 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x12, 0x2f, 0x0a, 0x13, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x12, 0x2e, 0x0a, 0x13, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, 0x75, 0x6e, 0x74, 0x69, + 0x6c, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x55, 0x6e, 0x74, 0x69, 0x6c, 0x45, 0x78, 0x70, 0x69, 0x72, + 0x79, 0x22, 0xc2, 0x02, 0x0a, 0x17, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x12, 0x13, 0x0a, + 0x05, 0x74, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x78, + 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x08, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x44, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x52, 0x08, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, + 0x12, 0x41, 0x0a, 0x1d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, + 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x44, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x61, 0x74, 0x6f, 0x73, + 0x68, 0x69, 0x73, 0x12, 0x3a, 0x0a, 0x19, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x6e, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x14, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x41, 0x6d, - 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x12, 0x2f, 0x0a, 0x13, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x65, 0x69, - 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x99, 0x02, - 0x0a, 0x17, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4c, - 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x53, 0x77, 0x61, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x77, 0x61, - 0x70, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x77, - 0x61, 0x70, 0x48, 0x61, 0x73, 0x68, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x10, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69, - 0x6e, 0x74, 0x73, 0x12, 0x3b, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, - 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, - 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x12, 0x30, 0x0a, 0x14, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, - 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, - 0x73, 0x77, 0x61, 0x70, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x61, 0x74, 0x6f, 0x73, 0x68, - 0x69, 0x73, 0x12, 0x45, 0x0a, 0x1f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x73, 0x61, 0x74, - 0x6f, 0x73, 0x68, 0x69, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1c, 0x70, 0x61, 0x79, - 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x41, 0x6d, 0x6f, 0x75, 0x6e, - 0x74, 0x53, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x22, 0xc3, 0x02, 0x0a, 0x1a, 0x53, 0x74, - 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, - 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6f, 0x75, 0x74, 0x70, - 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x6f, 0x75, 0x74, - 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x31, 0x0a, 0x15, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x77, - 0x61, 0x70, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x6d, 0x61, 0x78, 0x53, 0x77, 0x61, 0x70, 0x46, 0x65, - 0x65, 0x53, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x6c, 0x61, 0x73, - 0x74, 0x5f, 0x68, 0x6f, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6c, 0x61, 0x73, - 0x74, 0x48, 0x6f, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, - 0x69, 0x74, 0x69, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, - 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x33, 0x0a, 0x0b, 0x72, 0x6f, 0x75, 0x74, - 0x65, 0x5f, 0x68, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, - 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x48, 0x69, 0x6e, - 0x74, 0x52, 0x0a, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x48, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x18, 0x0a, - 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, - 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x70, 0x61, 0x79, 0x6d, 0x65, - 0x6e, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, - 0x64, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x15, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, - 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, - 0xb5, 0x03, 0x0a, 0x1b, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x1b, 0x0a, 0x09, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x08, 0x73, 0x77, 0x61, 0x70, 0x48, 0x61, 0x73, 0x68, 0x12, 0x14, 0x0a, 0x05, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x68, 0x74, - 0x6c, 0x63, 0x5f, 0x63, 0x6c, 0x74, 0x76, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x68, - 0x74, 0x6c, 0x63, 0x43, 0x6c, 0x74, 0x76, 0x12, 0x37, 0x0a, 0x18, 0x71, 0x75, 0x6f, 0x74, 0x65, - 0x64, 0x5f, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x73, 0x61, 0x74, 0x6f, 0x73, - 0x68, 0x69, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x71, 0x75, 0x6f, 0x74, 0x65, - 0x64, 0x53, 0x77, 0x61, 0x70, 0x46, 0x65, 0x65, 0x53, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, - 0x12, 0x31, 0x0a, 0x15, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x66, 0x65, 0x65, - 0x5f, 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x12, 0x6d, 0x61, 0x78, 0x53, 0x77, 0x61, 0x70, 0x46, 0x65, 0x65, 0x53, 0x61, 0x74, 0x6f, 0x73, - 0x68, 0x69, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, - 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x12, 0x29, 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x5f, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6c, - 0x61, 0x62, 0x65, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, - 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x0a, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x6f, 0x72, 0x12, - 0x36, 0x0a, 0x17, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, - 0x75, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x15, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, - 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0xa2, 0x01, 0x0a, 0x13, 0x41, 0x73, 0x73, 0x65, - 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x19, 0x0a, 0x08, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x07, 0x61, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x61, 0x73, - 0x73, 0x65, 0x74, 0x5f, 0x65, 0x64, 0x67, 0x65, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x61, 0x73, 0x73, 0x65, 0x74, 0x45, 0x64, 0x67, 0x65, 0x4e, 0x6f, - 0x64, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x6d, 0x61, 0x78, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, - 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x69, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, - 0x52, 0x12, 0x6d, 0x61, 0x78, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, - 0x6c, 0x69, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x22, 0xcd, 0x02, 0x0a, - 0x0c, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x66, 0x71, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x22, 0x0a, - 0x0d, 0x70, 0x72, 0x65, 0x70, 0x61, 0x79, 0x5f, 0x72, 0x66, 0x71, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x70, 0x72, 0x65, 0x70, 0x61, 0x79, 0x52, 0x66, 0x71, 0x49, - 0x64, 0x12, 0x2f, 0x0a, 0x14, 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x72, 0x65, 0x70, 0x61, 0x79, 0x5f, - 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x61, 0x6d, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x11, 0x6d, 0x61, 0x78, 0x50, 0x72, 0x65, 0x70, 0x61, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x41, - 0x6d, 0x74, 0x12, 0x3f, 0x0a, 0x11, 0x70, 0x72, 0x65, 0x70, 0x61, 0x79, 0x5f, 0x61, 0x73, 0x73, - 0x65, 0x74, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, - 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x69, 0x78, 0x65, 0x64, 0x50, 0x6f, 0x69, - 0x6e, 0x74, 0x52, 0x0f, 0x70, 0x72, 0x65, 0x70, 0x61, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, - 0x61, 0x74, 0x65, 0x12, 0x1e, 0x0a, 0x0b, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x72, 0x66, 0x71, 0x5f, - 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x77, 0x61, 0x70, 0x52, 0x66, - 0x71, 0x49, 0x64, 0x12, 0x2b, 0x0a, 0x12, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x77, 0x61, 0x70, 0x5f, - 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x61, 0x6d, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x0f, 0x6d, 0x61, 0x78, 0x53, 0x77, 0x61, 0x70, 0x41, 0x73, 0x73, 0x65, 0x74, 0x41, 0x6d, 0x74, - 0x12, 0x3b, 0x0a, 0x0f, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x72, - 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, - 0x72, 0x70, 0x63, 0x2e, 0x46, 0x69, 0x78, 0x65, 0x64, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x0d, - 0x73, 0x77, 0x61, 0x70, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x0a, - 0x0a, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x61, 0x73, 0x73, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x44, 0x0a, 0x0a, - 0x46, 0x69, 0x78, 0x65, 0x64, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, - 0x65, 0x66, 0x66, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, - 0x73, 0x63, 0x61, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x73, 0x63, 0x61, - 0x6c, 0x65, 0x22, 0x7c, 0x0a, 0x10, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, - 0x75, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x73, 0x73, 0x65, 0x74, 0x49, - 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x73, 0x73, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x2e, 0x0a, 0x13, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x73, 0x74, 0x5f, 0x6f, - 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x61, - 0x73, 0x73, 0x65, 0x74, 0x43, 0x6f, 0x73, 0x74, 0x4f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x2a, 0x3b, 0x0a, 0x0b, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x18, 0x0a, 0x14, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, - 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x54, 0x41, 0x50, - 0x52, 0x4f, 0x4f, 0x54, 0x5f, 0x50, 0x55, 0x42, 0x4b, 0x45, 0x59, 0x10, 0x01, 0x2a, 0x25, 0x0a, - 0x08, 0x53, 0x77, 0x61, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x4c, 0x4f, 0x4f, - 0x50, 0x5f, 0x4f, 0x55, 0x54, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x4c, 0x4f, 0x4f, 0x50, 0x5f, - 0x49, 0x4e, 0x10, 0x01, 0x2a, 0x73, 0x0a, 0x09, 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x12, 0x0d, 0x0a, 0x09, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x54, 0x45, 0x44, 0x10, 0x00, - 0x12, 0x15, 0x0a, 0x11, 0x50, 0x52, 0x45, 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x52, 0x45, 0x56, - 0x45, 0x41, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x48, 0x54, 0x4c, 0x43, 0x5f, - 0x50, 0x55, 0x42, 0x4c, 0x49, 0x53, 0x48, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x53, - 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, - 0x45, 0x44, 0x10, 0x04, 0x12, 0x13, 0x0a, 0x0f, 0x49, 0x4e, 0x56, 0x4f, 0x49, 0x43, 0x45, 0x5f, - 0x53, 0x45, 0x54, 0x54, 0x4c, 0x45, 0x44, 0x10, 0x05, 0x2a, 0xeb, 0x02, 0x0a, 0x0d, 0x46, 0x61, - 0x69, 0x6c, 0x75, 0x72, 0x65, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x13, 0x46, - 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, - 0x4e, 0x45, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, - 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4f, 0x46, 0x46, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x10, - 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, - 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x02, 0x12, 0x20, 0x0a, - 0x1c, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, - 0x53, 0x57, 0x45, 0x45, 0x50, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x03, 0x12, - 0x25, 0x0a, 0x21, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, - 0x4e, 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x56, - 0x41, 0x4c, 0x55, 0x45, 0x10, 0x04, 0x12, 0x1c, 0x0a, 0x18, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, - 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x4f, 0x52, 0x41, - 0x52, 0x59, 0x10, 0x05, 0x12, 0x23, 0x0a, 0x1f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, - 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x43, 0x4f, 0x52, 0x52, 0x45, 0x43, 0x54, - 0x5f, 0x41, 0x4d, 0x4f, 0x55, 0x4e, 0x54, 0x10, 0x06, 0x12, 0x1c, 0x0a, 0x18, 0x46, 0x41, 0x49, - 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x41, 0x42, 0x41, 0x4e, - 0x44, 0x4f, 0x4e, 0x45, 0x44, 0x10, 0x07, 0x12, 0x31, 0x0a, 0x2d, 0x46, 0x41, 0x49, 0x4c, 0x55, - 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46, - 0x49, 0x43, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d, 0x45, 0x44, - 0x5f, 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x10, 0x08, 0x12, 0x2b, 0x0a, 0x27, 0x46, 0x41, - 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x43, - 0x4f, 0x52, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x48, 0x54, 0x4c, 0x43, 0x5f, 0x41, 0x4d, 0x54, 0x5f, - 0x53, 0x57, 0x45, 0x50, 0x54, 0x10, 0x09, 0x2a, 0x2f, 0x0a, 0x11, 0x4c, 0x69, 0x71, 0x75, 0x69, - 0x64, 0x69, 0x74, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, - 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x48, 0x52, - 0x45, 0x53, 0x48, 0x4f, 0x4c, 0x44, 0x10, 0x01, 0x2a, 0xa6, 0x03, 0x0a, 0x0a, 0x41, 0x75, 0x74, - 0x6f, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x13, 0x41, 0x55, 0x54, 0x4f, 0x5f, - 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, - 0x12, 0x22, 0x0a, 0x1e, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, - 0x42, 0x55, 0x44, 0x47, 0x45, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, - 0x45, 0x44, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, - 0x53, 0x4f, 0x4e, 0x5f, 0x53, 0x57, 0x45, 0x45, 0x50, 0x5f, 0x46, 0x45, 0x45, 0x53, 0x10, 0x02, - 0x12, 0x1e, 0x0a, 0x1a, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, - 0x42, 0x55, 0x44, 0x47, 0x45, 0x54, 0x5f, 0x45, 0x4c, 0x41, 0x50, 0x53, 0x45, 0x44, 0x10, 0x03, - 0x12, 0x19, 0x0a, 0x15, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, - 0x49, 0x4e, 0x5f, 0x46, 0x4c, 0x49, 0x47, 0x48, 0x54, 0x10, 0x04, 0x12, 0x18, 0x0a, 0x14, 0x41, - 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x53, 0x57, 0x41, 0x50, 0x5f, - 0x46, 0x45, 0x45, 0x10, 0x05, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, - 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4d, 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x46, 0x45, 0x45, 0x10, 0x06, - 0x12, 0x16, 0x0a, 0x12, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, - 0x50, 0x52, 0x45, 0x50, 0x41, 0x59, 0x10, 0x07, 0x12, 0x1f, 0x0a, 0x1b, 0x41, 0x55, 0x54, 0x4f, - 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, - 0x42, 0x41, 0x43, 0x4b, 0x4f, 0x46, 0x46, 0x10, 0x08, 0x12, 0x18, 0x0a, 0x14, 0x41, 0x55, 0x54, - 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4c, 0x4f, 0x4f, 0x50, 0x5f, 0x4f, 0x55, - 0x54, 0x10, 0x09, 0x12, 0x17, 0x0a, 0x13, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, - 0x4f, 0x4e, 0x5f, 0x4c, 0x4f, 0x4f, 0x50, 0x5f, 0x49, 0x4e, 0x10, 0x0a, 0x12, 0x1c, 0x0a, 0x18, - 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4c, 0x49, 0x51, 0x55, - 0x49, 0x44, 0x49, 0x54, 0x59, 0x5f, 0x4f, 0x4b, 0x10, 0x0b, 0x12, 0x23, 0x0a, 0x1f, 0x41, 0x55, - 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x42, 0x55, 0x44, 0x47, 0x45, 0x54, - 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x54, 0x10, 0x0c, 0x12, - 0x20, 0x0a, 0x1c, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x46, - 0x45, 0x45, 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x54, 0x10, - 0x0d, 0x2a, 0xdc, 0x01, 0x0a, 0x0c, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x12, 0x11, 0x0a, 0x0d, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x53, 0x54, - 0x41, 0x54, 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x44, 0x45, 0x50, 0x4f, 0x53, 0x49, 0x54, - 0x45, 0x44, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x57, 0x49, 0x54, 0x48, 0x44, 0x52, 0x41, 0x57, - 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x57, 0x49, 0x54, 0x48, 0x44, 0x52, 0x41, - 0x57, 0x4e, 0x10, 0x03, 0x12, 0x0e, 0x0a, 0x0a, 0x4c, 0x4f, 0x4f, 0x50, 0x49, 0x4e, 0x47, 0x5f, - 0x49, 0x4e, 0x10, 0x04, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x4f, 0x4f, 0x50, 0x45, 0x44, 0x5f, 0x49, - 0x4e, 0x10, 0x05, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x57, 0x45, 0x45, 0x50, 0x5f, 0x48, 0x54, 0x4c, - 0x43, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x06, 0x12, 0x16, 0x0a, 0x12, 0x48, - 0x54, 0x4c, 0x43, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x5f, 0x53, 0x57, 0x45, 0x50, - 0x54, 0x10, 0x07, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x53, 0x48, 0x5f, 0x45, - 0x58, 0x50, 0x49, 0x52, 0x45, 0x44, 0x10, 0x08, 0x12, 0x19, 0x0a, 0x15, 0x57, 0x41, 0x49, 0x54, - 0x5f, 0x46, 0x4f, 0x52, 0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, 0x59, 0x5f, 0x53, 0x57, 0x45, 0x45, - 0x50, 0x10, 0x09, 0x12, 0x0b, 0x0a, 0x07, 0x45, 0x58, 0x50, 0x49, 0x52, 0x45, 0x44, 0x10, 0x0a, - 0x2a, 0xef, 0x02, 0x0a, 0x1c, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x12, 0x25, 0x0a, 0x21, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x53, 0x54, 0x41, - 0x54, 0x49, 0x43, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x53, 0x57, 0x41, 0x50, - 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x49, 0x4e, 0x49, 0x54, - 0x5f, 0x48, 0x54, 0x4c, 0x43, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x49, 0x47, 0x4e, 0x5f, - 0x48, 0x54, 0x4c, 0x43, 0x5f, 0x54, 0x58, 0x10, 0x02, 0x12, 0x1b, 0x0a, 0x17, 0x4d, 0x4f, 0x4e, - 0x49, 0x54, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x4f, 0x49, 0x43, 0x45, 0x5f, 0x48, 0x54, 0x4c, - 0x43, 0x5f, 0x54, 0x58, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, - 0x54, 0x5f, 0x52, 0x45, 0x43, 0x45, 0x49, 0x56, 0x45, 0x44, 0x10, 0x04, 0x12, 0x25, 0x0a, 0x21, - 0x53, 0x57, 0x45, 0x45, 0x50, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, 0x5f, 0x41, 0x44, 0x44, - 0x52, 0x45, 0x53, 0x53, 0x5f, 0x48, 0x54, 0x4c, 0x43, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, - 0x54, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x4d, 0x4f, 0x4e, 0x49, 0x54, 0x4f, 0x52, 0x5f, 0x48, - 0x54, 0x4c, 0x43, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x5f, 0x53, 0x57, 0x45, 0x45, - 0x50, 0x10, 0x06, 0x12, 0x25, 0x0a, 0x21, 0x48, 0x54, 0x4c, 0x43, 0x5f, 0x53, 0x54, 0x41, 0x54, - 0x49, 0x43, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, - 0x55, 0x54, 0x5f, 0x53, 0x57, 0x45, 0x50, 0x54, 0x10, 0x07, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x55, - 0x43, 0x43, 0x45, 0x45, 0x44, 0x45, 0x44, 0x10, 0x08, 0x12, 0x22, 0x0a, 0x1e, 0x53, 0x55, 0x43, - 0x43, 0x45, 0x45, 0x44, 0x45, 0x44, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x49, 0x4f, - 0x4e, 0x49, 0x4e, 0x47, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x09, 0x12, 0x13, 0x0a, - 0x0f, 0x55, 0x4e, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x53, - 0x10, 0x0a, 0x12, 0x1e, 0x0a, 0x1a, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x53, 0x54, 0x41, - 0x54, 0x49, 0x43, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x53, 0x57, 0x41, 0x50, - 0x10, 0x0b, 0x32, 0xe3, 0x12, 0x0a, 0x0a, 0x53, 0x77, 0x61, 0x70, 0x43, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x12, 0x39, 0x0a, 0x07, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x12, 0x17, 0x2e, 0x6c, - 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, - 0x53, 0x77, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x06, - 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x12, 0x16, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, - 0x2e, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, - 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x07, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, - 0x12, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, - 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, - 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x30, 0x01, - 0x12, 0x42, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x12, 0x19, 0x2e, - 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, - 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x08, 0x53, 0x77, 0x61, 0x70, 0x49, 0x6e, 0x66, 0x6f, - 0x12, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x49, - 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6f, 0x6f, - 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, - 0x48, 0x0a, 0x0b, 0x41, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x53, 0x77, 0x61, 0x70, 0x12, 0x1b, - 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, - 0x53, 0x77, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x6f, - 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x53, 0x77, 0x61, - 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0c, 0x4c, 0x6f, 0x6f, - 0x70, 0x4f, 0x75, 0x74, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x12, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, - 0x72, 0x70, 0x63, 0x2e, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x19, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, 0x74, 0x54, 0x65, - 0x72, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0c, 0x4c, - 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x15, 0x2e, 0x6c, 0x6f, - 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, 0x74, - 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, - 0x0e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x12, - 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, - 0x2e, 0x49, 0x6e, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x41, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x51, 0x75, 0x6f, - 0x74, 0x65, 0x12, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x6f, - 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, - 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x05, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x15, 0x2e, 0x6c, - 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x72, - 0x6f, 0x62, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0d, 0x47, - 0x65, 0x74, 0x4c, 0x34, 0x30, 0x32, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x16, 0x2e, 0x6c, - 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x54, - 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, - 0x0d, 0x47, 0x65, 0x74, 0x4c, 0x73, 0x61, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x16, - 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, - 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x51, 0x0a, 0x0e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x4c, 0x34, 0x30, 0x32, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x12, 0x1e, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x65, 0x74, 0x63, - 0x68, 0x4c, 0x34, 0x30, 0x32, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1f, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x65, 0x74, 0x63, - 0x68, 0x4c, 0x34, 0x30, 0x32, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x17, 0x2e, - 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, - 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x56, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, - 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x22, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, - 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, - 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x6f, 0x6f, - 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, - 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x5d, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x4c, - 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x22, - 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, - 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x74, - 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0c, 0x53, 0x75, 0x67, 0x67, 0x65, - 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x12, 0x1c, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, - 0x63, 0x2e, 0x53, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, - 0x53, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x65, - 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, - 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6c, 0x6f, 0x6f, - 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, - 0x0a, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x12, 0x1a, 0x2e, 0x6c, 0x6f, - 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, - 0x63, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, - 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x1f, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, - 0x63, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, + 0x6e, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x12, + 0x34, 0x0a, 0x16, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x5f, 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x14, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x61, 0x74, + 0x6f, 0x73, 0x68, 0x69, 0x73, 0x12, 0x2f, 0x0a, 0x13, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x99, 0x02, 0x0a, 0x17, 0x53, 0x74, 0x61, 0x74, 0x69, + 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x53, 0x77, + 0x61, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x77, 0x61, 0x70, 0x48, 0x61, 0x73, 0x68, 0x12, + 0x2b, 0x0a, 0x11, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x64, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x3b, 0x0a, 0x05, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x6c, 0x6f, + 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x77, 0x61, + 0x70, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, + 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x73, 0x77, 0x61, 0x70, 0x41, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x53, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x12, 0x45, 0x0a, 0x1f, 0x70, + 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x61, + 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x1c, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x61, 0x74, 0x6f, 0x73, 0x68, + 0x69, 0x73, 0x22, 0xdb, 0x02, 0x0a, 0x1a, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, + 0x31, 0x0a, 0x15, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x66, 0x65, 0x65, 0x5f, + 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, + 0x6d, 0x61, 0x78, 0x53, 0x77, 0x61, 0x70, 0x46, 0x65, 0x65, 0x53, 0x61, 0x74, 0x6f, 0x73, 0x68, + 0x69, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x68, 0x6f, 0x70, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6c, 0x61, 0x73, 0x74, 0x48, 0x6f, 0x70, 0x12, 0x14, 0x0a, + 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x6f, 0x72, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x6f, + 0x72, 0x12, 0x33, 0x0a, 0x0b, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x68, 0x69, 0x6e, 0x74, 0x73, + 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, + 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x48, 0x69, 0x6e, 0x74, 0x52, 0x0a, 0x72, 0x6f, 0x75, 0x74, + 0x65, 0x48, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, + 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, + 0x12, 0x36, 0x0a, 0x17, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x15, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, + 0x74, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, + 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x22, 0xb5, 0x03, 0x0a, 0x1b, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x77, 0x61, 0x70, 0x48, 0x61, 0x73, 0x68, 0x12, 0x14, 0x0a, + 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x68, + 0x74, 0x6c, 0x63, 0x5f, 0x63, 0x6c, 0x74, 0x76, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, + 0x68, 0x74, 0x6c, 0x63, 0x43, 0x6c, 0x74, 0x76, 0x12, 0x37, 0x0a, 0x18, 0x71, 0x75, 0x6f, 0x74, + 0x65, 0x64, 0x5f, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x73, 0x61, 0x74, 0x6f, + 0x73, 0x68, 0x69, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x71, 0x75, 0x6f, 0x74, + 0x65, 0x64, 0x53, 0x77, 0x61, 0x70, 0x46, 0x65, 0x65, 0x53, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, + 0x73, 0x12, 0x31, 0x0a, 0x15, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x66, 0x65, + 0x65, 0x5f, 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x12, 0x6d, 0x61, 0x78, 0x53, 0x77, 0x61, 0x70, 0x46, 0x65, 0x65, 0x53, 0x61, 0x74, 0x6f, + 0x73, 0x68, 0x69, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x10, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x12, 0x29, 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x5f, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x6f, 0x72, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x6f, 0x72, + 0x12, 0x36, 0x0a, 0x17, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x15, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, + 0x74, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0xa2, 0x01, 0x0a, 0x13, 0x41, 0x73, 0x73, + 0x65, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x19, 0x0a, 0x08, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x07, 0x61, 0x73, 0x73, 0x65, 0x74, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x61, + 0x73, 0x73, 0x65, 0x74, 0x5f, 0x65, 0x64, 0x67, 0x65, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x61, 0x73, 0x73, 0x65, 0x74, 0x45, 0x64, 0x67, 0x65, 0x4e, + 0x6f, 0x64, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x6d, 0x61, 0x78, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, + 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x69, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x01, 0x52, 0x12, 0x6d, 0x61, 0x78, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x4d, 0x75, 0x6c, 0x74, 0x69, + 0x70, 0x6c, 0x69, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x22, 0xcd, 0x02, + 0x0a, 0x0c, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x66, 0x71, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x22, + 0x0a, 0x0d, 0x70, 0x72, 0x65, 0x70, 0x61, 0x79, 0x5f, 0x72, 0x66, 0x71, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x70, 0x72, 0x65, 0x70, 0x61, 0x79, 0x52, 0x66, 0x71, + 0x49, 0x64, 0x12, 0x2f, 0x0a, 0x14, 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x72, 0x65, 0x70, 0x61, 0x79, + 0x5f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x61, 0x6d, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x11, 0x6d, 0x61, 0x78, 0x50, 0x72, 0x65, 0x70, 0x61, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, + 0x41, 0x6d, 0x74, 0x12, 0x3f, 0x0a, 0x11, 0x70, 0x72, 0x65, 0x70, 0x61, 0x79, 0x5f, 0x61, 0x73, + 0x73, 0x65, 0x74, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, + 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x69, 0x78, 0x65, 0x64, 0x50, 0x6f, + 0x69, 0x6e, 0x74, 0x52, 0x0f, 0x70, 0x72, 0x65, 0x70, 0x61, 0x79, 0x41, 0x73, 0x73, 0x65, 0x74, + 0x52, 0x61, 0x74, 0x65, 0x12, 0x1e, 0x0a, 0x0b, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x72, 0x66, 0x71, + 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x77, 0x61, 0x70, 0x52, + 0x66, 0x71, 0x49, 0x64, 0x12, 0x2b, 0x0a, 0x12, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x77, 0x61, 0x70, + 0x5f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x61, 0x6d, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x0f, 0x6d, 0x61, 0x78, 0x53, 0x77, 0x61, 0x70, 0x41, 0x73, 0x73, 0x65, 0x74, 0x41, 0x6d, + 0x74, 0x12, 0x3b, 0x0a, 0x0f, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, + 0x72, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6c, 0x6f, 0x6f, + 0x70, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x69, 0x78, 0x65, 0x64, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, + 0x0d, 0x73, 0x77, 0x61, 0x70, 0x41, 0x73, 0x73, 0x65, 0x74, 0x52, 0x61, 0x74, 0x65, 0x12, 0x1d, + 0x0a, 0x0a, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x61, 0x73, 0x73, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x44, 0x0a, + 0x0a, 0x46, 0x69, 0x78, 0x65, 0x64, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x63, + 0x6f, 0x65, 0x66, 0x66, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x0a, + 0x05, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x73, 0x63, + 0x61, 0x6c, 0x65, 0x22, 0x7c, 0x0a, 0x10, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4c, 0x6f, 0x6f, 0x70, + 0x4f, 0x75, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x73, 0x73, 0x65, 0x74, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x73, 0x73, 0x65, 0x74, + 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x73, 0x73, 0x65, 0x74, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x73, 0x74, 0x5f, + 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, + 0x61, 0x73, 0x73, 0x65, 0x74, 0x43, 0x6f, 0x73, 0x74, 0x4f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x2a, 0x3b, 0x0a, 0x0b, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x18, 0x0a, 0x14, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x54, 0x41, + 0x50, 0x52, 0x4f, 0x4f, 0x54, 0x5f, 0x50, 0x55, 0x42, 0x4b, 0x45, 0x59, 0x10, 0x01, 0x2a, 0x25, + 0x0a, 0x08, 0x53, 0x77, 0x61, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x4c, 0x4f, + 0x4f, 0x50, 0x5f, 0x4f, 0x55, 0x54, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x4c, 0x4f, 0x4f, 0x50, + 0x5f, 0x49, 0x4e, 0x10, 0x01, 0x2a, 0x73, 0x0a, 0x09, 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x12, 0x0d, 0x0a, 0x09, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x54, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x15, 0x0a, 0x11, 0x50, 0x52, 0x45, 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x52, 0x45, + 0x56, 0x45, 0x41, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x48, 0x54, 0x4c, 0x43, + 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x53, 0x48, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, + 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49, + 0x4c, 0x45, 0x44, 0x10, 0x04, 0x12, 0x13, 0x0a, 0x0f, 0x49, 0x4e, 0x56, 0x4f, 0x49, 0x43, 0x45, + 0x5f, 0x53, 0x45, 0x54, 0x54, 0x4c, 0x45, 0x44, 0x10, 0x05, 0x2a, 0xeb, 0x02, 0x0a, 0x0d, 0x46, + 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x13, + 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4e, + 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, + 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4f, 0x46, 0x46, 0x43, 0x48, 0x41, 0x49, 0x4e, + 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, + 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x02, 0x12, 0x20, + 0x0a, 0x1c, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, + 0x5f, 0x53, 0x57, 0x45, 0x45, 0x50, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x03, + 0x12, 0x25, 0x0a, 0x21, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, + 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x54, 0x5f, + 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x04, 0x12, 0x1c, 0x0a, 0x18, 0x46, 0x41, 0x49, 0x4c, 0x55, + 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x4f, 0x52, + 0x41, 0x52, 0x59, 0x10, 0x05, 0x12, 0x23, 0x0a, 0x1f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, + 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x43, 0x4f, 0x52, 0x52, 0x45, 0x43, + 0x54, 0x5f, 0x41, 0x4d, 0x4f, 0x55, 0x4e, 0x54, 0x10, 0x06, 0x12, 0x1c, 0x0a, 0x18, 0x46, 0x41, + 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x41, 0x42, 0x41, + 0x4e, 0x44, 0x4f, 0x4e, 0x45, 0x44, 0x10, 0x07, 0x12, 0x31, 0x0a, 0x2d, 0x46, 0x41, 0x49, 0x4c, + 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x46, + 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d, 0x45, + 0x44, 0x5f, 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x10, 0x08, 0x12, 0x2b, 0x0a, 0x27, 0x46, + 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, + 0x43, 0x4f, 0x52, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x48, 0x54, 0x4c, 0x43, 0x5f, 0x41, 0x4d, 0x54, + 0x5f, 0x53, 0x57, 0x45, 0x50, 0x54, 0x10, 0x09, 0x2a, 0x2f, 0x0a, 0x11, 0x4c, 0x69, 0x71, 0x75, + 0x69, 0x64, 0x69, 0x74, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, + 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x48, + 0x52, 0x45, 0x53, 0x48, 0x4f, 0x4c, 0x44, 0x10, 0x01, 0x2a, 0xa6, 0x03, 0x0a, 0x0a, 0x41, 0x75, + 0x74, 0x6f, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x13, 0x41, 0x55, 0x54, 0x4f, + 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, + 0x00, 0x12, 0x22, 0x0a, 0x1e, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, + 0x5f, 0x42, 0x55, 0x44, 0x47, 0x45, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x52, + 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, + 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x53, 0x57, 0x45, 0x45, 0x50, 0x5f, 0x46, 0x45, 0x45, 0x53, 0x10, + 0x02, 0x12, 0x1e, 0x0a, 0x1a, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, + 0x5f, 0x42, 0x55, 0x44, 0x47, 0x45, 0x54, 0x5f, 0x45, 0x4c, 0x41, 0x50, 0x53, 0x45, 0x44, 0x10, + 0x03, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, + 0x5f, 0x49, 0x4e, 0x5f, 0x46, 0x4c, 0x49, 0x47, 0x48, 0x54, 0x10, 0x04, 0x12, 0x18, 0x0a, 0x14, + 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x53, 0x57, 0x41, 0x50, + 0x5f, 0x46, 0x45, 0x45, 0x10, 0x05, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, + 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4d, 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x46, 0x45, 0x45, 0x10, + 0x06, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, + 0x5f, 0x50, 0x52, 0x45, 0x50, 0x41, 0x59, 0x10, 0x07, 0x12, 0x1f, 0x0a, 0x1b, 0x41, 0x55, 0x54, + 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, + 0x5f, 0x42, 0x41, 0x43, 0x4b, 0x4f, 0x46, 0x46, 0x10, 0x08, 0x12, 0x18, 0x0a, 0x14, 0x41, 0x55, + 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4c, 0x4f, 0x4f, 0x50, 0x5f, 0x4f, + 0x55, 0x54, 0x10, 0x09, 0x12, 0x17, 0x0a, 0x13, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, + 0x53, 0x4f, 0x4e, 0x5f, 0x4c, 0x4f, 0x4f, 0x50, 0x5f, 0x49, 0x4e, 0x10, 0x0a, 0x12, 0x1c, 0x0a, + 0x18, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4c, 0x49, 0x51, + 0x55, 0x49, 0x44, 0x49, 0x54, 0x59, 0x5f, 0x4f, 0x4b, 0x10, 0x0b, 0x12, 0x23, 0x0a, 0x1f, 0x41, + 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x42, 0x55, 0x44, 0x47, 0x45, + 0x54, 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x54, 0x10, 0x0c, + 0x12, 0x20, 0x0a, 0x1c, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, + 0x46, 0x45, 0x45, 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x54, + 0x10, 0x0d, 0x2a, 0xdc, 0x01, 0x0a, 0x0c, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x12, 0x11, 0x0a, 0x0d, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x53, + 0x54, 0x41, 0x54, 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x44, 0x45, 0x50, 0x4f, 0x53, 0x49, + 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x57, 0x49, 0x54, 0x48, 0x44, 0x52, 0x41, + 0x57, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x57, 0x49, 0x54, 0x48, 0x44, 0x52, + 0x41, 0x57, 0x4e, 0x10, 0x03, 0x12, 0x0e, 0x0a, 0x0a, 0x4c, 0x4f, 0x4f, 0x50, 0x49, 0x4e, 0x47, + 0x5f, 0x49, 0x4e, 0x10, 0x04, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x4f, 0x4f, 0x50, 0x45, 0x44, 0x5f, + 0x49, 0x4e, 0x10, 0x05, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x57, 0x45, 0x45, 0x50, 0x5f, 0x48, 0x54, + 0x4c, 0x43, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x06, 0x12, 0x16, 0x0a, 0x12, + 0x48, 0x54, 0x4c, 0x43, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x5f, 0x53, 0x57, 0x45, + 0x50, 0x54, 0x10, 0x07, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x53, 0x48, 0x5f, + 0x45, 0x58, 0x50, 0x49, 0x52, 0x45, 0x44, 0x10, 0x08, 0x12, 0x19, 0x0a, 0x15, 0x57, 0x41, 0x49, + 0x54, 0x5f, 0x46, 0x4f, 0x52, 0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, 0x59, 0x5f, 0x53, 0x57, 0x45, + 0x45, 0x50, 0x10, 0x09, 0x12, 0x0b, 0x0a, 0x07, 0x45, 0x58, 0x50, 0x49, 0x52, 0x45, 0x44, 0x10, + 0x0a, 0x2a, 0xef, 0x02, 0x0a, 0x1c, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x12, 0x25, 0x0a, 0x21, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x49, 0x43, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x53, 0x57, 0x41, + 0x50, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x49, 0x4e, 0x49, + 0x54, 0x5f, 0x48, 0x54, 0x4c, 0x43, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x49, 0x47, 0x4e, + 0x5f, 0x48, 0x54, 0x4c, 0x43, 0x5f, 0x54, 0x58, 0x10, 0x02, 0x12, 0x1b, 0x0a, 0x17, 0x4d, 0x4f, + 0x4e, 0x49, 0x54, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x4f, 0x49, 0x43, 0x45, 0x5f, 0x48, 0x54, + 0x4c, 0x43, 0x5f, 0x54, 0x58, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x50, 0x41, 0x59, 0x4d, 0x45, + 0x4e, 0x54, 0x5f, 0x52, 0x45, 0x43, 0x45, 0x49, 0x56, 0x45, 0x44, 0x10, 0x04, 0x12, 0x25, 0x0a, + 0x21, 0x53, 0x57, 0x45, 0x45, 0x50, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, 0x5f, 0x41, 0x44, + 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x48, 0x54, 0x4c, 0x43, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, + 0x55, 0x54, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x4d, 0x4f, 0x4e, 0x49, 0x54, 0x4f, 0x52, 0x5f, + 0x48, 0x54, 0x4c, 0x43, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x5f, 0x53, 0x57, 0x45, + 0x45, 0x50, 0x10, 0x06, 0x12, 0x25, 0x0a, 0x21, 0x48, 0x54, 0x4c, 0x43, 0x5f, 0x53, 0x54, 0x41, + 0x54, 0x49, 0x43, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x49, 0x4d, 0x45, + 0x4f, 0x55, 0x54, 0x5f, 0x53, 0x57, 0x45, 0x50, 0x54, 0x10, 0x07, 0x12, 0x0d, 0x0a, 0x09, 0x53, + 0x55, 0x43, 0x43, 0x45, 0x45, 0x44, 0x45, 0x44, 0x10, 0x08, 0x12, 0x22, 0x0a, 0x1e, 0x53, 0x55, + 0x43, 0x43, 0x45, 0x45, 0x44, 0x45, 0x44, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x49, + 0x4f, 0x4e, 0x49, 0x4e, 0x47, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x09, 0x12, 0x13, + 0x0a, 0x0f, 0x55, 0x4e, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x50, 0x4f, 0x53, 0x49, 0x54, + 0x53, 0x10, 0x0a, 0x12, 0x1e, 0x0a, 0x1a, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x49, 0x43, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x53, 0x57, 0x41, + 0x50, 0x10, 0x0b, 0x32, 0xe3, 0x12, 0x0a, 0x0a, 0x53, 0x77, 0x61, 0x70, 0x43, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x12, 0x39, 0x0a, 0x07, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x12, 0x17, 0x2e, + 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, + 0x2e, 0x53, 0x77, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, + 0x06, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x12, 0x16, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, + 0x63, 0x2e, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x07, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, + 0x72, 0x12, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6f, 0x6f, + 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x30, + 0x01, 0x12, 0x42, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x12, 0x19, + 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x77, 0x61, + 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, + 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x08, 0x53, 0x77, 0x61, 0x70, 0x49, 0x6e, 0x66, + 0x6f, 0x12, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6f, + 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x48, 0x0a, 0x0b, 0x41, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x53, 0x77, 0x61, 0x70, 0x12, + 0x1b, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x62, 0x61, 0x6e, 0x64, 0x6f, + 0x6e, 0x53, 0x77, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, + 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x53, 0x77, + 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0c, 0x4c, 0x6f, + 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x12, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, + 0x70, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x19, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, 0x74, 0x54, + 0x65, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0c, + 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x15, 0x2e, 0x6c, + 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, + 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, + 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x54, 0x65, 0x72, 0x6d, 0x73, + 0x12, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x65, 0x72, 0x6d, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, + 0x63, 0x2e, 0x49, 0x6e, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x41, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x51, 0x75, + 0x6f, 0x74, 0x65, 0x12, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, + 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, + 0x70, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x05, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x15, 0x2e, + 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x50, + 0x72, 0x6f, 0x62, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0d, + 0x47, 0x65, 0x74, 0x4c, 0x34, 0x30, 0x32, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x16, 0x2e, + 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, + 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4c, 0x73, 0x61, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, + 0x16, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, + 0x63, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x51, 0x0a, 0x0e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x4c, 0x34, 0x30, 0x32, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x12, 0x1e, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x65, 0x74, + 0x63, 0x68, 0x4c, 0x34, 0x30, 0x32, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x65, 0x74, + 0x63, 0x68, 0x4c, 0x34, 0x30, 0x32, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x17, + 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, + 0x63, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x56, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, + 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x22, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, + 0x63, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x6f, + 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x5d, 0x0a, 0x12, 0x53, 0x65, 0x74, + 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, + 0x22, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x74, 0x4c, 0x69, 0x71, + 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, + 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0c, 0x53, 0x75, 0x67, 0x67, + 0x65, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x12, 0x1c, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, + 0x70, 0x63, 0x2e, 0x53, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, + 0x2e, 0x53, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, + 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, + 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6c, 0x6f, + 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, + 0x0a, 0x0a, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x12, 0x1a, 0x2e, 0x6c, + 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, + 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, + 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x1f, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, - 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x4c, 0x69, - 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x73, 0x12, 0x1f, 0x2e, - 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, + 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, + 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x51, 0x75, + 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x4c, + 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x73, 0x12, 0x1f, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x57, 0x0a, 0x10, 0x4e, 0x65, 0x77, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x12, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4e, - 0x65, 0x77, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, - 0x2e, 0x4e, 0x65, 0x77, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x13, 0x4c, 0x69, 0x73, - 0x74, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, - 0x12, 0x23, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, - 0x6e, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x10, 0x57, - 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x12, - 0x20, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, - 0x61, 0x77, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x21, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x57, 0x69, 0x74, 0x68, - 0x64, 0x72, 0x61, 0x77, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, - 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x73, 0x12, 0x29, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x44, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x6c, - 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x69, - 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x79, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, - 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x57, 0x69, 0x74, - 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x73, 0x12, 0x2b, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, - 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x69, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x69, - 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x77, 0x61, 0x70, 0x73, 0x12, 0x26, 0x2e, + 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x20, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x57, 0x0a, 0x10, 0x4e, 0x65, 0x77, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, + 0x4e, 0x65, 0x77, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, + 0x63, 0x2e, 0x4e, 0x65, 0x77, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x13, 0x4c, 0x69, + 0x73, 0x74, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x73, 0x12, 0x23, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x55, 0x6e, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x10, + 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, + 0x12, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x57, 0x69, 0x74, 0x68, 0x64, + 0x72, 0x61, 0x77, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x57, 0x69, 0x74, + 0x68, 0x64, 0x72, 0x61, 0x77, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, + 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x73, 0x12, 0x29, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x44, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, - 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x66, - 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x24, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, - 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x25, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x13, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x12, 0x23, 0x2e, - 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, - 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x27, 0x5a, 0x25, 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, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, - 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x79, 0x0a, 0x1c, 0x4c, 0x69, 0x73, + 0x74, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x57, 0x69, + 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x73, 0x12, 0x2b, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, + 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x69, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, + 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x77, 0x61, 0x70, 0x73, 0x12, 0x26, + 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, + 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x66, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x24, 0x2e, 0x6c, 0x6f, 0x6f, + 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x25, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x69, + 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x13, 0x53, 0x74, 0x61, 0x74, 0x69, + 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x12, 0x23, + 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, + 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x27, 0x5a, 0x25, 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, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x6c, 0x6f, 0x6f, 0x70, 0x72, + 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/looprpc/client.proto b/looprpc/client.proto index b1247e98e..44f2826b6 100644 --- a/looprpc/client.proto +++ b/looprpc/client.proto @@ -775,7 +775,10 @@ message OutTermsResponse { message QuoteRequest { /* - The amount to swap in satoshis. + The amount to swap in satoshis. In the loop-in case this can either be taken + from the connected lnd wallet or coin-selected from static address deposits. + This is controlled by the select_deposits flag. If deposit_outpoints are + specified, the coins are taken out of that. */ int64 amt = 1; @@ -823,8 +826,9 @@ message QuoteRequest { /* Static address deposit outpoints that will be quoted for. This option only - pertains to loop in swaps. Either this or the amt parameter can be set at - the same time. + pertains to loop in swaps. If the amt field is set as well the respective + partial amount will be swapped. Cannot be used in conjunction with + select_deposits. */ repeated string deposit_outpoints = 8; @@ -833,6 +837,14 @@ message QuoteRequest { be returned in the specified asset. */ AssetLoopOutRequest asset_info = 9; + + /* + This field indicates whether the swap amount should be covered by our lnd + wallet or by static address deposits. If set to true, the swap amount + will be selected from the static address deposits. This field cannot be used + in conjunction with deposit_outpoints. + */ + bool select_deposits = 10; } message InQuoteResponse { @@ -2078,6 +2090,21 @@ message StaticAddressLoopInRequest { side and the client can retry the swap with different parameters. */ uint32 payment_timeout_seconds = 8; + + /* + The optional swap amount the client is attempting to swap. It can be + provided in combination with the outpoints or separately. If provided with + outpoints the client takes out this amount from the sum of provided + outpoints and sends the change back to the static address. If the amount is + provided without outpoints, the client will select deposits automatically. + The coin selection strategy is simplified by sorting all available deposits + in descending order by amount, and equal amounts in ascending order of + blocks until expiry, and then selecting the largest deposits first until the + amount is reached. The change will be sent back to the static address. If a + subset of outpoints suffice to cover the specified amount the swap will be + canceled to allow the user to safe on transaction fees. + */ + int64 amount = 9; } message StaticAddressLoopInResponse { diff --git a/looprpc/client.swagger.json b/looprpc/client.swagger.json index a949dc5f9..73b0a6007 100644 --- a/looprpc/client.swagger.json +++ b/looprpc/client.swagger.json @@ -211,7 +211,7 @@ "parameters": [ { "name": "amt", - "description": "The amount to swap in satoshis.", + "description": "The amount to swap in satoshis. In the loop-in case this can either be taken\nfrom the connected lnd wallet or coin-selected from static address deposits.\nThis is controlled by the select_deposits flag. If deposit_outpoints are\nspecified, the coins are taken out of that.", "in": "path", "required": true, "type": "string", @@ -257,7 +257,7 @@ }, { "name": "deposit_outpoints", - "description": "Static address deposit outpoints that will be quoted for. This option only\npertains to loop in swaps. Either this or the amt parameter can be set at\nthe same time.", + "description": "Static address deposit outpoints that will be quoted for. This option only\npertains to loop in swaps. If the amt field is set as well the respective\npartial amount will be swapped. Cannot be used in conjunction with\nselect_deposits.", "in": "query", "required": false, "type": "array", @@ -297,6 +297,13 @@ "required": false, "type": "string", "format": "int64" + }, + { + "name": "select_deposits", + "description": "This field indicates whether the swap amount should be covered by our lnd\nwallet or by static address deposits. If set to true, the swap amount\nwill be selected from the static address deposits. This field cannot be used\nin conjunction with deposit_outpoints.", + "in": "query", + "required": false, + "type": "boolean" } ], "tags": [ @@ -404,7 +411,7 @@ "parameters": [ { "name": "amt", - "description": "The amount to swap in satoshis.", + "description": "The amount to swap in satoshis. In the loop-in case this can either be taken\nfrom the connected lnd wallet or coin-selected from static address deposits.\nThis is controlled by the select_deposits flag. If deposit_outpoints are\nspecified, the coins are taken out of that.", "in": "path", "required": true, "type": "string", @@ -450,7 +457,7 @@ }, { "name": "deposit_outpoints", - "description": "Static address deposit outpoints that will be quoted for. This option only\npertains to loop in swaps. Either this or the amt parameter can be set at\nthe same time.", + "description": "Static address deposit outpoints that will be quoted for. This option only\npertains to loop in swaps. If the amt field is set as well the respective\npartial amount will be swapped. Cannot be used in conjunction with\nselect_deposits.", "in": "query", "required": false, "type": "array", @@ -490,6 +497,13 @@ "required": false, "type": "string", "format": "int64" + }, + { + "name": "select_deposits", + "description": "This field indicates whether the swap amount should be covered by our lnd\nwallet or by static address deposits. If set to true, the swap amount\nwill be selected from the static address deposits. This field cannot be used\nin conjunction with deposit_outpoints.", + "in": "query", + "required": false, + "type": "boolean" } ], "tags": [ From affd0e31174f499b63767fa900a873e7449d5157 Mon Sep 17 00:00:00 2001 From: Slyghtning Date: Fri, 27 Jun 2025 10:56:28 +0200 Subject: [PATCH 08/12] staticaddr: arbitrary loop-in amount In this commit we add a new function SelectDeposits to the loop-in manager. It coin-selects deposits that meet an arbitrary swap amount provided by the client. We have to ensure that the server creates the correct change outputs for the htlc- and sweepless sweep transactions. --- interface.go | 5 + staticaddr/loopin/actions.go | 24 +++- staticaddr/loopin/interface.go | 5 + staticaddr/loopin/loopin.go | 57 +++++++- staticaddr/loopin/manager.go | 220 ++++++++++++++++++++++++++---- staticaddr/loopin/manager_test.go | 126 +++++++++++++++++ staticaddr/loopin/sql_store.go | 8 +- 7 files changed, 407 insertions(+), 38 deletions(-) create mode 100644 staticaddr/loopin/manager_test.go diff --git a/interface.go b/interface.go index 310bda33d..5a82ce62c 100644 --- a/interface.go +++ b/interface.go @@ -338,6 +338,11 @@ type StaticAddressLoopInRequest struct { // swap payment. If the timeout is reached the swap will be aborted and // the client can retry the swap if desired with different parameters. PaymentTimeoutSeconds uint32 + + // SelectedAmount is the amount that the user selected for the swap. If + // the user did not select an amount, the amount of the selected + // deposits is used. + SelectedAmount btcutil.Amount } // LoopInTerms are the server terms on which it executes loop in swaps. diff --git a/staticaddr/loopin/actions.go b/staticaddr/loopin/actions.go index add35b4ab..5fff0872e 100644 --- a/staticaddr/loopin/actions.go +++ b/staticaddr/loopin/actions.go @@ -68,9 +68,18 @@ func (f *FSM) InitHtlcAction(ctx context.Context, } // Calculate the swap invoice amount. The server needs to pay us the - // sum of all deposits minus the fees that the server charges for the - // swap. - swapInvoiceAmt := f.loopIn.TotalDepositAmount() - f.loopIn.QuotedSwapFee + // swap amount minus the fees that the server charges for the swap. The + // swap amount is either the total value of the selected deposits, or + // the selected amount if a specific amount was requested. + swapAmount := f.loopIn.TotalDepositAmount() + var hasChange bool + if f.loopIn.SelectedAmount > 0 { + swapAmount = f.loopIn.SelectedAmount + remainingAmount := f.loopIn.TotalDepositAmount() - swapAmount + hasChange = remainingAmount > 0 && remainingAmount < + f.loopIn.TotalDepositAmount() + } + swapInvoiceAmt := swapAmount - f.loopIn.QuotedSwapFee // Generate random preimage. var swapPreimage lntypes.Preimage @@ -120,6 +129,7 @@ func (f *FSM) InitHtlcAction(ctx context.Context, loopInReq := &swapserverrpc.ServerStaticAddressLoopInRequest{ SwapHash: f.loopIn.SwapHash[:], DepositOutpoints: f.loopIn.DepositOutpoints, + Amount: uint64(f.loopIn.SelectedAmount), HtlcClientPubKey: f.loopIn.ClientPubkey.SerializeCompressed(), SwapInvoice: f.loopIn.SwapInvoice, ProtocolVersion: version.CurrentRPCProtocolVersion(), @@ -204,7 +214,7 @@ func (f *FSM) InitHtlcAction(ctx context.Context, // We need to defend against the server setting high fees for the htlc // tx since we might have to sweep the timeout path. We maximally allow // a configured percentage of the swap value to be spent on fees. - amt := float64(f.loopIn.TotalDepositAmount()) + amt := float64(swapAmount) maxHtlcTxFee := btcutil.Amount(amt * f.cfg.MaxStaticAddrHtlcFeePercentage) @@ -212,7 +222,7 @@ func (f *FSM) InitHtlcAction(ctx context.Context, f.cfg.MaxStaticAddrHtlcBackupFeePercentage) feeRate := chainfee.SatPerKWeight(loopInResp.StandardHtlcInfo.FeeRate) - fee := feeRate.FeeForWeight(f.loopIn.htlcWeight()) + fee := feeRate.FeeForWeight(f.loopIn.htlcWeight(hasChange)) if fee > maxHtlcTxFee { // Abort the swap by pushing empty sigs to the server. pushEmptySigs() @@ -225,7 +235,7 @@ func (f *FSM) InitHtlcAction(ctx context.Context, f.loopIn.HtlcTxFeeRate = feeRate highFeeRate := chainfee.SatPerKWeight(loopInResp.HighFeeHtlcInfo.FeeRate) - fee = highFeeRate.FeeForWeight(f.loopIn.htlcWeight()) + fee = highFeeRate.FeeForWeight(f.loopIn.htlcWeight(hasChange)) if fee > maxHtlcTxBackupFee { // Abort the swap by pushing empty sigs to the server. pushEmptySigs() @@ -241,7 +251,7 @@ func (f *FSM) InitHtlcAction(ctx context.Context, extremelyHighFeeRate := chainfee.SatPerKWeight( loopInResp.ExtremeFeeHtlcInfo.FeeRate, ) - fee = extremelyHighFeeRate.FeeForWeight(f.loopIn.htlcWeight()) + fee = extremelyHighFeeRate.FeeForWeight(f.loopIn.htlcWeight(hasChange)) if fee > maxHtlcTxBackupFee { // Abort the swap by pushing empty sigs to the server. pushEmptySigs() diff --git a/staticaddr/loopin/interface.go b/staticaddr/loopin/interface.go index cf95f838b..3dd8cfbc8 100644 --- a/staticaddr/loopin/interface.go +++ b/staticaddr/loopin/interface.go @@ -53,6 +53,11 @@ type DepositManager interface { // outpoints. DepositsForOutpoints(ctx context.Context, outpoints []string) ( []*deposit.Deposit, error) + + // GetActiveDepositsInState returns all active deposits in the given + // state. + GetActiveDepositsInState(stateFilter fsm.StateType) ([]*deposit.Deposit, + error) } // StaticAddressLoopInStore provides access to the static address loop-in DB. diff --git a/staticaddr/loopin/loopin.go b/staticaddr/loopin/loopin.go index aa7c3a2da..320d1f01f 100644 --- a/staticaddr/loopin/loopin.go +++ b/staticaddr/loopin/loopin.go @@ -1,6 +1,7 @@ package loopin import ( + "bytes" "context" "errors" "fmt" @@ -93,6 +94,11 @@ type StaticAddressLoopIn struct { // swap. DepositOutpoints []string + // SelectedAmount is the amount that the user selected for the swap. If + // the user did not select an amount, the amount of all deposits is + // used. + SelectedAmount btcutil.Amount + // state is the current state of the swap. state fsm.StateType @@ -283,14 +289,25 @@ func (l *StaticAddressLoopIn) createHtlcTx(chainParams *chaincfg.Params, }) } + // Determine the swap amount. If the user selected a specific amount, we + // use that and use the difference to the total deposit amount as the + // change. + var ( + swapAmt = l.TotalDepositAmount() + changeAmount btcutil.Amount + ) + if l.SelectedAmount > 0 { + swapAmt = l.SelectedAmount + changeAmount = l.TotalDepositAmount() - l.SelectedAmount + } + // Calculate htlc tx fee for server provided fee rate. - weight := l.htlcWeight() + hasChange := changeAmount > 0 + weight := l.htlcWeight(hasChange) fee := feeRate.FeeForWeight(weight) // Check if the server breaches our fee limits. - amt := float64(l.TotalDepositAmount()) - feeLimit := btcutil.Amount(amt * maxFeePercentage) - + feeLimit := btcutil.Amount(float64(swapAmt) * maxFeePercentage) if fee > feeLimit { return nil, fmt.Errorf("htlc tx fee %v exceeds max fee %v", fee, feeLimit) @@ -308,12 +325,20 @@ func (l *StaticAddressLoopIn) createHtlcTx(chainParams *chaincfg.Params, // Create the sweep output sweepOutput := &wire.TxOut{ - Value: int64(l.TotalDepositAmount()) - int64(fee), + Value: int64(swapAmt - fee), PkScript: pkscript, } msgTx.AddTxOut(sweepOutput) + // We expect change to be sent back to our static address output script. + if changeAmount > 0 { + msgTx.AddTxOut(&wire.TxOut{ + Value: int64(changeAmount), + PkScript: l.AddressParams.PkScript, + }) + } + return msgTx, nil } @@ -325,7 +350,7 @@ func (l *StaticAddressLoopIn) isHtlcTimedOut(height int32) bool { } // htlcWeight returns the weight for the htlc transaction. -func (l *StaticAddressLoopIn) htlcWeight() lntypes.WeightUnit { +func (l *StaticAddressLoopIn) htlcWeight(hasChange bool) lntypes.WeightUnit { var weightEstimator input.TxWeightEstimator for i := 0; i < len(l.Deposits); i++ { weightEstimator.AddTaprootKeySpendInput( @@ -335,6 +360,10 @@ func (l *StaticAddressLoopIn) htlcWeight() lntypes.WeightUnit { weightEstimator.AddP2WSHOutput() + if hasChange { + weightEstimator.AddP2TROutput() + } + return weightEstimator.Weight() } @@ -373,11 +402,25 @@ func (l *StaticAddressLoopIn) createHtlcSweepTx(ctx context.Context, return nil, err } + // Check if the htlc tx has a change output. If so we need to select the + // non-change output index to construct the sweep with. + htlcInputIndex := uint32(0) + if len(htlcTx.TxOut) == 2 { + // If the first htlc tx output matches our static address + // script we need to select the second output to sweep from. + if bytes.Equal( + htlcTx.TxOut[0].PkScript, l.AddressParams.PkScript, + ) { + + htlcInputIndex = 1 + } + } + // Add the htlc input. sweepTx.AddTxIn(&wire.TxIn{ PreviousOutPoint: wire.OutPoint{ Hash: htlcTx.TxHash(), - Index: 0, + Index: htlcInputIndex, }, SignatureScript: htlc.SigScript, Sequence: htlc.SuccessSequence(), diff --git a/staticaddr/loopin/manager.go b/staticaddr/loopin/manager.go index 79423fdc3..cfb9b5de5 100644 --- a/staticaddr/loopin/manager.go +++ b/staticaddr/loopin/manager.go @@ -4,10 +4,12 @@ import ( "bytes" "context" "fmt" + "sort" "sync/atomic" "time" "github.com/btcsuite/btcd/btcec/v2/schnorr/musig2" + "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/btcutil/psbt" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg/chainhash" @@ -19,7 +21,9 @@ import ( "github.com/lightninglabs/loop/labels" "github.com/lightninglabs/loop/staticaddr/deposit" "github.com/lightninglabs/loop/swapserverrpc" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/lntypes" + "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/routing/route" ) @@ -277,6 +281,14 @@ func (m *Manager) handleLoopInSweepReq(ctx context.Context, return err } + deposits, err := m.cfg.DepositManager.DepositsForOutpoints( + ctx, loopIn.DepositOutpoints, + ) + if err != nil { + return err + } + loopIn.Deposits = deposits + reader := bytes.NewReader(req.SweepTxPsbt) sweepPacket, err := psbt.NewFromRawBytes(reader, false) if err != nil { @@ -302,6 +314,34 @@ func (m *Manager) handleLoopInSweepReq(ctx context.Context, len(req.PrevoutInfo), len(sweepTx.TxIn)) } + // If the user selected an amount that is less than the total deposit + // amount we'll check that the server sends us the correct change amount + // back to our static address. + totalDepositAmount := loopIn.TotalDepositAmount() + changeAmt := totalDepositAmount - loopIn.SelectedAmount + if changeAmt > 0 && changeAmt < totalDepositAmount { + var foundChange bool + changePkScript := loopIn.AddressParams.PkScript + + for _, out := range sweepTx.TxOut { + if out.Value == int64(changeAmt) && + bytes.Equal(out.PkScript, changePkScript) { + + foundChange = true + break + } + } + + if !foundChange { + return fmt.Errorf("expected change output to our "+ + "static address, total_deposit_amount=%v, "+ + "selected_amount=%v, "+ + "expected_change_amount=%v ", + totalDepositAmount, loopIn.SelectedAmount, + changeAmt) + } + } + // Check if all the deposits requested are part of the loop-in and // find them in the requested sweep. depositToIdxMap, err := mapDepositsToIndices(req, loopIn, sweepTx) @@ -528,29 +568,83 @@ func (m *Manager) DeliverLoopInRequest(ctx context.Context, func (m *Manager) initiateLoopIn(ctx context.Context, req *loop.StaticAddressLoopInRequest) (*StaticAddressLoopIn, error) { - // Validate the loop-in request. - if len(req.DepositOutpoints) == 0 { - return nil, fmt.Errorf("no deposit outpoints provided") - } - - // Retrieve all deposits referenced by the outpoints and ensure that - // they are in state Deposited. - deposits, active := m.cfg.DepositManager.AllStringOutpointsActiveDeposits( //nolint:lll - req.DepositOutpoints, deposit.Deposited, + var ( + err error + selectedOutpoints = req.DepositOutpoints + selectedDeposits []*deposit.Deposit ) - if !active { - return nil, fmt.Errorf("one or more deposits are not in "+ - "state %s", deposit.Deposited) + + // Determine which deposits to use for the loop-in swap. If none are + // selected by the client we will coin-select them based on the amount. + switch { + case len(selectedOutpoints) == 0 && req.SelectedAmount == 0: + return nil, fmt.Errorf("neither deposit outpoints nor amount " + + "provided") + + case len(selectedOutpoints) > 0: + // Retrieve all deposits referenced by the outpoints and ensure + // that they are in state Deposited. + var active bool + selectedDeposits, active = m.cfg.DepositManager. + AllStringOutpointsActiveDeposits( + selectedOutpoints, deposit.Deposited, + ) + if !active { + return nil, fmt.Errorf("one or more deposits are not in "+ + "state %s", deposit.Deposited) + } + + case len(selectedOutpoints) == 0: + // If an amount was provided we'll coin-select deposits to cover + // for the amount. + allDeposits, err := m.cfg.DepositManager. + GetActiveDepositsInState(deposit.Deposited) + if err != nil { + return nil, fmt.Errorf("unable to retrieve all "+ + "deposits: %w", err) + } + + // TODO(hieblmi): add params to deposit for multi-address + // support. + params, err := m.cfg.AddressManager.GetStaticAddressParameters( + ctx, + ) + if err != nil { + return nil, fmt.Errorf("unable to retrieve static "+ + "address parameters: %w", err) + } + + selectedDeposits, err = SelectDeposits( + req.SelectedAmount, allDeposits, params.Expiry, + m.currentHeight.Load(), + ) + if err != nil { + return nil, fmt.Errorf("unable to select deposits: %w", + err) + } + + selectedOutpoints = make([]string, 0, len(selectedDeposits)) + for _, deposit := range selectedDeposits { + selectedOutpoints = append(selectedOutpoints, + deposit.String()) + } } - // Calculate the total deposit amount. + // Calculate the total deposit amount and check if the selected amount + // would leave a dust output. tmp := &StaticAddressLoopIn{ - Deposits: deposits, + Deposits: selectedDeposits, + } + swapAmount, err := SwapAmountFromSelectedAmount( + tmp.TotalDepositAmount(), req.SelectedAmount, + ) + if err != nil { + return nil, fmt.Errorf("unable to determine swap amount: %w", + err) } - totalDepositAmount := tmp.TotalDepositAmount() // Check that the label is valid. - err := labels.Validate(req.Label) + err = labels.Validate(req.Label) if err != nil { return nil, fmt.Errorf("invalid label: %w", err) } @@ -574,7 +668,7 @@ func (m *Manager) initiateLoopIn(ctx context.Context, // Because the Private flag is set, we'll generate our own set // of hop hints. req.RouteHints, err = loop.SelectHopHints( - ctx, m.cfg.LndClient, totalDepositAmount, + ctx, m.cfg.LndClient, swapAmount, loop.DefaultMaxHopHints, includeNodes, ) if err != nil { @@ -591,11 +685,11 @@ func (m *Manager) initiateLoopIn(ctx context.Context, // directly anyway and there they have the option to add specific route // hints. // The quote call will also request a probe from the server to ensure - // feasibility of a loop-in for the totalDepositAmount. - numDeposits := uint32(len(deposits)) + // feasibility of a loop-in for the selected. + numDeposits := uint32(len(selectedDeposits)) quote, err := m.cfg.QuoteGetter.GetLoopInQuote( - ctx, totalDepositAmount, m.cfg.NodePubkey, req.LastHop, - req.RouteHints, req.Initiator, numDeposits, + ctx, swapAmount, m.cfg.NodePubkey, req.LastHop, req.RouteHints, + req.Initiator, numDeposits, ) if err != nil { return nil, fmt.Errorf("unable to get loop in quote: %w", err) @@ -616,8 +710,9 @@ func (m *Manager) initiateLoopIn(ctx context.Context, } swap := &StaticAddressLoopIn{ - DepositOutpoints: req.DepositOutpoints, - Deposits: deposits, + SelectedAmount: req.SelectedAmount, + DepositOutpoints: selectedOutpoints, + Deposits: selectedDeposits, Label: req.Label, Initiator: req.Initiator, InitiationTime: time.Now(), @@ -707,6 +802,85 @@ func (m *Manager) GetAllSwaps(ctx context.Context) ([]*StaticAddressLoopIn, return swaps, nil } +// SelectDeposits sorts the deposits by amount in descending order, then by +// blocks-until-expiry in ascending order. It then selects the deposits that +// are needed to cover the amount requested without leaving a dust change. It +// returns an error if the sum of deposits minus dust is less than the requested +// amount. +func SelectDeposits(targetAmount btcutil.Amount, deposits []*deposit.Deposit, + csvExpiry uint32, blockHeight uint32) ([]*deposit.Deposit, error) { + + // Sort the deposits by amount in descending order, then by + // blocks-until-expiry in ascending order. + sort.Slice(deposits, func(i, j int) bool { + if deposits[i].Value == deposits[j].Value { + iExp := uint32(deposits[i].ConfirmationHeight) + + csvExpiry - blockHeight + jExp := uint32(deposits[j].ConfirmationHeight) + + csvExpiry - blockHeight + + return iExp < jExp + } + return deposits[i].Value > deposits[j].Value + }) + + // Select the deposits that are needed to cover the swap amount without + // leaving a dust change. + var selectedDeposits []*deposit.Deposit + var selectedAmount btcutil.Amount + dustLimit := lnwallet.DustLimitForSize(input.P2TRSize) + for _, deposit := range deposits { + selectedDeposits = append(selectedDeposits, deposit) + selectedAmount += deposit.Value + if selectedAmount == targetAmount { + return selectedDeposits, nil + } + if selectedAmount > targetAmount { + if selectedAmount-targetAmount >= dustLimit { + return selectedDeposits, nil + } + } + } + + return nil, fmt.Errorf("not enough deposits to cover "+ + "requested amount or prevent dust change, have %d but need %d", + selectedAmount, targetAmount) +} + +// SwapAmountFromSelectedAmount calculates the swap amount based on the +// selected amount and the total deposit amount. It checks if the selected +// amount leaves a dust change output or exceeds the total deposits value. +func SwapAmountFromSelectedAmount(totalDepositAmount btcutil.Amount, + selectedAmount btcutil.Amount) (btcutil.Amount, error) { + + // If the selected amount would leave a dust change output or exceeds + // the total deposits value, we return an error. + swapAmount := selectedAmount + dustLimit := lnwallet.DustLimitForSize(input.P2TRSize) + remainingAmount := totalDepositAmount - selectedAmount + switch { + case remainingAmount < 0: + return 0, fmt.Errorf("selected amount %v exceeds total "+ + "deposit value %v", selectedAmount, totalDepositAmount) + + case remainingAmount > 0 && remainingAmount < dustLimit: + return 0, fmt.Errorf("selected amount %v leaves dust change "+ + "%v", selectedAmount, remainingAmount) + + default: + // If the remaining amount is 0 or equal or greater than the + // dust limit, we can proceed with the swap. + } + + // If the client didn't select an amount we quote for the total + // deposits value. + if selectedAmount == 0 { + swapAmount = totalDepositAmount + } + + return swapAmount, nil +} + // mapDepositsToIndices maps the deposit outpoints to their respective indices // in the sweep transaction. func mapDepositsToIndices(req *swapserverrpc.ServerStaticLoopInSweepNotification, //nolint:lll diff --git a/staticaddr/loopin/manager_test.go b/staticaddr/loopin/manager_test.go new file mode 100644 index 000000000..1ee7e34da --- /dev/null +++ b/staticaddr/loopin/manager_test.go @@ -0,0 +1,126 @@ +package loopin + +import ( + "testing" + + "github.com/btcsuite/btcd/btcutil" + "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lightninglabs/loop/staticaddr/deposit" + "github.com/lightningnetwork/lnd/input" + "github.com/lightningnetwork/lnd/lnwallet" + "github.com/stretchr/testify/require" +) + +type testCase struct { + deposits []*deposit.Deposit + targetValue btcutil.Amount + csvExpiry uint32 + blockHeight uint32 + expected []*deposit.Deposit + expectedErr string +} + +// TestSelectDeposits tests the selectDeposits function, which selects +// deposits that can cover a target value, while respecting the dust limit. +func TestSelectDeposits(t *testing.T) { + dustLimit := lnwallet.DustLimitForSize(input.P2TRSize) + d1, d2, d3, d4 := &deposit.Deposit{ + Value: 1_000_000, + ConfirmationHeight: 1000, + }, &deposit.Deposit{ + Value: 2_000_000, + ConfirmationHeight: 2000, + }, &deposit.Deposit{ + Value: 3_000_000, + ConfirmationHeight: 3000, + }, + &deposit.Deposit{ + Value: 3_000_000, + ConfirmationHeight: 3001, + } + d1.Hash = chainhash.Hash{1} + d1.Index = 0 + d2.Hash = chainhash.Hash{2} + d2.Index = 0 + d3.Hash = chainhash.Hash{3} + d3.Index = 0 + d4.Hash = chainhash.Hash{4} + d4.Index = 0 + + testCases := []testCase{ + { + deposits: []*deposit.Deposit{d1}, + targetValue: 1_000_000, + expected: []*deposit.Deposit{d1}, + expectedErr: "", + }, + { + deposits: []*deposit.Deposit{d1, d2}, + targetValue: 1_000_000, + expected: []*deposit.Deposit{d2}, + expectedErr: "", + }, + { + deposits: []*deposit.Deposit{d1, d2, d3}, + targetValue: 1_000_000, + expected: []*deposit.Deposit{d3}, + expectedErr: "", + }, + { + deposits: []*deposit.Deposit{d1}, + targetValue: 1_000_001, + expected: []*deposit.Deposit{}, + expectedErr: "not enough deposits to cover", + }, + { + deposits: []*deposit.Deposit{d1}, + targetValue: 1_000_000 - dustLimit, + expected: []*deposit.Deposit{d1}, + expectedErr: "", + }, + { + deposits: []*deposit.Deposit{d1}, + targetValue: 1_000_000 - dustLimit + 1, + expected: []*deposit.Deposit{}, + expectedErr: "not enough deposits to cover", + }, + { + deposits: []*deposit.Deposit{d1, d2, d3}, + targetValue: d1.Value + d2.Value + d3.Value, + expected: []*deposit.Deposit{d1, d2, d3}, + expectedErr: "", + }, + { + deposits: []*deposit.Deposit{d1, d2, d3}, + targetValue: d1.Value + d2.Value + d3.Value - dustLimit, + expected: []*deposit.Deposit{d1, d2, d3}, + expectedErr: "", + }, + { + deposits: []*deposit.Deposit{d1, d2, d3}, + targetValue: d1.Value + d2.Value + d3.Value - dustLimit + 1, + expected: []*deposit.Deposit{}, + expectedErr: "not enough deposits to cover", + }, + { + deposits: []*deposit.Deposit{d3, d4}, + targetValue: d4.Value - dustLimit, // d3/d4 have the + // same value but different expiration. + expected: []*deposit.Deposit{d3}, + expectedErr: "", + }, + } + + for _, tc := range testCases { + selectedDeposits, err := SelectDeposits( + tc.targetValue, tc.deposits, tc.csvExpiry, + tc.blockHeight, + ) + if tc.expectedErr == "" { + require.NoError(t, err) + } else { + require.ErrorContains(t, err, tc.expectedErr) + } + require.ElementsMatch(t, tc.expected, selectedDeposits) + } +} diff --git a/staticaddr/loopin/sql_store.go b/staticaddr/loopin/sql_store.go index e6ba5aadd..122aaa594 100644 --- a/staticaddr/loopin/sql_store.go +++ b/staticaddr/loopin/sql_store.go @@ -190,11 +190,15 @@ func toStrings(states []fsm.StateType) []string { func (s *SqlStore) CreateLoopIn(ctx context.Context, loopIn *StaticAddressLoopIn) error { + amountRequested := int64(loopIn.TotalDepositAmount()) + if loopIn.SelectedAmount > 0 { + amountRequested = int64(loopIn.SelectedAmount) + } swapArgs := sqlc.InsertSwapParams{ SwapHash: loopIn.SwapHash[:], Preimage: loopIn.SwapPreimage[:], InitiationTime: loopIn.InitiationTime, - AmountRequested: int64(loopIn.TotalDepositAmount()), + AmountRequested: amountRequested, CltvExpiry: loopIn.HtlcCltvExpiry, MaxSwapFee: int64(loopIn.MaxSwapFee), InitiationHeight: int32(loopIn.InitiationHeight), @@ -230,6 +234,7 @@ func (s *SqlStore) CreateLoopIn(ctx context.Context, HtlcTimeoutSweepAddress: loopIn.HtlcTimeoutSweepAddress.String(), HtlcTxFeeRateSatKw: int64(loopIn.HtlcTxFeeRate), DepositOutpoints: joinedOutpoints, + SelectedAmount: int64(loopIn.SelectedAmount), PaymentTimeoutSeconds: int32(loopIn.PaymentTimeoutSeconds), } @@ -378,6 +383,7 @@ func toStaticAddressLoopIn(_ context.Context, network *chaincfg.Params, LastHop: row.LastHop, QuotedSwapFee: btcutil.Amount(row.QuotedSwapFeeSatoshis), DepositOutpoints: depositOutpoints, + SelectedAmount: btcutil.Amount(row.SelectedAmount), HtlcTxFeeRate: chainfee.SatPerKWeight( row.HtlcTxFeeRateSatKw, ), From afad010eb5fe56cefa4c90679c94830963a60050 Mon Sep 17 00:00:00 2001 From: Slyghtning Date: Fri, 27 Jun 2025 10:56:03 +0200 Subject: [PATCH 09/12] loopd: deposit selection for GetLoopInQuote If a quote request contains an amount and flag SelectDeposits set to true the quoting coin- selects the required deposits to meet the swap amount in order to quote for the number of deposits. --- loopd/swapclient_server.go | 115 +++++++++++++++++++++++++------- loopd/swapclient_server_test.go | 25 ++++++- 2 files changed, 114 insertions(+), 26 deletions(-) diff --git a/loopd/swapclient_server.go b/loopd/swapclient_server.go index 313db6fc3..4cf64250c 100644 --- a/loopd/swapclient_server.go +++ b/loopd/swapclient_server.go @@ -893,22 +893,62 @@ func (s *swapClientServer) GetLoopInQuote(ctx context.Context, infof("Loop in quote request received") var ( - numDeposits = uint32(len(req.DepositOutpoints)) - err error + selectedAmount = btcutil.Amount(req.Amt) + totalDepositAmount btcutil.Amount + autoSelectDeposits = req.SelectDeposits + err error ) htlcConfTarget, err := validateLoopInRequest( - req.ConfTarget, req.ExternalHtlc, numDeposits, req.Amt, + req.ConfTarget, req.ExternalHtlc, + uint32(len(req.DepositOutpoints)), int64(selectedAmount), + autoSelectDeposits, ) if err != nil { return nil, err } - // Retrieve deposits to calculate their total value. - var depositList *looprpc.ListStaticAddressDepositsResponse - amount := btcutil.Amount(req.Amt) - if len(req.DepositOutpoints) > 0 { - depositList, err = s.ListStaticAddressDeposits( + // If deposits should be automatically selected we do so and count the + // number of deposits to quote for. + numDeposits := 0 + if autoSelectDeposits { + deposits, err := s.depositManager.GetActiveDepositsInState( + deposit.Deposited, + ) + if err != nil { + return nil, fmt.Errorf("unable to retrieve all "+ + "deposits: %w", err) + } + + // TODO(hieblmi): add params to deposit for multi-address + // support. + params, err := s.staticAddressManager.GetStaticAddressParameters( + ctx, + ) + if err != nil { + return nil, fmt.Errorf("unable to retrieve static "+ + "address parameters: %w", err) + } + + info, err := s.lnd.Client.GetInfo(ctx) + if err != nil { + return nil, fmt.Errorf("unable to get lnd info: %w", + err) + } + selectedDeposits, err := loopin.SelectDeposits( + selectedAmount, deposits, params.Expiry, + info.BlockHeight, + ) + if err != nil { + return nil, fmt.Errorf("unable to select deposits: %w", + err) + } + + numDeposits = len(selectedDeposits) + } else if len(req.DepositOutpoints) > 0 { + // If deposits are selected, we need to retrieve them to + // calculate the total value which we request a quote for. + depositList, err := s.ListStaticAddressDeposits( ctx, &looprpc.ListStaticAddressDepositsRequest{ Outpoints: req.DepositOutpoints, }, @@ -922,20 +962,34 @@ func (s *swapClientServer) GetLoopInQuote(ctx context.Context, "deposit outpoints") } - // The requested amount should be 0 here if the request - // contained deposit outpoints. - if amount != 0 && len(depositList.FilteredDeposits) > 0 { - return nil, fmt.Errorf("amount should be 0 for " + - "deposit quotes") + if len(req.DepositOutpoints) != + len(depositList.FilteredDeposits) { + + return nil, fmt.Errorf("expected %d deposits, got %d", + numDeposits, len(depositList.FilteredDeposits)) + } else { + numDeposits = len(depositList.FilteredDeposits) } // In case we quote for deposits we send the server both the - // total value and the number of deposits. This is so the server - // can probe the total amount and calculate the per input fee. - if amount == 0 && len(depositList.FilteredDeposits) > 0 { - for _, deposit := range depositList.FilteredDeposits { - amount += btcutil.Amount(deposit.Value) - } + // selected value and the number of deposits. This is so the + // server can probe the selected value and calculate the per + // input fee. + for _, deposit := range depositList.FilteredDeposits { + totalDepositAmount += btcutil.Amount( + deposit.Value, + ) + } + + // If a fractional amount is also selected, we check if it would + // lead to a dust change output. + selectedAmount, err = loopin.SwapAmountFromSelectedAmount( + totalDepositAmount, selectedAmount, + ) + if err != nil { + return nil, fmt.Errorf("error calculating "+ + "swap amount from selected amount: %v", + err) } } @@ -962,14 +1016,14 @@ func (s *swapClientServer) GetLoopInQuote(ctx context.Context, } quote, err := s.impl.LoopInQuote(ctx, &loop.LoopInQuoteRequest{ - Amount: amount, + Amount: selectedAmount, HtlcConfTarget: htlcConfTarget, ExternalHtlc: req.ExternalHtlc, LastHop: lastHop, RouteHints: routeHints, Private: req.Private, Initiator: defaultLoopdInitiator, - NumDeposits: numDeposits, + NumDeposits: uint32(numDeposits), }) if err != nil { return nil, err @@ -1065,8 +1119,11 @@ func (s *swapClientServer) LoopIn(ctx context.Context, infof("Loop in request received") + selectDeposits := false + numDeposits := uint32(0) htlcConfTarget, err := validateLoopInRequest( - in.HtlcConfTarget, in.ExternalHtlc, 0, in.Amt, + in.HtlcConfTarget, in.ExternalHtlc, numDeposits, in.Amt, + selectDeposits, ) if err != nil { return nil, err @@ -1868,6 +1925,7 @@ func (s *swapClientServer) StaticAddressLoopIn(ctx context.Context, } req := &loop.StaticAddressLoopInRequest{ + SelectedAmount: btcutil.Amount(in.Amount), DepositOutpoints: in.Outpoints, MaxSwapFee: btcutil.Amount(in.MaxSwapFeeSatoshis), Label: in.Label, @@ -2166,10 +2224,17 @@ func validateConfTarget(target, defaultTarget int32) (int32, error) { // validateLoopInRequest fails if the mutually exclusive conf target and // external parameters are both set. func validateLoopInRequest(htlcConfTarget int32, external bool, - numDeposits uint32, amount int64) (int32, error) { + numDeposits uint32, amount int64, autoSelectDeposits bool) (int32, + error) { if amount == 0 && numDeposits == 0 { - return 0, errors.New("either amount or deposits must be set") + return 0, errors.New("either amount, or deposits or both " + + "must be set") + } + + if autoSelectDeposits && numDeposits > 0 { + return 0, errors.New("cannot auto-select deposits while " + + "providing deposits at the same time") } // If the htlc is going to be externally set, the htlcConfTarget should @@ -2187,7 +2252,7 @@ func validateLoopInRequest(htlcConfTarget int32, external bool, // If the loop in uses static address deposits, we do not need to set a // confirmation target since the HTLC won't be published by the client. - if numDeposits > 0 { + if numDeposits > 0 || autoSelectDeposits { return 0, nil } diff --git a/loopd/swapclient_server_test.go b/loopd/swapclient_server_test.go index f104fc856..ccfee4a72 100644 --- a/loopd/swapclient_server_test.go +++ b/loopd/swapclient_server_test.go @@ -152,6 +152,7 @@ func TestValidateLoopInRequest(t *testing.T) { numDeposits uint32 external bool confTarget int32 + depositSelect bool expectErr bool expectedTarget int32 }{ @@ -210,6 +211,28 @@ func TestValidateLoopInRequest(t *testing.T) { external: false, expectErr: false, }, + + { + name: "not external, deposit fractional amount", + amount: 100_000, + numDeposits: 1, + external: false, + expectErr: false, + }, + { + name: "amount with deposit coin select", + amount: 100_000, + depositSelect: true, + external: false, + expectErr: false, + }, + { + name: "amount with deposit coin select", + numDeposits: 1, + depositSelect: true, + external: false, + expectErr: true, + }, } for _, test := range tests { @@ -217,7 +240,7 @@ func TestValidateLoopInRequest(t *testing.T) { external := test.external conf, err := validateLoopInRequest( test.confTarget, external, test.numDeposits, - test.amount, + test.amount, test.depositSelect, ) if test.expectErr { From ee6ec7220dcf23369e44a42ee8bfe05a1cbd97ab Mon Sep 17 00:00:00 2001 From: Slyghtning Date: Wed, 2 Apr 2025 14:37:12 +0200 Subject: [PATCH 10/12] staticaddr: fix swap amount in listswaps command --- loopd/swapclient_server.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/loopd/swapclient_server.go b/loopd/swapclient_server.go index 4cf64250c..63f3277b1 100644 --- a/loopd/swapclient_server.go +++ b/loopd/swapclient_server.go @@ -1812,13 +1812,18 @@ func (s *swapClientServer) ListStaticAddressSwaps(ctx context.Context, return nil, fmt.Errorf("error decoding swap invoice: "+ "%v", err) } + + swapAmount := swp.TotalDepositAmount() + if swp.SelectedAmount > 0 { + swapAmount = swp.SelectedAmount + } swap := &looprpc.StaticAddressLoopInSwap{ SwapHash: swp.SwapHash[:], DepositOutpoints: swp.DepositOutpoints, State: toClientStaticAddressLoopInState( swp.GetState(), ), - SwapAmountSatoshis: int64(swp.TotalDepositAmount()), + SwapAmountSatoshis: int64(swapAmount), PaymentRequestAmountSatoshis: int64( swapPayReq.MilliSat.ToSatoshis(), ), From a20235af080c14056250d842389727ddd22f696a Mon Sep 17 00:00:00 2001 From: Slyghtning Date: Wed, 11 Jun 2025 12:02:25 +0200 Subject: [PATCH 11/12] staticaddr: selected swap amount migration The selected_amount column of all previous swaps is filled with the total value of deposits that partook in these swaps. --- loopd/daemon.go | 10 ++ loopdb/sqlc/querier.go | 1 + loopdb/sqlc/queries/static_address_loopin.sql | 6 + loopdb/sqlc/static_address_loopin.sql.go | 17 +++ .../loopin/selected_amount_migration.go | 84 ++++++++++++++ .../loopin/selected_amount_migration_test.go | 106 ++++++++++++++++++ staticaddr/loopin/sql_store.go | 34 +++++- 7 files changed, 254 insertions(+), 4 deletions(-) create mode 100644 staticaddr/loopin/selected_amount_migration.go create mode 100644 staticaddr/loopin/selected_amount_migration_test.go diff --git a/loopd/daemon.go b/loopd/daemon.go index 7212933ad..b5f5ae21e 100644 --- a/loopd/daemon.go +++ b/loopd/daemon.go @@ -626,6 +626,16 @@ func (d *Daemon) initialize(withMacaroonService bool) error { clock.NewDefaultClock(), d.lnd.ChainParams, ) + // Run the selected amount migration. + err = loopin.MigrateSelectedSwapAmount( + d.mainCtx, swapDb, depositStore, staticAddressLoopInStore, + ) + if err != nil { + errorf("Selected amount migration failed: %v", err) + + return err + } + staticLoopInManager = loopin.NewManager(&loopin.Config{ Server: staticAddressClient, QuoteGetter: swapClient.Server, diff --git a/loopdb/sqlc/querier.go b/loopdb/sqlc/querier.go index 26e4c0554..5f4640612 100644 --- a/loopdb/sqlc/querier.go +++ b/loopdb/sqlc/querier.go @@ -62,6 +62,7 @@ type Querier interface { InsertSwap(ctx context.Context, arg InsertSwapParams) error InsertSwapUpdate(ctx context.Context, arg InsertSwapUpdateParams) error IsStored(ctx context.Context, swapHash []byte) (bool, error) + OverrideSelectedSwapAmount(ctx context.Context, arg OverrideSelectedSwapAmountParams) error OverrideSwapCosts(ctx context.Context, arg OverrideSwapCostsParams) error UpdateBatch(ctx context.Context, arg UpdateBatchParams) error UpdateDeposit(ctx context.Context, arg UpdateDepositParams) error diff --git a/loopdb/sqlc/queries/static_address_loopin.sql b/loopdb/sqlc/queries/static_address_loopin.sql index 16fa9ab3a..b0202e4b6 100644 --- a/loopdb/sqlc/queries/static_address_loopin.sql +++ b/loopdb/sqlc/queries/static_address_loopin.sql @@ -95,3 +95,9 @@ SELECT EXISTS ( FROM static_address_swaps WHERE swap_hash = $1 ); + +-- name: OverrideSelectedSwapAmount :exec +UPDATE static_address_swaps +SET + selected_amount = $2 +WHERE swap_hash = $1; diff --git a/loopdb/sqlc/static_address_loopin.sql.go b/loopdb/sqlc/static_address_loopin.sql.go index d18496912..a028a119c 100644 --- a/loopdb/sqlc/static_address_loopin.sql.go +++ b/loopdb/sqlc/static_address_loopin.sql.go @@ -336,6 +336,23 @@ func (q *Queries) IsStored(ctx context.Context, swapHash []byte) (bool, error) { return exists, err } +const overrideSelectedSwapAmount = `-- name: OverrideSelectedSwapAmount :exec +UPDATE static_address_swaps +SET + selected_amount = $2 +WHERE swap_hash = $1 +` + +type OverrideSelectedSwapAmountParams struct { + SwapHash []byte + SelectedAmount int64 +} + +func (q *Queries) OverrideSelectedSwapAmount(ctx context.Context, arg OverrideSelectedSwapAmountParams) error { + _, err := q.db.ExecContext(ctx, overrideSelectedSwapAmount, arg.SwapHash, arg.SelectedAmount) + return err +} + const updateStaticAddressLoopIn = `-- name: UpdateStaticAddressLoopIn :exec UPDATE static_address_swaps SET diff --git a/staticaddr/loopin/selected_amount_migration.go b/staticaddr/loopin/selected_amount_migration.go new file mode 100644 index 000000000..fa3c6d885 --- /dev/null +++ b/staticaddr/loopin/selected_amount_migration.go @@ -0,0 +1,84 @@ +package loopin + +import ( + "context" + "fmt" + "time" + + "github.com/btcsuite/btcd/btcutil" + "github.com/lightninglabs/loop/loopdb" + "github.com/lightninglabs/loop/staticaddr/deposit" + "github.com/lightningnetwork/lnd/lntypes" +) + +const ( + // selectedAmountMigrationID is the identifier for the selected swap + // amount migration. + selectedAmountMigrationID = "selected_amount" +) + +// MigrateSelectedSwapAmount will update the selected swap amount of past swaps +// with the sum of the values of the deposits they swapped. +func MigrateSelectedSwapAmount(ctx context.Context, db loopdb.SwapStore, + depositStore *deposit.SqlStore, swapStore *SqlStore) error { + + migrationDone, err := db.HasMigration(ctx, selectedAmountMigrationID) + if err != nil { + return fmt.Errorf("unable to check migration status: %w", err) + } + if migrationDone { + log.Infof("Selected swap amount migration already done, " + + "skipping") + + return nil + } + + log.Infof("Starting swap amount migration") + startTs := time.Now() + defer func() { + log.Infof("Finished swap amount migration in %v", + time.Since(startTs)) + }() + + // First we'll fetch all loop out swaps from the database. + swaps, err := swapStore.GetStaticAddressLoopInSwapsByStates( + ctx, FinalStates, + ) + if err != nil { + return err + } + + // Now we'll calculate the cost for each swap and finally update the + // costs in the database. + // TODO(hieblmi): normalize swap hash and deposit ids. + updateAmounts := make(map[lntypes.Hash]btcutil.Amount) + for _, swap := range swaps { + for _, outpoint := range swap.DepositOutpoints { + deposit, err := depositStore.DepositForOutpoint( + ctx, outpoint, + ) + if err != nil { + return fmt.Errorf("unable to fetch deposit "+ + "for outpoint %s: %w", outpoint, err) + } + if deposit == nil { + return fmt.Errorf("deposit for outpoint %s "+ + "not found", outpoint) + } + + // Set the selected amount to the value of the deposit. + updateAmounts[swap.SwapHash] += deposit.Value + } + } + + log.Infof("Updating selected swap amounts for %d loop out swaps", + len(updateAmounts)) + + err = swapStore.BatchUpdateSelectedSwapAmounts(ctx, updateAmounts) + if err != nil { + return err + } + + // Finally mark the migration as done. + return db.SetMigration(ctx, selectedAmountMigrationID) +} diff --git a/staticaddr/loopin/selected_amount_migration_test.go b/staticaddr/loopin/selected_amount_migration_test.go new file mode 100644 index 000000000..4796b230e --- /dev/null +++ b/staticaddr/loopin/selected_amount_migration_test.go @@ -0,0 +1,106 @@ +package loopin + +import ( + "context" + "testing" + "time" + + "github.com/btcsuite/btcd/btcutil" + "github.com/btcsuite/btcd/chaincfg" + "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/btcsuite/btcd/wire" + "github.com/lightninglabs/loop/loopdb" + "github.com/lightninglabs/loop/staticaddr/deposit" + "github.com/lightninglabs/loop/test" + "github.com/lightningnetwork/lnd/clock" + "github.com/lightningnetwork/lnd/lntypes" + "github.com/stretchr/testify/require" +) + +// TestMigrateSelectedSwapAmount tests the selected amount migration. +func TestMigrateSelectedSwapAmount(t *testing.T) { + // Set up test context objects. + ctxb := context.Background() + testDb := loopdb.NewTestDB(t) + testClock := clock.NewTestClock(time.Now()) + defer testDb.Close() + + db := loopdb.NewStoreMock(t) + depositStore := deposit.NewSqlStore(testDb.BaseDB) + swapStore := NewSqlStore( + loopdb.NewTypedStore[Querier](testDb), testClock, + &chaincfg.MainNetParams, + ) + + newID := func() deposit.ID { + did, err := deposit.GetRandomDepositID() + require.NoError(t, err) + + return did + } + + d1, d2 := &deposit.Deposit{ + ID: newID(), + OutPoint: wire.OutPoint{ + Hash: chainhash.Hash{0x1a, 0x2b, 0x3c, 0x4d}, + Index: 0, + }, + Value: btcutil.Amount(100_000), + TimeOutSweepPkScript: []byte{ + 0x00, 0x14, 0x1a, 0x2b, 0x3c, 0x41, + }, + }, + &deposit.Deposit{ + ID: newID(), + OutPoint: wire.OutPoint{ + Hash: chainhash.Hash{0x2a, 0x2b, 0x3c, 0x4e}, + Index: 1, + }, + Value: btcutil.Amount(200_000), + TimeOutSweepPkScript: []byte{ + 0x00, 0x14, 0x1a, 0x2b, 0x3c, 0x4d, + }, + } + + err := depositStore.CreateDeposit(ctxb, d1) + require.NoError(t, err) + err = depositStore.CreateDeposit(ctxb, d2) + require.NoError(t, err) + + outpoints := []string{ + d1.OutPoint.String(), + d2.OutPoint.String(), + } + _, clientPubKey := test.CreateKey(1) + _, serverPubKey := test.CreateKey(2) + p2wkhAddr := "bcrt1qq68r6ff4k4pjx39efs44gcyccf7unqnu5qtjjz" + addr, err := btcutil.DecodeAddress(p2wkhAddr, nil) + require.NoError(t, err) + + swap := StaticAddressLoopIn{ + SwapHash: lntypes.Hash{0x1, 0x2, 0x3, 0x4}, + DepositOutpoints: outpoints, + ClientPubkey: clientPubKey, + ServerPubkey: serverPubKey, + HtlcTimeoutSweepAddress: addr, + } + swap.SetState(Succeeded) + + err = swapStore.CreateLoopIn(ctxb, &swap) + require.NoError(t, err) + + storedSwaps, err := swapStore.GetStaticAddressLoopInSwapsByStates( + ctxb, FinalStates, + ) + require.NoError(t, err) + require.EqualValues(t, 0, storedSwaps[0].SelectedAmount) + + err = MigrateSelectedSwapAmount(ctxb, db, depositStore, swapStore) + require.NoError(t, err) + + storedSwaps, err = swapStore.GetStaticAddressLoopInSwapsByStates( + ctxb, FinalStates, + ) + require.NoError(t, err) + require.EqualValues(t, d1.Value+d2.Value, storedSwaps[0].SelectedAmount) +} diff --git a/staticaddr/loopin/sql_store.go b/staticaddr/loopin/sql_store.go index 122aaa594..6807b59e9 100644 --- a/staticaddr/loopin/sql_store.go +++ b/staticaddr/loopin/sql_store.go @@ -20,7 +20,7 @@ import ( "github.com/lightningnetwork/lnd/lnwallet/chainfee" ) -const outpointSeparator = ";" +const OutpointSeparator = ";" var ( // ErrInvalidOutpoint is returned when an outpoint contains the outpoint @@ -68,6 +68,11 @@ type Querier interface { // IsStored returns true if a swap with the given hash is stored in the // database, false otherwise. IsStored(ctx context.Context, swapHash []byte) (bool, error) + + // OverrideSelectedSwapAmount updates the selected swap amount for + // a given swap hash. + OverrideSelectedSwapAmount(ctx context.Context, + params sqlc.OverrideSelectedSwapAmountParams) error } // BaseDB is the interface that contains all the queries generated by sqlc for @@ -218,13 +223,13 @@ func (s *SqlStore) CreateLoopIn(ctx context.Context, // If so, we reject the loop-in to prevent potential issues with // parsing. for _, outpoint := range loopIn.DepositOutpoints { - if strings.Contains(outpoint, outpointSeparator) { + if strings.Contains(outpoint, OutpointSeparator) { return ErrInvalidOutpoint } } joinedOutpoints := strings.Join( - loopIn.DepositOutpoints, outpointSeparator, + loopIn.DepositOutpoints, OutpointSeparator, ) staticAddressLoopInParams := sqlc.InsertStaticAddressLoopInParams{ SwapHash: loopIn.SwapHash[:], @@ -303,6 +308,27 @@ func (s *SqlStore) UpdateLoopIn(ctx context.Context, ) } +func (s *SqlStore) BatchUpdateSelectedSwapAmounts(ctx context.Context, + updateAmounts map[lntypes.Hash]btcutil.Amount) error { + + return s.baseDB.ExecTx(ctx, loopdb.NewSqlWriteOpts(), + func(q Querier) error { + for swapHash, amount := range updateAmounts { + err := q.OverrideSelectedSwapAmount( + ctx, sqlc.OverrideSelectedSwapAmountParams{ + SwapHash: swapHash[:], + SelectedAmount: int64(amount), + }, + ) + if err != nil { + return err + } + } + + return nil + }) +} + // IsStored returns true if a swap with the given hash is stored in the // database, false otherwise. func (s *SqlStore) IsStored(ctx context.Context, swapHash lntypes.Hash) (bool, @@ -347,7 +373,7 @@ func toStaticAddressLoopIn(_ context.Context, network *chaincfg.Params, } depositOutpoints := strings.Split( - row.DepositOutpoints, outpointSeparator, + row.DepositOutpoints, OutpointSeparator, ) timeoutAddressString := row.HtlcTimeoutSweepAddress From 588f4be2440684792adac789ec40327d2ac2a120 Mon Sep 17 00:00:00 2001 From: Slyghtning Date: Thu, 20 Feb 2025 15:42:24 +0100 Subject: [PATCH 12/12] loopd: fractional static address swap amount --- cmd/loop/staticaddr.go | 74 ++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 42 deletions(-) diff --git a/cmd/loop/staticaddr.go b/cmd/loop/staticaddr.go index c9e08db55..78457e8fb 100644 --- a/cmd/loop/staticaddr.go +++ b/cmd/loop/staticaddr.go @@ -477,6 +477,13 @@ var staticAddressLoopInCommand = cli.Command{ "The client can retry the swap with adjusted " + "parameters after the payment timed out.", }, + cli.IntFlag{ + Name: "amount", + Usage: "the number of satoshis that should be " + + "swapped from the selected deposits. If there" + + "is change it is sent back to the static " + + "address.", + }, lastHopFlag, labelFlag, routeHintsFlag, @@ -499,13 +506,15 @@ func staticAddressLoopIn(ctx *cli.Context) error { defer cleanup() var ( - ctxb = context.Background() - isAllSelected = ctx.IsSet("all") - isUtxoSelected = ctx.IsSet("utxo") - label = ctx.String("static-loop-in") - hints []*swapserverrpc.RouteHint - lastHop []byte - paymentTimeoutSeconds = uint32(loopin.DefaultPaymentTimeoutSeconds) + ctxb = context.Background() + isAllSelected = ctx.IsSet("all") + isUtxoSelected = ctx.IsSet("utxo") + selectedAmount = ctx.Int64("amount") + selectDepositsForQuote bool + label = ctx.String("static-loop-in") + hints []*swapserverrpc.RouteHint + lastHop []byte + paymentTimeoutSeconds = uint32(loopin.DefaultPaymentTimeoutSeconds) ) // Validate our label early so that we can fail before getting a quote. @@ -541,7 +550,9 @@ func staticAddressLoopIn(ctx *cli.Context) error { return err } - if len(depositList.FilteredDeposits) == 0 { + allDeposits := depositList.FilteredDeposits + + if len(allDeposits) == 0 { errString := fmt.Sprintf("no confirmed deposits available, "+ "deposits need at least %v confirmations", deposit.MinConfs) @@ -551,17 +562,18 @@ func staticAddressLoopIn(ctx *cli.Context) error { var depositOutpoints []string switch { - case isAllSelected == isUtxoSelected: - return errors.New("must select either all or some utxos") + case isAllSelected && isUtxoSelected: + return errors.New("cannot select all and specific utxos") case isAllSelected: - depositOutpoints = depositsToOutpoints( - depositList.FilteredDeposits, - ) + depositOutpoints = depositsToOutpoints(allDeposits) case isUtxoSelected: depositOutpoints = ctx.StringSlice("utxo") + case selectedAmount > 0: + // If only an amount is selected we will trigger coin selection. + default: return fmt.Errorf("unknown quote request") } @@ -570,11 +582,17 @@ func staticAddressLoopIn(ctx *cli.Context) error { return errors.New("duplicate outpoints detected") } + if len(depositOutpoints) == 0 && selectedAmount > 0 { + selectDepositsForQuote = true + } + quoteReq := &looprpc.QuoteRequest{ + Amt: selectedAmount, LoopInRouteHints: hints, LoopInLastHop: lastHop, Private: ctx.Bool(privateFlag.Name), DepositOutpoints: depositOutpoints, + SelectDeposits: selectDepositsForQuote, } quote, err := client.GetLoopInQuote(ctxb, quoteReq) if err != nil { @@ -583,15 +601,6 @@ func staticAddressLoopIn(ctx *cli.Context) error { limits := getInLimits(quote) - // populate the quote request with the sum of selected deposits and - // prompt the user for acceptance. - quoteReq.Amt, err = sumDeposits( - depositOutpoints, depositList.FilteredDeposits, - ) - if err != nil { - return err - } - if !(ctx.Bool("force") || ctx.Bool("f")) { err = displayInDetails(quoteReq, quote, ctx.Bool("verbose")) if err != nil { @@ -604,6 +613,7 @@ func staticAddressLoopIn(ctx *cli.Context) error { } req := &looprpc.StaticAddressLoopInRequest{ + Amount: quoteReq.Amt, Outpoints: depositOutpoints, MaxSwapFeeSatoshis: int64(limits.maxSwapFee), LastHop: lastHop, @@ -636,26 +646,6 @@ func containsDuplicates(outpoints []string) bool { return false } -func sumDeposits(outpoints []string, deposits []*looprpc.Deposit) (int64, - error) { - - var sum int64 - depositMap := make(map[string]*looprpc.Deposit) - for _, deposit := range deposits { - depositMap[deposit.Outpoint] = deposit - } - - for _, outpoint := range outpoints { - if _, ok := depositMap[outpoint]; !ok { - return 0, fmt.Errorf("deposit %v not found", outpoint) - } - - sum += depositMap[outpoint].Value - } - - return sum, nil -} - func depositsToOutpoints(deposits []*looprpc.Deposit) []string { outpoints := make([]string, 0, len(deposits)) for _, deposit := range deposits {