Allow to pass custom VUB for IR service calls #790

Merged
fyrchik merged 6 commits from dstepanov-yadro/frostfs-node:fix/ir_vub into master 2024-09-04 19:51:04 +00:00
38 changed files with 421 additions and 187 deletions

View file

@ -1,6 +1,9 @@
package control
import "github.com/spf13/cobra"
import (
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
"github.com/spf13/cobra"
)
var irCmd = &cobra.Command{
Use: "ir",
@ -19,3 +22,13 @@ func initControlIRCmd() {
initControlIRHealthCheckCmd()
initControlIRRemoveContainerCmd()
}
func printVUB(cmd *cobra.Command, vub uint32) {
cmd.Printf("Transaction's valid until block is %d\n", vub)
}
func parseVUB(cmd *cobra.Command) uint32 {
vub, err := cmd.Flags().GetUint32(irFlagNameVUB)
commonCmd.ExitOnErr(cmd, "invalid valid until block value: %w", err)
return vub
fyrchik marked this conversation as resolved Outdated

Why do we need this check? Default value is 0 and it is logically invalid.
I believe cmd.Flags().GetUint32() returns an error if the flag is missing in definitions and cobra prints error immediately otherwise, but this needs check.

Why do we need this check? Default value is 0 and it is logically invalid. I believe `cmd.Flags().GetUint32()` returns an error if the flag is missing in definitions and cobra prints error immediately otherwise, but this needs check.

you are right, fixed

you are right, fixed
}

View file

@ -29,7 +29,7 @@ To check removal status "frostfs-cli container list" command can be used.`,
}
func initControlIRRemoveContainerCmd() {
initControlFlags(removeContainerCmd)
initControlIRFlags(removeContainerCmd)
flags := removeContainerCmd.Flags()
flags.String(commonflags.CIDFlag, "", commonflags.CIDFlagUsage)
@ -60,6 +60,7 @@ func removeContainer(cmd *cobra.Command, _ []string) {
} else {
cmd.Println("User containers sheduled to removal")
}
printVUB(cmd, resp.GetBody().GetVub())
}
func prepareRemoveContainerRequest(cmd *cobra.Command) *ircontrol.RemoveContainerRequest {
@ -90,5 +91,8 @@ func prepareRemoveContainerRequest(cmd *cobra.Command) *ircontrol.RemoveContaine
commonCmd.ExitOnErr(cmd, "invalid container ID: %w", containerID.DecodeString(cidStr))
req.Body.ContainerId = containerID[:]
}
req.Body.Vub = parseVUB(cmd)
return req
}

View file

@ -20,7 +20,7 @@ var removeNodeCmd = &cobra.Command{
}
func initControlIRRemoveNodeCmd() {
initControlFlags(removeNodeCmd)
initControlIRFlags(removeNodeCmd)
flags := removeNodeCmd.Flags()
flags.String("node", "", "Node public key as a hex string")
@ -41,6 +41,7 @@ func removeNode(cmd *cobra.Command, _ []string) {
req := new(ircontrol.RemoveNodeRequest)
req.SetBody(&ircontrol.RemoveNodeRequest_Body{
Key: nodeKey,
Vub: parseVUB(cmd),
})
commonCmd.ExitOnErr(cmd, "could not sign request: %w", ircontrolsrv.SignMessage(pk, req))
@ -55,4 +56,5 @@ func removeNode(cmd *cobra.Command, _ []string) {
verifyResponse(cmd, resp.GetSignature(), resp.GetBody())
cmd.Println("Node removed")
printVUB(cmd, resp.GetBody().GetVub())
}

View file

@ -17,7 +17,7 @@ var tickEpochCmd = &cobra.Command{
}
func initControlIRTickEpochCmd() {
initControlFlags(tickEpochCmd)
initControlIRFlags(tickEpochCmd)
}
func tickEpoch(cmd *cobra.Command, _ []string) {
@ -25,7 +25,9 @@ func tickEpoch(cmd *cobra.Command, _ []string) {
c := getClient(cmd, pk)
req := new(ircontrol.TickEpochRequest)
req.SetBody(new(ircontrol.TickEpochRequest_Body))
req.SetBody(&ircontrol.TickEpochRequest_Body{
Vub: parseVUB(cmd),
})
err := ircontrolsrv.SignMessage(pk, req)
commonCmd.ExitOnErr(cmd, "could not sign request: %w", err)
@ -40,4 +42,5 @@ func tickEpoch(cmd *cobra.Command, _ []string) {
verifyResponse(cmd, resp.GetSignature(), resp.GetBody())
cmd.Println("Epoch tick requested")
printVUB(cmd, resp.GetBody().GetVub())
}

View file

@ -14,6 +14,10 @@ import (
"github.com/spf13/cobra"
)
const (
irFlagNameVUB = "vub"
)
func initControlFlags(cmd *cobra.Command) {
ff := cmd.Flags()
ff.StringP(commonflags.WalletPath, commonflags.WalletPathShorthand, commonflags.WalletPathDefault, commonflags.WalletPathUsage)
@ -22,6 +26,13 @@ func initControlFlags(cmd *cobra.Command) {
ff.DurationP(commonflags.Timeout, commonflags.TimeoutShorthand, commonflags.TimeoutDefault, commonflags.TimeoutUsage)
}
func initControlIRFlags(cmd *cobra.Command) {
initControlFlags(cmd)
ff := cmd.Flags()
ff.Uint32(irFlagNameVUB, 0, "Valid until block value for notary transaction")
}
func signRequest(cmd *cobra.Command, pk *ecdsa.PrivateKey, req controlSvc.SignedMessage) {
err := controlSvc.SignMessage(pk, req)
commonCmd.ExitOnErr(cmd, "could not sign request: %w", err)

View file

@ -418,7 +418,8 @@ func (c *cfg) updateNetMapState(stateSetter func(*nmClient.UpdatePeerPrm)) error
prm.SetKey(c.key.PublicKey().Bytes())
stateSetter(&prm)
return c.cfgNetmap.wrapper.UpdatePeerState(prm)
_, err := c.cfgNetmap.wrapper.UpdatePeerState(prm)
return err
}
type netInfo struct {

View file

@ -246,7 +246,7 @@ type testMorphClient struct {
batchTransferedGas []batchTransferGas
}
func (c *testMorphClient) Invoke(contract util.Uint160, fee fixedn.Fixed8, method string, args ...any) error {
func (c *testMorphClient) Invoke(contract util.Uint160, fee fixedn.Fixed8, method string, args ...any) (uint32, error) {
c.invokedMethods = append(c.invokedMethods,
invokedMethod{
contract: contract,
@ -254,7 +254,7 @@ func (c *testMorphClient) Invoke(contract util.Uint160, fee fixedn.Fixed8, metho
method: method,
args: args,
})
return nil
return 0, nil
}
func (c *testMorphClient) TransferGas(receiver util.Uint160, amount fixedn.Fixed8) error {

View file

@ -30,7 +30,7 @@ func (ap *Processor) processEmit() bool {
}
// there is no signature collecting, so we don't need extra fee
err := ap.morphClient.Invoke(contract, 0, emitMethod)
_, err := ap.morphClient.Invoke(contract, 0, emitMethod)
if err != nil {
ap.log.Warn(logs.AlphabetCantInvokeAlphabetEmitMethod, zap.String("error", err.Error()))

View file

@ -40,7 +40,7 @@ type (
}
morphClient interface {
Invoke(contract util.Uint160, fee fixedn.Fixed8, method string, args ...any) error
Invoke(contract util.Uint160, fee fixedn.Fixed8, method string, args ...any) (uint32, error)
TransferGas(receiver util.Uint160, amount fixedn.Fixed8) error
BatchTransferGas(receivers []util.Uint160, amount fixedn.Fixed8) error
}

View file

@ -399,7 +399,7 @@ func (c *testNetmapClient) NetMap() (*netmap.NetMap, error) {
return c.netmap, nil
}
func (c *testNetmapClient) NewEpoch(epoch uint64, force bool) error {
func (c *testNetmapClient) NewEpoch(epoch uint64) error {
c.newEpochs = append(c.newEpochs, epoch)
return nil
}

View file

@ -77,7 +77,7 @@ func (np *Processor) processNewEpochTick() bool {
nextEpoch := np.epochState.EpochCounter() + 1
np.log.Debug(logs.NetmapNextEpoch, zap.Uint64("value", nextEpoch))
err := np.netmapClient.NewEpoch(nextEpoch, false)
err := np.netmapClient.NewEpoch(nextEpoch)
if err != nil {
np.log.Error(logs.NetmapCantInvokeNetmapNewEpoch, zap.Error(err))
return false

View file

@ -60,7 +60,7 @@ type (
EpochDuration() (uint64, error)
MorphTxHeight(h util.Uint256) (res uint32, err error)
NetMap() (*netmap.NetMap, error)
NewEpoch(epoch uint64, force bool) error
NewEpoch(epoch uint64) error
MorphIsValidScript(script []byte, signers []transaction.Signer) (valid bool, err error)
MorphNotarySignAndInvokeTX(mainTx *transaction.Transaction) error
}

View file

@ -19,11 +19,13 @@ type netmapClientWrapper struct {
}
func (w *netmapClientWrapper) UpdatePeerState(p netmapclient.UpdatePeerPrm) error {
return w.netmapClient.UpdatePeerState(p)
_, err := w.netmapClient.UpdatePeerState(p)
return err
}
func (w *netmapClientWrapper) MorphNotaryInvoke(contract util.Uint160, fee fixedn.Fixed8, nonce uint32, vub *uint32, method string, args ...any) error {
return w.netmapClient.Morph().NotaryInvoke(contract, fee, nonce, vub, method, args...)
_, err := w.netmapClient.Morph().NotaryInvoke(contract, fee, nonce, vub, method, args...)
return err
}
func (w *netmapClientWrapper) ContractAddress() util.Uint160 {
@ -42,8 +44,8 @@ func (w *netmapClientWrapper) NetMap() (*netmap.NetMap, error) {
return w.netmapClient.NetMap()
}
func (w *netmapClientWrapper) NewEpoch(epoch uint64, force bool) error {
return w.netmapClient.NewEpoch(epoch, force)
func (w *netmapClientWrapper) NewEpoch(epoch uint64) error {
return w.netmapClient.NewEpoch(epoch)
}
func (w *netmapClientWrapper) MorphIsValidScript(script []byte, signers []transaction.Signer) (valid bool, err error) {

View file

@ -117,7 +117,7 @@ func (s *Server) voteForSidechainValidator(prm governance.VoteValidatorPrm) erro
)
if prm.Hash != nil {
nonce, vub, err = s.morphClient.CalculateNonceAndVUB(*prm.Hash)
nonce, vub, err = s.morphClient.CalculateNonceAndVUB(prm.Hash)
if err != nil {
return fmt.Errorf("could not calculate nonce and `validUntilBlock` values: %w", err)
}
@ -125,7 +125,7 @@ func (s *Server) voteForSidechainValidator(prm governance.VoteValidatorPrm) erro
}
s.contracts.alphabet.iterate(func(letter GlagoliticLetter, contract util.Uint160) {
err := s.morphClient.NotaryInvoke(contract, s.feeConfig.SideChainFee(), nonce, vubP, voteMethod, epoch, validators)
_, err := s.morphClient.NotaryInvoke(contract, s.feeConfig.SideChainFee(), nonce, vubP, voteMethod, epoch, validators)
if err != nil {
s.log.Warn(logs.InnerringCantInvokeVoteMethodInAlphabetContract,
zap.Int8("alphabet_index", int8(letter)),

View file

@ -36,5 +36,6 @@ func (c *Client) Burn(p BurnPrm) error {
prm.SetArgs(p.to, p.amount, p.id)
prm.InvokePrmOptional = p.InvokePrmOptional
return c.client.Invoke(prm)
_, err := c.client.Invoke(prm)
return err
}

View file

@ -48,5 +48,6 @@ func (c *Client) Lock(p LockPrm) error {
prm.SetArgs(p.id, p.user, p.lock, p.amount, p.dueEpoch)
prm.InvokePrmOptional = p.InvokePrmOptional
return c.client.Invoke(prm)
_, err := c.client.Invoke(prm)
return err
}

View file

@ -36,5 +36,6 @@ func (c *Client) Mint(p MintPrm) error {
prm.SetArgs(p.to, p.amount, p.id)
prm.InvokePrmOptional = p.InvokePrmOptional
return c.client.Invoke(prm)
_, err := c.client.Invoke(prm)
return err
}

View file

@ -39,7 +39,7 @@ func (c *Client) TransferX(p TransferPrm) error {
prm.SetArgs(from, to, p.Amount, p.Details)
prm.InvokePrmOptional = p.InvokePrmOptional
err = c.client.Invoke(prm)
_, err = c.client.Invoke(prm)
if err != nil {
return fmt.Errorf("could not invoke method (%s): %w", transferXMethod, err)
}

View file

@ -174,8 +174,9 @@ func wrapFrostFSError(err error) error {
}
// Invoke invokes contract method by sending transaction into blockchain.
// Returns valid until block value.
// Supported args types: int64, string, util.Uint160, []byte and bool.
func (c *Client) Invoke(contract util.Uint160, fee fixedn.Fixed8, method string, args ...any) error {
func (c *Client) Invoke(contract util.Uint160, fee fixedn.Fixed8, method string, args ...any) (uint32, error) {
start := time.Now()
success := false
defer func() {
@ -186,12 +187,12 @@ func (c *Client) Invoke(contract util.Uint160, fee fixedn.Fixed8, method string,
defer c.switchLock.RUnlock()
if c.inactive {
return ErrConnectionLost
return 0, ErrConnectionLost
}
txHash, vub, err := c.rpcActor.SendTunedCall(contract, method, nil, addFeeCheckerModifier(int64(fee)), args...)
if err != nil {
return fmt.Errorf("could not invoke %s: %w", method, err)
return 0, fmt.Errorf("could not invoke %s: %w", method, err)
}
c.logger.Debug(logs.ClientNeoClientInvoke,
@ -200,7 +201,7 @@ func (c *Client) Invoke(contract util.Uint160, fee fixedn.Fixed8, method string,
zap.Stringer("tx_hash", txHash.Reverse()))
success = true
return nil
return vub, nil
}
// TestInvokeIterator invokes contract method returning an iterator and executes cb on each element.

View file

@ -26,7 +26,8 @@ func Delete(c *Client, witness core.RemovalWitness) error {
prm.SetToken(tok.Marshal())
}
return c.Delete(prm)
_, err := c.Delete(prm)
return err
}
// DeletePrm groups parameters of Delete client operation.
@ -62,13 +63,13 @@ func (d *DeletePrm) SetKey(key []byte) {
// Delete removes the container from FrostFS system
// through Container contract call.
//
// Returns any error encountered that caused
// Returns valid until block and any error encountered that caused
// the removal to interrupt.
//
// If TryNotary is provided, calls notary contract.
func (c *Client) Delete(p DeletePrm) error {
func (c *Client) Delete(p DeletePrm) (uint32, error) {
if len(p.signature) == 0 && !p.IsControl() {
return errNilArgument
return 0, errNilArgument
}
prm := client.InvokePrm{}
@ -76,9 +77,9 @@ func (c *Client) Delete(p DeletePrm) error {
prm.SetArgs(p.cnr, p.signature, p.key, p.token)
prm.InvokePrmOptional = p.InvokePrmOptional
err := c.client.Invoke(prm)
res, err := c.client.Invoke(prm)
if err != nil {
return fmt.Errorf("could not invoke method (%s): %w", deleteMethod, err)
return 0, fmt.Errorf("could not invoke method (%s): %w", deleteMethod, err)
}
return nil
return res.VUB, nil
}

View file

@ -85,7 +85,7 @@ func (c *Client) PutEACL(p PutEACLPrm) error {
prm.SetArgs(p.table, p.sig, p.key, p.token)
prm.InvokePrmOptional = p.InvokePrmOptional
err := c.client.Invoke(prm)
_, err := c.client.Invoke(prm)
if err != nil {
return fmt.Errorf("could not invoke method (%s): %w", setEACLMethod, err)
}

View file

@ -34,7 +34,7 @@ func (c *Client) StartEstimation(p StartEstimationPrm) error {
prm.SetArgs(p.epoch)
prm.InvokePrmOptional = p.InvokePrmOptional
if err := c.client.Invoke(prm); err != nil {
if _, err := c.client.Invoke(prm); err != nil {
return fmt.Errorf("could not invoke method (%s): %w", startEstimationMethod, err)
}
return nil
@ -47,7 +47,7 @@ func (c *Client) StopEstimation(p StopEstimationPrm) error {
prm.SetArgs(p.epoch)
prm.InvokePrmOptional = p.InvokePrmOptional
if err := c.client.Invoke(prm); err != nil {
if _, err := c.client.Invoke(prm); err != nil {
return fmt.Errorf("could not invoke method (%s): %w", stopEstimationMethod, err)
}
return nil

View file

@ -41,7 +41,7 @@ func (c *Client) AnnounceLoad(p AnnounceLoadPrm) error {
prm.SetArgs(p.a.Epoch(), binCnr, p.a.Value(), p.key)
prm.InvokePrmOptional = p.InvokePrmOptional
err := c.client.Invoke(prm)
_, err := c.client.Invoke(prm)
if err != nil {
return fmt.Errorf("could not invoke method (%s): %w", putSizeMethod, err)
}

View file

@ -116,7 +116,7 @@ func (c *Client) Put(p PutPrm) error {
prm.SetMethod(method)
prm.InvokePrmOptional = p.InvokePrmOptional
err := c.client.Invoke(prm)
_, err := c.client.Invoke(prm)
if err != nil {
return fmt.Errorf("could not invoke method (%s): %w", method, err)
}

View file

@ -41,7 +41,7 @@ func (x *Client) BindKeys(p BindKeysPrm) error {
prm.SetArgs(p.scriptHash, p.keys)
prm.InvokePrmOptional = p.InvokePrmOptional
err := x.client.Invoke(prm)
_, err := x.client.Invoke(prm)
if err != nil {
return fmt.Errorf("could not invoke method (%s): %w", bindKeysMethod, err)
}
@ -62,7 +62,7 @@ func (x *Client) UnbindKeys(args UnbindKeysPrm) error {
prm.SetArgs(args.scriptHash, args.keys)
prm.InvokePrmOptional = args.InvokePrmOptional
err := x.client.Invoke(prm)
_, err := x.client.Invoke(prm)
if err != nil {
return fmt.Errorf("could not invoke method (%s): %w", unbindKeysMethod, err)
}

View file

@ -43,7 +43,8 @@ func (x *Client) Cheque(p ChequePrm) error {
prm.SetArgs(p.id, p.user, p.amount, p.lock)
prm.InvokePrmOptional = p.InvokePrmOptional
return x.client.Invoke(prm)
_, err := x.client.Invoke(prm)
return err
}
// AlphabetUpdatePrm groups parameters of AlphabetUpdate operation.
@ -71,5 +72,6 @@ func (x *Client) AlphabetUpdate(p AlphabetUpdatePrm) error {
prm.SetArgs(p.id, p.pubs)
prm.InvokePrmOptional = p.InvokePrmOptional
return x.client.Invoke(prm)
_, err := x.client.Invoke(prm)
return err
}

View file

@ -36,7 +36,7 @@ func (x *Client) AddKeys(p CommonBindPrm) error {
prm.SetArgs(p.ownerID, p.keys)
prm.InvokePrmOptional = p.InvokePrmOptional
err := x.client.Invoke(prm)
_, err := x.client.Invoke(prm)
if err != nil {
return fmt.Errorf("could not invoke method (%s): %w", addKeysMethod, err)
}
@ -52,7 +52,7 @@ func (x *Client) RemoveKeys(args CommonBindPrm) error {
prm.SetArgs(args.ownerID, args.keys)
prm.InvokePrmOptional = args.InvokePrmOptional
err := x.client.Invoke(prm)
_, err := x.client.Invoke(prm)
if err != nil {
return fmt.Errorf("could not invoke method (%s): %w", removeKeysMethod, err)
}

View file

@ -159,7 +159,8 @@ func (c *Client) SetConfig(p SetConfigPrm) error {
prm.SetArgs(p.id, p.key, p.value)
prm.InvokePrmOptional = p.InvokePrmOptional
return c.client.Invoke(prm)
_, err := c.client.Invoke(prm)
return err
}
// RawNetworkParameter is a FrostFS network parameter which is transmitted but

View file

@ -34,7 +34,8 @@ func (c *Client) UpdateInnerRing(p UpdateIRPrm) error {
prm.SetArgs(args)
prm.InvokePrmOptional = p.InvokePrmOptional
return c.client.Invoke(prm)
_, err := c.client.Invoke(prm)
return err
}
// GetInnerRingList return current IR list.

View file

@ -8,17 +8,32 @@ import (
// NewEpoch updates FrostFS epoch number through
// Netmap contract call.
// If `force` is true, this call is normally initiated by a control
// service command and uses a control notary transaction internally
// to ensure all nodes produce the same transaction with high probability.
func (c *Client) NewEpoch(epoch uint64, force bool) error {
func (c *Client) NewEpoch(epoch uint64) error {
prm := client.InvokePrm{}
prm.SetMethod(newEpochMethod)
prm.SetArgs(epoch)
prm.SetControlTX(force)
fyrchik marked this conversation as resolved Outdated

I feel like the interface is starting to blow up: we have 2 parameters specifically to cover IR control service needs.
How about using a separate method? #781 would be easier later and clients are not oblidged to provide unnecessary parameters.

I feel like the interface is starting to blow up: we have 2 parameters specifically to cover IR control service needs. How about using a separate method? #781 would be easier later and clients are not oblidged to provide unnecessary parameters.

This method called by IR and by wrapper, that passes 0 and false. So looks like not complex.

This method called by IR and by wrapper, that passes `0` and `false`. So looks like not complex.

I have simplified wrapper's intrface.

I have simplified wrapper's intrface.

Done

Done
if err := c.client.Invoke(prm); err != nil {
_, err := c.client.Invoke(prm)
if err != nil {
return fmt.Errorf("could not invoke method (%s): %w", newEpochMethod, err)
}
return nil
}
// NewEpochControl updates FrostFS epoch number through
// control notary transaction internally to ensure all
// nodes produce the same transaction with high probability.
// If vub > 0, vub will be used as valid until block value.
func (c *Client) NewEpochControl(epoch uint64, vub uint32) (uint32, error) {
prm := client.InvokePrm{}
prm.SetMethod(newEpochMethod)
prm.SetArgs(epoch)
prm.SetControlTX(true)
prm.SetVUB(vub)
res, err := c.client.Invoke(prm)
if err != nil {
return 0, fmt.Errorf("could not invoke method (%s): %w", newEpochMethod, err)
}
return res.VUB, nil
}

View file

@ -36,24 +36,27 @@ func (c *Client) AddPeer(p AddPeerPrm) error {
prm.SetArgs(p.nodeInfo.Marshal())
prm.InvokePrmOptional = p.InvokePrmOptional
if err := c.client.Invoke(prm); err != nil {
if _, err := c.client.Invoke(prm); err != nil {
return fmt.Errorf("could not invoke method (%s): %w", method, err)
}
return nil
}
// ForceRemovePeer marks the given peer as offline via a notary control transaction.
func (c *Client) ForceRemovePeer(nodeInfo netmap.NodeInfo) error {
// If vub > 0, vub will be used as valid until block value.
func (c *Client) ForceRemovePeer(nodeInfo netmap.NodeInfo, vub uint32) (uint32, error) {
if !c.client.WithNotary() {
return fmt.Errorf("peer can be forcefully removed only in notary environment")
return 0, fmt.Errorf("peer can be forcefully removed only in notary environment")
}
prm := UpdatePeerPrm{}
prm.SetKey(nodeInfo.PublicKey())
prm.SetControlTX(true)
prm.SetVUB(vub)
if err := c.UpdatePeerState(prm); err != nil {
return fmt.Errorf("updating peer state: %v", err)
vub, err := c.UpdatePeerState(prm)
if err != nil {
return 0, fmt.Errorf("updating peer state: %v", err)
}
return nil
return vub, nil
}

View file

@ -36,7 +36,7 @@ func (u *UpdatePeerPrm) SetMaintenance() {
}
// UpdatePeerState changes peer status through Netmap contract call.
func (c *Client) UpdatePeerState(p UpdatePeerPrm) error {
func (c *Client) UpdatePeerState(p UpdatePeerPrm) (uint32, error) {
method := updateStateMethod
if c.client.WithNotary() && c.client.IsAlpha() {
@ -55,8 +55,9 @@ func (c *Client) UpdatePeerState(p UpdatePeerPrm) error {
prm.SetArgs(int64(p.state), p.key)
prm.InvokePrmOptional = p.InvokePrmOptional
if err := c.client.Invoke(prm); err != nil {
return fmt.Errorf("could not invoke smart contract: %w", err)
res, err := c.client.Invoke(prm)
if err != nil {
return 0, fmt.Errorf("could not invoke smart contract: %w", err)
}
return nil
return res.VUB, nil
}

View file

@ -289,7 +289,7 @@ func (c *Client) UpdateNotaryList(prm UpdateNotaryListPrm) error {
panic(notaryNotEnabledPanicMsg)
}
nonce, vub, err := c.CalculateNonceAndVUB(prm.hash)
nonce, vub, err := c.CalculateNonceAndVUB(&prm.hash)
if err != nil {
return fmt.Errorf("could not calculate nonce and `valicUntilBlock` values: %w", err)
}
@ -337,7 +337,7 @@ func (c *Client) UpdateNeoFSAlphabetList(prm UpdateAlphabetListPrm) error {
panic(notaryNotEnabledPanicMsg)
}
nonce, vub, err := c.CalculateNonceAndVUB(prm.hash)
nonce, vub, err := c.CalculateNonceAndVUB(&prm.hash)
if err != nil {
return fmt.Errorf("could not calculate nonce and `valicUntilBlock` values: %w", err)
}
@ -355,13 +355,15 @@ func (c *Client) UpdateNeoFSAlphabetList(prm UpdateAlphabetListPrm) error {
// blockchain. Fallback tx is a `RET`. If Notary support is not enabled
// it fallbacks to a simple `Invoke()`.
//
// Returns valid until block value.
//
// `nonce` and `vub` are used only if notary is enabled.
func (c *Client) NotaryInvoke(contract util.Uint160, fee fixedn.Fixed8, nonce uint32, vub *uint32, method string, args ...any) error {
func (c *Client) NotaryInvoke(contract util.Uint160, fee fixedn.Fixed8, nonce uint32, vub *uint32, method string, args ...any) (uint32, error) {
c.switchLock.RLock()
defer c.switchLock.RUnlock()
if c.inactive {
return ErrConnectionLost
return 0, ErrConnectionLost
}
if c.notary == nil {
@ -376,19 +378,19 @@ func (c *Client) NotaryInvoke(contract util.Uint160, fee fixedn.Fixed8, nonce ui
// not expected to be signed by the current node.
//
// Considered to be used by non-IR nodes.
func (c *Client) NotaryInvokeNotAlpha(contract util.Uint160, fee fixedn.Fixed8, method string, args ...any) error {
func (c *Client) NotaryInvokeNotAlpha(contract util.Uint160, fee fixedn.Fixed8, vubP *uint32, method string, args ...any) (uint32, error) {
c.switchLock.RLock()
defer c.switchLock.RUnlock()
if c.inactive {
return ErrConnectionLost
return 0, ErrConnectionLost
}
if c.notary == nil {
return c.Invoke(contract, fee, method, args...)
}
return c.notaryInvoke(false, false, contract, rand.Uint32(), nil, method, args...)
return c.notaryInvoke(false, false, contract, rand.Uint32(), vubP, method, args...)
}
// NotarySignAndInvokeTX signs and sends notary request that was received from
@ -440,10 +442,11 @@ func (c *Client) NotarySignAndInvokeTX(mainTx *transaction.Transaction) error {
func (c *Client) notaryInvokeAsCommittee(method string, nonce, vub uint32, args ...any) error {
designate := c.GetDesignateHash()
return c.notaryInvoke(true, true, designate, nonce, &vub, method, args...)
_, err := c.notaryInvoke(true, true, designate, nonce, &vub, method, args...)
return err
}
func (c *Client) notaryInvoke(committee, invokedByAlpha bool, contract util.Uint160, nonce uint32, vub *uint32, method string, args ...any) error {
func (c *Client) notaryInvoke(committee, invokedByAlpha bool, contract util.Uint160, nonce uint32, vub *uint32, method string, args ...any) (uint32, error) {
start := time.Now()
success := false
defer func() {
@ -452,22 +455,22 @@ func (c *Client) notaryInvoke(committee, invokedByAlpha bool, contract util.Uint
alphabetList, err := c.notary.alphabetSource()
if err != nil {
return err
return 0, err
}
until, err := c.getUntilValue(vub)
if err != nil {
return err
return 0, err
}
cosigners, err := c.notaryCosigners(invokedByAlpha, alphabetList, committee)
if err != nil {
return err
return 0, err
}
nAct, err := notary.NewActor(c.client, cosigners, c.acc)
if err != nil {
return err
return 0, err
}
mainH, fbH, untilActual, err := nAct.Notarize(nAct.MakeTunedCall(contract, method, nil, func(r *result.Invoke, t *transaction.Transaction) error {
@ -482,7 +485,7 @@ func (c *Client) notaryInvoke(committee, invokedByAlpha bool, contract util.Uint
}, args...))
if err != nil && !alreadyOnChainError(err) {
return err
return 0, err
}
c.logger.Debug(logs.ClientNotaryRequestInvoked,
@ -492,7 +495,7 @@ func (c *Client) notaryInvoke(committee, invokedByAlpha bool, contract util.Uint
zap.String("fallback_hash", fbH.StringLE()))
success = true
return nil
return until, nil
}
func (c *Client) notaryCosignersFromTx(mainTx *transaction.Transaction, alphabetList keys.PublicKeys) ([]actor.SignerAccount, error) {
@ -760,17 +763,19 @@ func CalculateNotaryDepositAmount(c *Client, gasMul, gasDiv int64) (fixedn.Fixed
// CalculateNonceAndVUB calculates nonce and ValidUntilBlock values
// based on transaction hash.
func (c *Client) CalculateNonceAndVUB(hash util.Uint256) (nonce uint32, vub uint32, err error) {
func (c *Client) CalculateNonceAndVUB(hash *util.Uint256) (nonce uint32, vub uint32, err error) {
return c.calculateNonceAndVUB(hash, false)
}
// CalculateNonceAndVUBControl calculates nonce and rounded ValidUntilBlock values
// based on transaction hash for use in control transactions.
func (c *Client) CalculateNonceAndVUBControl(hash util.Uint256) (nonce uint32, vub uint32, err error) {
func (c *Client) CalculateNonceAndVUBControl(hash *util.Uint256) (nonce uint32, vub uint32, err error) {
return c.calculateNonceAndVUB(hash, true)
}
func (c *Client) calculateNonceAndVUB(hash util.Uint256, roundBlockHeight bool) (nonce uint32, vub uint32, err error) {
// If hash specified, transaction's height and hash are used to compute VUB and nonce.
// If not, then current block height used to compute VUB and nonce.
func (c *Client) calculateNonceAndVUB(hash *util.Uint256, roundBlockHeight bool) (nonce uint32, vub uint32, err error) {
c.switchLock.RLock()
defer c.switchLock.RUnlock()
@ -782,11 +787,18 @@ func (c *Client) calculateNonceAndVUB(hash util.Uint256, roundBlockHeight bool)
return 0, 0, nil
}
nonce = binary.LittleEndian.Uint32(hash.BytesLE())
var height uint32

This fix doesn't relates to task, but fixes the situation when vub is computed in different places: in this function when hash != nil, and in notary, when hash == nil.

This fix doesn't relates to task, but fixes the situation when vub is computed in different places: in this function when hash != nil, and in notary, when hash == nil.
height, err := c.getTransactionHeight(hash)
if err != nil {
return 0, 0, fmt.Errorf("could not get transaction height: %w", err)
if hash != nil {
height, err = c.getTransactionHeight(*hash)
if err != nil {
return 0, 0, fmt.Errorf("could not get transaction height: %w", err)
}
} else {
height, err = c.rpcActor.GetBlockCount()
if err != nil {
return 0, 0, fmt.Errorf("could not get chain height: %w", err)
}
}
// For control transactions, we round down the block height to control the
@ -797,7 +809,10 @@ func (c *Client) calculateNonceAndVUB(hash util.Uint256, roundBlockHeight bool)
height = height / inc * inc
}
return nonce, height + c.notary.txValidTime, nil
if hash != nil {
return binary.LittleEndian.Uint32(hash.BytesLE()), height + c.notary.txValidTime, nil
fyrchik marked this conversation as resolved Outdated

Some comments are needed here, it could easily be a typo

Some comments are needed here, it could easily be a typo

Done

Done
}
return height + c.notary.txValidTime, height + c.notary.txValidTime, nil
}
func (c *Client) getTransactionHeight(h util.Uint256) (uint32, error) {

View file

@ -100,6 +100,8 @@ type InvokePrmOptional struct {
// It's only used by notary transactions and it affects only the
// computation of `validUntilBlock` values.
controlTX bool
// vub is used to set custom valid until block value.
vub uint32
}
// SetHash sets optional hash of the transaction.
@ -120,6 +122,15 @@ func (i *InvokePrmOptional) IsControl() bool {
return i.controlTX
}
// SetVUB sets valid until block value.
func (i *InvokePrmOptional) SetVUB(v uint32) {
i.vub = v
}
type InvokeRes struct {
VUB uint32
}
// Invoke calls Invoke method of Client with static internal script hash and fee.
// Supported args types are the same as in Client.
//
@ -129,41 +140,54 @@ func (i *InvokePrmOptional) IsControl() bool {
//
// If fee for the operation executed using specified method is customized, then StaticClient uses it.
// Otherwise, default fee is used.
func (s StaticClient) Invoke(prm InvokePrm) error {
func (s StaticClient) Invoke(prm InvokePrm) (InvokeRes, error) {
var res InvokeRes
var err error
var vubP *uint32
if s.tryNotary {
if s.alpha {
var (
nonce uint32 = 1
vubP *uint32
vub uint32
err error
)
if prm.hash != nil {
if prm.controlTX {
nonce, vub, err = s.client.CalculateNonceAndVUBControl(*prm.hash)
nonce, vub, err = s.client.CalculateNonceAndVUBControl(prm.hash)
} else {
nonce, vub, err = s.client.CalculateNonceAndVUB(*prm.hash)
nonce, vub, err = s.client.CalculateNonceAndVUB(prm.hash)
}
if err != nil {
return fmt.Errorf("could not calculate nonce and VUB for notary alphabet invoke: %w", err)
return InvokeRes{}, fmt.Errorf("could not calculate nonce and VUB for notary alphabet invoke: %w", err)
}
vubP = &vub
}
return s.client.NotaryInvoke(s.scScriptHash, s.fee, nonce, vubP, prm.method, prm.args...)
if prm.vub > 0 {
vubP = &prm.vub
}
res.VUB, err = s.client.NotaryInvoke(s.scScriptHash, s.fee, nonce, vubP, prm.method, prm.args...)
return res, err
}
return s.client.NotaryInvokeNotAlpha(s.scScriptHash, s.fee, prm.method, prm.args...)
if prm.vub > 0 {
vubP = &prm.vub
}
res.VUB, err = s.client.NotaryInvokeNotAlpha(s.scScriptHash, s.fee, vubP, prm.method, prm.args...)
return res, err
}
return s.client.Invoke(
res.VUB, err = s.client.Invoke(
s.scScriptHash,
s.fee,
prm.method,
prm.args...,
)
return res, err
}
// TestInvokePrm groups parameters of the TestInvoke operation.

View file

@ -53,9 +53,11 @@ func (s *Server) TickEpoch(_ context.Context, req *control.TickEpochRequest) (*c
return nil, fmt.Errorf("getting current epoch: %w", err)
}
if err := s.netmapClient.NewEpoch(epoch+1, true); err != nil {
vub, err := s.netmapClient.NewEpochControl(epoch+1, req.GetBody().GetVub())
if err != nil {
return nil, fmt.Errorf("forcing new epoch: %w", err)
}
resp.Body.Vub = vub
if err := SignMessage(&s.prm.key.PrivateKey, resp); err != nil {
return nil, status.Error(codes.Internal, err.Error())
@ -93,9 +95,11 @@ func (s *Server) RemoveNode(_ context.Context, req *control.RemoveNodeRequest) (
return nil, status.Error(codes.FailedPrecondition, "node is already offline")
}
if err := s.netmapClient.ForceRemovePeer(nodeInfo); err != nil {
vub, err := s.netmapClient.ForceRemovePeer(nodeInfo, req.GetBody().GetVub())
if err != nil {
return nil, fmt.Errorf("forcing node removal: %w", err)
}
resp.Body.Vub = vub
if err := SignMessage(&s.prm.key.PrivateKey, resp); err != nil {
return nil, status.Error(codes.Internal, err.Error())
@ -113,13 +117,15 @@ func (s *Server) RemoveContainer(_ context.Context, req *control.RemoveContainer
if len(req.Body.GetContainerId()) > 0 && len(req.Body.GetOwner()) > 0 {
return nil, status.Error(codes.InvalidArgument, "specify the owner and container at the same time is not allowed")
}
var vub uint32
if len(req.Body.GetContainerId()) > 0 {
var containerID cid.ID
if err := containerID.Decode(req.Body.GetContainerId()); err != nil {
return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("failed to parse container ID: %s", err.Error()))
}
if err := s.removeContainer(containerID); err != nil {
var err error
vub, err = s.removeContainer(containerID, req.GetBody().GetVub())
if err != nil {
return nil, err
}
} else {
@ -138,14 +144,17 @@ func (s *Server) RemoveContainer(_ context.Context, req *control.RemoveContainer
}
for _, containerID := range cids {
if err := s.removeContainer(containerID); err != nil {
vub, err = s.removeContainer(containerID, req.GetBody().GetVub())
if err != nil {
return nil, err
}
}
}
resp := &control.RemoveContainerResponse{
Body: &control.RemoveContainerResponse_Body{},
Body: &control.RemoveContainerResponse_Body{
Vub: vub,
},
}
if err := SignMessage(&s.prm.key.PrivateKey, resp); err != nil {
return nil, status.Error(codes.Internal, err.Error())
@ -153,13 +162,15 @@ func (s *Server) RemoveContainer(_ context.Context, req *control.RemoveContainer
return resp, nil
}
func (s *Server) removeContainer(containerID cid.ID) error {
func (s *Server) removeContainer(containerID cid.ID, vub uint32) (uint32, error) {
var prm container.DeletePrm
prm.SetCID(containerID[:])
prm.SetControlTX(true)
prm.SetVUB(vub)
if err := s.containerClient.Delete(prm); err != nil {
return fmt.Errorf("forcing container removal: %w", err)
vub, err := s.containerClient.Delete(prm)
if err != nil {
return 0, fmt.Errorf("forcing container removal: %w", err)
}
return nil
return vub, nil
}

View file

@ -560,6 +560,9 @@ type TickEpochRequest_Body struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Valid until block value override.
Vub uint32 `protobuf:"varint,1,opt,name=vub,proto3" json:"vub,omitempty"`
}
func (x *TickEpochRequest_Body) Reset() {
@ -594,10 +597,20 @@ func (*TickEpochRequest_Body) Descriptor() ([]byte, []int) {
return file_pkg_services_control_ir_service_proto_rawDescGZIP(), []int{2, 0}
}
func (x *TickEpochRequest_Body) GetVub() uint32 {
if x != nil {
return x.Vub
}
return 0
}
type TickEpochResponse_Body struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Valid until block value for transaction.
Vub uint32 `protobuf:"varint,1,opt,name=vub,proto3" json:"vub,omitempty"`
}
func (x *TickEpochResponse_Body) Reset() {
@ -632,12 +645,21 @@ func (*TickEpochResponse_Body) Descriptor() ([]byte, []int) {
return file_pkg_services_control_ir_service_proto_rawDescGZIP(), []int{3, 0}
}
func (x *TickEpochResponse_Body) GetVub() uint32 {
if x != nil {
return x.Vub
}
return 0
}
type RemoveNodeRequest_Body struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
// Valid until block value override.
Vub uint32 `protobuf:"varint,2,opt,name=vub,proto3" json:"vub,omitempty"`
}
func (x *RemoveNodeRequest_Body) Reset() {
@ -679,10 +701,20 @@ func (x *RemoveNodeRequest_Body) GetKey() []byte {
return nil
}
func (x *RemoveNodeRequest_Body) GetVub() uint32 {
if x != nil {
return x.Vub
}
return 0
}
type RemoveNodeResponse_Body struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Valid until block value for transaction.
Vub uint32 `protobuf:"varint,1,opt,name=vub,proto3" json:"vub,omitempty"`
}
func (x *RemoveNodeResponse_Body) Reset() {
@ -717,6 +749,13 @@ func (*RemoveNodeResponse_Body) Descriptor() ([]byte, []int) {
return file_pkg_services_control_ir_service_proto_rawDescGZIP(), []int{5, 0}
}
func (x *RemoveNodeResponse_Body) GetVub() uint32 {
if x != nil {
return x.Vub
}
return 0
}
type RemoveContainerRequest_Body struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@ -724,6 +763,8 @@ type RemoveContainerRequest_Body struct {
ContainerId []byte `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"`
Owner []byte `protobuf:"bytes,2,opt,name=owner,proto3" json:"owner,omitempty"`
// Valid until block value override.
Vub uint32 `protobuf:"varint,3,opt,name=vub,proto3" json:"vub,omitempty"`
}
func (x *RemoveContainerRequest_Body) Reset() {
@ -772,10 +813,20 @@ func (x *RemoveContainerRequest_Body) GetOwner() []byte {
return nil
}
func (x *RemoveContainerRequest_Body) GetVub() uint32 {
if x != nil {
return x.Vub
}
return 0
}
type RemoveContainerResponse_Body struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Valid until block value for transaction.
Vub uint32 `protobuf:"varint,1,opt,name=vub,proto3" json:"vub,omitempty"`
}
func (x *RemoveContainerResponse_Body) Reset() {
@ -810,6 +861,13 @@ func (*RemoveContainerResponse_Body) Descriptor() ([]byte, []int) {
return file_pkg_services_control_ir_service_proto_rawDescGZIP(), []int{7, 0}
}
func (x *RemoveContainerResponse_Body) GetVub() uint32 {
if x != nil {
return x.Vub
}
return 0
}
var File_pkg_services_control_ir_service_proto protoreflect.FileDescriptor
var file_pkg_services_control_ir_service_proto_rawDesc = []byte{
@ -839,7 +897,7 @@ var file_pkg_services_control_ir_service_proto_rawDesc = []byte{
0x3c, 0x0a, 0x0d, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72,
0x6f, 0x6c, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52,
0x0c, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x84, 0x01,
0x0c, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x96, 0x01,
0x0a, 0x10, 0x54, 0x69, 0x63, 0x6b, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x34, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x20, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x54, 0x69, 0x63,
@ -847,82 +905,89 @@ var file_pkg_services_control_ir_service_proto_rawDesc = []byte{
0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x32, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e,
0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x69, 0x72,
0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72,
0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x06, 0x0a, 0x04,
0x42, 0x6f, 0x64, 0x79, 0x22, 0x86, 0x01, 0x0a, 0x11, 0x54, 0x69, 0x63, 0x6b, 0x45, 0x70, 0x6f,
0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x62, 0x6f,
0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e,
0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x54, 0x69, 0x63, 0x6b, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64,
0x79, 0x12, 0x32, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e,
0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x06, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x22, 0x98, 0x01,
0x0a, 0x11, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x12, 0x35, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x21, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x52, 0x65,
0x6d, 0x6f, 0x76, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e,
0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x32, 0x0a, 0x09, 0x73, 0x69,
0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e,
0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74,
0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x18,
0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x88, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x6d,
0x6f, 0x76, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x36, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e,
0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65,
0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x42, 0x6f, 0x64,
0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x32, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61,
0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x69, 0x72, 0x63,
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65,
0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x06, 0x0a, 0x04, 0x42,
0x6f, 0x64, 0x79, 0x22, 0xc9, 0x01, 0x0a, 0x16, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f,
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a,
0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x69,
0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43,
0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e,
0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x32, 0x0a, 0x09, 0x73, 0x69,
0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e,
0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74,
0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x3f,
0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69,
0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f,
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x77, 0x6e,
0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x22,
0x92, 0x01, 0x0a, 0x17, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69,
0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x62,
0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x69, 0x72, 0x63, 0x6f,
0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74,
0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x42, 0x6f,
0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x32, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e,
0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x69, 0x72,
0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72,
0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x06, 0x0a, 0x04,
0x42, 0x6f, 0x64, 0x79, 0x32, 0xcb, 0x02, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4c, 0x0a, 0x0b, 0x48, 0x65, 0x61, 0x6c, 0x74,
0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x1d, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72,
0x6f, 0x6c, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
0x6c, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x09, 0x54, 0x69, 0x63, 0x6b, 0x45, 0x70, 0x6f,
0x63, 0x68, 0x12, 0x1b, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x54,
0x69, 0x63, 0x6b, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x1c, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x54, 0x69, 0x63, 0x6b,
0x45, 0x70, 0x6f, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49, 0x0a,
0x0a, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x1c, 0x2e, 0x69, 0x72,
0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4e, 0x6f,
0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x69, 0x72, 0x63, 0x6f,
0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4e, 0x6f, 0x64, 0x65,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x58, 0x0a, 0x0f, 0x52, 0x65, 0x6d, 0x6f,
0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x21, 0x2e, 0x69, 0x72,
0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f,
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22,
0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76,
0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x42, 0x44, 0x5a, 0x42, 0x67, 0x69, 0x74, 0x2e, 0x66, 0x72, 0x6f, 0x73, 0x74, 0x66,
0x73, 0x2e, 0x69, 0x6e, 0x66, 0x6f, 0x2f, 0x54, 0x72, 0x75, 0x65, 0x43, 0x6c, 0x6f, 0x75, 0x64,
0x4c, 0x61, 0x62, 0x2f, 0x66, 0x72, 0x6f, 0x73, 0x74, 0x66, 0x73, 0x2d, 0x6e, 0x6f, 0x64, 0x65,
0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x72,
0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x18, 0x0a, 0x04,
0x42, 0x6f, 0x64, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x76, 0x75, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28,
0x0d, 0x52, 0x03, 0x76, 0x75, 0x62, 0x22, 0x98, 0x01, 0x0a, 0x11, 0x54, 0x69, 0x63, 0x6b, 0x45,
0x70, 0x6f, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x04,
0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x69, 0x72, 0x63,
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x54, 0x69, 0x63, 0x6b, 0x45, 0x70, 0x6f, 0x63, 0x68,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62,
0x6f, 0x64, 0x79, 0x12, 0x32, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72,
0x6f, 0x6c, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69,
0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x18, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x12,
0x10, 0x0a, 0x03, 0x76, 0x75, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x76, 0x75,
0x62, 0x22, 0xaa, 0x01, 0x0a, 0x11, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4e, 0x6f, 0x64, 0x65,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x35, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
0x6c, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x32,
0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x14, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x53, 0x69,
0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75,
0x72, 0x65, 0x1a, 0x2a, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65,
0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03,
0x76, 0x75, 0x62, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x76, 0x75, 0x62, 0x22, 0x9a,
0x01, 0x0a, 0x12, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e,
0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x32, 0x0a,
0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x14, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x53, 0x69, 0x67,
0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72,
0x65, 0x1a, 0x18, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x76, 0x75, 0x62,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x76, 0x75, 0x62, 0x22, 0xdb, 0x01, 0x0a, 0x16,
0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f,
0x64, 0x79, 0x12, 0x32, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18,
0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
0x6c, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67,
0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x51, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x21,
0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49,
0x64, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c,
0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x76, 0x75, 0x62, 0x18, 0x03,
0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x76, 0x75, 0x62, 0x22, 0xa4, 0x01, 0x0a, 0x17, 0x52, 0x65,
0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e,
0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f,
0x64, 0x79, 0x12, 0x32, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18,
0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
0x6c, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67,
0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x18, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x10,
0x0a, 0x03, 0x76, 0x75, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x76, 0x75, 0x62,
0x32, 0xcb, 0x02, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x53, 0x65, 0x72, 0x76,
0x69, 0x63, 0x65, 0x12, 0x4c, 0x0a, 0x0b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65,
0x63, 0x6b, 0x12, 0x1d, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x48,
0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x1e, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x48, 0x65,
0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x46, 0x0a, 0x09, 0x54, 0x69, 0x63, 0x6b, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x1b,
0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x54, 0x69, 0x63, 0x6b, 0x45,
0x70, 0x6f, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x69, 0x72,
0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x54, 0x69, 0x63, 0x6b, 0x45, 0x70, 0x6f, 0x63,
0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49, 0x0a, 0x0a, 0x52, 0x65, 0x6d,
0x6f, 0x76, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x1c, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74,
0x72, 0x6f, 0x6c, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
0x6c, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x58, 0x0a, 0x0f, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f,
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x21, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74,
0x72, 0x6f, 0x6c, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69,
0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x69, 0x72, 0x63,
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e,
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x44,
0x5a, 0x42, 0x67, 0x69, 0x74, 0x2e, 0x66, 0x72, 0x6f, 0x73, 0x74, 0x66, 0x73, 0x2e, 0x69, 0x6e,
0x66, 0x6f, 0x2f, 0x54, 0x72, 0x75, 0x65, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x4c, 0x61, 0x62, 0x2f,
0x66, 0x72, 0x6f, 0x73, 0x74, 0x66, 0x73, 0x2d, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x70, 0x6b, 0x67,
0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x72, 0x2f, 0x63, 0x6f, 0x6e,
0x74, 0x72, 0x6f, 0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (

View file

@ -21,8 +21,7 @@ service ControlService {
// Health check request.
message HealthCheckRequest {
// Health check request body.
message Body {
}
message Body {}
// Body of health check request message.
Body body = 1;
@ -49,14 +48,20 @@ message HealthCheckResponse {
}
message TickEpochRequest {
message Body{}
message Body{
// Valid until block value override.
uint32 vub = 1;
}
Body body = 1;
Signature signature = 2;
}
message TickEpochResponse {
message Body{}
message Body{
// Valid until block value for transaction.
uint32 vub = 1;
}
Body body = 1;
Signature signature = 2;
@ -65,6 +70,8 @@ message TickEpochResponse {
message RemoveNodeRequest {
message Body{
bytes key = 1;
// Valid until block value override.
uint32 vub = 2;
}
Body body = 1;
@ -72,7 +79,10 @@ message RemoveNodeRequest {
}
message RemoveNodeResponse {
message Body{}
message Body{
// Valid until block value for transaction.
uint32 vub = 1;
}
Body body = 1;
Signature signature = 2;
@ -82,6 +92,8 @@ message RemoveContainerRequest {
message Body{
bytes container_id = 1;
bytes owner = 2;
// Valid until block value override.
uint32 vub = 3;
}
Body body = 1;
@ -89,7 +101,10 @@ message RemoveContainerRequest {
}
message RemoveContainerResponse {
message Body{}
message Body{
// Valid until block value for transaction.
uint32 vub = 1;
}
Body body = 1;
Signature signature = 2;

View file

@ -174,6 +174,7 @@ func (x *TickEpochRequest_Body) StableSize() (size int) {
if x == nil {
return 0
}
size += proto.UInt32Size(1, x.Vub)
return size
}
@ -186,6 +187,14 @@ func (x *TickEpochRequest_Body) StableSize() (size int) {
//
// Structures with the same field values have the same binary format.
func (x *TickEpochRequest_Body) StableMarshal(buf []byte) []byte {
if x == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, x.StableSize())
}
var offset int
offset += proto.UInt32Marshal(1, buf[offset:], x.Vub)
return buf
}
@ -251,6 +260,7 @@ func (x *TickEpochResponse_Body) StableSize() (size int) {
if x == nil {
return 0
}
size += proto.UInt32Size(1, x.Vub)
return size
}
@ -263,6 +273,14 @@ func (x *TickEpochResponse_Body) StableSize() (size int) {
//
// Structures with the same field values have the same binary format.
func (x *TickEpochResponse_Body) StableMarshal(buf []byte) []byte {
if x == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, x.StableSize())
}
var offset int
offset += proto.UInt32Marshal(1, buf[offset:], x.Vub)
return buf
}
@ -329,6 +347,7 @@ func (x *RemoveNodeRequest_Body) StableSize() (size int) {
return 0
}
size += proto.BytesSize(1, x.Key)
size += proto.UInt32Size(2, x.Vub)
return size
}
@ -349,6 +368,7 @@ func (x *RemoveNodeRequest_Body) StableMarshal(buf []byte) []byte {
}
var offset int
offset += proto.BytesMarshal(1, buf[offset:], x.Key)
offset += proto.UInt32Marshal(2, buf[offset:], x.Vub)
return buf
}
@ -414,6 +434,7 @@ func (x *RemoveNodeResponse_Body) StableSize() (size int) {
if x == nil {
return 0
}
size += proto.UInt32Size(1, x.Vub)
return size
}
@ -426,6 +447,14 @@ func (x *RemoveNodeResponse_Body) StableSize() (size int) {
//
// Structures with the same field values have the same binary format.
func (x *RemoveNodeResponse_Body) StableMarshal(buf []byte) []byte {
if x == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, x.StableSize())
}
var offset int
offset += proto.UInt32Marshal(1, buf[offset:], x.Vub)
return buf
}
@ -493,6 +522,7 @@ func (x *RemoveContainerRequest_Body) StableSize() (size int) {
}
size += proto.BytesSize(1, x.ContainerId)
size += proto.BytesSize(2, x.Owner)
size += proto.UInt32Size(3, x.Vub)
return size
}
@ -514,6 +544,7 @@ func (x *RemoveContainerRequest_Body) StableMarshal(buf []byte) []byte {
var offset int
offset += proto.BytesMarshal(1, buf[offset:], x.ContainerId)
offset += proto.BytesMarshal(2, buf[offset:], x.Owner)
offset += proto.UInt32Marshal(3, buf[offset:], x.Vub)
return buf
}
@ -579,6 +610,7 @@ func (x *RemoveContainerResponse_Body) StableSize() (size int) {
if x == nil {
return 0
}
size += proto.UInt32Size(1, x.Vub)
return size
}
@ -591,6 +623,14 @@ func (x *RemoveContainerResponse_Body) StableSize() (size int) {
//
// Structures with the same field values have the same binary format.
func (x *RemoveContainerResponse_Body) StableMarshal(buf []byte) []byte {
if x == nil {
return []byte{}
}
if buf == nil {
buf = make([]byte, x.StableSize())
}
var offset int
offset += proto.UInt32Marshal(1, buf[offset:], x.Vub)
return buf
}