diff --git a/cmd/neofs-node/config/tree/config.go b/cmd/neofs-node/config/tree/config.go new file mode 100644 index 000000000..8fdc11011 --- /dev/null +++ b/cmd/neofs-node/config/tree/config.go @@ -0,0 +1,39 @@ +package treeconfig + +import ( + "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config" +) + +// GRPCConfig is a wrapper over "grpc" config section which provides access +// to gRPC configuration of control service. +type GRPCConfig struct { + cfg *config.Config +} + +const ( + subsection = "tree" + grpcSubsection = "grpc" + + // GRPCEndpointDefault is a default endpoint of gRPC Control service. + GRPCEndpointDefault = "" +) + +// GRPC returns structure that provides access to "grpc" subsection of +// "tree" section. +func GRPC(c *config.Config) GRPCConfig { + return GRPCConfig{ + c.Sub(subsection).Sub(grpcSubsection), + } +} + +// Endpoint returns value of "endpoint" config parameter. +// +// Returns GRPCEndpointDefault if value is not a non-empty string. +func (g GRPCConfig) Endpoint() string { + v := config.String(g.cfg, "endpoint") + if v != "" { + return v + } + + return GRPCEndpointDefault +} diff --git a/cmd/neofs-node/config/tree/config_test.go b/cmd/neofs-node/config/tree/config_test.go new file mode 100644 index 000000000..9ac92fe6d --- /dev/null +++ b/cmd/neofs-node/config/tree/config_test.go @@ -0,0 +1,30 @@ +package treeconfig_test + +import ( + "testing" + + "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config" + configtest "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/test" + treeconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/tree" + "github.com/stretchr/testify/require" +) + +func TestControlSection(t *testing.T) { + t.Run("defaults", func(t *testing.T) { + empty := configtest.EmptyConfig() + + require.Equal(t, treeconfig.GRPCEndpointDefault, treeconfig.GRPC(empty).Endpoint()) + }) + + const path = "../../../../config/example/node" + + var fileConfigTest = func(c *config.Config) { + require.Equal(t, "127.0.0.1:8091", treeconfig.GRPC(c).Endpoint()) + } + + configtest.ForEachFileType(path, fileConfigTest) + + t.Run("ENV", func(t *testing.T) { + configtest.ForEnvFileType(path, fileConfigTest) + }) +} diff --git a/cmd/neofs-node/main.go b/cmd/neofs-node/main.go index 807dce4c3..67aca2812 100644 --- a/cmd/neofs-node/main.go +++ b/cmd/neofs-node/main.go @@ -81,6 +81,7 @@ func initApp(c *cfg) { initAndLog(c, "pprof", initProfiler) initAndLog(c, "prometheus", initMetrics) initAndLog(c, "control", initControlService) + initAndLog(c, "tree", initTreeService) initAndLog(c, "storage engine", func(c *cfg) { fatalOnErr(c.cfgObject.cfgLocalStorage.localStorage.Open()) diff --git a/cmd/neofs-node/tree.go b/cmd/neofs-node/tree.go new file mode 100644 index 000000000..37dd331e6 --- /dev/null +++ b/cmd/neofs-node/tree.go @@ -0,0 +1,41 @@ +package main + +import ( + "context" + "net" + + treeconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/tree" + "github.com/nspcc-dev/neofs-node/pkg/services/tree" + "google.golang.org/grpc" +) + +func initTreeService(c *cfg) { + endpoint := treeconfig.GRPC(c.appCfg).Endpoint() + if endpoint == treeconfig.GRPCEndpointDefault { + return + } + + treeSvc := tree.New( + tree.WithContainerSource(c.cfgObject.cnrSource), + tree.WithNetmapSource(c.netMapSource), + tree.WithPrivateKey(&c.key.PrivateKey), + tree.WithLogger(c.log), + tree.WithStorage(c.cfgObject.cfgLocalStorage.localStorage)) + + treeServer := grpc.NewServer() + + c.onShutdown(func() { + stopGRPC("NeoFS Tree Service API", treeServer, c.log) + treeSvc.Shutdown() + }) + + lis, err := net.Listen("tcp", endpoint) + fatalOnErr(err) + + tree.RegisterTreeServiceServer(treeServer, treeSvc) + + c.workers = append(c.workers, newWorkerFromFunc(func(ctx context.Context) { + treeSvc.Start(ctx) + fatalOnErr(treeServer.Serve(lis)) + })) +} diff --git a/config/example/node.env b/config/example/node.env index 3c674ee71..1c31501f0 100644 --- a/config/example/node.env +++ b/config/example/node.env @@ -46,6 +46,9 @@ NEOFS_GRPC_1_TLS_ENABLED=false NEOFS_CONTROL_AUTHORIZED_KEYS="035839e45d472a3b7769a2a1bd7d54c4ccd4943c3b40f547870e83a8fcbfb3ce11 028f42cfcb74499d7b15b35d9bff260a1c8d27de4f446a627406a382d8961486d6" NEOFS_CONTROL_GRPC_ENDPOINT=localhost:8090 +# Tree service section +NEOFS_TREE_GRPC_ENDPOINT=127.0.0.1:8091 + # Contracts section NEOFS_CONTRACTS_BALANCE=5263abba1abedbf79bb57f3e40b50b4425d2d6cd NEOFS_CONTRACTS_CONTAINER=5d084790d7aa36cea7b53fe897380dab11d2cd3c diff --git a/config/example/node.json b/config/example/node.json index 569aff46f..b3ae78508 100644 --- a/config/example/node.json +++ b/config/example/node.json @@ -84,6 +84,11 @@ "endpoint": "localhost:8090" } }, + "tree": { + "grpc": { + "endpoint": "127.0.0.1:8091" + } + }, "contracts": { "balance": "5263abba1abedbf79bb57f3e40b50b4425d2d6cd", "container": "5d084790d7aa36cea7b53fe897380dab11d2cd3c", diff --git a/config/example/node.yaml b/config/example/node.yaml index b3eec6380..3465eb071 100644 --- a/config/example/node.yaml +++ b/config/example/node.yaml @@ -66,6 +66,10 @@ control: grpc: endpoint: localhost:8090 # endpoint that is listened by the Control Service +tree: + grpc: + endpoint: 127.0.0.1:8091 # endpoint that is listened by the Tree Service + contracts: # side chain NEOFS contract script hashes; optional, override values retrieved from NNS contract balance: 5263abba1abedbf79bb57f3e40b50b4425d2d6cd container: 5d084790d7aa36cea7b53fe897380dab11d2cd3c diff --git a/go.mod b/go.mod index a6ccbecc1..46a96c06f 100644 --- a/go.mod +++ b/go.mod @@ -38,7 +38,10 @@ require ( gopkg.in/yaml.v3 v3.0.1 ) +require google.golang.org/api v0.44.0 + require ( + cloud.google.com/go v0.81.0 // indirect github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210521073959-f0d4d129b7f1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/btcsuite/btcd v0.22.0-beta // indirect @@ -47,8 +50,10 @@ require ( github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/fsnotify/fsnotify v1.4.9 // indirect + github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/golang/snappy v0.0.3 // indirect + github.com/google/go-cmp v0.5.6 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/gorilla/websocket v1.4.2 // indirect github.com/hashicorp/hcl v1.0.0 // indirect @@ -87,12 +92,15 @@ require ( github.com/syndtr/goleveldb v1.0.1-0.20210305035536-64b5b1c73954 // indirect github.com/twmb/murmur3 v1.1.5 // indirect github.com/urfave/cli v1.22.5 // indirect + go.opencensus.io v0.23.0 // indirect go.uber.org/multierr v1.6.0 // indirect golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce // indirect golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect + golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602 // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect golang.org/x/text v0.3.7 // indirect + google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c // indirect gopkg.in/ini.v1 v1.62.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 1c82bb69f..c0f0a43cc 100644 --- a/go.sum +++ b/go.sum @@ -17,6 +17,7 @@ cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKP cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0 h1:at8Tk2zUz63cLPR0JPWm5vp77pEZmzxEQBEfRKn1VV8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= @@ -161,6 +162,7 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -559,6 +561,7 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -687,6 +690,7 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602 h1:0Ja1LBD+yisY6RWM/BH7TJVXWsSjs2VwBSmvSX4HdBc= golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -871,6 +875,7 @@ google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34q google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.44.0 h1:URs6qR1lAxDsqWITsQXI4ZkGiYJ5dHtRNiCpfs2OeKA= google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -878,6 +883,7 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= diff --git a/pkg/services/tree/options.go b/pkg/services/tree/options.go new file mode 100644 index 000000000..2cf2bdf45 --- /dev/null +++ b/pkg/services/tree/options.go @@ -0,0 +1,59 @@ +package tree + +import ( + "crypto/ecdsa" + + "github.com/nspcc-dev/neofs-node/pkg/core/container" + "github.com/nspcc-dev/neofs-node/pkg/core/netmap" + "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/pilorama" + "go.uber.org/zap" +) + +type cfg struct { + log *zap.Logger + key *ecdsa.PrivateKey + nmSource netmap.Source + cnrSource container.Source + forest pilorama.Forest +} + +// Option represents configuration option for a tree service. +type Option func(*cfg) + +// WithContainerSource sets a container source for a tree service. +// This option is required. +func WithContainerSource(src container.Source) Option { + return func(c *cfg) { + c.cnrSource = src + } +} + +// WithNetmapSource sets a netmap source for a tree service. +// This option is required. +func WithNetmapSource(src netmap.Source) Option { + return func(c *cfg) { + c.nmSource = src + } +} + +// WithPrivateKey sets a netmap source for a tree service. +// This option is required. +func WithPrivateKey(key *ecdsa.PrivateKey) Option { + return func(c *cfg) { + c.key = key + } +} + +// WithLogger sets logger for a tree service. +func WithLogger(log *zap.Logger) Option { + return func(c *cfg) { + c.log = log + } +} + +// WithStorage sets tree storage for a service. +func WithStorage(s pilorama.Forest) Option { + return func(c *cfg) { + c.forest = s + } +} diff --git a/pkg/services/tree/replicator.go b/pkg/services/tree/replicator.go new file mode 100644 index 000000000..87cced5b4 --- /dev/null +++ b/pkg/services/tree/replicator.go @@ -0,0 +1,145 @@ +package tree + +import ( + "context" + "crypto/sha256" + "encoding/base64" + "fmt" + "time" + + clientcore "github.com/nspcc-dev/neofs-node/pkg/core/client" + "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/pilorama" + "github.com/nspcc-dev/neofs-node/pkg/network" + "github.com/nspcc-dev/neofs-node/pkg/services/object_manager/placement" + cidSDK "github.com/nspcc-dev/neofs-sdk-go/container/id" + netmapSDK "github.com/nspcc-dev/neofs-sdk-go/netmap" + "go.uber.org/zap" + "google.golang.org/api/option" + "google.golang.org/api/transport/grpc" +) + +type movePair struct { + cid cidSDK.ID + treeID string + op *pilorama.LogMove +} + +const ( + defaultReplicatorCapacity = 64 + defaultReplicatorTimeout = time.Second * 2 +) + +func (s *Service) replicateLoop(ctx context.Context) { + for { + select { + case <-s.closeCh: + case <-ctx.Done(): + return + case op := <-s.replicateCh: + ctx, cancel := context.WithTimeout(ctx, defaultReplicatorTimeout) + err := s.replicate(ctx, op) + cancel() + + if err != nil { + s.log.Error("error during replication", + zap.String("err", err.Error()), + zap.Stringer("cid", op.cid), + zap.String("treeID", op.treeID)) + } + } + } +} + +func (s *Service) replicate(ctx context.Context, op movePair) error { + req := newApplyRequest(&op) + // TODO(@fyrchik): #1328 access control + //err := signature.SignDataWithHandler(s.key, req, func(key, sign []byte) { + // req.Signature = &Signature{ + // Key: key, + // Sign: sign, + // } + //}) + //if err != nil { + // return fmt.Errorf("can't sign data: %w", err) + //} + + nodes, err := s.getContainerNodes(op.cid) + if err != nil { + return fmt.Errorf("can't get container nodes: %w", err) + } + + var node clientcore.NodeInfo + for _, n := range nodes { + var lastErr error + + n.IterateNetworkEndpoints(func(addr string) bool { + cc, err := grpc.Dial(ctx, option.WithEndpoint(addr)) + if err != nil { + lastErr = err + return false + } + + // TODO cache clients + c := NewTreeServiceClient(cc) + + _, lastErr = c.Apply(ctx, req) + return lastErr == nil + }) + + if lastErr != nil { + s.log.Warn("failed to sent update to the node", + zap.String("last_error", lastErr.Error()), + zap.String("address", network.StringifyGroup(node.AddressGroup())), + zap.String("key", base64.StdEncoding.EncodeToString(node.PublicKey()))) + } + } + return nil +} + +func (s *Service) pushToQueue(cid cidSDK.ID, treeID string, op *pilorama.LogMove) { + s.replicateCh <- movePair{ + cid: cid, + treeID: treeID, + op: op, + } +} + +func (s *Service) getContainerNodes(cid cidSDK.ID) ([]netmapSDK.NodeInfo, error) { + nm, err := s.nmSource.GetNetMap(0) + if err != nil { + return nil, fmt.Errorf("can't get netmap: %w", err) + } + + cnr, err := s.cnrSource.Get(cid) + if err != nil { + return nil, fmt.Errorf("can't get container: %w", err) + } + + policy := cnr.Value.PlacementPolicy() + rawCID := make([]byte, sha256.Size) + cid.Encode(rawCID) + + nodes, err := nm.ContainerNodes(policy, rawCID) + if err != nil { + return nil, err + } + + return placement.FlattenNodes(nodes), nil +} + +func newApplyRequest(op *movePair) *ApplyRequest { + rawCID := make([]byte, sha256.Size) + op.cid.Encode(rawCID) + + return &ApplyRequest{ + Body: &ApplyRequest_Body{ + ContainerId: rawCID, + TreeId: op.treeID, + Operation: &LogMove{ + ParentId: op.op.Parent, + Meta: op.op.Meta.Bytes(), + ChildId: op.op.Child, + }, + }, + } +} diff --git a/pkg/services/tree/service.go b/pkg/services/tree/service.go new file mode 100644 index 000000000..00de22b8a --- /dev/null +++ b/pkg/services/tree/service.go @@ -0,0 +1,294 @@ +package tree + +import ( + "bytes" + "context" + "errors" + "fmt" + + "github.com/nspcc-dev/neofs-api-go/v2/signature" + "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/pilorama" + cidSDK "github.com/nspcc-dev/neofs-sdk-go/container/id" + "go.uber.org/zap" +) + +// Service represents tree-service capable of working with multiple +// instances of CRDT trees. +type Service struct { + cfg + + replicateCh chan movePair + closeCh chan struct{} +} + +var _ TreeServiceServer = (*Service)(nil) + +// New creates new tree service instance. +func New(opts ...Option) *Service { + var s Service + for i := range opts { + opts[i](&s.cfg) + } + + if s.log == nil { + s.log = zap.NewNop() + } + + s.closeCh = make(chan struct{}) + s.replicateCh = make(chan movePair, defaultReplicatorCapacity) + + return &s +} + +// Start starts the service. +func (s *Service) Start(ctx context.Context) { + go s.replicateLoop(ctx) +} + +// Shutdown shutdowns the service. +func (s *Service) Shutdown() { + close(s.closeCh) +} + +func (s *Service) Add(_ context.Context, req *AddRequest) (*AddResponse, error) { + b := req.GetBody() + + var cid cidSDK.ID + if err := cid.Decode(b.GetContainerId()); err != nil { + return nil, err + } + + err := s.verifyClient(req, cid, req.GetSignature().GetKey()) + if err != nil { + return nil, err + } + + log, err := s.forest.TreeMove(cid, b.GetTreeId(), &pilorama.Move{ + Parent: b.GetParentId(), + Child: pilorama.RootID, + Meta: pilorama.Meta{Items: constructMeta(b.GetMeta())}, + }) + if err != nil { + return nil, err + } + + s.pushToQueue(cid, b.GetTreeId(), log) + return &AddResponse{ + Body: &AddResponse_Body{ + NodeId: log.Child, + }, + }, nil +} + +func (s *Service) AddByPath(_ context.Context, req *AddByPathRequest) (*AddByPathResponse, error) { + b := req.GetBody() + + var cid cidSDK.ID + if err := cid.Decode(b.GetContainerId()); err != nil { + return nil, err + } + + err := s.verifyClient(req, cid, req.GetSignature().GetKey()) + if err != nil { + return nil, err + } + + meta := constructMeta(b.GetMeta()) + + attr := b.GetPathAttribute() + if len(attr) == 0 { + attr = pilorama.AttributeFilename + } + + logs, err := s.forest.TreeAddByPath(cid, b.GetTreeId(), attr, b.GetPath(), meta) + if err != nil { + return nil, err + } + + for i := range logs { + s.pushToQueue(cid, b.GetTreeId(), &logs[i]) + } + + nodes := make([]uint64, len(logs)) + nodes[0] = logs[len(logs)-1].Child + for i, l := range logs[:len(logs)-1] { + nodes[i+1] = l.Child + } + + return &AddByPathResponse{ + Body: &AddByPathResponse_Body{ + Nodes: nodes, + }, + }, nil +} + +func (s *Service) Remove(_ context.Context, req *RemoveRequest) (*RemoveResponse, error) { + b := req.GetBody() + + var cid cidSDK.ID + if err := cid.Decode(b.GetContainerId()); err != nil { + return nil, err + } + + err := s.verifyClient(req, cid, req.GetSignature().GetKey()) + if err != nil { + return nil, err + } + + if b.GetNodeId() == pilorama.RootID { + return nil, fmt.Errorf("node with ID %d is root and can't be removed", b.GetNodeId()) + } + + log, err := s.forest.TreeMove(cid, b.GetTreeId(), &pilorama.Move{ + Parent: pilorama.TrashID, + Child: b.GetNodeId(), + }) + if err != nil { + return nil, err + } + + s.pushToQueue(cid, b.GetTreeId(), log) + return new(RemoveResponse), nil +} + +// Move applies client operation to the specified tree and pushes in queue +// for replication on other nodes. +func (s *Service) Move(_ context.Context, req *MoveRequest) (*MoveResponse, error) { + b := req.GetBody() + + var cid cidSDK.ID + if err := cid.Decode(b.GetContainerId()); err != nil { + return nil, err + } + + err := s.verifyClient(req, cid, req.GetSignature().GetKey()) + if err != nil { + return nil, err + } + + if b.GetNodeId() == pilorama.RootID { + return nil, fmt.Errorf("node with ID %d is root and can't be moved", b.GetNodeId()) + } + + log, err := s.forest.TreeMove(cid, b.GetTreeId(), &pilorama.Move{ + Parent: b.GetParentId(), + Child: b.GetNodeId(), + Meta: pilorama.Meta{Items: constructMeta(b.GetMeta())}, + }) + if err != nil { + return nil, err + } + + s.pushToQueue(cid, b.GetTreeId(), log) + return new(MoveResponse), nil +} + +func (s *Service) GetNodeByPath(_ context.Context, req *GetNodeByPathRequest) (*GetNodeByPathResponse, error) { + b := req.GetBody() + + var cid cidSDK.ID + if err := cid.Decode(b.GetContainerId()); err != nil { + return nil, err + } + + attr := b.GetPathAttribute() + if len(attr) == 0 { + attr = pilorama.AttributeFilename + } + + nodes, err := s.forest.TreeGetByPath(cid, b.GetTreeId(), attr, b.GetPath(), b.GetLatestOnly()) + if err != nil { + return nil, err + } + + info := make([]*GetNodeByPathResponse_Info, 0, len(nodes)) + for _, node := range nodes { + m, err := s.forest.TreeGetMeta(cid, b.GetTreeId(), node) + if err != nil { + return nil, err + } + + var x GetNodeByPathResponse_Info + x.NodeId = node + x.Timestamp = m.Time + for _, kv := range m.Items { + needAttr := b.AllAttributes + if !needAttr { + for _, attr := range b.GetAttributes() { + if kv.Key == attr { + needAttr = true + break + } + } + } + + if needAttr { + x.Meta = append(x.Meta, &KeyValue{ + Key: kv.Key, + Value: kv.Value, + }) + } + } + info = append(info, &x) + } + + return &GetNodeByPathResponse{ + Body: &GetNodeByPathResponse_Body{ + Nodes: info, + }, + }, nil +} + +func (s *Service) GetSubTree(_ context.Context, req *GetSubTreeRequest) (*GetSubTreeResponse, error) { + return nil, errors.New("GetSubTree is unimplemented") +} + +// Apply locally applies operation from the remote node to the tree. +func (s *Service) Apply(_ context.Context, req *ApplyRequest) (*ApplyResponse, error) { + err := signature.VerifyServiceMessage(req) + if err != nil { + return nil, err + } + + var cid cidSDK.ID + if err := cid.Decode(req.GetBody().GetContainerId()); err != nil { + return nil, err + } + + found := false + key := req.GetSignature().GetKey() + nodes, _ := s.getContainerNodes(cid) + +loop: + for _, n := range nodes { + if bytes.Equal(key, n.PublicKey()) { + found = true + break loop + } + } + if !found { + return nil, errors.New("`Apply` request must be signed by a container node") + } + + op := req.GetBody().GetOperation() + + var meta pilorama.Meta + if err := meta.FromBytes(op.GetMeta()); err != nil { + return nil, fmt.Errorf("can't parse meta-information: %w", err) + } + + return nil, s.forest.TreeApply(cid, req.GetBody().GetTreeId(), &pilorama.Move{ + Parent: op.GetParentId(), + Child: op.GetChildId(), + Meta: meta, + }) +} + +func constructMeta(arr []*KeyValue) []pilorama.KeyValue { + meta := make([]pilorama.KeyValue, len(arr)) + for i, kv := range arr { + meta[i].Key = kv.Key + meta[i].Value = kv.Value + } + return meta +} diff --git a/pkg/services/tree/service.pb.go b/pkg/services/tree/service.pb.go new file mode 100644 index 000000000..bf1f26904 --- /dev/null +++ b/pkg/services/tree/service.pb.go @@ -0,0 +1,2453 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v3.19.4 +// source: pkg/services/tree/service.proto + +package tree + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type AddRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Body *AddRequest_Body `protobuf:"bytes,1,opt,name=body,proto3" json:"body,omitempty"` + Signature *Signature `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (x *AddRequest) Reset() { + *x = AddRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AddRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddRequest) ProtoMessage() {} + +func (x *AddRequest) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AddRequest.ProtoReflect.Descriptor instead. +func (*AddRequest) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{0} +} + +func (x *AddRequest) GetBody() *AddRequest_Body { + if x != nil { + return x.Body + } + return nil +} + +func (x *AddRequest) GetSignature() *Signature { + if x != nil { + return x.Signature + } + return nil +} + +type AddResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Body *AddResponse_Body `protobuf:"bytes,1,opt,name=body,proto3" json:"body,omitempty"` + Signature *Signature `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (x *AddResponse) Reset() { + *x = AddResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AddResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddResponse) ProtoMessage() {} + +func (x *AddResponse) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AddResponse.ProtoReflect.Descriptor instead. +func (*AddResponse) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{1} +} + +func (x *AddResponse) GetBody() *AddResponse_Body { + if x != nil { + return x.Body + } + return nil +} + +func (x *AddResponse) GetSignature() *Signature { + if x != nil { + return x.Signature + } + return nil +} + +type AddByPathRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Body *AddByPathRequest_Body `protobuf:"bytes,1,opt,name=body,proto3" json:"body,omitempty"` + Signature *Signature `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (x *AddByPathRequest) Reset() { + *x = AddByPathRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AddByPathRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddByPathRequest) ProtoMessage() {} + +func (x *AddByPathRequest) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AddByPathRequest.ProtoReflect.Descriptor instead. +func (*AddByPathRequest) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{2} +} + +func (x *AddByPathRequest) GetBody() *AddByPathRequest_Body { + if x != nil { + return x.Body + } + return nil +} + +func (x *AddByPathRequest) GetSignature() *Signature { + if x != nil { + return x.Signature + } + return nil +} + +type AddByPathResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Body *AddByPathResponse_Body `protobuf:"bytes,1,opt,name=body,proto3" json:"body,omitempty"` + Signature *Signature `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (x *AddByPathResponse) Reset() { + *x = AddByPathResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AddByPathResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddByPathResponse) ProtoMessage() {} + +func (x *AddByPathResponse) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AddByPathResponse.ProtoReflect.Descriptor instead. +func (*AddByPathResponse) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{3} +} + +func (x *AddByPathResponse) GetBody() *AddByPathResponse_Body { + if x != nil { + return x.Body + } + return nil +} + +func (x *AddByPathResponse) GetSignature() *Signature { + if x != nil { + return x.Signature + } + return nil +} + +type RemoveRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Body *RemoveRequest_Body `protobuf:"bytes,1,opt,name=body,proto3" json:"body,omitempty"` + Signature *Signature `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (x *RemoveRequest) Reset() { + *x = RemoveRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemoveRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveRequest) ProtoMessage() {} + +func (x *RemoveRequest) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RemoveRequest.ProtoReflect.Descriptor instead. +func (*RemoveRequest) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{4} +} + +func (x *RemoveRequest) GetBody() *RemoveRequest_Body { + if x != nil { + return x.Body + } + return nil +} + +func (x *RemoveRequest) GetSignature() *Signature { + if x != nil { + return x.Signature + } + return nil +} + +type RemoveResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Body *RemoveResponse_Body `protobuf:"bytes,1,opt,name=body,proto3" json:"body,omitempty"` + Signature *Signature `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (x *RemoveResponse) Reset() { + *x = RemoveResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemoveResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveResponse) ProtoMessage() {} + +func (x *RemoveResponse) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RemoveResponse.ProtoReflect.Descriptor instead. +func (*RemoveResponse) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{5} +} + +func (x *RemoveResponse) GetBody() *RemoveResponse_Body { + if x != nil { + return x.Body + } + return nil +} + +func (x *RemoveResponse) GetSignature() *Signature { + if x != nil { + return x.Signature + } + return nil +} + +type MoveRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Body *MoveRequest_Body `protobuf:"bytes,1,opt,name=body,proto3" json:"body,omitempty"` + Signature *Signature `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (x *MoveRequest) Reset() { + *x = MoveRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MoveRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MoveRequest) ProtoMessage() {} + +func (x *MoveRequest) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MoveRequest.ProtoReflect.Descriptor instead. +func (*MoveRequest) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{6} +} + +func (x *MoveRequest) GetBody() *MoveRequest_Body { + if x != nil { + return x.Body + } + return nil +} + +func (x *MoveRequest) GetSignature() *Signature { + if x != nil { + return x.Signature + } + return nil +} + +type MoveResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Body *MoveResponse_Body `protobuf:"bytes,1,opt,name=body,proto3" json:"body,omitempty"` + Signature *Signature `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (x *MoveResponse) Reset() { + *x = MoveResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MoveResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MoveResponse) ProtoMessage() {} + +func (x *MoveResponse) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MoveResponse.ProtoReflect.Descriptor instead. +func (*MoveResponse) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{7} +} + +func (x *MoveResponse) GetBody() *MoveResponse_Body { + if x != nil { + return x.Body + } + return nil +} + +func (x *MoveResponse) GetSignature() *Signature { + if x != nil { + return x.Signature + } + return nil +} + +type GetNodeByPathRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Body *GetNodeByPathRequest_Body `protobuf:"bytes,1,opt,name=body,proto3" json:"body,omitempty"` + Signature *Signature `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (x *GetNodeByPathRequest) Reset() { + *x = GetNodeByPathRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetNodeByPathRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetNodeByPathRequest) ProtoMessage() {} + +func (x *GetNodeByPathRequest) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetNodeByPathRequest.ProtoReflect.Descriptor instead. +func (*GetNodeByPathRequest) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{8} +} + +func (x *GetNodeByPathRequest) GetBody() *GetNodeByPathRequest_Body { + if x != nil { + return x.Body + } + return nil +} + +func (x *GetNodeByPathRequest) GetSignature() *Signature { + if x != nil { + return x.Signature + } + return nil +} + +type GetNodeByPathResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Body *GetNodeByPathResponse_Body `protobuf:"bytes,1,opt,name=body,proto3" json:"body,omitempty"` + Signature *Signature `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (x *GetNodeByPathResponse) Reset() { + *x = GetNodeByPathResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetNodeByPathResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetNodeByPathResponse) ProtoMessage() {} + +func (x *GetNodeByPathResponse) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetNodeByPathResponse.ProtoReflect.Descriptor instead. +func (*GetNodeByPathResponse) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{9} +} + +func (x *GetNodeByPathResponse) GetBody() *GetNodeByPathResponse_Body { + if x != nil { + return x.Body + } + return nil +} + +func (x *GetNodeByPathResponse) GetSignature() *Signature { + if x != nil { + return x.Signature + } + return nil +} + +type GetSubTreeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Body *GetSubTreeRequest_Body `protobuf:"bytes,1,opt,name=body,proto3" json:"body,omitempty"` + Signature *Signature `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (x *GetSubTreeRequest) Reset() { + *x = GetSubTreeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetSubTreeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetSubTreeRequest) ProtoMessage() {} + +func (x *GetSubTreeRequest) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetSubTreeRequest.ProtoReflect.Descriptor instead. +func (*GetSubTreeRequest) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{10} +} + +func (x *GetSubTreeRequest) GetBody() *GetSubTreeRequest_Body { + if x != nil { + return x.Body + } + return nil +} + +func (x *GetSubTreeRequest) GetSignature() *Signature { + if x != nil { + return x.Signature + } + return nil +} + +type GetSubTreeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Body *GetSubTreeResponse_Body `protobuf:"bytes,1,opt,name=body,proto3" json:"body,omitempty"` + Signature *Signature `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (x *GetSubTreeResponse) Reset() { + *x = GetSubTreeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetSubTreeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetSubTreeResponse) ProtoMessage() {} + +func (x *GetSubTreeResponse) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetSubTreeResponse.ProtoReflect.Descriptor instead. +func (*GetSubTreeResponse) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{11} +} + +func (x *GetSubTreeResponse) GetBody() *GetSubTreeResponse_Body { + if x != nil { + return x.Body + } + return nil +} + +func (x *GetSubTreeResponse) GetSignature() *Signature { + if x != nil { + return x.Signature + } + return nil +} + +type ApplyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Body *ApplyRequest_Body `protobuf:"bytes,1,opt,name=body,proto3" json:"body,omitempty"` + Signature *Signature `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (x *ApplyRequest) Reset() { + *x = ApplyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ApplyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ApplyRequest) ProtoMessage() {} + +func (x *ApplyRequest) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ApplyRequest.ProtoReflect.Descriptor instead. +func (*ApplyRequest) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{12} +} + +func (x *ApplyRequest) GetBody() *ApplyRequest_Body { + if x != nil { + return x.Body + } + return nil +} + +func (x *ApplyRequest) GetSignature() *Signature { + if x != nil { + return x.Signature + } + return nil +} + +type ApplyResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Body *ApplyResponse_Body `protobuf:"bytes,1,opt,name=body,proto3" json:"body,omitempty"` + Signature *Signature `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (x *ApplyResponse) Reset() { + *x = ApplyResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ApplyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ApplyResponse) ProtoMessage() {} + +func (x *ApplyResponse) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ApplyResponse.ProtoReflect.Descriptor instead. +func (*ApplyResponse) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{13} +} + +func (x *ApplyResponse) GetBody() *ApplyResponse_Body { + if x != nil { + return x.Body + } + return nil +} + +func (x *ApplyResponse) GetSignature() *Signature { + if x != nil { + return x.Signature + } + return nil +} + +type AddRequest_Body struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ContainerId []byte `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` + TreeId string `protobuf:"bytes,2,opt,name=tree_id,json=treeId,proto3" json:"tree_id,omitempty"` + ParentId uint64 `protobuf:"varint,3,opt,name=parent_id,json=parentId,proto3" json:"parent_id,omitempty"` + Meta []*KeyValue `protobuf:"bytes,4,rep,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *AddRequest_Body) Reset() { + *x = AddRequest_Body{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AddRequest_Body) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddRequest_Body) ProtoMessage() {} + +func (x *AddRequest_Body) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AddRequest_Body.ProtoReflect.Descriptor instead. +func (*AddRequest_Body) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{0, 0} +} + +func (x *AddRequest_Body) GetContainerId() []byte { + if x != nil { + return x.ContainerId + } + return nil +} + +func (x *AddRequest_Body) GetTreeId() string { + if x != nil { + return x.TreeId + } + return "" +} + +func (x *AddRequest_Body) GetParentId() uint64 { + if x != nil { + return x.ParentId + } + return 0 +} + +func (x *AddRequest_Body) GetMeta() []*KeyValue { + if x != nil { + return x.Meta + } + return nil +} + +type AddResponse_Body struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + NodeId uint64 `protobuf:"varint,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` +} + +func (x *AddResponse_Body) Reset() { + *x = AddResponse_Body{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AddResponse_Body) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddResponse_Body) ProtoMessage() {} + +func (x *AddResponse_Body) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AddResponse_Body.ProtoReflect.Descriptor instead. +func (*AddResponse_Body) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{1, 0} +} + +func (x *AddResponse_Body) GetNodeId() uint64 { + if x != nil { + return x.NodeId + } + return 0 +} + +type AddByPathRequest_Body struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ContainerId []byte `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` + TreeId string `protobuf:"bytes,2,opt,name=tree_id,json=treeId,proto3" json:"tree_id,omitempty"` + PathAttribute string `protobuf:"bytes,3,opt,name=path_attribute,json=pathAttribute,proto3" json:"path_attribute,omitempty"` + Path []string `protobuf:"bytes,4,rep,name=path,proto3" json:"path,omitempty"` + Meta []*KeyValue `protobuf:"bytes,5,rep,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *AddByPathRequest_Body) Reset() { + *x = AddByPathRequest_Body{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AddByPathRequest_Body) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddByPathRequest_Body) ProtoMessage() {} + +func (x *AddByPathRequest_Body) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AddByPathRequest_Body.ProtoReflect.Descriptor instead. +func (*AddByPathRequest_Body) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{2, 0} +} + +func (x *AddByPathRequest_Body) GetContainerId() []byte { + if x != nil { + return x.ContainerId + } + return nil +} + +func (x *AddByPathRequest_Body) GetTreeId() string { + if x != nil { + return x.TreeId + } + return "" +} + +func (x *AddByPathRequest_Body) GetPathAttribute() string { + if x != nil { + return x.PathAttribute + } + return "" +} + +func (x *AddByPathRequest_Body) GetPath() []string { + if x != nil { + return x.Path + } + return nil +} + +func (x *AddByPathRequest_Body) GetMeta() []*KeyValue { + if x != nil { + return x.Meta + } + return nil +} + +type AddByPathResponse_Body struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Nodes []uint64 `protobuf:"varint,1,rep,packed,name=nodes,proto3" json:"nodes,omitempty"` + ParentId uint64 `protobuf:"varint,2,opt,name=parent_id,json=parentId,proto3" json:"parent_id,omitempty"` +} + +func (x *AddByPathResponse_Body) Reset() { + *x = AddByPathResponse_Body{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AddByPathResponse_Body) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddByPathResponse_Body) ProtoMessage() {} + +func (x *AddByPathResponse_Body) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AddByPathResponse_Body.ProtoReflect.Descriptor instead. +func (*AddByPathResponse_Body) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{3, 0} +} + +func (x *AddByPathResponse_Body) GetNodes() []uint64 { + if x != nil { + return x.Nodes + } + return nil +} + +func (x *AddByPathResponse_Body) GetParentId() uint64 { + if x != nil { + return x.ParentId + } + return 0 +} + +type RemoveRequest_Body struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ContainerId []byte `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` + TreeId string `protobuf:"bytes,2,opt,name=tree_id,json=treeId,proto3" json:"tree_id,omitempty"` + NodeId uint64 `protobuf:"varint,3,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` +} + +func (x *RemoveRequest_Body) Reset() { + *x = RemoveRequest_Body{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemoveRequest_Body) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveRequest_Body) ProtoMessage() {} + +func (x *RemoveRequest_Body) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RemoveRequest_Body.ProtoReflect.Descriptor instead. +func (*RemoveRequest_Body) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{4, 0} +} + +func (x *RemoveRequest_Body) GetContainerId() []byte { + if x != nil { + return x.ContainerId + } + return nil +} + +func (x *RemoveRequest_Body) GetTreeId() string { + if x != nil { + return x.TreeId + } + return "" +} + +func (x *RemoveRequest_Body) GetNodeId() uint64 { + if x != nil { + return x.NodeId + } + return 0 +} + +type RemoveResponse_Body struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *RemoveResponse_Body) Reset() { + *x = RemoveResponse_Body{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemoveResponse_Body) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveResponse_Body) ProtoMessage() {} + +func (x *RemoveResponse_Body) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RemoveResponse_Body.ProtoReflect.Descriptor instead. +func (*RemoveResponse_Body) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{5, 0} +} + +type MoveRequest_Body struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // TODO import neo.fs.v2.refs.ContainerID directly. + ContainerId []byte `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` + TreeId string `protobuf:"bytes,2,opt,name=tree_id,json=treeId,proto3" json:"tree_id,omitempty"` + ParentId uint64 `protobuf:"varint,3,opt,name=parent_id,json=parentId,proto3" json:"parent_id,omitempty"` + NodeId uint64 `protobuf:"varint,4,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` + Meta []*KeyValue `protobuf:"bytes,5,rep,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *MoveRequest_Body) Reset() { + *x = MoveRequest_Body{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MoveRequest_Body) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MoveRequest_Body) ProtoMessage() {} + +func (x *MoveRequest_Body) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MoveRequest_Body.ProtoReflect.Descriptor instead. +func (*MoveRequest_Body) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{6, 0} +} + +func (x *MoveRequest_Body) GetContainerId() []byte { + if x != nil { + return x.ContainerId + } + return nil +} + +func (x *MoveRequest_Body) GetTreeId() string { + if x != nil { + return x.TreeId + } + return "" +} + +func (x *MoveRequest_Body) GetParentId() uint64 { + if x != nil { + return x.ParentId + } + return 0 +} + +func (x *MoveRequest_Body) GetNodeId() uint64 { + if x != nil { + return x.NodeId + } + return 0 +} + +func (x *MoveRequest_Body) GetMeta() []*KeyValue { + if x != nil { + return x.Meta + } + return nil +} + +type MoveResponse_Body struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *MoveResponse_Body) Reset() { + *x = MoveResponse_Body{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MoveResponse_Body) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MoveResponse_Body) ProtoMessage() {} + +func (x *MoveResponse_Body) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MoveResponse_Body.ProtoReflect.Descriptor instead. +func (*MoveResponse_Body) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{7, 0} +} + +type GetNodeByPathRequest_Body struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ContainerId []byte `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` + TreeId string `protobuf:"bytes,2,opt,name=tree_id,json=treeId,proto3" json:"tree_id,omitempty"` + PathAttribute string `protobuf:"bytes,3,opt,name=path_attribute,json=pathAttribute,proto3" json:"path_attribute,omitempty"` + Path []string `protobuf:"bytes,4,rep,name=path,proto3" json:"path,omitempty"` + Attributes []string `protobuf:"bytes,5,rep,name=attributes,proto3" json:"attributes,omitempty"` + LatestOnly bool `protobuf:"varint,6,opt,name=latest_only,json=latestOnly,proto3" json:"latest_only,omitempty"` + AllAttributes bool `protobuf:"varint,7,opt,name=all_attributes,json=allAttributes,proto3" json:"all_attributes,omitempty"` +} + +func (x *GetNodeByPathRequest_Body) Reset() { + *x = GetNodeByPathRequest_Body{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetNodeByPathRequest_Body) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetNodeByPathRequest_Body) ProtoMessage() {} + +func (x *GetNodeByPathRequest_Body) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetNodeByPathRequest_Body.ProtoReflect.Descriptor instead. +func (*GetNodeByPathRequest_Body) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{8, 0} +} + +func (x *GetNodeByPathRequest_Body) GetContainerId() []byte { + if x != nil { + return x.ContainerId + } + return nil +} + +func (x *GetNodeByPathRequest_Body) GetTreeId() string { + if x != nil { + return x.TreeId + } + return "" +} + +func (x *GetNodeByPathRequest_Body) GetPathAttribute() string { + if x != nil { + return x.PathAttribute + } + return "" +} + +func (x *GetNodeByPathRequest_Body) GetPath() []string { + if x != nil { + return x.Path + } + return nil +} + +func (x *GetNodeByPathRequest_Body) GetAttributes() []string { + if x != nil { + return x.Attributes + } + return nil +} + +func (x *GetNodeByPathRequest_Body) GetLatestOnly() bool { + if x != nil { + return x.LatestOnly + } + return false +} + +func (x *GetNodeByPathRequest_Body) GetAllAttributes() bool { + if x != nil { + return x.AllAttributes + } + return false +} + +type GetNodeByPathResponse_Info struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + NodeId uint64 `protobuf:"varint,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` + Timestamp uint64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + Meta []*KeyValue `protobuf:"bytes,3,rep,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *GetNodeByPathResponse_Info) Reset() { + *x = GetNodeByPathResponse_Info{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetNodeByPathResponse_Info) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetNodeByPathResponse_Info) ProtoMessage() {} + +func (x *GetNodeByPathResponse_Info) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetNodeByPathResponse_Info.ProtoReflect.Descriptor instead. +func (*GetNodeByPathResponse_Info) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{9, 0} +} + +func (x *GetNodeByPathResponse_Info) GetNodeId() uint64 { + if x != nil { + return x.NodeId + } + return 0 +} + +func (x *GetNodeByPathResponse_Info) GetTimestamp() uint64 { + if x != nil { + return x.Timestamp + } + return 0 +} + +func (x *GetNodeByPathResponse_Info) GetMeta() []*KeyValue { + if x != nil { + return x.Meta + } + return nil +} + +type GetNodeByPathResponse_Body struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Nodes []*GetNodeByPathResponse_Info `protobuf:"bytes,1,rep,name=nodes,proto3" json:"nodes,omitempty"` +} + +func (x *GetNodeByPathResponse_Body) Reset() { + *x = GetNodeByPathResponse_Body{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetNodeByPathResponse_Body) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetNodeByPathResponse_Body) ProtoMessage() {} + +func (x *GetNodeByPathResponse_Body) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[24] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetNodeByPathResponse_Body.ProtoReflect.Descriptor instead. +func (*GetNodeByPathResponse_Body) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{9, 1} +} + +func (x *GetNodeByPathResponse_Body) GetNodes() []*GetNodeByPathResponse_Info { + if x != nil { + return x.Nodes + } + return nil +} + +type GetSubTreeRequest_Body struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ContainerId []byte `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` + TreeId string `protobuf:"bytes,2,opt,name=tree_id,json=treeId,proto3" json:"tree_id,omitempty"` + Nodes []uint64 `protobuf:"varint,3,rep,packed,name=nodes,proto3" json:"nodes,omitempty"` +} + +func (x *GetSubTreeRequest_Body) Reset() { + *x = GetSubTreeRequest_Body{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetSubTreeRequest_Body) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetSubTreeRequest_Body) ProtoMessage() {} + +func (x *GetSubTreeRequest_Body) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[25] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetSubTreeRequest_Body.ProtoReflect.Descriptor instead. +func (*GetSubTreeRequest_Body) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{10, 0} +} + +func (x *GetSubTreeRequest_Body) GetContainerId() []byte { + if x != nil { + return x.ContainerId + } + return nil +} + +func (x *GetSubTreeRequest_Body) GetTreeId() string { + if x != nil { + return x.TreeId + } + return "" +} + +func (x *GetSubTreeRequest_Body) GetNodes() []uint64 { + if x != nil { + return x.Nodes + } + return nil +} + +type GetSubTreeResponse_Info struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + NodeId uint64 `protobuf:"varint,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` + Meta []*KeyValue `protobuf:"bytes,2,rep,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *GetSubTreeResponse_Info) Reset() { + *x = GetSubTreeResponse_Info{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetSubTreeResponse_Info) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetSubTreeResponse_Info) ProtoMessage() {} + +func (x *GetSubTreeResponse_Info) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[26] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetSubTreeResponse_Info.ProtoReflect.Descriptor instead. +func (*GetSubTreeResponse_Info) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{11, 0} +} + +func (x *GetSubTreeResponse_Info) GetNodeId() uint64 { + if x != nil { + return x.NodeId + } + return 0 +} + +func (x *GetSubTreeResponse_Info) GetMeta() []*KeyValue { + if x != nil { + return x.Meta + } + return nil +} + +type GetSubTreeResponse_Body struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Info []*GetSubTreeResponse_Info `protobuf:"bytes,1,rep,name=info,proto3" json:"info,omitempty"` +} + +func (x *GetSubTreeResponse_Body) Reset() { + *x = GetSubTreeResponse_Body{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetSubTreeResponse_Body) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetSubTreeResponse_Body) ProtoMessage() {} + +func (x *GetSubTreeResponse_Body) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[27] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetSubTreeResponse_Body.ProtoReflect.Descriptor instead. +func (*GetSubTreeResponse_Body) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{11, 1} +} + +func (x *GetSubTreeResponse_Body) GetInfo() []*GetSubTreeResponse_Info { + if x != nil { + return x.Info + } + return nil +} + +type ApplyRequest_Body struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ContainerId []byte `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` + TreeId string `protobuf:"bytes,2,opt,name=tree_id,json=treeId,proto3" json:"tree_id,omitempty"` + Operation *LogMove `protobuf:"bytes,3,opt,name=operation,proto3" json:"operation,omitempty"` +} + +func (x *ApplyRequest_Body) Reset() { + *x = ApplyRequest_Body{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ApplyRequest_Body) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ApplyRequest_Body) ProtoMessage() {} + +func (x *ApplyRequest_Body) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[28] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ApplyRequest_Body.ProtoReflect.Descriptor instead. +func (*ApplyRequest_Body) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{12, 0} +} + +func (x *ApplyRequest_Body) GetContainerId() []byte { + if x != nil { + return x.ContainerId + } + return nil +} + +func (x *ApplyRequest_Body) GetTreeId() string { + if x != nil { + return x.TreeId + } + return "" +} + +func (x *ApplyRequest_Body) GetOperation() *LogMove { + if x != nil { + return x.Operation + } + return nil +} + +type ApplyResponse_Body struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ApplyResponse_Body) Reset() { + *x = ApplyResponse_Body{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_service_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ApplyResponse_Body) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ApplyResponse_Body) ProtoMessage() {} + +func (x *ApplyResponse_Body) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_service_proto_msgTypes[29] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ApplyResponse_Body.ProtoReflect.Descriptor instead. +func (*ApplyResponse_Body) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_service_proto_rawDescGZIP(), []int{13, 0} +} + +var File_pkg_services_tree_service_proto protoreflect.FileDescriptor + +var file_pkg_services_tree_service_proto_rawDesc = []byte{ + 0x0a, 0x1f, 0x70, 0x6b, 0x67, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x74, + 0x72, 0x65, 0x65, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x04, 0x74, 0x72, 0x65, 0x65, 0x1a, 0x1d, 0x70, 0x6b, 0x67, 0x2f, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x74, 0x72, 0x65, 0x65, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xec, 0x01, 0x0a, 0x0a, 0x41, 0x64, 0x64, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, + 0x12, 0x2d, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, + 0x83, 0x01, 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, 0x17, 0x0a, 0x07, 0x74, + 0x72, 0x65, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x72, + 0x65, 0x65, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, + 0x64, 0x12, 0x22, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x0e, 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, + 0x04, 0x6d, 0x65, 0x74, 0x61, 0x22, 0x89, 0x01, 0x0a, 0x0b, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, + 0x79, 0x12, 0x2d, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x53, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x1a, 0x1f, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, + 0x64, 0x22, 0x96, 0x02, 0x0a, 0x10, 0x41, 0x64, 0x64, 0x42, 0x79, 0x50, 0x61, 0x74, 0x68, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x42, + 0x79, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x42, 0x6f, 0x64, + 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x2d, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x72, 0x65, + 0x65, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0xa1, 0x01, 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, 0x17, 0x0a, 0x07, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x72, 0x65, 0x65, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x70, + 0x61, 0x74, 0x68, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x61, 0x74, 0x68, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x22, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x05, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x4b, 0x65, 0x79, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x22, 0xaf, 0x01, 0x0a, 0x11, 0x41, + 0x64, 0x64, 0x42, 0x79, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x30, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, + 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x42, 0x79, 0x50, 0x61, 0x74, 0x68, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, + 0x64, 0x79, 0x12, 0x2d, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x53, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x1a, 0x39, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x64, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x04, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x12, + 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x22, 0xc9, 0x01, 0x0a, + 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2c, + 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, + 0x72, 0x65, 0x65, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x2d, 0x0a, 0x09, + 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0f, 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x5b, 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, 0x17, 0x0a, 0x07, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x72, 0x65, 0x65, 0x49, 0x64, 0x12, + 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x22, 0x76, 0x0a, 0x0e, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x04, 0x62, 0x6f, + 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, + 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x42, + 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x2d, 0x0a, 0x09, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, + 0x72, 0x65, 0x65, 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, 0x87, 0x02, 0x0a, 0x0b, 0x4d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x2a, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, + 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x2d, 0x0a, 0x09, + 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0f, 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x9c, 0x01, 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, 0x17, 0x0a, 0x07, 0x74, 0x72, 0x65, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x72, 0x65, 0x65, 0x49, 0x64, + 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x17, 0x0a, + 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, + 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x05, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x4b, 0x65, 0x79, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x22, 0x72, 0x0a, 0x0c, 0x4d, 0x6f, + 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x04, 0x62, 0x6f, + 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, + 0x4d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x42, 0x6f, 0x64, + 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x2d, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x72, 0x65, + 0x65, 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, 0xe2, + 0x02, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x42, 0x79, 0x50, 0x61, 0x74, 0x68, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x33, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x47, 0x65, 0x74, + 0x4e, 0x6f, 0x64, 0x65, 0x42, 0x79, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x2d, 0x0a, 0x09, + 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0f, 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0xe5, 0x01, 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, 0x17, 0x0a, 0x07, 0x74, 0x72, 0x65, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x72, 0x65, 0x65, 0x49, 0x64, + 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x61, 0x74, 0x68, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x1e, 0x0a, 0x0a, 0x61, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, + 0x61, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0a, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x25, 0x0a, 0x0e, + 0x61, 0x6c, 0x6c, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61, 0x6c, 0x6c, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x22, 0x9f, 0x02, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x42, + 0x79, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, + 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x74, 0x72, + 0x65, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x42, 0x79, 0x50, 0x61, 0x74, 0x68, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, + 0x6f, 0x64, 0x79, 0x12, 0x2d, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x53, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x1a, 0x61, 0x0a, 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, + 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6e, 0x6f, 0x64, + 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x12, 0x22, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x0e, 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, + 0x04, 0x6d, 0x65, 0x74, 0x61, 0x1a, 0x3e, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x36, 0x0a, + 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x74, + 0x72, 0x65, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x42, 0x79, 0x50, 0x61, 0x74, + 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, + 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x22, 0xce, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x53, 0x75, 0x62, + 0x54, 0x72, 0x65, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x30, 0x0a, 0x04, 0x62, + 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x72, 0x65, 0x65, + 0x2e, 0x47, 0x65, 0x74, 0x53, 0x75, 0x62, 0x54, 0x72, 0x65, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x2d, 0x0a, + 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0f, 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x58, 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, 0x17, 0x0a, 0x07, 0x74, 0x72, 0x65, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x72, 0x65, 0x65, 0x49, 0x64, + 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x04, 0x52, + 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x22, 0xf6, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x53, 0x75, + 0x62, 0x54, 0x72, 0x65, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, + 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x72, + 0x65, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x75, 0x62, 0x54, 0x72, 0x65, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, + 0x12, 0x2d, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, + 0x43, 0x0a, 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, + 0x12, 0x22, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, + 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x04, + 0x6d, 0x65, 0x74, 0x61, 0x1a, 0x39, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x31, 0x0a, 0x04, + 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x72, 0x65, + 0x65, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x75, 0x62, 0x54, 0x72, 0x65, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x22, + 0xdb, 0x01, 0x0a, 0x0c, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x2b, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x2d, 0x0a, + 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0f, 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x6f, 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, 0x17, 0x0a, 0x07, 0x74, 0x72, 0x65, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x72, 0x65, 0x65, 0x49, 0x64, + 0x12, 0x2b, 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x4c, 0x6f, 0x67, 0x4d, 0x6f, + 0x76, 0x65, 0x52, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x74, 0x0a, + 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, + 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, + 0x72, 0x65, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x2d, 0x0a, 0x09, + 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0f, 0x2e, 0x74, 0x72, 0x65, 0x65, 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, 0x98, 0x03, 0x0a, 0x0b, 0x54, 0x72, 0x65, 0x65, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x2a, 0x0a, 0x03, 0x41, 0x64, 0x64, 0x12, 0x10, 0x2e, 0x74, 0x72, 0x65, + 0x65, 0x2e, 0x41, 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x74, + 0x72, 0x65, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x3c, 0x0a, 0x09, 0x41, 0x64, 0x64, 0x42, 0x79, 0x50, 0x61, 0x74, 0x68, 0x12, 0x16, 0x2e, 0x74, + 0x72, 0x65, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x42, 0x79, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x42, + 0x79, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, + 0x06, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x12, 0x13, 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x52, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x74, + 0x72, 0x65, 0x65, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x04, 0x4d, 0x6f, 0x76, 0x65, 0x12, 0x11, 0x2e, 0x74, 0x72, 0x65, + 0x65, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, + 0x74, 0x72, 0x65, 0x65, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x48, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x42, 0x79, 0x50, 0x61, + 0x74, 0x68, 0x12, 0x1a, 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, + 0x65, 0x42, 0x79, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, + 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x42, 0x79, 0x50, + 0x61, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x0a, 0x47, + 0x65, 0x74, 0x53, 0x75, 0x62, 0x54, 0x72, 0x65, 0x65, 0x12, 0x17, 0x2e, 0x74, 0x72, 0x65, 0x65, + 0x2e, 0x47, 0x65, 0x74, 0x53, 0x75, 0x62, 0x54, 0x72, 0x65, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x75, 0x62, + 0x54, 0x72, 0x65, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x05, + 0x41, 0x70, 0x70, 0x6c, 0x79, 0x12, 0x12, 0x2e, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x41, 0x70, 0x70, + 0x6c, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x74, 0x72, 0x65, 0x65, + 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x33, + 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6e, 0x73, 0x70, + 0x63, 0x63, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x6e, 0x65, 0x6f, 0x66, 0x73, 0x2d, 0x6e, 0x6f, 0x64, + 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x74, + 0x72, 0x65, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_pkg_services_tree_service_proto_rawDescOnce sync.Once + file_pkg_services_tree_service_proto_rawDescData = file_pkg_services_tree_service_proto_rawDesc +) + +func file_pkg_services_tree_service_proto_rawDescGZIP() []byte { + file_pkg_services_tree_service_proto_rawDescOnce.Do(func() { + file_pkg_services_tree_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_pkg_services_tree_service_proto_rawDescData) + }) + return file_pkg_services_tree_service_proto_rawDescData +} + +var file_pkg_services_tree_service_proto_msgTypes = make([]protoimpl.MessageInfo, 30) +var file_pkg_services_tree_service_proto_goTypes = []interface{}{ + (*AddRequest)(nil), // 0: tree.AddRequest + (*AddResponse)(nil), // 1: tree.AddResponse + (*AddByPathRequest)(nil), // 2: tree.AddByPathRequest + (*AddByPathResponse)(nil), // 3: tree.AddByPathResponse + (*RemoveRequest)(nil), // 4: tree.RemoveRequest + (*RemoveResponse)(nil), // 5: tree.RemoveResponse + (*MoveRequest)(nil), // 6: tree.MoveRequest + (*MoveResponse)(nil), // 7: tree.MoveResponse + (*GetNodeByPathRequest)(nil), // 8: tree.GetNodeByPathRequest + (*GetNodeByPathResponse)(nil), // 9: tree.GetNodeByPathResponse + (*GetSubTreeRequest)(nil), // 10: tree.GetSubTreeRequest + (*GetSubTreeResponse)(nil), // 11: tree.GetSubTreeResponse + (*ApplyRequest)(nil), // 12: tree.ApplyRequest + (*ApplyResponse)(nil), // 13: tree.ApplyResponse + (*AddRequest_Body)(nil), // 14: tree.AddRequest.Body + (*AddResponse_Body)(nil), // 15: tree.AddResponse.Body + (*AddByPathRequest_Body)(nil), // 16: tree.AddByPathRequest.Body + (*AddByPathResponse_Body)(nil), // 17: tree.AddByPathResponse.Body + (*RemoveRequest_Body)(nil), // 18: tree.RemoveRequest.Body + (*RemoveResponse_Body)(nil), // 19: tree.RemoveResponse.Body + (*MoveRequest_Body)(nil), // 20: tree.MoveRequest.Body + (*MoveResponse_Body)(nil), // 21: tree.MoveResponse.Body + (*GetNodeByPathRequest_Body)(nil), // 22: tree.GetNodeByPathRequest.Body + (*GetNodeByPathResponse_Info)(nil), // 23: tree.GetNodeByPathResponse.Info + (*GetNodeByPathResponse_Body)(nil), // 24: tree.GetNodeByPathResponse.Body + (*GetSubTreeRequest_Body)(nil), // 25: tree.GetSubTreeRequest.Body + (*GetSubTreeResponse_Info)(nil), // 26: tree.GetSubTreeResponse.Info + (*GetSubTreeResponse_Body)(nil), // 27: tree.GetSubTreeResponse.Body + (*ApplyRequest_Body)(nil), // 28: tree.ApplyRequest.Body + (*ApplyResponse_Body)(nil), // 29: tree.ApplyResponse.Body + (*Signature)(nil), // 30: tree.Signature + (*KeyValue)(nil), // 31: tree.KeyValue + (*LogMove)(nil), // 32: tree.LogMove +} +var file_pkg_services_tree_service_proto_depIdxs = []int32{ + 14, // 0: tree.AddRequest.body:type_name -> tree.AddRequest.Body + 30, // 1: tree.AddRequest.signature:type_name -> tree.Signature + 15, // 2: tree.AddResponse.body:type_name -> tree.AddResponse.Body + 30, // 3: tree.AddResponse.signature:type_name -> tree.Signature + 16, // 4: tree.AddByPathRequest.body:type_name -> tree.AddByPathRequest.Body + 30, // 5: tree.AddByPathRequest.signature:type_name -> tree.Signature + 17, // 6: tree.AddByPathResponse.body:type_name -> tree.AddByPathResponse.Body + 30, // 7: tree.AddByPathResponse.signature:type_name -> tree.Signature + 18, // 8: tree.RemoveRequest.body:type_name -> tree.RemoveRequest.Body + 30, // 9: tree.RemoveRequest.signature:type_name -> tree.Signature + 19, // 10: tree.RemoveResponse.body:type_name -> tree.RemoveResponse.Body + 30, // 11: tree.RemoveResponse.signature:type_name -> tree.Signature + 20, // 12: tree.MoveRequest.body:type_name -> tree.MoveRequest.Body + 30, // 13: tree.MoveRequest.signature:type_name -> tree.Signature + 21, // 14: tree.MoveResponse.body:type_name -> tree.MoveResponse.Body + 30, // 15: tree.MoveResponse.signature:type_name -> tree.Signature + 22, // 16: tree.GetNodeByPathRequest.body:type_name -> tree.GetNodeByPathRequest.Body + 30, // 17: tree.GetNodeByPathRequest.signature:type_name -> tree.Signature + 24, // 18: tree.GetNodeByPathResponse.body:type_name -> tree.GetNodeByPathResponse.Body + 30, // 19: tree.GetNodeByPathResponse.signature:type_name -> tree.Signature + 25, // 20: tree.GetSubTreeRequest.body:type_name -> tree.GetSubTreeRequest.Body + 30, // 21: tree.GetSubTreeRequest.signature:type_name -> tree.Signature + 27, // 22: tree.GetSubTreeResponse.body:type_name -> tree.GetSubTreeResponse.Body + 30, // 23: tree.GetSubTreeResponse.signature:type_name -> tree.Signature + 28, // 24: tree.ApplyRequest.body:type_name -> tree.ApplyRequest.Body + 30, // 25: tree.ApplyRequest.signature:type_name -> tree.Signature + 29, // 26: tree.ApplyResponse.body:type_name -> tree.ApplyResponse.Body + 30, // 27: tree.ApplyResponse.signature:type_name -> tree.Signature + 31, // 28: tree.AddRequest.Body.meta:type_name -> tree.KeyValue + 31, // 29: tree.AddByPathRequest.Body.meta:type_name -> tree.KeyValue + 31, // 30: tree.MoveRequest.Body.meta:type_name -> tree.KeyValue + 31, // 31: tree.GetNodeByPathResponse.Info.meta:type_name -> tree.KeyValue + 23, // 32: tree.GetNodeByPathResponse.Body.nodes:type_name -> tree.GetNodeByPathResponse.Info + 31, // 33: tree.GetSubTreeResponse.Info.meta:type_name -> tree.KeyValue + 26, // 34: tree.GetSubTreeResponse.Body.info:type_name -> tree.GetSubTreeResponse.Info + 32, // 35: tree.ApplyRequest.Body.operation:type_name -> tree.LogMove + 0, // 36: tree.TreeService.Add:input_type -> tree.AddRequest + 2, // 37: tree.TreeService.AddByPath:input_type -> tree.AddByPathRequest + 4, // 38: tree.TreeService.Remove:input_type -> tree.RemoveRequest + 6, // 39: tree.TreeService.Move:input_type -> tree.MoveRequest + 8, // 40: tree.TreeService.GetNodeByPath:input_type -> tree.GetNodeByPathRequest + 10, // 41: tree.TreeService.GetSubTree:input_type -> tree.GetSubTreeRequest + 12, // 42: tree.TreeService.Apply:input_type -> tree.ApplyRequest + 1, // 43: tree.TreeService.Add:output_type -> tree.AddResponse + 3, // 44: tree.TreeService.AddByPath:output_type -> tree.AddByPathResponse + 5, // 45: tree.TreeService.Remove:output_type -> tree.RemoveResponse + 7, // 46: tree.TreeService.Move:output_type -> tree.MoveResponse + 9, // 47: tree.TreeService.GetNodeByPath:output_type -> tree.GetNodeByPathResponse + 11, // 48: tree.TreeService.GetSubTree:output_type -> tree.GetSubTreeResponse + 13, // 49: tree.TreeService.Apply:output_type -> tree.ApplyResponse + 43, // [43:50] is the sub-list for method output_type + 36, // [36:43] is the sub-list for method input_type + 36, // [36:36] is the sub-list for extension type_name + 36, // [36:36] is the sub-list for extension extendee + 0, // [0:36] is the sub-list for field type_name +} + +func init() { file_pkg_services_tree_service_proto_init() } +func file_pkg_services_tree_service_proto_init() { + if File_pkg_services_tree_service_proto != nil { + return + } + file_pkg_services_tree_types_proto_init() + if !protoimpl.UnsafeEnabled { + file_pkg_services_tree_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AddRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AddResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AddByPathRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AddByPathResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RemoveRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RemoveResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_service_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MoveRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_service_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MoveResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_service_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetNodeByPathRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_service_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetNodeByPathResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_service_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetSubTreeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_service_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetSubTreeResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_service_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ApplyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_service_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ApplyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_service_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AddRequest_Body); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_service_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AddResponse_Body); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_service_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AddByPathRequest_Body); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_service_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AddByPathResponse_Body); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_service_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RemoveRequest_Body); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_service_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RemoveResponse_Body); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_service_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MoveRequest_Body); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_service_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MoveResponse_Body); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_service_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetNodeByPathRequest_Body); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_service_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetNodeByPathResponse_Info); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_service_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetNodeByPathResponse_Body); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_service_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetSubTreeRequest_Body); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_service_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetSubTreeResponse_Info); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_service_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetSubTreeResponse_Body); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_service_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ApplyRequest_Body); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_service_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ApplyResponse_Body); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_pkg_services_tree_service_proto_rawDesc, + NumEnums: 0, + NumMessages: 30, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_pkg_services_tree_service_proto_goTypes, + DependencyIndexes: file_pkg_services_tree_service_proto_depIdxs, + MessageInfos: file_pkg_services_tree_service_proto_msgTypes, + }.Build() + File_pkg_services_tree_service_proto = out.File + file_pkg_services_tree_service_proto_rawDesc = nil + file_pkg_services_tree_service_proto_goTypes = nil + file_pkg_services_tree_service_proto_depIdxs = nil +} diff --git a/pkg/services/tree/service.proto b/pkg/services/tree/service.proto new file mode 100644 index 000000000..f18b835f7 --- /dev/null +++ b/pkg/services/tree/service.proto @@ -0,0 +1,194 @@ +syntax = "proto3"; + +package tree; + +import "pkg/services/tree/types.proto"; + +option go_package = "github.com/nspcc-dev/neofs-node/pkg/services/tree"; + +// `TreeService` provides an interface for working with distributed tree. +service TreeService { + /* Client API */ + + // Add adds new node to the tree. Invoked by a client. + rpc Add (AddRequest) returns (AddResponse); + // AddByPath adds new node to the tree by path. Invoked by a client. + rpc AddByPath (AddByPathRequest) returns (AddByPathResponse); + // Remove removes node from the tree. Invoked by a client. + rpc Remove (RemoveRequest) returns (RemoveResponse); + // Move moves node from one parent to another. Invoked by a client. + rpc Move (MoveRequest) returns (MoveResponse); + // GetNodeByPath returns list of IDs corresponding to a specific filepath. + rpc GetNodeByPath (GetNodeByPathRequest) returns (GetNodeByPathResponse); + // GetSubTree returns tree corresponding to a specific node. + rpc GetSubTree (GetSubTreeRequest) returns (GetSubTreeResponse); + + /* Synchronization API */ + + // Apply pushes log operation from another node to the current. + // The request must be signed by a container node. + rpc Apply (ApplyRequest) returns (ApplyResponse); +} + +message AddRequest { + message Body { + bytes container_id = 1; + string tree_id = 2; + uint64 parent_id = 3; + repeated KeyValue meta = 4; + } + + Body body = 1; + Signature signature = 2; +} + +message AddResponse { + message Body { + uint64 node_id = 1; + } + + Body body = 1; + Signature signature = 2; +}; + + +message AddByPathRequest { + message Body { + bytes container_id = 1; + string tree_id = 2; + string path_attribute = 3; + repeated string path = 4; + repeated KeyValue meta = 5; + } + + Body body = 1; + Signature signature = 2; +} + +message AddByPathResponse { + message Body { + repeated uint64 nodes = 1; + uint64 parent_id = 2; + } + + Body body = 1; + Signature signature = 2; +}; + + +message RemoveRequest { + message Body { + bytes container_id = 1; + string tree_id = 2; + uint64 node_id = 3; + } + + Body body = 1; + Signature signature = 2; +} + +message RemoveResponse { + message Body { + } + + Body body = 1; + Signature signature = 2; +}; + + +message MoveRequest { + message Body { + // TODO import neo.fs.v2.refs.ContainerID directly. + bytes container_id = 1; + string tree_id = 2; + uint64 parent_id = 3; + uint64 node_id = 4; + repeated KeyValue meta = 5; + } + + Body body = 1; + Signature signature = 2; +} + +message MoveResponse { + message Body { + } + + Body body = 1; + Signature signature = 2; +}; + + +message GetNodeByPathRequest { + message Body { + bytes container_id = 1; + string tree_id = 2; + string path_attribute = 3; + repeated string path = 4; + repeated string attributes = 5; + bool latest_only = 6; + bool all_attributes = 7; + } + + Body body = 1; + Signature signature = 2; +} + +message GetNodeByPathResponse { + message Info { + uint64 node_id = 1; + uint64 timestamp = 2; + repeated KeyValue meta = 3; + } + message Body { + repeated Info nodes = 1; + } + + Body body = 1; + Signature signature = 2; +}; + + +message GetSubTreeRequest { + message Body { + bytes container_id = 1; + string tree_id = 2; + repeated uint64 nodes = 3; + } + + Body body = 1; + Signature signature = 2; +} + +message GetSubTreeResponse { + message Info { + uint64 node_id = 1; + repeated KeyValue meta = 2; + } + message Body { + repeated Info info = 1; + } + + Body body = 1; + Signature signature = 2; +}; + + +message ApplyRequest { + message Body { + bytes container_id = 1; + string tree_id = 2; + LogMove operation = 3; + } + + Body body = 1; + Signature signature = 2; +} + +message ApplyResponse { + message Body { + } + + Body body = 1; + Signature signature = 2; +}; diff --git a/pkg/services/tree/service_grpc.pb.go b/pkg/services/tree/service_grpc.pb.go new file mode 100644 index 000000000..47aac0f78 --- /dev/null +++ b/pkg/services/tree/service_grpc.pb.go @@ -0,0 +1,335 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.19.4 +// source: pkg/services/tree/service.proto + +package tree + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// TreeServiceClient is the client API for TreeService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type TreeServiceClient interface { + // Add adds new node to the tree. Invoked by a client. + Add(ctx context.Context, in *AddRequest, opts ...grpc.CallOption) (*AddResponse, error) + // AddByPath adds new node to the tree by path. Invoked by a client. + AddByPath(ctx context.Context, in *AddByPathRequest, opts ...grpc.CallOption) (*AddByPathResponse, error) + // Remove removes node from the tree. Invoked by a client. + Remove(ctx context.Context, in *RemoveRequest, opts ...grpc.CallOption) (*RemoveResponse, error) + // Move moves node from one parent to another. Invoked by a client. + Move(ctx context.Context, in *MoveRequest, opts ...grpc.CallOption) (*MoveResponse, error) + // GetNodeByPath returns list of IDs corresponding to a specific filepath. + GetNodeByPath(ctx context.Context, in *GetNodeByPathRequest, opts ...grpc.CallOption) (*GetNodeByPathResponse, error) + // GetSubTree returns tree corresponding to a specific node. + GetSubTree(ctx context.Context, in *GetSubTreeRequest, opts ...grpc.CallOption) (*GetSubTreeResponse, error) + // Apply pushes log operation from another node to the current. + // The request must be signed by a container node. + Apply(ctx context.Context, in *ApplyRequest, opts ...grpc.CallOption) (*ApplyResponse, error) +} + +type treeServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewTreeServiceClient(cc grpc.ClientConnInterface) TreeServiceClient { + return &treeServiceClient{cc} +} + +func (c *treeServiceClient) Add(ctx context.Context, in *AddRequest, opts ...grpc.CallOption) (*AddResponse, error) { + out := new(AddResponse) + err := c.cc.Invoke(ctx, "/tree.TreeService/Add", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *treeServiceClient) AddByPath(ctx context.Context, in *AddByPathRequest, opts ...grpc.CallOption) (*AddByPathResponse, error) { + out := new(AddByPathResponse) + err := c.cc.Invoke(ctx, "/tree.TreeService/AddByPath", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *treeServiceClient) Remove(ctx context.Context, in *RemoveRequest, opts ...grpc.CallOption) (*RemoveResponse, error) { + out := new(RemoveResponse) + err := c.cc.Invoke(ctx, "/tree.TreeService/Remove", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *treeServiceClient) Move(ctx context.Context, in *MoveRequest, opts ...grpc.CallOption) (*MoveResponse, error) { + out := new(MoveResponse) + err := c.cc.Invoke(ctx, "/tree.TreeService/Move", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *treeServiceClient) GetNodeByPath(ctx context.Context, in *GetNodeByPathRequest, opts ...grpc.CallOption) (*GetNodeByPathResponse, error) { + out := new(GetNodeByPathResponse) + err := c.cc.Invoke(ctx, "/tree.TreeService/GetNodeByPath", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *treeServiceClient) GetSubTree(ctx context.Context, in *GetSubTreeRequest, opts ...grpc.CallOption) (*GetSubTreeResponse, error) { + out := new(GetSubTreeResponse) + err := c.cc.Invoke(ctx, "/tree.TreeService/GetSubTree", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *treeServiceClient) Apply(ctx context.Context, in *ApplyRequest, opts ...grpc.CallOption) (*ApplyResponse, error) { + out := new(ApplyResponse) + err := c.cc.Invoke(ctx, "/tree.TreeService/Apply", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// TreeServiceServer is the server API for TreeService service. +// All implementations should embed UnimplementedTreeServiceServer +// for forward compatibility +type TreeServiceServer interface { + // Add adds new node to the tree. Invoked by a client. + Add(context.Context, *AddRequest) (*AddResponse, error) + // AddByPath adds new node to the tree by path. Invoked by a client. + AddByPath(context.Context, *AddByPathRequest) (*AddByPathResponse, error) + // Remove removes node from the tree. Invoked by a client. + Remove(context.Context, *RemoveRequest) (*RemoveResponse, error) + // Move moves node from one parent to another. Invoked by a client. + Move(context.Context, *MoveRequest) (*MoveResponse, error) + // GetNodeByPath returns list of IDs corresponding to a specific filepath. + GetNodeByPath(context.Context, *GetNodeByPathRequest) (*GetNodeByPathResponse, error) + // GetSubTree returns tree corresponding to a specific node. + GetSubTree(context.Context, *GetSubTreeRequest) (*GetSubTreeResponse, error) + // Apply pushes log operation from another node to the current. + // The request must be signed by a container node. + Apply(context.Context, *ApplyRequest) (*ApplyResponse, error) +} + +// UnimplementedTreeServiceServer should be embedded to have forward compatible implementations. +type UnimplementedTreeServiceServer struct { +} + +func (UnimplementedTreeServiceServer) Add(context.Context, *AddRequest) (*AddResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Add not implemented") +} +func (UnimplementedTreeServiceServer) AddByPath(context.Context, *AddByPathRequest) (*AddByPathResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AddByPath not implemented") +} +func (UnimplementedTreeServiceServer) Remove(context.Context, *RemoveRequest) (*RemoveResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Remove not implemented") +} +func (UnimplementedTreeServiceServer) Move(context.Context, *MoveRequest) (*MoveResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Move not implemented") +} +func (UnimplementedTreeServiceServer) GetNodeByPath(context.Context, *GetNodeByPathRequest) (*GetNodeByPathResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetNodeByPath not implemented") +} +func (UnimplementedTreeServiceServer) GetSubTree(context.Context, *GetSubTreeRequest) (*GetSubTreeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetSubTree not implemented") +} +func (UnimplementedTreeServiceServer) Apply(context.Context, *ApplyRequest) (*ApplyResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Apply not implemented") +} + +// UnsafeTreeServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to TreeServiceServer will +// result in compilation errors. +type UnsafeTreeServiceServer interface { + mustEmbedUnimplementedTreeServiceServer() +} + +func RegisterTreeServiceServer(s grpc.ServiceRegistrar, srv TreeServiceServer) { + s.RegisterService(&TreeService_ServiceDesc, srv) +} + +func _TreeService_Add_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AddRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TreeServiceServer).Add(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/tree.TreeService/Add", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TreeServiceServer).Add(ctx, req.(*AddRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _TreeService_AddByPath_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AddByPathRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TreeServiceServer).AddByPath(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/tree.TreeService/AddByPath", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TreeServiceServer).AddByPath(ctx, req.(*AddByPathRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _TreeService_Remove_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RemoveRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TreeServiceServer).Remove(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/tree.TreeService/Remove", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TreeServiceServer).Remove(ctx, req.(*RemoveRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _TreeService_Move_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MoveRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TreeServiceServer).Move(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/tree.TreeService/Move", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TreeServiceServer).Move(ctx, req.(*MoveRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _TreeService_GetNodeByPath_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetNodeByPathRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TreeServiceServer).GetNodeByPath(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/tree.TreeService/GetNodeByPath", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TreeServiceServer).GetNodeByPath(ctx, req.(*GetNodeByPathRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _TreeService_GetSubTree_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetSubTreeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TreeServiceServer).GetSubTree(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/tree.TreeService/GetSubTree", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TreeServiceServer).GetSubTree(ctx, req.(*GetSubTreeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _TreeService_Apply_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ApplyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TreeServiceServer).Apply(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/tree.TreeService/Apply", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TreeServiceServer).Apply(ctx, req.(*ApplyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// TreeService_ServiceDesc is the grpc.ServiceDesc for TreeService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var TreeService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "tree.TreeService", + HandlerType: (*TreeServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Add", + Handler: _TreeService_Add_Handler, + }, + { + MethodName: "AddByPath", + Handler: _TreeService_AddByPath_Handler, + }, + { + MethodName: "Remove", + Handler: _TreeService_Remove_Handler, + }, + { + MethodName: "Move", + Handler: _TreeService_Move_Handler, + }, + { + MethodName: "GetNodeByPath", + Handler: _TreeService_GetNodeByPath_Handler, + }, + { + MethodName: "GetSubTree", + Handler: _TreeService_GetSubTree_Handler, + }, + { + MethodName: "Apply", + Handler: _TreeService_Apply_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "pkg/services/tree/service.proto", +} diff --git a/pkg/services/tree/signature.go b/pkg/services/tree/signature.go new file mode 100644 index 000000000..299f3ad34 --- /dev/null +++ b/pkg/services/tree/signature.go @@ -0,0 +1,44 @@ +package tree + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "errors" + "fmt" + + "github.com/nspcc-dev/neo-go/pkg/crypto/keys" + "github.com/nspcc-dev/neofs-api-go/v2/signature" + cidSDK "github.com/nspcc-dev/neofs-sdk-go/container/id" + "github.com/nspcc-dev/neofs-sdk-go/user" +) + +func (s *Service) verifyClient(req interface{}, cid cidSDK.ID, rawKey []byte) error { + // TODO(@fyrchik): #1328 access control + return nil + //nolint:govet + err := signature.VerifyServiceMessage(req) + if err != nil { + return err + } + + cnr, err := s.cnrSource.Get(cid) + if err != nil { + return fmt.Errorf("can't get container %s: %w", cid, err) + } + + ownerID := cnr.Value.Owner() + + pub, err := keys.NewPublicKeyFromBytes(rawKey, elliptic.P256()) + if err != nil { + return fmt.Errorf("invalid public key: %w", err) + } + + var actualID user.ID + user.IDFromKey(&actualID, (ecdsa.PublicKey)(*pub)) + + if !actualID.Equals(ownerID) { + return errors.New("`Move` request must be signed by a container owner") + } + + return nil +} diff --git a/pkg/services/tree/types.pb.go b/pkg/services/tree/types.pb.go new file mode 100644 index 000000000..d72370c65 --- /dev/null +++ b/pkg/services/tree/types.pb.go @@ -0,0 +1,313 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v3.19.4 +// source: pkg/services/tree/types.proto + +package tree + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// KeyValue represents key-value pair attached to an object. +type KeyValue struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *KeyValue) Reset() { + *x = KeyValue{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_types_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *KeyValue) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*KeyValue) ProtoMessage() {} + +func (x *KeyValue) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_types_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use KeyValue.ProtoReflect.Descriptor instead. +func (*KeyValue) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_types_proto_rawDescGZIP(), []int{0} +} + +func (x *KeyValue) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *KeyValue) GetValue() []byte { + if x != nil { + return x.Value + } + return nil +} + +// LogMove represents log-entry for a single move operation. +type LogMove struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // ID of the parent node. + ParentId uint64 `protobuf:"varint,2,opt,name=parent_id,json=parentID,proto3" json:"parent_id,omitempty"` + // Node meta information, including operation timestamp. + Meta []byte `protobuf:"bytes,3,opt,name=meta,proto3" json:"meta,omitempty"` + // ID of the node to move. + ChildId uint64 `protobuf:"varint,4,opt,name=child_id,json=childID,proto3" json:"child_id,omitempty"` +} + +func (x *LogMove) Reset() { + *x = LogMove{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_types_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LogMove) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LogMove) ProtoMessage() {} + +func (x *LogMove) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_types_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LogMove.ProtoReflect.Descriptor instead. +func (*LogMove) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_types_proto_rawDescGZIP(), []int{1} +} + +func (x *LogMove) GetParentId() uint64 { + if x != nil { + return x.ParentId + } + return 0 +} + +func (x *LogMove) GetMeta() []byte { + if x != nil { + return x.Meta + } + return nil +} + +func (x *LogMove) GetChildId() uint64 { + if x != nil { + return x.ChildId + } + return 0 +} + +// Signature of a message. +type Signature struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Sign []byte `protobuf:"bytes,2,opt,name=sign,json=signature,proto3" json:"sign,omitempty"` +} + +func (x *Signature) Reset() { + *x = Signature{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_tree_types_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Signature) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Signature) ProtoMessage() {} + +func (x *Signature) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_tree_types_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Signature.ProtoReflect.Descriptor instead. +func (*Signature) Descriptor() ([]byte, []int) { + return file_pkg_services_tree_types_proto_rawDescGZIP(), []int{2} +} + +func (x *Signature) GetKey() []byte { + if x != nil { + return x.Key + } + return nil +} + +func (x *Signature) GetSign() []byte { + if x != nil { + return x.Sign + } + return nil +} + +var File_pkg_services_tree_types_proto protoreflect.FileDescriptor + +var file_pkg_services_tree_types_proto_rawDesc = []byte{ + 0x0a, 0x1d, 0x70, 0x6b, 0x67, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x74, + 0x72, 0x65, 0x65, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x04, 0x74, 0x72, 0x65, 0x65, 0x22, 0x32, 0x0a, 0x08, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x55, 0x0a, 0x07, 0x4c, 0x6f, 0x67, + 0x4d, 0x6f, 0x76, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, + 0x44, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x5f, 0x69, + 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x49, 0x44, + 0x22, 0x36, 0x0a, 0x09, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x17, 0x0a, 0x04, 0x73, 0x69, 0x67, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6e, 0x73, 0x70, 0x63, 0x63, 0x2d, 0x64, 0x65, 0x76, + 0x2f, 0x6e, 0x65, 0x6f, 0x66, 0x73, 0x2d, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x74, 0x72, 0x65, 0x65, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_pkg_services_tree_types_proto_rawDescOnce sync.Once + file_pkg_services_tree_types_proto_rawDescData = file_pkg_services_tree_types_proto_rawDesc +) + +func file_pkg_services_tree_types_proto_rawDescGZIP() []byte { + file_pkg_services_tree_types_proto_rawDescOnce.Do(func() { + file_pkg_services_tree_types_proto_rawDescData = protoimpl.X.CompressGZIP(file_pkg_services_tree_types_proto_rawDescData) + }) + return file_pkg_services_tree_types_proto_rawDescData +} + +var file_pkg_services_tree_types_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_pkg_services_tree_types_proto_goTypes = []interface{}{ + (*KeyValue)(nil), // 0: tree.KeyValue + (*LogMove)(nil), // 1: tree.LogMove + (*Signature)(nil), // 2: tree.Signature +} +var file_pkg_services_tree_types_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_pkg_services_tree_types_proto_init() } +func file_pkg_services_tree_types_proto_init() { + if File_pkg_services_tree_types_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_pkg_services_tree_types_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*KeyValue); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_types_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LogMove); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_tree_types_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Signature); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_pkg_services_tree_types_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_pkg_services_tree_types_proto_goTypes, + DependencyIndexes: file_pkg_services_tree_types_proto_depIdxs, + MessageInfos: file_pkg_services_tree_types_proto_msgTypes, + }.Build() + File_pkg_services_tree_types_proto = out.File + file_pkg_services_tree_types_proto_rawDesc = nil + file_pkg_services_tree_types_proto_goTypes = nil + file_pkg_services_tree_types_proto_depIdxs = nil +} diff --git a/pkg/services/tree/types.proto b/pkg/services/tree/types.proto new file mode 100644 index 000000000..420fa4dfa --- /dev/null +++ b/pkg/services/tree/types.proto @@ -0,0 +1,27 @@ +syntax = "proto3"; + +package tree; + +option go_package = "github.com/nspcc-dev/neofs-node/pkg/services/tree"; + +// KeyValue represents key-value pair attached to an object. +message KeyValue { + string key = 1 [json_name = "key"]; + bytes value = 2 [json_name = "value"]; +} + +// LogMove represents log-entry for a single move operation. +message LogMove { + // ID of the parent node. + uint64 parent_id = 2 [json_name = "parentID"]; + // Node meta information, including operation timestamp. + bytes meta = 3 [json_name = "meta"]; + // ID of the node to move. + uint64 child_id = 4 [json_name = "childID"]; +} + +// Signature of a message. +message Signature { + bytes key = 1 [json_name = "key"]; + bytes sign = 2 [json_name = "signature"]; +}