From afe6ce97b61b2e189d88874dd8c9c5302f7356c2 Mon Sep 17 00:00:00 2001 From: Jeremy Letang Date: Tue, 15 Oct 2024 14:20:35 +0100 Subject: [PATCH] feat: add staking staking from collateral asset - staking from general account with a transfer to the locked_for_staking account - staking from vesting and vested account, as soon as a reward is payed on the vesting account - unstaking as soon as funds are transfered back to the general account from the locked_for_staking - unstaking as soon as funds are transfered out of the vested account. Signed-off-by: Jeremy Letang --- commands/transfer_funds.go | 5 +- core/banking/engine.go | 17 +- core/banking/engine_test.go | 5 +- core/banking/mocks/mocks.go | 37 +- core/banking/oneoff_transfers.go | 62 +++ core/collateral/engine.go | 12 + core/integration/setup_test.go | 4 +- .../integration/stubs/staking_account_stub.go | 2 + core/protocol/all_services.go | 12 +- core/rewards/engine.go | 4 +- core/rewards/engine_test.go | 2 +- core/rewards/mocks/mocks.go | 8 +- core/types/collateral.go | 1 + core/vesting/engine.go | 65 ++- core/vesting/engine_test.go | 14 +- core/vesting/helper_for_test.go | 14 +- core/vesting/mocks/mocks.go | 76 +++- core/vesting/snapshot.go | 18 +- core/vesting/snapshot_test.go | 20 +- datanode/gateway/graphql/schema.graphql | 2 + protos/sources/vega/vega.proto | 3 + protos/vega/vega.pb.go | 406 +++++++++--------- 22 files changed, 550 insertions(+), 239 deletions(-) diff --git a/commands/transfer_funds.go b/commands/transfer_funds.go index 43e66a632d0..9b5697653c6 100644 --- a/commands/transfer_funds.go +++ b/commands/transfer_funds.go @@ -74,7 +74,8 @@ func checkTransfer(cmd *commandspb.Transfer) (e Errors) { } if cmd.FromAccountType != vega.AccountType_ACCOUNT_TYPE_GENERAL && - cmd.FromAccountType != vega.AccountType_ACCOUNT_TYPE_VESTED_REWARDS { + cmd.FromAccountType != vega.AccountType_ACCOUNT_TYPE_VESTED_REWARDS && + cmd.FromAccountType != vega.AccountType_ACCOUNT_TYPE_LOCKED_FOR_STAKING { errs.AddForProperty("transfer.from_account_type", ErrIsNotValid) } @@ -109,7 +110,7 @@ func checkTransfer(cmd *commandspb.Transfer) (e Errors) { } else { switch k := cmd.Kind.(type) { case *commandspb.Transfer_OneOff: - if cmd.ToAccountType != vega.AccountType_ACCOUNT_TYPE_GLOBAL_REWARD && cmd.ToAccountType != vega.AccountType_ACCOUNT_TYPE_GENERAL && cmd.ToAccountType != vega.AccountType_ACCOUNT_TYPE_UNSPECIFIED && cmd.ToAccountType != vega.AccountType_ACCOUNT_TYPE_NETWORK_TREASURY && cmd.ToAccountType != vega.AccountType_ACCOUNT_TYPE_BUY_BACK_FEES { + if cmd.ToAccountType != vega.AccountType_ACCOUNT_TYPE_GLOBAL_REWARD && cmd.ToAccountType != vega.AccountType_ACCOUNT_TYPE_GENERAL && cmd.ToAccountType != vega.AccountType_ACCOUNT_TYPE_UNSPECIFIED && cmd.ToAccountType != vega.AccountType_ACCOUNT_TYPE_NETWORK_TREASURY && cmd.ToAccountType != vega.AccountType_ACCOUNT_TYPE_BUY_BACK_FEES && cmd.ToAccountType != vega.AccountType_ACCOUNT_TYPE_LOCKED_FOR_STAKING { errs.AddForProperty("transfer.to_account_type", errors.New("account type is not valid for one off transfer")) } if k.OneOff.GetDeliverOn() < 0 { diff --git a/core/banking/engine.go b/core/banking/engine.go index f9567b69997..318c1bdae50 100644 --- a/core/banking/engine.go +++ b/core/banking/engine.go @@ -40,7 +40,7 @@ import ( "golang.org/x/exp/maps" ) -//go:generate go run github.com/golang/mock/mockgen -destination mocks/mocks.go -package mocks code.vegaprotocol.io/vega/core/banking Assets,Notary,Collateral,Witness,TimeService,EpochService,Topology,MarketActivityTracker,ERC20BridgeView,EthereumEventSource,Parties +//go:generate go run github.com/golang/mock/mockgen -destination mocks/mocks.go -package mocks code.vegaprotocol.io/vega/core/banking Assets,Notary,Collateral,Witness,TimeService,EpochService,Topology,MarketActivityTracker,ERC20BridgeView,EthereumEventSource,Parties,StakeAccounting var ( ErrWrongAssetTypeUsedInBuiltinAssetChainEvent = errors.New("non builtin asset used for builtin asset chain event") @@ -106,6 +106,11 @@ type Topology interface { IsValidator() bool } +// StakeAccounting ... +type StakeAccounting interface { + AddEvent(ctx context.Context, evt *types.StakeLinking) +} + type MarketActivityTracker interface { CalculateMetricForIndividuals(ctx context.Context, ds *vega.DispatchStrategy) []*types.PartyContributionScore CalculateMetricForTeams(ctx context.Context, ds *vega.DispatchStrategy) ([]*types.PartyContributionScore, map[string][]*types.PartyContributionScore) @@ -223,6 +228,9 @@ type Engine struct { // transient cache used to market a dispatch strategy as checked for eligibility for this round so we don't check again. dispatchRequiredCache map[string]bool + + stakingAsset string + stakeAccounting StakeAccounting } type withdrawalRef struct { @@ -244,6 +252,7 @@ func New(log *logging.Logger, secondaryBridgeView ERC20BridgeView, ethEventSource EthereumEventSource, parties Parties, + stakeAccounting StakeAccounting, ) (e *Engine) { log = log.Named(namedLogger) log.SetLevel(cfg.Level.Get()) @@ -290,9 +299,15 @@ func New(log *logging.Logger, primaryBridgeView: primaryBridgeView, secondaryBridgeView: secondaryBridgeView, dispatchRequiredCache: map[string]bool{}, + stakeAccounting: stakeAccounting, } } +func (e *Engine) OnStakingAsset(_ context.Context, a string) error { + e.stakingAsset = a + return nil +} + func (e *Engine) OnMaxFractionChanged(ctx context.Context, f num.Decimal) error { e.maxGovTransferFraction = f return nil diff --git a/core/banking/engine_test.go b/core/banking/engine_test.go index a2d14c00abd..8d822c55c4f 100644 --- a/core/banking/engine_test.go +++ b/core/banking/engine_test.go @@ -56,6 +56,7 @@ type testEngine struct { ethSource *mocks.MockEthereumEventSource secondaryBridgeView *mocks.MockERC20BridgeView parties *mocks.MockParties + stakeAccounting *mocks.MockStakeAccounting } func getTestEngine(t *testing.T) *testEngine { @@ -73,6 +74,7 @@ func getTestEngine(t *testing.T) *testEngine { broker := bmocks.NewMockBroker(ctrl) top := mocks.NewMockTopology(ctrl) epoch := mocks.NewMockEpochService(ctrl) + stakeAccounting := mocks.NewMockStakeAccounting(ctrl) primaryBridgeView := mocks.NewMockERC20BridgeView(ctrl) secondaryBridgeView := mocks.NewMockERC20BridgeView(ctrl) marketActivityTracker := mocks.NewMockMarketActivityTracker(ctrl) @@ -82,7 +84,7 @@ func getTestEngine(t *testing.T) *testEngine { notary.EXPECT().OfferSignatures(gomock.Any(), gomock.Any()).AnyTimes() epoch.EXPECT().NotifyOnEpoch(gomock.Any(), gomock.Any()).AnyTimes() parties := mocks.NewMockParties(ctrl) - eng := banking.New(logging.NewTestLogger(), banking.NewDefaultConfig(), col, witness, tsvc, assets, notary, broker, top, marketActivityTracker, primaryBridgeView, secondaryBridgeView, ethSource, parties) + eng := banking.New(logging.NewTestLogger(), banking.NewDefaultConfig(), col, witness, tsvc, assets, notary, broker, top, marketActivityTracker, primaryBridgeView, secondaryBridgeView, ethSource, parties, stakeAccounting) require.NoError(t, eng.OnMaxQuantumAmountUpdate(context.Background(), num.DecimalOne())) eng.OnPrimaryEthChainIDUpdated("1", "hello") @@ -103,6 +105,7 @@ func getTestEngine(t *testing.T) *testEngine { marketActivityTracker: marketActivityTracker, ethSource: ethSource, parties: parties, + stakeAccounting: stakeAccounting, } } diff --git a/core/banking/mocks/mocks.go b/core/banking/mocks/mocks.go index 1ba00cf6c38..edbdd08013e 100644 --- a/core/banking/mocks/mocks.go +++ b/core/banking/mocks/mocks.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: code.vegaprotocol.io/vega/core/banking (interfaces: Assets,Notary,Collateral,Witness,TimeService,EpochService,Topology,MarketActivityTracker,ERC20BridgeView,EthereumEventSource,Parties) +// Source: code.vegaprotocol.io/vega/core/banking (interfaces: Assets,Notary,Collateral,Witness,TimeService,EpochService,Topology,MarketActivityTracker,ERC20BridgeView,EthereumEventSource,Parties,StakeAccounting) // Package mocks is a generated GoMock package. package mocks @@ -784,3 +784,38 @@ func (mr *MockPartiesMockRecorder) CheckDerivedKeyOwnership(arg0, arg1 interface mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckDerivedKeyOwnership", reflect.TypeOf((*MockParties)(nil).CheckDerivedKeyOwnership), arg0, arg1) } + +// MockStakeAccounting is a mock of StakeAccounting interface. +type MockStakeAccounting struct { + ctrl *gomock.Controller + recorder *MockStakeAccountingMockRecorder +} + +// MockStakeAccountingMockRecorder is the mock recorder for MockStakeAccounting. +type MockStakeAccountingMockRecorder struct { + mock *MockStakeAccounting +} + +// NewMockStakeAccounting creates a new mock instance. +func NewMockStakeAccounting(ctrl *gomock.Controller) *MockStakeAccounting { + mock := &MockStakeAccounting{ctrl: ctrl} + mock.recorder = &MockStakeAccountingMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockStakeAccounting) EXPECT() *MockStakeAccountingMockRecorder { + return m.recorder +} + +// AddEvent mocks base method. +func (m *MockStakeAccounting) AddEvent(arg0 context.Context, arg1 *types.StakeLinking) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddEvent", arg0, arg1) +} + +// AddEvent indicates an expected call of AddEvent. +func (mr *MockStakeAccountingMockRecorder) AddEvent(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddEvent", reflect.TypeOf((*MockStakeAccounting)(nil).AddEvent), arg0, arg1) +} diff --git a/core/banking/oneoff_transfers.go b/core/banking/oneoff_transfers.go index 1e8d1c58cef..9531c506610 100644 --- a/core/banking/oneoff_transfers.go +++ b/core/banking/oneoff_transfers.go @@ -24,6 +24,8 @@ import ( "code.vegaprotocol.io/vega/core/events" "code.vegaprotocol.io/vega/core/types" + vgcontext "code.vegaprotocol.io/vega/libs/context" + "code.vegaprotocol.io/vega/libs/crypto" "code.vegaprotocol.io/vega/logging" checkpoint "code.vegaprotocol.io/vega/protos/vega/checkpoint/v1" ) @@ -61,6 +63,65 @@ func scheduledTransferFromProto(p *checkpoint.ScheduledTransfer) (scheduledTrans }, nil } +func (e *Engine) updateStakingAccounts( + ctx context.Context, transfer *types.OneOffTransfer, +) { + if transfer.Asset != e.stakingAsset { + // nothing to do + return + } + + var ( + now = e.timeService.GetTimeNow().Unix() + height, _ = vgcontext.BlockHeightFromContext(ctx) + txhash, _ = vgcontext.TxHashFromContext(ctx) + id = crypto.HashStrToHex(fmt.Sprintf("%v%v", txhash, height)) + stakeLinking *types.StakeLinking + ) + + // manually send funds from the general account to the locked for staking + if transfer.FromAccountType == types.AccountTypeGeneral && transfer.ToAccountType == types.AccountTypeLockedForStaking { + stakeLinking = &types.StakeLinking{ + ID: id, + Type: types.StakeLinkingTypeDeposited, + TS: now, + Party: transfer.From, + Amount: transfer.Amount.Clone(), + Status: types.StakeLinkingStatusAccepted, + FinalizedAt: now, + TxHash: txhash, + BlockHeight: height, + BlockTime: now, + LogIndex: 1, + EthereumAddress: transfer.From, + } + } + + // from staking account or vested rewards, we send a remove event + if (transfer.FromAccountType == types.AccountTypeLockedForStaking && transfer.ToAccountType == types.AccountTypeGeneral) || + (transfer.FromAccountType == types.AccountTypeVestedRewards && transfer.ToAccountType == types.AccountTypeGeneral) { + stakeLinking = &types.StakeLinking{ + ID: id, + Type: types.StakeLinkingTypeRemoved, + TS: now, + Party: transfer.From, + Amount: transfer.Amount.Clone(), + Status: types.StakeLinkingStatusAccepted, + FinalizedAt: now, + TxHash: txhash, + BlockHeight: height, + BlockTime: now, + LogIndex: 1, + EthereumAddress: transfer.From, + } + } + + if stakeLinking != nil { + e.stakeAccounting.AddEvent(ctx, stakeLinking) + e.broker.Send(events.NewStakeLinking(ctx, *stakeLinking)) + } +} + func (e *Engine) oneOffTransfer( ctx context.Context, transfer *types.OneOffTransfer, @@ -70,6 +131,7 @@ func (e *Engine) oneOffTransfer( e.broker.Send(events.NewOneOffTransferFundsEventWithReason(ctx, transfer, err.Error())) } else { e.broker.Send(events.NewOneOffTransferFundsEvent(ctx, transfer)) + e.updateStakingAccounts(ctx, transfer) } }() diff --git a/core/collateral/engine.go b/core/collateral/engine.go index 298133c20ee..655fa042228 100644 --- a/core/collateral/engine.go +++ b/core/collateral/engine.go @@ -356,6 +356,18 @@ func (e *Engine) GetAllVestingQuantumBalance(party string) num.Decimal { return balance } +func (e *Engine) GetAllVestingAndVestedAccountForAsset(asset string) []*types.Account { + accs := []*types.Account{} + + for _, v := range e.hashableAccs { + if v.Asset == asset && (v.Type == types.AccountTypeVestingRewards || v.Type == types.AccountTypeVestedRewards) { + accs = append(accs, v.Clone()) + } + } + + return accs +} + func (e *Engine) GetVestingRecovery() map[string]map[string]*num.Uint { out := e.vesting e.vesting = map[string]map[string]*num.Uint{} diff --git a/core/integration/setup_test.go b/core/integration/setup_test.go index 601e44a92e7..a2164c0fdc4 100644 --- a/core/integration/setup_test.go +++ b/core/integration/setup_test.go @@ -202,7 +202,7 @@ func newExecutionTestSetup() *executionTestSetup { execsetup.epochEngine.NotifyOnEpoch(execsetup.volumeDiscountProgram.OnEpoch, execsetup.volumeDiscountProgram.OnEpochRestore) execsetup.volumeRebateProgram = volumerebate.New(execsetup.broker, execsetup.marketActivityTracker) - execsetup.banking = banking.New(execsetup.log, banking.NewDefaultConfig(), execsetup.collateralEngine, execsetup.witness, execsetup.timeService, execsetup.assetsEngine, execsetup.notary, execsetup.broker, execsetup.topology, execsetup.marketActivityTracker, stubs.NewBridgeViewStub(), stubs.NewBridgeViewStub(), eventHeartbeat, execsetup.profilesEngine) + execsetup.banking = banking.New(execsetup.log, banking.NewDefaultConfig(), execsetup.collateralEngine, execsetup.witness, execsetup.timeService, execsetup.assetsEngine, execsetup.notary, execsetup.broker, execsetup.topology, execsetup.marketActivityTracker, stubs.NewBridgeViewStub(), stubs.NewBridgeViewStub(), eventHeartbeat, execsetup.profilesEngine, execsetup.stakingAccount) execsetup.executionEngine = newExEng( execution.NewEngine( @@ -233,7 +233,7 @@ func newExecutionTestSetup() *executionTestSetup { execsetup.activityStreak = activitystreak.New(execsetup.log, execsetup.executionEngine, execsetup.broker) execsetup.epochEngine.NotifyOnEpoch(execsetup.activityStreak.OnEpochEvent, execsetup.activityStreak.OnEpochRestore) - execsetup.vesting = vesting.New(execsetup.log, execsetup.collateralEngine, execsetup.activityStreak, execsetup.broker, execsetup.assetsEngine, execsetup.profilesEngine) + execsetup.vesting = vesting.New(execsetup.log, execsetup.collateralEngine, execsetup.activityStreak, execsetup.broker, execsetup.assetsEngine, execsetup.profilesEngine, execsetup.timeService) execsetup.rewardsEngine = rewards.New(execsetup.log, rewards.NewDefaultConfig(), execsetup.broker, execsetup.delegationEngine, execsetup.epochEngine, execsetup.collateralEngine, execsetup.timeService, execsetup.marketActivityTracker, execsetup.topology, execsetup.vesting, execsetup.banking, execsetup.activityStreak) // register this after the rewards engine is created to make sure the on epoch is called in the right order. diff --git a/core/integration/stubs/staking_account_stub.go b/core/integration/stubs/staking_account_stub.go index 21d6c084e84..f8833cb5619 100644 --- a/core/integration/stubs/staking_account_stub.go +++ b/core/integration/stubs/staking_account_stub.go @@ -32,6 +32,8 @@ type StakingAccountStub struct { currentEpoch *types.Epoch } +func (t *StakingAccountStub) AddEvent(ctx context.Context, evt *types.StakeLinking) {} + func (t *StakingAccountStub) OnEpochEvent(ctx context.Context, epoch types.Epoch) { if t.currentEpoch == nil || t.currentEpoch.Seq != epoch.Seq { t.currentEpoch = &epoch diff --git a/core/protocol/all_services.go b/core/protocol/all_services.go index e4a3f79fe92..64695e4a8e0 100644 --- a/core/protocol/all_services.go +++ b/core/protocol/all_services.go @@ -340,7 +340,7 @@ func newServices( svcs.volumeRebate = volumerebate.NewSnapshottedEngine(svcs.broker, svcs.marketActivityTracker) svcs.banking = banking.New(svcs.log, svcs.conf.Banking, svcs.collateral, svcs.witness, svcs.timeService, svcs.assets, svcs.notary, svcs.broker, svcs.topology, svcs.marketActivityTracker, svcs.primaryBridgeView, - svcs.secondaryBridgeView, svcs.forwarderHeartbeat, svcs.partiesEngine) + svcs.secondaryBridgeView, svcs.forwarderHeartbeat, svcs.partiesEngine, svcs.stakingAccounts) // instantiate the execution engine svcs.executionEngine = execution.NewEngine( @@ -392,7 +392,7 @@ func newServices( svcs.activityStreak.OnEpochRestore, ) - svcs.vesting = vesting.NewSnapshotEngine(svcs.log, svcs.collateral, svcs.activityStreak, svcs.broker, svcs.assets, svcs.partiesEngine) + svcs.vesting = vesting.NewSnapshotEngine(svcs.log, svcs.collateral, svcs.activityStreak, svcs.broker, svcs.assets, svcs.partiesEngine, svcs.timeService) svcs.timeService.NotifyOnTick(svcs.vesting.OnTick) svcs.rewards = rewards.New(svcs.log, svcs.conf.Rewards, svcs.broker, svcs.delegation, svcs.epochService, svcs.collateral, svcs.timeService, svcs.marketActivityTracker, svcs.topology, svcs.vesting, svcs.banking, svcs.activityStreak) @@ -673,6 +673,14 @@ func (svcs *allServices) setupNetParameters(powWatchers []netparams.WatchParam) } watchers := []netparams.WatchParam{ + { + Param: netparams.RewardAsset, + Watcher: svcs.banking.OnStakingAsset, + }, + { + Param: netparams.RewardAsset, + Watcher: svcs.vesting.OnStakingAssetUpdate, + }, { Param: netparams.SpamProtectionBalanceSnapshotFrequency, Watcher: svcs.collateral.OnBalanceSnapshotFrequencyUpdated, diff --git a/core/rewards/engine.go b/core/rewards/engine.go index 1270a6e3e25..257ce8b7e5e 100644 --- a/core/rewards/engine.go +++ b/core/rewards/engine.go @@ -89,7 +89,7 @@ type Teams interface { } type Vesting interface { - AddReward(party, asset string, amount *num.Uint, lockedForEpochs uint64) + AddReward(ctx context.Context, party, asset string, amount *num.Uint, lockedForEpochs uint64) GetSingleAndSummedRewardBonusMultipliers(party string) (vesting.MultiplierAndQuantBalance, vesting.MultiplierAndQuantBalance) } @@ -492,7 +492,7 @@ func (e *Engine) distributePayout(ctx context.Context, po *payout) { if po.rewardType != types.AccountTypeFeesInfrastructure { for _, party := range partyIDs { amt := po.partyToAmount[party] - e.vesting.AddReward(party, po.asset, amt, po.lockedForEpochs) + e.vesting.AddReward(ctx, party, po.asset, amt, po.lockedForEpochs) } } e.broker.Send(events.NewLedgerMovements(ctx, responses)) diff --git a/core/rewards/engine_test.go b/core/rewards/engine_test.go index 152e0dfce8b..570c5f683df 100644 --- a/core/rewards/engine_test.go +++ b/core/rewards/engine_test.go @@ -450,7 +450,7 @@ func getEngine(t *testing.T) *testEngine { topology := mocks.NewMockTopology(ctrl) marketActivityTracker := mocks.NewMockMarketActivityTracker(ctrl) vesting := mocks.NewMockVesting(ctrl) - vesting.EXPECT().AddReward(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() + vesting.EXPECT().AddReward(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() transfers := mocks.NewMockTransfers(ctrl) activityStreak := mocks.NewMockActivityStreak(ctrl) engine := New(logger, conf, broker, delegation, epochEngine, collateralEng, ts, marketActivityTracker, topology, vesting, transfers, activityStreak) diff --git a/core/rewards/mocks/mocks.go b/core/rewards/mocks/mocks.go index f6b1c4a7d34..efad8c301e6 100644 --- a/core/rewards/mocks/mocks.go +++ b/core/rewards/mocks/mocks.go @@ -363,15 +363,15 @@ func (m *MockVesting) EXPECT() *MockVestingMockRecorder { } // AddReward mocks base method. -func (m *MockVesting) AddReward(arg0, arg1 string, arg2 *num.Uint, arg3 uint64) { +func (m *MockVesting) AddReward(arg0 context.Context, arg1, arg2 string, arg3 *num.Uint, arg4 uint64) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddReward", arg0, arg1, arg2, arg3) + m.ctrl.Call(m, "AddReward", arg0, arg1, arg2, arg3, arg4) } // AddReward indicates an expected call of AddReward. -func (mr *MockVestingMockRecorder) AddReward(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockVestingMockRecorder) AddReward(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddReward", reflect.TypeOf((*MockVesting)(nil).AddReward), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddReward", reflect.TypeOf((*MockVesting)(nil).AddReward), arg0, arg1, arg2, arg3, arg4) } // GetSingleAndSummedRewardBonusMultipliers mocks base method. diff --git a/core/types/collateral.go b/core/types/collateral.go index fb0ad84bb7d..d69bebeb304 100644 --- a/core/types/collateral.go +++ b/core/types/collateral.go @@ -325,4 +325,5 @@ const ( AccountTypeBuyBackFees AccountType = proto.AccountType_ACCOUNT_TYPE_BUY_BACK_FEES // Account for eligible entities rewards. AccountTypeEligibleEntitiesReward = proto.AccountType_ACCOUNT_TYPE_REWARD_ELIGIBLE_ENTITIES + AccountTypeLockedForStaking = proto.AccountType_ACCOUNT_TYPE_LOCKED_FOR_STAKING ) diff --git a/core/vesting/engine.go b/core/vesting/engine.go index fd5cdd34ad3..e817da676c7 100644 --- a/core/vesting/engine.go +++ b/core/vesting/engine.go @@ -24,6 +24,8 @@ import ( "code.vegaprotocol.io/vega/core/assets" "code.vegaprotocol.io/vega/core/events" "code.vegaprotocol.io/vega/core/types" + vgcontext "code.vegaprotocol.io/vega/libs/context" + "code.vegaprotocol.io/vega/libs/crypto" "code.vegaprotocol.io/vega/libs/num" "code.vegaprotocol.io/vega/logging" proto "code.vegaprotocol.io/vega/protos/vega" @@ -33,12 +35,13 @@ import ( "golang.org/x/exp/slices" ) -//go:generate go run github.com/golang/mock/mockgen -destination mocks/mocks.go -package mocks code.vegaprotocol.io/vega/core/vesting ActivityStreakVestingMultiplier,Assets,Parties +//go:generate go run github.com/golang/mock/mockgen -destination mocks/mocks.go -package mocks code.vegaprotocol.io/vega/core/vesting ActivityStreakVestingMultiplier,Assets,Parties,StakeAccounting,Time type Collateral interface { TransferVestedRewards(ctx context.Context, transfers []*types.Transfer) ([]*types.LedgerMovement, error) GetVestingRecovery() map[string]map[string]*num.Uint GetAllVestingQuantumBalance(party string) num.Decimal + GetAllVestingAndVestedAccountForAsset(asset string) []*types.Account } type ActivityStreakVestingMultiplier interface { @@ -47,6 +50,7 @@ type ActivityStreakVestingMultiplier interface { type Broker interface { Send(events events.Event) + Stage(event events.Event) } type Assets interface { @@ -57,6 +61,14 @@ type Parties interface { RelatedKeys(key string) (*types.PartyID, []string) } +type StakeAccounting interface { + AddEvent(ctx context.Context, evt *types.StakeLinking) +} + +type Time interface { + GetTimeNow() time.Time +} + type PartyRewards struct { // the amounts per assets still being locked in the // account and not available to be released @@ -93,6 +105,11 @@ type Engine struct { // cache the reward bonus multiplier and quantum balance rewardBonusMultiplierCache map[string]MultiplierAndQuantBalance + + stakingAsset string + stakeAccounting StakeAccounting + + t Time } func New( @@ -102,6 +119,7 @@ func New( broker Broker, assets Assets, parties Parties, + t Time, ) *Engine { log = log.Named(namedLogger) @@ -114,6 +132,7 @@ func New( parties: parties, state: map[string]*PartyRewards{}, rewardBonusMultiplierCache: map[string]MultiplierAndQuantBalance{}, + t: t, } } @@ -139,6 +158,11 @@ func (e *Engine) OnBenefitTiersUpdate(_ context.Context, v interface{}) error { return nil } +func (e *Engine) OnStakingAssetUpdate(_ context.Context, stakingAsset string) error { + e.stakingAsset = stakingAsset + return nil +} + func (e *Engine) OnRewardVestingBaseRateUpdate(_ context.Context, baseRate num.Decimal) error { e.baseRate = baseRate return nil @@ -165,11 +189,50 @@ func (e *Engine) OnEpochRestore(_ context.Context, epoch types.Epoch) { e.epochSeq = epoch.Seq } +func (e *Engine) updateStakingAccount( + ctx context.Context, + party string, + amount *num.Uint, + logIndex uint64, + brokerFunc func(events.Event), +) { + var ( + now = e.t.GetTimeNow().Unix() + height, _ = vgcontext.BlockHeightFromContext(ctx) + txhash, _ = vgcontext.TxHashFromContext(ctx) + id = crypto.HashStrToHex(fmt.Sprintf("%v%v%v", party, txhash, height)) + ) + + stakeLinking := &types.StakeLinking{ + ID: id, + Type: types.StakeLinkingTypeDeposited, + TS: now, + Party: party, + Amount: amount, + Status: types.StakeLinkingStatusAccepted, + FinalizedAt: now, + TxHash: txhash, + BlockHeight: height, + BlockTime: now, + LogIndex: logIndex, + EthereumAddress: party, + } + + e.stakeAccounting.AddEvent(context.Background(), stakeLinking) + brokerFunc(events.NewStakeLinking(ctx, *stakeLinking)) +} + func (e *Engine) AddReward( + ctx context.Context, party, asset string, amount *num.Uint, lockedForEpochs uint64, ) { + // send to staking + if asset == e.stakingAsset { + e.updateStakingAccount(ctx, party, amount.Clone(), 1, e.broker.Send) + } + // no locktime, just increase the amount in vesting if lockedForEpochs == 0 { e.increaseVestingBalance(party, asset, amount) diff --git a/core/vesting/engine_test.go b/core/vesting/engine_test.go index b4f664b3f7f..f6dbe22eeee 100644 --- a/core/vesting/engine_test.go +++ b/core/vesting/engine_test.go @@ -98,7 +98,7 @@ func TestDistributeAfterDelay(t *testing.T) { }) t.Run("Add a reward locked for 3 epochs", func(t *testing.T) { - v.AddReward(party, vegaAsset, num.NewUint(100), 3) + v.AddReward(context.Background(), party, vegaAsset, num.NewUint(100), 3) }) t.Run("Wait for 3 epochs", func(t *testing.T) { @@ -332,7 +332,7 @@ func TestDistributeWithNoDelay(t *testing.T) { }) t.Run("Add a reward without epoch lock", func(t *testing.T) { - v.AddReward(party, vegaAsset, num.NewUint(100), 0) + v.AddReward(context.Background(), party, vegaAsset, num.NewUint(100), 0) }) t.Run("First reward payment", func(t *testing.T) { @@ -514,7 +514,7 @@ func TestDistributeWithStreakRate(t *testing.T) { }) t.Run("Add a reward without epoch lock", func(t *testing.T) { - v.AddReward(party, vegaAsset, num.NewUint(100), 0) + v.AddReward(context.Background(), party, vegaAsset, num.NewUint(100), 0) }) t.Run("First reward payment", func(t *testing.T) { @@ -696,11 +696,11 @@ func TestDistributeMultipleAfterDelay(t *testing.T) { }) t.Run("Add a reward locked for 2 epochs", func(t *testing.T) { - v.AddReward(party, vegaAsset, num.NewUint(100), 2) + v.AddReward(context.Background(), party, vegaAsset, num.NewUint(100), 2) }) t.Run("Add another reward locked for 1 epoch", func(t *testing.T) { - v.AddReward(party, vegaAsset, num.NewUint(100), 1) + v.AddReward(context.Background(), party, vegaAsset, num.NewUint(100), 1) }) t.Run("Wait for 1 epoch", func(t *testing.T) { @@ -1046,10 +1046,10 @@ func TestDistributeWithRelatedKeys(t *testing.T) { }) t.Run("Add a reward without epoch lock", func(t *testing.T) { - v.AddReward(party, vegaAsset, num.NewUint(100), 0) + v.AddReward(context.Background(), party, vegaAsset, num.NewUint(100), 0) for _, key := range derivedKeys { - v.AddReward(key, vegaAsset, num.NewUint(50), 0) + v.AddReward(context.Background(), key, vegaAsset, num.NewUint(50), 0) } }) diff --git a/core/vesting/helper_for_test.go b/core/vesting/helper_for_test.go index 8572c0cc342..44c6bfd0fe6 100644 --- a/core/vesting/helper_for_test.go +++ b/core/vesting/helper_for_test.go @@ -46,6 +46,7 @@ type testEngine struct { broker *bmocks.MockBroker assets *mocks.MockAssets parties *mocks.MockParties + t *mocks.MockTime } func getTestEngine(t *testing.T) *testEngine { @@ -57,10 +58,11 @@ func getTestEngine(t *testing.T) *testEngine { asvm := mocks.NewMockActivityStreakVestingMultiplier(ctrl) assets := mocks.NewMockAssets(ctrl) parties := mocks.NewMockParties(ctrl) + tim := mocks.NewMockTime(ctrl) return &testEngine{ Engine: vesting.New( - logger, col, asvm, broker, assets, parties, + logger, col, asvm, broker, assets, parties, tim, ), ctrl: ctrl, broker: broker, @@ -68,6 +70,7 @@ func getTestEngine(t *testing.T) *testEngine { asvm: asvm, assets: assets, parties: parties, + t: tim, } } @@ -80,6 +83,7 @@ type testSnapshotEngine struct { broker *bmocks.MockBroker assets *mocks.MockAssets parties *mocks.MockParties + t *mocks.MockTime currentEpoch uint64 } @@ -92,10 +96,11 @@ func newEngine(t *testing.T) *testSnapshotEngine { broker := bmocks.NewMockBroker(ctrl) assets := mocks.NewMockAssets(ctrl) parties := mocks.NewMockParties(ctrl) + tim := mocks.NewMockTime(ctrl) return &testSnapshotEngine{ engine: vesting.NewSnapshotEngine( - logging.NewTestLogger(), col, asvm, broker, assets, parties, + logging.NewTestLogger(), col, asvm, broker, assets, parties, tim, ), ctrl: ctrl, col: col, @@ -104,6 +109,7 @@ func newEngine(t *testing.T) *testSnapshotEngine { assets: assets, parties: parties, currentEpoch: 10, + t: tim, } } @@ -170,6 +176,10 @@ func (c *collateralMock) GetVestingQuantumBalanceCallCount() int { return c.vestingQuantumBalanceCallCount } +func (c *collateralMock) GetAllVestingAndVestedAccountForAsset(asset string) []*types.Account { + return nil +} + func newCollateralMock(t *testing.T) *collateralMock { t.Helper() diff --git a/core/vesting/mocks/mocks.go b/core/vesting/mocks/mocks.go index 2ff1049dd3f..09cef96fbf7 100644 --- a/core/vesting/mocks/mocks.go +++ b/core/vesting/mocks/mocks.go @@ -1,11 +1,13 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: code.vegaprotocol.io/vega/core/vesting (interfaces: ActivityStreakVestingMultiplier,Assets,Parties) +// Source: code.vegaprotocol.io/vega/core/vesting (interfaces: ActivityStreakVestingMultiplier,Assets,Parties,StakeAccounting,Time) // Package mocks is a generated GoMock package. package mocks import ( + context "context" reflect "reflect" + time "time" assets "code.vegaprotocol.io/vega/core/assets" types "code.vegaprotocol.io/vega/core/types" @@ -125,3 +127,75 @@ func (mr *MockPartiesMockRecorder) RelatedKeys(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RelatedKeys", reflect.TypeOf((*MockParties)(nil).RelatedKeys), arg0) } + +// MockStakeAccounting is a mock of StakeAccounting interface. +type MockStakeAccounting struct { + ctrl *gomock.Controller + recorder *MockStakeAccountingMockRecorder +} + +// MockStakeAccountingMockRecorder is the mock recorder for MockStakeAccounting. +type MockStakeAccountingMockRecorder struct { + mock *MockStakeAccounting +} + +// NewMockStakeAccounting creates a new mock instance. +func NewMockStakeAccounting(ctrl *gomock.Controller) *MockStakeAccounting { + mock := &MockStakeAccounting{ctrl: ctrl} + mock.recorder = &MockStakeAccountingMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockStakeAccounting) EXPECT() *MockStakeAccountingMockRecorder { + return m.recorder +} + +// AddEvent mocks base method. +func (m *MockStakeAccounting) AddEvent(arg0 context.Context, arg1 *types.StakeLinking) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddEvent", arg0, arg1) +} + +// AddEvent indicates an expected call of AddEvent. +func (mr *MockStakeAccountingMockRecorder) AddEvent(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddEvent", reflect.TypeOf((*MockStakeAccounting)(nil).AddEvent), arg0, arg1) +} + +// MockTime is a mock of Time interface. +type MockTime struct { + ctrl *gomock.Controller + recorder *MockTimeMockRecorder +} + +// MockTimeMockRecorder is the mock recorder for MockTime. +type MockTimeMockRecorder struct { + mock *MockTime +} + +// NewMockTime creates a new mock instance. +func NewMockTime(ctrl *gomock.Controller) *MockTime { + mock := &MockTime{ctrl: ctrl} + mock.recorder = &MockTimeMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockTime) EXPECT() *MockTimeMockRecorder { + return m.recorder +} + +// GetTimeNow mocks base method. +func (m *MockTime) GetTimeNow() time.Time { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetTimeNow") + ret0, _ := ret[0].(time.Time) + return ret0 +} + +// GetTimeNow indicates an expected call of GetTimeNow. +func (mr *MockTimeMockRecorder) GetTimeNow() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTimeNow", reflect.TypeOf((*MockTime)(nil).GetTimeNow)) +} diff --git a/core/vesting/snapshot.go b/core/vesting/snapshot.go index 883e9bf66b9..15adcd1e3a1 100644 --- a/core/vesting/snapshot.go +++ b/core/vesting/snapshot.go @@ -21,6 +21,7 @@ import ( "sort" "code.vegaprotocol.io/vega/core/types" + vgcontext "code.vegaprotocol.io/vega/libs/context" "code.vegaprotocol.io/vega/libs/num" "code.vegaprotocol.io/vega/libs/proto" "code.vegaprotocol.io/vega/logging" @@ -40,9 +41,10 @@ func NewSnapshotEngine( broker Broker, assets Assets, parties Parties, + t Time, ) *SnapshotEngine { se := &SnapshotEngine{ - Engine: New(log, c, asvm, broker, assets, parties), + Engine: New(log, c, asvm, broker, assets, parties, t), } return se @@ -79,7 +81,7 @@ func (e *SnapshotEngine) LoadState(ctx context.Context, p *types.Payload) ([]typ } } -func (e *SnapshotEngine) loadStateFromSnapshot(_ context.Context, state *snapshotpb.Vesting) { +func (e *SnapshotEngine) loadStateFromSnapshot(ctx context.Context, state *snapshotpb.Vesting) { for _, entry := range state.PartiesReward { for _, v := range entry.InVesting { balance, underflow := num.UintFromString(v.Balance, 10) @@ -101,6 +103,18 @@ func (e *SnapshotEngine) loadStateFromSnapshot(_ context.Context, state *snapsho } } } + + if vgcontext.InProgressUpgradeFrom(ctx, "v0.78.8") { + e.updateStakingOnUpgrade79(ctx) + } +} + +// updateStakingOnUpgrade79 update staking balance for party which had +// rewards vesting before the upgrade. +func (e *SnapshotEngine) updateStakingOnUpgrade79(ctx context.Context) { + for i, v := range e.c.GetAllVestingAndVestedAccountForAsset(e.stakingAsset) { + e.updateStakingAccount(ctx, v.Owner, v.Balance.Clone(), uint64(i), e.broker.Stage) + } } func (e *SnapshotEngine) serialise(k string) ([]byte, error) { diff --git a/core/vesting/snapshot_test.go b/core/vesting/snapshot_test.go index 167d618b0b1..5566b60945a 100644 --- a/core/vesting/snapshot_test.go +++ b/core/vesting/snapshot_test.go @@ -48,19 +48,19 @@ func TestSnapshotEngine(t *testing.T) { setupMocks(t, te1) setupNetParams(ctx, t, te1) - te1.engine.AddReward("party1", "eth", num.NewUint(100), 4) - te1.engine.AddReward("party1", "btc", num.NewUint(150), 1) - te1.engine.AddReward("party1", "eth", num.NewUint(200), 0) + te1.engine.AddReward(context.Background(), "party1", "eth", num.NewUint(100), 4) + te1.engine.AddReward(context.Background(), "party1", "btc", num.NewUint(150), 1) + te1.engine.AddReward(context.Background(), "party1", "eth", num.NewUint(200), 0) nextEpoch(ctx, t, te1, time.Now()) - te1.engine.AddReward("party2", "btc", num.NewUint(100), 2) - te1.engine.AddReward("party3", "btc", num.NewUint(100), 0) + te1.engine.AddReward(context.Background(), "party2", "btc", num.NewUint(100), 2) + te1.engine.AddReward(context.Background(), "party3", "btc", num.NewUint(100), 0) nextEpoch(ctx, t, te1, time.Now()) - te1.engine.AddReward("party4", "eth", num.NewUint(100), 1) - te1.engine.AddReward("party5", "doge", num.NewUint(100), 0) + te1.engine.AddReward(context.Background(), "party4", "eth", num.NewUint(100), 1) + te1.engine.AddReward(context.Background(), "party5", "doge", num.NewUint(100), 0) // Take a snapshot. hash1, err := snapshotEngine1.SnapshotNow(ctx) @@ -69,12 +69,12 @@ func TestSnapshotEngine(t *testing.T) { // This is what must be replayed after snapshot restoration. replayFn := func(te *testSnapshotEngine) { - te.engine.AddReward("party6", "doge", num.NewUint(100), 3) + te.engine.AddReward(context.Background(), "party6", "doge", num.NewUint(100), 3) nextEpoch(ctx, t, te, time.Now()) - te.engine.AddReward("party7", "eth", num.NewUint(100), 2) - te.engine.AddReward("party8", "vega", num.NewUint(100), 10) + te.engine.AddReward(context.Background(), "party7", "eth", num.NewUint(100), 2) + te.engine.AddReward(context.Background(), "party8", "vega", num.NewUint(100), 10) nextEpoch(ctx, t, te, time.Now()) } diff --git a/datanode/gateway/graphql/schema.graphql b/datanode/gateway/graphql/schema.graphql index b7b0461f443..1c26ff60dcb 100644 --- a/datanode/gateway/graphql/schema.graphql +++ b/datanode/gateway/graphql/schema.graphql @@ -4707,6 +4707,8 @@ enum AccountType { ACCOUNT_TYPE_REWARD_AVERAGE_NOTIONAL "Reward account for the eligible entities metric" ACCOUNT_TYPE_REWARD_ELIGIBLE_ENTITIES + "Locked for staking" + ACCOUNT_TYPE_LOCKED_FOR_STAKING } "Types that describe why a transfer has been made" diff --git a/protos/sources/vega/vega.proto b/protos/sources/vega/vega.proto index 8c6d61d4b03..f161d02bf06 100644 --- a/protos/sources/vega/vega.proto +++ b/protos/sources/vega/vega.proto @@ -971,6 +971,9 @@ enum AccountType { // Reward account for the eligible entities metric. ACCOUNT_TYPE_REWARD_ELIGIBLE_ENTITIES = 33; + // Locked for staking. + ACCOUNT_TYPE_LOCKED_FOR_STAKING = 34; + // Note: If adding an enum value, add a matching entry in: // - gateway/graphql/helpers_enum.go // - gateway/graphql/schema.graphql (enum AccountType) diff --git a/protos/vega/vega.pb.go b/protos/vega/vega.pb.go index bcf21b0de07..86a7bc8cf83 100644 --- a/protos/vega/vega.pb.go +++ b/protos/vega/vega.pb.go @@ -761,6 +761,8 @@ const ( AccountType_ACCOUNT_TYPE_REWARD_AVERAGE_NOTIONAL AccountType = 32 // Reward account for the eligible entities metric. AccountType_ACCOUNT_TYPE_REWARD_ELIGIBLE_ENTITIES AccountType = 33 + // Locked for staking. + AccountType_ACCOUNT_TYPE_LOCKED_FOR_STAKING AccountType = 34 ) // Enum value maps for AccountType. @@ -798,6 +800,7 @@ var ( 31: "ACCOUNT_TYPE_BUY_BACK_FEES", 32: "ACCOUNT_TYPE_REWARD_AVERAGE_NOTIONAL", 33: "ACCOUNT_TYPE_REWARD_ELIGIBLE_ENTITIES", + 34: "ACCOUNT_TYPE_LOCKED_FOR_STAKING", } AccountType_value = map[string]int32{ "ACCOUNT_TYPE_UNSPECIFIED": 0, @@ -832,6 +835,7 @@ var ( "ACCOUNT_TYPE_BUY_BACK_FEES": 31, "ACCOUNT_TYPE_REWARD_AVERAGE_NOTIONAL": 32, "ACCOUNT_TYPE_REWARD_ELIGIBLE_ENTITIES": 33, + "ACCOUNT_TYPE_LOCKED_FOR_STAKING": 34, } ) @@ -12265,7 +12269,7 @@ var file_vega_vega_proto_rawDesc = []byte{ 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x59, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, - 0x53, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x03, 0x2a, 0x8c, 0x09, + 0x53, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x03, 0x2a, 0xb1, 0x09, 0x0a, 0x0b, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x18, 0x41, 0x43, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x41, @@ -12338,212 +12342,214 @@ var file_vega_vega_proto_rawDesc = []byte{ 0x4e, 0x41, 0x4c, 0x10, 0x20, 0x12, 0x29, 0x0a, 0x25, 0x41, 0x43, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x52, 0x45, 0x57, 0x41, 0x52, 0x44, 0x5f, 0x45, 0x4c, 0x49, 0x47, 0x49, 0x42, 0x4c, 0x45, 0x5f, 0x45, 0x4e, 0x54, 0x49, 0x54, 0x49, 0x45, 0x53, 0x10, 0x21, - 0x22, 0x04, 0x08, 0x08, 0x10, 0x08, 0x22, 0x04, 0x08, 0x18, 0x10, 0x18, 0x2a, 0xd0, 0x0e, 0x0a, - 0x0c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, - 0x19, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, - 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, - 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4c, 0x4f, - 0x53, 0x53, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, - 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x57, 0x49, 0x4e, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x54, - 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x54, 0x4d, - 0x5f, 0x4c, 0x4f, 0x53, 0x53, 0x10, 0x04, 0x12, 0x19, 0x0a, 0x15, 0x54, 0x52, 0x41, 0x4e, 0x53, - 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x54, 0x4d, 0x5f, 0x57, 0x49, 0x4e, - 0x10, 0x05, 0x12, 0x1c, 0x0a, 0x18, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x41, 0x52, 0x47, 0x49, 0x4e, 0x5f, 0x4c, 0x4f, 0x57, 0x10, 0x06, - 0x12, 0x1d, 0x0a, 0x19, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x4d, 0x41, 0x52, 0x47, 0x49, 0x4e, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x10, 0x07, 0x12, - 0x24, 0x0a, 0x20, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x4d, 0x41, 0x52, 0x47, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x53, 0x43, 0x41, - 0x54, 0x45, 0x44, 0x10, 0x08, 0x12, 0x1f, 0x0a, 0x1b, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, - 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x41, 0x4b, 0x45, 0x52, 0x5f, 0x46, 0x45, 0x45, - 0x5f, 0x50, 0x41, 0x59, 0x10, 0x09, 0x12, 0x23, 0x0a, 0x1f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, - 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x41, 0x4b, 0x45, 0x52, 0x5f, 0x46, 0x45, - 0x45, 0x5f, 0x52, 0x45, 0x43, 0x45, 0x49, 0x56, 0x45, 0x10, 0x0a, 0x12, 0x28, 0x0a, 0x24, 0x54, - 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x46, - 0x52, 0x41, 0x53, 0x54, 0x52, 0x55, 0x43, 0x54, 0x55, 0x52, 0x45, 0x5f, 0x46, 0x45, 0x45, 0x5f, - 0x50, 0x41, 0x59, 0x10, 0x0b, 0x12, 0x2f, 0x0a, 0x2b, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, - 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x46, 0x52, 0x41, 0x53, 0x54, 0x52, 0x55, - 0x43, 0x54, 0x55, 0x52, 0x45, 0x5f, 0x46, 0x45, 0x45, 0x5f, 0x44, 0x49, 0x53, 0x54, 0x52, 0x49, - 0x42, 0x55, 0x54, 0x45, 0x10, 0x0c, 0x12, 0x23, 0x0a, 0x1f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, - 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4c, 0x49, 0x51, 0x55, 0x49, 0x44, 0x49, 0x54, - 0x59, 0x5f, 0x46, 0x45, 0x45, 0x5f, 0x50, 0x41, 0x59, 0x10, 0x0d, 0x12, 0x2a, 0x0a, 0x26, 0x54, - 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4c, 0x49, 0x51, - 0x55, 0x49, 0x44, 0x49, 0x54, 0x59, 0x5f, 0x46, 0x45, 0x45, 0x5f, 0x44, 0x49, 0x53, 0x54, 0x52, - 0x49, 0x42, 0x55, 0x54, 0x45, 0x10, 0x0e, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x52, 0x41, 0x4e, 0x53, - 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x4f, 0x4e, 0x44, 0x5f, 0x4c, 0x4f, - 0x57, 0x10, 0x0f, 0x12, 0x1b, 0x0a, 0x17, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x4f, 0x4e, 0x44, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x10, 0x10, + 0x12, 0x23, 0x0a, 0x1f, 0x41, 0x43, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x4c, 0x4f, 0x43, 0x4b, 0x45, 0x44, 0x5f, 0x46, 0x4f, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x4b, + 0x49, 0x4e, 0x47, 0x10, 0x22, 0x22, 0x04, 0x08, 0x08, 0x10, 0x08, 0x22, 0x04, 0x08, 0x18, 0x10, + 0x18, 0x2a, 0xd0, 0x0e, 0x0a, 0x0c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, + 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x16, 0x0a, 0x12, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, + 0x50, 0x45, 0x5f, 0x4c, 0x4f, 0x53, 0x53, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x52, 0x41, + 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x57, 0x49, 0x4e, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x57, 0x49, 0x54, 0x48, 0x44, 0x52, 0x41, 0x57, 0x10, 0x12, 0x12, 0x19, 0x0a, 0x15, - 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x45, - 0x50, 0x4f, 0x53, 0x49, 0x54, 0x10, 0x13, 0x12, 0x1f, 0x0a, 0x1b, 0x54, 0x52, 0x41, 0x4e, 0x53, - 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x4f, 0x4e, 0x44, 0x5f, 0x53, 0x4c, - 0x41, 0x53, 0x48, 0x49, 0x4e, 0x47, 0x10, 0x14, 0x12, 0x1f, 0x0a, 0x1b, 0x54, 0x52, 0x41, 0x4e, - 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x52, 0x45, 0x57, 0x41, 0x52, 0x44, - 0x5f, 0x50, 0x41, 0x59, 0x4f, 0x55, 0x54, 0x10, 0x15, 0x12, 0x25, 0x0a, 0x21, 0x54, 0x52, 0x41, - 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, - 0x46, 0x45, 0x52, 0x5f, 0x46, 0x55, 0x4e, 0x44, 0x53, 0x5f, 0x53, 0x45, 0x4e, 0x44, 0x10, 0x16, - 0x12, 0x2b, 0x0a, 0x27, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x46, 0x55, 0x4e, 0x44, 0x53, - 0x5f, 0x44, 0x49, 0x53, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x45, 0x10, 0x17, 0x12, 0x1f, 0x0a, - 0x1b, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, - 0x4c, 0x45, 0x41, 0x52, 0x5f, 0x41, 0x43, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x10, 0x18, 0x12, 0x2c, - 0x0a, 0x28, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, - 0x43, 0x48, 0x45, 0x43, 0x4b, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x5f, 0x42, 0x41, 0x4c, 0x41, 0x4e, - 0x43, 0x45, 0x5f, 0x52, 0x45, 0x53, 0x54, 0x4f, 0x52, 0x45, 0x10, 0x19, 0x12, 0x16, 0x0a, 0x12, - 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x50, - 0x4f, 0x54, 0x10, 0x1a, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, - 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x48, 0x4f, 0x4c, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x4c, 0x4f, - 0x43, 0x4b, 0x10, 0x1b, 0x12, 0x21, 0x0a, 0x1d, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, - 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x48, 0x4f, 0x4c, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x52, 0x45, - 0x4c, 0x45, 0x41, 0x53, 0x45, 0x10, 0x1c, 0x12, 0x2e, 0x0a, 0x2a, 0x54, 0x52, 0x41, 0x4e, 0x53, - 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, - 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x52, 0x41, 0x4e, 0x43, 0x45, 0x5f, 0x46, 0x52, 0x41, - 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x1d, 0x12, 0x28, 0x0a, 0x24, 0x54, 0x52, 0x41, 0x4e, 0x53, - 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4c, 0x49, 0x51, 0x55, 0x49, 0x44, 0x49, - 0x54, 0x59, 0x5f, 0x46, 0x45, 0x45, 0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x45, 0x10, - 0x1e, 0x12, 0x2e, 0x0a, 0x2a, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, - 0x50, 0x45, 0x5f, 0x4c, 0x49, 0x51, 0x55, 0x49, 0x44, 0x49, 0x54, 0x59, 0x5f, 0x46, 0x45, 0x45, - 0x5f, 0x4e, 0x45, 0x54, 0x5f, 0x44, 0x49, 0x53, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x45, 0x10, - 0x1f, 0x12, 0x28, 0x0a, 0x24, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, - 0x50, 0x45, 0x5f, 0x53, 0x4c, 0x41, 0x5f, 0x50, 0x45, 0x4e, 0x41, 0x4c, 0x54, 0x59, 0x5f, 0x42, - 0x4f, 0x4e, 0x44, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x59, 0x10, 0x20, 0x12, 0x2a, 0x0a, 0x26, 0x54, - 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x4c, 0x41, - 0x5f, 0x50, 0x45, 0x4e, 0x41, 0x4c, 0x54, 0x59, 0x5f, 0x4c, 0x50, 0x5f, 0x46, 0x45, 0x45, 0x5f, - 0x41, 0x50, 0x50, 0x4c, 0x59, 0x10, 0x21, 0x12, 0x2e, 0x0a, 0x2a, 0x54, 0x52, 0x41, 0x4e, 0x53, - 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4c, 0x49, 0x51, 0x55, 0x49, 0x44, 0x49, - 0x54, 0x59, 0x5f, 0x46, 0x45, 0x45, 0x5f, 0x55, 0x4e, 0x50, 0x41, 0x49, 0x44, 0x5f, 0x43, 0x4f, - 0x4c, 0x4c, 0x45, 0x43, 0x54, 0x10, 0x22, 0x12, 0x32, 0x0a, 0x2e, 0x54, 0x52, 0x41, 0x4e, 0x53, - 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x4c, 0x41, 0x5f, 0x50, 0x45, 0x52, - 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x4e, 0x43, 0x45, 0x5f, 0x42, 0x4f, 0x4e, 0x55, 0x53, 0x5f, 0x44, - 0x49, 0x53, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x45, 0x10, 0x23, 0x12, 0x29, 0x0a, 0x25, 0x54, + 0x45, 0x5f, 0x4d, 0x54, 0x4d, 0x5f, 0x4c, 0x4f, 0x53, 0x53, 0x10, 0x04, 0x12, 0x19, 0x0a, 0x15, + 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x54, + 0x4d, 0x5f, 0x57, 0x49, 0x4e, 0x10, 0x05, 0x12, 0x1c, 0x0a, 0x18, 0x54, 0x52, 0x41, 0x4e, 0x53, + 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x41, 0x52, 0x47, 0x49, 0x4e, 0x5f, + 0x4c, 0x4f, 0x57, 0x10, 0x06, 0x12, 0x1d, 0x0a, 0x19, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, + 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x41, 0x52, 0x47, 0x49, 0x4e, 0x5f, 0x48, 0x49, + 0x47, 0x48, 0x10, 0x07, 0x12, 0x24, 0x0a, 0x20, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, + 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x41, 0x52, 0x47, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x4e, + 0x46, 0x49, 0x53, 0x43, 0x41, 0x54, 0x45, 0x44, 0x10, 0x08, 0x12, 0x1f, 0x0a, 0x1b, 0x54, 0x52, + 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x41, 0x4b, 0x45, + 0x52, 0x5f, 0x46, 0x45, 0x45, 0x5f, 0x50, 0x41, 0x59, 0x10, 0x09, 0x12, 0x23, 0x0a, 0x1f, 0x54, + 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x41, 0x4b, + 0x45, 0x52, 0x5f, 0x46, 0x45, 0x45, 0x5f, 0x52, 0x45, 0x43, 0x45, 0x49, 0x56, 0x45, 0x10, 0x0a, + 0x12, 0x28, 0x0a, 0x24, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x49, 0x4e, 0x46, 0x52, 0x41, 0x53, 0x54, 0x52, 0x55, 0x43, 0x54, 0x55, 0x52, 0x45, + 0x5f, 0x46, 0x45, 0x45, 0x5f, 0x50, 0x41, 0x59, 0x10, 0x0b, 0x12, 0x2f, 0x0a, 0x2b, 0x54, 0x52, + 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x46, 0x52, + 0x41, 0x53, 0x54, 0x52, 0x55, 0x43, 0x54, 0x55, 0x52, 0x45, 0x5f, 0x46, 0x45, 0x45, 0x5f, 0x44, + 0x49, 0x53, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x45, 0x10, 0x0c, 0x12, 0x23, 0x0a, 0x1f, 0x54, + 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4c, 0x49, 0x51, + 0x55, 0x49, 0x44, 0x49, 0x54, 0x59, 0x5f, 0x46, 0x45, 0x45, 0x5f, 0x50, 0x41, 0x59, 0x10, 0x0d, + 0x12, 0x2a, 0x0a, 0x26, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x4c, 0x49, 0x51, 0x55, 0x49, 0x44, 0x49, 0x54, 0x59, 0x5f, 0x46, 0x45, 0x45, 0x5f, + 0x44, 0x49, 0x53, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x45, 0x10, 0x0e, 0x12, 0x1a, 0x0a, 0x16, + 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x4f, + 0x4e, 0x44, 0x5f, 0x4c, 0x4f, 0x57, 0x10, 0x0f, 0x12, 0x1b, 0x0a, 0x17, 0x54, 0x52, 0x41, 0x4e, + 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x4f, 0x4e, 0x44, 0x5f, 0x48, + 0x49, 0x47, 0x48, 0x10, 0x10, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, + 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x57, 0x49, 0x54, 0x48, 0x44, 0x52, 0x41, 0x57, 0x10, + 0x12, 0x12, 0x19, 0x0a, 0x15, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, + 0x50, 0x45, 0x5f, 0x44, 0x45, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x10, 0x13, 0x12, 0x1f, 0x0a, 0x1b, + 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x4f, + 0x4e, 0x44, 0x5f, 0x53, 0x4c, 0x41, 0x53, 0x48, 0x49, 0x4e, 0x47, 0x10, 0x14, 0x12, 0x1f, 0x0a, + 0x1b, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x52, + 0x45, 0x57, 0x41, 0x52, 0x44, 0x5f, 0x50, 0x41, 0x59, 0x4f, 0x55, 0x54, 0x10, 0x15, 0x12, 0x25, + 0x0a, 0x21, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x46, 0x55, 0x4e, 0x44, 0x53, 0x5f, 0x53, + 0x45, 0x4e, 0x44, 0x10, 0x16, 0x12, 0x2b, 0x0a, 0x27, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, + 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, + 0x46, 0x55, 0x4e, 0x44, 0x53, 0x5f, 0x44, 0x49, 0x53, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x45, + 0x10, 0x17, 0x12, 0x1f, 0x0a, 0x1b, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, + 0x59, 0x50, 0x45, 0x5f, 0x43, 0x4c, 0x45, 0x41, 0x52, 0x5f, 0x41, 0x43, 0x43, 0x4f, 0x55, 0x4e, + 0x54, 0x10, 0x18, 0x12, 0x2c, 0x0a, 0x28, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x5f, + 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x5f, 0x52, 0x45, 0x53, 0x54, 0x4f, 0x52, 0x45, 0x10, + 0x19, 0x12, 0x16, 0x0a, 0x12, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, + 0x50, 0x45, 0x5f, 0x53, 0x50, 0x4f, 0x54, 0x10, 0x1a, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x52, 0x41, + 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x48, 0x4f, 0x4c, 0x44, 0x49, + 0x4e, 0x47, 0x5f, 0x4c, 0x4f, 0x43, 0x4b, 0x10, 0x1b, 0x12, 0x21, 0x0a, 0x1d, 0x54, 0x52, 0x41, + 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x48, 0x4f, 0x4c, 0x44, 0x49, + 0x4e, 0x47, 0x5f, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, 0x10, 0x1c, 0x12, 0x2e, 0x0a, 0x2a, + 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x55, + 0x43, 0x43, 0x45, 0x53, 0x53, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x52, 0x41, 0x4e, 0x43, + 0x45, 0x5f, 0x46, 0x52, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x1d, 0x12, 0x28, 0x0a, 0x24, + 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4c, 0x49, + 0x51, 0x55, 0x49, 0x44, 0x49, 0x54, 0x59, 0x5f, 0x46, 0x45, 0x45, 0x5f, 0x41, 0x4c, 0x4c, 0x4f, + 0x43, 0x41, 0x54, 0x45, 0x10, 0x1e, 0x12, 0x2e, 0x0a, 0x2a, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, + 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4c, 0x49, 0x51, 0x55, 0x49, 0x44, 0x49, 0x54, + 0x59, 0x5f, 0x46, 0x45, 0x45, 0x5f, 0x4e, 0x45, 0x54, 0x5f, 0x44, 0x49, 0x53, 0x54, 0x52, 0x49, + 0x42, 0x55, 0x54, 0x45, 0x10, 0x1f, 0x12, 0x28, 0x0a, 0x24, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, + 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x4c, 0x41, 0x5f, 0x50, 0x45, 0x4e, 0x41, + 0x4c, 0x54, 0x59, 0x5f, 0x42, 0x4f, 0x4e, 0x44, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x59, 0x10, 0x20, + 0x12, 0x2a, 0x0a, 0x26, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x53, 0x4c, 0x41, 0x5f, 0x50, 0x45, 0x4e, 0x41, 0x4c, 0x54, 0x59, 0x5f, 0x4c, 0x50, + 0x5f, 0x46, 0x45, 0x45, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x59, 0x10, 0x21, 0x12, 0x2e, 0x0a, 0x2a, + 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4c, 0x49, + 0x51, 0x55, 0x49, 0x44, 0x49, 0x54, 0x59, 0x5f, 0x46, 0x45, 0x45, 0x5f, 0x55, 0x4e, 0x50, 0x41, + 0x49, 0x44, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x45, 0x43, 0x54, 0x10, 0x22, 0x12, 0x32, 0x0a, 0x2e, + 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x4c, + 0x41, 0x5f, 0x50, 0x45, 0x52, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x4e, 0x43, 0x45, 0x5f, 0x42, 0x4f, + 0x4e, 0x55, 0x53, 0x5f, 0x44, 0x49, 0x53, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x45, 0x10, 0x23, + 0x12, 0x29, 0x0a, 0x25, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x50, 0x45, 0x52, 0x50, 0x45, 0x54, 0x55, 0x41, 0x4c, 0x53, 0x5f, 0x46, 0x55, 0x4e, + 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x4c, 0x4f, 0x53, 0x53, 0x10, 0x24, 0x12, 0x28, 0x0a, 0x24, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x45, 0x52, 0x50, 0x45, 0x54, 0x55, 0x41, 0x4c, 0x53, 0x5f, 0x46, 0x55, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x5f, - 0x4c, 0x4f, 0x53, 0x53, 0x10, 0x24, 0x12, 0x28, 0x0a, 0x24, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, - 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x45, 0x52, 0x50, 0x45, 0x54, 0x55, 0x41, - 0x4c, 0x53, 0x5f, 0x46, 0x55, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x57, 0x49, 0x4e, 0x10, 0x25, - 0x12, 0x20, 0x0a, 0x1c, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x52, 0x45, 0x57, 0x41, 0x52, 0x44, 0x53, 0x5f, 0x56, 0x45, 0x53, 0x54, 0x45, 0x44, - 0x10, 0x26, 0x12, 0x29, 0x0a, 0x25, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, + 0x57, 0x49, 0x4e, 0x10, 0x25, 0x12, 0x20, 0x0a, 0x1c, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, + 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x52, 0x45, 0x57, 0x41, 0x52, 0x44, 0x53, 0x5f, 0x56, + 0x45, 0x53, 0x54, 0x45, 0x44, 0x10, 0x26, 0x12, 0x29, 0x0a, 0x25, 0x54, 0x52, 0x41, 0x4e, 0x53, + 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x45, 0x45, 0x5f, 0x52, 0x45, 0x46, + 0x45, 0x52, 0x52, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x57, 0x41, 0x52, 0x44, 0x5f, 0x50, 0x41, 0x59, + 0x10, 0x27, 0x12, 0x30, 0x0a, 0x2c, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x45, 0x45, 0x5f, 0x52, 0x45, 0x46, 0x45, 0x52, 0x52, 0x45, 0x52, - 0x5f, 0x52, 0x45, 0x57, 0x41, 0x52, 0x44, 0x5f, 0x50, 0x41, 0x59, 0x10, 0x27, 0x12, 0x30, 0x0a, - 0x2c, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, - 0x45, 0x45, 0x5f, 0x52, 0x45, 0x46, 0x45, 0x52, 0x52, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x57, 0x41, - 0x52, 0x44, 0x5f, 0x44, 0x49, 0x53, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x45, 0x10, 0x2c, 0x12, - 0x22, 0x0a, 0x1e, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x4d, 0x41, 0x52, 0x47, 0x49, 0x4e, 0x5f, 0x4c, 0x4f, - 0x57, 0x10, 0x2d, 0x12, 0x23, 0x0a, 0x1f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x4d, 0x41, 0x52, 0x47, 0x49, - 0x4e, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x10, 0x2e, 0x12, 0x25, 0x0a, 0x21, 0x54, 0x52, 0x41, 0x4e, - 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x53, 0x4f, 0x4c, 0x41, 0x54, - 0x45, 0x44, 0x5f, 0x4d, 0x41, 0x52, 0x47, 0x49, 0x4e, 0x5f, 0x4c, 0x4f, 0x57, 0x10, 0x2f, 0x12, - 0x26, 0x0a, 0x22, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x49, 0x53, 0x4f, 0x4c, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x4d, 0x41, 0x52, 0x47, 0x49, 0x4e, - 0x5f, 0x48, 0x49, 0x47, 0x48, 0x10, 0x30, 0x12, 0x19, 0x0a, 0x15, 0x54, 0x52, 0x41, 0x4e, 0x53, - 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x4d, 0x4d, 0x5f, 0x4c, 0x4f, 0x57, - 0x10, 0x31, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x41, 0x4d, 0x4d, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x10, 0x32, 0x12, 0x1d, - 0x0a, 0x19, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, - 0x41, 0x4d, 0x4d, 0x5f, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, 0x10, 0x33, 0x12, 0x22, 0x0a, - 0x1e, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x54, - 0x52, 0x45, 0x41, 0x53, 0x55, 0x52, 0x59, 0x5f, 0x46, 0x45, 0x45, 0x5f, 0x50, 0x41, 0x59, 0x10, - 0x34, 0x12, 0x22, 0x0a, 0x1e, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, - 0x50, 0x45, 0x5f, 0x42, 0x55, 0x59, 0x5f, 0x42, 0x41, 0x43, 0x4b, 0x5f, 0x46, 0x45, 0x45, 0x5f, - 0x50, 0x41, 0x59, 0x10, 0x35, 0x12, 0x2b, 0x0a, 0x27, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, - 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x5f, 0x4d, 0x41, 0x4b, 0x45, - 0x52, 0x5f, 0x46, 0x45, 0x45, 0x5f, 0x52, 0x45, 0x42, 0x41, 0x54, 0x45, 0x5f, 0x50, 0x41, 0x59, - 0x10, 0x36, 0x12, 0x2f, 0x0a, 0x2b, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x5f, 0x4d, 0x41, 0x4b, 0x45, 0x52, 0x5f, 0x46, - 0x45, 0x45, 0x5f, 0x52, 0x45, 0x42, 0x41, 0x54, 0x45, 0x5f, 0x52, 0x45, 0x43, 0x45, 0x49, 0x56, - 0x45, 0x10, 0x37, 0x22, 0x04, 0x08, 0x03, 0x10, 0x03, 0x22, 0x04, 0x08, 0x11, 0x10, 0x11, 0x2a, - 0xb2, 0x03, 0x0a, 0x0e, 0x44, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x65, 0x74, 0x72, - 0x69, 0x63, 0x12, 0x1f, 0x0a, 0x1b, 0x44, 0x49, 0x53, 0x50, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x4d, - 0x45, 0x54, 0x52, 0x49, 0x43, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, - 0x44, 0x10, 0x00, 0x12, 0x23, 0x0a, 0x1f, 0x44, 0x49, 0x53, 0x50, 0x41, 0x54, 0x43, 0x48, 0x5f, - 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x5f, 0x4d, 0x41, 0x4b, 0x45, 0x52, 0x5f, 0x46, 0x45, 0x45, - 0x53, 0x5f, 0x50, 0x41, 0x49, 0x44, 0x10, 0x01, 0x12, 0x27, 0x0a, 0x23, 0x44, 0x49, 0x53, 0x50, + 0x5f, 0x52, 0x45, 0x57, 0x41, 0x52, 0x44, 0x5f, 0x44, 0x49, 0x53, 0x54, 0x52, 0x49, 0x42, 0x55, + 0x54, 0x45, 0x10, 0x2c, 0x12, 0x22, 0x0a, 0x1e, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, + 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x4d, 0x41, 0x52, 0x47, + 0x49, 0x4e, 0x5f, 0x4c, 0x4f, 0x57, 0x10, 0x2d, 0x12, 0x23, 0x0a, 0x1f, 0x54, 0x52, 0x41, 0x4e, + 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, + 0x4d, 0x41, 0x52, 0x47, 0x49, 0x4e, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x10, 0x2e, 0x12, 0x25, 0x0a, + 0x21, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, + 0x53, 0x4f, 0x4c, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x4d, 0x41, 0x52, 0x47, 0x49, 0x4e, 0x5f, 0x4c, + 0x4f, 0x57, 0x10, 0x2f, 0x12, 0x26, 0x0a, 0x22, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, + 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x53, 0x4f, 0x4c, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x4d, + 0x41, 0x52, 0x47, 0x49, 0x4e, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x10, 0x30, 0x12, 0x19, 0x0a, 0x15, + 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x4d, + 0x4d, 0x5f, 0x4c, 0x4f, 0x57, 0x10, 0x31, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x52, 0x41, 0x4e, 0x53, + 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x4d, 0x4d, 0x5f, 0x48, 0x49, 0x47, + 0x48, 0x10, 0x32, 0x12, 0x1d, 0x0a, 0x19, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x4d, 0x4d, 0x5f, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, + 0x10, 0x33, 0x12, 0x22, 0x0a, 0x1e, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, + 0x59, 0x50, 0x45, 0x5f, 0x54, 0x52, 0x45, 0x41, 0x53, 0x55, 0x52, 0x59, 0x5f, 0x46, 0x45, 0x45, + 0x5f, 0x50, 0x41, 0x59, 0x10, 0x34, 0x12, 0x22, 0x0a, 0x1e, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, + 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x55, 0x59, 0x5f, 0x42, 0x41, 0x43, 0x4b, + 0x5f, 0x46, 0x45, 0x45, 0x5f, 0x50, 0x41, 0x59, 0x10, 0x35, 0x12, 0x2b, 0x0a, 0x27, 0x54, 0x52, + 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x48, 0x49, 0x47, 0x48, + 0x5f, 0x4d, 0x41, 0x4b, 0x45, 0x52, 0x5f, 0x46, 0x45, 0x45, 0x5f, 0x52, 0x45, 0x42, 0x41, 0x54, + 0x45, 0x5f, 0x50, 0x41, 0x59, 0x10, 0x36, 0x12, 0x2f, 0x0a, 0x2b, 0x54, 0x52, 0x41, 0x4e, 0x53, + 0x46, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x5f, 0x4d, 0x41, + 0x4b, 0x45, 0x52, 0x5f, 0x46, 0x45, 0x45, 0x5f, 0x52, 0x45, 0x42, 0x41, 0x54, 0x45, 0x5f, 0x52, + 0x45, 0x43, 0x45, 0x49, 0x56, 0x45, 0x10, 0x37, 0x22, 0x04, 0x08, 0x03, 0x10, 0x03, 0x22, 0x04, + 0x08, 0x11, 0x10, 0x11, 0x2a, 0xb2, 0x03, 0x0a, 0x0e, 0x44, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, + 0x68, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x1f, 0x0a, 0x1b, 0x44, 0x49, 0x53, 0x50, 0x41, + 0x54, 0x43, 0x48, 0x5f, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, + 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x23, 0x0a, 0x1f, 0x44, 0x49, 0x53, 0x50, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x5f, 0x4d, 0x41, 0x4b, 0x45, - 0x52, 0x5f, 0x46, 0x45, 0x45, 0x53, 0x5f, 0x52, 0x45, 0x43, 0x45, 0x49, 0x56, 0x45, 0x44, 0x10, - 0x02, 0x12, 0x24, 0x0a, 0x20, 0x44, 0x49, 0x53, 0x50, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x4d, 0x45, - 0x54, 0x52, 0x49, 0x43, 0x5f, 0x4c, 0x50, 0x5f, 0x46, 0x45, 0x45, 0x53, 0x5f, 0x52, 0x45, 0x43, - 0x45, 0x49, 0x56, 0x45, 0x44, 0x10, 0x03, 0x12, 0x20, 0x0a, 0x1c, 0x44, 0x49, 0x53, 0x50, 0x41, - 0x54, 0x43, 0x48, 0x5f, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x5f, 0x4d, 0x41, 0x52, 0x4b, 0x45, - 0x54, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x04, 0x12, 0x23, 0x0a, 0x1f, 0x44, 0x49, 0x53, - 0x50, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x5f, 0x52, 0x45, 0x4c, - 0x41, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x52, 0x45, 0x54, 0x55, 0x52, 0x4e, 0x10, 0x06, 0x12, 0x25, - 0x0a, 0x21, 0x44, 0x49, 0x53, 0x50, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x4d, 0x45, 0x54, 0x52, 0x49, - 0x43, 0x5f, 0x52, 0x45, 0x54, 0x55, 0x52, 0x4e, 0x5f, 0x56, 0x4f, 0x4c, 0x41, 0x54, 0x49, 0x4c, - 0x49, 0x54, 0x59, 0x10, 0x07, 0x12, 0x25, 0x0a, 0x21, 0x44, 0x49, 0x53, 0x50, 0x41, 0x54, 0x43, - 0x48, 0x5f, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x5f, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, - 0x4f, 0x52, 0x5f, 0x52, 0x41, 0x4e, 0x4b, 0x49, 0x4e, 0x47, 0x10, 0x08, 0x12, 0x23, 0x0a, 0x1f, + 0x52, 0x5f, 0x46, 0x45, 0x45, 0x53, 0x5f, 0x50, 0x41, 0x49, 0x44, 0x10, 0x01, 0x12, 0x27, 0x0a, + 0x23, 0x44, 0x49, 0x53, 0x50, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, + 0x5f, 0x4d, 0x41, 0x4b, 0x45, 0x52, 0x5f, 0x46, 0x45, 0x45, 0x53, 0x5f, 0x52, 0x45, 0x43, 0x45, + 0x49, 0x56, 0x45, 0x44, 0x10, 0x02, 0x12, 0x24, 0x0a, 0x20, 0x44, 0x49, 0x53, 0x50, 0x41, 0x54, + 0x43, 0x48, 0x5f, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x5f, 0x4c, 0x50, 0x5f, 0x46, 0x45, 0x45, + 0x53, 0x5f, 0x52, 0x45, 0x43, 0x45, 0x49, 0x56, 0x45, 0x44, 0x10, 0x03, 0x12, 0x20, 0x0a, 0x1c, 0x44, 0x49, 0x53, 0x50, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x5f, - 0x52, 0x45, 0x41, 0x4c, 0x49, 0x53, 0x45, 0x44, 0x5f, 0x52, 0x45, 0x54, 0x55, 0x52, 0x4e, 0x10, - 0x09, 0x12, 0x24, 0x0a, 0x20, 0x44, 0x49, 0x53, 0x50, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x4d, 0x45, - 0x54, 0x52, 0x49, 0x43, 0x5f, 0x41, 0x56, 0x45, 0x52, 0x41, 0x47, 0x45, 0x5f, 0x4e, 0x4f, 0x54, - 0x49, 0x4f, 0x4e, 0x41, 0x4c, 0x10, 0x0a, 0x12, 0x25, 0x0a, 0x21, 0x44, 0x49, 0x53, 0x50, 0x41, - 0x54, 0x43, 0x48, 0x5f, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x5f, 0x45, 0x4c, 0x49, 0x47, 0x49, - 0x42, 0x4c, 0x45, 0x5f, 0x45, 0x4e, 0x54, 0x49, 0x54, 0x49, 0x45, 0x53, 0x10, 0x0b, 0x22, 0x04, - 0x08, 0x05, 0x10, 0x05, 0x2a, 0x61, 0x0a, 0x0b, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x53, 0x63, - 0x6f, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x18, 0x45, 0x4e, 0x54, 0x49, 0x54, 0x59, 0x5f, 0x53, 0x43, - 0x4f, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, - 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x45, 0x4e, 0x54, 0x49, 0x54, 0x59, 0x5f, 0x53, 0x43, 0x4f, 0x50, - 0x45, 0x5f, 0x49, 0x4e, 0x44, 0x49, 0x56, 0x49, 0x44, 0x55, 0x41, 0x4c, 0x53, 0x10, 0x01, 0x12, - 0x16, 0x0a, 0x12, 0x45, 0x4e, 0x54, 0x49, 0x54, 0x59, 0x5f, 0x53, 0x43, 0x4f, 0x50, 0x45, 0x5f, - 0x54, 0x45, 0x41, 0x4d, 0x53, 0x10, 0x02, 0x2a, 0xa7, 0x01, 0x0a, 0x0f, 0x49, 0x6e, 0x64, 0x69, - 0x76, 0x69, 0x64, 0x75, 0x61, 0x6c, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x1c, 0x49, - 0x4e, 0x44, 0x49, 0x56, 0x49, 0x44, 0x55, 0x41, 0x4c, 0x5f, 0x53, 0x43, 0x4f, 0x50, 0x45, 0x5f, - 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x18, 0x0a, - 0x14, 0x49, 0x4e, 0x44, 0x49, 0x56, 0x49, 0x44, 0x55, 0x41, 0x4c, 0x5f, 0x53, 0x43, 0x4f, 0x50, - 0x45, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x49, 0x4e, 0x44, 0x49, 0x56, - 0x49, 0x44, 0x55, 0x41, 0x4c, 0x5f, 0x53, 0x43, 0x4f, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x5f, 0x54, - 0x45, 0x41, 0x4d, 0x10, 0x02, 0x12, 0x20, 0x0a, 0x1c, 0x49, 0x4e, 0x44, 0x49, 0x56, 0x49, 0x44, - 0x55, 0x41, 0x4c, 0x5f, 0x53, 0x43, 0x4f, 0x50, 0x45, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x49, 0x4e, - 0x5f, 0x54, 0x45, 0x41, 0x4d, 0x10, 0x03, 0x12, 0x18, 0x0a, 0x14, 0x49, 0x4e, 0x44, 0x49, 0x56, - 0x49, 0x44, 0x55, 0x41, 0x4c, 0x5f, 0x53, 0x43, 0x4f, 0x50, 0x45, 0x5f, 0x41, 0x4d, 0x4d, 0x10, - 0x04, 0x2a, 0xa9, 0x01, 0x0a, 0x14, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, - 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x25, 0x0a, 0x21, 0x44, 0x49, + 0x4d, 0x41, 0x52, 0x4b, 0x45, 0x54, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x04, 0x12, 0x23, + 0x0a, 0x1f, 0x44, 0x49, 0x53, 0x50, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x4d, 0x45, 0x54, 0x52, 0x49, + 0x43, 0x5f, 0x52, 0x45, 0x4c, 0x41, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x52, 0x45, 0x54, 0x55, 0x52, + 0x4e, 0x10, 0x06, 0x12, 0x25, 0x0a, 0x21, 0x44, 0x49, 0x53, 0x50, 0x41, 0x54, 0x43, 0x48, 0x5f, + 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x5f, 0x52, 0x45, 0x54, 0x55, 0x52, 0x4e, 0x5f, 0x56, 0x4f, + 0x4c, 0x41, 0x54, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x10, 0x07, 0x12, 0x25, 0x0a, 0x21, 0x44, 0x49, + 0x53, 0x50, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x5f, 0x56, 0x41, + 0x4c, 0x49, 0x44, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x52, 0x41, 0x4e, 0x4b, 0x49, 0x4e, 0x47, 0x10, + 0x08, 0x12, 0x23, 0x0a, 0x1f, 0x44, 0x49, 0x53, 0x50, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x4d, 0x45, + 0x54, 0x52, 0x49, 0x43, 0x5f, 0x52, 0x45, 0x41, 0x4c, 0x49, 0x53, 0x45, 0x44, 0x5f, 0x52, 0x45, + 0x54, 0x55, 0x52, 0x4e, 0x10, 0x09, 0x12, 0x24, 0x0a, 0x20, 0x44, 0x49, 0x53, 0x50, 0x41, 0x54, + 0x43, 0x48, 0x5f, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x5f, 0x41, 0x56, 0x45, 0x52, 0x41, 0x47, + 0x45, 0x5f, 0x4e, 0x4f, 0x54, 0x49, 0x4f, 0x4e, 0x41, 0x4c, 0x10, 0x0a, 0x12, 0x25, 0x0a, 0x21, + 0x44, 0x49, 0x53, 0x50, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x5f, + 0x45, 0x4c, 0x49, 0x47, 0x49, 0x42, 0x4c, 0x45, 0x5f, 0x45, 0x4e, 0x54, 0x49, 0x54, 0x49, 0x45, + 0x53, 0x10, 0x0b, 0x22, 0x04, 0x08, 0x05, 0x10, 0x05, 0x2a, 0x61, 0x0a, 0x0b, 0x45, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x18, 0x45, 0x4e, 0x54, 0x49, + 0x54, 0x59, 0x5f, 0x53, 0x43, 0x4f, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x45, 0x4e, 0x54, 0x49, 0x54, 0x59, + 0x5f, 0x53, 0x43, 0x4f, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x44, 0x49, 0x56, 0x49, 0x44, 0x55, 0x41, + 0x4c, 0x53, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x45, 0x4e, 0x54, 0x49, 0x54, 0x59, 0x5f, 0x53, + 0x43, 0x4f, 0x50, 0x45, 0x5f, 0x54, 0x45, 0x41, 0x4d, 0x53, 0x10, 0x02, 0x2a, 0xa7, 0x01, 0x0a, + 0x0f, 0x49, 0x6e, 0x64, 0x69, 0x76, 0x69, 0x64, 0x75, 0x61, 0x6c, 0x53, 0x63, 0x6f, 0x70, 0x65, + 0x12, 0x20, 0x0a, 0x1c, 0x49, 0x4e, 0x44, 0x49, 0x56, 0x49, 0x44, 0x55, 0x41, 0x4c, 0x5f, 0x53, + 0x43, 0x4f, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x49, 0x4e, 0x44, 0x49, 0x56, 0x49, 0x44, 0x55, 0x41, 0x4c, + 0x5f, 0x53, 0x43, 0x4f, 0x50, 0x45, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, + 0x49, 0x4e, 0x44, 0x49, 0x56, 0x49, 0x44, 0x55, 0x41, 0x4c, 0x5f, 0x53, 0x43, 0x4f, 0x50, 0x45, + 0x5f, 0x49, 0x4e, 0x5f, 0x54, 0x45, 0x41, 0x4d, 0x10, 0x02, 0x12, 0x20, 0x0a, 0x1c, 0x49, 0x4e, + 0x44, 0x49, 0x56, 0x49, 0x44, 0x55, 0x41, 0x4c, 0x5f, 0x53, 0x43, 0x4f, 0x50, 0x45, 0x5f, 0x4e, + 0x4f, 0x54, 0x5f, 0x49, 0x4e, 0x5f, 0x54, 0x45, 0x41, 0x4d, 0x10, 0x03, 0x12, 0x18, 0x0a, 0x14, + 0x49, 0x4e, 0x44, 0x49, 0x56, 0x49, 0x44, 0x55, 0x41, 0x4c, 0x5f, 0x53, 0x43, 0x4f, 0x50, 0x45, + 0x5f, 0x41, 0x4d, 0x4d, 0x10, 0x04, 0x2a, 0xa9, 0x01, 0x0a, 0x14, 0x44, 0x69, 0x73, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, + 0x25, 0x0a, 0x21, 0x44, 0x49, 0x53, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x49, 0x4f, 0x4e, 0x5f, + 0x53, 0x54, 0x52, 0x41, 0x54, 0x45, 0x47, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x22, 0x0a, 0x1e, 0x44, 0x49, 0x53, 0x54, 0x52, 0x49, + 0x42, 0x55, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x52, 0x41, 0x54, 0x45, 0x47, 0x59, 0x5f, + 0x50, 0x52, 0x4f, 0x5f, 0x52, 0x41, 0x54, 0x41, 0x10, 0x01, 0x12, 0x1e, 0x0a, 0x1a, 0x44, 0x49, + 0x53, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x52, 0x41, 0x54, + 0x45, 0x47, 0x59, 0x5f, 0x52, 0x41, 0x4e, 0x4b, 0x10, 0x02, 0x12, 0x26, 0x0a, 0x22, 0x44, 0x49, 0x53, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x52, 0x41, 0x54, - 0x45, 0x47, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, - 0x00, 0x12, 0x22, 0x0a, 0x1e, 0x44, 0x49, 0x53, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x53, 0x54, 0x52, 0x41, 0x54, 0x45, 0x47, 0x59, 0x5f, 0x50, 0x52, 0x4f, 0x5f, 0x52, - 0x41, 0x54, 0x41, 0x10, 0x01, 0x12, 0x1e, 0x0a, 0x1a, 0x44, 0x49, 0x53, 0x54, 0x52, 0x49, 0x42, - 0x55, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x52, 0x41, 0x54, 0x45, 0x47, 0x59, 0x5f, 0x52, - 0x41, 0x4e, 0x4b, 0x10, 0x02, 0x12, 0x26, 0x0a, 0x22, 0x44, 0x49, 0x53, 0x54, 0x52, 0x49, 0x42, - 0x55, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x52, 0x41, 0x54, 0x45, 0x47, 0x59, 0x5f, 0x52, - 0x41, 0x4e, 0x4b, 0x5f, 0x4c, 0x4f, 0x54, 0x54, 0x45, 0x52, 0x59, 0x10, 0x03, 0x2a, 0x63, 0x0a, - 0x0a, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1b, 0x0a, 0x17, 0x4e, - 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, - 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x4e, 0x4f, 0x44, 0x45, - 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x4f, - 0x52, 0x10, 0x01, 0x12, 0x1d, 0x0a, 0x19, 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, - 0x55, 0x53, 0x5f, 0x4e, 0x4f, 0x4e, 0x5f, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x4f, 0x52, - 0x10, 0x02, 0x2a, 0x59, 0x0a, 0x0b, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x41, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x1c, 0x0a, 0x18, 0x45, 0x50, 0x4f, 0x43, 0x48, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, - 0x16, 0x0a, 0x12, 0x45, 0x50, 0x4f, 0x43, 0x48, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, - 0x53, 0x54, 0x41, 0x52, 0x54, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x45, 0x50, 0x4f, 0x43, 0x48, - 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x44, 0x10, 0x02, 0x2a, 0xa7, 0x01, - 0x0a, 0x13, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x4e, 0x6f, 0x64, 0x65, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x25, 0x0a, 0x21, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, - 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, - 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x24, 0x0a, 0x20, - 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x53, - 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x54, 0x45, 0x4e, 0x44, 0x45, 0x52, 0x4d, 0x49, 0x4e, 0x54, - 0x10, 0x01, 0x12, 0x20, 0x0a, 0x1c, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x4f, 0x52, 0x5f, - 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x52, 0x53, 0x41, - 0x54, 0x5a, 0x10, 0x02, 0x12, 0x21, 0x0a, 0x1d, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x4f, - 0x52, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x45, - 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x03, 0x2a, 0x68, 0x0a, 0x0a, 0x4d, 0x61, 0x72, 0x67, 0x69, - 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x4d, 0x41, 0x52, 0x47, 0x49, 0x4e, 0x5f, - 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x4d, 0x41, 0x52, 0x47, 0x49, 0x4e, 0x5f, 0x4d, 0x4f, 0x44, - 0x45, 0x5f, 0x43, 0x52, 0x4f, 0x53, 0x53, 0x5f, 0x4d, 0x41, 0x52, 0x47, 0x49, 0x4e, 0x10, 0x01, - 0x12, 0x1f, 0x0a, 0x1b, 0x4d, 0x41, 0x52, 0x47, 0x49, 0x4e, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, - 0x49, 0x53, 0x4f, 0x4c, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x4d, 0x41, 0x52, 0x47, 0x49, 0x4e, 0x10, - 0x02, 0x42, 0x27, 0x5a, 0x25, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x65, 0x67, 0x61, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x65, 0x67, 0x61, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x76, 0x65, 0x67, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x45, 0x47, 0x59, 0x5f, 0x52, 0x41, 0x4e, 0x4b, 0x5f, 0x4c, 0x4f, 0x54, 0x54, 0x45, 0x52, 0x59, + 0x10, 0x03, 0x2a, 0x63, 0x0a, 0x0a, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x1b, 0x0a, 0x17, 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, + 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, + 0x15, 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x56, 0x41, 0x4c, + 0x49, 0x44, 0x41, 0x54, 0x4f, 0x52, 0x10, 0x01, 0x12, 0x1d, 0x0a, 0x19, 0x4e, 0x4f, 0x44, 0x45, + 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4e, 0x4f, 0x4e, 0x5f, 0x56, 0x41, 0x4c, 0x49, + 0x44, 0x41, 0x54, 0x4f, 0x52, 0x10, 0x02, 0x2a, 0x59, 0x0a, 0x0b, 0x45, 0x70, 0x6f, 0x63, 0x68, + 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x18, 0x45, 0x50, 0x4f, 0x43, 0x48, 0x5f, + 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, + 0x45, 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x45, 0x50, 0x4f, 0x43, 0x48, 0x5f, 0x41, 0x43, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, + 0x45, 0x50, 0x4f, 0x43, 0x48, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x44, + 0x10, 0x02, 0x2a, 0xa7, 0x01, 0x0a, 0x13, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, + 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x25, 0x0a, 0x21, 0x56, 0x41, + 0x4c, 0x49, 0x44, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x41, + 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x24, 0x0a, 0x20, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x4e, + 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x54, 0x45, 0x4e, 0x44, 0x45, + 0x52, 0x4d, 0x49, 0x4e, 0x54, 0x10, 0x01, 0x12, 0x20, 0x0a, 0x1c, 0x56, 0x41, 0x4c, 0x49, 0x44, + 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, + 0x5f, 0x45, 0x52, 0x53, 0x41, 0x54, 0x5a, 0x10, 0x02, 0x12, 0x21, 0x0a, 0x1d, 0x56, 0x41, 0x4c, + 0x49, 0x44, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, + 0x55, 0x53, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x03, 0x2a, 0x68, 0x0a, 0x0a, + 0x4d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x4d, 0x41, + 0x52, 0x47, 0x49, 0x4e, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x4d, 0x41, 0x52, 0x47, 0x49, + 0x4e, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x43, 0x52, 0x4f, 0x53, 0x53, 0x5f, 0x4d, 0x41, 0x52, + 0x47, 0x49, 0x4e, 0x10, 0x01, 0x12, 0x1f, 0x0a, 0x1b, 0x4d, 0x41, 0x52, 0x47, 0x49, 0x4e, 0x5f, + 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x49, 0x53, 0x4f, 0x4c, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x4d, 0x41, + 0x52, 0x47, 0x49, 0x4e, 0x10, 0x02, 0x42, 0x27, 0x5a, 0x25, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x76, + 0x65, 0x67, 0x61, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x69, 0x6f, 0x2f, 0x76, + 0x65, 0x67, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x76, 0x65, 0x67, 0x61, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var (