diff --git a/.gitignore b/.gitignore index 66fd13c9..26edddfa 100644 --- a/.gitignore +++ b/.gitignore @@ -8,8 +8,30 @@ # Test binary, built with `go test -c` *.test +# playground folder for testing different clients +playground + +# .paw folder for macos paw client +.paw + # Output of the go coverage tool, specifically when used with LiteIDE *.out +# Golang vendor folder +vendor + +# database +db + +# artefacts for Intelli-J fleet +.fleet + +# Intelli-J files +.idea + +# MacOS file that stores custom attributes of its containing folder, +# such as folder view options, icon positions, and other visual information +.DS_Store + # Dependency directories (remove the comment below to include it) # vendor/ diff --git a/Makefile b/Makefile index 82cb14de..75f43ddc 100644 --- a/Makefile +++ b/Makefile @@ -12,29 +12,15 @@ endif export PATH=$(GOPATH)/bin:$(shell echo $$PATH) -# TODO: folders were changed, so we should update Makefile and protos generation -protos-go: - @echo 'Generating protobuf packages (Go)...' -# Uncomment if needed - @$(eval ROOT_PKG := pkg) - @$(eval GOGO_START := GOGO_NO_UNDERSCORE=1 GOGO_EXPORT_ONEOF_INTERFACE=1) - @$(eval P_TREE_STORAGE_PATH_PB := $(ROOT_PKG)/acl/treestorage/treepb) - @$(eval P_ACL_CHANGES_PATH_PB := $(ROOT_PKG)/acl/aclchanges/aclpb) - @$(eval P_PLAINTEXT_CHANGES_PATH_PB := $(ROOT_PKG)/acl/testutils/testchanges/testchangepb) - @$(eval P_SYNC_CHANGES_PATH_PB := syncproto) - @$(eval P_TIMESTAMP := Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types) - @$(eval P_STRUCT := Mgoogle/protobuf/struct.proto=github.com/gogo/protobuf/types) - @$(eval P_ACL_CHANGES := M$(P_ACL_CHANGES_PATH_PB)/protos/aclchanges.proto=github.com/anytypeio/go-anytype-infrastructure-experiments/$(P_ACL_CHANGES_PATH_PB)) - @$(eval P_TREE_CHANGES := M$(P_TREE_STORAGE_PATH_PB)/protos/tree.proto=github.com/anytypeio/go-anytype-infrastructure-experiments/$(P_TREE_STORAGE_PATH_PB)) - - # use if needed $(eval PKGMAP := $$(P_TIMESTAMP),$$(P_STRUCT)) - $(GOGO_START) protoc --gogofaster_out=:. $(P_ACL_CHANGES_PATH_PB)/protos/*.proto; mv $(P_ACL_CHANGES_PATH_PB)/protos/*.go $(P_ACL_CHANGES_PATH_PB) - $(GOGO_START) protoc --gogofaster_out=:. $(P_TREE_STORAGE_PATH_PB)/protos/*.proto; mv $(P_TREE_STORAGE_PATH_PB)/protos/*.go $(P_TREE_STORAGE_PATH_PB) - $(GOGO_START) protoc --gogofaster_out=:. $(P_PLAINTEXT_CHANGES_PATH_PB)/protos/*.proto; mv $(P_PLAINTEXT_CHANGES_PATH_PB)/protos/*.go $(P_PLAINTEXT_CHANGES_PATH_PB) - $(eval PKGMAP := $$(P_ACL_CHANGES),$$(P_TREE_CHANGES)) - $(GOGO_START) protoc --gogofaster_out=$(PKGMAP):. $(P_SYNC_CHANGES_PATH_PB)/proto/*.proto - $(GOGO_START) protoc --gogofaster_out=$(PKGMAP):. service/space/spacesync/protos/*.proto +proto: + $(MAKE) -C common proto + $(MAKE) -C consensus proto build: - @$(eval FLAGS := $$(shell govvv -flags -pkg github.com/anytypeio/go-anytype-infrastructure-experiments/app)) - go build -v -o bin/anytype-node -ldflags "$(FLAGS)" cmd/node/node.go \ No newline at end of file + $(MAKE) -C node build + $(MAKE) -C consensus build + +test: + $(MAKE) -C node test + $(MAKE) -C consensus test + $(MAKE) -C common test \ No newline at end of file diff --git a/app/logger/log.go b/app/logger/log.go deleted file mode 100644 index 99826bcf..00000000 --- a/app/logger/log.go +++ /dev/null @@ -1,21 +0,0 @@ -package logger - -import "go.uber.org/zap" - -var DefaultLogger *zap.Logger - -func init() { - DefaultLogger, _ = zap.NewDevelopment(zap.IncreaseLevel(zap.InfoLevel)) -} - -func Default() *zap.Logger { - return DefaultLogger -} - -func NewNamed(name string, fields ...zap.Field) *zap.Logger { - l := DefaultLogger.Named(name) - if len(fields) > 0 { - l = l.With(fields...) - } - return l -} diff --git a/client/account/service.go b/client/account/service.go new file mode 100644 index 00000000..d73f9c8d --- /dev/null +++ b/client/account/service.go @@ -0,0 +1,71 @@ +package account + +import ( + commonaccount "github.com/anytypeio/go-anytype-infrastructure-experiments/common/account" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/config" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/account" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/encryptionkey" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/signingkey" +) + +type service struct { + accountData *account.AccountData + peerId string +} + +func (s *service) Account() *account.AccountData { + return s.accountData +} + +func New() app.Component { + return &service{} +} + +func (s *service) Init(a *app.App) (err error) { + acc := a.MustComponent(config.CName).(commonaccount.ConfigGetter).GetAccount() + + decodedEncryptionKey, err := keys.DecodeKeyFromString( + acc.EncryptionKey, + encryptionkey.NewEncryptionRsaPrivKeyFromBytes, + nil) + if err != nil { + return err + } + + decodedSigningKey, err := keys.DecodeKeyFromString( + acc.SigningKey, + signingkey.NewSigningEd25519PrivKeyFromBytes, + nil) + if err != nil { + return err + } + + decodedPeerKey, err := keys.DecodeKeyFromString( + acc.PeerKey, + signingkey.NewSigningEd25519PrivKeyFromBytes, + nil) + if err != nil { + return err + } + + identity, err := decodedSigningKey.GetPublic().Raw() + if err != nil { + return err + } + + s.accountData = &account.AccountData{ + Identity: identity, + PeerKey: decodedPeerKey, + SignKey: decodedSigningKey, + EncKey: decodedEncryptionKey, + } + s.peerId = acc.PeerId + + return nil +} + +func (s *service) Name() (name string) { + return commonaccount.CName +} diff --git a/client/api/controller.go b/client/api/controller.go new file mode 100644 index 00000000..9e897dac --- /dev/null +++ b/client/api/controller.go @@ -0,0 +1,125 @@ +package api + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/client/clientspace" + "github.com/anytypeio/go-anytype-infrastructure-experiments/client/document" + "github.com/anytypeio/go-anytype-infrastructure-experiments/client/storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/account" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/symmetric" + "math/rand" +) + +type Controller interface { + // DeriveSpace derives the space from current account + DeriveSpace() (id string, err error) + // CreateSpace creates new space with random data + CreateSpace() (id string, err error) + // AllSpaceIds returns ids of all spaces + AllSpaceIds() (ids []string, err error) + // LoadSpace asks node to load a particular space + LoadSpace(id string) (err error) + + // CreateDocument creates new document in space + CreateDocument(spaceId string) (id string, err error) + // AllDocumentIds gets all ids of documents in space + AllDocumentIds(spaceId string) (ids []string, err error) + // AddText adds text to space document + AddText(spaceId, documentId, text string) (err error) + // DumpDocumentTree dumps the tree data into string + DumpDocumentTree(spaceId, documentId string) (dump string, err error) + + ValidInvites(spaceId string) (invites []string, err error) + GenerateInvite(spaceId string) (invite string, err error) + JoinSpace(invite string) (err error) +} + +type controller struct { + spaceService clientspace.Service + storageService storage.ClientStorage + docService document.Service + account account.Service +} + +func newController(spaceService clientspace.Service, + storageService storage.ClientStorage, + docService document.Service, + account account.Service) Controller { + return &controller{ + spaceService: spaceService, + storageService: storageService, + docService: docService, + account: account, + } +} + +func (c *controller) DeriveSpace() (id string, err error) { + sp, err := c.spaceService.DeriveSpace(context.Background(), commonspace.SpaceDerivePayload{ + SigningKey: c.account.Account().SignKey, + EncryptionKey: c.account.Account().EncKey, + }) + if err != nil { + return + } + id = sp.Id() + return +} + +func (c *controller) CreateSpace() (id string, err error) { + key, err := symmetric.NewRandom() + if err != nil { + return + } + sp, err := c.spaceService.CreateSpace(context.Background(), commonspace.SpaceCreatePayload{ + SigningKey: c.account.Account().SignKey, + EncryptionKey: c.account.Account().EncKey, + ReadKey: key.Bytes(), + ReplicationKey: rand.Uint64(), + }) + if err != nil { + return + } + id = sp.Id() + return +} + +func (c *controller) AllSpaceIds() (ids []string, err error) { + return c.storageService.AllSpaceIds() +} + +func (c *controller) LoadSpace(id string) (err error) { + _, err = c.spaceService.GetSpace(context.Background(), id) + return +} + +func (c *controller) CreateDocument(spaceId string) (id string, err error) { + return c.docService.CreateDocument(spaceId) +} + +func (c *controller) AllDocumentIds(spaceId string) (ids []string, err error) { + return c.docService.AllDocumentIds(spaceId) +} + +func (c *controller) AddText(spaceId, documentId, text string) (err error) { + return c.docService.AddText(spaceId, documentId, text) +} + +func (c *controller) DumpDocumentTree(spaceId, documentId string) (dump string, err error) { + return c.docService.DumpDocumentTree(spaceId, documentId) +} + +func (c *controller) ValidInvites(spaceId string) (invites []string, err error) { + //TODO implement me + panic("implement me") +} + +func (c *controller) GenerateInvite(spaceId string) (invite string, err error) { + //TODO implement me + panic("implement me") +} + +func (c *controller) JoinSpace(invite string) (err error) { + //TODO implement me + panic("implement me") +} diff --git a/client/api/service.go b/client/api/service.go new file mode 100644 index 00000000..1f7ed647 --- /dev/null +++ b/client/api/service.go @@ -0,0 +1,181 @@ +package api + +import ( + "context" + "fmt" + "github.com/anytypeio/go-anytype-infrastructure-experiments/client/clientspace" + "github.com/anytypeio/go-anytype-infrastructure-experiments/client/document" + clientstorage "github.com/anytypeio/go-anytype-infrastructure-experiments/client/storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/account" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/config" + "go.uber.org/zap" + "io" + "net/http" + "strings" +) + +const CName = "api.service" + +var log = logger.NewNamed("api") + +func New() Service { + return &service{} +} + +type Service interface { + app.ComponentRunnable +} + +type service struct { + controller Controller + srv *http.Server + cfg *config.Config +} + +func (s *service) Init(a *app.App) (err error) { + s.controller = newController( + a.MustComponent(clientspace.CName).(clientspace.Service), + a.MustComponent(storage.CName).(clientstorage.ClientStorage), + a.MustComponent(document.CName).(document.Service), + a.MustComponent(account.CName).(account.Service)) + s.cfg = a.MustComponent(config.CName).(*config.Config) + return nil +} + +func (s *service) Name() (name string) { + return CName +} + +func (s *service) Run(ctx context.Context) (err error) { + defer func() { + if err == nil { + log.With(zap.String("port", s.cfg.APIServer.Port)).Info("api server started running") + } + }() + + s.srv = &http.Server{ + Addr: fmt.Sprintf(":%s", s.cfg.APIServer.Port), + } + mux := http.NewServeMux() + mux.HandleFunc("/deriveSpace", s.deriveSpace) + mux.HandleFunc("/createSpace", s.createSpace) + mux.HandleFunc("/loadSpace", s.loadSpace) + mux.HandleFunc("/allSpaceIds", s.allSpaceIds) + mux.HandleFunc("/createDocument", s.createDocument) + mux.HandleFunc("/allDocumentIds", s.allDocumentIds) + mux.HandleFunc("/addText", s.addText) + mux.HandleFunc("/dumpDocumentTree", s.dumpDocumentTree) + s.srv.Handler = mux + + go s.runServer() + return nil +} + +func (s *service) runServer() { + err := s.srv.ListenAndServe() + if err != nil { + log.With(zap.Error(err)).Error("could not run api server") + } +} + +func (s *service) Close(ctx context.Context) (err error) { + return s.srv.Shutdown(ctx) +} + +func (s *service) deriveSpace(w http.ResponseWriter, req *http.Request) { + id, err := s.controller.DeriveSpace() + if err != nil { + sendText(w, http.StatusInternalServerError, err.Error()) + return + } + sendText(w, http.StatusOK, id) +} + +func (s *service) loadSpace(w http.ResponseWriter, req *http.Request) { + query := req.URL.Query() + spaceId := query.Get("spaceId") + err := s.controller.LoadSpace(query.Get("spaceId")) + if err != nil { + sendText(w, http.StatusInternalServerError, err.Error()) + return + } + sendText(w, http.StatusOK, spaceId) +} + +func (s *service) createSpace(w http.ResponseWriter, req *http.Request) { + id, err := s.controller.CreateSpace() + if err != nil { + sendText(w, http.StatusInternalServerError, err.Error()) + return + } + sendText(w, http.StatusOK, id) +} + +func (s *service) allSpaceIds(w http.ResponseWriter, req *http.Request) { + ids, err := s.controller.AllSpaceIds() + if err != nil { + sendText(w, http.StatusInternalServerError, err.Error()) + return + } + sendText(w, http.StatusOK, strings.Join(ids, "\n")) +} + +func (s *service) createDocument(w http.ResponseWriter, req *http.Request) { + query := req.URL.Query() + spaceId := query.Get("spaceId") + id, err := s.controller.CreateDocument(spaceId) + if err != nil { + sendText(w, http.StatusInternalServerError, err.Error()) + return + } + sendText(w, http.StatusOK, id) +} + +func (s *service) allDocumentIds(w http.ResponseWriter, req *http.Request) { + query := req.URL.Query() + spaceId := query.Get("spaceId") + ids, err := s.controller.AllDocumentIds(spaceId) + if err != nil { + sendText(w, http.StatusInternalServerError, err.Error()) + return + } + sendText(w, http.StatusOK, strings.Join(ids, "\n")) +} + +func (s *service) addText(w http.ResponseWriter, req *http.Request) { + query := req.URL.Query() + spaceId := query.Get("spaceId") + documentId := query.Get("documentId") + text := query.Get("text") + err := s.controller.AddText(spaceId, documentId, text) + if err != nil { + sendText(w, http.StatusInternalServerError, err.Error()) + return + } + sendText(w, http.StatusOK, "Text added") +} + +func (s *service) dumpDocumentTree(w http.ResponseWriter, req *http.Request) { + query := req.URL.Query() + spaceId := query.Get("spaceId") + documentId := query.Get("documentId") + dump, err := s.controller.DumpDocumentTree(spaceId, documentId) + if err != nil { + sendText(w, http.StatusInternalServerError, err.Error()) + return + } + sendText(w, http.StatusOK, dump) +} + +func sendText(r http.ResponseWriter, code int, body string) { + r.Header().Set("Content-Type", "text/plain") + r.WriteHeader(code) + + _, err := io.WriteString(r, fmt.Sprintf("%s\n", body)) + if err != nil { + log.Error("writing response failed", zap.Error(err)) + } +} diff --git a/client/badgerprovider/service.go b/client/badgerprovider/service.go new file mode 100644 index 00000000..64f80c2d --- /dev/null +++ b/client/badgerprovider/service.go @@ -0,0 +1,45 @@ +package badgerprovider + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/config" + "github.com/dgraph-io/badger/v3" +) + +type BadgerProvider interface { + app.ComponentRunnable + Badger() *badger.DB +} + +var CName = "client.badgerprovider" + +type service struct { + db *badger.DB +} + +func New() BadgerProvider { + return &service{} +} + +func (s *service) Init(a *app.App) (err error) { + cfg := a.MustComponent(config.CName).(*config.Config) + s.db, err = badger.Open(badger.DefaultOptions(cfg.Storage.Path)) + return +} + +func (s *service) Name() (name string) { + return CName +} + +func (s *service) Badger() *badger.DB { + return s.db +} + +func (s *service) Run(ctx context.Context) (err error) { + return +} + +func (s *service) Close(ctx context.Context) (err error) { + return s.db.Close() +} diff --git a/client/clientspace/clientcache/treecache.go b/client/clientspace/clientcache/treecache.go new file mode 100644 index 00000000..5422b91c --- /dev/null +++ b/client/clientspace/clientcache/treecache.go @@ -0,0 +1,108 @@ +package clientcache + +import ( + "context" + "errors" + "github.com/anytypeio/go-anytype-infrastructure-experiments/client/clientspace" + "github.com/anytypeio/go-anytype-infrastructure-experiments/client/document/textdocument" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/account" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ocache" + "go.uber.org/zap" + "time" +) + +var log = logger.NewNamed("treecache") +var ErrCacheObjectWithoutTree = errors.New("cache object contains no tree") + +type ctxKey int + +const spaceKey ctxKey = 0 + +type treeCache struct { + gcttl int + cache ocache.OCache + account account.Service + clientService clientspace.Service +} + +type TreeCache interface { + treegetter.TreeGetter + GetDocument(ctx context.Context, spaceId, id string) (doc textdocument.TextDocument, err error) +} + +type updateListener struct { +} + +func (u *updateListener) Update(tree tree.ObjectTree) { + log.With( + zap.Strings("heads", tree.Heads()), + zap.String("tree id", tree.ID())). + Debug("updating tree") +} + +func (u *updateListener) Rebuild(tree tree.ObjectTree) { + log.With( + zap.Strings("heads", tree.Heads()), + zap.String("tree id", tree.ID())). + Debug("rebuilding tree") +} + +func New(ttl int) TreeCache { + return &treeCache{ + gcttl: ttl, + } +} + +func (c *treeCache) Run(ctx context.Context) (err error) { + return nil +} + +func (c *treeCache) Close(ctx context.Context) (err error) { + return c.cache.Close() +} + +func (c *treeCache) Init(a *app.App) (err error) { + c.clientService = a.MustComponent(clientspace.CName).(clientspace.Service) + c.account = a.MustComponent(account.CName).(account.Service) + c.cache = ocache.New( + func(ctx context.Context, id string) (value ocache.Object, err error) { + spaceId := ctx.Value(spaceKey).(string) + space, err := c.clientService.GetSpace(ctx, spaceId) + if err != nil { + return + } + return textdocument.NewTextDocument(ctx, space, id, &updateListener{}, c.account) + }, + ocache.WithLogger(log.Sugar()), + ocache.WithGCPeriod(time.Minute), + ocache.WithTTL(time.Duration(c.gcttl)*time.Second), + ) + return nil +} + +func (c *treeCache) Name() (name string) { + return treegetter.CName +} + +func (c *treeCache) GetDocument(ctx context.Context, spaceId, id string) (doc textdocument.TextDocument, err error) { + ctx = context.WithValue(ctx, spaceKey, spaceId) + v, err := c.cache.Get(ctx, id) + if err != nil { + return + } + doc = v.(textdocument.TextDocument) + return +} + +func (c *treeCache) GetTree(ctx context.Context, spaceId, id string) (tr tree.ObjectTree, err error) { + doc, err := c.GetDocument(ctx, spaceId, id) + if err != nil { + return + } + tr = doc.Tree() + return +} diff --git a/client/clientspace/rpchandler.go b/client/clientspace/rpchandler.go new file mode 100644 index 00000000..8f6a7989 --- /dev/null +++ b/client/clientspace/rpchandler.go @@ -0,0 +1,63 @@ +package clientspace + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" +) + +type rpcHandler struct { + s *service +} + +func (r *rpcHandler) PullSpace(ctx context.Context, request *spacesyncproto.PullSpaceRequest) (resp *spacesyncproto.PullSpaceResponse, err error) { + sp, err := r.s.GetSpace(ctx, request.Id) + if err != nil { + if err != spacesyncproto.ErrSpaceMissing { + err = spacesyncproto.ErrUnexpected + } + return + } + + description := sp.Description() + resp = &spacesyncproto.PullSpaceResponse{ + SpaceHeader: description.SpaceHeader, + AclPayload: description.AclPayload, + AclPayloadId: description.AclId, + } + return +} + +func (r *rpcHandler) PushSpace(ctx context.Context, req *spacesyncproto.PushSpaceRequest) (resp *spacesyncproto.PushSpaceResponse, err error) { + description := commonspace.SpaceDescription{ + SpaceHeader: req.SpaceHeader, + AclId: req.AclPayloadId, + AclPayload: req.AclPayload, + } + err = r.s.AddSpace(ctx, description) + if err != nil { + return + } + resp = &spacesyncproto.PushSpaceResponse{} + return +} + +func (r *rpcHandler) HeadSync(ctx context.Context, req *spacesyncproto.HeadSyncRequest) (*spacesyncproto.HeadSyncResponse, error) { + sp, err := r.s.GetSpace(ctx, req.SpaceId) + if err != nil { + return nil, spacesyncproto.ErrSpaceMissing + } + return sp.SpaceSyncRpc().HeadSync(ctx, req) +} + +func (r *rpcHandler) Stream(stream spacesyncproto.DRPCSpace_StreamStream) error { + msg, err := stream.Recv() + if err != nil { + return err + } + sp, err := r.s.GetSpace(stream.Context(), msg.SpaceId) + if err != nil { + return spacesyncproto.ErrSpaceMissing + } + return sp.SpaceSyncRpc().Stream(stream) +} diff --git a/client/clientspace/service.go b/client/clientspace/service.go new file mode 100644 index 00000000..d22ab135 --- /dev/null +++ b/client/clientspace/service.go @@ -0,0 +1,115 @@ +package clientspace + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage" + config2 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/config" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/rpc/server" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ocache" + "time" +) + +const CName = "client.clientspace" + +var log = logger.NewNamed(CName) + +func New() Service { + return &service{} +} + +type Service interface { + GetSpace(ctx context.Context, id string) (commonspace.Space, error) + AddSpace(ctx context.Context, description commonspace.SpaceDescription) (err error) + CreateSpace(ctx context.Context, payload commonspace.SpaceCreatePayload) (commonspace.Space, error) + DeriveSpace(ctx context.Context, payload commonspace.SpaceDerivePayload) (commonspace.Space, error) + app.ComponentRunnable +} + +type service struct { + conf config2.Space + spaceCache ocache.OCache + commonSpace commonspace.Service + spaceStorageProvider storage.SpaceStorageProvider +} + +func (s *service) Init(a *app.App) (err error) { + s.conf = a.MustComponent(config2.CName).(*config2.Config).Space + s.commonSpace = a.MustComponent(commonspace.CName).(commonspace.Service) + s.spaceStorageProvider = a.MustComponent(storage.CName).(storage.SpaceStorageProvider) + s.spaceCache = ocache.New( + s.loadSpace, + ocache.WithLogger(log.Sugar()), + ocache.WithGCPeriod(time.Minute), + ocache.WithTTL(time.Duration(s.conf.GCTTL)*time.Second), + ) + return spacesyncproto.DRPCRegisterSpace(a.MustComponent(server.CName).(server.DRPCServer), &rpcHandler{s}) +} + +func (s *service) Name() (name string) { + return CName +} + +func (s *service) Run(ctx context.Context) (err error) { + return +} + +func (s *service) CreateSpace(ctx context.Context, payload commonspace.SpaceCreatePayload) (container commonspace.Space, err error) { + id, err := s.commonSpace.CreateSpace(ctx, payload) + if err != nil { + return + } + + obj, err := s.spaceCache.Get(ctx, id) + if err != nil { + return + } + return obj.(commonspace.Space), nil +} + +func (s *service) DeriveSpace(ctx context.Context, payload commonspace.SpaceDerivePayload) (container commonspace.Space, err error) { + id, err := s.commonSpace.DeriveSpace(ctx, payload) + if err != nil { + return + } + + obj, err := s.spaceCache.Get(ctx, id) + if err != nil { + return + } + return obj.(commonspace.Space), nil +} + +func (s *service) GetSpace(ctx context.Context, id string) (container commonspace.Space, err error) { + v, err := s.spaceCache.Get(ctx, id) + if err != nil { + return + } + return v.(commonspace.Space), nil +} + +func (s *service) AddSpace(ctx context.Context, description commonspace.SpaceDescription) (err error) { + return s.commonSpace.AddSpace(ctx, description) +} + +func (s *service) loadSpace(ctx context.Context, id string) (value ocache.Object, err error) { + cc, err := s.commonSpace.NewSpace(ctx, id) + if err != nil { + return + } + ns, err := newClientSpace(cc) + if err != nil { + return + } + if err = ns.Init(ctx); err != nil { + return + } + return ns, nil +} + +func (s *service) Close(ctx context.Context) (err error) { + return s.spaceCache.Close() +} diff --git a/client/clientspace/space.go b/client/clientspace/space.go new file mode 100644 index 00000000..f0e7fda3 --- /dev/null +++ b/client/clientspace/space.go @@ -0,0 +1,22 @@ +package clientspace + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace" +) + +func newClientSpace(cc commonspace.Space) (commonspace.Space, error) { + return &clientSpace{cc}, nil +} + +type clientSpace struct { + commonspace.Space +} + +func (s *clientSpace) Init(ctx context.Context) (err error) { + return s.Space.Init(ctx) +} + +func (s *clientSpace) Close() (err error) { + return s.Space.Close() +} diff --git a/client/cmd/client.go b/client/cmd/client.go new file mode 100644 index 00000000..b3698842 --- /dev/null +++ b/client/cmd/client.go @@ -0,0 +1,112 @@ +package main + +import ( + "context" + "flag" + "fmt" + "github.com/anytypeio/go-anytype-infrastructure-experiments/client/account" + "github.com/anytypeio/go-anytype-infrastructure-experiments/client/api" + "github.com/anytypeio/go-anytype-infrastructure-experiments/client/badgerprovider" + "github.com/anytypeio/go-anytype-infrastructure-experiments/client/clientspace" + "github.com/anytypeio/go-anytype-infrastructure-experiments/client/clientspace/clientcache" + "github.com/anytypeio/go-anytype-infrastructure-experiments/client/document" + "github.com/anytypeio/go-anytype-infrastructure-experiments/client/storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/config" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/metric" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/dialer" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/pool" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/rpc/server" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/secure" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf" + "go.uber.org/zap" + "net/http" + _ "net/http/pprof" + "os" + "os/signal" + "syscall" + "time" +) + +var log = logger.NewNamed("main") + +var ( + flagConfigFile = flag.String("c", "etc/client.yml", "path to config file") + // we can't use "v" here because of glog init (through badger) setting flag.Bool with "v" + flagVersion = flag.Bool("ver", false, "show version and exit") + flagHelp = flag.Bool("h", false, "show help and exit") +) + +func main() { + flag.Parse() + + if *flagVersion { + fmt.Println(app.VersionDescription()) + return + } + if *flagHelp { + flag.PrintDefaults() + return + } + + if debug, ok := os.LookupEnv("ANYPROF"); ok && debug != "" { + go func() { + http.ListenAndServe(debug, nil) + }() + } + + // create app + ctx := context.Background() + a := new(app.App) + + // open config file + conf, err := config.NewFromFile(*flagConfigFile) + if err != nil { + log.Fatal("can't open config file", zap.Error(err)) + } + + // bootstrap components + a.Register(conf) + Bootstrap(a) + + // start app + if err := a.Start(ctx); err != nil { + log.Fatal("can't start app", zap.Error(err)) + } + log.Info("app started", zap.String("version", a.Version())) + + // wait exit signal + exit := make(chan os.Signal, 1) + signal.Notify(exit, os.Interrupt, syscall.SIGKILL, syscall.SIGTERM, syscall.SIGQUIT) + sig := <-exit + log.Info("received exit signal, stop app...", zap.String("signal", fmt.Sprint(sig))) + + // close app + ctx, cancel := context.WithTimeout(ctx, time.Minute) + defer cancel() + if err := a.Close(ctx); err != nil { + log.Fatal("close error", zap.Error(err)) + } else { + log.Info("goodbye!") + } + time.Sleep(time.Second / 3) +} + +func Bootstrap(a *app.App) { + a.Register(account.New()). + Register(nodeconf.New()). + Register(metric.New()). + Register(badgerprovider.New()). + Register(storage.New()). + Register(clientcache.New(200)). + Register(secure.New()). + Register(dialer.New()). + Register(pool.New()). + Register(commonspace.New()). + Register(clientspace.New()). + Register(server.New()). + Register(document.New()). + Register(api.New()) +} diff --git a/client/document/service.go b/client/document/service.go new file mode 100644 index 00000000..399363b8 --- /dev/null +++ b/client/document/service.go @@ -0,0 +1,83 @@ +package document + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/client/clientspace" + "github.com/anytypeio/go-anytype-infrastructure-experiments/client/clientspace/clientcache" + "github.com/anytypeio/go-anytype-infrastructure-experiments/client/document/textdocument" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/account" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter" +) + +type Service interface { + app.Component + CreateDocument(spaceId string) (id string, err error) + AllDocumentIds(spaceId string) (ids []string, err error) + AddText(spaceId, documentId, text string) (err error) + DumpDocumentTree(spaceId, documentId string) (dump string, err error) +} + +const CName = "client.document" + +var log = logger.NewNamed(CName) + +type service struct { + account account.Service + spaceService clientspace.Service + cache clientcache.TreeCache +} + +func New() Service { + return &service{} +} + +func (s *service) Init(a *app.App) (err error) { + s.account = a.MustComponent(account.CName).(account.Service) + s.spaceService = a.MustComponent(clientspace.CName).(clientspace.Service) + s.cache = a.MustComponent(treegetter.CName).(clientcache.TreeCache) + return +} + +func (s *service) Name() (name string) { + return CName +} + +func (s *service) CreateDocument(spaceId string) (id string, err error) { + space, err := s.spaceService.GetSpace(context.Background(), spaceId) + if err != nil { + return + } + doc, err := textdocument.CreateTextDocument(context.Background(), space, s.account, nil) + if err != nil { + return + } + id = doc.Tree().ID() + return +} + +func (s *service) AllDocumentIds(spaceId string) (ids []string, err error) { + space, err := s.spaceService.GetSpace(context.Background(), spaceId) + if err != nil { + return + } + ids = space.StoredIds() + return +} + +func (s *service) AddText(spaceId, documentId, text string) (err error) { + doc, err := s.cache.GetDocument(context.Background(), spaceId, documentId) + if err != nil { + return + } + return doc.AddText(text) +} + +func (s *service) DumpDocumentTree(spaceId, documentId string) (dump string, err error) { + doc, err := s.cache.GetDocument(context.Background(), spaceId, documentId) + if err != nil { + return + } + return doc.Tree().DebugDump() +} diff --git a/client/document/textdocument/textdocument.go b/client/document/textdocument/textdocument.go new file mode 100644 index 00000000..7b754670 --- /dev/null +++ b/client/document/textdocument/textdocument.go @@ -0,0 +1,116 @@ +package textdocument + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/account" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree/updatelistener" + testchanges "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/testutils/testchanges/proto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree" + "github.com/gogo/protobuf/proto" +) + +type TextDocument interface { + Tree() tree.ObjectTree + AddText(text string) error + Text() (string, error) + TreeDump() string + Close() error +} + +type textDocument struct { + objTree tree.ObjectTree + account account.Service +} + +func CreateTextDocument( + ctx context.Context, + space commonspace.Space, + account account.Service, + listener updatelistener.UpdateListener) (doc TextDocument, err error) { + payload := tree.ObjectTreeCreatePayload{ + SignKey: account.Account().SignKey, + SpaceId: space.Id(), + Identity: account.Account().Identity, + } + t, err := space.CreateTree(ctx, payload, listener) + if err != nil { + return + } + + return &textDocument{ + objTree: t, + account: account, + }, nil +} + +func NewTextDocument(ctx context.Context, space commonspace.Space, id string, listener updatelistener.UpdateListener, account account.Service) (doc TextDocument, err error) { + t, err := space.BuildTree(ctx, id, listener) + if err != nil { + return + } + return &textDocument{ + objTree: t, + account: account, + }, nil +} + +func (t *textDocument) Tree() tree.ObjectTree { + return t.objTree +} + +func (t *textDocument) AddText(text string) (err error) { + content := &testchanges.TextContent_TextAppend{ + TextAppend: &testchanges.TextAppend{Text: text}, + } + change := &testchanges.TextData{ + Content: []*testchanges.TextContent{ + {content}, + }, + Snapshot: nil, + } + res, err := change.Marshal() + if err != nil { + return + } + t.objTree.Lock() + defer t.objTree.Unlock() + _, err = t.objTree.AddContent(context.Background(), tree.SignableChangeContent{ + Data: res, + Key: t.account.Account().SignKey, + Identity: t.account.Account().Identity, + IsSnapshot: false, + }) + return +} + +func (t *textDocument) Text() (text string, err error) { + t.objTree.RLock() + defer t.objTree.RUnlock() + + err = t.objTree.Iterate( + func(decrypted []byte) (any, error) { + textChange := &testchanges.TextData{} + err = proto.Unmarshal(decrypted, textChange) + if err != nil { + return nil, err + } + for _, cnt := range textChange.Content { + if cnt.GetTextAppend() != nil { + text += cnt.GetTextAppend().Text + } + } + return textChange, nil + }, func(change *tree.Change) bool { + return true + }) + return +} + +func (t *textDocument) TreeDump() string { + return t.TreeDump() +} + +func (t *textDocument) Close() error { + return nil +} diff --git a/client/go.mod b/client/go.mod new file mode 100644 index 00000000..8aeae7af --- /dev/null +++ b/client/go.mod @@ -0,0 +1,71 @@ +module github.com/anytypeio/go-anytype-infrastructure-experiments/client + +replace github.com/anytypeio/go-anytype-infrastructure-experiments/common => ../common + +go 1.19 + +require ( + github.com/anytypeio/go-anytype-infrastructure-experiments/common v0.0.0-00010101000000-000000000000 + github.com/dgraph-io/badger/v3 v3.2103.3 + github.com/gogo/protobuf v1.3.2 + go.uber.org/zap v1.23.0 +) + +require ( + github.com/anytypeio/go-chash v0.0.0-20220629194632-4ad1154fe232 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash v1.1.0 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect + github.com/dgraph-io/ristretto v0.1.1 // indirect + github.com/dustin/go-humanize v1.0.0 // indirect + github.com/fogleman/gg v1.3.0 // indirect + github.com/goccy/go-graphviz v0.0.9 // indirect + github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect + github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // 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/flatbuffers v1.12.1 // indirect + github.com/huandu/skiplist v1.2.0 // indirect + github.com/ipfs/go-cid v0.3.2 // indirect + github.com/ipfs/go-log/v2 v2.5.1 // indirect + github.com/klauspost/compress v1.15.10 // indirect + github.com/klauspost/cpuid/v2 v2.1.1 // indirect + github.com/libp2p/go-buffer-pool v0.1.0 // indirect + github.com/libp2p/go-libp2p v0.23.2 // indirect + github.com/libp2p/go-libp2p-core v0.20.1 // indirect + github.com/libp2p/go-openssl v0.1.0 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-pointer v0.0.1 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/minio/sha256-simd v1.0.0 // indirect + github.com/mr-tron/base58 v1.2.0 // indirect + github.com/multiformats/go-base32 v0.1.0 // indirect + github.com/multiformats/go-base36 v0.1.0 // indirect + github.com/multiformats/go-multiaddr v0.7.0 // indirect + github.com/multiformats/go-multibase v0.1.1 // indirect + github.com/multiformats/go-multicodec v0.6.0 // indirect + github.com/multiformats/go-multihash v0.2.1 // indirect + github.com/multiformats/go-varint v0.0.6 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/prometheus/client_golang v1.13.0 // indirect + github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/common v0.37.0 // indirect + github.com/prometheus/procfs v0.8.0 // indirect + github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect + github.com/zeebo/blake3 v0.2.3 // indirect + github.com/zeebo/errs v1.3.0 // indirect + go.opencensus.io v0.23.0 // indirect + go.uber.org/atomic v1.10.0 // indirect + go.uber.org/multierr v1.8.0 // indirect + golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect + golang.org/x/image v0.0.0-20200119044424-58c23975cae1 // indirect + golang.org/x/net v0.0.0-20220920183852-bf014ff85ad5 // indirect + golang.org/x/sys v0.0.0-20221010170243-090e33056c14 // indirect + google.golang.org/protobuf v1.28.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + lukechampine.com/blake3 v1.1.7 // indirect + storj.io/drpc v0.0.32 // indirect +) diff --git a/client/go.sum b/client/go.sum new file mode 100644 index 00000000..b91db95f --- /dev/null +++ b/client/go.sum @@ -0,0 +1,660 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +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= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/anytypeio/go-chash v0.0.0-20220629194632-4ad1154fe232 h1:kMPPZYmJgbs4AJfodbg2OCXg5cp+9LPAJcLZJqmcghk= +github.com/anytypeio/go-chash v0.0.0-20220629194632-4ad1154fe232/go.mod h1:+PeHBAWp7gUh/yw6uAauKc5ku0w4cFNg6DUddGxoGq0= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/awalterschulze/gographviz v2.0.3+incompatible h1:9sVEXJBJLwGX7EQVhLm2elIKCm7P2YHFC8v6096G09E= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/corona10/goimagehash v1.0.2 h1:pUfB0LnsJASMPGEZLj7tGY251vF+qLGqOgEP4rUs6kA= +github.com/corona10/goimagehash v1.0.2/go.mod h1:/l9umBhvcHQXVtQO1V6Gp1yD20STawkhRnnX0D1bvVI= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= +github.com/dgraph-io/badger/v3 v3.2103.3 h1:s63J1pisDhKpzWslXFe+ChuthuZptpwTE6qEKoczPb4= +github.com/dgraph-io/badger/v3 v3.2103.3/go.mod h1:4MPiseMeDQ3FNCYwRbbcBOGJLf5jsE0PPFzRiKjtcdw= +github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= +github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8= +github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/goccy/go-graphviz v0.0.9 h1:s/FMMJ1Joj6La3S5ApO3Jk2cwM4LpXECC2muFx3IPQQ= +github.com/goccy/go-graphviz v0.0.9/go.mod h1:wXVsXxmyMQU6TN3zGRttjNn3h+iCAS7xQFC6TlNvLhk= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +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= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= +github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c= +github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= +github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw= +github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/ipfs/go-cid v0.3.2 h1:OGgOd+JCFM+y1DjWPmVH+2/4POtpDzwcr7VgnB7mZXc= +github.com/ipfs/go-cid v0.3.2/go.mod h1:gQ8pKqT/sUxGY+tIwy1RPpAojYu7jAyCp5Tz1svoupw= +github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= +github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.15.10 h1:Ai8UzuomSCDw90e1qNMtb15msBXsNpH6gzkkENQNcJo= +github.com/klauspost/compress v1.15.10/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= +github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= +github.com/klauspost/cpuid/v2 v2.1.1 h1:t0wUqjowdm8ezddV5k0tLWVklVuvLJpoHeb4WBdydm0= +github.com/klauspost/cpuid/v2 v2.1.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= +github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= +github.com/libp2p/go-libp2p v0.23.2 h1:yqyTeKQJyofWXxEv/eEVUvOrGdt/9x+0PIQ4N1kaxmE= +github.com/libp2p/go-libp2p v0.23.2/go.mod h1:s9DEa5NLR4g+LZS+md5uGU4emjMWFiqkZr6hBTY8UxI= +github.com/libp2p/go-libp2p-core v0.20.1 h1:fQz4BJyIFmSZAiTbKV8qoYhEH5Dtv/cVhZbG3Ib/+Cw= +github.com/libp2p/go-libp2p-core v0.20.1/go.mod h1:6zR8H7CvQWgYLsbG4on6oLNSGcyKaYFSEYyDt51+bIY= +github.com/libp2p/go-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+Ooo= +github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= +github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= +github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= +github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= +github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= +github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4= +github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= +github.com/multiformats/go-multiaddr v0.7.0 h1:gskHcdaCyPtp9XskVwtvEeQOG465sCohbQIirSyqxrc= +github.com/multiformats/go-multiaddr v0.7.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs= +github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI= +github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8= +github.com/multiformats/go-multicodec v0.6.0 h1:KhH2kSuCARyuJraYMFxrNO3DqIaYhOdS039kbhgVwpE= +github.com/multiformats/go-multicodec v0.6.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw= +github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108= +github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= +github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY= +github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5 h1:BvoENQQU+fZ9uukda/RzCAL/191HHwJA5b13R6diVlY= +github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU= +github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= +github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= +github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= +github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= +github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg= +github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvvKCaQ= +github.com/zeebo/errs v1.3.0 h1:hmiaKqgYZzcVgRL1Vkc1Mn2914BbzB0IBxs+ebeutGs= +github.com/zeebo/errs v1.3.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= +github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= +github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +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.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= +go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= +go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= +go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= +golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200119044424-58c23975cae1 h1:5h3ngYt7+vXCDZCup/HkCQgW5XwmSvR/nA2JmJ0RErg= +golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220920183852-bf014ff85ad5 h1:KafLifaRFIuSJ5C+7CyFJOF9haxKNC1CEIDk8GX6X0k= +golang.org/x/net v0.0.0-20220920183852-bf014ff85ad5/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +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= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20221010170243-090e33056c14 h1:k5II8e6QD8mITdi+okbbmR/cIyEbeXLBhy5Ha4nevyc= +golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +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= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +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/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 h1:VpOs+IwYnYBaFnrNAeB8UUWtL3vEUnzSCL1nVjPhqrw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= +lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +storj.io/drpc v0.0.32 h1:5p5ZwsK/VOgapaCu+oxaPVwO6UwIs+iwdMiD50+R4PI= +storj.io/drpc v0.0.32/go.mod h1:6rcOyR/QQkSTX/9L5ZGtlZaE2PtXTTZl8d+ulSeeYEg= diff --git a/client/storage/helpers.go b/client/storage/helpers.go new file mode 100644 index 00000000..d1d5915a --- /dev/null +++ b/client/storage/helpers.go @@ -0,0 +1,41 @@ +package storage + +import ( + "github.com/dgraph-io/badger/v3" +) + +func hasDB(db *badger.DB, key []byte) bool { + return db.View(func(txn *badger.Txn) error { + _, err := txn.Get(key) + return err + }) == nil +} + +func putDB(db *badger.DB, key, value []byte) (err error) { + return db.Update(func(txn *badger.Txn) error { + return txn.Set(key, value) + }) +} + +func getDB(db *badger.DB, key []byte) (value []byte, err error) { + err = db.View(func(txn *badger.Txn) error { + item, err := txn.Get(key) + if err != nil { + return err + } + value, err = item.ValueCopy(value) + if err != nil { + return err + } + return err + }) + return +} + +func getTxn(txn *badger.Txn, key []byte) (value []byte, err error) { + item, err := txn.Get(key) + if err != nil { + return + } + return item.ValueCopy(value) +} diff --git a/client/storage/keys.go b/client/storage/keys.go new file mode 100644 index 00000000..05bf7e7f --- /dev/null +++ b/client/storage/keys.go @@ -0,0 +1,91 @@ +package storage + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage" +) + +type aclKeys struct { + spaceId string + rootKey []byte + headKey []byte +} + +func newACLKeys(spaceId string) aclKeys { + return aclKeys{ + spaceId: spaceId, + rootKey: storage.JoinStringsToBytes("space", spaceId, "a", "rootId"), + headKey: storage.JoinStringsToBytes("space", spaceId, "a", "headId"), + } +} + +func (a aclKeys) HeadIdKey() []byte { + return a.headKey +} + +func (a aclKeys) RootIdKey() []byte { + return a.rootKey +} + +func (a aclKeys) RawRecordKey(id string) []byte { + return storage.JoinStringsToBytes("space", a.spaceId, "a", id) +} + +type treeKeys struct { + id string + spaceId string + headsKey []byte + rootKey []byte +} + +func newTreeKeys(spaceId, id string) treeKeys { + return treeKeys{ + id: id, + spaceId: spaceId, + headsKey: storage.JoinStringsToBytes("space", spaceId, "t", id, "heads"), + rootKey: storage.JoinStringsToBytes("space", spaceId, "t", "rootId", id), + } +} + +func (t treeKeys) HeadsKey() []byte { + return t.headsKey +} + +func (t treeKeys) RootIdKey() []byte { + return t.rootKey +} + +func (t treeKeys) RawChangeKey(id string) []byte { + return storage.JoinStringsToBytes("space", t.spaceId, "t", t.id, id) +} + +type spaceKeys struct { + headerKey []byte + treePrefixKey []byte +} + +func newSpaceKeys(spaceId string) spaceKeys { + return spaceKeys{ + headerKey: storage.JoinStringsToBytes("space", "header", spaceId), + treePrefixKey: storage.JoinStringsToBytes("space", spaceId, "t", "rootId"), + } +} + +func (s spaceKeys) HeaderKey() []byte { + return s.headerKey +} + +func (s spaceKeys) TreeRootPrefix() []byte { + return s.treePrefixKey +} + +type storageServiceKeys struct { + spacePrefix []byte +} + +func newStorageServiceKeys() storageServiceKeys { + return storageServiceKeys{spacePrefix: []byte("space/header")} +} + +func (s storageServiceKeys) SpacePrefix() []byte { + return s.spacePrefix +} diff --git a/client/storage/liststorage.go b/client/storage/liststorage.go new file mode 100644 index 00000000..fbe10d35 --- /dev/null +++ b/client/storage/liststorage.go @@ -0,0 +1,119 @@ +package storage + +import ( + "context" + "errors" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage" + "github.com/dgraph-io/badger/v3" +) + +var ErrIncorrectKey = errors.New("key format is incorrect") + +type listStorage struct { + db *badger.DB + keys aclKeys + id string + root *aclrecordproto.RawACLRecordWithId +} + +func newListStorage(spaceId string, db *badger.DB, txn *badger.Txn) (ls storage.ListStorage, err error) { + keys := newACLKeys(spaceId) + rootId, err := getTxn(txn, keys.RootIdKey()) + if err != nil { + return + } + + stringId := string(rootId) + value, err := getTxn(txn, keys.RawRecordKey(stringId)) + if err != nil { + return + } + + rootWithId := &aclrecordproto.RawACLRecordWithId{ + Payload: value, + Id: stringId, + } + + ls = &listStorage{ + db: db, + keys: keys, + id: stringId, + root: rootWithId, + } + return +} + +func createListStorage(spaceId string, db *badger.DB, txn *badger.Txn, root *aclrecordproto.RawACLRecordWithId) (ls storage.ListStorage, err error) { + keys := newACLKeys(spaceId) + _, err = getTxn(txn, keys.RootIdKey()) + if err != badger.ErrKeyNotFound { + if err == nil { + return newListStorage(spaceId, db, txn) + } + return + } + + err = txn.Set(keys.HeadIdKey(), []byte(root.Id)) + if err != nil { + return + } + + err = txn.Set(keys.RawRecordKey(root.Id), root.Payload) + if err != nil { + return + } + err = txn.Set(keys.RootIdKey(), []byte(root.Id)) + if err != nil { + return + } + + ls = &listStorage{ + db: db, + keys: keys, + id: root.Id, + root: root, + } + return +} + +func (l *listStorage) Id() string { + return l.id +} + +func (l *listStorage) Root() (*aclrecordproto.RawACLRecordWithId, error) { + return l.root, nil +} + +func (l *listStorage) Head() (head string, err error) { + bytes, err := getDB(l.db, l.keys.HeadIdKey()) + if err != nil { + return + } + head = string(bytes) + return +} + +func (l *listStorage) GetRawRecord(ctx context.Context, id string) (raw *aclrecordproto.RawACLRecordWithId, err error) { + res, err := getDB(l.db, l.keys.RawRecordKey(id)) + if err != nil { + if err == badger.ErrKeyNotFound { + err = storage.ErrUnknownRecord + } + return + } + + raw = &aclrecordproto.RawACLRecordWithId{ + Payload: res, + Id: id, + } + return +} + +func (l *listStorage) SetHead(headId string) (err error) { + return putDB(l.db, l.keys.HeadIdKey(), []byte(headId)) +} + +func (l *listStorage) AddRawRecord(ctx context.Context, rec *aclrecordproto.RawACLRecordWithId) error { + return putDB(l.db, l.keys.RawRecordKey(rec.Id), rec.Payload) +} diff --git a/client/storage/liststorage_test.go b/client/storage/liststorage_test.go new file mode 100644 index 00000000..4c4df686 --- /dev/null +++ b/client/storage/liststorage_test.go @@ -0,0 +1,72 @@ +package storage + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage" + "github.com/dgraph-io/badger/v3" + "github.com/stretchr/testify/require" + "testing" +) + +func testList(t *testing.T, store storage.ListStorage, root *aclrecordproto.RawACLRecordWithId, head string) { + require.Equal(t, store.Id(), root.Id) + + aclRoot, err := store.Root() + require.NoError(t, err) + require.Equal(t, root, aclRoot) + + aclHead, err := store.Head() + require.NoError(t, err) + require.Equal(t, head, aclHead) +} + +func TestListStorage(t *testing.T) { + fx := newFixture(t) + fx.open(t) + defer fx.stop(t) + spaceId := "spaceId" + aclRoot := &aclrecordproto.RawACLRecordWithId{Payload: []byte("root"), Id: "someRootId"} + + fx.db.Update(func(txn *badger.Txn) error { + _, err := createListStorage(spaceId, fx.db, txn, aclRoot) + require.NoError(t, err) + return nil + }) + + var listStore storage.ListStorage + fx.db.View(func(txn *badger.Txn) (err error) { + listStore, err = newListStorage(spaceId, fx.db, txn) + require.NoError(t, err) + testList(t, listStore, aclRoot, aclRoot.Id) + + return nil + }) + + t.Run("create same storage returns no error", func(t *testing.T) { + fx.db.View(func(txn *badger.Txn) error { + // this is ok, because we only create new list storage when we create space storage + listStore, err := createListStorage(spaceId, fx.db, txn, aclRoot) + require.NoError(t, err) + testList(t, listStore, aclRoot, aclRoot.Id) + + return nil + }) + }) + + t.Run("set head", func(t *testing.T) { + head := "newHead" + require.NoError(t, listStore.SetHead(head)) + aclHead, err := listStore.Head() + require.NoError(t, err) + require.Equal(t, head, aclHead) + }) + + t.Run("add raw record and get raw record", func(t *testing.T) { + newRec := &aclrecordproto.RawACLRecordWithId{Payload: []byte("rec"), Id: "someRecId"} + require.NoError(t, listStore.AddRawRecord(context.Background(), newRec)) + aclRec, err := listStore.GetRawRecord(context.Background(), newRec.Id) + require.NoError(t, err) + require.Equal(t, newRec, aclRec) + }) +} diff --git a/client/storage/spacestorage.go b/client/storage/spacestorage.go new file mode 100644 index 00000000..8d41b298 --- /dev/null +++ b/client/storage/spacestorage.go @@ -0,0 +1,129 @@ +package storage + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" + spacestorage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage" + storage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage" + "github.com/dgraph-io/badger/v3" + "sync" +) + +type spaceStorage struct { + spaceId string + objDb *badger.DB + keys spaceKeys + aclStorage storage.ListStorage + header *spacesyncproto.RawSpaceHeaderWithId + mx sync.Mutex +} + +func newSpaceStorage(objDb *badger.DB, spaceId string) (store spacestorage.SpaceStorage, err error) { + keys := newSpaceKeys(spaceId) + err = objDb.View(func(txn *badger.Txn) error { + header, err := getTxn(txn, keys.HeaderKey()) + if err != nil { + return err + } + + aclStorage, err := newListStorage(spaceId, objDb, txn) + if err != nil { + return err + } + + store = &spaceStorage{ + spaceId: spaceId, + objDb: objDb, + keys: keys, + header: &spacesyncproto.RawSpaceHeaderWithId{ + RawHeader: header, + Id: spaceId, + }, + aclStorage: aclStorage, + } + return nil + }) + if err == badger.ErrKeyNotFound { + err = spacesyncproto.ErrSpaceMissing + } + return +} + +func createSpaceStorage(db *badger.DB, payload spacestorage.SpaceStorageCreatePayload) (store spacestorage.SpaceStorage, err error) { + keys := newSpaceKeys(payload.SpaceHeaderWithId.Id) + if hasDB(db, keys.HeaderKey()) { + err = spacesyncproto.ErrSpaceExists + return + } + err = db.Update(func(txn *badger.Txn) error { + aclStorage, err := createListStorage(payload.SpaceHeaderWithId.Id, db, txn, payload.RecWithId) + if err != nil { + return err + } + + err = txn.Set(keys.HeaderKey(), payload.SpaceHeaderWithId.RawHeader) + if err != nil { + return err + } + + store = &spaceStorage{ + spaceId: payload.SpaceHeaderWithId.Id, + objDb: db, + keys: keys, + aclStorage: aclStorage, + header: payload.SpaceHeaderWithId, + } + return nil + }) + return +} + +func (s *spaceStorage) Id() string { + return s.spaceId +} + +func (s *spaceStorage) TreeStorage(id string) (storage.TreeStorage, error) { + return newTreeStorage(s.objDb, s.spaceId, id) +} + +func (s *spaceStorage) CreateTreeStorage(payload storage.TreeStorageCreatePayload) (ts storage.TreeStorage, err error) { + // we have mutex here, so we prevent overwriting the heads of a tree on concurrent creation + s.mx.Lock() + defer s.mx.Unlock() + + return createTreeStorage(s.objDb, s.spaceId, payload) +} + +func (s *spaceStorage) ACLStorage() (storage.ListStorage, error) { + return s.aclStorage, nil +} + +func (s *spaceStorage) SpaceHeader() (header *spacesyncproto.RawSpaceHeaderWithId, err error) { + return s.header, nil +} + +func (s *spaceStorage) StoredIds() (ids []string, err error) { + err = s.objDb.View(func(txn *badger.Txn) error { + opts := badger.DefaultIteratorOptions + opts.PrefetchValues = false + opts.Prefix = s.keys.TreeRootPrefix() + + it := txn.NewIterator(opts) + defer it.Close() + + for it.Rewind(); it.Valid(); it.Next() { + item := it.Item() + id := item.Key() + if len(id) <= len(s.keys.TreeRootPrefix())+1 { + continue + } + id = id[len(s.keys.TreeRootPrefix())+1:] + ids = append(ids, string(id)) + } + return nil + }) + return +} + +func (s *spaceStorage) Close() (err error) { + return nil +} diff --git a/client/storage/spacestorage_test.go b/client/storage/spacestorage_test.go new file mode 100644 index 00000000..8540d338 --- /dev/null +++ b/client/storage/spacestorage_test.go @@ -0,0 +1,108 @@ +package storage + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" + spacestorage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" + "github.com/stretchr/testify/require" + "strconv" + "testing" +) + +func spaceTestPayload() spacestorage.SpaceStorageCreatePayload { + header := &spacesyncproto.RawSpaceHeaderWithId{ + RawHeader: []byte("header"), + Id: "headerId", + } + aclRoot := &aclrecordproto.RawACLRecordWithId{ + Payload: []byte("aclRoot"), + Id: "aclRootId", + } + return spacestorage.SpaceStorageCreatePayload{ + RecWithId: aclRoot, + SpaceHeaderWithId: header, + } +} + +func testSpace(t *testing.T, store spacestorage.SpaceStorage, payload spacestorage.SpaceStorageCreatePayload) { + header, err := store.SpaceHeader() + require.NoError(t, err) + require.Equal(t, payload.SpaceHeaderWithId, header) + + aclStorage, err := store.ACLStorage() + require.NoError(t, err) + testList(t, aclStorage, payload.RecWithId, payload.RecWithId.Id) +} + +func TestSpaceStorage_Create(t *testing.T) { + fx := newFixture(t) + fx.open(t) + defer fx.stop(t) + + payload := spaceTestPayload() + store, err := createSpaceStorage(fx.db, payload) + require.NoError(t, err) + + testSpace(t, store, payload) + require.NoError(t, store.Close()) + + t.Run("create same storage returns error", func(t *testing.T) { + _, err := createSpaceStorage(fx.db, payload) + require.Error(t, err) + }) +} + +func TestSpaceStorage_NewAndCreateTree(t *testing.T) { + fx := newFixture(t) + fx.open(t) + + payload := spaceTestPayload() + store, err := createSpaceStorage(fx.db, payload) + require.NoError(t, err) + require.NoError(t, store.Close()) + fx.stop(t) + + fx.open(t) + defer fx.stop(t) + store, err = newSpaceStorage(fx.db, payload.SpaceHeaderWithId.Id) + require.NoError(t, err) + testSpace(t, store, payload) + + t.Run("create tree and get tree", func(t *testing.T) { + payload := treeTestPayload() + treeStore, err := store.CreateTreeStorage(payload) + require.NoError(t, err) + testTreePayload(t, treeStore, payload) + + otherStore, err := store.TreeStorage(payload.RootRawChange.Id) + require.NoError(t, err) + testTreePayload(t, otherStore, payload) + }) +} + +func TestSpaceStorage_StoredIds(t *testing.T) { + fx := newFixture(t) + fx.open(t) + defer fx.stop(t) + + payload := spaceTestPayload() + store, err := createSpaceStorage(fx.db, payload) + require.NoError(t, err) + defer func() { + require.NoError(t, store.Close()) + }() + + n := 5 + var ids []string + for i := 0; i < n; i++ { + treePayload := treeTestPayload() + treePayload.RootRawChange.Id += strconv.Itoa(i) + ids = append(ids, treePayload.RootRawChange.Id) + _, err := store.CreateTreeStorage(treePayload) + require.NoError(t, err) + } + + storedIds, err := store.StoredIds() + require.NoError(t, err) + require.Equal(t, ids, storedIds) +} diff --git a/client/storage/storageservice.go b/client/storage/storageservice.go new file mode 100644 index 00000000..43b9c6f4 --- /dev/null +++ b/client/storage/storageservice.go @@ -0,0 +1,74 @@ +package storage + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/client/badgerprovider" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage" + "github.com/dgraph-io/badger/v3" +) + +type storageService struct { + keys storageServiceKeys + db *badger.DB +} + +type ClientStorage interface { + storage.SpaceStorageProvider + app.ComponentRunnable + AllSpaceIds() (ids []string, err error) +} + +func New() ClientStorage { + return &storageService{} +} + +func (s *storageService) Init(a *app.App) (err error) { + provider := a.MustComponent(badgerprovider.CName).(badgerprovider.BadgerProvider) + s.db = provider.Badger() + s.keys = newStorageServiceKeys() + return +} + +func (s *storageService) Name() (name string) { + return storage.CName +} + +func (s *storageService) SpaceStorage(id string) (storage.SpaceStorage, error) { + return newSpaceStorage(s.db, id) +} + +func (s *storageService) CreateSpaceStorage(payload storage.SpaceStorageCreatePayload) (storage.SpaceStorage, error) { + return createSpaceStorage(s.db, payload) +} + +func (s *storageService) AllSpaceIds() (ids []string, err error) { + err = s.db.View(func(txn *badger.Txn) error { + opts := badger.DefaultIteratorOptions + opts.PrefetchValues = false + opts.Prefix = s.keys.SpacePrefix() + + it := txn.NewIterator(opts) + defer it.Close() + + for it.Rewind(); it.Valid(); it.Next() { + item := it.Item() + id := item.Key() + if len(id) <= len(s.keys.SpacePrefix())+1 { + continue + } + id = id[len(s.keys.SpacePrefix())+1:] + ids = append(ids, string(id)) + } + return nil + }) + return +} + +func (s *storageService) Run(ctx context.Context) (err error) { + return nil +} + +func (s *storageService) Close(ctx context.Context) (err error) { + return s.db.Close() +} diff --git a/client/storage/treestorage.go b/client/storage/treestorage.go new file mode 100644 index 00000000..2c555555 --- /dev/null +++ b/client/storage/treestorage.go @@ -0,0 +1,138 @@ +package storage + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto" + "github.com/dgraph-io/badger/v3" +) + +type treeStorage struct { + db *badger.DB + keys treeKeys + id string + root *treechangeproto.RawTreeChangeWithId +} + +func newTreeStorage(db *badger.DB, spaceId, treeId string) (ts storage.TreeStorage, err error) { + keys := newTreeKeys(spaceId, treeId) + err = db.View(func(txn *badger.Txn) error { + _, err := txn.Get(keys.RootIdKey()) + if err != nil { + return err + } + + root, err := getTxn(txn, keys.RawChangeKey(treeId)) + if err != nil { + return err + } + + rootWithId := &treechangeproto.RawTreeChangeWithId{ + RawChange: root, + Id: treeId, + } + + ts = &treeStorage{ + db: db, + keys: keys, + id: treeId, + root: rootWithId, + } + return nil + }) + if err == badger.ErrKeyNotFound { + err = storage.ErrUnknownTreeId + } + return +} + +func createTreeStorage(db *badger.DB, spaceId string, payload storage.TreeStorageCreatePayload) (ts storage.TreeStorage, err error) { + keys := newTreeKeys(spaceId, payload.RootRawChange.Id) + if hasDB(db, keys.RootIdKey()) { + err = storage.ErrTreeExists + return + } + err = db.Update(func(txn *badger.Txn) error { + heads := storage.CreateHeadsPayload(payload.Heads) + + for _, ch := range payload.Changes { + err = txn.Set(keys.RawChangeKey(ch.Id), ch.GetRawChange()) + if err != nil { + return err + } + } + + err = txn.Set(keys.RawChangeKey(payload.RootRawChange.Id), payload.RootRawChange.GetRawChange()) + if err != nil { + return err + } + + err = txn.Set(keys.HeadsKey(), heads) + if err != nil { + return err + } + + err = txn.Set(keys.RootIdKey(), nil) + if err != nil { + return err + } + + ts = &treeStorage{ + db: db, + keys: keys, + id: payload.RootRawChange.Id, + root: payload.RootRawChange, + } + return nil + }) + return +} + +func (t *treeStorage) Id() string { + return t.id +} + +func (t *treeStorage) Root() (raw *treechangeproto.RawTreeChangeWithId, err error) { + return t.root, nil +} + +func (t *treeStorage) Heads() (heads []string, err error) { + headsBytes, err := getDB(t.db, t.keys.HeadsKey()) + if err != nil { + if err == badger.ErrKeyNotFound { + err = storage.ErrUnknownTreeId + } + return + } + heads = storage.ParseHeads(headsBytes) + return +} + +func (t *treeStorage) SetHeads(heads []string) (err error) { + payload := storage.CreateHeadsPayload(heads) + return putDB(t.db, t.keys.HeadsKey(), payload) +} + +func (t *treeStorage) AddRawChange(change *treechangeproto.RawTreeChangeWithId) (err error) { + return putDB(t.db, t.keys.RawChangeKey(change.Id), change.RawChange) +} + +func (t *treeStorage) GetRawChange(ctx context.Context, id string) (raw *treechangeproto.RawTreeChangeWithId, err error) { + res, err := getDB(t.db, t.keys.RawChangeKey(id)) + if err != nil { + if err == badger.ErrKeyNotFound { + err = storage.ErrUnknownTreeId + } + return + } + + raw = &treechangeproto.RawTreeChangeWithId{ + RawChange: res, + Id: id, + } + return +} + +func (t *treeStorage) HasChange(ctx context.Context, id string) (bool, error) { + return hasDB(t.db, t.keys.RawChangeKey(id)), nil +} diff --git a/client/storage/treestorage_test.go b/client/storage/treestorage_test.go new file mode 100644 index 00000000..84b422d5 --- /dev/null +++ b/client/storage/treestorage_test.go @@ -0,0 +1,123 @@ +package storage + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto" + "github.com/dgraph-io/badger/v3" + "github.com/stretchr/testify/require" + "os" + "testing" +) + +func treeTestPayload() storage.TreeStorageCreatePayload { + rootRawChange := &treechangeproto.RawTreeChangeWithId{RawChange: []byte("some"), Id: "someRootId"} + otherChange := &treechangeproto.RawTreeChangeWithId{RawChange: []byte("some other"), Id: "otherId"} + changes := []*treechangeproto.RawTreeChangeWithId{rootRawChange, otherChange} + return storage.TreeStorageCreatePayload{ + RootRawChange: rootRawChange, + Changes: changes, + Heads: []string{rootRawChange.Id}, + } +} + +type fixture struct { + dir string + db *badger.DB +} + +func testTreePayload(t *testing.T, store storage.TreeStorage, payload storage.TreeStorageCreatePayload) { + require.Equal(t, payload.RootRawChange.Id, store.Id()) + + root, err := store.Root() + require.NoError(t, err) + require.Equal(t, root, payload.RootRawChange) + + heads, err := store.Heads() + require.NoError(t, err) + require.Equal(t, payload.Heads, heads) + + for _, ch := range payload.Changes { + dbCh, err := store.GetRawChange(context.Background(), ch.Id) + require.NoError(t, err) + require.Equal(t, ch, dbCh) + } + return +} + +func newFixture(t *testing.T) *fixture { + dir, err := os.MkdirTemp("", "") + require.NoError(t, err) + return &fixture{dir: dir} +} + +func (fx *fixture) open(t *testing.T) { + var err error + fx.db, err = badger.Open(badger.DefaultOptions(fx.dir)) + require.NoError(t, err) +} + +func (fx *fixture) stop(t *testing.T) { + require.NoError(t, fx.db.Close()) +} + +func TestTreeStorage_Create(t *testing.T) { + fx := newFixture(t) + fx.open(t) + defer fx.stop(t) + + spaceId := "spaceId" + payload := treeTestPayload() + store, err := createTreeStorage(fx.db, spaceId, payload) + require.NoError(t, err) + testTreePayload(t, store, payload) + + t.Run("create same storage returns error", func(t *testing.T) { + _, err := createTreeStorage(fx.db, spaceId, payload) + require.Error(t, err) + }) +} + +func TestTreeStorage_Methods(t *testing.T) { + fx := newFixture(t) + fx.open(t) + payload := treeTestPayload() + spaceId := "spaceId" + _, err := createTreeStorage(fx.db, spaceId, payload) + require.NoError(t, err) + fx.stop(t) + + fx.open(t) + defer fx.stop(t) + store, err := newTreeStorage(fx.db, spaceId, payload.RootRawChange.Id) + require.NoError(t, err) + testTreePayload(t, store, payload) + + t.Run("update heads", func(t *testing.T) { + newHeads := []string{"a", "b"} + require.NoError(t, store.SetHeads(newHeads)) + heads, err := store.Heads() + require.NoError(t, err) + require.Equal(t, newHeads, heads) + }) + + t.Run("add raw change, get change and has change", func(t *testing.T) { + newChange := &treechangeproto.RawTreeChangeWithId{RawChange: []byte("ab"), Id: "newId"} + require.NoError(t, store.AddRawChange(newChange)) + rawCh, err := store.GetRawChange(context.Background(), newChange.Id) + require.NoError(t, err) + require.Equal(t, newChange, rawCh) + has, err := store.HasChange(context.Background(), newChange.Id) + require.NoError(t, err) + require.True(t, has) + }) + + t.Run("get and has for unknown change", func(t *testing.T) { + incorrectId := "incorrectId" + _, err := store.GetRawChange(context.Background(), incorrectId) + require.Error(t, err) + has, err := store.HasChange(context.Background(), incorrectId) + require.NoError(t, err) + require.False(t, has) + }) +} diff --git a/cmd/nodesgen/gen.go b/cmd/nodesgen/gen.go deleted file mode 100644 index 069c3c59..00000000 --- a/cmd/nodesgen/gen.go +++ /dev/null @@ -1,136 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "github.com/anytypeio/go-anytype-infrastructure-experiments/config" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/peer" - "gopkg.in/yaml.v3" - "io/ioutil" - "os" -) - -var ( - flagNodeMap = flag.String("n", "cmd/nodesgen/nodemap.yml", "path to nodes map file") - flagEtcPath = flag.String("e", "etc", "path to etc directory") -) - -type NodesMap struct { - Nodes []struct { - Addresses []string `yaml:"grpcAddresses"` - APIPort string `yaml:"apiPort"` - } `yaml:"nodes"` -} - -func main() { - nodesMap := &NodesMap{} - data, err := ioutil.ReadFile(*flagNodeMap) - if err != nil { - panic(err) - } - - err = yaml.Unmarshal(data, nodesMap) - if err != nil { - panic(err) - } - flag.Parse() - - var configs []config.Config - var nodes []config.Node - for _, n := range nodesMap.Nodes { - cfg, err := genConfig(n.Addresses, n.APIPort) - if err != nil { - panic(fmt.Sprintf("could not generate the config file: %s", err.Error())) - } - configs = append(configs, cfg) - - node := config.Node{ - PeerId: cfg.Account.PeerId, - Address: cfg.GrpcServer.ListenAddrs[0], - SigningKey: cfg.Account.SigningKey, - EncryptionKey: cfg.Account.EncryptionKey, - } - nodes = append(nodes, node) - } - for idx := range configs { - configs[idx].Nodes = nodes - } - - // saving configs - configsPath := fmt.Sprintf("%s/configs", *flagEtcPath) - createDir := func() { - err := os.Mkdir(configsPath, os.ModePerm) - if err != nil { - panic(fmt.Sprintf("failed to create the configs directory: %v", err)) - } - } - if _, err := os.Stat(configsPath); os.IsNotExist(err) { - createDir() - } else { - err = os.RemoveAll(configsPath) - if err != nil { - panic(fmt.Sprintf("failed to remove the configs directory: %v", err)) - } - createDir() - } - for _, cfg := range configs { - path := fmt.Sprintf("%s/%s.yml", configsPath, cfg.Account.PeerId) - bytes, err := yaml.Marshal(cfg) - if err != nil { - panic(fmt.Sprintf("could not marshal the keys: %v", err)) - } - - err = os.WriteFile(path, bytes, os.ModePerm) - if err != nil { - panic(fmt.Sprintf("could not write the config to file: %v", err)) - } - } -} - -func genConfig(addresses []string, apiPort string) (config.Config, error) { - encKey, _, err := encryptionkey.GenerateRandomRSAKeyPair(2048) - if err != nil { - return config.Config{}, err - } - - signKey, _, err := signingkey.GenerateRandomEd25519KeyPair() - if err != nil { - return config.Config{}, err - } - - encKeyDecoder := encryptionkey.NewRSAPrivKeyDecoder() - signKeyDecoder := signingkey.NewEDPrivKeyDecoder() - - encEncKey, err := encKeyDecoder.EncodeToString(encKey) - if err != nil { - return config.Config{}, err - } - - encSignKey, err := signKeyDecoder.EncodeToString(signKey) - if err != nil { - return config.Config{}, err - } - - peerID, err := peer.IDFromSigningPubKey(signKey.GetPublic()) - if err != nil { - return config.Config{}, err - } - - return config.Config{ - Anytype: config.Anytype{SwarmKey: "/key/swarm/psk/1.0.0/base16/209992e611c27d5dce8fbd2e7389f6b51da9bee980992ef60739460b536139ec"}, - GrpcServer: config.GrpcServer{ - ListenAddrs: addresses, - TLS: false, - }, - Account: config.Account{ - PeerId: peerID.String(), - SigningKey: encSignKey, - EncryptionKey: encEncKey, - }, - APIServer: config.APIServer{ - Port: apiPort, - }, - }, nil -} diff --git a/cmd/nodesgen/nodemap.yml b/cmd/nodesgen/nodemap.yml deleted file mode 100644 index 6a5ae28b..00000000 --- a/cmd/nodesgen/nodemap.yml +++ /dev/null @@ -1,13 +0,0 @@ -nodes: - - grpcAddresses: - - "127.0.0.1:4430" - apiPort: "8080" - - grpcAddresses: - - "127.0.0.1:4431" - apiPort: "8081" - - grpcAddresses: - - "127.0.0.1:4432" - apiPort: "8082" - - grpcAddresses: - - "127.0.0.1:4433" - apiPort: "8083" diff --git a/common/Makefile b/common/Makefile new file mode 100644 index 00000000..6773d454 --- /dev/null +++ b/common/Makefile @@ -0,0 +1,22 @@ +.PHONY: proto test +export GOPRIVATE=github.com/anytypeio + +proto: + @echo 'Generating protobuf packages (Go)...' +# Uncomment if needed + @$(eval GOGO_START := GOGO_NO_UNDERSCORE=1 GOGO_EXPORT_ONEOF_INTERFACE=1) + @$(eval P_ACL_RECORDS_PATH_PB := pkg/acl/aclrecordproto) + @$(eval P_TREE_CHANGES_PATH_PB := pkg/acl/treechangeproto) + @$(eval P_SYNC_CHANGES_PATH_PB := syncproto) + @$(eval P_TEST_CHANGES_PATH_PB := pkg/acl/testutils/testchanges) + @$(eval P_ACL_RECORDS := M$(P_ACL_RECORDS_PATH_PB)/protos/aclrecord.proto=github.com/anytypeio/go-anytype-infrastructure-experiments/common/$(P_ACL_RECORDS_PATH_PB)) + @$(eval P_TREE_CHANGES := M$(P_TREE_CHANGES_PATH_PB)/protos/treechange.proto=github.com/anytypeio/go-anytype-infrastructure-experiments/common/$(P_TREE_CHANGES_PATH_PB)) + + $(GOGO_START) protoc --gogofaster_out=:. $(P_ACL_RECORDS_PATH_PB)/protos/*.proto + $(GOGO_START) protoc --gogofaster_out=:. $(P_TREE_CHANGES_PATH_PB)/protos/*.proto + $(GOGO_START) protoc --gogofaster_out=:. $(P_TEST_CHANGES_PATH_PB)/proto/*.proto + $(eval PKGMAP := $$(P_TREE_CHANGES),$$(P_ACL_RECORDS)) + $(GOGO_START) protoc --gogofaster_out=$(PKGMAP):. --go-drpc_out=protolib=github.com/gogo/protobuf:. commonspace/spacesyncproto/protos/*.proto + +test: + go test ./... --cover \ No newline at end of file diff --git a/common/account/service.go b/common/account/service.go new file mode 100644 index 00000000..ab009a51 --- /dev/null +++ b/common/account/service.go @@ -0,0 +1,18 @@ +package account + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/config" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/account" +) + +const CName = "common.account" + +type Service interface { + app.Component + Account() *account.AccountData +} + +type ConfigGetter interface { + GetAccount() config.Account +} diff --git a/app/app.go b/common/app/app.go similarity index 97% rename from app/app.go rename to common/app/app.go index ef0d46bd..9e2e3fa0 100644 --- a/app/app.go +++ b/common/app/app.go @@ -4,7 +4,7 @@ import ( "context" "errors" "fmt" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" "go.uber.org/zap" "os" "runtime" @@ -27,7 +27,7 @@ var ( type Component interface { // Init will be called first // When returned error is not nil - app start will be aborted - Init(ctx context.Context, a *App) (err error) + Init(a *App) (err error) // Name must return unique service name Name() (name string) } @@ -157,7 +157,7 @@ func (app *App) Start(ctx context.Context) (err error) { } for i, s := range app.components { - if err = s.Init(ctx, app); err != nil { + if err = s.Init(app); err != nil { closeServices(i) return fmt.Errorf("can't init service '%s': %v", s.Name(), err) } diff --git a/app/app_test.go b/common/app/app_test.go similarity index 98% rename from app/app_test.go rename to common/app/app_test.go index b4a93007..cdc52445 100644 --- a/app/app_test.go +++ b/common/app/app_test.go @@ -131,7 +131,7 @@ type testComponent struct { ids testIds } -func (t *testComponent) Init(ctx context.Context, a *App) error { +func (t *testComponent) Init(a *App) error { t.ids.initId = t.seq.New() return t.err } diff --git a/common/app/logger/log.go b/common/app/logger/log.go new file mode 100644 index 00000000..a9f30252 --- /dev/null +++ b/common/app/logger/log.go @@ -0,0 +1,50 @@ +package logger + +import ( + "go.uber.org/zap" + "sync" +) + +var ( + mu sync.Mutex + defaultLogger *zap.Logger + levels = make(map[string]zap.AtomicLevel) + loggers = make(map[string]*zap.Logger) +) + +func init() { + defaultLogger, _ = zap.NewDevelopment() + zap.NewProduction() +} + +func SetDefault(l *zap.Logger) { + mu.Lock() + defer mu.Unlock() + *defaultLogger = *l + for name, l := range loggers { + *l = *defaultLogger.Named(name) + } +} + +func SetNamedLevels(l map[string]zap.AtomicLevel) { + mu.Lock() + defer mu.Unlock() + levels = l +} + +func Default() *zap.Logger { + mu.Lock() + defer mu.Unlock() + return defaultLogger +} + +func NewNamed(name string, fields ...zap.Field) *zap.Logger { + mu.Lock() + defer mu.Unlock() + l := defaultLogger.Named(name) + if len(fields) > 0 { + l = l.With(fields...) + } + loggers[name] = l + return l +} diff --git a/common/commonspace/commongetter.go b/common/commonspace/commongetter.go new file mode 100644 index 00000000..da40bfff --- /dev/null +++ b/common/commonspace/commongetter.go @@ -0,0 +1,35 @@ +package commonspace + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/objectgetter" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncacl" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter" +) + +type commonSpaceGetter struct { + spaceId string + aclList *syncacl.SyncACL + treeGetter treegetter.TreeGetter +} + +func newCommonSpaceGetter(spaceId string, aclList *syncacl.SyncACL, treeGetter treegetter.TreeGetter) objectgetter.ObjectGetter { + return &commonSpaceGetter{ + spaceId: spaceId, + aclList: aclList, + treeGetter: treeGetter, + } +} + +func (c *commonSpaceGetter) GetObject(ctx context.Context, objectId string) (obj objectgetter.Object, err error) { + if c.aclList.ID() == objectId { + obj = c.aclList + return + } + t, err := c.treeGetter.GetTree(ctx, c.spaceId, objectId) + if err != nil { + return + } + obj = t.(objectgetter.Object) + return +} diff --git a/common/commonspace/diffservice/diffservice.go b/common/commonspace/diffservice/diffservice.go new file mode 100644 index 00000000..71fe9bef --- /dev/null +++ b/common/commonspace/diffservice/diffservice.go @@ -0,0 +1,123 @@ +//go:generate mockgen -destination mock_diffservice/mock_diffservice.go github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/diffservice DiffSyncer,PeriodicSync +package diffservice + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/remotediff" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ldiff" + "go.uber.org/zap" + "strings" +) + +type DiffService interface { + HeadNotifiable + HandleRangeRequest(ctx context.Context, req *spacesyncproto.HeadSyncRequest) (resp *spacesyncproto.HeadSyncResponse, err error) + RemoveObject(id string) + AllIds() []string + + Init(objectIds []string) + Close() (err error) +} + +type diffService struct { + spaceId string + periodicSync PeriodicSync + storage storage.SpaceStorage + diff ldiff.Diff + log *zap.Logger + + syncPeriod int +} + +func NewDiffService( + spaceId string, + syncPeriod int, + storage storage.SpaceStorage, + confConnector nodeconf.ConfConnector, + cache treegetter.TreeGetter, + log *zap.Logger) DiffService { + + diff := ldiff.New(16, 16) + l := log.With(zap.String("spaceId", spaceId)) + factory := spacesyncproto.ClientFactoryFunc(spacesyncproto.NewDRPCSpaceClient) + syncer := newDiffSyncer(spaceId, diff, confConnector, cache, storage, factory, l) + periodicSync := newPeriodicSync(syncPeriod, syncer, l) + + return &diffService{ + spaceId: spaceId, + storage: storage, + periodicSync: periodicSync, + diff: diff, + log: log, + syncPeriod: syncPeriod, + } +} + +func (d *diffService) Init(objectIds []string) { + d.fillDiff(objectIds) + d.periodicSync.Run() +} + +func (d *diffService) HandleRangeRequest(ctx context.Context, req *spacesyncproto.HeadSyncRequest) (resp *spacesyncproto.HeadSyncResponse, err error) { + return remotediff.HandleRangeRequest(ctx, d.diff, req) +} + +func (d *diffService) UpdateHeads(id string, heads []string) { + d.diff.Set(ldiff.Element{ + Id: id, + Head: concatStrings(heads), + }) +} + +func (d *diffService) AllIds() []string { + return d.diff.Ids() +} + +func (d *diffService) RemoveObject(id string) { + // TODO: add space document to remove ids + d.diff.RemoveId(id) +} + +func (d *diffService) Close() (err error) { + d.periodicSync.Close() + return nil +} + +func (d *diffService) fillDiff(objectIds []string) { + var els = make([]ldiff.Element, 0, len(objectIds)) + for _, id := range objectIds { + st, err := d.storage.TreeStorage(id) + if err != nil { + continue + } + heads, err := st.Heads() + if err != nil { + continue + } + els = append(els, ldiff.Element{ + Id: id, + Head: concatStrings(heads), + }) + } + d.diff.Set(els...) +} + +func concatStrings(strs []string) string { + var ( + b strings.Builder + totalLen int + ) + for _, s := range strs { + totalLen += len(s) + } + + b.Grow(totalLen) + for _, s := range strs { + b.WriteString(s) + } + return b.String() +} diff --git a/common/commonspace/diffservice/diffservice_test.go b/common/commonspace/diffservice/diffservice_test.go new file mode 100644 index 00000000..9df40e46 --- /dev/null +++ b/common/commonspace/diffservice/diffservice_test.go @@ -0,0 +1,59 @@ +package diffservice + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/diffservice/mock_diffservice" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage/mock_storage" + mock_storage2 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage/mock_storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ldiff" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ldiff/mock_ldiff" + "github.com/golang/mock/gomock" + "testing" +) + +func TestDiffService(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + spaceId := "spaceId" + l := logger.NewNamed("sync") + pSyncMock := mock_diffservice.NewMockPeriodicSync(ctrl) + storageMock := mock_storage.NewMockSpaceStorage(ctrl) + treeStorageMock := mock_storage2.NewMockTreeStorage(ctrl) + diffMock := mock_ldiff.NewMockDiff(ctrl) + syncPeriod := 1 + initId := "initId" + + service := &diffService{ + spaceId: spaceId, + storage: storageMock, + periodicSync: pSyncMock, + diff: diffMock, + log: l, + syncPeriod: syncPeriod, + } + + t.Run("init", func(t *testing.T) { + storageMock.EXPECT().TreeStorage(initId).Return(treeStorageMock, nil) + treeStorageMock.EXPECT().Heads().Return([]string{"h1", "h2"}, nil) + diffMock.EXPECT().Set(ldiff.Element{ + Id: initId, + Head: "h1h2", + }) + pSyncMock.EXPECT().Run() + service.Init([]string{initId}) + }) + + t.Run("update heads", func(t *testing.T) { + diffMock.EXPECT().Set(ldiff.Element{ + Id: initId, + Head: "h1h2", + }) + service.UpdateHeads(initId, []string{"h1", "h2"}) + }) + + t.Run("close", func(t *testing.T) { + pSyncMock.EXPECT().Close() + service.Close() + }) +} diff --git a/common/commonspace/diffservice/diffsyncer.go b/common/commonspace/diffservice/diffsyncer.go new file mode 100644 index 00000000..f9ca9f26 --- /dev/null +++ b/common/commonspace/diffservice/diffsyncer.go @@ -0,0 +1,117 @@ +package diffservice + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/remotediff" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/peer" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/rpc/rpcerr" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ldiff" + "go.uber.org/zap" + "time" +) + +type DiffSyncer interface { + Sync(ctx context.Context) error +} + +func newDiffSyncer( + spaceId string, + diff ldiff.Diff, + confConnector nodeconf.ConfConnector, + cache treegetter.TreeGetter, + storage storage.SpaceStorage, + clientFactory spacesyncproto.ClientFactory, + log *zap.Logger) DiffSyncer { + return &diffSyncer{ + diff: diff, + spaceId: spaceId, + cache: cache, + storage: storage, + confConnector: confConnector, + clientFactory: clientFactory, + log: log, + } +} + +type diffSyncer struct { + spaceId string + diff ldiff.Diff + confConnector nodeconf.ConfConnector + cache treegetter.TreeGetter + storage storage.SpaceStorage + clientFactory spacesyncproto.ClientFactory + log *zap.Logger +} + +func (d *diffSyncer) Sync(ctx context.Context) error { + st := time.Now() + // diffing with responsible peers according to configuration + peers, err := d.confConnector.GetResponsiblePeers(ctx, d.spaceId) + if err != nil { + return err + } + for _, p := range peers { + if err := d.syncWithPeer(ctx, p); err != nil { + d.log.Error("can't sync with peer", zap.String("peer", p.Id()), zap.Error(err)) + } + } + d.log.Info("synced", zap.String("spaceId", d.spaceId), zap.Duration("dur", time.Since(st))) + return nil +} + +func (d *diffSyncer) syncWithPeer(ctx context.Context, p peer.Peer) (err error) { + cl := d.clientFactory.Client(p) + rdiff := remotediff.NewRemoteDiff(d.spaceId, cl) + newIds, changedIds, removedIds, err := d.diff.Diff(ctx, rdiff) + err = rpcerr.Unwrap(err) + if err != nil && err != spacesyncproto.ErrSpaceMissing { + return err + } + if err == spacesyncproto.ErrSpaceMissing { + return d.sendPushSpaceRequest(ctx, cl) + } + + ctx = peer.CtxWithPeerId(ctx, p.Id()) + d.pingTreesInCache(ctx, newIds) + d.pingTreesInCache(ctx, changedIds) + d.pingTreesInCache(ctx, removedIds) + + d.log.Info("sync done:", zap.Int("newIds", len(newIds)), + zap.Int("changedIds", len(changedIds)), + zap.Int("removedIds", len(removedIds))) + return +} + +func (d *diffSyncer) pingTreesInCache(ctx context.Context, trees []string) { + for _, tId := range trees { + _, _ = d.cache.GetTree(ctx, d.spaceId, tId) + } +} + +func (d *diffSyncer) sendPushSpaceRequest(ctx context.Context, cl spacesyncproto.DRPCSpaceClient) (err error) { + aclStorage, err := d.storage.ACLStorage() + if err != nil { + return + } + + root, err := aclStorage.Root() + if err != nil { + return + } + + header, err := d.storage.SpaceHeader() + if err != nil { + return + } + + _, err = cl.PushSpace(ctx, &spacesyncproto.PushSpaceRequest{ + SpaceHeader: header, + AclPayload: root.Payload, + AclPayloadId: root.Id, + }) + return +} diff --git a/common/commonspace/diffservice/diffsyncer_test.go b/common/commonspace/diffservice/diffsyncer_test.go new file mode 100644 index 00000000..13001df8 --- /dev/null +++ b/common/commonspace/diffservice/diffsyncer_test.go @@ -0,0 +1,169 @@ +package diffservice + +import ( + "context" + "fmt" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/remotediff" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto/mock_spacesyncproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage/mock_storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter/mock_treegetter" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/peer" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf/mock_nodeconf" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" + mock_aclstorage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage/mock_storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ldiff/mock_ldiff" + "github.com/golang/mock/gomock" + "github.com/libp2p/go-libp2p/core/sec" + "github.com/stretchr/testify/require" + "storj.io/drpc" + "testing" + "time" +) + +type pushSpaceRequestMatcher struct { + spaceId string + aclRootId string + spaceHeader *spacesyncproto.RawSpaceHeaderWithId +} + +func (p pushSpaceRequestMatcher) Matches(x interface{}) bool { + res, ok := x.(*spacesyncproto.PushSpaceRequest) + if !ok { + return false + } + + return res.AclPayloadId == p.aclRootId && res.SpaceHeader == p.spaceHeader +} + +func (p pushSpaceRequestMatcher) String() string { + return "" +} + +type mockPeer struct{} + +func (m mockPeer) Id() string { + return "mockId" +} + +func (m mockPeer) LastUsage() time.Time { + return time.Time{} +} + +func (m mockPeer) Secure() sec.SecureConn { + return nil +} + +func (m mockPeer) UpdateLastUsage() { +} + +func (m mockPeer) Close() error { + return nil +} + +func (m mockPeer) Closed() <-chan struct{} { + return make(chan struct{}) +} + +func (m mockPeer) Invoke(ctx context.Context, rpc string, enc drpc.Encoding, in, out drpc.Message) error { + return nil +} + +func (m mockPeer) NewStream(ctx context.Context, rpc string, enc drpc.Encoding) (drpc.Stream, error) { + return nil, nil +} + +func newPushSpaceRequestMatcher( + spaceId string, + aclRootId string, + spaceHeader *spacesyncproto.RawSpaceHeaderWithId) *pushSpaceRequestMatcher { + return &pushSpaceRequestMatcher{ + spaceId: spaceId, + aclRootId: aclRootId, + spaceHeader: spaceHeader, + } +} + +func TestDiffSyncer_Sync(t *testing.T) { + // setup + ctx := context.Background() + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + diffMock := mock_ldiff.NewMockDiff(ctrl) + connectorMock := mock_nodeconf.NewMockConfConnector(ctrl) + cacheMock := mock_treegetter.NewMockTreeGetter(ctrl) + stMock := mock_storage.NewMockSpaceStorage(ctrl) + clientMock := mock_spacesyncproto.NewMockDRPCSpaceClient(ctrl) + factory := spacesyncproto.ClientFactoryFunc(func(cc drpc.Conn) spacesyncproto.DRPCSpaceClient { + return clientMock + }) + spaceId := "spaceId" + aclRootId := "aclRootId" + l := logger.NewNamed(spaceId) + diffSyncer := newDiffSyncer(spaceId, diffMock, connectorMock, cacheMock, stMock, factory, l) + + t.Run("diff syncer sync simple", func(t *testing.T) { + connectorMock.EXPECT(). + GetResponsiblePeers(gomock.Any(), spaceId). + Return([]peer.Peer{mockPeer{}}, nil) + diffMock.EXPECT(). + Diff(gomock.Any(), gomock.Eq(remotediff.NewRemoteDiff(spaceId, clientMock))). + Return([]string{"new"}, []string{"changed"}, nil, nil) + for _, arg := range []string{"new", "changed"} { + cacheMock.EXPECT(). + GetTree(gomock.Any(), spaceId, arg). + Return(nil, nil) + } + require.NoError(t, diffSyncer.Sync(ctx)) + }) + + t.Run("diff syncer sync conf error", func(t *testing.T) { + connectorMock.EXPECT(). + GetResponsiblePeers(gomock.Any(), spaceId). + Return(nil, fmt.Errorf("some error")) + + require.Error(t, diffSyncer.Sync(ctx)) + }) + + t.Run("diff syncer sync space missing", func(t *testing.T) { + aclStorageMock := mock_aclstorage.NewMockListStorage(ctrl) + aclRoot := &aclrecordproto.RawACLRecordWithId{ + Id: aclRootId, + } + spaceHeader := &spacesyncproto.RawSpaceHeaderWithId{} + + connectorMock.EXPECT(). + GetResponsiblePeers(gomock.Any(), spaceId). + Return([]peer.Peer{mockPeer{}}, nil) + diffMock.EXPECT(). + Diff(gomock.Any(), gomock.Eq(remotediff.NewRemoteDiff(spaceId, clientMock))). + Return(nil, nil, nil, spacesyncproto.ErrSpaceMissing) + stMock.EXPECT(). + ACLStorage(). + Return(aclStorageMock, nil) + stMock.EXPECT(). + SpaceHeader(). + Return(spaceHeader, nil) + aclStorageMock.EXPECT(). + Root(). + Return(aclRoot, nil) + clientMock.EXPECT(). + PushSpace(gomock.Any(), newPushSpaceRequestMatcher(spaceId, aclRootId, spaceHeader)). + Return(nil, nil) + + require.NoError(t, diffSyncer.Sync(ctx)) + }) + + t.Run("diff syncer sync other error", func(t *testing.T) { + connectorMock.EXPECT(). + GetResponsiblePeers(gomock.Any(), spaceId). + Return([]peer.Peer{mockPeer{}}, nil) + diffMock.EXPECT(). + Diff(gomock.Any(), gomock.Eq(remotediff.NewRemoteDiff(spaceId, clientMock))). + Return(nil, nil, nil, spacesyncproto.ErrUnexpected) + + require.NoError(t, diffSyncer.Sync(ctx)) + }) +} diff --git a/common/commonspace/diffservice/headnotifiable.go b/common/commonspace/diffservice/headnotifiable.go new file mode 100644 index 00000000..80819bfe --- /dev/null +++ b/common/commonspace/diffservice/headnotifiable.go @@ -0,0 +1,5 @@ +package diffservice + +type HeadNotifiable interface { + UpdateHeads(id string, heads []string) +} diff --git a/common/commonspace/diffservice/mock_diffservice/mock_diffservice.go b/common/commonspace/diffservice/mock_diffservice/mock_diffservice.go new file mode 100644 index 00000000..966a7cc5 --- /dev/null +++ b/common/commonspace/diffservice/mock_diffservice/mock_diffservice.go @@ -0,0 +1,96 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/diffservice (interfaces: DiffSyncer,PeriodicSync) + +// Package mock_diffservice is a generated GoMock package. +package mock_diffservice + +import ( + context "context" + reflect "reflect" + + gomock "github.com/golang/mock/gomock" +) + +// MockDiffSyncer is a mock of DiffSyncer interface. +type MockDiffSyncer struct { + ctrl *gomock.Controller + recorder *MockDiffSyncerMockRecorder +} + +// MockDiffSyncerMockRecorder is the mock recorder for MockDiffSyncer. +type MockDiffSyncerMockRecorder struct { + mock *MockDiffSyncer +} + +// NewMockDiffSyncer creates a new mock instance. +func NewMockDiffSyncer(ctrl *gomock.Controller) *MockDiffSyncer { + mock := &MockDiffSyncer{ctrl: ctrl} + mock.recorder = &MockDiffSyncerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockDiffSyncer) EXPECT() *MockDiffSyncerMockRecorder { + return m.recorder +} + +// Sync mocks base method. +func (m *MockDiffSyncer) Sync(arg0 context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Sync", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Sync indicates an expected call of Sync. +func (mr *MockDiffSyncerMockRecorder) Sync(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Sync", reflect.TypeOf((*MockDiffSyncer)(nil).Sync), arg0) +} + +// MockPeriodicSync is a mock of PeriodicSync interface. +type MockPeriodicSync struct { + ctrl *gomock.Controller + recorder *MockPeriodicSyncMockRecorder +} + +// MockPeriodicSyncMockRecorder is the mock recorder for MockPeriodicSync. +type MockPeriodicSyncMockRecorder struct { + mock *MockPeriodicSync +} + +// NewMockPeriodicSync creates a new mock instance. +func NewMockPeriodicSync(ctrl *gomock.Controller) *MockPeriodicSync { + mock := &MockPeriodicSync{ctrl: ctrl} + mock.recorder = &MockPeriodicSyncMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockPeriodicSync) EXPECT() *MockPeriodicSyncMockRecorder { + return m.recorder +} + +// Close mocks base method. +func (m *MockPeriodicSync) Close() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Close") +} + +// Close indicates an expected call of Close. +func (mr *MockPeriodicSyncMockRecorder) Close() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockPeriodicSync)(nil).Close)) +} + +// Run mocks base method. +func (m *MockPeriodicSync) Run() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Run") +} + +// Run indicates an expected call of Run. +func (mr *MockPeriodicSyncMockRecorder) Run() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockPeriodicSync)(nil).Run)) +} diff --git a/common/commonspace/diffservice/periodicsync.go b/common/commonspace/diffservice/periodicsync.go new file mode 100644 index 00000000..a74b25cf --- /dev/null +++ b/common/commonspace/diffservice/periodicsync.go @@ -0,0 +1,67 @@ +package diffservice + +import ( + "context" + "go.uber.org/zap" + "time" +) + +type PeriodicSync interface { + Run() + Close() +} + +func newPeriodicSync(periodSeconds int, syncer DiffSyncer, l *zap.Logger) *periodicSync { + ctx, cancel := context.WithCancel(context.Background()) + return &periodicSync{ + syncer: syncer, + log: l, + syncCtx: ctx, + syncCancel: cancel, + syncLoopDone: make(chan struct{}), + periodSeconds: periodSeconds, + } +} + +type periodicSync struct { + log *zap.Logger + syncer DiffSyncer + syncCtx context.Context + syncCancel context.CancelFunc + syncLoopDone chan struct{} + periodSeconds int +} + +func (p *periodicSync) Run() { + go p.syncLoop(p.periodSeconds) +} + +func (p *periodicSync) syncLoop(periodSeconds int) { + period := time.Duration(periodSeconds) * time.Second + defer close(p.syncLoopDone) + doSync := func() { + ctx, cancel := context.WithTimeout(p.syncCtx, time.Minute) + defer cancel() + if err := p.syncer.Sync(ctx); err != nil { + p.log.Warn("periodic sync error", zap.Error(err)) + } + } + doSync() + if period > 0 { + ticker := time.NewTicker(period) + defer ticker.Stop() + for { + select { + case <-p.syncCtx.Done(): + return + case <-ticker.C: + doSync() + } + } + } +} + +func (p *periodicSync) Close() { + p.syncCancel() + <-p.syncLoopDone +} diff --git a/common/commonspace/diffservice/periodicsync_test.go b/common/commonspace/diffservice/periodicsync_test.go new file mode 100644 index 00000000..068da366 --- /dev/null +++ b/common/commonspace/diffservice/periodicsync_test.go @@ -0,0 +1,38 @@ +package diffservice + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/diffservice/mock_diffservice" + "github.com/golang/mock/gomock" + "testing" + "time" +) + +func TestPeriodicSync_Run(t *testing.T) { + // setup + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + l := logger.NewNamed("sync") + diffSyncer := mock_diffservice.NewMockDiffSyncer(ctrl) + t.Run("diff syncer 1 time", func(t *testing.T) { + secs := 0 + pSync := newPeriodicSync(secs, diffSyncer, l) + + diffSyncer.EXPECT().Sync(gomock.Any()).Times(1).Return(nil) + + pSync.Run() + pSync.Close() + }) + + t.Run("diff syncer 2 times", func(t *testing.T) { + secs := 1 + + pSync := newPeriodicSync(secs, diffSyncer, l) + diffSyncer.EXPECT().Sync(gomock.Any()).Times(2).Return(nil) + + pSync.Run() + time.Sleep(time.Second * time.Duration(secs)) + pSync.Close() + }) +} diff --git a/common/commonspace/objectgetter/objectgetter.go b/common/commonspace/objectgetter/objectgetter.go new file mode 100644 index 00000000..11b9e835 --- /dev/null +++ b/common/commonspace/objectgetter/objectgetter.go @@ -0,0 +1,14 @@ +package objectgetter + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice/synchandler" +) + +type Object interface { + synchandler.SyncHandler +} + +type ObjectGetter interface { + GetObject(ctx context.Context, objectId string) (Object, error) +} diff --git a/common/commonspace/payloads.go b/common/commonspace/payloads.go new file mode 100644 index 00000000..66d257ec --- /dev/null +++ b/common/commonspace/payloads.go @@ -0,0 +1,211 @@ +package commonspace + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage" + aclrecordproto2 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/cid" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/signingkey" + "hash/fnv" + "math/rand" + "time" +) + +func storagePayloadForSpaceCreate(payload SpaceCreatePayload) (storagePayload storage.SpaceStorageCreatePayload, err error) { + // unmarshalling signing and encryption keys + identity, err := payload.SigningKey.GetPublic().Raw() + if err != nil { + return + } + encPubKey, err := payload.EncryptionKey.GetPublic().Raw() + if err != nil { + return + } + + // preparing header and space id + bytes := make([]byte, 32) + _, err = rand.Read(bytes) + if err != nil { + return + } + header := &spacesyncproto.SpaceHeader{ + Identity: identity, + Timestamp: time.Now().UnixNano(), + SpaceType: payload.SpaceType, + ReplicationKey: payload.ReplicationKey, + Seed: bytes, + } + marshalled, err := header.Marshal() + if err != nil { + return + } + signature, err := payload.SigningKey.Sign(marshalled) + if err != nil { + return + } + rawHeader := &spacesyncproto.RawSpaceHeader{SpaceHeader: marshalled, Signature: signature} + marshalled, err = rawHeader.Marshal() + if err != nil { + return + } + id, err := cid.NewCIDFromBytes(marshalled) + spaceId := NewSpaceId(id, payload.ReplicationKey) + rawHeaderWithId := &spacesyncproto.RawSpaceHeaderWithId{ + RawHeader: marshalled, + Id: spaceId, + } + + // encrypting read key + hasher := fnv.New64() + _, err = hasher.Write(payload.ReadKey) + if err != nil { + return + } + readKeyHash := hasher.Sum64() + encReadKey, err := payload.EncryptionKey.GetPublic().Encrypt(payload.ReadKey) + if err != nil { + return + } + + // preparing acl + aclRoot := &aclrecordproto2.ACLRoot{ + Identity: identity, + EncryptionKey: encPubKey, + SpaceId: spaceId, + EncryptedReadKey: encReadKey, + DerivationScheme: "", + CurrentReadKeyHash: readKeyHash, + Timestamp: time.Now().UnixNano(), + } + rawWithId, err := marshalACLRoot(aclRoot, payload.SigningKey) + if err != nil { + return + } + + // creating storage + storagePayload = storage.SpaceStorageCreatePayload{ + RecWithId: rawWithId, + SpaceHeaderWithId: rawHeaderWithId, + } + return +} + +func storagePayloadForSpaceDerive(payload SpaceDerivePayload) (storagePayload storage.SpaceStorageCreatePayload, err error) { + // unmarshalling signing and encryption keys + identity, err := payload.SigningKey.GetPublic().Raw() + if err != nil { + return + } + signPrivKey, err := payload.SigningKey.Raw() + if err != nil { + return + } + encPubKey, err := payload.EncryptionKey.GetPublic().Raw() + if err != nil { + return + } + encPrivKey, err := payload.EncryptionKey.Raw() + if err != nil { + return + } + + // preparing replication key + hasher := fnv.New64() + _, err = hasher.Write(identity) + if err != nil { + return + } + repKey := hasher.Sum64() + + // preparing header and space id + header := &spacesyncproto.SpaceHeader{ + Identity: identity, + SpaceType: SpaceTypeDerived, + ReplicationKey: repKey, + } + marshalled, err := header.Marshal() + if err != nil { + return + } + signature, err := payload.SigningKey.Sign(marshalled) + if err != nil { + return + } + rawHeader := &spacesyncproto.RawSpaceHeader{SpaceHeader: marshalled, Signature: signature} + marshalled, err = rawHeader.Marshal() + if err != nil { + return + } + id, err := cid.NewCIDFromBytes(marshalled) + spaceId := NewSpaceId(id, repKey) + rawHeaderWithId := &spacesyncproto.RawSpaceHeaderWithId{ + RawHeader: marshalled, + Id: spaceId, + } + + // deriving and encrypting read key + readKey, err := aclrecordproto2.ACLReadKeyDerive(signPrivKey, encPrivKey) + if err != nil { + return + } + hasher = fnv.New64() + _, err = hasher.Write(readKey.Bytes()) + if err != nil { + return + } + readKeyHash := hasher.Sum64() + encReadKey, err := payload.EncryptionKey.GetPublic().Encrypt(readKey.Bytes()) + if err != nil { + return + } + + // preparing acl + aclRoot := &aclrecordproto2.ACLRoot{ + Identity: identity, + EncryptionKey: encPubKey, + SpaceId: spaceId, + EncryptedReadKey: encReadKey, + DerivationScheme: "", + CurrentReadKeyHash: readKeyHash, + Timestamp: time.Now().UnixNano(), + } + rawWithId, err := marshalACLRoot(aclRoot, payload.SigningKey) + if err != nil { + return + } + + // creating storage + storagePayload = storage.SpaceStorageCreatePayload{ + RecWithId: rawWithId, + SpaceHeaderWithId: rawHeaderWithId, + } + return +} + +func marshalACLRoot(aclRoot *aclrecordproto2.ACLRoot, key signingkey.PrivKey) (rawWithId *aclrecordproto2.RawACLRecordWithId, err error) { + marshalledRoot, err := aclRoot.Marshal() + if err != nil { + return + } + signature, err := key.Sign(marshalledRoot) + if err != nil { + return + } + raw := &aclrecordproto2.RawACLRecord{ + Payload: marshalledRoot, + Signature: signature, + } + marshalledRaw, err := raw.Marshal() + if err != nil { + return + } + aclHeadId, err := cid.NewCIDFromBytes(marshalledRaw) + if err != nil { + return + } + rawWithId = &aclrecordproto2.RawACLRecordWithId{ + Payload: marshalledRaw, + Id: aclHeadId, + } + return +} diff --git a/common/commonspace/remotediff/remotediff.go b/common/commonspace/remotediff/remotediff.go new file mode 100644 index 00000000..e11606ec --- /dev/null +++ b/common/commonspace/remotediff/remotediff.go @@ -0,0 +1,98 @@ +package remotediff + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ldiff" +) + +type Client interface { + HeadSync(ctx context.Context, in *spacesyncproto.HeadSyncRequest) (*spacesyncproto.HeadSyncResponse, error) +} + +func NewRemoteDiff(spaceId string, client Client) ldiff.Remote { + return remote{ + spaceId: spaceId, + client: client, + } +} + +type remote struct { + spaceId string + client Client +} + +func (r remote) Ranges(ctx context.Context, ranges []ldiff.Range, resBuf []ldiff.RangeResult) (results []ldiff.RangeResult, err error) { + results = resBuf[:0] + pbRanges := make([]*spacesyncproto.HeadSyncRange, 0, len(ranges)) + for _, rg := range ranges { + pbRanges = append(pbRanges, &spacesyncproto.HeadSyncRange{ + From: rg.From, + To: rg.To, + Limit: uint32(rg.Limit), + }) + } + req := &spacesyncproto.HeadSyncRequest{ + SpaceId: r.spaceId, + Ranges: pbRanges, + } + resp, err := r.client.HeadSync(ctx, req) + if err != nil { + return + } + for _, rr := range resp.Results { + var elms []ldiff.Element + if len(rr.Elements) > 0 { + elms = make([]ldiff.Element, 0, len(rr.Elements)) + } + for _, e := range rr.Elements { + elms = append(elms, ldiff.Element{ + Id: e.Id, + Head: e.Head, + }) + } + results = append(results, ldiff.RangeResult{ + Hash: rr.Hash, + Elements: elms, + Count: int(rr.Count), + }) + } + return +} + +func HandleRangeRequest(ctx context.Context, d ldiff.Diff, req *spacesyncproto.HeadSyncRequest) (resp *spacesyncproto.HeadSyncResponse, err error) { + ranges := make([]ldiff.Range, 0, len(req.Ranges)) + for _, reqRange := range req.Ranges { + ranges = append(ranges, ldiff.Range{ + From: reqRange.From, + To: reqRange.To, + Limit: int(reqRange.Limit), + }) + } + res, err := d.Ranges(ctx, ranges, nil) + if err != nil { + return + } + + resp = &spacesyncproto.HeadSyncResponse{ + Results: make([]*spacesyncproto.HeadSyncResult, 0, len(res)), + } + for _, rangeRes := range res { + var elements []*spacesyncproto.HeadSyncResultElement + if len(rangeRes.Elements) > 0 { + elements = make([]*spacesyncproto.HeadSyncResultElement, 0, len(rangeRes.Elements)) + for _, el := range rangeRes.Elements { + elements = append(elements, &spacesyncproto.HeadSyncResultElement{ + Id: el.Id, + Head: el.Head, + }) + } + } + resp.Results = append(resp.Results, &spacesyncproto.HeadSyncResult{ + Hash: rangeRes.Hash, + Elements: elements, + Count: uint32(rangeRes.Count), + }) + } + return +} diff --git a/common/commonspace/remotediff/remotediff_test.go b/common/commonspace/remotediff/remotediff_test.go new file mode 100644 index 00000000..11473aeb --- /dev/null +++ b/common/commonspace/remotediff/remotediff_test.go @@ -0,0 +1,41 @@ +package remotediff + +import ( + "context" + "fmt" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ldiff" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "testing" +) + +func TestRemote(t *testing.T) { + ldLocal := ldiff.New(8, 8) + ldRemote := ldiff.New(8, 8) + for i := 0; i < 100; i++ { + el := ldiff.Element{ + Id: fmt.Sprint(i), + Head: fmt.Sprint(i), + } + ldRemote.Set(el) + if i%10 != 0 { + ldLocal.Set(el) + } + } + + rd := NewRemoteDiff("1", &mockClient{l: ldRemote}) + newIds, changedIds, removedIds, err := ldLocal.Diff(context.Background(), rd) + require.NoError(t, err) + assert.Len(t, newIds, 10) + assert.Len(t, changedIds, 0) + assert.Len(t, removedIds, 0) +} + +type mockClient struct { + l ldiff.Diff +} + +func (m *mockClient) HeadSync(ctx context.Context, in *spacesyncproto.HeadSyncRequest) (*spacesyncproto.HeadSyncResponse, error) { + return HandleRangeRequest(ctx, m.l, in) +} diff --git a/common/commonspace/rpchandler.go b/common/commonspace/rpchandler.go new file mode 100644 index 00000000..dbc5b7aa --- /dev/null +++ b/common/commonspace/rpchandler.go @@ -0,0 +1,23 @@ +package commonspace + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" +) + +type RpcHandler interface { + HeadSync(ctx context.Context, req *spacesyncproto.HeadSyncRequest) (*spacesyncproto.HeadSyncResponse, error) + Stream(stream spacesyncproto.DRPCSpace_StreamStream) error +} + +type rpcHandler struct { + s *space +} + +func (r *rpcHandler) HeadSync(ctx context.Context, req *spacesyncproto.HeadSyncRequest) (*spacesyncproto.HeadSyncResponse, error) { + return r.s.DiffService().HandleRangeRequest(ctx, req) +} + +func (r *rpcHandler) Stream(stream spacesyncproto.DRPCSpace_StreamStream) (err error) { + return r.s.SyncService().StreamPool().AddAndReadStreamSync(stream) +} diff --git a/common/commonspace/service.go b/common/commonspace/service.go new file mode 100644 index 00000000..f9ca00d8 --- /dev/null +++ b/common/commonspace/service.go @@ -0,0 +1,172 @@ +package commonspace + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/account" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/diffservice" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/config" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/peer" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/pool" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" +) + +const CName = "common.commonspace" + +var log = logger.NewNamed(CName) + +func New() Service { + return &service{} +} + +type Service interface { + DeriveSpace(ctx context.Context, payload SpaceDerivePayload) (string, error) + CreateSpace(ctx context.Context, payload SpaceCreatePayload) (string, error) + NewSpace(ctx context.Context, id string) (sp Space, err error) + AddSpace(ctx context.Context, spaceDescription SpaceDescription) (err error) + app.Component +} + +type service struct { + config config.Space + account account.Service + configurationService nodeconf.Service + storageProvider storage.SpaceStorageProvider + treeGetter treegetter.TreeGetter + pool pool.Pool +} + +func (s *service) Init(a *app.App) (err error) { + s.config = a.MustComponent(config.CName).(*config.Config).Space + s.account = a.MustComponent(account.CName).(account.Service) + s.storageProvider = a.MustComponent(storage.CName).(storage.SpaceStorageProvider) + s.configurationService = a.MustComponent(nodeconf.CName).(nodeconf.Service) + s.treeGetter = a.MustComponent(treegetter.CName).(treegetter.TreeGetter) + s.pool = a.MustComponent(pool.CName).(pool.Pool) + return nil +} + +func (s *service) Name() (name string) { + return CName +} + +func (s *service) CreateSpace(ctx context.Context, payload SpaceCreatePayload) (id string, err error) { + storageCreate, err := storagePayloadForSpaceCreate(payload) + if err != nil { + return + } + store, err := s.storageProvider.CreateSpaceStorage(storageCreate) + if err != nil { + return + } + + return store.Id(), nil +} + +func (s *service) DeriveSpace(ctx context.Context, payload SpaceDerivePayload) (id string, err error) { + storageCreate, err := storagePayloadForSpaceDerive(payload) + if err != nil { + return + } + store, err := s.storageProvider.CreateSpaceStorage(storageCreate) + if err != nil { + return + } + + return store.Id(), nil +} + +func (s *service) AddSpace(ctx context.Context, spaceDescription SpaceDescription) (err error) { + _, err = s.storageProvider.SpaceStorage(spaceDescription.SpaceHeader.Id) + if err == nil { + err = spacesyncproto.ErrSpaceExists + return + } + if err != storage.ErrSpaceStorageMissing { + err = spacesyncproto.ErrUnexpected + return + } + + payload := storage.SpaceStorageCreatePayload{ + RecWithId: &aclrecordproto.RawACLRecordWithId{ + Payload: spaceDescription.AclPayload, + Id: spaceDescription.AclId, + }, + SpaceHeaderWithId: spaceDescription.SpaceHeader, + } + st, err := s.storageProvider.CreateSpaceStorage(payload) + if err != nil { + err = spacesyncproto.ErrUnexpected + if err == storage.ErrSpaceStorageExists { + err = spacesyncproto.ErrSpaceExists + } + return + } + err = st.Close() + return +} + +func (s *service) NewSpace(ctx context.Context, id string) (Space, error) { + st, err := s.storageProvider.SpaceStorage(id) + if err != nil { + if err != spacesyncproto.ErrSpaceMissing { + return nil, err + } + + st, err = s.getSpaceStorageFromRemote(ctx, id) + if err != nil { + err = storage.ErrSpaceStorageMissing + return nil, err + } + } + + lastConfiguration := s.configurationService.GetLast() + confConnector := nodeconf.NewConfConnector(lastConfiguration, s.pool) + diffService := diffservice.NewDiffService(id, s.config.SyncPeriod, st, confConnector, s.treeGetter, log) + syncService := syncservice.NewSyncService(id, confConnector) + sp := &space{ + id: id, + syncService: syncService, + diffService: diffService, + cache: s.treeGetter, + account: s.account, + configuration: lastConfiguration, + storage: st, + } + return sp, nil +} + +func (s *service) getSpaceStorageFromRemote(ctx context.Context, id string) (st storage.SpaceStorage, err error) { + var p peer.Peer + lastConfiguration := s.configurationService.GetLast() + // for nodes we always get remote space only if we have id in the context + if lastConfiguration.IsResponsible(id) { + err = spacesyncproto.ErrSpaceMissing + return + } + + p, err = s.pool.DialOneOf(ctx, lastConfiguration.NodeIds(id)) + if err != nil { + return + } + + cl := spacesyncproto.NewDRPCSpaceClient(p) + res, err := cl.PullSpace(ctx, &spacesyncproto.PullSpaceRequest{Id: id}) + if err != nil { + return + } + st, err = s.storageProvider.CreateSpaceStorage(storage.SpaceStorageCreatePayload{ + RecWithId: &aclrecordproto.RawACLRecordWithId{ + Payload: res.AclPayload, + Id: res.AclPayloadId, + }, + SpaceHeaderWithId: res.SpaceHeader, + }) + return +} diff --git a/common/commonspace/space.go b/common/commonspace/space.go new file mode 100644 index 00000000..8b72008d --- /dev/null +++ b/common/commonspace/space.go @@ -0,0 +1,226 @@ +package commonspace + +import ( + "context" + "errors" + "fmt" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/account" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/diffservice" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncacl" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree/updatelistener" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/list" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/encryptionkey" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/signingkey" + "github.com/zeebo/errs" + "go.uber.org/zap" + "sync" + "sync/atomic" + "time" +) + +var ErrSpaceClosed = errors.New("space is closed") + +type SpaceCreatePayload struct { + // SigningKey is the signing key of the owner + SigningKey signingkey.PrivKey + // EncryptionKey is the encryption key of the owner + EncryptionKey encryptionkey.PrivKey + // SpaceType is an arbitrary string + SpaceType string + // ReadKey is a first symmetric encryption key for a space + ReadKey []byte + // ReplicationKey is a key which is to be used to determine the node where the space should be held + ReplicationKey uint64 +} + +const SpaceTypeDerived = "derived.space" + +type SpaceDerivePayload struct { + SigningKey signingkey.PrivKey + EncryptionKey encryptionkey.PrivKey +} + +type SpaceDescription struct { + SpaceHeader *spacesyncproto.RawSpaceHeaderWithId + AclId string + AclPayload []byte +} + +func NewSpaceId(id string, repKey uint64) string { + return fmt.Sprintf("%s.%d", id, repKey) +} + +type Space interface { + Id() string + Init(ctx context.Context) error + + StoredIds() []string + Description() SpaceDescription + + SpaceSyncRpc() RpcHandler + + DeriveTree(ctx context.Context, payload tree.ObjectTreeCreatePayload, listener updatelistener.UpdateListener) (tree.ObjectTree, error) + CreateTree(ctx context.Context, payload tree.ObjectTreeCreatePayload, listener updatelistener.UpdateListener) (tree.ObjectTree, error) + BuildTree(ctx context.Context, id string, listener updatelistener.UpdateListener) (tree.ObjectTree, error) + + Close() error +} + +type space struct { + id string + mu sync.RWMutex + header *spacesyncproto.RawSpaceHeaderWithId + + rpc *rpcHandler + + syncService syncservice.SyncService + diffService diffservice.DiffService + storage storage.SpaceStorage + cache treegetter.TreeGetter + account account.Service + aclList *syncacl.SyncACL + configuration nodeconf.Configuration + + isClosed atomic.Bool +} + +func (s *space) LastUsage() time.Time { + return s.syncService.LastUsage() +} + +func (s *space) Id() string { + return s.id +} + +func (s *space) Description() SpaceDescription { + root := s.aclList.Root() + return SpaceDescription{ + SpaceHeader: s.header, + AclId: root.Id, + AclPayload: root.Payload, + } +} + +func (s *space) Init(ctx context.Context) (err error) { + header, err := s.storage.SpaceHeader() + if err != nil { + return + } + s.header = header + s.rpc = &rpcHandler{s: s} + initialIds, err := s.storage.StoredIds() + if err != nil { + return + } + aclStorage, err := s.storage.ACLStorage() + if err != nil { + return + } + aclList, err := list.BuildACLListWithIdentity(s.account.Account(), aclStorage) + if err != nil { + return + } + s.aclList = syncacl.NewSyncACL(aclList, s.syncService.StreamPool()) + objectGetter := newCommonSpaceGetter(s.id, s.aclList, s.cache) + s.syncService.Init(objectGetter) + s.diffService.Init(initialIds) + return nil +} + +func (s *space) SpaceSyncRpc() RpcHandler { + return s.rpc +} + +func (s *space) SyncService() syncservice.SyncService { + return s.syncService +} + +func (s *space) DiffService() diffservice.DiffService { + return s.diffService +} + +func (s *space) StoredIds() []string { + return s.diffService.AllIds() +} + +func (s *space) DeriveTree(ctx context.Context, payload tree.ObjectTreeCreatePayload, listener updatelistener.UpdateListener) (tr tree.ObjectTree, err error) { + if s.isClosed.Load() { + err = ErrSpaceClosed + return + } + deps := synctree.CreateDeps{ + SpaceId: s.id, + Payload: payload, + StreamPool: s.syncService.StreamPool(), + Configuration: s.configuration, + HeadNotifiable: s.diffService, + Listener: listener, + AclList: s.aclList, + CreateStorage: s.storage.CreateTreeStorage, + } + return synctree.DeriveSyncTree(ctx, deps) +} + +func (s *space) CreateTree(ctx context.Context, payload tree.ObjectTreeCreatePayload, listener updatelistener.UpdateListener) (tr tree.ObjectTree, err error) { + if s.isClosed.Load() { + err = ErrSpaceClosed + return + } + deps := synctree.CreateDeps{ + SpaceId: s.id, + Payload: payload, + StreamPool: s.syncService.StreamPool(), + Configuration: s.configuration, + HeadNotifiable: s.diffService, + Listener: listener, + AclList: s.aclList, + CreateStorage: s.storage.CreateTreeStorage, + } + return synctree.CreateSyncTree(ctx, deps) +} + +func (s *space) BuildTree(ctx context.Context, id string, listener updatelistener.UpdateListener) (t tree.ObjectTree, err error) { + if s.isClosed.Load() { + err = ErrSpaceClosed + return + } + deps := synctree.BuildDeps{ + SpaceId: s.id, + StreamPool: s.syncService.StreamPool(), + Configuration: s.configuration, + HeadNotifiable: s.diffService, + Listener: listener, + AclList: s.aclList, + SpaceStorage: s.storage, + } + return synctree.BuildSyncTreeOrGetRemote(ctx, id, deps) +} + +func (s *space) Close() error { + log.With(zap.String("id", s.id)).Debug("space is closing") + defer func() { + s.isClosed.Store(true) + log.With(zap.String("id", s.id)).Debug("space closed") + }() + var mError errs.Group + if err := s.diffService.Close(); err != nil { + mError.Add(err) + } + if err := s.syncService.Close(); err != nil { + mError.Add(err) + } + if err := s.aclList.Close(); err != nil { + mError.Add(err) + } + if err := s.storage.Close(); err != nil { + mError.Add(err) + } + return mError.Err() +} diff --git a/common/commonspace/spacesyncproto/errors.go b/common/commonspace/spacesyncproto/errors.go new file mode 100644 index 00000000..44034ccb --- /dev/null +++ b/common/commonspace/spacesyncproto/errors.go @@ -0,0 +1,14 @@ +package spacesyncproto + +import ( + "errors" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/rpc/rpcerr" +) + +var ( + errGroup = rpcerr.ErrGroup(ErrCodes_ErrorOffset) + + ErrUnexpected = errGroup.Register(errors.New("unexpected error"), uint64(ErrCodes_Unexpected)) + ErrSpaceMissing = errGroup.Register(errors.New("space is missing"), uint64(ErrCodes_SpaceMissing)) + ErrSpaceExists = errGroup.Register(errors.New("space exists"), uint64(ErrCodes_SpaceExists)) +) diff --git a/common/commonspace/spacesyncproto/mock_spacesyncproto/mock_spacesyncproto.go b/common/commonspace/spacesyncproto/mock_spacesyncproto/mock_spacesyncproto.go new file mode 100644 index 00000000..0df3a6ff --- /dev/null +++ b/common/commonspace/spacesyncproto/mock_spacesyncproto/mock_spacesyncproto.go @@ -0,0 +1,111 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto (interfaces: DRPCSpaceClient) + +// Package mock_spacesyncproto is a generated GoMock package. +package mock_spacesyncproto + +import ( + context "context" + reflect "reflect" + + spacesyncproto "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" + gomock "github.com/golang/mock/gomock" + drpc "storj.io/drpc" +) + +// MockDRPCSpaceClient is a mock of DRPCSpaceClient interface. +type MockDRPCSpaceClient struct { + ctrl *gomock.Controller + recorder *MockDRPCSpaceClientMockRecorder +} + +// MockDRPCSpaceClientMockRecorder is the mock recorder for MockDRPCSpaceClient. +type MockDRPCSpaceClientMockRecorder struct { + mock *MockDRPCSpaceClient +} + +// NewMockDRPCSpaceClient creates a new mock instance. +func NewMockDRPCSpaceClient(ctrl *gomock.Controller) *MockDRPCSpaceClient { + mock := &MockDRPCSpaceClient{ctrl: ctrl} + mock.recorder = &MockDRPCSpaceClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockDRPCSpaceClient) EXPECT() *MockDRPCSpaceClientMockRecorder { + return m.recorder +} + +// DRPCConn mocks base method. +func (m *MockDRPCSpaceClient) DRPCConn() drpc.Conn { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DRPCConn") + ret0, _ := ret[0].(drpc.Conn) + return ret0 +} + +// DRPCConn indicates an expected call of DRPCConn. +func (mr *MockDRPCSpaceClientMockRecorder) DRPCConn() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DRPCConn", reflect.TypeOf((*MockDRPCSpaceClient)(nil).DRPCConn)) +} + +// HeadSync mocks base method. +func (m *MockDRPCSpaceClient) HeadSync(arg0 context.Context, arg1 *spacesyncproto.HeadSyncRequest) (*spacesyncproto.HeadSyncResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HeadSync", arg0, arg1) + ret0, _ := ret[0].(*spacesyncproto.HeadSyncResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// HeadSync indicates an expected call of HeadSync. +func (mr *MockDRPCSpaceClientMockRecorder) HeadSync(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HeadSync", reflect.TypeOf((*MockDRPCSpaceClient)(nil).HeadSync), arg0, arg1) +} + +// PullSpace mocks base method. +func (m *MockDRPCSpaceClient) PullSpace(arg0 context.Context, arg1 *spacesyncproto.PullSpaceRequest) (*spacesyncproto.PullSpaceResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PullSpace", arg0, arg1) + ret0, _ := ret[0].(*spacesyncproto.PullSpaceResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PullSpace indicates an expected call of PullSpace. +func (mr *MockDRPCSpaceClientMockRecorder) PullSpace(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PullSpace", reflect.TypeOf((*MockDRPCSpaceClient)(nil).PullSpace), arg0, arg1) +} + +// PushSpace mocks base method. +func (m *MockDRPCSpaceClient) PushSpace(arg0 context.Context, arg1 *spacesyncproto.PushSpaceRequest) (*spacesyncproto.PushSpaceResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PushSpace", arg0, arg1) + ret0, _ := ret[0].(*spacesyncproto.PushSpaceResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PushSpace indicates an expected call of PushSpace. +func (mr *MockDRPCSpaceClientMockRecorder) PushSpace(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PushSpace", reflect.TypeOf((*MockDRPCSpaceClient)(nil).PushSpace), arg0, arg1) +} + +// Stream mocks base method. +func (m *MockDRPCSpaceClient) Stream(arg0 context.Context) (spacesyncproto.DRPCSpace_StreamClient, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Stream", arg0) + ret0, _ := ret[0].(spacesyncproto.DRPCSpace_StreamClient) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Stream indicates an expected call of Stream. +func (mr *MockDRPCSpaceClientMockRecorder) Stream(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stream", reflect.TypeOf((*MockDRPCSpaceClient)(nil).Stream), arg0) +} diff --git a/common/commonspace/spacesyncproto/protos/spacesync.proto b/common/commonspace/spacesyncproto/protos/spacesync.proto new file mode 100644 index 00000000..441c0992 --- /dev/null +++ b/common/commonspace/spacesyncproto/protos/spacesync.proto @@ -0,0 +1,104 @@ +syntax = "proto3"; +package anySpace; + +option go_package = "commonspace/spacesyncproto"; + +enum ErrCodes { + Unexpected = 0; + SpaceMissing = 1; + SpaceExists = 2; + ErrorOffset = 100; +} + +service Space { + // HeadSync compares all objects and their hashes in a space + rpc HeadSync(HeadSyncRequest) returns (HeadSyncResponse); + // PushSpace sends new space to the node + rpc PushSpace(PushSpaceRequest) returns (PushSpaceResponse); + // PullSpace gets space from the remote peer + rpc PullSpace(PullSpaceRequest) returns (PullSpaceResponse); + // Stream opens object sync stream with node or client + rpc Stream(stream ObjectSyncMessage) returns (stream ObjectSyncMessage); +} + +// HeadSyncRange presenting a request for one range +message HeadSyncRange { + uint64 from = 1; + uint64 to = 2; + uint32 limit = 3; +} + +// HeadSyncResult presenting a response for one range +message HeadSyncResult { + bytes hash = 1; + repeated HeadSyncResultElement elements = 2; + uint32 count = 3; +} + +// HeadSyncResultElement presenting state of one object +message HeadSyncResultElement { + string id = 1; + string head = 2; +} + +// HeadSyncRequest is a request for HeadSync +message HeadSyncRequest { + string spaceId = 1; + repeated HeadSyncRange ranges = 2; +} + +// HeadSyncResponse is a response for HeadSync +message HeadSyncResponse { + repeated HeadSyncResult results = 1; +} + +// ObjectSyncMessage is a message sent on object sync +message ObjectSyncMessage { + string spaceId = 1; + string replyId = 2; + bytes payload = 3; + string objectId = 4; +// string identity = 5; +// string peerSignature = 6; +} + +// PushSpaceRequest is a request to add space on a node containing only one acl record +message PushSpaceRequest { + RawSpaceHeaderWithId spaceHeader = 1; + bytes aclPayload = 2; + string aclPayloadId = 3; +} + +// PushSpaceResponse is an empty response +message PushSpaceResponse {} + +// PullSpaceRequest is a request to request a space on a node that doesn't have it +message PullSpaceRequest { + string id = 1; +} + +// PullSpaceResponse is a response with header and acl root +message PullSpaceResponse { + RawSpaceHeaderWithId spaceHeader = 1; + bytes aclPayload = 2; + string aclPayloadId = 3; +} + +// SpaceHeader is a header for a space +message SpaceHeader { + bytes identity = 1; + int64 timestamp = 2; + string spaceType = 3; + uint64 replicationKey = 4; + bytes seed = 5; +} + +message RawSpaceHeader { + bytes spaceHeader = 1; + bytes signature = 2; +} + +message RawSpaceHeaderWithId { + bytes rawHeader = 1; + string id = 2; +} diff --git a/common/commonspace/spacesyncproto/spacesync.go b/common/commonspace/spacesyncproto/spacesync.go new file mode 100644 index 00000000..7c55930f --- /dev/null +++ b/common/commonspace/spacesyncproto/spacesync.go @@ -0,0 +1,18 @@ +//go:generate mockgen -destination mock_spacesyncproto/mock_spacesyncproto.go github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto DRPCSpaceClient +package spacesyncproto + +import ( + "storj.io/drpc" +) + +type SpaceStream = DRPCSpace_StreamStream + +type ClientFactoryFunc func(cc drpc.Conn) DRPCSpaceClient + +func (c ClientFactoryFunc) Client(cc drpc.Conn) DRPCSpaceClient { + return c(cc) +} + +type ClientFactory interface { + Client(cc drpc.Conn) DRPCSpaceClient +} diff --git a/common/commonspace/spacesyncproto/spacesync.pb.go b/common/commonspace/spacesyncproto/spacesync.pb.go new file mode 100644 index 00000000..9f73b956 --- /dev/null +++ b/common/commonspace/spacesyncproto/spacesync.pb.go @@ -0,0 +1,3326 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: commonspace/spacesyncproto/protos/spacesync.proto + +package spacesyncproto + +import ( + fmt "fmt" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type ErrCodes int32 + +const ( + ErrCodes_Unexpected ErrCodes = 0 + ErrCodes_SpaceMissing ErrCodes = 1 + ErrCodes_SpaceExists ErrCodes = 2 + ErrCodes_ErrorOffset ErrCodes = 100 +) + +var ErrCodes_name = map[int32]string{ + 0: "Unexpected", + 1: "SpaceMissing", + 2: "SpaceExists", + 100: "ErrorOffset", +} + +var ErrCodes_value = map[string]int32{ + "Unexpected": 0, + "SpaceMissing": 1, + "SpaceExists": 2, + "ErrorOffset": 100, +} + +func (x ErrCodes) String() string { + return proto.EnumName(ErrCodes_name, int32(x)) +} + +func (ErrCodes) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_80e49f1f4ac27799, []int{0} +} + +// HeadSyncRange presenting a request for one range +type HeadSyncRange struct { + From uint64 `protobuf:"varint,1,opt,name=from,proto3" json:"from,omitempty"` + To uint64 `protobuf:"varint,2,opt,name=to,proto3" json:"to,omitempty"` + Limit uint32 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"` +} + +func (m *HeadSyncRange) Reset() { *m = HeadSyncRange{} } +func (m *HeadSyncRange) String() string { return proto.CompactTextString(m) } +func (*HeadSyncRange) ProtoMessage() {} +func (*HeadSyncRange) Descriptor() ([]byte, []int) { + return fileDescriptor_80e49f1f4ac27799, []int{0} +} +func (m *HeadSyncRange) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *HeadSyncRange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_HeadSyncRange.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *HeadSyncRange) XXX_Merge(src proto.Message) { + xxx_messageInfo_HeadSyncRange.Merge(m, src) +} +func (m *HeadSyncRange) XXX_Size() int { + return m.Size() +} +func (m *HeadSyncRange) XXX_DiscardUnknown() { + xxx_messageInfo_HeadSyncRange.DiscardUnknown(m) +} + +var xxx_messageInfo_HeadSyncRange proto.InternalMessageInfo + +func (m *HeadSyncRange) GetFrom() uint64 { + if m != nil { + return m.From + } + return 0 +} + +func (m *HeadSyncRange) GetTo() uint64 { + if m != nil { + return m.To + } + return 0 +} + +func (m *HeadSyncRange) GetLimit() uint32 { + if m != nil { + return m.Limit + } + return 0 +} + +// HeadSyncResult presenting a response for one range +type HeadSyncResult struct { + Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` + Elements []*HeadSyncResultElement `protobuf:"bytes,2,rep,name=elements,proto3" json:"elements,omitempty"` + Count uint32 `protobuf:"varint,3,opt,name=count,proto3" json:"count,omitempty"` +} + +func (m *HeadSyncResult) Reset() { *m = HeadSyncResult{} } +func (m *HeadSyncResult) String() string { return proto.CompactTextString(m) } +func (*HeadSyncResult) ProtoMessage() {} +func (*HeadSyncResult) Descriptor() ([]byte, []int) { + return fileDescriptor_80e49f1f4ac27799, []int{1} +} +func (m *HeadSyncResult) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *HeadSyncResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_HeadSyncResult.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *HeadSyncResult) XXX_Merge(src proto.Message) { + xxx_messageInfo_HeadSyncResult.Merge(m, src) +} +func (m *HeadSyncResult) XXX_Size() int { + return m.Size() +} +func (m *HeadSyncResult) XXX_DiscardUnknown() { + xxx_messageInfo_HeadSyncResult.DiscardUnknown(m) +} + +var xxx_messageInfo_HeadSyncResult proto.InternalMessageInfo + +func (m *HeadSyncResult) GetHash() []byte { + if m != nil { + return m.Hash + } + return nil +} + +func (m *HeadSyncResult) GetElements() []*HeadSyncResultElement { + if m != nil { + return m.Elements + } + return nil +} + +func (m *HeadSyncResult) GetCount() uint32 { + if m != nil { + return m.Count + } + return 0 +} + +// HeadSyncResultElement presenting state of one object +type HeadSyncResultElement struct { + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Head string `protobuf:"bytes,2,opt,name=head,proto3" json:"head,omitempty"` +} + +func (m *HeadSyncResultElement) Reset() { *m = HeadSyncResultElement{} } +func (m *HeadSyncResultElement) String() string { return proto.CompactTextString(m) } +func (*HeadSyncResultElement) ProtoMessage() {} +func (*HeadSyncResultElement) Descriptor() ([]byte, []int) { + return fileDescriptor_80e49f1f4ac27799, []int{2} +} +func (m *HeadSyncResultElement) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *HeadSyncResultElement) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_HeadSyncResultElement.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *HeadSyncResultElement) XXX_Merge(src proto.Message) { + xxx_messageInfo_HeadSyncResultElement.Merge(m, src) +} +func (m *HeadSyncResultElement) XXX_Size() int { + return m.Size() +} +func (m *HeadSyncResultElement) XXX_DiscardUnknown() { + xxx_messageInfo_HeadSyncResultElement.DiscardUnknown(m) +} + +var xxx_messageInfo_HeadSyncResultElement proto.InternalMessageInfo + +func (m *HeadSyncResultElement) GetId() string { + if m != nil { + return m.Id + } + return "" +} + +func (m *HeadSyncResultElement) GetHead() string { + if m != nil { + return m.Head + } + return "" +} + +// HeadSyncRequest is a request for HeadSync +type HeadSyncRequest struct { + SpaceId string `protobuf:"bytes,1,opt,name=spaceId,proto3" json:"spaceId,omitempty"` + Ranges []*HeadSyncRange `protobuf:"bytes,2,rep,name=ranges,proto3" json:"ranges,omitempty"` +} + +func (m *HeadSyncRequest) Reset() { *m = HeadSyncRequest{} } +func (m *HeadSyncRequest) String() string { return proto.CompactTextString(m) } +func (*HeadSyncRequest) ProtoMessage() {} +func (*HeadSyncRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_80e49f1f4ac27799, []int{3} +} +func (m *HeadSyncRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *HeadSyncRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_HeadSyncRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *HeadSyncRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_HeadSyncRequest.Merge(m, src) +} +func (m *HeadSyncRequest) XXX_Size() int { + return m.Size() +} +func (m *HeadSyncRequest) XXX_DiscardUnknown() { + xxx_messageInfo_HeadSyncRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_HeadSyncRequest proto.InternalMessageInfo + +func (m *HeadSyncRequest) GetSpaceId() string { + if m != nil { + return m.SpaceId + } + return "" +} + +func (m *HeadSyncRequest) GetRanges() []*HeadSyncRange { + if m != nil { + return m.Ranges + } + return nil +} + +// HeadSyncResponse is a response for HeadSync +type HeadSyncResponse struct { + Results []*HeadSyncResult `protobuf:"bytes,1,rep,name=results,proto3" json:"results,omitempty"` +} + +func (m *HeadSyncResponse) Reset() { *m = HeadSyncResponse{} } +func (m *HeadSyncResponse) String() string { return proto.CompactTextString(m) } +func (*HeadSyncResponse) ProtoMessage() {} +func (*HeadSyncResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_80e49f1f4ac27799, []int{4} +} +func (m *HeadSyncResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *HeadSyncResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_HeadSyncResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *HeadSyncResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_HeadSyncResponse.Merge(m, src) +} +func (m *HeadSyncResponse) XXX_Size() int { + return m.Size() +} +func (m *HeadSyncResponse) XXX_DiscardUnknown() { + xxx_messageInfo_HeadSyncResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_HeadSyncResponse proto.InternalMessageInfo + +func (m *HeadSyncResponse) GetResults() []*HeadSyncResult { + if m != nil { + return m.Results + } + return nil +} + +// ObjectSyncMessage is a message sent on object sync +type ObjectSyncMessage struct { + SpaceId string `protobuf:"bytes,1,opt,name=spaceId,proto3" json:"spaceId,omitempty"` + ReplyId string `protobuf:"bytes,2,opt,name=replyId,proto3" json:"replyId,omitempty"` + Payload []byte `protobuf:"bytes,3,opt,name=payload,proto3" json:"payload,omitempty"` + ObjectId string `protobuf:"bytes,4,opt,name=objectId,proto3" json:"objectId,omitempty"` +} + +func (m *ObjectSyncMessage) Reset() { *m = ObjectSyncMessage{} } +func (m *ObjectSyncMessage) String() string { return proto.CompactTextString(m) } +func (*ObjectSyncMessage) ProtoMessage() {} +func (*ObjectSyncMessage) Descriptor() ([]byte, []int) { + return fileDescriptor_80e49f1f4ac27799, []int{5} +} +func (m *ObjectSyncMessage) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ObjectSyncMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ObjectSyncMessage.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ObjectSyncMessage) XXX_Merge(src proto.Message) { + xxx_messageInfo_ObjectSyncMessage.Merge(m, src) +} +func (m *ObjectSyncMessage) XXX_Size() int { + return m.Size() +} +func (m *ObjectSyncMessage) XXX_DiscardUnknown() { + xxx_messageInfo_ObjectSyncMessage.DiscardUnknown(m) +} + +var xxx_messageInfo_ObjectSyncMessage proto.InternalMessageInfo + +func (m *ObjectSyncMessage) GetSpaceId() string { + if m != nil { + return m.SpaceId + } + return "" +} + +func (m *ObjectSyncMessage) GetReplyId() string { + if m != nil { + return m.ReplyId + } + return "" +} + +func (m *ObjectSyncMessage) GetPayload() []byte { + if m != nil { + return m.Payload + } + return nil +} + +func (m *ObjectSyncMessage) GetObjectId() string { + if m != nil { + return m.ObjectId + } + return "" +} + +// PushSpaceRequest is a request to add space on a node containing only one acl record +type PushSpaceRequest struct { + SpaceHeader *RawSpaceHeaderWithId `protobuf:"bytes,1,opt,name=spaceHeader,proto3" json:"spaceHeader,omitempty"` + AclPayload []byte `protobuf:"bytes,2,opt,name=aclPayload,proto3" json:"aclPayload,omitempty"` + AclPayloadId string `protobuf:"bytes,3,opt,name=aclPayloadId,proto3" json:"aclPayloadId,omitempty"` +} + +func (m *PushSpaceRequest) Reset() { *m = PushSpaceRequest{} } +func (m *PushSpaceRequest) String() string { return proto.CompactTextString(m) } +func (*PushSpaceRequest) ProtoMessage() {} +func (*PushSpaceRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_80e49f1f4ac27799, []int{6} +} +func (m *PushSpaceRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PushSpaceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PushSpaceRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PushSpaceRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_PushSpaceRequest.Merge(m, src) +} +func (m *PushSpaceRequest) XXX_Size() int { + return m.Size() +} +func (m *PushSpaceRequest) XXX_DiscardUnknown() { + xxx_messageInfo_PushSpaceRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_PushSpaceRequest proto.InternalMessageInfo + +func (m *PushSpaceRequest) GetSpaceHeader() *RawSpaceHeaderWithId { + if m != nil { + return m.SpaceHeader + } + return nil +} + +func (m *PushSpaceRequest) GetAclPayload() []byte { + if m != nil { + return m.AclPayload + } + return nil +} + +func (m *PushSpaceRequest) GetAclPayloadId() string { + if m != nil { + return m.AclPayloadId + } + return "" +} + +// PushSpaceResponse is an empty response +type PushSpaceResponse struct { +} + +func (m *PushSpaceResponse) Reset() { *m = PushSpaceResponse{} } +func (m *PushSpaceResponse) String() string { return proto.CompactTextString(m) } +func (*PushSpaceResponse) ProtoMessage() {} +func (*PushSpaceResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_80e49f1f4ac27799, []int{7} +} +func (m *PushSpaceResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PushSpaceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PushSpaceResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PushSpaceResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_PushSpaceResponse.Merge(m, src) +} +func (m *PushSpaceResponse) XXX_Size() int { + return m.Size() +} +func (m *PushSpaceResponse) XXX_DiscardUnknown() { + xxx_messageInfo_PushSpaceResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_PushSpaceResponse proto.InternalMessageInfo + +// PullSpaceRequest is a request to request a space on a node that doesn't have it +type PullSpaceRequest struct { + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (m *PullSpaceRequest) Reset() { *m = PullSpaceRequest{} } +func (m *PullSpaceRequest) String() string { return proto.CompactTextString(m) } +func (*PullSpaceRequest) ProtoMessage() {} +func (*PullSpaceRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_80e49f1f4ac27799, []int{8} +} +func (m *PullSpaceRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PullSpaceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PullSpaceRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PullSpaceRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_PullSpaceRequest.Merge(m, src) +} +func (m *PullSpaceRequest) XXX_Size() int { + return m.Size() +} +func (m *PullSpaceRequest) XXX_DiscardUnknown() { + xxx_messageInfo_PullSpaceRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_PullSpaceRequest proto.InternalMessageInfo + +func (m *PullSpaceRequest) GetId() string { + if m != nil { + return m.Id + } + return "" +} + +// PullSpaceResponse is a response with header and acl root +type PullSpaceResponse struct { + SpaceHeader *RawSpaceHeaderWithId `protobuf:"bytes,1,opt,name=spaceHeader,proto3" json:"spaceHeader,omitempty"` + AclPayload []byte `protobuf:"bytes,2,opt,name=aclPayload,proto3" json:"aclPayload,omitempty"` + AclPayloadId string `protobuf:"bytes,3,opt,name=aclPayloadId,proto3" json:"aclPayloadId,omitempty"` +} + +func (m *PullSpaceResponse) Reset() { *m = PullSpaceResponse{} } +func (m *PullSpaceResponse) String() string { return proto.CompactTextString(m) } +func (*PullSpaceResponse) ProtoMessage() {} +func (*PullSpaceResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_80e49f1f4ac27799, []int{9} +} +func (m *PullSpaceResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PullSpaceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PullSpaceResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PullSpaceResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_PullSpaceResponse.Merge(m, src) +} +func (m *PullSpaceResponse) XXX_Size() int { + return m.Size() +} +func (m *PullSpaceResponse) XXX_DiscardUnknown() { + xxx_messageInfo_PullSpaceResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_PullSpaceResponse proto.InternalMessageInfo + +func (m *PullSpaceResponse) GetSpaceHeader() *RawSpaceHeaderWithId { + if m != nil { + return m.SpaceHeader + } + return nil +} + +func (m *PullSpaceResponse) GetAclPayload() []byte { + if m != nil { + return m.AclPayload + } + return nil +} + +func (m *PullSpaceResponse) GetAclPayloadId() string { + if m != nil { + return m.AclPayloadId + } + return "" +} + +// SpaceHeader is a header for a space +type SpaceHeader struct { + Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` + Timestamp int64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + SpaceType string `protobuf:"bytes,3,opt,name=spaceType,proto3" json:"spaceType,omitempty"` + ReplicationKey uint64 `protobuf:"varint,4,opt,name=replicationKey,proto3" json:"replicationKey,omitempty"` + Seed []byte `protobuf:"bytes,5,opt,name=seed,proto3" json:"seed,omitempty"` +} + +func (m *SpaceHeader) Reset() { *m = SpaceHeader{} } +func (m *SpaceHeader) String() string { return proto.CompactTextString(m) } +func (*SpaceHeader) ProtoMessage() {} +func (*SpaceHeader) Descriptor() ([]byte, []int) { + return fileDescriptor_80e49f1f4ac27799, []int{10} +} +func (m *SpaceHeader) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SpaceHeader) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SpaceHeader.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *SpaceHeader) XXX_Merge(src proto.Message) { + xxx_messageInfo_SpaceHeader.Merge(m, src) +} +func (m *SpaceHeader) XXX_Size() int { + return m.Size() +} +func (m *SpaceHeader) XXX_DiscardUnknown() { + xxx_messageInfo_SpaceHeader.DiscardUnknown(m) +} + +var xxx_messageInfo_SpaceHeader proto.InternalMessageInfo + +func (m *SpaceHeader) GetIdentity() []byte { + if m != nil { + return m.Identity + } + return nil +} + +func (m *SpaceHeader) GetTimestamp() int64 { + if m != nil { + return m.Timestamp + } + return 0 +} + +func (m *SpaceHeader) GetSpaceType() string { + if m != nil { + return m.SpaceType + } + return "" +} + +func (m *SpaceHeader) GetReplicationKey() uint64 { + if m != nil { + return m.ReplicationKey + } + return 0 +} + +func (m *SpaceHeader) GetSeed() []byte { + if m != nil { + return m.Seed + } + return nil +} + +type RawSpaceHeader struct { + SpaceHeader []byte `protobuf:"bytes,1,opt,name=spaceHeader,proto3" json:"spaceHeader,omitempty"` + Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (m *RawSpaceHeader) Reset() { *m = RawSpaceHeader{} } +func (m *RawSpaceHeader) String() string { return proto.CompactTextString(m) } +func (*RawSpaceHeader) ProtoMessage() {} +func (*RawSpaceHeader) Descriptor() ([]byte, []int) { + return fileDescriptor_80e49f1f4ac27799, []int{11} +} +func (m *RawSpaceHeader) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RawSpaceHeader) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RawSpaceHeader.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RawSpaceHeader) XXX_Merge(src proto.Message) { + xxx_messageInfo_RawSpaceHeader.Merge(m, src) +} +func (m *RawSpaceHeader) XXX_Size() int { + return m.Size() +} +func (m *RawSpaceHeader) XXX_DiscardUnknown() { + xxx_messageInfo_RawSpaceHeader.DiscardUnknown(m) +} + +var xxx_messageInfo_RawSpaceHeader proto.InternalMessageInfo + +func (m *RawSpaceHeader) GetSpaceHeader() []byte { + if m != nil { + return m.SpaceHeader + } + return nil +} + +func (m *RawSpaceHeader) GetSignature() []byte { + if m != nil { + return m.Signature + } + return nil +} + +type RawSpaceHeaderWithId struct { + RawHeader []byte `protobuf:"bytes,1,opt,name=rawHeader,proto3" json:"rawHeader,omitempty"` + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` +} + +func (m *RawSpaceHeaderWithId) Reset() { *m = RawSpaceHeaderWithId{} } +func (m *RawSpaceHeaderWithId) String() string { return proto.CompactTextString(m) } +func (*RawSpaceHeaderWithId) ProtoMessage() {} +func (*RawSpaceHeaderWithId) Descriptor() ([]byte, []int) { + return fileDescriptor_80e49f1f4ac27799, []int{12} +} +func (m *RawSpaceHeaderWithId) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RawSpaceHeaderWithId) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RawSpaceHeaderWithId.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RawSpaceHeaderWithId) XXX_Merge(src proto.Message) { + xxx_messageInfo_RawSpaceHeaderWithId.Merge(m, src) +} +func (m *RawSpaceHeaderWithId) XXX_Size() int { + return m.Size() +} +func (m *RawSpaceHeaderWithId) XXX_DiscardUnknown() { + xxx_messageInfo_RawSpaceHeaderWithId.DiscardUnknown(m) +} + +var xxx_messageInfo_RawSpaceHeaderWithId proto.InternalMessageInfo + +func (m *RawSpaceHeaderWithId) GetRawHeader() []byte { + if m != nil { + return m.RawHeader + } + return nil +} + +func (m *RawSpaceHeaderWithId) GetId() string { + if m != nil { + return m.Id + } + return "" +} + +func init() { + proto.RegisterEnum("anySpace.ErrCodes", ErrCodes_name, ErrCodes_value) + proto.RegisterType((*HeadSyncRange)(nil), "anySpace.HeadSyncRange") + proto.RegisterType((*HeadSyncResult)(nil), "anySpace.HeadSyncResult") + proto.RegisterType((*HeadSyncResultElement)(nil), "anySpace.HeadSyncResultElement") + proto.RegisterType((*HeadSyncRequest)(nil), "anySpace.HeadSyncRequest") + proto.RegisterType((*HeadSyncResponse)(nil), "anySpace.HeadSyncResponse") + proto.RegisterType((*ObjectSyncMessage)(nil), "anySpace.ObjectSyncMessage") + proto.RegisterType((*PushSpaceRequest)(nil), "anySpace.PushSpaceRequest") + proto.RegisterType((*PushSpaceResponse)(nil), "anySpace.PushSpaceResponse") + proto.RegisterType((*PullSpaceRequest)(nil), "anySpace.PullSpaceRequest") + proto.RegisterType((*PullSpaceResponse)(nil), "anySpace.PullSpaceResponse") + proto.RegisterType((*SpaceHeader)(nil), "anySpace.SpaceHeader") + proto.RegisterType((*RawSpaceHeader)(nil), "anySpace.RawSpaceHeader") + proto.RegisterType((*RawSpaceHeaderWithId)(nil), "anySpace.RawSpaceHeaderWithId") +} + +func init() { + proto.RegisterFile("commonspace/spacesyncproto/protos/spacesync.proto", fileDescriptor_80e49f1f4ac27799) +} + +var fileDescriptor_80e49f1f4ac27799 = []byte{ + // 721 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x55, 0xcd, 0x6e, 0xd3, 0x4a, + 0x14, 0x8e, 0xdd, 0xb4, 0x4d, 0x4e, 0xd2, 0x34, 0x9d, 0xdb, 0xab, 0xeb, 0x1b, 0x90, 0x89, 0xbc, + 0x40, 0x11, 0x8b, 0x16, 0x02, 0xbb, 0x6e, 0xf8, 0x69, 0x2a, 0x22, 0x54, 0x5a, 0x4d, 0x40, 0x48, + 0x88, 0xcd, 0xd4, 0x9e, 0x26, 0x46, 0xfe, 0xc3, 0x33, 0x51, 0xeb, 0x05, 0xef, 0xc0, 0x12, 0x36, + 0x48, 0xbc, 0x0d, 0xcb, 0x2e, 0x59, 0xa2, 0xf6, 0x45, 0xd0, 0x9c, 0xd8, 0xb1, 0x9d, 0xa6, 0x5d, + 0xb3, 0x71, 0xe7, 0x7c, 0xe7, 0xef, 0x9b, 0x6f, 0xce, 0x69, 0xe0, 0x91, 0x1d, 0xfa, 0x7e, 0x18, + 0x88, 0x88, 0xd9, 0x7c, 0x17, 0xbf, 0x22, 0x09, 0xec, 0x28, 0x0e, 0x65, 0xb8, 0x8b, 0x5f, 0x91, + 0xa3, 0x3b, 0x08, 0x90, 0x1a, 0x0b, 0x92, 0x91, 0xc2, 0xac, 0x21, 0x6c, 0xbc, 0xe4, 0xcc, 0x19, + 0x25, 0x81, 0x4d, 0x59, 0x30, 0xe6, 0x84, 0x40, 0xf5, 0x34, 0x0e, 0x7d, 0x43, 0xeb, 0x6a, 0xbd, + 0x2a, 0xc5, 0x33, 0x69, 0x81, 0x2e, 0x43, 0x43, 0x47, 0x44, 0x97, 0x21, 0xd9, 0x86, 0x55, 0xcf, + 0xf5, 0x5d, 0x69, 0xac, 0x74, 0xb5, 0xde, 0x06, 0x9d, 0x19, 0xd6, 0x19, 0xb4, 0xe6, 0xa5, 0xb8, + 0x98, 0x7a, 0x52, 0xd5, 0x9a, 0x30, 0x31, 0xc1, 0x5a, 0x4d, 0x8a, 0x67, 0xb2, 0x07, 0x35, 0xee, + 0x71, 0x9f, 0x07, 0x52, 0x18, 0x7a, 0x77, 0xa5, 0xd7, 0xe8, 0xdf, 0xdb, 0xc9, 0xd8, 0xec, 0x94, + 0xf3, 0x07, 0xb3, 0x38, 0x3a, 0x4f, 0x50, 0x8d, 0xed, 0x70, 0x1a, 0xcc, 0x1b, 0xa3, 0x61, 0xed, + 0xc1, 0xbf, 0x4b, 0x13, 0x15, 0x6f, 0xd7, 0xc1, 0xee, 0x75, 0xaa, 0xbb, 0x0e, 0xf2, 0xe1, 0xcc, + 0xc1, 0x9b, 0xd4, 0x29, 0x9e, 0xad, 0x0f, 0xb0, 0x99, 0x27, 0x7f, 0x9a, 0x72, 0x21, 0x89, 0x01, + 0xeb, 0x28, 0xd8, 0x30, 0xcb, 0xcd, 0x4c, 0xb2, 0x0b, 0x6b, 0xb1, 0x52, 0x29, 0xa3, 0xfe, 0xdf, + 0x12, 0xea, 0xca, 0x4f, 0xd3, 0x30, 0xeb, 0x00, 0xda, 0x05, 0x6a, 0x51, 0x18, 0x08, 0x4e, 0xfa, + 0xb0, 0x1e, 0x23, 0x4d, 0x61, 0x68, 0x58, 0xc5, 0xb8, 0x49, 0x00, 0x9a, 0x05, 0x5a, 0x9f, 0x61, + 0xeb, 0xe8, 0xe4, 0x23, 0xb7, 0xa5, 0x72, 0x1e, 0x72, 0x21, 0xd8, 0x98, 0xdf, 0xc2, 0xd3, 0x50, + 0x2d, 0x22, 0x2f, 0x19, 0x66, 0x77, 0xcd, 0x4c, 0xe5, 0x89, 0x58, 0xe2, 0x85, 0xcc, 0x41, 0x0d, + 0x9b, 0x34, 0x33, 0x49, 0x07, 0x6a, 0x21, 0xb6, 0x18, 0x3a, 0x46, 0x15, 0x93, 0xe6, 0xb6, 0xf5, + 0x55, 0x83, 0xf6, 0xf1, 0x54, 0x4c, 0x90, 0x64, 0x26, 0xd3, 0x53, 0x68, 0x60, 0x3f, 0xc5, 0x99, + 0xc7, 0x48, 0xa1, 0xd1, 0x37, 0xf3, 0xbb, 0x50, 0x76, 0x36, 0xca, 0xfd, 0xef, 0x5c, 0x39, 0x19, + 0x3a, 0xb4, 0x98, 0x42, 0x4c, 0x00, 0x66, 0x7b, 0xc7, 0x29, 0x1f, 0x1d, 0xf9, 0x14, 0x10, 0x62, + 0x41, 0x33, 0xb7, 0x86, 0x33, 0xc6, 0x75, 0x5a, 0xc2, 0xac, 0x7f, 0x60, 0xab, 0xc0, 0x6c, 0x26, + 0xb1, 0x65, 0x29, 0xba, 0x9e, 0x57, 0xa2, 0xbb, 0x30, 0x0c, 0xd6, 0x37, 0x4d, 0x65, 0xce, 0x83, + 0xd2, 0xc7, 0xf9, 0x3b, 0x2e, 0xf5, 0x43, 0x83, 0x46, 0xa1, 0x8d, 0x7a, 0x1b, 0xd7, 0xe1, 0x81, + 0x74, 0x65, 0x92, 0x2e, 0xd3, 0xdc, 0x26, 0x77, 0xa1, 0x2e, 0x5d, 0x9f, 0x0b, 0xc9, 0xfc, 0x08, + 0xdb, 0xad, 0xd0, 0x1c, 0x50, 0x5e, 0x24, 0xf7, 0x26, 0x89, 0x78, 0xda, 0x2a, 0x07, 0xc8, 0x7d, + 0x68, 0xa9, 0xc1, 0x70, 0x6d, 0x26, 0xdd, 0x30, 0x78, 0xc5, 0x13, 0x7c, 0xf9, 0x2a, 0x5d, 0x40, + 0xd5, 0xe2, 0x08, 0xce, 0x1d, 0x63, 0x75, 0xb6, 0xc8, 0xea, 0x6c, 0x1d, 0x43, 0xab, 0x2c, 0x06, + 0xe9, 0x5e, 0xd7, 0xae, 0x59, 0xd6, 0x46, 0xb1, 0x71, 0xc7, 0x01, 0x93, 0xd3, 0x98, 0xa7, 0xd2, + 0xe4, 0x80, 0xb5, 0x0f, 0xdb, 0xcb, 0xe4, 0x55, 0x59, 0x31, 0x3b, 0x2b, 0x55, 0xcd, 0x81, 0xf4, + 0x5d, 0xf5, 0xec, 0x5d, 0x1f, 0xbc, 0x86, 0xda, 0x20, 0x8e, 0x5f, 0x84, 0x0e, 0x17, 0xa4, 0x05, + 0xf0, 0x36, 0xe0, 0xe7, 0x11, 0xb7, 0x25, 0x77, 0xda, 0x15, 0xd2, 0x86, 0x26, 0x96, 0x3f, 0x74, + 0x85, 0x70, 0x83, 0x71, 0x5b, 0x23, 0x9b, 0xa9, 0xd0, 0x83, 0x73, 0x57, 0x48, 0xd1, 0xd6, 0x15, + 0x30, 0x88, 0xe3, 0x30, 0x3e, 0x3a, 0x3d, 0x15, 0x5c, 0xb6, 0x9d, 0xfe, 0x77, 0x1d, 0x56, 0x31, + 0x84, 0x3c, 0x83, 0x5a, 0xb6, 0x9f, 0xe4, 0xff, 0x65, 0x3b, 0x8b, 0x83, 0xd6, 0xe9, 0x2c, 0x5d, + 0xe7, 0xd9, 0x78, 0xed, 0x43, 0x7d, 0x3e, 0xad, 0xa4, 0x10, 0xb8, 0xb8, 0x5c, 0x9d, 0x3b, 0x4b, + 0x7d, 0xc5, 0x2a, 0xe9, 0xe4, 0x96, 0xab, 0x94, 0x67, 0xbe, 0x5c, 0x65, 0x71, 0xd4, 0x0f, 0x60, + 0x6d, 0x24, 0x63, 0xce, 0x7c, 0x52, 0x08, 0xbb, 0xf6, 0x5f, 0xa6, 0x73, 0x9b, 0xb3, 0xa7, 0x3d, + 0xd4, 0x9e, 0x3f, 0xf9, 0x79, 0x69, 0x6a, 0x17, 0x97, 0xa6, 0xf6, 0xfb, 0xd2, 0xd4, 0xbe, 0x5c, + 0x99, 0x95, 0x8b, 0x2b, 0xb3, 0xf2, 0xeb, 0xca, 0xac, 0xbc, 0xef, 0xdc, 0xfc, 0xcb, 0x74, 0xb2, + 0x86, 0x7f, 0x1e, 0xff, 0x09, 0x00, 0x00, 0xff, 0xff, 0xf7, 0x95, 0x5b, 0xbc, 0xbe, 0x06, 0x00, + 0x00, +} + +func (m *HeadSyncRange) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *HeadSyncRange) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *HeadSyncRange) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Limit != 0 { + i = encodeVarintSpacesync(dAtA, i, uint64(m.Limit)) + i-- + dAtA[i] = 0x18 + } + if m.To != 0 { + i = encodeVarintSpacesync(dAtA, i, uint64(m.To)) + i-- + dAtA[i] = 0x10 + } + if m.From != 0 { + i = encodeVarintSpacesync(dAtA, i, uint64(m.From)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *HeadSyncResult) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *HeadSyncResult) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *HeadSyncResult) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Count != 0 { + i = encodeVarintSpacesync(dAtA, i, uint64(m.Count)) + i-- + dAtA[i] = 0x18 + } + if len(m.Elements) > 0 { + for iNdEx := len(m.Elements) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Elements[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSpacesync(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.Hash) > 0 { + i -= len(m.Hash) + copy(dAtA[i:], m.Hash) + i = encodeVarintSpacesync(dAtA, i, uint64(len(m.Hash))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *HeadSyncResultElement) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *HeadSyncResultElement) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *HeadSyncResultElement) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Head) > 0 { + i -= len(m.Head) + copy(dAtA[i:], m.Head) + i = encodeVarintSpacesync(dAtA, i, uint64(len(m.Head))) + i-- + dAtA[i] = 0x12 + } + if len(m.Id) > 0 { + i -= len(m.Id) + copy(dAtA[i:], m.Id) + i = encodeVarintSpacesync(dAtA, i, uint64(len(m.Id))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *HeadSyncRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *HeadSyncRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *HeadSyncRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Ranges) > 0 { + for iNdEx := len(m.Ranges) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Ranges[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSpacesync(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.SpaceId) > 0 { + i -= len(m.SpaceId) + copy(dAtA[i:], m.SpaceId) + i = encodeVarintSpacesync(dAtA, i, uint64(len(m.SpaceId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *HeadSyncResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *HeadSyncResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *HeadSyncResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Results) > 0 { + for iNdEx := len(m.Results) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Results[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSpacesync(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *ObjectSyncMessage) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ObjectSyncMessage) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ObjectSyncMessage) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ObjectId) > 0 { + i -= len(m.ObjectId) + copy(dAtA[i:], m.ObjectId) + i = encodeVarintSpacesync(dAtA, i, uint64(len(m.ObjectId))) + i-- + dAtA[i] = 0x22 + } + if len(m.Payload) > 0 { + i -= len(m.Payload) + copy(dAtA[i:], m.Payload) + i = encodeVarintSpacesync(dAtA, i, uint64(len(m.Payload))) + i-- + dAtA[i] = 0x1a + } + if len(m.ReplyId) > 0 { + i -= len(m.ReplyId) + copy(dAtA[i:], m.ReplyId) + i = encodeVarintSpacesync(dAtA, i, uint64(len(m.ReplyId))) + i-- + dAtA[i] = 0x12 + } + if len(m.SpaceId) > 0 { + i -= len(m.SpaceId) + copy(dAtA[i:], m.SpaceId) + i = encodeVarintSpacesync(dAtA, i, uint64(len(m.SpaceId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *PushSpaceRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PushSpaceRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PushSpaceRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.AclPayloadId) > 0 { + i -= len(m.AclPayloadId) + copy(dAtA[i:], m.AclPayloadId) + i = encodeVarintSpacesync(dAtA, i, uint64(len(m.AclPayloadId))) + i-- + dAtA[i] = 0x1a + } + if len(m.AclPayload) > 0 { + i -= len(m.AclPayload) + copy(dAtA[i:], m.AclPayload) + i = encodeVarintSpacesync(dAtA, i, uint64(len(m.AclPayload))) + i-- + dAtA[i] = 0x12 + } + if m.SpaceHeader != nil { + { + size, err := m.SpaceHeader.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSpacesync(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *PushSpaceResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PushSpaceResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PushSpaceResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *PullSpaceRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PullSpaceRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PullSpaceRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Id) > 0 { + i -= len(m.Id) + copy(dAtA[i:], m.Id) + i = encodeVarintSpacesync(dAtA, i, uint64(len(m.Id))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *PullSpaceResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PullSpaceResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PullSpaceResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.AclPayloadId) > 0 { + i -= len(m.AclPayloadId) + copy(dAtA[i:], m.AclPayloadId) + i = encodeVarintSpacesync(dAtA, i, uint64(len(m.AclPayloadId))) + i-- + dAtA[i] = 0x1a + } + if len(m.AclPayload) > 0 { + i -= len(m.AclPayload) + copy(dAtA[i:], m.AclPayload) + i = encodeVarintSpacesync(dAtA, i, uint64(len(m.AclPayload))) + i-- + dAtA[i] = 0x12 + } + if m.SpaceHeader != nil { + { + size, err := m.SpaceHeader.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSpacesync(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *SpaceHeader) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SpaceHeader) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SpaceHeader) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Seed) > 0 { + i -= len(m.Seed) + copy(dAtA[i:], m.Seed) + i = encodeVarintSpacesync(dAtA, i, uint64(len(m.Seed))) + i-- + dAtA[i] = 0x2a + } + if m.ReplicationKey != 0 { + i = encodeVarintSpacesync(dAtA, i, uint64(m.ReplicationKey)) + i-- + dAtA[i] = 0x20 + } + if len(m.SpaceType) > 0 { + i -= len(m.SpaceType) + copy(dAtA[i:], m.SpaceType) + i = encodeVarintSpacesync(dAtA, i, uint64(len(m.SpaceType))) + i-- + dAtA[i] = 0x1a + } + if m.Timestamp != 0 { + i = encodeVarintSpacesync(dAtA, i, uint64(m.Timestamp)) + i-- + dAtA[i] = 0x10 + } + if len(m.Identity) > 0 { + i -= len(m.Identity) + copy(dAtA[i:], m.Identity) + i = encodeVarintSpacesync(dAtA, i, uint64(len(m.Identity))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *RawSpaceHeader) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RawSpaceHeader) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RawSpaceHeader) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signature) > 0 { + i -= len(m.Signature) + copy(dAtA[i:], m.Signature) + i = encodeVarintSpacesync(dAtA, i, uint64(len(m.Signature))) + i-- + dAtA[i] = 0x12 + } + if len(m.SpaceHeader) > 0 { + i -= len(m.SpaceHeader) + copy(dAtA[i:], m.SpaceHeader) + i = encodeVarintSpacesync(dAtA, i, uint64(len(m.SpaceHeader))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *RawSpaceHeaderWithId) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RawSpaceHeaderWithId) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RawSpaceHeaderWithId) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Id) > 0 { + i -= len(m.Id) + copy(dAtA[i:], m.Id) + i = encodeVarintSpacesync(dAtA, i, uint64(len(m.Id))) + i-- + dAtA[i] = 0x12 + } + if len(m.RawHeader) > 0 { + i -= len(m.RawHeader) + copy(dAtA[i:], m.RawHeader) + i = encodeVarintSpacesync(dAtA, i, uint64(len(m.RawHeader))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintSpacesync(dAtA []byte, offset int, v uint64) int { + offset -= sovSpacesync(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *HeadSyncRange) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.From != 0 { + n += 1 + sovSpacesync(uint64(m.From)) + } + if m.To != 0 { + n += 1 + sovSpacesync(uint64(m.To)) + } + if m.Limit != 0 { + n += 1 + sovSpacesync(uint64(m.Limit)) + } + return n +} + +func (m *HeadSyncResult) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Hash) + if l > 0 { + n += 1 + l + sovSpacesync(uint64(l)) + } + if len(m.Elements) > 0 { + for _, e := range m.Elements { + l = e.Size() + n += 1 + l + sovSpacesync(uint64(l)) + } + } + if m.Count != 0 { + n += 1 + sovSpacesync(uint64(m.Count)) + } + return n +} + +func (m *HeadSyncResultElement) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Id) + if l > 0 { + n += 1 + l + sovSpacesync(uint64(l)) + } + l = len(m.Head) + if l > 0 { + n += 1 + l + sovSpacesync(uint64(l)) + } + return n +} + +func (m *HeadSyncRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.SpaceId) + if l > 0 { + n += 1 + l + sovSpacesync(uint64(l)) + } + if len(m.Ranges) > 0 { + for _, e := range m.Ranges { + l = e.Size() + n += 1 + l + sovSpacesync(uint64(l)) + } + } + return n +} + +func (m *HeadSyncResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Results) > 0 { + for _, e := range m.Results { + l = e.Size() + n += 1 + l + sovSpacesync(uint64(l)) + } + } + return n +} + +func (m *ObjectSyncMessage) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.SpaceId) + if l > 0 { + n += 1 + l + sovSpacesync(uint64(l)) + } + l = len(m.ReplyId) + if l > 0 { + n += 1 + l + sovSpacesync(uint64(l)) + } + l = len(m.Payload) + if l > 0 { + n += 1 + l + sovSpacesync(uint64(l)) + } + l = len(m.ObjectId) + if l > 0 { + n += 1 + l + sovSpacesync(uint64(l)) + } + return n +} + +func (m *PushSpaceRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SpaceHeader != nil { + l = m.SpaceHeader.Size() + n += 1 + l + sovSpacesync(uint64(l)) + } + l = len(m.AclPayload) + if l > 0 { + n += 1 + l + sovSpacesync(uint64(l)) + } + l = len(m.AclPayloadId) + if l > 0 { + n += 1 + l + sovSpacesync(uint64(l)) + } + return n +} + +func (m *PushSpaceResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *PullSpaceRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Id) + if l > 0 { + n += 1 + l + sovSpacesync(uint64(l)) + } + return n +} + +func (m *PullSpaceResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SpaceHeader != nil { + l = m.SpaceHeader.Size() + n += 1 + l + sovSpacesync(uint64(l)) + } + l = len(m.AclPayload) + if l > 0 { + n += 1 + l + sovSpacesync(uint64(l)) + } + l = len(m.AclPayloadId) + if l > 0 { + n += 1 + l + sovSpacesync(uint64(l)) + } + return n +} + +func (m *SpaceHeader) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Identity) + if l > 0 { + n += 1 + l + sovSpacesync(uint64(l)) + } + if m.Timestamp != 0 { + n += 1 + sovSpacesync(uint64(m.Timestamp)) + } + l = len(m.SpaceType) + if l > 0 { + n += 1 + l + sovSpacesync(uint64(l)) + } + if m.ReplicationKey != 0 { + n += 1 + sovSpacesync(uint64(m.ReplicationKey)) + } + l = len(m.Seed) + if l > 0 { + n += 1 + l + sovSpacesync(uint64(l)) + } + return n +} + +func (m *RawSpaceHeader) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.SpaceHeader) + if l > 0 { + n += 1 + l + sovSpacesync(uint64(l)) + } + l = len(m.Signature) + if l > 0 { + n += 1 + l + sovSpacesync(uint64(l)) + } + return n +} + +func (m *RawSpaceHeaderWithId) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.RawHeader) + if l > 0 { + n += 1 + l + sovSpacesync(uint64(l)) + } + l = len(m.Id) + if l > 0 { + n += 1 + l + sovSpacesync(uint64(l)) + } + return n +} + +func sovSpacesync(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozSpacesync(x uint64) (n int) { + return sovSpacesync(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *HeadSyncRange) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: HeadSyncRange: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: HeadSyncRange: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field From", wireType) + } + m.From = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.From |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field To", wireType) + } + m.To = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.To |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType) + } + m.Limit = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Limit |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipSpacesync(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSpacesync + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *HeadSyncResult) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: HeadSyncResult: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: HeadSyncResult: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSpacesync + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSpacesync + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Hash = append(m.Hash[:0], dAtA[iNdEx:postIndex]...) + if m.Hash == nil { + m.Hash = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Elements", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSpacesync + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSpacesync + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Elements = append(m.Elements, &HeadSyncResultElement{}) + if err := m.Elements[len(m.Elements)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Count", wireType) + } + m.Count = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Count |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipSpacesync(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSpacesync + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *HeadSyncResultElement) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: HeadSyncResultElement: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: HeadSyncResultElement: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSpacesync + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSpacesync + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Id = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Head", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSpacesync + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSpacesync + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Head = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSpacesync(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSpacesync + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *HeadSyncRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: HeadSyncRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: HeadSyncRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SpaceId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSpacesync + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSpacesync + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SpaceId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ranges", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSpacesync + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSpacesync + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Ranges = append(m.Ranges, &HeadSyncRange{}) + if err := m.Ranges[len(m.Ranges)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSpacesync(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSpacesync + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *HeadSyncResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: HeadSyncResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: HeadSyncResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Results", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSpacesync + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSpacesync + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Results = append(m.Results, &HeadSyncResult{}) + if err := m.Results[len(m.Results)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSpacesync(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSpacesync + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ObjectSyncMessage) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ObjectSyncMessage: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ObjectSyncMessage: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SpaceId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSpacesync + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSpacesync + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SpaceId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ReplyId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSpacesync + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSpacesync + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ReplyId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Payload", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSpacesync + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSpacesync + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Payload = append(m.Payload[:0], dAtA[iNdEx:postIndex]...) + if m.Payload == nil { + m.Payload = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSpacesync + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSpacesync + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ObjectId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSpacesync(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSpacesync + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PushSpaceRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PushSpaceRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PushSpaceRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SpaceHeader", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSpacesync + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSpacesync + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.SpaceHeader == nil { + m.SpaceHeader = &RawSpaceHeaderWithId{} + } + if err := m.SpaceHeader.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AclPayload", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSpacesync + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSpacesync + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AclPayload = append(m.AclPayload[:0], dAtA[iNdEx:postIndex]...) + if m.AclPayload == nil { + m.AclPayload = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AclPayloadId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSpacesync + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSpacesync + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AclPayloadId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSpacesync(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSpacesync + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PushSpaceResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PushSpaceResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PushSpaceResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipSpacesync(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSpacesync + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PullSpaceRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PullSpaceRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PullSpaceRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSpacesync + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSpacesync + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Id = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSpacesync(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSpacesync + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PullSpaceResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PullSpaceResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PullSpaceResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SpaceHeader", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSpacesync + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSpacesync + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.SpaceHeader == nil { + m.SpaceHeader = &RawSpaceHeaderWithId{} + } + if err := m.SpaceHeader.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AclPayload", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSpacesync + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSpacesync + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AclPayload = append(m.AclPayload[:0], dAtA[iNdEx:postIndex]...) + if m.AclPayload == nil { + m.AclPayload = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AclPayloadId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSpacesync + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSpacesync + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AclPayloadId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSpacesync(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSpacesync + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SpaceHeader) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SpaceHeader: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SpaceHeader: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Identity", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSpacesync + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSpacesync + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Identity = append(m.Identity[:0], dAtA[iNdEx:postIndex]...) + if m.Identity == nil { + m.Identity = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) + } + m.Timestamp = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Timestamp |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SpaceType", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSpacesync + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSpacesync + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SpaceType = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ReplicationKey", wireType) + } + m.ReplicationKey = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ReplicationKey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Seed", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSpacesync + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSpacesync + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Seed = append(m.Seed[:0], dAtA[iNdEx:postIndex]...) + if m.Seed == nil { + m.Seed = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSpacesync(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSpacesync + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RawSpaceHeader) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RawSpaceHeader: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RawSpaceHeader: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SpaceHeader", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSpacesync + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSpacesync + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SpaceHeader = append(m.SpaceHeader[:0], dAtA[iNdEx:postIndex]...) + if m.SpaceHeader == nil { + m.SpaceHeader = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSpacesync + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSpacesync + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signature = append(m.Signature[:0], dAtA[iNdEx:postIndex]...) + if m.Signature == nil { + m.Signature = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSpacesync(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSpacesync + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RawSpaceHeaderWithId) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RawSpaceHeaderWithId: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RawSpaceHeaderWithId: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RawHeader", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSpacesync + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSpacesync + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RawHeader = append(m.RawHeader[:0], dAtA[iNdEx:postIndex]...) + if m.RawHeader == nil { + m.RawHeader = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSpacesync + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSpacesync + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Id = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSpacesync(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSpacesync + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipSpacesync(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowSpacesync + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowSpacesync + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowSpacesync + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthSpacesync + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupSpacesync + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthSpacesync + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthSpacesync = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowSpacesync = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupSpacesync = fmt.Errorf("proto: unexpected end of group") +) diff --git a/common/commonspace/spacesyncproto/spacesync_drpc.pb.go b/common/commonspace/spacesyncproto/spacesync_drpc.pb.go new file mode 100644 index 00000000..b1a0a929 --- /dev/null +++ b/common/commonspace/spacesyncproto/spacesync_drpc.pb.go @@ -0,0 +1,268 @@ +// Code generated by protoc-gen-go-drpc. DO NOT EDIT. +// protoc-gen-go-drpc version: v0.0.32 +// source: commonspace/spacesyncproto/protos/spacesync.proto + +package spacesyncproto + +import ( + bytes "bytes" + context "context" + errors "errors" + jsonpb "github.com/gogo/protobuf/jsonpb" + proto "github.com/gogo/protobuf/proto" + drpc "storj.io/drpc" + drpcerr "storj.io/drpc/drpcerr" +) + +type drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto struct{} + +func (drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto) Marshal(msg drpc.Message) ([]byte, error) { + return proto.Marshal(msg.(proto.Message)) +} + +func (drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto) Unmarshal(buf []byte, msg drpc.Message) error { + return proto.Unmarshal(buf, msg.(proto.Message)) +} + +func (drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto) JSONMarshal(msg drpc.Message) ([]byte, error) { + var buf bytes.Buffer + err := new(jsonpb.Marshaler).Marshal(&buf, msg.(proto.Message)) + if err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +func (drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto) JSONUnmarshal(buf []byte, msg drpc.Message) error { + return jsonpb.Unmarshal(bytes.NewReader(buf), msg.(proto.Message)) +} + +type DRPCSpaceClient interface { + DRPCConn() drpc.Conn + + HeadSync(ctx context.Context, in *HeadSyncRequest) (*HeadSyncResponse, error) + PushSpace(ctx context.Context, in *PushSpaceRequest) (*PushSpaceResponse, error) + PullSpace(ctx context.Context, in *PullSpaceRequest) (*PullSpaceResponse, error) + Stream(ctx context.Context) (DRPCSpace_StreamClient, error) +} + +type drpcSpaceClient struct { + cc drpc.Conn +} + +func NewDRPCSpaceClient(cc drpc.Conn) DRPCSpaceClient { + return &drpcSpaceClient{cc} +} + +func (c *drpcSpaceClient) DRPCConn() drpc.Conn { return c.cc } + +func (c *drpcSpaceClient) HeadSync(ctx context.Context, in *HeadSyncRequest) (*HeadSyncResponse, error) { + out := new(HeadSyncResponse) + err := c.cc.Invoke(ctx, "/anySpace.Space/HeadSync", drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto{}, in, out) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *drpcSpaceClient) PushSpace(ctx context.Context, in *PushSpaceRequest) (*PushSpaceResponse, error) { + out := new(PushSpaceResponse) + err := c.cc.Invoke(ctx, "/anySpace.Space/PushSpace", drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto{}, in, out) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *drpcSpaceClient) PullSpace(ctx context.Context, in *PullSpaceRequest) (*PullSpaceResponse, error) { + out := new(PullSpaceResponse) + err := c.cc.Invoke(ctx, "/anySpace.Space/PullSpace", drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto{}, in, out) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *drpcSpaceClient) Stream(ctx context.Context) (DRPCSpace_StreamClient, error) { + stream, err := c.cc.NewStream(ctx, "/anySpace.Space/Stream", drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto{}) + if err != nil { + return nil, err + } + x := &drpcSpace_StreamClient{stream} + return x, nil +} + +type DRPCSpace_StreamClient interface { + drpc.Stream + Send(*ObjectSyncMessage) error + Recv() (*ObjectSyncMessage, error) +} + +type drpcSpace_StreamClient struct { + drpc.Stream +} + +func (x *drpcSpace_StreamClient) Send(m *ObjectSyncMessage) error { + return x.MsgSend(m, drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto{}) +} + +func (x *drpcSpace_StreamClient) Recv() (*ObjectSyncMessage, error) { + m := new(ObjectSyncMessage) + if err := x.MsgRecv(m, drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto{}); err != nil { + return nil, err + } + return m, nil +} + +func (x *drpcSpace_StreamClient) RecvMsg(m *ObjectSyncMessage) error { + return x.MsgRecv(m, drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto{}) +} + +type DRPCSpaceServer interface { + HeadSync(context.Context, *HeadSyncRequest) (*HeadSyncResponse, error) + PushSpace(context.Context, *PushSpaceRequest) (*PushSpaceResponse, error) + PullSpace(context.Context, *PullSpaceRequest) (*PullSpaceResponse, error) + Stream(DRPCSpace_StreamStream) error +} + +type DRPCSpaceUnimplementedServer struct{} + +func (s *DRPCSpaceUnimplementedServer) HeadSync(context.Context, *HeadSyncRequest) (*HeadSyncResponse, error) { + return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) +} + +func (s *DRPCSpaceUnimplementedServer) PushSpace(context.Context, *PushSpaceRequest) (*PushSpaceResponse, error) { + return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) +} + +func (s *DRPCSpaceUnimplementedServer) PullSpace(context.Context, *PullSpaceRequest) (*PullSpaceResponse, error) { + return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) +} + +func (s *DRPCSpaceUnimplementedServer) Stream(DRPCSpace_StreamStream) error { + return drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) +} + +type DRPCSpaceDescription struct{} + +func (DRPCSpaceDescription) NumMethods() int { return 4 } + +func (DRPCSpaceDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver, interface{}, bool) { + switch n { + case 0: + return "/anySpace.Space/HeadSync", drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto{}, + func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { + return srv.(DRPCSpaceServer). + HeadSync( + ctx, + in1.(*HeadSyncRequest), + ) + }, DRPCSpaceServer.HeadSync, true + case 1: + return "/anySpace.Space/PushSpace", drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto{}, + func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { + return srv.(DRPCSpaceServer). + PushSpace( + ctx, + in1.(*PushSpaceRequest), + ) + }, DRPCSpaceServer.PushSpace, true + case 2: + return "/anySpace.Space/PullSpace", drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto{}, + func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { + return srv.(DRPCSpaceServer). + PullSpace( + ctx, + in1.(*PullSpaceRequest), + ) + }, DRPCSpaceServer.PullSpace, true + case 3: + return "/anySpace.Space/Stream", drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto{}, + func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { + return nil, srv.(DRPCSpaceServer). + Stream( + &drpcSpace_StreamStream{in1.(drpc.Stream)}, + ) + }, DRPCSpaceServer.Stream, true + default: + return "", nil, nil, nil, false + } +} + +func DRPCRegisterSpace(mux drpc.Mux, impl DRPCSpaceServer) error { + return mux.Register(impl, DRPCSpaceDescription{}) +} + +type DRPCSpace_HeadSyncStream interface { + drpc.Stream + SendAndClose(*HeadSyncResponse) error +} + +type drpcSpace_HeadSyncStream struct { + drpc.Stream +} + +func (x *drpcSpace_HeadSyncStream) SendAndClose(m *HeadSyncResponse) error { + if err := x.MsgSend(m, drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto{}); err != nil { + return err + } + return x.CloseSend() +} + +type DRPCSpace_PushSpaceStream interface { + drpc.Stream + SendAndClose(*PushSpaceResponse) error +} + +type drpcSpace_PushSpaceStream struct { + drpc.Stream +} + +func (x *drpcSpace_PushSpaceStream) SendAndClose(m *PushSpaceResponse) error { + if err := x.MsgSend(m, drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto{}); err != nil { + return err + } + return x.CloseSend() +} + +type DRPCSpace_PullSpaceStream interface { + drpc.Stream + SendAndClose(*PullSpaceResponse) error +} + +type drpcSpace_PullSpaceStream struct { + drpc.Stream +} + +func (x *drpcSpace_PullSpaceStream) SendAndClose(m *PullSpaceResponse) error { + if err := x.MsgSend(m, drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto{}); err != nil { + return err + } + return x.CloseSend() +} + +type DRPCSpace_StreamStream interface { + drpc.Stream + Send(*ObjectSyncMessage) error + Recv() (*ObjectSyncMessage, error) +} + +type drpcSpace_StreamStream struct { + drpc.Stream +} + +func (x *drpcSpace_StreamStream) Send(m *ObjectSyncMessage) error { + return x.MsgSend(m, drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto{}) +} + +func (x *drpcSpace_StreamStream) Recv() (*ObjectSyncMessage, error) { + m := new(ObjectSyncMessage) + if err := x.MsgRecv(m, drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto{}); err != nil { + return nil, err + } + return m, nil +} + +func (x *drpcSpace_StreamStream) RecvMsg(m *ObjectSyncMessage) error { + return x.MsgRecv(m, drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto{}) +} diff --git a/common/commonspace/storage/mock_storage/mock_storage.go b/common/commonspace/storage/mock_storage/mock_storage.go new file mode 100644 index 00000000..419c61fa --- /dev/null +++ b/common/commonspace/storage/mock_storage/mock_storage.go @@ -0,0 +1,222 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage (interfaces: SpaceStorageProvider,SpaceStorage) + +// Package mock_storage is a generated GoMock package. +package mock_storage + +import ( + reflect "reflect" + + app "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + spacesyncproto "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" + storage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage" + storage0 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage" + gomock "github.com/golang/mock/gomock" +) + +// MockSpaceStorageProvider is a mock of SpaceStorageProvider interface. +type MockSpaceStorageProvider struct { + ctrl *gomock.Controller + recorder *MockSpaceStorageProviderMockRecorder +} + +// MockSpaceStorageProviderMockRecorder is the mock recorder for MockSpaceStorageProvider. +type MockSpaceStorageProviderMockRecorder struct { + mock *MockSpaceStorageProvider +} + +// NewMockSpaceStorageProvider creates a new mock instance. +func NewMockSpaceStorageProvider(ctrl *gomock.Controller) *MockSpaceStorageProvider { + mock := &MockSpaceStorageProvider{ctrl: ctrl} + mock.recorder = &MockSpaceStorageProviderMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockSpaceStorageProvider) EXPECT() *MockSpaceStorageProviderMockRecorder { + return m.recorder +} + +// CreateSpaceStorage mocks base method. +func (m *MockSpaceStorageProvider) CreateSpaceStorage(arg0 storage.SpaceStorageCreatePayload) (storage.SpaceStorage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateSpaceStorage", arg0) + ret0, _ := ret[0].(storage.SpaceStorage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateSpaceStorage indicates an expected call of CreateSpaceStorage. +func (mr *MockSpaceStorageProviderMockRecorder) CreateSpaceStorage(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateSpaceStorage", reflect.TypeOf((*MockSpaceStorageProvider)(nil).CreateSpaceStorage), arg0) +} + +// Init mocks base method. +func (m *MockSpaceStorageProvider) Init(arg0 *app.App) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Init", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Init indicates an expected call of Init. +func (mr *MockSpaceStorageProviderMockRecorder) Init(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockSpaceStorageProvider)(nil).Init), arg0) +} + +// Name mocks base method. +func (m *MockSpaceStorageProvider) Name() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Name") + ret0, _ := ret[0].(string) + return ret0 +} + +// Name indicates an expected call of Name. +func (mr *MockSpaceStorageProviderMockRecorder) Name() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockSpaceStorageProvider)(nil).Name)) +} + +// SpaceStorage mocks base method. +func (m *MockSpaceStorageProvider) SpaceStorage(arg0 string) (storage.SpaceStorage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SpaceStorage", arg0) + ret0, _ := ret[0].(storage.SpaceStorage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SpaceStorage indicates an expected call of SpaceStorage. +func (mr *MockSpaceStorageProviderMockRecorder) SpaceStorage(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SpaceStorage", reflect.TypeOf((*MockSpaceStorageProvider)(nil).SpaceStorage), arg0) +} + +// MockSpaceStorage is a mock of SpaceStorage interface. +type MockSpaceStorage struct { + ctrl *gomock.Controller + recorder *MockSpaceStorageMockRecorder +} + +// MockSpaceStorageMockRecorder is the mock recorder for MockSpaceStorage. +type MockSpaceStorageMockRecorder struct { + mock *MockSpaceStorage +} + +// NewMockSpaceStorage creates a new mock instance. +func NewMockSpaceStorage(ctrl *gomock.Controller) *MockSpaceStorage { + mock := &MockSpaceStorage{ctrl: ctrl} + mock.recorder = &MockSpaceStorageMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockSpaceStorage) EXPECT() *MockSpaceStorageMockRecorder { + return m.recorder +} + +// ACLStorage mocks base method. +func (m *MockSpaceStorage) ACLStorage() (storage0.ListStorage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ACLStorage") + ret0, _ := ret[0].(storage0.ListStorage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ACLStorage indicates an expected call of ACLStorage. +func (mr *MockSpaceStorageMockRecorder) ACLStorage() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ACLStorage", reflect.TypeOf((*MockSpaceStorage)(nil).ACLStorage)) +} + +// Close mocks base method. +func (m *MockSpaceStorage) Close() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Close") + ret0, _ := ret[0].(error) + return ret0 +} + +// Close indicates an expected call of Close. +func (mr *MockSpaceStorageMockRecorder) Close() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockSpaceStorage)(nil).Close)) +} + +// CreateTreeStorage mocks base method. +func (m *MockSpaceStorage) CreateTreeStorage(arg0 storage0.TreeStorageCreatePayload) (storage0.TreeStorage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateTreeStorage", arg0) + ret0, _ := ret[0].(storage0.TreeStorage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateTreeStorage indicates an expected call of CreateTreeStorage. +func (mr *MockSpaceStorageMockRecorder) CreateTreeStorage(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateTreeStorage", reflect.TypeOf((*MockSpaceStorage)(nil).CreateTreeStorage), arg0) +} + +// Id mocks base method. +func (m *MockSpaceStorage) Id() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Id") + ret0, _ := ret[0].(string) + return ret0 +} + +// Id indicates an expected call of Id. +func (mr *MockSpaceStorageMockRecorder) Id() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Id", reflect.TypeOf((*MockSpaceStorage)(nil).Id)) +} + +// SpaceHeader mocks base method. +func (m *MockSpaceStorage) SpaceHeader() (*spacesyncproto.RawSpaceHeaderWithId, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SpaceHeader") + ret0, _ := ret[0].(*spacesyncproto.RawSpaceHeaderWithId) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SpaceHeader indicates an expected call of SpaceHeader. +func (mr *MockSpaceStorageMockRecorder) SpaceHeader() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SpaceHeader", reflect.TypeOf((*MockSpaceStorage)(nil).SpaceHeader)) +} + +// StoredIds mocks base method. +func (m *MockSpaceStorage) StoredIds() ([]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StoredIds") + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StoredIds indicates an expected call of StoredIds. +func (mr *MockSpaceStorageMockRecorder) StoredIds() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StoredIds", reflect.TypeOf((*MockSpaceStorage)(nil).StoredIds)) +} + +// TreeStorage mocks base method. +func (m *MockSpaceStorage) TreeStorage(arg0 string) (storage0.TreeStorage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TreeStorage", arg0) + ret0, _ := ret[0].(storage0.TreeStorage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// TreeStorage indicates an expected call of TreeStorage. +func (mr *MockSpaceStorageMockRecorder) TreeStorage(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TreeStorage", reflect.TypeOf((*MockSpaceStorage)(nil).TreeStorage), arg0) +} diff --git a/common/commonspace/storage/storage.go b/common/commonspace/storage/storage.go new file mode 100644 index 00000000..a18b9c16 --- /dev/null +++ b/common/commonspace/storage/storage.go @@ -0,0 +1,35 @@ +//go:generate mockgen -destination mock_storage/mock_storage.go github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage SpaceStorageProvider,SpaceStorage +package storage + +import ( + "errors" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage" +) + +const CName = "commonspace.storage" + +var ErrSpaceStorageExists = errors.New("space storage exists") +var ErrSpaceStorageMissing = errors.New("space storage missing") + +type SpaceStorage interface { + storage.Provider + Id() string + ACLStorage() (storage.ListStorage, error) + SpaceHeader() (*spacesyncproto.RawSpaceHeaderWithId, error) + StoredIds() ([]string, error) + Close() error +} + +type SpaceStorageCreatePayload struct { + RecWithId *aclrecordproto.RawACLRecordWithId + SpaceHeaderWithId *spacesyncproto.RawSpaceHeaderWithId +} + +type SpaceStorageProvider interface { + app.Component + SpaceStorage(id string) (SpaceStorage, error) + CreateSpaceStorage(payload SpaceStorageCreatePayload) (SpaceStorage, error) +} diff --git a/common/commonspace/syncacl/syncacl.go b/common/commonspace/syncacl/syncacl.go new file mode 100644 index 00000000..c7343625 --- /dev/null +++ b/common/commonspace/syncacl/syncacl.go @@ -0,0 +1,21 @@ +package syncacl + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice/synchandler" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/list" +) + +type SyncACL struct { + list.ACLList + synchandler.SyncHandler + streamPool syncservice.StreamPool +} + +func NewSyncACL(aclList list.ACLList, streamPool syncservice.StreamPool) *SyncACL { + return &SyncACL{ + ACLList: aclList, + SyncHandler: nil, + streamPool: streamPool, + } +} diff --git a/common/commonspace/syncacl/syncaclhandler.go b/common/commonspace/syncacl/syncaclhandler.go new file mode 100644 index 00000000..feb78e07 --- /dev/null +++ b/common/commonspace/syncacl/syncaclhandler.go @@ -0,0 +1,31 @@ +package syncacl + +import ( + "context" + "fmt" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/list" +) + +type syncAclHandler struct { + acl list.ACLList +} + +func (s *syncAclHandler) HandleMessage(ctx context.Context, senderId string, req *spacesyncproto.ObjectSyncMessage) (err error) { + aclMsg := &aclrecordproto.ACLSyncMessage{} + if err = aclMsg.Unmarshal(req.Payload); err != nil { + return + } + content := aclMsg.GetContent() + switch { + case content.GetAddRecords() != nil: + return s.handleAddRecords(ctx, senderId, content.GetAddRecords()) + default: + return fmt.Errorf("unexpected aclSync message: %T", content.Value) + } +} + +func (s *syncAclHandler) handleAddRecords(ctx context.Context, senderId string, addRecord *aclrecordproto.ACLAddRecords) (err error) { + return +} diff --git a/common/commonspace/syncservice/streampool.go b/common/commonspace/syncservice/streampool.go new file mode 100644 index 00000000..a2bbe4ce --- /dev/null +++ b/common/commonspace/syncservice/streampool.go @@ -0,0 +1,281 @@ +package syncservice + +import ( + "context" + "errors" + "fmt" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/peer" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ocache" + "sync" + "sync/atomic" + "time" +) + +var ErrEmptyPeer = errors.New("don't have such a peer") +var ErrStreamClosed = errors.New("stream is already closed") + +var maxSimultaneousOperationsPerStream = 10 +var syncWaitPeriod = 2 * time.Second + +var ErrSyncTimeout = errors.New("too long wait on sync receive") + +// StreamPool can be made generic to work with different streams +type StreamPool interface { + ocache.ObjectLastUsage + AddAndReadStreamSync(stream spacesyncproto.SpaceStream) (err error) + AddAndReadStreamAsync(stream spacesyncproto.SpaceStream) + + SendSync(peerId string, message *spacesyncproto.ObjectSyncMessage) (reply *spacesyncproto.ObjectSyncMessage, err error) + SendAsync(peers []string, message *spacesyncproto.ObjectSyncMessage) (err error) + BroadcastAsync(message *spacesyncproto.ObjectSyncMessage) (err error) + + HasActiveStream(peerId string) bool + Close() (err error) +} + +type MessageHandler func(ctx context.Context, senderId string, message *spacesyncproto.ObjectSyncMessage) (err error) + +type responseWaiter struct { + ch chan *spacesyncproto.ObjectSyncMessage +} + +type streamPool struct { + sync.Mutex + peerStreams map[string]spacesyncproto.SpaceStream + messageHandler MessageHandler + wg *sync.WaitGroup + waiters map[string]responseWaiter + waitersMx sync.Mutex + counter atomic.Uint64 + lastUsage atomic.Int64 +} + +func newStreamPool(messageHandler MessageHandler) StreamPool { + s := &streamPool{ + peerStreams: make(map[string]spacesyncproto.SpaceStream), + messageHandler: messageHandler, + waiters: make(map[string]responseWaiter), + wg: &sync.WaitGroup{}, + } + s.lastUsage.Store(time.Now().Unix()) + return s +} + +func (s *streamPool) LastUsage() time.Time { + return time.Unix(s.lastUsage.Load(), 0) +} + +func (s *streamPool) HasActiveStream(peerId string) (res bool) { + s.Lock() + defer s.Unlock() + _, err := s.getOrDeleteStream(peerId) + return err == nil +} + +func (s *streamPool) SendSync( + peerId string, + msg *spacesyncproto.ObjectSyncMessage) (reply *spacesyncproto.ObjectSyncMessage, err error) { + newCounter := s.counter.Add(1) + msg.ReplyId = genStreamPoolKey(peerId, msg.ObjectId, newCounter) + + s.waitersMx.Lock() + waiter := responseWaiter{ + ch: make(chan *spacesyncproto.ObjectSyncMessage, 1), + } + s.waiters[msg.ReplyId] = waiter + s.waitersMx.Unlock() + + err = s.SendAsync([]string{peerId}, msg) + if err != nil { + return + } + delay := time.NewTimer(syncWaitPeriod) + select { + case <-delay.C: + s.waitersMx.Lock() + delete(s.waiters, msg.ReplyId) + s.waitersMx.Unlock() + + log.With("replyId", msg.ReplyId).Error("time elapsed when waiting") + err = ErrSyncTimeout + case reply = <-waiter.ch: + if !delay.Stop() { + <-delay.C + } + } + return +} + +func (s *streamPool) SendAsync(peers []string, message *spacesyncproto.ObjectSyncMessage) (err error) { + s.lastUsage.Store(time.Now().Unix()) + getStreams := func() (streams []spacesyncproto.SpaceStream) { + for _, pId := range peers { + stream, err := s.getOrDeleteStream(pId) + if err != nil { + continue + } + streams = append(streams, stream) + } + return streams + } + + s.Lock() + streams := getStreams() + s.Unlock() + + log.With("objectId", message.ObjectId). + Debugf("sending message to %d peers", len(streams)) + for _, s := range streams { + err = s.Send(message) + } + if len(peers) != 1 { + err = nil + } + return err +} + +func (s *streamPool) getOrDeleteStream(id string) (stream spacesyncproto.SpaceStream, err error) { + stream, exists := s.peerStreams[id] + if !exists { + err = ErrEmptyPeer + return + } + + select { + case <-stream.Context().Done(): + delete(s.peerStreams, id) + err = ErrStreamClosed + default: + } + + return +} + +func (s *streamPool) getAllStreams() (streams []spacesyncproto.SpaceStream) { + s.Lock() + defer s.Unlock() +Loop: + for id, stream := range s.peerStreams { + select { + case <-stream.Context().Done(): + delete(s.peerStreams, id) + continue Loop + default: + break + } + streams = append(streams, stream) + } + + return +} + +func (s *streamPool) BroadcastAsync(message *spacesyncproto.ObjectSyncMessage) (err error) { + streams := s.getAllStreams() + log.With("objectId", message.ObjectId). + Debugf("broadcasting message to %d peers", len(streams)) + for _, stream := range streams { + if err = stream.Send(message); err != nil { + // TODO: add logging + } + } + + return nil +} + +func (s *streamPool) AddAndReadStreamAsync(stream spacesyncproto.SpaceStream) { + go s.AddAndReadStreamSync(stream) +} + +func (s *streamPool) AddAndReadStreamSync(stream spacesyncproto.SpaceStream) (err error) { + s.Lock() + peerId, err := peer.CtxPeerId(stream.Context()) + if err != nil { + s.Unlock() + return + } + + s.peerStreams[peerId] = stream + s.wg.Add(1) + s.Unlock() + log.With("peerId", peerId).Debug("reading stream from peer") + return s.readPeerLoop(peerId, stream) +} + +func (s *streamPool) Close() (err error) { + s.Lock() + wg := s.wg + s.Unlock() + if wg != nil { + wg.Wait() + } + return nil +} + +func (s *streamPool) readPeerLoop(peerId string, stream spacesyncproto.SpaceStream) (err error) { + defer s.wg.Done() + limiter := make(chan struct{}, maxSimultaneousOperationsPerStream) + for i := 0; i < maxSimultaneousOperationsPerStream; i++ { + limiter <- struct{}{} + } + + process := func(msg *spacesyncproto.ObjectSyncMessage) { + s.lastUsage.Store(time.Now().Unix()) + if msg.ReplyId == "" { + s.messageHandler(stream.Context(), peerId, msg) + return + } + log.With("replyId", msg.ReplyId).Debug("getting message with reply id") + s.waitersMx.Lock() + waiter, exists := s.waiters[msg.ReplyId] + + if !exists { + log.With("replyId", msg.ReplyId).Debug("reply id not exists") + s.waitersMx.Unlock() + s.messageHandler(stream.Context(), peerId, msg) + return + } + log.With("replyId", msg.ReplyId).Debug("reply id exists") + + delete(s.waiters, msg.ReplyId) + s.waitersMx.Unlock() + waiter.ch <- msg + } + +Loop: + for { + var msg *spacesyncproto.ObjectSyncMessage + msg, err = stream.Recv() + s.lastUsage.Store(time.Now().Unix()) + if err != nil { + break + } + select { + case <-limiter: + case <-stream.Context().Done(): + break Loop + } + go func() { + process(msg) + limiter <- struct{}{} + }() + } + log.With("peerId", peerId).Debug("stopped reading stream from peer") + s.removePeer(peerId) + return +} + +func (s *streamPool) removePeer(peerId string) (err error) { + s.Lock() + defer s.Unlock() + _, ok := s.peerStreams[peerId] + if !ok { + return ErrEmptyPeer + } + delete(s.peerStreams, peerId) + return +} + +func genStreamPoolKey(peerId, treeId string, counter uint64) string { + return fmt.Sprintf("%s.%s.%d", peerId, treeId, counter) +} diff --git a/common/commonspace/syncservice/streampool_test.go b/common/commonspace/syncservice/streampool_test.go new file mode 100644 index 00000000..2d2ff512 --- /dev/null +++ b/common/commonspace/syncservice/streampool_test.go @@ -0,0 +1,325 @@ +package syncservice + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/peer" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/rpc/rpctest" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto" + "github.com/stretchr/testify/require" + "testing" + "time" +) + +type testServer struct { + stream chan spacesyncproto.DRPCSpace_StreamStream + addLog func(ctx context.Context, req *consensusproto.AddLogRequest) error + addRecord func(ctx context.Context, req *consensusproto.AddRecordRequest) error + releaseStream chan error + watchErrOnce bool +} + +func (t *testServer) HeadSync(ctx context.Context, request *spacesyncproto.HeadSyncRequest) (*spacesyncproto.HeadSyncResponse, error) { + panic("implement me") +} + +func (t *testServer) PushSpace(ctx context.Context, request *spacesyncproto.PushSpaceRequest) (*spacesyncproto.PushSpaceResponse, error) { + panic("implement me") +} + +func (t *testServer) PullSpace(ctx context.Context, request *spacesyncproto.PullSpaceRequest) (*spacesyncproto.PullSpaceResponse, error) { + panic("implement me") +} + +func (t *testServer) Stream(stream spacesyncproto.DRPCSpace_StreamStream) error { + t.stream <- stream + return <-t.releaseStream +} + +func (t *testServer) waitStream(test *testing.T) spacesyncproto.DRPCSpace_StreamStream { + select { + case <-time.After(time.Second * 5): + test.Fatalf("waiteStream timeout") + case st := <-t.stream: + return st + } + return nil +} + +type fixture struct { + testServer *testServer + drpcTS *rpctest.TesServer + client spacesyncproto.DRPCSpaceClient + clientStream spacesyncproto.DRPCSpace_StreamStream + serverStream spacesyncproto.DRPCSpace_StreamStream + pool *streamPool + clientId string + serverId string +} + +func newFixture(t *testing.T, clientId, serverId string, handler MessageHandler) *fixture { + fx := &fixture{ + testServer: &testServer{}, + drpcTS: rpctest.NewTestServer(), + clientId: clientId, + serverId: serverId, + } + fx.testServer.stream = make(chan spacesyncproto.DRPCSpace_StreamStream, 1) + require.NoError(t, spacesyncproto.DRPCRegisterSpace(fx.drpcTS.Mux, fx.testServer)) + fx.client = spacesyncproto.NewDRPCSpaceClient(fx.drpcTS.Dial(peer.CtxWithPeerId(context.Background(), clientId))) + + var err error + fx.clientStream, err = fx.client.Stream(peer.CtxWithPeerId(context.Background(), serverId)) + require.NoError(t, err) + fx.serverStream = fx.testServer.waitStream(t) + fx.pool = newStreamPool(handler).(*streamPool) + + return fx +} + +func (fx *fixture) run(t *testing.T) chan error { + waitCh := make(chan error) + go func() { + err := fx.pool.AddAndReadStreamSync(fx.clientStream) + waitCh <- err + }() + + time.Sleep(time.Millisecond * 10) + fx.pool.Lock() + require.Equal(t, fx.pool.peerStreams[fx.serverId], fx.clientStream) + fx.pool.Unlock() + + return waitCh +} + +func TestStreamPool_AddAndReadStreamAsync(t *testing.T) { + remId := "remoteId" + + t.Run("client close", func(t *testing.T) { + fx := newFixture(t, "", remId, nil) + waitCh := fx.run(t) + + err := fx.clientStream.Close() + require.NoError(t, err) + err = <-waitCh + + require.Error(t, err) + require.Nil(t, fx.pool.peerStreams[remId]) + }) + t.Run("server close", func(t *testing.T) { + fx := newFixture(t, "", remId, nil) + waitCh := fx.run(t) + + err := fx.serverStream.Close() + require.NoError(t, err) + + err = <-waitCh + require.Error(t, err) + require.Nil(t, fx.pool.peerStreams[remId]) + }) +} + +func TestStreamPool_Close(t *testing.T) { + remId := "remoteId" + + t.Run("client close", func(t *testing.T) { + fx := newFixture(t, "", remId, nil) + fx.run(t) + var events []string + recvChan := make(chan struct{}) + go func() { + fx.pool.Close() + events = append(events, "pool_close") + recvChan <- struct{}{} + }() + time.Sleep(50 * time.Millisecond) //err = <-waitCh + events = append(events, "stream_close") + err := fx.clientStream.Close() + require.NoError(t, err) + <-recvChan + require.Equal(t, []string{"stream_close", "pool_close"}, events) + }) + t.Run("server close", func(t *testing.T) { + fx := newFixture(t, "", remId, nil) + fx.run(t) + var events []string + recvChan := make(chan struct{}) + go func() { + fx.pool.Close() + events = append(events, "pool_close") + recvChan <- struct{}{} + }() + time.Sleep(50 * time.Millisecond) //err = <-waitCh + events = append(events, "stream_close") + err := fx.clientStream.Close() + require.NoError(t, err) + <-recvChan + require.Equal(t, []string{"stream_close", "pool_close"}, events) + }) +} + +func TestStreamPool_ReceiveMessage(t *testing.T) { + remId := "remoteId" + t.Run("pool receive message from server", func(t *testing.T) { + objectId := "objectId" + msg := &spacesyncproto.ObjectSyncMessage{ + ObjectId: objectId, + } + recvChan := make(chan struct{}) + fx := newFixture(t, "", remId, func(ctx context.Context, senderId string, message *spacesyncproto.ObjectSyncMessage) (err error) { + require.Equal(t, msg, message) + recvChan <- struct{}{} + return nil + }) + waitCh := fx.run(t) + + err := fx.serverStream.Send(msg) + require.NoError(t, err) + <-recvChan + err = fx.clientStream.Close() + require.NoError(t, err) + err = <-waitCh + + require.Error(t, err) + require.Nil(t, fx.pool.peerStreams[remId]) + }) +} + +func TestStreamPool_HasActiveStream(t *testing.T) { + remId := "remoteId" + t.Run("pool has active stream", func(t *testing.T) { + fx := newFixture(t, "", remId, nil) + waitCh := fx.run(t) + require.True(t, fx.pool.HasActiveStream(remId)) + + err := fx.clientStream.Close() + require.NoError(t, err) + err = <-waitCh + + require.Error(t, err) + require.Nil(t, fx.pool.peerStreams[remId]) + }) + t.Run("pool has no active stream", func(t *testing.T) { + fx := newFixture(t, "", remId, nil) + waitCh := fx.run(t) + err := fx.clientStream.Close() + require.NoError(t, err) + err = <-waitCh + require.Error(t, err) + require.False(t, fx.pool.HasActiveStream(remId)) + require.Nil(t, fx.pool.peerStreams[remId]) + }) +} + +func TestStreamPool_SendAsync(t *testing.T) { + remId := "remoteId" + t.Run("pool send async to server", func(t *testing.T) { + objectId := "objectId" + msg := &spacesyncproto.ObjectSyncMessage{ + ObjectId: objectId, + } + fx := newFixture(t, "", remId, nil) + recvChan := make(chan struct{}) + go func() { + message, err := fx.serverStream.Recv() + require.NoError(t, err) + require.Equal(t, msg, message) + recvChan <- struct{}{} + }() + waitCh := fx.run(t) + + err := fx.pool.SendAsync([]string{remId}, msg) + require.NoError(t, err) + <-recvChan + err = fx.clientStream.Close() + require.NoError(t, err) + err = <-waitCh + + require.Error(t, err) + require.Nil(t, fx.pool.peerStreams[remId]) + }) +} + +func TestStreamPool_SendSync(t *testing.T) { + remId := "remoteId" + t.Run("pool send sync to server", func(t *testing.T) { + objectId := "objectId" + payload := []byte("payload") + msg := &spacesyncproto.ObjectSyncMessage{ + ObjectId: objectId, + } + fx := newFixture(t, "", remId, nil) + go func() { + message, err := fx.serverStream.Recv() + require.NoError(t, err) + require.Equal(t, msg.ObjectId, message.ObjectId) + require.NotEmpty(t, message.ReplyId) + message.Payload = payload + err = fx.serverStream.Send(message) + require.NoError(t, err) + }() + waitCh := fx.run(t) + res, err := fx.pool.SendSync(remId, msg) + require.NoError(t, err) + require.Equal(t, payload, res.Payload) + err = fx.clientStream.Close() + require.NoError(t, err) + err = <-waitCh + + require.Error(t, err) + require.Nil(t, fx.pool.peerStreams[remId]) + }) + + t.Run("pool send sync timeout", func(t *testing.T) { + objectId := "objectId" + msg := &spacesyncproto.ObjectSyncMessage{ + ObjectId: objectId, + } + fx := newFixture(t, "", remId, nil) + syncWaitPeriod = time.Millisecond * 30 + go func() { + message, err := fx.serverStream.Recv() + require.NoError(t, err) + require.Equal(t, msg.ObjectId, message.ObjectId) + require.NotEmpty(t, message.ReplyId) + }() + waitCh := fx.run(t) + _, err := fx.pool.SendSync(remId, msg) + require.Equal(t, ErrSyncTimeout, err) + err = fx.clientStream.Close() + require.NoError(t, err) + err = <-waitCh + + require.Error(t, err) + require.Nil(t, fx.pool.peerStreams[remId]) + }) +} + +func TestStreamPool_BroadcastAsync(t *testing.T) { + remId := "remoteId" + t.Run("pool broadcast async to server", func(t *testing.T) { + objectId := "objectId" + msg := &spacesyncproto.ObjectSyncMessage{ + ObjectId: objectId, + } + fx := newFixture(t, "", remId, nil) + recvChan := make(chan struct{}) + go func() { + message, err := fx.serverStream.Recv() + require.NoError(t, err) + require.Equal(t, msg, message) + recvChan <- struct{}{} + }() + waitCh := fx.run(t) + + err := fx.pool.BroadcastAsync(msg) + require.NoError(t, err) + <-recvChan + err = fx.clientStream.Close() + require.NoError(t, err) + err = <-waitCh + + require.Error(t, err) + require.Nil(t, fx.pool.peerStreams[remId]) + }) +} diff --git a/common/commonspace/syncservice/synchandler/synchhandler.go b/common/commonspace/syncservice/synchandler/synchhandler.go new file mode 100644 index 00000000..e6bed4bf --- /dev/null +++ b/common/commonspace/syncservice/synchandler/synchhandler.go @@ -0,0 +1,10 @@ +package synchandler + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" +) + +type SyncHandler interface { + HandleMessage(ctx context.Context, senderId string, request *spacesyncproto.ObjectSyncMessage) (err error) +} diff --git a/common/commonspace/syncservice/syncservice.go b/common/commonspace/syncservice/syncservice.go new file mode 100644 index 00000000..983f5698 --- /dev/null +++ b/common/commonspace/syncservice/syncservice.go @@ -0,0 +1,138 @@ +package syncservice + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/objectgetter" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice/synchandler" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/rpc/rpcerr" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ocache" + "time" +) + +var log = logger.NewNamed("syncservice").Sugar() + +type SyncService interface { + ocache.ObjectLastUsage + synchandler.SyncHandler + StreamPool() StreamPool + + Init(getter objectgetter.ObjectGetter) + Close() (err error) +} + +const respPeersStreamCheckInterval = time.Second * 10 + +type syncService struct { + spaceId string + + streamPool StreamPool + clientFactory spacesyncproto.ClientFactory + objectGetter objectgetter.ObjectGetter + + streamLoopCtx context.Context + stopStreamLoop context.CancelFunc + connector nodeconf.ConfConnector + streamLoopDone chan struct{} +} + +func NewSyncService( + spaceId string, + confConnector nodeconf.ConfConnector) (syncService SyncService) { + streamPool := newStreamPool(func(ctx context.Context, senderId string, message *spacesyncproto.ObjectSyncMessage) (err error) { + return syncService.HandleMessage(ctx, senderId, message) + }) + syncService = newSyncService( + spaceId, + streamPool, + spacesyncproto.ClientFactoryFunc(spacesyncproto.NewDRPCSpaceClient), + confConnector) + return +} + +func newSyncService( + spaceId string, + streamPool StreamPool, + clientFactory spacesyncproto.ClientFactory, + connector nodeconf.ConfConnector) *syncService { + return &syncService{ + streamPool: streamPool, + connector: connector, + clientFactory: clientFactory, + spaceId: spaceId, + streamLoopDone: make(chan struct{}), + } +} + +func (s *syncService) Init(objectGetter objectgetter.ObjectGetter) { + s.objectGetter = objectGetter + s.streamLoopCtx, s.stopStreamLoop = context.WithCancel(context.Background()) + go s.responsibleStreamCheckLoop(s.streamLoopCtx) +} + +func (s *syncService) Close() (err error) { + s.stopStreamLoop() + <-s.streamLoopDone + return s.streamPool.Close() +} + +func (s *syncService) LastUsage() time.Time { + return s.streamPool.LastUsage() +} + +func (s *syncService) HandleMessage(ctx context.Context, senderId string, message *spacesyncproto.ObjectSyncMessage) (err error) { + obj, err := s.objectGetter.GetObject(ctx, message.ObjectId) + if err != nil { + return + } + return obj.HandleMessage(ctx, senderId, message) +} + +func (s *syncService) responsibleStreamCheckLoop(ctx context.Context) { + defer close(s.streamLoopDone) + checkResponsiblePeers := func() { + respPeers, err := s.connector.DialResponsiblePeers(ctx, s.spaceId) + if err != nil { + return + } + for _, p := range respPeers { + if s.streamPool.HasActiveStream(p.Id()) { + continue + } + stream, err := s.clientFactory.Client(p).Stream(ctx) + if err != nil { + err = rpcerr.Unwrap(err) + log.With("spaceId", s.spaceId).Errorf("failed to open stream: %v", err) + // so here probably the request is failed because there is no such space, + // but diffService should handle such cases by sending pushSpace + continue + } + // sending empty message for the server to understand from which space is it coming + err = stream.Send(&spacesyncproto.ObjectSyncMessage{SpaceId: s.spaceId}) + if err != nil { + err = rpcerr.Unwrap(err) + log.With("spaceId", s.spaceId).Errorf("failed to send first message to stream: %v", err) + continue + } + s.streamPool.AddAndReadStreamAsync(stream) + } + } + + checkResponsiblePeers() + ticker := time.NewTicker(respPeersStreamCheckInterval) + defer ticker.Stop() + for { + select { + case <-s.streamLoopCtx.Done(): + return + case <-ticker.C: + checkResponsiblePeers() + } + } +} + +func (s *syncService) StreamPool() StreamPool { + return s.streamPool +} diff --git a/common/commonspace/synctree/mock_synctree/mock_synctree.go b/common/commonspace/synctree/mock_synctree/mock_synctree.go new file mode 100644 index 00000000..914a6ec1 --- /dev/null +++ b/common/commonspace/synctree/mock_synctree/mock_synctree.go @@ -0,0 +1,136 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree (interfaces: SyncClient) + +// Package mock_synctree is a generated GoMock package. +package mock_synctree + +import ( + reflect "reflect" + + tree "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree" + treechangeproto "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto" + gomock "github.com/golang/mock/gomock" +) + +// MockSyncClient is a mock of SyncClient interface. +type MockSyncClient struct { + ctrl *gomock.Controller + recorder *MockSyncClientMockRecorder +} + +// MockSyncClientMockRecorder is the mock recorder for MockSyncClient. +type MockSyncClientMockRecorder struct { + mock *MockSyncClient +} + +// NewMockSyncClient creates a new mock instance. +func NewMockSyncClient(ctrl *gomock.Controller) *MockSyncClient { + mock := &MockSyncClient{ctrl: ctrl} + mock.recorder = &MockSyncClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockSyncClient) EXPECT() *MockSyncClientMockRecorder { + return m.recorder +} + +// BroadcastAsync mocks base method. +func (m *MockSyncClient) BroadcastAsync(arg0 *treechangeproto.TreeSyncMessage) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BroadcastAsync", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// BroadcastAsync indicates an expected call of BroadcastAsync. +func (mr *MockSyncClientMockRecorder) BroadcastAsync(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BroadcastAsync", reflect.TypeOf((*MockSyncClient)(nil).BroadcastAsync), arg0) +} + +// BroadcastAsyncOrSendResponsible mocks base method. +func (m *MockSyncClient) BroadcastAsyncOrSendResponsible(arg0 *treechangeproto.TreeSyncMessage) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BroadcastAsyncOrSendResponsible", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// BroadcastAsyncOrSendResponsible indicates an expected call of BroadcastAsyncOrSendResponsible. +func (mr *MockSyncClientMockRecorder) BroadcastAsyncOrSendResponsible(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BroadcastAsyncOrSendResponsible", reflect.TypeOf((*MockSyncClient)(nil).BroadcastAsyncOrSendResponsible), arg0) +} + +// CreateFullSyncRequest mocks base method. +func (m *MockSyncClient) CreateFullSyncRequest(arg0 tree.ObjectTree, arg1, arg2 []string) (*treechangeproto.TreeSyncMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateFullSyncRequest", arg0, arg1, arg2) + ret0, _ := ret[0].(*treechangeproto.TreeSyncMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateFullSyncRequest indicates an expected call of CreateFullSyncRequest. +func (mr *MockSyncClientMockRecorder) CreateFullSyncRequest(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateFullSyncRequest", reflect.TypeOf((*MockSyncClient)(nil).CreateFullSyncRequest), arg0, arg1, arg2) +} + +// CreateFullSyncResponse mocks base method. +func (m *MockSyncClient) CreateFullSyncResponse(arg0 tree.ObjectTree, arg1, arg2 []string) (*treechangeproto.TreeSyncMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateFullSyncResponse", arg0, arg1, arg2) + ret0, _ := ret[0].(*treechangeproto.TreeSyncMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateFullSyncResponse indicates an expected call of CreateFullSyncResponse. +func (mr *MockSyncClientMockRecorder) CreateFullSyncResponse(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateFullSyncResponse", reflect.TypeOf((*MockSyncClient)(nil).CreateFullSyncResponse), arg0, arg1, arg2) +} + +// CreateHeadUpdate mocks base method. +func (m *MockSyncClient) CreateHeadUpdate(arg0 tree.ObjectTree, arg1 []*treechangeproto.RawTreeChangeWithId) *treechangeproto.TreeSyncMessage { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateHeadUpdate", arg0, arg1) + ret0, _ := ret[0].(*treechangeproto.TreeSyncMessage) + return ret0 +} + +// CreateHeadUpdate indicates an expected call of CreateHeadUpdate. +func (mr *MockSyncClientMockRecorder) CreateHeadUpdate(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateHeadUpdate", reflect.TypeOf((*MockSyncClient)(nil).CreateHeadUpdate), arg0, arg1) +} + +// CreateNewTreeRequest mocks base method. +func (m *MockSyncClient) CreateNewTreeRequest() *treechangeproto.TreeSyncMessage { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateNewTreeRequest") + ret0, _ := ret[0].(*treechangeproto.TreeSyncMessage) + return ret0 +} + +// CreateNewTreeRequest indicates an expected call of CreateNewTreeRequest. +func (mr *MockSyncClientMockRecorder) CreateNewTreeRequest() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateNewTreeRequest", reflect.TypeOf((*MockSyncClient)(nil).CreateNewTreeRequest)) +} + +// SendAsync mocks base method. +func (m *MockSyncClient) SendAsync(arg0 string, arg1 *treechangeproto.TreeSyncMessage, arg2 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SendAsync", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// SendAsync indicates an expected call of SendAsync. +func (mr *MockSyncClientMockRecorder) SendAsync(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendAsync", reflect.TypeOf((*MockSyncClient)(nil).SendAsync), arg0, arg1, arg2) +} diff --git a/common/commonspace/synctree/requestfactory.go b/common/commonspace/synctree/requestfactory.go new file mode 100644 index 00000000..b66a2689 --- /dev/null +++ b/common/commonspace/synctree/requestfactory.go @@ -0,0 +1,74 @@ +package synctree + +import ( + "fmt" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/slice" +) + +type RequestFactory interface { + CreateHeadUpdate(t tree.ObjectTree, added []*treechangeproto.RawTreeChangeWithId) (msg *treechangeproto.TreeSyncMessage) + CreateNewTreeRequest() (msg *treechangeproto.TreeSyncMessage) + CreateFullSyncRequest(t tree.ObjectTree, theirHeads, theirSnapshotPath []string) (req *treechangeproto.TreeSyncMessage, err error) + CreateFullSyncResponse(t tree.ObjectTree, theirHeads, theirSnapshotPath []string) (*treechangeproto.TreeSyncMessage, error) +} + +var sharedFactory = &requestFactory{} + +func GetRequestFactory() RequestFactory { + return sharedFactory +} + +type requestFactory struct{} + +func (r *requestFactory) CreateHeadUpdate(t tree.ObjectTree, added []*treechangeproto.RawTreeChangeWithId) (msg *treechangeproto.TreeSyncMessage) { + return treechangeproto.WrapHeadUpdate(&treechangeproto.TreeHeadUpdate{ + Heads: t.Heads(), + Changes: added, + SnapshotPath: t.SnapshotPath(), + }, t.Header()) +} + +func (r *requestFactory) CreateNewTreeRequest() (msg *treechangeproto.TreeSyncMessage) { + return treechangeproto.WrapFullRequest(&treechangeproto.TreeFullSyncRequest{}, nil) +} + +func (r *requestFactory) CreateFullSyncRequest(t tree.ObjectTree, theirHeads, theirSnapshotPath []string) (msg *treechangeproto.TreeSyncMessage, err error) { + req := &treechangeproto.TreeFullSyncRequest{} + if t == nil { + return nil, fmt.Errorf("tree should not be empty") + } + + req.Heads = t.Heads() + req.SnapshotPath = t.SnapshotPath() + + var changesAfterSnapshot []*treechangeproto.RawTreeChangeWithId + changesAfterSnapshot, err = t.ChangesAfterCommonSnapshot(theirSnapshotPath, theirHeads) + if err != nil { + return + } + + req.Changes = changesAfterSnapshot + msg = treechangeproto.WrapFullRequest(req, t.Header()) + return +} + +func (r *requestFactory) CreateFullSyncResponse(t tree.ObjectTree, theirHeads, theirSnapshotPath []string) (msg *treechangeproto.TreeSyncMessage, err error) { + resp := &treechangeproto.TreeFullSyncResponse{ + Heads: t.Heads(), + SnapshotPath: t.SnapshotPath(), + } + if slice.UnsortedEquals(theirHeads, t.Heads()) { + msg = treechangeproto.WrapFullResponse(resp, t.Header()) + return + } + + ourChanges, err := t.ChangesAfterCommonSnapshot(theirSnapshotPath, theirHeads) + if err != nil { + return + } + resp.Changes = ourChanges + msg = treechangeproto.WrapFullResponse(resp, t.Header()) + return +} diff --git a/common/commonspace/synctree/syncclient.go b/common/commonspace/synctree/syncclient.go new file mode 100644 index 00000000..d8a721ec --- /dev/null +++ b/common/commonspace/synctree/syncclient.go @@ -0,0 +1,89 @@ +//go:generate mockgen -destination mock_synctree/mock_synctree.go github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree SyncClient +package synctree + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/diffservice" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto" +) + +type SyncClient interface { + RequestFactory + BroadcastAsync(message *treechangeproto.TreeSyncMessage) (err error) + BroadcastAsyncOrSendResponsible(message *treechangeproto.TreeSyncMessage) (err error) + SendAsync(peerId string, message *treechangeproto.TreeSyncMessage, replyId string) (err error) +} + +type syncClient struct { + syncservice.StreamPool + RequestFactory + spaceId string + notifiable diffservice.HeadNotifiable + configuration nodeconf.Configuration +} + +func newSyncClient( + spaceId string, + pool syncservice.StreamPool, + notifiable diffservice.HeadNotifiable, + factory RequestFactory, + configuration nodeconf.Configuration) SyncClient { + return &syncClient{ + StreamPool: pool, + RequestFactory: factory, + notifiable: notifiable, + configuration: configuration, + spaceId: spaceId, + } +} + +func (s *syncClient) BroadcastAsync(message *treechangeproto.TreeSyncMessage) (err error) { + s.notifyIfNeeded(message) + objMsg, err := marshallTreeMessage(message, message.RootChange.Id, "") + if err != nil { + return + } + return s.StreamPool.BroadcastAsync(objMsg) +} + +func (s *syncClient) SendAsync(peerId string, message *treechangeproto.TreeSyncMessage, replyId string) (err error) { + objMsg, err := marshallTreeMessage(message, message.RootChange.Id, replyId) + if err != nil { + return + } + return s.StreamPool.SendAsync([]string{peerId}, objMsg) +} + +func (s *syncClient) BroadcastAsyncOrSendResponsible(message *treechangeproto.TreeSyncMessage) (err error) { + s.notifyIfNeeded(message) + objMsg, err := marshallTreeMessage(message, message.RootChange.Id, "") + if err != nil { + return + } + if s.configuration.IsResponsible(s.spaceId) { + return s.StreamPool.SendAsync(s.configuration.NodeIds(s.spaceId), objMsg) + } + return s.BroadcastAsync(message) +} + +func (s *syncClient) notifyIfNeeded(message *treechangeproto.TreeSyncMessage) { + if message.GetContent().GetHeadUpdate() != nil { + update := message.GetContent().GetHeadUpdate() + s.notifiable.UpdateHeads(message.RootChange.Id, update.Heads) + } +} + +func marshallTreeMessage(message *treechangeproto.TreeSyncMessage, id, replyId string) (objMsg *spacesyncproto.ObjectSyncMessage, err error) { + payload, err := message.Marshal() + if err != nil { + return + } + objMsg = &spacesyncproto.ObjectSyncMessage{ + ReplyId: replyId, + Payload: payload, + ObjectId: id, + } + return +} diff --git a/common/commonspace/synctree/synctree.go b/common/commonspace/synctree/synctree.go new file mode 100644 index 00000000..c3d09d96 --- /dev/null +++ b/common/commonspace/synctree/synctree.go @@ -0,0 +1,257 @@ +package synctree + +import ( + "context" + "errors" + "fmt" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/diffservice" + spacestorage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice/synchandler" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree/updatelistener" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/peer" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/list" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto" + "github.com/gogo/protobuf/proto" + "go.uber.org/zap" +) + +var ErrSyncTreeClosed = errors.New("sync tree is closed") + +// SyncTree sends head updates to sync service and also sends new changes to update listener +type SyncTree struct { + tree.ObjectTree + synchandler.SyncHandler + syncClient SyncClient + listener updatelistener.UpdateListener + isClosed bool +} + +var log = logger.NewNamed("commonspace.synctree").Sugar() + +var createDerivedObjectTree = tree.CreateDerivedObjectTree +var createObjectTree = tree.CreateObjectTree +var buildObjectTree = tree.BuildObjectTree +var createSyncClient = newSyncClient + +type CreateDeps struct { + SpaceId string + Payload tree.ObjectTreeCreatePayload + Configuration nodeconf.Configuration + HeadNotifiable diffservice.HeadNotifiable + StreamPool syncservice.StreamPool + Listener updatelistener.UpdateListener + AclList list.ACLList + CreateStorage storage.TreeStorageCreatorFunc +} + +type BuildDeps struct { + SpaceId string + StreamPool syncservice.StreamPool + Configuration nodeconf.Configuration + HeadNotifiable diffservice.HeadNotifiable + Listener updatelistener.UpdateListener + AclList list.ACLList + SpaceStorage spacestorage.SpaceStorage + TreeStorage storage.TreeStorage +} + +func DeriveSyncTree(ctx context.Context, deps CreateDeps) (t tree.ObjectTree, err error) { + t, err = createDerivedObjectTree(deps.Payload, deps.AclList, deps.CreateStorage) + if err != nil { + return + } + syncClient := createSyncClient( + deps.SpaceId, + deps.StreamPool, + deps.HeadNotifiable, + sharedFactory, + deps.Configuration) + syncTree := &SyncTree{ + ObjectTree: t, + syncClient: syncClient, + listener: deps.Listener, + } + syncHandler := newSyncTreeHandler(syncTree, syncClient) + syncTree.SyncHandler = syncHandler + t = syncTree + + headUpdate := syncClient.CreateHeadUpdate(t, nil) + err = syncClient.BroadcastAsync(headUpdate) + return +} + +func CreateSyncTree(ctx context.Context, deps CreateDeps) (t tree.ObjectTree, err error) { + t, err = createObjectTree(deps.Payload, deps.AclList, deps.CreateStorage) + if err != nil { + return + } + syncClient := createSyncClient( + deps.SpaceId, + deps.StreamPool, + deps.HeadNotifiable, + GetRequestFactory(), + deps.Configuration) + syncTree := &SyncTree{ + ObjectTree: t, + syncClient: syncClient, + listener: deps.Listener, + } + syncHandler := newSyncTreeHandler(syncTree, syncClient) + syncTree.SyncHandler = syncHandler + t = syncTree + + headUpdate := syncClient.CreateHeadUpdate(t, nil) + err = syncClient.BroadcastAsync(headUpdate) + return +} + +func BuildSyncTreeOrGetRemote(ctx context.Context, id string, deps BuildDeps) (t tree.ObjectTree, err error) { + getTreeRemote := func() (msg *treechangeproto.TreeSyncMessage, err error) { + peerId, err := peer.CtxPeerId(ctx) + if err != nil { + return + } + newTreeRequest := GetRequestFactory().CreateNewTreeRequest() + objMsg, err := marshallTreeMessage(newTreeRequest, id, "") + if err != nil { + return + } + + resp, err := deps.StreamPool.SendSync(peerId, objMsg) + if err != nil { + return + } + msg = &treechangeproto.TreeSyncMessage{} + err = proto.Unmarshal(resp.Payload, msg) + return + } + + deps.TreeStorage, err = deps.SpaceStorage.TreeStorage(id) + if err == nil { + return buildSyncTree(ctx, false, deps) + } + + if err != nil && err != storage.ErrUnknownTreeId { + return + } + + resp, err := getTreeRemote() + if err != nil { + return + } + if resp.GetContent().GetFullSyncResponse() == nil { + err = fmt.Errorf("expected to get full sync response, but got something else") + return + } + fullSyncResp := resp.GetContent().GetFullSyncResponse() + + payload := storage.TreeStorageCreatePayload{ + RootRawChange: resp.RootChange, + Changes: fullSyncResp.Changes, + Heads: fullSyncResp.Heads, + } + + // basically building tree with in-memory storage and validating that it was without errors + log.With(zap.String("id", id)).Debug("validating tree") + err = tree.ValidateRawTree(payload, deps.AclList) + if err != nil { + return + } + // now we are sure that we can save it to the storage + deps.TreeStorage, err = deps.SpaceStorage.CreateTreeStorage(payload) + if err != nil { + return + } + return buildSyncTree(ctx, true, deps) +} + +func buildSyncTree(ctx context.Context, isFirstBuild bool, deps BuildDeps) (t tree.ObjectTree, err error) { + + t, err = buildObjectTree(deps.TreeStorage, deps.AclList) + if err != nil { + return + } + syncClient := createSyncClient( + deps.SpaceId, + deps.StreamPool, + deps.HeadNotifiable, + GetRequestFactory(), + deps.Configuration) + syncTree := &SyncTree{ + ObjectTree: t, + syncClient: syncClient, + listener: deps.Listener, + } + syncHandler := newSyncTreeHandler(syncTree, syncClient) + syncTree.SyncHandler = syncHandler + t = syncTree + + headUpdate := syncTree.syncClient.CreateHeadUpdate(t, nil) + // here we will have different behaviour based on who is sending this update + if isFirstBuild { + // send to everybody, because everybody should know that the node or client got new tree + err = syncTree.syncClient.BroadcastAsync(headUpdate) + } else { + // send either to everybody if client or to replica set if node + err = syncTree.syncClient.BroadcastAsyncOrSendResponsible(headUpdate) + } + return +} + +func (s *SyncTree) AddContent(ctx context.Context, content tree.SignableChangeContent) (res tree.AddResult, err error) { + if s.isClosed { + err = ErrSyncTreeClosed + return + } + res, err = s.ObjectTree.AddContent(ctx, content) + if err != nil { + return + } + headUpdate := s.syncClient.CreateHeadUpdate(s, res.Added) + err = s.syncClient.BroadcastAsync(headUpdate) + return +} + +func (s *SyncTree) AddRawChanges(ctx context.Context, changes ...*treechangeproto.RawTreeChangeWithId) (res tree.AddResult, err error) { + if s.isClosed { + err = ErrSyncTreeClosed + return + } + res, err = s.ObjectTree.AddRawChanges(ctx, changes...) + if err != nil { + return + } + if s.listener != nil { + switch res.Mode { + case tree.Nothing: + return + case tree.Append: + s.listener.Update(s) + case tree.Rebuild: + s.listener.Rebuild(s) + } + } + //if res.Mode != tree.Nothing { + headUpdate := s.syncClient.CreateHeadUpdate(s, res.Added) + err = s.syncClient.BroadcastAsync(headUpdate) + //} + return +} + +func (s *SyncTree) Close() (err error) { + log.With("id", s.ID()).Debug("closing sync tree") + s.Lock() + defer s.Unlock() + log.With("id", s.ID()).Debug("taken lock on sync tree") + if s.isClosed { + err = ErrSyncTreeClosed + return + } + s.isClosed = true + return +} diff --git a/common/commonspace/synctree/synctree_test.go b/common/commonspace/synctree/synctree_test.go new file mode 100644 index 00000000..95a3436a --- /dev/null +++ b/common/commonspace/synctree/synctree_test.go @@ -0,0 +1,179 @@ +package synctree + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/diffservice" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree/mock_synctree" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree/updatelistener" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree/updatelistener/mock_updatelistener" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/list" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/list/mock_list" + storage2 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage" + tree "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree/mock_objecttree" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + "testing" +) + +type syncTreeMatcher struct { + objTree tree.ObjectTree + client SyncClient + listener updatelistener.UpdateListener +} + +func (s syncTreeMatcher) Matches(x interface{}) bool { + t, ok := x.(*SyncTree) + if !ok { + return false + } + return s.objTree == t.ObjectTree && t.syncClient == s.client && t.listener == s.listener +} + +func (s syncTreeMatcher) String() string { + return "" +} + +func Test_DeriveSyncTree(t *testing.T) { + ctx := context.Background() + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + updateListenerMock := mock_updatelistener.NewMockUpdateListener(ctrl) + syncClientMock := mock_synctree.NewMockSyncClient(ctrl) + aclListMock := mock_list.NewMockACLList(ctrl) + objTreeMock := mock_tree.NewMockObjectTree(ctrl) + spaceId := "spaceId" + expectedPayload := tree.ObjectTreeCreatePayload{SpaceId: spaceId} + createDerivedObjectTree = func(payload tree.ObjectTreeCreatePayload, l list.ACLList, create storage2.TreeStorageCreatorFunc) (objTree tree.ObjectTree, err error) { + require.Equal(t, l, aclListMock) + require.Equal(t, expectedPayload, payload) + return objTreeMock, nil + } + createSyncClient = func(spaceId string, pool syncservice.StreamPool, notifiable diffservice.HeadNotifiable, factory RequestFactory, configuration nodeconf.Configuration) SyncClient { + return syncClientMock + } + headUpdate := &treechangeproto.TreeSyncMessage{} + syncClientMock.EXPECT().CreateHeadUpdate(syncTreeMatcher{objTreeMock, syncClientMock, updateListenerMock}, gomock.Nil()).Return(headUpdate) + syncClientMock.EXPECT().BroadcastAsync(gomock.Eq(headUpdate)).Return(nil) + deps := CreateDeps{AclList: aclListMock, SpaceId: spaceId, Payload: expectedPayload, Listener: updateListenerMock} + + _, err := DeriveSyncTree(ctx, deps) + require.NoError(t, err) +} + +func Test_CreateSyncTree(t *testing.T) { + ctx := context.Background() + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + updateListenerMock := mock_updatelistener.NewMockUpdateListener(ctrl) + syncClientMock := mock_synctree.NewMockSyncClient(ctrl) + aclListMock := mock_list.NewMockACLList(ctrl) + objTreeMock := mock_tree.NewMockObjectTree(ctrl) + spaceId := "spaceId" + expectedPayload := tree.ObjectTreeCreatePayload{SpaceId: spaceId} + createObjectTree = func(payload tree.ObjectTreeCreatePayload, l list.ACLList, create storage2.TreeStorageCreatorFunc) (objTree tree.ObjectTree, err error) { + require.Equal(t, l, aclListMock) + require.Equal(t, expectedPayload, payload) + return objTreeMock, nil + } + createSyncClient = func(spaceId string, pool syncservice.StreamPool, notifiable diffservice.HeadNotifiable, factory RequestFactory, configuration nodeconf.Configuration) SyncClient { + return syncClientMock + } + headUpdate := &treechangeproto.TreeSyncMessage{} + syncClientMock.EXPECT().CreateHeadUpdate(syncTreeMatcher{objTreeMock, syncClientMock, updateListenerMock}, gomock.Nil()).Return(headUpdate) + syncClientMock.EXPECT().BroadcastAsync(gomock.Eq(headUpdate)).Return(nil) + deps := CreateDeps{AclList: aclListMock, SpaceId: spaceId, Payload: expectedPayload, Listener: updateListenerMock} + + _, err := CreateSyncTree(ctx, deps) + require.NoError(t, err) +} + +func Test_BuildSyncTree(t *testing.T) { + ctx := context.Background() + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + updateListenerMock := mock_updatelistener.NewMockUpdateListener(ctrl) + syncClientMock := mock_synctree.NewMockSyncClient(ctrl) + objTreeMock := mock_tree.NewMockObjectTree(ctrl) + tr := &SyncTree{ + ObjectTree: objTreeMock, + SyncHandler: nil, + syncClient: syncClientMock, + listener: updateListenerMock, + isClosed: false, + } + + headUpdate := &treechangeproto.TreeSyncMessage{} + t.Run("AddRawChanges update", func(t *testing.T) { + changes := []*treechangeproto.RawTreeChangeWithId{{Id: "some"}} + expectedRes := tree.AddResult{ + Added: changes, + Mode: tree.Append, + } + objTreeMock.EXPECT().AddRawChanges(gomock.Any(), gomock.Eq(changes)). + Return(expectedRes, nil) + updateListenerMock.EXPECT().Update(tr) + + syncClientMock.EXPECT().CreateHeadUpdate(gomock.Eq(tr), gomock.Eq(changes)).Return(headUpdate) + syncClientMock.EXPECT().BroadcastAsync(gomock.Eq(headUpdate)).Return(nil) + res, err := tr.AddRawChanges(ctx, changes...) + require.NoError(t, err) + require.Equal(t, expectedRes, res) + }) + + t.Run("AddRawChanges rebuild", func(t *testing.T) { + changes := []*treechangeproto.RawTreeChangeWithId{{Id: "some"}} + expectedRes := tree.AddResult{ + Added: changes, + Mode: tree.Rebuild, + } + objTreeMock.EXPECT().AddRawChanges(gomock.Any(), gomock.Eq(changes)). + Return(expectedRes, nil) + updateListenerMock.EXPECT().Rebuild(tr) + + syncClientMock.EXPECT().CreateHeadUpdate(gomock.Eq(tr), gomock.Eq(changes)).Return(headUpdate) + syncClientMock.EXPECT().BroadcastAsync(gomock.Eq(headUpdate)).Return(nil) + res, err := tr.AddRawChanges(ctx, changes...) + require.NoError(t, err) + require.Equal(t, expectedRes, res) + }) + + t.Run("AddRawChanges nothing", func(t *testing.T) { + changes := []*treechangeproto.RawTreeChangeWithId{{Id: "some"}} + expectedRes := tree.AddResult{ + Added: changes, + Mode: tree.Nothing, + } + objTreeMock.EXPECT().AddRawChanges(gomock.Any(), gomock.Eq(changes)). + Return(expectedRes, nil) + + res, err := tr.AddRawChanges(ctx, changes...) + require.NoError(t, err) + require.Equal(t, expectedRes, res) + }) + + t.Run("AddContent", func(t *testing.T) { + changes := []*treechangeproto.RawTreeChangeWithId{{Id: "some"}} + content := tree.SignableChangeContent{ + Data: []byte("abcde"), + } + expectedRes := tree.AddResult{ + Mode: tree.Append, + Added: changes, + } + objTreeMock.EXPECT().AddContent(gomock.Any(), gomock.Eq(content)). + Return(expectedRes, nil) + + syncClientMock.EXPECT().CreateHeadUpdate(gomock.Eq(tr), gomock.Eq(changes)).Return(headUpdate) + syncClientMock.EXPECT().BroadcastAsync(gomock.Eq(headUpdate)).Return(nil) + res, err := tr.AddContent(ctx, content) + require.NoError(t, err) + require.Equal(t, expectedRes, res) + }) +} diff --git a/common/commonspace/synctree/synctreehandler.go b/common/commonspace/synctree/synctreehandler.go new file mode 100644 index 00000000..8c119e2a --- /dev/null +++ b/common/commonspace/synctree/synctreehandler.go @@ -0,0 +1,184 @@ +package synctree + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice/synchandler" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/slice" + "github.com/gogo/protobuf/proto" +) + +type syncTreeHandler struct { + objTree tree.ObjectTree + syncClient SyncClient +} + +func newSyncTreeHandler(objTree tree.ObjectTree, syncClient SyncClient) synchandler.SyncHandler { + return &syncTreeHandler{ + objTree: objTree, + syncClient: syncClient, + } +} + +func (s *syncTreeHandler) HandleMessage(ctx context.Context, senderId string, msg *spacesyncproto.ObjectSyncMessage) (err error) { + unmarshalled := &treechangeproto.TreeSyncMessage{} + err = proto.Unmarshal(msg.Payload, unmarshalled) + if err != nil { + return + } + + content := unmarshalled.GetContent() + switch { + case content.GetHeadUpdate() != nil: + return s.handleHeadUpdate(ctx, senderId, content.GetHeadUpdate(), msg.ReplyId) + case content.GetFullSyncRequest() != nil: + return s.handleFullSyncRequest(ctx, senderId, content.GetFullSyncRequest(), msg.ReplyId) + case content.GetFullSyncResponse() != nil: + return s.handleFullSyncResponse(ctx, senderId, content.GetFullSyncResponse()) + } + return nil +} + +func (s *syncTreeHandler) handleHeadUpdate( + ctx context.Context, + senderId string, + update *treechangeproto.TreeHeadUpdate, + replyId string) (err error) { + log.With("senderId", senderId). + With("heads", update.Heads). + With("treeId", s.objTree.ID()). + Debug("received head update message") + var ( + fullRequest *treechangeproto.TreeSyncMessage + isEmptyUpdate = len(update.Changes) == 0 + objTree = s.objTree + ) + + err = func() error { + objTree.Lock() + defer objTree.Unlock() + + // isEmptyUpdate is sent when the tree is brought up from cache + if isEmptyUpdate { + log.With("treeId", objTree.ID()).Debug("is empty update") + if slice.UnsortedEquals(objTree.Heads(), update.Heads) { + return nil + } + // we need to sync in any case + fullRequest, err = s.syncClient.CreateFullSyncRequest(objTree, update.Heads, update.SnapshotPath) + return err + } + + if s.alreadyHasHeads(objTree, update.Heads) { + return nil + } + + _, err = objTree.AddRawChanges(ctx, update.Changes...) + if err != nil { + return err + } + + if s.alreadyHasHeads(objTree, update.Heads) { + return nil + } + + fullRequest, err = s.syncClient.CreateFullSyncRequest(objTree, update.Heads, update.SnapshotPath) + return err + }() + + if fullRequest != nil { + log.With("senderId", senderId). + With("heads", objTree.Heads()). + With("treeId", objTree.ID()). + Debug("sending full sync request") + return s.syncClient.SendAsync(senderId, fullRequest, replyId) + } + log.With("senderId", senderId). + With("heads", update.Heads). + With("treeId", objTree.ID()). + Debug("head update finished correctly") + return +} + +func (s *syncTreeHandler) handleFullSyncRequest( + ctx context.Context, + senderId string, + request *treechangeproto.TreeFullSyncRequest, + replyId string) (err error) { + log.With("senderId", senderId). + With("heads", request.Heads). + With("treeId", s.objTree.ID()). + With("trackingId", replyId). + Debug("received full sync request message") + var ( + fullResponse *treechangeproto.TreeSyncMessage + header = s.objTree.Header() + objTree = s.objTree + ) + defer func() { + if err != nil { + s.syncClient.SendAsync(senderId, treechangeproto.WrapError(err, header), replyId) + } + }() + + err = func() error { + objTree.Lock() + defer objTree.Unlock() + + if len(request.Changes) != 0 && !s.alreadyHasHeads(objTree, request.Heads) { + _, err = objTree.AddRawChanges(ctx, request.Changes...) + if err != nil { + return err + } + } + + fullResponse, err = s.syncClient.CreateFullSyncResponse(objTree, request.Heads, request.SnapshotPath) + return err + }() + + if err != nil { + return + } + return s.syncClient.SendAsync(senderId, fullResponse, replyId) +} + +func (s *syncTreeHandler) handleFullSyncResponse( + ctx context.Context, + senderId string, + response *treechangeproto.TreeFullSyncResponse) (err error) { + log.With("senderId", senderId). + With("heads", response.Heads). + With("treeId", s.objTree.ID()). + Debug("received full sync response message") + objTree := s.objTree + if err != nil { + log.With("senderId", senderId). + With("heads", response.Heads). + With("treeId", s.objTree.ID()). + Debug("failed to find the tree in full sync response") + return + } + err = func() error { + objTree.Lock() + defer objTree.Unlock() + + if s.alreadyHasHeads(objTree, response.Heads) { + return nil + } + + _, err = objTree.AddRawChanges(ctx, response.Changes...) + return err + }() + log.With("error", err != nil). + With("heads", response.Heads). + With("treeId", s.objTree.ID()). + Debug("finished full sync response") + + return +} + +func (s *syncTreeHandler) alreadyHasHeads(t tree.ObjectTree, heads []string) bool { + return slice.UnsortedEquals(t.Heads(), heads) || t.HasChanges(heads...) +} diff --git a/common/commonspace/synctree/synctreehandler_test.go b/common/commonspace/synctree/synctreehandler_test.go new file mode 100644 index 00000000..72cda749 --- /dev/null +++ b/common/commonspace/synctree/synctreehandler_test.go @@ -0,0 +1,378 @@ +package synctree + +import ( + "context" + "fmt" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree/mock_synctree" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree/mock_objecttree" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + "go.uber.org/zap" + "sync" + "testing" +) + +type testObjTreeMock struct { + *mock_tree.MockObjectTree + m sync.Mutex +} + +func newTestObjMock(mockTree *mock_tree.MockObjectTree) *testObjTreeMock { + return &testObjTreeMock{ + MockObjectTree: mockTree, + } +} + +func (t *testObjTreeMock) Lock() { + t.m.Lock() +} + +func (t *testObjTreeMock) Unlock() { + t.m.Unlock() +} + +func TestSyncHandler_HandleHeadUpdate(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + ctx := context.Background() + syncClientMock := mock_synctree.NewMockSyncClient(ctrl) + objectTreeMock := newTestObjMock(mock_tree.NewMockObjectTree(ctrl)) + + syncHandler := newSyncTreeHandler(objectTreeMock, syncClientMock) + log = zap.NewNop().Sugar() + + t.Run("head update non empty all heads added", func(t *testing.T) { + treeId := "treeId" + senderId := "senderId" + chWithId := &treechangeproto.RawTreeChangeWithId{} + headUpdate := &treechangeproto.TreeHeadUpdate{ + Heads: []string{"h1"}, + Changes: []*treechangeproto.RawTreeChangeWithId{chWithId}, + SnapshotPath: []string{"h1"}, + } + treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) + objectMsg, _ := marshallTreeMessage(treeMsg, treeId, "") + + objectTreeMock.EXPECT(). + ID().AnyTimes().Return(treeId) + objectTreeMock.EXPECT(). + Heads(). + Return([]string{"h2"}) + objectTreeMock.EXPECT(). + HasChanges(gomock.Eq([]string{"h1"})). + Return(false) + objectTreeMock.EXPECT(). + AddRawChanges(gomock.Any(), gomock.Eq([]*treechangeproto.RawTreeChangeWithId{chWithId})). + Return(tree.AddResult{}, nil) + objectTreeMock.EXPECT(). + Heads(). + Return([]string{"h2", "h1"}) + objectTreeMock.EXPECT(). + HasChanges(gomock.Eq([]string{"h1"})). + Return(true) + + err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + require.NoError(t, err) + }) + + t.Run("head update non empty heads not added", func(t *testing.T) { + treeId := "treeId" + senderId := "senderId" + chWithId := &treechangeproto.RawTreeChangeWithId{} + headUpdate := &treechangeproto.TreeHeadUpdate{ + Heads: []string{"h1"}, + Changes: []*treechangeproto.RawTreeChangeWithId{chWithId}, + SnapshotPath: []string{"h1"}, + } + treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) + objectMsg, _ := marshallTreeMessage(treeMsg, treeId, "") + fullRequest := &treechangeproto.TreeSyncMessage{} + + objectTreeMock.EXPECT(). + ID().AnyTimes().Return(treeId) + objectTreeMock.EXPECT(). + Heads(). + Return([]string{"h2"}) + objectTreeMock.EXPECT(). + HasChanges(gomock.Eq([]string{"h1"})). + Return(false) + objectTreeMock.EXPECT(). + AddRawChanges(gomock.Any(), gomock.Eq([]*treechangeproto.RawTreeChangeWithId{chWithId})). + Return(tree.AddResult{}, nil) + objectTreeMock.EXPECT(). + Heads(). + Return([]string{"h2"}) + objectTreeMock.EXPECT(). + HasChanges(gomock.Eq([]string{"h1"})). + Return(false) + syncClientMock.EXPECT(). + CreateFullSyncRequest(gomock.Eq(objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). + Return(fullRequest, nil) + objectTreeMock.EXPECT(). + Heads(). + Return([]string{"h2"}) + + syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Eq(fullRequest), gomock.Eq("")) + + err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + require.NoError(t, err) + }) + + t.Run("head update non empty equal heads", func(t *testing.T) { + treeId := "treeId" + senderId := "senderId" + chWithId := &treechangeproto.RawTreeChangeWithId{} + headUpdate := &treechangeproto.TreeHeadUpdate{ + Heads: []string{"h1"}, + Changes: []*treechangeproto.RawTreeChangeWithId{chWithId}, + SnapshotPath: []string{"h1"}, + } + treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) + objectMsg, _ := marshallTreeMessage(treeMsg, treeId, "") + + objectTreeMock.EXPECT(). + ID().AnyTimes().Return(treeId) + objectTreeMock.EXPECT(). + Heads(). + Return([]string{"h1"}) + + err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + require.NoError(t, err) + }) + + t.Run("head update empty", func(t *testing.T) { + treeId := "treeId" + senderId := "senderId" + chWithId := &treechangeproto.RawTreeChangeWithId{} + headUpdate := &treechangeproto.TreeHeadUpdate{ + Heads: []string{"h1"}, + Changes: nil, + SnapshotPath: []string{"h1"}, + } + treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) + objectMsg, _ := marshallTreeMessage(treeMsg, treeId, "") + fullRequest := &treechangeproto.TreeSyncMessage{} + + objectTreeMock.EXPECT(). + ID().AnyTimes().Return(treeId) + objectTreeMock.EXPECT(). + Heads(). + Return([]string{"h2"}) + syncClientMock.EXPECT(). + CreateFullSyncRequest(gomock.Eq(objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). + Return(fullRequest, nil) + objectTreeMock.EXPECT(). + Heads(). + Return([]string{"h2"}) + + syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Eq(fullRequest), gomock.Eq("")) + + err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + require.NoError(t, err) + }) + + t.Run("head update empty equal heads", func(t *testing.T) { + treeId := "treeId" + senderId := "senderId" + chWithId := &treechangeproto.RawTreeChangeWithId{} + headUpdate := &treechangeproto.TreeHeadUpdate{ + Heads: []string{"h1"}, + Changes: nil, + SnapshotPath: []string{"h1"}, + } + treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) + objectMsg, _ := marshallTreeMessage(treeMsg, treeId, "") + + objectTreeMock.EXPECT(). + ID().AnyTimes().Return(treeId) + objectTreeMock.EXPECT(). + Heads(). + Return([]string{"h1"}) + + err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + require.NoError(t, err) + }) +} + +func TestSyncHandler_HandleFullSyncRequest(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + ctx := context.Background() + syncClientMock := mock_synctree.NewMockSyncClient(ctrl) + objectTreeMock := newTestObjMock(mock_tree.NewMockObjectTree(ctrl)) + + syncHandler := newSyncTreeHandler(objectTreeMock, syncClientMock) + log = zap.NewNop().Sugar() + t.Run("full sync request with change", func(t *testing.T) { + treeId := "treeId" + senderId := "senderId" + chWithId := &treechangeproto.RawTreeChangeWithId{} + fullSyncRequest := &treechangeproto.TreeFullSyncRequest{ + Heads: []string{"h1"}, + Changes: []*treechangeproto.RawTreeChangeWithId{chWithId}, + SnapshotPath: []string{"h1"}, + } + treeMsg := treechangeproto.WrapFullRequest(fullSyncRequest, chWithId) + objectMsg, _ := marshallTreeMessage(treeMsg, treeId, "") + fullResponse := &treechangeproto.TreeSyncMessage{} + objectTreeMock.EXPECT(). + ID().AnyTimes().Return(treeId) + objectTreeMock.EXPECT().Header().Return(nil) + objectTreeMock.EXPECT(). + Heads(). + Return([]string{"h2"}) + objectTreeMock.EXPECT(). + HasChanges(gomock.Eq([]string{"h1"})). + Return(false) + objectTreeMock.EXPECT(). + AddRawChanges(gomock.Any(), gomock.Eq([]*treechangeproto.RawTreeChangeWithId{chWithId})). + Return(tree.AddResult{}, nil) + syncClientMock.EXPECT(). + CreateFullSyncResponse(gomock.Eq(objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). + Return(fullResponse, nil) + syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Eq(fullResponse), gomock.Eq("")) + err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + require.NoError(t, err) + }) + + t.Run("full sync request with change same heads", func(t *testing.T) { + treeId := "treeId" + senderId := "senderId" + chWithId := &treechangeproto.RawTreeChangeWithId{} + fullSyncRequest := &treechangeproto.TreeFullSyncRequest{ + Heads: []string{"h1"}, + Changes: []*treechangeproto.RawTreeChangeWithId{chWithId}, + SnapshotPath: []string{"h1"}, + } + treeMsg := treechangeproto.WrapFullRequest(fullSyncRequest, chWithId) + objectMsg, _ := marshallTreeMessage(treeMsg, treeId, "") + fullResponse := &treechangeproto.TreeSyncMessage{} + objectTreeMock.EXPECT(). + ID().AnyTimes().Return(treeId) + objectTreeMock.EXPECT().Header().Return(nil) + objectTreeMock.EXPECT(). + Heads(). + Return([]string{"h1"}) + syncClientMock.EXPECT(). + CreateFullSyncResponse(gomock.Eq(objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). + Return(fullResponse, nil) + syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Eq(fullResponse), gomock.Eq("")) + err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + require.NoError(t, err) + }) + + t.Run("full sync request without change but with reply id", func(t *testing.T) { + treeId := "treeId" + senderId := "senderId" + replyId := "replyId" + chWithId := &treechangeproto.RawTreeChangeWithId{} + fullSyncRequest := &treechangeproto.TreeFullSyncRequest{ + Heads: []string{"h1"}, + SnapshotPath: []string{"h1"}, + } + treeMsg := treechangeproto.WrapFullRequest(fullSyncRequest, chWithId) + objectMsg, _ := marshallTreeMessage(treeMsg, treeId, replyId) + fullResponse := &treechangeproto.TreeSyncMessage{} + objectTreeMock.EXPECT(). + ID().AnyTimes().Return(treeId) + objectTreeMock.EXPECT().Header().Return(nil) + syncClientMock.EXPECT(). + CreateFullSyncResponse(gomock.Eq(objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). + Return(fullResponse, nil) + syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Eq(fullResponse), gomock.Eq(replyId)) + err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + require.NoError(t, err) + }) + + t.Run("full sync request with add raw changes error", func(t *testing.T) { + treeId := "treeId" + senderId := "senderId" + chWithId := &treechangeproto.RawTreeChangeWithId{} + fullSyncRequest := &treechangeproto.TreeFullSyncRequest{ + Heads: []string{"h1"}, + Changes: []*treechangeproto.RawTreeChangeWithId{chWithId}, + SnapshotPath: []string{"h1"}, + } + treeMsg := treechangeproto.WrapFullRequest(fullSyncRequest, chWithId) + objectMsg, _ := marshallTreeMessage(treeMsg, treeId, "") + objectTreeMock.EXPECT(). + ID().AnyTimes().Return(treeId) + objectTreeMock.EXPECT().Header().Return(nil) + objectTreeMock.EXPECT(). + Heads(). + Return([]string{"h2"}) + objectTreeMock.EXPECT(). + HasChanges(gomock.Eq([]string{"h1"})). + Return(false) + objectTreeMock.EXPECT(). + AddRawChanges(gomock.Any(), gomock.Eq([]*treechangeproto.RawTreeChangeWithId{chWithId})). + Return(tree.AddResult{}, fmt.Errorf("")) + syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Any(), gomock.Eq("")) + err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + require.Error(t, err) + }) +} + +func TestSyncHandler_HandleFullSyncResponse(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + ctx := context.Background() + syncClientMock := mock_synctree.NewMockSyncClient(ctrl) + objectTreeMock := newTestObjMock(mock_tree.NewMockObjectTree(ctrl)) + + syncHandler := newSyncTreeHandler(objectTreeMock, syncClientMock) + log = zap.NewNop().Sugar() + + t.Run("full sync response with change", func(t *testing.T) { + treeId := "treeId" + senderId := "senderId" + replyId := "replyId" + chWithId := &treechangeproto.RawTreeChangeWithId{} + fullSyncResponse := &treechangeproto.TreeFullSyncResponse{ + Heads: []string{"h1"}, + Changes: []*treechangeproto.RawTreeChangeWithId{chWithId}, + SnapshotPath: []string{"h1"}, + } + treeMsg := treechangeproto.WrapFullResponse(fullSyncResponse, chWithId) + objectMsg, _ := marshallTreeMessage(treeMsg, treeId, replyId) + objectTreeMock.EXPECT().ID().AnyTimes().Return(treeId) + objectTreeMock.EXPECT(). + Heads(). + Return([]string{"h2"}) + objectTreeMock.EXPECT(). + HasChanges(gomock.Eq([]string{"h1"})). + Return(false) + objectTreeMock.EXPECT(). + AddRawChanges(gomock.Any(), gomock.Eq([]*treechangeproto.RawTreeChangeWithId{chWithId})). + Return(tree.AddResult{}, nil) + + err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + require.NoError(t, err) + }) + + t.Run("full sync response with same heads", func(t *testing.T) { + treeId := "treeId" + senderId := "senderId" + replyId := "replyId" + chWithId := &treechangeproto.RawTreeChangeWithId{} + fullSyncResponse := &treechangeproto.TreeFullSyncResponse{ + Heads: []string{"h1"}, + Changes: []*treechangeproto.RawTreeChangeWithId{chWithId}, + SnapshotPath: []string{"h1"}, + } + treeMsg := treechangeproto.WrapFullResponse(fullSyncResponse, chWithId) + objectMsg, _ := marshallTreeMessage(treeMsg, treeId, replyId) + objectTreeMock.EXPECT().ID().AnyTimes().Return(treeId) + objectTreeMock.EXPECT(). + Heads(). + Return([]string{"h1"}) + + err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + require.NoError(t, err) + }) +} diff --git a/common/commonspace/synctree/updatelistener/mock_updatelistener/mock_updatelistener.go b/common/commonspace/synctree/updatelistener/mock_updatelistener/mock_updatelistener.go new file mode 100644 index 00000000..c72db6e3 --- /dev/null +++ b/common/commonspace/synctree/updatelistener/mock_updatelistener/mock_updatelistener.go @@ -0,0 +1,59 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree/updatelistener (interfaces: UpdateListener) + +// Package mock_updatelistener is a generated GoMock package. +package mock_updatelistener + +import ( + reflect "reflect" + + tree "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree" + gomock "github.com/golang/mock/gomock" +) + +// MockUpdateListener is a mock of UpdateListener interface. +type MockUpdateListener struct { + ctrl *gomock.Controller + recorder *MockUpdateListenerMockRecorder +} + +// MockUpdateListenerMockRecorder is the mock recorder for MockUpdateListener. +type MockUpdateListenerMockRecorder struct { + mock *MockUpdateListener +} + +// NewMockUpdateListener creates a new mock instance. +func NewMockUpdateListener(ctrl *gomock.Controller) *MockUpdateListener { + mock := &MockUpdateListener{ctrl: ctrl} + mock.recorder = &MockUpdateListenerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockUpdateListener) EXPECT() *MockUpdateListenerMockRecorder { + return m.recorder +} + +// Rebuild mocks base method. +func (m *MockUpdateListener) Rebuild(arg0 tree.ObjectTree) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Rebuild", arg0) +} + +// Rebuild indicates an expected call of Rebuild. +func (mr *MockUpdateListenerMockRecorder) Rebuild(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Rebuild", reflect.TypeOf((*MockUpdateListener)(nil).Rebuild), arg0) +} + +// Update mocks base method. +func (m *MockUpdateListener) Update(arg0 tree.ObjectTree) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Update", arg0) +} + +// Update indicates an expected call of Update. +func (mr *MockUpdateListenerMockRecorder) Update(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockUpdateListener)(nil).Update), arg0) +} diff --git a/common/commonspace/synctree/updatelistener/updatelistener.go b/common/commonspace/synctree/updatelistener/updatelistener.go new file mode 100644 index 00000000..5d8f6e2f --- /dev/null +++ b/common/commonspace/synctree/updatelistener/updatelistener.go @@ -0,0 +1,11 @@ +//go:generate mockgen -destination mock_updatelistener/mock_updatelistener.go github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree/updatelistener UpdateListener +package updatelistener + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree" +) + +type UpdateListener interface { + Update(tree tree.ObjectTree) + Rebuild(tree tree.ObjectTree) +} diff --git a/common/commonspace/treegetter/mock_treegetter/mock_treegetter.go b/common/commonspace/treegetter/mock_treegetter/mock_treegetter.go new file mode 100644 index 00000000..a07949bc --- /dev/null +++ b/common/commonspace/treegetter/mock_treegetter/mock_treegetter.go @@ -0,0 +1,108 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter (interfaces: TreeGetter) + +// Package mock_treegetter is a generated GoMock package. +package mock_treegetter + +import ( + context "context" + reflect "reflect" + + app "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + tree "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree" + gomock "github.com/golang/mock/gomock" +) + +// MockTreeGetter is a mock of TreeGetter interface. +type MockTreeGetter struct { + ctrl *gomock.Controller + recorder *MockTreeGetterMockRecorder +} + +// MockTreeGetterMockRecorder is the mock recorder for MockTreeGetter. +type MockTreeGetterMockRecorder struct { + mock *MockTreeGetter +} + +// NewMockTreeGetter creates a new mock instance. +func NewMockTreeGetter(ctrl *gomock.Controller) *MockTreeGetter { + mock := &MockTreeGetter{ctrl: ctrl} + mock.recorder = &MockTreeGetterMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockTreeGetter) EXPECT() *MockTreeGetterMockRecorder { + return m.recorder +} + +// Close mocks base method. +func (m *MockTreeGetter) Close(arg0 context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Close", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Close indicates an expected call of Close. +func (mr *MockTreeGetterMockRecorder) Close(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockTreeGetter)(nil).Close), arg0) +} + +// GetTree mocks base method. +func (m *MockTreeGetter) GetTree(arg0 context.Context, arg1, arg2 string) (tree.ObjectTree, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetTree", arg0, arg1, arg2) + ret0, _ := ret[0].(tree.ObjectTree) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetTree indicates an expected call of GetTree. +func (mr *MockTreeGetterMockRecorder) GetTree(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTree", reflect.TypeOf((*MockTreeGetter)(nil).GetTree), arg0, arg1, arg2) +} + +// Init mocks base method. +func (m *MockTreeGetter) Init(arg0 *app.App) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Init", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Init indicates an expected call of Init. +func (mr *MockTreeGetterMockRecorder) Init(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockTreeGetter)(nil).Init), arg0) +} + +// Name mocks base method. +func (m *MockTreeGetter) Name() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Name") + ret0, _ := ret[0].(string) + return ret0 +} + +// Name indicates an expected call of Name. +func (mr *MockTreeGetterMockRecorder) Name() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockTreeGetter)(nil).Name)) +} + +// Run mocks base method. +func (m *MockTreeGetter) Run(arg0 context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Run", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Run indicates an expected call of Run. +func (mr *MockTreeGetterMockRecorder) Run(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockTreeGetter)(nil).Run), arg0) +} diff --git a/common/commonspace/treegetter/treegetter.go b/common/commonspace/treegetter/treegetter.go new file mode 100644 index 00000000..9047e273 --- /dev/null +++ b/common/commonspace/treegetter/treegetter.go @@ -0,0 +1,18 @@ +//go:generate mockgen -destination mock_treegetter/mock_treegetter.go github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter TreeGetter +package treegetter + +import ( + "context" + "errors" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree" +) + +const CName = "commonspace.treeGetter" + +var ErrSpaceNotFound = errors.New("space not found") + +type TreeGetter interface { + app.ComponentRunnable + GetTree(ctx context.Context, spaceId, treeId string) (tree.ObjectTree, error) +} diff --git a/config/account.go b/common/config/account.go similarity index 80% rename from config/account.go rename to common/config/account.go index 4525b26f..1ca9a8fd 100644 --- a/config/account.go +++ b/common/config/account.go @@ -2,6 +2,7 @@ package config type Account struct { PeerId string `yaml:"peerId"` + PeerKey string `yaml:"peerKey"` SigningKey string `yaml:"signingKey"` EncryptionKey string `yaml:"encryptionKey"` } diff --git a/config/anytype.go b/common/config/anytype.go similarity index 100% rename from config/anytype.go rename to common/config/anytype.go diff --git a/config/api.go b/common/config/api.go similarity index 100% rename from config/api.go rename to common/config/api.go diff --git a/config/config.go b/common/config/config.go similarity index 51% rename from config/config.go rename to common/config/config.go index 4c1e8aa9..06168a4d 100644 --- a/config/config.go +++ b/common/config/config.go @@ -1,10 +1,9 @@ package config import ( - "context" "fmt" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" "gopkg.in/yaml.v3" "io/ioutil" ) @@ -30,13 +29,32 @@ type Config struct { APIServer APIServer `yaml:"apiServer"` Nodes []Node `yaml:"nodes"` Space Space `yaml:"space"` + Storage Storage `yaml:"storage"` + Metric Metric `yaml:"metric"` + Log Log `yaml:"log"` } -func (c *Config) Init(ctx context.Context, a *app.App) (err error) { - logger.NewNamed("config").Info(fmt.Sprint(*c)) +func (c *Config) Init(a *app.App) (err error) { + logger.NewNamed("config").Info(fmt.Sprint(c.Space)) return } func (c Config) Name() (name string) { return CName } + +func (c Config) GetAnytype() Anytype { + return c.Anytype +} + +func (c Config) GetGRPCServer() GrpcServer { + return c.GrpcServer +} + +func (c Config) GetAccount() Account { + return c.Account +} + +func (c Config) GetMetric() Metric { + return c.Metric +} diff --git a/config/grpc.go b/common/config/grpc.go similarity index 100% rename from config/grpc.go rename to common/config/grpc.go diff --git a/common/config/log.go b/common/config/log.go new file mode 100644 index 00000000..ca7bffea --- /dev/null +++ b/common/config/log.go @@ -0,0 +1,36 @@ +package config + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" + "go.uber.org/zap" +) + +type Log struct { + Production bool `yaml:"production"` + DefaultLevel string `yaml:"defaultLevel"` + NamedLevels map[string]string `yaml:"namedLevels"` +} + +func (l Log) ApplyGlobal() { + var conf zap.Config + if l.Production { + conf = zap.NewProductionConfig() + } else { + conf = zap.NewDevelopmentConfig() + } + if defaultLevel, err := zap.ParseAtomicLevel(l.DefaultLevel); err == nil { + conf.Level = defaultLevel + } + var levels = make(map[string]zap.AtomicLevel) + for k, v := range l.NamedLevels { + if lev, err := zap.ParseAtomicLevel(v); err != nil { + levels[k] = lev + } + } + defaultLogger, err := conf.Build() + if err != nil { + logger.Default().Fatal("can't build logger", zap.Error(err)) + } + logger.SetDefault(defaultLogger) + logger.SetNamedLevels(levels) +} diff --git a/common/config/metric.go b/common/config/metric.go new file mode 100644 index 00000000..8cc29227 --- /dev/null +++ b/common/config/metric.go @@ -0,0 +1,5 @@ +package config + +type Metric struct { + Addr string `yaml:"addr"` +} diff --git a/common/config/nodes.go b/common/config/nodes.go new file mode 100644 index 00000000..9583d833 --- /dev/null +++ b/common/config/nodes.go @@ -0,0 +1,9 @@ +package config + +type Node struct { + PeerId string `yaml:"peerId"` + Address string `yaml:"address"` + SigningKey string `yaml:"signingKey,omitempty"` + EncryptionKey string `yaml:"encryptionKey,omitempty"` + IsConsensus bool `yaml:"isConsensus,omitempty"` +} diff --git a/config/peer.go b/common/config/peer.go similarity index 100% rename from config/peer.go rename to common/config/peer.go diff --git a/common/config/space.go b/common/config/space.go new file mode 100644 index 00000000..5b603715 --- /dev/null +++ b/common/config/space.go @@ -0,0 +1,6 @@ +package config + +type Space struct { + GCTTL int `yaml:"gcTTL"` + SyncPeriod int `yaml:"syncPeriod"` +} diff --git a/common/config/storage.go b/common/config/storage.go new file mode 100644 index 00000000..ebafe622 --- /dev/null +++ b/common/config/storage.go @@ -0,0 +1,5 @@ +package config + +type Storage struct { + Path string `yaml:"path"` +} diff --git a/common/go.mod b/common/go.mod new file mode 100644 index 00000000..8dfec05d --- /dev/null +++ b/common/go.mod @@ -0,0 +1,63 @@ +module github.com/anytypeio/go-anytype-infrastructure-experiments/common + +go 1.19 + +require ( + github.com/anytypeio/go-chash v0.0.0-20220629194632-4ad1154fe232 + github.com/awalterschulze/gographviz v2.0.3+incompatible + github.com/cespare/xxhash v1.1.0 + github.com/goccy/go-graphviz v0.0.9 + github.com/gogo/protobuf v1.3.2 + github.com/golang/mock v1.6.0 + github.com/huandu/skiplist v1.2.0 + github.com/ipfs/go-cid v0.3.2 + github.com/libp2p/go-libp2p v0.23.2 + github.com/minio/sha256-simd v1.0.0 + github.com/multiformats/go-multibase v0.1.1 + github.com/multiformats/go-multihash v0.2.1 + github.com/prometheus/client_golang v1.13.0 + github.com/stretchr/testify v1.8.0 + github.com/zeebo/blake3 v0.2.3 + github.com/zeebo/errs v1.3.0 + go.uber.org/zap v1.23.0 + gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 + gopkg.in/yaml.v3 v3.0.1 + storj.io/drpc v0.0.32 +) + +require ( + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect + github.com/fogleman/gg v1.3.0 // indirect + github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/ipfs/go-log/v2 v2.5.1 // indirect + github.com/klauspost/cpuid/v2 v2.1.1 // indirect + github.com/libp2p/go-buffer-pool v0.1.0 // indirect + github.com/libp2p/go-openssl v0.1.0 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-pointer v0.0.1 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/mr-tron/base58 v1.2.0 // indirect + github.com/multiformats/go-base32 v0.1.0 // indirect + github.com/multiformats/go-base36 v0.1.0 // indirect + github.com/multiformats/go-multiaddr v0.7.0 // indirect + github.com/multiformats/go-multicodec v0.6.0 // indirect + github.com/multiformats/go-varint v0.0.6 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/common v0.37.0 // indirect + github.com/prometheus/procfs v0.8.0 // indirect + github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect + go.uber.org/atomic v1.10.0 // indirect + go.uber.org/multierr v1.8.0 // indirect + golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect + golang.org/x/image v0.0.0-20200119044424-58c23975cae1 // indirect + golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect + google.golang.org/protobuf v1.28.1 // indirect + lukechampine.com/blake3 v1.1.7 // indirect +) diff --git a/common/go.sum b/common/go.sum new file mode 100644 index 00000000..03e87801 --- /dev/null +++ b/common/go.sum @@ -0,0 +1,615 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +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= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/anytypeio/go-chash v0.0.0-20220629194632-4ad1154fe232 h1:kMPPZYmJgbs4AJfodbg2OCXg5cp+9LPAJcLZJqmcghk= +github.com/anytypeio/go-chash v0.0.0-20220629194632-4ad1154fe232/go.mod h1:+PeHBAWp7gUh/yw6uAauKc5ku0w4cFNg6DUddGxoGq0= +github.com/awalterschulze/gographviz v2.0.3+incompatible h1:9sVEXJBJLwGX7EQVhLm2elIKCm7P2YHFC8v6096G09E= +github.com/awalterschulze/gographviz v2.0.3+incompatible/go.mod h1:GEV5wmg4YquNw7v1kkyoX9etIk8yVmXj+AkDHuuETHs= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/corona10/goimagehash v1.0.2 h1:pUfB0LnsJASMPGEZLj7tGY251vF+qLGqOgEP4rUs6kA= +github.com/corona10/goimagehash v1.0.2/go.mod h1:/l9umBhvcHQXVtQO1V6Gp1yD20STawkhRnnX0D1bvVI= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8= +github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/goccy/go-graphviz v0.0.9 h1:s/FMMJ1Joj6La3S5ApO3Jk2cwM4LpXECC2muFx3IPQQ= +github.com/goccy/go-graphviz v0.0.9/go.mod h1:wXVsXxmyMQU6TN3zGRttjNn3h+iCAS7xQFC6TlNvLhk= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +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/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= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c= +github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= +github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw= +github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ipfs/go-cid v0.3.2 h1:OGgOd+JCFM+y1DjWPmVH+2/4POtpDzwcr7VgnB7mZXc= +github.com/ipfs/go-cid v0.3.2/go.mod h1:gQ8pKqT/sUxGY+tIwy1RPpAojYu7jAyCp5Tz1svoupw= +github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= +github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= +github.com/klauspost/cpuid/v2 v2.1.1 h1:t0wUqjowdm8ezddV5k0tLWVklVuvLJpoHeb4WBdydm0= +github.com/klauspost/cpuid/v2 v2.1.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= +github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= +github.com/libp2p/go-libp2p v0.23.2 h1:yqyTeKQJyofWXxEv/eEVUvOrGdt/9x+0PIQ4N1kaxmE= +github.com/libp2p/go-libp2p v0.23.2/go.mod h1:s9DEa5NLR4g+LZS+md5uGU4emjMWFiqkZr6hBTY8UxI= +github.com/libp2p/go-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+Ooo= +github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= +github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= +github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= +github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= +github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= +github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4= +github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= +github.com/multiformats/go-multiaddr v0.7.0 h1:gskHcdaCyPtp9XskVwtvEeQOG465sCohbQIirSyqxrc= +github.com/multiformats/go-multiaddr v0.7.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs= +github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI= +github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8= +github.com/multiformats/go-multicodec v0.6.0 h1:KhH2kSuCARyuJraYMFxrNO3DqIaYhOdS039kbhgVwpE= +github.com/multiformats/go-multicodec v0.6.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw= +github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108= +github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= +github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY= +github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5 h1:BvoENQQU+fZ9uukda/RzCAL/191HHwJA5b13R6diVlY= +github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU= +github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= +github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= +github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= +github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= +github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg= +github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvvKCaQ= +github.com/zeebo/errs v1.3.0 h1:hmiaKqgYZzcVgRL1Vkc1Mn2914BbzB0IBxs+ebeutGs= +github.com/zeebo/errs v1.3.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= +github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= +github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +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.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= +go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= +go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= +go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= +golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200119044424-58c23975cae1 h1:5h3ngYt7+vXCDZCup/HkCQgW5XwmSvR/nA2JmJ0RErg= +golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +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= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +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= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +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/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 h1:VpOs+IwYnYBaFnrNAeB8UUWtL3vEUnzSCL1nVjPhqrw= +gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= +lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +storj.io/drpc v0.0.32 h1:5p5ZwsK/VOgapaCu+oxaPVwO6UwIs+iwdMiD50+R4PI= +storj.io/drpc v0.0.32/go.mod h1:6rcOyR/QQkSTX/9L5ZGtlZaE2PtXTTZl8d+ulSeeYEg= diff --git a/common/metric/drpc.go b/common/metric/drpc.go new file mode 100644 index 00000000..97c01f8a --- /dev/null +++ b/common/metric/drpc.go @@ -0,0 +1,20 @@ +package metric + +import ( + "github.com/prometheus/client_golang/prometheus" + "storj.io/drpc" + "time" +) + +type PrometheusDRPC struct { + drpc.Handler + SummaryVec *prometheus.SummaryVec +} + +func (ph *PrometheusDRPC) HandleRPC(stream drpc.Stream, rpc string) (err error) { + st := time.Now() + defer func() { + ph.SummaryVec.WithLabelValues(rpc).Observe(time.Since(st).Seconds()) + }() + return ph.Handler.HandleRPC(stream, rpc) +} diff --git a/common/metric/metric.go b/common/metric/metric.go new file mode 100644 index 00000000..64ecbd84 --- /dev/null +++ b/common/metric/metric.go @@ -0,0 +1,71 @@ +package metric + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + config2 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/config" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/collectors" + "github.com/prometheus/client_golang/prometheus/promhttp" + "net/http" + "time" +) + +const CName = "common.metric" + +func New() Metric { + return new(metric) +} + +type Metric interface { + Registry() *prometheus.Registry + app.ComponentRunnable +} + +type metric struct { + registry *prometheus.Registry + config config2.Metric +} + +type configSource interface { + GetMetric() config2.Metric +} + +func (m *metric) Init(a *app.App) (err error) { + m.registry = prometheus.NewRegistry() + m.config = a.MustComponent(config2.CName).(configSource).GetMetric() + return nil +} + +func (m *metric) Name() string { + return CName +} + +func (m *metric) Run(ctx context.Context) (err error) { + if err = m.registry.Register(collectors.NewBuildInfoCollector()); err != nil { + return err + } + if err = m.registry.Register(collectors.NewGoCollector()); err != nil { + return err + } + if m.config.Addr != "" { + var errCh = make(chan error) + http.Handle("/metrics", promhttp.HandlerFor(m.registry, promhttp.HandlerOpts{})) + go func() { + errCh <- http.ListenAndServe(m.config.Addr, nil) + }() + select { + case err = <-errCh: + case <-time.After(time.Second / 5): + } + } + return +} + +func (m *metric) Registry() *prometheus.Registry { + return m.registry +} + +func (m *metric) Close(ctx context.Context) (err error) { + return +} diff --git a/service/net/dialer/dialer.go b/common/net/dialer/dialer.go similarity index 59% rename from service/net/dialer/dialer.go rename to common/net/dialer/dialer.go index b90bf872..ebef079b 100644 --- a/service/net/dialer/dialer.go +++ b/common/net/dialer/dialer.go @@ -3,13 +3,12 @@ package dialer import ( "context" "errors" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger" - "github.com/anytypeio/go-anytype-infrastructure-experiments/config" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/peer" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/rpc" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/secure" - "github.com/libp2p/go-libp2p-core/sec" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/config" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/peer" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/secure" + "github.com/libp2p/go-libp2p/core/sec" "go.uber.org/zap" "net" "storj.io/drpc" @@ -17,7 +16,7 @@ import ( "sync" ) -const CName = "net/dialer" +const CName = "common.net.dialer" var ErrArrdsNotFound = errors.New("addrs for peer not found") @@ -40,7 +39,7 @@ type dialer struct { mu sync.RWMutex } -func (d *dialer) Init(ctx context.Context, a *app.App) (err error) { +func (d *dialer) Init(a *app.App) (err error) { d.transport = a.MustComponent(secure.CName).(secure.Service) nodes := a.MustComponent(config.CName).(*config.Config).Nodes d.peerAddrs = map[string][]string{} @@ -60,7 +59,7 @@ func (d *dialer) UpdateAddrs(addrs map[string][]string) { d.mu.Unlock() } -func (d *dialer) Dial(ctx context.Context, peerId string) (peer peer.Peer, err error) { +func (d *dialer) Dial(ctx context.Context, peerId string) (p peer.Peer, err error) { d.mu.RLock() defer d.mu.RUnlock() addrs, ok := d.peerAddrs[peerId] @@ -68,11 +67,11 @@ func (d *dialer) Dial(ctx context.Context, peerId string) (peer peer.Peer, err e return nil, ErrArrdsNotFound } var ( - stream drpc.Stream - sc sec.SecureConn + conn drpc.Conn + sc sec.SecureConn ) for _, addr := range addrs { - stream, sc, err = d.makeStream(ctx, addr) + conn, sc, err = d.handshake(ctx, addr) if err != nil { log.Info("can't connect to host", zap.String("addr", addr)) } else { @@ -83,10 +82,10 @@ func (d *dialer) Dial(ctx context.Context, peerId string) (peer peer.Peer, err e if err != nil { return } - return rpc.PeerFromStream(sc, stream, false), nil + return peer.NewPeer(sc, conn), nil } -func (d *dialer) makeStream(ctx context.Context, addr string) (stream drpc.Stream, sc sec.SecureConn, err error) { +func (d *dialer) handshake(ctx context.Context, addr string) (conn drpc.Conn, sc sec.SecureConn, err error) { tcpConn, err := net.Dial("tcp", addr) if err != nil { return @@ -96,9 +95,6 @@ func (d *dialer) makeStream(ctx context.Context, addr string) (stream drpc.Strea return } log.Info("connected with remote host", zap.String("serverPeer", sc.RemotePeer().String()), zap.String("per", sc.LocalPeer().String())) - stream, err = drpcconn.New(sc).NewStream(ctx, "", rpc.Encoding) - if err != nil { - return - } - return stream, sc, err + conn = drpcconn.New(sc) + return conn, sc, err } diff --git a/common/net/peer/context.go b/common/net/peer/context.go new file mode 100644 index 00000000..bf3b79f3 --- /dev/null +++ b/common/net/peer/context.go @@ -0,0 +1,32 @@ +package peer + +import ( + "context" + "errors" + "github.com/libp2p/go-libp2p/core/sec" + "storj.io/drpc/drpcctx" +) + +type contextKey uint + +const ( + contextKeyPeerId contextKey = iota +) + +var ErrPeerIdNotFoundInContext = errors.New("peer id not found in context") + +// CtxPeerId first tries to get peer id under our own key, but if it is not found tries to get through DRPC key +func CtxPeerId(ctx context.Context) (string, error) { + if peerId, ok := ctx.Value(contextKeyPeerId).(string); ok { + return peerId, nil + } + if conn, ok := ctx.Value(drpcctx.TransportKey{}).(sec.SecureConn); ok { + return conn.RemotePeer().String(), nil + } + return "", ErrPeerIdNotFoundInContext +} + +// CtxWithPeerId sets peer id in the context +func CtxWithPeerId(ctx context.Context, peerId string) context.Context { + return context.WithValue(ctx, contextKeyPeerId, peerId) +} diff --git a/common/net/peer/peer.go b/common/net/peer/peer.go new file mode 100644 index 00000000..6056b0b9 --- /dev/null +++ b/common/net/peer/peer.go @@ -0,0 +1,59 @@ +package peer + +import ( + "context" + "github.com/libp2p/go-libp2p/core/sec" + "storj.io/drpc" + "sync/atomic" + "time" +) + +func NewPeer(sc sec.SecureConn, conn drpc.Conn) Peer { + return &peer{ + id: sc.RemotePeer().String(), + lastUsage: time.Now().Unix(), + sc: sc, + Conn: conn, + } +} + +type Peer interface { + Id() string + LastUsage() time.Time + UpdateLastUsage() + drpc.Conn +} + +type peer struct { + id string + lastUsage int64 + sc sec.SecureConn + drpc.Conn +} + +func (p *peer) Id() string { + return p.id +} + +func (p *peer) LastUsage() time.Time { + select { + case <-p.Closed(): + return time.Unix(0, 0) + default: + } + return time.Unix(atomic.LoadInt64(&p.lastUsage), 0) +} + +func (p *peer) Invoke(ctx context.Context, rpc string, enc drpc.Encoding, in, out drpc.Message) error { + defer p.UpdateLastUsage() + return p.Conn.Invoke(ctx, rpc, enc, in, out) +} + +func (p *peer) NewStream(ctx context.Context, rpc string, enc drpc.Encoding) (drpc.Stream, error) { + defer p.UpdateLastUsage() + return p.Conn.NewStream(ctx, rpc, enc) +} + +func (p *peer) UpdateLastUsage() { + atomic.StoreInt64(&p.lastUsage, time.Now().Unix()) +} diff --git a/common/net/pool/pool.go b/common/net/pool/pool.go new file mode 100644 index 00000000..819fee23 --- /dev/null +++ b/common/net/pool/pool.go @@ -0,0 +1,129 @@ +package pool + +import ( + "context" + "errors" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/dialer" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/peer" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ocache" + "math/rand" + "time" +) + +const ( + CName = "common.net.pool" +) + +var log = logger.NewNamed(CName) + +var ( + ErrUnableToConnect = errors.New("unable to connect") +) + +func New() Pool { + return &pool{} +} + +// Pool creates and caches outgoing connection +type Pool interface { + // Get lookups to peer in existing connections or creates and cache new one + Get(ctx context.Context, id string) (peer.Peer, error) + // Dial creates new connection to peer and not use cache + Dial(ctx context.Context, id string) (peer.Peer, error) + // GetOneOf searches at least one existing connection in cache or creates a new one from a randomly selected id from given list + GetOneOf(ctx context.Context, peerIds []string) (peer.Peer, error) + + DialOneOf(ctx context.Context, peerIds []string) (peer.Peer, error) + + app.ComponentRunnable +} + +type pool struct { + cache ocache.OCache + dialer dialer.Dialer +} + +func (p *pool) Init(a *app.App) (err error) { + p.dialer = a.MustComponent(dialer.CName).(dialer.Dialer) + p.cache = ocache.New( + func(ctx context.Context, id string) (value ocache.Object, err error) { + return p.dialer.Dial(ctx, id) + }, + ocache.WithLogger(log.Sugar()), + ocache.WithGCPeriod(time.Minute), + ocache.WithTTL(time.Minute*5), + ) + return nil +} + +func (p *pool) Name() (name string) { + return CName +} + +func (p *pool) Run(ctx context.Context) (err error) { + return nil +} + +func (p *pool) Get(ctx context.Context, id string) (peer.Peer, error) { + v, err := p.cache.Get(ctx, id) + if err != nil { + return nil, err + } + pr := v.(peer.Peer) + select { + case <-pr.Closed(): + default: + return pr, nil + } + p.cache.Remove(id) + return p.Get(ctx, id) +} + +func (p *pool) Dial(ctx context.Context, id string) (peer.Peer, error) { + return p.dialer.Dial(ctx, id) +} + +func (p *pool) GetOneOf(ctx context.Context, peerIds []string) (peer.Peer, error) { + // finding existing connection + for _, peerId := range peerIds { + if v, err := p.cache.Pick(ctx, peerId); err == nil { + pr := v.(peer.Peer) + select { + case <-pr.Closed(): + default: + return pr, nil + } + } + } + // shuffle ids for better consistency + rand.Shuffle(len(peerIds), func(i, j int) { + peerIds[i], peerIds[j] = peerIds[j], peerIds[i] + }) + // connecting + for _, peerId := range peerIds { + if v, err := p.cache.Get(ctx, peerId); err == nil { + return v.(peer.Peer), nil + } + } + return nil, ErrUnableToConnect +} + +func (p *pool) DialOneOf(ctx context.Context, peerIds []string) (peer.Peer, error) { + // shuffle ids for better consistency + rand.Shuffle(len(peerIds), func(i, j int) { + peerIds[i], peerIds[j] = peerIds[j], peerIds[i] + }) + // connecting + for _, peerId := range peerIds { + if v, err := p.dialer.Dial(ctx, peerId); err == nil { + return v.(peer.Peer), nil + } + } + return nil, ErrUnableToConnect +} + +func (p *pool) Close(ctx context.Context) (err error) { + return p.cache.Close() +} diff --git a/common/net/pool/pool_test.go b/common/net/pool/pool_test.go new file mode 100644 index 00000000..2a9dce82 --- /dev/null +++ b/common/net/pool/pool_test.go @@ -0,0 +1,213 @@ +package pool + +import ( + "context" + "errors" + "fmt" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/dialer" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/peer" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "storj.io/drpc" + "testing" + "time" +) + +var ctx = context.Background() + +func TestPool_Get(t *testing.T) { + t.Run("dial error", func(t *testing.T) { + fx := newFixture(t) + defer fx.Finish() + var expErr = errors.New("dial error") + fx.Dialer.dial = func(ctx context.Context, peerId string) (peer peer.Peer, err error) { + return nil, expErr + } + p, err := fx.Get(ctx, "1") + assert.Nil(t, p) + assert.EqualError(t, err, expErr.Error()) + }) + t.Run("dial and cached", func(t *testing.T) { + fx := newFixture(t) + defer fx.Finish() + fx.Dialer.dial = func(ctx context.Context, peerId string) (peer peer.Peer, err error) { + return newTestPeer("1"), nil + } + p, err := fx.Get(ctx, "1") + assert.NoError(t, err) + assert.NotNil(t, p) + fx.Dialer.dial = nil + p, err = fx.Get(ctx, "1") + assert.NoError(t, err) + assert.NotNil(t, p) + }) + t.Run("retry for closed", func(t *testing.T) { + fx := newFixture(t) + defer fx.Finish() + tp := newTestPeer("1") + fx.Dialer.dial = func(ctx context.Context, peerId string) (peer peer.Peer, err error) { + return tp, nil + } + p, err := fx.Get(ctx, "1") + assert.NoError(t, err) + assert.NotNil(t, p) + p.Close() + tp2 := newTestPeer("1") + fx.Dialer.dial = func(ctx context.Context, peerId string) (peer peer.Peer, err error) { + return tp2, nil + } + p, err = fx.Get(ctx, "1") + assert.NoError(t, err) + assert.Equal(t, p, tp2) + }) +} + +func TestPool_GetOneOf(t *testing.T) { + addToCache := func(t *testing.T, fx *fixture, tp *testPeer) { + fx.Dialer.dial = func(ctx context.Context, peerId string) (peer peer.Peer, err error) { + return tp, nil + } + gp, err := fx.Get(ctx, tp.Id()) + require.NoError(t, err) + require.Equal(t, gp, tp) + } + + t.Run("from cache", func(t *testing.T) { + fx := newFixture(t) + defer fx.Finish() + tp1 := newTestPeer("1") + addToCache(t, fx, tp1) + p, err := fx.GetOneOf(ctx, []string{"3", "2", "1"}) + require.NoError(t, err) + assert.Equal(t, tp1, p) + }) + t.Run("from cache - skip closed", func(t *testing.T) { + fx := newFixture(t) + defer fx.Finish() + tp2 := newTestPeer("2") + addToCache(t, fx, tp2) + tp2.Close() + tp1 := newTestPeer("1") + addToCache(t, fx, tp1) + p, err := fx.GetOneOf(ctx, []string{"3", "2", "1"}) + require.NoError(t, err) + assert.Equal(t, tp1, p) + }) + t.Run("dial", func(t *testing.T) { + fx := newFixture(t) + defer fx.Finish() + var called bool + fx.Dialer.dial = func(ctx context.Context, peerId string) (peer peer.Peer, err error) { + if called { + return nil, fmt.Errorf("not expected call") + } + called = true + return newTestPeer(peerId), nil + } + p, err := fx.GetOneOf(ctx, []string{"3", "2", "1"}) + require.NoError(t, err) + assert.NotNil(t, p) + }) + t.Run("unable to connect", func(t *testing.T) { + fx := newFixture(t) + defer fx.Finish() + fx.Dialer.dial = func(ctx context.Context, peerId string) (peer peer.Peer, err error) { + return nil, fmt.Errorf("persistent error") + } + p, err := fx.GetOneOf(ctx, []string{"3", "2", "1"}) + assert.Equal(t, ErrUnableToConnect, err) + assert.Nil(t, p) + }) +} + +func newFixture(t *testing.T) *fixture { + fx := &fixture{ + Pool: New(), + Dialer: &dialerMock{}, + } + a := new(app.App) + a.Register(fx.Pool) + a.Register(fx.Dialer) + require.NoError(t, a.Start(context.Background())) + fx.a = a + fx.t = t + return fx +} + +func (fx *fixture) Finish() { + require.NoError(fx.t, fx.a.Close(context.Background())) +} + +type fixture struct { + Pool + Dialer *dialerMock + a *app.App + t *testing.T +} + +var _ dialer.Dialer = (*dialerMock)(nil) + +type dialerMock struct { + dial func(ctx context.Context, peerId string) (peer peer.Peer, err error) +} + +func (d *dialerMock) Dial(ctx context.Context, peerId string) (peer peer.Peer, err error) { + return d.dial(ctx, peerId) +} + +func (d *dialerMock) UpdateAddrs(addrs map[string][]string) { + return +} + +func (d *dialerMock) Init(a *app.App) (err error) { + return +} + +func (d *dialerMock) Name() (name string) { + return dialer.CName +} + +func newTestPeer(id string) *testPeer { + return &testPeer{ + id: id, + closed: make(chan struct{}), + } +} + +type testPeer struct { + id string + closed chan struct{} +} + +func (t *testPeer) Id() string { + return t.id +} + +func (t *testPeer) LastUsage() time.Time { + return time.Now() +} + +func (t *testPeer) UpdateLastUsage() {} + +func (t *testPeer) Close() error { + select { + case <-t.closed: + return fmt.Errorf("already closed") + default: + close(t.closed) + } + return nil +} + +func (t *testPeer) Closed() <-chan struct{} { + return t.closed +} + +func (t *testPeer) Invoke(ctx context.Context, rpc string, enc drpc.Encoding, in, out drpc.Message) error { + return fmt.Errorf("call Invoke on test peer") +} + +func (t *testPeer) NewStream(ctx context.Context, rpc string, enc drpc.Encoding) (drpc.Stream, error) { + return nil, fmt.Errorf("call NewStream on test peer") +} diff --git a/common/net/rpc/rpcerr/registry.go b/common/net/rpc/rpcerr/registry.go new file mode 100644 index 00000000..5160fec3 --- /dev/null +++ b/common/net/rpc/rpcerr/registry.go @@ -0,0 +1,51 @@ +package rpcerr + +import ( + "errors" + "fmt" + "storj.io/drpc/drpcerr" +) + +var ( + Unexpected = RegisterErr(errors.New("unexpected"), 1) + Closed = RegisterErr(errors.New("closed"), 2) +) + +var ( + errsMap = make(map[uint64]error) +) + +func RegisterErr(err error, code uint64) error { + if e, ok := errsMap[code]; ok { + panic(fmt.Errorf("attempt to register error with existing code: %d; registered error: %v", code, e)) + } + errWithCode := drpcerr.WithCode(err, code) + errsMap[code] = errWithCode + return errWithCode +} + +func Err(code uint64) error { + err, ok := errsMap[code] + if !ok { + return drpcerr.WithCode(fmt.Errorf("unexpected error, code: %d", code), code) + } + return err +} + +func Unwrap(e error) error { + code := drpcerr.Code(e) + if code == 0 { + return e + } + err, ok := errsMap[code] + if !ok { + return drpcerr.WithCode(fmt.Errorf("unexpected error: %v; code: %d", err, code), code) + } + return err +} + +type ErrGroup int64 + +func (g ErrGroup) Register(err error, code uint64) error { + return RegisterErr(err, uint64(g)+code) +} diff --git a/common/net/rpc/rpctest/pool.go b/common/net/rpc/rpctest/pool.go new file mode 100644 index 00000000..549e8712 --- /dev/null +++ b/common/net/rpc/rpctest/pool.go @@ -0,0 +1,98 @@ +package rpctest + +import ( + "context" + "errors" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/peer" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/pool" + "math/rand" + "storj.io/drpc" + "sync" + "time" +) + +var ErrCantConnect = errors.New("can't connect to test server") + +func NewTestPool() *TestPool { + return &TestPool{} +} + +type TestPool struct { + ts *TesServer + mu sync.Mutex +} + +func (t *TestPool) WithServer(ts *TesServer) *TestPool { + t.mu.Lock() + defer t.mu.Unlock() + t.ts = ts + return t +} + +func (t *TestPool) Get(ctx context.Context, id string) (peer.Peer, error) { + t.mu.Lock() + defer t.mu.Unlock() + if t.ts == nil { + return nil, ErrCantConnect + } + return &testPeer{id: id, Conn: t.ts.Dial(ctx)}, nil +} + +func (t *TestPool) Dial(ctx context.Context, id string) (peer.Peer, error) { + t.mu.Lock() + defer t.mu.Unlock() + if t.ts == nil { + return nil, ErrCantConnect + } + return &testPeer{id: id, Conn: t.ts.Dial(ctx)}, nil +} + +func (t *TestPool) GetOneOf(ctx context.Context, peerIds []string) (peer.Peer, error) { + t.mu.Lock() + defer t.mu.Unlock() + if t.ts == nil { + return nil, ErrCantConnect + } + return &testPeer{id: peerIds[rand.Intn(len(peerIds))], Conn: t.ts.Dial(ctx)}, nil +} + +func (t *TestPool) DialOneOf(ctx context.Context, peerIds []string) (peer.Peer, error) { + t.mu.Lock() + defer t.mu.Unlock() + if t.ts == nil { + return nil, ErrCantConnect + } + return &testPeer{id: peerIds[rand.Intn(len(peerIds))], Conn: t.ts.Dial(ctx)}, nil +} + +func (t *TestPool) Init(a *app.App) (err error) { + return nil +} + +func (t *TestPool) Name() (name string) { + return pool.CName +} + +func (t *TestPool) Run(ctx context.Context) (err error) { + return nil +} + +func (t *TestPool) Close(ctx context.Context) (err error) { + return nil +} + +type testPeer struct { + id string + drpc.Conn +} + +func (t testPeer) Id() string { + return t.id +} + +func (t testPeer) LastUsage() time.Time { + return time.Now() +} + +func (t testPeer) UpdateLastUsage() {} diff --git a/common/net/rpc/rpctest/server.go b/common/net/rpc/rpctest/server.go new file mode 100644 index 00000000..9a36d288 --- /dev/null +++ b/common/net/rpc/rpctest/server.go @@ -0,0 +1,29 @@ +package rpctest + +import ( + "context" + "net" + "storj.io/drpc" + "storj.io/drpc/drpcconn" + "storj.io/drpc/drpcmux" + "storj.io/drpc/drpcserver" +) + +func NewTestServer() *TesServer { + ts := &TesServer{ + Mux: drpcmux.New(), + } + ts.Server = drpcserver.New(ts.Mux) + return ts +} + +type TesServer struct { + *drpcmux.Mux + *drpcserver.Server +} + +func (ts *TesServer) Dial(ctx context.Context) drpc.Conn { + sc, cc := net.Pipe() + go ts.Server.ServeOne(ctx, sc) + return drpcconn.New(cc) +} diff --git a/service/net/rpc/server/drpcserver.go b/common/net/rpc/server/drpcserver.go similarity index 62% rename from service/net/rpc/server/drpcserver.go rename to common/net/rpc/server/drpcserver.go index 684b6d40..3d1341b6 100644 --- a/service/net/rpc/server/drpcserver.go +++ b/common/net/rpc/server/drpcserver.go @@ -2,30 +2,37 @@ package server import ( "context" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger" - "github.com/anytypeio/go-anytype-infrastructure-experiments/config" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/pool" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/rpc" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/secure" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/config" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/metric" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/secure" + "github.com/prometheus/client_golang/prometheus" + "github.com/zeebo/errs" "go.uber.org/zap" + "io" "net" "storj.io/drpc" + "storj.io/drpc/drpcmux" "storj.io/drpc/drpcserver" - "strings" "time" ) -const CName = "net/drpcserver" +const CName = "common.net.drpcserver" var log = logger.NewNamed(CName) func New() DRPCServer { - return &drpcServer{} + return &drpcServer{Mux: drpcmux.New()} } type DRPCServer interface { app.ComponentRunnable + drpc.Mux +} + +type configGetter interface { + GetGRPCServer() config.GrpcServer } type drpcServer struct { @@ -33,14 +40,15 @@ type drpcServer struct { drpcServer *drpcserver.Server transport secure.Service listeners []secure.ContextListener - pool pool.Pool + metric metric.Metric cancel func() + *drpcmux.Mux } -func (s *drpcServer) Init(ctx context.Context, a *app.App) (err error) { - s.config = a.MustComponent(config.CName).(*config.Config).GrpcServer +func (s *drpcServer) Init(a *app.App) (err error) { + s.config = a.MustComponent(config.CName).(configGetter).GetGRPCServer() s.transport = a.MustComponent(secure.CName).(secure.Service) - s.pool = a.MustComponent(pool.CName).(pool.Pool) + s.metric = a.MustComponent(metric.CName).(metric.Metric) return nil } @@ -49,9 +57,24 @@ func (s *drpcServer) Name() (name string) { } func (s *drpcServer) Run(ctx context.Context) (err error) { - s.drpcServer = drpcserver.New(s) - - s.drpcServer = drpcserver.New(mux) + histVec := prometheus.NewSummaryVec(prometheus.SummaryOpts{ + Namespace: "drpc", + Subsystem: "server", + Name: "duration_seconds", + Objectives: map[float64]float64{ + 0.5: 0.5, + 0.85: 0.01, + 0.95: 0.0005, + 0.99: 0.0001, + }, + }, []string{"rpc"}) + s.drpcServer = drpcserver.New(&metric.PrometheusDRPC{ + Handler: s.Mux, + SummaryVec: histVec, + }) + if err = s.metric.Registry().Register(histVec); err != nil { + return + } ctx, s.cancel = context.WithCancel(ctx) for _, addr := range s.config.ListenAddrs { tcpList, err := net.Listen("tcp", addr) @@ -103,7 +126,7 @@ func (s *drpcServer) serveConn(ctx context.Context, conn net.Conn) { l := log.With(zap.String("remoteAddr", conn.RemoteAddr().String())).With(zap.String("localAddr", conn.LocalAddr().String())) l.Debug("connection opened") if err := s.drpcServer.ServeOne(ctx, conn); err != nil { - if err == context.Canceled || strings.Contains(err.Error(), "EOF") { + if errs.Is(err, context.Canceled) || errs.Is(err, io.EOF) { l.Debug("connection closed") } else { l.Warn("serve connection error", zap.Error(err)) @@ -111,16 +134,6 @@ func (s *drpcServer) serveConn(ctx context.Context, conn net.Conn) { } } -func (s *drpcServer) HandleRPC(stream drpc.Stream, _ string) (err error) { - ctx := stream.Context() - sc, err := secure.CtxSecureConn(ctx) - if err != nil { - return - } - log.With(zap.String("peer", sc.RemotePeer().String())).Debug("stream opened") - return s.pool.AddAndReadPeer(rpc.PeerFromStream(sc, stream, true)) -} - func (s *drpcServer) Close(ctx context.Context) (err error) { if s.cancel != nil { s.cancel() diff --git a/service/net/rpc/server/util.go b/common/net/rpc/server/util.go similarity index 100% rename from service/net/rpc/server/util.go rename to common/net/rpc/server/util.go diff --git a/service/net/rpc/server/util_windows.go b/common/net/rpc/server/util_windows.go similarity index 100% rename from service/net/rpc/server/util_windows.go rename to common/net/rpc/server/util_windows.go diff --git a/service/net/secure/listener.go b/common/net/secure/listener.go similarity index 86% rename from service/net/secure/listener.go rename to common/net/secure/listener.go index a0c61d56..db16470f 100644 --- a/service/net/secure/listener.go +++ b/common/net/secure/listener.go @@ -2,7 +2,8 @@ package secure import ( "context" - "github.com/libp2p/go-libp2p-core/crypto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/peer" + "github.com/libp2p/go-libp2p/core/crypto" libp2ptls "github.com/libp2p/go-libp2p/p2p/security/tls" "net" ) @@ -45,6 +46,6 @@ func (p *tlsListener) upgradeConn(ctx context.Context, conn net.Conn) (context.C if err != nil { return nil, nil, HandshakeError(err) } - ctx = ctxWithSecureConn(ctx, secure) + ctx = peer.CtxWithPeerId(ctx, secure.RemotePeer().String()) return ctx, secure, nil } diff --git a/common/net/secure/service.go b/common/net/secure/service.go new file mode 100644 index 00000000..c3ba0d40 --- /dev/null +++ b/common/net/secure/service.go @@ -0,0 +1,66 @@ +package secure + +import ( + "context" + commonaccount "github.com/anytypeio/go-anytype-infrastructure-experiments/common/account" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/config" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/sec" + libp2ptls "github.com/libp2p/go-libp2p/p2p/security/tls" + "go.uber.org/zap" + "net" +) + +type HandshakeError error + +const CName = "common.net.secure" + +var log = logger.NewNamed(CName) + +func New() Service { + return &service{} +} + +type Service interface { + TLSListener(lis net.Listener) ContextListener + TLSConn(ctx context.Context, conn net.Conn) (sec.SecureConn, error) + app.Component +} + +type service struct { + key crypto.PrivKey +} + +func (s *service) Init(a *app.App) (err error) { + account := a.MustComponent(config.CName).(commonaccount.ConfigGetter).GetAccount() + pkb, err := keys.DecodeBytesFromString(account.PeerKey) + if err != nil { + return + } + if s.key, err = crypto.UnmarshalEd25519PrivateKey(pkb); err != nil { + return + } + + log.Info("secure service init", zap.String("peerId", account.PeerId)) + + return nil +} + +func (s *service) Name() (name string) { + return CName +} + +func (s *service) TLSListener(lis net.Listener) ContextListener { + return newTLSListener(s.key, lis) +} + +func (s *service) TLSConn(ctx context.Context, conn net.Conn) (sec.SecureConn, error) { + tr, err := libp2ptls.New(s.key) + if err != nil { + return nil, err + } + return tr.SecureOutbound(ctx, conn, "") +} diff --git a/common/nodeconf/confconnector.go b/common/nodeconf/confconnector.go new file mode 100644 index 00000000..bb2c302a --- /dev/null +++ b/common/nodeconf/confconnector.go @@ -0,0 +1,54 @@ +package nodeconf + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/peer" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/pool" +) + +type ConfConnector interface { + GetResponsiblePeers(ctx context.Context, spaceId string) ([]peer.Peer, error) + DialResponsiblePeers(ctx context.Context, spaceId string) ([]peer.Peer, error) +} + +type confConnector struct { + conf Configuration + pool pool.Pool +} + +func NewConfConnector(conf Configuration, pool pool.Pool) ConfConnector { + return &confConnector{conf: conf, pool: pool} +} + +func (s *confConnector) GetResponsiblePeers(ctx context.Context, spaceId string) ([]peer.Peer, error) { + return s.connectOneOrMany(ctx, spaceId, s.pool.Get, s.pool.GetOneOf) +} + +func (s *confConnector) DialResponsiblePeers(ctx context.Context, spaceId string) ([]peer.Peer, error) { + return s.connectOneOrMany(ctx, spaceId, s.pool.Dial, s.pool.DialOneOf) +} + +func (s *confConnector) connectOneOrMany( + ctx context.Context, spaceId string, + connectOne func(context.Context, string) (peer.Peer, error), + connectOneOf func(context.Context, []string) (peer.Peer, error)) (peers []peer.Peer, err error) { + allNodes := s.conf.NodeIds(spaceId) + if s.conf.IsResponsible(spaceId) { + for _, id := range allNodes { + var p peer.Peer + p, err = connectOne(ctx, id) + if err != nil { + continue + } + peers = append(peers, p) + } + } else { + var p peer.Peer + p, err = connectOneOf(ctx, allNodes) + if err != nil { + return + } + peers = []peer.Peer{p} + } + return +} diff --git a/common/nodeconf/configuration.go b/common/nodeconf/configuration.go new file mode 100644 index 00000000..eecc53c3 --- /dev/null +++ b/common/nodeconf/configuration.go @@ -0,0 +1,49 @@ +//go:generate mockgen -destination mock_nodeconf/mock_nodeconf.go github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf Service,Configuration,ConfConnector +package nodeconf + +import ( + "github.com/anytypeio/go-chash" +) + +func New() Service { + return new(service) +} + +type Configuration interface { + // Id returns current nodeconf id + Id() string + // NodeIds returns list of peerId for given spaceId + NodeIds(spaceId string) []string + // IsResponsible checks if current account responsible for given spaceId + IsResponsible(spaceId string) bool +} + +type configuration struct { + id string + accountId string + chash chash.CHash +} + +func (c *configuration) Id() string { + return c.id +} + +func (c *configuration) NodeIds(spaceId string) []string { + members := c.chash.GetMembers(spaceId) + res := make([]string, 0, len(members)) + for _, m := range members { + if m.Id() != c.accountId { + res = append(res, m.Id()) + } + } + return res +} + +func (c *configuration) IsResponsible(spaceId string) bool { + for _, m := range c.chash.GetMembers(spaceId) { + if m.Id() == c.accountId { + return true + } + } + return false +} diff --git a/common/nodeconf/mock_nodeconf/mock_nodeconf.go b/common/nodeconf/mock_nodeconf/mock_nodeconf.go new file mode 100644 index 00000000..206c2528 --- /dev/null +++ b/common/nodeconf/mock_nodeconf/mock_nodeconf.go @@ -0,0 +1,226 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf (interfaces: Service,Configuration,ConfConnector) + +// Package mock_nodeconf is a generated GoMock package. +package mock_nodeconf + +import ( + context "context" + reflect "reflect" + + app "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + peer "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/peer" + nodeconf "github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf" + gomock "github.com/golang/mock/gomock" +) + +// MockService is a mock of Service interface. +type MockService struct { + ctrl *gomock.Controller + recorder *MockServiceMockRecorder +} + +// MockServiceMockRecorder is the mock recorder for MockService. +type MockServiceMockRecorder struct { + mock *MockService +} + +// NewMockService creates a new mock instance. +func NewMockService(ctrl *gomock.Controller) *MockService { + mock := &MockService{ctrl: ctrl} + mock.recorder = &MockServiceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockService) EXPECT() *MockServiceMockRecorder { + return m.recorder +} + +// ConsensusPeers mocks base method. +func (m *MockService) ConsensusPeers() []string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ConsensusPeers") + ret0, _ := ret[0].([]string) + return ret0 +} + +// ConsensusPeers indicates an expected call of ConsensusPeers. +func (mr *MockServiceMockRecorder) ConsensusPeers() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConsensusPeers", reflect.TypeOf((*MockService)(nil).ConsensusPeers)) +} + +// GetById mocks base method. +func (m *MockService) GetById(arg0 string) nodeconf.Configuration { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetById", arg0) + ret0, _ := ret[0].(nodeconf.Configuration) + return ret0 +} + +// GetById indicates an expected call of GetById. +func (mr *MockServiceMockRecorder) GetById(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetById", reflect.TypeOf((*MockService)(nil).GetById), arg0) +} + +// GetLast mocks base method. +func (m *MockService) GetLast() nodeconf.Configuration { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetLast") + ret0, _ := ret[0].(nodeconf.Configuration) + return ret0 +} + +// GetLast indicates an expected call of GetLast. +func (mr *MockServiceMockRecorder) GetLast() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLast", reflect.TypeOf((*MockService)(nil).GetLast)) +} + +// Init mocks base method. +func (m *MockService) Init(arg0 *app.App) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Init", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Init indicates an expected call of Init. +func (mr *MockServiceMockRecorder) Init(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockService)(nil).Init), arg0) +} + +// Name mocks base method. +func (m *MockService) Name() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Name") + ret0, _ := ret[0].(string) + return ret0 +} + +// Name indicates an expected call of Name. +func (mr *MockServiceMockRecorder) Name() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockService)(nil).Name)) +} + +// MockConfiguration is a mock of Configuration interface. +type MockConfiguration struct { + ctrl *gomock.Controller + recorder *MockConfigurationMockRecorder +} + +// MockConfigurationMockRecorder is the mock recorder for MockConfiguration. +type MockConfigurationMockRecorder struct { + mock *MockConfiguration +} + +// NewMockConfiguration creates a new mock instance. +func NewMockConfiguration(ctrl *gomock.Controller) *MockConfiguration { + mock := &MockConfiguration{ctrl: ctrl} + mock.recorder = &MockConfigurationMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockConfiguration) EXPECT() *MockConfigurationMockRecorder { + return m.recorder +} + +// Id mocks base method. +func (m *MockConfiguration) Id() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Id") + ret0, _ := ret[0].(string) + return ret0 +} + +// Id indicates an expected call of Id. +func (mr *MockConfigurationMockRecorder) Id() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Id", reflect.TypeOf((*MockConfiguration)(nil).Id)) +} + +// IsResponsible mocks base method. +func (m *MockConfiguration) IsResponsible(arg0 string) bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IsResponsible", arg0) + ret0, _ := ret[0].(bool) + return ret0 +} + +// IsResponsible indicates an expected call of IsResponsible. +func (mr *MockConfigurationMockRecorder) IsResponsible(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsResponsible", reflect.TypeOf((*MockConfiguration)(nil).IsResponsible), arg0) +} + +// NodeIds mocks base method. +func (m *MockConfiguration) NodeIds(arg0 string) []string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NodeIds", arg0) + ret0, _ := ret[0].([]string) + return ret0 +} + +// NodeIds indicates an expected call of NodeIds. +func (mr *MockConfigurationMockRecorder) NodeIds(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NodeIds", reflect.TypeOf((*MockConfiguration)(nil).NodeIds), arg0) +} + +// MockConfConnector is a mock of ConfConnector interface. +type MockConfConnector struct { + ctrl *gomock.Controller + recorder *MockConfConnectorMockRecorder +} + +// MockConfConnectorMockRecorder is the mock recorder for MockConfConnector. +type MockConfConnectorMockRecorder struct { + mock *MockConfConnector +} + +// NewMockConfConnector creates a new mock instance. +func NewMockConfConnector(ctrl *gomock.Controller) *MockConfConnector { + mock := &MockConfConnector{ctrl: ctrl} + mock.recorder = &MockConfConnectorMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockConfConnector) EXPECT() *MockConfConnectorMockRecorder { + return m.recorder +} + +// DialResponsiblePeers mocks base method. +func (m *MockConfConnector) DialResponsiblePeers(arg0 context.Context, arg1 string) ([]peer.Peer, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DialResponsiblePeers", arg0, arg1) + ret0, _ := ret[0].([]peer.Peer) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DialResponsiblePeers indicates an expected call of DialResponsiblePeers. +func (mr *MockConfConnectorMockRecorder) DialResponsiblePeers(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DialResponsiblePeers", reflect.TypeOf((*MockConfConnector)(nil).DialResponsiblePeers), arg0, arg1) +} + +// GetResponsiblePeers mocks base method. +func (m *MockConfConnector) GetResponsiblePeers(arg0 context.Context, arg1 string) ([]peer.Peer, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetResponsiblePeers", arg0, arg1) + ret0, _ := ret[0].([]peer.Peer) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetResponsiblePeers indicates an expected call of GetResponsiblePeers. +func (mr *MockConfConnectorMockRecorder) GetResponsiblePeers(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetResponsiblePeers", reflect.TypeOf((*MockConfConnector)(nil).GetResponsiblePeers), arg0, arg1) +} diff --git a/common/nodeconf/service.go b/common/nodeconf/service.go new file mode 100644 index 00000000..babf13ba --- /dev/null +++ b/common/nodeconf/service.go @@ -0,0 +1,126 @@ +package nodeconf + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/config" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/encryptionkey" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/signingkey" + "github.com/anytypeio/go-chash" +) + +const CName = "common.nodeconf" + +const ( + partitionCount = 3000 + replicationFactor = 3 +) + +var log = logger.NewNamed(CName) + +type Service interface { + GetLast() Configuration + GetById(id string) Configuration + ConsensusPeers() []string + app.Component +} + +type service struct { + accountId string + + consensusPeers []string + last Configuration +} + +type Node struct { + Address string + PeerId string + SigningKey signingkey.PubKey + EncryptionKey encryptionkey.PubKey +} + +func (n *Node) Id() string { + return n.PeerId +} + +func (n *Node) Capacity() float64 { + return 1 +} + +func (s *service) Init(a *app.App) (err error) { + conf := a.MustComponent(config.CName).(*config.Config) + s.accountId = conf.Account.PeerId + + config := &configuration{ + id: "config", + accountId: s.accountId, + } + if config.chash, err = chash.New(chash.Config{ + PartitionCount: partitionCount, + ReplicationFactor: replicationFactor, + }); err != nil { + return + } + members := make([]chash.Member, 0, len(conf.Nodes)) + for _, n := range conf.Nodes { + if n.IsConsensus { + s.consensusPeers = append(s.consensusPeers, n.PeerId) + continue + } + var member *Node + member, err = nodeFromConfigNode(n) + if err != nil { + return + } + members = append(members, member) + } + if err = config.chash.AddMembers(members...); err != nil { + return + } + s.last = config + return +} + +func (s *service) Name() (name string) { + return CName +} + +func (s *service) GetLast() Configuration { + return s.last +} + +func (s *service) GetById(id string) Configuration { + //TODO implement me + panic("implement me") +} + +func (s *service) ConsensusPeers() []string { + return s.consensusPeers +} + +func nodeFromConfigNode( + n config.Node) (*Node, error) { + decodedSigningKey, err := keys.DecodeKeyFromString( + n.SigningKey, + signingkey.UnmarshalEd25519PrivateKey, + nil) + if err != nil { + return nil, err + } + + decodedEncryptionKey, err := keys.DecodeKeyFromString( + n.EncryptionKey, + encryptionkey.NewEncryptionRsaPrivKeyFromBytes, + nil) + if err != nil { + return nil, err + } + + return &Node{ + Address: n.Address, + PeerId: n.PeerId, + SigningKey: decodedSigningKey.GetPublic(), + EncryptionKey: decodedEncryptionKey.GetPublic(), + }, nil +} diff --git a/common/pkg/acl/account/accountdata.go b/common/pkg/acl/account/accountdata.go new file mode 100644 index 00000000..13bcf342 --- /dev/null +++ b/common/pkg/acl/account/accountdata.go @@ -0,0 +1,13 @@ +package account + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/encryptionkey" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/signingkey" +) + +type AccountData struct { // TODO: create a convenient constructor for this + Identity []byte // public key + PeerKey signingkey.PrivKey + SignKey signingkey.PrivKey + EncKey encryptionkey.PrivKey +} diff --git a/common/pkg/acl/aclrecordproto/aclreadkeyderive.go b/common/pkg/acl/aclrecordproto/aclreadkeyderive.go new file mode 100644 index 00000000..40acc8ec --- /dev/null +++ b/common/pkg/acl/aclrecordproto/aclreadkeyderive.go @@ -0,0 +1,12 @@ +package aclrecordproto + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/symmetric" +) + +func ACLReadKeyDerive(signKey []byte, encKey []byte) (*symmetric.Key, error) { + concBuf := make([]byte, 0, len(signKey)+len(encKey)) + concBuf = append(concBuf, signKey...) + concBuf = append(concBuf, encKey...) + return symmetric.DeriveFromBytes(concBuf) +} diff --git a/common/pkg/acl/aclrecordproto/aclrecord.pb.go b/common/pkg/acl/aclrecordproto/aclrecord.pb.go new file mode 100644 index 00000000..ea582a27 --- /dev/null +++ b/common/pkg/acl/aclrecordproto/aclrecord.pb.go @@ -0,0 +1,5357 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: pkg/acl/aclrecordproto/protos/aclrecord.proto + +package aclrecordproto + +import ( + fmt "fmt" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type ACLUserPermissions int32 + +const ( + ACLUserPermissions_Admin ACLUserPermissions = 0 + ACLUserPermissions_Writer ACLUserPermissions = 1 + ACLUserPermissions_Reader ACLUserPermissions = 2 +) + +var ACLUserPermissions_name = map[int32]string{ + 0: "Admin", + 1: "Writer", + 2: "Reader", +} + +var ACLUserPermissions_value = map[string]int32{ + "Admin": 0, + "Writer": 1, + "Reader": 2, +} + +func (x ACLUserPermissions) String() string { + return proto.EnumName(ACLUserPermissions_name, int32(x)) +} + +func (ACLUserPermissions) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_14abe0d1b4206d54, []int{0} +} + +type RawACLRecord struct { + Payload []byte `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"` + Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` + AcceptorIdentity []byte `protobuf:"bytes,3,opt,name=acceptorIdentity,proto3" json:"acceptorIdentity,omitempty"` + AcceptorSignature []byte `protobuf:"bytes,4,opt,name=acceptorSignature,proto3" json:"acceptorSignature,omitempty"` +} + +func (m *RawACLRecord) Reset() { *m = RawACLRecord{} } +func (m *RawACLRecord) String() string { return proto.CompactTextString(m) } +func (*RawACLRecord) ProtoMessage() {} +func (*RawACLRecord) Descriptor() ([]byte, []int) { + return fileDescriptor_14abe0d1b4206d54, []int{0} +} +func (m *RawACLRecord) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RawACLRecord) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RawACLRecord.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RawACLRecord) XXX_Merge(src proto.Message) { + xxx_messageInfo_RawACLRecord.Merge(m, src) +} +func (m *RawACLRecord) XXX_Size() int { + return m.Size() +} +func (m *RawACLRecord) XXX_DiscardUnknown() { + xxx_messageInfo_RawACLRecord.DiscardUnknown(m) +} + +var xxx_messageInfo_RawACLRecord proto.InternalMessageInfo + +func (m *RawACLRecord) GetPayload() []byte { + if m != nil { + return m.Payload + } + return nil +} + +func (m *RawACLRecord) GetSignature() []byte { + if m != nil { + return m.Signature + } + return nil +} + +func (m *RawACLRecord) GetAcceptorIdentity() []byte { + if m != nil { + return m.AcceptorIdentity + } + return nil +} + +func (m *RawACLRecord) GetAcceptorSignature() []byte { + if m != nil { + return m.AcceptorSignature + } + return nil +} + +type RawACLRecordWithId struct { + Payload []byte `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"` + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` +} + +func (m *RawACLRecordWithId) Reset() { *m = RawACLRecordWithId{} } +func (m *RawACLRecordWithId) String() string { return proto.CompactTextString(m) } +func (*RawACLRecordWithId) ProtoMessage() {} +func (*RawACLRecordWithId) Descriptor() ([]byte, []int) { + return fileDescriptor_14abe0d1b4206d54, []int{1} +} +func (m *RawACLRecordWithId) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RawACLRecordWithId) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RawACLRecordWithId.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RawACLRecordWithId) XXX_Merge(src proto.Message) { + xxx_messageInfo_RawACLRecordWithId.Merge(m, src) +} +func (m *RawACLRecordWithId) XXX_Size() int { + return m.Size() +} +func (m *RawACLRecordWithId) XXX_DiscardUnknown() { + xxx_messageInfo_RawACLRecordWithId.DiscardUnknown(m) +} + +var xxx_messageInfo_RawACLRecordWithId proto.InternalMessageInfo + +func (m *RawACLRecordWithId) GetPayload() []byte { + if m != nil { + return m.Payload + } + return nil +} + +func (m *RawACLRecordWithId) GetId() string { + if m != nil { + return m.Id + } + return "" +} + +type ACLRecord struct { + PrevId string `protobuf:"bytes,1,opt,name=prevId,proto3" json:"prevId,omitempty"` + Identity []byte `protobuf:"bytes,2,opt,name=identity,proto3" json:"identity,omitempty"` + Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` + CurrentReadKeyHash uint64 `protobuf:"varint,4,opt,name=currentReadKeyHash,proto3" json:"currentReadKeyHash,omitempty"` + Timestamp int64 `protobuf:"varint,5,opt,name=timestamp,proto3" json:"timestamp,omitempty"` +} + +func (m *ACLRecord) Reset() { *m = ACLRecord{} } +func (m *ACLRecord) String() string { return proto.CompactTextString(m) } +func (*ACLRecord) ProtoMessage() {} +func (*ACLRecord) Descriptor() ([]byte, []int) { + return fileDescriptor_14abe0d1b4206d54, []int{2} +} +func (m *ACLRecord) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ACLRecord) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ACLRecord.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ACLRecord) XXX_Merge(src proto.Message) { + xxx_messageInfo_ACLRecord.Merge(m, src) +} +func (m *ACLRecord) XXX_Size() int { + return m.Size() +} +func (m *ACLRecord) XXX_DiscardUnknown() { + xxx_messageInfo_ACLRecord.DiscardUnknown(m) +} + +var xxx_messageInfo_ACLRecord proto.InternalMessageInfo + +func (m *ACLRecord) GetPrevId() string { + if m != nil { + return m.PrevId + } + return "" +} + +func (m *ACLRecord) GetIdentity() []byte { + if m != nil { + return m.Identity + } + return nil +} + +func (m *ACLRecord) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +func (m *ACLRecord) GetCurrentReadKeyHash() uint64 { + if m != nil { + return m.CurrentReadKeyHash + } + return 0 +} + +func (m *ACLRecord) GetTimestamp() int64 { + if m != nil { + return m.Timestamp + } + return 0 +} + +type ACLRoot struct { + Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` + EncryptionKey []byte `protobuf:"bytes,2,opt,name=encryptionKey,proto3" json:"encryptionKey,omitempty"` + SpaceId string `protobuf:"bytes,3,opt,name=spaceId,proto3" json:"spaceId,omitempty"` + EncryptedReadKey []byte `protobuf:"bytes,4,opt,name=encryptedReadKey,proto3" json:"encryptedReadKey,omitempty"` + DerivationScheme string `protobuf:"bytes,5,opt,name=derivationScheme,proto3" json:"derivationScheme,omitempty"` + CurrentReadKeyHash uint64 `protobuf:"varint,6,opt,name=currentReadKeyHash,proto3" json:"currentReadKeyHash,omitempty"` + Timestamp int64 `protobuf:"varint,7,opt,name=timestamp,proto3" json:"timestamp,omitempty"` +} + +func (m *ACLRoot) Reset() { *m = ACLRoot{} } +func (m *ACLRoot) String() string { return proto.CompactTextString(m) } +func (*ACLRoot) ProtoMessage() {} +func (*ACLRoot) Descriptor() ([]byte, []int) { + return fileDescriptor_14abe0d1b4206d54, []int{3} +} +func (m *ACLRoot) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ACLRoot) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ACLRoot.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ACLRoot) XXX_Merge(src proto.Message) { + xxx_messageInfo_ACLRoot.Merge(m, src) +} +func (m *ACLRoot) XXX_Size() int { + return m.Size() +} +func (m *ACLRoot) XXX_DiscardUnknown() { + xxx_messageInfo_ACLRoot.DiscardUnknown(m) +} + +var xxx_messageInfo_ACLRoot proto.InternalMessageInfo + +func (m *ACLRoot) GetIdentity() []byte { + if m != nil { + return m.Identity + } + return nil +} + +func (m *ACLRoot) GetEncryptionKey() []byte { + if m != nil { + return m.EncryptionKey + } + return nil +} + +func (m *ACLRoot) GetSpaceId() string { + if m != nil { + return m.SpaceId + } + return "" +} + +func (m *ACLRoot) GetEncryptedReadKey() []byte { + if m != nil { + return m.EncryptedReadKey + } + return nil +} + +func (m *ACLRoot) GetDerivationScheme() string { + if m != nil { + return m.DerivationScheme + } + return "" +} + +func (m *ACLRoot) GetCurrentReadKeyHash() uint64 { + if m != nil { + return m.CurrentReadKeyHash + } + return 0 +} + +func (m *ACLRoot) GetTimestamp() int64 { + if m != nil { + return m.Timestamp + } + return 0 +} + +type ACLContentValue struct { + // Types that are valid to be assigned to Value: + // + // *ACLContentValue_UserAdd + // *ACLContentValue_UserRemove + // *ACLContentValue_UserPermissionChange + // *ACLContentValue_UserInvite + // *ACLContentValue_UserJoin + Value isACLContentValue_Value `protobuf_oneof:"value"` +} + +func (m *ACLContentValue) Reset() { *m = ACLContentValue{} } +func (m *ACLContentValue) String() string { return proto.CompactTextString(m) } +func (*ACLContentValue) ProtoMessage() {} +func (*ACLContentValue) Descriptor() ([]byte, []int) { + return fileDescriptor_14abe0d1b4206d54, []int{4} +} +func (m *ACLContentValue) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ACLContentValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ACLContentValue.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ACLContentValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_ACLContentValue.Merge(m, src) +} +func (m *ACLContentValue) XXX_Size() int { + return m.Size() +} +func (m *ACLContentValue) XXX_DiscardUnknown() { + xxx_messageInfo_ACLContentValue.DiscardUnknown(m) +} + +var xxx_messageInfo_ACLContentValue proto.InternalMessageInfo + +type isACLContentValue_Value interface { + isACLContentValue_Value() + MarshalTo([]byte) (int, error) + Size() int +} + +type ACLContentValue_UserAdd struct { + UserAdd *ACLUserAdd `protobuf:"bytes,1,opt,name=userAdd,proto3,oneof" json:"userAdd,omitempty"` +} +type ACLContentValue_UserRemove struct { + UserRemove *ACLUserRemove `protobuf:"bytes,2,opt,name=userRemove,proto3,oneof" json:"userRemove,omitempty"` +} +type ACLContentValue_UserPermissionChange struct { + UserPermissionChange *ACLUserPermissionChange `protobuf:"bytes,3,opt,name=userPermissionChange,proto3,oneof" json:"userPermissionChange,omitempty"` +} +type ACLContentValue_UserInvite struct { + UserInvite *ACLUserInvite `protobuf:"bytes,4,opt,name=userInvite,proto3,oneof" json:"userInvite,omitempty"` +} +type ACLContentValue_UserJoin struct { + UserJoin *ACLUserJoin `protobuf:"bytes,5,opt,name=userJoin,proto3,oneof" json:"userJoin,omitempty"` +} + +func (*ACLContentValue_UserAdd) isACLContentValue_Value() {} +func (*ACLContentValue_UserRemove) isACLContentValue_Value() {} +func (*ACLContentValue_UserPermissionChange) isACLContentValue_Value() {} +func (*ACLContentValue_UserInvite) isACLContentValue_Value() {} +func (*ACLContentValue_UserJoin) isACLContentValue_Value() {} + +func (m *ACLContentValue) GetValue() isACLContentValue_Value { + if m != nil { + return m.Value + } + return nil +} + +func (m *ACLContentValue) GetUserAdd() *ACLUserAdd { + if x, ok := m.GetValue().(*ACLContentValue_UserAdd); ok { + return x.UserAdd + } + return nil +} + +func (m *ACLContentValue) GetUserRemove() *ACLUserRemove { + if x, ok := m.GetValue().(*ACLContentValue_UserRemove); ok { + return x.UserRemove + } + return nil +} + +func (m *ACLContentValue) GetUserPermissionChange() *ACLUserPermissionChange { + if x, ok := m.GetValue().(*ACLContentValue_UserPermissionChange); ok { + return x.UserPermissionChange + } + return nil +} + +func (m *ACLContentValue) GetUserInvite() *ACLUserInvite { + if x, ok := m.GetValue().(*ACLContentValue_UserInvite); ok { + return x.UserInvite + } + return nil +} + +func (m *ACLContentValue) GetUserJoin() *ACLUserJoin { + if x, ok := m.GetValue().(*ACLContentValue_UserJoin); ok { + return x.UserJoin + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*ACLContentValue) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*ACLContentValue_UserAdd)(nil), + (*ACLContentValue_UserRemove)(nil), + (*ACLContentValue_UserPermissionChange)(nil), + (*ACLContentValue_UserInvite)(nil), + (*ACLContentValue_UserJoin)(nil), + } +} + +type ACLData struct { + AclContent []*ACLContentValue `protobuf:"bytes,1,rep,name=aclContent,proto3" json:"aclContent,omitempty"` +} + +func (m *ACLData) Reset() { *m = ACLData{} } +func (m *ACLData) String() string { return proto.CompactTextString(m) } +func (*ACLData) ProtoMessage() {} +func (*ACLData) Descriptor() ([]byte, []int) { + return fileDescriptor_14abe0d1b4206d54, []int{5} +} +func (m *ACLData) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ACLData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ACLData.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ACLData) XXX_Merge(src proto.Message) { + xxx_messageInfo_ACLData.Merge(m, src) +} +func (m *ACLData) XXX_Size() int { + return m.Size() +} +func (m *ACLData) XXX_DiscardUnknown() { + xxx_messageInfo_ACLData.DiscardUnknown(m) +} + +var xxx_messageInfo_ACLData proto.InternalMessageInfo + +func (m *ACLData) GetAclContent() []*ACLContentValue { + if m != nil { + return m.AclContent + } + return nil +} + +type ACLState struct { + ReadKeyHashes []uint64 `protobuf:"varint,1,rep,packed,name=readKeyHashes,proto3" json:"readKeyHashes,omitempty"` + UserStates []*ACLUserState `protobuf:"bytes,2,rep,name=userStates,proto3" json:"userStates,omitempty"` + Invites map[string]*ACLUserInvite `protobuf:"bytes,3,rep,name=invites,proto3" json:"invites,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (m *ACLState) Reset() { *m = ACLState{} } +func (m *ACLState) String() string { return proto.CompactTextString(m) } +func (*ACLState) ProtoMessage() {} +func (*ACLState) Descriptor() ([]byte, []int) { + return fileDescriptor_14abe0d1b4206d54, []int{6} +} +func (m *ACLState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ACLState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ACLState.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ACLState) XXX_Merge(src proto.Message) { + xxx_messageInfo_ACLState.Merge(m, src) +} +func (m *ACLState) XXX_Size() int { + return m.Size() +} +func (m *ACLState) XXX_DiscardUnknown() { + xxx_messageInfo_ACLState.DiscardUnknown(m) +} + +var xxx_messageInfo_ACLState proto.InternalMessageInfo + +func (m *ACLState) GetReadKeyHashes() []uint64 { + if m != nil { + return m.ReadKeyHashes + } + return nil +} + +func (m *ACLState) GetUserStates() []*ACLUserState { + if m != nil { + return m.UserStates + } + return nil +} + +func (m *ACLState) GetInvites() map[string]*ACLUserInvite { + if m != nil { + return m.Invites + } + return nil +} + +type ACLUserState struct { + Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` + EncryptionKey []byte `protobuf:"bytes,2,opt,name=encryptionKey,proto3" json:"encryptionKey,omitempty"` + Permissions ACLUserPermissions `protobuf:"varint,3,opt,name=permissions,proto3,enum=aclrecord.ACLUserPermissions" json:"permissions,omitempty"` +} + +func (m *ACLUserState) Reset() { *m = ACLUserState{} } +func (m *ACLUserState) String() string { return proto.CompactTextString(m) } +func (*ACLUserState) ProtoMessage() {} +func (*ACLUserState) Descriptor() ([]byte, []int) { + return fileDescriptor_14abe0d1b4206d54, []int{7} +} +func (m *ACLUserState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ACLUserState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ACLUserState.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ACLUserState) XXX_Merge(src proto.Message) { + xxx_messageInfo_ACLUserState.Merge(m, src) +} +func (m *ACLUserState) XXX_Size() int { + return m.Size() +} +func (m *ACLUserState) XXX_DiscardUnknown() { + xxx_messageInfo_ACLUserState.DiscardUnknown(m) +} + +var xxx_messageInfo_ACLUserState proto.InternalMessageInfo + +func (m *ACLUserState) GetIdentity() []byte { + if m != nil { + return m.Identity + } + return nil +} + +func (m *ACLUserState) GetEncryptionKey() []byte { + if m != nil { + return m.EncryptionKey + } + return nil +} + +func (m *ACLUserState) GetPermissions() ACLUserPermissions { + if m != nil { + return m.Permissions + } + return ACLUserPermissions_Admin +} + +type ACLUserAdd struct { + Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` + EncryptionKey []byte `protobuf:"bytes,2,opt,name=encryptionKey,proto3" json:"encryptionKey,omitempty"` + EncryptedReadKeys [][]byte `protobuf:"bytes,3,rep,name=encryptedReadKeys,proto3" json:"encryptedReadKeys,omitempty"` + Permissions ACLUserPermissions `protobuf:"varint,4,opt,name=permissions,proto3,enum=aclrecord.ACLUserPermissions" json:"permissions,omitempty"` +} + +func (m *ACLUserAdd) Reset() { *m = ACLUserAdd{} } +func (m *ACLUserAdd) String() string { return proto.CompactTextString(m) } +func (*ACLUserAdd) ProtoMessage() {} +func (*ACLUserAdd) Descriptor() ([]byte, []int) { + return fileDescriptor_14abe0d1b4206d54, []int{8} +} +func (m *ACLUserAdd) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ACLUserAdd) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ACLUserAdd.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ACLUserAdd) XXX_Merge(src proto.Message) { + xxx_messageInfo_ACLUserAdd.Merge(m, src) +} +func (m *ACLUserAdd) XXX_Size() int { + return m.Size() +} +func (m *ACLUserAdd) XXX_DiscardUnknown() { + xxx_messageInfo_ACLUserAdd.DiscardUnknown(m) +} + +var xxx_messageInfo_ACLUserAdd proto.InternalMessageInfo + +func (m *ACLUserAdd) GetIdentity() []byte { + if m != nil { + return m.Identity + } + return nil +} + +func (m *ACLUserAdd) GetEncryptionKey() []byte { + if m != nil { + return m.EncryptionKey + } + return nil +} + +func (m *ACLUserAdd) GetEncryptedReadKeys() [][]byte { + if m != nil { + return m.EncryptedReadKeys + } + return nil +} + +func (m *ACLUserAdd) GetPermissions() ACLUserPermissions { + if m != nil { + return m.Permissions + } + return ACLUserPermissions_Admin +} + +type ACLUserInvite struct { + AcceptPublicKey []byte `protobuf:"bytes,1,opt,name=acceptPublicKey,proto3" json:"acceptPublicKey,omitempty"` + EncryptSymKeyHash uint64 `protobuf:"varint,2,opt,name=encryptSymKeyHash,proto3" json:"encryptSymKeyHash,omitempty"` + EncryptedReadKeys [][]byte `protobuf:"bytes,3,rep,name=encryptedReadKeys,proto3" json:"encryptedReadKeys,omitempty"` + Permissions ACLUserPermissions `protobuf:"varint,4,opt,name=permissions,proto3,enum=aclrecord.ACLUserPermissions" json:"permissions,omitempty"` +} + +func (m *ACLUserInvite) Reset() { *m = ACLUserInvite{} } +func (m *ACLUserInvite) String() string { return proto.CompactTextString(m) } +func (*ACLUserInvite) ProtoMessage() {} +func (*ACLUserInvite) Descriptor() ([]byte, []int) { + return fileDescriptor_14abe0d1b4206d54, []int{9} +} +func (m *ACLUserInvite) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ACLUserInvite) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ACLUserInvite.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ACLUserInvite) XXX_Merge(src proto.Message) { + xxx_messageInfo_ACLUserInvite.Merge(m, src) +} +func (m *ACLUserInvite) XXX_Size() int { + return m.Size() +} +func (m *ACLUserInvite) XXX_DiscardUnknown() { + xxx_messageInfo_ACLUserInvite.DiscardUnknown(m) +} + +var xxx_messageInfo_ACLUserInvite proto.InternalMessageInfo + +func (m *ACLUserInvite) GetAcceptPublicKey() []byte { + if m != nil { + return m.AcceptPublicKey + } + return nil +} + +func (m *ACLUserInvite) GetEncryptSymKeyHash() uint64 { + if m != nil { + return m.EncryptSymKeyHash + } + return 0 +} + +func (m *ACLUserInvite) GetEncryptedReadKeys() [][]byte { + if m != nil { + return m.EncryptedReadKeys + } + return nil +} + +func (m *ACLUserInvite) GetPermissions() ACLUserPermissions { + if m != nil { + return m.Permissions + } + return ACLUserPermissions_Admin +} + +type ACLUserJoin struct { + Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` + EncryptionKey []byte `protobuf:"bytes,2,opt,name=encryptionKey,proto3" json:"encryptionKey,omitempty"` + AcceptSignature []byte `protobuf:"bytes,3,opt,name=acceptSignature,proto3" json:"acceptSignature,omitempty"` + AcceptPubKey []byte `protobuf:"bytes,4,opt,name=acceptPubKey,proto3" json:"acceptPubKey,omitempty"` + EncryptedReadKeys [][]byte `protobuf:"bytes,5,rep,name=encryptedReadKeys,proto3" json:"encryptedReadKeys,omitempty"` +} + +func (m *ACLUserJoin) Reset() { *m = ACLUserJoin{} } +func (m *ACLUserJoin) String() string { return proto.CompactTextString(m) } +func (*ACLUserJoin) ProtoMessage() {} +func (*ACLUserJoin) Descriptor() ([]byte, []int) { + return fileDescriptor_14abe0d1b4206d54, []int{10} +} +func (m *ACLUserJoin) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ACLUserJoin) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ACLUserJoin.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ACLUserJoin) XXX_Merge(src proto.Message) { + xxx_messageInfo_ACLUserJoin.Merge(m, src) +} +func (m *ACLUserJoin) XXX_Size() int { + return m.Size() +} +func (m *ACLUserJoin) XXX_DiscardUnknown() { + xxx_messageInfo_ACLUserJoin.DiscardUnknown(m) +} + +var xxx_messageInfo_ACLUserJoin proto.InternalMessageInfo + +func (m *ACLUserJoin) GetIdentity() []byte { + if m != nil { + return m.Identity + } + return nil +} + +func (m *ACLUserJoin) GetEncryptionKey() []byte { + if m != nil { + return m.EncryptionKey + } + return nil +} + +func (m *ACLUserJoin) GetAcceptSignature() []byte { + if m != nil { + return m.AcceptSignature + } + return nil +} + +func (m *ACLUserJoin) GetAcceptPubKey() []byte { + if m != nil { + return m.AcceptPubKey + } + return nil +} + +func (m *ACLUserJoin) GetEncryptedReadKeys() [][]byte { + if m != nil { + return m.EncryptedReadKeys + } + return nil +} + +type ACLUserRemove struct { + Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` + ReadKeyReplaces []*ACLReadKeyReplace `protobuf:"bytes,2,rep,name=readKeyReplaces,proto3" json:"readKeyReplaces,omitempty"` +} + +func (m *ACLUserRemove) Reset() { *m = ACLUserRemove{} } +func (m *ACLUserRemove) String() string { return proto.CompactTextString(m) } +func (*ACLUserRemove) ProtoMessage() {} +func (*ACLUserRemove) Descriptor() ([]byte, []int) { + return fileDescriptor_14abe0d1b4206d54, []int{11} +} +func (m *ACLUserRemove) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ACLUserRemove) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ACLUserRemove.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ACLUserRemove) XXX_Merge(src proto.Message) { + xxx_messageInfo_ACLUserRemove.Merge(m, src) +} +func (m *ACLUserRemove) XXX_Size() int { + return m.Size() +} +func (m *ACLUserRemove) XXX_DiscardUnknown() { + xxx_messageInfo_ACLUserRemove.DiscardUnknown(m) +} + +var xxx_messageInfo_ACLUserRemove proto.InternalMessageInfo + +func (m *ACLUserRemove) GetIdentity() []byte { + if m != nil { + return m.Identity + } + return nil +} + +func (m *ACLUserRemove) GetReadKeyReplaces() []*ACLReadKeyReplace { + if m != nil { + return m.ReadKeyReplaces + } + return nil +} + +type ACLReadKeyReplace struct { + Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` + EncryptionKey []byte `protobuf:"bytes,2,opt,name=encryptionKey,proto3" json:"encryptionKey,omitempty"` + EncryptedReadKey []byte `protobuf:"bytes,3,opt,name=encryptedReadKey,proto3" json:"encryptedReadKey,omitempty"` +} + +func (m *ACLReadKeyReplace) Reset() { *m = ACLReadKeyReplace{} } +func (m *ACLReadKeyReplace) String() string { return proto.CompactTextString(m) } +func (*ACLReadKeyReplace) ProtoMessage() {} +func (*ACLReadKeyReplace) Descriptor() ([]byte, []int) { + return fileDescriptor_14abe0d1b4206d54, []int{12} +} +func (m *ACLReadKeyReplace) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ACLReadKeyReplace) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ACLReadKeyReplace.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ACLReadKeyReplace) XXX_Merge(src proto.Message) { + xxx_messageInfo_ACLReadKeyReplace.Merge(m, src) +} +func (m *ACLReadKeyReplace) XXX_Size() int { + return m.Size() +} +func (m *ACLReadKeyReplace) XXX_DiscardUnknown() { + xxx_messageInfo_ACLReadKeyReplace.DiscardUnknown(m) +} + +var xxx_messageInfo_ACLReadKeyReplace proto.InternalMessageInfo + +func (m *ACLReadKeyReplace) GetIdentity() []byte { + if m != nil { + return m.Identity + } + return nil +} + +func (m *ACLReadKeyReplace) GetEncryptionKey() []byte { + if m != nil { + return m.EncryptionKey + } + return nil +} + +func (m *ACLReadKeyReplace) GetEncryptedReadKey() []byte { + if m != nil { + return m.EncryptedReadKey + } + return nil +} + +type ACLUserPermissionChange struct { + Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` + Permissions ACLUserPermissions `protobuf:"varint,2,opt,name=permissions,proto3,enum=aclrecord.ACLUserPermissions" json:"permissions,omitempty"` +} + +func (m *ACLUserPermissionChange) Reset() { *m = ACLUserPermissionChange{} } +func (m *ACLUserPermissionChange) String() string { return proto.CompactTextString(m) } +func (*ACLUserPermissionChange) ProtoMessage() {} +func (*ACLUserPermissionChange) Descriptor() ([]byte, []int) { + return fileDescriptor_14abe0d1b4206d54, []int{13} +} +func (m *ACLUserPermissionChange) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ACLUserPermissionChange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ACLUserPermissionChange.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ACLUserPermissionChange) XXX_Merge(src proto.Message) { + xxx_messageInfo_ACLUserPermissionChange.Merge(m, src) +} +func (m *ACLUserPermissionChange) XXX_Size() int { + return m.Size() +} +func (m *ACLUserPermissionChange) XXX_DiscardUnknown() { + xxx_messageInfo_ACLUserPermissionChange.DiscardUnknown(m) +} + +var xxx_messageInfo_ACLUserPermissionChange proto.InternalMessageInfo + +func (m *ACLUserPermissionChange) GetIdentity() []byte { + if m != nil { + return m.Identity + } + return nil +} + +func (m *ACLUserPermissionChange) GetPermissions() ACLUserPermissions { + if m != nil { + return m.Permissions + } + return ACLUserPermissions_Admin +} + +type ACLSyncMessage struct { + Content *ACLSyncContentValue `protobuf:"bytes,2,opt,name=content,proto3" json:"content,omitempty"` +} + +func (m *ACLSyncMessage) Reset() { *m = ACLSyncMessage{} } +func (m *ACLSyncMessage) String() string { return proto.CompactTextString(m) } +func (*ACLSyncMessage) ProtoMessage() {} +func (*ACLSyncMessage) Descriptor() ([]byte, []int) { + return fileDescriptor_14abe0d1b4206d54, []int{14} +} +func (m *ACLSyncMessage) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ACLSyncMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ACLSyncMessage.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ACLSyncMessage) XXX_Merge(src proto.Message) { + xxx_messageInfo_ACLSyncMessage.Merge(m, src) +} +func (m *ACLSyncMessage) XXX_Size() int { + return m.Size() +} +func (m *ACLSyncMessage) XXX_DiscardUnknown() { + xxx_messageInfo_ACLSyncMessage.DiscardUnknown(m) +} + +var xxx_messageInfo_ACLSyncMessage proto.InternalMessageInfo + +func (m *ACLSyncMessage) GetContent() *ACLSyncContentValue { + if m != nil { + return m.Content + } + return nil +} + +// ACLSyncContentValue provides different types for acl sync +type ACLSyncContentValue struct { + // Types that are valid to be assigned to Value: + // + // *ACLSyncContentValue_AddRecords + Value isACLSyncContentValue_Value `protobuf_oneof:"value"` +} + +func (m *ACLSyncContentValue) Reset() { *m = ACLSyncContentValue{} } +func (m *ACLSyncContentValue) String() string { return proto.CompactTextString(m) } +func (*ACLSyncContentValue) ProtoMessage() {} +func (*ACLSyncContentValue) Descriptor() ([]byte, []int) { + return fileDescriptor_14abe0d1b4206d54, []int{15} +} +func (m *ACLSyncContentValue) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ACLSyncContentValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ACLSyncContentValue.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ACLSyncContentValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_ACLSyncContentValue.Merge(m, src) +} +func (m *ACLSyncContentValue) XXX_Size() int { + return m.Size() +} +func (m *ACLSyncContentValue) XXX_DiscardUnknown() { + xxx_messageInfo_ACLSyncContentValue.DiscardUnknown(m) +} + +var xxx_messageInfo_ACLSyncContentValue proto.InternalMessageInfo + +type isACLSyncContentValue_Value interface { + isACLSyncContentValue_Value() + MarshalTo([]byte) (int, error) + Size() int +} + +type ACLSyncContentValue_AddRecords struct { + AddRecords *ACLAddRecords `protobuf:"bytes,1,opt,name=addRecords,proto3,oneof" json:"addRecords,omitempty"` +} + +func (*ACLSyncContentValue_AddRecords) isACLSyncContentValue_Value() {} + +func (m *ACLSyncContentValue) GetValue() isACLSyncContentValue_Value { + if m != nil { + return m.Value + } + return nil +} + +func (m *ACLSyncContentValue) GetAddRecords() *ACLAddRecords { + if x, ok := m.GetValue().(*ACLSyncContentValue_AddRecords); ok { + return x.AddRecords + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*ACLSyncContentValue) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*ACLSyncContentValue_AddRecords)(nil), + } +} + +type ACLAddRecords struct { + Records []*RawACLRecordWithId `protobuf:"bytes,1,rep,name=records,proto3" json:"records,omitempty"` +} + +func (m *ACLAddRecords) Reset() { *m = ACLAddRecords{} } +func (m *ACLAddRecords) String() string { return proto.CompactTextString(m) } +func (*ACLAddRecords) ProtoMessage() {} +func (*ACLAddRecords) Descriptor() ([]byte, []int) { + return fileDescriptor_14abe0d1b4206d54, []int{16} +} +func (m *ACLAddRecords) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ACLAddRecords) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ACLAddRecords.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ACLAddRecords) XXX_Merge(src proto.Message) { + xxx_messageInfo_ACLAddRecords.Merge(m, src) +} +func (m *ACLAddRecords) XXX_Size() int { + return m.Size() +} +func (m *ACLAddRecords) XXX_DiscardUnknown() { + xxx_messageInfo_ACLAddRecords.DiscardUnknown(m) +} + +var xxx_messageInfo_ACLAddRecords proto.InternalMessageInfo + +func (m *ACLAddRecords) GetRecords() []*RawACLRecordWithId { + if m != nil { + return m.Records + } + return nil +} + +func init() { + proto.RegisterEnum("aclrecord.ACLUserPermissions", ACLUserPermissions_name, ACLUserPermissions_value) + proto.RegisterType((*RawACLRecord)(nil), "aclrecord.RawACLRecord") + proto.RegisterType((*RawACLRecordWithId)(nil), "aclrecord.RawACLRecordWithId") + proto.RegisterType((*ACLRecord)(nil), "aclrecord.ACLRecord") + proto.RegisterType((*ACLRoot)(nil), "aclrecord.ACLRoot") + proto.RegisterType((*ACLContentValue)(nil), "aclrecord.ACLContentValue") + proto.RegisterType((*ACLData)(nil), "aclrecord.ACLData") + proto.RegisterType((*ACLState)(nil), "aclrecord.ACLState") + proto.RegisterMapType((map[string]*ACLUserInvite)(nil), "aclrecord.ACLState.InvitesEntry") + proto.RegisterType((*ACLUserState)(nil), "aclrecord.ACLUserState") + proto.RegisterType((*ACLUserAdd)(nil), "aclrecord.ACLUserAdd") + proto.RegisterType((*ACLUserInvite)(nil), "aclrecord.ACLUserInvite") + proto.RegisterType((*ACLUserJoin)(nil), "aclrecord.ACLUserJoin") + proto.RegisterType((*ACLUserRemove)(nil), "aclrecord.ACLUserRemove") + proto.RegisterType((*ACLReadKeyReplace)(nil), "aclrecord.ACLReadKeyReplace") + proto.RegisterType((*ACLUserPermissionChange)(nil), "aclrecord.ACLUserPermissionChange") + proto.RegisterType((*ACLSyncMessage)(nil), "aclrecord.ACLSyncMessage") + proto.RegisterType((*ACLSyncContentValue)(nil), "aclrecord.ACLSyncContentValue") + proto.RegisterType((*ACLAddRecords)(nil), "aclrecord.ACLAddRecords") +} + +func init() { + proto.RegisterFile("pkg/acl/aclrecordproto/protos/aclrecord.proto", fileDescriptor_14abe0d1b4206d54) +} + +var fileDescriptor_14abe0d1b4206d54 = []byte{ + // 954 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0x4f, 0x6f, 0x1b, 0x45, + 0x14, 0xf7, 0xac, 0x9d, 0x38, 0x7e, 0x76, 0x13, 0x67, 0x80, 0x74, 0x15, 0x15, 0x2b, 0x5a, 0x71, + 0x88, 0xaa, 0xe2, 0x82, 0x41, 0x4a, 0x95, 0x03, 0xc8, 0x35, 0x45, 0x76, 0x13, 0xa4, 0x6a, 0x02, + 0x14, 0xf5, 0x36, 0xdd, 0x1d, 0x25, 0xab, 0xda, 0xbb, 0xab, 0x99, 0xb1, 0xd1, 0x1e, 0x39, 0x73, + 0x81, 0x6f, 0x00, 0x1f, 0x84, 0x3b, 0x12, 0x97, 0x5e, 0x40, 0x1c, 0x51, 0xf2, 0x31, 0xb8, 0xa0, + 0x99, 0xd9, 0xff, 0xeb, 0x44, 0x54, 0x8a, 0x7a, 0x48, 0x32, 0xf3, 0xde, 0xef, 0x4d, 0x7e, 0xef, + 0xf7, 0xde, 0xbc, 0x59, 0xf8, 0x30, 0x7a, 0x75, 0xfe, 0x90, 0xba, 0x73, 0xf5, 0xc3, 0x99, 0x1b, + 0x72, 0x2f, 0xe2, 0xa1, 0x0c, 0x1f, 0xea, 0xdf, 0x22, 0xb7, 0x0e, 0xb5, 0x01, 0x77, 0x32, 0x83, + 0xf3, 0x0b, 0x82, 0x1e, 0xa1, 0xdf, 0x8f, 0x27, 0xa7, 0x44, 0x1b, 0xb0, 0x0d, 0xed, 0x88, 0xc6, + 0xf3, 0x90, 0x7a, 0x36, 0x3a, 0x40, 0x87, 0x3d, 0x92, 0x6e, 0xf1, 0x3d, 0xe8, 0x08, 0xff, 0x3c, + 0xa0, 0x72, 0xc9, 0x99, 0x6d, 0x69, 0x5f, 0x6e, 0xc0, 0xf7, 0xa1, 0x4f, 0x5d, 0x97, 0x45, 0x32, + 0xe4, 0x33, 0x8f, 0x05, 0xd2, 0x97, 0xb1, 0xdd, 0xd4, 0xa0, 0x9a, 0x1d, 0x3f, 0x80, 0xdd, 0xd4, + 0x76, 0x96, 0x9d, 0xd8, 0xd2, 0xe0, 0xba, 0xc3, 0xf9, 0x0c, 0x70, 0x91, 0xe1, 0x73, 0x5f, 0x5e, + 0xcc, 0x6e, 0xe2, 0xb9, 0x0d, 0x96, 0xef, 0x69, 0x82, 0x1d, 0x62, 0xf9, 0x9e, 0xf3, 0x2b, 0x82, + 0x4e, 0x9e, 0xdf, 0x1e, 0x6c, 0x46, 0x9c, 0xad, 0x66, 0x26, 0xac, 0x43, 0x92, 0x1d, 0xde, 0x87, + 0x2d, 0x3f, 0xe5, 0x6d, 0x92, 0xcb, 0xf6, 0x18, 0x43, 0xcb, 0xa3, 0x92, 0x26, 0xf9, 0xe8, 0x35, + 0x1e, 0x02, 0x76, 0x97, 0x9c, 0xb3, 0x40, 0x12, 0x46, 0xbd, 0x13, 0x16, 0x4f, 0xa9, 0xb8, 0xd0, + 0x49, 0xb4, 0xc8, 0x1a, 0x8f, 0x52, 0x4f, 0xfa, 0x0b, 0x26, 0x24, 0x5d, 0x44, 0xf6, 0xc6, 0x01, + 0x3a, 0x6c, 0x92, 0xdc, 0xe0, 0xfc, 0x68, 0x41, 0x5b, 0x71, 0x0c, 0x43, 0x59, 0x62, 0x82, 0x2a, + 0x4c, 0x3e, 0x80, 0x3b, 0x2c, 0x70, 0x79, 0x1c, 0x49, 0x3f, 0x0c, 0x4e, 0x58, 0x4a, 0xb5, 0x6c, + 0x54, 0xda, 0x88, 0x88, 0xba, 0x6c, 0xe6, 0x69, 0xca, 0x1d, 0x92, 0x6e, 0x55, 0x95, 0x12, 0x28, + 0xf3, 0x12, 0x76, 0x89, 0xf0, 0x35, 0xbb, 0xc2, 0x7a, 0x8c, 0xfb, 0x2b, 0xaa, 0x8e, 0x3d, 0x73, + 0x2f, 0xd8, 0x82, 0x69, 0xe2, 0x1d, 0x52, 0xb3, 0x5f, 0xa3, 0xc6, 0xe6, 0xff, 0x53, 0xa3, 0x5d, + 0x55, 0xe3, 0x4f, 0x0b, 0x76, 0xc6, 0x93, 0xd3, 0x49, 0x18, 0x48, 0x16, 0xc8, 0x6f, 0xe9, 0x7c, + 0xc9, 0xf0, 0xc7, 0xd0, 0x5e, 0x0a, 0xc6, 0xc7, 0x9e, 0x29, 0x5c, 0x77, 0xf4, 0xde, 0x30, 0x6f, + 0xeb, 0xf1, 0xe4, 0xf4, 0x1b, 0xe3, 0x9c, 0x36, 0x48, 0x8a, 0xc3, 0xc7, 0x00, 0x6a, 0x49, 0xd8, + 0x22, 0x5c, 0x99, 0x8e, 0xed, 0x8e, 0xec, 0x7a, 0x94, 0xf1, 0x4f, 0x1b, 0xa4, 0x80, 0xc6, 0xdf, + 0xc1, 0xbb, 0x6a, 0xf7, 0x8c, 0xf1, 0x85, 0x2f, 0x84, 0x1f, 0x06, 0x93, 0x0b, 0x1a, 0x9c, 0x33, + 0xad, 0x67, 0x77, 0xe4, 0xd4, 0x4f, 0xa9, 0x22, 0xa7, 0x0d, 0xb2, 0xf6, 0x84, 0x94, 0xd5, 0x2c, + 0x58, 0xf9, 0xd2, 0x74, 0xfd, 0x5a, 0x56, 0xc6, 0x9f, 0xb2, 0x32, 0x3b, 0xfc, 0x29, 0x6c, 0xa9, + 0xdd, 0xd3, 0xd0, 0x0f, 0x74, 0x29, 0xba, 0xa3, 0xbd, 0x7a, 0xa4, 0xf2, 0x4e, 0x1b, 0x24, 0x43, + 0x3e, 0x6e, 0xc3, 0xc6, 0x4a, 0x69, 0xe8, 0x3c, 0xd1, 0x4d, 0xf6, 0x85, 0x6a, 0xdf, 0x63, 0x00, + 0xea, 0xce, 0x13, 0x85, 0x6d, 0x74, 0xd0, 0x3c, 0xec, 0x8e, 0xf6, 0xcb, 0x67, 0x15, 0xe5, 0x27, + 0x05, 0xb4, 0xf3, 0x2f, 0x82, 0xad, 0xf1, 0xe4, 0xf4, 0x4c, 0x52, 0xc9, 0x54, 0x47, 0xf2, 0xbc, + 0xb0, 0x4c, 0xe8, 0xb3, 0x5a, 0xa4, 0x6c, 0xc4, 0x47, 0x26, 0x69, 0x1d, 0x22, 0x6c, 0x4b, 0xff, + 0xbb, 0xbb, 0x75, 0xea, 0xda, 0x4f, 0x0a, 0x50, 0x7c, 0x0c, 0x6d, 0x5f, 0xe7, 0x2e, 0xec, 0xa6, + 0x8e, 0x3a, 0x28, 0x47, 0x69, 0xd8, 0xd0, 0xc8, 0x23, 0x9e, 0x04, 0x92, 0xc7, 0x24, 0x0d, 0xd8, + 0xff, 0x1a, 0x7a, 0x45, 0x07, 0xee, 0x43, 0xf3, 0x15, 0x8b, 0x93, 0x7b, 0xaf, 0x96, 0x78, 0x98, + 0x28, 0x73, 0x7d, 0x73, 0x98, 0x03, 0x88, 0x81, 0x1d, 0x5b, 0x8f, 0x90, 0xf3, 0x33, 0x82, 0x5e, + 0x91, 0xee, 0x2d, 0xdc, 0xd7, 0xcf, 0xa1, 0x1b, 0x65, 0x6d, 0x22, 0x74, 0x8f, 0x6d, 0x8f, 0xde, + 0xbf, 0xa9, 0xc7, 0x04, 0x29, 0x46, 0x38, 0xbf, 0x21, 0x80, 0xfc, 0x0e, 0xdc, 0x02, 0xa3, 0x07, + 0xb0, 0x5b, 0x9d, 0x07, 0xa6, 0x00, 0x3d, 0x52, 0x77, 0x54, 0xf9, 0xb7, 0xde, 0x98, 0xff, 0x5f, + 0x08, 0xee, 0x94, 0x04, 0xc7, 0x87, 0xb0, 0x63, 0x5e, 0x82, 0x67, 0xcb, 0x97, 0x73, 0xdf, 0x3d, + 0x61, 0x69, 0x26, 0x55, 0x73, 0x81, 0xea, 0x59, 0xbc, 0x48, 0x27, 0x8f, 0xa5, 0x27, 0x4f, 0xdd, + 0xf1, 0xb6, 0x13, 0xfb, 0x03, 0x41, 0xb7, 0x70, 0x2d, 0x6f, 0xa1, 0x32, 0x99, 0x30, 0xf9, 0xcb, + 0xd9, 0x2c, 0x0a, 0x93, 0x99, 0xb1, 0x03, 0xbd, 0x4c, 0xab, 0x7c, 0xce, 0x97, 0x6c, 0xeb, 0xe5, + 0xd8, 0xb8, 0x46, 0x0e, 0x47, 0x64, 0x55, 0x4a, 0xa6, 0xe4, 0x4d, 0xe9, 0x7c, 0x09, 0x3b, 0xc9, + 0x0c, 0x20, 0x2c, 0x9a, 0x53, 0x37, 0xbb, 0xf7, 0xf7, 0xca, 0xfa, 0x91, 0x12, 0x88, 0x54, 0x83, + 0x9c, 0x1f, 0x10, 0xec, 0xd6, 0x60, 0xb7, 0x20, 0xe4, 0xba, 0xa7, 0xb0, 0xb9, 0xfe, 0x29, 0x74, + 0x56, 0x70, 0xf7, 0x9a, 0x31, 0x7f, 0x23, 0x91, 0x4a, 0xfb, 0x58, 0x6f, 0xdc, 0x3e, 0x4f, 0x61, + 0x5b, 0xcd, 0xb8, 0x38, 0x70, 0xbf, 0x62, 0x42, 0xd0, 0x73, 0x86, 0x1f, 0x41, 0xdb, 0x4d, 0x86, + 0xb6, 0x99, 0x59, 0x83, 0xca, 0x3c, 0x8c, 0x03, 0xb7, 0x34, 0xb8, 0x53, 0xb8, 0xf3, 0x02, 0xde, + 0x59, 0xe3, 0xd7, 0x0f, 0x81, 0xe7, 0x99, 0x8f, 0x23, 0x91, 0x3c, 0xad, 0x95, 0x39, 0x38, 0xce, + 0xfc, 0xea, 0x39, 0xca, 0xd1, 0xf9, 0xc3, 0x32, 0xd5, 0x8d, 0x91, 0xe3, 0xf0, 0x11, 0xb4, 0x79, + 0x76, 0xa4, 0x2a, 0x7a, 0x31, 0xeb, 0xfa, 0xd7, 0x1c, 0x49, 0xd1, 0xf7, 0x8f, 0x00, 0xd7, 0x45, + 0xc1, 0x1d, 0xd8, 0x18, 0x7b, 0x0b, 0x3f, 0xe8, 0x37, 0x30, 0xc0, 0xe6, 0x73, 0xee, 0x4b, 0xc6, + 0xfb, 0x48, 0xad, 0x55, 0x85, 0x18, 0xef, 0x5b, 0x8f, 0x3f, 0xfa, 0xfd, 0x72, 0x80, 0x5e, 0x5f, + 0x0e, 0xd0, 0x3f, 0x97, 0x03, 0xf4, 0xd3, 0xd5, 0xa0, 0xf1, 0xfa, 0x6a, 0xd0, 0xf8, 0xfb, 0x6a, + 0xd0, 0x78, 0xb1, 0xb7, 0xfe, 0xe3, 0xf8, 0xe5, 0xa6, 0xfe, 0xf3, 0xc9, 0x7f, 0x01, 0x00, 0x00, + 0xff, 0xff, 0xa9, 0xbd, 0x7e, 0xe0, 0x3d, 0x0b, 0x00, 0x00, +} + +func (m *RawACLRecord) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RawACLRecord) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RawACLRecord) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.AcceptorSignature) > 0 { + i -= len(m.AcceptorSignature) + copy(dAtA[i:], m.AcceptorSignature) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.AcceptorSignature))) + i-- + dAtA[i] = 0x22 + } + if len(m.AcceptorIdentity) > 0 { + i -= len(m.AcceptorIdentity) + copy(dAtA[i:], m.AcceptorIdentity) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.AcceptorIdentity))) + i-- + dAtA[i] = 0x1a + } + if len(m.Signature) > 0 { + i -= len(m.Signature) + copy(dAtA[i:], m.Signature) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.Signature))) + i-- + dAtA[i] = 0x12 + } + if len(m.Payload) > 0 { + i -= len(m.Payload) + copy(dAtA[i:], m.Payload) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.Payload))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *RawACLRecordWithId) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RawACLRecordWithId) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RawACLRecordWithId) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Id) > 0 { + i -= len(m.Id) + copy(dAtA[i:], m.Id) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.Id))) + i-- + dAtA[i] = 0x12 + } + if len(m.Payload) > 0 { + i -= len(m.Payload) + copy(dAtA[i:], m.Payload) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.Payload))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ACLRecord) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ACLRecord) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ACLRecord) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Timestamp != 0 { + i = encodeVarintAclrecord(dAtA, i, uint64(m.Timestamp)) + i-- + dAtA[i] = 0x28 + } + if m.CurrentReadKeyHash != 0 { + i = encodeVarintAclrecord(dAtA, i, uint64(m.CurrentReadKeyHash)) + i-- + dAtA[i] = 0x20 + } + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0x1a + } + if len(m.Identity) > 0 { + i -= len(m.Identity) + copy(dAtA[i:], m.Identity) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.Identity))) + i-- + dAtA[i] = 0x12 + } + if len(m.PrevId) > 0 { + i -= len(m.PrevId) + copy(dAtA[i:], m.PrevId) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.PrevId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ACLRoot) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ACLRoot) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ACLRoot) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Timestamp != 0 { + i = encodeVarintAclrecord(dAtA, i, uint64(m.Timestamp)) + i-- + dAtA[i] = 0x38 + } + if m.CurrentReadKeyHash != 0 { + i = encodeVarintAclrecord(dAtA, i, uint64(m.CurrentReadKeyHash)) + i-- + dAtA[i] = 0x30 + } + if len(m.DerivationScheme) > 0 { + i -= len(m.DerivationScheme) + copy(dAtA[i:], m.DerivationScheme) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.DerivationScheme))) + i-- + dAtA[i] = 0x2a + } + if len(m.EncryptedReadKey) > 0 { + i -= len(m.EncryptedReadKey) + copy(dAtA[i:], m.EncryptedReadKey) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.EncryptedReadKey))) + i-- + dAtA[i] = 0x22 + } + if len(m.SpaceId) > 0 { + i -= len(m.SpaceId) + copy(dAtA[i:], m.SpaceId) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.SpaceId))) + i-- + dAtA[i] = 0x1a + } + if len(m.EncryptionKey) > 0 { + i -= len(m.EncryptionKey) + copy(dAtA[i:], m.EncryptionKey) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.EncryptionKey))) + i-- + dAtA[i] = 0x12 + } + if len(m.Identity) > 0 { + i -= len(m.Identity) + copy(dAtA[i:], m.Identity) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.Identity))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ACLContentValue) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ACLContentValue) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ACLContentValue) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Value != nil { + { + size := m.Value.Size() + i -= size + if _, err := m.Value.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + return len(dAtA) - i, nil +} + +func (m *ACLContentValue_UserAdd) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ACLContentValue_UserAdd) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.UserAdd != nil { + { + size, err := m.UserAdd.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAclrecord(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} +func (m *ACLContentValue_UserRemove) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ACLContentValue_UserRemove) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.UserRemove != nil { + { + size, err := m.UserRemove.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAclrecord(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + return len(dAtA) - i, nil +} +func (m *ACLContentValue_UserPermissionChange) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ACLContentValue_UserPermissionChange) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.UserPermissionChange != nil { + { + size, err := m.UserPermissionChange.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAclrecord(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + return len(dAtA) - i, nil +} +func (m *ACLContentValue_UserInvite) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ACLContentValue_UserInvite) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.UserInvite != nil { + { + size, err := m.UserInvite.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAclrecord(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + return len(dAtA) - i, nil +} +func (m *ACLContentValue_UserJoin) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ACLContentValue_UserJoin) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.UserJoin != nil { + { + size, err := m.UserJoin.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAclrecord(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + return len(dAtA) - i, nil +} +func (m *ACLData) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ACLData) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ACLData) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.AclContent) > 0 { + for iNdEx := len(m.AclContent) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.AclContent[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAclrecord(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *ACLState) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ACLState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ACLState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Invites) > 0 { + for k := range m.Invites { + v := m.Invites[k] + baseI := i + if v != nil { + { + size, err := v.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAclrecord(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + i -= len(k) + copy(dAtA[i:], k) + i = encodeVarintAclrecord(dAtA, i, uint64(len(k))) + i-- + dAtA[i] = 0xa + i = encodeVarintAclrecord(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x1a + } + } + if len(m.UserStates) > 0 { + for iNdEx := len(m.UserStates) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.UserStates[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAclrecord(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.ReadKeyHashes) > 0 { + dAtA8 := make([]byte, len(m.ReadKeyHashes)*10) + var j7 int + for _, num := range m.ReadKeyHashes { + for num >= 1<<7 { + dAtA8[j7] = uint8(uint64(num)&0x7f | 0x80) + num >>= 7 + j7++ + } + dAtA8[j7] = uint8(num) + j7++ + } + i -= j7 + copy(dAtA[i:], dAtA8[:j7]) + i = encodeVarintAclrecord(dAtA, i, uint64(j7)) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ACLUserState) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ACLUserState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ACLUserState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Permissions != 0 { + i = encodeVarintAclrecord(dAtA, i, uint64(m.Permissions)) + i-- + dAtA[i] = 0x18 + } + if len(m.EncryptionKey) > 0 { + i -= len(m.EncryptionKey) + copy(dAtA[i:], m.EncryptionKey) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.EncryptionKey))) + i-- + dAtA[i] = 0x12 + } + if len(m.Identity) > 0 { + i -= len(m.Identity) + copy(dAtA[i:], m.Identity) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.Identity))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ACLUserAdd) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ACLUserAdd) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ACLUserAdd) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Permissions != 0 { + i = encodeVarintAclrecord(dAtA, i, uint64(m.Permissions)) + i-- + dAtA[i] = 0x20 + } + if len(m.EncryptedReadKeys) > 0 { + for iNdEx := len(m.EncryptedReadKeys) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.EncryptedReadKeys[iNdEx]) + copy(dAtA[i:], m.EncryptedReadKeys[iNdEx]) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.EncryptedReadKeys[iNdEx]))) + i-- + dAtA[i] = 0x1a + } + } + if len(m.EncryptionKey) > 0 { + i -= len(m.EncryptionKey) + copy(dAtA[i:], m.EncryptionKey) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.EncryptionKey))) + i-- + dAtA[i] = 0x12 + } + if len(m.Identity) > 0 { + i -= len(m.Identity) + copy(dAtA[i:], m.Identity) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.Identity))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ACLUserInvite) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ACLUserInvite) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ACLUserInvite) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Permissions != 0 { + i = encodeVarintAclrecord(dAtA, i, uint64(m.Permissions)) + i-- + dAtA[i] = 0x20 + } + if len(m.EncryptedReadKeys) > 0 { + for iNdEx := len(m.EncryptedReadKeys) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.EncryptedReadKeys[iNdEx]) + copy(dAtA[i:], m.EncryptedReadKeys[iNdEx]) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.EncryptedReadKeys[iNdEx]))) + i-- + dAtA[i] = 0x1a + } + } + if m.EncryptSymKeyHash != 0 { + i = encodeVarintAclrecord(dAtA, i, uint64(m.EncryptSymKeyHash)) + i-- + dAtA[i] = 0x10 + } + if len(m.AcceptPublicKey) > 0 { + i -= len(m.AcceptPublicKey) + copy(dAtA[i:], m.AcceptPublicKey) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.AcceptPublicKey))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ACLUserJoin) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ACLUserJoin) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ACLUserJoin) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.EncryptedReadKeys) > 0 { + for iNdEx := len(m.EncryptedReadKeys) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.EncryptedReadKeys[iNdEx]) + copy(dAtA[i:], m.EncryptedReadKeys[iNdEx]) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.EncryptedReadKeys[iNdEx]))) + i-- + dAtA[i] = 0x2a + } + } + if len(m.AcceptPubKey) > 0 { + i -= len(m.AcceptPubKey) + copy(dAtA[i:], m.AcceptPubKey) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.AcceptPubKey))) + i-- + dAtA[i] = 0x22 + } + if len(m.AcceptSignature) > 0 { + i -= len(m.AcceptSignature) + copy(dAtA[i:], m.AcceptSignature) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.AcceptSignature))) + i-- + dAtA[i] = 0x1a + } + if len(m.EncryptionKey) > 0 { + i -= len(m.EncryptionKey) + copy(dAtA[i:], m.EncryptionKey) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.EncryptionKey))) + i-- + dAtA[i] = 0x12 + } + if len(m.Identity) > 0 { + i -= len(m.Identity) + copy(dAtA[i:], m.Identity) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.Identity))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ACLUserRemove) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ACLUserRemove) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ACLUserRemove) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ReadKeyReplaces) > 0 { + for iNdEx := len(m.ReadKeyReplaces) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ReadKeyReplaces[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAclrecord(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.Identity) > 0 { + i -= len(m.Identity) + copy(dAtA[i:], m.Identity) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.Identity))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ACLReadKeyReplace) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ACLReadKeyReplace) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ACLReadKeyReplace) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.EncryptedReadKey) > 0 { + i -= len(m.EncryptedReadKey) + copy(dAtA[i:], m.EncryptedReadKey) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.EncryptedReadKey))) + i-- + dAtA[i] = 0x1a + } + if len(m.EncryptionKey) > 0 { + i -= len(m.EncryptionKey) + copy(dAtA[i:], m.EncryptionKey) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.EncryptionKey))) + i-- + dAtA[i] = 0x12 + } + if len(m.Identity) > 0 { + i -= len(m.Identity) + copy(dAtA[i:], m.Identity) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.Identity))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ACLUserPermissionChange) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ACLUserPermissionChange) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ACLUserPermissionChange) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Permissions != 0 { + i = encodeVarintAclrecord(dAtA, i, uint64(m.Permissions)) + i-- + dAtA[i] = 0x10 + } + if len(m.Identity) > 0 { + i -= len(m.Identity) + copy(dAtA[i:], m.Identity) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.Identity))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ACLSyncMessage) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ACLSyncMessage) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ACLSyncMessage) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Content != nil { + { + size, err := m.Content.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAclrecord(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + return len(dAtA) - i, nil +} + +func (m *ACLSyncContentValue) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ACLSyncContentValue) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ACLSyncContentValue) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Value != nil { + { + size := m.Value.Size() + i -= size + if _, err := m.Value.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + return len(dAtA) - i, nil +} + +func (m *ACLSyncContentValue_AddRecords) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ACLSyncContentValue_AddRecords) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.AddRecords != nil { + { + size, err := m.AddRecords.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAclrecord(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} +func (m *ACLAddRecords) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ACLAddRecords) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ACLAddRecords) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Records) > 0 { + for iNdEx := len(m.Records) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Records[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAclrecord(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintAclrecord(dAtA []byte, offset int, v uint64) int { + offset -= sovAclrecord(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *RawACLRecord) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Payload) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + l = len(m.Signature) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + l = len(m.AcceptorIdentity) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + l = len(m.AcceptorSignature) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + return n +} + +func (m *RawACLRecordWithId) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Payload) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + l = len(m.Id) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + return n +} + +func (m *ACLRecord) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PrevId) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + l = len(m.Identity) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + l = len(m.Data) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + if m.CurrentReadKeyHash != 0 { + n += 1 + sovAclrecord(uint64(m.CurrentReadKeyHash)) + } + if m.Timestamp != 0 { + n += 1 + sovAclrecord(uint64(m.Timestamp)) + } + return n +} + +func (m *ACLRoot) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Identity) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + l = len(m.EncryptionKey) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + l = len(m.SpaceId) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + l = len(m.EncryptedReadKey) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + l = len(m.DerivationScheme) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + if m.CurrentReadKeyHash != 0 { + n += 1 + sovAclrecord(uint64(m.CurrentReadKeyHash)) + } + if m.Timestamp != 0 { + n += 1 + sovAclrecord(uint64(m.Timestamp)) + } + return n +} + +func (m *ACLContentValue) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Value != nil { + n += m.Value.Size() + } + return n +} + +func (m *ACLContentValue_UserAdd) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.UserAdd != nil { + l = m.UserAdd.Size() + n += 1 + l + sovAclrecord(uint64(l)) + } + return n +} +func (m *ACLContentValue_UserRemove) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.UserRemove != nil { + l = m.UserRemove.Size() + n += 1 + l + sovAclrecord(uint64(l)) + } + return n +} +func (m *ACLContentValue_UserPermissionChange) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.UserPermissionChange != nil { + l = m.UserPermissionChange.Size() + n += 1 + l + sovAclrecord(uint64(l)) + } + return n +} +func (m *ACLContentValue_UserInvite) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.UserInvite != nil { + l = m.UserInvite.Size() + n += 1 + l + sovAclrecord(uint64(l)) + } + return n +} +func (m *ACLContentValue_UserJoin) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.UserJoin != nil { + l = m.UserJoin.Size() + n += 1 + l + sovAclrecord(uint64(l)) + } + return n +} +func (m *ACLData) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.AclContent) > 0 { + for _, e := range m.AclContent { + l = e.Size() + n += 1 + l + sovAclrecord(uint64(l)) + } + } + return n +} + +func (m *ACLState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.ReadKeyHashes) > 0 { + l = 0 + for _, e := range m.ReadKeyHashes { + l += sovAclrecord(uint64(e)) + } + n += 1 + sovAclrecord(uint64(l)) + l + } + if len(m.UserStates) > 0 { + for _, e := range m.UserStates { + l = e.Size() + n += 1 + l + sovAclrecord(uint64(l)) + } + } + if len(m.Invites) > 0 { + for k, v := range m.Invites { + _ = k + _ = v + l = 0 + if v != nil { + l = v.Size() + l += 1 + sovAclrecord(uint64(l)) + } + mapEntrySize := 1 + len(k) + sovAclrecord(uint64(len(k))) + l + n += mapEntrySize + 1 + sovAclrecord(uint64(mapEntrySize)) + } + } + return n +} + +func (m *ACLUserState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Identity) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + l = len(m.EncryptionKey) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + if m.Permissions != 0 { + n += 1 + sovAclrecord(uint64(m.Permissions)) + } + return n +} + +func (m *ACLUserAdd) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Identity) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + l = len(m.EncryptionKey) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + if len(m.EncryptedReadKeys) > 0 { + for _, b := range m.EncryptedReadKeys { + l = len(b) + n += 1 + l + sovAclrecord(uint64(l)) + } + } + if m.Permissions != 0 { + n += 1 + sovAclrecord(uint64(m.Permissions)) + } + return n +} + +func (m *ACLUserInvite) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.AcceptPublicKey) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + if m.EncryptSymKeyHash != 0 { + n += 1 + sovAclrecord(uint64(m.EncryptSymKeyHash)) + } + if len(m.EncryptedReadKeys) > 0 { + for _, b := range m.EncryptedReadKeys { + l = len(b) + n += 1 + l + sovAclrecord(uint64(l)) + } + } + if m.Permissions != 0 { + n += 1 + sovAclrecord(uint64(m.Permissions)) + } + return n +} + +func (m *ACLUserJoin) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Identity) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + l = len(m.EncryptionKey) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + l = len(m.AcceptSignature) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + l = len(m.AcceptPubKey) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + if len(m.EncryptedReadKeys) > 0 { + for _, b := range m.EncryptedReadKeys { + l = len(b) + n += 1 + l + sovAclrecord(uint64(l)) + } + } + return n +} + +func (m *ACLUserRemove) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Identity) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + if len(m.ReadKeyReplaces) > 0 { + for _, e := range m.ReadKeyReplaces { + l = e.Size() + n += 1 + l + sovAclrecord(uint64(l)) + } + } + return n +} + +func (m *ACLReadKeyReplace) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Identity) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + l = len(m.EncryptionKey) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + l = len(m.EncryptedReadKey) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + return n +} + +func (m *ACLUserPermissionChange) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Identity) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + if m.Permissions != 0 { + n += 1 + sovAclrecord(uint64(m.Permissions)) + } + return n +} + +func (m *ACLSyncMessage) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Content != nil { + l = m.Content.Size() + n += 1 + l + sovAclrecord(uint64(l)) + } + return n +} + +func (m *ACLSyncContentValue) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Value != nil { + n += m.Value.Size() + } + return n +} + +func (m *ACLSyncContentValue_AddRecords) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.AddRecords != nil { + l = m.AddRecords.Size() + n += 1 + l + sovAclrecord(uint64(l)) + } + return n +} +func (m *ACLAddRecords) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Records) > 0 { + for _, e := range m.Records { + l = e.Size() + n += 1 + l + sovAclrecord(uint64(l)) + } + } + return n +} + +func sovAclrecord(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozAclrecord(x uint64) (n int) { + return sovAclrecord(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *RawACLRecord) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RawACLRecord: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RawACLRecord: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Payload", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Payload = append(m.Payload[:0], dAtA[iNdEx:postIndex]...) + if m.Payload == nil { + m.Payload = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signature = append(m.Signature[:0], dAtA[iNdEx:postIndex]...) + if m.Signature == nil { + m.Signature = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AcceptorIdentity", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AcceptorIdentity = append(m.AcceptorIdentity[:0], dAtA[iNdEx:postIndex]...) + if m.AcceptorIdentity == nil { + m.AcceptorIdentity = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AcceptorSignature", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AcceptorSignature = append(m.AcceptorSignature[:0], dAtA[iNdEx:postIndex]...) + if m.AcceptorSignature == nil { + m.AcceptorSignature = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAclrecord(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAclrecord + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RawACLRecordWithId) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RawACLRecordWithId: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RawACLRecordWithId: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Payload", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Payload = append(m.Payload[:0], dAtA[iNdEx:postIndex]...) + if m.Payload == nil { + m.Payload = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Id = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAclrecord(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAclrecord + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ACLRecord) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ACLRecord: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ACLRecord: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PrevId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PrevId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Identity", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Identity = append(m.Identity[:0], dAtA[iNdEx:postIndex]...) + if m.Identity == nil { + m.Identity = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CurrentReadKeyHash", wireType) + } + m.CurrentReadKeyHash = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CurrentReadKeyHash |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) + } + m.Timestamp = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Timestamp |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipAclrecord(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAclrecord + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ACLRoot) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ACLRoot: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ACLRoot: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Identity", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Identity = append(m.Identity[:0], dAtA[iNdEx:postIndex]...) + if m.Identity == nil { + m.Identity = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EncryptionKey", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.EncryptionKey = append(m.EncryptionKey[:0], dAtA[iNdEx:postIndex]...) + if m.EncryptionKey == nil { + m.EncryptionKey = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SpaceId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SpaceId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EncryptedReadKey", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.EncryptedReadKey = append(m.EncryptedReadKey[:0], dAtA[iNdEx:postIndex]...) + if m.EncryptedReadKey == nil { + m.EncryptedReadKey = []byte{} + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DerivationScheme", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DerivationScheme = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CurrentReadKeyHash", wireType) + } + m.CurrentReadKeyHash = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CurrentReadKeyHash |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) + } + m.Timestamp = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Timestamp |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipAclrecord(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAclrecord + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ACLContentValue) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ACLContentValue: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ACLContentValue: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UserAdd", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &ACLUserAdd{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Value = &ACLContentValue_UserAdd{v} + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UserRemove", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &ACLUserRemove{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Value = &ACLContentValue_UserRemove{v} + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UserPermissionChange", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &ACLUserPermissionChange{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Value = &ACLContentValue_UserPermissionChange{v} + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UserInvite", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &ACLUserInvite{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Value = &ACLContentValue_UserInvite{v} + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UserJoin", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &ACLUserJoin{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Value = &ACLContentValue_UserJoin{v} + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAclrecord(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAclrecord + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ACLData) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ACLData: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ACLData: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AclContent", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AclContent = append(m.AclContent, &ACLContentValue{}) + if err := m.AclContent[len(m.AclContent)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAclrecord(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAclrecord + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ACLState) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ACLState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ACLState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType == 0 { + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.ReadKeyHashes = append(m.ReadKeyHashes, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + var count int + for _, integer := range dAtA[iNdEx:postIndex] { + if integer < 128 { + count++ + } + } + elementCount = count + if elementCount != 0 && len(m.ReadKeyHashes) == 0 { + m.ReadKeyHashes = make([]uint64, 0, elementCount) + } + for iNdEx < postIndex { + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.ReadKeyHashes = append(m.ReadKeyHashes, v) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field ReadKeyHashes", wireType) + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UserStates", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UserStates = append(m.UserStates, &ACLUserState{}) + if err := m.UserStates[len(m.UserStates)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Invites", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Invites == nil { + m.Invites = make(map[string]*ACLUserInvite) + } + var mapkey string + var mapvalue *ACLUserInvite + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthAclrecord + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthAclrecord + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return ErrInvalidLengthAclrecord + } + postmsgIndex := iNdEx + mapmsglen + if postmsgIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postmsgIndex > l { + return io.ErrUnexpectedEOF + } + mapvalue = &ACLUserInvite{} + if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { + return err + } + iNdEx = postmsgIndex + } else { + iNdEx = entryPreIndex + skippy, err := skipAclrecord(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAclrecord + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.Invites[mapkey] = mapvalue + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAclrecord(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAclrecord + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ACLUserState) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ACLUserState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ACLUserState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Identity", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Identity = append(m.Identity[:0], dAtA[iNdEx:postIndex]...) + if m.Identity == nil { + m.Identity = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EncryptionKey", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.EncryptionKey = append(m.EncryptionKey[:0], dAtA[iNdEx:postIndex]...) + if m.EncryptionKey == nil { + m.EncryptionKey = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Permissions", wireType) + } + m.Permissions = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Permissions |= ACLUserPermissions(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipAclrecord(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAclrecord + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ACLUserAdd) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ACLUserAdd: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ACLUserAdd: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Identity", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Identity = append(m.Identity[:0], dAtA[iNdEx:postIndex]...) + if m.Identity == nil { + m.Identity = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EncryptionKey", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.EncryptionKey = append(m.EncryptionKey[:0], dAtA[iNdEx:postIndex]...) + if m.EncryptionKey == nil { + m.EncryptionKey = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EncryptedReadKeys", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.EncryptedReadKeys = append(m.EncryptedReadKeys, make([]byte, postIndex-iNdEx)) + copy(m.EncryptedReadKeys[len(m.EncryptedReadKeys)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Permissions", wireType) + } + m.Permissions = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Permissions |= ACLUserPermissions(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipAclrecord(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAclrecord + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ACLUserInvite) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ACLUserInvite: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ACLUserInvite: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AcceptPublicKey", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AcceptPublicKey = append(m.AcceptPublicKey[:0], dAtA[iNdEx:postIndex]...) + if m.AcceptPublicKey == nil { + m.AcceptPublicKey = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EncryptSymKeyHash", wireType) + } + m.EncryptSymKeyHash = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.EncryptSymKeyHash |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EncryptedReadKeys", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.EncryptedReadKeys = append(m.EncryptedReadKeys, make([]byte, postIndex-iNdEx)) + copy(m.EncryptedReadKeys[len(m.EncryptedReadKeys)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Permissions", wireType) + } + m.Permissions = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Permissions |= ACLUserPermissions(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipAclrecord(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAclrecord + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ACLUserJoin) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ACLUserJoin: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ACLUserJoin: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Identity", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Identity = append(m.Identity[:0], dAtA[iNdEx:postIndex]...) + if m.Identity == nil { + m.Identity = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EncryptionKey", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.EncryptionKey = append(m.EncryptionKey[:0], dAtA[iNdEx:postIndex]...) + if m.EncryptionKey == nil { + m.EncryptionKey = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AcceptSignature", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AcceptSignature = append(m.AcceptSignature[:0], dAtA[iNdEx:postIndex]...) + if m.AcceptSignature == nil { + m.AcceptSignature = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AcceptPubKey", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AcceptPubKey = append(m.AcceptPubKey[:0], dAtA[iNdEx:postIndex]...) + if m.AcceptPubKey == nil { + m.AcceptPubKey = []byte{} + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EncryptedReadKeys", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.EncryptedReadKeys = append(m.EncryptedReadKeys, make([]byte, postIndex-iNdEx)) + copy(m.EncryptedReadKeys[len(m.EncryptedReadKeys)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAclrecord(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAclrecord + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ACLUserRemove) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ACLUserRemove: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ACLUserRemove: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Identity", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Identity = append(m.Identity[:0], dAtA[iNdEx:postIndex]...) + if m.Identity == nil { + m.Identity = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ReadKeyReplaces", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ReadKeyReplaces = append(m.ReadKeyReplaces, &ACLReadKeyReplace{}) + if err := m.ReadKeyReplaces[len(m.ReadKeyReplaces)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAclrecord(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAclrecord + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ACLReadKeyReplace) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ACLReadKeyReplace: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ACLReadKeyReplace: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Identity", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Identity = append(m.Identity[:0], dAtA[iNdEx:postIndex]...) + if m.Identity == nil { + m.Identity = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EncryptionKey", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.EncryptionKey = append(m.EncryptionKey[:0], dAtA[iNdEx:postIndex]...) + if m.EncryptionKey == nil { + m.EncryptionKey = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EncryptedReadKey", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.EncryptedReadKey = append(m.EncryptedReadKey[:0], dAtA[iNdEx:postIndex]...) + if m.EncryptedReadKey == nil { + m.EncryptedReadKey = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAclrecord(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAclrecord + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ACLUserPermissionChange) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ACLUserPermissionChange: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ACLUserPermissionChange: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Identity", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Identity = append(m.Identity[:0], dAtA[iNdEx:postIndex]...) + if m.Identity == nil { + m.Identity = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Permissions", wireType) + } + m.Permissions = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Permissions |= ACLUserPermissions(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipAclrecord(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAclrecord + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ACLSyncMessage) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ACLSyncMessage: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ACLSyncMessage: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Content", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Content == nil { + m.Content = &ACLSyncContentValue{} + } + if err := m.Content.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAclrecord(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAclrecord + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ACLSyncContentValue) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ACLSyncContentValue: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ACLSyncContentValue: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AddRecords", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &ACLAddRecords{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Value = &ACLSyncContentValue_AddRecords{v} + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAclrecord(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAclrecord + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ACLAddRecords) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ACLAddRecords: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ACLAddRecords: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Records", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAclrecord + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Records = append(m.Records, &RawACLRecordWithId{}) + if err := m.Records[len(m.Records)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAclrecord(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAclrecord + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipAclrecord(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowAclrecord + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowAclrecord + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowAclrecord + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthAclrecord + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupAclrecord + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthAclrecord + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthAclrecord = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowAclrecord = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupAclrecord = fmt.Errorf("proto: unexpected end of group") +) diff --git a/common/pkg/acl/aclrecordproto/protos/aclrecord.proto b/common/pkg/acl/aclrecordproto/protos/aclrecord.proto new file mode 100644 index 00000000..51f74853 --- /dev/null +++ b/common/pkg/acl/aclrecordproto/protos/aclrecord.proto @@ -0,0 +1,118 @@ +syntax = "proto3"; +package aclrecord; +option go_package = "pkg/acl/aclrecordproto"; + +message RawACLRecord { + bytes payload = 1; + bytes signature = 2; + bytes acceptorIdentity = 3; + bytes acceptorSignature = 4; +} + +message RawACLRecordWithId { + bytes payload = 1; + string id = 2; +} + +message ACLRecord { + string prevId = 1; + bytes identity = 2; + bytes data = 3; + uint64 currentReadKeyHash = 4; + int64 timestamp = 5; +} + +message ACLRoot { + bytes identity = 1; + bytes encryptionKey = 2; + string spaceId = 3; + bytes encryptedReadKey = 4; + string derivationScheme = 5; + uint64 currentReadKeyHash = 6; + int64 timestamp = 7; +} + +message ACLContentValue { + oneof value { + ACLUserAdd userAdd = 1; + ACLUserRemove userRemove = 2; + ACLUserPermissionChange userPermissionChange = 3; + ACLUserInvite userInvite = 4; + ACLUserJoin userJoin = 5; + } +} + +message ACLData { + repeated ACLContentValue aclContent = 1; +} + +message ACLState { + repeated uint64 readKeyHashes = 1; + repeated ACLUserState userStates = 2; + map invites = 3; +} + +message ACLUserState { + bytes identity = 1; + bytes encryptionKey = 2; + ACLUserPermissions permissions = 3; +} + +message ACLUserAdd { + bytes identity = 1; + bytes encryptionKey = 2; + repeated bytes encryptedReadKeys = 3; + ACLUserPermissions permissions = 4; +} + +message ACLUserInvite { + bytes acceptPublicKey = 1; + uint64 encryptSymKeyHash = 2; + repeated bytes encryptedReadKeys = 3; + ACLUserPermissions permissions = 4; +} + +message ACLUserJoin { + bytes identity = 1; + bytes encryptionKey = 2; + bytes acceptSignature = 3; + bytes acceptPubKey = 4; + repeated bytes encryptedReadKeys = 5; +} + +message ACLUserRemove { + bytes identity = 1; + repeated ACLReadKeyReplace readKeyReplaces = 2; +} + +message ACLReadKeyReplace { + bytes identity = 1; + bytes encryptionKey = 2; + bytes encryptedReadKey = 3; +} + +message ACLUserPermissionChange { + bytes identity = 1; + ACLUserPermissions permissions = 2; +} + +enum ACLUserPermissions { + Admin = 0; + Writer = 1; + Reader = 2; +} + +message ACLSyncMessage { + ACLSyncContentValue content = 2; +} + +// ACLSyncContentValue provides different types for acl sync +message ACLSyncContentValue { + oneof value { + ACLAddRecords addRecords = 1; + } +} + +message ACLAddRecords { + repeated RawACLRecordWithId records = 1; +} \ No newline at end of file diff --git a/common/pkg/acl/common/keychain.go b/common/pkg/acl/common/keychain.go new file mode 100644 index 00000000..b6de00b2 --- /dev/null +++ b/common/pkg/acl/common/keychain.go @@ -0,0 +1,28 @@ +package common + +import ( + signingkey2 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/signingkey" +) + +type Keychain struct { + keys map[string]signingkey2.PubKey +} + +func NewKeychain() *Keychain { + return &Keychain{ + keys: make(map[string]signingkey2.PubKey), + } +} + +func (k *Keychain) GetOrAdd(identity string) (signingkey2.PubKey, error) { + if key, exists := k.keys[identity]; exists { + return key, nil + } + res, err := signingkey2.NewSigningEd25519PubKeyFromBytes([]byte(identity)) + if err != nil { + return nil, err + } + + k.keys[identity] = res.(signingkey2.PubKey) + return res.(signingkey2.PubKey), nil +} diff --git a/common/pkg/acl/list/aclrecordbuilder.go b/common/pkg/acl/list/aclrecordbuilder.go new file mode 100644 index 00000000..bb99f7bc --- /dev/null +++ b/common/pkg/acl/list/aclrecordbuilder.go @@ -0,0 +1,177 @@ +package list + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/common" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/cid" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/signingkey" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/symmetric" + "github.com/gogo/protobuf/proto" + "time" +) + +// remove interface +type ACLRecordBuilder interface { + ConvertFromRaw(rawIdRecord *aclrecordproto.RawACLRecordWithId) (rec *ACLRecord, err error) + BuildUserJoin(acceptPrivKeyBytes []byte, encSymKeyBytes []byte, state *ACLState) (rec *aclrecordproto.RawACLRecord, err error) +} + +type aclRecordBuilder struct { + id string + keychain *common.Keychain +} + +func newACLRecordBuilder(id string, keychain *common.Keychain) ACLRecordBuilder { + return &aclRecordBuilder{ + id: id, + keychain: keychain, + } +} + +func (a *aclRecordBuilder) BuildUserJoin(acceptPrivKeyBytes []byte, encSymKeyBytes []byte, state *ACLState) (rec *aclrecordproto.RawACLRecord, err error) { + acceptPrivKey, err := signingkey.NewSigningEd25519PrivKeyFromBytes(acceptPrivKeyBytes) + if err != nil { + return + } + acceptPubKeyBytes, err := acceptPrivKey.GetPublic().Raw() + if err != nil { + return + } + encSymKey, err := symmetric.FromBytes(encSymKeyBytes) + if err != nil { + return + } + + invite, err := state.Invite(acceptPubKeyBytes) + if err != nil { + return + } + + encPrivKey, signPrivKey := state.UserKeys() + var symKeys [][]byte + for _, rk := range invite.EncryptedReadKeys { + dec, err := encSymKey.Decrypt(rk) + if err != nil { + return nil, err + } + newEnc, err := encPrivKey.GetPublic().Encrypt(dec) + if err != nil { + return nil, err + } + symKeys = append(symKeys, newEnc) + } + idSignature, err := acceptPrivKey.Sign(state.Identity()) + if err != nil { + return + } + encPubKeyBytes, err := encPrivKey.GetPublic().Raw() + if err != nil { + return + } + + userJoin := &aclrecordproto.ACLUserJoin{ + Identity: state.Identity(), + EncryptionKey: encPubKeyBytes, + AcceptSignature: idSignature, + AcceptPubKey: acceptPubKeyBytes, + EncryptedReadKeys: symKeys, + } + aclData := &aclrecordproto.ACLData{AclContent: []*aclrecordproto.ACLContentValue{ + {Value: &aclrecordproto.ACLContentValue_UserJoin{UserJoin: userJoin}}, + }} + marshalledJoin, err := aclData.Marshal() + if err != nil { + return + } + aclRecord := &aclrecordproto.ACLRecord{ + PrevId: state.LastRecordId(), + Identity: state.Identity(), + Data: marshalledJoin, + CurrentReadKeyHash: state.CurrentReadKeyHash(), + Timestamp: time.Now().UnixNano(), + } + marshalledRecord, err := aclRecord.Marshal() + if err != nil { + return + } + recSignature, err := signPrivKey.Sign(marshalledRecord) + if err != nil { + return + } + rec = &aclrecordproto.RawACLRecord{ + Payload: marshalledRecord, + Signature: recSignature, + } + return +} + +func (a *aclRecordBuilder) ConvertFromRaw(rawIdRecord *aclrecordproto.RawACLRecordWithId) (rec *ACLRecord, err error) { + rawRec := &aclrecordproto.RawACLRecord{} + err = proto.Unmarshal(rawIdRecord.Payload, rawRec) + if err != nil { + return + } + + if rawIdRecord.Id == a.id { + aclRoot := &aclrecordproto.ACLRoot{} + err = proto.Unmarshal(rawRec.Payload, aclRoot) + if err != nil { + return + } + + rec = &ACLRecord{ + Id: rawIdRecord.Id, + CurrentReadKeyHash: aclRoot.CurrentReadKeyHash, + Timestamp: aclRoot.Timestamp, + Signature: rawRec.Signature, + Identity: aclRoot.Identity, + Model: aclRoot, + } + } else { + aclRecord := &aclrecordproto.ACLRecord{} + err = proto.Unmarshal(rawRec.Payload, aclRecord) + if err != nil { + return + } + + rec = &ACLRecord{ + Id: rawIdRecord.Id, + PrevId: aclRecord.PrevId, + CurrentReadKeyHash: aclRecord.CurrentReadKeyHash, + Timestamp: aclRecord.Timestamp, + Data: aclRecord.Data, + Signature: rawRec.Signature, + Identity: aclRecord.Identity, + } + } + + err = verifyRaw(a.keychain, rawRec, rawIdRecord, rec.Identity) + return +} + +func verifyRaw( + keychain *common.Keychain, + rawRec *aclrecordproto.RawACLRecord, + recWithId *aclrecordproto.RawACLRecordWithId, + identity []byte) (err error) { + identityKey, err := keychain.GetOrAdd(string(identity)) + if err != nil { + return + } + + // verifying signature + res, err := identityKey.Verify(rawRec.Payload, rawRec.Signature) + if err != nil { + return + } + if !res { + err = ErrInvalidSignature + return + } + + // verifying ID + if !cid.VerifyCID(recWithId.Payload, recWithId.Id) { + err = ErrIncorrectCID + } + return +} diff --git a/common/pkg/acl/list/aclrecordbuilder_test.go b/common/pkg/acl/list/aclrecordbuilder_test.go new file mode 100644 index 00000000..a804bcb4 --- /dev/null +++ b/common/pkg/acl/list/aclrecordbuilder_test.go @@ -0,0 +1,50 @@ +package list + +import ( + account "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/account" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/common" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/testutils/acllistbuilder" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/cid" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/signingkey" + "github.com/stretchr/testify/require" + "testing" +) + +func TestAclRecordBuilder_BuildUserJoin(t *testing.T) { + st, err := acllistbuilder.NewListStorageWithTestName("userjoinexample.yml") + require.NoError(t, err, "building storage should not result in error") + + keychain := st.(*acllistbuilder.ACLListStorageBuilder).GetKeychain() + identity := keychain.GeneratedIdentities["D"] + signPrivKey := keychain.SigningKeysByYAMLName["D"] + encPrivKey := keychain.EncryptionKeysByYAMLName["D"] + acc := &account.AccountData{ + Identity: []byte(identity), + SignKey: signPrivKey, + EncKey: encPrivKey, + } + + aclList, err := BuildACLListWithIdentity(acc, st) + require.NoError(t, err, "building acl list should be without error") + recordBuilder := newACLRecordBuilder(aclList.ID(), common.NewKeychain()) + rk, err := keychain.GetKey("key.Read.EncKey").(*acllistbuilder.SymKey).Key.Raw() + require.NoError(t, err) + privKey, err := keychain.GetKey("key.Sign.Onetime1").(signingkey.PrivKey).Raw() + require.NoError(t, err) + + userJoin, err := recordBuilder.BuildUserJoin(privKey, rk, aclList.ACLState()) + require.NoError(t, err) + marshalledJoin, err := userJoin.Marshal() + require.NoError(t, err) + id, err := cid.NewCIDFromBytes(marshalledJoin) + require.NoError(t, err) + rawRec := &aclrecordproto.RawACLRecordWithId{ + Payload: marshalledJoin, + Id: id, + } + res, err := aclList.AddRawRecord(rawRec) + require.True(t, res) + require.NoError(t, err) + require.Equal(t, aclrecordproto.ACLUserPermissions_Writer, aclList.ACLState().UserStates()[identity].Permissions) +} diff --git a/common/pkg/acl/list/aclstate.go b/common/pkg/acl/list/aclstate.go new file mode 100644 index 00000000..94754aba --- /dev/null +++ b/common/pkg/acl/list/aclstate.go @@ -0,0 +1,462 @@ +package list + +import ( + "bytes" + "errors" + "fmt" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/common" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/encryptionkey" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/signingkey" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/symmetric" + "github.com/gogo/protobuf/proto" + "go.uber.org/zap" + "hash/fnv" +) + +var log = logger.NewNamed("acllist").Sugar() + +var ErrNoSuchUser = errors.New("no such user") +var ErrFailedToDecrypt = errors.New("failed to decrypt key") +var ErrUserRemoved = errors.New("user was removed from the document") +var ErrDocumentForbidden = errors.New("your user was forbidden access to the document") +var ErrUserAlreadyExists = errors.New("user already exists") +var ErrNoSuchRecord = errors.New("no such record") +var ErrNoSuchInvite = errors.New("no such invite") +var ErrOldInvite = errors.New("invite is too old") +var ErrInsufficientPermissions = errors.New("insufficient permissions") +var ErrNoReadKey = errors.New("acl state doesn't have a read key") +var ErrInvalidSignature = errors.New("signature is invalid") +var ErrIncorrectRoot = errors.New("incorrect root") +var ErrIncorrectRecordSequence = errors.New("incorrect prev id of a record") + +type UserPermissionPair struct { + Identity string + Permission aclrecordproto.ACLUserPermissions +} + +type ACLState struct { + id string + currentReadKeyHash uint64 + userReadKeys map[uint64]*symmetric.Key + userStates map[string]*aclrecordproto.ACLUserState + userInvites map[string]*aclrecordproto.ACLUserInvite + encryptionKey encryptionkey.PrivKey + signingKey signingkey.PrivKey + totalReadKeys int + + identity string + permissionsAtRecord map[string][]UserPermissionPair + lastRecordId string + + keychain *common.Keychain +} + +func newACLStateWithKeys( + id string, + signingKey signingkey.PrivKey, + encryptionKey encryptionkey.PrivKey) (*ACLState, error) { + identity, err := signingKey.GetPublic().Raw() + if err != nil { + return nil, err + } + return &ACLState{ + id: id, + identity: string(identity), + signingKey: signingKey, + encryptionKey: encryptionKey, + userReadKeys: make(map[uint64]*symmetric.Key), + userStates: make(map[string]*aclrecordproto.ACLUserState), + userInvites: make(map[string]*aclrecordproto.ACLUserInvite), + permissionsAtRecord: make(map[string][]UserPermissionPair), + }, nil +} + +func newACLState(id string) *ACLState { + return &ACLState{ + id: id, + userReadKeys: make(map[uint64]*symmetric.Key), + userStates: make(map[string]*aclrecordproto.ACLUserState), + userInvites: make(map[string]*aclrecordproto.ACLUserInvite), + permissionsAtRecord: make(map[string][]UserPermissionPair), + } +} + +func (st *ACLState) CurrentReadKeyHash() uint64 { + return st.currentReadKeyHash +} + +func (st *ACLState) CurrentReadKey() (*symmetric.Key, error) { + key, exists := st.userReadKeys[st.currentReadKeyHash] + if !exists { + return nil, ErrNoReadKey + } + return key, nil +} + +func (st *ACLState) UserReadKeys() map[uint64]*symmetric.Key { + return st.userReadKeys +} + +func (st *ACLState) PermissionsAtRecord(id string, identity string) (UserPermissionPair, error) { + permissions, ok := st.permissionsAtRecord[id] + if !ok { + log.Errorf("missing record at id %s", id) + return UserPermissionPair{}, ErrNoSuchRecord + } + + for _, perm := range permissions { + if perm.Identity == identity { + return perm, nil + } + } + return UserPermissionPair{}, ErrNoSuchUser +} + +func (st *ACLState) applyRecord(record *ACLRecord) (err error) { + defer func() { + if err == nil { + st.lastRecordId = record.Id + } + }() + if st.lastRecordId != record.PrevId { + err = ErrIncorrectRecordSequence + return + } + if record.Id == st.id { + root, ok := record.Model.(*aclrecordproto.ACLRoot) + if !ok { + return ErrIncorrectRoot + } + err = st.applyRoot(root) + if err != nil { + return + } + st.permissionsAtRecord[record.Id] = []UserPermissionPair{ + {Identity: string(root.Identity), Permission: aclrecordproto.ACLUserPermissions_Admin}, + } + return + } + aclData := &aclrecordproto.ACLData{} + + if record.Model != nil { + aclData = record.Model.(*aclrecordproto.ACLData) + } else { + err = proto.Unmarshal(record.Data, aclData) + if err != nil { + return + } + record.Model = aclData + } + + err = st.applyChangeData(aclData, record.CurrentReadKeyHash, record.Identity) + if err != nil { + return + } + + // getting all permissions for users at record + var permissions []UserPermissionPair + for _, state := range st.userStates { + permission := UserPermissionPair{ + Identity: string(state.Identity), + Permission: state.Permissions, + } + permissions = append(permissions, permission) + } + + st.permissionsAtRecord[record.Id] = permissions + return +} + +func (st *ACLState) applyRoot(root *aclrecordproto.ACLRoot) (err error) { + if st.signingKey != nil && st.encryptionKey != nil && st.identity == string(root.Identity) { + err = st.saveReadKeyFromRoot(root) + if err != nil { + return + } + } + + // adding user to the list + userState := &aclrecordproto.ACLUserState{ + Identity: root.Identity, + EncryptionKey: root.EncryptionKey, + Permissions: aclrecordproto.ACLUserPermissions_Admin, + } + st.currentReadKeyHash = root.CurrentReadKeyHash + st.userStates[string(root.Identity)] = userState + st.totalReadKeys++ + return +} + +func (st *ACLState) saveReadKeyFromRoot(root *aclrecordproto.ACLRoot) (err error) { + var readKey *symmetric.Key + if len(root.GetDerivationScheme()) != 0 { + var encPrivKey []byte + encPrivKey, err = st.encryptionKey.Raw() + if err != nil { + return + } + var signPrivKey []byte + signPrivKey, err = st.signingKey.Raw() + if err != nil { + return + } + + readKey, err = aclrecordproto.ACLReadKeyDerive(signPrivKey, encPrivKey) + if err != nil { + return + } + } else { + readKey, _, err = st.decryptReadKeyAndHash(root.EncryptedReadKey) + if err != nil { + return + } + } + + hasher := fnv.New64() + _, err = hasher.Write(readKey.Bytes()) + if err != nil { + return + } + if hasher.Sum64() != root.CurrentReadKeyHash { + return ErrIncorrectRoot + } + st.userReadKeys[root.CurrentReadKeyHash] = readKey + + return +} + +func (st *ACLState) applyChangeData(changeData *aclrecordproto.ACLData, hash uint64, identity []byte) (err error) { + defer func() { + if err != nil { + return + } + if hash != st.currentReadKeyHash { + st.totalReadKeys++ + st.currentReadKeyHash = hash + } + }() + + if !st.isUserJoin(changeData) { + // we check signature when we add this to the List, so no need to do it here + if _, exists := st.userStates[string(identity)]; !exists { + err = ErrNoSuchUser + return + } + + if !st.hasPermission(identity, aclrecordproto.ACLUserPermissions_Admin) { + err = fmt.Errorf("user %s must have admin permissions", identity) + return + } + } + + for _, ch := range changeData.GetAclContent() { + if err = st.applyChangeContent(ch); err != nil { + log.Info("error while applying changes: %v; ignore", zap.Error(err)) + return err + } + } + + return nil +} + +func (st *ACLState) applyChangeContent(ch *aclrecordproto.ACLContentValue) error { + switch { + case ch.GetUserPermissionChange() != nil: + return st.applyUserPermissionChange(ch.GetUserPermissionChange()) + case ch.GetUserAdd() != nil: + return st.applyUserAdd(ch.GetUserAdd()) + case ch.GetUserRemove() != nil: + return st.applyUserRemove(ch.GetUserRemove()) + case ch.GetUserInvite() != nil: + return st.applyUserInvite(ch.GetUserInvite()) + case ch.GetUserJoin() != nil: + return st.applyUserJoin(ch.GetUserJoin()) + default: + return fmt.Errorf("unexpected change type: %v", ch) + } +} + +func (st *ACLState) applyUserPermissionChange(ch *aclrecordproto.ACLUserPermissionChange) error { + chIdentity := string(ch.Identity) + state, exists := st.userStates[chIdentity] + if !exists { + return ErrNoSuchUser + } + + state.Permissions = ch.Permissions + return nil +} + +func (st *ACLState) applyUserInvite(ch *aclrecordproto.ACLUserInvite) error { + st.userInvites[string(ch.AcceptPublicKey)] = ch + return nil +} + +func (st *ACLState) applyUserJoin(ch *aclrecordproto.ACLUserJoin) error { + invite, exists := st.userInvites[string(ch.AcceptPubKey)] + if !exists { + return fmt.Errorf("no such invite with such public key %s", keys.EncodeBytesToString(ch.AcceptPubKey)) + } + chIdentity := string(ch.Identity) + + if _, exists = st.userStates[chIdentity]; exists { + return ErrUserAlreadyExists + } + + // validating signature + signature := ch.GetAcceptSignature() + verificationKey, err := signingkey.NewSigningEd25519PubKeyFromBytes(invite.AcceptPublicKey) + if err != nil { + return fmt.Errorf("public key verifying invite accepts is given in incorrect format: %v", err) + } + + res, err := verificationKey.Verify(ch.Identity, signature) + if err != nil { + return fmt.Errorf("verification returned error: %w", err) + } + if !res { + return ErrInvalidSignature + } + + // if ourselves -> we need to decrypt the read keys + if st.identity == chIdentity { + for _, key := range ch.EncryptedReadKeys { + key, hash, err := st.decryptReadKeyAndHash(key) + if err != nil { + return ErrFailedToDecrypt + } + + st.userReadKeys[hash] = key + } + } + + // adding user to the list + userState := &aclrecordproto.ACLUserState{ + Identity: ch.Identity, + EncryptionKey: ch.EncryptionKey, + Permissions: invite.Permissions, + } + st.userStates[chIdentity] = userState + return nil +} + +func (st *ACLState) applyUserAdd(ch *aclrecordproto.ACLUserAdd) error { + chIdentity := string(ch.Identity) + if _, exists := st.userStates[chIdentity]; exists { + return ErrUserAlreadyExists + } + + st.userStates[chIdentity] = &aclrecordproto.ACLUserState{ + Identity: ch.Identity, + EncryptionKey: ch.EncryptionKey, + Permissions: ch.Permissions, + } + + if chIdentity == st.identity { + for _, key := range ch.EncryptedReadKeys { + key, hash, err := st.decryptReadKeyAndHash(key) + if err != nil { + return ErrFailedToDecrypt + } + + st.userReadKeys[hash] = key + } + } + + return nil +} + +func (st *ACLState) applyUserRemove(ch *aclrecordproto.ACLUserRemove) error { + chIdentity := string(ch.Identity) + if chIdentity == st.identity { + return ErrDocumentForbidden + } + + if _, exists := st.userStates[chIdentity]; !exists { + return ErrNoSuchUser + } + + delete(st.userStates, chIdentity) + + for _, replace := range ch.ReadKeyReplaces { + repIdentity := string(replace.Identity) + // if this is our identity then we have to decrypt the key + if repIdentity == st.identity { + key, hash, err := st.decryptReadKeyAndHash(replace.EncryptedReadKey) + if err != nil { + return ErrFailedToDecrypt + } + + st.userReadKeys[hash] = key + break + } + } + return nil +} + +func (st *ACLState) decryptReadKeyAndHash(msg []byte) (*symmetric.Key, uint64, error) { + decrypted, err := st.encryptionKey.Decrypt(msg) + if err != nil { + return nil, 0, ErrFailedToDecrypt + } + + key, err := symmetric.FromBytes(decrypted) + if err != nil { + return nil, 0, ErrFailedToDecrypt + } + + hasher := fnv.New64() + hasher.Write(decrypted) + return key, hasher.Sum64(), nil +} + +func (st *ACLState) hasPermission(identity []byte, permission aclrecordproto.ACLUserPermissions) bool { + state, exists := st.userStates[string(identity)] + if !exists { + return false + } + + return state.Permissions == permission +} + +func (st *ACLState) isUserJoin(data *aclrecordproto.ACLData) bool { + // if we have a UserJoin, then it should always be the first one applied + return data.GetAclContent() != nil && data.GetAclContent()[0].GetUserJoin() != nil +} + +func (st *ACLState) isUserAdd(data *aclrecordproto.ACLData, identity []byte) bool { + // if we have a UserAdd, then it should always be the first one applied + userAdd := data.GetAclContent()[0].GetUserAdd() + return data.GetAclContent() != nil && userAdd != nil && bytes.Compare(userAdd.GetIdentity(), identity) == 0 +} + +func (st *ACLState) UserStates() map[string]*aclrecordproto.ACLUserState { + return st.userStates +} + +func (st *ACLState) Invite(acceptPubKey []byte) (invite *aclrecordproto.ACLUserInvite, err error) { + invite, exists := st.userInvites[string(acceptPubKey)] + if !exists { + err = ErrNoSuchInvite + return + } + if len(invite.EncryptedReadKeys) != st.totalReadKeys { + err = ErrOldInvite + } + return +} + +func (st *ACLState) UserKeys() (encKey encryptionkey.PrivKey, signKey signingkey.PrivKey) { + return st.encryptionKey, st.signingKey +} + +func (st *ACLState) Identity() []byte { + return []byte(st.identity) +} + +func (st *ACLState) LastRecordId() string { + return st.lastRecordId +} diff --git a/common/pkg/acl/list/aclstatebuilder.go b/common/pkg/acl/list/aclstatebuilder.go new file mode 100644 index 00000000..2ef79cd5 --- /dev/null +++ b/common/pkg/acl/list/aclstatebuilder.go @@ -0,0 +1,57 @@ +package list + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/account" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/encryptionkey" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/signingkey" +) + +type aclStateBuilder struct { + signPrivKey signingkey.PrivKey + encPrivKey encryptionkey.PrivKey + id string +} + +func newACLStateBuilderWithIdentity(accountData *account.AccountData) *aclStateBuilder { + return &aclStateBuilder{ + signPrivKey: accountData.SignKey, + encPrivKey: accountData.EncKey, + } +} + +func newACLStateBuilder() *aclStateBuilder { + return &aclStateBuilder{} +} + +func (sb *aclStateBuilder) Init(id string) { + sb.id = id +} + +func (sb *aclStateBuilder) Build(records []*ACLRecord) (state *ACLState, err error) { + if sb.encPrivKey != nil && sb.signPrivKey != nil { + state, err = newACLStateWithKeys(sb.id, sb.signPrivKey, sb.encPrivKey) + if err != nil { + return + } + } else { + state = newACLState(sb.id) + } + for _, rec := range records { + err = state.applyRecord(rec) + if err != nil { + return nil, err + } + } + + return state, err +} + +func (sb *aclStateBuilder) Append(state *ACLState, records []*ACLRecord) (err error) { + for _, rec := range records { + err = state.applyRecord(rec) + if err != nil { + return + } + } + return +} diff --git a/common/pkg/acl/list/list.go b/common/pkg/acl/list/list.go new file mode 100644 index 00000000..e2f486d2 --- /dev/null +++ b/common/pkg/acl/list/list.go @@ -0,0 +1,222 @@ +//go:generate mockgen -destination mock_list/mock_list.go github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/list ACLList +package list + +import ( + "context" + "errors" + "fmt" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/account" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/common" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage" + "sync" +) + +type IterFunc = func(record *ACLRecord) (IsContinue bool) + +var ErrIncorrectCID = errors.New("incorrect CID") + +type RWLocker interface { + sync.Locker + RLock() + RUnlock() +} + +type ACLList interface { + RWLocker + ID() string + Root() *aclrecordproto.RawACLRecordWithId + Records() []*ACLRecord + ACLState() *ACLState + IsAfter(first string, second string) (bool, error) + Head() *ACLRecord + Get(id string) (*ACLRecord, error) + Iterate(iterFunc IterFunc) + IterateFrom(startId string, iterFunc IterFunc) + + AddRawRecord(rawRec *aclrecordproto.RawACLRecordWithId) (added bool, err error) + + Close() (err error) +} + +type aclList struct { + root *aclrecordproto.RawACLRecordWithId + records []*ACLRecord + indexes map[string]int + id string + + stateBuilder *aclStateBuilder + recordBuilder ACLRecordBuilder + aclState *ACLState + keychain *common.Keychain + storage storage.ListStorage + + sync.RWMutex +} + +func BuildACLListWithIdentity(acc *account.AccountData, storage storage.ListStorage) (ACLList, error) { + builder := newACLStateBuilderWithIdentity(acc) + return build(storage.Id(), builder, newACLRecordBuilder(storage.Id(), common.NewKeychain()), storage) +} + +func BuildACLList(storage storage.ListStorage) (ACLList, error) { + return build(storage.Id(), newACLStateBuilder(), newACLRecordBuilder(storage.Id(), common.NewKeychain()), storage) +} + +func build(id string, stateBuilder *aclStateBuilder, recBuilder ACLRecordBuilder, storage storage.ListStorage) (list ACLList, err error) { + head, err := storage.Head() + if err != nil { + return + } + + rawRecordWithId, err := storage.GetRawRecord(context.Background(), head) + if err != nil { + return + } + + record, err := recBuilder.ConvertFromRaw(rawRecordWithId) + if err != nil { + return + } + records := []*ACLRecord{record} + + for record.PrevId != "" { + rawRecordWithId, err = storage.GetRawRecord(context.Background(), record.PrevId) + if err != nil { + return + } + + record, err = recBuilder.ConvertFromRaw(rawRecordWithId) + if err != nil { + return + } + records = append(records, record) + } + + indexes := make(map[string]int) + for i, j := 0, len(records)-1; i < j; i, j = i+1, j-1 { + records[i], records[j] = records[j], records[i] + indexes[records[i].Id] = i + indexes[records[j].Id] = j + } + // adding missed index if needed + if len(records)%2 != 0 { + indexes[records[len(records)/2].Id] = len(records) / 2 + } + + stateBuilder.Init(id) + state, err := stateBuilder.Build(records) + if err != nil { + return + } + + // TODO: check if this is correct (raw model instead of unmarshalled) + rootWithId, err := storage.Root() + if err != nil { + return + } + + list = &aclList{ + root: rootWithId, + records: records, + indexes: indexes, + stateBuilder: stateBuilder, + recordBuilder: recBuilder, + aclState: state, + storage: storage, + id: id, + } + return +} + +func (a *aclList) Records() []*ACLRecord { + return a.records +} + +func (a *aclList) AddRawRecord(rawRec *aclrecordproto.RawACLRecordWithId) (added bool, err error) { + if _, ok := a.indexes[rawRec.Id]; ok { + return + } + record, err := a.recordBuilder.ConvertFromRaw(rawRec) + if err != nil { + return + } + if err = a.aclState.applyRecord(record); err != nil { + return + } + a.records = append(a.records, record) + a.indexes[record.Id] = len(a.records) - 1 + if err = a.storage.AddRawRecord(context.Background(), rawRec); err != nil { + return + } + if err = a.storage.SetHead(rawRec.Id); err != nil { + return + } + return true, nil +} + +func (a *aclList) IsValidNext(rawRec *aclrecordproto.RawACLRecordWithId) (err error) { + _, err = a.recordBuilder.ConvertFromRaw(rawRec) + if err != nil { + return + } + // TODO: change state and add "check" method for records + return +} + +func (a *aclList) ID() string { + return a.id +} + +func (a *aclList) Root() *aclrecordproto.RawACLRecordWithId { + return a.root +} + +func (a *aclList) ACLState() *ACLState { + return a.aclState +} + +func (a *aclList) IsAfter(first string, second string) (bool, error) { + firstRec, okFirst := a.indexes[first] + secondRec, okSecond := a.indexes[second] + if !okFirst || !okSecond { + return false, fmt.Errorf("not all entries are there: first (%t), second (%t)", okFirst, okSecond) + } + return firstRec >= secondRec, nil +} + +func (a *aclList) Head() *ACLRecord { + return a.records[len(a.records)-1] +} + +func (a *aclList) Get(id string) (*ACLRecord, error) { + recIdx, ok := a.indexes[id] + if !ok { + return nil, fmt.Errorf("no such record") + } + return a.records[recIdx], nil +} + +func (a *aclList) Iterate(iterFunc IterFunc) { + for _, rec := range a.records { + if !iterFunc(rec) { + return + } + } +} + +func (a *aclList) IterateFrom(startId string, iterFunc IterFunc) { + recIdx, ok := a.indexes[startId] + if !ok { + return + } + for i := recIdx; i < len(a.records); i++ { + if !iterFunc(a.records[i]) { + return + } + } +} + +func (a *aclList) Close() (err error) { + return nil +} diff --git a/common/pkg/acl/list/list_test.go b/common/pkg/acl/list/list_test.go new file mode 100644 index 00000000..c4effdae --- /dev/null +++ b/common/pkg/acl/list/list_test.go @@ -0,0 +1,91 @@ +package list + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/testutils/acllistbuilder" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "testing" +) + +func TestAclList_ACLState_UserInviteAndJoin(t *testing.T) { + st, err := acllistbuilder.NewListStorageWithTestName("userjoinexample.yml") + require.NoError(t, err, "building storage should not result in error") + + keychain := st.(*acllistbuilder.ACLListStorageBuilder).GetKeychain() + + aclList, err := BuildACLList(st) + require.NoError(t, err, "building acl list should be without error") + + idA := keychain.GetIdentity("A") + idB := keychain.GetIdentity("B") + idC := keychain.GetIdentity("C") + + // checking final state + assert.Equal(t, aclrecordproto.ACLUserPermissions_Admin, aclList.ACLState().UserStates()[idA].Permissions) + assert.Equal(t, aclrecordproto.ACLUserPermissions_Writer, aclList.ACLState().UserStates()[idB].Permissions) + assert.Equal(t, aclrecordproto.ACLUserPermissions_Reader, aclList.ACLState().UserStates()[idC].Permissions) + assert.Equal(t, aclList.Head().CurrentReadKeyHash, aclList.ACLState().CurrentReadKeyHash()) + + var records []*ACLRecord + aclList.Iterate(func(record *ACLRecord) (IsContinue bool) { + records = append(records, record) + return true + }) + + // checking permissions at specific records + assert.Equal(t, 3, len(records)) + + _, err = aclList.ACLState().PermissionsAtRecord(records[1].Id, idB) + assert.Error(t, err, "B should have no permissions at record 1") + + perm, err := aclList.ACLState().PermissionsAtRecord(records[2].Id, idB) + assert.NoError(t, err, "should have no error with permissions of B in the record 2") + assert.Equal(t, UserPermissionPair{ + Identity: idB, + Permission: aclrecordproto.ACLUserPermissions_Writer, + }, perm) +} + +func TestAclList_ACLState_UserJoinAndRemove(t *testing.T) { + st, err := acllistbuilder.NewListStorageWithTestName("userremoveexample.yml") + require.NoError(t, err, "building storage should not result in error") + + keychain := st.(*acllistbuilder.ACLListStorageBuilder).GetKeychain() + + aclList, err := BuildACLList(st) + require.NoError(t, err, "building acl list should be without error") + + idA := keychain.GetIdentity("A") + idB := keychain.GetIdentity("B") + idC := keychain.GetIdentity("C") + + // checking final state + assert.Equal(t, aclrecordproto.ACLUserPermissions_Admin, aclList.ACLState().UserStates()[idA].Permissions) + assert.Equal(t, aclrecordproto.ACLUserPermissions_Reader, aclList.ACLState().UserStates()[idC].Permissions) + assert.Equal(t, aclList.Head().CurrentReadKeyHash, aclList.ACLState().CurrentReadKeyHash()) + + _, exists := aclList.ACLState().UserStates()[idB] + assert.Equal(t, false, exists) + + var records []*ACLRecord + aclList.Iterate(func(record *ACLRecord) (IsContinue bool) { + records = append(records, record) + return true + }) + + // checking permissions at specific records + assert.Equal(t, 4, len(records)) + + assert.NotEqual(t, records[2].CurrentReadKeyHash, aclList.ACLState().CurrentReadKeyHash()) + + perm, err := aclList.ACLState().PermissionsAtRecord(records[2].Id, idB) + assert.NoError(t, err, "should have no error with permissions of B in the record 2") + assert.Equal(t, UserPermissionPair{ + Identity: idB, + Permission: aclrecordproto.ACLUserPermissions_Writer, + }, perm) + + _, err = aclList.ACLState().PermissionsAtRecord(records[3].Id, idB) + assert.Error(t, err, "B should have no permissions at record 3, because user should be removed") +} diff --git a/common/pkg/acl/list/mock_list/mock_list.go b/common/pkg/acl/list/mock_list/mock_list.go new file mode 100644 index 00000000..c70c183b --- /dev/null +++ b/common/pkg/acl/list/mock_list/mock_list.go @@ -0,0 +1,237 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/list (interfaces: ACLList) + +// Package mock_list is a generated GoMock package. +package mock_list + +import ( + reflect "reflect" + + aclrecordproto "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" + list "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/list" + gomock "github.com/golang/mock/gomock" +) + +// MockACLList is a mock of ACLList interface. +type MockACLList struct { + ctrl *gomock.Controller + recorder *MockACLListMockRecorder +} + +// MockACLListMockRecorder is the mock recorder for MockACLList. +type MockACLListMockRecorder struct { + mock *MockACLList +} + +// NewMockACLList creates a new mock instance. +func NewMockACLList(ctrl *gomock.Controller) *MockACLList { + mock := &MockACLList{ctrl: ctrl} + mock.recorder = &MockACLListMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockACLList) EXPECT() *MockACLListMockRecorder { + return m.recorder +} + +// ACLState mocks base method. +func (m *MockACLList) ACLState() *list.ACLState { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ACLState") + ret0, _ := ret[0].(*list.ACLState) + return ret0 +} + +// ACLState indicates an expected call of ACLState. +func (mr *MockACLListMockRecorder) ACLState() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ACLState", reflect.TypeOf((*MockACLList)(nil).ACLState)) +} + +// AddRawRecord mocks base method. +func (m *MockACLList) AddRawRecord(arg0 *aclrecordproto.RawACLRecordWithId) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AddRawRecord", arg0) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// AddRawRecord indicates an expected call of AddRawRecord. +func (mr *MockACLListMockRecorder) AddRawRecord(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRawRecord", reflect.TypeOf((*MockACLList)(nil).AddRawRecord), arg0) +} + +// Close mocks base method. +func (m *MockACLList) Close() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Close") + ret0, _ := ret[0].(error) + return ret0 +} + +// Close indicates an expected call of Close. +func (mr *MockACLListMockRecorder) Close() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockACLList)(nil).Close)) +} + +// Get mocks base method. +func (m *MockACLList) Get(arg0 string) (*list.ACLRecord, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Get", arg0) + ret0, _ := ret[0].(*list.ACLRecord) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Get indicates an expected call of Get. +func (mr *MockACLListMockRecorder) Get(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockACLList)(nil).Get), arg0) +} + +// Head mocks base method. +func (m *MockACLList) Head() *list.ACLRecord { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Head") + ret0, _ := ret[0].(*list.ACLRecord) + return ret0 +} + +// Head indicates an expected call of Head. +func (mr *MockACLListMockRecorder) Head() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Head", reflect.TypeOf((*MockACLList)(nil).Head)) +} + +// ID mocks base method. +func (m *MockACLList) ID() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ID") + ret0, _ := ret[0].(string) + return ret0 +} + +// ID indicates an expected call of ID. +func (mr *MockACLListMockRecorder) ID() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ID", reflect.TypeOf((*MockACLList)(nil).ID)) +} + +// IsAfter mocks base method. +func (m *MockACLList) IsAfter(arg0, arg1 string) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IsAfter", arg0, arg1) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// IsAfter indicates an expected call of IsAfter. +func (mr *MockACLListMockRecorder) IsAfter(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsAfter", reflect.TypeOf((*MockACLList)(nil).IsAfter), arg0, arg1) +} + +// Iterate mocks base method. +func (m *MockACLList) Iterate(arg0 func(*list.ACLRecord) bool) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Iterate", arg0) +} + +// Iterate indicates an expected call of Iterate. +func (mr *MockACLListMockRecorder) Iterate(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Iterate", reflect.TypeOf((*MockACLList)(nil).Iterate), arg0) +} + +// IterateFrom mocks base method. +func (m *MockACLList) IterateFrom(arg0 string, arg1 func(*list.ACLRecord) bool) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "IterateFrom", arg0, arg1) +} + +// IterateFrom indicates an expected call of IterateFrom. +func (mr *MockACLListMockRecorder) IterateFrom(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IterateFrom", reflect.TypeOf((*MockACLList)(nil).IterateFrom), arg0, arg1) +} + +// Lock mocks base method. +func (m *MockACLList) Lock() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Lock") +} + +// Lock indicates an expected call of Lock. +func (mr *MockACLListMockRecorder) Lock() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Lock", reflect.TypeOf((*MockACLList)(nil).Lock)) +} + +// RLock mocks base method. +func (m *MockACLList) RLock() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "RLock") +} + +// RLock indicates an expected call of RLock. +func (mr *MockACLListMockRecorder) RLock() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RLock", reflect.TypeOf((*MockACLList)(nil).RLock)) +} + +// RUnlock mocks base method. +func (m *MockACLList) RUnlock() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "RUnlock") +} + +// RUnlock indicates an expected call of RUnlock. +func (mr *MockACLListMockRecorder) RUnlock() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RUnlock", reflect.TypeOf((*MockACLList)(nil).RUnlock)) +} + +// Records mocks base method. +func (m *MockACLList) Records() []*list.ACLRecord { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Records") + ret0, _ := ret[0].([]*list.ACLRecord) + return ret0 +} + +// Records indicates an expected call of Records. +func (mr *MockACLListMockRecorder) Records() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Records", reflect.TypeOf((*MockACLList)(nil).Records)) +} + +// Root mocks base method. +func (m *MockACLList) Root() *aclrecordproto.RawACLRecordWithId { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Root") + ret0, _ := ret[0].(*aclrecordproto.RawACLRecordWithId) + return ret0 +} + +// Root indicates an expected call of Root. +func (mr *MockACLListMockRecorder) Root() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Root", reflect.TypeOf((*MockACLList)(nil).Root)) +} + +// Unlock mocks base method. +func (m *MockACLList) Unlock() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Unlock") +} + +// Unlock indicates an expected call of Unlock. +func (mr *MockACLListMockRecorder) Unlock() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Unlock", reflect.TypeOf((*MockACLList)(nil).Unlock)) +} diff --git a/common/pkg/acl/list/record.go b/common/pkg/acl/list/record.go new file mode 100644 index 00000000..abb37736 --- /dev/null +++ b/common/pkg/acl/list/record.go @@ -0,0 +1,12 @@ +package list + +type ACLRecord struct { + Id string + PrevId string + CurrentReadKeyHash uint64 + Timestamp int64 + Data []byte + Identity []byte + Model interface{} + Signature []byte +} diff --git a/common/pkg/acl/storage/helpers.go b/common/pkg/acl/storage/helpers.go new file mode 100644 index 00000000..7796a15f --- /dev/null +++ b/common/pkg/acl/storage/helpers.go @@ -0,0 +1,34 @@ +package storage + +import ( + "bytes" + "strings" +) + +func ParseHeads(headsPayload []byte) []string { + return strings.Split(string(headsPayload), "/") +} + +func CreateHeadsPayload(heads []string) []byte { + return JoinStringsToBytes(heads...) +} + +func JoinStringsToBytes(strs ...string) []byte { + var ( + b bytes.Buffer + totalLen int + ) + for _, s := range strs { + totalLen += len(s) + } + // adding separators + totalLen += len(strs) - 1 + b.Grow(totalLen) + for idx, s := range strs { + if idx > 0 { + b.WriteString("/") + } + b.WriteString(s) + } + return b.Bytes() +} diff --git a/common/pkg/acl/storage/inmemory.go b/common/pkg/acl/storage/inmemory.go new file mode 100644 index 00000000..273f6c83 --- /dev/null +++ b/common/pkg/acl/storage/inmemory.go @@ -0,0 +1,190 @@ +package storage + +import ( + "context" + "fmt" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto" + "sync" +) + +type inMemoryACLListStorage struct { + id string + root *aclrecordproto.RawACLRecordWithId + head string + records map[string]*aclrecordproto.RawACLRecordWithId + + sync.RWMutex +} + +func NewInMemoryACLListStorage( + id string, + records []*aclrecordproto.RawACLRecordWithId) (ListStorage, error) { + + allRecords := make(map[string]*aclrecordproto.RawACLRecordWithId) + for _, ch := range records { + allRecords[ch.Id] = ch + } + root := records[0] + head := records[len(records)-1] + + return &inMemoryACLListStorage{ + id: root.Id, + root: root, + head: head.Id, + records: allRecords, + }, nil +} + +func (t *inMemoryACLListStorage) Id() string { + t.RLock() + defer t.RUnlock() + return t.id +} + +func (t *inMemoryACLListStorage) Root() (*aclrecordproto.RawACLRecordWithId, error) { + t.RLock() + defer t.RUnlock() + return t.root, nil +} + +func (t *inMemoryACLListStorage) Head() (string, error) { + t.RLock() + defer t.RUnlock() + return t.head, nil +} + +func (t *inMemoryACLListStorage) SetHead(head string) error { + t.Lock() + defer t.Unlock() + t.head = head + return nil +} + +func (t *inMemoryACLListStorage) AddRawRecord(ctx context.Context, record *aclrecordproto.RawACLRecordWithId) error { + t.Lock() + defer t.Unlock() + // TODO: better to do deep copy + t.records[record.Id] = record + return nil +} + +func (t *inMemoryACLListStorage) GetRawRecord(ctx context.Context, recordId string) (*aclrecordproto.RawACLRecordWithId, error) { + t.RLock() + defer t.RUnlock() + if res, exists := t.records[recordId]; exists { + return res, nil + } + return nil, fmt.Errorf("could not get record with id: %s", recordId) +} + +type inMemoryTreeStorage struct { + id string + root *treechangeproto.RawTreeChangeWithId + heads []string + changes map[string]*treechangeproto.RawTreeChangeWithId + + sync.RWMutex +} + +func NewInMemoryTreeStorage( + root *treechangeproto.RawTreeChangeWithId, + heads []string, + changes []*treechangeproto.RawTreeChangeWithId) (TreeStorage, error) { + allChanges := make(map[string]*treechangeproto.RawTreeChangeWithId) + for _, ch := range changes { + allChanges[ch.Id] = ch + } + allChanges[root.Id] = root + + return &inMemoryTreeStorage{ + id: root.Id, + root: root, + heads: heads, + changes: allChanges, + RWMutex: sync.RWMutex{}, + }, nil +} + +func (t *inMemoryTreeStorage) HasChange(ctx context.Context, id string) (bool, error) { + _, exists := t.changes[id] + return exists, nil +} + +func (t *inMemoryTreeStorage) Id() string { + t.RLock() + defer t.RUnlock() + return t.id +} + +func (t *inMemoryTreeStorage) Root() (*treechangeproto.RawTreeChangeWithId, error) { + t.RLock() + defer t.RUnlock() + return t.root, nil +} + +func (t *inMemoryTreeStorage) Heads() ([]string, error) { + t.RLock() + defer t.RUnlock() + return t.heads, nil +} + +func (t *inMemoryTreeStorage) SetHeads(heads []string) error { + t.Lock() + defer t.Unlock() + t.heads = t.heads[:0] + + for _, h := range heads { + t.heads = append(t.heads, h) + } + return nil +} + +func (t *inMemoryTreeStorage) AddRawChange(change *treechangeproto.RawTreeChangeWithId) error { + t.Lock() + defer t.Unlock() + // TODO: better to do deep copy + t.changes[change.Id] = change + return nil +} + +func (t *inMemoryTreeStorage) GetRawChange(ctx context.Context, changeId string) (*treechangeproto.RawTreeChangeWithId, error) { + t.RLock() + defer t.RUnlock() + if res, exists := t.changes[changeId]; exists { + return res, nil + } + return nil, fmt.Errorf("could not get change with id: %s", changeId) +} + +type inMemoryStorageProvider struct { + objects map[string]TreeStorage + sync.RWMutex +} + +func (i *inMemoryStorageProvider) TreeStorage(id string) (TreeStorage, error) { + i.RLock() + defer i.RUnlock() + if tree, exists := i.objects[id]; exists { + return tree, nil + } + return nil, ErrUnknownTreeId +} + +func (i *inMemoryStorageProvider) CreateTreeStorage(payload TreeStorageCreatePayload) (TreeStorage, error) { + i.Lock() + defer i.Unlock() + res, err := NewInMemoryTreeStorage(payload.RootRawChange, payload.Heads, payload.Changes) + if err != nil { + return nil, err + } + + i.objects[payload.RootRawChange.Id] = res + return res, nil +} + +func NewInMemoryTreeStorageProvider() Provider { + return &inMemoryStorageProvider{ + objects: make(map[string]TreeStorage), + } +} diff --git a/common/pkg/acl/storage/liststorage.go b/common/pkg/acl/storage/liststorage.go new file mode 100644 index 00000000..bfe47ab9 --- /dev/null +++ b/common/pkg/acl/storage/liststorage.go @@ -0,0 +1,22 @@ +//go:generate mockgen -destination mock_storage/mock_storage.go github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage ListStorage,TreeStorage +package storage + +import ( + "context" + "errors" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" +) + +var ErrUnknownACLId = errors.New("acl does not exist") +var ErrACLExists = errors.New("acl already exists") +var ErrUnknownRecord = errors.New("record doesn't exist") + +type ListStorage interface { + Id() string + Root() (*aclrecordproto.RawACLRecordWithId, error) + Head() (string, error) + SetHead(headId string) error + + GetRawRecord(ctx context.Context, id string) (*aclrecordproto.RawACLRecordWithId, error) + AddRawRecord(ctx context.Context, rec *aclrecordproto.RawACLRecordWithId) error +} diff --git a/common/pkg/acl/storage/mock_storage/mock_storage.go b/common/pkg/acl/storage/mock_storage/mock_storage.go new file mode 100644 index 00000000..751184a7 --- /dev/null +++ b/common/pkg/acl/storage/mock_storage/mock_storage.go @@ -0,0 +1,249 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage (interfaces: ListStorage,TreeStorage) + +// Package mock_storage is a generated GoMock package. +package mock_storage + +import ( + context "context" + reflect "reflect" + + aclrecordproto "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" + treechangeproto "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto" + gomock "github.com/golang/mock/gomock" +) + +// MockListStorage is a mock of ListStorage interface. +type MockListStorage struct { + ctrl *gomock.Controller + recorder *MockListStorageMockRecorder +} + +// MockListStorageMockRecorder is the mock recorder for MockListStorage. +type MockListStorageMockRecorder struct { + mock *MockListStorage +} + +// NewMockListStorage creates a new mock instance. +func NewMockListStorage(ctrl *gomock.Controller) *MockListStorage { + mock := &MockListStorage{ctrl: ctrl} + mock.recorder = &MockListStorageMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockListStorage) EXPECT() *MockListStorageMockRecorder { + return m.recorder +} + +// AddRawRecord mocks base method. +func (m *MockListStorage) AddRawRecord(arg0 context.Context, arg1 *aclrecordproto.RawACLRecordWithId) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AddRawRecord", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// AddRawRecord indicates an expected call of AddRawRecord. +func (mr *MockListStorageMockRecorder) AddRawRecord(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRawRecord", reflect.TypeOf((*MockListStorage)(nil).AddRawRecord), arg0, arg1) +} + +// GetRawRecord mocks base method. +func (m *MockListStorage) GetRawRecord(arg0 context.Context, arg1 string) (*aclrecordproto.RawACLRecordWithId, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetRawRecord", arg0, arg1) + ret0, _ := ret[0].(*aclrecordproto.RawACLRecordWithId) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetRawRecord indicates an expected call of GetRawRecord. +func (mr *MockListStorageMockRecorder) GetRawRecord(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRawRecord", reflect.TypeOf((*MockListStorage)(nil).GetRawRecord), arg0, arg1) +} + +// Head mocks base method. +func (m *MockListStorage) Head() (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Head") + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Head indicates an expected call of Head. +func (mr *MockListStorageMockRecorder) Head() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Head", reflect.TypeOf((*MockListStorage)(nil).Head)) +} + +// Id mocks base method. +func (m *MockListStorage) Id() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Id") + ret0, _ := ret[0].(string) + return ret0 +} + +// Id indicates an expected call of Id. +func (mr *MockListStorageMockRecorder) Id() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Id", reflect.TypeOf((*MockListStorage)(nil).Id)) +} + +// Root mocks base method. +func (m *MockListStorage) Root() (*aclrecordproto.RawACLRecordWithId, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Root") + ret0, _ := ret[0].(*aclrecordproto.RawACLRecordWithId) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Root indicates an expected call of Root. +func (mr *MockListStorageMockRecorder) Root() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Root", reflect.TypeOf((*MockListStorage)(nil).Root)) +} + +// SetHead mocks base method. +func (m *MockListStorage) SetHead(arg0 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetHead", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetHead indicates an expected call of SetHead. +func (mr *MockListStorageMockRecorder) SetHead(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetHead", reflect.TypeOf((*MockListStorage)(nil).SetHead), arg0) +} + +// MockTreeStorage is a mock of TreeStorage interface. +type MockTreeStorage struct { + ctrl *gomock.Controller + recorder *MockTreeStorageMockRecorder +} + +// MockTreeStorageMockRecorder is the mock recorder for MockTreeStorage. +type MockTreeStorageMockRecorder struct { + mock *MockTreeStorage +} + +// NewMockTreeStorage creates a new mock instance. +func NewMockTreeStorage(ctrl *gomock.Controller) *MockTreeStorage { + mock := &MockTreeStorage{ctrl: ctrl} + mock.recorder = &MockTreeStorageMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockTreeStorage) EXPECT() *MockTreeStorageMockRecorder { + return m.recorder +} + +// AddRawChange mocks base method. +func (m *MockTreeStorage) AddRawChange(arg0 *treechangeproto.RawTreeChangeWithId) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AddRawChange", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// AddRawChange indicates an expected call of AddRawChange. +func (mr *MockTreeStorageMockRecorder) AddRawChange(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRawChange", reflect.TypeOf((*MockTreeStorage)(nil).AddRawChange), arg0) +} + +// GetRawChange mocks base method. +func (m *MockTreeStorage) GetRawChange(arg0 context.Context, arg1 string) (*treechangeproto.RawTreeChangeWithId, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetRawChange", arg0, arg1) + ret0, _ := ret[0].(*treechangeproto.RawTreeChangeWithId) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetRawChange indicates an expected call of GetRawChange. +func (mr *MockTreeStorageMockRecorder) GetRawChange(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRawChange", reflect.TypeOf((*MockTreeStorage)(nil).GetRawChange), arg0, arg1) +} + +// HasChange mocks base method. +func (m *MockTreeStorage) HasChange(arg0 context.Context, arg1 string) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HasChange", arg0, arg1) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// HasChange indicates an expected call of HasChange. +func (mr *MockTreeStorageMockRecorder) HasChange(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasChange", reflect.TypeOf((*MockTreeStorage)(nil).HasChange), arg0, arg1) +} + +// Heads mocks base method. +func (m *MockTreeStorage) Heads() ([]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Heads") + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Heads indicates an expected call of Heads. +func (mr *MockTreeStorageMockRecorder) Heads() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Heads", reflect.TypeOf((*MockTreeStorage)(nil).Heads)) +} + +// Id mocks base method. +func (m *MockTreeStorage) Id() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Id") + ret0, _ := ret[0].(string) + return ret0 +} + +// Id indicates an expected call of Id. +func (mr *MockTreeStorageMockRecorder) Id() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Id", reflect.TypeOf((*MockTreeStorage)(nil).Id)) +} + +// Root mocks base method. +func (m *MockTreeStorage) Root() (*treechangeproto.RawTreeChangeWithId, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Root") + ret0, _ := ret[0].(*treechangeproto.RawTreeChangeWithId) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Root indicates an expected call of Root. +func (mr *MockTreeStorageMockRecorder) Root() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Root", reflect.TypeOf((*MockTreeStorage)(nil).Root)) +} + +// SetHeads mocks base method. +func (m *MockTreeStorage) SetHeads(arg0 []string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetHeads", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetHeads indicates an expected call of SetHeads. +func (mr *MockTreeStorageMockRecorder) SetHeads(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetHeads", reflect.TypeOf((*MockTreeStorage)(nil).SetHeads), arg0) +} diff --git a/common/pkg/acl/storage/provider.go b/common/pkg/acl/storage/provider.go new file mode 100644 index 00000000..51b53b4f --- /dev/null +++ b/common/pkg/acl/storage/provider.go @@ -0,0 +1,21 @@ +package storage + +import ( + "errors" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto" +) + +var ErrUnknownTreeId = errors.New("tree does not exist") +var ErrTreeExists = errors.New("tree already exists") +var ErrUnkownChange = errors.New("change doesn't exist") + +type TreeStorageCreatePayload struct { + RootRawChange *treechangeproto.RawTreeChangeWithId + Changes []*treechangeproto.RawTreeChangeWithId + Heads []string +} + +type Provider interface { + TreeStorage(id string) (TreeStorage, error) + CreateTreeStorage(payload TreeStorageCreatePayload) (TreeStorage, error) +} diff --git a/common/pkg/acl/storage/treestorage.go b/common/pkg/acl/storage/treestorage.go new file mode 100644 index 00000000..549e872a --- /dev/null +++ b/common/pkg/acl/storage/treestorage.go @@ -0,0 +1,19 @@ +package storage + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto" +) + +type TreeStorage interface { + Id() string + Root() (*treechangeproto.RawTreeChangeWithId, error) + Heads() ([]string, error) + SetHeads(heads []string) error + + AddRawChange(change *treechangeproto.RawTreeChangeWithId) error + GetRawChange(ctx context.Context, id string) (*treechangeproto.RawTreeChangeWithId, error) + HasChange(ctx context.Context, id string) (bool, error) +} + +type TreeStorageCreatorFunc = func(payload TreeStorageCreatePayload) (TreeStorage, error) diff --git a/common/pkg/acl/testutils/acllistbuilder/keychain.go b/common/pkg/acl/testutils/acllistbuilder/keychain.go new file mode 100644 index 00000000..ff0b9b04 --- /dev/null +++ b/common/pkg/acl/testutils/acllistbuilder/keychain.go @@ -0,0 +1,194 @@ +package acllistbuilder + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys" + encryptionkey2 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/encryptionkey" + signingkey2 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/signingkey" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/symmetric" + "hash/fnv" + "strings" +) + +type SymKey struct { + Hash uint64 + Key *symmetric.Key +} + +type YAMLKeychain struct { + SigningKeysByYAMLName map[string]signingkey2.PrivKey + SigningKeysByRealIdentity map[string]signingkey2.PrivKey + EncryptionKeysByYAMLName map[string]encryptionkey2.PrivKey + ReadKeysByYAMLName map[string]*SymKey + ReadKeysByHash map[uint64]*SymKey + GeneratedIdentities map[string]string +} + +func NewKeychain() *YAMLKeychain { + return &YAMLKeychain{ + SigningKeysByYAMLName: map[string]signingkey2.PrivKey{}, + SigningKeysByRealIdentity: map[string]signingkey2.PrivKey{}, + EncryptionKeysByYAMLName: map[string]encryptionkey2.PrivKey{}, + GeneratedIdentities: map[string]string{}, + ReadKeysByYAMLName: map[string]*SymKey{}, + ReadKeysByHash: map[uint64]*SymKey{}, + } +} + +func (k *YAMLKeychain) ParseKeys(keys *Keys) { + for _, encKey := range keys.Enc { + k.AddEncryptionKey(encKey) + } + + for _, signKey := range keys.Sign { + k.AddSigningKey(signKey) + } + + for _, readKey := range keys.Read { + k.AddReadKey(readKey) + } +} + +func (k *YAMLKeychain) AddEncryptionKey(key *Key) { + if _, exists := k.EncryptionKeysByYAMLName[key.Name]; exists { + return + } + var ( + newPrivKey encryptionkey2.PrivKey + err error + ) + if key.Value == "generated" { + newPrivKey, _, err = encryptionkey2.GenerateRandomRSAKeyPair(2048) + if err != nil { + panic(err) + } + } else { + newPrivKey, err = keys.DecodeKeyFromString(key.Value, encryptionkey2.NewEncryptionRsaPrivKeyFromBytes, nil) + if err != nil { + panic(err) + } + } + k.EncryptionKeysByYAMLName[key.Name] = newPrivKey +} + +func (k *YAMLKeychain) AddSigningKey(key *Key) { + if _, exists := k.SigningKeysByYAMLName[key.Name]; exists { + return + } + var ( + newPrivKey signingkey2.PrivKey + pubKey signingkey2.PubKey + err error + ) + if key.Value == "generated" { + newPrivKey, pubKey, err = signingkey2.GenerateRandomEd25519KeyPair() + if err != nil { + panic(err) + } + } else { + newPrivKey, err = keys.DecodeKeyFromString(key.Value, signingkey2.NewSigningEd25519PrivKeyFromBytes, nil) + if err != nil { + panic(err) + } + pubKey = newPrivKey.GetPublic() + } + + k.SigningKeysByYAMLName[key.Name] = newPrivKey + rawPubKey, err := pubKey.Raw() + if err != nil { + panic(err) + } + encoded := string(rawPubKey) + + k.SigningKeysByRealIdentity[encoded] = newPrivKey + k.GeneratedIdentities[key.Name] = encoded +} + +func (k *YAMLKeychain) AddReadKey(key *Key) { + if _, exists := k.ReadKeysByYAMLName[key.Name]; exists { + return + } + + var ( + rkey *symmetric.Key + err error + ) + if key.Value == "generated" { + rkey, err = symmetric.NewRandom() + if err != nil { + panic("should be able to generate symmetric key") + } + } else if key.Value == "derived" { + signKey, _ := k.SigningKeysByYAMLName[key.Name].Raw() + encKey, _ := k.EncryptionKeysByYAMLName[key.Name].Raw() + rkey, err = aclrecordproto.ACLReadKeyDerive(signKey, encKey) + if err != nil { + panic("should be able to derive symmetric key") + } + } else { + rkey, err = symmetric.FromString(key.Value) + if err != nil { + panic("should be able to parse symmetric key") + } + } + + hasher := fnv.New64() + hasher.Write(rkey.Bytes()) + + k.ReadKeysByYAMLName[key.Name] = &SymKey{ + Hash: hasher.Sum64(), + Key: rkey, + } + k.ReadKeysByHash[hasher.Sum64()] = &SymKey{ + Hash: hasher.Sum64(), + Key: rkey, + } +} + +func (k *YAMLKeychain) AddKey(key *Key) { + parts := strings.Split(key.Name, ".") + if len(parts) != 3 { + panic("cannot parse a key") + } + + switch parts[1] { + case "Signature": + k.AddSigningKey(key) + case "Enc": + k.AddEncryptionKey(key) + case "Read": + k.AddReadKey(key) + default: + panic("incorrect format") + } +} + +func (k *YAMLKeychain) GetKey(key string) interface{} { + parts := strings.Split(key, ".") + if len(parts) != 3 { + panic("cannot parse a key") + } + name := parts[2] + + switch parts[1] { + case "Sign": + if key, exists := k.SigningKeysByYAMLName[name]; exists { + return key + } + case "Enc": + if key, exists := k.EncryptionKeysByYAMLName[name]; exists { + return key + } + case "Read": + if key, exists := k.ReadKeysByYAMLName[name]; exists { + return key + } + default: + panic("incorrect format") + } + return nil +} + +func (k *YAMLKeychain) GetIdentity(name string) string { + return k.GeneratedIdentities[name] +} diff --git a/common/pkg/acl/testutils/acllistbuilder/liststoragebuilder.go b/common/pkg/acl/testutils/acllistbuilder/liststoragebuilder.go new file mode 100644 index 00000000..a1309073 --- /dev/null +++ b/common/pkg/acl/testutils/acllistbuilder/liststoragebuilder.go @@ -0,0 +1,295 @@ +package acllistbuilder + +import ( + "context" + "fmt" + aclrecordproto "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/testutils/yamltests" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/cid" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/encryptionkey" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/signingkey" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/symmetric" + "io/ioutil" + "path" + "time" + + "github.com/gogo/protobuf/proto" + "gopkg.in/yaml.v3" +) + +type ACLListStorageBuilder struct { + storage.ListStorage + keychain *YAMLKeychain +} + +func NewACLListStorageBuilder(keychain *YAMLKeychain) *ACLListStorageBuilder { + return &ACLListStorageBuilder{ + keychain: keychain, + } +} + +func NewListStorageWithTestName(name string) (storage.ListStorage, error) { + filePath := path.Join(yamltests.Path(), name) + return NewACLListStorageBuilderFromFile(filePath) +} + +func NewACLListStorageBuilderFromFile(file string) (*ACLListStorageBuilder, error) { + content, err := ioutil.ReadFile(file) + if err != nil { + return nil, err + } + + ymlTree := YMLList{} + err = yaml.Unmarshal(content, &ymlTree) + if err != nil { + return nil, err + } + + tb := NewACLListStorageBuilder(NewKeychain()) + tb.Parse(&ymlTree) + + return tb, nil +} + +func (t *ACLListStorageBuilder) createRaw(rec proto.Marshaler, identity []byte) *aclrecordproto.RawACLRecordWithId { + protoMarshalled, err := rec.Marshal() + if err != nil { + panic("should be able to marshal final acl message!") + } + + signature, err := t.keychain.SigningKeysByRealIdentity[string(identity)].Sign(protoMarshalled) + if err != nil { + panic("should be able to sign final acl message!") + } + + rawRec := &aclrecordproto.RawACLRecord{ + Payload: protoMarshalled, + Signature: signature, + } + + rawMarshalled, err := proto.Marshal(rawRec) + if err != nil { + panic(err) + } + + id, _ := cid.NewCIDFromBytes(rawMarshalled) + + return &aclrecordproto.RawACLRecordWithId{ + Payload: rawMarshalled, + Id: id, + } +} + +func (t *ACLListStorageBuilder) GetKeychain() *YAMLKeychain { + return t.keychain +} + +func (t *ACLListStorageBuilder) Parse(l *YMLList) { + // Just to clarify - we are generating new identities for the ones that + // are specified in the yml file, because our identities should be Ed25519 + // the same thing is happening for the encryption keys + t.keychain.ParseKeys(&l.Keys) + rawRoot := t.parseRoot(l.Root) + var err error + t.ListStorage, err = storage.NewInMemoryACLListStorage(rawRoot.Id, []*aclrecordproto.RawACLRecordWithId{rawRoot}) + if err != nil { + panic(err) + } + prevId := rawRoot.Id + for _, rec := range l.Records { + newRecord := t.parseRecord(rec, prevId) + rawRecord := t.createRaw(newRecord, newRecord.Identity) + err = t.AddRawRecord(context.Background(), rawRecord) + if err != nil { + panic(err) + } + prevId = rawRecord.Id + } + t.SetHead(prevId) +} + +func (t *ACLListStorageBuilder) parseRecord(rec *Record, prevId string) *aclrecordproto.ACLRecord { + k := t.keychain.GetKey(rec.ReadKey).(*SymKey) + var aclChangeContents []*aclrecordproto.ACLContentValue + for _, ch := range rec.AclChanges { + aclChangeContent := t.parseACLChange(ch) + aclChangeContents = append(aclChangeContents, aclChangeContent) + } + data := &aclrecordproto.ACLData{ + AclContent: aclChangeContents, + } + bytes, _ := data.Marshal() + + return &aclrecordproto.ACLRecord{ + PrevId: prevId, + Identity: []byte(t.keychain.GetIdentity(rec.Identity)), + Data: bytes, + CurrentReadKeyHash: k.Hash, + Timestamp: time.Now().UnixNano(), + } +} + +func (t *ACLListStorageBuilder) parseACLChange(ch *ACLChange) (convCh *aclrecordproto.ACLContentValue) { + switch { + case ch.UserAdd != nil: + add := ch.UserAdd + + encKey := t.keychain.GetKey(add.EncryptionKey).(encryptionkey.PrivKey) + rawKey, _ := encKey.GetPublic().Raw() + + convCh = &aclrecordproto.ACLContentValue{ + Value: &aclrecordproto.ACLContentValue_UserAdd{ + UserAdd: &aclrecordproto.ACLUserAdd{ + Identity: []byte(t.keychain.GetIdentity(add.Identity)), + EncryptionKey: rawKey, + EncryptedReadKeys: t.encryptReadKeysWithPubKey(add.EncryptedReadKeys, encKey), + Permissions: t.convertPermission(add.Permission), + }, + }, + } + case ch.UserJoin != nil: + join := ch.UserJoin + + encKey := t.keychain.GetKey(join.EncryptionKey).(encryptionkey.PrivKey) + rawKey, _ := encKey.GetPublic().Raw() + + idKey, _ := t.keychain.SigningKeysByYAMLName[join.Identity].GetPublic().Raw() + signKey := t.keychain.GetKey(join.AcceptKey).(signingkey.PrivKey) + signature, err := signKey.Sign(idKey) + if err != nil { + panic(err) + } + acceptPubKey, _ := signKey.GetPublic().Raw() + + convCh = &aclrecordproto.ACLContentValue{ + Value: &aclrecordproto.ACLContentValue_UserJoin{ + UserJoin: &aclrecordproto.ACLUserJoin{ + Identity: []byte(t.keychain.GetIdentity(join.Identity)), + EncryptionKey: rawKey, + AcceptSignature: signature, + AcceptPubKey: acceptPubKey, + EncryptedReadKeys: t.encryptReadKeysWithPubKey(join.EncryptedReadKeys, encKey), + }, + }, + } + case ch.UserInvite != nil: + invite := ch.UserInvite + rawAcceptKey, _ := t.keychain.GetKey(invite.AcceptKey).(signingkey.PrivKey).GetPublic().Raw() + hash := t.keychain.GetKey(invite.EncryptionKey).(*SymKey).Hash + encKey := t.keychain.ReadKeysByHash[hash] + + convCh = &aclrecordproto.ACLContentValue{ + Value: &aclrecordproto.ACLContentValue_UserInvite{ + UserInvite: &aclrecordproto.ACLUserInvite{ + AcceptPublicKey: rawAcceptKey, + EncryptSymKeyHash: hash, + EncryptedReadKeys: t.encryptReadKeysWithSymKey(invite.EncryptedReadKeys, encKey.Key), + Permissions: t.convertPermission(invite.Permissions), + }, + }, + } + case ch.UserPermissionChange != nil: + permissionChange := ch.UserPermissionChange + + convCh = &aclrecordproto.ACLContentValue{ + Value: &aclrecordproto.ACLContentValue_UserPermissionChange{ + UserPermissionChange: &aclrecordproto.ACLUserPermissionChange{ + Identity: []byte(t.keychain.GetIdentity(permissionChange.Identity)), + Permissions: t.convertPermission(permissionChange.Permission), + }, + }, + } + case ch.UserRemove != nil: + remove := ch.UserRemove + + newReadKey := t.keychain.GetKey(remove.NewReadKey).(*SymKey) + + var replaces []*aclrecordproto.ACLReadKeyReplace + for _, id := range remove.IdentitiesLeft { + encKey := t.keychain.EncryptionKeysByYAMLName[id] + rawEncKey, _ := encKey.GetPublic().Raw() + encReadKey, err := encKey.GetPublic().Encrypt(newReadKey.Key.Bytes()) + if err != nil { + panic(err) + } + replaces = append(replaces, &aclrecordproto.ACLReadKeyReplace{ + Identity: []byte(t.keychain.GetIdentity(id)), + EncryptionKey: rawEncKey, + EncryptedReadKey: encReadKey, + }) + } + + convCh = &aclrecordproto.ACLContentValue{ + Value: &aclrecordproto.ACLContentValue_UserRemove{ + UserRemove: &aclrecordproto.ACLUserRemove{ + Identity: []byte(t.keychain.GetIdentity(remove.RemovedIdentity)), + ReadKeyReplaces: replaces, + }, + }, + } + } + if convCh == nil { + panic("cannot have empty acl change") + } + + return convCh +} + +func (t *ACLListStorageBuilder) encryptReadKeysWithPubKey(keys []string, encKey encryptionkey.PrivKey) (enc [][]byte) { + for _, k := range keys { + realKey := t.keychain.GetKey(k).(*SymKey).Key.Bytes() + res, err := encKey.GetPublic().Encrypt(realKey) + if err != nil { + panic(err) + } + + enc = append(enc, res) + } + return +} + +func (t *ACLListStorageBuilder) encryptReadKeysWithSymKey(keys []string, key *symmetric.Key) (enc [][]byte) { + for _, k := range keys { + realKey := t.keychain.GetKey(k).(*SymKey).Key.Bytes() + res, err := key.Encrypt(realKey) + if err != nil { + panic(err) + } + + enc = append(enc, res) + } + return +} + +func (t *ACLListStorageBuilder) convertPermission(perm string) aclrecordproto.ACLUserPermissions { + switch perm { + case "admin": + return aclrecordproto.ACLUserPermissions_Admin + case "writer": + return aclrecordproto.ACLUserPermissions_Writer + case "reader": + return aclrecordproto.ACLUserPermissions_Reader + default: + panic(fmt.Sprintf("incorrect permission: %s", perm)) + } +} + +func (t *ACLListStorageBuilder) traverseFromHead(f func(rec *aclrecordproto.ACLRecord, id string) error) (err error) { + panic("this was removed, add if needed") +} + +func (t *ACLListStorageBuilder) parseRoot(root *Root) (rawRoot *aclrecordproto.RawACLRecordWithId) { + rawSignKey, _ := t.keychain.SigningKeysByYAMLName[root.Identity].GetPublic().Raw() + rawEncKey, _ := t.keychain.EncryptionKeysByYAMLName[root.Identity].GetPublic().Raw() + readKey := t.keychain.ReadKeysByYAMLName[root.Identity] + aclRoot := &aclrecordproto.ACLRoot{ + Identity: rawSignKey, + EncryptionKey: rawEncKey, + SpaceId: root.SpaceId, + EncryptedReadKey: nil, + DerivationScheme: "scheme", + CurrentReadKeyHash: readKey.Hash, + } + return t.createRaw(aclRoot, rawSignKey) +} diff --git a/pkg/acl/testutils/treestoragebuilder/treestoragebuildergraph.go b/common/pkg/acl/testutils/acllistbuilder/liststoragebuildergraph.go similarity index 72% rename from pkg/acl/testutils/treestoragebuilder/treestoragebuildergraph.go rename to common/pkg/acl/testutils/acllistbuilder/liststoragebuildergraph.go index 11c6609d..ae4f1027 100644 --- a/pkg/acl/testutils/treestoragebuilder/treestoragebuildergraph.go +++ b/common/pkg/acl/testutils/acllistbuilder/liststoragebuildergraph.go @@ -2,10 +2,10 @@ // +build !linux,!darwin android ios nographviz // +build !amd64 -package treestoragebuilder +package acllistbuilder import "fmt" -func (t *TreeStorageBuilder) Graph() (string, error) { +func (t *ACLListStorageBuilder) Graph() (string, error) { return "", fmt.Errorf("building graphs is not supported") } diff --git a/common/pkg/acl/testutils/acllistbuilder/liststoragebuildergraph_nix.go b/common/pkg/acl/testutils/acllistbuilder/liststoragebuildergraph_nix.go new file mode 100644 index 00000000..ba2679f3 --- /dev/null +++ b/common/pkg/acl/testutils/acllistbuilder/liststoragebuildergraph_nix.go @@ -0,0 +1,120 @@ +//go:build (linux || darwin) && !android && !ios && !nographviz && (amd64 || arm64) +// +build linux darwin +// +build !android +// +build !ios +// +build !nographviz +// +build amd64 arm64 + +package acllistbuilder + +import ( + "fmt" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" + "github.com/gogo/protobuf/proto" + "strings" + "unicode" + + "github.com/awalterschulze/gographviz" +) + +// To quickly look at visualized string you can use https://dreampuf.github.io/GraphvizOnline + +type EdgeParameters struct { + style string + color string + label string +} + +func (t *ACLListStorageBuilder) Graph() (string, error) { + // TODO: check updates on https://github.com/goccy/go-graphviz/issues/52 or make a fix yourself to use better library here + graph := gographviz.NewGraph() + graph.SetName("G") + graph.SetDir(true) + var nodes = make(map[string]struct{}) + + var addNodes = func(r *aclrecordproto.ACLRecord, id string) error { + style := "solid" + + var chSymbs []string + aclData := &aclrecordproto.ACLData{} + err := proto.Unmarshal(r.GetData(), aclData) + if err != nil { + return err + } + + for _, chc := range aclData.AclContent { + tp := fmt.Sprintf("%T", chc.Value) + tp = strings.Replace(tp, "ACLChangeACLContentValueValueOf", "", 1) + res := "" + for _, ts := range tp { + if unicode.IsUpper(ts) { + res += string(ts) + } + } + chSymbs = append(chSymbs, res) + } + + shortId := id + label := fmt.Sprintf("Id: %s\nChanges: %s\n", + shortId, + strings.Join(chSymbs, ","), + ) + e := graph.AddNode("G", "\""+id+"\"", map[string]string{ + "label": "\"" + label + "\"", + "style": "\"" + style + "\"", + }) + if e != nil { + return e + } + nodes[id] = struct{}{} + return nil + } + + var createEdge = func(firstId, secondId string, params EdgeParameters) error { + _, exists := nodes[firstId] + if !exists { + return fmt.Errorf("no such node") + } + _, exists = nodes[secondId] + if !exists { + return fmt.Errorf("no previous node") + } + + err := graph.AddEdge("\""+firstId+"\"", "\""+secondId+"\"", true, map[string]string{ + "color": params.color, + "style": params.style, + }) + if err != nil { + return err + } + + return nil + } + + var addLinks = func(r *aclrecordproto.ACLRecord, id string) error { + if r.PrevId == "" { + return nil + } + err := createEdge(id, r.PrevId, EdgeParameters{ + style: "dashed", + color: "red", + }) + if err != nil { + return err + } + + return nil + } + + err := t.traverseFromHead(addNodes) + if err != nil { + return "", err + } + + err = t.traverseFromHead(addLinks) + if err != nil { + return "", err + } + + return graph.String(), nil +} diff --git a/common/pkg/acl/testutils/acllistbuilder/ymlentities.go b/common/pkg/acl/testutils/acllistbuilder/ymlentities.go new file mode 100644 index 00000000..ccdfd295 --- /dev/null +++ b/common/pkg/acl/testutils/acllistbuilder/ymlentities.go @@ -0,0 +1,70 @@ +package acllistbuilder + +type Key struct { + Name string `yaml:"name"` + Value string `yaml:"value"` +} + +type Keys struct { + Derived string `yaml:"Derived"` + Enc []*Key `yaml:"Enc"` + Sign []*Key `yaml:"Sign"` + Read []*Key `yaml:"Read"` +} + +type ACLChange struct { + UserAdd *struct { + Identity string `yaml:"identity"` + EncryptionKey string `yaml:"encryptionKey"` + EncryptedReadKeys []string `yaml:"encryptedReadKeys"` + Permission string `yaml:"permission"` + } `yaml:"userAdd"` + + UserJoin *struct { + Identity string `yaml:"identity"` + EncryptionKey string `yaml:"encryptionKey"` + AcceptKey string `yaml:"acceptKey"` + EncryptedReadKeys []string `yaml:"encryptedReadKeys"` + } `yaml:"userJoin"` + + UserInvite *struct { + AcceptKey string `yaml:"acceptKey"` + EncryptionKey string `yaml:"encryptionKey"` + EncryptedReadKeys []string `yaml:"encryptedReadKeys"` + Permissions string `yaml:"permissions"` + } `yaml:"userInvite"` + + UserRemove *struct { + RemovedIdentity string `yaml:"removedIdentity"` + NewReadKey string `yaml:"newReadKey"` + IdentitiesLeft []string `yaml:"identitiesLeft"` + } `yaml:"userRemove"` + + UserPermissionChange *struct { + Identity string `yaml:"identity"` + Permission string `yaml:"permission"` + } +} + +type Record struct { + Identity string `yaml:"identity"` + AclChanges []*ACLChange `yaml:"aclChanges"` + ReadKey string `yaml:"readKey"` +} + +type Header struct { + FirstChangeId string `yaml:"firstChangeId"` + IsWorkspace bool `yaml:"isWorkspace"` +} + +type Root struct { + Identity string `yaml:"identity"` + SpaceId string `yaml:"spaceId"` +} + +type YMLList struct { + Root *Root + Records []*Record `yaml:"records"` + + Keys Keys `yaml:"keys"` +} diff --git a/common/pkg/acl/testutils/testchanges/proto/test.pb.go b/common/pkg/acl/testutils/testchanges/proto/test.pb.go new file mode 100644 index 00000000..9071b091 --- /dev/null +++ b/common/pkg/acl/testutils/testchanges/proto/test.pb.go @@ -0,0 +1,969 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: pkg/acl/testutils/testchanges/proto/test.proto + +package testchanges + +import ( + fmt "fmt" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type TextContent struct { + // Types that are valid to be assigned to Value: + // + // *TextContent_TextAppend + Value isTextContent_Value `protobuf_oneof:"value"` +} + +func (m *TextContent) Reset() { *m = TextContent{} } +func (m *TextContent) String() string { return proto.CompactTextString(m) } +func (*TextContent) ProtoMessage() {} +func (*TextContent) Descriptor() ([]byte, []int) { + return fileDescriptor_37f33c266ada4318, []int{0} +} +func (m *TextContent) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TextContent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TextContent.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TextContent) XXX_Merge(src proto.Message) { + xxx_messageInfo_TextContent.Merge(m, src) +} +func (m *TextContent) XXX_Size() int { + return m.Size() +} +func (m *TextContent) XXX_DiscardUnknown() { + xxx_messageInfo_TextContent.DiscardUnknown(m) +} + +var xxx_messageInfo_TextContent proto.InternalMessageInfo + +type isTextContent_Value interface { + isTextContent_Value() + MarshalTo([]byte) (int, error) + Size() int +} + +type TextContent_TextAppend struct { + TextAppend *TextAppend `protobuf:"bytes,1,opt,name=textAppend,proto3,oneof" json:"textAppend,omitempty"` +} + +func (*TextContent_TextAppend) isTextContent_Value() {} + +func (m *TextContent) GetValue() isTextContent_Value { + if m != nil { + return m.Value + } + return nil +} + +func (m *TextContent) GetTextAppend() *TextAppend { + if x, ok := m.GetValue().(*TextContent_TextAppend); ok { + return x.TextAppend + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*TextContent) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*TextContent_TextAppend)(nil), + } +} + +type TextAppend struct { + Text string `protobuf:"bytes,1,opt,name=text,proto3" json:"text,omitempty"` +} + +func (m *TextAppend) Reset() { *m = TextAppend{} } +func (m *TextAppend) String() string { return proto.CompactTextString(m) } +func (*TextAppend) ProtoMessage() {} +func (*TextAppend) Descriptor() ([]byte, []int) { + return fileDescriptor_37f33c266ada4318, []int{1} +} +func (m *TextAppend) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TextAppend) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TextAppend.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TextAppend) XXX_Merge(src proto.Message) { + xxx_messageInfo_TextAppend.Merge(m, src) +} +func (m *TextAppend) XXX_Size() int { + return m.Size() +} +func (m *TextAppend) XXX_DiscardUnknown() { + xxx_messageInfo_TextAppend.DiscardUnknown(m) +} + +var xxx_messageInfo_TextAppend proto.InternalMessageInfo + +func (m *TextAppend) GetText() string { + if m != nil { + return m.Text + } + return "" +} + +type TextSnapshot struct { + Text string `protobuf:"bytes,1,opt,name=text,proto3" json:"text,omitempty"` +} + +func (m *TextSnapshot) Reset() { *m = TextSnapshot{} } +func (m *TextSnapshot) String() string { return proto.CompactTextString(m) } +func (*TextSnapshot) ProtoMessage() {} +func (*TextSnapshot) Descriptor() ([]byte, []int) { + return fileDescriptor_37f33c266ada4318, []int{2} +} +func (m *TextSnapshot) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TextSnapshot) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TextSnapshot.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TextSnapshot) XXX_Merge(src proto.Message) { + xxx_messageInfo_TextSnapshot.Merge(m, src) +} +func (m *TextSnapshot) XXX_Size() int { + return m.Size() +} +func (m *TextSnapshot) XXX_DiscardUnknown() { + xxx_messageInfo_TextSnapshot.DiscardUnknown(m) +} + +var xxx_messageInfo_TextSnapshot proto.InternalMessageInfo + +func (m *TextSnapshot) GetText() string { + if m != nil { + return m.Text + } + return "" +} + +type TextData struct { + Content []*TextContent `protobuf:"bytes,1,rep,name=content,proto3" json:"content,omitempty"` + Snapshot *TextSnapshot `protobuf:"bytes,2,opt,name=snapshot,proto3" json:"snapshot,omitempty"` +} + +func (m *TextData) Reset() { *m = TextData{} } +func (m *TextData) String() string { return proto.CompactTextString(m) } +func (*TextData) ProtoMessage() {} +func (*TextData) Descriptor() ([]byte, []int) { + return fileDescriptor_37f33c266ada4318, []int{3} +} +func (m *TextData) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TextData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TextData.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TextData) XXX_Merge(src proto.Message) { + xxx_messageInfo_TextData.Merge(m, src) +} +func (m *TextData) XXX_Size() int { + return m.Size() +} +func (m *TextData) XXX_DiscardUnknown() { + xxx_messageInfo_TextData.DiscardUnknown(m) +} + +var xxx_messageInfo_TextData proto.InternalMessageInfo + +func (m *TextData) GetContent() []*TextContent { + if m != nil { + return m.Content + } + return nil +} + +func (m *TextData) GetSnapshot() *TextSnapshot { + if m != nil { + return m.Snapshot + } + return nil +} + +func init() { + proto.RegisterType((*TextContent)(nil), "anytype.TextContent") + proto.RegisterType((*TextAppend)(nil), "anytype.TextAppend") + proto.RegisterType((*TextSnapshot)(nil), "anytype.TextSnapshot") + proto.RegisterType((*TextData)(nil), "anytype.TextData") +} + +func init() { + proto.RegisterFile("pkg/acl/testutils/testchanges/proto/test.proto", fileDescriptor_37f33c266ada4318) +} + +var fileDescriptor_37f33c266ada4318 = []byte{ + // 252 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x2b, 0xc8, 0x4e, 0xd7, + 0x4f, 0x4c, 0xce, 0xd1, 0x2f, 0x49, 0x2d, 0x2e, 0x29, 0x2d, 0xc9, 0xcc, 0x29, 0x06, 0xb3, 0x92, + 0x33, 0x12, 0xf3, 0xd2, 0x53, 0x8b, 0xf5, 0x0b, 0x8a, 0xf2, 0x4b, 0xf2, 0xc1, 0x22, 0x7a, 0x60, + 0xa6, 0x10, 0x7b, 0x62, 0x5e, 0x65, 0x49, 0x65, 0x41, 0xaa, 0x92, 0x2f, 0x17, 0x77, 0x48, 0x6a, + 0x45, 0x89, 0x73, 0x7e, 0x5e, 0x49, 0x6a, 0x5e, 0x89, 0x90, 0x29, 0x17, 0x57, 0x49, 0x6a, 0x45, + 0x89, 0x63, 0x41, 0x41, 0x6a, 0x5e, 0x8a, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0xb7, 0x91, 0xb0, 0x1e, + 0x54, 0xb1, 0x5e, 0x08, 0x5c, 0xca, 0x83, 0x21, 0x08, 0x49, 0xa1, 0x13, 0x3b, 0x17, 0x6b, 0x59, + 0x62, 0x4e, 0x69, 0xaa, 0x92, 0x02, 0x17, 0x17, 0x42, 0x91, 0x90, 0x10, 0x17, 0x0b, 0x48, 0x11, + 0xd8, 0x1c, 0xce, 0x20, 0x30, 0x5b, 0x49, 0x89, 0x8b, 0x07, 0xa4, 0x22, 0x38, 0x2f, 0xb1, 0xa0, + 0x38, 0x23, 0xbf, 0x04, 0xab, 0x9a, 0x5c, 0x2e, 0x0e, 0x90, 0x1a, 0x97, 0xc4, 0x92, 0x44, 0x21, + 0x3d, 0x2e, 0xf6, 0x64, 0x88, 0xe3, 0x24, 0x18, 0x15, 0x98, 0x35, 0xb8, 0x8d, 0x44, 0x50, 0x9c, + 0x03, 0x75, 0x78, 0x10, 0x4c, 0x91, 0x90, 0x21, 0x17, 0x47, 0x31, 0xd4, 0x6c, 0x09, 0x26, 0xb0, + 0xfb, 0x45, 0x51, 0x34, 0xc0, 0x2c, 0x0e, 0x82, 0x2b, 0x73, 0x52, 0x3d, 0xf1, 0x48, 0x8e, 0xf1, + 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, + 0xe1, 0xc6, 0x63, 0x39, 0x86, 0x28, 0x6e, 0xa4, 0x40, 0x4c, 0x62, 0x03, 0x07, 0x9d, 0x31, 0x20, + 0x00, 0x00, 0xff, 0xff, 0xdc, 0xbf, 0x78, 0xe5, 0x6c, 0x01, 0x00, 0x00, +} + +func (m *TextContent) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TextContent) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TextContent) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Value != nil { + { + size := m.Value.Size() + i -= size + if _, err := m.Value.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + return len(dAtA) - i, nil +} + +func (m *TextContent_TextAppend) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TextContent_TextAppend) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.TextAppend != nil { + { + size, err := m.TextAppend.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTest(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} +func (m *TextAppend) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TextAppend) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TextAppend) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Text) > 0 { + i -= len(m.Text) + copy(dAtA[i:], m.Text) + i = encodeVarintTest(dAtA, i, uint64(len(m.Text))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *TextSnapshot) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TextSnapshot) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TextSnapshot) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Text) > 0 { + i -= len(m.Text) + copy(dAtA[i:], m.Text) + i = encodeVarintTest(dAtA, i, uint64(len(m.Text))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *TextData) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TextData) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TextData) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Snapshot != nil { + { + size, err := m.Snapshot.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTest(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Content) > 0 { + for iNdEx := len(m.Content) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Content[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTest(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintTest(dAtA []byte, offset int, v uint64) int { + offset -= sovTest(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *TextContent) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Value != nil { + n += m.Value.Size() + } + return n +} + +func (m *TextContent_TextAppend) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.TextAppend != nil { + l = m.TextAppend.Size() + n += 1 + l + sovTest(uint64(l)) + } + return n +} +func (m *TextAppend) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Text) + if l > 0 { + n += 1 + l + sovTest(uint64(l)) + } + return n +} + +func (m *TextSnapshot) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Text) + if l > 0 { + n += 1 + l + sovTest(uint64(l)) + } + return n +} + +func (m *TextData) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Content) > 0 { + for _, e := range m.Content { + l = e.Size() + n += 1 + l + sovTest(uint64(l)) + } + } + if m.Snapshot != nil { + l = m.Snapshot.Size() + n += 1 + l + sovTest(uint64(l)) + } + return n +} + +func sovTest(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTest(x uint64) (n int) { + return sovTest(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *TextContent) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTest + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TextContent: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TextContent: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TextAppend", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTest + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTest + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTest + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &TextAppend{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Value = &TextContent_TextAppend{v} + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTest(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTest + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TextAppend) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTest + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TextAppend: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TextAppend: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Text", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTest + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTest + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTest + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Text = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTest(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTest + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TextSnapshot) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTest + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TextSnapshot: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TextSnapshot: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Text", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTest + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTest + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTest + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Text = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTest(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTest + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TextData) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTest + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TextData: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TextData: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Content", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTest + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTest + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTest + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Content = append(m.Content, &TextContent{}) + if err := m.Content[len(m.Content)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Snapshot", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTest + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTest + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTest + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Snapshot == nil { + m.Snapshot = &TextSnapshot{} + } + if err := m.Snapshot.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTest(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTest + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTest(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTest + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTest + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTest + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthTest + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTest + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTest + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTest = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTest = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTest = fmt.Errorf("proto: unexpected end of group") +) diff --git a/common/pkg/acl/testutils/testchanges/proto/test.proto b/common/pkg/acl/testutils/testchanges/proto/test.proto new file mode 100644 index 00000000..2c9d5f66 --- /dev/null +++ b/common/pkg/acl/testutils/testchanges/proto/test.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; +package anytype; +option go_package = "testchanges"; + +message TextContent { + oneof value { + TextAppend textAppend = 1; + } +} + +message TextAppend { + string text = 1; +} + +message TextSnapshot { + string text = 1; +} + +message TextData { + repeated TextContent content = 1; + TextSnapshot snapshot = 2; +} diff --git a/pkg/acl/testutils/yamltests/path.go b/common/pkg/acl/testutils/yamltests/path.go similarity index 100% rename from pkg/acl/testutils/yamltests/path.go rename to common/pkg/acl/testutils/yamltests/path.go diff --git a/common/pkg/acl/testutils/yamltests/userjoinexample.yml b/common/pkg/acl/testutils/yamltests/userjoinexample.yml new file mode 100644 index 00000000..fd90c063 --- /dev/null +++ b/common/pkg/acl/testutils/yamltests/userjoinexample.yml @@ -0,0 +1,53 @@ +root: + identity: A + spaceId: space +records: + - identity: A + aclChanges: + - userInvite: + acceptKey: key.Sign.Onetime1 + encryptionKey: key.Read.EncKey + encryptedReadKeys: [key.Read.A] + permissions: writer + - userAdd: + identity: C + permission: reader + encryptionKey: key.Enc.C + encryptedReadKeys: [key.Read.A] + readKey: key.Read.A + - identity: B + aclChanges: + - userJoin: + identity: B + encryptionKey: key.Enc.B + acceptKey: key.Sign.Onetime1 + encryptedReadKeys: [key.Read.A] + readKey: key.Read.A +keys: + Enc: + - name: A + value: generated + - name: B + value: generated + - name: C + value: generated + - name: D + value: generated + - name: Onetime1 + value: generated + Sign: + - name: A + value: generated + - name: B + value: generated + - name: C + value: generated + - name: D + value: generated + - name: Onetime1 + value: generated + Read: + - name: A + value: derived + - name: EncKey + value: generated diff --git a/common/pkg/acl/testutils/yamltests/userremoveexample.yml b/common/pkg/acl/testutils/yamltests/userremoveexample.yml new file mode 100644 index 00000000..cc6d817e --- /dev/null +++ b/common/pkg/acl/testutils/yamltests/userremoveexample.yml @@ -0,0 +1,58 @@ +root: + identity: A + spaceId: space +records: + - identity: A + aclChanges: + - userInvite: + acceptKey: key.Sign.Onetime1 + encryptionKey: key.Read.EncKey + encryptedReadKeys: [key.Read.A] + permissions: writer + - userAdd: + identity: C + permission: reader + encryptionKey: key.Enc.C + encryptedReadKeys: [key.Read.A] + readKey: key.Read.A + - identity: B + aclChanges: + - userJoin: + identity: B + encryptionKey: key.Enc.B + acceptKey: key.Sign.Onetime1 + encryptedReadKeys: [key.Read.A] + readKey: key.Read.A + - identity: A + aclChanges: + - userRemove: + removedIdentity: B + newReadKey: key.Read.2 + identitiesLeft: [A, C] + readKey: key.Read.2 +keys: + Enc: + - name: A + value: generated + - name: B + value: generated + - name: C + value: generated + - name: Onetime1 + value: generated + Sign: + - name: A + value: generated + - name: B + value: generated + - name: C + value: generated + - name: Onetime1 + value: generated + Read: + - name: A + value: derived + - name: 2 + value: generated + - name: EncKey + value: generated diff --git a/common/pkg/acl/tree/change.go b/common/pkg/acl/tree/change.go new file mode 100644 index 00000000..308ee958 --- /dev/null +++ b/common/pkg/acl/tree/change.go @@ -0,0 +1,63 @@ +package tree + +import ( + "errors" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto" +) + +var ( + ErrIncorrectSignature = errors.New("change has incorrect signature") + ErrIncorrectCID = errors.New("change has incorrect CID") +) + +// Change is an abstract type for all types of changes +type Change struct { + Next []*Change + PreviousIds []string + AclHeadId string + Id string + SnapshotId string + IsSnapshot bool + Timestamp int64 + ReadKeyHash uint64 + Identity string + Data []byte + Model interface{} + + // iterator helpers + visited bool + branchesFinished bool + + Signature []byte +} + +func NewChange(id string, ch *treechangeproto.TreeChange, signature []byte) *Change { + return &Change{ + Next: nil, + PreviousIds: ch.TreeHeadIds, + AclHeadId: ch.AclHeadId, + Timestamp: ch.Timestamp, + ReadKeyHash: ch.CurrentReadKeyHash, + Id: id, + Data: ch.ChangesData, + SnapshotId: ch.SnapshotBaseId, + IsSnapshot: ch.IsSnapshot, + Identity: string(ch.Identity), + Signature: signature, + } +} + +func NewChangeFromRoot(id string, ch *treechangeproto.RootChange, signature []byte) *Change { + return &Change{ + Next: nil, + AclHeadId: ch.AclHeadId, + Id: id, + IsSnapshot: true, + Identity: string(ch.Identity), + Signature: signature, + } +} + +func (ch *Change) CID() string { + return ch.Id +} diff --git a/common/pkg/acl/tree/changebuilder.go b/common/pkg/acl/tree/changebuilder.go new file mode 100644 index 00000000..05d37721 --- /dev/null +++ b/common/pkg/acl/tree/changebuilder.go @@ -0,0 +1,254 @@ +package tree + +import ( + "errors" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/common" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/cid" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/signingkey" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/symmetric" + "github.com/gogo/protobuf/proto" + "time" +) + +var ErrEmptyChange = errors.New("change payload should not be empty") + +type BuilderContent struct { + TreeHeadIds []string + AclHeadId string + SnapshotBaseId string + CurrentReadKeyHash uint64 + Identity []byte + IsSnapshot bool + SigningKey signingkey.PrivKey + ReadKey *symmetric.Key + Content []byte +} + +type InitialContent struct { + AclHeadId string + Identity []byte + SigningKey signingkey.PrivKey + SpaceId string + Seed []byte + ChangeType string + Timestamp int64 +} + +type ChangeBuilder interface { + ConvertFromRaw(rawIdChange *treechangeproto.RawTreeChangeWithId, verify bool) (ch *Change, err error) + BuildContent(payload BuilderContent) (ch *Change, raw *treechangeproto.RawTreeChangeWithId, err error) + BuildInitialContent(payload InitialContent) (ch *Change, raw *treechangeproto.RawTreeChangeWithId, err error) + BuildRaw(ch *Change) (*treechangeproto.RawTreeChangeWithId, error) + SetRootRawChange(rawIdChange *treechangeproto.RawTreeChangeWithId) +} + +type changeBuilder struct { + rootChange *treechangeproto.RawTreeChangeWithId + keys *common.Keychain +} + +func newChangeBuilder(keys *common.Keychain, rootChange *treechangeproto.RawTreeChangeWithId) ChangeBuilder { + return &changeBuilder{keys: keys, rootChange: rootChange} +} + +func (c *changeBuilder) ConvertFromRaw(rawIdChange *treechangeproto.RawTreeChangeWithId, verify bool) (ch *Change, err error) { + if rawIdChange.GetRawChange() == nil { + err = ErrEmptyChange + return + } + + if verify { + // verifying ID + if !cid.VerifyCID(rawIdChange.RawChange, rawIdChange.Id) { + err = ErrIncorrectCID + return + } + } + + raw := &treechangeproto.RawTreeChange{} // TODO: sync pool + err = proto.Unmarshal(rawIdChange.GetRawChange(), raw) + if err != nil { + return + } + ch, err = c.unmarshallRawChange(raw, rawIdChange.Id) + if err != nil { + return + } + + if verify { + var identityKey signingkey.PubKey + identityKey, err = c.keys.GetOrAdd(ch.Identity) + if err != nil { + return + } + + // verifying signature + var res bool + res, err = identityKey.Verify(raw.Payload, raw.Signature) + if err != nil { + return + } + if !res { + err = ErrIncorrectSignature + return + } + } + return +} + +func (c *changeBuilder) SetRootRawChange(rawIdChange *treechangeproto.RawTreeChangeWithId) { + c.rootChange = rawIdChange +} + +func (c *changeBuilder) BuildInitialContent(payload InitialContent) (ch *Change, rawIdChange *treechangeproto.RawTreeChangeWithId, err error) { + change := &treechangeproto.RootChange{ + AclHeadId: payload.AclHeadId, + Timestamp: payload.Timestamp, + Identity: payload.Identity, + ChangeType: payload.ChangeType, + SpaceId: payload.SpaceId, + Seed: payload.Seed, + } + + marshalledChange, err := proto.Marshal(change) + if err != nil { + return + } + + signature, err := payload.SigningKey.Sign(marshalledChange) + if err != nil { + return + } + + raw := &treechangeproto.RawTreeChange{ + Payload: marshalledChange, + Signature: signature, + } + + marshalledRawChange, err := proto.Marshal(raw) + if err != nil { + return + } + + id, err := cid.NewCIDFromBytes(marshalledRawChange) + if err != nil { + return + } + + ch = NewChangeFromRoot(id, change, signature) + + rawIdChange = &treechangeproto.RawTreeChangeWithId{ + RawChange: marshalledRawChange, + Id: id, + } + return +} + +func (c *changeBuilder) BuildContent(payload BuilderContent) (ch *Change, rawIdChange *treechangeproto.RawTreeChangeWithId, err error) { + change := &treechangeproto.TreeChange{ + TreeHeadIds: payload.TreeHeadIds, + AclHeadId: payload.AclHeadId, + SnapshotBaseId: payload.SnapshotBaseId, + CurrentReadKeyHash: payload.CurrentReadKeyHash, + Timestamp: int64(time.Now().Nanosecond()), + Identity: payload.Identity, + IsSnapshot: payload.IsSnapshot, + } + + encrypted, err := payload.ReadKey.Encrypt(payload.Content) + if err != nil { + return + } + change.ChangesData = encrypted + + marshalledChange, err := proto.Marshal(change) + if err != nil { + return + } + + signature, err := payload.SigningKey.Sign(marshalledChange) + if err != nil { + return + } + + raw := &treechangeproto.RawTreeChange{ + Payload: marshalledChange, + Signature: signature, + } + + marshalledRawChange, err := proto.Marshal(raw) + if err != nil { + return + } + + id, err := cid.NewCIDFromBytes(marshalledRawChange) + if err != nil { + return + } + + ch = NewChange(id, change, signature) + ch.Model = payload.Content + + rawIdChange = &treechangeproto.RawTreeChangeWithId{ + RawChange: marshalledRawChange, + Id: id, + } + return +} + +func (c *changeBuilder) BuildRaw(ch *Change) (raw *treechangeproto.RawTreeChangeWithId, err error) { + if ch.Id == c.rootChange.Id { + return c.rootChange, nil + } + treeChange := &treechangeproto.TreeChange{ + TreeHeadIds: ch.PreviousIds, + AclHeadId: ch.AclHeadId, + SnapshotBaseId: ch.SnapshotId, + ChangesData: ch.Data, + CurrentReadKeyHash: ch.ReadKeyHash, + Timestamp: ch.Timestamp, + Identity: []byte(ch.Identity), + IsSnapshot: ch.IsSnapshot, + } + var marshalled []byte + marshalled, err = treeChange.Marshal() + if err != nil { + return + } + + marshalledRawChange, err := proto.Marshal(&treechangeproto.RawTreeChange{ + Payload: marshalled, + Signature: ch.Signature, + }) + if err != nil { + return + } + + raw = &treechangeproto.RawTreeChangeWithId{ + RawChange: marshalledRawChange, + Id: ch.Id, + } + return +} + +func (c *changeBuilder) unmarshallRawChange(raw *treechangeproto.RawTreeChange, id string) (ch *Change, err error) { + if c.rootChange.Id == id { + unmarshalled := &treechangeproto.RootChange{} + err = proto.Unmarshal(raw.Payload, unmarshalled) + if err != nil { + return + } + ch = NewChangeFromRoot(id, unmarshalled, raw.Signature) + return + } + + unmarshalled := &treechangeproto.TreeChange{} + err = proto.Unmarshal(raw.Payload, unmarshalled) + if err != nil { + return + } + + ch = NewChange(id, unmarshalled, raw.Signature) + return +} diff --git a/common/pkg/acl/tree/changevalidator.go b/common/pkg/acl/tree/changevalidator.go new file mode 100644 index 00000000..b4d63ea9 --- /dev/null +++ b/common/pkg/acl/tree/changevalidator.go @@ -0,0 +1,77 @@ +package tree + +import ( + "fmt" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/list" +) + +type ObjectTreeValidator interface { + // ValidateFullTree should always be entered while holding a read lock on ACLList + ValidateFullTree(tree *Tree, aclList list.ACLList) error + // ValidateNewChanges should always be entered while holding a read lock on ACLList + ValidateNewChanges(tree *Tree, aclList list.ACLList, newChanges []*Change) error +} + +type objectTreeValidator struct{} + +func newTreeValidator() ObjectTreeValidator { + return &objectTreeValidator{} +} + +func (v *objectTreeValidator) ValidateFullTree(tree *Tree, aclList list.ACLList) (err error) { + tree.Iterate(tree.RootId(), func(c *Change) (isContinue bool) { + err = v.validateChange(tree, aclList, c) + return err == nil + }) + return err +} + +func (v *objectTreeValidator) ValidateNewChanges(tree *Tree, aclList list.ACLList, newChanges []*Change) (err error) { + for _, c := range newChanges { + err = v.validateChange(tree, aclList, c) + if err != nil { + return + } + } + return +} + +func (v *objectTreeValidator) validateChange(tree *Tree, aclList list.ACLList, c *Change) (err error) { + var ( + perm list.UserPermissionPair + state = aclList.ACLState() + ) + // checking if the user could write + perm, err = state.PermissionsAtRecord(c.AclHeadId, c.Identity) + if err != nil { + return + } + + if perm.Permission != aclrecordproto.ACLUserPermissions_Writer && perm.Permission != aclrecordproto.ACLUserPermissions_Admin { + err = list.ErrInsufficientPermissions + return + } + + if c.Id == tree.RootId() { + return + } + + // checking if the change refers to later acl heads than its previous ids + for _, id := range c.PreviousIds { + prevChange := tree.attached[id] + if prevChange.AclHeadId == c.AclHeadId { + continue + } + var after bool + after, err = aclList.IsAfter(c.AclHeadId, prevChange.AclHeadId) + if err != nil { + return + } + if !after { + err = fmt.Errorf("current acl head id (%s) should be after each of the previous ones (%s)", c.AclHeadId, prevChange.AclHeadId) + return + } + } + return +} diff --git a/common/pkg/acl/tree/descriptionparser.go b/common/pkg/acl/tree/descriptionparser.go new file mode 100644 index 00000000..c7ad3bfe --- /dev/null +++ b/common/pkg/acl/tree/descriptionparser.go @@ -0,0 +1,13 @@ +package tree + +type DescriptionParser interface { + ParseChange(*Change) ([]string, error) +} + +var NoOpDescriptionParser = noopDescriptionParser{} + +type noopDescriptionParser struct{} + +func (n noopDescriptionParser) ParseChange(change *Change) ([]string, error) { + return []string{"DOC"}, nil +} diff --git a/common/pkg/acl/tree/mock_objecttree/mock_objecttree.go b/common/pkg/acl/tree/mock_objecttree/mock_objecttree.go new file mode 100644 index 00000000..205fb8ce --- /dev/null +++ b/common/pkg/acl/tree/mock_objecttree/mock_objecttree.go @@ -0,0 +1,295 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree (interfaces: ObjectTree) + +// Package mock_tree is a generated GoMock package. +package mock_tree + +import ( + context "context" + reflect "reflect" + + storage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage" + tree "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree" + treechangeproto "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto" + gomock "github.com/golang/mock/gomock" +) + +// MockObjectTree is a mock of ObjectTree interface. +type MockObjectTree struct { + ctrl *gomock.Controller + recorder *MockObjectTreeMockRecorder +} + +// MockObjectTreeMockRecorder is the mock recorder for MockObjectTree. +type MockObjectTreeMockRecorder struct { + mock *MockObjectTree +} + +// NewMockObjectTree creates a new mock instance. +func NewMockObjectTree(ctrl *gomock.Controller) *MockObjectTree { + mock := &MockObjectTree{ctrl: ctrl} + mock.recorder = &MockObjectTreeMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockObjectTree) EXPECT() *MockObjectTreeMockRecorder { + return m.recorder +} + +// AddContent mocks base method. +func (m *MockObjectTree) AddContent(arg0 context.Context, arg1 tree.SignableChangeContent) (tree.AddResult, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AddContent", arg0, arg1) + ret0, _ := ret[0].(tree.AddResult) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// AddContent indicates an expected call of AddContent. +func (mr *MockObjectTreeMockRecorder) AddContent(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddContent", reflect.TypeOf((*MockObjectTree)(nil).AddContent), arg0, arg1) +} + +// AddRawChanges mocks base method. +func (m *MockObjectTree) AddRawChanges(arg0 context.Context, arg1 ...*treechangeproto.RawTreeChangeWithId) (tree.AddResult, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0} + for _, a := range arg1 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "AddRawChanges", varargs...) + ret0, _ := ret[0].(tree.AddResult) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// AddRawChanges indicates an expected call of AddRawChanges. +func (mr *MockObjectTreeMockRecorder) AddRawChanges(arg0 interface{}, arg1 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0}, arg1...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRawChanges", reflect.TypeOf((*MockObjectTree)(nil).AddRawChanges), varargs...) +} + +// ChangesAfterCommonSnapshot mocks base method. +func (m *MockObjectTree) ChangesAfterCommonSnapshot(arg0, arg1 []string) ([]*treechangeproto.RawTreeChangeWithId, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChangesAfterCommonSnapshot", arg0, arg1) + ret0, _ := ret[0].([]*treechangeproto.RawTreeChangeWithId) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChangesAfterCommonSnapshot indicates an expected call of ChangesAfterCommonSnapshot. +func (mr *MockObjectTreeMockRecorder) ChangesAfterCommonSnapshot(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChangesAfterCommonSnapshot", reflect.TypeOf((*MockObjectTree)(nil).ChangesAfterCommonSnapshot), arg0, arg1) +} + +// Close mocks base method. +func (m *MockObjectTree) Close() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Close") + ret0, _ := ret[0].(error) + return ret0 +} + +// Close indicates an expected call of Close. +func (mr *MockObjectTreeMockRecorder) Close() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockObjectTree)(nil).Close)) +} + +// DebugDump mocks base method. +func (m *MockObjectTree) DebugDump() (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DebugDump") + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DebugDump indicates an expected call of DebugDump. +func (mr *MockObjectTreeMockRecorder) DebugDump() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DebugDump", reflect.TypeOf((*MockObjectTree)(nil).DebugDump)) +} + +// HasChanges mocks base method. +func (m *MockObjectTree) HasChanges(arg0 ...string) bool { + m.ctrl.T.Helper() + varargs := []interface{}{} + for _, a := range arg0 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "HasChanges", varargs...) + ret0, _ := ret[0].(bool) + return ret0 +} + +// HasChanges indicates an expected call of HasChanges. +func (mr *MockObjectTreeMockRecorder) HasChanges(arg0 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasChanges", reflect.TypeOf((*MockObjectTree)(nil).HasChanges), arg0...) +} + +// Header mocks base method. +func (m *MockObjectTree) Header() *treechangeproto.RawTreeChangeWithId { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Header") + ret0, _ := ret[0].(*treechangeproto.RawTreeChangeWithId) + return ret0 +} + +// Header indicates an expected call of Header. +func (mr *MockObjectTreeMockRecorder) Header() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Header", reflect.TypeOf((*MockObjectTree)(nil).Header)) +} + +// Heads mocks base method. +func (m *MockObjectTree) Heads() []string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Heads") + ret0, _ := ret[0].([]string) + return ret0 +} + +// Heads indicates an expected call of Heads. +func (mr *MockObjectTreeMockRecorder) Heads() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Heads", reflect.TypeOf((*MockObjectTree)(nil).Heads)) +} + +// ID mocks base method. +func (m *MockObjectTree) ID() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ID") + ret0, _ := ret[0].(string) + return ret0 +} + +// ID indicates an expected call of ID. +func (mr *MockObjectTreeMockRecorder) ID() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ID", reflect.TypeOf((*MockObjectTree)(nil).ID)) +} + +// Iterate mocks base method. +func (m *MockObjectTree) Iterate(arg0 func([]byte) (interface{}, error), arg1 func(*tree.Change) bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Iterate", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// Iterate indicates an expected call of Iterate. +func (mr *MockObjectTreeMockRecorder) Iterate(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Iterate", reflect.TypeOf((*MockObjectTree)(nil).Iterate), arg0, arg1) +} + +// IterateFrom mocks base method. +func (m *MockObjectTree) IterateFrom(arg0 string, arg1 func([]byte) (interface{}, error), arg2 func(*tree.Change) bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IterateFrom", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// IterateFrom indicates an expected call of IterateFrom. +func (mr *MockObjectTreeMockRecorder) IterateFrom(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IterateFrom", reflect.TypeOf((*MockObjectTree)(nil).IterateFrom), arg0, arg1, arg2) +} + +// Lock mocks base method. +func (m *MockObjectTree) Lock() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Lock") +} + +// Lock indicates an expected call of Lock. +func (mr *MockObjectTreeMockRecorder) Lock() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Lock", reflect.TypeOf((*MockObjectTree)(nil).Lock)) +} + +// RLock mocks base method. +func (m *MockObjectTree) RLock() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "RLock") +} + +// RLock indicates an expected call of RLock. +func (mr *MockObjectTreeMockRecorder) RLock() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RLock", reflect.TypeOf((*MockObjectTree)(nil).RLock)) +} + +// RUnlock mocks base method. +func (m *MockObjectTree) RUnlock() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "RUnlock") +} + +// RUnlock indicates an expected call of RUnlock. +func (mr *MockObjectTreeMockRecorder) RUnlock() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RUnlock", reflect.TypeOf((*MockObjectTree)(nil).RUnlock)) +} + +// Root mocks base method. +func (m *MockObjectTree) Root() *tree.Change { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Root") + ret0, _ := ret[0].(*tree.Change) + return ret0 +} + +// Root indicates an expected call of Root. +func (mr *MockObjectTreeMockRecorder) Root() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Root", reflect.TypeOf((*MockObjectTree)(nil).Root)) +} + +// SnapshotPath mocks base method. +func (m *MockObjectTree) SnapshotPath() []string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SnapshotPath") + ret0, _ := ret[0].([]string) + return ret0 +} + +// SnapshotPath indicates an expected call of SnapshotPath. +func (mr *MockObjectTreeMockRecorder) SnapshotPath() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SnapshotPath", reflect.TypeOf((*MockObjectTree)(nil).SnapshotPath)) +} + +// Storage mocks base method. +func (m *MockObjectTree) Storage() storage.TreeStorage { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Storage") + ret0, _ := ret[0].(storage.TreeStorage) + return ret0 +} + +// Storage indicates an expected call of Storage. +func (mr *MockObjectTreeMockRecorder) Storage() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Storage", reflect.TypeOf((*MockObjectTree)(nil).Storage)) +} + +// Unlock mocks base method. +func (m *MockObjectTree) Unlock() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Unlock") +} + +// Unlock indicates an expected call of Unlock. +func (mr *MockObjectTreeMockRecorder) Unlock() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Unlock", reflect.TypeOf((*MockObjectTree)(nil).Unlock)) +} diff --git a/common/pkg/acl/tree/objecttree.go b/common/pkg/acl/tree/objecttree.go new file mode 100644 index 00000000..a89b3a29 --- /dev/null +++ b/common/pkg/acl/tree/objecttree.go @@ -0,0 +1,589 @@ +//go:generate mockgen -destination mock_objecttree/mock_objecttree.go github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree ObjectTree +package tree + +import ( + "context" + "errors" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/common" + list2 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/list" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/symmetric" + "sync" +) + +type RWLocker interface { + sync.Locker + RLock() + RUnlock() +} + +var ( + ErrHasInvalidChanges = errors.New("the change is invalid") + ErrNoCommonSnapshot = errors.New("trees doesn't have a common snapshot") +) + +type AddResultSummary int + +type AddResult struct { + OldHeads []string + Heads []string + Added []*treechangeproto.RawTreeChangeWithId + + Mode Mode +} + +type ChangeIterateFunc = func(change *Change) bool +type ChangeConvertFunc = func(decrypted []byte) (any, error) + +type ObjectTree interface { + RWLocker + + ID() string + Header() *treechangeproto.RawTreeChangeWithId + Heads() []string + Root() *Change + HasChanges(...string) bool + DebugDump() (string, error) + + Iterate(convert ChangeConvertFunc, iterate ChangeIterateFunc) error + IterateFrom(id string, convert ChangeConvertFunc, iterate ChangeIterateFunc) error + + SnapshotPath() []string + ChangesAfterCommonSnapshot(snapshotPath, heads []string) ([]*treechangeproto.RawTreeChangeWithId, error) + + Storage() storage.TreeStorage + + AddContent(ctx context.Context, content SignableChangeContent) (AddResult, error) + AddRawChanges(ctx context.Context, changes ...*treechangeproto.RawTreeChangeWithId) (AddResult, error) + + Close() error +} + +type objectTree struct { + treeStorage storage.TreeStorage + changeBuilder ChangeBuilder + validator ObjectTreeValidator + rawChangeLoader *rawChangeLoader + treeBuilder *treeBuilder + aclList list2.ACLList + + id string + root *treechangeproto.RawTreeChangeWithId + tree *Tree + + keys map[uint64]*symmetric.Key + + // buffers + difSnapshotBuf []*treechangeproto.RawTreeChangeWithId + newChangesBuf []*Change + newSnapshotsBuf []*Change + notSeenIdxBuf []int + + snapshotPath []string + + sync.RWMutex +} + +type objectTreeDeps struct { + changeBuilder ChangeBuilder + treeBuilder *treeBuilder + treeStorage storage.TreeStorage + validator ObjectTreeValidator + rawChangeLoader *rawChangeLoader + aclList list2.ACLList +} + +func defaultObjectTreeDeps( + rootChange *treechangeproto.RawTreeChangeWithId, + treeStorage storage.TreeStorage, + aclList list2.ACLList) objectTreeDeps { + + keychain := common.NewKeychain() + changeBuilder := newChangeBuilder(keychain, rootChange) + treeBuilder := newTreeBuilder(treeStorage, changeBuilder) + return objectTreeDeps{ + changeBuilder: changeBuilder, + treeBuilder: treeBuilder, + treeStorage: treeStorage, + validator: newTreeValidator(), + rawChangeLoader: newRawChangeLoader(treeStorage, changeBuilder), + aclList: aclList, + } +} + +func (ot *objectTree) rebuildFromStorage(newChanges []*Change) (err error) { + ot.treeBuilder.Reset() + + ot.tree, err = ot.treeBuilder.Build(newChanges) + if err != nil { + return + } + + // during building the tree we may have marked some changes as possible roots, + // but obviously they are not roots, because of the way how we construct the tree + ot.tree.clearPossibleRoots() + + // it is a good question whether we need to validate everything + // because maybe we can trust the stuff that is already in the storage + return ot.validateTree(nil) +} + +func (ot *objectTree) ID() string { + return ot.id +} + +func (ot *objectTree) Header() *treechangeproto.RawTreeChangeWithId { + return ot.root +} + +func (ot *objectTree) Storage() storage.TreeStorage { + return ot.treeStorage +} + +func (ot *objectTree) AddContent(ctx context.Context, content SignableChangeContent) (res AddResult, err error) { + payload, err := ot.prepareBuilderContent(content) + if err != nil { + return + } + + // saving old heads + oldHeads := make([]string, 0, len(ot.tree.Heads())) + oldHeads = append(oldHeads, ot.tree.Heads()...) + + objChange, rawChange, err := ot.changeBuilder.BuildContent(payload) + if content.IsSnapshot { + // clearing tree, because we already saved everything in the last snapshot + ot.tree = &Tree{} + } + err = ot.tree.AddMergedHead(objChange) + if err != nil { + panic(err) + } + + err = ot.treeStorage.AddRawChange(rawChange) + if err != nil { + return + } + + err = ot.treeStorage.SetHeads([]string{objChange.Id}) + if err != nil { + return + } + + res = AddResult{ + OldHeads: oldHeads, + Heads: []string{objChange.Id}, + Added: []*treechangeproto.RawTreeChangeWithId{rawChange}, + Mode: Append, + } + log.With("treeId", ot.id).With("head", objChange.Id). + Debug("finished adding content") + return +} + +func (ot *objectTree) prepareBuilderContent(content SignableChangeContent) (cnt BuilderContent, err error) { + ot.aclList.RLock() + defer ot.aclList.RUnlock() + + state := ot.aclList.ACLState() // special method for own keys + readKey, err := state.CurrentReadKey() + if err != nil { + return + } + cnt = BuilderContent{ + TreeHeadIds: ot.tree.Heads(), + AclHeadId: ot.aclList.Head().Id, + SnapshotBaseId: ot.tree.RootId(), + CurrentReadKeyHash: state.CurrentReadKeyHash(), + Identity: content.Identity, + IsSnapshot: content.IsSnapshot, + SigningKey: content.Key, + ReadKey: readKey, + Content: content.Data, + } + return +} + +func (ot *objectTree) AddRawChanges(ctx context.Context, rawChanges ...*treechangeproto.RawTreeChangeWithId) (addResult AddResult, err error) { + addResult, err = ot.addRawChanges(ctx, rawChanges...) + if err != nil { + return + } + + // reducing tree if we have new roots + ot.tree.reduceTree() + + // adding to database all the added changes only after they are good + for _, ch := range addResult.Added { + err = ot.treeStorage.AddRawChange(ch) + if err != nil { + return + } + } + + // setting heads + err = ot.treeStorage.SetHeads(ot.tree.Heads()) + return +} + +func (ot *objectTree) addRawChanges(ctx context.Context, rawChanges ...*treechangeproto.RawTreeChangeWithId) (addResult AddResult, err error) { + // resetting buffers + ot.newChangesBuf = ot.newChangesBuf[:0] + ot.notSeenIdxBuf = ot.notSeenIdxBuf[:0] + ot.difSnapshotBuf = ot.difSnapshotBuf[:0] + ot.newSnapshotsBuf = ot.newSnapshotsBuf[:0] + + headsCopy := func() []string { + newHeads := make([]string, 0, len(ot.tree.Heads())) + newHeads = append(newHeads, ot.tree.Heads()...) + return newHeads + } + + // this will be returned to client, so we shouldn't use buffer here + prevHeadsCopy := headsCopy() + + // filtering changes, verifying and unmarshalling them + for idx, ch := range rawChanges { + // not unmarshalling the changes if they were already added either as unattached or attached + if _, exists := ot.tree.attached[ch.Id]; exists { + continue + } + + var change *Change + if unAttached, exists := ot.tree.unAttached[ch.Id]; exists { + change = unAttached + } else { + change, err = ot.changeBuilder.ConvertFromRaw(ch, true) + if err != nil { + return + } + } + + if change.IsSnapshot { + ot.newSnapshotsBuf = append(ot.newSnapshotsBuf, change) + } + ot.newChangesBuf = append(ot.newChangesBuf, change) + ot.notSeenIdxBuf = append(ot.notSeenIdxBuf, idx) + } + + // if no new changes, then returning + if len(ot.notSeenIdxBuf) == 0 { + addResult = AddResult{ + OldHeads: prevHeadsCopy, + Heads: prevHeadsCopy, + Mode: Nothing, + } + return + } + + rollback := func(changes []*Change) { + for _, ch := range changes { + if _, exists := ot.tree.attached[ch.Id]; exists { + delete(ot.tree.attached, ch.Id) + } + } + } + + // checks if we need to go to database + isOldSnapshot := func(ch *Change) bool { + if ch.SnapshotId == ot.tree.RootId() { + return false + } + for _, sn := range ot.newSnapshotsBuf { + // if change refers to newly received snapshot + if ch.SnapshotId == sn.Id { + return false + } + } + return true + } + + shouldRebuildFromStorage := false + // checking if we have some changes with different snapshot and then rebuilding + for idx, ch := range ot.newChangesBuf { + if isOldSnapshot(ch) { + var exists bool + // checking if it exists in the storage, if yes, then at some point it was added to the tree + // thus we don't need to look at this change + exists, err = ot.treeStorage.HasChange(ctx, ch.Id) + if err != nil { + return + } + if exists { + // marking as nil to delete after + ot.newChangesBuf[idx] = nil + continue + } + // we haven't seen the change, and it refers to old snapshot, so we should rebuild + shouldRebuildFromStorage = true + } + } + // discarding all previously seen changes + ot.newChangesBuf = discardFromSlice(ot.newChangesBuf, func(ch *Change) bool { return ch == nil }) + + if shouldRebuildFromStorage { + err = ot.rebuildFromStorage(ot.newChangesBuf) + if err != nil { + // rebuilding without new changes + ot.rebuildFromStorage(nil) + return + } + addResult, err = ot.createAddResult(prevHeadsCopy, Rebuild, nil, rawChanges) + if err != nil { + // that means that some unattached changes were somehow corrupted in memory + // this shouldn't happen but if that happens, then rebuilding from storage + ot.rebuildFromStorage(nil) + return + } + return + } + + // normal mode of operation, where we don't need to rebuild from database + mode, treeChangesAdded := ot.tree.Add(ot.newChangesBuf...) + switch mode { + case Nothing: + addResult = AddResult{ + OldHeads: prevHeadsCopy, + Heads: prevHeadsCopy, + Mode: mode, + } + return + + default: + // we need to validate only newly added changes + err = ot.validateTree(treeChangesAdded) + if err != nil { + rollback(treeChangesAdded) + err = ErrHasInvalidChanges + return + } + addResult, err = ot.createAddResult(prevHeadsCopy, mode, treeChangesAdded, rawChanges) + if err != nil { + // that means that some unattached changes were somehow corrupted in memory + // this shouldn't happen but if that happens, then rebuilding from storage + ot.rebuildFromStorage(nil) + return + } + return + } + return +} + +func (ot *objectTree) createAddResult(oldHeads []string, mode Mode, treeChangesAdded []*Change, rawChanges []*treechangeproto.RawTreeChangeWithId) (addResult AddResult, err error) { + headsCopy := func() []string { + newHeads := make([]string, 0, len(ot.tree.Heads())) + newHeads = append(newHeads, ot.tree.Heads()...) + return newHeads + } + + // returns changes that we added to the tree as attached this round + // they can include not only the changes that were added now, + // but also the changes that were previously in the tree + getAddedChanges := func(toConvert []*Change) (added []*treechangeproto.RawTreeChangeWithId, err error) { + alreadyConverted := make(map[*Change]struct{}) + + // first we see if we have already unmarshalled those changes + for _, idx := range ot.notSeenIdxBuf { + rawChange := rawChanges[idx] + if ch, exists := ot.tree.attached[rawChange.Id]; exists { + if len(toConvert) != 0 { + alreadyConverted[ch] = struct{}{} + } + added = append(added, rawChange) + } + } + // this will happen in case we called rebuild from storage + // or if all the changes that we added were contained in current add request + // (this what would happen in most cases) + if len(toConvert) == 0 || len(added) == len(toConvert) { + return + } + + // but in some cases it may happen that the changes that were added this round + // were contained in unattached from previous requests + for _, ch := range toConvert { + // if we got some changes that we need to convert to raw + if _, exists := alreadyConverted[ch]; !exists { + var raw *treechangeproto.RawTreeChangeWithId + raw, err = ot.changeBuilder.BuildRaw(ch) + if err != nil { + return + } + added = append(added, raw) + } + } + return + } + + var added []*treechangeproto.RawTreeChangeWithId + added, err = getAddedChanges(treeChangesAdded) + if err != nil { + return + } + addResult = AddResult{ + OldHeads: oldHeads, + Heads: headsCopy(), + Added: added, + Mode: mode, + } + return +} + +func (ot *objectTree) Iterate(convert ChangeConvertFunc, iterate ChangeIterateFunc) (err error) { + return ot.IterateFrom(ot.tree.RootId(), convert, iterate) +} + +func (ot *objectTree) IterateFrom(id string, convert ChangeConvertFunc, iterate ChangeIterateFunc) (err error) { + if convert == nil { + ot.tree.Iterate(id, iterate) + return + } + + ot.tree.Iterate(ot.tree.RootId(), func(c *Change) (isContinue bool) { + var model any + if c.Model != nil { + return iterate(c) + } + // if this is a root change + if c.Id == ot.id { + return iterate(c) + } + readKey, exists := ot.keys[c.ReadKeyHash] + if !exists { + err = list2.ErrNoReadKey + return false + } + + var decrypted []byte + decrypted, err = readKey.Decrypt(c.Data) + if err != nil { + return false + } + + model, err = convert(decrypted) + if err != nil { + return false + } + + c.Model = model + return iterate(c) + }) + return +} + +func (ot *objectTree) HasChanges(chs ...string) bool { + hasChange := func(s string) bool { + _, attachedExists := ot.tree.attached[s] + if attachedExists { + return attachedExists + } + + has, err := ot.treeStorage.HasChange(context.Background(), s) + if err != nil { + return false + } + + return has + } + + for _, ch := range chs { + if !hasChange(ch) { + return false + } + } + + return true +} + +func (ot *objectTree) Heads() []string { + return ot.tree.Heads() +} + +func (ot *objectTree) Root() *Change { + return ot.tree.Root() +} + +func (ot *objectTree) Close() error { + return nil +} + +func (ot *objectTree) SnapshotPath() []string { + // TODO: Add error as return parameter + if ot.snapshotPathIsActual() { + return ot.snapshotPath + } + + var path []string + // TODO: think that the user may have not all of the snapshots locally + currentSnapshotId := ot.tree.RootId() + for currentSnapshotId != "" { + sn, err := ot.treeBuilder.loadChange(currentSnapshotId) + if err != nil { + break + } + path = append(path, currentSnapshotId) + currentSnapshotId = sn.SnapshotId + } + ot.snapshotPath = path + + return path +} + +func (ot *objectTree) ChangesAfterCommonSnapshot(theirPath, theirHeads []string) ([]*treechangeproto.RawTreeChangeWithId, error) { + var ( + needFullDocument = len(theirPath) == 0 + ourPath = ot.SnapshotPath() + // by default returning everything we have from start + commonSnapshot = ourPath[len(ourPath)-1] + err error + ) + + // if this is non-empty request + if !needFullDocument { + commonSnapshot, err = commonSnapshotForTwoPaths(ourPath, theirPath) + if err != nil { + return nil, err + } + } + + if commonSnapshot == ot.tree.RootId() { + return ot.getChangesFromTree(theirHeads) + } else { + return ot.getChangesFromDB(commonSnapshot, theirHeads) + } +} + +func (ot *objectTree) getChangesFromTree(theirHeads []string) (rawChanges []*treechangeproto.RawTreeChangeWithId, err error) { + return ot.rawChangeLoader.LoadFromTree(ot.tree, theirHeads) +} + +func (ot *objectTree) getChangesFromDB(commonSnapshot string, theirHeads []string) (rawChanges []*treechangeproto.RawTreeChangeWithId, err error) { + return ot.rawChangeLoader.LoadFromStorage(commonSnapshot, ot.tree.headIds, theirHeads) +} + +func (ot *objectTree) snapshotPathIsActual() bool { + return len(ot.snapshotPath) != 0 && ot.snapshotPath[0] == ot.tree.RootId() +} + +func (ot *objectTree) validateTree(newChanges []*Change) error { + ot.aclList.RLock() + defer ot.aclList.RUnlock() + state := ot.aclList.ACLState() + + // just not to take lock many times, updating the key map from aclList + if len(ot.keys) != len(state.UserReadKeys()) { + for key, value := range state.UserReadKeys() { + ot.keys[key] = value + } + } + if len(newChanges) == 0 { + return ot.validator.ValidateFullTree(ot.tree, ot.aclList) + } + + return ot.validator.ValidateNewChanges(ot.tree, ot.aclList, newChanges) +} + +func (ot *objectTree) DebugDump() (string, error) { + return ot.tree.Graph(NoOpDescriptionParser) +} diff --git a/common/pkg/acl/tree/objecttree_test.go b/common/pkg/acl/tree/objecttree_test.go new file mode 100644 index 00000000..da9f2364 --- /dev/null +++ b/common/pkg/acl/tree/objecttree_test.go @@ -0,0 +1,502 @@ +package tree + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/list" + storage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/testutils/acllistbuilder" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "testing" +) + +type mockChangeCreator struct{} + +func (c *mockChangeCreator) createRoot(id, aclId string) *treechangeproto.RawTreeChangeWithId { + aclChange := &treechangeproto.RootChange{ + AclHeadId: aclId, + } + res, _ := aclChange.Marshal() + + raw := &treechangeproto.RawTreeChange{ + Payload: res, + Signature: nil, + } + rawMarshalled, _ := raw.Marshal() + + return &treechangeproto.RawTreeChangeWithId{ + RawChange: rawMarshalled, + Id: id, + } +} + +func (c *mockChangeCreator) createRaw(id, aclId, snapshotId string, isSnapshot bool, prevIds ...string) *treechangeproto.RawTreeChangeWithId { + aclChange := &treechangeproto.TreeChange{ + TreeHeadIds: prevIds, + AclHeadId: aclId, + SnapshotBaseId: snapshotId, + ChangesData: nil, + IsSnapshot: isSnapshot, + } + res, _ := aclChange.Marshal() + + raw := &treechangeproto.RawTreeChange{ + Payload: res, + Signature: nil, + } + rawMarshalled, _ := raw.Marshal() + + return &treechangeproto.RawTreeChangeWithId{ + RawChange: rawMarshalled, + Id: id, + } +} + +func (c *mockChangeCreator) createNewTreeStorage(treeId, aclHeadId string) storage.TreeStorage { + root := c.createRoot(treeId, aclHeadId) + treeStorage, _ := storage.NewInMemoryTreeStorage(root, []string{root.Id}, []*treechangeproto.RawTreeChangeWithId{root}) + return treeStorage +} + +type mockChangeBuilder struct { + originalBuilder ChangeBuilder +} + +func (c *mockChangeBuilder) BuildInitialContent(payload InitialContent) (ch *Change, raw *treechangeproto.RawTreeChangeWithId, err error) { + panic("implement me") +} + +func (c *mockChangeBuilder) SetRootRawChange(rawIdChange *treechangeproto.RawTreeChangeWithId) { + c.originalBuilder.SetRootRawChange(rawIdChange) +} + +func (c *mockChangeBuilder) ConvertFromRaw(rawChange *treechangeproto.RawTreeChangeWithId, verify bool) (ch *Change, err error) { + return c.originalBuilder.ConvertFromRaw(rawChange, false) +} + +func (c *mockChangeBuilder) BuildContent(payload BuilderContent) (ch *Change, raw *treechangeproto.RawTreeChangeWithId, err error) { + panic("implement me") +} + +func (c *mockChangeBuilder) BuildRaw(ch *Change) (raw *treechangeproto.RawTreeChangeWithId, err error) { + return c.originalBuilder.BuildRaw(ch) +} + +type mockChangeValidator struct{} + +func (m *mockChangeValidator) ValidateNewChanges(tree *Tree, aclList list.ACLList, newChanges []*Change) error { + return nil +} + +func (m *mockChangeValidator) ValidateFullTree(tree *Tree, aclList list.ACLList) error { + return nil +} + +type testTreeContext struct { + aclList list.ACLList + treeStorage storage.TreeStorage + changeBuilder *mockChangeBuilder + changeCreator *mockChangeCreator + objTree ObjectTree +} + +func prepareACLList(t *testing.T) list.ACLList { + st, err := acllistbuilder.NewListStorageWithTestName("userjoinexample.yml") + require.NoError(t, err, "building storage should not result in error") + + aclList, err := list.BuildACLList(st) + require.NoError(t, err, "building acl list should be without error") + + return aclList +} + +func prepareTreeContext(t *testing.T, aclList list.ACLList) testTreeContext { + changeCreator := &mockChangeCreator{} + treeStorage := changeCreator.createNewTreeStorage("0", aclList.Head().Id) + root, _ := treeStorage.Root() + changeBuilder := &mockChangeBuilder{ + originalBuilder: newChangeBuilder(nil, root), + } + deps := objectTreeDeps{ + changeBuilder: changeBuilder, + treeBuilder: newTreeBuilder(treeStorage, changeBuilder), + treeStorage: treeStorage, + rawChangeLoader: newRawChangeLoader(treeStorage, changeBuilder), + validator: &mockChangeValidator{}, + aclList: aclList, + } + + // check build + objTree, err := buildObjectTree(deps) + require.NoError(t, err, "building tree should be without error") + + // check tree iterate + var iterChangesId []string + err = objTree.Iterate(nil, func(change *Change) bool { + iterChangesId = append(iterChangesId, change.Id) + return true + }) + require.NoError(t, err, "iterate should be without error") + assert.Equal(t, []string{"0"}, iterChangesId) + return testTreeContext{ + aclList: aclList, + treeStorage: treeStorage, + changeBuilder: changeBuilder, + changeCreator: changeCreator, + objTree: objTree, + } +} + +func TestObjectTree(t *testing.T) { + aclList := prepareACLList(t) + + t.Run("add simple", func(t *testing.T) { + ctx := prepareTreeContext(t, aclList) + treeStorage := ctx.treeStorage + changeCreator := ctx.changeCreator + objTree := ctx.objTree + + rawChanges := []*treechangeproto.RawTreeChangeWithId{ + changeCreator.createRaw("1", aclList.Head().Id, "0", false, "0"), + changeCreator.createRaw("2", aclList.Head().Id, "0", false, "1"), + } + res, err := objTree.AddRawChanges(context.Background(), rawChanges...) + require.NoError(t, err, "adding changes should be without error") + + // check result + assert.Equal(t, []string{"0"}, res.OldHeads) + assert.Equal(t, []string{"2"}, res.Heads) + assert.Equal(t, len(rawChanges), len(res.Added)) + assert.Equal(t, Append, res.Mode) + + // check tree heads + assert.Equal(t, []string{"2"}, objTree.Heads()) + + // check tree iterate + var iterChangesId []string + err = objTree.Iterate(nil, func(change *Change) bool { + iterChangesId = append(iterChangesId, change.Id) + return true + }) + require.NoError(t, err, "iterate should be without error") + assert.Equal(t, []string{"0", "1", "2"}, iterChangesId) + + // check storage + heads, _ := treeStorage.Heads() + assert.Equal(t, []string{"2"}, heads) + + for _, ch := range rawChanges { + raw, err := treeStorage.GetRawChange(context.Background(), ch.Id) + assert.NoError(t, err, "storage should have all the changes") + assert.Equal(t, ch, raw, "the changes in the storage should be the same") + } + }) + + t.Run("add no new changes", func(t *testing.T) { + ctx := prepareTreeContext(t, aclList) + changeCreator := ctx.changeCreator + objTree := ctx.objTree + + rawChanges := []*treechangeproto.RawTreeChangeWithId{ + changeCreator.createRaw("0", aclList.Head().Id, "", true, ""), + } + res, err := objTree.AddRawChanges(context.Background(), rawChanges...) + require.NoError(t, err, "adding changes should be without error") + + // check result + assert.Equal(t, []string{"0"}, res.OldHeads) + assert.Equal(t, []string{"0"}, res.Heads) + assert.Equal(t, 0, len(res.Added)) + + // check tree heads + assert.Equal(t, []string{"0"}, objTree.Heads()) + }) + + t.Run("add unattachable changes", func(t *testing.T) { + ctx := prepareTreeContext(t, aclList) + changeCreator := ctx.changeCreator + objTree := ctx.objTree + + rawChanges := []*treechangeproto.RawTreeChangeWithId{ + changeCreator.createRaw("2", aclList.Head().Id, "0", false, "1"), + } + res, err := objTree.AddRawChanges(context.Background(), rawChanges...) + require.NoError(t, err, "adding changes should be without error") + + // check result + assert.Equal(t, []string{"0"}, res.OldHeads) + assert.Equal(t, []string{"0"}, res.Heads) + assert.Equal(t, 0, len(res.Added)) + assert.Equal(t, Nothing, res.Mode) + + // check tree heads + assert.Equal(t, []string{"0"}, objTree.Heads()) + }) + + t.Run("add new snapshot simple", func(t *testing.T) { + ctx := prepareTreeContext(t, aclList) + treeStorage := ctx.treeStorage + changeCreator := ctx.changeCreator + objTree := ctx.objTree + + rawChanges := []*treechangeproto.RawTreeChangeWithId{ + changeCreator.createRaw("1", aclList.Head().Id, "0", false, "0"), + changeCreator.createRaw("2", aclList.Head().Id, "0", false, "1"), + changeCreator.createRaw("3", aclList.Head().Id, "0", true, "2"), + changeCreator.createRaw("4", aclList.Head().Id, "3", false, "3"), + } + res, err := objTree.AddRawChanges(context.Background(), rawChanges...) + require.NoError(t, err, "adding changes should be without error") + + // check result + assert.Equal(t, []string{"0"}, res.OldHeads) + assert.Equal(t, []string{"4"}, res.Heads) + assert.Equal(t, len(rawChanges), len(res.Added)) + assert.Equal(t, Append, res.Mode) + + // check tree heads + assert.Equal(t, []string{"4"}, objTree.Heads()) + + // check tree iterate + var iterChangesId []string + err = objTree.Iterate(nil, func(change *Change) bool { + iterChangesId = append(iterChangesId, change.Id) + return true + }) + require.NoError(t, err, "iterate should be without error") + assert.Equal(t, []string{"3", "4"}, iterChangesId) + assert.Equal(t, "3", objTree.Root().Id) + + // check storage + heads, _ := treeStorage.Heads() + assert.Equal(t, []string{"4"}, heads) + + for _, ch := range rawChanges { + raw, err := treeStorage.GetRawChange(context.Background(), ch.Id) + assert.NoError(t, err, "storage should have all the changes") + assert.Equal(t, ch, raw, "the changes in the storage should be the same") + } + }) + + t.Run("snapshot path", func(t *testing.T) { + ctx := prepareTreeContext(t, aclList) + changeCreator := ctx.changeCreator + objTree := ctx.objTree + + rawChanges := []*treechangeproto.RawTreeChangeWithId{ + changeCreator.createRaw("1", aclList.Head().Id, "0", false, "0"), + changeCreator.createRaw("2", aclList.Head().Id, "0", false, "1"), + changeCreator.createRaw("3", aclList.Head().Id, "0", true, "2"), + } + _, err := objTree.AddRawChanges(context.Background(), rawChanges...) + require.NoError(t, err, "adding changes should be without error") + + snapshotPath := objTree.SnapshotPath() + assert.Equal(t, []string{"3", "0"}, snapshotPath) + + assert.Equal(t, true, objTree.(*objectTree).snapshotPathIsActual()) + }) + + t.Run("changes from tree after common snapshot complex", func(t *testing.T) { + ctx := prepareTreeContext(t, aclList) + changeCreator := ctx.changeCreator + objTree := ctx.objTree + + rawChanges := []*treechangeproto.RawTreeChangeWithId{ + changeCreator.createRaw("1", aclList.Head().Id, "0", false, "0"), + changeCreator.createRaw("2", aclList.Head().Id, "0", false, "1"), + changeCreator.createRaw("3", aclList.Head().Id, "0", true, "2"), + changeCreator.createRaw("4", aclList.Head().Id, "0", false, "2"), + changeCreator.createRaw("5", aclList.Head().Id, "0", false, "1"), + changeCreator.createRaw("6", aclList.Head().Id, "0", false, "3", "4", "5"), + } + + _, err := objTree.AddRawChanges(context.Background(), rawChanges...) + require.NoError(t, err, "adding changes should be without error") + require.Equal(t, "0", objTree.Root().Id) + + t.Run("all changes from tree", func(t *testing.T) { + changes, err := objTree.ChangesAfterCommonSnapshot([]string{"3", "0"}, []string{}) + require.NoError(t, err, "changes after common snapshot should be without error") + + changeIds := make(map[string]struct{}) + for _, ch := range changes { + changeIds[ch.Id] = struct{}{} + } + + for _, raw := range rawChanges { + _, ok := changeIds[raw.Id] + assert.Equal(t, true, ok) + } + _, ok := changeIds["0"] + assert.Equal(t, true, ok) + }) + + t.Run("changes from tree after 1", func(t *testing.T) { + changes, err := objTree.ChangesAfterCommonSnapshot([]string{"3", "0"}, []string{"1"}) + require.NoError(t, err, "changes after common snapshot should be without error") + + changeIds := make(map[string]struct{}) + for _, ch := range changes { + changeIds[ch.Id] = struct{}{} + } + + for _, id := range []string{"2", "3", "4", "5", "6"} { + _, ok := changeIds[id] + assert.Equal(t, true, ok) + } + for _, id := range []string{"0", "1"} { + _, ok := changeIds[id] + assert.Equal(t, false, ok) + } + }) + + t.Run("changes from tree after 5", func(t *testing.T) { + changes, err := objTree.ChangesAfterCommonSnapshot([]string{"3", "0"}, []string{"5"}) + require.NoError(t, err, "changes after common snapshot should be without error") + + changeIds := make(map[string]struct{}) + for _, ch := range changes { + changeIds[ch.Id] = struct{}{} + } + + for _, id := range []string{"2", "3", "4", "6"} { + _, ok := changeIds[id] + assert.Equal(t, true, ok) + } + for _, id := range []string{"0", "1", "5"} { + _, ok := changeIds[id] + assert.Equal(t, false, ok) + } + }) + }) + + t.Run("changes after common snapshot db complex", func(t *testing.T) { + ctx := prepareTreeContext(t, aclList) + changeCreator := ctx.changeCreator + objTree := ctx.objTree + + rawChanges := []*treechangeproto.RawTreeChangeWithId{ + changeCreator.createRaw("1", aclList.Head().Id, "0", false, "0"), + changeCreator.createRaw("2", aclList.Head().Id, "0", false, "1"), + changeCreator.createRaw("3", aclList.Head().Id, "0", true, "2"), + changeCreator.createRaw("4", aclList.Head().Id, "0", false, "2"), + changeCreator.createRaw("5", aclList.Head().Id, "0", false, "1"), + // main difference from tree example + changeCreator.createRaw("6", aclList.Head().Id, "0", true, "3", "4", "5"), + } + + _, err := objTree.AddRawChanges(context.Background(), rawChanges...) + require.NoError(t, err, "adding changes should be without error") + require.Equal(t, "6", objTree.Root().Id) + + t.Run("all changes from db", func(t *testing.T) { + changes, err := objTree.ChangesAfterCommonSnapshot([]string{"3", "0"}, []string{}) + require.NoError(t, err, "changes after common snapshot should be without error") + + changeIds := make(map[string]struct{}) + for _, ch := range changes { + changeIds[ch.Id] = struct{}{} + } + + for _, raw := range rawChanges { + _, ok := changeIds[raw.Id] + assert.Equal(t, true, ok) + } + _, ok := changeIds["0"] + assert.Equal(t, true, ok) + }) + + t.Run("changes from tree db 1", func(t *testing.T) { + changes, err := objTree.ChangesAfterCommonSnapshot([]string{"3", "0"}, []string{"1"}) + require.NoError(t, err, "changes after common snapshot should be without error") + + changeIds := make(map[string]struct{}) + for _, ch := range changes { + changeIds[ch.Id] = struct{}{} + } + + for _, id := range []string{"2", "3", "4", "5", "6"} { + _, ok := changeIds[id] + assert.Equal(t, true, ok) + } + for _, id := range []string{"0", "1"} { + _, ok := changeIds[id] + assert.Equal(t, false, ok) + } + }) + + t.Run("changes from tree db 5", func(t *testing.T) { + changes, err := objTree.ChangesAfterCommonSnapshot([]string{"3", "0"}, []string{"5"}) + require.NoError(t, err, "changes after common snapshot should be without error") + + changeIds := make(map[string]struct{}) + for _, ch := range changes { + changeIds[ch.Id] = struct{}{} + } + + for _, id := range []string{"2", "3", "4", "6"} { + _, ok := changeIds[id] + assert.Equal(t, true, ok) + } + for _, id := range []string{"0", "1", "5"} { + _, ok := changeIds[id] + assert.Equal(t, false, ok) + } + }) + }) + + t.Run("add new changes related to previous snapshot", func(t *testing.T) { + ctx := prepareTreeContext(t, aclList) + treeStorage := ctx.treeStorage + changeCreator := ctx.changeCreator + objTree := ctx.objTree + + rawChanges := []*treechangeproto.RawTreeChangeWithId{ + changeCreator.createRaw("1", aclList.Head().Id, "0", false, "0"), + changeCreator.createRaw("2", aclList.Head().Id, "0", false, "1"), + changeCreator.createRaw("3", aclList.Head().Id, "0", true, "2"), + } + res, err := objTree.AddRawChanges(context.Background(), rawChanges...) + require.NoError(t, err, "adding changes should be without error") + require.Equal(t, "3", objTree.Root().Id) + + rawChanges = []*treechangeproto.RawTreeChangeWithId{ + changeCreator.createRaw("4", aclList.Head().Id, "0", false, "2"), + changeCreator.createRaw("5", aclList.Head().Id, "0", false, "1"), + changeCreator.createRaw("6", aclList.Head().Id, "0", false, "3", "4", "5"), + } + res, err = objTree.AddRawChanges(context.Background(), rawChanges...) + require.NoError(t, err, "adding changes should be without error") + + // check result + assert.Equal(t, []string{"3"}, res.OldHeads) + assert.Equal(t, []string{"6"}, res.Heads) + assert.Equal(t, len(rawChanges), len(res.Added)) + assert.Equal(t, Rebuild, res.Mode) + + // check tree heads + assert.Equal(t, []string{"6"}, objTree.Heads()) + + // check tree iterate + var iterChangesId []string + err = objTree.Iterate(nil, func(change *Change) bool { + iterChangesId = append(iterChangesId, change.Id) + return true + }) + require.NoError(t, err, "iterate should be without error") + assert.Equal(t, []string{"0", "1", "2", "3", "4", "5", "6"}, iterChangesId) + assert.Equal(t, "0", objTree.Root().Id) + + // check storage + heads, _ := treeStorage.Heads() + assert.Equal(t, []string{"6"}, heads) + + for _, ch := range rawChanges { + raw, err := treeStorage.GetRawChange(context.Background(), ch.Id) + assert.NoError(t, err, "storage should have all the changes") + assert.Equal(t, ch, raw, "the changes in the storage should be the same") + } + }) +} diff --git a/common/pkg/acl/tree/objecttreefactory.go b/common/pkg/acl/tree/objecttreefactory.go new file mode 100644 index 00000000..26912377 --- /dev/null +++ b/common/pkg/acl/tree/objecttreefactory.go @@ -0,0 +1,144 @@ +package tree + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/common" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/list" + storage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/signingkey" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/symmetric" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/slice" + "go.uber.org/zap" + "math/rand" + "time" +) + +type ObjectTreeCreatePayload struct { + SignKey signingkey.PrivKey + ChangeType string + SpaceId string + Identity []byte +} + +func BuildObjectTree(treeStorage storage.TreeStorage, aclList list.ACLList) (ObjectTree, error) { + rootChange, err := treeStorage.Root() + if err != nil { + return nil, err + } + deps := defaultObjectTreeDeps(rootChange, treeStorage, aclList) + return buildObjectTree(deps) +} + +func CreateDerivedObjectTree( + payload ObjectTreeCreatePayload, + aclList list.ACLList, + createStorage storage.TreeStorageCreatorFunc) (objTree ObjectTree, err error) { + return createObjectTree(payload, 0, nil, aclList, createStorage) +} + +func CreateObjectTree( + payload ObjectTreeCreatePayload, + aclList list.ACLList, + createStorage storage.TreeStorageCreatorFunc) (objTree ObjectTree, err error) { + bytes := make([]byte, 32) + _, err = rand.Read(bytes) + if err != nil { + return + } + return createObjectTree(payload, time.Now().UnixNano(), bytes, aclList, createStorage) +} + +func createObjectTree( + payload ObjectTreeCreatePayload, + timestamp int64, + seed []byte, + aclList list.ACLList, + createStorage storage.TreeStorageCreatorFunc) (objTree ObjectTree, err error) { + aclList.RLock() + aclHeadId := aclList.Head().Id + aclList.RUnlock() + + if err != nil { + return + } + cnt := InitialContent{ + AclHeadId: aclHeadId, + Identity: payload.Identity, + SigningKey: payload.SignKey, + SpaceId: payload.SpaceId, + ChangeType: payload.ChangeType, + Timestamp: timestamp, + Seed: seed, + } + + _, raw, err := newChangeBuilder(common.NewKeychain(), nil).BuildInitialContent(cnt) + if err != nil { + return + } + + // create storage + st, err := createStorage(storage.TreeStorageCreatePayload{ + RootRawChange: raw, + Changes: []*treechangeproto.RawTreeChangeWithId{raw}, + Heads: []string{raw.Id}, + }) + if err != nil { + return + } + + return BuildObjectTree(st, aclList) +} + +func buildObjectTree(deps objectTreeDeps) (ObjectTree, error) { + objTree := &objectTree{ + treeStorage: deps.treeStorage, + treeBuilder: deps.treeBuilder, + validator: deps.validator, + aclList: deps.aclList, + changeBuilder: deps.changeBuilder, + rawChangeLoader: deps.rawChangeLoader, + tree: nil, + keys: make(map[uint64]*symmetric.Key), + newChangesBuf: make([]*Change, 0, 10), + difSnapshotBuf: make([]*treechangeproto.RawTreeChangeWithId, 0, 10), + notSeenIdxBuf: make([]int, 0, 10), + newSnapshotsBuf: make([]*Change, 0, 10), + } + + err := objTree.rebuildFromStorage(nil) + if err != nil { + return nil, err + } + storageHeads, err := objTree.treeStorage.Heads() + if err != nil { + return nil, err + } + + // comparing rebuilt heads with heads in storage + // in theory it can happen that we didn't set heads because the process has crashed + // therefore we want to set them later + if !slice.UnsortedEquals(storageHeads, objTree.tree.Heads()) { + log.With(zap.Strings("storage", storageHeads), zap.Strings("rebuilt", objTree.tree.Heads())). + Errorf("the heads in storage and objTree are different") + err = objTree.treeStorage.SetHeads(objTree.tree.Heads()) + if err != nil { + return nil, err + } + } + + objTree.id = objTree.treeStorage.Id() + + objTree.id = objTree.treeStorage.Id() + objTree.root, err = objTree.treeStorage.Root() + if err != nil { + return nil, err + } + + // verifying root + _, err = objTree.changeBuilder.ConvertFromRaw(objTree.root, true) + if err != nil { + return nil, err + } + + return objTree, nil +} diff --git a/common/pkg/acl/tree/rawloader.go b/common/pkg/acl/tree/rawloader.go new file mode 100644 index 00000000..e6c556ff --- /dev/null +++ b/common/pkg/acl/tree/rawloader.go @@ -0,0 +1,233 @@ +package tree + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto" + "time" +) + +type rawChangeLoader struct { + treeStorage storage.TreeStorage + changeBuilder ChangeBuilder + + // buffers + idStack []string + cache map[string]rawCacheEntry +} + +type rawCacheEntry struct { + change *Change + rawChange *treechangeproto.RawTreeChangeWithId + position int +} + +func newRawChangeLoader(treeStorage storage.TreeStorage, changeBuilder ChangeBuilder) *rawChangeLoader { + return &rawChangeLoader{ + treeStorage: treeStorage, + changeBuilder: changeBuilder, + } +} + +func (r *rawChangeLoader) LoadFromTree(t *Tree, breakpoints []string) ([]*treechangeproto.RawTreeChangeWithId, error) { + var stack []*Change + for _, h := range t.headIds { + stack = append(stack, t.attached[h]) + } + + convert := func(chs []*Change) (rawChanges []*treechangeproto.RawTreeChangeWithId, err error) { + for _, ch := range chs { + var raw *treechangeproto.RawTreeChangeWithId + raw, err = r.changeBuilder.BuildRaw(ch) + if err != nil { + return + } + rawChanges = append(rawChanges, raw) + } + return + } + + // getting all changes that we visit + var results []*Change + rootVisited := false + t.dfsPrev( + stack, + breakpoints, + func(ch *Change) bool { + results = append(results, ch) + return true + }, + func(visited []*Change) { + if t.root.visited { + rootVisited = true + } + }, + ) + + // if we stopped at breakpoints or there are no breakpoints + if !rootVisited || len(breakpoints) == 0 { + // in this case we will add root if there are no breakpoints + return convert(results) + } + + // now starting from breakpoints + stack = stack[:0] + for _, h := range breakpoints { + if c, exists := t.attached[h]; exists { + stack = append(stack, c) + } + } + + // doing another dfs to get all changes before breakpoints, we need to exclude them from results + // if we don't have some breakpoints we will just ignore them + t.dfsPrev( + stack, + []string{}, + func(ch *Change) bool { + return true + }, + func(visited []*Change) { + results = discardFromSlice(results, func(change *Change) bool { + return change.visited + }) + }, + ) + + // otherwise we want to exclude everything that wasn't in breakpoints + return convert(results) +} + +func (r *rawChangeLoader) LoadFromStorage(commonSnapshot string, heads, breakpoints []string) ([]*treechangeproto.RawTreeChangeWithId, error) { + // resetting cache + r.cache = make(map[string]rawCacheEntry) + defer func() { + r.cache = nil + }() + + existingBreakpoints := make([]string, 0, len(breakpoints)) + for _, b := range breakpoints { + entry, err := r.loadEntry(b) + if err != nil { + continue + } + entry.position = -1 + r.cache[b] = entry + existingBreakpoints = append(existingBreakpoints, b) + } + r.cache[commonSnapshot] = rawCacheEntry{position: -1} + + dfs := func( + commonSnapshot string, + heads []string, + startCounter int, + shouldVisit func(counter int, mapExists bool) bool, + visit func(entry rawCacheEntry) rawCacheEntry) bool { + + // resetting stack + r.idStack = r.idStack[:0] + r.idStack = append(r.idStack, heads...) + + commonSnapshotVisited := false + var err error + for len(r.idStack) > 0 { + id := r.idStack[len(r.idStack)-1] + r.idStack = r.idStack[:len(r.idStack)-1] + + entry, exists := r.cache[id] + if !shouldVisit(entry.position, exists) { + continue + } + if !exists { + entry, err = r.loadEntry(id) + if err != nil { + continue + } + } + + // setting the counter when we visit + r.cache[id] = visit(entry) + + for _, prev := range entry.change.PreviousIds { + if prev == commonSnapshot { + commonSnapshotVisited = true + break + } + entry, exists = r.cache[prev] + if !shouldVisit(entry.position, exists) { + continue + } + r.idStack = append(r.idStack, prev) + } + } + return commonSnapshotVisited + } + + // preparing first pass + r.idStack = append(r.idStack, heads...) + var buffer []*treechangeproto.RawTreeChangeWithId + + rootVisited := dfs(commonSnapshot, heads, 0, + func(counter int, mapExists bool) bool { + return !mapExists + }, + func(entry rawCacheEntry) rawCacheEntry { + buffer = append(buffer, entry.rawChange) + entry.position = len(buffer) - 1 + return entry + }) + + // checking if we stopped at breakpoints + if !rootVisited { + return buffer, nil + } + + // if there are no breakpoints then we should load root also + if len(breakpoints) == 0 { + common, err := r.loadEntry(commonSnapshot) + if err != nil { + return nil, err + } + buffer = append(buffer, common.rawChange) + return buffer, nil + } + + // marking all visited as nil + dfs(commonSnapshot, existingBreakpoints, len(buffer), + func(counter int, mapExists bool) bool { + return !mapExists || counter < len(buffer) + }, + func(entry rawCacheEntry) rawCacheEntry { + if entry.position != -1 { + buffer[entry.position] = nil + } + entry.position = len(buffer) + 1 + return entry + }) + + // discarding visited + buffer = discardFromSlice(buffer, func(change *treechangeproto.RawTreeChangeWithId) bool { + return change == nil + }) + + return buffer, nil +} + +func (r *rawChangeLoader) loadEntry(id string) (entry rawCacheEntry, err error) { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) + defer cancel() + + rawChange, err := r.treeStorage.GetRawChange(ctx, id) + if err != nil { + return + } + + change, err := r.changeBuilder.ConvertFromRaw(rawChange, false) + if err != nil { + return + } + entry = rawCacheEntry{ + change: change, + rawChange: rawChange, + } + return +} diff --git a/common/pkg/acl/tree/rawtreevalidator.go b/common/pkg/acl/tree/rawtreevalidator.go new file mode 100644 index 00000000..aac7dd99 --- /dev/null +++ b/common/pkg/acl/tree/rawtreevalidator.go @@ -0,0 +1,17 @@ +package tree + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/list" + storage2 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage" +) + +func ValidateRawTree(payload storage2.TreeStorageCreatePayload, aclList list.ACLList) (err error) { + provider := storage2.NewInMemoryTreeStorageProvider() + treeStorage, err := provider.CreateTreeStorage(payload) + if err != nil { + return + } + + _, err = BuildObjectTree(treeStorage, aclList) + return +} diff --git a/common/pkg/acl/tree/signablecontent.go b/common/pkg/acl/tree/signablecontent.go new file mode 100644 index 00000000..086d1b06 --- /dev/null +++ b/common/pkg/acl/tree/signablecontent.go @@ -0,0 +1,12 @@ +package tree + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/signingkey" +) + +type SignableChangeContent struct { + Data []byte + Key signingkey.PrivKey + Identity []byte + IsSnapshot bool +} diff --git a/pkg/acl/acltree/tree.go b/common/pkg/acl/tree/tree.go similarity index 50% rename from pkg/acl/acltree/tree.go rename to common/pkg/acl/tree/tree.go index e47ed212..80bbb78c 100644 --- a/pkg/acl/acltree/tree.go +++ b/common/pkg/acl/tree/tree.go @@ -1,10 +1,9 @@ -package acltree +package tree import ( "bytes" "crypto/md5" "fmt" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice" "sort" ) @@ -16,28 +15,26 @@ const ( Nothing ) -// TODO: consider abstracting into separate package with iterator, remove type Tree struct { - root *Change - headIds []string - metaHeadIds []string - attached map[string]*Change - unAttached map[string]*Change + root *Change + headIds []string + lastIteratedHeadId string + metaHeadIds []string + attached map[string]*Change + unAttached map[string]*Change // missed id -> list of dependency ids waitList map[string][]string invalidChanges map[string]struct{} + possibleRoots []*Change // bufs - iterCompBuf []*Change - iterQueue []*Change + visitedBuf []*Change + stackBuf []*Change + addedBuf []*Change duplicateEvents int } -func (t *Tree) GetUnattachedChanges(changes ...*Change) []*Change { - return nil -} - func (t *Tree) RootId() string { if t.root != nil { return t.root.Id @@ -49,7 +46,8 @@ func (t *Tree) Root() *Change { return t.root } -func (t *Tree) AddFast(changes ...*Change) { +func (t *Tree) AddFast(changes ...*Change) []*Change { + t.addedBuf = t.addedBuf[:0] for _, c := range changes { // ignore existing if _, ok := t.attached[c.Id]; ok { @@ -60,12 +58,40 @@ func (t *Tree) AddFast(changes ...*Change) { t.add(c) } t.updateHeads() + return t.addedBuf } -func (t *Tree) Add(changes ...*Change) (mode Mode) { - var beforeHeadIds = t.headIds - var attached bool - var empty = t.Len() == 0 +func (t *Tree) AddMergedHead(c *Change) error { + // check that it was not inserted previously + if _, ok := t.attached[c.Id]; ok { + return fmt.Errorf("change already exists") // TODO: named error + } else if _, ok := t.unAttached[c.Id]; ok { + return fmt.Errorf("change already exists") + } + + // check that it was attached after adding + if !t.add(c) { + return fmt.Errorf("change is not attached") + } + + // check that previous heads have new change as next + for _, prevHead := range t.headIds { + head := t.attached[prevHead] + if len(head.Next) != 1 || head.Next[0].Id != c.Id { + return fmt.Errorf("this is not a new head") + } + } + t.headIds = []string{c.Id} + return nil +} + +func (t *Tree) Add(changes ...*Change) (mode Mode, added []*Change) { + t.addedBuf = t.addedBuf[:0] + var ( + // this is previous head id which should have been iterated last + lastIteratedHeadId = t.lastIteratedHeadId + empty = t.Len() == 0 + ) for _, c := range changes { // ignore existing if _, ok := t.attached[c.Id]; ok { @@ -73,29 +99,54 @@ func (t *Tree) Add(changes ...*Change) (mode Mode) { } else if _, ok := t.unAttached[c.Id]; ok { continue } - if t.add(c) { - attached = true - } + t.add(c) } - if !attached { - return Nothing + if len(t.addedBuf) == 0 { + mode = Nothing + return } t.updateHeads() + added = t.addedBuf + if empty { - return Rebuild + mode = Rebuild + return } - for _, hid := range beforeHeadIds { - for _, newCh := range changes { - if _, ok := t.attached[newCh.Id]; ok { - if !t.after(newCh.Id, hid) { - return Rebuild + + // mode is Append for cases when we can safely start iterating from lastIteratedHeadId to build state + // the idea here is that if all new changes have lastIteratedHeadId as previous, + // then according to topological sorting order they will be looked at later than lastIteratedHeadId + // + // one important consideration is that if some unattached changes were added to the tree + // as a result of adding new changes, then each of these unattached changes + // will also have at least one of new changes as ancestor + // and that means they will also be iterated later than lastIteratedHeadId + mode = Append + t.dfsNext([]*Change{t.attached[lastIteratedHeadId]}, + func(_ *Change) (isContinue bool) { + return true + }, + func(_ []*Change) { + // checking if some new changes were not visited + for _, ch := range changes { + // if the change was not added to the tree, then skipping + if _, ok := t.attached[ch.Id]; !ok { + continue + } + // if some new change was not visited, + // then we can't start from lastIteratedHeadId, + // we need to start from root, so Rebuild + if !ch.visited { + mode = Rebuild + break } } - } - } - return Append + }) + + return } +// RemoveInvalidChange removes all the changes that are descendants of id func (t *Tree) RemoveInvalidChange(id string) { stack := []string{id} // removing all children of this id (either next or unattached) @@ -112,6 +163,7 @@ func (t *Tree) RemoveInvalidChange(id string) { t.invalidChanges[top] = struct{}{} if rem, exists = t.unAttached[top]; exists { delete(t.unAttached, top) + // TODO: delete waitlist, this can only help for memory/performance } else if rem, exists = t.attached[top]; exists { // remove from all prev changes for _, id := range rem.PreviousIds { @@ -129,9 +181,6 @@ func (t *Tree) RemoveInvalidChange(id string) { } delete(t.attached, top) } - for _, el := range rem.Unattached { - stack = append(stack, el.Id) - } for _, el := range rem.Next { stack = append(stack, el.Id) } @@ -149,12 +198,15 @@ func (t *Tree) add(c *Change) (attached bool) { if t.root == nil { // first element t.root = c + t.lastIteratedHeadId = t.root.Id t.attached = map[string]*Change{ c.Id: c, } t.unAttached = make(map[string]*Change) t.waitList = make(map[string][]string) t.invalidChanges = make(map[string]struct{}) + t.possibleRoots = make([]*Change, 0, 10) + t.addedBuf = append(t.addedBuf, c) return true } if len(c.PreviousIds) > 1 { @@ -163,15 +215,11 @@ func (t *Tree) add(c *Change) (attached bool) { // attaching only if all prev ids are attached attached = true for _, pid := range c.PreviousIds { - if prev, ok := t.attached[pid]; ok { - prev.Unattached = append(prev.Unattached, c) + if _, ok := t.attached[pid]; ok { continue } attached = false - if prev, ok := t.unAttached[pid]; ok { - prev.Unattached = append(prev.Unattached, c) - continue - } + // updating wait list for either unseen or unAttached changes wl := t.waitList[pid] wl = append(wl, c.Id) t.waitList[pid] = wl @@ -179,11 +227,6 @@ func (t *Tree) add(c *Change) (attached bool) { if attached { t.attach(c, true) } else { - // clearing wait list - for _, wid := range t.waitList[c.Id] { - c.Unattached = append(c.Unattached, t.unAttached[wid]) - } - delete(t.waitList, c.Id) t.unAttached[c.Id] = c } return @@ -197,6 +240,7 @@ func (t *Tree) canAttach(c *Change) (attach bool) { for _, id := range c.PreviousIds { if _, exists := t.attached[id]; !exists { attach = false + break } } return @@ -204,43 +248,50 @@ func (t *Tree) canAttach(c *Change) (attach bool) { func (t *Tree) attach(c *Change, newEl bool) { t.attached[c.Id] = c + t.addedBuf = append(t.addedBuf, c) if !newEl { delete(t.unAttached, c.Id) } + if c.IsSnapshot { + t.possibleRoots = append(t.possibleRoots, c) + } // add next to all prev changes for _, id := range c.PreviousIds { - // prev id must be attached if we attach this id + // prev id must already be attached if we attach this id, so we don't need to check if it exists prev := t.attached[id] - prev.Next = append(prev.Next, c) - if len(prev.Next) > 1 { - sort.Sort(sortChanges(prev.Next)) - } - for i, next := range prev.Unattached { - if next.Id == c.Id { - prev.Unattached[i] = nil - prev.Unattached = append(prev.Unattached[:i], prev.Unattached[i+1:]...) - break + // appending c to next changes of all previous changes + if len(prev.Next) == 0 || prev.Next[len(prev.Next)-1].Id <= c.Id { + prev.Next = append(prev.Next, c) + } else { + // inserting in correct position, before the change which is greater or equal + insertIdx := 0 + for idx, el := range prev.Next { + if el.Id >= c.Id { + insertIdx = idx + break + } } + prev.Next = append(prev.Next[:insertIdx+1], prev.Next[insertIdx:]...) + prev.Next[insertIdx] = c } } + // TODO: as a future optimization we can actually sort next later after we finished building the tree // clearing wait list if waitIds, ok := t.waitList[c.Id]; ok { for _, wid := range waitIds { + // next can only be in unAttached, because if next is attached then previous (we) are attached + // which is obviously not true, because we are attaching previous only now next := t.unAttached[wid] if t.canAttach(next) { t.attach(next, false) } + // if we can't attach next that means that some other change will trigger attachment later, + // so we don't care about those changes } delete(t.waitList, c.Id) } - - for _, next := range c.Unattached { - if t.canAttach(next) { - t.attach(next, false) - } - } } func (t *Tree) after(id1, id2 string) (found bool) { @@ -254,29 +305,83 @@ func (t *Tree) after(id1, id2 string) (found bool) { return } -func (t *Tree) dfs(startChange string) (uniqMap map[string]*Change) { - stack := make([]*Change, 0, 10) - stack = append(stack, t.attached[startChange]) - uniqMap = map[string]*Change{} +func (t *Tree) dfsPrev(stack []*Change, breakpoints []string, visit func(ch *Change) (isContinue bool), afterVisit func([]*Change)) { + t.visitedBuf = t.visitedBuf[:0] + + // setting breakpoints as visited + for _, breakpoint := range breakpoints { + if ch, ok := t.attached[breakpoint]; ok { + ch.visited = true + t.visitedBuf = append(t.visitedBuf, ch) + } + } + + defer func() { + if afterVisit != nil { + afterVisit(t.visitedBuf) + } + for _, ch := range t.visitedBuf { + ch.visited = false + } + }() for len(stack) > 0 { ch := stack[len(stack)-1] stack = stack[:len(stack)-1] - if _, exists := uniqMap[ch.Id]; exists { + if ch.visited { continue } - uniqMap[ch.Id] = ch + ch.visited = true + t.visitedBuf = append(t.visitedBuf, ch) - for _, prev := range ch.PreviousIds { - stack = append(stack, t.attached[prev]) + for _, prevId := range ch.PreviousIds { + prevCh := t.attached[prevId] + if !prevCh.visited { + stack = append(stack, prevCh) + } + } + if !visit(ch) { + return + } + } +} + +func (t *Tree) dfsNext(stack []*Change, visit func(ch *Change) (isContinue bool), afterVisit func([]*Change)) { + t.visitedBuf = t.visitedBuf[:0] + + defer func() { + if afterVisit != nil { + afterVisit(t.visitedBuf) + } + for _, ch := range t.visitedBuf { + ch.visited = false + } + }() + + for len(stack) > 0 { + ch := stack[len(stack)-1] + stack = stack[:len(stack)-1] + if ch.visited { + continue + } + + ch.visited = true + t.visitedBuf = append(t.visitedBuf, ch) + + for _, next := range ch.Next { + if !next.visited { + stack = append(stack, next) + } + } + if !visit(ch) { + return } } - return uniqMap } func (t *Tree) updateHeads() { - var newHeadIds, newMetaHeadIds []string + var newHeadIds []string t.iterate(t.root, func(c *Change) (isContinue bool) { if len(c.Next) == 0 { newHeadIds = append(newHeadIds, c.Id) @@ -284,37 +389,10 @@ func (t *Tree) updateHeads() { return true }) t.headIds = newHeadIds - t.metaHeadIds = newMetaHeadIds + // the lastIteratedHeadId is the id of the head which was iterated last according to the order + t.lastIteratedHeadId = newHeadIds[len(newHeadIds)-1] + // TODO: check why do we need sorting here sort.Strings(t.headIds) - sort.Strings(t.metaHeadIds) -} - -func (t *Tree) ACLHeads() []string { - var aclTreeHeads []string - for _, head := range t.Heads() { - if slice.FindPos(aclTreeHeads, head) != -1 { // do not scan known heads - continue - } - precedingHeads := t.getPrecedingACLHeads(head) - - for _, aclHead := range precedingHeads { - if slice.FindPos(aclTreeHeads, aclHead) != -1 { - continue - } - aclTreeHeads = append(aclTreeHeads, aclHead) - } - } - return aclTreeHeads -} - -func (t *Tree) getPrecedingACLHeads(head string) []string { - headChange := t.attached[head] - - if headChange.Content.GetAclData() != nil { - return []string{head} - } else { - return headChange.Content.AclHeadIds - } } func (t *Tree) iterate(start *Change, f func(c *Change) (isContinue bool)) { @@ -381,6 +459,14 @@ func (t *Tree) Heads() []string { return t.headIds } +func (t *Tree) HeadsChanges() []*Change { + var heads []*Change + for _, head := range t.headIds { + heads = append(heads, t.attached[head]) + } + return heads +} + func (t *Tree) String() string { var buf = bytes.NewBuffer(nil) t.Iterate(t.RootId(), func(c *Change) (isContinue bool) { @@ -400,17 +486,3 @@ func (t *Tree) String() string { func (t *Tree) Get(id string) *Change { return t.attached[id] } - -type sortChanges []*Change - -func (s sortChanges) Len() int { - return len(s) -} - -func (s sortChanges) Less(i, j int) bool { - return s[i].Id < s[j].Id -} - -func (s sortChanges) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} diff --git a/common/pkg/acl/tree/tree_test.go b/common/pkg/acl/tree/tree_test.go new file mode 100644 index 00000000..4c7f5ae7 --- /dev/null +++ b/common/pkg/acl/tree/tree_test.go @@ -0,0 +1,331 @@ +package tree + +import ( + "fmt" + "github.com/stretchr/testify/assert" + "math/rand" + "testing" + "time" +) + +func newChange(id string, snapshotId string, prevIds ...string) *Change { + return &Change{ + PreviousIds: prevIds, + Id: id, + SnapshotId: snapshotId, + IsSnapshot: false, + } +} + +func newSnapshot(id, snapshotId string, prevIds ...string) *Change { + return &Change{ + PreviousIds: prevIds, + Id: id, + SnapshotId: snapshotId, + IsSnapshot: true, + } +} + +func TestTree_Add(t *testing.T) { + t.Run("add first el", func(t *testing.T) { + tr := new(Tree) + res, _ := tr.Add(newSnapshot("root", "")) + assert.Equal(t, Rebuild, res) + assert.Equal(t, tr.root.Id, "root") + assert.Equal(t, []string{"root"}, tr.Heads()) + }) + t.Run("linear add", func(t *testing.T) { + tr := new(Tree) + res, _ := tr.Add( + newSnapshot("root", ""), + newChange("one", "root", "root"), + newChange("two", "root", "one"), + ) + assert.Equal(t, Rebuild, res) + assert.Equal(t, []string{"two"}, tr.Heads()) + res, _ = tr.Add(newChange("three", "root", "two")) + assert.Equal(t, Append, res) + el := tr.root + var ids []string + for el != nil { + ids = append(ids, el.Id) + if len(el.Next) > 0 { + el = el.Next[0] + } else { + el = nil + } + } + assert.Equal(t, []string{"root", "one", "two", "three"}, ids) + assert.Equal(t, []string{"three"}, tr.Heads()) + }) + t.Run("branch", func(t *testing.T) { + tr := new(Tree) + res, _ := tr.Add( + newSnapshot("root", ""), + newChange("1", "root", "root"), + newChange("2", "root", "1"), + ) + assert.Equal(t, Rebuild, res) + assert.Equal(t, []string{"2"}, tr.Heads()) + res, _ = tr.Add( + newChange("1.2", "root", "1.1"), + newChange("1.3", "root", "1.2"), + newChange("1.1", "root", "1"), + ) + assert.Equal(t, Rebuild, res) + assert.Len(t, tr.attached["1"].Next, 2) + assert.Len(t, tr.unAttached, 0) + assert.Len(t, tr.attached, 6) + assert.Equal(t, []string{"1.3", "2"}, tr.Heads()) + }) + t.Run("branch union", func(t *testing.T) { + tr := new(Tree) + res, _ := tr.Add( + newSnapshot("root", ""), + newChange("1", "root", "root"), + newChange("2", "root", "1"), + newChange("1.2", "root", "1.1"), + newChange("1.3", "root", "1.2"), + newChange("1.1", "root", "1"), + newChange("3", "root", "2", "1.3"), + newChange("4", "root", "3"), + ) + assert.Equal(t, Rebuild, res) + assert.Len(t, tr.unAttached, 0) + assert.Len(t, tr.attached, 8) + assert.Equal(t, []string{"4"}, tr.Heads()) + }) + t.Run("big set", func(t *testing.T) { + tr := new(Tree) + tr.Add(newSnapshot("root", "")) + var changes []*Change + for i := 0; i < 10000; i++ { + if i == 0 { + changes = append(changes, newChange(fmt.Sprint(i), "root", "root")) + } else { + changes = append(changes, newChange(fmt.Sprint(i), "root", fmt.Sprint(i-1))) + } + } + st := time.Now() + tr.AddFast(changes...) + t.Log(time.Since(st)) + assert.Equal(t, []string{"9999"}, tr.Heads()) + }) + // TODO: add my tests +} + +func TestTree_Hash(t *testing.T) { + tr := new(Tree) + tr.Add(newSnapshot("root", "")) + hash1 := tr.Hash() + assert.Equal(t, tr.Hash(), hash1) + tr.Add(newChange("1", "root", "root")) + assert.NotEqual(t, tr.Hash(), hash1) + assert.Equal(t, tr.Hash(), tr.Hash()) +} + +func TestTree_AddFuzzy(t *testing.T) { + rand.Seed(time.Now().UnixNano()) + getChanges := func() []*Change { + changes := []*Change{ + newChange("1", "root", "root"), + newChange("2", "root", "1"), + newChange("1.2", "root", "1.1"), + newChange("1.3", "root", "1.2"), + newChange("1.1", "root", "1"), + newChange("3", "root", "2", "1.3"), + } + rand.Shuffle(len(changes), func(i, j int) { + changes[i], changes[j] = changes[j], changes[i] + }) + return changes + } + var phash string + for i := 0; i < 100; i++ { + tr := new(Tree) + tr.Add(newSnapshot("root", "")) + tr.Add(getChanges()...) + assert.Len(t, tr.unAttached, 0) + assert.Len(t, tr.attached, 7) + hash := tr.Hash() + if phash != "" { + assert.Equal(t, phash, hash) + } + phash = hash + assert.Equal(t, []string{"3"}, tr.Heads()) + } +} + +func TestTree_CheckRootReduce(t *testing.T) { + t.Run("check root once", func(t *testing.T) { + tr := new(Tree) + tr.Add( + newSnapshot("0", ""), + newChange("1", "0", "0"), + newChange("1.1", "0", "1"), + newChange("1.2", "0", "1"), + newChange("1.4", "0", "1.2"), + newChange("1.3", "0", "1"), + newChange("1.3.1", "0", "1.3"), + newChange("1.2+3", "0", "1.4", "1.3.1"), + newChange("1.2+3.1", "0", "1.2+3"), + newSnapshot("10", "0", "1.2+3.1", "1.1"), + newChange("last", "10", "10"), + ) + t.Run("check root", func(t *testing.T) { + total := tr.checkRoot(tr.attached["10"]) + assert.Equal(t, 1, total) + }) + t.Run("reduce", func(t *testing.T) { + tr.reduceTree() + assert.Equal(t, "10", tr.RootId()) + var res []string + tr.Iterate(tr.RootId(), func(c *Change) (isContinue bool) { + res = append(res, c.Id) + return true + }) + assert.Equal(t, []string{"10", "last"}, res) + }) + }) + t.Run("check root many", func(t *testing.T) { + tr := new(Tree) + tr.Add( + newSnapshot("0", ""), + newSnapshot("1", "0", "0"), + newChange("1.2", "0", "1"), + newChange("1.3", "0", "1"), + newChange("1.3.1", "0", "1.3"), + newSnapshot("1.2+3", "1", "1.2", "1.3.1"), + newChange("1.2+3.1", "1", "1.2+3"), + newChange("1.2+3.2", "1", "1.2+3"), + newSnapshot("10", "1.2+3", "1.2+3.1", "1.2+3.2"), + newChange("last", "10", "10"), + ) + t.Run("check root", func(t *testing.T) { + total := tr.checkRoot(tr.attached["10"]) + assert.Equal(t, 1, total) + + total = tr.checkRoot(tr.attached["1.2+3"]) + assert.Equal(t, 4, total) + + total = tr.checkRoot(tr.attached["1"]) + assert.Equal(t, 8, total) + }) + t.Run("reduce", func(t *testing.T) { + tr.reduceTree() + assert.Equal(t, "10", tr.RootId()) + var res []string + tr.Iterate(tr.RootId(), func(c *Change) (isContinue bool) { + res = append(res, c.Id) + return true + }) + assert.Equal(t, []string{"10", "last"}, res) + }) + }) + t.Run("check root incorrect", func(t *testing.T) { + tr := new(Tree) + tr.Add( + newSnapshot("0", ""), + newChange("1", "0", "0"), + newChange("1.1", "0", "1"), + newChange("1.2", "0", "1"), + newChange("1.4", "0", "1.2"), + newChange("1.3", "0", "1"), + newSnapshot("1.3.1", "0", "1.3"), + newChange("1.2+3", "0", "1.4", "1.3.1"), + newChange("1.2+3.1", "0", "1.2+3"), + newChange("10", "0", "1.2+3.1", "1.1"), + newChange("last", "10", "10"), + ) + t.Run("check root", func(t *testing.T) { + total := tr.checkRoot(tr.attached["1.3.1"]) + assert.Equal(t, -1, total) + }) + t.Run("reduce", func(t *testing.T) { + tr.reduceTree() + assert.Equal(t, "0", tr.RootId()) + assert.Equal(t, 0, len(tr.possibleRoots)) + }) + }) +} + +func TestTree_Iterate(t *testing.T) { + t.Run("complex tree", func(t *testing.T) { + tr := new(Tree) + tr.Add( + newSnapshot("0", ""), + newChange("1", "0", "0"), + newChange("1.1", "0", "1"), + newChange("1.2", "0", "1"), + newChange("1.4", "0", "1.2"), + newChange("1.3", "0", "1"), + newChange("1.3.1", "0", "1.3"), + newChange("1.2+3", "0", "1.4", "1.3.1"), + newChange("1.2+3.1", "0", "1.2+3"), + newChange("10", "0", "1.2+3.1", "1.1"), + newChange("last", "0", "10"), + ) + var res []string + tr.Iterate("0", func(c *Change) (isContinue bool) { + res = append(res, c.Id) + return true + }) + res = res[:0] + tr.Iterate("0", func(c *Change) (isContinue bool) { + res = append(res, c.Id) + return true + }) + assert.Equal(t, []string{"0", "1", "1.1", "1.2", "1.4", "1.3", "1.3.1", "1.2+3", "1.2+3.1", "10", "last"}, res) + }) +} + +func BenchmarkTree_Add(b *testing.B) { + getChanges := func() []*Change { + return []*Change{ + newChange("1", "root", "root"), + newChange("2", "root", "1"), + newChange("1.2", "root", "1.1"), + newChange("1.3", "root", "1.2"), + newChange("1.1", "root", "1"), + newChange("3", "root", "2", "1.3"), + } + } + b.Run("by one", func(b *testing.B) { + tr := new(Tree) + tr.Add(newSnapshot("root", "")) + tr.Add(getChanges()...) + for i := 0; i < b.N; i++ { + tr.Add(newChange(fmt.Sprint(i+4), "root", fmt.Sprint(i+3))) + } + }) + b.Run("add", func(b *testing.B) { + for i := 0; i < b.N; i++ { + tr := new(Tree) + tr.Add(newSnapshot("root", "")) + tr.Add(getChanges()...) + } + }) + b.Run("add fast", func(b *testing.B) { + for i := 0; i < b.N; i++ { + tr := new(Tree) + tr.AddFast(newSnapshot("root", "")) + tr.AddFast(getChanges()...) + } + }) +} + +func BenchmarkTree_IterateLinear(b *testing.B) { + // prepare linear tree + tr := new(Tree) + tr.AddFast(newSnapshot("0", "")) + for j := 0; j < 10000; j++ { + tr.Add(newChange(fmt.Sprint(j+1), "0", fmt.Sprint(j))) + } + b.Run("add linear", func(b *testing.B) { + for i := 0; i < b.N; i++ { + tr.Iterate("0", func(c *Change) (isContinue bool) { + return true + }) + } + }) +} diff --git a/pkg/acl/acltree/treebuilder.go b/common/pkg/acl/tree/treebuilder.go similarity index 56% rename from pkg/acl/acltree/treebuilder.go rename to common/pkg/acl/tree/treebuilder.go index 9bb9a4b8..1250bfdc 100644 --- a/pkg/acl/acltree/treebuilder.go +++ b/common/pkg/acl/tree/treebuilder.go @@ -1,12 +1,14 @@ -package acltree +package tree import ( + "context" "errors" "fmt" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/slice" + "go.uber.org/zap" + "time" ) var ( @@ -15,87 +17,83 @@ var ( ) type treeBuilder struct { - cache map[string]*Change - identityKeys map[string]signingkey.PubKey - signingPubKeyDecoder signingkey.PubKeyDecoder - tree *Tree - treeStorage treestorage.TreeStorage + treeStorage storage.TreeStorage + builder ChangeBuilder - *changeLoader + cache map[string]*Change + tree *Tree + + // buffers + idStack []string + loadBuffer []*Change } -func newTreeBuilder(t treestorage.TreeStorage, decoder signingkey.PubKeyDecoder) *treeBuilder { +func newTreeBuilder(storage storage.TreeStorage, builder ChangeBuilder) *treeBuilder { return &treeBuilder{ - signingPubKeyDecoder: decoder, - treeStorage: t, - changeLoader: newChangeLoader( - t, - decoder, - NewChange), + treeStorage: storage, + builder: builder, } } -func (tb *treeBuilder) Init() { +func (tb *treeBuilder) Reset() { tb.cache = make(map[string]*Change) - tb.identityKeys = make(map[string]signingkey.PubKey) tb.tree = &Tree{} - tb.changeLoader.Init(tb.cache, tb.identityKeys) } -func (tb *treeBuilder) Build(fromStart bool) (*Tree, error) { - var headsAndOrphans []string - orphans, err := tb.treeStorage.Orphans() - if err != nil { - return nil, err - } +func (tb *treeBuilder) Build(newChanges []*Change) (*Tree, error) { + var headsAndNewChanges []string heads, err := tb.treeStorage.Heads() if err != nil { return nil, err } - headsAndOrphans = append(headsAndOrphans, orphans...) - headsAndOrphans = append(headsAndOrphans, heads...) - if fromStart { - if err := tb.buildTreeFromStart(headsAndOrphans); err != nil { - return nil, fmt.Errorf("buildTree error: %v", err) - } - } else { - breakpoint, err := tb.findBreakpoint(headsAndOrphans) - if err != nil { - return nil, fmt.Errorf("findBreakpoint error: %v", err) - } - - if err = tb.buildTree(headsAndOrphans, breakpoint); err != nil { - return nil, fmt.Errorf("buildTree error: %v", err) - } + headsAndNewChanges = append(headsAndNewChanges, heads...) + tb.cache = make(map[string]*Change) + for _, ch := range newChanges { + headsAndNewChanges = append(headsAndNewChanges, ch.Id) + tb.cache[ch.Id] = ch } - tb.cache = nil + log.With(zap.Strings("heads", heads)).Debug("building tree") + breakpoint, err := tb.findBreakpoint(headsAndNewChanges) + if err != nil { + return nil, fmt.Errorf("findBreakpoint error: %v", err) + } + + if err = tb.buildTree(headsAndNewChanges, breakpoint); err != nil { + return nil, fmt.Errorf("buildTree error: %v", err) + } return tb.tree, nil } -func (tb *treeBuilder) buildTreeFromStart(heads []string) (err error) { - changes, root, err := tb.dfsFromStart(heads) +func (tb *treeBuilder) buildTree(heads []string, breakpoint string) (err error) { + ch, err := tb.loadChange(breakpoint) if err != nil { - return err + return } + tb.tree.AddFast(ch) + changes, err := tb.dfs(heads, breakpoint) - tb.tree.AddFast(root) tb.tree.AddFast(changes...) return } -func (tb *treeBuilder) dfsFromStart(heads []string) (buf []*Change, root *Change, err error) { - var possibleRoots []*Change - stack := make([]string, len(heads), len(heads)*2) - copy(stack, heads) +func (tb *treeBuilder) dfs(heads []string, breakpoint string) (buf []*Change, err error) { + // initializing buffers + tb.idStack = tb.idStack[:0] + tb.loadBuffer = tb.loadBuffer[:0] - buf = make([]*Change, 0, len(stack)*2) - uniqMap := make(map[string]struct{}) - for len(stack) > 0 { - id := stack[len(stack)-1] - stack = stack[:len(stack)-1] + // updating map + uniqMap := map[string]struct{}{breakpoint: {}} + + // preparing dfs + tb.idStack = append(tb.idStack, heads...) + + // dfs + for len(tb.idStack) > 0 { + id := tb.idStack[len(tb.idStack)-1] + tb.idStack = tb.idStack[:len(tb.idStack)-1] if _, exists := uniqMap[id]; exists { continue } @@ -106,69 +104,38 @@ func (tb *treeBuilder) dfsFromStart(heads []string) (buf []*Change, root *Change } uniqMap[id] = struct{}{} - buf = append(buf, ch) + tb.loadBuffer = append(tb.loadBuffer, ch) for _, prev := range ch.PreviousIds { - stack = append(stack, prev) - } - if len(ch.PreviousIds) == 0 { - possibleRoots = append(possibleRoots, ch) + if _, exists := uniqMap[prev]; exists { + continue + } + tb.idStack = append(tb.idStack, prev) } } - header, err := tb.treeStorage.Header() - if err != nil { - return nil, nil, err - } - for _, r := range possibleRoots { - if r.Id == header.FirstChangeId { - return buf, r, nil - } - } - - return nil, nil, fmt.Errorf("could not find root change") + return tb.loadBuffer, nil } -func (tb *treeBuilder) buildTree(heads []string, breakpoint string) (err error) { - ch, err := tb.loadChange(breakpoint) +func (tb *treeBuilder) loadChange(id string) (ch *Change, err error) { + if ch, ok := tb.cache[id]; ok { + return ch, nil + } + + ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) + defer cancel() + + change, err := tb.treeStorage.GetRawChange(ctx, id) if err != nil { - return + return nil, err } - tb.tree.AddFast(ch) - changes, err := tb.dfs(heads, breakpoint, tb.loadChange) - tb.tree.AddFast(changes...) - return -} - -func (tb *treeBuilder) dfs( - heads []string, - breakpoint string, - load func(string) (*Change, error)) (buf []*Change, err error) { - stack := make([]string, len(heads), len(heads)*2) - copy(stack, heads) - - buf = make([]*Change, 0, len(stack)*2) - uniqMap := map[string]struct{}{breakpoint: {}} - for len(stack) > 0 { - id := stack[len(stack)-1] - stack = stack[:len(stack)-1] - if _, exists := uniqMap[id]; exists { - continue - } - - ch, err := load(id) - if err != nil { - continue - } - - uniqMap[id] = struct{}{} - buf = append(buf, ch) - - for _, prev := range ch.PreviousIds { - stack = append(stack, prev) - } + ch, err = tb.builder.ConvertFromRaw(change, true) + if err != nil { + return nil, err } - return buf, nil + + tb.cache[id] = ch + return ch, nil } func (tb *treeBuilder) findBreakpoint(heads []string) (breakpoint string, err error) { @@ -281,11 +248,9 @@ func (tb *treeBuilder) findCommonForTwoSnapshots(s1, s2 string) (s string, err e } isEmptySnapshot := func(ch *Change) bool { - // TODO: add more sophisticated checks in Change for snapshots return !ch.IsSnapshot } - // TODO: can we even have empty snapshots? // prefer not empty snapshot if isEmptySnapshot(ch1) && !isEmptySnapshot(ch2) { log.Warnf("changes build Tree: prefer %s(not empty) over %s(empty)", s2, s1) @@ -295,7 +260,6 @@ func (tb *treeBuilder) findCommonForTwoSnapshots(s1, s2 string) (s string, err e return s1, nil } - // TODO: add virtual change mechanics // unexpected behavior - just return lesser id if s1 < s2 { log.Warnf("changes build Tree: prefer %s (%s<%s)", s1, s1, s2) diff --git a/pkg/acl/acltree/treegraph.go b/common/pkg/acl/tree/treegraph.go similarity index 68% rename from pkg/acl/acltree/treegraph.go rename to common/pkg/acl/tree/treegraph.go index 3b37fa2e..67cd42bd 100644 --- a/pkg/acl/acltree/treegraph.go +++ b/common/pkg/acl/tree/treegraph.go @@ -2,10 +2,10 @@ // +build !linux,!darwin android ios nographviz // +build !amd64 -package acltree +package tree import "fmt" -func (t *Tree) Graph() (data string, err error) { +func (t *Tree) Graph(parser DescriptionParser) (data []string, err error) { return "", fmt.Errorf("not supported") } diff --git a/pkg/acl/acltree/treegraph_nix.go b/common/pkg/acl/tree/treegraph_nix.go similarity index 64% rename from pkg/acl/acltree/treegraph_nix.go rename to common/pkg/acl/tree/treegraph_nix.go index 4d798939..ae4f5281 100644 --- a/pkg/acl/acltree/treegraph_nix.go +++ b/common/pkg/acl/tree/treegraph_nix.go @@ -5,20 +5,18 @@ // +build !nographviz // +build amd64 arm64 -package acltree +package tree import ( "bytes" "fmt" - "strings" - "time" - "unicode" - "github.com/goccy/go-graphviz" "github.com/goccy/go-graphviz/cgraph" + "strings" + "time" ) -func (t *Tree) Graph() (data string, err error) { +func (t *Tree) Graph(parser DescriptionParser) (data string, err error) { var order = make(map[string]string) var seq = 0 t.Iterate(t.RootId(), func(c *Change) (isContinue bool) { @@ -46,51 +44,22 @@ func (t *Tree) Graph() (data string, err error) { if e != nil { return e } - if c.Content.GetAclData() != nil { - n.SetStyle(cgraph.FilledNodeStyle) - } else if c.IsSnapshot { - n.SetStyle(cgraph.DashedNodeStyle) - } + n.SetStyle(cgraph.FilledNodeStyle) nodes[c.Id] = n ord := order[c.Id] if ord == "" { ord = "miss" } - var chSymbs []string - if c.Content.AclData != nil { - for _, chc := range c.Content.AclData.AclContent { - tp := fmt.Sprintf("%T", chc.Value) - tp = strings.Replace(tp, "ACLChangeACLContentValueValueOf", "", 1) - res := "" - for _, ts := range tp { - if unicode.IsUpper(ts) { - res += string(ts) - } - } - chSymbs = append(chSymbs, res) - } - } - if c.DecryptedDocumentChange != nil { - // TODO: add some parser to provide custom unmarshalling for the document change - //for _, chc := range c.DecryptedDocumentChange.Content { - // tp := fmt.Sprintf("%T", chc.Value) - // tp = strings.Replace(tp, "ChangeContentValueOf", "", 1) - // res := "" - // for _, ts := range tp { - // if unicode.IsUpper(ts) { - // res += string(ts) - // } - // } - // chSymbs = append(chSymbs, res) - //} - chSymbs = append(chSymbs, "DEC") + chSymbs, err := parser.ParseChange(c) + if err != nil { + return err } shortId := c.Id label := fmt.Sprintf("Id: %s\nOrd: %s\nTime: %s\nChanges: %s\n", shortId, ord, - time.Unix(c.Content.Timestamp, 0).Format("02.01.06 15:04:05"), + time.Unix(c.Timestamp, 0).Format("02.01.06 15:04:05"), strings.Join(chSymbs, ","), ) n.SetLabel(label) diff --git a/common/pkg/acl/tree/treeiterator.go b/common/pkg/acl/tree/treeiterator.go new file mode 100644 index 00000000..cee20c7e --- /dev/null +++ b/common/pkg/acl/tree/treeiterator.go @@ -0,0 +1,93 @@ +package tree + +import ( + "sync" +) + +var itPool = &sync.Pool{ + New: func() interface{} { + return &iterator{ + stack: make([]*Change, 0, 100), + resBuf: make([]*Change, 0, 100), + } + }, +} + +func newIterator() *iterator { + return itPool.Get().(*iterator) +} + +func freeIterator(i *iterator) { + itPool.Put(i) +} + +type iterator struct { + resBuf []*Change + stack []*Change + f func(c *Change) bool +} + +func (i *iterator) iterateSkip(start *Change, skipBefore *Change, f func(c *Change) (isContinue bool)) { + skipping := true + i.iterate(start, func(c *Change) (isContinue bool) { + if skipping && c != skipBefore { + return true + } + skipping = false + return f(c) + }) +} + +func (i *iterator) topSort(start *Change) { + stack := i.stack + stack = append(stack, start) + + for len(stack) > 0 { + ch := stack[len(stack)-1] + stack = stack[:len(stack)-1] + + // here we visit the change second time to add it to results + // all next changes at this point were visited + if ch.branchesFinished { + i.resBuf = append(i.resBuf, ch) + ch.branchesFinished = false + continue + } + + if ch.visited { + continue + } + + // put the change again into stack, so we can add it to results + // after all the next changes + stack = append(stack, ch) + ch.visited = true + ch.branchesFinished = true + + for j := 0; j < len(ch.Next); j++ { + if !ch.Next[j].visited { + stack = append(stack, ch.Next[j]) + } + } + } + for _, ch := range i.resBuf { + ch.visited = false + } +} + +func (i *iterator) iterate(start *Change, f func(c *Change) (isContinue bool)) { + if start == nil { + return + } + // reset + i.resBuf = i.resBuf[:0] + i.stack = i.stack[:0] + i.f = f + + i.topSort(start) + for idx := len(i.resBuf) - 1; idx >= 0; idx-- { + if !f(i.resBuf[idx]) { + return + } + } +} diff --git a/common/pkg/acl/tree/treereduce.go b/common/pkg/acl/tree/treereduce.go new file mode 100644 index 00000000..0cd201d9 --- /dev/null +++ b/common/pkg/acl/tree/treereduce.go @@ -0,0 +1,92 @@ +package tree + +import "math" + +// clearPossibleRoots force removes any snapshots which can further be deemed as roots +func (t *Tree) clearPossibleRoots() { + t.possibleRoots = t.possibleRoots[:0] +} + +// checkRoot checks if a change can be a new root for the tree +// it returns total changes which were discovered during dfsPrev from heads +func (t *Tree) checkRoot(change *Change) (total int) { + t.stackBuf = t.stackBuf[:0] + stack := t.stackBuf + + // starting with heads + for _, h := range t.headIds { + stack = append(stack, t.attached[h]) + } + + t.dfsPrev( + stack, + []string{change.Id}, + func(ch *Change) bool { + total += 1 + return true + }, + func(changes []*Change) { + if t.root.visited { + total = -1 + } + }, + ) + + return +} + +// makeRootAndRemove removes all changes before start and makes start the root +func (t *Tree) makeRootAndRemove(start *Change) { + t.stackBuf = t.stackBuf[:0] + stack := t.stackBuf + for _, prev := range start.PreviousIds { + stack = append(stack, t.attached[prev]) + } + + t.dfsPrev( + stack, + []string{}, + func(ch *Change) bool { + return true + }, + func(changes []*Change) { + for _, ch := range changes { + delete(t.attached, ch.Id) + } + }, + ) + + // removing unattached because they may refer to previous root + t.unAttached = make(map[string]*Change) + t.root = start +} + +// reduceTree tries to reduce the tree to one of possible tree roots +func (t *Tree) reduceTree() (res bool) { + if len(t.possibleRoots) == 0 { + return + } + var ( + minRoot *Change + minTotal = math.MaxInt + ) + + // checking if we can reduce tree to other root + for _, root := range t.possibleRoots { + totalChanges := t.checkRoot(root) + // we prefer new root with min amount of total changes + if totalChanges != -1 && totalChanges < minTotal { + minRoot = root + minTotal = totalChanges + } + } + + t.clearPossibleRoots() + if minRoot == nil { + return + } + + t.makeRootAndRemove(minRoot) + res = true + return +} diff --git a/common/pkg/acl/tree/util.go b/common/pkg/acl/tree/util.go new file mode 100644 index 00000000..baf7be14 --- /dev/null +++ b/common/pkg/acl/tree/util.go @@ -0,0 +1,47 @@ +package tree + +func commonSnapshotForTwoPaths(ourPath []string, theirPath []string) (string, error) { + var i int + var j int +OuterLoop: + // find starting point from the right + for i = len(ourPath) - 1; i >= 0; i-- { + for j = len(theirPath) - 1; j >= 0; j-- { + // most likely there would be only one comparison, because mostly the snapshot path will start from the root for nodes + if ourPath[i] == theirPath[j] { + break OuterLoop + } + } + } + if i < 0 || j < 0 { + return "", ErrNoCommonSnapshot + } + // find last common element of the sequence moving from right to left + for i >= 0 && j >= 0 { + if ourPath[i] == theirPath[j] { + i-- + j-- + } else { + break + } + } + return ourPath[i+1], nil +} + +func discardFromSlice[T any](elements []T, isDiscarded func(T) bool) []T { + var ( + finishedIdx = 0 + currentIdx = 0 + ) + for currentIdx < len(elements) { + if !isDiscarded(elements[currentIdx]) { + if finishedIdx != currentIdx { + elements[finishedIdx] = elements[currentIdx] + } + finishedIdx++ + } + currentIdx++ + } + elements = elements[:finishedIdx] + return elements +} diff --git a/common/pkg/acl/treechangeproto/protos/treechange.proto b/common/pkg/acl/treechangeproto/protos/treechange.proto new file mode 100644 index 00000000..3a55e031 --- /dev/null +++ b/common/pkg/acl/treechangeproto/protos/treechange.proto @@ -0,0 +1,96 @@ +syntax = "proto3"; +package treechange; +option go_package = "pkg/acl/treechangeproto"; + +// RootChange is a root of a tree +message RootChange { + // AclHeadId is a cid of latest acl record at the time of tree creation + string aclHeadId = 1; + // SpaceId is an id of space where the document is placed + string spaceId = 2; + // ChangeType is a type of tree which this RootChange is a root of + string changeType = 3; + // Timestamp is this change creation timestamp + int64 timestamp = 4; + // Seed is a random bytes to make root change unique + bytes seed = 5; + // Identity is a public key of the tree's creator + bytes identity = 6; +} + +// TreeChange is a change of a tree +message TreeChange { + // TreeHeadIds are previous ids for this TreeChange + repeated string treeHeadIds = 1; + // AclHeadId is a cid of latest acl record at the time of this change + string aclHeadId = 2; + // SnapshotBaseId is a snapshot (root) of the tree where this change is added + string snapshotBaseId = 3; + // ChangesData is an arbitrary payload to be read by the client + bytes changesData = 4; + // CurrentReadKeyHash is the hash of the read key which is used to encrypt this change + uint64 currentReadKeyHash = 5; + // Timestamp is this change creation timestamp + int64 timestamp = 6; + // Identity is a public key with which the raw payload of this change is signed + bytes identity = 7; + // IsSnapshot indicates whether this change contains a snapshot of state + bool isSnapshot = 8; +} + +// RawTreeChange is a marshalled TreeChange (or RootChange) payload and a signature of this payload +message RawTreeChange { + // Payload is a byte payload containing TreeChange + bytes payload = 1; + // Signature is a signature made by identity indicated in the TreeChange payload + bytes signature = 2; +} + +// RawTreeChangeWithId is a marshalled RawTreeChange with CID +message RawTreeChangeWithId { + // RawChange is a byte payload of RawTreeChange + bytes rawChange = 1; + // Id is a cid made from rawChange payload + string id = 2; +} + +message TreeSyncMessage { + TreeSyncContentValue content = 1; + RawTreeChangeWithId rootChange = 2; +} + +// TreeSyncContentValue provides different types for tree sync +message TreeSyncContentValue { + oneof value { + TreeHeadUpdate headUpdate = 1; + TreeFullSyncRequest fullSyncRequest = 2; + TreeFullSyncResponse fullSyncResponse = 3; + TreeErrorResponse errorResponse = 4; + } +} + +// TreeHeadUpdate is a message sent on document head update +message TreeHeadUpdate { + repeated string heads = 1; + repeated RawTreeChangeWithId changes = 2; + repeated string snapshotPath = 3; +} + +// TreeHeadUpdate is a message sent when document needs full sync +message TreeFullSyncRequest { + repeated string heads = 1; + repeated RawTreeChangeWithId changes = 2; + repeated string snapshotPath = 3; +} + +// TreeFullSyncResponse is a message sent as a response for a specific full sync +message TreeFullSyncResponse { + repeated string heads = 1; + repeated RawTreeChangeWithId changes = 2; + repeated string snapshotPath = 3; +} + +// TreeErrorResponse is an error sent as a response for a full sync request +message TreeErrorResponse { + string error = 1; +} diff --git a/common/pkg/acl/treechangeproto/treechange.go b/common/pkg/acl/treechangeproto/treechange.go new file mode 100644 index 00000000..9e4f1854 --- /dev/null +++ b/common/pkg/acl/treechangeproto/treechange.go @@ -0,0 +1,37 @@ +package treechangeproto + +func WrapHeadUpdate(update *TreeHeadUpdate, rootChange *RawTreeChangeWithId) *TreeSyncMessage { + return &TreeSyncMessage{ + Content: &TreeSyncContentValue{ + Value: &TreeSyncContentValue_HeadUpdate{HeadUpdate: update}, + }, + RootChange: rootChange, + } +} + +func WrapFullRequest(request *TreeFullSyncRequest, rootChange *RawTreeChangeWithId) *TreeSyncMessage { + return &TreeSyncMessage{ + Content: &TreeSyncContentValue{ + Value: &TreeSyncContentValue_FullSyncRequest{FullSyncRequest: request}, + }, + RootChange: rootChange, + } +} + +func WrapFullResponse(response *TreeFullSyncResponse, rootChange *RawTreeChangeWithId) *TreeSyncMessage { + return &TreeSyncMessage{ + Content: &TreeSyncContentValue{ + Value: &TreeSyncContentValue_FullSyncResponse{FullSyncResponse: response}, + }, + RootChange: rootChange, + } +} + +func WrapError(err error, rootChange *RawTreeChangeWithId) *TreeSyncMessage { + return &TreeSyncMessage{ + Content: &TreeSyncContentValue{ + Value: &TreeSyncContentValue_ErrorResponse{ErrorResponse: &TreeErrorResponse{Error: err.Error()}}, + }, + RootChange: rootChange, + } +} diff --git a/common/pkg/acl/treechangeproto/treechange.pb.go b/common/pkg/acl/treechangeproto/treechange.pb.go new file mode 100644 index 00000000..0c97164b --- /dev/null +++ b/common/pkg/acl/treechangeproto/treechange.pb.go @@ -0,0 +1,3319 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: pkg/acl/treechangeproto/protos/treechange.proto + +package treechangeproto + +import ( + fmt "fmt" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// RootChange is a root of a tree +type RootChange struct { + // AclHeadId is a cid of latest acl record at the time of tree creation + AclHeadId string `protobuf:"bytes,1,opt,name=aclHeadId,proto3" json:"aclHeadId,omitempty"` + // SpaceId is an id of space where the document is placed + SpaceId string `protobuf:"bytes,2,opt,name=spaceId,proto3" json:"spaceId,omitempty"` + // ChangeType is a type of tree which this RootChange is a root of + ChangeType string `protobuf:"bytes,3,opt,name=changeType,proto3" json:"changeType,omitempty"` + // Timestamp is this change creation timestamp + Timestamp int64 `protobuf:"varint,4,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + // Seed is a random bytes to make root change unique + Seed []byte `protobuf:"bytes,5,opt,name=seed,proto3" json:"seed,omitempty"` + // Identity is a public key of the tree's creator + Identity []byte `protobuf:"bytes,6,opt,name=identity,proto3" json:"identity,omitempty"` +} + +func (m *RootChange) Reset() { *m = RootChange{} } +func (m *RootChange) String() string { return proto.CompactTextString(m) } +func (*RootChange) ProtoMessage() {} +func (*RootChange) Descriptor() ([]byte, []int) { + return fileDescriptor_f177d8514fae978f, []int{0} +} +func (m *RootChange) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RootChange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RootChange.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RootChange) XXX_Merge(src proto.Message) { + xxx_messageInfo_RootChange.Merge(m, src) +} +func (m *RootChange) XXX_Size() int { + return m.Size() +} +func (m *RootChange) XXX_DiscardUnknown() { + xxx_messageInfo_RootChange.DiscardUnknown(m) +} + +var xxx_messageInfo_RootChange proto.InternalMessageInfo + +func (m *RootChange) GetAclHeadId() string { + if m != nil { + return m.AclHeadId + } + return "" +} + +func (m *RootChange) GetSpaceId() string { + if m != nil { + return m.SpaceId + } + return "" +} + +func (m *RootChange) GetChangeType() string { + if m != nil { + return m.ChangeType + } + return "" +} + +func (m *RootChange) GetTimestamp() int64 { + if m != nil { + return m.Timestamp + } + return 0 +} + +func (m *RootChange) GetSeed() []byte { + if m != nil { + return m.Seed + } + return nil +} + +func (m *RootChange) GetIdentity() []byte { + if m != nil { + return m.Identity + } + return nil +} + +// TreeChange is a change of a tree +type TreeChange struct { + // TreeHeadIds are previous ids for this TreeChange + TreeHeadIds []string `protobuf:"bytes,1,rep,name=treeHeadIds,proto3" json:"treeHeadIds,omitempty"` + // AclHeadId is a cid of latest acl record at the time of this change + AclHeadId string `protobuf:"bytes,2,opt,name=aclHeadId,proto3" json:"aclHeadId,omitempty"` + // SnapshotBaseId is a snapshot (root) of the tree where this change is added + SnapshotBaseId string `protobuf:"bytes,3,opt,name=snapshotBaseId,proto3" json:"snapshotBaseId,omitempty"` + // ChangesData is an arbitrary payload to be read by the client + ChangesData []byte `protobuf:"bytes,4,opt,name=changesData,proto3" json:"changesData,omitempty"` + // CurrentReadKeyHash is the hash of the read key which is used to encrypt this change + CurrentReadKeyHash uint64 `protobuf:"varint,5,opt,name=currentReadKeyHash,proto3" json:"currentReadKeyHash,omitempty"` + // Timestamp is this change creation timestamp + Timestamp int64 `protobuf:"varint,6,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + // Identity is a public key with which the raw payload of this change is signed + Identity []byte `protobuf:"bytes,7,opt,name=identity,proto3" json:"identity,omitempty"` + // IsSnapshot indicates whether this change contains a snapshot of state + IsSnapshot bool `protobuf:"varint,8,opt,name=isSnapshot,proto3" json:"isSnapshot,omitempty"` +} + +func (m *TreeChange) Reset() { *m = TreeChange{} } +func (m *TreeChange) String() string { return proto.CompactTextString(m) } +func (*TreeChange) ProtoMessage() {} +func (*TreeChange) Descriptor() ([]byte, []int) { + return fileDescriptor_f177d8514fae978f, []int{1} +} +func (m *TreeChange) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TreeChange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TreeChange.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TreeChange) XXX_Merge(src proto.Message) { + xxx_messageInfo_TreeChange.Merge(m, src) +} +func (m *TreeChange) XXX_Size() int { + return m.Size() +} +func (m *TreeChange) XXX_DiscardUnknown() { + xxx_messageInfo_TreeChange.DiscardUnknown(m) +} + +var xxx_messageInfo_TreeChange proto.InternalMessageInfo + +func (m *TreeChange) GetTreeHeadIds() []string { + if m != nil { + return m.TreeHeadIds + } + return nil +} + +func (m *TreeChange) GetAclHeadId() string { + if m != nil { + return m.AclHeadId + } + return "" +} + +func (m *TreeChange) GetSnapshotBaseId() string { + if m != nil { + return m.SnapshotBaseId + } + return "" +} + +func (m *TreeChange) GetChangesData() []byte { + if m != nil { + return m.ChangesData + } + return nil +} + +func (m *TreeChange) GetCurrentReadKeyHash() uint64 { + if m != nil { + return m.CurrentReadKeyHash + } + return 0 +} + +func (m *TreeChange) GetTimestamp() int64 { + if m != nil { + return m.Timestamp + } + return 0 +} + +func (m *TreeChange) GetIdentity() []byte { + if m != nil { + return m.Identity + } + return nil +} + +func (m *TreeChange) GetIsSnapshot() bool { + if m != nil { + return m.IsSnapshot + } + return false +} + +// RawTreeChange is a marshalled TreeChange (or RootChange) payload and a signature of this payload +type RawTreeChange struct { + // Payload is a byte payload containing TreeChange + Payload []byte `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"` + // Signature is a signature made by identity indicated in the TreeChange payload + Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (m *RawTreeChange) Reset() { *m = RawTreeChange{} } +func (m *RawTreeChange) String() string { return proto.CompactTextString(m) } +func (*RawTreeChange) ProtoMessage() {} +func (*RawTreeChange) Descriptor() ([]byte, []int) { + return fileDescriptor_f177d8514fae978f, []int{2} +} +func (m *RawTreeChange) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RawTreeChange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RawTreeChange.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RawTreeChange) XXX_Merge(src proto.Message) { + xxx_messageInfo_RawTreeChange.Merge(m, src) +} +func (m *RawTreeChange) XXX_Size() int { + return m.Size() +} +func (m *RawTreeChange) XXX_DiscardUnknown() { + xxx_messageInfo_RawTreeChange.DiscardUnknown(m) +} + +var xxx_messageInfo_RawTreeChange proto.InternalMessageInfo + +func (m *RawTreeChange) GetPayload() []byte { + if m != nil { + return m.Payload + } + return nil +} + +func (m *RawTreeChange) GetSignature() []byte { + if m != nil { + return m.Signature + } + return nil +} + +// RawTreeChangeWithId is a marshalled RawTreeChange with CID +type RawTreeChangeWithId struct { + // RawChange is a byte payload of RawTreeChange + RawChange []byte `protobuf:"bytes,1,opt,name=rawChange,proto3" json:"rawChange,omitempty"` + // Id is a cid made from rawChange payload + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` +} + +func (m *RawTreeChangeWithId) Reset() { *m = RawTreeChangeWithId{} } +func (m *RawTreeChangeWithId) String() string { return proto.CompactTextString(m) } +func (*RawTreeChangeWithId) ProtoMessage() {} +func (*RawTreeChangeWithId) Descriptor() ([]byte, []int) { + return fileDescriptor_f177d8514fae978f, []int{3} +} +func (m *RawTreeChangeWithId) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RawTreeChangeWithId) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RawTreeChangeWithId.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RawTreeChangeWithId) XXX_Merge(src proto.Message) { + xxx_messageInfo_RawTreeChangeWithId.Merge(m, src) +} +func (m *RawTreeChangeWithId) XXX_Size() int { + return m.Size() +} +func (m *RawTreeChangeWithId) XXX_DiscardUnknown() { + xxx_messageInfo_RawTreeChangeWithId.DiscardUnknown(m) +} + +var xxx_messageInfo_RawTreeChangeWithId proto.InternalMessageInfo + +func (m *RawTreeChangeWithId) GetRawChange() []byte { + if m != nil { + return m.RawChange + } + return nil +} + +func (m *RawTreeChangeWithId) GetId() string { + if m != nil { + return m.Id + } + return "" +} + +type TreeSyncMessage struct { + Content *TreeSyncContentValue `protobuf:"bytes,1,opt,name=content,proto3" json:"content,omitempty"` + RootChange *RawTreeChangeWithId `protobuf:"bytes,2,opt,name=rootChange,proto3" json:"rootChange,omitempty"` +} + +func (m *TreeSyncMessage) Reset() { *m = TreeSyncMessage{} } +func (m *TreeSyncMessage) String() string { return proto.CompactTextString(m) } +func (*TreeSyncMessage) ProtoMessage() {} +func (*TreeSyncMessage) Descriptor() ([]byte, []int) { + return fileDescriptor_f177d8514fae978f, []int{4} +} +func (m *TreeSyncMessage) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TreeSyncMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TreeSyncMessage.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TreeSyncMessage) XXX_Merge(src proto.Message) { + xxx_messageInfo_TreeSyncMessage.Merge(m, src) +} +func (m *TreeSyncMessage) XXX_Size() int { + return m.Size() +} +func (m *TreeSyncMessage) XXX_DiscardUnknown() { + xxx_messageInfo_TreeSyncMessage.DiscardUnknown(m) +} + +var xxx_messageInfo_TreeSyncMessage proto.InternalMessageInfo + +func (m *TreeSyncMessage) GetContent() *TreeSyncContentValue { + if m != nil { + return m.Content + } + return nil +} + +func (m *TreeSyncMessage) GetRootChange() *RawTreeChangeWithId { + if m != nil { + return m.RootChange + } + return nil +} + +// TreeSyncContentValue provides different types for tree sync +type TreeSyncContentValue struct { + // Types that are valid to be assigned to Value: + // + // *TreeSyncContentValue_HeadUpdate + // *TreeSyncContentValue_FullSyncRequest + // *TreeSyncContentValue_FullSyncResponse + // *TreeSyncContentValue_ErrorResponse + Value isTreeSyncContentValue_Value `protobuf_oneof:"value"` +} + +func (m *TreeSyncContentValue) Reset() { *m = TreeSyncContentValue{} } +func (m *TreeSyncContentValue) String() string { return proto.CompactTextString(m) } +func (*TreeSyncContentValue) ProtoMessage() {} +func (*TreeSyncContentValue) Descriptor() ([]byte, []int) { + return fileDescriptor_f177d8514fae978f, []int{5} +} +func (m *TreeSyncContentValue) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TreeSyncContentValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TreeSyncContentValue.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TreeSyncContentValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_TreeSyncContentValue.Merge(m, src) +} +func (m *TreeSyncContentValue) XXX_Size() int { + return m.Size() +} +func (m *TreeSyncContentValue) XXX_DiscardUnknown() { + xxx_messageInfo_TreeSyncContentValue.DiscardUnknown(m) +} + +var xxx_messageInfo_TreeSyncContentValue proto.InternalMessageInfo + +type isTreeSyncContentValue_Value interface { + isTreeSyncContentValue_Value() + MarshalTo([]byte) (int, error) + Size() int +} + +type TreeSyncContentValue_HeadUpdate struct { + HeadUpdate *TreeHeadUpdate `protobuf:"bytes,1,opt,name=headUpdate,proto3,oneof" json:"headUpdate,omitempty"` +} +type TreeSyncContentValue_FullSyncRequest struct { + FullSyncRequest *TreeFullSyncRequest `protobuf:"bytes,2,opt,name=fullSyncRequest,proto3,oneof" json:"fullSyncRequest,omitempty"` +} +type TreeSyncContentValue_FullSyncResponse struct { + FullSyncResponse *TreeFullSyncResponse `protobuf:"bytes,3,opt,name=fullSyncResponse,proto3,oneof" json:"fullSyncResponse,omitempty"` +} +type TreeSyncContentValue_ErrorResponse struct { + ErrorResponse *TreeErrorResponse `protobuf:"bytes,4,opt,name=errorResponse,proto3,oneof" json:"errorResponse,omitempty"` +} + +func (*TreeSyncContentValue_HeadUpdate) isTreeSyncContentValue_Value() {} +func (*TreeSyncContentValue_FullSyncRequest) isTreeSyncContentValue_Value() {} +func (*TreeSyncContentValue_FullSyncResponse) isTreeSyncContentValue_Value() {} +func (*TreeSyncContentValue_ErrorResponse) isTreeSyncContentValue_Value() {} + +func (m *TreeSyncContentValue) GetValue() isTreeSyncContentValue_Value { + if m != nil { + return m.Value + } + return nil +} + +func (m *TreeSyncContentValue) GetHeadUpdate() *TreeHeadUpdate { + if x, ok := m.GetValue().(*TreeSyncContentValue_HeadUpdate); ok { + return x.HeadUpdate + } + return nil +} + +func (m *TreeSyncContentValue) GetFullSyncRequest() *TreeFullSyncRequest { + if x, ok := m.GetValue().(*TreeSyncContentValue_FullSyncRequest); ok { + return x.FullSyncRequest + } + return nil +} + +func (m *TreeSyncContentValue) GetFullSyncResponse() *TreeFullSyncResponse { + if x, ok := m.GetValue().(*TreeSyncContentValue_FullSyncResponse); ok { + return x.FullSyncResponse + } + return nil +} + +func (m *TreeSyncContentValue) GetErrorResponse() *TreeErrorResponse { + if x, ok := m.GetValue().(*TreeSyncContentValue_ErrorResponse); ok { + return x.ErrorResponse + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*TreeSyncContentValue) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*TreeSyncContentValue_HeadUpdate)(nil), + (*TreeSyncContentValue_FullSyncRequest)(nil), + (*TreeSyncContentValue_FullSyncResponse)(nil), + (*TreeSyncContentValue_ErrorResponse)(nil), + } +} + +// TreeHeadUpdate is a message sent on document head update +type TreeHeadUpdate struct { + Heads []string `protobuf:"bytes,1,rep,name=heads,proto3" json:"heads,omitempty"` + Changes []*RawTreeChangeWithId `protobuf:"bytes,2,rep,name=changes,proto3" json:"changes,omitempty"` + SnapshotPath []string `protobuf:"bytes,3,rep,name=snapshotPath,proto3" json:"snapshotPath,omitempty"` +} + +func (m *TreeHeadUpdate) Reset() { *m = TreeHeadUpdate{} } +func (m *TreeHeadUpdate) String() string { return proto.CompactTextString(m) } +func (*TreeHeadUpdate) ProtoMessage() {} +func (*TreeHeadUpdate) Descriptor() ([]byte, []int) { + return fileDescriptor_f177d8514fae978f, []int{6} +} +func (m *TreeHeadUpdate) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TreeHeadUpdate) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TreeHeadUpdate.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TreeHeadUpdate) XXX_Merge(src proto.Message) { + xxx_messageInfo_TreeHeadUpdate.Merge(m, src) +} +func (m *TreeHeadUpdate) XXX_Size() int { + return m.Size() +} +func (m *TreeHeadUpdate) XXX_DiscardUnknown() { + xxx_messageInfo_TreeHeadUpdate.DiscardUnknown(m) +} + +var xxx_messageInfo_TreeHeadUpdate proto.InternalMessageInfo + +func (m *TreeHeadUpdate) GetHeads() []string { + if m != nil { + return m.Heads + } + return nil +} + +func (m *TreeHeadUpdate) GetChanges() []*RawTreeChangeWithId { + if m != nil { + return m.Changes + } + return nil +} + +func (m *TreeHeadUpdate) GetSnapshotPath() []string { + if m != nil { + return m.SnapshotPath + } + return nil +} + +// TreeHeadUpdate is a message sent when document needs full sync +type TreeFullSyncRequest struct { + Heads []string `protobuf:"bytes,1,rep,name=heads,proto3" json:"heads,omitempty"` + Changes []*RawTreeChangeWithId `protobuf:"bytes,2,rep,name=changes,proto3" json:"changes,omitempty"` + SnapshotPath []string `protobuf:"bytes,3,rep,name=snapshotPath,proto3" json:"snapshotPath,omitempty"` +} + +func (m *TreeFullSyncRequest) Reset() { *m = TreeFullSyncRequest{} } +func (m *TreeFullSyncRequest) String() string { return proto.CompactTextString(m) } +func (*TreeFullSyncRequest) ProtoMessage() {} +func (*TreeFullSyncRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f177d8514fae978f, []int{7} +} +func (m *TreeFullSyncRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TreeFullSyncRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TreeFullSyncRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TreeFullSyncRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_TreeFullSyncRequest.Merge(m, src) +} +func (m *TreeFullSyncRequest) XXX_Size() int { + return m.Size() +} +func (m *TreeFullSyncRequest) XXX_DiscardUnknown() { + xxx_messageInfo_TreeFullSyncRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_TreeFullSyncRequest proto.InternalMessageInfo + +func (m *TreeFullSyncRequest) GetHeads() []string { + if m != nil { + return m.Heads + } + return nil +} + +func (m *TreeFullSyncRequest) GetChanges() []*RawTreeChangeWithId { + if m != nil { + return m.Changes + } + return nil +} + +func (m *TreeFullSyncRequest) GetSnapshotPath() []string { + if m != nil { + return m.SnapshotPath + } + return nil +} + +// TreeFullSyncResponse is a message sent as a response for a specific full sync +type TreeFullSyncResponse struct { + Heads []string `protobuf:"bytes,1,rep,name=heads,proto3" json:"heads,omitempty"` + Changes []*RawTreeChangeWithId `protobuf:"bytes,2,rep,name=changes,proto3" json:"changes,omitempty"` + SnapshotPath []string `protobuf:"bytes,3,rep,name=snapshotPath,proto3" json:"snapshotPath,omitempty"` +} + +func (m *TreeFullSyncResponse) Reset() { *m = TreeFullSyncResponse{} } +func (m *TreeFullSyncResponse) String() string { return proto.CompactTextString(m) } +func (*TreeFullSyncResponse) ProtoMessage() {} +func (*TreeFullSyncResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f177d8514fae978f, []int{8} +} +func (m *TreeFullSyncResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TreeFullSyncResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TreeFullSyncResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TreeFullSyncResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_TreeFullSyncResponse.Merge(m, src) +} +func (m *TreeFullSyncResponse) XXX_Size() int { + return m.Size() +} +func (m *TreeFullSyncResponse) XXX_DiscardUnknown() { + xxx_messageInfo_TreeFullSyncResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_TreeFullSyncResponse proto.InternalMessageInfo + +func (m *TreeFullSyncResponse) GetHeads() []string { + if m != nil { + return m.Heads + } + return nil +} + +func (m *TreeFullSyncResponse) GetChanges() []*RawTreeChangeWithId { + if m != nil { + return m.Changes + } + return nil +} + +func (m *TreeFullSyncResponse) GetSnapshotPath() []string { + if m != nil { + return m.SnapshotPath + } + return nil +} + +// TreeErrorResponse is an error sent as a response for a full sync request +type TreeErrorResponse struct { + Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` +} + +func (m *TreeErrorResponse) Reset() { *m = TreeErrorResponse{} } +func (m *TreeErrorResponse) String() string { return proto.CompactTextString(m) } +func (*TreeErrorResponse) ProtoMessage() {} +func (*TreeErrorResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f177d8514fae978f, []int{9} +} +func (m *TreeErrorResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TreeErrorResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TreeErrorResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TreeErrorResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_TreeErrorResponse.Merge(m, src) +} +func (m *TreeErrorResponse) XXX_Size() int { + return m.Size() +} +func (m *TreeErrorResponse) XXX_DiscardUnknown() { + xxx_messageInfo_TreeErrorResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_TreeErrorResponse proto.InternalMessageInfo + +func (m *TreeErrorResponse) GetError() string { + if m != nil { + return m.Error + } + return "" +} + +func init() { + proto.RegisterType((*RootChange)(nil), "treechange.RootChange") + proto.RegisterType((*TreeChange)(nil), "treechange.TreeChange") + proto.RegisterType((*RawTreeChange)(nil), "treechange.RawTreeChange") + proto.RegisterType((*RawTreeChangeWithId)(nil), "treechange.RawTreeChangeWithId") + proto.RegisterType((*TreeSyncMessage)(nil), "treechange.TreeSyncMessage") + proto.RegisterType((*TreeSyncContentValue)(nil), "treechange.TreeSyncContentValue") + proto.RegisterType((*TreeHeadUpdate)(nil), "treechange.TreeHeadUpdate") + proto.RegisterType((*TreeFullSyncRequest)(nil), "treechange.TreeFullSyncRequest") + proto.RegisterType((*TreeFullSyncResponse)(nil), "treechange.TreeFullSyncResponse") + proto.RegisterType((*TreeErrorResponse)(nil), "treechange.TreeErrorResponse") +} + +func init() { + proto.RegisterFile("pkg/acl/treechangeproto/protos/treechange.proto", fileDescriptor_f177d8514fae978f) +} + +var fileDescriptor_f177d8514fae978f = []byte{ + // 647 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x55, 0xc1, 0x6e, 0xd3, 0x40, + 0x10, 0xf5, 0x3a, 0x69, 0xd3, 0x4e, 0xd3, 0x16, 0xb6, 0x95, 0xb0, 0x2a, 0x30, 0x96, 0x0f, 0x28, + 0x5c, 0x1a, 0x51, 0x4e, 0x20, 0x24, 0xa4, 0x96, 0x16, 0x57, 0x15, 0x08, 0x6d, 0x0b, 0x48, 0xdc, + 0x16, 0x7b, 0x48, 0x2c, 0x52, 0xdb, 0x78, 0x37, 0x54, 0xf9, 0x00, 0x2e, 0x20, 0x21, 0x3e, 0x81, + 0x6f, 0xe0, 0x0f, 0xb8, 0x71, 0xec, 0x91, 0x23, 0x6a, 0x7e, 0x04, 0xed, 0x3a, 0x4e, 0xd6, 0x6e, + 0x90, 0xb8, 0xf5, 0x92, 0x78, 0xde, 0xce, 0xbc, 0x7d, 0xf3, 0x66, 0xd7, 0x86, 0x6e, 0xf6, 0xbe, + 0xd7, 0xe5, 0xe1, 0xa0, 0x2b, 0x73, 0xc4, 0xb0, 0xcf, 0x93, 0x1e, 0x66, 0x79, 0x2a, 0xd3, 0xae, + 0xfe, 0x15, 0x06, 0xbc, 0xad, 0x11, 0x0a, 0x33, 0xc4, 0xff, 0x41, 0x00, 0x58, 0x9a, 0xca, 0x3d, + 0x1d, 0xd2, 0x9b, 0xb0, 0xcc, 0xc3, 0x41, 0x80, 0x3c, 0x3a, 0x8c, 0x1c, 0xe2, 0x91, 0xce, 0x32, + 0x9b, 0x01, 0xd4, 0x81, 0x96, 0xc8, 0x78, 0x88, 0x87, 0x91, 0x63, 0xeb, 0xb5, 0x32, 0xa4, 0x2e, + 0x40, 0x41, 0x78, 0x32, 0xca, 0xd0, 0x69, 0xe8, 0x45, 0x03, 0x51, 0xbc, 0x32, 0x3e, 0x45, 0x21, + 0xf9, 0x69, 0xe6, 0x34, 0x3d, 0xd2, 0x69, 0xb0, 0x19, 0x40, 0x29, 0x34, 0x05, 0x62, 0xe4, 0x2c, + 0x78, 0xa4, 0xd3, 0x66, 0xfa, 0x99, 0x6e, 0xc1, 0x52, 0x1c, 0x61, 0x22, 0x63, 0x39, 0x72, 0x16, + 0x35, 0x3e, 0x8d, 0xfd, 0xef, 0x36, 0xc0, 0x49, 0x8e, 0x38, 0x11, 0xed, 0xc1, 0x8a, 0xea, 0xa8, + 0x10, 0x29, 0x1c, 0xe2, 0x35, 0x3a, 0xcb, 0xcc, 0x84, 0xaa, 0x6d, 0xd9, 0xf5, 0xb6, 0xee, 0xc0, + 0x9a, 0x48, 0x78, 0x26, 0xfa, 0xa9, 0xdc, 0xe5, 0x42, 0x75, 0x57, 0x34, 0x50, 0x43, 0xd5, 0x3e, + 0x45, 0x4b, 0xe2, 0x09, 0x97, 0x5c, 0xb7, 0xd1, 0x66, 0x26, 0x44, 0xb7, 0x81, 0x86, 0xc3, 0x3c, + 0xc7, 0x44, 0x32, 0xe4, 0xd1, 0x11, 0x8e, 0x02, 0x2e, 0xfa, 0xba, 0xad, 0x26, 0x9b, 0xb3, 0x52, + 0xb5, 0x65, 0xb1, 0x6e, 0x8b, 0x69, 0x41, 0xab, 0x6a, 0x81, 0x32, 0x3c, 0x16, 0xc7, 0x13, 0x7d, + 0xce, 0x92, 0x47, 0x3a, 0x4b, 0xcc, 0x40, 0xfc, 0xa7, 0xb0, 0xca, 0xf8, 0x99, 0x61, 0x92, 0x03, + 0xad, 0x8c, 0x8f, 0x06, 0x29, 0x2f, 0xe6, 0xda, 0x66, 0x65, 0xa8, 0x44, 0x88, 0xb8, 0x97, 0x70, + 0x39, 0xcc, 0x51, 0x9b, 0xd3, 0x66, 0x33, 0xc0, 0xdf, 0x83, 0x8d, 0x0a, 0xd1, 0xeb, 0x58, 0xf6, + 0x0f, 0x75, 0x51, 0xce, 0xcf, 0x0a, 0x68, 0x42, 0x38, 0x03, 0xe8, 0x1a, 0xd8, 0x71, 0x69, 0xb4, + 0x1d, 0x47, 0xfe, 0x57, 0x02, 0xeb, 0x8a, 0xe2, 0x78, 0x94, 0x84, 0xcf, 0x50, 0x08, 0xde, 0x43, + 0xfa, 0x10, 0x5a, 0x61, 0x9a, 0x48, 0x4c, 0xa4, 0xae, 0x5f, 0xd9, 0xf1, 0xb6, 0x8d, 0x93, 0x5a, + 0x66, 0xef, 0x15, 0x29, 0xaf, 0xf8, 0x60, 0x88, 0xac, 0x2c, 0xa0, 0x8f, 0x01, 0xf2, 0xe9, 0xa1, + 0xd5, 0xfb, 0xac, 0xec, 0xdc, 0x36, 0xcb, 0xe7, 0x48, 0x66, 0x46, 0x89, 0xff, 0xd3, 0x86, 0xcd, + 0x79, 0x5b, 0xd0, 0x47, 0x00, 0x7d, 0xe4, 0xd1, 0xcb, 0x2c, 0xe2, 0x12, 0x27, 0xc2, 0xb6, 0xea, + 0xc2, 0x82, 0x69, 0x46, 0x60, 0x31, 0x23, 0x9f, 0x1e, 0xc1, 0xfa, 0xbb, 0xe1, 0x60, 0xa0, 0x58, + 0x19, 0x7e, 0x18, 0xa2, 0x90, 0xf3, 0xc4, 0x29, 0x8a, 0x83, 0x6a, 0x5a, 0x60, 0xb1, 0x7a, 0x25, + 0x7d, 0x0e, 0xd7, 0x66, 0x90, 0xc8, 0xd2, 0x44, 0x14, 0x37, 0x6b, 0x8e, 0x53, 0x07, 0xb5, 0xbc, + 0xc0, 0x62, 0x97, 0x6a, 0xe9, 0x3e, 0xac, 0x62, 0x9e, 0xa7, 0xf9, 0x94, 0xac, 0xa9, 0xc9, 0x6e, + 0xd5, 0xc9, 0xf6, 0xcd, 0xa4, 0xc0, 0x62, 0xd5, 0xaa, 0xdd, 0x16, 0x2c, 0x7c, 0x54, 0x56, 0xf9, + 0x9f, 0x08, 0xac, 0x55, 0xdd, 0xa0, 0x9b, 0xb0, 0xa0, 0xdc, 0x28, 0xef, 0x60, 0x11, 0xd0, 0x07, + 0xd0, 0x9a, 0x5c, 0x12, 0xc7, 0xf6, 0x1a, 0xff, 0x33, 0xaa, 0x32, 0x9f, 0xfa, 0xd0, 0x2e, 0x2f, + 0xe1, 0x0b, 0x2e, 0xfb, 0x4e, 0x43, 0xf3, 0x56, 0x30, 0xff, 0x33, 0x81, 0x8d, 0x39, 0x96, 0x5e, + 0x8d, 0x98, 0x2f, 0xa4, 0x38, 0x58, 0xf5, 0x89, 0x5c, 0x8d, 0x9a, 0xbb, 0x70, 0xfd, 0xd2, 0x44, + 0x95, 0x12, 0x3d, 0xd1, 0xc9, 0xfb, 0xbd, 0x08, 0x76, 0xef, 0xfd, 0xba, 0x70, 0xc9, 0xf9, 0x85, + 0x4b, 0xfe, 0x5c, 0xb8, 0xe4, 0xdb, 0xd8, 0xb5, 0xce, 0xc7, 0xae, 0xf5, 0x7b, 0xec, 0x5a, 0x6f, + 0x6e, 0xfc, 0xe3, 0xfb, 0xf2, 0x76, 0x51, 0xff, 0xdd, 0xff, 0x1b, 0x00, 0x00, 0xff, 0xff, 0xca, + 0xe3, 0xc1, 0xeb, 0x81, 0x06, 0x00, 0x00, +} + +func (m *RootChange) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RootChange) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RootChange) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Identity) > 0 { + i -= len(m.Identity) + copy(dAtA[i:], m.Identity) + i = encodeVarintTreechange(dAtA, i, uint64(len(m.Identity))) + i-- + dAtA[i] = 0x32 + } + if len(m.Seed) > 0 { + i -= len(m.Seed) + copy(dAtA[i:], m.Seed) + i = encodeVarintTreechange(dAtA, i, uint64(len(m.Seed))) + i-- + dAtA[i] = 0x2a + } + if m.Timestamp != 0 { + i = encodeVarintTreechange(dAtA, i, uint64(m.Timestamp)) + i-- + dAtA[i] = 0x20 + } + if len(m.ChangeType) > 0 { + i -= len(m.ChangeType) + copy(dAtA[i:], m.ChangeType) + i = encodeVarintTreechange(dAtA, i, uint64(len(m.ChangeType))) + i-- + dAtA[i] = 0x1a + } + if len(m.SpaceId) > 0 { + i -= len(m.SpaceId) + copy(dAtA[i:], m.SpaceId) + i = encodeVarintTreechange(dAtA, i, uint64(len(m.SpaceId))) + i-- + dAtA[i] = 0x12 + } + if len(m.AclHeadId) > 0 { + i -= len(m.AclHeadId) + copy(dAtA[i:], m.AclHeadId) + i = encodeVarintTreechange(dAtA, i, uint64(len(m.AclHeadId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *TreeChange) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TreeChange) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TreeChange) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.IsSnapshot { + i-- + if m.IsSnapshot { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x40 + } + if len(m.Identity) > 0 { + i -= len(m.Identity) + copy(dAtA[i:], m.Identity) + i = encodeVarintTreechange(dAtA, i, uint64(len(m.Identity))) + i-- + dAtA[i] = 0x3a + } + if m.Timestamp != 0 { + i = encodeVarintTreechange(dAtA, i, uint64(m.Timestamp)) + i-- + dAtA[i] = 0x30 + } + if m.CurrentReadKeyHash != 0 { + i = encodeVarintTreechange(dAtA, i, uint64(m.CurrentReadKeyHash)) + i-- + dAtA[i] = 0x28 + } + if len(m.ChangesData) > 0 { + i -= len(m.ChangesData) + copy(dAtA[i:], m.ChangesData) + i = encodeVarintTreechange(dAtA, i, uint64(len(m.ChangesData))) + i-- + dAtA[i] = 0x22 + } + if len(m.SnapshotBaseId) > 0 { + i -= len(m.SnapshotBaseId) + copy(dAtA[i:], m.SnapshotBaseId) + i = encodeVarintTreechange(dAtA, i, uint64(len(m.SnapshotBaseId))) + i-- + dAtA[i] = 0x1a + } + if len(m.AclHeadId) > 0 { + i -= len(m.AclHeadId) + copy(dAtA[i:], m.AclHeadId) + i = encodeVarintTreechange(dAtA, i, uint64(len(m.AclHeadId))) + i-- + dAtA[i] = 0x12 + } + if len(m.TreeHeadIds) > 0 { + for iNdEx := len(m.TreeHeadIds) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.TreeHeadIds[iNdEx]) + copy(dAtA[i:], m.TreeHeadIds[iNdEx]) + i = encodeVarintTreechange(dAtA, i, uint64(len(m.TreeHeadIds[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *RawTreeChange) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RawTreeChange) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RawTreeChange) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signature) > 0 { + i -= len(m.Signature) + copy(dAtA[i:], m.Signature) + i = encodeVarintTreechange(dAtA, i, uint64(len(m.Signature))) + i-- + dAtA[i] = 0x12 + } + if len(m.Payload) > 0 { + i -= len(m.Payload) + copy(dAtA[i:], m.Payload) + i = encodeVarintTreechange(dAtA, i, uint64(len(m.Payload))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *RawTreeChangeWithId) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RawTreeChangeWithId) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RawTreeChangeWithId) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Id) > 0 { + i -= len(m.Id) + copy(dAtA[i:], m.Id) + i = encodeVarintTreechange(dAtA, i, uint64(len(m.Id))) + i-- + dAtA[i] = 0x12 + } + if len(m.RawChange) > 0 { + i -= len(m.RawChange) + copy(dAtA[i:], m.RawChange) + i = encodeVarintTreechange(dAtA, i, uint64(len(m.RawChange))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *TreeSyncMessage) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TreeSyncMessage) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TreeSyncMessage) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.RootChange != nil { + { + size, err := m.RootChange.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTreechange(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.Content != nil { + { + size, err := m.Content.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTreechange(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *TreeSyncContentValue) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TreeSyncContentValue) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TreeSyncContentValue) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Value != nil { + { + size := m.Value.Size() + i -= size + if _, err := m.Value.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + return len(dAtA) - i, nil +} + +func (m *TreeSyncContentValue_HeadUpdate) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TreeSyncContentValue_HeadUpdate) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.HeadUpdate != nil { + { + size, err := m.HeadUpdate.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTreechange(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} +func (m *TreeSyncContentValue_FullSyncRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TreeSyncContentValue_FullSyncRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.FullSyncRequest != nil { + { + size, err := m.FullSyncRequest.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTreechange(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + return len(dAtA) - i, nil +} +func (m *TreeSyncContentValue_FullSyncResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TreeSyncContentValue_FullSyncResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.FullSyncResponse != nil { + { + size, err := m.FullSyncResponse.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTreechange(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + return len(dAtA) - i, nil +} +func (m *TreeSyncContentValue_ErrorResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TreeSyncContentValue_ErrorResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.ErrorResponse != nil { + { + size, err := m.ErrorResponse.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTreechange(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + return len(dAtA) - i, nil +} +func (m *TreeHeadUpdate) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TreeHeadUpdate) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TreeHeadUpdate) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.SnapshotPath) > 0 { + for iNdEx := len(m.SnapshotPath) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.SnapshotPath[iNdEx]) + copy(dAtA[i:], m.SnapshotPath[iNdEx]) + i = encodeVarintTreechange(dAtA, i, uint64(len(m.SnapshotPath[iNdEx]))) + i-- + dAtA[i] = 0x1a + } + } + if len(m.Changes) > 0 { + for iNdEx := len(m.Changes) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Changes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTreechange(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.Heads) > 0 { + for iNdEx := len(m.Heads) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Heads[iNdEx]) + copy(dAtA[i:], m.Heads[iNdEx]) + i = encodeVarintTreechange(dAtA, i, uint64(len(m.Heads[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *TreeFullSyncRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TreeFullSyncRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TreeFullSyncRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.SnapshotPath) > 0 { + for iNdEx := len(m.SnapshotPath) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.SnapshotPath[iNdEx]) + copy(dAtA[i:], m.SnapshotPath[iNdEx]) + i = encodeVarintTreechange(dAtA, i, uint64(len(m.SnapshotPath[iNdEx]))) + i-- + dAtA[i] = 0x1a + } + } + if len(m.Changes) > 0 { + for iNdEx := len(m.Changes) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Changes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTreechange(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.Heads) > 0 { + for iNdEx := len(m.Heads) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Heads[iNdEx]) + copy(dAtA[i:], m.Heads[iNdEx]) + i = encodeVarintTreechange(dAtA, i, uint64(len(m.Heads[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *TreeFullSyncResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TreeFullSyncResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TreeFullSyncResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.SnapshotPath) > 0 { + for iNdEx := len(m.SnapshotPath) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.SnapshotPath[iNdEx]) + copy(dAtA[i:], m.SnapshotPath[iNdEx]) + i = encodeVarintTreechange(dAtA, i, uint64(len(m.SnapshotPath[iNdEx]))) + i-- + dAtA[i] = 0x1a + } + } + if len(m.Changes) > 0 { + for iNdEx := len(m.Changes) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Changes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTreechange(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.Heads) > 0 { + for iNdEx := len(m.Heads) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Heads[iNdEx]) + copy(dAtA[i:], m.Heads[iNdEx]) + i = encodeVarintTreechange(dAtA, i, uint64(len(m.Heads[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *TreeErrorResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TreeErrorResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TreeErrorResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Error) > 0 { + i -= len(m.Error) + copy(dAtA[i:], m.Error) + i = encodeVarintTreechange(dAtA, i, uint64(len(m.Error))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintTreechange(dAtA []byte, offset int, v uint64) int { + offset -= sovTreechange(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *RootChange) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.AclHeadId) + if l > 0 { + n += 1 + l + sovTreechange(uint64(l)) + } + l = len(m.SpaceId) + if l > 0 { + n += 1 + l + sovTreechange(uint64(l)) + } + l = len(m.ChangeType) + if l > 0 { + n += 1 + l + sovTreechange(uint64(l)) + } + if m.Timestamp != 0 { + n += 1 + sovTreechange(uint64(m.Timestamp)) + } + l = len(m.Seed) + if l > 0 { + n += 1 + l + sovTreechange(uint64(l)) + } + l = len(m.Identity) + if l > 0 { + n += 1 + l + sovTreechange(uint64(l)) + } + return n +} + +func (m *TreeChange) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.TreeHeadIds) > 0 { + for _, s := range m.TreeHeadIds { + l = len(s) + n += 1 + l + sovTreechange(uint64(l)) + } + } + l = len(m.AclHeadId) + if l > 0 { + n += 1 + l + sovTreechange(uint64(l)) + } + l = len(m.SnapshotBaseId) + if l > 0 { + n += 1 + l + sovTreechange(uint64(l)) + } + l = len(m.ChangesData) + if l > 0 { + n += 1 + l + sovTreechange(uint64(l)) + } + if m.CurrentReadKeyHash != 0 { + n += 1 + sovTreechange(uint64(m.CurrentReadKeyHash)) + } + if m.Timestamp != 0 { + n += 1 + sovTreechange(uint64(m.Timestamp)) + } + l = len(m.Identity) + if l > 0 { + n += 1 + l + sovTreechange(uint64(l)) + } + if m.IsSnapshot { + n += 2 + } + return n +} + +func (m *RawTreeChange) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Payload) + if l > 0 { + n += 1 + l + sovTreechange(uint64(l)) + } + l = len(m.Signature) + if l > 0 { + n += 1 + l + sovTreechange(uint64(l)) + } + return n +} + +func (m *RawTreeChangeWithId) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.RawChange) + if l > 0 { + n += 1 + l + sovTreechange(uint64(l)) + } + l = len(m.Id) + if l > 0 { + n += 1 + l + sovTreechange(uint64(l)) + } + return n +} + +func (m *TreeSyncMessage) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Content != nil { + l = m.Content.Size() + n += 1 + l + sovTreechange(uint64(l)) + } + if m.RootChange != nil { + l = m.RootChange.Size() + n += 1 + l + sovTreechange(uint64(l)) + } + return n +} + +func (m *TreeSyncContentValue) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Value != nil { + n += m.Value.Size() + } + return n +} + +func (m *TreeSyncContentValue_HeadUpdate) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.HeadUpdate != nil { + l = m.HeadUpdate.Size() + n += 1 + l + sovTreechange(uint64(l)) + } + return n +} +func (m *TreeSyncContentValue_FullSyncRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.FullSyncRequest != nil { + l = m.FullSyncRequest.Size() + n += 1 + l + sovTreechange(uint64(l)) + } + return n +} +func (m *TreeSyncContentValue_FullSyncResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.FullSyncResponse != nil { + l = m.FullSyncResponse.Size() + n += 1 + l + sovTreechange(uint64(l)) + } + return n +} +func (m *TreeSyncContentValue_ErrorResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ErrorResponse != nil { + l = m.ErrorResponse.Size() + n += 1 + l + sovTreechange(uint64(l)) + } + return n +} +func (m *TreeHeadUpdate) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Heads) > 0 { + for _, s := range m.Heads { + l = len(s) + n += 1 + l + sovTreechange(uint64(l)) + } + } + if len(m.Changes) > 0 { + for _, e := range m.Changes { + l = e.Size() + n += 1 + l + sovTreechange(uint64(l)) + } + } + if len(m.SnapshotPath) > 0 { + for _, s := range m.SnapshotPath { + l = len(s) + n += 1 + l + sovTreechange(uint64(l)) + } + } + return n +} + +func (m *TreeFullSyncRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Heads) > 0 { + for _, s := range m.Heads { + l = len(s) + n += 1 + l + sovTreechange(uint64(l)) + } + } + if len(m.Changes) > 0 { + for _, e := range m.Changes { + l = e.Size() + n += 1 + l + sovTreechange(uint64(l)) + } + } + if len(m.SnapshotPath) > 0 { + for _, s := range m.SnapshotPath { + l = len(s) + n += 1 + l + sovTreechange(uint64(l)) + } + } + return n +} + +func (m *TreeFullSyncResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Heads) > 0 { + for _, s := range m.Heads { + l = len(s) + n += 1 + l + sovTreechange(uint64(l)) + } + } + if len(m.Changes) > 0 { + for _, e := range m.Changes { + l = e.Size() + n += 1 + l + sovTreechange(uint64(l)) + } + } + if len(m.SnapshotPath) > 0 { + for _, s := range m.SnapshotPath { + l = len(s) + n += 1 + l + sovTreechange(uint64(l)) + } + } + return n +} + +func (m *TreeErrorResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Error) + if l > 0 { + n += 1 + l + sovTreechange(uint64(l)) + } + return n +} + +func sovTreechange(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTreechange(x uint64) (n int) { + return sovTreechange(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *RootChange) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RootChange: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RootChange: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AclHeadId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AclHeadId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SpaceId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SpaceId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChangeType", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChangeType = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) + } + m.Timestamp = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Timestamp |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Seed", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Seed = append(m.Seed[:0], dAtA[iNdEx:postIndex]...) + if m.Seed == nil { + m.Seed = []byte{} + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Identity", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Identity = append(m.Identity[:0], dAtA[iNdEx:postIndex]...) + if m.Identity == nil { + m.Identity = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTreechange(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTreechange + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TreeChange) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TreeChange: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TreeChange: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TreeHeadIds", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TreeHeadIds = append(m.TreeHeadIds, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AclHeadId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AclHeadId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SnapshotBaseId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SnapshotBaseId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChangesData", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChangesData = append(m.ChangesData[:0], dAtA[iNdEx:postIndex]...) + if m.ChangesData == nil { + m.ChangesData = []byte{} + } + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CurrentReadKeyHash", wireType) + } + m.CurrentReadKeyHash = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CurrentReadKeyHash |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) + } + m.Timestamp = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Timestamp |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Identity", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Identity = append(m.Identity[:0], dAtA[iNdEx:postIndex]...) + if m.Identity == nil { + m.Identity = []byte{} + } + iNdEx = postIndex + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IsSnapshot", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IsSnapshot = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipTreechange(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTreechange + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RawTreeChange) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RawTreeChange: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RawTreeChange: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Payload", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Payload = append(m.Payload[:0], dAtA[iNdEx:postIndex]...) + if m.Payload == nil { + m.Payload = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signature = append(m.Signature[:0], dAtA[iNdEx:postIndex]...) + if m.Signature == nil { + m.Signature = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTreechange(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTreechange + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RawTreeChangeWithId) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RawTreeChangeWithId: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RawTreeChangeWithId: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RawChange", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RawChange = append(m.RawChange[:0], dAtA[iNdEx:postIndex]...) + if m.RawChange == nil { + m.RawChange = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Id = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTreechange(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTreechange + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TreeSyncMessage) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TreeSyncMessage: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TreeSyncMessage: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Content", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Content == nil { + m.Content = &TreeSyncContentValue{} + } + if err := m.Content.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RootChange", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.RootChange == nil { + m.RootChange = &RawTreeChangeWithId{} + } + if err := m.RootChange.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTreechange(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTreechange + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TreeSyncContentValue) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TreeSyncContentValue: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TreeSyncContentValue: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field HeadUpdate", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &TreeHeadUpdate{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Value = &TreeSyncContentValue_HeadUpdate{v} + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FullSyncRequest", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &TreeFullSyncRequest{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Value = &TreeSyncContentValue_FullSyncRequest{v} + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FullSyncResponse", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &TreeFullSyncResponse{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Value = &TreeSyncContentValue_FullSyncResponse{v} + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ErrorResponse", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &TreeErrorResponse{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Value = &TreeSyncContentValue_ErrorResponse{v} + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTreechange(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTreechange + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TreeHeadUpdate) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TreeHeadUpdate: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TreeHeadUpdate: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Heads", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Heads = append(m.Heads, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Changes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Changes = append(m.Changes, &RawTreeChangeWithId{}) + if err := m.Changes[len(m.Changes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SnapshotPath", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SnapshotPath = append(m.SnapshotPath, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTreechange(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTreechange + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TreeFullSyncRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TreeFullSyncRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TreeFullSyncRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Heads", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Heads = append(m.Heads, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Changes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Changes = append(m.Changes, &RawTreeChangeWithId{}) + if err := m.Changes[len(m.Changes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SnapshotPath", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SnapshotPath = append(m.SnapshotPath, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTreechange(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTreechange + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TreeFullSyncResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TreeFullSyncResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TreeFullSyncResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Heads", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Heads = append(m.Heads, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Changes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Changes = append(m.Changes, &RawTreeChangeWithId{}) + if err := m.Changes[len(m.Changes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SnapshotPath", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SnapshotPath = append(m.SnapshotPath, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTreechange(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTreechange + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TreeErrorResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TreeErrorResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TreeErrorResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTreechange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTreechange + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTreechange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Error = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTreechange(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTreechange + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTreechange(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTreechange + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTreechange + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTreechange + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthTreechange + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTreechange + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTreechange + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTreechange = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTreechange = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTreechange = fmt.Errorf("proto: unexpected end of group") +) diff --git a/pkg/ldiff/diff.go b/common/pkg/ldiff/diff.go similarity index 89% rename from pkg/ldiff/diff.go rename to common/pkg/ldiff/diff.go index 6f276afd..68b0f115 100644 --- a/pkg/ldiff/diff.go +++ b/common/pkg/ldiff/diff.go @@ -1,5 +1,7 @@ // Package ldiff provides a container of elements with fixed id and changeable content. // Diff can calculate the difference with another diff container (you can make it remote) with minimum hops and traffic. +// +//go:generate mockgen -destination mock_ldiff/mock_ldiff.go github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ldiff Diff,Remote package ldiff import ( @@ -83,6 +85,10 @@ type Diff interface { RemoveId(id string) error // Diff makes diff with remote container Diff(ctx context.Context, dl Remote) (newIds, changedIds, removedIds []string, err error) + // Elements retrieves all elements in the Diff + Elements() []Element + // Ids retrieves ids of all elements in the Diff + Ids() []string } // Remote interface for using in the Diff @@ -133,6 +139,36 @@ func (d *diff) Set(elements ...Element) { } } +func (d *diff) Ids() (ids []string) { + d.mu.RLock() + defer d.mu.RUnlock() + + ids = make([]string, 0, d.sl.Len()) + + cur := d.sl.Front() + for cur != nil { + el := cur.Key().(*element).Element + ids = append(ids, el.Id) + cur = cur.Next() + } + return +} + +func (d *diff) Elements() (elements []Element) { + d.mu.RLock() + defer d.mu.RUnlock() + + elements = make([]Element, 0, d.sl.Len()) + + cur := d.sl.Front() + for cur != nil { + el := cur.Key().(*element).Element + elements = append(elements, el) + cur = cur.Next() + } + return +} + // RemoveId removes element by id func (d *diff) RemoveId(id string) error { d.mu.Lock() @@ -181,6 +217,7 @@ func (d *diff) getRange(r Range) (rr RangeResult) { func (d *diff) Ranges(ctx context.Context, ranges []Range, resBuf []RangeResult) (results []RangeResult, err error) { d.mu.RLock() defer d.mu.RUnlock() + results = resBuf[:0] for _, r := range ranges { results = append(results, d.getRange(r)) @@ -199,9 +236,6 @@ var errMismatched = errors.New("query and results mismatched") // Diff makes diff with remote container func (d *diff) Diff(ctx context.Context, dl Remote) (newIds, changedIds, removedIds []string, err error) { - d.mu.RLock() - defer d.mu.RUnlock() - dctx := &diffCtx{} dctx.toSend = append(dctx.toSend, Range{ From: 0, @@ -215,10 +249,10 @@ func (d *diff) Diff(ctx context.Context, dl Remote) (newIds, changedIds, removed return default: } - if dctx.myRes, err = d.Ranges(ctx, dctx.toSend, dctx.myRes); err != nil { + if dctx.otherRes, err = dl.Ranges(ctx, dctx.toSend, dctx.otherRes); err != nil { return } - if dctx.otherRes, err = dl.Ranges(ctx, dctx.toSend, dctx.otherRes); err != nil { + if dctx.myRes, err = d.Ranges(ctx, dctx.toSend, dctx.myRes); err != nil { return } if len(dctx.otherRes) != len(dctx.toSend) || len(dctx.myRes) != len(dctx.toSend) { diff --git a/pkg/ldiff/diff_test.go b/common/pkg/ldiff/diff_test.go similarity index 100% rename from pkg/ldiff/diff_test.go rename to common/pkg/ldiff/diff_test.go diff --git a/common/pkg/ldiff/mock_ldiff/mock_ldiff.go b/common/pkg/ldiff/mock_ldiff/mock_ldiff.go new file mode 100644 index 00000000..d2170600 --- /dev/null +++ b/common/pkg/ldiff/mock_ldiff/mock_ldiff.go @@ -0,0 +1,164 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ldiff (interfaces: Diff,Remote) + +// Package mock_ldiff is a generated GoMock package. +package mock_ldiff + +import ( + context "context" + reflect "reflect" + + ldiff "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ldiff" + gomock "github.com/golang/mock/gomock" +) + +// MockDiff is a mock of Diff interface. +type MockDiff struct { + ctrl *gomock.Controller + recorder *MockDiffMockRecorder +} + +// MockDiffMockRecorder is the mock recorder for MockDiff. +type MockDiffMockRecorder struct { + mock *MockDiff +} + +// NewMockDiff creates a new mock instance. +func NewMockDiff(ctrl *gomock.Controller) *MockDiff { + mock := &MockDiff{ctrl: ctrl} + mock.recorder = &MockDiffMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockDiff) EXPECT() *MockDiffMockRecorder { + return m.recorder +} + +// Diff mocks base method. +func (m *MockDiff) Diff(arg0 context.Context, arg1 ldiff.Remote) ([]string, []string, []string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Diff", arg0, arg1) + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].([]string) + ret2, _ := ret[2].([]string) + ret3, _ := ret[3].(error) + return ret0, ret1, ret2, ret3 +} + +// Diff indicates an expected call of Diff. +func (mr *MockDiffMockRecorder) Diff(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Diff", reflect.TypeOf((*MockDiff)(nil).Diff), arg0, arg1) +} + +// Elements mocks base method. +func (m *MockDiff) Elements() []ldiff.Element { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Elements") + ret0, _ := ret[0].([]ldiff.Element) + return ret0 +} + +// Elements indicates an expected call of Elements. +func (mr *MockDiffMockRecorder) Elements() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Elements", reflect.TypeOf((*MockDiff)(nil).Elements)) +} + +// Ids mocks base method. +func (m *MockDiff) Ids() []string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Ids") + ret0, _ := ret[0].([]string) + return ret0 +} + +// Ids indicates an expected call of Ids. +func (mr *MockDiffMockRecorder) Ids() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ids", reflect.TypeOf((*MockDiff)(nil).Ids)) +} + +// Ranges mocks base method. +func (m *MockDiff) Ranges(arg0 context.Context, arg1 []ldiff.Range, arg2 []ldiff.RangeResult) ([]ldiff.RangeResult, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Ranges", arg0, arg1, arg2) + ret0, _ := ret[0].([]ldiff.RangeResult) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Ranges indicates an expected call of Ranges. +func (mr *MockDiffMockRecorder) Ranges(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ranges", reflect.TypeOf((*MockDiff)(nil).Ranges), arg0, arg1, arg2) +} + +// RemoveId mocks base method. +func (m *MockDiff) RemoveId(arg0 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RemoveId", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// RemoveId indicates an expected call of RemoveId. +func (mr *MockDiffMockRecorder) RemoveId(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveId", reflect.TypeOf((*MockDiff)(nil).RemoveId), arg0) +} + +// Set mocks base method. +func (m *MockDiff) Set(arg0 ...ldiff.Element) { + m.ctrl.T.Helper() + varargs := []interface{}{} + for _, a := range arg0 { + varargs = append(varargs, a) + } + m.ctrl.Call(m, "Set", varargs...) +} + +// Set indicates an expected call of Set. +func (mr *MockDiffMockRecorder) Set(arg0 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Set", reflect.TypeOf((*MockDiff)(nil).Set), arg0...) +} + +// MockRemote is a mock of Remote interface. +type MockRemote struct { + ctrl *gomock.Controller + recorder *MockRemoteMockRecorder +} + +// MockRemoteMockRecorder is the mock recorder for MockRemote. +type MockRemoteMockRecorder struct { + mock *MockRemote +} + +// NewMockRemote creates a new mock instance. +func NewMockRemote(ctrl *gomock.Controller) *MockRemote { + mock := &MockRemote{ctrl: ctrl} + mock.recorder = &MockRemoteMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockRemote) EXPECT() *MockRemoteMockRecorder { + return m.recorder +} + +// Ranges mocks base method. +func (m *MockRemote) Ranges(arg0 context.Context, arg1 []ldiff.Range, arg2 []ldiff.RangeResult) ([]ldiff.RangeResult, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Ranges", arg0, arg1, arg2) + ret0, _ := ret[0].([]ldiff.RangeResult) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Ranges indicates an expected call of Ranges. +func (mr *MockRemoteMockRecorder) Ranges(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ranges", reflect.TypeOf((*MockRemote)(nil).Ranges), arg0, arg1, arg2) +} diff --git a/common/pkg/ocache/metrics.go b/common/pkg/ocache/metrics.go new file mode 100644 index 00000000..77bbfee3 --- /dev/null +++ b/common/pkg/ocache/metrics.go @@ -0,0 +1,52 @@ +package ocache + +import "github.com/prometheus/client_golang/prometheus" + +func WithPrometheus(reg *prometheus.Registry, namespace, subsystem string) Option { + if subsystem == "" { + subsystem = "cache" + } + return func(cache *oCache) { + cache.metrics = &metrics{ + hit: prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "hit", + Help: "cache hit count", + }), + miss: prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "miss", + Help: "cache miss count", + }), + gc: prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "gc", + Help: "garbage collected count", + }), + size: prometheus.NewGaugeFunc(prometheus.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "size", + Help: "cache size", + }, func() float64 { + return float64(cache.Len()) + }), + } + reg.MustRegister( + cache.metrics.hit, + cache.metrics.miss, + cache.metrics.gc, + cache.metrics.size, + ) + } +} + +type metrics struct { + hit prometheus.Counter + miss prometheus.Counter + gc prometheus.Counter + size prometheus.GaugeFunc +} diff --git a/pkg/ocache/ocache.go b/common/pkg/ocache/ocache.go similarity index 72% rename from pkg/ocache/ocache.go rename to common/pkg/ocache/ocache.go index b0460ca6..629a5864 100644 --- a/pkg/ocache/ocache.go +++ b/common/pkg/ocache/ocache.go @@ -3,7 +3,7 @@ package ocache import ( "context" "errors" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" "go.uber.org/zap" "sync" "time" @@ -12,7 +12,6 @@ import ( var ( ErrClosed = errors.New("object cache closed") ErrExists = errors.New("object exists") - ErrTimeout = errors.New("loading object timed out") ErrNotExists = errors.New("object not exists") ) @@ -27,9 +26,9 @@ type LoadFunc func(ctx context.Context, id string) (value Object, err error) type Option func(*oCache) -var WithLogServiceName = func(name string) Option { +var WithLogger = func(l *zap.SugaredLogger) Option { return func(cache *oCache) { - cache.log = cache.log.With("service_name", name) + cache.log = l } } @@ -45,6 +44,12 @@ var WithGCPeriod = func(gcPeriod time.Duration) Option { } } +var WithRefCounter = func(enable bool) Option { + return func(cache *oCache) { + cache.refCounter = enable + } +} + func New(loadFunc LoadFunc, opts ...Option) OCache { c := &oCache{ data: make(map[string]*entry), @@ -69,17 +74,22 @@ type Object interface { } type ObjectLocker interface { - Object Locked() bool } +type ObjectLastUsage interface { + LastUsage() time.Time +} + type entry struct { id string lastUsage time.Time refCount uint32 + isClosing bool load chan struct{} loadErr error value Object + close chan struct{} } func (e *entry) locked() bool { @@ -99,7 +109,7 @@ type OCache interface { // When 'loadFunc' returns a non-nil error, an object will not be stored to cache Get(ctx context.Context, id string) (value Object, err error) // Pick returns value if it's presents in cache (will not call loadFunc) - Pick(id string) (value Object, err error) + Pick(ctx context.Context, id string) (value Object, err error) // Add adds new object to cache // Returns error when object exists Add(id string, value Object) (err error) @@ -121,15 +131,17 @@ type OCache interface { } type oCache struct { - mu sync.Mutex - data map[string]*entry - loadFunc LoadFunc - timeNow func() time.Time - ttl time.Duration - gc time.Duration - closed bool - closeCh chan struct{} - log *zap.SugaredLogger + mu sync.Mutex + data map[string]*entry + loadFunc LoadFunc + timeNow func() time.Time + ttl time.Duration + gc time.Duration + closed bool + closeCh chan struct{} + log *zap.SugaredLogger + metrics *metrics + refCounter bool } func (c *oCache) Get(ctx context.Context, id string) (value Object, err error) { @@ -138,6 +150,7 @@ func (c *oCache) Get(ctx context.Context, id string) (value Object, err error) { ok bool load bool ) +Load: c.mu.Lock() if c.closed { c.mu.Unlock() @@ -151,13 +164,29 @@ func (c *oCache) Get(ctx context.Context, id string) (value Object, err error) { } c.data[id] = e } - e.lastUsage = c.timeNow() - e.refCount++ + closing := e.isClosing + if !e.isClosing { + e.lastUsage = c.timeNow() + if c.refCounter { + e.refCount++ + } + } c.mu.Unlock() + if closing { + <-e.close + goto Load + } if load { go c.load(ctx, id, e) } + if c.metrics != nil { + if load { + c.metrics.miss.Inc() + } else { + c.metrics.hit.Inc() + } + } select { case <-ctx.Done(): return nil, ctx.Err() @@ -166,15 +195,25 @@ func (c *oCache) Get(ctx context.Context, id string) (value Object, err error) { return e.value, e.loadErr } -func (c *oCache) Pick(id string) (value Object, err error) { +func (c *oCache) Pick(ctx context.Context, id string) (value Object, err error) { c.mu.Lock() val, ok := c.data[id] - c.mu.Unlock() - if !ok { + if !ok || val.isClosing { + c.mu.Unlock() return nil, ErrNotExists } - <-val.load - return val.value, val.loadErr + c.mu.Unlock() + + if c.metrics != nil { + c.metrics.hit.Inc() + } + + select { + case <-ctx.Done(): + return nil, ctx.Err() + case <-val.load: + return val.value, val.loadErr + } } func (c *oCache) load(ctx context.Context, id string, e *entry) { @@ -198,7 +237,7 @@ func (c *oCache) Release(id string) bool { return false } if e, ok := c.data[id]; ok { - if e.refCount > 0 { + if c.refCounter && e.refCount > 0 { e.refCount-- return true } @@ -221,17 +260,30 @@ func (c *oCache) Reset(id string) bool { func (c *oCache) Remove(id string) (ok bool, err error) { c.mu.Lock() - e, ok := c.data[id] - if ok { - delete(c.data, id) + if c.closed { + c.mu.Unlock() + err = ErrClosed + return } + var e *entry + e, ok = c.data[id] + if !ok || e.isClosing { + c.mu.Unlock() + return + } + e.isClosing = true + e.close = make(chan struct{}) c.mu.Unlock() - if ok { - <-e.load - if e.value != nil { - err = e.value.Close() - } + + <-e.load + if e.value != nil { + err = e.value.Close() } + c.mu.Lock() + close(e.close) + delete(c.data, e.id) + c.mu.Unlock() + return } @@ -271,7 +323,7 @@ func (c *oCache) ForEach(f func(obj Object) (isContinue bool)) { for _, v := range c.data { select { case <-v.load: - if v.value != nil { + if v.value != nil && !v.isClosing { objects = append(objects, v.value) } default: @@ -306,15 +358,23 @@ func (c *oCache) GC() { } deadline := c.timeNow().Add(-c.ttl) var toClose []*entry - for k, e := range c.data { - if !e.locked() && e.refCount <= 0 && e.lastUsage.Before(deadline) { - delete(c.data, k) + for _, e := range c.data { + if e.isClosing { + continue + } + lu := e.lastUsage + if lug, ok := e.value.(ObjectLastUsage); ok { + lu = lug.LastUsage() + } + if !e.locked() && e.refCount <= 0 && lu.Before(deadline) { + e.isClosing = true + e.close = make(chan struct{}) toClose = append(toClose, e) } } size := len(c.data) c.mu.Unlock() - c.log.Infof("GC: removed %d; cache size: %d", len(toClose), size) + for _, e := range toClose { <-e.load if e.value != nil { @@ -323,6 +383,16 @@ func (c *oCache) GC() { } } } + c.log.Infof("GC: removed %d; cache size: %d", len(toClose), size) + if len(toClose) > 0 && c.metrics != nil { + c.metrics.gc.Add(float64(len(toClose))) + } + c.mu.Lock() + for _, e := range toClose { + close(e.close) + delete(c.data, e.id) + } + c.mu.Unlock() } func (c *oCache) Len() int { @@ -339,9 +409,13 @@ func (c *oCache) Close() (err error) { } c.closed = true close(c.closeCh) - var toClose []*entry + var toClose, alreadyClosing []*entry for _, e := range c.data { - toClose = append(toClose, e) + if e.isClosing { + alreadyClosing = append(alreadyClosing, e) + } else { + toClose = append(toClose, e) + } } c.mu.Unlock() for _, e := range toClose { @@ -352,5 +426,8 @@ func (c *oCache) Close() (err error) { } } } + for _, e := range alreadyClosing { + <-e.close + } return nil } diff --git a/pkg/ocache/ocache_test.go b/common/pkg/ocache/ocache_test.go similarity index 52% rename from pkg/ocache/ocache_test.go rename to common/pkg/ocache/ocache_test.go index 55bf2e95..54034141 100644 --- a/pkg/ocache/ocache_test.go +++ b/common/pkg/ocache/ocache_test.go @@ -14,16 +14,23 @@ import ( type testObject struct { name string closeErr error + closeCh chan struct{} +} + +func NewTestObject(name string, closeCh chan struct{}) *testObject { + return &testObject{ + name: name, + closeCh: closeCh, + } } func (t *testObject) Close() (err error) { + if t.closeCh != nil { + <-t.closeCh + } return t.closeErr } -func (t *testObject) ShouldClose() bool { - return true -} - func TestOCache_Get(t *testing.T) { t.Run("successful", func(t *testing.T) { c := New(func(ctx context.Context, id string) (value Object, err error) { @@ -109,20 +116,91 @@ func TestOCache_Get(t *testing.T) { } func TestOCache_GC(t *testing.T) { + t.Run("test without close wait", func(t *testing.T) { + c := New(func(ctx context.Context, id string) (value Object, err error) { + return &testObject{name: id}, nil + }, WithTTL(time.Millisecond*10), WithRefCounter(true)) + val, err := c.Get(context.TODO(), "id") + require.NoError(t, err) + require.NotNil(t, val) + assert.Equal(t, 1, c.Len()) + c.GC() + assert.Equal(t, 1, c.Len()) + time.Sleep(time.Millisecond * 30) + c.GC() + assert.Equal(t, 1, c.Len()) + assert.True(t, c.Release("id")) + c.GC() + assert.Equal(t, 0, c.Len()) + assert.False(t, c.Release("id")) + }) + t.Run("test with close wait", func(t *testing.T) { + closeCh := make(chan struct{}) + getCh := make(chan struct{}) + + c := New(func(ctx context.Context, id string) (value Object, err error) { + return NewTestObject(id, closeCh), nil + }, WithTTL(time.Millisecond*10), WithRefCounter(true)) + val, err := c.Get(context.TODO(), "id") + require.NoError(t, err) + require.NotNil(t, val) + assert.Equal(t, 1, c.Len()) + assert.True(t, c.Release("id")) + // making ttl pass + time.Sleep(time.Millisecond * 40) + // first gc will be run after 20 secs, so calling it manually + go c.GC() + // waiting until all objects are marked as closing + time.Sleep(time.Millisecond * 40) + var events []string + go func() { + _, err := c.Get(context.TODO(), "id") + require.NoError(t, err) + require.NotNil(t, val) + events = append(events, "get") + close(getCh) + }() + events = append(events, "close") + // sleeping to make sure that Get is called + time.Sleep(time.Millisecond * 40) + close(closeCh) + + <-getCh + require.Equal(t, []string{"close", "get"}, events) + }) +} + +func Test_OCache_Remove(t *testing.T) { + closeCh := make(chan struct{}) + getCh := make(chan struct{}) + c := New(func(ctx context.Context, id string) (value Object, err error) { - return &testObject{name: id}, nil + return NewTestObject(id, closeCh), nil }, WithTTL(time.Millisecond*10)) val, err := c.Get(context.TODO(), "id") require.NoError(t, err) require.NotNil(t, val) assert.Equal(t, 1, c.Len()) - c.GC() - assert.Equal(t, 1, c.Len()) - time.Sleep(time.Millisecond * 30) - c.GC() - assert.Equal(t, 1, c.Len()) - assert.True(t, c.Release("id")) - c.GC() - assert.Equal(t, 0, c.Len()) - assert.False(t, c.Release("id")) + // removing the object, so we will wait on closing + go func() { + _, err := c.Remove("id") + require.NoError(t, err) + }() + time.Sleep(time.Millisecond * 40) + + var events []string + go func() { + _, err := c.Get(context.TODO(), "id") + require.NoError(t, err) + require.NotNil(t, val) + events = append(events, "get") + close(getCh) + }() + events = append(events, "close") + // sleeping to make sure that Get is called + time.Sleep(time.Millisecond * 40) + close(closeCh) + + <-getCh + require.Equal(t, []string{"close", "get"}, events) } diff --git a/common/testutil/testaccount/service.go b/common/testutil/testaccount/service.go new file mode 100644 index 00000000..7995621d --- /dev/null +++ b/common/testutil/testaccount/service.go @@ -0,0 +1,44 @@ +package testaccount + +import ( + accountService "github.com/anytypeio/go-anytype-infrastructure-experiments/common/account" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/account" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/encryptionkey" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/signingkey" +) + +// AccountTestService provides service for test purposes, generates new random account every Init +type AccountTestService struct { + acc *account.AccountData +} + +func (s *AccountTestService) Init(a *app.App) (err error) { + encKey, _, err := encryptionkey.GenerateRandomRSAKeyPair(2048) + if err != nil { + return + } + + signKey, _, err := signingkey.GenerateRandomEd25519KeyPair() + if err != nil { + return + } + ident, err := signKey.GetPublic().Raw() + if err != nil { + return + } + s.acc = &account.AccountData{ + Identity: ident, + SignKey: signKey, + EncKey: encKey, + } + return nil +} + +func (s *AccountTestService) Name() (name string) { + return accountService.CName +} + +func (s *AccountTestService) Account() *account.AccountData { + return s.acc +} diff --git a/util/cid/cid.go b/common/util/cid/cid.go similarity index 100% rename from util/cid/cid.go rename to common/util/cid/cid.go diff --git a/util/keys/asymmetric/encryptionkey/encryptionkey.go b/common/util/keys/asymmetric/encryptionkey/encryptionkey.go similarity index 67% rename from util/keys/asymmetric/encryptionkey/encryptionkey.go rename to common/util/keys/asymmetric/encryptionkey/encryptionkey.go index 970fcfdd..76e2f21f 100644 --- a/util/keys/asymmetric/encryptionkey/encryptionkey.go +++ b/common/util/keys/asymmetric/encryptionkey/encryptionkey.go @@ -1,6 +1,8 @@ package encryptionkey -import "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys" +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys" +) type PrivKey interface { keys.Key diff --git a/util/keys/asymmetric/encryptionkey/rsa.go b/common/util/keys/asymmetric/encryptionkey/rsa.go similarity index 90% rename from util/keys/asymmetric/encryptionkey/rsa.go rename to common/util/keys/asymmetric/encryptionkey/rsa.go index 4e70091a..a1afc2bb 100644 --- a/util/keys/asymmetric/encryptionkey/rsa.go +++ b/common/util/keys/asymmetric/encryptionkey/rsa.go @@ -7,7 +7,7 @@ import ( "crypto/subtle" "crypto/x509" "errors" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys" "io" ) @@ -107,14 +107,6 @@ func NewEncryptionRsaPubKeyFromBytes(bytes []byte) (PubKey, error) { return &EncryptionRsaPubKey{pubKey: *pk}, nil } -func NewRSAPrivKeyDecoder() keys.Decoder { - return keys.NewKeyDecoder(NewEncryptionRsaPrivKeyFromBytes) -} - -func NewRSAPubKeyDecoder() keys.Decoder { - return keys.NewKeyDecoder(NewEncryptionRsaPubKeyFromBytes) -} - func keyEquals(k1, k2 keys.Key) bool { a, err := k1.Raw() if err != nil { diff --git a/util/keys/asymmetric/signingkey/ed25519.go b/common/util/keys/asymmetric/signingkey/ed25519.go similarity index 75% rename from util/keys/asymmetric/signingkey/ed25519.go rename to common/util/keys/asymmetric/signingkey/ed25519.go index 90763e67..3df2cd3d 100644 --- a/util/keys/asymmetric/signingkey/ed25519.go +++ b/common/util/keys/asymmetric/signingkey/ed25519.go @@ -7,10 +7,8 @@ import ( "crypto/subtle" "errors" "fmt" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys" "io" - - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/strkey" ) // Ed25519PrivateKey is an ed25519 private key. @@ -147,43 +145,3 @@ func UnmarshalEd25519PrivateKey(data []byte) (PrivKey, error) { k: ed25519.PrivateKey(data), }, nil } - -// TODO: remove this one in favor of new one -type Ed25519SigningPubKeyDecoder struct{} - -func NewEd25519PubKeyDecoder() PubKeyDecoder { - return &Ed25519SigningPubKeyDecoder{} -} - -func (e *Ed25519SigningPubKeyDecoder) DecodeFromBytes(bytes []byte) (PubKey, error) { - return NewSigningEd25519PubKeyFromBytes(bytes) -} - -func (e *Ed25519SigningPubKeyDecoder) DecodeFromString(identity string) (PubKey, error) { - pubKeyRaw, err := strkey.Decode(0x5b, identity) - if err != nil { - return nil, err - } - - return e.DecodeFromBytes(pubKeyRaw) -} - -func (e *Ed25519SigningPubKeyDecoder) DecodeFromStringIntoBytes(identity string) ([]byte, error) { - return strkey.Decode(0x5b, identity) -} - -func (e *Ed25519SigningPubKeyDecoder) EncodeToString(pubkey PubKey) (string, error) { - raw, err := pubkey.Raw() - if err != nil { - return "", err - } - return strkey.Encode(0x5b, raw) -} - -func NewEDPrivKeyDecoder() keys.Decoder { - return keys.NewKeyDecoder(NewSigningEd25519PrivKeyFromBytes) -} - -func NewEDPubKeyDecoder() keys.Decoder { - return keys.NewKeyDecoder(NewSigningEd25519PubKeyFromBytes) -} diff --git a/common/util/keys/asymmetric/signingkey/signingkey.go b/common/util/keys/asymmetric/signingkey/signingkey.go new file mode 100644 index 00000000..c5d09011 --- /dev/null +++ b/common/util/keys/asymmetric/signingkey/signingkey.go @@ -0,0 +1,19 @@ +package signingkey + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys" +) + +type PrivKey interface { + keys.Key + + Sign([]byte) ([]byte, error) + + GetPublic() PubKey +} + +type PubKey interface { + keys.Key + + Verify(data []byte, sig []byte) (bool, error) +} diff --git a/common/util/keys/decode.go b/common/util/keys/decode.go new file mode 100644 index 00000000..c08e7c41 --- /dev/null +++ b/common/util/keys/decode.go @@ -0,0 +1,30 @@ +package keys + +import ( + "encoding/base64" +) + +func EncodeKeyToString[T Key](key T) (str string, err error) { + raw, err := key.Raw() + if err != nil { + return + } + str = EncodeBytesToString(raw) + return +} + +func EncodeBytesToString(bytes []byte) string { + return base64.StdEncoding.EncodeToString(bytes) +} + +func DecodeKeyFromString[T Key](str string, construct func([]byte) (T, error), def T) (T, error) { + dec, err := DecodeBytesFromString(str) + if err != nil { + return def, err + } + return construct(dec) +} + +func DecodeBytesFromString(str string) (bytes []byte, err error) { + return base64.StdEncoding.DecodeString(str) +} diff --git a/util/keys/key.go b/common/util/keys/key.go similarity index 57% rename from util/keys/key.go rename to common/util/keys/key.go index 2170fac8..150d0897 100644 --- a/util/keys/key.go +++ b/common/util/keys/key.go @@ -8,13 +8,6 @@ type Key interface { Raw() ([]byte, error) } -type Decoder interface { - DecodeFromBytes(bytes []byte) (Key, error) - DecodeFromString(identity string) (Key, error) - DecodeFromStringIntoBytes(identity string) ([]byte, error) - EncodeToString(key Key) (string, error) -} - func KeyEquals(k1, k2 Key) bool { a, err := k1.Raw() if err != nil { diff --git a/util/keys/symmetric/symmetric.go b/common/util/keys/symmetric/symmetric.go similarity index 94% rename from util/keys/symmetric/symmetric.go rename to common/util/keys/symmetric/symmetric.go index 22648769..711f1fdd 100644 --- a/util/keys/symmetric/symmetric.go +++ b/common/util/keys/symmetric/symmetric.go @@ -5,6 +5,7 @@ import ( "crypto/cipher" "crypto/rand" "fmt" + "github.com/minio/sha256-simd" mbase "github.com/multiformats/go-multibase" ) @@ -21,6 +22,12 @@ type Key struct { raw []byte } +func DeriveFromBytes(bytes []byte) (*Key, error) { + bArray := sha256.Sum256(bytes) + bSlice := bArray[:] + return FromBytes(bSlice) +} + func (k *Key) Equals(otherKey *Key) bool { otherRaw := otherKey.raw keyRaw := k.raw diff --git a/util/peer/peer.go b/common/util/peer/peer.go similarity index 62% rename from util/peer/peer.go rename to common/util/peer/peer.go index dfa03282..32ea21ee 100644 --- a/util/peer/peer.go +++ b/common/util/peer/peer.go @@ -1,9 +1,9 @@ package peer import ( - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/signingkey" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" ) func IDFromSigningPubKey(pubKey signingkey.PubKey) (peer.ID, error) { diff --git a/util/slice/slice.go b/common/util/slice/slice.go similarity index 100% rename from util/slice/slice.go rename to common/util/slice/slice.go diff --git a/config/nodes.go b/config/nodes.go deleted file mode 100644 index 932a76a9..00000000 --- a/config/nodes.go +++ /dev/null @@ -1,8 +0,0 @@ -package config - -type Node struct { - PeerId string `yaml:"peerId"` - Address string `yaml:"address"` - SigningKey string `yaml:"signingKey"` - EncryptionKey string `yaml:"encryptionKey"` -} diff --git a/config/space.go b/config/space.go deleted file mode 100644 index 4de7cde0..00000000 --- a/config/space.go +++ /dev/null @@ -1,6 +0,0 @@ -package config - -type Space struct { - GCTTL int `json:"gcTTL"` - SyncPeriod int `json:"syncPeriod"` -} diff --git a/consensus/Makefile b/consensus/Makefile new file mode 100644 index 00000000..f48adb7e --- /dev/null +++ b/consensus/Makefile @@ -0,0 +1,12 @@ +.PHONY: proto build test +export GOPRIVATE=github.com/anytypeio + +proto: + protoc --gogofaster_out=:. --go-drpc_out=protolib=github.com/gogo/protobuf:. consensusproto/protos/*.proto + +build: + @$(eval FLAGS := $$(shell govvv -flags -pkg github.com/anytypeio/go-anytype-infrastructure-experiments/consensus)) + go build -v -o ../bin/consensus-node -ldflags "$(FLAGS)" github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/cmd + +test: + go test ./... --cover \ No newline at end of file diff --git a/consensus/account/service.go b/consensus/account/service.go new file mode 100644 index 00000000..6f81b4fe --- /dev/null +++ b/consensus/account/service.go @@ -0,0 +1,62 @@ +package account + +import ( + commonaccount "github.com/anytypeio/go-anytype-infrastructure-experiments/common/account" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/config" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/account" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/encryptionkey" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/signingkey" +) + +type service struct { + accountData *account.AccountData + peerId string +} + +func (s *service) Account() *account.AccountData { + return s.accountData +} + +func New() app.Component { + return &service{} +} + +func (s *service) Init(a *app.App) (err error) { + acc := a.MustComponent(config.CName).(commonaccount.ConfigGetter).GetAccount() + + decodedEncryptionKey, err := keys.DecodeKeyFromString( + acc.EncryptionKey, + encryptionkey.NewEncryptionRsaPrivKeyFromBytes, + nil) + if err != nil { + return err + } + + decodedSigningKey, err := keys.DecodeKeyFromString( + acc.SigningKey, + signingkey.NewSigningEd25519PrivKeyFromBytes, + nil) + if err != nil { + return err + } + + identity, err := decodedSigningKey.GetPublic().Raw() + if err != nil { + return err + } + + s.accountData = &account.AccountData{ + Identity: identity, + SignKey: decodedSigningKey, + EncKey: decodedEncryptionKey, + } + s.peerId = acc.PeerId + + return nil +} + +func (s *service) Name() (name string) { + return commonaccount.CName +} diff --git a/consensus/cmd/consensusnode.go b/consensus/cmd/consensusnode.go new file mode 100644 index 00000000..136f2af9 --- /dev/null +++ b/consensus/cmd/consensusnode.go @@ -0,0 +1,97 @@ +package main + +import ( + "context" + "flag" + "fmt" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/metric" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/rpc/server" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/secure" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/account" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/config" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusrpc" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/db" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/stream" + "go.uber.org/zap" + "net/http" + _ "net/http/pprof" + "os" + "os/signal" + "syscall" + "time" +) + +var log = logger.NewNamed("main") + +var ( + flagConfigFile = flag.String("c", "etc/consensus-config.yml", "path to config file") + flagVersion = flag.Bool("v", false, "show version and exit") + flagHelp = flag.Bool("h", false, "show help and exit") +) + +func main() { + flag.Parse() + + if *flagVersion { + fmt.Println(app.VersionDescription()) + return + } + if *flagHelp { + flag.PrintDefaults() + return + } + + if debug, ok := os.LookupEnv("ANYPROF"); ok && debug != "" { + go func() { + http.ListenAndServe(debug, nil) + }() + } + + // create app + ctx := context.Background() + a := new(app.App) + + // open config file + conf, err := config.NewFromFile(*flagConfigFile) + if err != nil { + log.Fatal("can't open config file", zap.Error(err)) + } + conf.Log.ApplyGlobal() + // bootstrap components + a.Register(conf) + Bootstrap(a) + + // start app + if err := a.Start(ctx); err != nil { + log.Fatal("can't start app", zap.Error(err)) + } + log.Info("app started", zap.String("version", a.Version())) + + // wait exit signal + exit := make(chan os.Signal, 1) + signal.Notify(exit, os.Interrupt, syscall.SIGKILL, syscall.SIGTERM, syscall.SIGQUIT) + sig := <-exit + log.Info("received exit signal, stop app...", zap.String("signal", fmt.Sprint(sig))) + + // close app + ctx, cancel := context.WithTimeout(ctx, time.Minute) + defer cancel() + if err := a.Close(ctx); err != nil { + log.Fatal("close error", zap.Error(err)) + } else { + log.Info("goodbye!") + } + time.Sleep(time.Second / 3) +} + +func Bootstrap(a *app.App) { + a.Register(metric.New()). + Register(account.New()). + Register(secure.New()). + Register(server.New()). + Register(db.New()). + Register(stream.New()). + Register(consensusrpc.New()) +} diff --git a/consensus/config/config.go b/consensus/config/config.go new file mode 100644 index 00000000..e50d92d5 --- /dev/null +++ b/consensus/config/config.go @@ -0,0 +1,54 @@ +package config + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + config2 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/config" + "gopkg.in/yaml.v3" + "io/ioutil" +) + +const CName = "config" + +func NewFromFile(path string) (c *Config, err error) { + c = &Config{} + data, err := ioutil.ReadFile(path) + if err != nil { + return nil, err + } + if err = yaml.Unmarshal(data, c); err != nil { + return nil, err + } + return +} + +type Config struct { + GrpcServer config2.GrpcServer `yaml:"grpcServer"` + Account config2.Account `yaml:"account"` + Mongo Mongo `yaml:"mongo"` + Metric config2.Metric `yaml:"metric"` + Log config2.Log `yaml:"log"` +} + +func (c *Config) Init(a *app.App) (err error) { + return +} + +func (c Config) Name() (name string) { + return CName +} + +func (c Config) GetMongo() Mongo { + return c.Mongo +} + +func (c Config) GetGRPCServer() config2.GrpcServer { + return c.GrpcServer +} + +func (c Config) GetAccount() config2.Account { + return c.Account +} + +func (c Config) GetMetric() config2.Metric { + return c.Metric +} diff --git a/consensus/config/mongo.go b/consensus/config/mongo.go new file mode 100644 index 00000000..87fb679d --- /dev/null +++ b/consensus/config/mongo.go @@ -0,0 +1,7 @@ +package config + +type Mongo struct { + Connect string `yaml:"connect"` + Database string `yaml:"database"` + LogCollection string `yaml:"logCollection"` +} diff --git a/consensus/consensus.go b/consensus/consensus.go new file mode 100644 index 00000000..02371b1b --- /dev/null +++ b/consensus/consensus.go @@ -0,0 +1,16 @@ +package consensus + +import "time" + +type Log struct { + Id []byte `bson:"_id"` + Records []Record `bson:"records"` + Err error `bson:"-"` +} + +type Record struct { + Id []byte `bson:"id"` + PrevId []byte `bson:"prevId"` + Payload []byte `bson:"payload"` + Created time.Time `bson:"created"'` +} diff --git a/consensus/consensusclient/client.go b/consensus/consensusclient/client.go new file mode 100644 index 00000000..48576dd4 --- /dev/null +++ b/consensus/consensusclient/client.go @@ -0,0 +1,244 @@ +//go:generate mockgen -destination mock_consensusclient/mock_consensusclient.go github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusclient Service +package consensusclient + +import ( + "context" + "errors" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/pool" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/rpc/rpcerr" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto" + _ "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto/consensuserr" + "go.uber.org/zap" + "sync" + "time" +) + +const CName = "consensus.client" + +var log = logger.NewNamed(CName) + +var ( + ErrWatcherExists = errors.New("watcher exists") + ErrWatcherNotExists = errors.New("watcher not exists") +) + +func New() Service { + return new(service) +} + +// Watcher watches new events by specified logId +type Watcher interface { + AddConsensusRecords(recs []*consensusproto.Record) + AddConsensusError(err error) +} + +type Service interface { + // AddLog adds new log to consensus servers + AddLog(ctx context.Context, clog *consensusproto.Log) (err error) + // AddRecord adds new record to consensus servers + AddRecord(ctx context.Context, logId []byte, clog *consensusproto.Record) (err error) + // Watch starts watching to given logId and calls watcher when any relative event received + Watch(logId []byte, w Watcher) (err error) + // UnWatch stops watching given logId and removes watcher + UnWatch(logId []byte) (err error) + app.ComponentRunnable +} + +type service struct { + pool pool.Pool + nodeconf nodeconf.Service + + watchers map[string]Watcher + stream *stream + close chan struct{} + mu sync.Mutex +} + +func (s *service) Init(a *app.App) (err error) { + s.pool = a.MustComponent(pool.CName).(pool.Pool) + s.nodeconf = a.MustComponent(nodeconf.CName).(nodeconf.Service) + s.watchers = make(map[string]Watcher) + s.close = make(chan struct{}) + return nil +} + +func (s *service) Name() (name string) { + return CName +} + +func (s *service) Run(_ context.Context) error { + go s.streamWatcher() + return nil +} + +func (s *service) getClient(ctx context.Context) (consensusproto.DRPCConsensusClient, error) { + peer, err := s.pool.GetOneOf(ctx, s.nodeconf.ConsensusPeers()) + if err != nil { + return nil, err + } + return consensusproto.NewDRPCConsensusClient(peer), nil +} + +func (s *service) dialClient(ctx context.Context) (consensusproto.DRPCConsensusClient, error) { + peer, err := s.pool.DialOneOf(ctx, s.nodeconf.ConsensusPeers()) + if err != nil { + return nil, err + } + return consensusproto.NewDRPCConsensusClient(peer), nil +} + +func (s *service) AddLog(ctx context.Context, clog *consensusproto.Log) (err error) { + cl, err := s.getClient(ctx) + if err != nil { + return + } + if _, err = cl.AddLog(ctx, &consensusproto.AddLogRequest{ + Log: clog, + }); err != nil { + return rpcerr.Unwrap(err) + } + return +} + +func (s *service) AddRecord(ctx context.Context, logId []byte, clog *consensusproto.Record) (err error) { + cl, err := s.getClient(ctx) + if err != nil { + return + } + if _, err = cl.AddRecord(ctx, &consensusproto.AddRecordRequest{ + LogId: logId, + Record: clog, + }); err != nil { + return rpcerr.Unwrap(err) + } + return +} + +func (s *service) Watch(logId []byte, w Watcher) (err error) { + s.mu.Lock() + defer s.mu.Unlock() + if _, ok := s.watchers[string(logId)]; ok { + return ErrWatcherExists + } + s.watchers[string(logId)] = w + if s.stream != nil { + if wErr := s.stream.WatchIds([][]byte{logId}); wErr != nil { + log.Warn("WatchIds error", zap.Error(wErr)) + } + } + return +} + +func (s *service) UnWatch(logId []byte) (err error) { + s.mu.Lock() + defer s.mu.Unlock() + if _, ok := s.watchers[string(logId)]; !ok { + return ErrWatcherNotExists + } + delete(s.watchers, string(logId)) + if s.stream != nil { + if wErr := s.stream.UnwatchIds([][]byte{logId}); wErr != nil { + log.Warn("UnWatchIds error", zap.Error(wErr)) + } + } + return +} + +func (s *service) openStream(ctx context.Context) (st *stream, err error) { + cl, err := s.dialClient(ctx) + if err != nil { + return + } + rpcStream, err := cl.WatchLog(ctx) + if err != nil { + return nil, rpcerr.Unwrap(err) + } + return runStream(rpcStream), nil +} + +func (s *service) streamWatcher() { + var ( + err error + st *stream + i int + ) + for { + // open stream + if st, err = s.openStream(context.Background()); err != nil { + // can't open stream, we will retry until success connection or close + if i < 60 { + i++ + } + sleepTime := time.Second * time.Duration(i) + log.Error("watch log error", zap.Error(err), zap.Duration("waitTime", sleepTime)) + select { + case <-time.After(sleepTime): + continue + case <-s.close: + return + } + } + i = 0 + + // collect ids and setup stream + s.mu.Lock() + var logIds = make([][]byte, 0, len(s.watchers)) + for id := range s.watchers { + logIds = append(logIds, []byte(id)) + } + s.stream = st + s.mu.Unlock() + + // restore subscriptions + if len(logIds) > 0 { + if err = s.stream.WatchIds(logIds); err != nil { + log.Error("watch ids error", zap.Error(err)) + continue + } + } + + // read stream + if err = s.streamReader(); err != nil { + log.Error("stream read error", zap.Error(err)) + continue + } + return + } +} + +func (s *service) streamReader() error { + for { + events := s.stream.WaitLogs() + if len(events) == 0 { + return s.stream.Err() + } + for _, e := range events { + if w, ok := s.watchers[string(e.LogId)]; ok { + if e.Error == nil { + w.AddConsensusRecords(e.Records) + } else { + w.AddConsensusError(rpcerr.Err(uint64(e.Error.Error))) + } + } else { + log.Warn("received unexpected log id", zap.Binary("logId", e.LogId)) + } + } + } +} + +func (s *service) Close(_ context.Context) error { + s.mu.Lock() + if s.stream != nil { + _ = s.stream.Close() + } + s.mu.Unlock() + select { + case <-s.close: + default: + close(s.close) + } + return nil +} diff --git a/consensus/consensusclient/client_test.go b/consensus/consensusclient/client_test.go new file mode 100644 index 00000000..e7557d0d --- /dev/null +++ b/consensus/consensusclient/client_test.go @@ -0,0 +1,230 @@ +package consensusclient + +import ( + "context" + "fmt" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/pool" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/rpc/rpctest" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf/mock_nodeconf" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto/consensuserr" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "sync" + "testing" + "time" +) + +func TestService_Watch(t *testing.T) { + t.Run("not found error", func(t *testing.T) { + fx := newFixture(t).run(t) + defer fx.Finish() + var logId = []byte{'1'} + w := &testWatcher{ready: make(chan struct{})} + require.NoError(t, fx.Watch(logId, w)) + st := fx.testServer.waitStream(t) + req, err := st.Recv() + require.NoError(t, err) + assert.Equal(t, [][]byte{logId}, req.WatchIds) + require.NoError(t, st.Send(&consensusproto.WatchLogEvent{ + LogId: logId, + Error: &consensusproto.Err{ + Error: consensusproto.ErrCodes_ErrorOffset + consensusproto.ErrCodes_LogNotFound, + }, + })) + <-w.ready + assert.Equal(t, consensuserr.ErrLogNotFound, w.err) + fx.testServer.releaseStream <- nil + }) + t.Run("watcherExists error", func(t *testing.T) { + fx := newFixture(t).run(t) + defer fx.Finish() + var logId = []byte{'1'} + w := &testWatcher{} + require.NoError(t, fx.Watch(logId, w)) + require.Error(t, fx.Watch(logId, w)) + st := fx.testServer.waitStream(t) + st.Recv() + fx.testServer.releaseStream <- nil + }) + t.Run("watch", func(t *testing.T) { + fx := newFixture(t).run(t) + defer fx.Finish() + var logId1 = []byte{'1'} + w := &testWatcher{} + require.NoError(t, fx.Watch(logId1, w)) + st := fx.testServer.waitStream(t) + req, err := st.Recv() + require.NoError(t, err) + assert.Equal(t, [][]byte{logId1}, req.WatchIds) + + var logId2 = []byte{'2'} + w = &testWatcher{} + require.NoError(t, fx.Watch(logId2, w)) + req, err = st.Recv() + require.NoError(t, err) + assert.Equal(t, [][]byte{logId2}, req.WatchIds) + + fx.testServer.releaseStream <- nil + }) +} + +func TestService_UnWatch(t *testing.T) { + t.Run("no watcher", func(t *testing.T) { + fx := newFixture(t).run(t) + defer fx.Finish() + require.Error(t, fx.UnWatch([]byte{'1'})) + }) + t.Run("success", func(t *testing.T) { + fx := newFixture(t).run(t) + defer fx.Finish() + w := &testWatcher{} + require.NoError(t, fx.Watch([]byte{'1'}, w)) + assert.NoError(t, fx.UnWatch([]byte{'1'})) + }) +} + +func TestService_Init(t *testing.T) { + t.Run("reconnect on watch err", func(t *testing.T) { + fx := newFixture(t) + fx.testServer.watchErrOnce = true + fx.run(t) + defer fx.Finish() + fx.testServer.waitStream(t) + fx.testServer.releaseStream <- nil + }) + t.Run("reconnect on start", func(t *testing.T) { + fx := newFixture(t) + fx.a.MustComponent(pool.CName).(*rpctest.TestPool).WithServer(nil) + fx.run(t) + defer fx.Finish() + time.Sleep(time.Millisecond * 50) + fx.a.MustComponent(pool.CName).(*rpctest.TestPool).WithServer(fx.drpcTS) + fx.testServer.waitStream(t) + fx.testServer.releaseStream <- nil + }) +} + +func TestService_AddLog(t *testing.T) { + fx := newFixture(t).run(t) + defer fx.Finish() + assert.NoError(t, fx.AddLog(ctx, &consensusproto.Log{})) +} + +func TestService_AddRecord(t *testing.T) { + fx := newFixture(t).run(t) + defer fx.Finish() + assert.NoError(t, fx.AddRecord(ctx, []byte{'1'}, &consensusproto.Record{})) +} + +var ctx = context.Background() + +func newFixture(t *testing.T) *fixture { + fx := &fixture{ + Service: New(), + a: &app.App{}, + ctrl: gomock.NewController(t), + testServer: &testServer{ + stream: make(chan consensusproto.DRPCConsensus_WatchLogStream), + releaseStream: make(chan error), + }, + } + fx.nodeconf = mock_nodeconf.NewMockService(fx.ctrl) + fx.nodeconf.EXPECT().Init(gomock.Any()) + fx.nodeconf.EXPECT().Name().Return(nodeconf.CName).AnyTimes() + fx.nodeconf.EXPECT().ConsensusPeers().Return([]string{"c1", "c2"}).AnyTimes() + fx.drpcTS = rpctest.NewTestServer() + require.NoError(t, consensusproto.DRPCRegisterConsensus(fx.drpcTS.Mux, fx.testServer)) + fx.a.Register(fx.Service). + Register(fx.nodeconf). + Register(rpctest.NewTestPool().WithServer(fx.drpcTS)) + return fx +} + +type fixture struct { + Service + nodeconf *mock_nodeconf.MockService + a *app.App + ctrl *gomock.Controller + testServer *testServer + drpcTS *rpctest.TesServer +} + +func (fx *fixture) run(t *testing.T) *fixture { + require.NoError(t, fx.a.Start(ctx)) + return fx +} + +func (fx *fixture) Finish() { + assert.NoError(fx.ctrl.T, fx.a.Close(ctx)) + fx.ctrl.Finish() +} + +type testServer struct { + stream chan consensusproto.DRPCConsensus_WatchLogStream + addLog func(ctx context.Context, req *consensusproto.AddLogRequest) error + addRecord func(ctx context.Context, req *consensusproto.AddRecordRequest) error + releaseStream chan error + watchErrOnce bool +} + +func (t *testServer) AddLog(ctx context.Context, req *consensusproto.AddLogRequest) (*consensusproto.Ok, error) { + if t.addLog != nil { + if err := t.addLog(ctx, req); err != nil { + return nil, err + } + } + return &consensusproto.Ok{}, nil +} + +func (t *testServer) AddRecord(ctx context.Context, req *consensusproto.AddRecordRequest) (*consensusproto.Ok, error) { + if t.addRecord != nil { + if err := t.addRecord(ctx, req); err != nil { + return nil, err + } + } + return &consensusproto.Ok{}, nil +} + +func (t *testServer) WatchLog(stream consensusproto.DRPCConsensus_WatchLogStream) error { + if t.watchErrOnce { + t.watchErrOnce = false + return fmt.Errorf("error") + } + t.stream <- stream + return <-t.releaseStream +} + +func (t *testServer) waitStream(test *testing.T) consensusproto.DRPCConsensus_WatchLogStream { + select { + case <-time.After(time.Second * 5): + test.Fatalf("waiteStream timeout") + case st := <-t.stream: + return st + } + return nil +} + +type testWatcher struct { + recs [][]*consensusproto.Record + err error + ready chan struct{} + once sync.Once +} + +func (t *testWatcher) AddConsensusRecords(recs []*consensusproto.Record) { + t.recs = append(t.recs, recs) + t.once.Do(func() { + close(t.ready) + }) +} + +func (t *testWatcher) AddConsensusError(err error) { + t.err = err + t.once.Do(func() { + close(t.ready) + }) +} diff --git a/consensus/consensusclient/mock_consensusclient/mock_consensusclient.go b/consensus/consensusclient/mock_consensusclient/mock_consensusclient.go new file mode 100644 index 00000000..356cb927 --- /dev/null +++ b/consensus/consensusclient/mock_consensusclient/mock_consensusclient.go @@ -0,0 +1,150 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusclient (interfaces: Service) + +// Package mock_consensusclient is a generated GoMock package. +package mock_consensusclient + +import ( + context "context" + reflect "reflect" + + app "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + consensusclient "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusclient" + consensusproto "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto" + gomock "github.com/golang/mock/gomock" +) + +// MockService is a mock of Service interface. +type MockService struct { + ctrl *gomock.Controller + recorder *MockServiceMockRecorder +} + +// MockServiceMockRecorder is the mock recorder for MockService. +type MockServiceMockRecorder struct { + mock *MockService +} + +// NewMockService creates a new mock instance. +func NewMockService(ctrl *gomock.Controller) *MockService { + mock := &MockService{ctrl: ctrl} + mock.recorder = &MockServiceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockService) EXPECT() *MockServiceMockRecorder { + return m.recorder +} + +// AddLog mocks base method. +func (m *MockService) AddLog(arg0 context.Context, arg1 *consensusproto.Log) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AddLog", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// AddLog indicates an expected call of AddLog. +func (mr *MockServiceMockRecorder) AddLog(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddLog", reflect.TypeOf((*MockService)(nil).AddLog), arg0, arg1) +} + +// AddRecord mocks base method. +func (m *MockService) AddRecord(arg0 context.Context, arg1 []byte, arg2 *consensusproto.Record) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AddRecord", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// AddRecord indicates an expected call of AddRecord. +func (mr *MockServiceMockRecorder) AddRecord(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRecord", reflect.TypeOf((*MockService)(nil).AddRecord), arg0, arg1, arg2) +} + +// Close mocks base method. +func (m *MockService) Close(arg0 context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Close", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Close indicates an expected call of Close. +func (mr *MockServiceMockRecorder) Close(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockService)(nil).Close), arg0) +} + +// Init mocks base method. +func (m *MockService) Init(arg0 *app.App) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Init", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Init indicates an expected call of Init. +func (mr *MockServiceMockRecorder) Init(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockService)(nil).Init), arg0) +} + +// Name mocks base method. +func (m *MockService) Name() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Name") + ret0, _ := ret[0].(string) + return ret0 +} + +// Name indicates an expected call of Name. +func (mr *MockServiceMockRecorder) Name() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockService)(nil).Name)) +} + +// Run mocks base method. +func (m *MockService) Run(arg0 context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Run", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Run indicates an expected call of Run. +func (mr *MockServiceMockRecorder) Run(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockService)(nil).Run), arg0) +} + +// UnWatch mocks base method. +func (m *MockService) UnWatch(arg0 []byte) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UnWatch", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// UnWatch indicates an expected call of UnWatch. +func (mr *MockServiceMockRecorder) UnWatch(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnWatch", reflect.TypeOf((*MockService)(nil).UnWatch), arg0) +} + +// Watch mocks base method. +func (m *MockService) Watch(arg0 []byte, arg1 consensusclient.Watcher) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Watch", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// Watch indicates an expected call of Watch. +func (mr *MockServiceMockRecorder) Watch(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Watch", reflect.TypeOf((*MockService)(nil).Watch), arg0, arg1) +} diff --git a/consensus/consensusclient/stream.go b/consensus/consensusclient/stream.go new file mode 100644 index 00000000..d2865326 --- /dev/null +++ b/consensus/consensusclient/stream.go @@ -0,0 +1,68 @@ +package consensusclient + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto" + "github.com/cheggaaa/mb/v2" + "sync" +) + +func runStream(rpcStream consensusproto.DRPCConsensus_WatchLogClient) *stream { + st := &stream{ + rpcStream: rpcStream, + mb: mb.New((*consensusproto.WatchLogEvent)(nil), 100), + } + go st.readStream() + return st +} + +type stream struct { + rpcStream consensusproto.DRPCConsensus_WatchLogClient + mb *mb.MB[*consensusproto.WatchLogEvent] + mu sync.Mutex + err error +} + +func (s *stream) WatchIds(logIds [][]byte) (err error) { + return s.rpcStream.Send(&consensusproto.WatchLogRequest{ + WatchIds: logIds, + }) +} + +func (s *stream) UnwatchIds(logIds [][]byte) (err error) { + return s.rpcStream.Send(&consensusproto.WatchLogRequest{ + UnwatchIds: logIds, + }) +} + +func (s *stream) WaitLogs() []*consensusproto.WatchLogEvent { + return s.mb.Wait() +} + +func (s *stream) Err() error { + s.mu.Lock() + defer s.mu.Unlock() + return s.err +} + +func (s *stream) readStream() { + defer s.Close() + for { + event, err := s.rpcStream.Recv() + if err != nil { + s.mu.Lock() + s.err = err + s.mu.Unlock() + return + } + if err = s.mb.Add(event); err != nil { + return + } + } +} + +func (s *stream) Close() error { + if err := s.mb.Close(); err == nil { + return s.rpcStream.Close() + } + return nil +} diff --git a/consensus/consensusproto/consensus.pb.go b/consensus/consensusproto/consensus.pb.go new file mode 100644 index 00000000..be7fc173 --- /dev/null +++ b/consensus/consensusproto/consensus.pb.go @@ -0,0 +1,1957 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: consensusproto/protos/consensus.proto + +package consensusproto + +import ( + fmt "fmt" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type ErrCodes int32 + +const ( + ErrCodes_Unexpected ErrCodes = 0 + ErrCodes_LogExists ErrCodes = 1 + ErrCodes_LogNotFound ErrCodes = 2 + ErrCodes_RecordConflict ErrCodes = 3 + ErrCodes_ErrorOffset ErrCodes = 300 +) + +var ErrCodes_name = map[int32]string{ + 0: "Unexpected", + 1: "LogExists", + 2: "LogNotFound", + 3: "RecordConflict", + 300: "ErrorOffset", +} + +var ErrCodes_value = map[string]int32{ + "Unexpected": 0, + "LogExists": 1, + "LogNotFound": 2, + "RecordConflict": 3, + "ErrorOffset": 300, +} + +func (x ErrCodes) String() string { + return proto.EnumName(ErrCodes_name, int32(x)) +} + +func (ErrCodes) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_6b92aaf7feaf5a54, []int{0} +} + +type Log struct { + Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Records []*Record `protobuf:"bytes,2,rep,name=records,proto3" json:"records,omitempty"` +} + +func (m *Log) Reset() { *m = Log{} } +func (m *Log) String() string { return proto.CompactTextString(m) } +func (*Log) ProtoMessage() {} +func (*Log) Descriptor() ([]byte, []int) { + return fileDescriptor_6b92aaf7feaf5a54, []int{0} +} +func (m *Log) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Log) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Log.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Log) XXX_Merge(src proto.Message) { + xxx_messageInfo_Log.Merge(m, src) +} +func (m *Log) XXX_Size() int { + return m.Size() +} +func (m *Log) XXX_DiscardUnknown() { + xxx_messageInfo_Log.DiscardUnknown(m) +} + +var xxx_messageInfo_Log proto.InternalMessageInfo + +func (m *Log) GetId() []byte { + if m != nil { + return m.Id + } + return nil +} + +func (m *Log) GetRecords() []*Record { + if m != nil { + return m.Records + } + return nil +} + +type Record struct { + Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + PrevId []byte `protobuf:"bytes,2,opt,name=prevId,proto3" json:"prevId,omitempty"` + Payload []byte `protobuf:"bytes,3,opt,name=payload,proto3" json:"payload,omitempty"` + CreatedUnix uint64 `protobuf:"varint,4,opt,name=createdUnix,proto3" json:"createdUnix,omitempty"` +} + +func (m *Record) Reset() { *m = Record{} } +func (m *Record) String() string { return proto.CompactTextString(m) } +func (*Record) ProtoMessage() {} +func (*Record) Descriptor() ([]byte, []int) { + return fileDescriptor_6b92aaf7feaf5a54, []int{1} +} +func (m *Record) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Record) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Record.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Record) XXX_Merge(src proto.Message) { + xxx_messageInfo_Record.Merge(m, src) +} +func (m *Record) XXX_Size() int { + return m.Size() +} +func (m *Record) XXX_DiscardUnknown() { + xxx_messageInfo_Record.DiscardUnknown(m) +} + +var xxx_messageInfo_Record proto.InternalMessageInfo + +func (m *Record) GetId() []byte { + if m != nil { + return m.Id + } + return nil +} + +func (m *Record) GetPrevId() []byte { + if m != nil { + return m.PrevId + } + return nil +} + +func (m *Record) GetPayload() []byte { + if m != nil { + return m.Payload + } + return nil +} + +func (m *Record) GetCreatedUnix() uint64 { + if m != nil { + return m.CreatedUnix + } + return 0 +} + +type Ok struct { +} + +func (m *Ok) Reset() { *m = Ok{} } +func (m *Ok) String() string { return proto.CompactTextString(m) } +func (*Ok) ProtoMessage() {} +func (*Ok) Descriptor() ([]byte, []int) { + return fileDescriptor_6b92aaf7feaf5a54, []int{2} +} +func (m *Ok) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Ok) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Ok.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Ok) XXX_Merge(src proto.Message) { + xxx_messageInfo_Ok.Merge(m, src) +} +func (m *Ok) XXX_Size() int { + return m.Size() +} +func (m *Ok) XXX_DiscardUnknown() { + xxx_messageInfo_Ok.DiscardUnknown(m) +} + +var xxx_messageInfo_Ok proto.InternalMessageInfo + +type AddLogRequest struct { + Log *Log `protobuf:"bytes,1,opt,name=log,proto3" json:"log,omitempty"` +} + +func (m *AddLogRequest) Reset() { *m = AddLogRequest{} } +func (m *AddLogRequest) String() string { return proto.CompactTextString(m) } +func (*AddLogRequest) ProtoMessage() {} +func (*AddLogRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_6b92aaf7feaf5a54, []int{3} +} +func (m *AddLogRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AddLogRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AddLogRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *AddLogRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_AddLogRequest.Merge(m, src) +} +func (m *AddLogRequest) XXX_Size() int { + return m.Size() +} +func (m *AddLogRequest) XXX_DiscardUnknown() { + xxx_messageInfo_AddLogRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_AddLogRequest proto.InternalMessageInfo + +func (m *AddLogRequest) GetLog() *Log { + if m != nil { + return m.Log + } + return nil +} + +type AddRecordRequest struct { + LogId []byte `protobuf:"bytes,1,opt,name=logId,proto3" json:"logId,omitempty"` + Record *Record `protobuf:"bytes,2,opt,name=record,proto3" json:"record,omitempty"` +} + +func (m *AddRecordRequest) Reset() { *m = AddRecordRequest{} } +func (m *AddRecordRequest) String() string { return proto.CompactTextString(m) } +func (*AddRecordRequest) ProtoMessage() {} +func (*AddRecordRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_6b92aaf7feaf5a54, []int{4} +} +func (m *AddRecordRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AddRecordRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AddRecordRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *AddRecordRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_AddRecordRequest.Merge(m, src) +} +func (m *AddRecordRequest) XXX_Size() int { + return m.Size() +} +func (m *AddRecordRequest) XXX_DiscardUnknown() { + xxx_messageInfo_AddRecordRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_AddRecordRequest proto.InternalMessageInfo + +func (m *AddRecordRequest) GetLogId() []byte { + if m != nil { + return m.LogId + } + return nil +} + +func (m *AddRecordRequest) GetRecord() *Record { + if m != nil { + return m.Record + } + return nil +} + +type WatchLogRequest struct { + WatchIds [][]byte `protobuf:"bytes,1,rep,name=watchIds,proto3" json:"watchIds,omitempty"` + UnwatchIds [][]byte `protobuf:"bytes,2,rep,name=unwatchIds,proto3" json:"unwatchIds,omitempty"` +} + +func (m *WatchLogRequest) Reset() { *m = WatchLogRequest{} } +func (m *WatchLogRequest) String() string { return proto.CompactTextString(m) } +func (*WatchLogRequest) ProtoMessage() {} +func (*WatchLogRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_6b92aaf7feaf5a54, []int{5} +} +func (m *WatchLogRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *WatchLogRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_WatchLogRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *WatchLogRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_WatchLogRequest.Merge(m, src) +} +func (m *WatchLogRequest) XXX_Size() int { + return m.Size() +} +func (m *WatchLogRequest) XXX_DiscardUnknown() { + xxx_messageInfo_WatchLogRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_WatchLogRequest proto.InternalMessageInfo + +func (m *WatchLogRequest) GetWatchIds() [][]byte { + if m != nil { + return m.WatchIds + } + return nil +} + +func (m *WatchLogRequest) GetUnwatchIds() [][]byte { + if m != nil { + return m.UnwatchIds + } + return nil +} + +type WatchLogEvent struct { + LogId []byte `protobuf:"bytes,1,opt,name=logId,proto3" json:"logId,omitempty"` + Records []*Record `protobuf:"bytes,2,rep,name=records,proto3" json:"records,omitempty"` + Error *Err `protobuf:"bytes,3,opt,name=error,proto3" json:"error,omitempty"` +} + +func (m *WatchLogEvent) Reset() { *m = WatchLogEvent{} } +func (m *WatchLogEvent) String() string { return proto.CompactTextString(m) } +func (*WatchLogEvent) ProtoMessage() {} +func (*WatchLogEvent) Descriptor() ([]byte, []int) { + return fileDescriptor_6b92aaf7feaf5a54, []int{6} +} +func (m *WatchLogEvent) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *WatchLogEvent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_WatchLogEvent.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *WatchLogEvent) XXX_Merge(src proto.Message) { + xxx_messageInfo_WatchLogEvent.Merge(m, src) +} +func (m *WatchLogEvent) XXX_Size() int { + return m.Size() +} +func (m *WatchLogEvent) XXX_DiscardUnknown() { + xxx_messageInfo_WatchLogEvent.DiscardUnknown(m) +} + +var xxx_messageInfo_WatchLogEvent proto.InternalMessageInfo + +func (m *WatchLogEvent) GetLogId() []byte { + if m != nil { + return m.LogId + } + return nil +} + +func (m *WatchLogEvent) GetRecords() []*Record { + if m != nil { + return m.Records + } + return nil +} + +func (m *WatchLogEvent) GetError() *Err { + if m != nil { + return m.Error + } + return nil +} + +type Err struct { + Error ErrCodes `protobuf:"varint,1,opt,name=error,proto3,enum=anyConsensus.ErrCodes" json:"error,omitempty"` +} + +func (m *Err) Reset() { *m = Err{} } +func (m *Err) String() string { return proto.CompactTextString(m) } +func (*Err) ProtoMessage() {} +func (*Err) Descriptor() ([]byte, []int) { + return fileDescriptor_6b92aaf7feaf5a54, []int{7} +} +func (m *Err) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Err) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Err.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Err) XXX_Merge(src proto.Message) { + xxx_messageInfo_Err.Merge(m, src) +} +func (m *Err) XXX_Size() int { + return m.Size() +} +func (m *Err) XXX_DiscardUnknown() { + xxx_messageInfo_Err.DiscardUnknown(m) +} + +var xxx_messageInfo_Err proto.InternalMessageInfo + +func (m *Err) GetError() ErrCodes { + if m != nil { + return m.Error + } + return ErrCodes_Unexpected +} + +func init() { + proto.RegisterEnum("anyConsensus.ErrCodes", ErrCodes_name, ErrCodes_value) + proto.RegisterType((*Log)(nil), "anyConsensus.Log") + proto.RegisterType((*Record)(nil), "anyConsensus.Record") + proto.RegisterType((*Ok)(nil), "anyConsensus.Ok") + proto.RegisterType((*AddLogRequest)(nil), "anyConsensus.AddLogRequest") + proto.RegisterType((*AddRecordRequest)(nil), "anyConsensus.AddRecordRequest") + proto.RegisterType((*WatchLogRequest)(nil), "anyConsensus.WatchLogRequest") + proto.RegisterType((*WatchLogEvent)(nil), "anyConsensus.WatchLogEvent") + proto.RegisterType((*Err)(nil), "anyConsensus.Err") +} + +func init() { + proto.RegisterFile("consensusproto/protos/consensus.proto", fileDescriptor_6b92aaf7feaf5a54) +} + +var fileDescriptor_6b92aaf7feaf5a54 = []byte{ + // 509 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x53, 0xcd, 0x8a, 0xd3, 0x50, + 0x14, 0xee, 0x4d, 0x3a, 0x9d, 0xf6, 0xf4, 0x2f, 0x1e, 0x86, 0x21, 0x74, 0x30, 0x94, 0x88, 0x58, + 0x65, 0x68, 0xa5, 0x23, 0xb8, 0x72, 0x31, 0x96, 0x0a, 0x95, 0x6a, 0x21, 0x30, 0x0a, 0xae, 0xac, + 0xb9, 0xb7, 0x31, 0x4c, 0xc8, 0xad, 0xf7, 0xa6, 0x63, 0x67, 0xe3, 0x33, 0xf8, 0x20, 0x3e, 0x88, + 0x3b, 0x67, 0xe9, 0x52, 0xda, 0x17, 0x91, 0xdc, 0xfc, 0xd0, 0xd8, 0x99, 0x85, 0x9b, 0x96, 0xf3, + 0x7d, 0xe7, 0xe7, 0xbb, 0xe7, 0x7c, 0x81, 0x87, 0x2e, 0x0f, 0x25, 0x0b, 0xe5, 0x4a, 0x2e, 0x05, + 0x8f, 0xf8, 0x40, 0xfd, 0xca, 0x41, 0x8e, 0xf6, 0x15, 0x80, 0x8d, 0x79, 0x78, 0x3d, 0xca, 0x30, + 0x7b, 0x0c, 0xfa, 0x94, 0x7b, 0xd8, 0x02, 0xcd, 0xa7, 0x26, 0xe9, 0x92, 0x5e, 0xc3, 0xd1, 0x7c, + 0x8a, 0x7d, 0x38, 0x14, 0xcc, 0xe5, 0x82, 0x4a, 0x53, 0xeb, 0xea, 0xbd, 0xfa, 0xf0, 0xa8, 0xbf, + 0x5b, 0xd6, 0x77, 0x14, 0xe9, 0x64, 0x49, 0x76, 0x00, 0x95, 0x04, 0xda, 0xeb, 0x74, 0x0c, 0x95, + 0xa5, 0x60, 0x57, 0x13, 0x6a, 0x6a, 0x0a, 0x4b, 0x23, 0x34, 0xe1, 0x70, 0x39, 0xbf, 0x0e, 0xf8, + 0x9c, 0x9a, 0xba, 0x22, 0xb2, 0x10, 0xbb, 0x50, 0x77, 0x05, 0x9b, 0x47, 0x8c, 0x5e, 0x84, 0xfe, + 0xda, 0x2c, 0x77, 0x49, 0xaf, 0xec, 0xec, 0x42, 0x76, 0x19, 0xb4, 0xd9, 0xa5, 0xfd, 0x0c, 0x9a, + 0xe7, 0x94, 0x4e, 0xb9, 0xe7, 0xb0, 0x2f, 0x2b, 0x26, 0x23, 0x7c, 0x00, 0x7a, 0xc0, 0x3d, 0x35, + 0xbb, 0x3e, 0xbc, 0x57, 0x14, 0x1c, 0xa7, 0xc5, 0xac, 0xfd, 0x0e, 0x8c, 0x73, 0x4a, 0x53, 0xfd, + 0x69, 0xe1, 0x11, 0x1c, 0x04, 0xdc, 0x9b, 0x64, 0xb2, 0x93, 0x00, 0x4f, 0xa1, 0x92, 0x3c, 0x4f, + 0x29, 0xbf, 0x6b, 0x05, 0x69, 0x8e, 0xfd, 0x06, 0xda, 0xef, 0xe7, 0x91, 0xfb, 0x79, 0x47, 0x4f, + 0x07, 0xaa, 0x5f, 0x63, 0x68, 0x42, 0xa5, 0x49, 0xba, 0x7a, 0xaf, 0xe1, 0xe4, 0x31, 0x5a, 0x00, + 0xab, 0x30, 0x67, 0x35, 0xc5, 0xee, 0x20, 0xf6, 0x37, 0x68, 0x66, 0xed, 0xc6, 0x57, 0x2c, 0xbc, + 0x4b, 0xe3, 0x7f, 0xde, 0x09, 0x1f, 0xc1, 0x01, 0x13, 0x82, 0x0b, 0xb5, 0xf3, 0xbd, 0x25, 0x8d, + 0x85, 0x70, 0x12, 0xde, 0x3e, 0x03, 0x7d, 0x2c, 0x04, 0x9e, 0x66, 0xf9, 0xf1, 0xd4, 0xd6, 0xf0, + 0x78, 0x2f, 0x7f, 0xc4, 0x29, 0x93, 0x69, 0xd1, 0x93, 0x8f, 0x50, 0xcd, 0x20, 0x6c, 0x01, 0x5c, + 0x84, 0x6c, 0xbd, 0x64, 0x6e, 0xc4, 0xa8, 0x51, 0xc2, 0x26, 0xd4, 0xe2, 0xb7, 0xac, 0x7d, 0x19, + 0x49, 0x83, 0x60, 0x1b, 0xea, 0x53, 0xee, 0xbd, 0xe5, 0xd1, 0x2b, 0xbe, 0x0a, 0xa9, 0xa1, 0x21, + 0x42, 0x2b, 0x11, 0x3b, 0xe2, 0xe1, 0x22, 0xf0, 0xdd, 0xc8, 0xd0, 0xd1, 0x80, 0xfa, 0x38, 0x6e, + 0x3c, 0x5b, 0x2c, 0x24, 0x8b, 0x8c, 0x1f, 0xda, 0xf0, 0x17, 0x81, 0x5a, 0x3e, 0x1f, 0x9f, 0x43, + 0x25, 0x71, 0x00, 0x9e, 0x14, 0x85, 0x15, 0x7c, 0xd1, 0x31, 0x8a, 0xe4, 0xec, 0x12, 0x5f, 0x40, + 0x2d, 0x37, 0x01, 0x5a, 0x7b, 0xb5, 0x05, 0x77, 0xdc, 0x52, 0xfe, 0x1a, 0xaa, 0xd9, 0x71, 0xf0, + 0x7e, 0x91, 0xfd, 0xc7, 0x03, 0x9d, 0x93, 0xdb, 0x69, 0x75, 0xd3, 0x1e, 0x79, 0x4a, 0x5e, 0x3e, + 0xfe, 0xb9, 0xb1, 0xc8, 0xcd, 0xc6, 0x22, 0x7f, 0x36, 0x16, 0xf9, 0xbe, 0xb5, 0x4a, 0x37, 0x5b, + 0xab, 0xf4, 0x7b, 0x6b, 0x95, 0x3e, 0xb4, 0x07, 0xc5, 0x0f, 0xfa, 0x53, 0x45, 0xfd, 0x9d, 0xfd, + 0x0d, 0x00, 0x00, 0xff, 0xff, 0xaa, 0x39, 0x8f, 0xb0, 0xe9, 0x03, 0x00, 0x00, +} + +func (m *Log) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Log) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Log) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Records) > 0 { + for iNdEx := len(m.Records) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Records[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintConsensus(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.Id) > 0 { + i -= len(m.Id) + copy(dAtA[i:], m.Id) + i = encodeVarintConsensus(dAtA, i, uint64(len(m.Id))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Record) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Record) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Record) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.CreatedUnix != 0 { + i = encodeVarintConsensus(dAtA, i, uint64(m.CreatedUnix)) + i-- + dAtA[i] = 0x20 + } + if len(m.Payload) > 0 { + i -= len(m.Payload) + copy(dAtA[i:], m.Payload) + i = encodeVarintConsensus(dAtA, i, uint64(len(m.Payload))) + i-- + dAtA[i] = 0x1a + } + if len(m.PrevId) > 0 { + i -= len(m.PrevId) + copy(dAtA[i:], m.PrevId) + i = encodeVarintConsensus(dAtA, i, uint64(len(m.PrevId))) + i-- + dAtA[i] = 0x12 + } + if len(m.Id) > 0 { + i -= len(m.Id) + copy(dAtA[i:], m.Id) + i = encodeVarintConsensus(dAtA, i, uint64(len(m.Id))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Ok) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Ok) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Ok) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *AddLogRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AddLogRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AddLogRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Log != nil { + { + size, err := m.Log.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintConsensus(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *AddRecordRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AddRecordRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AddRecordRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Record != nil { + { + size, err := m.Record.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintConsensus(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.LogId) > 0 { + i -= len(m.LogId) + copy(dAtA[i:], m.LogId) + i = encodeVarintConsensus(dAtA, i, uint64(len(m.LogId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *WatchLogRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *WatchLogRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *WatchLogRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.UnwatchIds) > 0 { + for iNdEx := len(m.UnwatchIds) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.UnwatchIds[iNdEx]) + copy(dAtA[i:], m.UnwatchIds[iNdEx]) + i = encodeVarintConsensus(dAtA, i, uint64(len(m.UnwatchIds[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } + if len(m.WatchIds) > 0 { + for iNdEx := len(m.WatchIds) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.WatchIds[iNdEx]) + copy(dAtA[i:], m.WatchIds[iNdEx]) + i = encodeVarintConsensus(dAtA, i, uint64(len(m.WatchIds[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *WatchLogEvent) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *WatchLogEvent) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *WatchLogEvent) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Error != nil { + { + size, err := m.Error.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintConsensus(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if len(m.Records) > 0 { + for iNdEx := len(m.Records) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Records[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintConsensus(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.LogId) > 0 { + i -= len(m.LogId) + copy(dAtA[i:], m.LogId) + i = encodeVarintConsensus(dAtA, i, uint64(len(m.LogId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Err) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Err) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Err) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Error != 0 { + i = encodeVarintConsensus(dAtA, i, uint64(m.Error)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintConsensus(dAtA []byte, offset int, v uint64) int { + offset -= sovConsensus(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Log) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Id) + if l > 0 { + n += 1 + l + sovConsensus(uint64(l)) + } + if len(m.Records) > 0 { + for _, e := range m.Records { + l = e.Size() + n += 1 + l + sovConsensus(uint64(l)) + } + } + return n +} + +func (m *Record) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Id) + if l > 0 { + n += 1 + l + sovConsensus(uint64(l)) + } + l = len(m.PrevId) + if l > 0 { + n += 1 + l + sovConsensus(uint64(l)) + } + l = len(m.Payload) + if l > 0 { + n += 1 + l + sovConsensus(uint64(l)) + } + if m.CreatedUnix != 0 { + n += 1 + sovConsensus(uint64(m.CreatedUnix)) + } + return n +} + +func (m *Ok) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *AddLogRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Log != nil { + l = m.Log.Size() + n += 1 + l + sovConsensus(uint64(l)) + } + return n +} + +func (m *AddRecordRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.LogId) + if l > 0 { + n += 1 + l + sovConsensus(uint64(l)) + } + if m.Record != nil { + l = m.Record.Size() + n += 1 + l + sovConsensus(uint64(l)) + } + return n +} + +func (m *WatchLogRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.WatchIds) > 0 { + for _, b := range m.WatchIds { + l = len(b) + n += 1 + l + sovConsensus(uint64(l)) + } + } + if len(m.UnwatchIds) > 0 { + for _, b := range m.UnwatchIds { + l = len(b) + n += 1 + l + sovConsensus(uint64(l)) + } + } + return n +} + +func (m *WatchLogEvent) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.LogId) + if l > 0 { + n += 1 + l + sovConsensus(uint64(l)) + } + if len(m.Records) > 0 { + for _, e := range m.Records { + l = e.Size() + n += 1 + l + sovConsensus(uint64(l)) + } + } + if m.Error != nil { + l = m.Error.Size() + n += 1 + l + sovConsensus(uint64(l)) + } + return n +} + +func (m *Err) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Error != 0 { + n += 1 + sovConsensus(uint64(m.Error)) + } + return n +} + +func sovConsensus(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozConsensus(x uint64) (n int) { + return sovConsensus(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Log) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConsensus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Log: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Log: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConsensus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthConsensus + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthConsensus + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Id = append(m.Id[:0], dAtA[iNdEx:postIndex]...) + if m.Id == nil { + m.Id = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Records", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConsensus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthConsensus + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthConsensus + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Records = append(m.Records, &Record{}) + if err := m.Records[len(m.Records)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipConsensus(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthConsensus + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Record) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConsensus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Record: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Record: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConsensus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthConsensus + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthConsensus + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Id = append(m.Id[:0], dAtA[iNdEx:postIndex]...) + if m.Id == nil { + m.Id = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PrevId", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConsensus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthConsensus + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthConsensus + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PrevId = append(m.PrevId[:0], dAtA[iNdEx:postIndex]...) + if m.PrevId == nil { + m.PrevId = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Payload", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConsensus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthConsensus + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthConsensus + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Payload = append(m.Payload[:0], dAtA[iNdEx:postIndex]...) + if m.Payload == nil { + m.Payload = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CreatedUnix", wireType) + } + m.CreatedUnix = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConsensus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CreatedUnix |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipConsensus(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthConsensus + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Ok) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConsensus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Ok: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Ok: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipConsensus(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthConsensus + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AddLogRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConsensus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AddLogRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AddLogRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Log", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConsensus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthConsensus + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthConsensus + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Log == nil { + m.Log = &Log{} + } + if err := m.Log.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipConsensus(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthConsensus + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AddRecordRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConsensus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AddRecordRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AddRecordRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LogId", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConsensus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthConsensus + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthConsensus + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.LogId = append(m.LogId[:0], dAtA[iNdEx:postIndex]...) + if m.LogId == nil { + m.LogId = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Record", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConsensus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthConsensus + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthConsensus + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Record == nil { + m.Record = &Record{} + } + if err := m.Record.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipConsensus(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthConsensus + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *WatchLogRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConsensus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: WatchLogRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: WatchLogRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field WatchIds", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConsensus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthConsensus + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthConsensus + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.WatchIds = append(m.WatchIds, make([]byte, postIndex-iNdEx)) + copy(m.WatchIds[len(m.WatchIds)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UnwatchIds", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConsensus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthConsensus + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthConsensus + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UnwatchIds = append(m.UnwatchIds, make([]byte, postIndex-iNdEx)) + copy(m.UnwatchIds[len(m.UnwatchIds)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipConsensus(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthConsensus + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *WatchLogEvent) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConsensus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: WatchLogEvent: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: WatchLogEvent: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LogId", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConsensus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthConsensus + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthConsensus + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.LogId = append(m.LogId[:0], dAtA[iNdEx:postIndex]...) + if m.LogId == nil { + m.LogId = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Records", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConsensus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthConsensus + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthConsensus + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Records = append(m.Records, &Record{}) + if err := m.Records[len(m.Records)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConsensus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthConsensus + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthConsensus + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Error == nil { + m.Error = &Err{} + } + if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipConsensus(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthConsensus + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Err) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConsensus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Err: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Err: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + } + m.Error = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConsensus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Error |= ErrCodes(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipConsensus(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthConsensus + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipConsensus(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowConsensus + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowConsensus + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowConsensus + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthConsensus + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupConsensus + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthConsensus + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthConsensus = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowConsensus = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupConsensus = fmt.Errorf("proto: unexpected end of group") +) diff --git a/consensus/consensusproto/consensus_drpc.pb.go b/consensus/consensusproto/consensus_drpc.pb.go new file mode 100644 index 00000000..c5ee4056 --- /dev/null +++ b/consensus/consensusproto/consensus_drpc.pb.go @@ -0,0 +1,228 @@ +// Code generated by protoc-gen-go-drpc. DO NOT EDIT. +// protoc-gen-go-drpc version: v0.0.32 +// source: consensusproto/protos/consensus.proto + +package consensusproto + +import ( + bytes "bytes" + context "context" + errors "errors" + jsonpb "github.com/gogo/protobuf/jsonpb" + proto "github.com/gogo/protobuf/proto" + drpc "storj.io/drpc" + drpcerr "storj.io/drpc/drpcerr" +) + +type drpcEncoding_File_consensusproto_protos_consensus_proto struct{} + +func (drpcEncoding_File_consensusproto_protos_consensus_proto) Marshal(msg drpc.Message) ([]byte, error) { + return proto.Marshal(msg.(proto.Message)) +} + +func (drpcEncoding_File_consensusproto_protos_consensus_proto) Unmarshal(buf []byte, msg drpc.Message) error { + return proto.Unmarshal(buf, msg.(proto.Message)) +} + +func (drpcEncoding_File_consensusproto_protos_consensus_proto) JSONMarshal(msg drpc.Message) ([]byte, error) { + var buf bytes.Buffer + err := new(jsonpb.Marshaler).Marshal(&buf, msg.(proto.Message)) + if err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +func (drpcEncoding_File_consensusproto_protos_consensus_proto) JSONUnmarshal(buf []byte, msg drpc.Message) error { + return jsonpb.Unmarshal(bytes.NewReader(buf), msg.(proto.Message)) +} + +type DRPCConsensusClient interface { + DRPCConn() drpc.Conn + + AddLog(ctx context.Context, in *AddLogRequest) (*Ok, error) + AddRecord(ctx context.Context, in *AddRecordRequest) (*Ok, error) + WatchLog(ctx context.Context) (DRPCConsensus_WatchLogClient, error) +} + +type drpcConsensusClient struct { + cc drpc.Conn +} + +func NewDRPCConsensusClient(cc drpc.Conn) DRPCConsensusClient { + return &drpcConsensusClient{cc} +} + +func (c *drpcConsensusClient) DRPCConn() drpc.Conn { return c.cc } + +func (c *drpcConsensusClient) AddLog(ctx context.Context, in *AddLogRequest) (*Ok, error) { + out := new(Ok) + err := c.cc.Invoke(ctx, "/anyConsensus.Consensus/AddLog", drpcEncoding_File_consensusproto_protos_consensus_proto{}, in, out) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *drpcConsensusClient) AddRecord(ctx context.Context, in *AddRecordRequest) (*Ok, error) { + out := new(Ok) + err := c.cc.Invoke(ctx, "/anyConsensus.Consensus/AddRecord", drpcEncoding_File_consensusproto_protos_consensus_proto{}, in, out) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *drpcConsensusClient) WatchLog(ctx context.Context) (DRPCConsensus_WatchLogClient, error) { + stream, err := c.cc.NewStream(ctx, "/anyConsensus.Consensus/WatchLog", drpcEncoding_File_consensusproto_protos_consensus_proto{}) + if err != nil { + return nil, err + } + x := &drpcConsensus_WatchLogClient{stream} + return x, nil +} + +type DRPCConsensus_WatchLogClient interface { + drpc.Stream + Send(*WatchLogRequest) error + Recv() (*WatchLogEvent, error) +} + +type drpcConsensus_WatchLogClient struct { + drpc.Stream +} + +func (x *drpcConsensus_WatchLogClient) Send(m *WatchLogRequest) error { + return x.MsgSend(m, drpcEncoding_File_consensusproto_protos_consensus_proto{}) +} + +func (x *drpcConsensus_WatchLogClient) Recv() (*WatchLogEvent, error) { + m := new(WatchLogEvent) + if err := x.MsgRecv(m, drpcEncoding_File_consensusproto_protos_consensus_proto{}); err != nil { + return nil, err + } + return m, nil +} + +func (x *drpcConsensus_WatchLogClient) RecvMsg(m *WatchLogEvent) error { + return x.MsgRecv(m, drpcEncoding_File_consensusproto_protos_consensus_proto{}) +} + +type DRPCConsensusServer interface { + AddLog(context.Context, *AddLogRequest) (*Ok, error) + AddRecord(context.Context, *AddRecordRequest) (*Ok, error) + WatchLog(DRPCConsensus_WatchLogStream) error +} + +type DRPCConsensusUnimplementedServer struct{} + +func (s *DRPCConsensusUnimplementedServer) AddLog(context.Context, *AddLogRequest) (*Ok, error) { + return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) +} + +func (s *DRPCConsensusUnimplementedServer) AddRecord(context.Context, *AddRecordRequest) (*Ok, error) { + return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) +} + +func (s *DRPCConsensusUnimplementedServer) WatchLog(DRPCConsensus_WatchLogStream) error { + return drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) +} + +type DRPCConsensusDescription struct{} + +func (DRPCConsensusDescription) NumMethods() int { return 3 } + +func (DRPCConsensusDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver, interface{}, bool) { + switch n { + case 0: + return "/anyConsensus.Consensus/AddLog", drpcEncoding_File_consensusproto_protos_consensus_proto{}, + func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { + return srv.(DRPCConsensusServer). + AddLog( + ctx, + in1.(*AddLogRequest), + ) + }, DRPCConsensusServer.AddLog, true + case 1: + return "/anyConsensus.Consensus/AddRecord", drpcEncoding_File_consensusproto_protos_consensus_proto{}, + func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { + return srv.(DRPCConsensusServer). + AddRecord( + ctx, + in1.(*AddRecordRequest), + ) + }, DRPCConsensusServer.AddRecord, true + case 2: + return "/anyConsensus.Consensus/WatchLog", drpcEncoding_File_consensusproto_protos_consensus_proto{}, + func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { + return nil, srv.(DRPCConsensusServer). + WatchLog( + &drpcConsensus_WatchLogStream{in1.(drpc.Stream)}, + ) + }, DRPCConsensusServer.WatchLog, true + default: + return "", nil, nil, nil, false + } +} + +func DRPCRegisterConsensus(mux drpc.Mux, impl DRPCConsensusServer) error { + return mux.Register(impl, DRPCConsensusDescription{}) +} + +type DRPCConsensus_AddLogStream interface { + drpc.Stream + SendAndClose(*Ok) error +} + +type drpcConsensus_AddLogStream struct { + drpc.Stream +} + +func (x *drpcConsensus_AddLogStream) SendAndClose(m *Ok) error { + if err := x.MsgSend(m, drpcEncoding_File_consensusproto_protos_consensus_proto{}); err != nil { + return err + } + return x.CloseSend() +} + +type DRPCConsensus_AddRecordStream interface { + drpc.Stream + SendAndClose(*Ok) error +} + +type drpcConsensus_AddRecordStream struct { + drpc.Stream +} + +func (x *drpcConsensus_AddRecordStream) SendAndClose(m *Ok) error { + if err := x.MsgSend(m, drpcEncoding_File_consensusproto_protos_consensus_proto{}); err != nil { + return err + } + return x.CloseSend() +} + +type DRPCConsensus_WatchLogStream interface { + drpc.Stream + Send(*WatchLogEvent) error + Recv() (*WatchLogRequest, error) +} + +type drpcConsensus_WatchLogStream struct { + drpc.Stream +} + +func (x *drpcConsensus_WatchLogStream) Send(m *WatchLogEvent) error { + return x.MsgSend(m, drpcEncoding_File_consensusproto_protos_consensus_proto{}) +} + +func (x *drpcConsensus_WatchLogStream) Recv() (*WatchLogRequest, error) { + m := new(WatchLogRequest) + if err := x.MsgRecv(m, drpcEncoding_File_consensusproto_protos_consensus_proto{}); err != nil { + return nil, err + } + return m, nil +} + +func (x *drpcConsensus_WatchLogStream) RecvMsg(m *WatchLogRequest) error { + return x.MsgRecv(m, drpcEncoding_File_consensusproto_protos_consensus_proto{}) +} diff --git a/consensus/consensusproto/consensuserr/errors.go b/consensus/consensusproto/consensuserr/errors.go new file mode 100644 index 00000000..f0ff33a6 --- /dev/null +++ b/consensus/consensusproto/consensuserr/errors.go @@ -0,0 +1,16 @@ +package consensuserr + +import ( + "fmt" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/rpc/rpcerr" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto" +) + +var ( + errGroup = rpcerr.ErrGroup(consensusproto.ErrCodes_ErrorOffset) + + ErrUnexpected = errGroup.Register(fmt.Errorf("unexpected consensus error"), uint64(consensusproto.ErrCodes_Unexpected)) + ErrConflict = errGroup.Register(fmt.Errorf("records conflict"), uint64(consensusproto.ErrCodes_RecordConflict)) + ErrLogExists = errGroup.Register(fmt.Errorf("log exists"), uint64(consensusproto.ErrCodes_LogExists)) + ErrLogNotFound = errGroup.Register(fmt.Errorf("log not found"), uint64(consensusproto.ErrCodes_LogNotFound)) +) diff --git a/consensus/consensusproto/protos/consensus.proto b/consensus/consensusproto/protos/consensus.proto new file mode 100644 index 00000000..17a1bce0 --- /dev/null +++ b/consensus/consensusproto/protos/consensus.proto @@ -0,0 +1,60 @@ +syntax = "proto3"; +package anyConsensus; + +option go_package = "/consensusproto"; + +enum ErrCodes { + Unexpected = 0; + LogExists = 1; + LogNotFound = 2; + RecordConflict = 3; + ErrorOffset = 300; +} + + +message Log { + bytes id = 1; + repeated Record records = 2; +} + +message Record { + bytes id = 1; + bytes prevId = 2; + bytes payload = 3; + uint64 createdUnix = 4; +} + +service Consensus { + // AddLog adds new log to consensus + rpc AddLog(AddLogRequest) returns (Ok); + // AddRecord adds new record to log + rpc AddRecord(AddRecordRequest) returns (Ok); + // WatchLog fetches log and subscribes for a changes + rpc WatchLog(stream WatchLogRequest) returns (stream WatchLogEvent); +} + +message Ok {} + +message AddLogRequest { + Log log = 1; +} + +message AddRecordRequest { + bytes logId = 1; + Record record = 2; +} + +message WatchLogRequest { + repeated bytes watchIds = 1; + repeated bytes unwatchIds = 2; +} + +message WatchLogEvent { + bytes logId = 1; + repeated Record records = 2; + Err error = 3; +} + +message Err { + ErrCodes error = 1; +} \ No newline at end of file diff --git a/consensus/consensusrpc/consensrpc.go b/consensus/consensusrpc/consensrpc.go new file mode 100644 index 00000000..bee34062 --- /dev/null +++ b/consensus/consensusrpc/consensrpc.go @@ -0,0 +1,134 @@ +package consensusrpc + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/rpc/server" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto/consensuserr" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/db" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/stream" + "storj.io/drpc/drpcerr" + "time" +) + +const CName = "consensus.consensusrpc" + +func New() app.Component { + return &consensusRpc{} +} + +// consensusRpc implements consensus rpc server +type consensusRpc struct { + db db.Service + stream stream.Service +} + +func (c *consensusRpc) Init(a *app.App) (err error) { + c.db = a.MustComponent(db.CName).(db.Service) + c.stream = a.MustComponent(stream.CName).(stream.Service) + return consensusproto.DRPCRegisterConsensus(a.MustComponent(server.CName).(server.DRPCServer), c) +} + +func (c *consensusRpc) Name() (name string) { + return CName +} + +func (c *consensusRpc) AddLog(ctx context.Context, req *consensusproto.AddLogRequest) (*consensusproto.Ok, error) { + if err := c.db.AddLog(ctx, logFromProto(req.Log)); err != nil { + return nil, err + } + return &consensusproto.Ok{}, nil +} + +func (c *consensusRpc) AddRecord(ctx context.Context, req *consensusproto.AddRecordRequest) (*consensusproto.Ok, error) { + if err := c.db.AddRecord(ctx, req.LogId, recordFromProto(req.Record)); err != nil { + return nil, err + } + return &consensusproto.Ok{}, nil +} + +func (c *consensusRpc) WatchLog(rpcStream consensusproto.DRPCConsensus_WatchLogStream) error { + stream := c.stream.NewStream() + defer stream.Close() + go c.readStream(stream, rpcStream) + for { + recs := stream.WaitLogs() + if len(recs) == 0 { + return rpcStream.Close() + } + for _, rec := range recs { + if rec.Err == nil { + if err := rpcStream.Send(&consensusproto.WatchLogEvent{ + LogId: rec.Id, + Records: recordsToProto(rec.Records), + }); err != nil { + return err + } + } else { + errCode := consensusproto.ErrCodes(drpcerr.Code(rec.Err)) + if errCode == 0 { + errCode = consensusproto.ErrCodes(drpcerr.Code(consensuserr.ErrUnexpected)) + } + if err := rpcStream.Send(&consensusproto.WatchLogEvent{ + LogId: rec.Id, + Error: &consensusproto.Err{ + Error: errCode, + }, + }); err != nil { + return err + } + } + } + } +} + +func (c *consensusRpc) readStream(st *stream.Stream, rpcStream consensusproto.DRPCConsensus_WatchLogStream) { + defer st.Close() + for { + req, err := rpcStream.Recv() + if err != nil { + return + } + st.UnwatchIds(rpcStream.Context(), req.UnwatchIds) + st.WatchIds(rpcStream.Context(), req.WatchIds) + } +} + +func logFromProto(log *consensusproto.Log) consensus.Log { + return consensus.Log{ + Id: log.Id, + Records: recordsFromProto(log.Records), + } +} + +func recordsFromProto(recs []*consensusproto.Record) []consensus.Record { + res := make([]consensus.Record, len(recs)) + for i, rec := range recs { + res[i] = recordFromProto(rec) + } + return res +} + +func recordFromProto(rec *consensusproto.Record) consensus.Record { + return consensus.Record{ + Id: rec.Id, + PrevId: rec.PrevId, + Payload: rec.Payload, + Created: time.Unix(int64(rec.CreatedUnix), 0), + } +} + +func recordsToProto(recs []consensus.Record) []*consensusproto.Record { + res := make([]*consensusproto.Record, len(recs)) + for i, rec := range recs { + res[i] = &consensusproto.Record{ + Id: rec.Id, + PrevId: rec.PrevId, + Payload: rec.Payload, + CreatedUnix: uint64(rec.Created.Unix()), + } + } + return res +} diff --git a/consensus/db/db.go b/consensus/db/db.go new file mode 100644 index 00000000..ac34d6a8 --- /dev/null +++ b/consensus/db/db.go @@ -0,0 +1,188 @@ +package db + +import ( + "context" + "fmt" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/config" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto/consensuserr" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" + "go.uber.org/zap" +) + +const CName = "consensus.db" + +var log = logger.NewNamed(CName) + +func New() Service { + return &service{} +} + +type ChangeReceiver func(logId []byte, records []consensus.Record) + +type Service interface { + // AddLog adds new log db + AddLog(ctx context.Context, log consensus.Log) (err error) + // AddRecord adds new record to existing log + // returns consensuserr.ErrConflict if record didn't match or log not found + AddRecord(ctx context.Context, logId []byte, record consensus.Record) (err error) + // FetchLog gets log by id + FetchLog(ctx context.Context, logId []byte) (log consensus.Log, err error) + // SetChangeReceiver sets the receiver for updates, it must be called before app.Run stage + SetChangeReceiver(receiver ChangeReceiver) (err error) + app.ComponentRunnable +} + +type service struct { + conf config.Mongo + logColl *mongo.Collection + running bool + changeReceiver ChangeReceiver + + streamCtx context.Context + streamCancel context.CancelFunc + listenerDone chan struct{} +} + +func (s *service) Init(a *app.App) (err error) { + s.conf = a.MustComponent(config.CName).(*config.Config).Mongo + return nil +} + +func (s *service) Name() (name string) { + return CName +} + +func (s *service) Run(ctx context.Context) (err error) { + client, err := mongo.Connect(ctx, options.Client().ApplyURI(s.conf.Connect)) + if err != nil { + return err + } + s.logColl = client.Database(s.conf.Database).Collection(s.conf.LogCollection) + s.running = true + if s.changeReceiver != nil { + if err = s.runStreamListener(ctx); err != nil { + return err + } + } + return +} + +func (s *service) AddLog(ctx context.Context, l consensus.Log) (err error) { + _, err = s.logColl.InsertOne(ctx, l) + if mongo.IsDuplicateKeyError(err) { + return consensuserr.ErrLogExists + } + return +} + +type findLogQuery struct { + Id []byte `bson:"_id"` +} + +type findRecordQuery struct { + Id []byte `bson:"_id"` + LastRecordId []byte `bson:"records.0.id"` +} + +type updateOp struct { + Push struct { + Records struct { + Each []consensus.Record `bson:"$each"` + Pos int `bson:"$position"` + } `bson:"records"` + } `bson:"$push"` +} + +func (s *service) AddRecord(ctx context.Context, logId []byte, record consensus.Record) (err error) { + var upd updateOp + upd.Push.Records.Each = []consensus.Record{record} + result, err := s.logColl.UpdateOne(ctx, findRecordQuery{ + Id: logId, + LastRecordId: record.PrevId, + }, upd) + if err != nil { + log.Error("addRecord update error", zap.Error(err)) + return consensuserr.ErrUnexpected + } + if result.ModifiedCount == 0 { + return consensuserr.ErrConflict + } + return +} + +func (s *service) FetchLog(ctx context.Context, logId []byte) (l consensus.Log, err error) { + if err = s.logColl.FindOne(ctx, findLogQuery{Id: logId}).Decode(&l); err != nil { + if err == mongo.ErrNoDocuments { + err = consensuserr.ErrLogNotFound + } + return + } + return +} + +func (s *service) SetChangeReceiver(receiver ChangeReceiver) (err error) { + if s.running { + return fmt.Errorf("set receiver must be called before Run") + } + s.changeReceiver = receiver + return +} + +type matchPipeline struct { + Match struct { + OT string `bson:"operationType"` + } `bson:"$match"` +} + +func (s *service) runStreamListener(ctx context.Context) (err error) { + var mp matchPipeline + mp.Match.OT = "update" + stream, err := s.logColl.Watch(ctx, []matchPipeline{mp}) + if err != nil { + return + } + s.listenerDone = make(chan struct{}) + s.streamCtx, s.streamCancel = context.WithCancel(context.Background()) + go s.streamListener(stream) + return +} + +type streamResult struct { + DocumentKey struct { + Id []byte `bson:"_id"` + } `bson:"documentKey"` + UpdateDescription struct { + UpdateFields struct { + Records []consensus.Record `bson:"records"` + } `bson:"updatedFields"` + } `bson:"updateDescription"` +} + +func (s *service) streamListener(stream *mongo.ChangeStream) { + defer close(s.listenerDone) + for stream.Next(s.streamCtx) { + var res streamResult + if err := stream.Decode(&res); err != nil { + // mongo driver maintains connections and handles reconnects so that the stream will work as usual in these cases + // here we have an unexpected error and should stop any operations to avoid an inconsistent state between db and cache + log.Fatal("stream decode error:", zap.Error(err)) + } + s.changeReceiver(res.DocumentKey.Id, res.UpdateDescription.UpdateFields.Records) + } +} + +func (s *service) Close(ctx context.Context) (err error) { + if s.logColl != nil { + err = s.logColl.Database().Client().Disconnect(ctx) + s.logColl = nil + } + if s.listenerDone != nil { + s.streamCancel() + <-s.listenerDone + } + return +} diff --git a/consensus/db/db_test.go b/consensus/db/db_test.go new file mode 100644 index 00000000..58acfef7 --- /dev/null +++ b/consensus/db/db_test.go @@ -0,0 +1,218 @@ +package db + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/config" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto/consensuserr" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "testing" + "time" +) + +var ctx = context.Background() + +func TestService_AddLog(t *testing.T) { + t.Run("success", func(t *testing.T) { + fx := newFixture(t, nil) + defer fx.Finish(t) + log := consensus.Log{ + Id: []byte("logOne"), + Records: []consensus.Record{ + { + Id: []byte("recordOne"), + PrevId: nil, + Payload: []byte("payload"), + Created: time.Now().Truncate(time.Second).UTC(), + }, + }, + } + require.NoError(t, fx.AddLog(ctx, log)) + fetched, err := fx.FetchLog(ctx, log.Id) + require.NoError(t, err) + assert.Equal(t, log, fetched) + }) + t.Run("duplicate error", func(t *testing.T) { + fx := newFixture(t, nil) + defer fx.Finish(t) + log := consensus.Log{ + Id: []byte("logOne"), + } + require.NoError(t, fx.AddLog(ctx, log)) + // TODO: check for specified error + require.Error(t, fx.AddLog(ctx, log)) + }) +} + +func TestService_AddRecord(t *testing.T) { + t.Run("success", func(t *testing.T) { + fx := newFixture(t, nil) + defer fx.Finish(t) + var records = []consensus.Record{ + { + Id: []byte("2"), + PrevId: []byte("1"), + }, + { + Id: []byte("3"), + PrevId: []byte("2"), + }, + { + Id: []byte("4"), + PrevId: []byte("3"), + }, + } + l := consensus.Log{ + Id: []byte("logTestRecords"), + Records: []consensus.Record{ + { + Id: []byte("1"), + }, + }, + } + require.NoError(t, fx.AddLog(ctx, l)) + for _, rec := range records { + require.NoError(t, fx.AddRecord(ctx, l.Id, rec)) + } + fx.assertLogValid(t, l.Id, 4) + }) + t.Run("conflict", func(t *testing.T) { + fx := newFixture(t, nil) + defer fx.Finish(t) + log := consensus.Log{ + Id: []byte("logTestRecords"), + Records: []consensus.Record{ + { + Id: []byte("1"), + }, + }, + } + require.NoError(t, fx.AddLog(ctx, log)) + assert.Error(t, fx.AddRecord(ctx, log.Id, consensus.Record{Id: []byte("2"), PrevId: []byte("3")})) + }) +} + +func TestService_FetchLog(t *testing.T) { + t.Run("not found", func(t *testing.T) { + fx := newFixture(t, nil) + defer fx.Finish(t) + l, err := fx.FetchLog(ctx, []byte("not exists")) + assert.Empty(t, l) + assert.ErrorIs(t, err, consensuserr.ErrLogNotFound) + }) +} + +func TestService_ChangeReceive(t *testing.T) { + t.Run("set after run", func(t *testing.T) { + fx := newFixture(t, nil) + defer fx.Finish(t) + assert.Error(t, fx.SetChangeReceiver(func(logId []byte, records []consensus.Record) {})) + }) + t.Run("receive changes", func(t *testing.T) { + var logs = make(chan consensus.Log, 10) + var count int + fx := newFixture(t, func(logId []byte, records []consensus.Record) { + logs <- consensus.Log{Id: logId, Records: records} + count++ + }) + defer fx.Finish(t) + var l = consensus.Log{ + Id: []byte("logTestStream"), + Records: []consensus.Record{ + { + Id: []byte("1"), + }, + }, + } + var records = []consensus.Record{ + { + Id: []byte("2"), + PrevId: []byte("1"), + }, + { + Id: []byte("3"), + PrevId: []byte("2"), + }, + { + Id: []byte("4"), + PrevId: []byte("3"), + }, + } + require.NoError(t, fx.AddLog(ctx, l)) + assert.Empty(t, count) + + for _, rec := range records { + require.NoError(t, fx.AddRecord(ctx, l.Id, rec)) + } + + timeout := time.After(time.Second) + for i := 0; i < len(records); i++ { + select { + case resLog := <-logs: + assertLogValid(t, resLog, i+2) + case <-timeout: + require.False(t, true) + } + } + }) +} + +func newFixture(t *testing.T, cr ChangeReceiver) *fixture { + ctx, cancel := context.WithTimeout(ctx, time.Second) + fx := &fixture{ + Service: New(), + cancel: cancel, + a: new(app.App), + } + fx.a.Register(&config.Config{ + Mongo: config.Mongo{ + Connect: "mongodb://localhost:27017/?w=majority", + Database: "consensus_test", + LogCollection: "log", + }, + }) + fx.a.Register(fx.Service) + require.NoError(t, fx.Service.SetChangeReceiver(cr)) + err := fx.a.Start(ctx) + if err != nil { + fx.cancel() + } + require.NoError(t, err) + return fx +} + +type fixture struct { + Service + a *app.App + cancel context.CancelFunc +} + +func (fx *fixture) Finish(t *testing.T) { + if fx.cancel != nil { + fx.cancel() + } + coll := fx.Service.(*service).logColl + t.Log(coll.Drop(ctx)) + assert.NoError(t, fx.a.Close(ctx)) +} + +func (fx *fixture) assertLogValid(t *testing.T, logId []byte, count int) { + log, err := fx.FetchLog(ctx, logId) + require.NoError(t, err) + assertLogValid(t, log, count) +} + +func assertLogValid(t *testing.T, log consensus.Log, count int) { + if count >= 0 { + assert.Len(t, log.Records, count) + } + var prevId []byte + for _, rec := range log.Records { + if len(prevId) != 0 { + assert.Equal(t, string(prevId), string(rec.Id)) + } + prevId = rec.PrevId + } +} diff --git a/consensus/go.mod b/consensus/go.mod new file mode 100644 index 00000000..9889f33e --- /dev/null +++ b/consensus/go.mod @@ -0,0 +1,68 @@ +module github.com/anytypeio/go-anytype-infrastructure-experiments/consensus + +go 1.19 + +replace github.com/anytypeio/go-anytype-infrastructure-experiments/common => ../common + +require ( + github.com/cheggaaa/mb/v2 v2.0.1 + github.com/gogo/protobuf v1.3.2 + github.com/mr-tron/base58 v1.2.0 + github.com/stretchr/testify v1.8.0 + go.mongodb.org/mongo-driver v1.10.3 + go.uber.org/zap v1.23.0 + gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 + gopkg.in/yaml.v3 v3.0.1 + storj.io/drpc v0.0.32 +) + +require ( + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash v1.1.0 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/snappy v0.0.1 // indirect + github.com/ipfs/go-cid v0.3.2 // indirect + github.com/ipfs/go-log/v2 v2.5.1 // indirect + github.com/klauspost/compress v1.15.10 // indirect + github.com/klauspost/cpuid/v2 v2.1.1 // indirect + github.com/libp2p/go-buffer-pool v0.1.0 // indirect + github.com/libp2p/go-libp2p v0.23.2 // indirect + github.com/libp2p/go-libp2p-core v0.20.1 // indirect + github.com/libp2p/go-openssl v0.1.0 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-pointer v0.0.1 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/minio/sha256-simd v1.0.0 // indirect + github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect + github.com/multiformats/go-base32 v0.1.0 // indirect + github.com/multiformats/go-base36 v0.1.0 // indirect + github.com/multiformats/go-multiaddr v0.7.0 // indirect + github.com/multiformats/go-multibase v0.1.1 // indirect + github.com/multiformats/go-multicodec v0.6.0 // indirect + github.com/multiformats/go-multihash v0.2.1 // indirect + github.com/multiformats/go-varint v0.0.6 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_golang v1.13.0 // indirect + github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/common v0.37.0 // indirect + github.com/prometheus/procfs v0.8.0 // indirect + github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect + github.com/xdg-go/pbkdf2 v1.0.0 // indirect + github.com/xdg-go/scram v1.1.1 // indirect + github.com/xdg-go/stringprep v1.0.3 // indirect + github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect + github.com/zeebo/errs v1.3.0 // indirect + go.uber.org/atomic v1.10.0 // indirect + go.uber.org/multierr v1.8.0 // indirect + golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect + golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect + golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect + golang.org/x/text v0.3.7 // indirect + google.golang.org/protobuf v1.28.1 // indirect + lukechampine.com/blake3 v1.1.7 // indirect +) diff --git a/consensus/go.sum b/consensus/go.sum new file mode 100644 index 00000000..69f2f44a --- /dev/null +++ b/consensus/go.sum @@ -0,0 +1,613 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +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= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cheggaaa/mb/v2 v2.0.1 h1:gn0khbEbKlw3i5VOYi0VnHEHayjZKfUDOyGSpHAybBs= +github.com/cheggaaa/mb/v2 v2.0.1/go.mod h1:XGeZw20Iqgjky26KL0mvCwk3+4NyZCUbshSo6ALne+c= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +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/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= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ipfs/go-cid v0.3.2 h1:OGgOd+JCFM+y1DjWPmVH+2/4POtpDzwcr7VgnB7mZXc= +github.com/ipfs/go-cid v0.3.2/go.mod h1:gQ8pKqT/sUxGY+tIwy1RPpAojYu7jAyCp5Tz1svoupw= +github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= +github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.15.10 h1:Ai8UzuomSCDw90e1qNMtb15msBXsNpH6gzkkENQNcJo= +github.com/klauspost/compress v1.15.10/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= +github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.1.1 h1:t0wUqjowdm8ezddV5k0tLWVklVuvLJpoHeb4WBdydm0= +github.com/klauspost/cpuid/v2 v2.1.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= +github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= +github.com/libp2p/go-libp2p v0.23.2 h1:yqyTeKQJyofWXxEv/eEVUvOrGdt/9x+0PIQ4N1kaxmE= +github.com/libp2p/go-libp2p v0.23.2/go.mod h1:s9DEa5NLR4g+LZS+md5uGU4emjMWFiqkZr6hBTY8UxI= +github.com/libp2p/go-libp2p-core v0.20.1 h1:fQz4BJyIFmSZAiTbKV8qoYhEH5Dtv/cVhZbG3Ib/+Cw= +github.com/libp2p/go-libp2p-core v0.20.1/go.mod h1:6zR8H7CvQWgYLsbG4on6oLNSGcyKaYFSEYyDt51+bIY= +github.com/libp2p/go-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+Ooo= +github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= +github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= +github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= +github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= +github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= +github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4= +github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= +github.com/multiformats/go-multiaddr v0.7.0 h1:gskHcdaCyPtp9XskVwtvEeQOG465sCohbQIirSyqxrc= +github.com/multiformats/go-multiaddr v0.7.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs= +github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI= +github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8= +github.com/multiformats/go-multicodec v0.6.0 h1:KhH2kSuCARyuJraYMFxrNO3DqIaYhOdS039kbhgVwpE= +github.com/multiformats/go-multicodec v0.6.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw= +github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108= +github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= +github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY= +github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU= +github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= +github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= +github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E= +github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= +github.com/xdg-go/stringprep v1.0.3 h1:kdwGpVNwPFtjs98xCGkHjQtGKh86rDcRZN17QEMCOIs= +github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= +github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= +github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= +github.com/zeebo/errs v1.3.0 h1:hmiaKqgYZzcVgRL1Vkc1Mn2914BbzB0IBxs+ebeutGs= +github.com/zeebo/errs v1.3.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= +go.mongodb.org/mongo-driver v1.10.3 h1:XDQEvmh6z1EUsXuIkXE9TaVeqHw6SwS1uf93jFs0HBA= +go.mongodb.org/mongo-driver v1.10.3/go.mod h1:z4XpeoU6w+9Vht+jAFyLgVrD+jGSQQe0+CBWFHNiHt8= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +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.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= +go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= +go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= +go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +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= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +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= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +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/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 h1:VpOs+IwYnYBaFnrNAeB8UUWtL3vEUnzSCL1nVjPhqrw= +gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= +lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +storj.io/drpc v0.0.32 h1:5p5ZwsK/VOgapaCu+oxaPVwO6UwIs+iwdMiD50+R4PI= +storj.io/drpc v0.0.32/go.mod h1:6rcOyR/QQkSTX/9L5ZGtlZaE2PtXTTZl8d+ulSeeYEg= diff --git a/consensus/stream/object.go b/consensus/stream/object.go new file mode 100644 index 00000000..22164911 --- /dev/null +++ b/consensus/stream/object.go @@ -0,0 +1,66 @@ +package stream + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus" + "sync" +) + +// object is a cache entry that holds the actual log state and maintains added streams +type object struct { + logId []byte + records []consensus.Record + + streams map[uint64]*Stream + + mu sync.Mutex +} + +// AddRecords adds new records to the log and sends new records to streams +// The records source is db and called via stream.Service +func (o *object) AddRecords(recs []consensus.Record) { + o.mu.Lock() + defer o.mu.Unlock() + + if len(recs) <= len(o.records) { + return + } + diff := recs[0 : len(recs)-len(o.records)] + o.records = recs + for _, st := range o.streams { + _ = st.AddRecords(o.logId, diff) + } +} + +// Records returns all log records +func (o *object) Records() []consensus.Record { + o.mu.Lock() + defer o.mu.Unlock() + return o.records +} + +// AddStream adds stream to the object +func (o *object) AddStream(s *Stream) { + o.mu.Lock() + defer o.mu.Unlock() + o.streams[s.id] = s + _ = s.AddRecords(o.logId, o.records) + return +} + +// RemoveStream remove stream from object +func (o *object) RemoveStream(id uint64) { + o.mu.Lock() + defer o.mu.Unlock() + delete(o.streams, id) +} + +// Locked indicates that object can be garbage collected +func (o *object) Locked() bool { + o.mu.Lock() + defer o.mu.Unlock() + return len(o.streams) > 0 +} + +func (o *object) Close() (err error) { + return nil +} diff --git a/consensus/stream/service.go b/consensus/stream/service.go new file mode 100644 index 00000000..c659786a --- /dev/null +++ b/consensus/stream/service.go @@ -0,0 +1,150 @@ +package stream + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/metric" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ocache" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/db" + "github.com/cheggaaa/mb/v2" + "github.com/mr-tron/base58" + "go.uber.org/zap" + "sync/atomic" + "time" +) + +const CName = "consensus.stream" + +var log = logger.NewNamed(CName) + +var ( + cacheTTL = time.Minute +) + +type ctxLog uint + +const ( + ctxLogKey ctxLog = 1 +) + +func New() Service { + return &service{} +} + +// Service maintains a cache for logs (receive updates from db) and creates new stream objects with able to subscribe/unsubscribe to log ids +type Service interface { + // NewStream creates new stream with able to watch and unwatch log ids + NewStream() *Stream + app.ComponentRunnable +} + +type service struct { + db db.Service + cache ocache.OCache + lastStreamId uint64 +} + +func (s *service) Init(a *app.App) (err error) { + s.db = a.MustComponent(db.CName).(db.Service) + cacheOpts := []ocache.Option{ + ocache.WithTTL(cacheTTL), + ocache.WithLogger(log.Named("cache").Sugar()), + } + if ms := a.Component(metric.CName); ms != nil { + cacheOpts = append(cacheOpts, ocache.WithPrometheus(ms.(metric.Metric).Registry(), "consensus", "logcache")) + } + s.cache = ocache.New(s.loadLog, cacheOpts...) + + return s.db.SetChangeReceiver(s.receiveChange) +} + +func (s *service) Name() (name string) { + return CName +} + +func (s *service) Run(ctx context.Context) (err error) { + return nil +} + +func (s *service) NewStream() *Stream { + return &Stream{ + id: atomic.AddUint64(&s.lastStreamId, 1), + logIds: make(map[string]struct{}), + mb: mb.New(consensus.Log{}, 100), + s: s, + } +} + +// AddStream to object with given logId +func (s *service) AddStream(ctx context.Context, logId []byte, stream *Stream) (err error) { + obj, err := s.getObject(ctx, logId) + if err != nil { + return err + } + obj.AddStream(stream) + return +} + +// RemoveStream from object with five logId +func (s *service) RemoveStream(ctx context.Context, logId []byte, streamId uint64) (err error) { + obj, err := s.getObject(ctx, logId) + if err != nil { + return err + } + obj.RemoveStream(streamId) + return +} + +func (s *service) loadLog(ctx context.Context, id string) (value ocache.Object, err error) { + if ctxLog := ctx.Value(ctxLogKey); ctxLog != nil { + return &object{ + logId: ctxLog.(consensus.Log).Id, + records: ctxLog.(consensus.Log).Records, + streams: make(map[uint64]*Stream), + }, nil + } + logId := logIdFromString(id) + dbLog, err := s.db.FetchLog(ctx, logId) + if err != nil { + return nil, err + } + return &object{ + logId: dbLog.Id, + records: dbLog.Records, + streams: make(map[uint64]*Stream), + }, nil +} + +func (s *service) receiveChange(logId []byte, records []consensus.Record) { + ctx := context.WithValue(context.Background(), ctxLogKey, consensus.Log{Id: logId, Records: records}) + obj, err := s.getObject(ctx, logId) + if err != nil { + log.Error("failed load object from cache", zap.Error(err)) + return + } + obj.AddRecords(records) +} + +func (s *service) getObject(ctx context.Context, logId []byte) (*object, error) { + id := logIdToString(logId) + cacheObj, err := s.cache.Get(ctx, id) + if err != nil { + return nil, err + } + return cacheObj.(*object), nil +} + +func (s *service) Close(ctx context.Context) (err error) { + return s.cache.Close() +} + +func logIdToString(logId []byte) string { + return base58.Encode(logId) +} + +func logIdFromString(s string) []byte { + logId, _ := base58.Decode(s) + return logId +} diff --git a/consensus/stream/service_test.go b/consensus/stream/service_test.go new file mode 100644 index 00000000..c804b581 --- /dev/null +++ b/consensus/stream/service_test.go @@ -0,0 +1,217 @@ +package stream + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto/consensuserr" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/db" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "testing" + "time" +) + +var ctx = context.Background() + +func TestService_NewStream(t *testing.T) { + t.Run("watch/unwatch", func(t *testing.T) { + fx := newFixture(t) + defer fx.Finish(t) + + var expLogId = []byte("logId") + var preloadLogId = []byte("preloadId") + + fx.mockDB.fetchLog = func(ctx context.Context, logId []byte) (log consensus.Log, err error) { + require.Equal(t, expLogId, logId) + return consensus.Log{ + Id: logId, + Records: []consensus.Record{ + { + Id: []byte{'1'}, + }, + }, + }, nil + } + + fx.mockDB.receiver(preloadLogId, []consensus.Record{ + { + Id: []byte{'2'}, + PrevId: []byte{'1'}, + }, + { + Id: []byte{'1'}, + }, + }) + + st1 := fx.NewStream() + sr1 := readStream(st1) + assert.Equal(t, uint64(1), sr1.id) + st1.WatchIds(ctx, [][]byte{expLogId, preloadLogId}) + st1.UnwatchIds(ctx, [][]byte{preloadLogId}) + assert.Equal(t, [][]byte{expLogId}, st1.LogIds()) + + st2 := fx.NewStream() + sr2 := readStream(st2) + assert.Equal(t, uint64(2), sr2.id) + st2.WatchIds(ctx, [][]byte{expLogId, preloadLogId}) + + fx.mockDB.receiver(expLogId, []consensus.Record{ + { + Id: []byte{'1'}, + }, + }) + fx.mockDB.receiver(expLogId, []consensus.Record{ + { + Id: []byte{'2'}, + PrevId: []byte{'1'}, + }, + { + Id: []byte{'1'}, + }, + }) + fx.mockDB.receiver(preloadLogId, []consensus.Record{ + { + Id: []byte{'3'}, + PrevId: []byte{'4'}, + }, + { + Id: []byte{'2'}, + PrevId: []byte{'1'}, + }, + { + Id: []byte{'1'}, + }, + }) + st1.Close() + st2.Close() + + for _, sr := range []*streamReader{sr1, sr2} { + select { + case <-time.After(time.Second / 3): + require.False(t, true, "timeout") + case <-sr.finished: + } + } + + require.Len(t, sr1.logs, 2) + assert.Len(t, sr1.logs[string(expLogId)].Records, 2) + assert.Equal(t, []byte{'2'}, sr1.logs[string(expLogId)].Records[0].Id) + assert.Equal(t, []byte{'2'}, sr1.logs[string(preloadLogId)].Records[0].Id) + + require.Len(t, sr2.logs, 2) + assert.Len(t, sr2.logs[string(expLogId)].Records, 2) + assert.Equal(t, []byte{'2'}, sr2.logs[string(expLogId)].Records[0].Id) + assert.Equal(t, []byte{'3'}, sr2.logs[string(preloadLogId)].Records[0].Id) + }) + t.Run("error", func(t *testing.T) { + fx := newFixture(t) + defer fx.Finish(t) + fx.mockDB.fetchLog = func(ctx context.Context, logId []byte) (log consensus.Log, err error) { + return log, consensuserr.ErrLogNotFound + } + st1 := fx.NewStream() + sr1 := readStream(st1) + id := []byte("nonExists") + assert.Equal(t, uint64(1), sr1.id) + st1.WatchIds(ctx, [][]byte{id}) + st1.Close() + <-sr1.finished + require.Len(t, sr1.logs, 1) + assert.Equal(t, consensuserr.ErrLogNotFound, sr1.logs[string(id)].Err) + }) +} + +func newFixture(t *testing.T) *fixture { + fx := &fixture{ + Service: New(), + mockDB: &mockDB{}, + a: new(app.App), + } + + fx.a.Register(fx.Service).Register(fx.mockDB) + require.NoError(t, fx.a.Start(ctx)) + return fx +} + +type fixture struct { + Service + mockDB *mockDB + a *app.App +} + +func (fx *fixture) Finish(t *testing.T) { + require.NoError(t, fx.a.Close(ctx)) +} + +func readStream(st *Stream) *streamReader { + sr := &streamReader{ + id: st.id, + stream: st, + logs: map[string]consensus.Log{}, + finished: make(chan struct{}), + } + go sr.read() + return sr +} + +type streamReader struct { + id uint64 + stream *Stream + + logs map[string]consensus.Log + finished chan struct{} +} + +func (sr *streamReader) read() { + defer close(sr.finished) + for { + logs := sr.stream.WaitLogs() + if len(logs) == 0 { + return + } + for _, l := range logs { + if el, ok := sr.logs[string(l.Id)]; !ok { + sr.logs[string(l.Id)] = l + } else { + el.Records = append(l.Records, el.Records...) + sr.logs[string(l.Id)] = el + } + } + } +} + +type mockDB struct { + receiver db.ChangeReceiver + fetchLog func(ctx context.Context, logId []byte) (log consensus.Log, err error) +} + +func (m *mockDB) AddLog(ctx context.Context, log consensus.Log) (err error) { return nil } +func (m *mockDB) AddRecord(ctx context.Context, logId []byte, record consensus.Record) (err error) { + return nil +} + +func (m *mockDB) FetchLog(ctx context.Context, logId []byte) (log consensus.Log, err error) { + return m.fetchLog(ctx, logId) +} + +func (m *mockDB) SetChangeReceiver(receiver db.ChangeReceiver) (err error) { + m.receiver = receiver + return nil +} + +func (m *mockDB) Init(a *app.App) (err error) { + return nil +} + +func (m *mockDB) Name() (name string) { + return db.CName +} + +func (m *mockDB) Run(ctx context.Context) (err error) { + return +} + +func (m *mockDB) Close(ctx context.Context) (err error) { + return +} diff --git a/consensus/stream/stream.go b/consensus/stream/stream.go new file mode 100644 index 00000000..83684677 --- /dev/null +++ b/consensus/stream/stream.go @@ -0,0 +1,86 @@ +package stream + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus" + "github.com/cheggaaa/mb/v2" + "go.uber.org/zap" + "sync" +) + +// Stream is a buffer that receives updates from object and gives back to a client +type Stream struct { + id uint64 + logIds map[string]struct{} + mu sync.Mutex + mb *mb.MB[consensus.Log] + s *service +} + +// LogIds returns watched log ids +func (s *Stream) LogIds() [][]byte { + s.mu.Lock() + defer s.mu.Unlock() + logIds := make([][]byte, 0, len(s.logIds)) + for logId := range s.logIds { + logIds = append(logIds, []byte(logId)) + } + return logIds +} + +// AddRecords adds new records to stream, called by objects +func (s *Stream) AddRecords(logId []byte, records []consensus.Record) (err error) { + return s.mb.Add(consensus.Log{Id: logId, Records: records}) +} + +// WaitLogs wait for new log records +// empty returned slice means that stream is closed +func (s *Stream) WaitLogs() []consensus.Log { + return s.mb.Wait() +} + +// WatchIds adds given ids to subscription +func (s *Stream) WatchIds(ctx context.Context, logIds [][]byte) { + s.mu.Lock() + defer s.mu.Unlock() + for _, logId := range logIds { + logIdKey := string(logId) + if _, ok := s.logIds[logIdKey]; !ok { + s.logIds[logIdKey] = struct{}{} + if addErr := s.s.AddStream(ctx, logId, s); addErr != nil { + log.Info("can't add stream for log", zap.Binary("logId", logId), zap.Error(addErr)) + _ = s.mb.Add(consensus.Log{ + Id: logId, + Err: addErr, + }) + } + } + } + return +} + +// UnwatchIds removes given ids from subscription +func (s *Stream) UnwatchIds(ctx context.Context, logIds [][]byte) { + s.mu.Lock() + defer s.mu.Unlock() + for _, logId := range logIds { + logIdKey := string(logId) + if _, ok := s.logIds[logIdKey]; ok { + delete(s.logIds, logIdKey) + if remErr := s.s.RemoveStream(ctx, logId, s.id); remErr != nil { + log.Warn("can't remove stream for log", zap.Binary("logId", logId), zap.Error(remErr)) + } + } + } + return +} + +// Close closes stream and unsubscribes all ids +func (s *Stream) Close() { + _ = s.mb.Close() + s.mu.Lock() + defer s.mu.Unlock() + for logId := range s.logIds { + _ = s.s.RemoveStream(context.TODO(), []byte(logId), s.id) + } +} diff --git a/etc/acl.yml b/etc/acl.yml new file mode 100644 index 00000000..a9a44268 --- /dev/null +++ b/etc/acl.yml @@ -0,0 +1,28 @@ +records: + - identity: A + aclChanges: + - userAdd: + identity: A + permission: admin + encryptionKey: key.Enc.A + encryptedReadKeys: [key.Read.1] + - userAdd: + identity: B + permission: admin + encryptionKey: key.Enc.B + encryptedReadKeys: [key.Read.1] + readKey: key.Read.1 +keys: + Enc: + - name: A + value: JgG4CcCbae1qEpe7mKpBzsHjZhXUmDSNVNX2B1gxFZsJyMX4V6kBQUott9zRWyeXaW1ZmpzuxDXnwSQpAnNurhXyGa9iQaAPqzY9A9VWBPD33Yy1eW7TRuVemzToh8jJQKQKnZNbF8ucTWV9qahusKzyvN8uyhrqoW2tAPfA9S3E3ognCuqbLSW6yjE2rBKayvyS1BVwzjSd6FZK4DDyjfU3pbEVjut3wytGEAn9af6sNMmyCnf2MX5vLovWs9rU8av61wD4z7HTsXyGFx4K75N4Go249Hpe9SKAT6HxhRc3yvj63krPLiQV5yMuH2UeMUXBDekUQyNmBEdn9wrur7mLqB67Bc6tcc2PP8XApBCdWJHvHjN4FktSpaG5vbCqoZbLD1oCbk36q2x9s6XM8pydVqD1J9P3nTbfgMb5pJCTFjNtgKeuKv6wjfJeA9jF1VhcJQisfsahgv9MvZ9M8FJpZTq1zKUhYDCRnZxUkraoMS5yNNVdDzaUckKEDthqik7BMWCWT79vq7uVgMwEvGwGi76gtoMg1159bbPMLZ4bdPVfhH2S9QjPrzQfwZSrzB2YeVPjWpaXDeLDity5H8n1NK2oniAQR6gE71n81neSptsuhV6o6QpQ89AU8y57XmEsou4VEryn8vUxBHhULLxrLNUouxyWamCeFiDjk5cSN6koQsf9BYKSNTPFTrwjTKForDokMhcPdMtFktKwjv7u9UEGcY4MKvNzZZkc77gHiP8bqVtdNNoLpTFUC5SZ9i7bKdHvK12HpSy7yzzPeMXJ9UwhLxkok1g81ngTbN1yxRhvYXyHZFtguCR9kvGojDjka91MTBtk551qDw9eCn2xZT9U8jqzBCjdpvSg3mRWKMPnYAGB7m7u1ye165wyGFvzcHAx3vtXjxAqLUeKYZCjv2m6V9D2Y4qH1TQNddWqH14T1JVMis971UCH9Ddpj6a3387oUnufD1P6HZN2ieJCvptrmbGVvxJYYSvmVf1dkwbtqurDRNWD7TJ7gf6iqSP549C9bxP4GpLt3ygjHmMtcuUzstBuztvunJUnQhfnJxqU6LjRdsFzm53wGWgXNxab7ZvQcPyLwsevn1b98FGPnVpS5iY4LjmqW4ugrC6HgrbsjrXiKzR1yZKhLQkCbLzPoaHb8iB5iBnCr7d4yf5CtfpFRqgoqMFdK5LNZYmDX4HzUKN6A7wC3gGiSRFTLcgGZeSMkB5Pa61CZBU7WCQgFxykycE9HRA7PiQa496GWDCV15teToCpFRsAa6jDmR1MGXPeLRqQgve49VXnQN5FL7c1VuEv5SWjeTuCnMB47DJKBaP7eKJNKgLwETALzSCMF3nRiRgeb15kfoS4BbrJ5yupjrvwmbmvNg1AYFFS5sYNWft7K8v87wQvBakRtGP71Kp8NX77XFtu6xdB7sR6jpfC6qJPyB9akWNXgCrWy9kE4ih42gwAZdUugNZ9YtEsgRM3pwb6qJhkAPyEJtrxrja859PCAgqPSQiPQN33PaMkgQ6HJknu8CrjKRiXAycZ16KLUkHV64TNhEjPTcX1a7rqpD131AYMWX8d7CCdc9Ys7RUb6BwguuNSh8rJK3x4AkMDSUsaE8ynKvpC7RXZpJ9Nxfhd + - name: B + value: JgG4CcCbae1qEpe7mKXzp7m5hNc56SSyZd9DwUaEStKJrq7RToAC2Vgd3i6hKRwa58zCWeN6Wjc3o6qrdKPEPRvcyEPysamajVo5mdQiUgWAmr97pGEsyjuRjQoC2GY2LvLiEQxEgwFgJxKGMHMiaWMtDfxCDUaDEm4bu5RdMhqRZekAWho6c3WoEeruSr14iX1TrocFNfBkBY7CjEw8kcywXCTNgtvhb2Qiwgj5AxEF4wyw4bzaNA9ctXb1hoHPFVMu6C51pkFY7jUD9zwyH3ukgnAewkGAcPNbKmaTAtMosKRVaAN97mAwXh2VRt1hWmRvVk7r76EjnVKhD4vbsKZc56RVcHTVWRVdhU7FGyPsiE5rSQAz1JQGYzxnZpX7EG77CyrmUGyfueVfRHhwY2oq8A4uQCRaQxSaJHYLowjXSxh8DQ2V6MTqyzti32C27utBYdHzLVCJSGkmdzGwrFcHqsq7nLDxmvJVErPvyReixEe8kFmqopJ3e6LLm8WdYw9K6JYBjXnEfwPzm7Von9sf3dcaGDUHYfttMyeke7fAXJkvPRje69hYVyzdQGAauuojzGkkvQWCSMK1KCMNMznRaPDCNvofrQhYrub24WhmwpKhorufdfW8Cb4T6reBDCtaWVsbuinjtL6F6Sui5aYHJFLJ6e4pPewr1P4EuZYRbMBZwN5KvDLhTGLBuBnaTqUUdF6bj2U22NoRYMogiHiftqKqiexKNDXX1Zg9RQEvxgjuVo6SBW42mVEA8agrLhruRqCmiduJxVrfqLNGeYXHXrcmMEgW7uosJbPXvTcfRvdFWS1ov7oSALvj6vhDQ28Yi9D2ETNdNsfVWAFQuwvPpW7CHQGXTitprVbqH8JYxNZuGygcLmr5efbB22Vzu4ntd1HoraQpG12qeDEUA7tXYUpoYyuSdWwKPjSAMtaQcCSfVrhKQHQuKJargrVrez8vjWuwLfvSucV7ZHe7gjqvYgULdE1ubRCRSd7DuLjEN2Vd6obzV2c3MRet7ZSf4Sp88WM5AuTyW7BjArBc4S3gUQ8rYaiZ8Tu7NCxkEzbFwWRaemZkwfvcsX3XxqjyF37tFSGkEqE5kuBvpZW72675LkDffj7kH1zA8yE6dVujJjWsNYVFJWndUtz5Vy2KCdZAbBgq19q4AtsxWPodU2N3yZXzFAFAzTrxS6V4P7Scpdau1avgRvHLcBQPunA37xaYMy8YMifJwtmRY25mnAQwZAk3eANk7tXwZd58SDnciLNvARJvwKzTQBXcshkwyy52SX8XmXDJsPnRLaHmiYBJ63Yzr5XpZuuAtxb9qrWG2NHCNxfomHokWacV1hjZPPd6ZxT1FuRozB6Qt2NLcyqY7bnTcQJb1jPUaTAGXXCR8WVmmmYo2fDQe8CdBmgyPvbzNTEJUyScBz4RdycB5PZap4SurJCWtHbuMyQbQUB6jJgURDstfXS5Akfe4oruNq9rnYcNtnsDJPtrhXHBqzDizmf1BDxR5FB2RCxzCgeAfg8WQ1Ug9PVAGTzob6ZqCrGXzWXEUniZnf1vjr7QhGKBYXEX9SWDoSMUpP4FreVDTnx15ijRZTV3p8xG5fE9e36TnugRVvTyq7XzmyPBjW2r66f1bior + Sign: + - name: A + value: 3id6ddLcoNoe9rDgGM88ET8T6TnvHm5GFqFdN6kBzn7Q8d6VUGgjeT59CNWFiaofdeRnHBvX2A5ZacMXvfwaYEFuCbug + - name: B + value: 3iiLPj6wMUQpPwTBNZcUgkbXub1jumg4AEV9LfMyFHZVc84GLyAjVbVvH6EAGhcNrxRxL82aW4BimhDZCpLsRCqx5vwj + Read: + - name: 1 + value: bamccoi5jdypwnjkiuuogkawvhkbowha4qg756uhnbkecr5vt3h4q diff --git a/etc/client.yml b/etc/client.yml new file mode 100644 index 00000000..1621ebbe --- /dev/null +++ b/etc/client.yml @@ -0,0 +1,37 @@ +anytype: + swarmKey: /key/swarm/psk/1.0.0/base16/209992e611c27d5dce8fbd2e7389f6b51da9bee980992ef60739460b536139ec +grpcServer: + listenAddrs: + - 127.0.0.1:4630 + tls: false +account: + peerId: 12D3KooWFqDLPcSZi74A1vVpDc8baTkGU6bd21AXcNxH8CFPMqp6 + peerKey: s6PUCRVry6ymxhyytNQcqSQVd2ECGyWNMIJB0FkyMUFZXbbOYSBb2yYPeQXrA9jdFdZDXyUSxtvzasvpSMpa6w== + signingKey: +UF/Do2KPeBLA0joKvnJj43jiH975JcHGjkLIkLR0p7FCFHnR1r/w4xLSa4RTjhEAQ3sDefjktShOJpalXnGvg== + encryptionKey: MIIEpQIBAAKCAQEA7NiHF065o9BfTTAWtAItg3KLqvFnRN2WVQMkjMZ/BukIj4UAd196ppexh2tnDvvqW53qVxFtXcW8oFqX9GmDJx61nnN/ce2FhXNB3aPMa7g3AchlVVB9RHyS8Z49HTkn3DVRi8I8EnbpWer35BjnpGOQ257O/kFpD1P5FzvxyTQ2gF50SyiwoDzibyT2VxgQqaDErr9BfFQKBZb8SEBeLACOlzjb2u0mCv7NeoZNfzl2KsqBC8tiCyfNahhauGfU9ZB7PtHMC1pJKTtPhXhNhQI8Rp39dd+Fr3kiTJl3Fe1f4bg4GDI7LbqCARVBbtCjsLEMi1BMzMS63bFPrPL9ewIDAQABAoIBAQCA261j+Oj3Pz8ad7diaGzqvz9N2dkdlpFb30HbdYNW9yI5M1t1lvTb/lwQGVcQx+5RujDs/gZKpnJhq+hQibdZaVPWyW/lRB0I5hRHyf5F/QuwZJ79M7VztXMdEcKeS6JsJHYhW6PjR97dlQEZkJM21RTS6CwmGOBX/o/fHDYICNxIqt4x7x1Hu+A9Qcs3LWvWq0qAkO48jSYBDeIFJ56BdXZacfIv9A7aCGWoVvih2vFIFEwdn+3z69FHmcW8JzVDK+WdkegtOlvuPcFGgDjS8cHq4zuKyEckur9EVm2Wer+GRdY2v7i9ypxiy/Ej4qJCqJLIa5rtWHmB9Dz7IyFBAoGBAPlIMpu9vAhAhJUeO48vsuEDdCn2ztyq2h4GwYcuNmfZUAnFdKRHHAfb48P7nR1uVCEEvnJYF9uUFkot8zljkDCoqc3J30sOd54PT2Jqn2vPhSWpjNJGW4Ku3CmZq/vfCH15z+bcr7whtlEswshE31bykbZlzCOSyW1tgfz2I+ydAoGBAPM6iEV6M74X+M4GoVCwUn9JMFRUX/JONOu4nfNT+1jDeABeXzVS3gzLSMJ/Vk/+1a/g6NFm73bt5PYHR8jG/jrT3xcTBPUiFj038w1MAM5Fsj2jSnIFRYFxwH8q0RfejWvKJRyWKUyTt7m43VRY9P01+YDfgt+VoLs94rV0PNr3AoGAahmWoL8S5xg+1hE2HG2a3zbPHIVV6oo1qA4MFPNQaMcPz/jg+oLhpV6sBOB1MO+ikyMnxBdGoEjZa90+5rA/0NYY3+QKTDHuK7IsgaEMFaEP9MXDkEQt8uNmBbbIgr2dKXrNSF+p1JMsvEQm64KU5Lb92fpd9s4lOZQgfYBuLekCgYEAwNvPg6+S6Y7edJZjQLSepVjmHmfMsDd81M/NRkx4Bvju5PPvcDul3+UsazRGvyVkUJH4aVnCVL3rB33cWIIYwZKP2R72llyR37bGXOu/088FtsQMWn59j1cf+HV91/xajHZ7mMAkPRj/3B6OOLxUfZZXoO0ZO6nMCcvXQGPLgR8CgYEA2W644EHrSwb4qsDsUmIEeKnjSejS8Vej4S5/g1YOyVzfWEr/5rtejw09Fv4U92SeYhp7Xp3C0UnRCduZKrpXIZJVPO8KgWLDtPi9KvHqDPzpQNRHMNrsXLpOLLv+bnnymWXjcyG8fRecU4sggaH4r1C/QyLPr+s/fLDyVUt7bC8= +apiServer: + port: "8090" +nodes: + - peerId: 12D3KooWLn13hDrZ6YRGM517fHf2zS6qhPNRu18inLMpRqn1YGKu + address: 127.0.0.1:4430 + signingKey: 3mzfKBWtn7mitFEgq8u4eysWOJ6ySbUs49irfHwcuOmi1YMpobz9anoqd4yaT1owZiRPYXqx5k2Z4sNVRE3kXA== + encryptionKey: MIIEpQIBAAKCAQEA3U7b4w9JTKE3TLM1WQ5iqdLbvUuozMp/hDEg7S15Gr6wrtLomMSBkfmVQ3Cu+CHdxAFqUFClItYlSFgtZWIFiSiQxCeaN2dmgczd9T4TlRAw6y6uJXtT9r7FIgizPP4B0/tnzPI6yYgpdwzCV2nRSjw3mMr5Nav3QYs18kYrJ1/Np2Wob5HOoRTUD++pPrToevTb7GNL/irrC8wXSE7oU6S7ix6Nh9vzEHg/V5FONBF/wWD/ri7Gy0j0qgUQ+gjxLWKr8xPDnRAve13zzo+54lGCyVvlm/rwCY9Jx378V1IuRx+S8F/GFuVozHD4XVaoSTtpCWPBQNSKDXgaIIKDowIDAQABAoIBACpMXj6ht1LMJXOldPbWhwkKYjFl+pdZxNGRSkfKvzDbbY2chhRcyp8J4vuG2ApY/rftxVIgd8+Wun1/TP3ppEE43aKAJzubqb35WBr9iGSfOZpZy7MiRUQN5kPBAfEQY20OyiIj0hSez74PVD283eGgbMfpU4Rsn8+JOgBaZPkbPViJLJY8PyHU6vwWw60dye1iJTz9yuBtoEqY0XKxnLaVXTQaWx0Te+VYU8twxDgXFWRaXtHuk7xnxOkCZDLrzIvuOYa5lsLoT8K62LDeXbyHBPhbdW0j4ZYzAOTsaUWpjuJzef9aj3JJdfyADiqb5iu6HHksvKzkZEau34zjilECgYEA/c8ZJm62uJMHNssTJYiLRw89l5hYwIZ/1TXdFRF8+xrTin5opYjpscSTO5bY2IYqLx2xuPiJCY1eGGB9L/RtkaVh51ySzq0d+4zpPIRKFcOOgdxHwlgoCgIhQECyfJZNMFGBUIlPXZ/phvXOXRvWFzDPhqThenVG2QzF+wLP0AUCgYEA3zfviQFJ1FOKJMozYO3tUZFmsIrAcO9hfuE7uuWz0Fw2m1XiwxjuOr1RbsSsh/lKke2h4tiGrlfiFhwCpIp91NkVTFrtFOQxbDxkYLkFiWkZDkOaK9YhKMa2cgEm3p+RGawokjbm51LKf+cbYN9xGaAe3y2WzIE4kNpfWE4SXYcCgYEAoagcrrvpqZoMCDxED63ud+4fHsUsEkQYe6Z5EAg5gH5PqnBlGrofjthTpqqnpxGdILFbFyNFtU3TVtduJPMcLp4Vw5TU9MqSxDu1+pOP1FjgFZpGImSf6+/7Wb9bb7sToujm4nLymAFYblt1exxVuiOeqnWuH58+5tQZ7YyW7DkCgYEAl7WuqZEkmpiEpWh/7vsGdo+6GXbUQG2R9+gg7m+7/HsP6hc/XZYOJAIT3JLzKB84nWHCyyiasNeuI5S5/xbZWtaH8TNDOxW0uXl6R3q41qGFk/pCSFTqiIo16dn6jwgoWCh4EpgZ61KLqs5p/zcd6Wq4ULrtaOTSizC/6IZ3WPUCgYEA6xCJy3+ICCgr8/c7hfd2Ylb3aOsXIffdgALhXjDcrNUCqgB4R+S3WReAwrABemQGl4tySQE/1f3Ru7SzMMciFogGyJ/YSXqSi6Y8oDD7MqlKPiWlN6WY1nSRMlLbkUOqpA5JaDM0kcmXjZpBBQr277GOnh9uKN8zUy5xoptctxI= + - peerId: 12D3KooWLtuKtCPBYrFJV1NdejiCr2s614ppe9rmUXnkTHtAUD5U + address: 127.0.0.1:4431 + signingKey: 07JMoW5cQUtGO9nNIGQo9e99b7Wf/4YvTtNEA0lt4gCkmhwB1EB9ay+kitxVJJgmdyGLxbUUlGqwXsAj0zlHWw== + encryptionKey: MIIEpAIBAAKCAQEA7cA6J/icl8wseeXkt8oJr5AeYadUAG5EdCOdHj4S/Z7ivff4MOIKAeQITpq+rqhmXxOePYXSpQXE20Y9PW9tuw4gzOuq1ylSG/MWMcLDH1eIxg66rnmUqUbdiW4GGJjVjc9jvN0Up+MfSrUF6fM0jWTFoXVJQIeQQGERCIYjFzjfBl1xYvPghdxNgei/K5ZGYRggT28143XdIH4KTXGtp51hAKoyY9eCqYMtm9wvjxazhPVxO2CsYaqMxBLshY3jfHNqJnx8u6+h4Bl4uUcdbLNUgMcEgk7ehbQp2K0CqNoKXxbCTI6V57UVcJHDIaO5B6FyR6BguzHHNPJ4yd3q9wIDAQABAoIBAQCm2Mf3VRlPzhFIWnVwJXE2q8Umcu8Yfkm712Jj3twk8GPfPS4H4Bl1yjmqMB6xI6zz/CiItGlnNe04lMpVWuV+6CNMq/ZwmKbuxmFE+pFEZYGuvJd16gzR3tGJqJTOnjMAGhK8b8oXJ+TF4NQNooe20ol/DXgiuQAargPuH3RwzjYmF3N8VI4KUc3LaG4TwVXn4LwPOxrQSnfwJlZwLml1HAKOV0qcG0mXX6ZXOpoVhEoRPdQyUHc8ZW+53Agbtind7bYh5TsMVDFUrcgNwnwTOsWjil049la1IJO2uMRluacKlrtyzEp6zqrW8ZJO7mYAO69x4WyGqf2ZgIdA6djBAoGBAPqRHWAIgPa80eXbwCYkRtUG/ONBsQGi7+wm6nyhkXvNXJeokgH2DCgLH2+fW2scfOJuZc9r5WftEjOBvNfr2LDcwdyTSTh21WYcPSZx9HDf2d5/SWTcjNcyU0b5qfWIUKi/Zm9UY7r3X7yMA5dUD/cvu1PBJ5NWFrK1Gm2ph44dAoGBAPLn+LkHweU0fbxQq/76T5yVVpMKUaE9xwrJlUxEDPAQGnLPbFg4JeUt/YPhsOV85W4c4oQE+uFZrF0uf+1fEnS6MOJ+sq668upzC2hBp1B5138wM7615v1rvXVVH6qXfFop67FdBzPHt1NAN43mEIBZHTQ5hSVXFlYSZp9mxuEjAoGBAKCzUVO2IIAeub/iIGpV+dfGk4ptJ0kVZyreCqXEObpdC3V496uqUkGcYJ0GZ2ta6f2PMFzHpmnw8it2mdchu+gyrWL6U4uTK2pB0jZF/7Ak4WaB3GCD0xBxhleO6CJBOvn/R4M/bHcNEKmsYuE7WMIAKvScfPVR0VzsKfcLM5VBAoGAVvWg32zdh1bBZLdku8WU1rPH6KAbFSRuq3f7UPBTyWWaclu7p+GB/4f1aE9V6vJJmKASn7zArAhUYo+REMOmcc9uTMea5F7dM/23qb1HTtIvycLR44ZviW4Wx3iP+5x70jOLw1VQjMME6HLm8I/afHhqshWdiv6ganPv9UTwEg0CgYBSDi2dqg8F7ij5CN+LMDLSn3b8GCw+7efGIt7imm/O2V/FlHD40IA6qGg6DXNQrnoZQt94nMb1cZEvm1dxi6rmQNrhCyoMogAaPqgFhZGq1OjmhVZiXFUWy4WAcjdzFc9wZd3/XtaofRKHLK+ngTFhhVApKypLk3Rg9bCAAjzyVg== + - peerId: 12D3KooWDCypXSyN6ppuMZGxVnBd1ZQCMV4y7Bn187S4duYmf8rA + address: 127.0.0.1:4432 + signingKey: SGyNE0dFaQgtgNuzdcO7LB+TEz9VHAOtlQLk6WWkrkQyXiZV3casg8Q2/4PO1Oylc8Fu72RU001Hclj5JCbiLw== + encryptionKey: MIIEpAIBAAKCAQEA0k3mw4FyexRkLgLjHzYs4Ppeyv6r9ZrP00imNf15JTuM8ajMx5oJX7JQTm8KOLRJjUdZZAd5Gtp0ezfYAQK1ZjEWwCmfp8j8FBgJIDSLpjxl88SXMLgATXYfhklnQvKlQjs/X3Ka4zdTrav2tMH9IAo6TSNZhlPQNsUory1SGHs+KqHv4p0sG8oWuKYhfBj8rWHQdUVptkIBKgojFDeJJD04Tbf9kUakbK/8KuXB6zF5H4WN3p4rMMwkClyTGeYO4LDg5TzVn8NnUi3/b/vO/3us1G/TMoRe/6umUfpQxrwo+7S2T6A4YwetWRp6xALLhp+HfAWnn0lA/D8/w1WpKwIDAQABAoIBAQC5cdQxRa5rddm48PbSCPWeFWkNW3DLDI6CYyedqDvxZwer+QtKXzww1I4X+7ZptiC9odLjb+uMkGHyXZXtnjPTPyounQWZ8JLILUGu0mbqWYwVXp9raHVr2OOHiKaz1D+BnbkOM4L9JUZ2eJL9ZaoNXLd4WdmRp8qM4WI0xqQDzOANx2HhyL/+dJmQeIUND+pdeH+Z+fYowU3ho32txNvBnMXQhF1T5K9i1VO5W49RAjIRbENsT+paPGKbNubDHRt1j36ktK4eC4HSdgv8tccdsGyrEiIbAt1XsTZfM8ie4D3A8RhSxiTC6Fkgv6vIm+iFTLzBFZKesOBcd8sfKeyBAoGBAOts5PQQJhldPDzlbnqzxMOR98WHbkVZjCqWSkNA34vqyFuPcRuX0rHK/qpg23ilbUP0fGMDTGgFzTt51FZLL16SXyRfjNhzjdmryryeddQwbp92ta2GEgnU6t1FyCuSCtcLDKJd/D9A9dC5UI6z+ES4TOnbR3nakXK9t4cUOFthAoGBAOSu+wL+SEA5erR+m3LpOsELK68CCJQPxn3VpoVfJZawgF+fEoXVMLTERxJput1+ADomIEdNc9ex86TjKx9gJ4piNHscRPFeT/AgESOIGHLOc1gk2DPqNj6wBIarUJQ9t4KcHScboh1dTPJeqqv2NSwIiLQoqFUIhfKZLnrW3zwLAoGBAJh0hC+o5YM3ZXLqAIllMN6VACbidP5j5ukNOjojIKCzAdyJH24G+2I3WoNrBbUzK3b+NC7KTAhw+V6ynlbjiWFs2D/twH/LFOkI3tkWpKcsVfbeIPimAbhsMUvpjJ7qjCqF9UCQLHGp14W6+/ftg7C8yNIINlkquVXclaTb60MBAoGAPqmL8ogG+EJH00mWAujRxq/u6meePiQMedKfbJBj1mTK6GjIRI/kZsQZzXvXTnYGTejAk4kvov0KDDaLTG+mpg6+3rUiVxlGwj+nMptKR7s2dAK0k5UsBAVrWBN9YwF+VXW9r0etJmq4ePljvvcaHtS/0M4LQjGxsoYy7EoQpX0CgYAhnf0McB7F1MxSjB0soMNv/v5utVzVihS3re2yKNdkI/YUEMB+yU3Q4gh+OljjBM6Y5To3BsQBAx4l2CysMKFHjIE/5AtdbvIS+chZZqB3vcZXSayvX8P1Z1uFdw/saiO2cRDJmR+TxaOPa2C9SzDoNTACthwLErHfzvEvVroKmw== +space: + gcTTL: 60 + syncPeriod: 10 +storage: + path: db +metric: + addr: "" +log: + production: false + defaultLevel: "" + namedLevels: {} diff --git a/etc/config.1.yml b/etc/config.1.yml deleted file mode 100644 index 0b704d76..00000000 --- a/etc/config.1.yml +++ /dev/null @@ -1,20 +0,0 @@ -anytype: - swarmKey: /key/swarm/psk/1.0.0/base16/209992e611c27d5dce8fbd2e7389f6b51da9bee980992ef60739460b536139ec -grpcServer: - listenAddrs: - - 127.0.0.1:4432 -account: - peerId: 12D3KooWT3c7Y5zvWhhjSxd5Ve3GKZi6WCsG6JHxcxgXixRFdBbw - signingKey: 3iiLPj6wMUQpPwTBNZcUgkbXub1jumg4AEV9LfMyFHZVc84GLyAjVbVvH6EAGhcNrxRxL82aW4BimhDZCpLsRCqx5vwj - encryptionKey: JgG4CcCbae1qEpe7mKXzp7m5hNc56SSyZd9DwUaEStKJrq7RToAC2Vgd3i6hKRwa58zCWeN6Wjc3o6qrdKPEPRvcyEPysamajVo5mdQiUgWAmr97pGEsyjuRjQoC2GY2LvLiEQxEgwFgJxKGMHMiaWMtDfxCDUaDEm4bu5RdMhqRZekAWho6c3WoEeruSr14iX1TrocFNfBkBY7CjEw8kcywXCTNgtvhb2Qiwgj5AxEF4wyw4bzaNA9ctXb1hoHPFVMu6C51pkFY7jUD9zwyH3ukgnAewkGAcPNbKmaTAtMosKRVaAN97mAwXh2VRt1hWmRvVk7r76EjnVKhD4vbsKZc56RVcHTVWRVdhU7FGyPsiE5rSQAz1JQGYzxnZpX7EG77CyrmUGyfueVfRHhwY2oq8A4uQCRaQxSaJHYLowjXSxh8DQ2V6MTqyzti32C27utBYdHzLVCJSGkmdzGwrFcHqsq7nLDxmvJVErPvyReixEe8kFmqopJ3e6LLm8WdYw9K6JYBjXnEfwPzm7Von9sf3dcaGDUHYfttMyeke7fAXJkvPRje69hYVyzdQGAauuojzGkkvQWCSMK1KCMNMznRaPDCNvofrQhYrub24WhmwpKhorufdfW8Cb4T6reBDCtaWVsbuinjtL6F6Sui5aYHJFLJ6e4pPewr1P4EuZYRbMBZwN5KvDLhTGLBuBnaTqUUdF6bj2U22NoRYMogiHiftqKqiexKNDXX1Zg9RQEvxgjuVo6SBW42mVEA8agrLhruRqCmiduJxVrfqLNGeYXHXrcmMEgW7uosJbPXvTcfRvdFWS1ov7oSALvj6vhDQ28Yi9D2ETNdNsfVWAFQuwvPpW7CHQGXTitprVbqH8JYxNZuGygcLmr5efbB22Vzu4ntd1HoraQpG12qeDEUA7tXYUpoYyuSdWwKPjSAMtaQcCSfVrhKQHQuKJargrVrez8vjWuwLfvSucV7ZHe7gjqvYgULdE1ubRCRSd7DuLjEN2Vd6obzV2c3MRet7ZSf4Sp88WM5AuTyW7BjArBc4S3gUQ8rYaiZ8Tu7NCxkEzbFwWRaemZkwfvcsX3XxqjyF37tFSGkEqE5kuBvpZW72675LkDffj7kH1zA8yE6dVujJjWsNYVFJWndUtz5Vy2KCdZAbBgq19q4AtsxWPodU2N3yZXzFAFAzTrxS6V4P7Scpdau1avgRvHLcBQPunA37xaYMy8YMifJwtmRY25mnAQwZAk3eANk7tXwZd58SDnciLNvARJvwKzTQBXcshkwyy52SX8XmXDJsPnRLaHmiYBJ63Yzr5XpZuuAtxb9qrWG2NHCNxfomHokWacV1hjZPPd6ZxT1FuRozB6Qt2NLcyqY7bnTcQJb1jPUaTAGXXCR8WVmmmYo2fDQe8CdBmgyPvbzNTEJUyScBz4RdycB5PZap4SurJCWtHbuMyQbQUB6jJgURDstfXS5Akfe4oruNq9rnYcNtnsDJPtrhXHBqzDizmf1BDxR5FB2RCxzCgeAfg8WQ1Ug9PVAGTzob6ZqCrGXzWXEUniZnf1vjr7QhGKBYXEX9SWDoSMUpP4FreVDTnx15ijRZTV3p8xG5fE9e36TnugRVvTyq7XzmyPBjW2r66f1bior -apiServer: - port: "8081" -nodes: - - peerId: 12D3KooWMHuhZgK2skkLrvL51QQTXaXQKYy2QqfvPNBFnzR2ubA1 - address: 127.0.0.1:4430 - signingKey: 3id6ddLcoNoe9rDgGM88ET8T6TnvHm5GFqFdN6kBzn7Q8d6VUGgjeT59CNWFiaofdeRnHBvX2A5ZacMXvfwaYEFuCbug - encryptionKey: JgG4CcCbae1qEpe7mKpBzsHjZhXUmDSNVNX2B1gxFZsJyMX4V6kBQUott9zRWyeXaW1ZmpzuxDXnwSQpAnNurhXyGa9iQaAPqzY9A9VWBPD33Yy1eW7TRuVemzToh8jJQKQKnZNbF8ucTWV9qahusKzyvN8uyhrqoW2tAPfA9S3E3ognCuqbLSW6yjE2rBKayvyS1BVwzjSd6FZK4DDyjfU3pbEVjut3wytGEAn9af6sNMmyCnf2MX5vLovWs9rU8av61wD4z7HTsXyGFx4K75N4Go249Hpe9SKAT6HxhRc3yvj63krPLiQV5yMuH2UeMUXBDekUQyNmBEdn9wrur7mLqB67Bc6tcc2PP8XApBCdWJHvHjN4FktSpaG5vbCqoZbLD1oCbk36q2x9s6XM8pydVqD1J9P3nTbfgMb5pJCTFjNtgKeuKv6wjfJeA9jF1VhcJQisfsahgv9MvZ9M8FJpZTq1zKUhYDCRnZxUkraoMS5yNNVdDzaUckKEDthqik7BMWCWT79vq7uVgMwEvGwGi76gtoMg1159bbPMLZ4bdPVfhH2S9QjPrzQfwZSrzB2YeVPjWpaXDeLDity5H8n1NK2oniAQR6gE71n81neSptsuhV6o6QpQ89AU8y57XmEsou4VEryn8vUxBHhULLxrLNUouxyWamCeFiDjk5cSN6koQsf9BYKSNTPFTrwjTKForDokMhcPdMtFktKwjv7u9UEGcY4MKvNzZZkc77gHiP8bqVtdNNoLpTFUC5SZ9i7bKdHvK12HpSy7yzzPeMXJ9UwhLxkok1g81ngTbN1yxRhvYXyHZFtguCR9kvGojDjka91MTBtk551qDw9eCn2xZT9U8jqzBCjdpvSg3mRWKMPnYAGB7m7u1ye165wyGFvzcHAx3vtXjxAqLUeKYZCjv2m6V9D2Y4qH1TQNddWqH14T1JVMis971UCH9Ddpj6a3387oUnufD1P6HZN2ieJCvptrmbGVvxJYYSvmVf1dkwbtqurDRNWD7TJ7gf6iqSP549C9bxP4GpLt3ygjHmMtcuUzstBuztvunJUnQhfnJxqU6LjRdsFzm53wGWgXNxab7ZvQcPyLwsevn1b98FGPnVpS5iY4LjmqW4ugrC6HgrbsjrXiKzR1yZKhLQkCbLzPoaHb8iB5iBnCr7d4yf5CtfpFRqgoqMFdK5LNZYmDX4HzUKN6A7wC3gGiSRFTLcgGZeSMkB5Pa61CZBU7WCQgFxykycE9HRA7PiQa496GWDCV15teToCpFRsAa6jDmR1MGXPeLRqQgve49VXnQN5FL7c1VuEv5SWjeTuCnMB47DJKBaP7eKJNKgLwETALzSCMF3nRiRgeb15kfoS4BbrJ5yupjrvwmbmvNg1AYFFS5sYNWft7K8v87wQvBakRtGP71Kp8NX77XFtu6xdB7sR6jpfC6qJPyB9akWNXgCrWy9kE4ih42gwAZdUugNZ9YtEsgRM3pwb6qJhkAPyEJtrxrja859PCAgqPSQiPQN33PaMkgQ6HJknu8CrjKRiXAycZ16KLUkHV64TNhEjPTcX1a7rqpD131AYMWX8d7CCdc9Ys7RUb6BwguuNSh8rJK3x4AkMDSUsaE8ynKvpC7RXZpJ9Nxfhd - - peerId: 12D3KooWT3c7Y5zvWhhjSxd5Ve3GKZi6WCsG6JHxcxgXixRFdBbw - address: 127.0.0.1:4432 - signingKey: 3iiLPj6wMUQpPwTBNZcUgkbXub1jumg4AEV9LfMyFHZVc84GLyAjVbVvH6EAGhcNrxRxL82aW4BimhDZCpLsRCqx5vwj - encryptionKey: JgG4CcCbae1qEpe7mKXzp7m5hNc56SSyZd9DwUaEStKJrq7RToAC2Vgd3i6hKRwa58zCWeN6Wjc3o6qrdKPEPRvcyEPysamajVo5mdQiUgWAmr97pGEsyjuRjQoC2GY2LvLiEQxEgwFgJxKGMHMiaWMtDfxCDUaDEm4bu5RdMhqRZekAWho6c3WoEeruSr14iX1TrocFNfBkBY7CjEw8kcywXCTNgtvhb2Qiwgj5AxEF4wyw4bzaNA9ctXb1hoHPFVMu6C51pkFY7jUD9zwyH3ukgnAewkGAcPNbKmaTAtMosKRVaAN97mAwXh2VRt1hWmRvVk7r76EjnVKhD4vbsKZc56RVcHTVWRVdhU7FGyPsiE5rSQAz1JQGYzxnZpX7EG77CyrmUGyfueVfRHhwY2oq8A4uQCRaQxSaJHYLowjXSxh8DQ2V6MTqyzti32C27utBYdHzLVCJSGkmdzGwrFcHqsq7nLDxmvJVErPvyReixEe8kFmqopJ3e6LLm8WdYw9K6JYBjXnEfwPzm7Von9sf3dcaGDUHYfttMyeke7fAXJkvPRje69hYVyzdQGAauuojzGkkvQWCSMK1KCMNMznRaPDCNvofrQhYrub24WhmwpKhorufdfW8Cb4T6reBDCtaWVsbuinjtL6F6Sui5aYHJFLJ6e4pPewr1P4EuZYRbMBZwN5KvDLhTGLBuBnaTqUUdF6bj2U22NoRYMogiHiftqKqiexKNDXX1Zg9RQEvxgjuVo6SBW42mVEA8agrLhruRqCmiduJxVrfqLNGeYXHXrcmMEgW7uosJbPXvTcfRvdFWS1ov7oSALvj6vhDQ28Yi9D2ETNdNsfVWAFQuwvPpW7CHQGXTitprVbqH8JYxNZuGygcLmr5efbB22Vzu4ntd1HoraQpG12qeDEUA7tXYUpoYyuSdWwKPjSAMtaQcCSfVrhKQHQuKJargrVrez8vjWuwLfvSucV7ZHe7gjqvYgULdE1ubRCRSd7DuLjEN2Vd6obzV2c3MRet7ZSf4Sp88WM5AuTyW7BjArBc4S3gUQ8rYaiZ8Tu7NCxkEzbFwWRaemZkwfvcsX3XxqjyF37tFSGkEqE5kuBvpZW72675LkDffj7kH1zA8yE6dVujJjWsNYVFJWndUtz5Vy2KCdZAbBgq19q4AtsxWPodU2N3yZXzFAFAzTrxS6V4P7Scpdau1avgRvHLcBQPunA37xaYMy8YMifJwtmRY25mnAQwZAk3eANk7tXwZd58SDnciLNvARJvwKzTQBXcshkwyy52SX8XmXDJsPnRLaHmiYBJ63Yzr5XpZuuAtxb9qrWG2NHCNxfomHokWacV1hjZPPd6ZxT1FuRozB6Qt2NLcyqY7bnTcQJb1jPUaTAGXXCR8WVmmmYo2fDQe8CdBmgyPvbzNTEJUyScBz4RdycB5PZap4SurJCWtHbuMyQbQUB6jJgURDstfXS5Akfe4oruNq9rnYcNtnsDJPtrhXHBqzDizmf1BDxR5FB2RCxzCgeAfg8WQ1Ug9PVAGTzob6ZqCrGXzWXEUniZnf1vjr7QhGKBYXEX9SWDoSMUpP4FreVDTnx15ijRZTV3p8xG5fE9e36TnugRVvTyq7XzmyPBjW2r66f1bior diff --git a/etc/config.2.yml b/etc/config.2.yml deleted file mode 100644 index 701fdc5f..00000000 --- a/etc/config.2.yml +++ /dev/null @@ -1,16 +0,0 @@ -anytype: - swarmKey: "/key/swarm/psk/1.0.0/base16/209992e611c27d5dce8fbd2e7389f6b51da9bee980992ef60739460b536139ec" - -grpcServer: - listenAddrs: - - "127.0.0.1:4432" - -peerList: - myId: - peerId: "12D3KooWK6c1CPLL4Bvjim9A9SDRmehy12hYjbqX1VASHKfH7W7H" - privKey: "jynYZBgtM4elT+6e7M5UERTJCZgUd3hDdmQjCqTpApyJ4h53V6TQan4Ru4OXqz+91rCLjpIVdphhaB0l+TvNsA==" - remote: - - peerId: "12D3KooWA4FLWvrMbCtp2MbzKcC5RRN7HqxxBxPcSADFfzrGiW3U" - addr: "127.0.0.1:4431" - - peerId: "12D3KooWHJpSEMQUZCyK8TK181LhjzntWjKfXDr7MWks9cw41R2C" - addr: "127.0.0.1:4430" diff --git a/etc/config.yml b/etc/config.yml index c9b15df0..7e3030e5 100644 --- a/etc/config.yml +++ b/etc/config.yml @@ -3,20 +3,35 @@ anytype: grpcServer: listenAddrs: - 127.0.0.1:4430 - - 127.0.0.1:4431 tls: false account: - peerId: 12D3KooWMHuhZgK2skkLrvL51QQTXaXQKYy2QqfvPNBFnzR2ubA1 - signingKey: 3id6ddLcoNoe9rDgGM88ET8T6TnvHm5GFqFdN6kBzn7Q8d6VUGgjeT59CNWFiaofdeRnHBvX2A5ZacMXvfwaYEFuCbug - encryptionKey: JgG4CcCbae1qEpe7mKpBzsHjZhXUmDSNVNX2B1gxFZsJyMX4V6kBQUott9zRWyeXaW1ZmpzuxDXnwSQpAnNurhXyGa9iQaAPqzY9A9VWBPD33Yy1eW7TRuVemzToh8jJQKQKnZNbF8ucTWV9qahusKzyvN8uyhrqoW2tAPfA9S3E3ognCuqbLSW6yjE2rBKayvyS1BVwzjSd6FZK4DDyjfU3pbEVjut3wytGEAn9af6sNMmyCnf2MX5vLovWs9rU8av61wD4z7HTsXyGFx4K75N4Go249Hpe9SKAT6HxhRc3yvj63krPLiQV5yMuH2UeMUXBDekUQyNmBEdn9wrur7mLqB67Bc6tcc2PP8XApBCdWJHvHjN4FktSpaG5vbCqoZbLD1oCbk36q2x9s6XM8pydVqD1J9P3nTbfgMb5pJCTFjNtgKeuKv6wjfJeA9jF1VhcJQisfsahgv9MvZ9M8FJpZTq1zKUhYDCRnZxUkraoMS5yNNVdDzaUckKEDthqik7BMWCWT79vq7uVgMwEvGwGi76gtoMg1159bbPMLZ4bdPVfhH2S9QjPrzQfwZSrzB2YeVPjWpaXDeLDity5H8n1NK2oniAQR6gE71n81neSptsuhV6o6QpQ89AU8y57XmEsou4VEryn8vUxBHhULLxrLNUouxyWamCeFiDjk5cSN6koQsf9BYKSNTPFTrwjTKForDokMhcPdMtFktKwjv7u9UEGcY4MKvNzZZkc77gHiP8bqVtdNNoLpTFUC5SZ9i7bKdHvK12HpSy7yzzPeMXJ9UwhLxkok1g81ngTbN1yxRhvYXyHZFtguCR9kvGojDjka91MTBtk551qDw9eCn2xZT9U8jqzBCjdpvSg3mRWKMPnYAGB7m7u1ye165wyGFvzcHAx3vtXjxAqLUeKYZCjv2m6V9D2Y4qH1TQNddWqH14T1JVMis971UCH9Ddpj6a3387oUnufD1P6HZN2ieJCvptrmbGVvxJYYSvmVf1dkwbtqurDRNWD7TJ7gf6iqSP549C9bxP4GpLt3ygjHmMtcuUzstBuztvunJUnQhfnJxqU6LjRdsFzm53wGWgXNxab7ZvQcPyLwsevn1b98FGPnVpS5iY4LjmqW4ugrC6HgrbsjrXiKzR1yZKhLQkCbLzPoaHb8iB5iBnCr7d4yf5CtfpFRqgoqMFdK5LNZYmDX4HzUKN6A7wC3gGiSRFTLcgGZeSMkB5Pa61CZBU7WCQgFxykycE9HRA7PiQa496GWDCV15teToCpFRsAa6jDmR1MGXPeLRqQgve49VXnQN5FL7c1VuEv5SWjeTuCnMB47DJKBaP7eKJNKgLwETALzSCMF3nRiRgeb15kfoS4BbrJ5yupjrvwmbmvNg1AYFFS5sYNWft7K8v87wQvBakRtGP71Kp8NX77XFtu6xdB7sR6jpfC6qJPyB9akWNXgCrWy9kE4ih42gwAZdUugNZ9YtEsgRM3pwb6qJhkAPyEJtrxrja859PCAgqPSQiPQN33PaMkgQ6HJknu8CrjKRiXAycZ16KLUkHV64TNhEjPTcX1a7rqpD131AYMWX8d7CCdc9Ys7RUb6BwguuNSh8rJK3x4AkMDSUsaE8ynKvpC7RXZpJ9Nxfhd + peerId: 12D3KooWLn13hDrZ6YRGM517fHf2zS6qhPNRu18inLMpRqn1YGKu + peerKey: 3mzfKBWtn7mitFEgq8u4eysWOJ6ySbUs49irfHwcuOmi1YMpobz9anoqd4yaT1owZiRPYXqx5k2Z4sNVRE3kXA== + signingKey: 3mzfKBWtn7mitFEgq8u4eysWOJ6ySbUs49irfHwcuOmi1YMpobz9anoqd4yaT1owZiRPYXqx5k2Z4sNVRE3kXA== + encryptionKey: MIIEpQIBAAKCAQEA3U7b4w9JTKE3TLM1WQ5iqdLbvUuozMp/hDEg7S15Gr6wrtLomMSBkfmVQ3Cu+CHdxAFqUFClItYlSFgtZWIFiSiQxCeaN2dmgczd9T4TlRAw6y6uJXtT9r7FIgizPP4B0/tnzPI6yYgpdwzCV2nRSjw3mMr5Nav3QYs18kYrJ1/Np2Wob5HOoRTUD++pPrToevTb7GNL/irrC8wXSE7oU6S7ix6Nh9vzEHg/V5FONBF/wWD/ri7Gy0j0qgUQ+gjxLWKr8xPDnRAve13zzo+54lGCyVvlm/rwCY9Jx378V1IuRx+S8F/GFuVozHD4XVaoSTtpCWPBQNSKDXgaIIKDowIDAQABAoIBACpMXj6ht1LMJXOldPbWhwkKYjFl+pdZxNGRSkfKvzDbbY2chhRcyp8J4vuG2ApY/rftxVIgd8+Wun1/TP3ppEE43aKAJzubqb35WBr9iGSfOZpZy7MiRUQN5kPBAfEQY20OyiIj0hSez74PVD283eGgbMfpU4Rsn8+JOgBaZPkbPViJLJY8PyHU6vwWw60dye1iJTz9yuBtoEqY0XKxnLaVXTQaWx0Te+VYU8twxDgXFWRaXtHuk7xnxOkCZDLrzIvuOYa5lsLoT8K62LDeXbyHBPhbdW0j4ZYzAOTsaUWpjuJzef9aj3JJdfyADiqb5iu6HHksvKzkZEau34zjilECgYEA/c8ZJm62uJMHNssTJYiLRw89l5hYwIZ/1TXdFRF8+xrTin5opYjpscSTO5bY2IYqLx2xuPiJCY1eGGB9L/RtkaVh51ySzq0d+4zpPIRKFcOOgdxHwlgoCgIhQECyfJZNMFGBUIlPXZ/phvXOXRvWFzDPhqThenVG2QzF+wLP0AUCgYEA3zfviQFJ1FOKJMozYO3tUZFmsIrAcO9hfuE7uuWz0Fw2m1XiwxjuOr1RbsSsh/lKke2h4tiGrlfiFhwCpIp91NkVTFrtFOQxbDxkYLkFiWkZDkOaK9YhKMa2cgEm3p+RGawokjbm51LKf+cbYN9xGaAe3y2WzIE4kNpfWE4SXYcCgYEAoagcrrvpqZoMCDxED63ud+4fHsUsEkQYe6Z5EAg5gH5PqnBlGrofjthTpqqnpxGdILFbFyNFtU3TVtduJPMcLp4Vw5TU9MqSxDu1+pOP1FjgFZpGImSf6+/7Wb9bb7sToujm4nLymAFYblt1exxVuiOeqnWuH58+5tQZ7YyW7DkCgYEAl7WuqZEkmpiEpWh/7vsGdo+6GXbUQG2R9+gg7m+7/HsP6hc/XZYOJAIT3JLzKB84nWHCyyiasNeuI5S5/xbZWtaH8TNDOxW0uXl6R3q41qGFk/pCSFTqiIo16dn6jwgoWCh4EpgZ61KLqs5p/zcd6Wq4ULrtaOTSizC/6IZ3WPUCgYEA6xCJy3+ICCgr8/c7hfd2Ylb3aOsXIffdgALhXjDcrNUCqgB4R+S3WReAwrABemQGl4tySQE/1f3Ru7SzMMciFogGyJ/YSXqSi6Y8oDD7MqlKPiWlN6WY1nSRMlLbkUOqpA5JaDM0kcmXjZpBBQr277GOnh9uKN8zUy5xoptctxI= apiServer: port: "8084" nodes: - - peerId: 12D3KooWMHuhZgK2skkLrvL51QQTXaXQKYy2QqfvPNBFnzR2ubA1 + - peerId: 12D3KooWLn13hDrZ6YRGM517fHf2zS6qhPNRu18inLMpRqn1YGKu address: 127.0.0.1:4430 - signingKey: 3id6ddLcoNoe9rDgGM88ET8T6TnvHm5GFqFdN6kBzn7Q8d6VUGgjeT59CNWFiaofdeRnHBvX2A5ZacMXvfwaYEFuCbug - encryptionKey: JgG4CcCbae1qEpe7mKpBzsHjZhXUmDSNVNX2B1gxFZsJyMX4V6kBQUott9zRWyeXaW1ZmpzuxDXnwSQpAnNurhXyGa9iQaAPqzY9A9VWBPD33Yy1eW7TRuVemzToh8jJQKQKnZNbF8ucTWV9qahusKzyvN8uyhrqoW2tAPfA9S3E3ognCuqbLSW6yjE2rBKayvyS1BVwzjSd6FZK4DDyjfU3pbEVjut3wytGEAn9af6sNMmyCnf2MX5vLovWs9rU8av61wD4z7HTsXyGFx4K75N4Go249Hpe9SKAT6HxhRc3yvj63krPLiQV5yMuH2UeMUXBDekUQyNmBEdn9wrur7mLqB67Bc6tcc2PP8XApBCdWJHvHjN4FktSpaG5vbCqoZbLD1oCbk36q2x9s6XM8pydVqD1J9P3nTbfgMb5pJCTFjNtgKeuKv6wjfJeA9jF1VhcJQisfsahgv9MvZ9M8FJpZTq1zKUhYDCRnZxUkraoMS5yNNVdDzaUckKEDthqik7BMWCWT79vq7uVgMwEvGwGi76gtoMg1159bbPMLZ4bdPVfhH2S9QjPrzQfwZSrzB2YeVPjWpaXDeLDity5H8n1NK2oniAQR6gE71n81neSptsuhV6o6QpQ89AU8y57XmEsou4VEryn8vUxBHhULLxrLNUouxyWamCeFiDjk5cSN6koQsf9BYKSNTPFTrwjTKForDokMhcPdMtFktKwjv7u9UEGcY4MKvNzZZkc77gHiP8bqVtdNNoLpTFUC5SZ9i7bKdHvK12HpSy7yzzPeMXJ9UwhLxkok1g81ngTbN1yxRhvYXyHZFtguCR9kvGojDjka91MTBtk551qDw9eCn2xZT9U8jqzBCjdpvSg3mRWKMPnYAGB7m7u1ye165wyGFvzcHAx3vtXjxAqLUeKYZCjv2m6V9D2Y4qH1TQNddWqH14T1JVMis971UCH9Ddpj6a3387oUnufD1P6HZN2ieJCvptrmbGVvxJYYSvmVf1dkwbtqurDRNWD7TJ7gf6iqSP549C9bxP4GpLt3ygjHmMtcuUzstBuztvunJUnQhfnJxqU6LjRdsFzm53wGWgXNxab7ZvQcPyLwsevn1b98FGPnVpS5iY4LjmqW4ugrC6HgrbsjrXiKzR1yZKhLQkCbLzPoaHb8iB5iBnCr7d4yf5CtfpFRqgoqMFdK5LNZYmDX4HzUKN6A7wC3gGiSRFTLcgGZeSMkB5Pa61CZBU7WCQgFxykycE9HRA7PiQa496GWDCV15teToCpFRsAa6jDmR1MGXPeLRqQgve49VXnQN5FL7c1VuEv5SWjeTuCnMB47DJKBaP7eKJNKgLwETALzSCMF3nRiRgeb15kfoS4BbrJ5yupjrvwmbmvNg1AYFFS5sYNWft7K8v87wQvBakRtGP71Kp8NX77XFtu6xdB7sR6jpfC6qJPyB9akWNXgCrWy9kE4ih42gwAZdUugNZ9YtEsgRM3pwb6qJhkAPyEJtrxrja859PCAgqPSQiPQN33PaMkgQ6HJknu8CrjKRiXAycZ16KLUkHV64TNhEjPTcX1a7rqpD131AYMWX8d7CCdc9Ys7RUb6BwguuNSh8rJK3x4AkMDSUsaE8ynKvpC7RXZpJ9Nxfhd - - peerId: 12D3KooWT3c7Y5zvWhhjSxd5Ve3GKZi6WCsG6JHxcxgXixRFdBbw + signingKey: 3mzfKBWtn7mitFEgq8u4eysWOJ6ySbUs49irfHwcuOmi1YMpobz9anoqd4yaT1owZiRPYXqx5k2Z4sNVRE3kXA== + encryptionKey: MIIEpQIBAAKCAQEA3U7b4w9JTKE3TLM1WQ5iqdLbvUuozMp/hDEg7S15Gr6wrtLomMSBkfmVQ3Cu+CHdxAFqUFClItYlSFgtZWIFiSiQxCeaN2dmgczd9T4TlRAw6y6uJXtT9r7FIgizPP4B0/tnzPI6yYgpdwzCV2nRSjw3mMr5Nav3QYs18kYrJ1/Np2Wob5HOoRTUD++pPrToevTb7GNL/irrC8wXSE7oU6S7ix6Nh9vzEHg/V5FONBF/wWD/ri7Gy0j0qgUQ+gjxLWKr8xPDnRAve13zzo+54lGCyVvlm/rwCY9Jx378V1IuRx+S8F/GFuVozHD4XVaoSTtpCWPBQNSKDXgaIIKDowIDAQABAoIBACpMXj6ht1LMJXOldPbWhwkKYjFl+pdZxNGRSkfKvzDbbY2chhRcyp8J4vuG2ApY/rftxVIgd8+Wun1/TP3ppEE43aKAJzubqb35WBr9iGSfOZpZy7MiRUQN5kPBAfEQY20OyiIj0hSez74PVD283eGgbMfpU4Rsn8+JOgBaZPkbPViJLJY8PyHU6vwWw60dye1iJTz9yuBtoEqY0XKxnLaVXTQaWx0Te+VYU8twxDgXFWRaXtHuk7xnxOkCZDLrzIvuOYa5lsLoT8K62LDeXbyHBPhbdW0j4ZYzAOTsaUWpjuJzef9aj3JJdfyADiqb5iu6HHksvKzkZEau34zjilECgYEA/c8ZJm62uJMHNssTJYiLRw89l5hYwIZ/1TXdFRF8+xrTin5opYjpscSTO5bY2IYqLx2xuPiJCY1eGGB9L/RtkaVh51ySzq0d+4zpPIRKFcOOgdxHwlgoCgIhQECyfJZNMFGBUIlPXZ/phvXOXRvWFzDPhqThenVG2QzF+wLP0AUCgYEA3zfviQFJ1FOKJMozYO3tUZFmsIrAcO9hfuE7uuWz0Fw2m1XiwxjuOr1RbsSsh/lKke2h4tiGrlfiFhwCpIp91NkVTFrtFOQxbDxkYLkFiWkZDkOaK9YhKMa2cgEm3p+RGawokjbm51LKf+cbYN9xGaAe3y2WzIE4kNpfWE4SXYcCgYEAoagcrrvpqZoMCDxED63ud+4fHsUsEkQYe6Z5EAg5gH5PqnBlGrofjthTpqqnpxGdILFbFyNFtU3TVtduJPMcLp4Vw5TU9MqSxDu1+pOP1FjgFZpGImSf6+/7Wb9bb7sToujm4nLymAFYblt1exxVuiOeqnWuH58+5tQZ7YyW7DkCgYEAl7WuqZEkmpiEpWh/7vsGdo+6GXbUQG2R9+gg7m+7/HsP6hc/XZYOJAIT3JLzKB84nWHCyyiasNeuI5S5/xbZWtaH8TNDOxW0uXl6R3q41qGFk/pCSFTqiIo16dn6jwgoWCh4EpgZ61KLqs5p/zcd6Wq4ULrtaOTSizC/6IZ3WPUCgYEA6xCJy3+ICCgr8/c7hfd2Ylb3aOsXIffdgALhXjDcrNUCqgB4R+S3WReAwrABemQGl4tySQE/1f3Ru7SzMMciFogGyJ/YSXqSi6Y8oDD7MqlKPiWlN6WY1nSRMlLbkUOqpA5JaDM0kcmXjZpBBQr277GOnh9uKN8zUy5xoptctxI= + - peerId: 12D3KooWLtuKtCPBYrFJV1NdejiCr2s614ppe9rmUXnkTHtAUD5U + address: 127.0.0.1:4431 + signingKey: 07JMoW5cQUtGO9nNIGQo9e99b7Wf/4YvTtNEA0lt4gCkmhwB1EB9ay+kitxVJJgmdyGLxbUUlGqwXsAj0zlHWw== + encryptionKey: MIIEpAIBAAKCAQEA7cA6J/icl8wseeXkt8oJr5AeYadUAG5EdCOdHj4S/Z7ivff4MOIKAeQITpq+rqhmXxOePYXSpQXE20Y9PW9tuw4gzOuq1ylSG/MWMcLDH1eIxg66rnmUqUbdiW4GGJjVjc9jvN0Up+MfSrUF6fM0jWTFoXVJQIeQQGERCIYjFzjfBl1xYvPghdxNgei/K5ZGYRggT28143XdIH4KTXGtp51hAKoyY9eCqYMtm9wvjxazhPVxO2CsYaqMxBLshY3jfHNqJnx8u6+h4Bl4uUcdbLNUgMcEgk7ehbQp2K0CqNoKXxbCTI6V57UVcJHDIaO5B6FyR6BguzHHNPJ4yd3q9wIDAQABAoIBAQCm2Mf3VRlPzhFIWnVwJXE2q8Umcu8Yfkm712Jj3twk8GPfPS4H4Bl1yjmqMB6xI6zz/CiItGlnNe04lMpVWuV+6CNMq/ZwmKbuxmFE+pFEZYGuvJd16gzR3tGJqJTOnjMAGhK8b8oXJ+TF4NQNooe20ol/DXgiuQAargPuH3RwzjYmF3N8VI4KUc3LaG4TwVXn4LwPOxrQSnfwJlZwLml1HAKOV0qcG0mXX6ZXOpoVhEoRPdQyUHc8ZW+53Agbtind7bYh5TsMVDFUrcgNwnwTOsWjil049la1IJO2uMRluacKlrtyzEp6zqrW8ZJO7mYAO69x4WyGqf2ZgIdA6djBAoGBAPqRHWAIgPa80eXbwCYkRtUG/ONBsQGi7+wm6nyhkXvNXJeokgH2DCgLH2+fW2scfOJuZc9r5WftEjOBvNfr2LDcwdyTSTh21WYcPSZx9HDf2d5/SWTcjNcyU0b5qfWIUKi/Zm9UY7r3X7yMA5dUD/cvu1PBJ5NWFrK1Gm2ph44dAoGBAPLn+LkHweU0fbxQq/76T5yVVpMKUaE9xwrJlUxEDPAQGnLPbFg4JeUt/YPhsOV85W4c4oQE+uFZrF0uf+1fEnS6MOJ+sq668upzC2hBp1B5138wM7615v1rvXVVH6qXfFop67FdBzPHt1NAN43mEIBZHTQ5hSVXFlYSZp9mxuEjAoGBAKCzUVO2IIAeub/iIGpV+dfGk4ptJ0kVZyreCqXEObpdC3V496uqUkGcYJ0GZ2ta6f2PMFzHpmnw8it2mdchu+gyrWL6U4uTK2pB0jZF/7Ak4WaB3GCD0xBxhleO6CJBOvn/R4M/bHcNEKmsYuE7WMIAKvScfPVR0VzsKfcLM5VBAoGAVvWg32zdh1bBZLdku8WU1rPH6KAbFSRuq3f7UPBTyWWaclu7p+GB/4f1aE9V6vJJmKASn7zArAhUYo+REMOmcc9uTMea5F7dM/23qb1HTtIvycLR44ZviW4Wx3iP+5x70jOLw1VQjMME6HLm8I/afHhqshWdiv6ganPv9UTwEg0CgYBSDi2dqg8F7ij5CN+LMDLSn3b8GCw+7efGIt7imm/O2V/FlHD40IA6qGg6DXNQrnoZQt94nMb1cZEvm1dxi6rmQNrhCyoMogAaPqgFhZGq1OjmhVZiXFUWy4WAcjdzFc9wZd3/XtaofRKHLK+ngTFhhVApKypLk3Rg9bCAAjzyVg== + - peerId: 12D3KooWDCypXSyN6ppuMZGxVnBd1ZQCMV4y7Bn187S4duYmf8rA address: 127.0.0.1:4432 - signingKey: 3iiLPj6wMUQpPwTBNZcUgkbXub1jumg4AEV9LfMyFHZVc84GLyAjVbVvH6EAGhcNrxRxL82aW4BimhDZCpLsRCqx5vwj - encryptionKey: JgG4CcCbae1qEpe7mKXzp7m5hNc56SSyZd9DwUaEStKJrq7RToAC2Vgd3i6hKRwa58zCWeN6Wjc3o6qrdKPEPRvcyEPysamajVo5mdQiUgWAmr97pGEsyjuRjQoC2GY2LvLiEQxEgwFgJxKGMHMiaWMtDfxCDUaDEm4bu5RdMhqRZekAWho6c3WoEeruSr14iX1TrocFNfBkBY7CjEw8kcywXCTNgtvhb2Qiwgj5AxEF4wyw4bzaNA9ctXb1hoHPFVMu6C51pkFY7jUD9zwyH3ukgnAewkGAcPNbKmaTAtMosKRVaAN97mAwXh2VRt1hWmRvVk7r76EjnVKhD4vbsKZc56RVcHTVWRVdhU7FGyPsiE5rSQAz1JQGYzxnZpX7EG77CyrmUGyfueVfRHhwY2oq8A4uQCRaQxSaJHYLowjXSxh8DQ2V6MTqyzti32C27utBYdHzLVCJSGkmdzGwrFcHqsq7nLDxmvJVErPvyReixEe8kFmqopJ3e6LLm8WdYw9K6JYBjXnEfwPzm7Von9sf3dcaGDUHYfttMyeke7fAXJkvPRje69hYVyzdQGAauuojzGkkvQWCSMK1KCMNMznRaPDCNvofrQhYrub24WhmwpKhorufdfW8Cb4T6reBDCtaWVsbuinjtL6F6Sui5aYHJFLJ6e4pPewr1P4EuZYRbMBZwN5KvDLhTGLBuBnaTqUUdF6bj2U22NoRYMogiHiftqKqiexKNDXX1Zg9RQEvxgjuVo6SBW42mVEA8agrLhruRqCmiduJxVrfqLNGeYXHXrcmMEgW7uosJbPXvTcfRvdFWS1ov7oSALvj6vhDQ28Yi9D2ETNdNsfVWAFQuwvPpW7CHQGXTitprVbqH8JYxNZuGygcLmr5efbB22Vzu4ntd1HoraQpG12qeDEUA7tXYUpoYyuSdWwKPjSAMtaQcCSfVrhKQHQuKJargrVrez8vjWuwLfvSucV7ZHe7gjqvYgULdE1ubRCRSd7DuLjEN2Vd6obzV2c3MRet7ZSf4Sp88WM5AuTyW7BjArBc4S3gUQ8rYaiZ8Tu7NCxkEzbFwWRaemZkwfvcsX3XxqjyF37tFSGkEqE5kuBvpZW72675LkDffj7kH1zA8yE6dVujJjWsNYVFJWndUtz5Vy2KCdZAbBgq19q4AtsxWPodU2N3yZXzFAFAzTrxS6V4P7Scpdau1avgRvHLcBQPunA37xaYMy8YMifJwtmRY25mnAQwZAk3eANk7tXwZd58SDnciLNvARJvwKzTQBXcshkwyy52SX8XmXDJsPnRLaHmiYBJ63Yzr5XpZuuAtxb9qrWG2NHCNxfomHokWacV1hjZPPd6ZxT1FuRozB6Qt2NLcyqY7bnTcQJb1jPUaTAGXXCR8WVmmmYo2fDQe8CdBmgyPvbzNTEJUyScBz4RdycB5PZap4SurJCWtHbuMyQbQUB6jJgURDstfXS5Akfe4oruNq9rnYcNtnsDJPtrhXHBqzDizmf1BDxR5FB2RCxzCgeAfg8WQ1Ug9PVAGTzob6ZqCrGXzWXEUniZnf1vjr7QhGKBYXEX9SWDoSMUpP4FreVDTnx15ijRZTV3p8xG5fE9e36TnugRVvTyq7XzmyPBjW2r66f1bior + signingKey: SGyNE0dFaQgtgNuzdcO7LB+TEz9VHAOtlQLk6WWkrkQyXiZV3casg8Q2/4PO1Oylc8Fu72RU001Hclj5JCbiLw== + encryptionKey: MIIEpAIBAAKCAQEA0k3mw4FyexRkLgLjHzYs4Ppeyv6r9ZrP00imNf15JTuM8ajMx5oJX7JQTm8KOLRJjUdZZAd5Gtp0ezfYAQK1ZjEWwCmfp8j8FBgJIDSLpjxl88SXMLgATXYfhklnQvKlQjs/X3Ka4zdTrav2tMH9IAo6TSNZhlPQNsUory1SGHs+KqHv4p0sG8oWuKYhfBj8rWHQdUVptkIBKgojFDeJJD04Tbf9kUakbK/8KuXB6zF5H4WN3p4rMMwkClyTGeYO4LDg5TzVn8NnUi3/b/vO/3us1G/TMoRe/6umUfpQxrwo+7S2T6A4YwetWRp6xALLhp+HfAWnn0lA/D8/w1WpKwIDAQABAoIBAQC5cdQxRa5rddm48PbSCPWeFWkNW3DLDI6CYyedqDvxZwer+QtKXzww1I4X+7ZptiC9odLjb+uMkGHyXZXtnjPTPyounQWZ8JLILUGu0mbqWYwVXp9raHVr2OOHiKaz1D+BnbkOM4L9JUZ2eJL9ZaoNXLd4WdmRp8qM4WI0xqQDzOANx2HhyL/+dJmQeIUND+pdeH+Z+fYowU3ho32txNvBnMXQhF1T5K9i1VO5W49RAjIRbENsT+paPGKbNubDHRt1j36ktK4eC4HSdgv8tccdsGyrEiIbAt1XsTZfM8ie4D3A8RhSxiTC6Fkgv6vIm+iFTLzBFZKesOBcd8sfKeyBAoGBAOts5PQQJhldPDzlbnqzxMOR98WHbkVZjCqWSkNA34vqyFuPcRuX0rHK/qpg23ilbUP0fGMDTGgFzTt51FZLL16SXyRfjNhzjdmryryeddQwbp92ta2GEgnU6t1FyCuSCtcLDKJd/D9A9dC5UI6z+ES4TOnbR3nakXK9t4cUOFthAoGBAOSu+wL+SEA5erR+m3LpOsELK68CCJQPxn3VpoVfJZawgF+fEoXVMLTERxJput1+ADomIEdNc9ex86TjKx9gJ4piNHscRPFeT/AgESOIGHLOc1gk2DPqNj6wBIarUJQ9t4KcHScboh1dTPJeqqv2NSwIiLQoqFUIhfKZLnrW3zwLAoGBAJh0hC+o5YM3ZXLqAIllMN6VACbidP5j5ukNOjojIKCzAdyJH24G+2I3WoNrBbUzK3b+NC7KTAhw+V6ynlbjiWFs2D/twH/LFOkI3tkWpKcsVfbeIPimAbhsMUvpjJ7qjCqF9UCQLHGp14W6+/ftg7C8yNIINlkquVXclaTb60MBAoGAPqmL8ogG+EJH00mWAujRxq/u6meePiQMedKfbJBj1mTK6GjIRI/kZsQZzXvXTnYGTejAk4kvov0KDDaLTG+mpg6+3rUiVxlGwj+nMptKR7s2dAK0k5UsBAVrWBN9YwF+VXW9r0etJmq4ePljvvcaHtS/0M4LQjGxsoYy7EoQpX0CgYAhnf0McB7F1MxSjB0soMNv/v5utVzVihS3re2yKNdkI/YUEMB+yU3Q4gh+OljjBM6Y5To3BsQBAx4l2CysMKFHjIE/5AtdbvIS+chZZqB3vcZXSayvX8P1Z1uFdw/saiO2cRDJmR+TxaOPa2C9SzDoNTACthwLErHfzvEvVroKmw== +space: + gcTTL: 60 + syncPeriod: 10 +storage: + path: db +metric: + addr: "" +log: + production: false + defaultLevel: "" + namedLevels: {} diff --git a/etc/configs/client1.yml b/etc/configs/client1.yml new file mode 100755 index 00000000..92f7461f --- /dev/null +++ b/etc/configs/client1.yml @@ -0,0 +1,37 @@ +anytype: + swarmKey: /key/swarm/psk/1.0.0/base16/209992e611c27d5dce8fbd2e7389f6b51da9bee980992ef60739460b536139ec +grpcServer: + listenAddrs: + - 127.0.0.1:4630 + tls: false +account: + peerId: 12D3KooWFqDLPcSZi74A1vVpDc8baTkGU6bd21AXcNxH8CFPMqp6 + peerKey: s6PUCRVry6ymxhyytNQcqSQVd2ECGyWNMIJB0FkyMUFZXbbOYSBb2yYPeQXrA9jdFdZDXyUSxtvzasvpSMpa6w== + signingKey: +UF/Do2KPeBLA0joKvnJj43jiH975JcHGjkLIkLR0p7FCFHnR1r/w4xLSa4RTjhEAQ3sDefjktShOJpalXnGvg== + encryptionKey: MIIEpQIBAAKCAQEA7NiHF065o9BfTTAWtAItg3KLqvFnRN2WVQMkjMZ/BukIj4UAd196ppexh2tnDvvqW53qVxFtXcW8oFqX9GmDJx61nnN/ce2FhXNB3aPMa7g3AchlVVB9RHyS8Z49HTkn3DVRi8I8EnbpWer35BjnpGOQ257O/kFpD1P5FzvxyTQ2gF50SyiwoDzibyT2VxgQqaDErr9BfFQKBZb8SEBeLACOlzjb2u0mCv7NeoZNfzl2KsqBC8tiCyfNahhauGfU9ZB7PtHMC1pJKTtPhXhNhQI8Rp39dd+Fr3kiTJl3Fe1f4bg4GDI7LbqCARVBbtCjsLEMi1BMzMS63bFPrPL9ewIDAQABAoIBAQCA261j+Oj3Pz8ad7diaGzqvz9N2dkdlpFb30HbdYNW9yI5M1t1lvTb/lwQGVcQx+5RujDs/gZKpnJhq+hQibdZaVPWyW/lRB0I5hRHyf5F/QuwZJ79M7VztXMdEcKeS6JsJHYhW6PjR97dlQEZkJM21RTS6CwmGOBX/o/fHDYICNxIqt4x7x1Hu+A9Qcs3LWvWq0qAkO48jSYBDeIFJ56BdXZacfIv9A7aCGWoVvih2vFIFEwdn+3z69FHmcW8JzVDK+WdkegtOlvuPcFGgDjS8cHq4zuKyEckur9EVm2Wer+GRdY2v7i9ypxiy/Ej4qJCqJLIa5rtWHmB9Dz7IyFBAoGBAPlIMpu9vAhAhJUeO48vsuEDdCn2ztyq2h4GwYcuNmfZUAnFdKRHHAfb48P7nR1uVCEEvnJYF9uUFkot8zljkDCoqc3J30sOd54PT2Jqn2vPhSWpjNJGW4Ku3CmZq/vfCH15z+bcr7whtlEswshE31bykbZlzCOSyW1tgfz2I+ydAoGBAPM6iEV6M74X+M4GoVCwUn9JMFRUX/JONOu4nfNT+1jDeABeXzVS3gzLSMJ/Vk/+1a/g6NFm73bt5PYHR8jG/jrT3xcTBPUiFj038w1MAM5Fsj2jSnIFRYFxwH8q0RfejWvKJRyWKUyTt7m43VRY9P01+YDfgt+VoLs94rV0PNr3AoGAahmWoL8S5xg+1hE2HG2a3zbPHIVV6oo1qA4MFPNQaMcPz/jg+oLhpV6sBOB1MO+ikyMnxBdGoEjZa90+5rA/0NYY3+QKTDHuK7IsgaEMFaEP9MXDkEQt8uNmBbbIgr2dKXrNSF+p1JMsvEQm64KU5Lb92fpd9s4lOZQgfYBuLekCgYEAwNvPg6+S6Y7edJZjQLSepVjmHmfMsDd81M/NRkx4Bvju5PPvcDul3+UsazRGvyVkUJH4aVnCVL3rB33cWIIYwZKP2R72llyR37bGXOu/088FtsQMWn59j1cf+HV91/xajHZ7mMAkPRj/3B6OOLxUfZZXoO0ZO6nMCcvXQGPLgR8CgYEA2W644EHrSwb4qsDsUmIEeKnjSejS8Vej4S5/g1YOyVzfWEr/5rtejw09Fv4U92SeYhp7Xp3C0UnRCduZKrpXIZJVPO8KgWLDtPi9KvHqDPzpQNRHMNrsXLpOLLv+bnnymWXjcyG8fRecU4sggaH4r1C/QyLPr+s/fLDyVUt7bC8= +apiServer: + port: "8090" +nodes: + - peerId: 12D3KooWLn13hDrZ6YRGM517fHf2zS6qhPNRu18inLMpRqn1YGKu + address: 127.0.0.1:4430 + signingKey: 3mzfKBWtn7mitFEgq8u4eysWOJ6ySbUs49irfHwcuOmi1YMpobz9anoqd4yaT1owZiRPYXqx5k2Z4sNVRE3kXA== + encryptionKey: MIIEpQIBAAKCAQEA3U7b4w9JTKE3TLM1WQ5iqdLbvUuozMp/hDEg7S15Gr6wrtLomMSBkfmVQ3Cu+CHdxAFqUFClItYlSFgtZWIFiSiQxCeaN2dmgczd9T4TlRAw6y6uJXtT9r7FIgizPP4B0/tnzPI6yYgpdwzCV2nRSjw3mMr5Nav3QYs18kYrJ1/Np2Wob5HOoRTUD++pPrToevTb7GNL/irrC8wXSE7oU6S7ix6Nh9vzEHg/V5FONBF/wWD/ri7Gy0j0qgUQ+gjxLWKr8xPDnRAve13zzo+54lGCyVvlm/rwCY9Jx378V1IuRx+S8F/GFuVozHD4XVaoSTtpCWPBQNSKDXgaIIKDowIDAQABAoIBACpMXj6ht1LMJXOldPbWhwkKYjFl+pdZxNGRSkfKvzDbbY2chhRcyp8J4vuG2ApY/rftxVIgd8+Wun1/TP3ppEE43aKAJzubqb35WBr9iGSfOZpZy7MiRUQN5kPBAfEQY20OyiIj0hSez74PVD283eGgbMfpU4Rsn8+JOgBaZPkbPViJLJY8PyHU6vwWw60dye1iJTz9yuBtoEqY0XKxnLaVXTQaWx0Te+VYU8twxDgXFWRaXtHuk7xnxOkCZDLrzIvuOYa5lsLoT8K62LDeXbyHBPhbdW0j4ZYzAOTsaUWpjuJzef9aj3JJdfyADiqb5iu6HHksvKzkZEau34zjilECgYEA/c8ZJm62uJMHNssTJYiLRw89l5hYwIZ/1TXdFRF8+xrTin5opYjpscSTO5bY2IYqLx2xuPiJCY1eGGB9L/RtkaVh51ySzq0d+4zpPIRKFcOOgdxHwlgoCgIhQECyfJZNMFGBUIlPXZ/phvXOXRvWFzDPhqThenVG2QzF+wLP0AUCgYEA3zfviQFJ1FOKJMozYO3tUZFmsIrAcO9hfuE7uuWz0Fw2m1XiwxjuOr1RbsSsh/lKke2h4tiGrlfiFhwCpIp91NkVTFrtFOQxbDxkYLkFiWkZDkOaK9YhKMa2cgEm3p+RGawokjbm51LKf+cbYN9xGaAe3y2WzIE4kNpfWE4SXYcCgYEAoagcrrvpqZoMCDxED63ud+4fHsUsEkQYe6Z5EAg5gH5PqnBlGrofjthTpqqnpxGdILFbFyNFtU3TVtduJPMcLp4Vw5TU9MqSxDu1+pOP1FjgFZpGImSf6+/7Wb9bb7sToujm4nLymAFYblt1exxVuiOeqnWuH58+5tQZ7YyW7DkCgYEAl7WuqZEkmpiEpWh/7vsGdo+6GXbUQG2R9+gg7m+7/HsP6hc/XZYOJAIT3JLzKB84nWHCyyiasNeuI5S5/xbZWtaH8TNDOxW0uXl6R3q41qGFk/pCSFTqiIo16dn6jwgoWCh4EpgZ61KLqs5p/zcd6Wq4ULrtaOTSizC/6IZ3WPUCgYEA6xCJy3+ICCgr8/c7hfd2Ylb3aOsXIffdgALhXjDcrNUCqgB4R+S3WReAwrABemQGl4tySQE/1f3Ru7SzMMciFogGyJ/YSXqSi6Y8oDD7MqlKPiWlN6WY1nSRMlLbkUOqpA5JaDM0kcmXjZpBBQr277GOnh9uKN8zUy5xoptctxI= + - peerId: 12D3KooWLtuKtCPBYrFJV1NdejiCr2s614ppe9rmUXnkTHtAUD5U + address: 127.0.0.1:4431 + signingKey: 07JMoW5cQUtGO9nNIGQo9e99b7Wf/4YvTtNEA0lt4gCkmhwB1EB9ay+kitxVJJgmdyGLxbUUlGqwXsAj0zlHWw== + encryptionKey: MIIEpAIBAAKCAQEA7cA6J/icl8wseeXkt8oJr5AeYadUAG5EdCOdHj4S/Z7ivff4MOIKAeQITpq+rqhmXxOePYXSpQXE20Y9PW9tuw4gzOuq1ylSG/MWMcLDH1eIxg66rnmUqUbdiW4GGJjVjc9jvN0Up+MfSrUF6fM0jWTFoXVJQIeQQGERCIYjFzjfBl1xYvPghdxNgei/K5ZGYRggT28143XdIH4KTXGtp51hAKoyY9eCqYMtm9wvjxazhPVxO2CsYaqMxBLshY3jfHNqJnx8u6+h4Bl4uUcdbLNUgMcEgk7ehbQp2K0CqNoKXxbCTI6V57UVcJHDIaO5B6FyR6BguzHHNPJ4yd3q9wIDAQABAoIBAQCm2Mf3VRlPzhFIWnVwJXE2q8Umcu8Yfkm712Jj3twk8GPfPS4H4Bl1yjmqMB6xI6zz/CiItGlnNe04lMpVWuV+6CNMq/ZwmKbuxmFE+pFEZYGuvJd16gzR3tGJqJTOnjMAGhK8b8oXJ+TF4NQNooe20ol/DXgiuQAargPuH3RwzjYmF3N8VI4KUc3LaG4TwVXn4LwPOxrQSnfwJlZwLml1HAKOV0qcG0mXX6ZXOpoVhEoRPdQyUHc8ZW+53Agbtind7bYh5TsMVDFUrcgNwnwTOsWjil049la1IJO2uMRluacKlrtyzEp6zqrW8ZJO7mYAO69x4WyGqf2ZgIdA6djBAoGBAPqRHWAIgPa80eXbwCYkRtUG/ONBsQGi7+wm6nyhkXvNXJeokgH2DCgLH2+fW2scfOJuZc9r5WftEjOBvNfr2LDcwdyTSTh21WYcPSZx9HDf2d5/SWTcjNcyU0b5qfWIUKi/Zm9UY7r3X7yMA5dUD/cvu1PBJ5NWFrK1Gm2ph44dAoGBAPLn+LkHweU0fbxQq/76T5yVVpMKUaE9xwrJlUxEDPAQGnLPbFg4JeUt/YPhsOV85W4c4oQE+uFZrF0uf+1fEnS6MOJ+sq668upzC2hBp1B5138wM7615v1rvXVVH6qXfFop67FdBzPHt1NAN43mEIBZHTQ5hSVXFlYSZp9mxuEjAoGBAKCzUVO2IIAeub/iIGpV+dfGk4ptJ0kVZyreCqXEObpdC3V496uqUkGcYJ0GZ2ta6f2PMFzHpmnw8it2mdchu+gyrWL6U4uTK2pB0jZF/7Ak4WaB3GCD0xBxhleO6CJBOvn/R4M/bHcNEKmsYuE7WMIAKvScfPVR0VzsKfcLM5VBAoGAVvWg32zdh1bBZLdku8WU1rPH6KAbFSRuq3f7UPBTyWWaclu7p+GB/4f1aE9V6vJJmKASn7zArAhUYo+REMOmcc9uTMea5F7dM/23qb1HTtIvycLR44ZviW4Wx3iP+5x70jOLw1VQjMME6HLm8I/afHhqshWdiv6ganPv9UTwEg0CgYBSDi2dqg8F7ij5CN+LMDLSn3b8GCw+7efGIt7imm/O2V/FlHD40IA6qGg6DXNQrnoZQt94nMb1cZEvm1dxi6rmQNrhCyoMogAaPqgFhZGq1OjmhVZiXFUWy4WAcjdzFc9wZd3/XtaofRKHLK+ngTFhhVApKypLk3Rg9bCAAjzyVg== + - peerId: 12D3KooWDCypXSyN6ppuMZGxVnBd1ZQCMV4y7Bn187S4duYmf8rA + address: 127.0.0.1:4432 + signingKey: SGyNE0dFaQgtgNuzdcO7LB+TEz9VHAOtlQLk6WWkrkQyXiZV3casg8Q2/4PO1Oylc8Fu72RU001Hclj5JCbiLw== + encryptionKey: MIIEpAIBAAKCAQEA0k3mw4FyexRkLgLjHzYs4Ppeyv6r9ZrP00imNf15JTuM8ajMx5oJX7JQTm8KOLRJjUdZZAd5Gtp0ezfYAQK1ZjEWwCmfp8j8FBgJIDSLpjxl88SXMLgATXYfhklnQvKlQjs/X3Ka4zdTrav2tMH9IAo6TSNZhlPQNsUory1SGHs+KqHv4p0sG8oWuKYhfBj8rWHQdUVptkIBKgojFDeJJD04Tbf9kUakbK/8KuXB6zF5H4WN3p4rMMwkClyTGeYO4LDg5TzVn8NnUi3/b/vO/3us1G/TMoRe/6umUfpQxrwo+7S2T6A4YwetWRp6xALLhp+HfAWnn0lA/D8/w1WpKwIDAQABAoIBAQC5cdQxRa5rddm48PbSCPWeFWkNW3DLDI6CYyedqDvxZwer+QtKXzww1I4X+7ZptiC9odLjb+uMkGHyXZXtnjPTPyounQWZ8JLILUGu0mbqWYwVXp9raHVr2OOHiKaz1D+BnbkOM4L9JUZ2eJL9ZaoNXLd4WdmRp8qM4WI0xqQDzOANx2HhyL/+dJmQeIUND+pdeH+Z+fYowU3ho32txNvBnMXQhF1T5K9i1VO5W49RAjIRbENsT+paPGKbNubDHRt1j36ktK4eC4HSdgv8tccdsGyrEiIbAt1XsTZfM8ie4D3A8RhSxiTC6Fkgv6vIm+iFTLzBFZKesOBcd8sfKeyBAoGBAOts5PQQJhldPDzlbnqzxMOR98WHbkVZjCqWSkNA34vqyFuPcRuX0rHK/qpg23ilbUP0fGMDTGgFzTt51FZLL16SXyRfjNhzjdmryryeddQwbp92ta2GEgnU6t1FyCuSCtcLDKJd/D9A9dC5UI6z+ES4TOnbR3nakXK9t4cUOFthAoGBAOSu+wL+SEA5erR+m3LpOsELK68CCJQPxn3VpoVfJZawgF+fEoXVMLTERxJput1+ADomIEdNc9ex86TjKx9gJ4piNHscRPFeT/AgESOIGHLOc1gk2DPqNj6wBIarUJQ9t4KcHScboh1dTPJeqqv2NSwIiLQoqFUIhfKZLnrW3zwLAoGBAJh0hC+o5YM3ZXLqAIllMN6VACbidP5j5ukNOjojIKCzAdyJH24G+2I3WoNrBbUzK3b+NC7KTAhw+V6ynlbjiWFs2D/twH/LFOkI3tkWpKcsVfbeIPimAbhsMUvpjJ7qjCqF9UCQLHGp14W6+/ftg7C8yNIINlkquVXclaTb60MBAoGAPqmL8ogG+EJH00mWAujRxq/u6meePiQMedKfbJBj1mTK6GjIRI/kZsQZzXvXTnYGTejAk4kvov0KDDaLTG+mpg6+3rUiVxlGwj+nMptKR7s2dAK0k5UsBAVrWBN9YwF+VXW9r0etJmq4ePljvvcaHtS/0M4LQjGxsoYy7EoQpX0CgYAhnf0McB7F1MxSjB0soMNv/v5utVzVihS3re2yKNdkI/YUEMB+yU3Q4gh+OljjBM6Y5To3BsQBAx4l2CysMKFHjIE/5AtdbvIS+chZZqB3vcZXSayvX8P1Z1uFdw/saiO2cRDJmR+TxaOPa2C9SzDoNTACthwLErHfzvEvVroKmw== +space: + gcTTL: 60 + syncPeriod: 10 +storage: + path: db +metric: + addr: "" +log: + production: false + defaultLevel: "" + namedLevels: {} diff --git a/etc/configs/client2.yml b/etc/configs/client2.yml new file mode 100755 index 00000000..bb8d6fbd --- /dev/null +++ b/etc/configs/client2.yml @@ -0,0 +1,37 @@ +anytype: + swarmKey: /key/swarm/psk/1.0.0/base16/209992e611c27d5dce8fbd2e7389f6b51da9bee980992ef60739460b536139ec +grpcServer: + listenAddrs: + - 127.0.0.1:4631 + tls: false +account: + peerId: 12D3KooWA7AHfBCyNPQaMnffj8S7Z9kZzKG6X1apLgtyP1CgpXiJ + peerKey: +KIj+xVyg241tP2So4JmRNGFFIgtzK1PWUo8El0e5x0ETXCrCksPkLsA8s6Xww0DJy92dyISwoBoMQ7XhLbdOw== + signingKey: +UF/Do2KPeBLA0joKvnJj43jiH975JcHGjkLIkLR0p7FCFHnR1r/w4xLSa4RTjhEAQ3sDefjktShOJpalXnGvg== + encryptionKey: MIIEpQIBAAKCAQEA7NiHF065o9BfTTAWtAItg3KLqvFnRN2WVQMkjMZ/BukIj4UAd196ppexh2tnDvvqW53qVxFtXcW8oFqX9GmDJx61nnN/ce2FhXNB3aPMa7g3AchlVVB9RHyS8Z49HTkn3DVRi8I8EnbpWer35BjnpGOQ257O/kFpD1P5FzvxyTQ2gF50SyiwoDzibyT2VxgQqaDErr9BfFQKBZb8SEBeLACOlzjb2u0mCv7NeoZNfzl2KsqBC8tiCyfNahhauGfU9ZB7PtHMC1pJKTtPhXhNhQI8Rp39dd+Fr3kiTJl3Fe1f4bg4GDI7LbqCARVBbtCjsLEMi1BMzMS63bFPrPL9ewIDAQABAoIBAQCA261j+Oj3Pz8ad7diaGzqvz9N2dkdlpFb30HbdYNW9yI5M1t1lvTb/lwQGVcQx+5RujDs/gZKpnJhq+hQibdZaVPWyW/lRB0I5hRHyf5F/QuwZJ79M7VztXMdEcKeS6JsJHYhW6PjR97dlQEZkJM21RTS6CwmGOBX/o/fHDYICNxIqt4x7x1Hu+A9Qcs3LWvWq0qAkO48jSYBDeIFJ56BdXZacfIv9A7aCGWoVvih2vFIFEwdn+3z69FHmcW8JzVDK+WdkegtOlvuPcFGgDjS8cHq4zuKyEckur9EVm2Wer+GRdY2v7i9ypxiy/Ej4qJCqJLIa5rtWHmB9Dz7IyFBAoGBAPlIMpu9vAhAhJUeO48vsuEDdCn2ztyq2h4GwYcuNmfZUAnFdKRHHAfb48P7nR1uVCEEvnJYF9uUFkot8zljkDCoqc3J30sOd54PT2Jqn2vPhSWpjNJGW4Ku3CmZq/vfCH15z+bcr7whtlEswshE31bykbZlzCOSyW1tgfz2I+ydAoGBAPM6iEV6M74X+M4GoVCwUn9JMFRUX/JONOu4nfNT+1jDeABeXzVS3gzLSMJ/Vk/+1a/g6NFm73bt5PYHR8jG/jrT3xcTBPUiFj038w1MAM5Fsj2jSnIFRYFxwH8q0RfejWvKJRyWKUyTt7m43VRY9P01+YDfgt+VoLs94rV0PNr3AoGAahmWoL8S5xg+1hE2HG2a3zbPHIVV6oo1qA4MFPNQaMcPz/jg+oLhpV6sBOB1MO+ikyMnxBdGoEjZa90+5rA/0NYY3+QKTDHuK7IsgaEMFaEP9MXDkEQt8uNmBbbIgr2dKXrNSF+p1JMsvEQm64KU5Lb92fpd9s4lOZQgfYBuLekCgYEAwNvPg6+S6Y7edJZjQLSepVjmHmfMsDd81M/NRkx4Bvju5PPvcDul3+UsazRGvyVkUJH4aVnCVL3rB33cWIIYwZKP2R72llyR37bGXOu/088FtsQMWn59j1cf+HV91/xajHZ7mMAkPRj/3B6OOLxUfZZXoO0ZO6nMCcvXQGPLgR8CgYEA2W644EHrSwb4qsDsUmIEeKnjSejS8Vej4S5/g1YOyVzfWEr/5rtejw09Fv4U92SeYhp7Xp3C0UnRCduZKrpXIZJVPO8KgWLDtPi9KvHqDPzpQNRHMNrsXLpOLLv+bnnymWXjcyG8fRecU4sggaH4r1C/QyLPr+s/fLDyVUt7bC8= +apiServer: + port: "8091" +nodes: + - peerId: 12D3KooWLn13hDrZ6YRGM517fHf2zS6qhPNRu18inLMpRqn1YGKu + address: 127.0.0.1:4430 + signingKey: 3mzfKBWtn7mitFEgq8u4eysWOJ6ySbUs49irfHwcuOmi1YMpobz9anoqd4yaT1owZiRPYXqx5k2Z4sNVRE3kXA== + encryptionKey: MIIEpQIBAAKCAQEA3U7b4w9JTKE3TLM1WQ5iqdLbvUuozMp/hDEg7S15Gr6wrtLomMSBkfmVQ3Cu+CHdxAFqUFClItYlSFgtZWIFiSiQxCeaN2dmgczd9T4TlRAw6y6uJXtT9r7FIgizPP4B0/tnzPI6yYgpdwzCV2nRSjw3mMr5Nav3QYs18kYrJ1/Np2Wob5HOoRTUD++pPrToevTb7GNL/irrC8wXSE7oU6S7ix6Nh9vzEHg/V5FONBF/wWD/ri7Gy0j0qgUQ+gjxLWKr8xPDnRAve13zzo+54lGCyVvlm/rwCY9Jx378V1IuRx+S8F/GFuVozHD4XVaoSTtpCWPBQNSKDXgaIIKDowIDAQABAoIBACpMXj6ht1LMJXOldPbWhwkKYjFl+pdZxNGRSkfKvzDbbY2chhRcyp8J4vuG2ApY/rftxVIgd8+Wun1/TP3ppEE43aKAJzubqb35WBr9iGSfOZpZy7MiRUQN5kPBAfEQY20OyiIj0hSez74PVD283eGgbMfpU4Rsn8+JOgBaZPkbPViJLJY8PyHU6vwWw60dye1iJTz9yuBtoEqY0XKxnLaVXTQaWx0Te+VYU8twxDgXFWRaXtHuk7xnxOkCZDLrzIvuOYa5lsLoT8K62LDeXbyHBPhbdW0j4ZYzAOTsaUWpjuJzef9aj3JJdfyADiqb5iu6HHksvKzkZEau34zjilECgYEA/c8ZJm62uJMHNssTJYiLRw89l5hYwIZ/1TXdFRF8+xrTin5opYjpscSTO5bY2IYqLx2xuPiJCY1eGGB9L/RtkaVh51ySzq0d+4zpPIRKFcOOgdxHwlgoCgIhQECyfJZNMFGBUIlPXZ/phvXOXRvWFzDPhqThenVG2QzF+wLP0AUCgYEA3zfviQFJ1FOKJMozYO3tUZFmsIrAcO9hfuE7uuWz0Fw2m1XiwxjuOr1RbsSsh/lKke2h4tiGrlfiFhwCpIp91NkVTFrtFOQxbDxkYLkFiWkZDkOaK9YhKMa2cgEm3p+RGawokjbm51LKf+cbYN9xGaAe3y2WzIE4kNpfWE4SXYcCgYEAoagcrrvpqZoMCDxED63ud+4fHsUsEkQYe6Z5EAg5gH5PqnBlGrofjthTpqqnpxGdILFbFyNFtU3TVtduJPMcLp4Vw5TU9MqSxDu1+pOP1FjgFZpGImSf6+/7Wb9bb7sToujm4nLymAFYblt1exxVuiOeqnWuH58+5tQZ7YyW7DkCgYEAl7WuqZEkmpiEpWh/7vsGdo+6GXbUQG2R9+gg7m+7/HsP6hc/XZYOJAIT3JLzKB84nWHCyyiasNeuI5S5/xbZWtaH8TNDOxW0uXl6R3q41qGFk/pCSFTqiIo16dn6jwgoWCh4EpgZ61KLqs5p/zcd6Wq4ULrtaOTSizC/6IZ3WPUCgYEA6xCJy3+ICCgr8/c7hfd2Ylb3aOsXIffdgALhXjDcrNUCqgB4R+S3WReAwrABemQGl4tySQE/1f3Ru7SzMMciFogGyJ/YSXqSi6Y8oDD7MqlKPiWlN6WY1nSRMlLbkUOqpA5JaDM0kcmXjZpBBQr277GOnh9uKN8zUy5xoptctxI= + - peerId: 12D3KooWLtuKtCPBYrFJV1NdejiCr2s614ppe9rmUXnkTHtAUD5U + address: 127.0.0.1:4431 + signingKey: 07JMoW5cQUtGO9nNIGQo9e99b7Wf/4YvTtNEA0lt4gCkmhwB1EB9ay+kitxVJJgmdyGLxbUUlGqwXsAj0zlHWw== + encryptionKey: MIIEpAIBAAKCAQEA7cA6J/icl8wseeXkt8oJr5AeYadUAG5EdCOdHj4S/Z7ivff4MOIKAeQITpq+rqhmXxOePYXSpQXE20Y9PW9tuw4gzOuq1ylSG/MWMcLDH1eIxg66rnmUqUbdiW4GGJjVjc9jvN0Up+MfSrUF6fM0jWTFoXVJQIeQQGERCIYjFzjfBl1xYvPghdxNgei/K5ZGYRggT28143XdIH4KTXGtp51hAKoyY9eCqYMtm9wvjxazhPVxO2CsYaqMxBLshY3jfHNqJnx8u6+h4Bl4uUcdbLNUgMcEgk7ehbQp2K0CqNoKXxbCTI6V57UVcJHDIaO5B6FyR6BguzHHNPJ4yd3q9wIDAQABAoIBAQCm2Mf3VRlPzhFIWnVwJXE2q8Umcu8Yfkm712Jj3twk8GPfPS4H4Bl1yjmqMB6xI6zz/CiItGlnNe04lMpVWuV+6CNMq/ZwmKbuxmFE+pFEZYGuvJd16gzR3tGJqJTOnjMAGhK8b8oXJ+TF4NQNooe20ol/DXgiuQAargPuH3RwzjYmF3N8VI4KUc3LaG4TwVXn4LwPOxrQSnfwJlZwLml1HAKOV0qcG0mXX6ZXOpoVhEoRPdQyUHc8ZW+53Agbtind7bYh5TsMVDFUrcgNwnwTOsWjil049la1IJO2uMRluacKlrtyzEp6zqrW8ZJO7mYAO69x4WyGqf2ZgIdA6djBAoGBAPqRHWAIgPa80eXbwCYkRtUG/ONBsQGi7+wm6nyhkXvNXJeokgH2DCgLH2+fW2scfOJuZc9r5WftEjOBvNfr2LDcwdyTSTh21WYcPSZx9HDf2d5/SWTcjNcyU0b5qfWIUKi/Zm9UY7r3X7yMA5dUD/cvu1PBJ5NWFrK1Gm2ph44dAoGBAPLn+LkHweU0fbxQq/76T5yVVpMKUaE9xwrJlUxEDPAQGnLPbFg4JeUt/YPhsOV85W4c4oQE+uFZrF0uf+1fEnS6MOJ+sq668upzC2hBp1B5138wM7615v1rvXVVH6qXfFop67FdBzPHt1NAN43mEIBZHTQ5hSVXFlYSZp9mxuEjAoGBAKCzUVO2IIAeub/iIGpV+dfGk4ptJ0kVZyreCqXEObpdC3V496uqUkGcYJ0GZ2ta6f2PMFzHpmnw8it2mdchu+gyrWL6U4uTK2pB0jZF/7Ak4WaB3GCD0xBxhleO6CJBOvn/R4M/bHcNEKmsYuE7WMIAKvScfPVR0VzsKfcLM5VBAoGAVvWg32zdh1bBZLdku8WU1rPH6KAbFSRuq3f7UPBTyWWaclu7p+GB/4f1aE9V6vJJmKASn7zArAhUYo+REMOmcc9uTMea5F7dM/23qb1HTtIvycLR44ZviW4Wx3iP+5x70jOLw1VQjMME6HLm8I/afHhqshWdiv6ganPv9UTwEg0CgYBSDi2dqg8F7ij5CN+LMDLSn3b8GCw+7efGIt7imm/O2V/FlHD40IA6qGg6DXNQrnoZQt94nMb1cZEvm1dxi6rmQNrhCyoMogAaPqgFhZGq1OjmhVZiXFUWy4WAcjdzFc9wZd3/XtaofRKHLK+ngTFhhVApKypLk3Rg9bCAAjzyVg== + - peerId: 12D3KooWDCypXSyN6ppuMZGxVnBd1ZQCMV4y7Bn187S4duYmf8rA + address: 127.0.0.1:4432 + signingKey: SGyNE0dFaQgtgNuzdcO7LB+TEz9VHAOtlQLk6WWkrkQyXiZV3casg8Q2/4PO1Oylc8Fu72RU001Hclj5JCbiLw== + encryptionKey: MIIEpAIBAAKCAQEA0k3mw4FyexRkLgLjHzYs4Ppeyv6r9ZrP00imNf15JTuM8ajMx5oJX7JQTm8KOLRJjUdZZAd5Gtp0ezfYAQK1ZjEWwCmfp8j8FBgJIDSLpjxl88SXMLgATXYfhklnQvKlQjs/X3Ka4zdTrav2tMH9IAo6TSNZhlPQNsUory1SGHs+KqHv4p0sG8oWuKYhfBj8rWHQdUVptkIBKgojFDeJJD04Tbf9kUakbK/8KuXB6zF5H4WN3p4rMMwkClyTGeYO4LDg5TzVn8NnUi3/b/vO/3us1G/TMoRe/6umUfpQxrwo+7S2T6A4YwetWRp6xALLhp+HfAWnn0lA/D8/w1WpKwIDAQABAoIBAQC5cdQxRa5rddm48PbSCPWeFWkNW3DLDI6CYyedqDvxZwer+QtKXzww1I4X+7ZptiC9odLjb+uMkGHyXZXtnjPTPyounQWZ8JLILUGu0mbqWYwVXp9raHVr2OOHiKaz1D+BnbkOM4L9JUZ2eJL9ZaoNXLd4WdmRp8qM4WI0xqQDzOANx2HhyL/+dJmQeIUND+pdeH+Z+fYowU3ho32txNvBnMXQhF1T5K9i1VO5W49RAjIRbENsT+paPGKbNubDHRt1j36ktK4eC4HSdgv8tccdsGyrEiIbAt1XsTZfM8ie4D3A8RhSxiTC6Fkgv6vIm+iFTLzBFZKesOBcd8sfKeyBAoGBAOts5PQQJhldPDzlbnqzxMOR98WHbkVZjCqWSkNA34vqyFuPcRuX0rHK/qpg23ilbUP0fGMDTGgFzTt51FZLL16SXyRfjNhzjdmryryeddQwbp92ta2GEgnU6t1FyCuSCtcLDKJd/D9A9dC5UI6z+ES4TOnbR3nakXK9t4cUOFthAoGBAOSu+wL+SEA5erR+m3LpOsELK68CCJQPxn3VpoVfJZawgF+fEoXVMLTERxJput1+ADomIEdNc9ex86TjKx9gJ4piNHscRPFeT/AgESOIGHLOc1gk2DPqNj6wBIarUJQ9t4KcHScboh1dTPJeqqv2NSwIiLQoqFUIhfKZLnrW3zwLAoGBAJh0hC+o5YM3ZXLqAIllMN6VACbidP5j5ukNOjojIKCzAdyJH24G+2I3WoNrBbUzK3b+NC7KTAhw+V6ynlbjiWFs2D/twH/LFOkI3tkWpKcsVfbeIPimAbhsMUvpjJ7qjCqF9UCQLHGp14W6+/ftg7C8yNIINlkquVXclaTb60MBAoGAPqmL8ogG+EJH00mWAujRxq/u6meePiQMedKfbJBj1mTK6GjIRI/kZsQZzXvXTnYGTejAk4kvov0KDDaLTG+mpg6+3rUiVxlGwj+nMptKR7s2dAK0k5UsBAVrWBN9YwF+VXW9r0etJmq4ePljvvcaHtS/0M4LQjGxsoYy7EoQpX0CgYAhnf0McB7F1MxSjB0soMNv/v5utVzVihS3re2yKNdkI/YUEMB+yU3Q4gh+OljjBM6Y5To3BsQBAx4l2CysMKFHjIE/5AtdbvIS+chZZqB3vcZXSayvX8P1Z1uFdw/saiO2cRDJmR+TxaOPa2C9SzDoNTACthwLErHfzvEvVroKmw== +space: + gcTTL: 60 + syncPeriod: 10 +storage: + path: db +metric: + addr: "" +log: + production: false + defaultLevel: "" + namedLevels: {} diff --git a/etc/configs/cons1.yml b/etc/configs/cons1.yml new file mode 100755 index 00000000..eea98cc4 --- /dev/null +++ b/etc/configs/cons1.yml @@ -0,0 +1,19 @@ +grpcServer: + listenAddrs: + - 127.0.0.1:4530 + tls: false +account: + peerId: 12D3KooWA1MZaN1U8NHDnkvbN5wsacRGvbn7dd341S4pAzXofSng + peerKey: rLHblNZKOvJxnAKrwIlxkWy70J3aXDiCYVr8iV+PyQAC0LQLKUjXGJzqOdS4tMU0UUPGNo0VQx8q4YHqqt3KLQ== + signingKey: rLHblNZKOvJxnAKrwIlxkWy70J3aXDiCYVr8iV+PyQAC0LQLKUjXGJzqOdS4tMU0UUPGNo0VQx8q4YHqqt3KLQ== + encryptionKey: MIIEowIBAAKCAQEAyzE3C3bWEdKCJ4HbBfP0psg34ZsdmiZcflOu55aLLnl2ctzWv17SO6dU6C8XEoVtJA4V+tvfsnQTro6sIy7DDcDpGMnA7HmLHzK9GFKQyC/9EzEFg6s9F4A6ZkW/hyQNNfE7NQBokJj+uvSXzw7wb1b535hvg+o+ZPdeQQfcKFIqZKQWMXOHHSseVV4JH2kJ7BNgvmRU1EEkZ/l9FmrdvDDSUv+SgLz0ogESQv3yR/bwwa07BVaMCAdwAMZAcD04KUjEGpEmHfsDERYRNGvOJ5bnJSHTI9QEow1P53CtOMVQ9Ak3YhqyycGtvaVmrY/CfnFJzUbb8IDmvgW6jw/rrQIDAQABAoIBAD38mJdFvI6ZUp1szv1k6/jJUcrggEpbc5ISQ2RhF7qo0Uq/NkARVD9gj9V5MCe1TpNWPLxXwUl2gd6Zpcfh5x1WAYZPXiyF87wjxW4bGhIIGcN2DAGcBroZozc6BfDbPbB8FBzaMAwUsHkmTv2ayByfQwFERpjOqBQzJqzeEfq2cxFovcQdyhHk3WmfH1+zrGENs4IVVmfmIG1LzXehaXJ7jHqlryyKyKpUmXOmymEtSB5It60pl+9RNNlaez9OzreWgE4bQaeQU09I8105YdIISmvZWGZ6PsBo3ma+Rj+si7zYGLF5CsbGxT+U9olpiO/DW+UbfrDHy0bAArlDOD0CgYEA5dI1b1GDwAifd4fR6Zv64AMFAFMo5hWW1EHsUtXVo1UD0IgheI0oxg4aqs93SkL7uMVrM5rKjfstFcpWfaSfzy38+8mneRsbsI4d17RR5g0F4D+2/uLRYRRU74m4ThQjfP6wf+eDAM1+rdmT86cyQab5y1VU9hqd159xCderu+8CgYEA4lZ77Ygdy2mHmfdzFyQ6eJJhsC5FoapJWnaw7LISEiJgnAun+qeIl1r3yFbuNK1Wx55qfdvz4v7X0KJV8HwFgpxzT7CoUybT3SncItWPwi80tq/lxklZvq6LUeOiNQrpGvECCUrPQ3Wdl0lcmOiUw1GXliAQEVdzBOT+0hGMZiMCgYEAtZ76O47f39LwszXS3hs2l/HK8gbGO460M+olKRF0VC/LY/ExAmQL5Pkgefya+UUWSV866P1bNflaF+5fi8udv81IMHOctkiGCXFGhEEst/Fyw1WW+LenYGEA/oyH6qxfn1hng60iCnBbvGhGVDe9r8SVg+tbyWIfe1e1rWGThmECgYBltGkBpn2E7wmw5OGBj5T6owRkj5ZYe9V0YgtEgQvfvDTfSdmUp32YTZc0HePyJcXt80B1B8ZCxTMjHB8z7fbn5vdl4sLwgm0HX4z81ixAHMg6IzZD8Kf0KCiQhpJX9Wwj4BKDLGuQK6TB24RRbYmTbvGH0yaFNF+J3oCm0p3dMwKBgA1TTXLpbL5lnBaAaWAHYSV9rtqvBkyVfcnB9/Ez9MNSBOQIbk82w9Pb892qjcNhTAfgRNrYTd6JZl8Sov98T0OJW0uMHFV04NSqo+RLQTaGjMfrWQ2ZWfSM4tFkoWA2mFh+R8VblzTJObdu1zDyuVYscfTv3sFnV/QX+zJWJipB +mongo: + connect: mongodb://localhost:27017/?w=majority + database: consensus + logCollection: log +metric: + addr: "" +log: + production: false + defaultLevel: "" + namedLevels: {} diff --git a/etc/configs/cons2.yml b/etc/configs/cons2.yml new file mode 100755 index 00000000..48bc0bde --- /dev/null +++ b/etc/configs/cons2.yml @@ -0,0 +1,19 @@ +grpcServer: + listenAddrs: + - 127.0.0.1:4531 + tls: false +account: + peerId: 12D3KooWKyYmekF5ongQGMwBgx4ZsPDQiyFjHtd5ZfKGsoXTYY7h + peerKey: jRWkSxzPtg8SF3rJ7oqhby6UvS6fnWGOO2GlAePHqkWW7xWHE1XC2R8Wt0E/4sFVhpam5OKqyIm9aDsWiILHmA== + signingKey: jRWkSxzPtg8SF3rJ7oqhby6UvS6fnWGOO2GlAePHqkWW7xWHE1XC2R8Wt0E/4sFVhpam5OKqyIm9aDsWiILHmA== + encryptionKey: MIIEpAIBAAKCAQEAy3UBKE5OifVxeU60KbYUQ9OFob6uixxauUVn8cn24ZX9C2qPAMLQGTYBcWp0GKILqRMgcDmDV1DXF4dNzSYQE4qFDvQ0C5ltoV9vDBAxhyDEN6nftD4K2vvn+fBVYYAXJp//I/2YcdZpOzu7KFHPst74tnFZB1+7LX0oGToGzevFKgqmvoQ1LUj7OqWnINBz4jA61h2WMp11j6/BO71kEeMdeMJyhmO+w6oFlLhd3b6Vsqd/nIc4SKh0yS3jdn+OchgQEMHvNL0KrvExPwdnzQGtU9E2nrf193loeFoCZayX29x+aDgTah2V8JlcN2do40q9h3dJJ6FCgJkk5gBz8wIDAQABAoIBADy0Ym4GP0TGaN8K7pJrc0xxdjO2UxnKkf8piEQKQJE6UU/wsU5G0hRTmsaePpmC7/u4aztQzbFlu2eXxUzqiG1sLRszHbxAQQefE+EDi+OHkUQSeV6sDE0eUC6w2KjIsR+jKVsxtSRyFt/HiKYVEuWJxaeZ1jhvBcgiya4NNC6IG/wS4JYG5iPs8QZZPDT+geR2y1jVQdttchVGxKbthMxDBPfSlG05QFhb/8frCfS+jqBHla1e3UhBfdlA6elZW+IxOoxoKvLLZtMrI5+3D162ZBsfoIGXuME3YqovMBdISnRQBbQ9gsSZlYQsosWofSd2JPxVOm7YdOmOIo4sEcECgYEA3F2W2vQLdxtJ+RaLPrGICtNTXwkP3Fi5KGT/QFGCguJpGo1Z3sGgL6dvD0iKBBCTcmyDj3eBGYW80B/2J+tRiAt/0ME413Pfa6txl7LgKNDlFgAb4/ycth0TocQQE2oL1OawHBr+BiE2b5IbIOyi8wsaQNdtORYzRLS9clieWKMCgYEA7Ft1H2/HAQMBOLeyyn2LMaPkewe5TM/6K+CoDA9orcoRmZ+B3ht2iBkcJE3Efa0c2YDDbL3GENfUzzntF91auyC/aKI3A8MxBZg/6QEiTytgcvbCSeXkwZUCJeNr+BAFLiWOE26sg8P2cJPT5JfjgPkqA4dLWvqwvMFe9LcInHECgYEArVoGSToAJvNVrthYM7puva1egX1cd8dn6OoCjjNQyuuXKOcXUo/ZFoPNbyVuRSJRC4tntx2Ydl5pmQP7nY2VdsMtCihmMb8ae9XDp0V050blX/g3+JKJKQ4YmoHk75DVu+a5lXJ6cJICA6TZKH5e9Xi/b1DIwEbBkAPqoCAseKcCgYEAxSTj5HzPeMCQ3EYdE1j0KUuS4CvpG3C+MqsIgEa6AXtygrjREfnGPG71UjKrmkgysBj+6EzCUHo2P0MJx8YST9NY1GW5jaHZ2djMNgWEIJUFtd6s4Aapb+5iBEhVXmu+ZmdcwkimDKH/hJdJPnqSgJlTue23pQNFN6vzEBs7S4ECgYBhY2YJL22+btVAYR6g/pOkn+50h8S/TtEH+NUL0SKnv8N96WvoBjUJapgNNrWPzzUgmGzS+uSweSTGM5LFeidNU4tEHZ1yNt7nrlnaJP2anGgVp3JcvNQiy1Ffwvs1efo0c8Tc+fORj9V4fhdctpSAoISETDtoGcZbQjUtB/aqYQ== +mongo: + connect: mongodb://localhost:27017/?w=majority + database: consensus + logCollection: log +metric: + addr: "" +log: + production: false + defaultLevel: "" + namedLevels: {} diff --git a/etc/configs/cons3.yml b/etc/configs/cons3.yml new file mode 100755 index 00000000..c6eb2d44 --- /dev/null +++ b/etc/configs/cons3.yml @@ -0,0 +1,19 @@ +grpcServer: + listenAddrs: + - 127.0.0.1:4532 + tls: false +account: + peerId: 12D3KooWLgWXJyeG869h3Awf9s7Jt7dw9ZnNg5ZFkMFKSHs6Bify + peerKey: 6DyqyTRgR35/TNWpEbqVm8NbbmOULNuQDYEk6C+ltyyhbVs1bhOkA2nigRoE6JFip83k2yVjsa2r4ST85kW0OA== + signingKey: 6DyqyTRgR35/TNWpEbqVm8NbbmOULNuQDYEk6C+ltyyhbVs1bhOkA2nigRoE6JFip83k2yVjsa2r4ST85kW0OA== + encryptionKey: MIIEogIBAAKCAQEAqCZtyjHrM7jUZNyZNchUAgYIZb27YRRsfC6ca2xgdbtIjq0ts9af1+JQcmHMjGyxUTvLjx4I4IPJzDF5KYRwiGSWM4avhfxKxVToW0j8UlqQH+nbN7/TmmQfW8+L4CsgaXcf34uE+CfnyoUnwPoWLe/6SI1m5n/99PcWa9X8monNoTSMoeSOCm/csyK+BBGW9BTOMgo+2Ceyu44KcERl/pdkBGmba1xz3SogEq1m7cpG2Y0Hmd9dyHVJU2jSFczVJQkWF6RuifRoGcjdtbRrY5E8LsF2CM8HeeAZ/0g/q7yoR6D/nCrWaejszXObi+GNEo51EdJW+7gD8g2U6vUqkQIDAQABAoIBAG010FbjhxRntiLwF94Th2RtEKUrznil8DPTfipTEG9GvUBVf/puqhBn38H6fQSzT5MoF/STGEbhsX4an8v0RbaARgGfN375NoLlu6gWRjMiuLrRg1y5DTEYWDmkGf/1Yq68/QmOr0URff1N8Fzo0ODzHQZkOHH6rTGeDYTqTY78ZfU17yGXoNSmXycAqbTGczBP1RvyDRd4mIuBg11E/+A4GBxe8QaSZzJsyfvtBi7jUqKgdDDDI5Gz4x90NZ90L6jRFNvlhuosGETQ80oyNN1soa6tVSq7UhGI7+wcJDyaXQF32/TnqIXArScH5gRLxHiP+FfTDCHzl5iZG5m/D3UCgYEAzHe6oorAELbpcRaUJQayOkMJIAI7KP5EVI2IbP1fhBaW+5BYtzGlxKZOXWZA057E0pjwO99rmVNs2rW6mU0mCfw9hP3oWv4EgszU2DEx1+iHhNF6cy/zGDh3lgDNXgRPoBRR05IS1Ffs8uEgVfhiVjtiv4FyrVE9fY2cTH+7YXcCgYEA0od8pJLXOhcj1ap/1Y0phaHv//ulSqLBtKEQTy36zDw9DfcIozB8LCIK/Q/3nr4RHmd1YQVRDoTB9pX8eUuoJvM3Do9CJiH5/0PXFgIOZZsDXtl/TmL/1diHw2isttDCQF6I+q5lRYlbA+oqc8Vko2c5LQchXE24oz9670gFFjcCgYApDSjVlZH2SSMZZ3Ua8fs6o1bjrE8Abfx+FWR8rWpN9NMfct28+iTUFKfLLMp7MndF6Rriinrp78v9JVtviAPJIXGgj/HkwvdY45MgTNA7Dx6WVhCFq+zcwgmQfly9MZRjCXFcTwmkxHp4USbS2+mycn3jATRrA9KasKHe4g5XBQKBgH/xPtp1Mr9m2Kw9FbseMqG3rDcRI36cMsQnLdYwxz3fTetyuZkTGiNn/O2WCpI6SAUGMttnc78zBv1oYSsFw4cIP+llPnoWI+vxuoDxdvZgoke+PhPRLlEzai5jKrNfYu3jhbNy0LDVrK5QXMRGrcZwMNsgfjGuOgtbxMYuKok5AoGAImYTQ6e0fliVoHO5CjClQRpj3oKsTmB4hwtMofSZ+tFVPOakVM6P4K8UzMa2jcgz3+KgLAD8awpHv0ISO+qdSwG9MgnfIxhz8jxatgRBXdhICHrnqCqwZqyV0hrVmuUeg0uXPN5AisvfGEiGpkAPsQCo3bhAqMD+4QooKCgpz+Y= +mongo: + connect: mongodb://localhost:27017/?w=majority + database: consensus + logCollection: log +metric: + addr: "" +log: + production: false + defaultLevel: "" + namedLevels: {} diff --git a/etc/configs/node1.yml b/etc/configs/node1.yml new file mode 100755 index 00000000..431d2b09 --- /dev/null +++ b/etc/configs/node1.yml @@ -0,0 +1,37 @@ +anytype: + swarmKey: /key/swarm/psk/1.0.0/base16/209992e611c27d5dce8fbd2e7389f6b51da9bee980992ef60739460b536139ec +grpcServer: + listenAddrs: + - 127.0.0.1:4430 + tls: false +account: + peerId: 12D3KooWLn13hDrZ6YRGM517fHf2zS6qhPNRu18inLMpRqn1YGKu + peerKey: 3mzfKBWtn7mitFEgq8u4eysWOJ6ySbUs49irfHwcuOmi1YMpobz9anoqd4yaT1owZiRPYXqx5k2Z4sNVRE3kXA== + signingKey: 3mzfKBWtn7mitFEgq8u4eysWOJ6ySbUs49irfHwcuOmi1YMpobz9anoqd4yaT1owZiRPYXqx5k2Z4sNVRE3kXA== + encryptionKey: MIIEpQIBAAKCAQEA3U7b4w9JTKE3TLM1WQ5iqdLbvUuozMp/hDEg7S15Gr6wrtLomMSBkfmVQ3Cu+CHdxAFqUFClItYlSFgtZWIFiSiQxCeaN2dmgczd9T4TlRAw6y6uJXtT9r7FIgizPP4B0/tnzPI6yYgpdwzCV2nRSjw3mMr5Nav3QYs18kYrJ1/Np2Wob5HOoRTUD++pPrToevTb7GNL/irrC8wXSE7oU6S7ix6Nh9vzEHg/V5FONBF/wWD/ri7Gy0j0qgUQ+gjxLWKr8xPDnRAve13zzo+54lGCyVvlm/rwCY9Jx378V1IuRx+S8F/GFuVozHD4XVaoSTtpCWPBQNSKDXgaIIKDowIDAQABAoIBACpMXj6ht1LMJXOldPbWhwkKYjFl+pdZxNGRSkfKvzDbbY2chhRcyp8J4vuG2ApY/rftxVIgd8+Wun1/TP3ppEE43aKAJzubqb35WBr9iGSfOZpZy7MiRUQN5kPBAfEQY20OyiIj0hSez74PVD283eGgbMfpU4Rsn8+JOgBaZPkbPViJLJY8PyHU6vwWw60dye1iJTz9yuBtoEqY0XKxnLaVXTQaWx0Te+VYU8twxDgXFWRaXtHuk7xnxOkCZDLrzIvuOYa5lsLoT8K62LDeXbyHBPhbdW0j4ZYzAOTsaUWpjuJzef9aj3JJdfyADiqb5iu6HHksvKzkZEau34zjilECgYEA/c8ZJm62uJMHNssTJYiLRw89l5hYwIZ/1TXdFRF8+xrTin5opYjpscSTO5bY2IYqLx2xuPiJCY1eGGB9L/RtkaVh51ySzq0d+4zpPIRKFcOOgdxHwlgoCgIhQECyfJZNMFGBUIlPXZ/phvXOXRvWFzDPhqThenVG2QzF+wLP0AUCgYEA3zfviQFJ1FOKJMozYO3tUZFmsIrAcO9hfuE7uuWz0Fw2m1XiwxjuOr1RbsSsh/lKke2h4tiGrlfiFhwCpIp91NkVTFrtFOQxbDxkYLkFiWkZDkOaK9YhKMa2cgEm3p+RGawokjbm51LKf+cbYN9xGaAe3y2WzIE4kNpfWE4SXYcCgYEAoagcrrvpqZoMCDxED63ud+4fHsUsEkQYe6Z5EAg5gH5PqnBlGrofjthTpqqnpxGdILFbFyNFtU3TVtduJPMcLp4Vw5TU9MqSxDu1+pOP1FjgFZpGImSf6+/7Wb9bb7sToujm4nLymAFYblt1exxVuiOeqnWuH58+5tQZ7YyW7DkCgYEAl7WuqZEkmpiEpWh/7vsGdo+6GXbUQG2R9+gg7m+7/HsP6hc/XZYOJAIT3JLzKB84nWHCyyiasNeuI5S5/xbZWtaH8TNDOxW0uXl6R3q41qGFk/pCSFTqiIo16dn6jwgoWCh4EpgZ61KLqs5p/zcd6Wq4ULrtaOTSizC/6IZ3WPUCgYEA6xCJy3+ICCgr8/c7hfd2Ylb3aOsXIffdgALhXjDcrNUCqgB4R+S3WReAwrABemQGl4tySQE/1f3Ru7SzMMciFogGyJ/YSXqSi6Y8oDD7MqlKPiWlN6WY1nSRMlLbkUOqpA5JaDM0kcmXjZpBBQr277GOnh9uKN8zUy5xoptctxI= +apiServer: + port: "8080" +nodes: + - peerId: 12D3KooWLn13hDrZ6YRGM517fHf2zS6qhPNRu18inLMpRqn1YGKu + address: 127.0.0.1:4430 + signingKey: 3mzfKBWtn7mitFEgq8u4eysWOJ6ySbUs49irfHwcuOmi1YMpobz9anoqd4yaT1owZiRPYXqx5k2Z4sNVRE3kXA== + encryptionKey: MIIEpQIBAAKCAQEA3U7b4w9JTKE3TLM1WQ5iqdLbvUuozMp/hDEg7S15Gr6wrtLomMSBkfmVQ3Cu+CHdxAFqUFClItYlSFgtZWIFiSiQxCeaN2dmgczd9T4TlRAw6y6uJXtT9r7FIgizPP4B0/tnzPI6yYgpdwzCV2nRSjw3mMr5Nav3QYs18kYrJ1/Np2Wob5HOoRTUD++pPrToevTb7GNL/irrC8wXSE7oU6S7ix6Nh9vzEHg/V5FONBF/wWD/ri7Gy0j0qgUQ+gjxLWKr8xPDnRAve13zzo+54lGCyVvlm/rwCY9Jx378V1IuRx+S8F/GFuVozHD4XVaoSTtpCWPBQNSKDXgaIIKDowIDAQABAoIBACpMXj6ht1LMJXOldPbWhwkKYjFl+pdZxNGRSkfKvzDbbY2chhRcyp8J4vuG2ApY/rftxVIgd8+Wun1/TP3ppEE43aKAJzubqb35WBr9iGSfOZpZy7MiRUQN5kPBAfEQY20OyiIj0hSez74PVD283eGgbMfpU4Rsn8+JOgBaZPkbPViJLJY8PyHU6vwWw60dye1iJTz9yuBtoEqY0XKxnLaVXTQaWx0Te+VYU8twxDgXFWRaXtHuk7xnxOkCZDLrzIvuOYa5lsLoT8K62LDeXbyHBPhbdW0j4ZYzAOTsaUWpjuJzef9aj3JJdfyADiqb5iu6HHksvKzkZEau34zjilECgYEA/c8ZJm62uJMHNssTJYiLRw89l5hYwIZ/1TXdFRF8+xrTin5opYjpscSTO5bY2IYqLx2xuPiJCY1eGGB9L/RtkaVh51ySzq0d+4zpPIRKFcOOgdxHwlgoCgIhQECyfJZNMFGBUIlPXZ/phvXOXRvWFzDPhqThenVG2QzF+wLP0AUCgYEA3zfviQFJ1FOKJMozYO3tUZFmsIrAcO9hfuE7uuWz0Fw2m1XiwxjuOr1RbsSsh/lKke2h4tiGrlfiFhwCpIp91NkVTFrtFOQxbDxkYLkFiWkZDkOaK9YhKMa2cgEm3p+RGawokjbm51LKf+cbYN9xGaAe3y2WzIE4kNpfWE4SXYcCgYEAoagcrrvpqZoMCDxED63ud+4fHsUsEkQYe6Z5EAg5gH5PqnBlGrofjthTpqqnpxGdILFbFyNFtU3TVtduJPMcLp4Vw5TU9MqSxDu1+pOP1FjgFZpGImSf6+/7Wb9bb7sToujm4nLymAFYblt1exxVuiOeqnWuH58+5tQZ7YyW7DkCgYEAl7WuqZEkmpiEpWh/7vsGdo+6GXbUQG2R9+gg7m+7/HsP6hc/XZYOJAIT3JLzKB84nWHCyyiasNeuI5S5/xbZWtaH8TNDOxW0uXl6R3q41qGFk/pCSFTqiIo16dn6jwgoWCh4EpgZ61KLqs5p/zcd6Wq4ULrtaOTSizC/6IZ3WPUCgYEA6xCJy3+ICCgr8/c7hfd2Ylb3aOsXIffdgALhXjDcrNUCqgB4R+S3WReAwrABemQGl4tySQE/1f3Ru7SzMMciFogGyJ/YSXqSi6Y8oDD7MqlKPiWlN6WY1nSRMlLbkUOqpA5JaDM0kcmXjZpBBQr277GOnh9uKN8zUy5xoptctxI= + - peerId: 12D3KooWLtuKtCPBYrFJV1NdejiCr2s614ppe9rmUXnkTHtAUD5U + address: 127.0.0.1:4431 + signingKey: 07JMoW5cQUtGO9nNIGQo9e99b7Wf/4YvTtNEA0lt4gCkmhwB1EB9ay+kitxVJJgmdyGLxbUUlGqwXsAj0zlHWw== + encryptionKey: MIIEpAIBAAKCAQEA7cA6J/icl8wseeXkt8oJr5AeYadUAG5EdCOdHj4S/Z7ivff4MOIKAeQITpq+rqhmXxOePYXSpQXE20Y9PW9tuw4gzOuq1ylSG/MWMcLDH1eIxg66rnmUqUbdiW4GGJjVjc9jvN0Up+MfSrUF6fM0jWTFoXVJQIeQQGERCIYjFzjfBl1xYvPghdxNgei/K5ZGYRggT28143XdIH4KTXGtp51hAKoyY9eCqYMtm9wvjxazhPVxO2CsYaqMxBLshY3jfHNqJnx8u6+h4Bl4uUcdbLNUgMcEgk7ehbQp2K0CqNoKXxbCTI6V57UVcJHDIaO5B6FyR6BguzHHNPJ4yd3q9wIDAQABAoIBAQCm2Mf3VRlPzhFIWnVwJXE2q8Umcu8Yfkm712Jj3twk8GPfPS4H4Bl1yjmqMB6xI6zz/CiItGlnNe04lMpVWuV+6CNMq/ZwmKbuxmFE+pFEZYGuvJd16gzR3tGJqJTOnjMAGhK8b8oXJ+TF4NQNooe20ol/DXgiuQAargPuH3RwzjYmF3N8VI4KUc3LaG4TwVXn4LwPOxrQSnfwJlZwLml1HAKOV0qcG0mXX6ZXOpoVhEoRPdQyUHc8ZW+53Agbtind7bYh5TsMVDFUrcgNwnwTOsWjil049la1IJO2uMRluacKlrtyzEp6zqrW8ZJO7mYAO69x4WyGqf2ZgIdA6djBAoGBAPqRHWAIgPa80eXbwCYkRtUG/ONBsQGi7+wm6nyhkXvNXJeokgH2DCgLH2+fW2scfOJuZc9r5WftEjOBvNfr2LDcwdyTSTh21WYcPSZx9HDf2d5/SWTcjNcyU0b5qfWIUKi/Zm9UY7r3X7yMA5dUD/cvu1PBJ5NWFrK1Gm2ph44dAoGBAPLn+LkHweU0fbxQq/76T5yVVpMKUaE9xwrJlUxEDPAQGnLPbFg4JeUt/YPhsOV85W4c4oQE+uFZrF0uf+1fEnS6MOJ+sq668upzC2hBp1B5138wM7615v1rvXVVH6qXfFop67FdBzPHt1NAN43mEIBZHTQ5hSVXFlYSZp9mxuEjAoGBAKCzUVO2IIAeub/iIGpV+dfGk4ptJ0kVZyreCqXEObpdC3V496uqUkGcYJ0GZ2ta6f2PMFzHpmnw8it2mdchu+gyrWL6U4uTK2pB0jZF/7Ak4WaB3GCD0xBxhleO6CJBOvn/R4M/bHcNEKmsYuE7WMIAKvScfPVR0VzsKfcLM5VBAoGAVvWg32zdh1bBZLdku8WU1rPH6KAbFSRuq3f7UPBTyWWaclu7p+GB/4f1aE9V6vJJmKASn7zArAhUYo+REMOmcc9uTMea5F7dM/23qb1HTtIvycLR44ZviW4Wx3iP+5x70jOLw1VQjMME6HLm8I/afHhqshWdiv6ganPv9UTwEg0CgYBSDi2dqg8F7ij5CN+LMDLSn3b8GCw+7efGIt7imm/O2V/FlHD40IA6qGg6DXNQrnoZQt94nMb1cZEvm1dxi6rmQNrhCyoMogAaPqgFhZGq1OjmhVZiXFUWy4WAcjdzFc9wZd3/XtaofRKHLK+ngTFhhVApKypLk3Rg9bCAAjzyVg== + - peerId: 12D3KooWDCypXSyN6ppuMZGxVnBd1ZQCMV4y7Bn187S4duYmf8rA + address: 127.0.0.1:4432 + signingKey: SGyNE0dFaQgtgNuzdcO7LB+TEz9VHAOtlQLk6WWkrkQyXiZV3casg8Q2/4PO1Oylc8Fu72RU001Hclj5JCbiLw== + encryptionKey: MIIEpAIBAAKCAQEA0k3mw4FyexRkLgLjHzYs4Ppeyv6r9ZrP00imNf15JTuM8ajMx5oJX7JQTm8KOLRJjUdZZAd5Gtp0ezfYAQK1ZjEWwCmfp8j8FBgJIDSLpjxl88SXMLgATXYfhklnQvKlQjs/X3Ka4zdTrav2tMH9IAo6TSNZhlPQNsUory1SGHs+KqHv4p0sG8oWuKYhfBj8rWHQdUVptkIBKgojFDeJJD04Tbf9kUakbK/8KuXB6zF5H4WN3p4rMMwkClyTGeYO4LDg5TzVn8NnUi3/b/vO/3us1G/TMoRe/6umUfpQxrwo+7S2T6A4YwetWRp6xALLhp+HfAWnn0lA/D8/w1WpKwIDAQABAoIBAQC5cdQxRa5rddm48PbSCPWeFWkNW3DLDI6CYyedqDvxZwer+QtKXzww1I4X+7ZptiC9odLjb+uMkGHyXZXtnjPTPyounQWZ8JLILUGu0mbqWYwVXp9raHVr2OOHiKaz1D+BnbkOM4L9JUZ2eJL9ZaoNXLd4WdmRp8qM4WI0xqQDzOANx2HhyL/+dJmQeIUND+pdeH+Z+fYowU3ho32txNvBnMXQhF1T5K9i1VO5W49RAjIRbENsT+paPGKbNubDHRt1j36ktK4eC4HSdgv8tccdsGyrEiIbAt1XsTZfM8ie4D3A8RhSxiTC6Fkgv6vIm+iFTLzBFZKesOBcd8sfKeyBAoGBAOts5PQQJhldPDzlbnqzxMOR98WHbkVZjCqWSkNA34vqyFuPcRuX0rHK/qpg23ilbUP0fGMDTGgFzTt51FZLL16SXyRfjNhzjdmryryeddQwbp92ta2GEgnU6t1FyCuSCtcLDKJd/D9A9dC5UI6z+ES4TOnbR3nakXK9t4cUOFthAoGBAOSu+wL+SEA5erR+m3LpOsELK68CCJQPxn3VpoVfJZawgF+fEoXVMLTERxJput1+ADomIEdNc9ex86TjKx9gJ4piNHscRPFeT/AgESOIGHLOc1gk2DPqNj6wBIarUJQ9t4KcHScboh1dTPJeqqv2NSwIiLQoqFUIhfKZLnrW3zwLAoGBAJh0hC+o5YM3ZXLqAIllMN6VACbidP5j5ukNOjojIKCzAdyJH24G+2I3WoNrBbUzK3b+NC7KTAhw+V6ynlbjiWFs2D/twH/LFOkI3tkWpKcsVfbeIPimAbhsMUvpjJ7qjCqF9UCQLHGp14W6+/ftg7C8yNIINlkquVXclaTb60MBAoGAPqmL8ogG+EJH00mWAujRxq/u6meePiQMedKfbJBj1mTK6GjIRI/kZsQZzXvXTnYGTejAk4kvov0KDDaLTG+mpg6+3rUiVxlGwj+nMptKR7s2dAK0k5UsBAVrWBN9YwF+VXW9r0etJmq4ePljvvcaHtS/0M4LQjGxsoYy7EoQpX0CgYAhnf0McB7F1MxSjB0soMNv/v5utVzVihS3re2yKNdkI/YUEMB+yU3Q4gh+OljjBM6Y5To3BsQBAx4l2CysMKFHjIE/5AtdbvIS+chZZqB3vcZXSayvX8P1Z1uFdw/saiO2cRDJmR+TxaOPa2C9SzDoNTACthwLErHfzvEvVroKmw== +space: + gcTTL: 60 + syncPeriod: 10 +storage: + path: db +metric: + addr: "" +log: + production: false + defaultLevel: "" + namedLevels: {} diff --git a/etc/configs/node2.yml b/etc/configs/node2.yml new file mode 100755 index 00000000..dabf73a2 --- /dev/null +++ b/etc/configs/node2.yml @@ -0,0 +1,37 @@ +anytype: + swarmKey: /key/swarm/psk/1.0.0/base16/209992e611c27d5dce8fbd2e7389f6b51da9bee980992ef60739460b536139ec +grpcServer: + listenAddrs: + - 127.0.0.1:4431 + tls: false +account: + peerId: 12D3KooWLtuKtCPBYrFJV1NdejiCr2s614ppe9rmUXnkTHtAUD5U + peerKey: 07JMoW5cQUtGO9nNIGQo9e99b7Wf/4YvTtNEA0lt4gCkmhwB1EB9ay+kitxVJJgmdyGLxbUUlGqwXsAj0zlHWw== + signingKey: 07JMoW5cQUtGO9nNIGQo9e99b7Wf/4YvTtNEA0lt4gCkmhwB1EB9ay+kitxVJJgmdyGLxbUUlGqwXsAj0zlHWw== + encryptionKey: MIIEpAIBAAKCAQEA7cA6J/icl8wseeXkt8oJr5AeYadUAG5EdCOdHj4S/Z7ivff4MOIKAeQITpq+rqhmXxOePYXSpQXE20Y9PW9tuw4gzOuq1ylSG/MWMcLDH1eIxg66rnmUqUbdiW4GGJjVjc9jvN0Up+MfSrUF6fM0jWTFoXVJQIeQQGERCIYjFzjfBl1xYvPghdxNgei/K5ZGYRggT28143XdIH4KTXGtp51hAKoyY9eCqYMtm9wvjxazhPVxO2CsYaqMxBLshY3jfHNqJnx8u6+h4Bl4uUcdbLNUgMcEgk7ehbQp2K0CqNoKXxbCTI6V57UVcJHDIaO5B6FyR6BguzHHNPJ4yd3q9wIDAQABAoIBAQCm2Mf3VRlPzhFIWnVwJXE2q8Umcu8Yfkm712Jj3twk8GPfPS4H4Bl1yjmqMB6xI6zz/CiItGlnNe04lMpVWuV+6CNMq/ZwmKbuxmFE+pFEZYGuvJd16gzR3tGJqJTOnjMAGhK8b8oXJ+TF4NQNooe20ol/DXgiuQAargPuH3RwzjYmF3N8VI4KUc3LaG4TwVXn4LwPOxrQSnfwJlZwLml1HAKOV0qcG0mXX6ZXOpoVhEoRPdQyUHc8ZW+53Agbtind7bYh5TsMVDFUrcgNwnwTOsWjil049la1IJO2uMRluacKlrtyzEp6zqrW8ZJO7mYAO69x4WyGqf2ZgIdA6djBAoGBAPqRHWAIgPa80eXbwCYkRtUG/ONBsQGi7+wm6nyhkXvNXJeokgH2DCgLH2+fW2scfOJuZc9r5WftEjOBvNfr2LDcwdyTSTh21WYcPSZx9HDf2d5/SWTcjNcyU0b5qfWIUKi/Zm9UY7r3X7yMA5dUD/cvu1PBJ5NWFrK1Gm2ph44dAoGBAPLn+LkHweU0fbxQq/76T5yVVpMKUaE9xwrJlUxEDPAQGnLPbFg4JeUt/YPhsOV85W4c4oQE+uFZrF0uf+1fEnS6MOJ+sq668upzC2hBp1B5138wM7615v1rvXVVH6qXfFop67FdBzPHt1NAN43mEIBZHTQ5hSVXFlYSZp9mxuEjAoGBAKCzUVO2IIAeub/iIGpV+dfGk4ptJ0kVZyreCqXEObpdC3V496uqUkGcYJ0GZ2ta6f2PMFzHpmnw8it2mdchu+gyrWL6U4uTK2pB0jZF/7Ak4WaB3GCD0xBxhleO6CJBOvn/R4M/bHcNEKmsYuE7WMIAKvScfPVR0VzsKfcLM5VBAoGAVvWg32zdh1bBZLdku8WU1rPH6KAbFSRuq3f7UPBTyWWaclu7p+GB/4f1aE9V6vJJmKASn7zArAhUYo+REMOmcc9uTMea5F7dM/23qb1HTtIvycLR44ZviW4Wx3iP+5x70jOLw1VQjMME6HLm8I/afHhqshWdiv6ganPv9UTwEg0CgYBSDi2dqg8F7ij5CN+LMDLSn3b8GCw+7efGIt7imm/O2V/FlHD40IA6qGg6DXNQrnoZQt94nMb1cZEvm1dxi6rmQNrhCyoMogAaPqgFhZGq1OjmhVZiXFUWy4WAcjdzFc9wZd3/XtaofRKHLK+ngTFhhVApKypLk3Rg9bCAAjzyVg== +apiServer: + port: "8081" +nodes: + - peerId: 12D3KooWLn13hDrZ6YRGM517fHf2zS6qhPNRu18inLMpRqn1YGKu + address: 127.0.0.1:4430 + signingKey: 3mzfKBWtn7mitFEgq8u4eysWOJ6ySbUs49irfHwcuOmi1YMpobz9anoqd4yaT1owZiRPYXqx5k2Z4sNVRE3kXA== + encryptionKey: MIIEpQIBAAKCAQEA3U7b4w9JTKE3TLM1WQ5iqdLbvUuozMp/hDEg7S15Gr6wrtLomMSBkfmVQ3Cu+CHdxAFqUFClItYlSFgtZWIFiSiQxCeaN2dmgczd9T4TlRAw6y6uJXtT9r7FIgizPP4B0/tnzPI6yYgpdwzCV2nRSjw3mMr5Nav3QYs18kYrJ1/Np2Wob5HOoRTUD++pPrToevTb7GNL/irrC8wXSE7oU6S7ix6Nh9vzEHg/V5FONBF/wWD/ri7Gy0j0qgUQ+gjxLWKr8xPDnRAve13zzo+54lGCyVvlm/rwCY9Jx378V1IuRx+S8F/GFuVozHD4XVaoSTtpCWPBQNSKDXgaIIKDowIDAQABAoIBACpMXj6ht1LMJXOldPbWhwkKYjFl+pdZxNGRSkfKvzDbbY2chhRcyp8J4vuG2ApY/rftxVIgd8+Wun1/TP3ppEE43aKAJzubqb35WBr9iGSfOZpZy7MiRUQN5kPBAfEQY20OyiIj0hSez74PVD283eGgbMfpU4Rsn8+JOgBaZPkbPViJLJY8PyHU6vwWw60dye1iJTz9yuBtoEqY0XKxnLaVXTQaWx0Te+VYU8twxDgXFWRaXtHuk7xnxOkCZDLrzIvuOYa5lsLoT8K62LDeXbyHBPhbdW0j4ZYzAOTsaUWpjuJzef9aj3JJdfyADiqb5iu6HHksvKzkZEau34zjilECgYEA/c8ZJm62uJMHNssTJYiLRw89l5hYwIZ/1TXdFRF8+xrTin5opYjpscSTO5bY2IYqLx2xuPiJCY1eGGB9L/RtkaVh51ySzq0d+4zpPIRKFcOOgdxHwlgoCgIhQECyfJZNMFGBUIlPXZ/phvXOXRvWFzDPhqThenVG2QzF+wLP0AUCgYEA3zfviQFJ1FOKJMozYO3tUZFmsIrAcO9hfuE7uuWz0Fw2m1XiwxjuOr1RbsSsh/lKke2h4tiGrlfiFhwCpIp91NkVTFrtFOQxbDxkYLkFiWkZDkOaK9YhKMa2cgEm3p+RGawokjbm51LKf+cbYN9xGaAe3y2WzIE4kNpfWE4SXYcCgYEAoagcrrvpqZoMCDxED63ud+4fHsUsEkQYe6Z5EAg5gH5PqnBlGrofjthTpqqnpxGdILFbFyNFtU3TVtduJPMcLp4Vw5TU9MqSxDu1+pOP1FjgFZpGImSf6+/7Wb9bb7sToujm4nLymAFYblt1exxVuiOeqnWuH58+5tQZ7YyW7DkCgYEAl7WuqZEkmpiEpWh/7vsGdo+6GXbUQG2R9+gg7m+7/HsP6hc/XZYOJAIT3JLzKB84nWHCyyiasNeuI5S5/xbZWtaH8TNDOxW0uXl6R3q41qGFk/pCSFTqiIo16dn6jwgoWCh4EpgZ61KLqs5p/zcd6Wq4ULrtaOTSizC/6IZ3WPUCgYEA6xCJy3+ICCgr8/c7hfd2Ylb3aOsXIffdgALhXjDcrNUCqgB4R+S3WReAwrABemQGl4tySQE/1f3Ru7SzMMciFogGyJ/YSXqSi6Y8oDD7MqlKPiWlN6WY1nSRMlLbkUOqpA5JaDM0kcmXjZpBBQr277GOnh9uKN8zUy5xoptctxI= + - peerId: 12D3KooWLtuKtCPBYrFJV1NdejiCr2s614ppe9rmUXnkTHtAUD5U + address: 127.0.0.1:4431 + signingKey: 07JMoW5cQUtGO9nNIGQo9e99b7Wf/4YvTtNEA0lt4gCkmhwB1EB9ay+kitxVJJgmdyGLxbUUlGqwXsAj0zlHWw== + encryptionKey: MIIEpAIBAAKCAQEA7cA6J/icl8wseeXkt8oJr5AeYadUAG5EdCOdHj4S/Z7ivff4MOIKAeQITpq+rqhmXxOePYXSpQXE20Y9PW9tuw4gzOuq1ylSG/MWMcLDH1eIxg66rnmUqUbdiW4GGJjVjc9jvN0Up+MfSrUF6fM0jWTFoXVJQIeQQGERCIYjFzjfBl1xYvPghdxNgei/K5ZGYRggT28143XdIH4KTXGtp51hAKoyY9eCqYMtm9wvjxazhPVxO2CsYaqMxBLshY3jfHNqJnx8u6+h4Bl4uUcdbLNUgMcEgk7ehbQp2K0CqNoKXxbCTI6V57UVcJHDIaO5B6FyR6BguzHHNPJ4yd3q9wIDAQABAoIBAQCm2Mf3VRlPzhFIWnVwJXE2q8Umcu8Yfkm712Jj3twk8GPfPS4H4Bl1yjmqMB6xI6zz/CiItGlnNe04lMpVWuV+6CNMq/ZwmKbuxmFE+pFEZYGuvJd16gzR3tGJqJTOnjMAGhK8b8oXJ+TF4NQNooe20ol/DXgiuQAargPuH3RwzjYmF3N8VI4KUc3LaG4TwVXn4LwPOxrQSnfwJlZwLml1HAKOV0qcG0mXX6ZXOpoVhEoRPdQyUHc8ZW+53Agbtind7bYh5TsMVDFUrcgNwnwTOsWjil049la1IJO2uMRluacKlrtyzEp6zqrW8ZJO7mYAO69x4WyGqf2ZgIdA6djBAoGBAPqRHWAIgPa80eXbwCYkRtUG/ONBsQGi7+wm6nyhkXvNXJeokgH2DCgLH2+fW2scfOJuZc9r5WftEjOBvNfr2LDcwdyTSTh21WYcPSZx9HDf2d5/SWTcjNcyU0b5qfWIUKi/Zm9UY7r3X7yMA5dUD/cvu1PBJ5NWFrK1Gm2ph44dAoGBAPLn+LkHweU0fbxQq/76T5yVVpMKUaE9xwrJlUxEDPAQGnLPbFg4JeUt/YPhsOV85W4c4oQE+uFZrF0uf+1fEnS6MOJ+sq668upzC2hBp1B5138wM7615v1rvXVVH6qXfFop67FdBzPHt1NAN43mEIBZHTQ5hSVXFlYSZp9mxuEjAoGBAKCzUVO2IIAeub/iIGpV+dfGk4ptJ0kVZyreCqXEObpdC3V496uqUkGcYJ0GZ2ta6f2PMFzHpmnw8it2mdchu+gyrWL6U4uTK2pB0jZF/7Ak4WaB3GCD0xBxhleO6CJBOvn/R4M/bHcNEKmsYuE7WMIAKvScfPVR0VzsKfcLM5VBAoGAVvWg32zdh1bBZLdku8WU1rPH6KAbFSRuq3f7UPBTyWWaclu7p+GB/4f1aE9V6vJJmKASn7zArAhUYo+REMOmcc9uTMea5F7dM/23qb1HTtIvycLR44ZviW4Wx3iP+5x70jOLw1VQjMME6HLm8I/afHhqshWdiv6ganPv9UTwEg0CgYBSDi2dqg8F7ij5CN+LMDLSn3b8GCw+7efGIt7imm/O2V/FlHD40IA6qGg6DXNQrnoZQt94nMb1cZEvm1dxi6rmQNrhCyoMogAaPqgFhZGq1OjmhVZiXFUWy4WAcjdzFc9wZd3/XtaofRKHLK+ngTFhhVApKypLk3Rg9bCAAjzyVg== + - peerId: 12D3KooWDCypXSyN6ppuMZGxVnBd1ZQCMV4y7Bn187S4duYmf8rA + address: 127.0.0.1:4432 + signingKey: SGyNE0dFaQgtgNuzdcO7LB+TEz9VHAOtlQLk6WWkrkQyXiZV3casg8Q2/4PO1Oylc8Fu72RU001Hclj5JCbiLw== + encryptionKey: MIIEpAIBAAKCAQEA0k3mw4FyexRkLgLjHzYs4Ppeyv6r9ZrP00imNf15JTuM8ajMx5oJX7JQTm8KOLRJjUdZZAd5Gtp0ezfYAQK1ZjEWwCmfp8j8FBgJIDSLpjxl88SXMLgATXYfhklnQvKlQjs/X3Ka4zdTrav2tMH9IAo6TSNZhlPQNsUory1SGHs+KqHv4p0sG8oWuKYhfBj8rWHQdUVptkIBKgojFDeJJD04Tbf9kUakbK/8KuXB6zF5H4WN3p4rMMwkClyTGeYO4LDg5TzVn8NnUi3/b/vO/3us1G/TMoRe/6umUfpQxrwo+7S2T6A4YwetWRp6xALLhp+HfAWnn0lA/D8/w1WpKwIDAQABAoIBAQC5cdQxRa5rddm48PbSCPWeFWkNW3DLDI6CYyedqDvxZwer+QtKXzww1I4X+7ZptiC9odLjb+uMkGHyXZXtnjPTPyounQWZ8JLILUGu0mbqWYwVXp9raHVr2OOHiKaz1D+BnbkOM4L9JUZ2eJL9ZaoNXLd4WdmRp8qM4WI0xqQDzOANx2HhyL/+dJmQeIUND+pdeH+Z+fYowU3ho32txNvBnMXQhF1T5K9i1VO5W49RAjIRbENsT+paPGKbNubDHRt1j36ktK4eC4HSdgv8tccdsGyrEiIbAt1XsTZfM8ie4D3A8RhSxiTC6Fkgv6vIm+iFTLzBFZKesOBcd8sfKeyBAoGBAOts5PQQJhldPDzlbnqzxMOR98WHbkVZjCqWSkNA34vqyFuPcRuX0rHK/qpg23ilbUP0fGMDTGgFzTt51FZLL16SXyRfjNhzjdmryryeddQwbp92ta2GEgnU6t1FyCuSCtcLDKJd/D9A9dC5UI6z+ES4TOnbR3nakXK9t4cUOFthAoGBAOSu+wL+SEA5erR+m3LpOsELK68CCJQPxn3VpoVfJZawgF+fEoXVMLTERxJput1+ADomIEdNc9ex86TjKx9gJ4piNHscRPFeT/AgESOIGHLOc1gk2DPqNj6wBIarUJQ9t4KcHScboh1dTPJeqqv2NSwIiLQoqFUIhfKZLnrW3zwLAoGBAJh0hC+o5YM3ZXLqAIllMN6VACbidP5j5ukNOjojIKCzAdyJH24G+2I3WoNrBbUzK3b+NC7KTAhw+V6ynlbjiWFs2D/twH/LFOkI3tkWpKcsVfbeIPimAbhsMUvpjJ7qjCqF9UCQLHGp14W6+/ftg7C8yNIINlkquVXclaTb60MBAoGAPqmL8ogG+EJH00mWAujRxq/u6meePiQMedKfbJBj1mTK6GjIRI/kZsQZzXvXTnYGTejAk4kvov0KDDaLTG+mpg6+3rUiVxlGwj+nMptKR7s2dAK0k5UsBAVrWBN9YwF+VXW9r0etJmq4ePljvvcaHtS/0M4LQjGxsoYy7EoQpX0CgYAhnf0McB7F1MxSjB0soMNv/v5utVzVihS3re2yKNdkI/YUEMB+yU3Q4gh+OljjBM6Y5To3BsQBAx4l2CysMKFHjIE/5AtdbvIS+chZZqB3vcZXSayvX8P1Z1uFdw/saiO2cRDJmR+TxaOPa2C9SzDoNTACthwLErHfzvEvVroKmw== +space: + gcTTL: 60 + syncPeriod: 10 +storage: + path: db +metric: + addr: "" +log: + production: false + defaultLevel: "" + namedLevels: {} diff --git a/etc/configs/node3.yml b/etc/configs/node3.yml new file mode 100755 index 00000000..a809a72b --- /dev/null +++ b/etc/configs/node3.yml @@ -0,0 +1,37 @@ +anytype: + swarmKey: /key/swarm/psk/1.0.0/base16/209992e611c27d5dce8fbd2e7389f6b51da9bee980992ef60739460b536139ec +grpcServer: + listenAddrs: + - 127.0.0.1:4432 + tls: false +account: + peerId: 12D3KooWDCypXSyN6ppuMZGxVnBd1ZQCMV4y7Bn187S4duYmf8rA + peerKey: SGyNE0dFaQgtgNuzdcO7LB+TEz9VHAOtlQLk6WWkrkQyXiZV3casg8Q2/4PO1Oylc8Fu72RU001Hclj5JCbiLw== + signingKey: SGyNE0dFaQgtgNuzdcO7LB+TEz9VHAOtlQLk6WWkrkQyXiZV3casg8Q2/4PO1Oylc8Fu72RU001Hclj5JCbiLw== + encryptionKey: MIIEpAIBAAKCAQEA0k3mw4FyexRkLgLjHzYs4Ppeyv6r9ZrP00imNf15JTuM8ajMx5oJX7JQTm8KOLRJjUdZZAd5Gtp0ezfYAQK1ZjEWwCmfp8j8FBgJIDSLpjxl88SXMLgATXYfhklnQvKlQjs/X3Ka4zdTrav2tMH9IAo6TSNZhlPQNsUory1SGHs+KqHv4p0sG8oWuKYhfBj8rWHQdUVptkIBKgojFDeJJD04Tbf9kUakbK/8KuXB6zF5H4WN3p4rMMwkClyTGeYO4LDg5TzVn8NnUi3/b/vO/3us1G/TMoRe/6umUfpQxrwo+7S2T6A4YwetWRp6xALLhp+HfAWnn0lA/D8/w1WpKwIDAQABAoIBAQC5cdQxRa5rddm48PbSCPWeFWkNW3DLDI6CYyedqDvxZwer+QtKXzww1I4X+7ZptiC9odLjb+uMkGHyXZXtnjPTPyounQWZ8JLILUGu0mbqWYwVXp9raHVr2OOHiKaz1D+BnbkOM4L9JUZ2eJL9ZaoNXLd4WdmRp8qM4WI0xqQDzOANx2HhyL/+dJmQeIUND+pdeH+Z+fYowU3ho32txNvBnMXQhF1T5K9i1VO5W49RAjIRbENsT+paPGKbNubDHRt1j36ktK4eC4HSdgv8tccdsGyrEiIbAt1XsTZfM8ie4D3A8RhSxiTC6Fkgv6vIm+iFTLzBFZKesOBcd8sfKeyBAoGBAOts5PQQJhldPDzlbnqzxMOR98WHbkVZjCqWSkNA34vqyFuPcRuX0rHK/qpg23ilbUP0fGMDTGgFzTt51FZLL16SXyRfjNhzjdmryryeddQwbp92ta2GEgnU6t1FyCuSCtcLDKJd/D9A9dC5UI6z+ES4TOnbR3nakXK9t4cUOFthAoGBAOSu+wL+SEA5erR+m3LpOsELK68CCJQPxn3VpoVfJZawgF+fEoXVMLTERxJput1+ADomIEdNc9ex86TjKx9gJ4piNHscRPFeT/AgESOIGHLOc1gk2DPqNj6wBIarUJQ9t4KcHScboh1dTPJeqqv2NSwIiLQoqFUIhfKZLnrW3zwLAoGBAJh0hC+o5YM3ZXLqAIllMN6VACbidP5j5ukNOjojIKCzAdyJH24G+2I3WoNrBbUzK3b+NC7KTAhw+V6ynlbjiWFs2D/twH/LFOkI3tkWpKcsVfbeIPimAbhsMUvpjJ7qjCqF9UCQLHGp14W6+/ftg7C8yNIINlkquVXclaTb60MBAoGAPqmL8ogG+EJH00mWAujRxq/u6meePiQMedKfbJBj1mTK6GjIRI/kZsQZzXvXTnYGTejAk4kvov0KDDaLTG+mpg6+3rUiVxlGwj+nMptKR7s2dAK0k5UsBAVrWBN9YwF+VXW9r0etJmq4ePljvvcaHtS/0M4LQjGxsoYy7EoQpX0CgYAhnf0McB7F1MxSjB0soMNv/v5utVzVihS3re2yKNdkI/YUEMB+yU3Q4gh+OljjBM6Y5To3BsQBAx4l2CysMKFHjIE/5AtdbvIS+chZZqB3vcZXSayvX8P1Z1uFdw/saiO2cRDJmR+TxaOPa2C9SzDoNTACthwLErHfzvEvVroKmw== +apiServer: + port: "8082" +nodes: + - peerId: 12D3KooWLn13hDrZ6YRGM517fHf2zS6qhPNRu18inLMpRqn1YGKu + address: 127.0.0.1:4430 + signingKey: 3mzfKBWtn7mitFEgq8u4eysWOJ6ySbUs49irfHwcuOmi1YMpobz9anoqd4yaT1owZiRPYXqx5k2Z4sNVRE3kXA== + encryptionKey: MIIEpQIBAAKCAQEA3U7b4w9JTKE3TLM1WQ5iqdLbvUuozMp/hDEg7S15Gr6wrtLomMSBkfmVQ3Cu+CHdxAFqUFClItYlSFgtZWIFiSiQxCeaN2dmgczd9T4TlRAw6y6uJXtT9r7FIgizPP4B0/tnzPI6yYgpdwzCV2nRSjw3mMr5Nav3QYs18kYrJ1/Np2Wob5HOoRTUD++pPrToevTb7GNL/irrC8wXSE7oU6S7ix6Nh9vzEHg/V5FONBF/wWD/ri7Gy0j0qgUQ+gjxLWKr8xPDnRAve13zzo+54lGCyVvlm/rwCY9Jx378V1IuRx+S8F/GFuVozHD4XVaoSTtpCWPBQNSKDXgaIIKDowIDAQABAoIBACpMXj6ht1LMJXOldPbWhwkKYjFl+pdZxNGRSkfKvzDbbY2chhRcyp8J4vuG2ApY/rftxVIgd8+Wun1/TP3ppEE43aKAJzubqb35WBr9iGSfOZpZy7MiRUQN5kPBAfEQY20OyiIj0hSez74PVD283eGgbMfpU4Rsn8+JOgBaZPkbPViJLJY8PyHU6vwWw60dye1iJTz9yuBtoEqY0XKxnLaVXTQaWx0Te+VYU8twxDgXFWRaXtHuk7xnxOkCZDLrzIvuOYa5lsLoT8K62LDeXbyHBPhbdW0j4ZYzAOTsaUWpjuJzef9aj3JJdfyADiqb5iu6HHksvKzkZEau34zjilECgYEA/c8ZJm62uJMHNssTJYiLRw89l5hYwIZ/1TXdFRF8+xrTin5opYjpscSTO5bY2IYqLx2xuPiJCY1eGGB9L/RtkaVh51ySzq0d+4zpPIRKFcOOgdxHwlgoCgIhQECyfJZNMFGBUIlPXZ/phvXOXRvWFzDPhqThenVG2QzF+wLP0AUCgYEA3zfviQFJ1FOKJMozYO3tUZFmsIrAcO9hfuE7uuWz0Fw2m1XiwxjuOr1RbsSsh/lKke2h4tiGrlfiFhwCpIp91NkVTFrtFOQxbDxkYLkFiWkZDkOaK9YhKMa2cgEm3p+RGawokjbm51LKf+cbYN9xGaAe3y2WzIE4kNpfWE4SXYcCgYEAoagcrrvpqZoMCDxED63ud+4fHsUsEkQYe6Z5EAg5gH5PqnBlGrofjthTpqqnpxGdILFbFyNFtU3TVtduJPMcLp4Vw5TU9MqSxDu1+pOP1FjgFZpGImSf6+/7Wb9bb7sToujm4nLymAFYblt1exxVuiOeqnWuH58+5tQZ7YyW7DkCgYEAl7WuqZEkmpiEpWh/7vsGdo+6GXbUQG2R9+gg7m+7/HsP6hc/XZYOJAIT3JLzKB84nWHCyyiasNeuI5S5/xbZWtaH8TNDOxW0uXl6R3q41qGFk/pCSFTqiIo16dn6jwgoWCh4EpgZ61KLqs5p/zcd6Wq4ULrtaOTSizC/6IZ3WPUCgYEA6xCJy3+ICCgr8/c7hfd2Ylb3aOsXIffdgALhXjDcrNUCqgB4R+S3WReAwrABemQGl4tySQE/1f3Ru7SzMMciFogGyJ/YSXqSi6Y8oDD7MqlKPiWlN6WY1nSRMlLbkUOqpA5JaDM0kcmXjZpBBQr277GOnh9uKN8zUy5xoptctxI= + - peerId: 12D3KooWLtuKtCPBYrFJV1NdejiCr2s614ppe9rmUXnkTHtAUD5U + address: 127.0.0.1:4431 + signingKey: 07JMoW5cQUtGO9nNIGQo9e99b7Wf/4YvTtNEA0lt4gCkmhwB1EB9ay+kitxVJJgmdyGLxbUUlGqwXsAj0zlHWw== + encryptionKey: MIIEpAIBAAKCAQEA7cA6J/icl8wseeXkt8oJr5AeYadUAG5EdCOdHj4S/Z7ivff4MOIKAeQITpq+rqhmXxOePYXSpQXE20Y9PW9tuw4gzOuq1ylSG/MWMcLDH1eIxg66rnmUqUbdiW4GGJjVjc9jvN0Up+MfSrUF6fM0jWTFoXVJQIeQQGERCIYjFzjfBl1xYvPghdxNgei/K5ZGYRggT28143XdIH4KTXGtp51hAKoyY9eCqYMtm9wvjxazhPVxO2CsYaqMxBLshY3jfHNqJnx8u6+h4Bl4uUcdbLNUgMcEgk7ehbQp2K0CqNoKXxbCTI6V57UVcJHDIaO5B6FyR6BguzHHNPJ4yd3q9wIDAQABAoIBAQCm2Mf3VRlPzhFIWnVwJXE2q8Umcu8Yfkm712Jj3twk8GPfPS4H4Bl1yjmqMB6xI6zz/CiItGlnNe04lMpVWuV+6CNMq/ZwmKbuxmFE+pFEZYGuvJd16gzR3tGJqJTOnjMAGhK8b8oXJ+TF4NQNooe20ol/DXgiuQAargPuH3RwzjYmF3N8VI4KUc3LaG4TwVXn4LwPOxrQSnfwJlZwLml1HAKOV0qcG0mXX6ZXOpoVhEoRPdQyUHc8ZW+53Agbtind7bYh5TsMVDFUrcgNwnwTOsWjil049la1IJO2uMRluacKlrtyzEp6zqrW8ZJO7mYAO69x4WyGqf2ZgIdA6djBAoGBAPqRHWAIgPa80eXbwCYkRtUG/ONBsQGi7+wm6nyhkXvNXJeokgH2DCgLH2+fW2scfOJuZc9r5WftEjOBvNfr2LDcwdyTSTh21WYcPSZx9HDf2d5/SWTcjNcyU0b5qfWIUKi/Zm9UY7r3X7yMA5dUD/cvu1PBJ5NWFrK1Gm2ph44dAoGBAPLn+LkHweU0fbxQq/76T5yVVpMKUaE9xwrJlUxEDPAQGnLPbFg4JeUt/YPhsOV85W4c4oQE+uFZrF0uf+1fEnS6MOJ+sq668upzC2hBp1B5138wM7615v1rvXVVH6qXfFop67FdBzPHt1NAN43mEIBZHTQ5hSVXFlYSZp9mxuEjAoGBAKCzUVO2IIAeub/iIGpV+dfGk4ptJ0kVZyreCqXEObpdC3V496uqUkGcYJ0GZ2ta6f2PMFzHpmnw8it2mdchu+gyrWL6U4uTK2pB0jZF/7Ak4WaB3GCD0xBxhleO6CJBOvn/R4M/bHcNEKmsYuE7WMIAKvScfPVR0VzsKfcLM5VBAoGAVvWg32zdh1bBZLdku8WU1rPH6KAbFSRuq3f7UPBTyWWaclu7p+GB/4f1aE9V6vJJmKASn7zArAhUYo+REMOmcc9uTMea5F7dM/23qb1HTtIvycLR44ZviW4Wx3iP+5x70jOLw1VQjMME6HLm8I/afHhqshWdiv6ganPv9UTwEg0CgYBSDi2dqg8F7ij5CN+LMDLSn3b8GCw+7efGIt7imm/O2V/FlHD40IA6qGg6DXNQrnoZQt94nMb1cZEvm1dxi6rmQNrhCyoMogAaPqgFhZGq1OjmhVZiXFUWy4WAcjdzFc9wZd3/XtaofRKHLK+ngTFhhVApKypLk3Rg9bCAAjzyVg== + - peerId: 12D3KooWDCypXSyN6ppuMZGxVnBd1ZQCMV4y7Bn187S4duYmf8rA + address: 127.0.0.1:4432 + signingKey: SGyNE0dFaQgtgNuzdcO7LB+TEz9VHAOtlQLk6WWkrkQyXiZV3casg8Q2/4PO1Oylc8Fu72RU001Hclj5JCbiLw== + encryptionKey: MIIEpAIBAAKCAQEA0k3mw4FyexRkLgLjHzYs4Ppeyv6r9ZrP00imNf15JTuM8ajMx5oJX7JQTm8KOLRJjUdZZAd5Gtp0ezfYAQK1ZjEWwCmfp8j8FBgJIDSLpjxl88SXMLgATXYfhklnQvKlQjs/X3Ka4zdTrav2tMH9IAo6TSNZhlPQNsUory1SGHs+KqHv4p0sG8oWuKYhfBj8rWHQdUVptkIBKgojFDeJJD04Tbf9kUakbK/8KuXB6zF5H4WN3p4rMMwkClyTGeYO4LDg5TzVn8NnUi3/b/vO/3us1G/TMoRe/6umUfpQxrwo+7S2T6A4YwetWRp6xALLhp+HfAWnn0lA/D8/w1WpKwIDAQABAoIBAQC5cdQxRa5rddm48PbSCPWeFWkNW3DLDI6CYyedqDvxZwer+QtKXzww1I4X+7ZptiC9odLjb+uMkGHyXZXtnjPTPyounQWZ8JLILUGu0mbqWYwVXp9raHVr2OOHiKaz1D+BnbkOM4L9JUZ2eJL9ZaoNXLd4WdmRp8qM4WI0xqQDzOANx2HhyL/+dJmQeIUND+pdeH+Z+fYowU3ho32txNvBnMXQhF1T5K9i1VO5W49RAjIRbENsT+paPGKbNubDHRt1j36ktK4eC4HSdgv8tccdsGyrEiIbAt1XsTZfM8ie4D3A8RhSxiTC6Fkgv6vIm+iFTLzBFZKesOBcd8sfKeyBAoGBAOts5PQQJhldPDzlbnqzxMOR98WHbkVZjCqWSkNA34vqyFuPcRuX0rHK/qpg23ilbUP0fGMDTGgFzTt51FZLL16SXyRfjNhzjdmryryeddQwbp92ta2GEgnU6t1FyCuSCtcLDKJd/D9A9dC5UI6z+ES4TOnbR3nakXK9t4cUOFthAoGBAOSu+wL+SEA5erR+m3LpOsELK68CCJQPxn3VpoVfJZawgF+fEoXVMLTERxJput1+ADomIEdNc9ex86TjKx9gJ4piNHscRPFeT/AgESOIGHLOc1gk2DPqNj6wBIarUJQ9t4KcHScboh1dTPJeqqv2NSwIiLQoqFUIhfKZLnrW3zwLAoGBAJh0hC+o5YM3ZXLqAIllMN6VACbidP5j5ukNOjojIKCzAdyJH24G+2I3WoNrBbUzK3b+NC7KTAhw+V6ynlbjiWFs2D/twH/LFOkI3tkWpKcsVfbeIPimAbhsMUvpjJ7qjCqF9UCQLHGp14W6+/ftg7C8yNIINlkquVXclaTb60MBAoGAPqmL8ogG+EJH00mWAujRxq/u6meePiQMedKfbJBj1mTK6GjIRI/kZsQZzXvXTnYGTejAk4kvov0KDDaLTG+mpg6+3rUiVxlGwj+nMptKR7s2dAK0k5UsBAVrWBN9YwF+VXW9r0etJmq4ePljvvcaHtS/0M4LQjGxsoYy7EoQpX0CgYAhnf0McB7F1MxSjB0soMNv/v5utVzVihS3re2yKNdkI/YUEMB+yU3Q4gh+OljjBM6Y5To3BsQBAx4l2CysMKFHjIE/5AtdbvIS+chZZqB3vcZXSayvX8P1Z1uFdw/saiO2cRDJmR+TxaOPa2C9SzDoNTACthwLErHfzvEvVroKmw== +space: + gcTTL: 60 + syncPeriod: 10 +storage: + path: db +metric: + addr: "" +log: + production: false + defaultLevel: "" + namedLevels: {} diff --git a/etc/consensus-node.yml b/etc/consensus-node.yml new file mode 100644 index 00000000..041c1c14 --- /dev/null +++ b/etc/consensus-node.yml @@ -0,0 +1,11 @@ +rpcServer: + listenAddrs: + - 127.0.0.1:4530 +account: + peerId: 12D3KooWSUx2LXPvoZGp72Dt7b7r1kPSmQ6zAUwKkHFyX64uiXRu + signingKey: 4QTrtkFLQe9wQcWT/cgFEwfMHB5pt4axInNmCIMCZaz3nVdyygRoO8/YH0V15X6Mnw1NQWsS1YIWiLS22hwepA== + encryptionKey: MIIEpAIBAAKCAQEAmqAAOPfR86po3m+zwSzbAlZGgMMF188v35Ulqf9Gb4KO8DZ9ifxrqpjlLZRxPKeXj3wSSQEXsJf3A82rZlDxddZSM0i7Mx5G2G0zRHWx9dC58PpX6o/fDuvSwcyXqOgIK55N/hyEuIbWQgp5Rk9uy2Zbrhv5ZL5CvceM0b9wSKt/hRvntxSbG+HRgXWaQvAReGuJrySVvkh6fhC3G0IwqyFbGNq2zqAJej6NBzZA3thHgTn5PoWD8O4cyukBxunKGu3HLE3vJtqEMFrkNFw5SMpdEtxyTLN6T1HIeYCY9RL+BFYfxIWg6pGtIoIJKUB0XapJr9ltzvXfT9KeSCU0VwIDAQABAoIBAAp/xsQXf7gN4CUKbKg3RX+5H/xqQaFPvi5uUCpk3QGBWfdRm+CctSrWSul3ZOD7eD0T7aHrYxJonysw8ex2no6jyN0WmS91ZNYZRBvn6feI/rcwKHwS3NCEjsD+BWZAqx1bGGyivxhQf4fociemCR3ii2MdHygKCzobrKIpX5RvhanI4j01dyLlxwqTsteuc/o5RR4jfg1eN0kldFjk3UcSNyzzEv5o5UhRsHCLJBTNTvYZBN4FpyaqcLT9gKS9aVBvQH63R+E5dyxo1+24tZZricW59h2bN3CFriqkwBo1y0gTnR6VQ22MBvIUxYUm82cxXs/Vr0YQTSAaEGThxFECgYEAxKQMRnM39WMzrNx1WDwpBERRj1T0TbLf1uq6viPiLdik2Tm2aCBZyr5j82Ey7fZ7OafKGfsM0I2AuYeoBdYDuYN6A7tE9kpnECubnWuIvUeYcL+1VzzMedVtdKwQXrYbhqKtyvnSJ9gQ6CusHtsDE1bQvTMxBX4KNBeBYllCUasCgYEAyU0RPUaj56CyLHKty8jNg6wl+06IZ0pUPIWZ//b1zeZrlHGYDp/InxS8huGFapzOg1sbQBS6j3j3YE3Ts6v6FNuIa4pcPQ91YuHiWWQdgVjrCZdleanFWGTjIx12+RGj9vx4voRhNQcHW1YeTvvyj4BN/ECR6GNaoS/ZjBKo1AUCgYEAj6AyxxJJARagG9Y6b2QhoVg1Kjem6UmJbPStyUt0XIAsh+07afqXGxrM7mtEQ8MQZiBD4Y4Y4gs4xkprUzfqKIn7iNYznKDjflAbrXNpwLaWhWPBFCL4RtS4ycsTedoRaNlRjzvBYBDU6H9djHvzVyDF/itx1s0krr+sZSVE51kCgYBxGRinecna+KFCccgNp6s34H+Se2QNzGgZfOKyOjmOTniA9XV+Oe3I2yi1C34fESzCBm0ACuVqeIdcFz3rQ6OFFnbGHP2H3OiR/uFiYepl4uRjBimgOm9DI6Ot9f8DHxMlUGIygEPxPBq5CWCL9egpEeg+4rRXgYLI7w5mMZGjVQKBgQDC4qyH7FK3lLv5JomoK6nNjpyPNBmr0Rt215oM/AWQaxDhFZH5un68ueZ7MfybwXxHHFQ4ZeSwYs006f1XGPNW6qrH6pi/3SCLFuGVfNnLVwCBkm3QaQrxFm3v9LmVCidTNta0l0DrUldZdK8/P31GBxKo/MmYF/f9LO/Mfm/uDg== +mongo: + connect: "mongodb://localhost:27017/?w=majority" + database: "consensus" + collection: "log" \ No newline at end of file diff --git a/etc/path.go b/etc/path.go new file mode 100644 index 00000000..a90b9125 --- /dev/null +++ b/etc/path.go @@ -0,0 +1,15 @@ +package etc + +import ( + "path/filepath" + "runtime" +) + +var ( + _, b, _, _ = runtime.Caller(0) + basepath = filepath.Dir(b) +) + +func Path() string { + return basepath +} diff --git a/go.mod b/go.mod deleted file mode 100644 index 4f505ee8..00000000 --- a/go.mod +++ /dev/null @@ -1,96 +0,0 @@ -module github.com/anytypeio/go-anytype-infrastructure-experiments - -go 1.18 - -require ( - github.com/akrylysov/pogreb v0.10.1 - github.com/anytypeio/go-chash v0.0.0-20220629194632-4ad1154fe232 - github.com/awalterschulze/gographviz v0.0.0-20190522210029-fa59802746ab - github.com/cespare/xxhash v1.1.0 - github.com/goccy/go-graphviz v0.0.9 - github.com/gogo/protobuf v1.3.2 - github.com/huandu/skiplist v1.2.0 - github.com/ipfs/go-block-format v0.0.3 - github.com/ipfs/go-blockservice v0.4.0 - github.com/ipfs/go-cid v0.3.0 - github.com/ipfs/go-datastore v0.6.0 - github.com/ipfs/go-ipfs-blockstore v1.2.0 - github.com/ipfs/go-ipfs-chunker v0.0.5 - github.com/ipfs/go-ipfs-exchange-interface v0.2.0 - github.com/ipfs/go-ipld-cbor v0.0.6 - github.com/ipfs/go-ipld-format v0.4.0 - github.com/ipfs/go-merkledag v0.7.0 - github.com/ipfs/go-unixfs v0.4.0 - github.com/libp2p/go-libp2p v0.20.3 - github.com/libp2p/go-libp2p-core v0.16.1 - github.com/mr-tron/base58 v1.2.0 - github.com/multiformats/go-multibase v0.1.1 - github.com/multiformats/go-multihash v0.2.1 - github.com/stretchr/testify v1.8.0 - github.com/zeebo/blake3 v0.2.3 - go.uber.org/zap v1.23.0 - gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 - gopkg.in/yaml.v3 v3.0.1 - storj.io/drpc v0.0.32 -) - -require ( - github.com/OneOfOne/xxhash v1.2.8 // indirect - github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a // indirect - github.com/btcsuite/btcd v0.22.1 // indirect - github.com/btcsuite/btcd/btcec/v2 v2.1.3 // indirect - github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect - github.com/fogleman/gg v1.3.0 // indirect - github.com/go-logr/logr v1.2.3 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect - github.com/google/uuid v1.3.0 // indirect - github.com/hashicorp/golang-lru v0.5.4 // indirect - github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/go-bitfield v1.0.0 // indirect - github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect - github.com/ipfs/go-ipfs-files v0.0.3 // indirect - github.com/ipfs/go-ipfs-posinfo v0.0.1 // indirect - github.com/ipfs/go-ipfs-util v0.0.2 // indirect - github.com/ipfs/go-ipld-legacy v0.1.1 // indirect - github.com/ipfs/go-log v1.0.5 // indirect - github.com/ipfs/go-log/v2 v2.5.1 // indirect - github.com/ipfs/go-metrics-interface v0.0.1 // indirect - github.com/ipfs/go-verifcid v0.0.2 // indirect - github.com/ipld/go-codec-dagpb v1.5.0 // indirect - github.com/ipld/go-ipld-prime v0.18.0 // indirect - github.com/jbenet/goprocess v0.1.4 // indirect - github.com/klauspost/cpuid/v2 v2.1.1 // indirect - github.com/libp2p/go-buffer-pool v0.1.0 // indirect - github.com/libp2p/go-openssl v0.0.7 // indirect - github.com/mattn/go-isatty v0.0.16 // indirect - github.com/minio/sha256-simd v1.0.0 // indirect - github.com/multiformats/go-base32 v0.1.0 // indirect - github.com/multiformats/go-base36 v0.1.0 // indirect - github.com/multiformats/go-multiaddr v0.5.0 // indirect - github.com/multiformats/go-multicodec v0.5.0 // indirect - github.com/multiformats/go-varint v0.0.6 // indirect - github.com/opentracing/opentracing-go v1.2.0 // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e // indirect - github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect - github.com/spaolacci/murmur3 v1.1.0 // indirect - github.com/whyrusleeping/cbor-gen v0.0.0-20220514204315-f29c37e9c44c // indirect - github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect - github.com/zeebo/errs v1.2.2 // indirect - go.opentelemetry.io/otel v1.9.0 // indirect - go.opentelemetry.io/otel/trace v1.9.0 // indirect - go.uber.org/atomic v1.10.0 // indirect - go.uber.org/multierr v1.8.0 // indirect - golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 // indirect - golang.org/x/image v0.0.0-20200119044424-58c23975cae1 // indirect - golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b // indirect - golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect - golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 // indirect - golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect - google.golang.org/protobuf v1.28.1 // indirect - lukechampine.com/blake3 v1.1.7 // indirect -) diff --git a/go.sum b/go.sum deleted file mode 100644 index 2ce17444..00000000 --- a/go.sum +++ /dev/null @@ -1,396 +0,0 @@ -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= -github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= -github.com/akrylysov/pogreb v0.10.1 h1:FqlR8VR7uCbJdfUob916tPM+idpKgeESDXOA1K0DK4w= -github.com/akrylysov/pogreb v0.10.1/go.mod h1:pNs6QmpQ1UlTJKDezuRWmaqkgUE2TuU0YTWyqJZ7+lI= -github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a h1:E/8AP5dFtMhl5KPJz66Kt9G0n+7Sn41Fy1wv9/jHOrc= -github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= -github.com/anytypeio/go-chash v0.0.0-20220629194632-4ad1154fe232 h1:kMPPZYmJgbs4AJfodbg2OCXg5cp+9LPAJcLZJqmcghk= -github.com/anytypeio/go-chash v0.0.0-20220629194632-4ad1154fe232/go.mod h1:+PeHBAWp7gUh/yw6uAauKc5ku0w4cFNg6DUddGxoGq0= -github.com/awalterschulze/gographviz v0.0.0-20190522210029-fa59802746ab h1:+cdNqtOJWjvepyhxy23G7z7vmpYCoC65AP0nqi1f53s= -github.com/awalterschulze/gographviz v0.0.0-20190522210029-fa59802746ab/go.mod h1:GEV5wmg4YquNw7v1kkyoX9etIk8yVmXj+AkDHuuETHs= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/btcsuite/btcd v0.22.1 h1:CnwP9LM/M9xuRrGSCGeMVs9iv09uMqwsVX7EeIpgV2c= -github.com/btcsuite/btcd v0.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= -github.com/btcsuite/btcd/btcec/v2 v2.1.3 h1:xM/n3yIhHAhHy04z4i43C8p4ehixJZMsnrVJkgl+MTE= -github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= -github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= -github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/corona10/goimagehash v1.0.2 h1:pUfB0LnsJASMPGEZLj7tGY251vF+qLGqOgEP4rUs6kA= -github.com/corona10/goimagehash v1.0.2/go.mod h1:/l9umBhvcHQXVtQO1V6Gp1yD20STawkhRnnX0D1bvVI= -github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= -github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= -github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8= -github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= -github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= -github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/goccy/go-graphviz v0.0.9 h1:s/FMMJ1Joj6La3S5ApO3Jk2cwM4LpXECC2muFx3IPQQ= -github.com/goccy/go-graphviz v0.0.9/go.mod h1:wXVsXxmyMQU6TN3zGRttjNn3h+iCAS7xQFC6TlNvLhk= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= -github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= -github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= -github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= -github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c= -github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= -github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw= -github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= -github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo= -github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= -github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/go-bitfield v1.0.0 h1:y/XHm2GEmD9wKngheWNNCNL0pzrWXZwCdQGv1ikXknQ= -github.com/ipfs/go-bitfield v1.0.0/go.mod h1:N/UiujQy+K+ceU1EF5EkVd1TNqevLrCQMIcAEPrdtus= -github.com/ipfs/go-bitswap v0.8.0 h1:UEV7kogQu2iGggkE9GhLykDrRCUpsNnpu2NODww/srw= -github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= -github.com/ipfs/go-block-format v0.0.3 h1:r8t66QstRp/pd/or4dpnbVfXT5Gt7lOqRvC+/dDTpMc= -github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= -github.com/ipfs/go-blockservice v0.4.0 h1:7MUijAW5SqdsqEW/EhnNFRJXVF8mGU5aGhZ3CQaCWbY= -github.com/ipfs/go-blockservice v0.4.0/go.mod h1:kRjO3wlGW9mS1aKuiCeGhx9K1DagQ10ACpVO59qgAx4= -github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= -github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= -github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= -github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= -github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= -github.com/ipfs/go-cid v0.0.6/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= -github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= -github.com/ipfs/go-cid v0.3.0 h1:gT6Cbs6YePaBNc7l6v5EXt0xTMup1jGV5EU1N+QLVpY= -github.com/ipfs/go-cid v0.3.0/go.mod h1:P+HXFDF4CVhaVayiEb4wkAy7zBHxBwsJyt0Y5U6MLro= -github.com/ipfs/go-datastore v0.5.0/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk= -github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= -github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= -github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= -github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= -github.com/ipfs/go-ipfs-blockstore v1.2.0 h1:n3WTeJ4LdICWs/0VSfjHrlqpPpl6MZ+ySd3j8qz0ykw= -github.com/ipfs/go-ipfs-blockstore v1.2.0/go.mod h1:eh8eTFLiINYNSNawfZOC7HOxNTxpB1PFuA5E1m/7exE= -github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= -github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= -github.com/ipfs/go-ipfs-chunker v0.0.5/go.mod h1:jhgdF8vxRHycr00k13FM8Y0E+6BoalYeobXmUyTreP8= -github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= -github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= -github.com/ipfs/go-ipfs-ds-help v1.1.0 h1:yLE2w9RAsl31LtfMt91tRZcrx+e61O5mDxFRR994w4Q= -github.com/ipfs/go-ipfs-ds-help v1.1.0/go.mod h1:YR5+6EaebOhfcqVCyqemItCLthrpVNot+rsOU/5IatU= -github.com/ipfs/go-ipfs-exchange-interface v0.2.0 h1:8lMSJmKogZYNo2jjhUs0izT+dck05pqUw4mWNW9Pw6Y= -github.com/ipfs/go-ipfs-exchange-interface v0.2.0/go.mod h1:z6+RhJuDQbqKguVyslSOuVDhqF9JtTrO3eptSAiW2/Y= -github.com/ipfs/go-ipfs-exchange-offline v0.3.0 h1:c/Dg8GDPzixGd0MC8Jh6mjOwU57uYokgWRFidfvEkuA= -github.com/ipfs/go-ipfs-files v0.0.3 h1:ME+QnC3uOyla1ciRPezDW0ynQYK2ikOh9OCKAEg4uUA= -github.com/ipfs/go-ipfs-files v0.0.3/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4= -github.com/ipfs/go-ipfs-posinfo v0.0.1 h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6OtpRs= -github.com/ipfs/go-ipfs-posinfo v0.0.1/go.mod h1:SwyeVP+jCwiDu0C313l/8jg6ZxM0qqtlt2a0vILTc1A= -github.com/ipfs/go-ipfs-pq v0.0.2 h1:e1vOOW6MuOwG2lqxcLA+wEn93i/9laCY8sXAw76jFOY= -github.com/ipfs/go-ipfs-routing v0.2.1 h1:E+whHWhJkdN9YeoHZNj5itzc+OR292AJ2uE9FFiW0BY= -github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= -github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= -github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= -github.com/ipfs/go-ipld-cbor v0.0.6 h1:pYuWHyvSpIsOOLw4Jy7NbBkCyzLDcl64Bf/LZW7eBQ0= -github.com/ipfs/go-ipld-cbor v0.0.6/go.mod h1:ssdxxaLJPXH7OjF5V4NSjBbcfh+evoR4ukuru0oPXMA= -github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= -github.com/ipfs/go-ipld-format v0.2.0/go.mod h1:3l3C1uKoadTPbeNfrDi+xMInYKlx2Cvg1BuydPSdzQs= -github.com/ipfs/go-ipld-format v0.3.0/go.mod h1:co/SdBE8h99968X0hViiw1MNlh6fvxxnHpvVLnH7jSM= -github.com/ipfs/go-ipld-format v0.4.0 h1:yqJSaJftjmjc9jEOFYlpkwOLVKv68OD27jFLlSghBlQ= -github.com/ipfs/go-ipld-format v0.4.0/go.mod h1:co/SdBE8h99968X0hViiw1MNlh6fvxxnHpvVLnH7jSM= -github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2cdcc= -github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= -github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= -github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= -github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= -github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= -github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= -github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= -github.com/ipfs/go-merkledag v0.7.0 h1:PHdWOGwx+J2uRAuP9Mu+bz89ulmf3W2QmbSS/N6O29U= -github.com/ipfs/go-merkledag v0.7.0/go.mod h1:/1cuN4VbcDn/xbVMAqjPUwejJYr8W9SvizmyYLU/B7k= -github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= -github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= -github.com/ipfs/go-peertaskqueue v0.7.0 h1:VyO6G4sbzX80K58N60cCaHsSsypbUNs1GjO5seGNsQ0= -github.com/ipfs/go-unixfs v0.4.0 h1:qSyyxfB/OiDdWHYiSbyaqKC7zfSE/TFL0QdwkRjBm20= -github.com/ipfs/go-unixfs v0.4.0/go.mod h1:I7Nqtm06HgOOd+setAoCU6rf/HgVFHE+peeNuOv/5+g= -github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= -github.com/ipfs/go-verifcid v0.0.2/go.mod h1:40cD9x1y4OWnFXbLNJYRe7MpNvWlMn3LZAG5Wb4xnPU= -github.com/ipld/go-codec-dagpb v1.5.0 h1:RspDRdsJpLfgCI0ONhTAnbHdySGD4t+LHSPK4X1+R0k= -github.com/ipld/go-codec-dagpb v1.5.0/go.mod h1:0yRIutEFD8o1DGVqw4RSHh+BUTlJA9XWldxaaWR/o4g= -github.com/ipld/go-ipld-prime v0.9.1-0.20210324083106-dc342a9917db/go.mod h1:KvBLMr4PX1gWptgkzRjVZCrLmSGcZCb/jioOQwCqZN8= -github.com/ipld/go-ipld-prime v0.18.0 h1:xUk7NUBSWHEXdjiOu2sLXouFJOMs0yoYzeI5RAqhYQo= -github.com/ipld/go-ipld-prime v0.18.0/go.mod h1:735yXW548CKrLwVCYXzqx90p5deRJMVVxM9eJ4Qe+qE= -github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= -github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= -github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= -github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= -github.com/klauspost/cpuid/v2 v2.1.1 h1:t0wUqjowdm8ezddV5k0tLWVklVuvLJpoHeb4WBdydm0= -github.com/klauspost/cpuid/v2 v2.1.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= -github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d h1:68u9r4wEvL3gYg2jvAOgROwZ3H+Y3hIDk4tbbmIjcYQ= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= -github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= -github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= -github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= -github.com/libp2p/go-eventbus v0.2.1 h1:VanAdErQnpTioN2TowqNcOijf6YwhuODe4pPKSDpxGc= -github.com/libp2p/go-libp2p v0.20.3 h1:tjjDNfp7FqdI/7v1rXtB/BtELaPlAThL2uzlj18kcrw= -github.com/libp2p/go-libp2p v0.20.3/go.mod h1:I+vndVanE/p/SjFbnA+BEmmfAUEpWxrdXZeyQ1Dus5c= -github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= -github.com/libp2p/go-libp2p-core v0.16.1 h1:bWoiEBqVkpJ13hbv/f69tHODp86t6mvc4fBN4DkK73M= -github.com/libp2p/go-libp2p-core v0.16.1/go.mod h1:O3i/7y+LqUb0N+qhzXjBjjpchgptWAVMG1Voegk7b4c= -github.com/libp2p/go-libp2p-loggables v0.1.0 h1:h3w8QFfCt2UJl/0/NW4K829HX/0S4KD31PQ7m8UXXO8= -github.com/libp2p/go-libp2p-netutil v0.1.0 h1:zscYDNVEcGxyUpMd0JReUZTrpMfia8PmLKcKF72EAMQ= -github.com/libp2p/go-libp2p-peerstore v0.6.0 h1:HJminhQSGISBIRb93N6WK3t6Fa8OOTnHd/VBjL4mY5A= -github.com/libp2p/go-libp2p-record v0.1.0 h1:wHwBGbFzymoIl69BpgwIu0O6ta3TXGcMPvHUAcodzRc= -github.com/libp2p/go-libp2p-testing v0.9.2 h1:dCpODRtRaDZKF8HXT9qqqgON+OMEB423Knrgeod8j84= -github.com/libp2p/go-msgio v0.2.0 h1:W6shmB+FeynDrUVl2dgFQvzfBZcXiyqY4VmpQLu9FqU= -github.com/libp2p/go-nat v0.1.0 h1:MfVsH6DLcpa04Xr+p8hmVRG4juse0s3J8HyNWYHffXg= -github.com/libp2p/go-netroute v0.2.0 h1:0FpsbsvuSnAhXFnCY0VLFbJOzaK0VnP0r1QT/o4nWRE= -github.com/libp2p/go-openssl v0.0.7 h1:eCAzdLejcNVBzP/iZM9vqHnQm+XyCEbSSIheIPRGNsw= -github.com/libp2p/go-openssl v0.0.7/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= -github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= -github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg= -github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= -github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= -github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= -github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= -github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= -github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= -github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= -github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= -github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= -github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= -github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4= -github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= -github.com/multiformats/go-multiaddr v0.5.0 h1:i/JuOoVg4szYQ4YEzDGtb2h0o8M7CG/Yq6cGlcjWZpM= -github.com/multiformats/go-multiaddr v0.5.0/go.mod h1:3KAxNkUqLTJ20AAwN4XVX4kZar+bR+gh4zgbfr3SNug= -github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= -github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= -github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= -github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= -github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI= -github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8= -github.com/multiformats/go-multicodec v0.5.0 h1:EgU6cBe/D7WRwQb1KmnBvU7lrcFGMggZVTPtOW9dDHs= -github.com/multiformats/go-multicodec v0.5.0/go.mod h1:DiY2HFaEp5EhEXb/iYzVAunmyX/aSFMxq2KMKfWEues= -github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= -github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= -github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= -github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= -github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg= -github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108= -github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= -github.com/multiformats/go-multistream v0.3.3 h1:d5PZpjwRgVlbwfdTDjife7XszfZd8KYWfROYFlGcR8o= -github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= -github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY= -github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= -github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5 h1:BvoENQQU+fZ9uukda/RzCAL/191HHwJA5b13R6diVlY= -github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= -github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= -github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= -github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= -github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e h1:ZOcivgkkFRnjfoTcGsDq3UQYiBmekwLA+qg0OjyB/ls= -github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa/go.mod h1:2RVY1rIf+2J2o/IM9+vPq9RzmHDSseB7FoXiSNIUsoU= -github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= -github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= -github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/warpfork/go-testmark v0.10.0 h1:E86YlUMYfwIacEsQGlnTvjk1IgYkyTGjPhF0RnwTCmw= -github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= -github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a h1:G++j5e0OC488te356JvdhaM8YS6nMsjLAYF7JxCv07w= -github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= -github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= -github.com/whyrusleeping/cbor-gen v0.0.0-20220514204315-f29c37e9c44c h1:6VPKXBDRt7mDUyiHx9X8ROnPYFDf3L7OfEuKCI5dZDI= -github.com/whyrusleeping/cbor-gen v0.0.0-20220514204315-f29c37e9c44c/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= -github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= -github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= -github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= -github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= -github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg= -github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvvKCaQ= -github.com/zeebo/errs v1.2.2 h1:5NFypMTuSdoySVTqlNs1dEoU21QVamMQJxW/Fii5O7g= -github.com/zeebo/errs v1.2.2/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= -github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= -github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= -go.opentelemetry.io/otel v1.9.0 h1:8WZNQFIB2a71LnANS9JeyidJKKGOOremcUtb/OtHISw= -go.opentelemetry.io/otel v1.9.0/go.mod h1:np4EoPGzoPs3O67xUVNoPPcmSvsfOxNlNA4F4AC+0Eo= -go.opentelemetry.io/otel/trace v1.9.0 h1:oZaCNJUjWcg60VXWee8lJKlqhPbXAPB51URuR47pQYc= -go.opentelemetry.io/otel/trace v1.9.0/go.mod h1:2737Q0MuG8q1uILYm2YYVkAyLtOofiTNGg6VODnOiPo= -go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= -go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= -go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= -go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= -go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= -go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= -golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM= -golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/image v0.0.0-20200119044424-58c23975cae1 h1:5h3ngYt7+vXCDZCup/HkCQgW5XwmSvR/nA2JmJ0RErg= -golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWIEjGcGAkacif7oYQaUY= -golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190302025703-b6889370fb10/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 h1:v6hYoSR9T5oet+pMXwUWkbiVqx/63mlHjefrHmxwfeY= -golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f h1:uF6paiQQebLeSXkrTqHqz0MXhXXS1KgF41eUdBNvxK0= -golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 h1:VpOs+IwYnYBaFnrNAeB8UUWtL3vEUnzSCL1nVjPhqrw= -gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= -lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= -storj.io/drpc v0.0.32 h1:5p5ZwsK/VOgapaCu+oxaPVwO6UwIs+iwdMiD50+R4PI= -storj.io/drpc v0.0.32/go.mod h1:6rcOyR/QQkSTX/9L5ZGtlZaE2PtXTTZl8d+ulSeeYEg= diff --git a/go.work b/go.work new file mode 100644 index 00000000..70bb12fa --- /dev/null +++ b/go.work @@ -0,0 +1,9 @@ +go 1.19 + +use ( + ./common + ./consensus + ./node + ./client + ./util +) diff --git a/go.work.sum b/go.work.sum new file mode 100644 index 00000000..b033a6bd --- /dev/null +++ b/go.work.sum @@ -0,0 +1,151 @@ +cloud.google.com/go v0.65.0 h1:Dg9iHVQfrhq82rUNu9ZxUDrJLaxFUe/HlCVaLyRruq8= +cloud.google.com/go/bigquery v1.8.0 h1:PQcPefKFdaIzjQFbiyOgAqyx8q5djaE7x9Sqe712DPA= +cloud.google.com/go/datastore v1.1.0 h1:/May9ojXjRkPBNVrq+oWLqmWCkr4OU5uRY29bu0mRyQ= +cloud.google.com/go/pubsub v1.3.1 h1:ukjixP1wl0LpnZ6LWtZJ0mX5tBmjp1f8Sqer8Z2OMUU= +cloud.google.com/go/storage v1.10.0 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY= +github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc= +github.com/akrylysov/pogreb v0.10.1 h1:FqlR8VR7uCbJdfUob916tPM+idpKgeESDXOA1K0DK4w= +github.com/akrylysov/pogreb v0.10.1/go.mod h1:pNs6QmpQ1UlTJKDezuRWmaqkgUE2TuU0YTWyqJZ7+lI= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6 h1:G1bPvciwNyF7IUmKXNt9Ak3m6u9DE1rF+RmtIkBpVdA= +github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk= +github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= +github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f h1:WBZRG4aNOuI15bLRrCgN8fCq8E5Xuty6jGbmSNEvSsU= +github.com/containerd/cgroups v1.0.4 h1:jN/mbWBEaz+T1pi5OFtnkQ+8qnmEbAr1Oo1FRm5B0dA= +github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04= +github.com/coreos/go-etcd v2.0.0+incompatible h1:bXhRBIXoTm9BYHS3gE0TtQuyNZyeEMux2sDi4oo5YOo= +github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY= +github.com/coreos/go-systemd/v22 v22.4.0 h1:y9YHcjnjynCd/DVbg5j9L/33jQM3MxJlbj/zWskzfGU= +github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= +github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= +github.com/dgraph-io/badger v1.6.2 h1:mNw0qs90GVgGGWylh0umH5iag1j6n/PeJtNvL6KY/x8= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= +github.com/envoyproxy/go-control-plane v0.9.4 h1:rEvIZUSZ3fx39WIi3JkQqQBitGwpELBIYWeBVh6wn+E= +github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= +github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= +github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= +github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 h1:WtGNWLvXpe6ZudgnXrq0barxBImvnnJoMEhXAzcbM0I= +github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= +github.com/go-kit/log v0.2.0 h1:7i2K3eKTos3Vc0enKCfnVcgHh2olr/MyfboYq7cAcFw= +github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= +github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= +github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= +github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= +github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= +github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= +github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= +github.com/google/martian/v3 v3.0.0 h1:pMen7vLs8nvgEYhywH3KDWJIJTeEr2ULsVWHWYHQyBs= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99 h1:Ak8CrdlwwXwAZxzS66vgPt4U8yUZX7JwLvVR58FN5jM= +github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6 h1:UDMh68UUwekSh5iP2OMhRRZJiiBccgV7axzUG8vi56c= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= +github.com/ipfs/go-ds-badger v0.3.0 h1:xREL3V0EH9S219kFFueOYJJTcjgNSZ2HY1iSvN7U1Ro= +github.com/ipfs/go-ds-leveldb v0.5.0 h1:s++MEBbD3ZKc9/8/njrn4flZLnCuY9I79v94gBUNumo= +github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= +github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= +github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= +github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= +github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= +github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= +github.com/kisielk/errcheck v1.5.0 h1:e8esj/e4R+SAOwFwN+n3zr0nYeCyeweozKfO23MvHzY= +github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= +github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= +github.com/koron/go-ssdp v0.0.3 h1:JivLMY45N76b4p/vsWGOKewBQu6uf39y8l+AQ7sDKx8= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= +github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw= +github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= +github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= +github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= +github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= +github.com/libp2p/go-mplex v0.7.0 h1:BDhFZdlk5tbr0oyFq/xv/NPGfjbnrsDam1EvutpBDbY= +github.com/libp2p/go-msgio v0.2.0 h1:W6shmB+FeynDrUVl2dgFQvzfBZcXiyqY4VmpQLu9FqU= +github.com/libp2p/go-nat v0.1.0 h1:MfVsH6DLcpa04Xr+p8hmVRG4juse0s3J8HyNWYHffXg= +github.com/libp2p/go-netroute v0.2.0 h1:0FpsbsvuSnAhXFnCY0VLFbJOzaK0VnP0r1QT/o4nWRE= +github.com/libp2p/go-reuseport v0.2.0 h1:18PRvIMlpY6ZK85nIAicSBuXXvrYoSw3dsBAR7zc560= +github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ= +github.com/libp2p/zeroconf/v2 v2.2.0 h1:Cup06Jv6u81HLhIj1KasuNM/RHHrJ8T7wOTS4+Tv53Q= +github.com/lucas-clemente/quic-go v0.29.1 h1:Z+WMJ++qMLhvpFkRZA+jl3BTxUjm415YBmWanXB8zP0= +github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= +github.com/marten-seemann/qpack v0.2.1 h1:jvTsT/HpCn2UZJdP+UUB53FfUUgeOyG5K1ns0OJOGVs= +github.com/marten-seemann/qtls-go1-18 v0.1.2 h1:JH6jmzbduz0ITVQ7ShevK10Av5+jBEKAHMntXmIV7kM= +github.com/marten-seemann/qtls-go1-19 v0.1.0 h1:rLFKD/9mp/uq1SYGYuVZhm83wkmU95pK5df3GufyYYU= +github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= +github.com/marten-seemann/webtransport-go v0.1.1 h1:TnyKp3pEXcDooTaNn4s9dYpMJ7kMnTp7k5h+SgYP/mc= +github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= +github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= +github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= +github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= +github.com/multiformats/go-multistream v0.3.3 h1:d5PZpjwRgVlbwfdTDjife7XszfZd8KYWfROYFlGcR8o= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= +github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= +github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= +github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk= +github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= +github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= +github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= +github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= +github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= +github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= +github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= +github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M= +github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= +github.com/stretchr/testify v1.7.3/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8 h1:3SVOIvH7Ae1KRYyQWRjXWJEA9sS/c/pjvH++55Gr648= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77 h1:ESFSdwYZvkeru3RtdrYueztKhOBCSAAzS4Gf+k0tEow= +github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/exp v0.0.0-20220916125017-b168a2c6b86b h1:SCE/18RnFsLrjydh/R/s5EVvHoZprqEQUuoxK8q2Pc4= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b h1:clP8eMhB30EHdc0bd2Twtq6kgU7yl5ub2cQLSdrv1Dg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= +golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +google.golang.org/api v0.30.0 h1:yfrXXP61wVuLb0vBcG6qaOoIoqYEzOQS8jum51jkv2w= +google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987 h1:PDIOdWxZ8eRizhKa1AAvY53xsvLB1cWorMjslvY3VA8= +google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= +gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8= +rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= +rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY= +rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= diff --git a/node/Makefile b/node/Makefile new file mode 100644 index 00000000..e33e5c6e --- /dev/null +++ b/node/Makefile @@ -0,0 +1,9 @@ +.PHONY: proto build test +export GOPRIVATE=github.com/anytypeio + +build: + @$(eval FLAGS := $$(shell govvv -flags -pkg github.com/anytypeio/go-anytype-infrastructure-experiments/node)) + go build -v -o ../bin/anytype-node -ldflags "$(FLAGS)" github.com/anytypeio/go-anytype-infrastructure-experiments/node/cmd + +test: + go test ./... --cover \ No newline at end of file diff --git a/node/account/service.go b/node/account/service.go new file mode 100644 index 00000000..91f237b4 --- /dev/null +++ b/node/account/service.go @@ -0,0 +1,70 @@ +package account + +import ( + commonaccount "github.com/anytypeio/go-anytype-infrastructure-experiments/common/account" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/config" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/account" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/encryptionkey" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/signingkey" +) + +type service struct { + accountData *account.AccountData + peerId string +} + +func (s *service) Account() *account.AccountData { + return s.accountData +} + +func New() app.Component { + return &service{} +} + +func (s *service) Init(a *app.App) (err error) { + acc := a.MustComponent(config.CName).(commonaccount.ConfigGetter).GetAccount() + + decodedEncryptionKey, err := keys.DecodeKeyFromString( + acc.EncryptionKey, + encryptionkey.NewEncryptionRsaPrivKeyFromBytes, + nil) + if err != nil { + return err + } + + decodedSigningKey, err := keys.DecodeKeyFromString( + acc.SigningKey, + signingkey.NewSigningEd25519PrivKeyFromBytes, + nil) + if err != nil { + return err + } + + decodedPeerKey, err := keys.DecodeKeyFromString( + acc.PeerKey, + signingkey.NewSigningEd25519PrivKeyFromBytes, + nil) + if err != nil { + return err + } + + identity, err := decodedSigningKey.GetPublic().Raw() + if err != nil { + return err + } + + s.accountData = &account.AccountData{ + Identity: identity, + PeerKey: decodedPeerKey, + SignKey: decodedSigningKey, + EncKey: decodedEncryptionKey, + } + + return nil +} + +func (s *service) Name() (name string) { + return commonaccount.CName +} diff --git a/node/acl/service.go b/node/acl/service.go new file mode 100644 index 00000000..a417778c --- /dev/null +++ b/node/acl/service.go @@ -0,0 +1,134 @@ +package acl + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/account" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice/synchandler" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/cid" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusclient" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto" + "time" +) + +const CName = "node.acl" + +var log = logger.NewNamed(CName) + +func New() Service { + return &service{} +} + +type Service interface { + CreateLog(ctx context.Context, aclId string, rawRec *aclrecordproto.RawACLRecord) (firstRecId string, err error) + AddRecord(ctx context.Context, aclId string, rawRec *aclrecordproto.RawACLRecord) (id string, err error) + Watch(ctx context.Context, spaceId, aclId string, h synchandler.SyncHandler) (err error) + UnWatch(aclId string) (err error) + app.Component +} + +type service struct { + consService consensusclient.Service + account account.Service +} + +func (s *service) Init(a *app.App) (err error) { + s.consService = a.MustComponent(consensusclient.CName).(consensusclient.Service) + s.account = a.MustComponent(account.CName).(account.Service) + return +} + +func (s *service) Name() (name string) { + return CName +} + +func (s *service) CreateLog(ctx context.Context, aclId string, rawRec *aclrecordproto.RawACLRecord) (firstRecId string, err error) { + logId, err := cidToByte(aclId) + if err != nil { + return + } + recId, _, payload, err := s.signAndMarshal(rawRec) + if err != nil { + return + } + if err = s.consService.AddLog(ctx, &consensusproto.Log{ + Id: logId, + Records: []*consensusproto.Record{ + { + Id: recId, + Payload: payload, + CreatedUnix: uint64(time.Now().Unix()), + }, + }, + }); err != nil { + return + } + return cidToString(recId) +} + +func (s *service) AddRecord(ctx context.Context, aclId string, rawRec *aclrecordproto.RawACLRecord) (id string, err error) { + logId, err := cidToByte(aclId) + if err != nil { + return + } + + recId, prevId, payload, err := s.signAndMarshal(rawRec) + if err != nil { + return + } + if err = s.consService.AddRecord(ctx, logId, &consensusproto.Record{ + Id: recId, + PrevId: prevId, + Payload: payload, + CreatedUnix: uint64(time.Now().Unix()), + }); err != nil { + return + } + return cidToString(recId) +} + +func (s *service) Watch(ctx context.Context, spaceId, aclId string, h synchandler.SyncHandler) (err error) { + w, err := newWatcher(spaceId, aclId, h) + if err != nil { + return + } + if err = s.consService.Watch(w.logId, w); err != nil { + return err + } + return w.Ready(ctx) +} + +func (s *service) UnWatch(aclId string) (err error) { + logId, err := cidToByte(aclId) + if err != nil { + return + } + return s.consService.UnWatch(logId) +} + +func (s *service) signAndMarshal(rawRec *aclrecordproto.RawACLRecord) (recId, prevId, payload []byte, err error) { + var rec = &aclrecordproto.ACLRecord{} + if err = rec.Unmarshal(rawRec.Payload); err != nil { + return + } + if rec.PrevId != "" { + if prevId, err = cidToByte(rec.PrevId); err != nil { + return + } + } + rawRec.AcceptorIdentity = s.account.Account().Identity + if rawRec.AcceptorSignature, err = s.account.Account().SignKey.Sign(rawRec.Payload); err != nil { + return + } + if payload, err = rawRec.Marshal(); err != nil { + return + } + recCid, err := cid.NewCIDFromBytes(payload) + if err != nil { + return + } + recId, err = cidToByte(recCid) + return +} diff --git a/node/acl/service_test.go b/node/acl/service_test.go new file mode 100644 index 00000000..eb720d64 --- /dev/null +++ b/node/acl/service_test.go @@ -0,0 +1,195 @@ +package acl + +import ( + "context" + "fmt" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/testutil/testaccount" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/cid" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusclient" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusclient/mock_consensusclient" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "testing" + "time" +) + +var ctx = context.Background() + +func TestService_CreateLog(t *testing.T) { + fx := newFixture(t) + defer fx.Finish(t) + var clog *consensusproto.Log + fx.mockClient.EXPECT().AddLog(ctx, gomock.Any()).Do(func(ctx context.Context, l *consensusproto.Log) { + clog = l + }) + + aclId, _ := cid.NewCIDFromBytes([]byte("aclId")) + + rec := &aclrecordproto.ACLRecord{ + PrevId: "", + Identity: fx.account.Account().Identity, + Data: []byte{'1', '2', '3'}, + Timestamp: time.Now().Unix(), + } + pl, _ := rec.Marshal() + + firstRecId, err := fx.CreateLog(ctx, aclId, &aclrecordproto.RawACLRecord{ + Payload: pl, + }) + require.NoError(t, err) + aclIdBytes, _ := cidToByte(aclId) + firstRecIdBytes, _ := cidToByte(firstRecId) + assert.Equal(t, aclIdBytes, clog.Id) + assert.NotEmpty(t, firstRecIdBytes) + require.Len(t, clog.Records, 1) + + var resultRawAcl = &aclrecordproto.RawACLRecord{} + require.NoError(t, resultRawAcl.Unmarshal(clog.Records[0].Payload)) + valid, err := fx.account.Account().SignKey.GetPublic().Verify(resultRawAcl.Payload, resultRawAcl.AcceptorSignature) + require.NoError(t, err) + require.True(t, valid) +} + +func TestService_AddRecord(t *testing.T) { + fx := newFixture(t) + defer fx.Finish(t) + var clog *consensusproto.Log + fx.mockClient.EXPECT().AddLog(ctx, gomock.Any()).Do(func(ctx context.Context, l *consensusproto.Log) { + clog = l + }) + + aclId, _ := cid.NewCIDFromBytes([]byte("aclId")) + + rec := &aclrecordproto.ACLRecord{ + PrevId: "", + Identity: fx.account.Account().Identity, + Data: []byte{'1', '2', '3'}, + Timestamp: time.Now().Unix(), + } + pl, _ := rec.Marshal() + + firstRecId, err := fx.CreateLog(ctx, aclId, &aclrecordproto.RawACLRecord{ + Payload: pl, + }) + require.NoError(t, err) + aclIdBytes, _ := cidToByte(aclId) + firstRecIdBytes, _ := cidToByte(firstRecId) + assert.Equal(t, aclIdBytes, clog.Id) + assert.NotEmpty(t, firstRecIdBytes) + var addRec *consensusproto.Record + fx.mockClient.EXPECT().AddRecord(ctx, aclIdBytes, gomock.Any()).Do(func(ctx context.Context, logId []byte, rec *consensusproto.Record) { + addRec = rec + }) + rec = &aclrecordproto.ACLRecord{ + PrevId: firstRecId, + Identity: fx.account.Account().Identity, + Data: []byte{'1', '2', '3', '4'}, + Timestamp: time.Now().Unix(), + } + pl, _ = rec.Marshal() + + newRecId, err := fx.AddRecord(ctx, aclId, &aclrecordproto.RawACLRecord{ + Payload: pl, + }) + require.NoError(t, err) + assert.NotEmpty(t, newRecId) + + assert.Equal(t, firstRecIdBytes, addRec.PrevId) + +} + +func TestService_Watch(t *testing.T) { + t.Run("remote error", func(t *testing.T) { + fx := newFixture(t) + defer fx.Finish(t) + var expErr = fmt.Errorf("error") + aclId, _ := cid.NewCIDFromBytes([]byte("aclId")) + aclIdBytes, _ := cidToByte(aclId) + fx.mockClient.EXPECT().Watch(aclIdBytes, gomock.Any()).Do(func(aid []byte, w consensusclient.Watcher) { + assert.Equal(t, aclIdBytes, aid) + go func() { + time.Sleep(time.Millisecond * 10) + w.AddConsensusError(expErr) + }() + }) + + th := &testHandler{} + err := fx.Watch(ctx, "123", aclId, th) + assert.Equal(t, expErr, err) + }) + t.Run("success", func(t *testing.T) { + fx := newFixture(t) + defer fx.Finish(t) + aclId, _ := cid.NewCIDFromBytes([]byte("aclId")) + aclIdBytes, _ := cidToByte(aclId) + fx.mockClient.EXPECT().Watch(aclIdBytes, gomock.Any()).Do(func(aid []byte, w consensusclient.Watcher) { + assert.Equal(t, aclIdBytes, aid) + go func() { + time.Sleep(time.Millisecond * 10) + r1cid, _ := cid.NewCIDFromBytes([]byte("r1")) + r2cid, _ := cid.NewCIDFromBytes([]byte("r2")) + r1cidB, _ := cidToByte(r1cid) + r2cidB, _ := cidToByte(r2cid) + w.AddConsensusRecords([]*consensusproto.Record{ + { + Id: r2cidB, + PrevId: r1cidB, + Payload: []byte("p1"), + }, + { + Id: r1cidB, + Payload: []byte("p1"), + }, + }) + }() + }) + + th := &testHandler{} + err := fx.Watch(ctx, "123", aclId, th) + require.NoError(t, err) + }) +} + +func newFixture(t *testing.T) *fixture { + fx := &fixture{ + a: new(app.App), + ctrl: gomock.NewController(t), + account: &testaccount.AccountTestService{}, + } + fx.mockClient = mock_consensusclient.NewMockService(fx.ctrl) + fx.mockClient.EXPECT().Name().Return(consensusclient.CName).AnyTimes() + fx.mockClient.EXPECT().Init(gomock.Any()).AnyTimes() + fx.mockClient.EXPECT().Run(gomock.Any()).AnyTimes() + fx.mockClient.EXPECT().Close(gomock.Any()).AnyTimes() + fx.Service = New() + fx.a.Register(fx.account).Register(fx.mockClient).Register(fx.Service) + require.NoError(t, fx.a.Start(ctx)) + return fx +} + +type fixture struct { + Service + mockClient *mock_consensusclient.MockService + ctrl *gomock.Controller + a *app.App + account *testaccount.AccountTestService +} + +func (fx *fixture) Finish(t *testing.T) { + require.NoError(t, fx.a.Close(ctx)) + fx.ctrl.Finish() +} + +type testHandler struct { + req *spacesyncproto.ObjectSyncMessage +} + +func (t *testHandler) HandleMessage(ctx context.Context, senderId string, request *spacesyncproto.ObjectSyncMessage) (err error) { + t.req = request + return +} diff --git a/node/acl/util.go b/node/acl/util.go new file mode 100644 index 00000000..c6784a33 --- /dev/null +++ b/node/acl/util.go @@ -0,0 +1,19 @@ +package acl + +import "github.com/ipfs/go-cid" + +func cidToString(b []byte) (s string, err error) { + rcid, err := cid.Cast(b) + if err != nil { + return + } + return rcid.String(), nil +} + +func cidToByte(s string) (b []byte, err error) { + rcid, err := cid.Decode(s) + if err != nil { + return + } + return rcid.Bytes(), nil +} diff --git a/node/acl/util_test.go b/node/acl/util_test.go new file mode 100644 index 00000000..1ebe5fcb --- /dev/null +++ b/node/acl/util_test.go @@ -0,0 +1,16 @@ +package acl + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/cid" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestCIDLen(t *testing.T) { + s, _ := cid.NewCIDFromBytes([]byte("some data")) + t.Log(s, len(s)) + b, _ := cidToByte(s) + t.Log(b, len(b)) + s2, _ := cidToString(b) + assert.Equal(t, s, s2) +} diff --git a/node/acl/watcher.go b/node/acl/watcher.go new file mode 100644 index 00000000..6a88cb0e --- /dev/null +++ b/node/acl/watcher.go @@ -0,0 +1,93 @@ +package acl + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice/synchandler" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto" + "go.uber.org/zap" + "sync" +) + +func newWatcher(spaceId, aclId string, h synchandler.SyncHandler) (w *watcher, err error) { + w = &watcher{ + aclId: aclId, + spaceId: spaceId, + handler: h, + ready: make(chan struct{}), + } + if w.logId, err = cidToByte(aclId); err != nil { + return nil, err + } + return +} + +type watcher struct { + spaceId string + aclId string + logId []byte + handler synchandler.SyncHandler + ready chan struct{} + isReady sync.Once + err error +} + +func (w *watcher) AddConsensusRecords(recs []*consensusproto.Record) { + w.isReady.Do(func() { + close(w.ready) + }) + records := make([]*aclrecordproto.RawACLRecordWithId, 0, len(recs)) + + for _, rec := range recs { + recId, err := cidToString(rec.Id) + if err != nil { + log.Error("received invalid id from consensus node", zap.Error(err)) + continue + } + records = append(records, &aclrecordproto.RawACLRecordWithId{ + Payload: rec.Payload, + Id: recId, + }) + } + + aclReq := &aclrecordproto.ACLSyncMessage{ + Content: &aclrecordproto.ACLSyncContentValue{ + Value: &aclrecordproto.ACLSyncContentValue_AddRecords{ + AddRecords: &aclrecordproto.ACLAddRecords{ + Records: records, + }, + }, + }, + } + payload, err := aclReq.Marshal() + if err != nil { + log.Error("acl payload marshal error", zap.Error(err)) + return + } + req := &spacesyncproto.ObjectSyncMessage{ + SpaceId: w.spaceId, + Payload: payload, + ObjectId: w.aclId, + } + + if err = w.handler.HandleMessage(context.TODO(), "", req); err != nil { + log.Warn("handle message error", zap.Error(err)) + } +} + +func (w *watcher) AddConsensusError(err error) { + w.isReady.Do(func() { + w.err = err + close(w.ready) + }) +} + +func (w *watcher) Ready(ctx context.Context) (err error) { + select { + case <-w.ready: + return w.err + case <-ctx.Done(): + return ctx.Err() + } +} diff --git a/cmd/node/node.go b/node/cmd/node.go similarity index 52% rename from cmd/node/node.go rename to node/cmd/node.go index 5020fe12..1606ac3e 100644 --- a/cmd/node/node.go +++ b/node/cmd/node.go @@ -4,22 +4,20 @@ import ( "context" "flag" "fmt" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger" - "github.com/anytypeio/go-anytype-infrastructure-experiments/config" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/account" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/api" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/configuration" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/file" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/dialer" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/pool" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/rpc/server" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/secure" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/node" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/sync/document" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/sync/message" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/sync/requesthandler" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/treecache" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/config" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/metric" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/dialer" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/pool" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/rpc/server" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/secure" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf" + "github.com/anytypeio/go-anytype-infrastructure-experiments/node/account" + "github.com/anytypeio/go-anytype-infrastructure-experiments/node/nodespace" + "github.com/anytypeio/go-anytype-infrastructure-experiments/node/nodespace/nodecache" + "github.com/anytypeio/go-anytype-infrastructure-experiments/node/storage" "go.uber.org/zap" "net/http" _ "net/http/pprof" @@ -94,16 +92,14 @@ func main() { func Bootstrap(a *app.App) { a.Register(account.New()). - Register(node.New()). + Register(metric.New()). + Register(storage.New()). + Register(nodecache.New(200)). + Register(nodeconf.New()). Register(secure.New()). - Register(server.New()). - Register(file.New()). Register(dialer.New()). - Register(pool.NewPool()). - Register(configuration.New()). - Register(document.New()). - Register(message.New()). - Register(requesthandler.New()). - Register(treecache.New()). - Register(api.New()) + Register(pool.New()). + Register(nodespace.New()). + Register(commonspace.New()). + Register(server.New()) } diff --git a/node/go.mod b/node/go.mod new file mode 100644 index 00000000..a65cf8f2 --- /dev/null +++ b/node/go.mod @@ -0,0 +1,66 @@ +module github.com/anytypeio/go-anytype-infrastructure-experiments/node + +go 1.19 + +replace github.com/anytypeio/go-anytype-infrastructure-experiments/common => ../common + +replace github.com/anytypeio/go-anytype-infrastructure-experiments/consensus => ../consensus + +require ( + github.com/akrylysov/pogreb v0.10.1 + github.com/anytypeio/go-anytype-infrastructure-experiments/common v0.0.0-00010101000000-000000000000 + github.com/anytypeio/go-anytype-infrastructure-experiments/consensus v0.0.0-00010101000000-000000000000 + go.uber.org/zap v1.23.0 +) + +require ( + github.com/anytypeio/go-chash v0.0.0-20220629194632-4ad1154fe232 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash v1.1.0 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/cheggaaa/mb/v2 v2.0.1 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect + github.com/fogleman/gg v1.3.0 // indirect + github.com/goccy/go-graphviz v0.0.9 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/huandu/skiplist v1.2.0 // indirect + github.com/ipfs/go-cid v0.3.2 // indirect + github.com/ipfs/go-log/v2 v2.5.1 // indirect + github.com/klauspost/cpuid/v2 v2.1.1 // indirect + github.com/libp2p/go-buffer-pool v0.1.0 // indirect + github.com/libp2p/go-libp2p v0.23.2 // indirect + github.com/libp2p/go-libp2p-core v0.20.1 // indirect + github.com/libp2p/go-openssl v0.1.0 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-pointer v0.0.1 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/minio/sha256-simd v1.0.0 // indirect + github.com/mr-tron/base58 v1.2.0 // indirect + github.com/multiformats/go-base32 v0.1.0 // indirect + github.com/multiformats/go-base36 v0.1.0 // indirect + github.com/multiformats/go-multiaddr v0.7.0 // indirect + github.com/multiformats/go-multibase v0.1.1 // indirect + github.com/multiformats/go-multicodec v0.6.0 // indirect + github.com/multiformats/go-multihash v0.2.1 // indirect + github.com/multiformats/go-varint v0.0.6 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/prometheus/client_golang v1.13.0 // indirect + github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/common v0.37.0 // indirect + github.com/prometheus/procfs v0.8.0 // indirect + github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect + github.com/zeebo/blake3 v0.2.3 // indirect + github.com/zeebo/errs v1.3.0 // indirect + go.uber.org/atomic v1.10.0 // indirect + go.uber.org/multierr v1.8.0 // indirect + golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect + golang.org/x/image v0.0.0-20200119044424-58c23975cae1 // indirect + golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect + google.golang.org/protobuf v1.28.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + lukechampine.com/blake3 v1.1.7 // indirect + storj.io/drpc v0.0.32 // indirect +) diff --git a/node/go.sum b/node/go.sum new file mode 100644 index 00000000..55067483 --- /dev/null +++ b/node/go.sum @@ -0,0 +1,613 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +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= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/akrylysov/pogreb v0.10.1 h1:FqlR8VR7uCbJdfUob916tPM+idpKgeESDXOA1K0DK4w= +github.com/akrylysov/pogreb v0.10.1/go.mod h1:pNs6QmpQ1UlTJKDezuRWmaqkgUE2TuU0YTWyqJZ7+lI= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/anytypeio/go-chash v0.0.0-20220629194632-4ad1154fe232 h1:kMPPZYmJgbs4AJfodbg2OCXg5cp+9LPAJcLZJqmcghk= +github.com/anytypeio/go-chash v0.0.0-20220629194632-4ad1154fe232/go.mod h1:+PeHBAWp7gUh/yw6uAauKc5ku0w4cFNg6DUddGxoGq0= +github.com/awalterschulze/gographviz v2.0.3+incompatible h1:9sVEXJBJLwGX7EQVhLm2elIKCm7P2YHFC8v6096G09E= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cheggaaa/mb/v2 v2.0.1 h1:gn0khbEbKlw3i5VOYi0VnHEHayjZKfUDOyGSpHAybBs= +github.com/cheggaaa/mb/v2 v2.0.1/go.mod h1:XGeZw20Iqgjky26KL0mvCwk3+4NyZCUbshSo6ALne+c= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/corona10/goimagehash v1.0.2 h1:pUfB0LnsJASMPGEZLj7tGY251vF+qLGqOgEP4rUs6kA= +github.com/corona10/goimagehash v1.0.2/go.mod h1:/l9umBhvcHQXVtQO1V6Gp1yD20STawkhRnnX0D1bvVI= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8= +github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/goccy/go-graphviz v0.0.9 h1:s/FMMJ1Joj6La3S5ApO3Jk2cwM4LpXECC2muFx3IPQQ= +github.com/goccy/go-graphviz v0.0.9/go.mod h1:wXVsXxmyMQU6TN3zGRttjNn3h+iCAS7xQFC6TlNvLhk= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +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/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= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c= +github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= +github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw= +github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ipfs/go-cid v0.3.2 h1:OGgOd+JCFM+y1DjWPmVH+2/4POtpDzwcr7VgnB7mZXc= +github.com/ipfs/go-cid v0.3.2/go.mod h1:gQ8pKqT/sUxGY+tIwy1RPpAojYu7jAyCp5Tz1svoupw= +github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= +github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= +github.com/klauspost/cpuid/v2 v2.1.1 h1:t0wUqjowdm8ezddV5k0tLWVklVuvLJpoHeb4WBdydm0= +github.com/klauspost/cpuid/v2 v2.1.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= +github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= +github.com/libp2p/go-libp2p v0.23.2 h1:yqyTeKQJyofWXxEv/eEVUvOrGdt/9x+0PIQ4N1kaxmE= +github.com/libp2p/go-libp2p v0.23.2/go.mod h1:s9DEa5NLR4g+LZS+md5uGU4emjMWFiqkZr6hBTY8UxI= +github.com/libp2p/go-libp2p-core v0.20.1 h1:fQz4BJyIFmSZAiTbKV8qoYhEH5Dtv/cVhZbG3Ib/+Cw= +github.com/libp2p/go-libp2p-core v0.20.1/go.mod h1:6zR8H7CvQWgYLsbG4on6oLNSGcyKaYFSEYyDt51+bIY= +github.com/libp2p/go-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+Ooo= +github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= +github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= +github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= +github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= +github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= +github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4= +github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= +github.com/multiformats/go-multiaddr v0.7.0 h1:gskHcdaCyPtp9XskVwtvEeQOG465sCohbQIirSyqxrc= +github.com/multiformats/go-multiaddr v0.7.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs= +github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI= +github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8= +github.com/multiformats/go-multicodec v0.6.0 h1:KhH2kSuCARyuJraYMFxrNO3DqIaYhOdS039kbhgVwpE= +github.com/multiformats/go-multicodec v0.6.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw= +github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108= +github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= +github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY= +github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5 h1:BvoENQQU+fZ9uukda/RzCAL/191HHwJA5b13R6diVlY= +github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU= +github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= +github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= +github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= +github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= +github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg= +github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvvKCaQ= +github.com/zeebo/errs v1.3.0 h1:hmiaKqgYZzcVgRL1Vkc1Mn2914BbzB0IBxs+ebeutGs= +github.com/zeebo/errs v1.3.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= +github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= +github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +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.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= +go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= +go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= +go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200119044424-58c23975cae1 h1:5h3ngYt7+vXCDZCup/HkCQgW5XwmSvR/nA2JmJ0RErg= +golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +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= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +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= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +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/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 h1:VpOs+IwYnYBaFnrNAeB8UUWtL3vEUnzSCL1nVjPhqrw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= +lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +storj.io/drpc v0.0.32 h1:5p5ZwsK/VOgapaCu+oxaPVwO6UwIs+iwdMiD50+R4PI= +storj.io/drpc v0.0.32/go.mod h1:6rcOyR/QQkSTX/9L5ZGtlZaE2PtXTTZl8d+ulSeeYEg= diff --git a/node/nodespace/nodecache/treecache.go b/node/nodespace/nodecache/treecache.go new file mode 100644 index 00000000..79d3ac01 --- /dev/null +++ b/node/nodespace/nodecache/treecache.go @@ -0,0 +1,72 @@ +package nodecache + +import ( + "context" + "errors" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ocache" + "github.com/anytypeio/go-anytype-infrastructure-experiments/node/nodespace" + "time" +) + +var log = logger.NewNamed("treecache") +var ErrCacheObjectWithoutTree = errors.New("cache object contains no tree") + +type ctxKey int + +const spaceKey ctxKey = 0 + +type treeCache struct { + gcttl int + cache ocache.OCache + nodeService nodespace.Service +} + +func New(ttl int) treegetter.TreeGetter { + return &treeCache{ + gcttl: ttl, + } +} + +func (c *treeCache) Run(ctx context.Context) (err error) { + return nil +} + +func (c *treeCache) Close(ctx context.Context) (err error) { + return c.cache.Close() +} + +func (c *treeCache) Init(a *app.App) (err error) { + c.nodeService = a.MustComponent(nodespace.CName).(nodespace.Service) + c.cache = ocache.New( + func(ctx context.Context, id string) (value ocache.Object, err error) { + spaceId := ctx.Value(spaceKey).(string) + space, err := c.nodeService.GetSpace(ctx, spaceId) + if err != nil { + return + } + return space.BuildTree(ctx, id, nil) + }, + ocache.WithLogger(log.Sugar()), + ocache.WithGCPeriod(time.Minute), + ocache.WithTTL(time.Duration(c.gcttl)*time.Second), + ) + return nil +} + +func (c *treeCache) Name() (name string) { + return treegetter.CName +} + +func (c *treeCache) GetTree(ctx context.Context, spaceId, id string) (tr tree.ObjectTree, err error) { + ctx = context.WithValue(ctx, spaceKey, spaceId) + value, err := c.cache.Get(ctx, id) + if err != nil { + return + } + tr = value.(tree.ObjectTree) + return +} diff --git a/node/nodespace/rpchandler.go b/node/nodespace/rpchandler.go new file mode 100644 index 00000000..da8deca1 --- /dev/null +++ b/node/nodespace/rpchandler.go @@ -0,0 +1,63 @@ +package nodespace + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" +) + +type rpcHandler struct { + s *service +} + +func (r *rpcHandler) PullSpace(ctx context.Context, request *spacesyncproto.PullSpaceRequest) (resp *spacesyncproto.PullSpaceResponse, err error) { + sp, err := r.s.GetSpace(ctx, request.Id) + if err != nil { + if err != spacesyncproto.ErrSpaceMissing { + err = spacesyncproto.ErrUnexpected + } + return + } + + description := sp.Description() + resp = &spacesyncproto.PullSpaceResponse{ + SpaceHeader: description.SpaceHeader, + AclPayload: description.AclPayload, + AclPayloadId: description.AclId, + } + return +} + +func (r *rpcHandler) PushSpace(ctx context.Context, req *spacesyncproto.PushSpaceRequest) (resp *spacesyncproto.PushSpaceResponse, err error) { + description := commonspace.SpaceDescription{ + SpaceHeader: req.SpaceHeader, + AclId: req.AclPayloadId, + AclPayload: req.AclPayload, + } + err = r.s.AddSpace(ctx, description) + if err != nil { + return + } + resp = &spacesyncproto.PushSpaceResponse{} + return +} + +func (r *rpcHandler) HeadSync(ctx context.Context, req *spacesyncproto.HeadSyncRequest) (*spacesyncproto.HeadSyncResponse, error) { + sp, err := r.s.GetSpace(ctx, req.SpaceId) + if err != nil { + return nil, spacesyncproto.ErrSpaceMissing + } + return sp.SpaceSyncRpc().HeadSync(ctx, req) +} + +func (r *rpcHandler) Stream(stream spacesyncproto.DRPCSpace_StreamStream) error { + msg, err := stream.Recv() + if err != nil { + return err + } + sp, err := r.s.GetSpace(stream.Context(), msg.SpaceId) + if err != nil { + return spacesyncproto.ErrSpaceMissing + } + return sp.SpaceSyncRpc().Stream(stream) +} diff --git a/node/nodespace/service.go b/node/nodespace/service.go new file mode 100644 index 00000000..a1ad1f0a --- /dev/null +++ b/node/nodespace/service.go @@ -0,0 +1,87 @@ +package nodespace + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/config" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/rpc/server" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ocache" + "time" +) + +const CName = "node.nodespace" + +var log = logger.NewNamed(CName) + +func New() Service { + return &service{} +} + +type Service interface { + AddSpace(ctx context.Context, description commonspace.SpaceDescription) (err error) + GetSpace(ctx context.Context, id string) (commonspace.Space, error) + app.ComponentRunnable +} + +type service struct { + conf config.Space + spaceCache ocache.OCache + commonSpace commonspace.Service + spaceStorageProvider storage.SpaceStorageProvider +} + +func (s *service) Init(a *app.App) (err error) { + s.conf = a.MustComponent(config.CName).(*config.Config).Space + s.commonSpace = a.MustComponent(commonspace.CName).(commonspace.Service) + s.spaceStorageProvider = a.MustComponent(storage.CName).(storage.SpaceStorageProvider) + s.spaceCache = ocache.New( + s.loadSpace, + ocache.WithLogger(log.Sugar()), + ocache.WithGCPeriod(time.Minute), + ocache.WithTTL(time.Duration(s.conf.GCTTL)*time.Second), + ) + return spacesyncproto.DRPCRegisterSpace(a.MustComponent(server.CName).(server.DRPCServer), &rpcHandler{s}) +} + +func (s *service) Name() (name string) { + return CName +} + +func (s *service) Run(ctx context.Context) (err error) { + return +} + +func (s *service) GetSpace(ctx context.Context, id string) (commonspace.Space, error) { + v, err := s.spaceCache.Get(ctx, id) + if err != nil { + return nil, err + } + return v.(commonspace.Space), nil +} + +func (s *service) AddSpace(ctx context.Context, description commonspace.SpaceDescription) (err error) { + return s.commonSpace.AddSpace(ctx, description) +} + +func (s *service) loadSpace(ctx context.Context, id string) (value ocache.Object, err error) { + cc, err := s.commonSpace.NewSpace(ctx, id) + if err != nil { + return + } + ns, err := newNodeSpace(cc) + if err != nil { + return + } + if err = ns.Init(ctx); err != nil { + return + } + return ns, nil +} + +func (s *service) Close(ctx context.Context) (err error) { + return s.spaceCache.Close() +} diff --git a/node/nodespace/space.go b/node/nodespace/space.go new file mode 100644 index 00000000..a1ffe43f --- /dev/null +++ b/node/nodespace/space.go @@ -0,0 +1,24 @@ +package nodespace + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace" +) + +func newNodeSpace(cc commonspace.Space) (commonspace.Space, error) { + return &nodeSpace{cc}, nil +} + +type nodeSpace struct { + commonspace.Space +} + +func (s *nodeSpace) Init(ctx context.Context) (err error) { + // try to push acl to consensus node + // + return s.Space.Init(ctx) +} + +func (s *nodeSpace) Close() (err error) { + return s.Space.Close() +} diff --git a/node/storage/keys.go b/node/storage/keys.go new file mode 100644 index 00000000..e21a7140 --- /dev/null +++ b/node/storage/keys.go @@ -0,0 +1,78 @@ +package storage + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage" + "strings" +) + +type aclKeys struct { +} + +var aclHeadIdKey = []byte("a/headId") +var aclRootIdKey = []byte("a/rootId") + +func (a aclKeys) HeadIdKey() []byte { + return aclHeadIdKey +} + +func (a aclKeys) RootIdKey() []byte { + return aclRootIdKey +} + +func (a aclKeys) RawRecordKey(id string) []byte { + return storage.JoinStringsToBytes("a", id) +} + +type treeKeys struct { + id string + headsKey []byte +} + +func newTreeKeys(id string) treeKeys { + return treeKeys{ + id: id, + headsKey: storage.JoinStringsToBytes("t", id, "heads"), + } +} + +func (t treeKeys) HeadsKey() []byte { + return t.headsKey +} + +func (t treeKeys) RawChangeKey(id string) []byte { + return storage.JoinStringsToBytes("t", t.id, id) +} + +type spaceKeys struct { + headerKey []byte +} + +func newSpaceKeys(spaceId string) spaceKeys { + return spaceKeys{headerKey: storage.JoinStringsToBytes("s", spaceId)} +} + +var spaceIdKey = []byte("spaceId") + +func (s spaceKeys) SpaceIdKey() []byte { + return spaceIdKey +} + +func (s spaceKeys) HeaderKey() []byte { + return s.headerKey +} + +func isRootIdKey(key string) bool { + return strings.HasPrefix(key, "t/") && strings.HasSuffix(key, "/heads") +} + +func getRootId(key string) string { + prefixLen := 2 // len("t/") + suffixLen := 6 // len("/heads") + rootLen := len(key) - suffixLen - prefixLen + sBuf := strings.Builder{} + sBuf.Grow(rootLen) + for i := prefixLen; i < prefixLen+rootLen; i++ { + sBuf.WriteByte(key[i]) + } + return sBuf.String() +} diff --git a/node/storage/liststorage.go b/node/storage/liststorage.go new file mode 100644 index 00000000..e7fa3aba --- /dev/null +++ b/node/storage/liststorage.go @@ -0,0 +1,129 @@ +package storage + +import ( + "context" + "github.com/akrylysov/pogreb" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage" +) + +type listStorage struct { + db *pogreb.DB + keys aclKeys + id string + root *aclrecordproto.RawACLRecordWithId +} + +func newListStorage(db *pogreb.DB) (ls storage.ListStorage, err error) { + keys := aclKeys{} + rootId, err := db.Get(keys.RootIdKey()) + if err != nil { + return + } + if rootId == nil { + err = storage.ErrUnknownACLId + return + } + + root, err := db.Get(keys.RawRecordKey(string(rootId))) + if err != nil { + return + } + if root == nil { + err = storage.ErrUnknownACLId + return + } + + rootWithId := &aclrecordproto.RawACLRecordWithId{ + Payload: root, + Id: string(rootId), + } + + ls = &listStorage{ + db: db, + keys: aclKeys{}, + id: string(rootId), + root: rootWithId, + } + return +} + +func createListStorage(db *pogreb.DB, root *aclrecordproto.RawACLRecordWithId) (ls storage.ListStorage, err error) { + keys := aclKeys{} + has, err := db.Has(keys.RootIdKey()) + if err != nil { + return + } + if has { + return newListStorage(db) + } + + err = db.Put(keys.HeadIdKey(), []byte(root.Id)) + if err != nil { + return + } + + err = db.Put(keys.RawRecordKey(root.Id), root.Payload) + if err != nil { + return + } + + err = db.Put(keys.RootIdKey(), []byte(root.Id)) + if err != nil { + return + } + + ls = &listStorage{ + db: db, + keys: aclKeys{}, + id: root.Id, + root: root, + } + return +} + +func (l *listStorage) Id() string { + return l.id +} + +func (l *listStorage) Root() (*aclrecordproto.RawACLRecordWithId, error) { + return l.root, nil +} + +func (l *listStorage) Head() (head string, err error) { + bytes, err := l.db.Get(l.keys.HeadIdKey()) + if err != nil { + return + } + if bytes == nil { + err = storage.ErrUnknownACLId + return + } + head = string(bytes) + return +} + +func (l *listStorage) GetRawRecord(ctx context.Context, id string) (raw *aclrecordproto.RawACLRecordWithId, err error) { + res, err := l.db.Get(l.keys.RawRecordKey(id)) + if err != nil { + return + } + if res == nil { + err = storage.ErrUnknownRecord + return + } + + raw = &aclrecordproto.RawACLRecordWithId{ + Payload: res, + Id: id, + } + return +} + +func (l *listStorage) SetHead(headId string) (err error) { + return l.db.Put(l.keys.HeadIdKey(), []byte(headId)) +} + +func (l *listStorage) AddRawRecord(ctx context.Context, rec *aclrecordproto.RawACLRecordWithId) error { + return l.db.Put(l.keys.RawRecordKey(rec.Id), rec.Payload) +} diff --git a/node/storage/liststorage_test.go b/node/storage/liststorage_test.go new file mode 100644 index 00000000..4df253d2 --- /dev/null +++ b/node/storage/liststorage_test.go @@ -0,0 +1,70 @@ +package storage + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage" + "github.com/stretchr/testify/require" + "testing" +) + +func testList(t *testing.T, store storage.ListStorage, root *aclrecordproto.RawACLRecordWithId, head string) { + require.Equal(t, store.Id(), root.Id) + + aclRoot, err := store.Root() + require.NoError(t, err) + require.Equal(t, root, aclRoot) + + aclHead, err := store.Head() + require.NoError(t, err) + require.Equal(t, head, aclHead) +} + +func TestListStorage_Create(t *testing.T) { + fx := newFixture(t) + fx.open(t) + defer fx.stop(t) + + aclRoot := &aclrecordproto.RawACLRecordWithId{Payload: []byte("root"), Id: "someRootId"} + listStore, err := createListStorage(fx.db, aclRoot) + require.NoError(t, err) + testList(t, listStore, aclRoot, aclRoot.Id) + + t.Run("create same list storage returns nil", func(t *testing.T) { + // this is ok, because we only create new list storage when we create space storage + listStore, err := createListStorage(fx.db, aclRoot) + require.NoError(t, err) + testList(t, listStore, aclRoot, aclRoot.Id) + }) +} + +func TestListStorage_Methods(t *testing.T) { + fx := newFixture(t) + fx.open(t) + aclRoot := &aclrecordproto.RawACLRecordWithId{Payload: []byte("root"), Id: "someRootId"} + _, err := createListStorage(fx.db, aclRoot) + require.NoError(t, err) + fx.stop(t) + + fx.open(t) + defer fx.stop(t) + listStore, err := newListStorage(fx.db) + require.NoError(t, err) + testList(t, listStore, aclRoot, aclRoot.Id) + + t.Run("set head", func(t *testing.T) { + head := "newHead" + require.NoError(t, listStore.SetHead(head)) + aclHead, err := listStore.Head() + require.NoError(t, err) + require.Equal(t, head, aclHead) + }) + + t.Run("add raw record and get raw record", func(t *testing.T) { + newRec := &aclrecordproto.RawACLRecordWithId{Payload: []byte("rec"), Id: "someRecId"} + require.NoError(t, listStore.AddRawRecord(context.Background(), newRec)) + aclRec, err := listStore.GetRawRecord(context.Background(), newRec.Id) + require.NoError(t, err) + require.Equal(t, newRec, aclRec) + }) +} diff --git a/node/storage/spacestorage.go b/node/storage/spacestorage.go new file mode 100644 index 00000000..018c6b04 --- /dev/null +++ b/node/storage/spacestorage.go @@ -0,0 +1,178 @@ +package storage + +import ( + "github.com/akrylysov/pogreb" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" + spacestorage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage" + "go.uber.org/zap" + "path" + "sync" + "time" +) + +var defPogrebOptions = &pogreb.Options{ + BackgroundCompactionInterval: time.Minute * 5, +} + +var log = logger.NewNamed("storage.spacestorage") + +type spaceStorage struct { + spaceId string + objDb *pogreb.DB + keys spaceKeys + aclStorage storage.ListStorage + header *spacesyncproto.RawSpaceHeaderWithId + mx sync.Mutex +} + +func newSpaceStorage(rootPath string, spaceId string) (store spacestorage.SpaceStorage, err error) { + log.With(zap.String("id", spaceId)).Debug("space storage opening with new") + dbPath := path.Join(rootPath, spaceId) + objDb, err := pogreb.Open(dbPath, defPogrebOptions) + if err != nil { + return + } + + defer func() { + if err != nil { + log.With(zap.String("id", spaceId), zap.Error(err)).Warn("failed to open storage") + objDb.Close() + } + }() + + keys := newSpaceKeys(spaceId) + has, err := objDb.Has(keys.SpaceIdKey()) + if err != nil { + return + } + if !has { + err = spacestorage.ErrSpaceStorageMissing + return + } + + header, err := objDb.Get(keys.HeaderKey()) + if err != nil { + return + } + if header == nil { + err = spacestorage.ErrSpaceStorageMissing + return + } + + aclStorage, err := newListStorage(objDb) + if err != nil { + return + } + + store = &spaceStorage{ + spaceId: spaceId, + objDb: objDb, + keys: keys, + header: &spacesyncproto.RawSpaceHeaderWithId{ + RawHeader: header, + Id: spaceId, + }, + aclStorage: aclStorage, + } + return +} + +func createSpaceStorage(rootPath string, payload spacestorage.SpaceStorageCreatePayload) (store spacestorage.SpaceStorage, err error) { + log.With(zap.String("id", payload.SpaceHeaderWithId.Id)).Debug("space storage creating") + dbPath := path.Join(rootPath, payload.SpaceHeaderWithId.Id) + db, err := pogreb.Open(dbPath, defPogrebOptions) + if err != nil { + return + } + + defer func() { + if err != nil { + log.With(zap.String("id", payload.SpaceHeaderWithId.Id), zap.Error(err)).Warn("failed to create storage") + db.Close() + } + }() + + keys := newSpaceKeys(payload.SpaceHeaderWithId.Id) + has, err := db.Has(keys.SpaceIdKey()) + if err != nil { + return + } + if has { + err = spacesyncproto.ErrSpaceExists + return + } + + aclStorage, err := createListStorage(db, payload.RecWithId) + if err != nil { + return + } + + err = db.Put(keys.HeaderKey(), payload.SpaceHeaderWithId.RawHeader) + if err != nil { + return + } + + err = db.Put(keys.SpaceIdKey(), []byte(payload.SpaceHeaderWithId.Id)) + if err != nil { + return + } + + store = &spaceStorage{ + spaceId: payload.SpaceHeaderWithId.Id, + objDb: db, + keys: keys, + aclStorage: aclStorage, + header: payload.SpaceHeaderWithId, + } + return +} + +func (s *spaceStorage) Id() string { + return s.spaceId +} + +func (s *spaceStorage) TreeStorage(id string) (storage.TreeStorage, error) { + return newTreeStorage(s.objDb, id) +} + +func (s *spaceStorage) CreateTreeStorage(payload storage.TreeStorageCreatePayload) (ts storage.TreeStorage, err error) { + // we have mutex here, so we prevent overwriting the heads of a tree on concurrent creation + s.mx.Lock() + defer s.mx.Unlock() + + return createTreeStorage(s.objDb, payload) +} + +func (s *spaceStorage) ACLStorage() (storage.ListStorage, error) { + return s.aclStorage, nil +} + +func (s *spaceStorage) SpaceHeader() (header *spacesyncproto.RawSpaceHeaderWithId, err error) { + return s.header, nil +} + +func (s *spaceStorage) StoredIds() (ids []string, err error) { + index := s.objDb.Items() + + key, _, err := index.Next() + for err == nil { + strKey := string(key) + if isRootIdKey(strKey) { + ids = append(ids, getRootId(strKey)) + } + key, _, err = index.Next() + } + + if err != pogreb.ErrIterationDone { + return + } + err = nil + return +} + +func (s *spaceStorage) Close() (err error) { + log.With(zap.String("id", s.spaceId)).Debug("space storage closed") + return s.objDb.Close() +} diff --git a/node/storage/spacestorage_test.go b/node/storage/spacestorage_test.go new file mode 100644 index 00000000..33243e0a --- /dev/null +++ b/node/storage/spacestorage_test.go @@ -0,0 +1,107 @@ +package storage + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" + spacestorage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" + "github.com/stretchr/testify/require" + "os" + "strconv" + "testing" +) + +func spaceTestPayload() spacestorage.SpaceStorageCreatePayload { + header := &spacesyncproto.RawSpaceHeaderWithId{ + RawHeader: []byte("header"), + Id: "headerId", + } + aclRoot := &aclrecordproto.RawACLRecordWithId{ + Payload: []byte("aclRoot"), + Id: "aclRootId", + } + return spacestorage.SpaceStorageCreatePayload{ + RecWithId: aclRoot, + SpaceHeaderWithId: header, + } +} + +func testSpace(t *testing.T, store spacestorage.SpaceStorage, payload spacestorage.SpaceStorageCreatePayload) { + header, err := store.SpaceHeader() + require.NoError(t, err) + require.Equal(t, payload.SpaceHeaderWithId, header) + + aclStorage, err := store.ACLStorage() + require.NoError(t, err) + testList(t, aclStorage, payload.RecWithId, payload.RecWithId.Id) +} + +func TestSpaceStorage_Create(t *testing.T) { + dir, err := os.MkdirTemp("", "") + require.NoError(t, err) + + payload := spaceTestPayload() + store, err := createSpaceStorage(dir, payload) + require.NoError(t, err) + + testSpace(t, store, payload) + require.NoError(t, store.Close()) + + t.Run("create same storage returns error", func(t *testing.T) { + _, err := createSpaceStorage(dir, payload) + require.Error(t, err) + }) +} + +func TestSpaceStorage_NewAndCreateTree(t *testing.T) { + dir, err := os.MkdirTemp("", "") + require.NoError(t, err) + + payload := spaceTestPayload() + store, err := createSpaceStorage(dir, payload) + require.NoError(t, err) + require.NoError(t, store.Close()) + + store, err = newSpaceStorage(dir, payload.SpaceHeaderWithId.Id) + require.NoError(t, err) + defer func() { + require.NoError(t, store.Close()) + }() + testSpace(t, store, payload) + + t.Run("create tree and get tree", func(t *testing.T) { + payload := treeTestPayload() + treeStore, err := store.CreateTreeStorage(payload) + require.NoError(t, err) + testTreePayload(t, treeStore, payload) + + otherStore, err := store.TreeStorage(payload.RootRawChange.Id) + require.NoError(t, err) + testTreePayload(t, otherStore, payload) + }) +} + +func TestSpaceStorage_StoredIds(t *testing.T) { + dir, err := os.MkdirTemp("", "") + require.NoError(t, err) + + payload := spaceTestPayload() + store, err := createSpaceStorage(dir, payload) + require.NoError(t, err) + defer func() { + require.NoError(t, store.Close()) + }() + + n := 5 + var ids []string + for i := 0; i < n; i++ { + treePayload := treeTestPayload() + treePayload.RootRawChange.Id += strconv.Itoa(i) + ids = append(ids, treePayload.RootRawChange.Id) + _, err := store.CreateTreeStorage(treePayload) + require.NoError(t, err) + } + + storedIds, err := store.StoredIds() + require.NoError(t, err) + require.Equal(t, ids, storedIds) +} diff --git a/node/storage/storageservice.go b/node/storage/storageservice.go new file mode 100644 index 00000000..9b703cd8 --- /dev/null +++ b/node/storage/storageservice.go @@ -0,0 +1,33 @@ +package storage + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/config" +) + +type storageService struct { + rootPath string +} + +func New() storage.SpaceStorageProvider { + return &storageService{} +} + +func (s *storageService) Init(a *app.App) (err error) { + cfg := a.MustComponent(config.CName).(*config.Config) + s.rootPath = cfg.Storage.Path + return nil +} + +func (s *storageService) Name() (name string) { + return storage.CName +} + +func (s *storageService) SpaceStorage(id string) (storage.SpaceStorage, error) { + return newSpaceStorage(s.rootPath, id) +} + +func (s *storageService) CreateSpaceStorage(payload storage.SpaceStorageCreatePayload) (storage.SpaceStorage, error) { + return createSpaceStorage(s.rootPath, payload) +} diff --git a/node/storage/treestorage.go b/node/storage/treestorage.go new file mode 100644 index 00000000..77234d2f --- /dev/null +++ b/node/storage/treestorage.go @@ -0,0 +1,137 @@ +package storage + +import ( + "context" + "github.com/akrylysov/pogreb" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto" +) + +type treeStorage struct { + db *pogreb.DB + keys treeKeys + id string + root *treechangeproto.RawTreeChangeWithId +} + +func newTreeStorage(db *pogreb.DB, treeId string) (ts storage.TreeStorage, err error) { + keys := newTreeKeys(treeId) + heads, err := db.Get(keys.HeadsKey()) + if err != nil { + return + } + if heads == nil { + err = storage.ErrUnknownTreeId + return + } + + root, err := db.Get(keys.RawChangeKey(treeId)) + if err != nil { + return + } + if root == nil { + err = storage.ErrUnknownTreeId + return + } + + rootWithId := &treechangeproto.RawTreeChangeWithId{ + RawChange: root, + Id: treeId, + } + ts = &treeStorage{ + db: db, + keys: keys, + id: treeId, + root: rootWithId, + } + return +} + +func createTreeStorage(db *pogreb.DB, payload storage.TreeStorageCreatePayload) (ts storage.TreeStorage, err error) { + keys := newTreeKeys(payload.RootRawChange.Id) + has, err := db.Has(keys.HeadsKey()) + if err != nil { + return + } + if has { + err = storage.ErrTreeExists + return + } + + heads := storage.CreateHeadsPayload(payload.Heads) + + for _, ch := range payload.Changes { + err = db.Put(keys.RawChangeKey(ch.Id), ch.GetRawChange()) + if err != nil { + return + } + } + + err = db.Put(keys.RawChangeKey(payload.RootRawChange.Id), payload.RootRawChange.GetRawChange()) + if err != nil { + return + } + + err = db.Put(keys.HeadsKey(), heads) + if err != nil { + return + } + + ts = &treeStorage{ + db: db, + keys: keys, + id: payload.RootRawChange.Id, + root: payload.RootRawChange, + } + return +} + +func (t *treeStorage) Id() string { + return t.id +} + +func (t *treeStorage) Root() (raw *treechangeproto.RawTreeChangeWithId, err error) { + return t.root, nil +} + +func (t *treeStorage) Heads() (heads []string, err error) { + headsBytes, err := t.db.Get(t.keys.HeadsKey()) + if err != nil { + return + } + if headsBytes == nil { + err = storage.ErrUnknownTreeId + return + } + heads = storage.ParseHeads(headsBytes) + return +} + +func (t *treeStorage) SetHeads(heads []string) (err error) { + payload := storage.CreateHeadsPayload(heads) + return t.db.Put(t.keys.HeadsKey(), payload) +} + +func (t *treeStorage) AddRawChange(change *treechangeproto.RawTreeChangeWithId) (err error) { + return t.db.Put(t.keys.RawChangeKey(change.Id), change.RawChange) +} + +func (t *treeStorage) GetRawChange(ctx context.Context, id string) (raw *treechangeproto.RawTreeChangeWithId, err error) { + res, err := t.db.Get(t.keys.RawChangeKey(id)) + if err != nil { + return + } + if res == nil { + err = storage.ErrUnkownChange + } + + raw = &treechangeproto.RawTreeChangeWithId{ + RawChange: res, + Id: id, + } + return +} + +func (t *treeStorage) HasChange(ctx context.Context, id string) (bool, error) { + return t.db.Has(t.keys.RawChangeKey(id)) +} diff --git a/node/storage/treestorage_test.go b/node/storage/treestorage_test.go new file mode 100644 index 00000000..00cce688 --- /dev/null +++ b/node/storage/treestorage_test.go @@ -0,0 +1,121 @@ +package storage + +import ( + "context" + "github.com/akrylysov/pogreb" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto" + "github.com/stretchr/testify/require" + "os" + "testing" +) + +func treeTestPayload() storage.TreeStorageCreatePayload { + rootRawChange := &treechangeproto.RawTreeChangeWithId{RawChange: []byte("some"), Id: "rootId"} + otherChange := &treechangeproto.RawTreeChangeWithId{RawChange: []byte("some other"), Id: "otherId"} + changes := []*treechangeproto.RawTreeChangeWithId{rootRawChange, otherChange} + return storage.TreeStorageCreatePayload{ + RootRawChange: rootRawChange, + Changes: changes, + Heads: []string{rootRawChange.Id}, + } +} + +type fixture struct { + dir string + db *pogreb.DB +} + +func newFixture(t *testing.T) *fixture { + dir, err := os.MkdirTemp("", "") + require.NoError(t, err) + return &fixture{dir: dir} +} + +func (fx *fixture) open(t *testing.T) { + var err error + fx.db, err = pogreb.Open(fx.dir, nil) + require.NoError(t, err) +} + +func (fx *fixture) stop(t *testing.T) { + require.NoError(t, fx.db.Close()) +} + +func testTreePayload(t *testing.T, store storage.TreeStorage, payload storage.TreeStorageCreatePayload) { + require.Equal(t, payload.RootRawChange.Id, store.Id()) + + root, err := store.Root() + require.NoError(t, err) + require.Equal(t, root, payload.RootRawChange) + + heads, err := store.Heads() + require.NoError(t, err) + require.Equal(t, payload.Heads, heads) + + for _, ch := range payload.Changes { + dbCh, err := store.GetRawChange(context.Background(), ch.Id) + require.NoError(t, err) + require.Equal(t, ch, dbCh) + } + return +} + +func TestTreeStorage_Create(t *testing.T) { + fx := newFixture(t) + fx.open(t) + defer fx.stop(t) + + payload := treeTestPayload() + store, err := createTreeStorage(fx.db, payload) + require.NoError(t, err) + testTreePayload(t, store, payload) + + t.Run("create same storage returns error", func(t *testing.T) { + _, err := createTreeStorage(fx.db, payload) + require.Error(t, err) + }) +} + +func TestTreeStorage_Methods(t *testing.T) { + fx := newFixture(t) + fx.open(t) + payload := treeTestPayload() + _, err := createTreeStorage(fx.db, payload) + require.NoError(t, err) + fx.stop(t) + + fx.open(t) + defer fx.stop(t) + store, err := newTreeStorage(fx.db, payload.RootRawChange.Id) + require.NoError(t, err) + testTreePayload(t, store, payload) + + t.Run("update heads", func(t *testing.T) { + newHeads := []string{"a", "b"} + require.NoError(t, store.SetHeads(newHeads)) + heads, err := store.Heads() + require.NoError(t, err) + require.Equal(t, newHeads, heads) + }) + + t.Run("add raw change, get change and has change", func(t *testing.T) { + newChange := &treechangeproto.RawTreeChangeWithId{RawChange: []byte("ab"), Id: "newId"} + require.NoError(t, store.AddRawChange(newChange)) + rawCh, err := store.GetRawChange(context.Background(), newChange.Id) + require.NoError(t, err) + require.Equal(t, newChange, rawCh) + has, err := store.HasChange(context.Background(), newChange.Id) + require.NoError(t, err) + require.True(t, has) + }) + + t.Run("get and has for unknown change", func(t *testing.T) { + incorrectId := "incorrectId" + _, err := store.GetRawChange(context.Background(), incorrectId) + require.Error(t, err) + has, err := store.HasChange(context.Background(), incorrectId) + require.NoError(t, err) + require.False(t, has) + }) +} diff --git a/pkg/acl/account/accountdata.go b/pkg/acl/account/accountdata.go deleted file mode 100644 index 7b0c773b..00000000 --- a/pkg/acl/account/accountdata.go +++ /dev/null @@ -1,13 +0,0 @@ -package account - -import ( - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey" -) - -type AccountData struct { // TODO: create a convenient constructor for this - Identity string // TODO: this is essentially the same as sign key - SignKey signingkey.PrivKey - EncKey encryptionkey.PrivKey - Decoder signingkey.PubKeyDecoder -} diff --git a/pkg/acl/aclchanges/aclpb/aclchanges.pb.go b/pkg/acl/aclchanges/aclpb/aclchanges.pb.go deleted file mode 100644 index 4a892fdf..00000000 --- a/pkg/acl/aclchanges/aclpb/aclchanges.pb.go +++ /dev/null @@ -1,4899 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: pkg/acl/aclchanges/aclpb/protos/aclchanges.proto - -package aclpb - -import ( - fmt "fmt" - proto "github.com/gogo/protobuf/proto" - io "io" - math "math" - math_bits "math/bits" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package - -type ACLChangeUserPermissions int32 - -const ( - ACLChange_Admin ACLChangeUserPermissions = 0 - ACLChange_Writer ACLChangeUserPermissions = 1 - ACLChange_Reader ACLChangeUserPermissions = 2 - ACLChange_Removed ACLChangeUserPermissions = 3 -) - -var ACLChangeUserPermissions_name = map[int32]string{ - 0: "Admin", - 1: "Writer", - 2: "Reader", - 3: "Removed", -} - -var ACLChangeUserPermissions_value = map[string]int32{ - "Admin": 0, - "Writer": 1, - "Reader": 2, - "Removed": 3, -} - -func (x ACLChangeUserPermissions) String() string { - return proto.EnumName(ACLChangeUserPermissions_name, int32(x)) -} - -func (ACLChangeUserPermissions) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{1, 0} -} - -type RawChange struct { - Payload []byte `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"` - Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` - Id string `protobuf:"bytes,3,opt,name=id,proto3" json:"id,omitempty"` -} - -func (m *RawChange) Reset() { *m = RawChange{} } -func (m *RawChange) String() string { return proto.CompactTextString(m) } -func (*RawChange) ProtoMessage() {} -func (*RawChange) Descriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{0} -} -func (m *RawChange) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *RawChange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_RawChange.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *RawChange) XXX_Merge(src proto.Message) { - xxx_messageInfo_RawChange.Merge(m, src) -} -func (m *RawChange) XXX_Size() int { - return m.Size() -} -func (m *RawChange) XXX_DiscardUnknown() { - xxx_messageInfo_RawChange.DiscardUnknown(m) -} - -var xxx_messageInfo_RawChange proto.InternalMessageInfo - -func (m *RawChange) GetPayload() []byte { - if m != nil { - return m.Payload - } - return nil -} - -func (m *RawChange) GetSignature() []byte { - if m != nil { - return m.Signature - } - return nil -} - -func (m *RawChange) GetId() string { - if m != nil { - return m.Id - } - return "" -} - -// the element of change tree used to store and internal apply smartBlock history -type ACLChange struct { - TreeHeadIds []string `protobuf:"bytes,1,rep,name=treeHeadIds,proto3" json:"treeHeadIds,omitempty"` - AclHeadIds []string `protobuf:"bytes,2,rep,name=aclHeadIds,proto3" json:"aclHeadIds,omitempty"` - SnapshotBaseId string `protobuf:"bytes,3,opt,name=snapshotBaseId,proto3" json:"snapshotBaseId,omitempty"` - AclData *ACLChangeACLData `protobuf:"bytes,4,opt,name=aclData,proto3" json:"aclData,omitempty"` - // the data is encoded with read key and should be read in ChangesData format - ChangesData []byte `protobuf:"bytes,5,opt,name=changesData,proto3" json:"changesData,omitempty"` - CurrentReadKeyHash uint64 `protobuf:"varint,6,opt,name=currentReadKeyHash,proto3" json:"currentReadKeyHash,omitempty"` - Timestamp int64 `protobuf:"varint,7,opt,name=timestamp,proto3" json:"timestamp,omitempty"` - Identity string `protobuf:"bytes,8,opt,name=identity,proto3" json:"identity,omitempty"` -} - -func (m *ACLChange) Reset() { *m = ACLChange{} } -func (m *ACLChange) String() string { return proto.CompactTextString(m) } -func (*ACLChange) ProtoMessage() {} -func (*ACLChange) Descriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{1} -} -func (m *ACLChange) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ACLChange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ACLChange.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *ACLChange) XXX_Merge(src proto.Message) { - xxx_messageInfo_ACLChange.Merge(m, src) -} -func (m *ACLChange) XXX_Size() int { - return m.Size() -} -func (m *ACLChange) XXX_DiscardUnknown() { - xxx_messageInfo_ACLChange.DiscardUnknown(m) -} - -var xxx_messageInfo_ACLChange proto.InternalMessageInfo - -func (m *ACLChange) GetTreeHeadIds() []string { - if m != nil { - return m.TreeHeadIds - } - return nil -} - -func (m *ACLChange) GetAclHeadIds() []string { - if m != nil { - return m.AclHeadIds - } - return nil -} - -func (m *ACLChange) GetSnapshotBaseId() string { - if m != nil { - return m.SnapshotBaseId - } - return "" -} - -func (m *ACLChange) GetAclData() *ACLChangeACLData { - if m != nil { - return m.AclData - } - return nil -} - -func (m *ACLChange) GetChangesData() []byte { - if m != nil { - return m.ChangesData - } - return nil -} - -func (m *ACLChange) GetCurrentReadKeyHash() uint64 { - if m != nil { - return m.CurrentReadKeyHash - } - return 0 -} - -func (m *ACLChange) GetTimestamp() int64 { - if m != nil { - return m.Timestamp - } - return 0 -} - -func (m *ACLChange) GetIdentity() string { - if m != nil { - return m.Identity - } - return "" -} - -type ACLChangeACLContentValue struct { - // Types that are valid to be assigned to Value: - // *ACLChangeACLContentValueValueOfUserAdd - // *ACLChangeACLContentValueValueOfUserRemove - // *ACLChangeACLContentValueValueOfUserPermissionChange - // *ACLChangeACLContentValueValueOfUserInvite - // *ACLChangeACLContentValueValueOfUserJoin - // *ACLChangeACLContentValueValueOfUserConfirm - Value IsACLChangeACLContentValueValue `protobuf_oneof:"value"` -} - -func (m *ACLChangeACLContentValue) Reset() { *m = ACLChangeACLContentValue{} } -func (m *ACLChangeACLContentValue) String() string { return proto.CompactTextString(m) } -func (*ACLChangeACLContentValue) ProtoMessage() {} -func (*ACLChangeACLContentValue) Descriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{1, 0} -} -func (m *ACLChangeACLContentValue) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ACLChangeACLContentValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ACLChangeACLContentValue.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *ACLChangeACLContentValue) XXX_Merge(src proto.Message) { - xxx_messageInfo_ACLChangeACLContentValue.Merge(m, src) -} -func (m *ACLChangeACLContentValue) XXX_Size() int { - return m.Size() -} -func (m *ACLChangeACLContentValue) XXX_DiscardUnknown() { - xxx_messageInfo_ACLChangeACLContentValue.DiscardUnknown(m) -} - -var xxx_messageInfo_ACLChangeACLContentValue proto.InternalMessageInfo - -type IsACLChangeACLContentValueValue interface { - IsACLChangeACLContentValueValue() - MarshalTo([]byte) (int, error) - Size() int -} - -type ACLChangeACLContentValueValueOfUserAdd struct { - UserAdd *ACLChangeUserAdd `protobuf:"bytes,1,opt,name=userAdd,proto3,oneof" json:"userAdd,omitempty"` -} -type ACLChangeACLContentValueValueOfUserRemove struct { - UserRemove *ACLChangeUserRemove `protobuf:"bytes,2,opt,name=userRemove,proto3,oneof" json:"userRemove,omitempty"` -} -type ACLChangeACLContentValueValueOfUserPermissionChange struct { - UserPermissionChange *ACLChangeUserPermissionChange `protobuf:"bytes,3,opt,name=userPermissionChange,proto3,oneof" json:"userPermissionChange,omitempty"` -} -type ACLChangeACLContentValueValueOfUserInvite struct { - UserInvite *ACLChangeUserInvite `protobuf:"bytes,4,opt,name=userInvite,proto3,oneof" json:"userInvite,omitempty"` -} -type ACLChangeACLContentValueValueOfUserJoin struct { - UserJoin *ACLChangeUserJoin `protobuf:"bytes,5,opt,name=userJoin,proto3,oneof" json:"userJoin,omitempty"` -} -type ACLChangeACLContentValueValueOfUserConfirm struct { - UserConfirm *ACLChangeUserConfirm `protobuf:"bytes,6,opt,name=userConfirm,proto3,oneof" json:"userConfirm,omitempty"` -} - -func (*ACLChangeACLContentValueValueOfUserAdd) IsACLChangeACLContentValueValue() {} -func (*ACLChangeACLContentValueValueOfUserRemove) IsACLChangeACLContentValueValue() {} -func (*ACLChangeACLContentValueValueOfUserPermissionChange) IsACLChangeACLContentValueValue() {} -func (*ACLChangeACLContentValueValueOfUserInvite) IsACLChangeACLContentValueValue() {} -func (*ACLChangeACLContentValueValueOfUserJoin) IsACLChangeACLContentValueValue() {} -func (*ACLChangeACLContentValueValueOfUserConfirm) IsACLChangeACLContentValueValue() {} - -func (m *ACLChangeACLContentValue) GetValue() IsACLChangeACLContentValueValue { - if m != nil { - return m.Value - } - return nil -} - -func (m *ACLChangeACLContentValue) GetUserAdd() *ACLChangeUserAdd { - if x, ok := m.GetValue().(*ACLChangeACLContentValueValueOfUserAdd); ok { - return x.UserAdd - } - return nil -} - -func (m *ACLChangeACLContentValue) GetUserRemove() *ACLChangeUserRemove { - if x, ok := m.GetValue().(*ACLChangeACLContentValueValueOfUserRemove); ok { - return x.UserRemove - } - return nil -} - -func (m *ACLChangeACLContentValue) GetUserPermissionChange() *ACLChangeUserPermissionChange { - if x, ok := m.GetValue().(*ACLChangeACLContentValueValueOfUserPermissionChange); ok { - return x.UserPermissionChange - } - return nil -} - -func (m *ACLChangeACLContentValue) GetUserInvite() *ACLChangeUserInvite { - if x, ok := m.GetValue().(*ACLChangeACLContentValueValueOfUserInvite); ok { - return x.UserInvite - } - return nil -} - -func (m *ACLChangeACLContentValue) GetUserJoin() *ACLChangeUserJoin { - if x, ok := m.GetValue().(*ACLChangeACLContentValueValueOfUserJoin); ok { - return x.UserJoin - } - return nil -} - -func (m *ACLChangeACLContentValue) GetUserConfirm() *ACLChangeUserConfirm { - if x, ok := m.GetValue().(*ACLChangeACLContentValueValueOfUserConfirm); ok { - return x.UserConfirm - } - return nil -} - -// XXX_OneofWrappers is for the internal use of the proto package. -func (*ACLChangeACLContentValue) XXX_OneofWrappers() []interface{} { - return []interface{}{ - (*ACLChangeACLContentValueValueOfUserAdd)(nil), - (*ACLChangeACLContentValueValueOfUserRemove)(nil), - (*ACLChangeACLContentValueValueOfUserPermissionChange)(nil), - (*ACLChangeACLContentValueValueOfUserInvite)(nil), - (*ACLChangeACLContentValueValueOfUserJoin)(nil), - (*ACLChangeACLContentValueValueOfUserConfirm)(nil), - } -} - -type ACLChangeACLData struct { - AclSnapshot *ACLChangeACLSnapshot `protobuf:"bytes,1,opt,name=aclSnapshot,proto3" json:"aclSnapshot,omitempty"` - AclContent []*ACLChangeACLContentValue `protobuf:"bytes,2,rep,name=aclContent,proto3" json:"aclContent,omitempty"` -} - -func (m *ACLChangeACLData) Reset() { *m = ACLChangeACLData{} } -func (m *ACLChangeACLData) String() string { return proto.CompactTextString(m) } -func (*ACLChangeACLData) ProtoMessage() {} -func (*ACLChangeACLData) Descriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{1, 1} -} -func (m *ACLChangeACLData) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ACLChangeACLData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ACLChangeACLData.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *ACLChangeACLData) XXX_Merge(src proto.Message) { - xxx_messageInfo_ACLChangeACLData.Merge(m, src) -} -func (m *ACLChangeACLData) XXX_Size() int { - return m.Size() -} -func (m *ACLChangeACLData) XXX_DiscardUnknown() { - xxx_messageInfo_ACLChangeACLData.DiscardUnknown(m) -} - -var xxx_messageInfo_ACLChangeACLData proto.InternalMessageInfo - -func (m *ACLChangeACLData) GetAclSnapshot() *ACLChangeACLSnapshot { - if m != nil { - return m.AclSnapshot - } - return nil -} - -func (m *ACLChangeACLData) GetAclContent() []*ACLChangeACLContentValue { - if m != nil { - return m.AclContent - } - return nil -} - -type ACLChangeACLSnapshot struct { - // We don't need ACLState as a separate message now, because we simplified the snapshot model - AclState *ACLChangeACLState `protobuf:"bytes,1,opt,name=aclState,proto3" json:"aclState,omitempty"` -} - -func (m *ACLChangeACLSnapshot) Reset() { *m = ACLChangeACLSnapshot{} } -func (m *ACLChangeACLSnapshot) String() string { return proto.CompactTextString(m) } -func (*ACLChangeACLSnapshot) ProtoMessage() {} -func (*ACLChangeACLSnapshot) Descriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{1, 2} -} -func (m *ACLChangeACLSnapshot) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ACLChangeACLSnapshot) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ACLChangeACLSnapshot.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *ACLChangeACLSnapshot) XXX_Merge(src proto.Message) { - xxx_messageInfo_ACLChangeACLSnapshot.Merge(m, src) -} -func (m *ACLChangeACLSnapshot) XXX_Size() int { - return m.Size() -} -func (m *ACLChangeACLSnapshot) XXX_DiscardUnknown() { - xxx_messageInfo_ACLChangeACLSnapshot.DiscardUnknown(m) -} - -var xxx_messageInfo_ACLChangeACLSnapshot proto.InternalMessageInfo - -func (m *ACLChangeACLSnapshot) GetAclState() *ACLChangeACLState { - if m != nil { - return m.AclState - } - return nil -} - -type ACLChangeACLState struct { - ReadKeyHashes []uint64 `protobuf:"varint,1,rep,packed,name=readKeyHashes,proto3" json:"readKeyHashes,omitempty"` - UserStates []*ACLChangeUserState `protobuf:"bytes,2,rep,name=userStates,proto3" json:"userStates,omitempty"` - Invites map[string]*ACLChangeUserInvite `protobuf:"bytes,3,rep,name=invites,proto3" json:"invites,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` -} - -func (m *ACLChangeACLState) Reset() { *m = ACLChangeACLState{} } -func (m *ACLChangeACLState) String() string { return proto.CompactTextString(m) } -func (*ACLChangeACLState) ProtoMessage() {} -func (*ACLChangeACLState) Descriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{1, 3} -} -func (m *ACLChangeACLState) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ACLChangeACLState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ACLChangeACLState.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *ACLChangeACLState) XXX_Merge(src proto.Message) { - xxx_messageInfo_ACLChangeACLState.Merge(m, src) -} -func (m *ACLChangeACLState) XXX_Size() int { - return m.Size() -} -func (m *ACLChangeACLState) XXX_DiscardUnknown() { - xxx_messageInfo_ACLChangeACLState.DiscardUnknown(m) -} - -var xxx_messageInfo_ACLChangeACLState proto.InternalMessageInfo - -func (m *ACLChangeACLState) GetReadKeyHashes() []uint64 { - if m != nil { - return m.ReadKeyHashes - } - return nil -} - -func (m *ACLChangeACLState) GetUserStates() []*ACLChangeUserState { - if m != nil { - return m.UserStates - } - return nil -} - -func (m *ACLChangeACLState) GetInvites() map[string]*ACLChangeUserInvite { - if m != nil { - return m.Invites - } - return nil -} - -type ACLChangeUserState struct { - Identity string `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` - EncryptionKey []byte `protobuf:"bytes,2,opt,name=encryptionKey,proto3" json:"encryptionKey,omitempty"` - EncryptedReadKeys [][]byte `protobuf:"bytes,3,rep,name=encryptedReadKeys,proto3" json:"encryptedReadKeys,omitempty"` - Permissions ACLChangeUserPermissions `protobuf:"varint,4,opt,name=permissions,proto3,enum=acl.ACLChangeUserPermissions" json:"permissions,omitempty"` - IsConfirmed bool `protobuf:"varint,5,opt,name=IsConfirmed,proto3" json:"IsConfirmed,omitempty"` -} - -func (m *ACLChangeUserState) Reset() { *m = ACLChangeUserState{} } -func (m *ACLChangeUserState) String() string { return proto.CompactTextString(m) } -func (*ACLChangeUserState) ProtoMessage() {} -func (*ACLChangeUserState) Descriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{1, 4} -} -func (m *ACLChangeUserState) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ACLChangeUserState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ACLChangeUserState.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *ACLChangeUserState) XXX_Merge(src proto.Message) { - xxx_messageInfo_ACLChangeUserState.Merge(m, src) -} -func (m *ACLChangeUserState) XXX_Size() int { - return m.Size() -} -func (m *ACLChangeUserState) XXX_DiscardUnknown() { - xxx_messageInfo_ACLChangeUserState.DiscardUnknown(m) -} - -var xxx_messageInfo_ACLChangeUserState proto.InternalMessageInfo - -func (m *ACLChangeUserState) GetIdentity() string { - if m != nil { - return m.Identity - } - return "" -} - -func (m *ACLChangeUserState) GetEncryptionKey() []byte { - if m != nil { - return m.EncryptionKey - } - return nil -} - -func (m *ACLChangeUserState) GetEncryptedReadKeys() [][]byte { - if m != nil { - return m.EncryptedReadKeys - } - return nil -} - -func (m *ACLChangeUserState) GetPermissions() ACLChangeUserPermissions { - if m != nil { - return m.Permissions - } - return ACLChange_Admin -} - -func (m *ACLChangeUserState) GetIsConfirmed() bool { - if m != nil { - return m.IsConfirmed - } - return false -} - -// we already know identity and encryptionKey -type ACLChangeUserAdd struct { - Identity string `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` - EncryptionKey []byte `protobuf:"bytes,2,opt,name=encryptionKey,proto3" json:"encryptionKey,omitempty"` - EncryptedReadKeys [][]byte `protobuf:"bytes,3,rep,name=encryptedReadKeys,proto3" json:"encryptedReadKeys,omitempty"` - Permissions ACLChangeUserPermissions `protobuf:"varint,4,opt,name=permissions,proto3,enum=acl.ACLChangeUserPermissions" json:"permissions,omitempty"` -} - -func (m *ACLChangeUserAdd) Reset() { *m = ACLChangeUserAdd{} } -func (m *ACLChangeUserAdd) String() string { return proto.CompactTextString(m) } -func (*ACLChangeUserAdd) ProtoMessage() {} -func (*ACLChangeUserAdd) Descriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{1, 5} -} -func (m *ACLChangeUserAdd) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ACLChangeUserAdd) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ACLChangeUserAdd.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *ACLChangeUserAdd) XXX_Merge(src proto.Message) { - xxx_messageInfo_ACLChangeUserAdd.Merge(m, src) -} -func (m *ACLChangeUserAdd) XXX_Size() int { - return m.Size() -} -func (m *ACLChangeUserAdd) XXX_DiscardUnknown() { - xxx_messageInfo_ACLChangeUserAdd.DiscardUnknown(m) -} - -var xxx_messageInfo_ACLChangeUserAdd proto.InternalMessageInfo - -func (m *ACLChangeUserAdd) GetIdentity() string { - if m != nil { - return m.Identity - } - return "" -} - -func (m *ACLChangeUserAdd) GetEncryptionKey() []byte { - if m != nil { - return m.EncryptionKey - } - return nil -} - -func (m *ACLChangeUserAdd) GetEncryptedReadKeys() [][]byte { - if m != nil { - return m.EncryptedReadKeys - } - return nil -} - -func (m *ACLChangeUserAdd) GetPermissions() ACLChangeUserPermissions { - if m != nil { - return m.Permissions - } - return ACLChange_Admin -} - -// TODO: this is not used as of now -type ACLChangeUserConfirm struct { - Identity string `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` - UserAddId string `protobuf:"bytes,2,opt,name=userAddId,proto3" json:"userAddId,omitempty"` -} - -func (m *ACLChangeUserConfirm) Reset() { *m = ACLChangeUserConfirm{} } -func (m *ACLChangeUserConfirm) String() string { return proto.CompactTextString(m) } -func (*ACLChangeUserConfirm) ProtoMessage() {} -func (*ACLChangeUserConfirm) Descriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{1, 6} -} -func (m *ACLChangeUserConfirm) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ACLChangeUserConfirm) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ACLChangeUserConfirm.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *ACLChangeUserConfirm) XXX_Merge(src proto.Message) { - xxx_messageInfo_ACLChangeUserConfirm.Merge(m, src) -} -func (m *ACLChangeUserConfirm) XXX_Size() int { - return m.Size() -} -func (m *ACLChangeUserConfirm) XXX_DiscardUnknown() { - xxx_messageInfo_ACLChangeUserConfirm.DiscardUnknown(m) -} - -var xxx_messageInfo_ACLChangeUserConfirm proto.InternalMessageInfo - -func (m *ACLChangeUserConfirm) GetIdentity() string { - if m != nil { - return m.Identity - } - return "" -} - -func (m *ACLChangeUserConfirm) GetUserAddId() string { - if m != nil { - return m.UserAddId - } - return "" -} - -type ACLChangeUserInvite struct { - AcceptPublicKey []byte `protobuf:"bytes,1,opt,name=acceptPublicKey,proto3" json:"acceptPublicKey,omitempty"` - EncryptPublicKey []byte `protobuf:"bytes,2,opt,name=encryptPublicKey,proto3" json:"encryptPublicKey,omitempty"` - EncryptedReadKeys [][]byte `protobuf:"bytes,3,rep,name=encryptedReadKeys,proto3" json:"encryptedReadKeys,omitempty"` - Permissions ACLChangeUserPermissions `protobuf:"varint,4,opt,name=permissions,proto3,enum=acl.ACLChangeUserPermissions" json:"permissions,omitempty"` - InviteId string `protobuf:"bytes,5,opt,name=InviteId,proto3" json:"InviteId,omitempty"` -} - -func (m *ACLChangeUserInvite) Reset() { *m = ACLChangeUserInvite{} } -func (m *ACLChangeUserInvite) String() string { return proto.CompactTextString(m) } -func (*ACLChangeUserInvite) ProtoMessage() {} -func (*ACLChangeUserInvite) Descriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{1, 7} -} -func (m *ACLChangeUserInvite) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ACLChangeUserInvite) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ACLChangeUserInvite.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *ACLChangeUserInvite) XXX_Merge(src proto.Message) { - xxx_messageInfo_ACLChangeUserInvite.Merge(m, src) -} -func (m *ACLChangeUserInvite) XXX_Size() int { - return m.Size() -} -func (m *ACLChangeUserInvite) XXX_DiscardUnknown() { - xxx_messageInfo_ACLChangeUserInvite.DiscardUnknown(m) -} - -var xxx_messageInfo_ACLChangeUserInvite proto.InternalMessageInfo - -func (m *ACLChangeUserInvite) GetAcceptPublicKey() []byte { - if m != nil { - return m.AcceptPublicKey - } - return nil -} - -func (m *ACLChangeUserInvite) GetEncryptPublicKey() []byte { - if m != nil { - return m.EncryptPublicKey - } - return nil -} - -func (m *ACLChangeUserInvite) GetEncryptedReadKeys() [][]byte { - if m != nil { - return m.EncryptedReadKeys - } - return nil -} - -func (m *ACLChangeUserInvite) GetPermissions() ACLChangeUserPermissions { - if m != nil { - return m.Permissions - } - return ACLChange_Admin -} - -func (m *ACLChangeUserInvite) GetInviteId() string { - if m != nil { - return m.InviteId - } - return "" -} - -type ACLChangeUserJoin struct { - Identity string `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` - EncryptionKey []byte `protobuf:"bytes,2,opt,name=encryptionKey,proto3" json:"encryptionKey,omitempty"` - AcceptSignature []byte `protobuf:"bytes,3,opt,name=acceptSignature,proto3" json:"acceptSignature,omitempty"` - UserInviteId string `protobuf:"bytes,4,opt,name=userInviteId,proto3" json:"userInviteId,omitempty"` - EncryptedReadKeys [][]byte `protobuf:"bytes,5,rep,name=encryptedReadKeys,proto3" json:"encryptedReadKeys,omitempty"` -} - -func (m *ACLChangeUserJoin) Reset() { *m = ACLChangeUserJoin{} } -func (m *ACLChangeUserJoin) String() string { return proto.CompactTextString(m) } -func (*ACLChangeUserJoin) ProtoMessage() {} -func (*ACLChangeUserJoin) Descriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{1, 8} -} -func (m *ACLChangeUserJoin) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ACLChangeUserJoin) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ACLChangeUserJoin.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *ACLChangeUserJoin) XXX_Merge(src proto.Message) { - xxx_messageInfo_ACLChangeUserJoin.Merge(m, src) -} -func (m *ACLChangeUserJoin) XXX_Size() int { - return m.Size() -} -func (m *ACLChangeUserJoin) XXX_DiscardUnknown() { - xxx_messageInfo_ACLChangeUserJoin.DiscardUnknown(m) -} - -var xxx_messageInfo_ACLChangeUserJoin proto.InternalMessageInfo - -func (m *ACLChangeUserJoin) GetIdentity() string { - if m != nil { - return m.Identity - } - return "" -} - -func (m *ACLChangeUserJoin) GetEncryptionKey() []byte { - if m != nil { - return m.EncryptionKey - } - return nil -} - -func (m *ACLChangeUserJoin) GetAcceptSignature() []byte { - if m != nil { - return m.AcceptSignature - } - return nil -} - -func (m *ACLChangeUserJoin) GetUserInviteId() string { - if m != nil { - return m.UserInviteId - } - return "" -} - -func (m *ACLChangeUserJoin) GetEncryptedReadKeys() [][]byte { - if m != nil { - return m.EncryptedReadKeys - } - return nil -} - -type ACLChangeUserRemove struct { - Identity string `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` - ReadKeyReplaces []*ACLChangeReadKeyReplace `protobuf:"bytes,3,rep,name=readKeyReplaces,proto3" json:"readKeyReplaces,omitempty"` -} - -func (m *ACLChangeUserRemove) Reset() { *m = ACLChangeUserRemove{} } -func (m *ACLChangeUserRemove) String() string { return proto.CompactTextString(m) } -func (*ACLChangeUserRemove) ProtoMessage() {} -func (*ACLChangeUserRemove) Descriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{1, 9} -} -func (m *ACLChangeUserRemove) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ACLChangeUserRemove) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ACLChangeUserRemove.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *ACLChangeUserRemove) XXX_Merge(src proto.Message) { - xxx_messageInfo_ACLChangeUserRemove.Merge(m, src) -} -func (m *ACLChangeUserRemove) XXX_Size() int { - return m.Size() -} -func (m *ACLChangeUserRemove) XXX_DiscardUnknown() { - xxx_messageInfo_ACLChangeUserRemove.DiscardUnknown(m) -} - -var xxx_messageInfo_ACLChangeUserRemove proto.InternalMessageInfo - -func (m *ACLChangeUserRemove) GetIdentity() string { - if m != nil { - return m.Identity - } - return "" -} - -func (m *ACLChangeUserRemove) GetReadKeyReplaces() []*ACLChangeReadKeyReplace { - if m != nil { - return m.ReadKeyReplaces - } - return nil -} - -type ACLChangeReadKeyReplace struct { - Identity string `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` - EncryptionKey []byte `protobuf:"bytes,2,opt,name=encryptionKey,proto3" json:"encryptionKey,omitempty"` - EncryptedReadKey []byte `protobuf:"bytes,3,opt,name=encryptedReadKey,proto3" json:"encryptedReadKey,omitempty"` -} - -func (m *ACLChangeReadKeyReplace) Reset() { *m = ACLChangeReadKeyReplace{} } -func (m *ACLChangeReadKeyReplace) String() string { return proto.CompactTextString(m) } -func (*ACLChangeReadKeyReplace) ProtoMessage() {} -func (*ACLChangeReadKeyReplace) Descriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{1, 10} -} -func (m *ACLChangeReadKeyReplace) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ACLChangeReadKeyReplace) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ACLChangeReadKeyReplace.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *ACLChangeReadKeyReplace) XXX_Merge(src proto.Message) { - xxx_messageInfo_ACLChangeReadKeyReplace.Merge(m, src) -} -func (m *ACLChangeReadKeyReplace) XXX_Size() int { - return m.Size() -} -func (m *ACLChangeReadKeyReplace) XXX_DiscardUnknown() { - xxx_messageInfo_ACLChangeReadKeyReplace.DiscardUnknown(m) -} - -var xxx_messageInfo_ACLChangeReadKeyReplace proto.InternalMessageInfo - -func (m *ACLChangeReadKeyReplace) GetIdentity() string { - if m != nil { - return m.Identity - } - return "" -} - -func (m *ACLChangeReadKeyReplace) GetEncryptionKey() []byte { - if m != nil { - return m.EncryptionKey - } - return nil -} - -func (m *ACLChangeReadKeyReplace) GetEncryptedReadKey() []byte { - if m != nil { - return m.EncryptedReadKey - } - return nil -} - -type ACLChangeUserPermissionChange struct { - Identity string `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` - Permissions ACLChangeUserPermissions `protobuf:"varint,2,opt,name=permissions,proto3,enum=acl.ACLChangeUserPermissions" json:"permissions,omitempty"` -} - -func (m *ACLChangeUserPermissionChange) Reset() { *m = ACLChangeUserPermissionChange{} } -func (m *ACLChangeUserPermissionChange) String() string { return proto.CompactTextString(m) } -func (*ACLChangeUserPermissionChange) ProtoMessage() {} -func (*ACLChangeUserPermissionChange) Descriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{1, 11} -} -func (m *ACLChangeUserPermissionChange) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ACLChangeUserPermissionChange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ACLChangeUserPermissionChange.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *ACLChangeUserPermissionChange) XXX_Merge(src proto.Message) { - xxx_messageInfo_ACLChangeUserPermissionChange.Merge(m, src) -} -func (m *ACLChangeUserPermissionChange) XXX_Size() int { - return m.Size() -} -func (m *ACLChangeUserPermissionChange) XXX_DiscardUnknown() { - xxx_messageInfo_ACLChangeUserPermissionChange.DiscardUnknown(m) -} - -var xxx_messageInfo_ACLChangeUserPermissionChange proto.InternalMessageInfo - -func (m *ACLChangeUserPermissionChange) GetIdentity() string { - if m != nil { - return m.Identity - } - return "" -} - -func (m *ACLChangeUserPermissionChange) GetPermissions() ACLChangeUserPermissions { - if m != nil { - return m.Permissions - } - return ACLChange_Admin -} - -func init() { - proto.RegisterEnum("acl.ACLChangeUserPermissions", ACLChangeUserPermissions_name, ACLChangeUserPermissions_value) - proto.RegisterType((*RawChange)(nil), "acl.RawChange") - proto.RegisterType((*ACLChange)(nil), "acl.ACLChange") - proto.RegisterType((*ACLChangeACLContentValue)(nil), "acl.ACLChange.ACLContentValue") - proto.RegisterType((*ACLChangeACLData)(nil), "acl.ACLChange.ACLData") - proto.RegisterType((*ACLChangeACLSnapshot)(nil), "acl.ACLChange.ACLSnapshot") - proto.RegisterType((*ACLChangeACLState)(nil), "acl.ACLChange.ACLState") - proto.RegisterMapType((map[string]*ACLChangeUserInvite)(nil), "acl.ACLChange.ACLState.InvitesEntry") - proto.RegisterType((*ACLChangeUserState)(nil), "acl.ACLChange.UserState") - proto.RegisterType((*ACLChangeUserAdd)(nil), "acl.ACLChange.UserAdd") - proto.RegisterType((*ACLChangeUserConfirm)(nil), "acl.ACLChange.UserConfirm") - proto.RegisterType((*ACLChangeUserInvite)(nil), "acl.ACLChange.UserInvite") - proto.RegisterType((*ACLChangeUserJoin)(nil), "acl.ACLChange.UserJoin") - proto.RegisterType((*ACLChangeUserRemove)(nil), "acl.ACLChange.UserRemove") - proto.RegisterType((*ACLChangeReadKeyReplace)(nil), "acl.ACLChange.ReadKeyReplace") - proto.RegisterType((*ACLChangeUserPermissionChange)(nil), "acl.ACLChange.UserPermissionChange") -} - -func init() { - proto.RegisterFile("pkg/acl/aclchanges/aclpb/protos/aclchanges.proto", fileDescriptor_37a022c841a51877) -} - -var fileDescriptor_37a022c841a51877 = []byte{ - // 948 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0x4f, 0x6f, 0xe3, 0x44, - 0x14, 0xf7, 0xc4, 0x4d, 0x1d, 0x3f, 0x87, 0x36, 0x0c, 0x2b, 0xd6, 0x58, 0x4b, 0x88, 0xca, 0x0a, - 0x45, 0x08, 0xa5, 0xab, 0xac, 0x90, 0x56, 0x80, 0x2a, 0xda, 0x82, 0x36, 0xa1, 0x1c, 0x56, 0x53, - 0x2d, 0x08, 0x6e, 0x53, 0x7b, 0x68, 0xad, 0x75, 0x6c, 0xe3, 0x99, 0x14, 0xe5, 0x82, 0xc4, 0x89, - 0x2b, 0x67, 0xbe, 0x0a, 0x5f, 0x60, 0x8f, 0x7b, 0xe4, 0x06, 0x6a, 0xef, 0x5c, 0xf8, 0x02, 0x68, - 0xfe, 0xd8, 0x71, 0x12, 0x6f, 0x24, 0xa4, 0x15, 0x12, 0x87, 0x4a, 0x33, 0xbf, 0xf7, 0x7b, 0xd3, - 0xf7, 0xde, 0xef, 0xbd, 0x17, 0xc3, 0x83, 0xfc, 0xd9, 0xe5, 0x21, 0x0d, 0x13, 0xf9, 0x17, 0x5e, - 0xd1, 0xf4, 0x92, 0x71, 0x79, 0xcc, 0x2f, 0x0e, 0xf3, 0x22, 0x13, 0x19, 0xaf, 0xe1, 0x23, 0x85, - 0x60, 0x9b, 0x86, 0xc9, 0xc1, 0x39, 0xb8, 0x84, 0xfe, 0x70, 0xaa, 0x0c, 0xd8, 0x07, 0x27, 0xa7, - 0x8b, 0x24, 0xa3, 0x91, 0x8f, 0x06, 0x68, 0xd8, 0x25, 0xe5, 0x15, 0xdf, 0x03, 0x97, 0xc7, 0x97, - 0x29, 0x15, 0xf3, 0x82, 0xf9, 0x2d, 0x65, 0x5b, 0x02, 0x78, 0x0f, 0x5a, 0x71, 0xe4, 0xdb, 0x03, - 0x34, 0x74, 0x49, 0x2b, 0x8e, 0x0e, 0xfe, 0x7e, 0x03, 0xdc, 0xe3, 0xd3, 0x2f, 0xcd, 0xab, 0x03, - 0xf0, 0x44, 0xc1, 0xd8, 0x84, 0xd1, 0x68, 0x1a, 0x71, 0x1f, 0x0d, 0xec, 0xa1, 0x4b, 0xea, 0x10, - 0xee, 0x03, 0xd0, 0x30, 0x29, 0x09, 0x2d, 0x45, 0xa8, 0x21, 0xf8, 0x3d, 0xd8, 0xe3, 0x29, 0xcd, - 0xf9, 0x55, 0x26, 0x4e, 0x28, 0x67, 0xd3, 0xf2, 0x7f, 0xad, 0xa1, 0xf8, 0x01, 0x38, 0x34, 0x4c, - 0x3e, 0xa3, 0x82, 0xfa, 0x3b, 0x03, 0x34, 0xf4, 0xc6, 0x6f, 0x8e, 0x68, 0x98, 0x8c, 0xaa, 0x50, - 0xe4, 0x49, 0x5a, 0x49, 0x49, 0x93, 0xb1, 0x99, 0xa2, 0x28, 0xaf, 0xb6, 0xca, 0xac, 0x0e, 0xe1, - 0x11, 0xe0, 0x70, 0x5e, 0x14, 0x2c, 0x15, 0x84, 0xd1, 0xe8, 0x8c, 0x2d, 0x26, 0x94, 0x5f, 0xf9, - 0xbb, 0x03, 0x34, 0xdc, 0x21, 0x0d, 0x16, 0x59, 0x29, 0x11, 0xcf, 0x18, 0x17, 0x74, 0x96, 0xfb, - 0xce, 0x00, 0x0d, 0x6d, 0xb2, 0x04, 0x70, 0x00, 0x9d, 0x38, 0x62, 0xa9, 0x88, 0xc5, 0xc2, 0xef, - 0xa8, 0x1c, 0xaa, 0x7b, 0xf0, 0xab, 0x0d, 0xfb, 0x32, 0xd4, 0x2c, 0x15, 0x2c, 0x15, 0x5f, 0xd1, - 0x64, 0xce, 0xf0, 0x18, 0x9c, 0x39, 0x67, 0xc5, 0x71, 0xa4, 0x15, 0xd9, 0xcc, 0xe8, 0xa9, 0xb6, - 0x4e, 0x2c, 0x52, 0x12, 0xf1, 0xc7, 0x00, 0xf2, 0x48, 0xd8, 0x2c, 0xbb, 0xd6, 0x62, 0x79, 0xe3, - 0xb7, 0x1a, 0xdc, 0x34, 0x61, 0x62, 0x91, 0x1a, 0x1d, 0x7f, 0x03, 0x77, 0xe4, 0xed, 0x09, 0x2b, - 0x66, 0x31, 0xe7, 0x71, 0x96, 0x6a, 0x07, 0x55, 0x70, 0x6f, 0xfc, 0x6e, 0xc3, 0x33, 0xeb, 0xd4, - 0x89, 0x45, 0x1a, 0x9f, 0x28, 0xe3, 0x9a, 0xa6, 0xd7, 0xb1, 0x60, 0x46, 0xa0, 0xa6, 0xb8, 0x34, - 0xa1, 0x8c, 0x4b, 0xdf, 0xf0, 0x87, 0xd0, 0x91, 0xb7, 0x2f, 0xb2, 0x38, 0x55, 0x2a, 0x79, 0xe3, - 0xbb, 0x0d, 0xae, 0xd2, 0x3c, 0xb1, 0x48, 0x45, 0xc5, 0x47, 0xe0, 0xc9, 0xf3, 0x69, 0x96, 0x7e, - 0x17, 0x17, 0x33, 0x25, 0x9b, 0x37, 0x0e, 0x1a, 0x3c, 0x0d, 0x63, 0x62, 0x91, 0xba, 0xc3, 0x89, - 0x03, 0xed, 0x6b, 0x29, 0x44, 0xf0, 0x33, 0x02, 0xc7, 0x74, 0x0f, 0xfe, 0x04, 0x3c, 0x1a, 0x26, - 0xe7, 0xa6, 0xf7, 0x8c, 0x30, 0xc1, 0x66, 0xab, 0x95, 0x0c, 0x52, 0xa7, 0xe3, 0x23, 0xd5, 0xec, - 0x46, 0x65, 0xd5, 0xec, 0xde, 0xb8, 0xbf, 0xe9, 0x5c, 0x6f, 0x03, 0x52, 0xf3, 0x08, 0x4e, 0xc0, - 0xab, 0xbd, 0x8d, 0x1f, 0x42, 0x47, 0xbe, 0x2e, 0xa8, 0x60, 0x26, 0x92, 0xbb, 0x0d, 0x91, 0x48, - 0x33, 0xa9, 0x88, 0xc1, 0x4f, 0x2d, 0xe8, 0x94, 0x30, 0xbe, 0x0f, 0xaf, 0x15, 0xcb, 0x06, 0x66, - 0x7a, 0x42, 0x77, 0xc8, 0x2a, 0x88, 0x1f, 0x69, 0xf5, 0x94, 0x0b, 0x37, 0x61, 0xfb, 0x0d, 0x85, - 0xd4, 0xff, 0xaa, 0xc6, 0xc5, 0x47, 0xe0, 0xc4, 0x4a, 0x44, 0xee, 0xdb, 0xca, 0xed, 0xfe, 0x4b, - 0x02, 0x1c, 0x69, 0xad, 0xf9, 0xe7, 0xa9, 0x28, 0x16, 0xa4, 0x74, 0x0a, 0x9e, 0x42, 0xb7, 0x6e, - 0xc0, 0x3d, 0xb0, 0x9f, 0xb1, 0x85, 0x4a, 0xd6, 0x25, 0xf2, 0x88, 0x0f, 0x8d, 0x4a, 0x5b, 0x9a, - 0x5d, 0xbf, 0x40, 0x34, 0xef, 0xa3, 0xd6, 0x23, 0x14, 0xfc, 0x81, 0xc0, 0xad, 0x02, 0x5e, 0x19, - 0x4c, 0xb4, 0x3a, 0x98, 0xb2, 0x40, 0x2c, 0x0d, 0x8b, 0x45, 0x2e, 0xe2, 0x2c, 0x3d, 0x63, 0x0b, - 0xb3, 0x00, 0x57, 0x41, 0xfc, 0x01, 0xbc, 0x6e, 0x00, 0x16, 0x99, 0x85, 0xa0, 0x13, 0xee, 0x92, - 0x4d, 0x03, 0xfe, 0x14, 0xbc, 0xbc, 0x1a, 0x10, 0xae, 0xa6, 0x61, 0x6f, 0xa3, 0x0d, 0x56, 0xc7, - 0x8b, 0x93, 0xba, 0x8b, 0x5c, 0x5d, 0x53, 0x6e, 0xfa, 0x94, 0x45, 0x6a, 0x28, 0x3a, 0xa4, 0x0e, - 0x05, 0xbf, 0x21, 0x70, 0xcc, 0x7e, 0xf8, 0xff, 0xe5, 0x17, 0x3c, 0x06, 0xaf, 0x36, 0x98, 0x5b, - 0x13, 0xb8, 0x07, 0xae, 0x59, 0x7e, 0xd3, 0x48, 0x05, 0xef, 0x92, 0x25, 0x10, 0xfc, 0x85, 0x00, - 0x96, 0x2d, 0x80, 0x87, 0xb0, 0x4f, 0xc3, 0x90, 0xe5, 0xe2, 0xc9, 0xfc, 0x22, 0x89, 0xc3, 0x33, - 0xd3, 0x4a, 0x5d, 0xb2, 0x0e, 0xe3, 0xf7, 0xa1, 0x67, 0x12, 0x5b, 0x52, 0x75, 0x69, 0x36, 0xf0, - 0xff, 0x5c, 0xfd, 0x00, 0x3a, 0x3a, 0x9f, 0xa9, 0x96, 0xde, 0x25, 0xd5, 0x3d, 0x78, 0x8e, 0xa0, - 0x53, 0x6e, 0xc3, 0x57, 0x20, 0x7c, 0x55, 0xb0, 0xf3, 0xea, 0x0b, 0xc0, 0xae, 0x17, 0xac, 0x82, - 0xf1, 0x01, 0x74, 0x97, 0x2b, 0x7b, 0x1a, 0xa9, 0xbc, 0x5c, 0xb2, 0x82, 0x35, 0x17, 0xaa, 0xfd, - 0x92, 0x42, 0x05, 0xdf, 0x6b, 0xe9, 0xcc, 0x8f, 0xd3, 0xb6, 0x5c, 0x1e, 0xc3, 0xbe, 0x59, 0x58, - 0x84, 0xe5, 0x09, 0x0d, 0xab, 0x6d, 0xf3, 0xf6, 0x5a, 0x59, 0xc9, 0x0a, 0x8b, 0xac, 0x7b, 0x05, - 0x3f, 0xc2, 0xde, 0x2a, 0xe5, 0x15, 0x94, 0x70, 0xd9, 0x49, 0x55, 0x6e, 0xa6, 0x86, 0x1b, 0x78, - 0x20, 0xe0, 0x4e, 0xd3, 0xcf, 0xea, 0xd6, 0x28, 0xd6, 0xfa, 0xa9, 0xf5, 0xaf, 0xfb, 0xe9, 0xe0, - 0x18, 0xf6, 0xd7, 0xec, 0xd8, 0x85, 0xf6, 0x71, 0x34, 0x8b, 0xd3, 0x9e, 0x85, 0x01, 0x76, 0xbf, - 0x2e, 0x62, 0xc1, 0x8a, 0x1e, 0x92, 0x67, 0x19, 0x2a, 0x2b, 0x7a, 0x2d, 0xec, 0x81, 0xa3, 0xa5, - 0x89, 0x7a, 0xf6, 0xc9, 0x3b, 0xcf, 0x6f, 0xfa, 0xe8, 0xc5, 0x4d, 0x1f, 0xfd, 0x79, 0xd3, 0x47, - 0xbf, 0xdc, 0xf6, 0xad, 0x17, 0xb7, 0x7d, 0xeb, 0xf7, 0xdb, 0xbe, 0xf5, 0x6d, 0x5b, 0x7d, 0x88, - 0x5e, 0xec, 0xaa, 0xef, 0xce, 0x87, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x2a, 0xe8, 0x23, 0x71, - 0xab, 0x0a, 0x00, 0x00, -} - -func (m *RawChange) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *RawChange) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *RawChange) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Id) > 0 { - i -= len(m.Id) - copy(dAtA[i:], m.Id) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.Id))) - i-- - dAtA[i] = 0x1a - } - if len(m.Signature) > 0 { - i -= len(m.Signature) - copy(dAtA[i:], m.Signature) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.Signature))) - i-- - dAtA[i] = 0x12 - } - if len(m.Payload) > 0 { - i -= len(m.Payload) - copy(dAtA[i:], m.Payload) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.Payload))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *ACLChange) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ACLChange) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ACLChange) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Identity) > 0 { - i -= len(m.Identity) - copy(dAtA[i:], m.Identity) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.Identity))) - i-- - dAtA[i] = 0x42 - } - if m.Timestamp != 0 { - i = encodeVarintAclchanges(dAtA, i, uint64(m.Timestamp)) - i-- - dAtA[i] = 0x38 - } - if m.CurrentReadKeyHash != 0 { - i = encodeVarintAclchanges(dAtA, i, uint64(m.CurrentReadKeyHash)) - i-- - dAtA[i] = 0x30 - } - if len(m.ChangesData) > 0 { - i -= len(m.ChangesData) - copy(dAtA[i:], m.ChangesData) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.ChangesData))) - i-- - dAtA[i] = 0x2a - } - if m.AclData != nil { - { - size, err := m.AclData.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintAclchanges(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x22 - } - if len(m.SnapshotBaseId) > 0 { - i -= len(m.SnapshotBaseId) - copy(dAtA[i:], m.SnapshotBaseId) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.SnapshotBaseId))) - i-- - dAtA[i] = 0x1a - } - if len(m.AclHeadIds) > 0 { - for iNdEx := len(m.AclHeadIds) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.AclHeadIds[iNdEx]) - copy(dAtA[i:], m.AclHeadIds[iNdEx]) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.AclHeadIds[iNdEx]))) - i-- - dAtA[i] = 0x12 - } - } - if len(m.TreeHeadIds) > 0 { - for iNdEx := len(m.TreeHeadIds) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.TreeHeadIds[iNdEx]) - copy(dAtA[i:], m.TreeHeadIds[iNdEx]) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.TreeHeadIds[iNdEx]))) - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - -func (m *ACLChangeACLContentValue) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ACLChangeACLContentValue) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ACLChangeACLContentValue) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Value != nil { - { - size := m.Value.Size() - i -= size - if _, err := m.Value.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - } - } - return len(dAtA) - i, nil -} - -func (m *ACLChangeACLContentValueValueOfUserAdd) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ACLChangeACLContentValueValueOfUserAdd) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.UserAdd != nil { - { - size, err := m.UserAdd.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintAclchanges(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} -func (m *ACLChangeACLContentValueValueOfUserRemove) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ACLChangeACLContentValueValueOfUserRemove) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.UserRemove != nil { - { - size, err := m.UserRemove.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintAclchanges(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - return len(dAtA) - i, nil -} -func (m *ACLChangeACLContentValueValueOfUserPermissionChange) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ACLChangeACLContentValueValueOfUserPermissionChange) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.UserPermissionChange != nil { - { - size, err := m.UserPermissionChange.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintAclchanges(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - return len(dAtA) - i, nil -} -func (m *ACLChangeACLContentValueValueOfUserInvite) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ACLChangeACLContentValueValueOfUserInvite) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.UserInvite != nil { - { - size, err := m.UserInvite.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintAclchanges(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x22 - } - return len(dAtA) - i, nil -} -func (m *ACLChangeACLContentValueValueOfUserJoin) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ACLChangeACLContentValueValueOfUserJoin) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.UserJoin != nil { - { - size, err := m.UserJoin.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintAclchanges(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x2a - } - return len(dAtA) - i, nil -} -func (m *ACLChangeACLContentValueValueOfUserConfirm) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ACLChangeACLContentValueValueOfUserConfirm) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.UserConfirm != nil { - { - size, err := m.UserConfirm.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintAclchanges(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x32 - } - return len(dAtA) - i, nil -} -func (m *ACLChangeACLData) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ACLChangeACLData) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ACLChangeACLData) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.AclContent) > 0 { - for iNdEx := len(m.AclContent) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.AclContent[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintAclchanges(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - if m.AclSnapshot != nil { - { - size, err := m.AclSnapshot.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintAclchanges(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *ACLChangeACLSnapshot) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ACLChangeACLSnapshot) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ACLChangeACLSnapshot) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.AclState != nil { - { - size, err := m.AclState.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintAclchanges(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *ACLChangeACLState) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ACLChangeACLState) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ACLChangeACLState) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Invites) > 0 { - for k := range m.Invites { - v := m.Invites[k] - baseI := i - if v != nil { - { - size, err := v.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintAclchanges(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - i -= len(k) - copy(dAtA[i:], k) - i = encodeVarintAclchanges(dAtA, i, uint64(len(k))) - i-- - dAtA[i] = 0xa - i = encodeVarintAclchanges(dAtA, i, uint64(baseI-i)) - i-- - dAtA[i] = 0x1a - } - } - if len(m.UserStates) > 0 { - for iNdEx := len(m.UserStates) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.UserStates[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintAclchanges(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - if len(m.ReadKeyHashes) > 0 { - dAtA12 := make([]byte, len(m.ReadKeyHashes)*10) - var j11 int - for _, num := range m.ReadKeyHashes { - for num >= 1<<7 { - dAtA12[j11] = uint8(uint64(num)&0x7f | 0x80) - num >>= 7 - j11++ - } - dAtA12[j11] = uint8(num) - j11++ - } - i -= j11 - copy(dAtA[i:], dAtA12[:j11]) - i = encodeVarintAclchanges(dAtA, i, uint64(j11)) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *ACLChangeUserState) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ACLChangeUserState) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ACLChangeUserState) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.IsConfirmed { - i-- - if m.IsConfirmed { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x28 - } - if m.Permissions != 0 { - i = encodeVarintAclchanges(dAtA, i, uint64(m.Permissions)) - i-- - dAtA[i] = 0x20 - } - if len(m.EncryptedReadKeys) > 0 { - for iNdEx := len(m.EncryptedReadKeys) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.EncryptedReadKeys[iNdEx]) - copy(dAtA[i:], m.EncryptedReadKeys[iNdEx]) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.EncryptedReadKeys[iNdEx]))) - i-- - dAtA[i] = 0x1a - } - } - if len(m.EncryptionKey) > 0 { - i -= len(m.EncryptionKey) - copy(dAtA[i:], m.EncryptionKey) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.EncryptionKey))) - i-- - dAtA[i] = 0x12 - } - if len(m.Identity) > 0 { - i -= len(m.Identity) - copy(dAtA[i:], m.Identity) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.Identity))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *ACLChangeUserAdd) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ACLChangeUserAdd) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ACLChangeUserAdd) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Permissions != 0 { - i = encodeVarintAclchanges(dAtA, i, uint64(m.Permissions)) - i-- - dAtA[i] = 0x20 - } - if len(m.EncryptedReadKeys) > 0 { - for iNdEx := len(m.EncryptedReadKeys) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.EncryptedReadKeys[iNdEx]) - copy(dAtA[i:], m.EncryptedReadKeys[iNdEx]) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.EncryptedReadKeys[iNdEx]))) - i-- - dAtA[i] = 0x1a - } - } - if len(m.EncryptionKey) > 0 { - i -= len(m.EncryptionKey) - copy(dAtA[i:], m.EncryptionKey) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.EncryptionKey))) - i-- - dAtA[i] = 0x12 - } - if len(m.Identity) > 0 { - i -= len(m.Identity) - copy(dAtA[i:], m.Identity) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.Identity))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *ACLChangeUserConfirm) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ACLChangeUserConfirm) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ACLChangeUserConfirm) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.UserAddId) > 0 { - i -= len(m.UserAddId) - copy(dAtA[i:], m.UserAddId) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.UserAddId))) - i-- - dAtA[i] = 0x12 - } - if len(m.Identity) > 0 { - i -= len(m.Identity) - copy(dAtA[i:], m.Identity) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.Identity))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *ACLChangeUserInvite) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ACLChangeUserInvite) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ACLChangeUserInvite) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.InviteId) > 0 { - i -= len(m.InviteId) - copy(dAtA[i:], m.InviteId) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.InviteId))) - i-- - dAtA[i] = 0x2a - } - if m.Permissions != 0 { - i = encodeVarintAclchanges(dAtA, i, uint64(m.Permissions)) - i-- - dAtA[i] = 0x20 - } - if len(m.EncryptedReadKeys) > 0 { - for iNdEx := len(m.EncryptedReadKeys) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.EncryptedReadKeys[iNdEx]) - copy(dAtA[i:], m.EncryptedReadKeys[iNdEx]) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.EncryptedReadKeys[iNdEx]))) - i-- - dAtA[i] = 0x1a - } - } - if len(m.EncryptPublicKey) > 0 { - i -= len(m.EncryptPublicKey) - copy(dAtA[i:], m.EncryptPublicKey) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.EncryptPublicKey))) - i-- - dAtA[i] = 0x12 - } - if len(m.AcceptPublicKey) > 0 { - i -= len(m.AcceptPublicKey) - copy(dAtA[i:], m.AcceptPublicKey) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.AcceptPublicKey))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *ACLChangeUserJoin) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ACLChangeUserJoin) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ACLChangeUserJoin) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.EncryptedReadKeys) > 0 { - for iNdEx := len(m.EncryptedReadKeys) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.EncryptedReadKeys[iNdEx]) - copy(dAtA[i:], m.EncryptedReadKeys[iNdEx]) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.EncryptedReadKeys[iNdEx]))) - i-- - dAtA[i] = 0x2a - } - } - if len(m.UserInviteId) > 0 { - i -= len(m.UserInviteId) - copy(dAtA[i:], m.UserInviteId) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.UserInviteId))) - i-- - dAtA[i] = 0x22 - } - if len(m.AcceptSignature) > 0 { - i -= len(m.AcceptSignature) - copy(dAtA[i:], m.AcceptSignature) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.AcceptSignature))) - i-- - dAtA[i] = 0x1a - } - if len(m.EncryptionKey) > 0 { - i -= len(m.EncryptionKey) - copy(dAtA[i:], m.EncryptionKey) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.EncryptionKey))) - i-- - dAtA[i] = 0x12 - } - if len(m.Identity) > 0 { - i -= len(m.Identity) - copy(dAtA[i:], m.Identity) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.Identity))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *ACLChangeUserRemove) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ACLChangeUserRemove) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ACLChangeUserRemove) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.ReadKeyReplaces) > 0 { - for iNdEx := len(m.ReadKeyReplaces) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.ReadKeyReplaces[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintAclchanges(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - } - if len(m.Identity) > 0 { - i -= len(m.Identity) - copy(dAtA[i:], m.Identity) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.Identity))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *ACLChangeReadKeyReplace) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ACLChangeReadKeyReplace) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ACLChangeReadKeyReplace) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.EncryptedReadKey) > 0 { - i -= len(m.EncryptedReadKey) - copy(dAtA[i:], m.EncryptedReadKey) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.EncryptedReadKey))) - i-- - dAtA[i] = 0x1a - } - if len(m.EncryptionKey) > 0 { - i -= len(m.EncryptionKey) - copy(dAtA[i:], m.EncryptionKey) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.EncryptionKey))) - i-- - dAtA[i] = 0x12 - } - if len(m.Identity) > 0 { - i -= len(m.Identity) - copy(dAtA[i:], m.Identity) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.Identity))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *ACLChangeUserPermissionChange) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ACLChangeUserPermissionChange) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ACLChangeUserPermissionChange) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Permissions != 0 { - i = encodeVarintAclchanges(dAtA, i, uint64(m.Permissions)) - i-- - dAtA[i] = 0x10 - } - if len(m.Identity) > 0 { - i -= len(m.Identity) - copy(dAtA[i:], m.Identity) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.Identity))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func encodeVarintAclchanges(dAtA []byte, offset int, v uint64) int { - offset -= sovAclchanges(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *RawChange) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Payload) - if l > 0 { - n += 1 + l + sovAclchanges(uint64(l)) - } - l = len(m.Signature) - if l > 0 { - n += 1 + l + sovAclchanges(uint64(l)) - } - l = len(m.Id) - if l > 0 { - n += 1 + l + sovAclchanges(uint64(l)) - } - return n -} - -func (m *ACLChange) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.TreeHeadIds) > 0 { - for _, s := range m.TreeHeadIds { - l = len(s) - n += 1 + l + sovAclchanges(uint64(l)) - } - } - if len(m.AclHeadIds) > 0 { - for _, s := range m.AclHeadIds { - l = len(s) - n += 1 + l + sovAclchanges(uint64(l)) - } - } - l = len(m.SnapshotBaseId) - if l > 0 { - n += 1 + l + sovAclchanges(uint64(l)) - } - if m.AclData != nil { - l = m.AclData.Size() - n += 1 + l + sovAclchanges(uint64(l)) - } - l = len(m.ChangesData) - if l > 0 { - n += 1 + l + sovAclchanges(uint64(l)) - } - if m.CurrentReadKeyHash != 0 { - n += 1 + sovAclchanges(uint64(m.CurrentReadKeyHash)) - } - if m.Timestamp != 0 { - n += 1 + sovAclchanges(uint64(m.Timestamp)) - } - l = len(m.Identity) - if l > 0 { - n += 1 + l + sovAclchanges(uint64(l)) - } - return n -} - -func (m *ACLChangeACLContentValue) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Value != nil { - n += m.Value.Size() - } - return n -} - -func (m *ACLChangeACLContentValueValueOfUserAdd) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.UserAdd != nil { - l = m.UserAdd.Size() - n += 1 + l + sovAclchanges(uint64(l)) - } - return n -} -func (m *ACLChangeACLContentValueValueOfUserRemove) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.UserRemove != nil { - l = m.UserRemove.Size() - n += 1 + l + sovAclchanges(uint64(l)) - } - return n -} -func (m *ACLChangeACLContentValueValueOfUserPermissionChange) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.UserPermissionChange != nil { - l = m.UserPermissionChange.Size() - n += 1 + l + sovAclchanges(uint64(l)) - } - return n -} -func (m *ACLChangeACLContentValueValueOfUserInvite) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.UserInvite != nil { - l = m.UserInvite.Size() - n += 1 + l + sovAclchanges(uint64(l)) - } - return n -} -func (m *ACLChangeACLContentValueValueOfUserJoin) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.UserJoin != nil { - l = m.UserJoin.Size() - n += 1 + l + sovAclchanges(uint64(l)) - } - return n -} -func (m *ACLChangeACLContentValueValueOfUserConfirm) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.UserConfirm != nil { - l = m.UserConfirm.Size() - n += 1 + l + sovAclchanges(uint64(l)) - } - return n -} -func (m *ACLChangeACLData) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.AclSnapshot != nil { - l = m.AclSnapshot.Size() - n += 1 + l + sovAclchanges(uint64(l)) - } - if len(m.AclContent) > 0 { - for _, e := range m.AclContent { - l = e.Size() - n += 1 + l + sovAclchanges(uint64(l)) - } - } - return n -} - -func (m *ACLChangeACLSnapshot) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.AclState != nil { - l = m.AclState.Size() - n += 1 + l + sovAclchanges(uint64(l)) - } - return n -} - -func (m *ACLChangeACLState) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.ReadKeyHashes) > 0 { - l = 0 - for _, e := range m.ReadKeyHashes { - l += sovAclchanges(uint64(e)) - } - n += 1 + sovAclchanges(uint64(l)) + l - } - if len(m.UserStates) > 0 { - for _, e := range m.UserStates { - l = e.Size() - n += 1 + l + sovAclchanges(uint64(l)) - } - } - if len(m.Invites) > 0 { - for k, v := range m.Invites { - _ = k - _ = v - l = 0 - if v != nil { - l = v.Size() - l += 1 + sovAclchanges(uint64(l)) - } - mapEntrySize := 1 + len(k) + sovAclchanges(uint64(len(k))) + l - n += mapEntrySize + 1 + sovAclchanges(uint64(mapEntrySize)) - } - } - return n -} - -func (m *ACLChangeUserState) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Identity) - if l > 0 { - n += 1 + l + sovAclchanges(uint64(l)) - } - l = len(m.EncryptionKey) - if l > 0 { - n += 1 + l + sovAclchanges(uint64(l)) - } - if len(m.EncryptedReadKeys) > 0 { - for _, b := range m.EncryptedReadKeys { - l = len(b) - n += 1 + l + sovAclchanges(uint64(l)) - } - } - if m.Permissions != 0 { - n += 1 + sovAclchanges(uint64(m.Permissions)) - } - if m.IsConfirmed { - n += 2 - } - return n -} - -func (m *ACLChangeUserAdd) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Identity) - if l > 0 { - n += 1 + l + sovAclchanges(uint64(l)) - } - l = len(m.EncryptionKey) - if l > 0 { - n += 1 + l + sovAclchanges(uint64(l)) - } - if len(m.EncryptedReadKeys) > 0 { - for _, b := range m.EncryptedReadKeys { - l = len(b) - n += 1 + l + sovAclchanges(uint64(l)) - } - } - if m.Permissions != 0 { - n += 1 + sovAclchanges(uint64(m.Permissions)) - } - return n -} - -func (m *ACLChangeUserConfirm) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Identity) - if l > 0 { - n += 1 + l + sovAclchanges(uint64(l)) - } - l = len(m.UserAddId) - if l > 0 { - n += 1 + l + sovAclchanges(uint64(l)) - } - return n -} - -func (m *ACLChangeUserInvite) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.AcceptPublicKey) - if l > 0 { - n += 1 + l + sovAclchanges(uint64(l)) - } - l = len(m.EncryptPublicKey) - if l > 0 { - n += 1 + l + sovAclchanges(uint64(l)) - } - if len(m.EncryptedReadKeys) > 0 { - for _, b := range m.EncryptedReadKeys { - l = len(b) - n += 1 + l + sovAclchanges(uint64(l)) - } - } - if m.Permissions != 0 { - n += 1 + sovAclchanges(uint64(m.Permissions)) - } - l = len(m.InviteId) - if l > 0 { - n += 1 + l + sovAclchanges(uint64(l)) - } - return n -} - -func (m *ACLChangeUserJoin) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Identity) - if l > 0 { - n += 1 + l + sovAclchanges(uint64(l)) - } - l = len(m.EncryptionKey) - if l > 0 { - n += 1 + l + sovAclchanges(uint64(l)) - } - l = len(m.AcceptSignature) - if l > 0 { - n += 1 + l + sovAclchanges(uint64(l)) - } - l = len(m.UserInviteId) - if l > 0 { - n += 1 + l + sovAclchanges(uint64(l)) - } - if len(m.EncryptedReadKeys) > 0 { - for _, b := range m.EncryptedReadKeys { - l = len(b) - n += 1 + l + sovAclchanges(uint64(l)) - } - } - return n -} - -func (m *ACLChangeUserRemove) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Identity) - if l > 0 { - n += 1 + l + sovAclchanges(uint64(l)) - } - if len(m.ReadKeyReplaces) > 0 { - for _, e := range m.ReadKeyReplaces { - l = e.Size() - n += 1 + l + sovAclchanges(uint64(l)) - } - } - return n -} - -func (m *ACLChangeReadKeyReplace) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Identity) - if l > 0 { - n += 1 + l + sovAclchanges(uint64(l)) - } - l = len(m.EncryptionKey) - if l > 0 { - n += 1 + l + sovAclchanges(uint64(l)) - } - l = len(m.EncryptedReadKey) - if l > 0 { - n += 1 + l + sovAclchanges(uint64(l)) - } - return n -} - -func (m *ACLChangeUserPermissionChange) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Identity) - if l > 0 { - n += 1 + l + sovAclchanges(uint64(l)) - } - if m.Permissions != 0 { - n += 1 + sovAclchanges(uint64(m.Permissions)) - } - return n -} - -func sovAclchanges(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozAclchanges(x uint64) (n int) { - return sovAclchanges(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *RawChange) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: RawChange: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: RawChange: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Payload", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Payload = append(m.Payload[:0], dAtA[iNdEx:postIndex]...) - if m.Payload == nil { - m.Payload = []byte{} - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Signature = append(m.Signature[:0], dAtA[iNdEx:postIndex]...) - if m.Signature == nil { - m.Signature = []byte{} - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Id = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipAclchanges(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthAclchanges - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ACLChange) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ACLChange: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ACLChange: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TreeHeadIds", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.TreeHeadIds = append(m.TreeHeadIds, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AclHeadIds", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.AclHeadIds = append(m.AclHeadIds, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SnapshotBaseId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.SnapshotBaseId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AclData", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.AclData == nil { - m.AclData = &ACLChangeACLData{} - } - if err := m.AclData.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChangesData", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ChangesData = append(m.ChangesData[:0], dAtA[iNdEx:postIndex]...) - if m.ChangesData == nil { - m.ChangesData = []byte{} - } - iNdEx = postIndex - case 6: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field CurrentReadKeyHash", wireType) - } - m.CurrentReadKeyHash = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.CurrentReadKeyHash |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 7: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) - } - m.Timestamp = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Timestamp |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 8: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Identity", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Identity = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipAclchanges(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthAclchanges - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ACLChangeACLContentValue) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ACLContentValue: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ACLContentValue: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserAdd", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &ACLChangeUserAdd{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Value = &ACLChangeACLContentValueValueOfUserAdd{v} - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserRemove", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &ACLChangeUserRemove{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Value = &ACLChangeACLContentValueValueOfUserRemove{v} - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserPermissionChange", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &ACLChangeUserPermissionChange{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Value = &ACLChangeACLContentValueValueOfUserPermissionChange{v} - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserInvite", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &ACLChangeUserInvite{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Value = &ACLChangeACLContentValueValueOfUserInvite{v} - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserJoin", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &ACLChangeUserJoin{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Value = &ACLChangeACLContentValueValueOfUserJoin{v} - iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserConfirm", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &ACLChangeUserConfirm{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Value = &ACLChangeACLContentValueValueOfUserConfirm{v} - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipAclchanges(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthAclchanges - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ACLChangeACLData) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ACLData: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ACLData: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AclSnapshot", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.AclSnapshot == nil { - m.AclSnapshot = &ACLChangeACLSnapshot{} - } - if err := m.AclSnapshot.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AclContent", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.AclContent = append(m.AclContent, &ACLChangeACLContentValue{}) - if err := m.AclContent[len(m.AclContent)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipAclchanges(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthAclchanges - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ACLChangeACLSnapshot) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ACLSnapshot: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ACLSnapshot: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AclState", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.AclState == nil { - m.AclState = &ACLChangeACLState{} - } - if err := m.AclState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipAclchanges(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthAclchanges - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ACLChangeACLState) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ACLState: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ACLState: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType == 0 { - var v uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.ReadKeyHashes = append(m.ReadKeyHashes, v) - } else if wireType == 2 { - var packedLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - packedLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if packedLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + packedLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - var elementCount int - var count int - for _, integer := range dAtA[iNdEx:postIndex] { - if integer < 128 { - count++ - } - } - elementCount = count - if elementCount != 0 && len(m.ReadKeyHashes) == 0 { - m.ReadKeyHashes = make([]uint64, 0, elementCount) - } - for iNdEx < postIndex { - var v uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.ReadKeyHashes = append(m.ReadKeyHashes, v) - } - } else { - return fmt.Errorf("proto: wrong wireType = %d for field ReadKeyHashes", wireType) - } - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserStates", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.UserStates = append(m.UserStates, &ACLChangeUserState{}) - if err := m.UserStates[len(m.UserStates)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Invites", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Invites == nil { - m.Invites = make(map[string]*ACLChangeUserInvite) - } - var mapkey string - var mapvalue *ACLChangeUserInvite - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLengthAclchanges - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLengthAclchanges - } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var mapmsglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - mapmsglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if mapmsglen < 0 { - return ErrInvalidLengthAclchanges - } - postmsgIndex := iNdEx + mapmsglen - if postmsgIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postmsgIndex > l { - return io.ErrUnexpectedEOF - } - mapvalue = &ACLChangeUserInvite{} - if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { - return err - } - iNdEx = postmsgIndex - } else { - iNdEx = entryPreIndex - skippy, err := skipAclchanges(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthAclchanges - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - m.Invites[mapkey] = mapvalue - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipAclchanges(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthAclchanges - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ACLChangeUserState) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: UserState: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: UserState: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Identity", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Identity = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field EncryptionKey", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.EncryptionKey = append(m.EncryptionKey[:0], dAtA[iNdEx:postIndex]...) - if m.EncryptionKey == nil { - m.EncryptionKey = []byte{} - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field EncryptedReadKeys", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.EncryptedReadKeys = append(m.EncryptedReadKeys, make([]byte, postIndex-iNdEx)) - copy(m.EncryptedReadKeys[len(m.EncryptedReadKeys)-1], dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Permissions", wireType) - } - m.Permissions = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Permissions |= ACLChangeUserPermissions(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field IsConfirmed", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.IsConfirmed = bool(v != 0) - default: - iNdEx = preIndex - skippy, err := skipAclchanges(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthAclchanges - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ACLChangeUserAdd) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: UserAdd: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: UserAdd: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Identity", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Identity = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field EncryptionKey", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.EncryptionKey = append(m.EncryptionKey[:0], dAtA[iNdEx:postIndex]...) - if m.EncryptionKey == nil { - m.EncryptionKey = []byte{} - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field EncryptedReadKeys", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.EncryptedReadKeys = append(m.EncryptedReadKeys, make([]byte, postIndex-iNdEx)) - copy(m.EncryptedReadKeys[len(m.EncryptedReadKeys)-1], dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Permissions", wireType) - } - m.Permissions = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Permissions |= ACLChangeUserPermissions(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := skipAclchanges(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthAclchanges - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ACLChangeUserConfirm) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: UserConfirm: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: UserConfirm: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Identity", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Identity = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserAddId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.UserAddId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipAclchanges(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthAclchanges - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ACLChangeUserInvite) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: UserInvite: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: UserInvite: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AcceptPublicKey", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.AcceptPublicKey = append(m.AcceptPublicKey[:0], dAtA[iNdEx:postIndex]...) - if m.AcceptPublicKey == nil { - m.AcceptPublicKey = []byte{} - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field EncryptPublicKey", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.EncryptPublicKey = append(m.EncryptPublicKey[:0], dAtA[iNdEx:postIndex]...) - if m.EncryptPublicKey == nil { - m.EncryptPublicKey = []byte{} - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field EncryptedReadKeys", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.EncryptedReadKeys = append(m.EncryptedReadKeys, make([]byte, postIndex-iNdEx)) - copy(m.EncryptedReadKeys[len(m.EncryptedReadKeys)-1], dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Permissions", wireType) - } - m.Permissions = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Permissions |= ACLChangeUserPermissions(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field InviteId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.InviteId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipAclchanges(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthAclchanges - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ACLChangeUserJoin) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: UserJoin: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: UserJoin: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Identity", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Identity = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field EncryptionKey", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.EncryptionKey = append(m.EncryptionKey[:0], dAtA[iNdEx:postIndex]...) - if m.EncryptionKey == nil { - m.EncryptionKey = []byte{} - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AcceptSignature", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.AcceptSignature = append(m.AcceptSignature[:0], dAtA[iNdEx:postIndex]...) - if m.AcceptSignature == nil { - m.AcceptSignature = []byte{} - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserInviteId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.UserInviteId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field EncryptedReadKeys", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.EncryptedReadKeys = append(m.EncryptedReadKeys, make([]byte, postIndex-iNdEx)) - copy(m.EncryptedReadKeys[len(m.EncryptedReadKeys)-1], dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipAclchanges(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthAclchanges - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ACLChangeUserRemove) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: UserRemove: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: UserRemove: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Identity", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Identity = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ReadKeyReplaces", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ReadKeyReplaces = append(m.ReadKeyReplaces, &ACLChangeReadKeyReplace{}) - if err := m.ReadKeyReplaces[len(m.ReadKeyReplaces)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipAclchanges(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthAclchanges - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ACLChangeReadKeyReplace) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ReadKeyReplace: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ReadKeyReplace: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Identity", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Identity = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field EncryptionKey", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.EncryptionKey = append(m.EncryptionKey[:0], dAtA[iNdEx:postIndex]...) - if m.EncryptionKey == nil { - m.EncryptionKey = []byte{} - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field EncryptedReadKey", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.EncryptedReadKey = append(m.EncryptedReadKey[:0], dAtA[iNdEx:postIndex]...) - if m.EncryptedReadKey == nil { - m.EncryptedReadKey = []byte{} - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipAclchanges(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthAclchanges - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ACLChangeUserPermissionChange) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: UserPermissionChange: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: UserPermissionChange: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Identity", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthAclchanges - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthAclchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Identity = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Permissions", wireType) - } - m.Permissions = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Permissions |= ACLChangeUserPermissions(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := skipAclchanges(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthAclchanges - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipAclchanges(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowAclchanges - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowAclchanges - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowAclchanges - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthAclchanges - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupAclchanges - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthAclchanges - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthAclchanges = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowAclchanges = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupAclchanges = fmt.Errorf("proto: unexpected end of group") -) diff --git a/pkg/acl/aclchanges/aclpb/protos/aclchanges.proto b/pkg/acl/aclchanges/aclpb/protos/aclchanges.proto deleted file mode 100644 index 1c8ceaf2..00000000 --- a/pkg/acl/aclchanges/aclpb/protos/aclchanges.proto +++ /dev/null @@ -1,111 +0,0 @@ -syntax = "proto3"; -package acl; -option go_package = "aclpb"; - -message RawChange { - bytes payload = 1; - bytes signature = 2; - string id = 3; -} - -// the element of change tree used to store and internal apply smartBlock history -message ACLChange { - repeated string treeHeadIds = 1; - repeated string aclHeadIds = 2; - string snapshotBaseId = 3; // we will only have one base snapshot for both - ACLData aclData = 4; - // the data is encoded with read key and should be read in ChangesData format - bytes changesData = 5; - uint64 currentReadKeyHash = 6; - int64 timestamp = 7; - string identity = 8; - - message ACLContentValue { - oneof value { - UserAdd userAdd = 1; - UserRemove userRemove = 2; - UserPermissionChange userPermissionChange = 3; - UserInvite userInvite = 4; - UserJoin userJoin = 5; - UserConfirm userConfirm = 6; - } - } - - message ACLData { - ACLSnapshot aclSnapshot = 1; - repeated ACLContentValue aclContent = 2; - } - - message ACLSnapshot { - // We don't need ACLState as a separate message now, because we simplified the snapshot model - ACLState aclState = 1; - } - - message ACLState { - repeated uint64 readKeyHashes = 1; - repeated UserState userStates = 2; - map invites = 3; // TODO: later - // repeated string unconfirmedUsers = 4; // TODO: later - } - - message UserState { - string identity = 1; - bytes encryptionKey = 2; - repeated bytes encryptedReadKeys = 3; // all read keys that we know - UserPermissions permissions = 4; - bool IsConfirmed = 5; - } - - // we already know identity and encryptionKey - message UserAdd { - string identity = 1; // public signing key - bytes encryptionKey = 2; // public encryption key - repeated bytes encryptedReadKeys = 3; // all read keys that we know for the user - UserPermissions permissions = 4; - } - - // TODO: this is not used as of now - message UserConfirm { // not needed for read permissions - string identity = 1; // not needed - string userAddId = 2; - } - - message UserInvite { - bytes acceptPublicKey = 1; - bytes encryptPublicKey = 2; - repeated bytes encryptedReadKeys = 3; // all read keys that we know for the user - UserPermissions permissions = 4; - string InviteId = 5; - } - - message UserJoin { - string identity = 1; - bytes encryptionKey = 2; - bytes acceptSignature = 3; // sign acceptPublicKey - string userInviteId = 4; - repeated bytes encryptedReadKeys = 5; // the idea is that user should itself reencrypt the keys with the pub key - } - - message UserRemove { - string identity = 1; - repeated ReadKeyReplace readKeyReplaces = 3; // new read key encrypted for all users - } - - message ReadKeyReplace { - string identity = 1; - bytes encryptionKey = 2; - bytes encryptedReadKey = 3; - } - - message UserPermissionChange { - string identity = 1; - UserPermissions permissions = 2; - } - - enum UserPermissions { - Admin = 0; - Writer = 1; - Reader = 2; - Removed = 3; - } -} diff --git a/pkg/acl/aclchanges/change.go b/pkg/acl/aclchanges/change.go deleted file mode 100644 index be08fca2..00000000 --- a/pkg/acl/aclchanges/change.go +++ /dev/null @@ -1,12 +0,0 @@ -package aclchanges - -import ( - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb" -) - -type Change interface { - ProtoChange() *aclpb.ACLChange - DecryptedChangeContent() []byte - Signature() []byte - CID() string -} diff --git a/pkg/acl/acltree/aclstate.go b/pkg/acl/acltree/aclstate.go deleted file mode 100644 index a7443f69..00000000 --- a/pkg/acl/acltree/aclstate.go +++ /dev/null @@ -1,411 +0,0 @@ -package acltree - -import ( - "bytes" - "errors" - "fmt" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/symmetric" - "hash/fnv" -) - -var ErrNoSuchUser = errors.New("no such user") -var ErrFailedToDecrypt = errors.New("failed to decrypt key") -var ErrUserRemoved = errors.New("user was removed from the document") -var ErrDocumentForbidden = errors.New("your user was forbidden access to the document") -var ErrUserAlreadyExists = errors.New("user already exists") - -type ACLState struct { - currentReadKeyHash uint64 - userReadKeys map[uint64]*symmetric.Key - userStates map[string]*aclpb.ACLChangeUserState - userInvites map[string]*aclpb.ACLChangeUserInvite - signingPubKeyDecoder signingkey.PubKeyDecoder - encryptionKey encryptionkey.PrivKey - identity string -} - -func newACLState( - identity string, - encryptionKey encryptionkey.PrivKey, - signingPubKeyDecoder signingkey.PubKeyDecoder) *ACLState { - return &ACLState{ - identity: identity, - encryptionKey: encryptionKey, - userReadKeys: make(map[uint64]*symmetric.Key), - userStates: make(map[string]*aclpb.ACLChangeUserState), - userInvites: make(map[string]*aclpb.ACLChangeUserInvite), - signingPubKeyDecoder: signingPubKeyDecoder, - } -} - -func newACLStateFromSnapshotChange( - snapshotChange *aclpb.ACLChange, - identity string, - encryptionKey encryptionkey.PrivKey, - signingPubKeyDecoder signingkey.PubKeyDecoder) (*ACLState, error) { - st := &ACLState{ - identity: identity, - encryptionKey: encryptionKey, - userReadKeys: make(map[uint64]*symmetric.Key), - userStates: make(map[string]*aclpb.ACLChangeUserState), - userInvites: make(map[string]*aclpb.ACLChangeUserInvite), - signingPubKeyDecoder: signingPubKeyDecoder, - } - err := st.recreateFromSnapshotChange(snapshotChange) - if err != nil { - return nil, err - } - return st, nil -} - -func (st *ACLState) recreateFromSnapshotChange(snapshotChange *aclpb.ACLChange) error { - snapshot := snapshotChange.GetAclData().GetAclSnapshot() - if snapshot == nil { - return fmt.Errorf("could not create state from snapshot, because it is nil") - } - state := snapshot.AclState - for _, userState := range state.UserStates { - st.userStates[userState.Identity] = userState - } - - userState, exists := st.userStates[st.identity] - if !exists { - return ErrNoSuchUser - } - for _, key := range userState.EncryptedReadKeys { - key, hash, err := st.decryptReadKeyAndHash(key) - if err != nil { - return ErrFailedToDecrypt - } - - st.userReadKeys[hash] = key - } - st.currentReadKeyHash = snapshotChange.CurrentReadKeyHash - if snapshot.GetAclState().GetInvites() != nil { - st.userInvites = snapshot.GetAclState().GetInvites() - } - return nil -} - -func (st *ACLState) makeSnapshot() *aclpb.ACLChangeACLSnapshot { - var userStates []*aclpb.ACLChangeUserState - for _, st := range st.userStates { - userStates = append(userStates, st) - } - - return &aclpb.ACLChangeACLSnapshot{AclState: &aclpb.ACLChangeACLState{ - ReadKeyHashes: nil, - UserStates: userStates, // TODO: make states and invites in same format - Invites: st.userInvites, - }} -} - -func (st *ACLState) applyChange(change *aclpb.ACLChange) (err error) { - defer func() { - if err != nil { - return - } - st.currentReadKeyHash = change.CurrentReadKeyHash - }() - - // we can't check this for the user which is joining, because it will not be in our list - // the same is for the first change to be added - skipIdentityCheck := st.isUserJoin(change) || (st.currentReadKeyHash == 0 && st.isUserAdd(change)) - if !skipIdentityCheck { - // we check signature when we add this to the Tree, so no need to do it here - if _, exists := st.userStates[change.Identity]; !exists { - err = ErrNoSuchUser - return - } - - if !st.hasPermission(change.Identity, aclpb.ACLChange_Admin) { - err = fmt.Errorf("user %s must have admin permissions", change.Identity) - return - } - } - - for _, ch := range change.GetAclData().GetAclContent() { - if err = st.applyChangeContent(ch); err != nil { - //log.Infof("error while applying changes: %v; ignore", err) - return err - } - } - - return nil -} - -// TODO: remove changeId, because it is not needed -func (st *ACLState) applyChangeContent(ch *aclpb.ACLChangeACLContentValue) error { - switch { - case ch.GetUserPermissionChange() != nil: - return st.applyUserPermissionChange(ch.GetUserPermissionChange()) - case ch.GetUserAdd() != nil: - return st.applyUserAdd(ch.GetUserAdd()) - case ch.GetUserRemove() != nil: - return st.applyUserRemove(ch.GetUserRemove()) - case ch.GetUserInvite() != nil: - return st.applyUserInvite(ch.GetUserInvite()) - case ch.GetUserJoin() != nil: - return st.applyUserJoin(ch.GetUserJoin()) - case ch.GetUserConfirm() != nil: - return st.applyUserConfirm(ch.GetUserConfirm()) - default: - return fmt.Errorf("unexpected change type: %v", ch) - } -} - -func (st *ACLState) applyUserPermissionChange(ch *aclpb.ACLChangeUserPermissionChange) error { - if _, exists := st.userStates[ch.Identity]; !exists { - return ErrNoSuchUser - } - - st.userStates[ch.Identity].Permissions = ch.Permissions - return nil -} - -func (st *ACLState) applyUserInvite(ch *aclpb.ACLChangeUserInvite) error { - st.userInvites[ch.InviteId] = ch - return nil -} - -func (st *ACLState) applyUserJoin(ch *aclpb.ACLChangeUserJoin) error { - invite, exists := st.userInvites[ch.UserInviteId] - if !exists { - return fmt.Errorf("no such invite with id %s", ch.UserInviteId) - } - - if _, exists = st.userStates[ch.Identity]; exists { - return ErrUserAlreadyExists - } - - // validating signature - signature := ch.GetAcceptSignature() - verificationKey, err := st.signingPubKeyDecoder.DecodeFromBytes(invite.AcceptPublicKey) - if err != nil { - return fmt.Errorf("public key verifying invite accepts is given in incorrect format: %v", err) - } - - rawSignedId, err := st.signingPubKeyDecoder.DecodeFromStringIntoBytes(ch.Identity) - if err != nil { - return fmt.Errorf("failed to decode signing identity as bytes") - } - - res, err := verificationKey.Verify(rawSignedId, signature) - if err != nil { - return fmt.Errorf("verification returned error: %w", err) - } - if !res { - return fmt.Errorf("signature is invalid") - } - - // if ourselves -> we need to decrypt the read keys - if st.identity == ch.Identity { - for _, key := range ch.EncryptedReadKeys { - key, hash, err := st.decryptReadKeyAndHash(key) - if err != nil { - return ErrFailedToDecrypt - } - - st.userReadKeys[hash] = key - } - } - - // adding user to the list - userState := &aclpb.ACLChangeUserState{ - Identity: ch.Identity, - EncryptionKey: ch.EncryptionKey, - EncryptedReadKeys: ch.EncryptedReadKeys, - Permissions: invite.Permissions, - IsConfirmed: true, - } - st.userStates[ch.Identity] = userState - return nil -} - -func (st *ACLState) applyUserAdd(ch *aclpb.ACLChangeUserAdd) error { - if _, exists := st.userStates[ch.Identity]; exists { - return ErrUserAlreadyExists - } - - st.userStates[ch.Identity] = &aclpb.ACLChangeUserState{ - Identity: ch.Identity, - EncryptionKey: ch.EncryptionKey, - Permissions: ch.Permissions, - EncryptedReadKeys: ch.EncryptedReadKeys, - } - - if ch.Identity == st.identity { - for _, key := range ch.EncryptedReadKeys { - key, hash, err := st.decryptReadKeyAndHash(key) - if err != nil { - return ErrFailedToDecrypt - } - - st.userReadKeys[hash] = key - } - } - - return nil -} - -func (st *ACLState) applyUserRemove(ch *aclpb.ACLChangeUserRemove) error { - if ch.Identity == st.identity { - return ErrDocumentForbidden - } - - if _, exists := st.userStates[ch.Identity]; !exists { - return ErrNoSuchUser - } - - delete(st.userStates, ch.Identity) - - for _, replace := range ch.ReadKeyReplaces { - userState, exists := st.userStates[replace.Identity] - if !exists { - continue - } - - userState.EncryptedReadKeys = append(userState.EncryptedReadKeys, replace.EncryptedReadKey) - // if this is our identity then we have to decrypt the key - if replace.Identity == st.identity { - key, hash, err := st.decryptReadKeyAndHash(replace.EncryptedReadKey) - if err != nil { - return ErrFailedToDecrypt - } - - st.currentReadKeyHash = hash - st.userReadKeys[st.currentReadKeyHash] = key - } - } - return nil -} - -func (st *ACLState) applyUserConfirm(ch *aclpb.ACLChangeUserConfirm) error { - if _, exists := st.userStates[ch.Identity]; !exists { - return ErrNoSuchUser - } - - userState := st.userStates[ch.Identity] - userState.IsConfirmed = true - return nil -} - -func (st *ACLState) decryptReadKeyAndHash(msg []byte) (*symmetric.Key, uint64, error) { - decrypted, err := st.encryptionKey.Decrypt(msg) - if err != nil { - return nil, 0, ErrFailedToDecrypt - } - - key, err := symmetric.FromBytes(decrypted) - if err != nil { - return nil, 0, ErrFailedToDecrypt - } - - hasher := fnv.New64() - hasher.Write(decrypted) - return key, hasher.Sum64(), nil -} - -func (st *ACLState) hasPermission(identity string, permission aclpb.ACLChangeUserPermissions) bool { - state, exists := st.userStates[identity] - if !exists { - return false - } - - return state.Permissions == permission -} - -func (st *ACLState) isUserJoin(ch *aclpb.ACLChange) bool { - // if we have a UserJoin, then it should always be the first one applied - return ch.AclData.GetAclContent() != nil && ch.AclData.GetAclContent()[0].GetUserJoin() != nil -} - -func (st *ACLState) isUserAdd(ch *aclpb.ACLChange) bool { - // if we have a UserAdd, then it should always be the first one applied - userAdd := ch.AclData.GetAclContent()[0].GetUserAdd() - return ch.AclData.GetAclContent() != nil && userAdd != nil && userAdd.GetIdentity() == ch.Identity -} - -func (st *ACLState) getPermissionDecreasedUsers(ch *aclpb.ACLChange) (identities []*aclpb.ACLChangeUserPermissionChange) { - // this should be called after general checks are completed - if ch.GetAclData().GetAclContent() == nil { - return nil - } - - contents := ch.GetAclData().GetAclContent() - for _, c := range contents { - if c.GetUserPermissionChange() != nil { - content := c.GetUserPermissionChange() - - currentState := st.userStates[content.Identity] - // the comparison works in different direction :-) - if content.Permissions > currentState.Permissions { - identities = append(identities, &aclpb.ACLChangeUserPermissionChange{ - Identity: content.Identity, - Permissions: content.Permissions, - }) - } - } - if c.GetUserRemove() != nil { - content := c.GetUserRemove() - identities = append(identities, &aclpb.ACLChangeUserPermissionChange{ - Identity: content.Identity, - Permissions: aclpb.ACLChange_Removed, - }) - } - } - - return identities -} - -func (st *ACLState) equal(other *ACLState) bool { - if st == nil && other == nil { - return true - } - - if st == nil || other == nil { - return false - } - - if st.currentReadKeyHash != other.currentReadKeyHash { - return false - } - - if st.identity != other.identity { - return false - } - - if len(st.userStates) != len(other.userStates) { - return false - } - - for _, st := range st.userStates { - otherSt, exists := other.userStates[st.Identity] - if !exists { - return false - } - - if st.Permissions != otherSt.Permissions { - return false - } - - if bytes.Compare(st.EncryptionKey, otherSt.EncryptionKey) != 0 { - return false - } - } - - if len(st.userInvites) != len(other.userInvites) { - return false - } - - // TODO: add detailed user invites comparison + compare other stuff - return true -} - -func (st *ACLState) GetUserStates() map[string]*aclpb.ACLChangeUserState { - // TODO: we should provide better API that would not allow to change this map from the outside - return st.userStates -} diff --git a/pkg/acl/acltree/aclstatebuilder.go b/pkg/acl/acltree/aclstatebuilder.go deleted file mode 100644 index d63d535c..00000000 --- a/pkg/acl/acltree/aclstatebuilder.go +++ /dev/null @@ -1,186 +0,0 @@ -package acltree - -import ( - "fmt" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey" -) - -type aclStateBuilder struct { - tree *Tree - identity string - key encryptionkey.PrivKey - decoder signingkey.PubKeyDecoder -} - -type decreasedPermissionsParameters struct { - users []*aclpb.ACLChangeUserPermissionChange - startChange string -} - -func newACLStateBuilder(decoder signingkey.PubKeyDecoder, accountData *account.AccountData) *aclStateBuilder { - return &aclStateBuilder{ - decoder: decoder, - identity: accountData.Identity, - key: accountData.EncKey, - } -} - -func (sb *aclStateBuilder) Init(tree *Tree) error { - sb.tree = tree - return nil -} - -func (sb *aclStateBuilder) Build() (*ACLState, error) { - state, _, err := sb.BuildBefore("") - return state, err -} - -// TODO: we can probably have only one state builder, because we can Build both at the same time -func (sb *aclStateBuilder) BuildBefore(beforeId string) (*ACLState, bool, error) { - var ( - err error - startChange = sb.tree.root - foundId bool - idSeenMap = make(map[string][]*Change) - decreasedPermissions *decreasedPermissionsParameters - ) - root := sb.tree.Root() - if !root.IsSnapshot { - return nil, false, fmt.Errorf("root should always be a snapshot") - } - - state, err := newACLStateFromSnapshotChange( - root.Content, - sb.identity, - sb.key, - sb.decoder) - if err != nil { - return nil, false, fmt.Errorf("could not build ACLState from snapshot: %w", err) - } - - idSeenMap[startChange.Content.Identity] = append(idSeenMap[startChange.Content.Identity], startChange) - - if startChange.Content.GetChangesData() != nil { - key, exists := state.userReadKeys[startChange.Content.CurrentReadKeyHash] - if !exists { - return nil, false, fmt.Errorf("no first snapshot") - } - - err = startChange.DecryptContents(key) - if err != nil { - return nil, false, fmt.Errorf("failed to decrypt contents of first snapshot") - } - } - - if beforeId == startChange.Id { - return state, true, nil - } - - for { - // TODO: we should optimize this method to just remember last state of iterator and not iterate from the start and skip if nothing was removed from the Tree - sb.tree.IterateSkip(sb.tree.root.Id, startChange.Id, func(c *Change) (isContinue bool) { - defer func() { - if err == nil { - startChange = c - } else if err != ErrDocumentForbidden { - //log.Errorf("marking change %s as invalid: %v", c.Id, err) - sb.tree.RemoveInvalidChange(c.Id) - } - }() - - // not applying root change - if c.Id == startChange.Id { - return true - } - - idSeenMap[c.Content.Identity] = append(idSeenMap[c.Content.Identity], c) - if c.Content.GetAclData() != nil { - err = state.applyChange(c.Content) - if err != nil { - return false - } - - // if we have some users who have less permissions now - users := state.getPermissionDecreasedUsers(c.Content) - if len(users) > 0 { - decreasedPermissions = &decreasedPermissionsParameters{ - users: users, - startChange: c.Id, - } - return false - } - } - - // the user can't make changes - if !state.hasPermission(c.Content.Identity, aclpb.ACLChange_Writer) && !state.hasPermission(c.Content.Identity, aclpb.ACLChange_Admin) { - err = fmt.Errorf("user %s cannot make changes", c.Content.Identity) - return false - } - - // decrypting contents on the fly - if c.Content.GetChangesData() != nil { - key, exists := state.userReadKeys[c.Content.CurrentReadKeyHash] - if !exists { - err = fmt.Errorf("failed to find key with hash: %d", c.Content.CurrentReadKeyHash) - return false - } - - err = c.DecryptContents(key) - if err != nil { - err = fmt.Errorf("failed to decrypt contents for hash: %d", c.Content.CurrentReadKeyHash) - return false - } - } - - if c.Id == beforeId { - foundId = true - return false - } - - return true - }) - - // if we have users with decreased permissions - if decreasedPermissions != nil { - var removed bool - validChanges := sb.tree.dfs(decreasedPermissions.startChange) - - for _, permChange := range decreasedPermissions.users { - seenChanges := idSeenMap[permChange.Identity] - - for _, seen := range seenChanges { - // if we find some invalid changes - if _, exists := validChanges[seen.Id]; !exists { - // if the user didn't have enough permission to make changes - if seen.IsACLChange() || permChange.Permissions > aclpb.ACLChange_Writer { - removed = true - sb.tree.RemoveInvalidChange(seen.Id) - } - } - } - } - - decreasedPermissions = nil - if removed { - // starting from the beginning but with updated Tree - return sb.BuildBefore(beforeId) - } - } else if err == nil { - // we can finish the acl state building process - break - } - - // the user is forbidden to access the document - if err == ErrDocumentForbidden { - return nil, foundId, err - } - - // otherwise we have to continue from the change which we had - err = nil - } - - return state, foundId, err -} diff --git a/pkg/acl/acltree/acltree.go b/pkg/acl/acltree/acltree.go deleted file mode 100644 index 07acee6c..00000000 --- a/pkg/acl/acltree/acltree.go +++ /dev/null @@ -1,520 +0,0 @@ -package acltree - -import ( - "context" - "errors" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb" - "go.uber.org/zap" - "sync" -) - -type AddResultSummary int - -const ( - AddResultSummaryNothing AddResultSummary = iota - AddResultSummaryAppend - AddResultSummaryRebuild -) - -type AddResult struct { - OldHeads []string - Heads []string - Added []*aclpb.RawChange - // TODO: add summary for changes - Summary AddResultSummary -} - -type TreeUpdateListener interface { - Update(tree ACLTree) - Rebuild(tree ACLTree) -} - -type NoOpListener struct{} - -func (n NoOpListener) Update(tree ACLTree) {} - -func (n NoOpListener) Rebuild(tree ACLTree) {} - -type RWLocker interface { - sync.Locker - RLock() - RUnlock() -} - -var ErrNoCommonSnapshot = errors.New("trees doesn't have a common snapshot") - -type ACLTree interface { - RWLocker - ID() string - Header() *treepb.TreeHeader - ACLState() *ACLState - AddContent(ctx context.Context, f func(builder ChangeBuilder) error) (*aclpb.RawChange, error) - AddRawChanges(ctx context.Context, changes ...*aclpb.RawChange) (AddResult, error) - Heads() []string - Root() *Change - Iterate(func(change *Change) bool) - IterateFrom(string, func(change *Change) bool) - HasChange(string) bool - SnapshotPath() []string - ChangesAfterCommonSnapshot(snapshotPath []string) ([]*aclpb.RawChange, error) - Storage() treestorage.TreeStorage - DebugDump() (string, error) - - Close() error -} - -type aclTree struct { - treeStorage treestorage.TreeStorage - accountData *account.AccountData - updateListener TreeUpdateListener - - id string - header *treepb.TreeHeader - fullTree *Tree - aclTreeFromStart *Tree // TODO: right now we don't use it, we can probably have only local var for now. This tree is built from start of the document - aclState *ACLState - - treeBuilder *treeBuilder - aclTreeBuilder *aclTreeBuilder - aclStateBuilder *aclStateBuilder - snapshotValidator *snapshotValidator - changeBuilder *changeBuilder - - sync.RWMutex -} - -func BuildACLTree( - t treestorage.TreeStorage, - acc *account.AccountData, - listener TreeUpdateListener) (ACLTree, error) { - aclTreeBuilder := newACLTreeBuilder(t, acc.Decoder) - treeBuilder := newTreeBuilder(t, acc.Decoder) - snapshotValidator := newSnapshotValidator(acc.Decoder, acc) // TODO: this looks weird, change it - aclStateBuilder := newACLStateBuilder(acc.Decoder, acc) - changeBuilder := newChangeBuilder() - - aclTree := &aclTree{ - treeStorage: t, - accountData: acc, - fullTree: nil, - aclState: nil, - treeBuilder: treeBuilder, - aclTreeBuilder: aclTreeBuilder, - aclStateBuilder: aclStateBuilder, - snapshotValidator: snapshotValidator, - changeBuilder: changeBuilder, - updateListener: listener, - } - err := aclTree.rebuildFromStorage(false) - if err != nil { - return nil, err - } - err = aclTree.removeOrphans() - if err != nil { - return nil, err - } - err = t.SetHeads(aclTree.Heads()) - if err != nil { - return nil, err - } - aclTree.id, err = t.TreeID() - if err != nil { - return nil, err - } - aclTree.header, err = t.Header() - if err != nil { - return nil, err - } - - listener.Rebuild(aclTree) - - return aclTree, nil -} - -// TODO: this is not used for now, in future we should think about not making full tree rebuild -//func (a *aclTree) rebuildFromTree(validateSnapshot bool) (err error) { -// if validateSnapshot { -// err = a.snapshotValidator.Init(a.aclTreeFromStart) -// if err != nil { -// return err -// } -// -// valid, err := a.snapshotValidator.ValidateSnapshot(a.fullTree.root) -// if err != nil { -// return err -// } -// if !valid { -// return a.rebuildFromStorage(true) -// } -// } -// -// err = a.aclStateBuilder.Init(a.fullTree) -// if err != nil { -// return err -// } -// -// a.aclState, err = a.aclStateBuilder.Build() -// if err != nil { -// return err -// } -// -// return nil -//} - -func (a *aclTree) removeOrphans() error { - // removing attached or invalid orphans - var toRemove []string - - orphans, err := a.treeStorage.Orphans() - if err != nil { - return err - } - for _, orphan := range orphans { - if _, exists := a.fullTree.attached[orphan]; exists { - toRemove = append(toRemove, orphan) - } - if _, exists := a.fullTree.invalidChanges[orphan]; exists { - toRemove = append(toRemove, orphan) - } - } - return a.treeStorage.RemoveOrphans(toRemove...) -} - -func (a *aclTree) rebuildFromStorage(fromStart bool) error { - a.treeBuilder.Init() - a.aclTreeBuilder.Init() - - var err error - a.fullTree, err = a.treeBuilder.Build(fromStart) - if err != nil { - return err - } - - // TODO: remove this from context as this is used only to validate snapshot - a.aclTreeFromStart, err = a.aclTreeBuilder.Build() - if err != nil { - return err - } - - if !fromStart { - err = a.snapshotValidator.Init(a.aclTreeFromStart) - if err != nil { - return err - } - - valid, err := a.snapshotValidator.ValidateSnapshot(a.fullTree.root) - if err != nil { - return err - } - if !valid { - return a.rebuildFromStorage(true) - } - } - // TODO: there is a question how we can validate not only that the full tree is built correctly - // but also that the ACL prev ids are not messed up. I think we should probably compare the resulting - // acl state with the acl state which is built in aclTreeFromStart - - err = a.aclStateBuilder.Init(a.fullTree) - if err != nil { - return err - } - - a.aclState, err = a.aclStateBuilder.Build() - if err != nil { - return err - } - - return nil -} - -func (a *aclTree) ID() string { - return a.id -} - -func (a *aclTree) Header() *treepb.TreeHeader { - return a.header -} - -func (a *aclTree) ACLState() *ACLState { - return a.aclState -} - -func (a *aclTree) Storage() treestorage.TreeStorage { - return a.treeStorage -} - -func (a *aclTree) AddContent(ctx context.Context, build func(builder ChangeBuilder) error) (*aclpb.RawChange, error) { - // TODO: add snapshot creation logic - defer func() { - // TODO: should this be called in a separate goroutine to prevent accidental cycles (tree->updater->tree) - a.updateListener.Update(a) - }() - - a.changeBuilder.Init(a.aclState, a.fullTree, a.accountData) - err := build(a.changeBuilder) - if err != nil { - return nil, err - } - - ch, marshalled, err := a.changeBuilder.BuildAndApply() - if err != nil { - return nil, err - } - a.fullTree.AddFast(ch) - rawCh := &aclpb.RawChange{ - Payload: marshalled, - Signature: ch.Signature(), - Id: ch.Id, - } - - err = a.treeStorage.AddRawChange(rawCh) - if err != nil { - return nil, err - } - - err = a.treeStorage.SetHeads([]string{ch.Id}) - if err != nil { - return nil, err - } - return rawCh, nil -} - -func (a *aclTree) AddRawChanges(ctx context.Context, rawChanges ...*aclpb.RawChange) (AddResult, error) { - // TODO: make proper error handling, because there are a lot of corner cases where this will break - var err error - var mode Mode - - var changes []*Change // TODO: = addChangesBuf[:0] ... - for _, ch := range rawChanges { - change, err := NewFromRawChange(ch) - // TODO: think what if we will have incorrect signatures on rawChanges, how everything will work - if err != nil { - continue - } - changes = append(changes, change) - } - - defer func() { - if err != nil { - return - } - - err = a.removeOrphans() - if err != nil { - return - } - - err = a.treeStorage.SetHeads(a.fullTree.Heads()) - if err != nil { - return - } - - switch mode { - case Append: - a.updateListener.Update(a) - case Rebuild: - a.updateListener.Rebuild(a) - default: - break - } - }() - - getAddedChanges := func() []*aclpb.RawChange { - var added []*aclpb.RawChange - for _, ch := range rawChanges { - if _, exists := a.fullTree.attached[ch.Id]; exists { - added = append(added, ch) - } - } - return added - } - - for _, ch := range changes { - err = a.treeStorage.AddChange(ch) - if err != nil { - return AddResult{}, err - } - err = a.treeStorage.AddOrphans(ch.Id) - if err != nil { - return AddResult{}, err - } - } - - prevHeads := a.fullTree.Heads() - mode = a.fullTree.Add(changes...) - switch mode { - case Nothing: - return AddResult{ - OldHeads: prevHeads, - Heads: prevHeads, - Summary: AddResultSummaryNothing, - }, nil - - case Rebuild: - err = a.rebuildFromStorage(false) - if err != nil { - return AddResult{}, err - } - - return AddResult{ - OldHeads: prevHeads, - Heads: a.fullTree.Heads(), - Added: getAddedChanges(), - Summary: AddResultSummaryRebuild, - }, nil - default: - // just rebuilding the state from start without reloading everything from tree storage - // as an optimization we could've started from current heads, but I didn't implement that - a.aclState, err = a.aclStateBuilder.Build() - if err != nil { - return AddResult{}, err - } - - return AddResult{ - OldHeads: prevHeads, - Heads: a.fullTree.Heads(), - Added: getAddedChanges(), - Summary: AddResultSummaryAppend, - }, nil - } -} - -func (a *aclTree) Iterate(f func(change *Change) bool) { - a.fullTree.Iterate(a.fullTree.RootId(), f) -} - -func (a *aclTree) IterateFrom(s string, f func(change *Change) bool) { - a.fullTree.Iterate(s, f) -} - -func (a *aclTree) HasChange(s string) bool { - _, attachedExists := a.fullTree.attached[s] - _, unattachedExists := a.fullTree.unAttached[s] - _, invalidExists := a.fullTree.invalidChanges[s] - return attachedExists || unattachedExists || invalidExists -} - -func (a *aclTree) Heads() []string { - return a.fullTree.Heads() -} - -func (a *aclTree) Root() *Change { - return a.fullTree.Root() -} - -func (a *aclTree) Close() error { - return nil -} - -func (a *aclTree) SnapshotPath() []string { - // TODO: think about caching this - - var path []string - // TODO: think that the user may have not all of the snapshots locally - currentSnapshotId := a.fullTree.RootId() - for currentSnapshotId != "" { - sn, err := a.treeBuilder.loadChange(currentSnapshotId) - if err != nil { - break - } - path = append(path, currentSnapshotId) - currentSnapshotId = sn.SnapshotId - } - return path -} - -func (a *aclTree) ChangesAfterCommonSnapshot(theirPath []string) ([]*aclpb.RawChange, error) { - // TODO: think about when the clients will have their full acl tree and thus full snapshots - // but no changes after some of the snapshots - - var ( - isNewDocument = len(theirPath) == 0 - ourPath = a.SnapshotPath() - // by default returning everything we have - commonSnapshot = ourPath[len(ourPath)-1] // TODO: root snapshot, probably it is better to have a specific method in treestorage - err error - ) - - // if this is non-empty request - if !isNewDocument { - commonSnapshot, err = a.commonSnapshotForTwoPaths(ourPath, theirPath) - if err != nil { - return nil, err - } - } - var rawChanges []*aclpb.RawChange - // using custom load function to skip verification step and save raw changes - load := func(id string) (*Change, error) { - raw, err := a.treeStorage.GetChange(context.Background(), id) - if err != nil { - return nil, err - } - - aclChange, err := a.treeBuilder.makeUnverifiedACLChange(raw) - if err != nil { - return nil, err - } - - ch := NewChange(id, aclChange) - rawChanges = append(rawChanges, raw) - return ch, nil - } - // we presume that we have everything after the common snapshot, though this may not be the case in case of clients and only ACL tree changes - log.With( - zap.Strings("heads", a.fullTree.Heads()), - zap.String("breakpoint", commonSnapshot), - zap.String("id", a.id)). - Debug("getting all changes from common snapshot") - _, err = a.treeBuilder.dfs(a.fullTree.Heads(), commonSnapshot, load) - if err != nil { - return nil, err - } - if isNewDocument { - // adding snapshot to raw changes - _, err = load(commonSnapshot) - if err != nil { - return nil, err - } - } - log.With( - zap.Int("len(changes)", len(rawChanges)), - zap.String("id", a.id)). - Debug("returning all changes after common snapshot") - - return rawChanges, nil -} - -func (a *aclTree) DebugDump() (string, error) { - return a.fullTree.Graph() -} - -func (a *aclTree) commonSnapshotForTwoPaths(ourPath []string, theirPath []string) (string, error) { - var i int - var j int - log.With(zap.Strings("our path", ourPath), zap.Strings("their path", theirPath)). - Debug("finding common snapshot for two paths") -OuterLoop: - // find starting point from the right - for i = len(ourPath) - 1; i >= 0; i-- { - for j = len(theirPath) - 1; j >= 0; j-- { - // most likely there would be only one comparison, because mostly the snapshot path will start from the root for nodes - if ourPath[i] == theirPath[j] { - break OuterLoop - } - } - } - if i < 0 || j < 0 { - return "", ErrNoCommonSnapshot - } - // find last common element of the sequence moving from right to left - for i >= 0 && j >= 0 { - if ourPath[i] == theirPath[j] { - i-- - j-- - } - } - return ourPath[i+1], nil -} diff --git a/pkg/acl/acltree/acltree_test.go b/pkg/acl/acltree/acltree_test.go deleted file mode 100644 index 8d89bac3..00000000 --- a/pkg/acl/acltree/acltree_test.go +++ /dev/null @@ -1,262 +0,0 @@ -package acltree - -import ( - "context" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/treestoragebuilder" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey" - "testing" - - "github.com/stretchr/testify/assert" -) - -type mockListener struct{} - -func (m *mockListener) Update(tree ACLTree) {} - -func (m *mockListener) Rebuild(tree ACLTree) {} - -func TestACLTree_UserJoinBuild(t *testing.T) { - thr, err := treestoragebuilder.NewTreeStorageBuilderWithTestName("userjoinexample.yml") - if err != nil { - t.Fatal(err) - } - keychain := thr.GetKeychain() - accountData := &account.AccountData{ - Identity: keychain.GetIdentity("A"), - SignKey: keychain.SigningKeys["A"], - EncKey: keychain.EncryptionKeys["A"], - Decoder: signingkey.NewEd25519PubKeyDecoder(), - } - listener := &mockListener{} - tree, err := BuildACLTree(thr, accountData, listener) - if err != nil { - t.Fatalf("should Build acl ACLState without err: %v", err) - } - aclState := tree.ACLState() - aId := keychain.GeneratedIdentities["A"] - bId := keychain.GeneratedIdentities["B"] - cId := keychain.GeneratedIdentities["C"] - - assert.Equal(t, aclState.identity, aId) - assert.Equal(t, aclState.userStates[aId].Permissions, aclpb.ACLChange_Admin) - assert.Equal(t, aclState.userStates[bId].Permissions, aclpb.ACLChange_Writer) - assert.Equal(t, aclState.userStates[cId].Permissions, aclpb.ACLChange_Reader) - - var changeIds []string - tree.Iterate(func(c *Change) (isContinue bool) { - changeIds = append(changeIds, c.Id) - return true - }) - assert.Equal(t, changeIds, []string{"A.1.1", "A.1.2", "B.1.1", "B.1.2"}) -} - -func TestACLTree_UserJoinUpdate_Append(t *testing.T) { - thr, err := treestoragebuilder.NewTreeStorageBuilderWithTestName("userjoinexampleupdate.yml") - if err != nil { - t.Fatal(err) - } - keychain := thr.GetKeychain() - accountData := &account.AccountData{ - Identity: keychain.GetIdentity("A"), - SignKey: keychain.SigningKeys["A"], - EncKey: keychain.EncryptionKeys["A"], - Decoder: signingkey.NewEd25519PubKeyDecoder(), - } - - listener := &mockListener{} - tree, err := BuildACLTree(thr, accountData, listener) - if err != nil { - t.Fatalf("should Build acl ACLState without err: %v", err) - } - rawChanges := thr.GetUpdates("append") - res, err := tree.AddRawChanges(context.Background(), rawChanges...) - assert.Equal(t, res.Summary, AddResultSummaryAppend) - - aclState := tree.ACLState() - aId := keychain.GeneratedIdentities["A"] - bId := keychain.GeneratedIdentities["B"] - cId := keychain.GeneratedIdentities["C"] - dId := keychain.GeneratedIdentities["D"] - - assert.Equal(t, aclState.identity, aId) - assert.Equal(t, aclState.userStates[aId].Permissions, aclpb.ACLChange_Admin) - assert.Equal(t, aclState.userStates[bId].Permissions, aclpb.ACLChange_Writer) - assert.Equal(t, aclState.userStates[cId].Permissions, aclpb.ACLChange_Reader) - assert.Equal(t, aclState.userStates[dId].Permissions, aclpb.ACLChange_Writer) - - var changeIds []string - tree.Iterate(func(c *Change) (isContinue bool) { - changeIds = append(changeIds, c.Id) - return true - }) - assert.Equal(t, changeIds, []string{"A.1.1", "A.1.2", "B.1.1", "B.1.2", "B.1.3", "A.1.4"}) -} - -func TestACLTree_UserJoinUpdate_Rebuild(t *testing.T) { - thr, err := treestoragebuilder.NewTreeStorageBuilderWithTestName("userjoinexampleupdate.yml") - if err != nil { - t.Fatal(err) - } - keychain := thr.GetKeychain() - accountData := &account.AccountData{ - Identity: keychain.GetIdentity("A"), - SignKey: keychain.SigningKeys["A"], - EncKey: keychain.EncryptionKeys["A"], - Decoder: signingkey.NewEd25519PubKeyDecoder(), - } - listener := &mockListener{} - tree, err := BuildACLTree(thr, accountData, listener) - if err != nil { - t.Fatalf("should Build acl ACLState without err: %v", err) - } - rawChanges := thr.GetUpdates("rebuild") - res, err := tree.AddRawChanges(context.Background(), rawChanges...) - assert.Equal(t, res.Summary, AddResultSummaryRebuild) - - aclState := tree.ACLState() - aId := keychain.GeneratedIdentities["A"] - bId := keychain.GeneratedIdentities["B"] - cId := keychain.GeneratedIdentities["C"] - dId := keychain.GeneratedIdentities["D"] - - assert.Equal(t, aclState.identity, aId) - assert.Equal(t, aclState.userStates[aId].Permissions, aclpb.ACLChange_Admin) - assert.Equal(t, aclState.userStates[bId].Permissions, aclpb.ACLChange_Writer) - assert.Equal(t, aclState.userStates[cId].Permissions, aclpb.ACLChange_Reader) - assert.Equal(t, aclState.userStates[dId].Permissions, aclpb.ACLChange_Writer) - - var changeIds []string - - tree.Iterate(func(c *Change) (isContinue bool) { - changeIds = append(changeIds, c.Id) - return true - }) - assert.Equal(t, changeIds, []string{"A.1.1", "A.1.2", "B.1.1", "B.1.2", "A.1.4"}) -} - -func TestACLTree_UserRemoveBuild(t *testing.T) { - thr, err := treestoragebuilder.NewTreeStorageBuilderWithTestName("userremoveexample.yml") - if err != nil { - t.Fatal(err) - } - keychain := thr.GetKeychain() - accountData := &account.AccountData{ - Identity: keychain.GetIdentity("A"), - SignKey: keychain.SigningKeys["A"], - EncKey: keychain.EncryptionKeys["A"], - Decoder: signingkey.NewEd25519PubKeyDecoder(), - } - listener := &mockListener{} - tree, err := BuildACLTree(thr, accountData, listener) - if err != nil { - t.Fatalf("should Build acl ACLState without err: %v", err) - } - aclState := tree.ACLState() - aId := keychain.GeneratedIdentities["A"] - - assert.Equal(t, aclState.identity, aId) - assert.Equal(t, aclState.userStates[aId].Permissions, aclpb.ACLChange_Admin) - - var changeIds []string - tree.Iterate(func(c *Change) (isContinue bool) { - changeIds = append(changeIds, c.Id) - return true - }) - assert.Equal(t, changeIds, []string{"A.1.1", "A.1.2", "B.1.1", "A.1.3", "A.1.4"}) -} - -func TestACLTree_UserRemoveBeforeBuild(t *testing.T) { - thr, err := treestoragebuilder.NewTreeStorageBuilderWithTestName("userremovebeforeexample.yml") - if err != nil { - t.Fatal(err) - } - keychain := thr.GetKeychain() - accountData := &account.AccountData{ - Identity: keychain.GetIdentity("A"), - SignKey: keychain.SigningKeys["A"], - EncKey: keychain.EncryptionKeys["A"], - Decoder: signingkey.NewEd25519PubKeyDecoder(), - } - listener := &mockListener{} - tree, err := BuildACLTree(thr, accountData, listener) - if err != nil { - t.Fatalf("should Build acl ACLState without err: %v", err) - } - aclState := tree.ACLState() - for _, s := range []string{"A", "C", "E"} { - assert.Equal(t, aclState.userStates[keychain.GetIdentity(s)].Permissions, aclpb.ACLChange_Admin) - } - assert.Equal(t, aclState.identity, keychain.GetIdentity("A")) - assert.Nil(t, aclState.userStates[keychain.GetIdentity("B")]) - - var changeIds []string - tree.Iterate(func(c *Change) (isContinue bool) { - changeIds = append(changeIds, c.Id) - return true - }) - assert.Equal(t, changeIds, []string{"A.1.1", "B.1.1", "A.1.2", "A.1.3"}) -} - -func TestACLTree_InvalidSnapshotBuild(t *testing.T) { - thr, err := treestoragebuilder.NewTreeStorageBuilderWithTestName("invalidsnapshotexample.yml") - if err != nil { - t.Fatal(err) - } - keychain := thr.GetKeychain() - accountData := &account.AccountData{ - Identity: keychain.GetIdentity("A"), - SignKey: keychain.SigningKeys["A"], - EncKey: keychain.EncryptionKeys["A"], - Decoder: signingkey.NewEd25519PubKeyDecoder(), - } - listener := &mockListener{} - tree, err := BuildACLTree(thr, accountData, listener) - if err != nil { - t.Fatalf("should Build acl ACLState without err: %v", err) - } - aclState := tree.ACLState() - for _, s := range []string{"A", "B", "C", "D", "E", "F"} { - assert.Equal(t, aclState.userStates[keychain.GetIdentity(s)].Permissions, aclpb.ACLChange_Admin) - } - assert.Equal(t, aclState.identity, keychain.GetIdentity("A")) - - var changeIds []string - tree.Iterate(func(c *Change) (isContinue bool) { - changeIds = append(changeIds, c.Id) - return true - }) - assert.Equal(t, []string{"A.1.1", "B.1.1", "A.1.2", "A.1.3", "B.1.2"}, changeIds) -} - -func TestACLTree_ValidSnapshotBuild(t *testing.T) { - thr, err := treestoragebuilder.NewTreeStorageBuilderWithTestName("validsnapshotexample.yml") - if err != nil { - t.Fatal(err) - } - keychain := thr.GetKeychain() - accountData := &account.AccountData{ - Identity: keychain.GetIdentity("A"), - SignKey: keychain.SigningKeys["A"], - EncKey: keychain.EncryptionKeys["A"], - Decoder: signingkey.NewEd25519PubKeyDecoder(), - } - listener := &mockListener{} - tree, err := BuildACLTree(thr, accountData, listener) - if err != nil { - t.Fatalf("should Build acl ACLState without err: %v", err) - } - aclState := tree.ACLState() - for _, s := range []string{"A", "B", "C", "D", "E", "F"} { - assert.Equal(t, aclState.userStates[keychain.GetIdentity(s)].Permissions, aclpb.ACLChange_Admin) - } - assert.Equal(t, aclState.identity, keychain.GetIdentity("A")) - - var changeIds []string - tree.Iterate(func(c *Change) (isContinue bool) { - changeIds = append(changeIds, c.Id) - return true - }) - assert.Equal(t, []string{"A.1.2", "A.1.3", "B.1.2"}, changeIds) -} diff --git a/pkg/acl/acltree/acltreebuilder.go b/pkg/acl/acltree/acltreebuilder.go deleted file mode 100644 index 71b5b304..00000000 --- a/pkg/acl/acltree/acltreebuilder.go +++ /dev/null @@ -1,154 +0,0 @@ -package acltree - -import ( - "fmt" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey" - - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice" -) - -type aclTreeBuilder struct { - cache map[string]*Change - identityKeys map[string]signingkey.PubKey - signingPubKeyDecoder signingkey.PubKeyDecoder - tree *Tree - treeStorage treestorage.TreeStorage - - *changeLoader -} - -func newACLTreeBuilder(t treestorage.TreeStorage, decoder signingkey.PubKeyDecoder) *aclTreeBuilder { - return &aclTreeBuilder{ - signingPubKeyDecoder: decoder, - treeStorage: t, - changeLoader: newChangeLoader( - t, - decoder, - NewACLChange), - } -} - -func (tb *aclTreeBuilder) Init() { - tb.cache = make(map[string]*Change) - tb.identityKeys = make(map[string]signingkey.PubKey) - tb.tree = &Tree{} - tb.changeLoader.Init(tb.cache, tb.identityKeys) -} - -func (tb *aclTreeBuilder) Build() (*Tree, error) { - var headsAndOrphans []string - orphans, err := tb.treeStorage.Orphans() - if err != nil { - return nil, err - } - heads, err := tb.treeStorage.Heads() - if err != nil { - return nil, err - } - headsAndOrphans = append(headsAndOrphans, orphans...) - headsAndOrphans = append(headsAndOrphans, heads...) - aclHeads, err := tb.getACLHeads(headsAndOrphans) - - if err != nil { - return nil, err - } - - if err = tb.buildTreeFromStart(aclHeads); err != nil { - return nil, fmt.Errorf("buildTree error: %v", err) - } - tb.cache = nil - - return tb.tree, nil -} - -func (tb *aclTreeBuilder) buildTreeFromStart(heads []string) (err error) { - changes, root, err := tb.dfsFromStart(heads) - if err != nil { - return err - } - - tb.tree.AddFast(root) - tb.tree.AddFast(changes...) - return -} - -func (tb *aclTreeBuilder) dfsFromStart(heads []string) (buf []*Change, root *Change, err error) { - var possibleRoots []*Change - stack := make([]string, len(heads), len(heads)*2) - copy(stack, heads) - - buf = make([]*Change, 0, len(stack)*2) - uniqMap := make(map[string]struct{}) - for len(stack) > 0 { - id := stack[len(stack)-1] - stack = stack[:len(stack)-1] - if _, exists := uniqMap[id]; exists { - continue - } - - ch, err := tb.loadChange(id) - if err != nil { - continue - } - - uniqMap[id] = struct{}{} - buf = append(buf, ch) - - for _, prev := range ch.PreviousIds { - stack = append(stack, prev) - } - if len(ch.PreviousIds) == 0 { - possibleRoots = append(possibleRoots, ch) - } - } - header, err := tb.treeStorage.Header() - if err != nil { - return nil, nil, err - } - - for _, r := range possibleRoots { - if r.Id == header.FirstChangeId { - return buf, r, nil - } - } - - return nil, nil, fmt.Errorf("could not find root change") -} - -func (tb *aclTreeBuilder) getACLHeads(heads []string) (aclTreeHeads []string, err error) { - for _, head := range heads { - if slice.FindPos(aclTreeHeads, head) != -1 { // do not scan known heads - continue - } - precedingHeads, err := tb.getPrecedingACLHeads(head) - if err != nil { - continue - } - - for _, aclHead := range precedingHeads { - if slice.FindPos(aclTreeHeads, aclHead) != -1 { - continue - } - aclTreeHeads = append(aclTreeHeads, aclHead) - } - } - - if len(aclTreeHeads) == 0 { - return nil, fmt.Errorf("no usable ACL heads in tree storage") - } - return aclTreeHeads, nil -} - -func (tb *aclTreeBuilder) getPrecedingACLHeads(head string) ([]string, error) { - headChange, err := tb.loadChange(head) - if err != nil { - return nil, err - } - - if headChange.Content.GetAclData() != nil { - return []string{head}, nil - } else { - return headChange.PreviousIds, nil - } -} diff --git a/pkg/acl/acltree/acltreestorage.go b/pkg/acl/acltree/acltreestorage.go deleted file mode 100644 index df03898a..00000000 --- a/pkg/acl/acltree/acltreestorage.go +++ /dev/null @@ -1,70 +0,0 @@ -package acltree - -import ( - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/cid" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey" - "github.com/gogo/protobuf/proto" -) - -func CreateNewTreeStorageWithACL( - acc *account.AccountData, - build func(builder ChangeBuilder) error, - create treestorage.CreatorFunc) (treestorage.TreeStorage, error) { - bld := newChangeBuilder() - bld.Init( - newACLState(acc.Identity, acc.EncKey, signingkey.NewEd25519PubKeyDecoder()), - &Tree{}, - acc) - err := build(bld) - if err != nil { - return nil, err - } - bld.SetMakeSnapshot(true) - - change, payload, err := bld.BuildAndApply() - if err != nil { - return nil, err - } - - rawChange := &aclpb.RawChange{ - Payload: payload, - Signature: change.Signature(), - Id: change.CID(), - } - header, id, err := createTreeHeaderAndId(rawChange) - if err != nil { - return nil, err - } - - thr, err := create(id, header, []*aclpb.RawChange{rawChange}) - if err != nil { - return nil, err - } - - err = thr.SetHeads([]string{change.CID()}) - if err != nil { - return nil, err - } - return thr, nil -} - -func createTreeHeaderAndId(change *aclpb.RawChange) (*treepb.TreeHeader, string, error) { - header := &treepb.TreeHeader{ - FirstChangeId: change.Id, - IsWorkspace: false, - } - marshalledHeader, err := proto.Marshal(header) - if err != nil { - return nil, "", err - } - treeId, err := cid.NewCIDFromBytes(marshalledHeader) - if err != nil { - return nil, "", err - } - - return header, treeId, nil -} diff --git a/pkg/acl/acltree/acltreestorage_test.go b/pkg/acl/acltree/acltreestorage_test.go deleted file mode 100644 index 8730a542..00000000 --- a/pkg/acl/acltree/acltreestorage_test.go +++ /dev/null @@ -1,63 +0,0 @@ -package acltree - -import ( - "context" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/treestoragebuilder" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage" - "github.com/stretchr/testify/assert" - "testing" -) - -func Test_BuildTreeStorageWithACL(t *testing.T) { - keychain := treestoragebuilder.NewKeychain() - keychain.AddSigningKey("A") - keychain.AddEncryptionKey("A") - data := &account.AccountData{ - Identity: keychain.GetIdentity("A"), - SignKey: keychain.SigningKeys["A"], - EncKey: keychain.EncryptionKeys["A"], - } - thr, err := CreateNewTreeStorageWithACL( - data, - func(builder ChangeBuilder) error { - return builder.UserAdd( - keychain.GetIdentity("A"), - keychain.EncryptionKeys["A"].GetPublic(), - aclpb.ACLChange_Admin) - }, - treestorage.NewInMemoryTreeStorage) - if err != nil { - t.Fatalf("build should not return error") - } - - heads, err := thr.Heads() - if err != nil { - t.Fatalf("should return heads: %v", err) - } - if len(heads) == 0 { - t.Fatalf("tree storage should have non-empty heads") - } - - header, err := thr.Header() - if err != nil { - t.Fatalf("tree storage header should return without error: %v", err) - } - assert.Equal(t, heads[0], header.FirstChangeId) - - treeId, err := thr.TreeID() - if err != nil { - t.Fatalf("tree id should return without error: %v", err) - } - assert.NotEmpty(t, treeId) - ch, err := thr.GetChange(context.Background(), header.FirstChangeId) - if err != nil { - t.Fatalf("get change should not return error: %v", err) - } - - _, err = NewFromRawChange(ch) - if err != nil { - t.Fatalf("we should be able to unmarshall change: %v", err) - } -} diff --git a/pkg/acl/acltree/change.go b/pkg/acl/acltree/change.go deleted file mode 100644 index c768ef23..00000000 --- a/pkg/acl/acltree/change.go +++ /dev/null @@ -1,97 +0,0 @@ -package acltree - -import ( - "fmt" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb" - "github.com/gogo/protobuf/proto" - - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/symmetric" -) - -type ChangeContent struct { - ChangesData proto.Marshaler - ACLData *aclpb.ACLChangeACLData - Id string // TODO: this is just for testing, because id should be created automatically from content -} - -// Change is an abstract type for all types of changes -type Change struct { - Next []*Change - Unattached []*Change - PreviousIds []string - Id string - SnapshotId string - IsSnapshot bool - DecryptedDocumentChange []byte - - Content *aclpb.ACLChange - Sign []byte -} - -func (ch *Change) DecryptContents(key *symmetric.Key) error { - if ch.Content.ChangesData == nil { - return nil - } - - decrypted, err := key.Decrypt(ch.Content.ChangesData) - if err != nil { - return fmt.Errorf("failed to decrypt changes data: %w", err) - } - - ch.DecryptedDocumentChange = decrypted - return nil -} - -func (ch *Change) IsACLChange() bool { - return ch.Content.GetAclData() != nil -} - -func NewFromRawChange(rawChange *aclpb.RawChange) (*Change, error) { - unmarshalled := &aclpb.ACLChange{} - err := proto.Unmarshal(rawChange.Payload, unmarshalled) - if err != nil { - return nil, err - } - - ch := NewChange(rawChange.Id, unmarshalled) - ch.Sign = rawChange.Signature - return ch, nil -} - -func NewChange(id string, ch *aclpb.ACLChange) *Change { - return &Change{ - Next: nil, - PreviousIds: ch.TreeHeadIds, - Id: id, - Content: ch, - SnapshotId: ch.SnapshotBaseId, - IsSnapshot: ch.GetAclData().GetAclSnapshot() != nil, - } -} - -func NewACLChange(id string, ch *aclpb.ACLChange) *Change { - return &Change{ - Next: nil, - PreviousIds: ch.AclHeadIds, - Id: id, - Content: ch, - SnapshotId: ch.SnapshotBaseId, - IsSnapshot: ch.GetAclData().GetAclSnapshot() != nil, - } -} - -func (ch *Change) ProtoChange() *aclpb.ACLChange { - return ch.Content -} - -func (ch *Change) DecryptedChangeContent() []byte { - return ch.DecryptedDocumentChange -} - -func (ch *Change) Signature() []byte { - return ch.Sign -} - -func (ch *Change) CID() string { - return ch.Id -} diff --git a/pkg/acl/acltree/changebuilder.go b/pkg/acl/acltree/changebuilder.go deleted file mode 100644 index b5b26b63..00000000 --- a/pkg/acl/acltree/changebuilder.go +++ /dev/null @@ -1,163 +0,0 @@ -package acltree - -import ( - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/cid" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/symmetric" - "github.com/gogo/protobuf/proto" - "hash/fnv" - "time" -) - -type MarshalledChange = []byte - -type ACLChangeBuilder interface { - UserAdd(identity string, encryptionKey encryptionkey.PubKey, permissions aclpb.ACLChangeUserPermissions) error - AddId(id string) // TODO: this is only for testing - SetMakeSnapshot(bool) // TODO: who should decide this? probably ACLTree so we can delete it -} - -type ChangeBuilder interface { - ACLChangeBuilder - AddChangeContent(marshaler proto.Marshaler) // user code should be responsible for making regular snapshots -} - -type changeBuilder struct { - aclState *ACLState - tree *Tree - acc *account.AccountData - - aclData *aclpb.ACLChangeACLData - changeContent proto.Marshaler - id string - makeSnapshot bool - readKey *symmetric.Key - readKeyHash uint64 -} - -func newChangeBuilder() *changeBuilder { - return &changeBuilder{} -} - -func (c *changeBuilder) Init(state *ACLState, tree *Tree, acc *account.AccountData) { - c.aclState = state - c.tree = tree - c.acc = acc - - c.aclData = &aclpb.ACLChangeACLData{} - // setting read key for further encryption etc - if state.currentReadKeyHash == 0 { - c.readKey, _ = symmetric.NewRandom() - - hasher := fnv.New64() - hasher.Write(c.readKey.Bytes()) - c.readKeyHash = hasher.Sum64() - } else { - c.readKey = c.aclState.userReadKeys[c.aclState.currentReadKeyHash] - c.readKeyHash = c.aclState.currentReadKeyHash - } -} - -func (c *changeBuilder) AddId(id string) { - c.id = id -} - -func (c *changeBuilder) SetMakeSnapshot(b bool) { - c.makeSnapshot = b -} - -func (c *changeBuilder) UserAdd(identity string, encryptionKey encryptionkey.PubKey, permissions aclpb.ACLChangeUserPermissions) error { - var allKeys []*symmetric.Key - if c.aclState.currentReadKeyHash != 0 { - for _, key := range c.aclState.userReadKeys { - allKeys = append(allKeys, key) - } - } else { - allKeys = append(allKeys, c.readKey) - } - - var encryptedKeys [][]byte - for _, k := range allKeys { - res, err := encryptionKey.Encrypt(k.Bytes()) - if err != nil { - return err - } - - encryptedKeys = append(encryptedKeys, res) - } - rawKey, err := encryptionKey.Raw() - if err != nil { - return err - } - ch := &aclpb.ACLChangeACLContentValue{ - Value: &aclpb.ACLChangeACLContentValueValueOfUserAdd{ - UserAdd: &aclpb.ACLChangeUserAdd{ - Identity: identity, - EncryptionKey: rawKey, - EncryptedReadKeys: encryptedKeys, - Permissions: permissions, - }, - }, - } - c.aclData.AclContent = append(c.aclData.AclContent, ch) - return nil -} - -func (c *changeBuilder) BuildAndApply() (*Change, []byte, error) { - aclChange := &aclpb.ACLChange{ - TreeHeadIds: c.tree.Heads(), - AclHeadIds: c.tree.ACLHeads(), - SnapshotBaseId: c.tree.RootId(), - AclData: c.aclData, - CurrentReadKeyHash: c.readKeyHash, - Timestamp: int64(time.Now().Nanosecond()), - Identity: c.acc.Identity, - } - err := c.aclState.applyChange(aclChange) - if err != nil { - return nil, nil, err - } - - if c.makeSnapshot { - c.aclData.AclSnapshot = c.aclState.makeSnapshot() - } - - var marshalled []byte - if c.changeContent != nil { - marshalled, err = c.changeContent.Marshal() - if err != nil { - return nil, nil, err - } - - encrypted, err := c.aclState.userReadKeys[c.aclState.currentReadKeyHash]. - Encrypt(marshalled) - if err != nil { - return nil, nil, err - } - aclChange.ChangesData = encrypted - } - - fullMarshalledChange, err := proto.Marshal(aclChange) - if err != nil { - return nil, nil, err - } - signature, err := c.acc.SignKey.Sign(fullMarshalledChange) - if err != nil { - return nil, nil, err - } - id, err := cid.NewCIDFromBytes(fullMarshalledChange) - if err != nil { - return nil, nil, err - } - ch := NewChange(id, aclChange) - ch.DecryptedDocumentChange = marshalled - ch.Sign = signature - - return ch, fullMarshalledChange, nil -} - -func (c *changeBuilder) AddChangeContent(marshaler proto.Marshaler) { - c.changeContent = marshaler -} diff --git a/pkg/acl/acltree/changeloader.go b/pkg/acl/acltree/changeloader.go deleted file mode 100644 index b308397a..00000000 --- a/pkg/acl/acltree/changeloader.go +++ /dev/null @@ -1,99 +0,0 @@ -package acltree - -import ( - "context" - "fmt" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey" - "time" - - "github.com/gogo/protobuf/proto" -) - -type changeLoader struct { - cache map[string]*Change - identityKeys map[string]signingkey.PubKey - signingPubKeyDecoder signingkey.PubKeyDecoder - treeStorage treestorage.TreeStorage - changeCreator func(id string, ch *aclpb.ACLChange) *Change -} - -func newChangeLoader( - treeStorage treestorage.TreeStorage, - signingPubKeyDecoder signingkey.PubKeyDecoder, - changeCreator func(id string, ch *aclpb.ACLChange) *Change) *changeLoader { - return &changeLoader{ - signingPubKeyDecoder: signingPubKeyDecoder, - treeStorage: treeStorage, - changeCreator: changeCreator, - } -} - -func (c *changeLoader) Init(cache map[string]*Change, - identityKeys map[string]signingkey.PubKey) { - c.cache = cache - c.identityKeys = identityKeys -} - -func (c *changeLoader) loadChange(id string) (ch *Change, err error) { - if ch, ok := c.cache[id]; ok { - return ch, nil - } - - // TODO: Add virtual changes logic - ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) - defer cancel() - - change, err := c.treeStorage.GetChange(ctx, id) - if err != nil { - return nil, err - } - - aclChange, err := c.makeVerifiedACLChange(change) - if err != nil { - return nil, err - } - - ch = c.changeCreator(id, aclChange) - c.cache[id] = ch - - return ch, nil -} - -func (c *changeLoader) verify(identity string, payload, signature []byte) (isVerified bool, err error) { - identityKey, exists := c.identityKeys[identity] - if !exists { - identityKey, err = c.signingPubKeyDecoder.DecodeFromString(identity) - if err != nil { - return - } - c.identityKeys[identity] = identityKey - } - return identityKey.Verify(payload, signature) -} - -func (c *changeLoader) makeVerifiedACLChange(change *aclpb.RawChange) (aclChange *aclpb.ACLChange, err error) { - aclChange = new(aclpb.ACLChange) - - // TODO: think what should we do with such cases, because this can be used by attacker to break our Tree - if err = proto.Unmarshal(change.Payload, aclChange); err != nil { - return - } - var verified bool - verified, err = c.verify(aclChange.Identity, change.Payload, change.Signature) - if err != nil { - return - } - if !verified { - err = fmt.Errorf("the signature of the payload cannot be verified") - return - } - return -} - -func (c *changeLoader) makeUnverifiedACLChange(change *aclpb.RawChange) (aclChange *aclpb.ACLChange, err error) { - aclChange = new(aclpb.ACLChange) - err = proto.Unmarshal(change.Payload, aclChange) - return -} diff --git a/pkg/acl/acltree/snapshotvalidator.go b/pkg/acl/acltree/snapshotvalidator.go deleted file mode 100644 index 8df94d32..00000000 --- a/pkg/acl/acltree/snapshotvalidator.go +++ /dev/null @@ -1,50 +0,0 @@ -package acltree - -import ( - "fmt" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey" -) - -type snapshotValidator struct { - aclTree *Tree - identity string - key encryptionkey.PrivKey - decoder signingkey.PubKeyDecoder - stateBuilder *aclStateBuilder -} - -func newSnapshotValidator( - decoder signingkey.PubKeyDecoder, - accountData *account.AccountData) *snapshotValidator { - return &snapshotValidator{ - identity: accountData.Identity, - key: accountData.EncKey, - decoder: decoder, - stateBuilder: newACLStateBuilder(decoder, accountData), - } -} - -func (s *snapshotValidator) Init(aclTree *Tree) error { - s.aclTree = aclTree - return s.stateBuilder.Init(aclTree) -} - -func (s *snapshotValidator) ValidateSnapshot(ch *Change) (bool, error) { - st, found, err := s.stateBuilder.BuildBefore(ch.Id) - if err != nil { - return false, err - } - - if !found { - return false, fmt.Errorf("didn't find snapshot in ACL Tree") - } - - otherSt, err := newACLStateFromSnapshotChange(ch.Content, s.identity, s.key, s.decoder) - if err != nil { - return false, err - } - - return st.equal(otherSt), nil -} diff --git a/pkg/acl/acltree/treebuilder_test.go b/pkg/acl/acltree/treebuilder_test.go deleted file mode 100644 index cc586148..00000000 --- a/pkg/acl/acltree/treebuilder_test.go +++ /dev/null @@ -1,64 +0,0 @@ -package acltree - -//func createTreeFromThread(t thread.Thread, fromStart bool) (*Tree, error) { -// treeBuilder := newTreeBuilder(t, keys.NewEd25519Decoder()) -// treeBuilder.Init() -// return treeBuilder.Build(fromStart) -//} -// -//func TestACLTreeBuilder_UserJoinCorrectHeadsAndLen(t *testing.T) { -// thread, err := threadbuilder.NewThreadBuilderWithTestName("threadbuilder/userjoinexample.yml") -// if err != nil { -// t.Fatal(err) -// } -// -// res, err := createTreeFromThread(thread) -// if err != nil { -// t.Fatalf("build Tree should not result in an error: %v", res) -// } -// -// assert.equal(t, res.Heads(), []string{"C.1.1"}) -// assert.equal(t, res.Len(), 4) -//} -// -//func TestTreeBuilder_UserJoinTestTreeIterate(t *testing.T) { -// thread, err := threadbuilder.NewThreadBuilderWithTestName("threadbuilder/userjoinexample.yml") -// if err != nil { -// t.Fatal(err) -// } -// -// res, err := createTreeFromThread(thread) -// if err != nil { -// t.Fatalf("build Tree should not result in an error: %v", res) -// } -// -// assert.equal(t, res.Heads(), []string{"C.1.1"}) -// assert.equal(t, res.Len(), 4) -// var changeIds []string -// res.iterate(res.root, func(c *Change) (isContinue bool) { -// changeIds = append(changeIds, c.Id) -// return true -// }) -// assert.equal(t, changeIds, []string{"A.1.1", "A.1.2", "B.1.1", "C.1.1"}) -//} -// -//func TestTreeBuilder_UserRemoveTestTreeIterate(t *testing.T) { -// thread, err := threadbuilder.NewThreadBuilderWithTestName("threadbuilder/userremoveexample.yml") -// if err != nil { -// t.Fatal(err) -// } -// -// res, err := createTreeFromThread(thread) -// if err != nil { -// t.Fatalf("build Tree should not result in an error: %v", res) -// } -// -// assert.equal(t, res.Heads(), []string{"A.1.3"}) -// assert.equal(t, res.Len(), 4) -// var changeIds []string -// res.iterate(res.root, func(c *Change) (isContinue bool) { -// changeIds = append(changeIds, c.Id) -// return true -// }) -// assert.equal(t, changeIds, []string{"A.1.1", "A.1.2", "B.1.1", "A.1.3"}) -//} diff --git a/pkg/acl/acltree/treeiterator.go b/pkg/acl/acltree/treeiterator.go deleted file mode 100644 index 19a20095..00000000 --- a/pkg/acl/acltree/treeiterator.go +++ /dev/null @@ -1,158 +0,0 @@ -package acltree - -import "sync" - -var itPool = &sync.Pool{ - New: func() interface{} { - return &iterator{} - }, -} - -func newIterator() *iterator { - return itPool.Get().(*iterator) -} - -func freeIterator(i *iterator) { - itPool.Put(i) -} - -type iterator struct { - compBuf []*Change - queue []*Change - doneMap map[*Change]struct{} - breakpoint *Change - f func(c *Change) bool -} - -func (i *iterator) iterateSkip(start *Change, skipBefore *Change, f func(c *Change) (isContinue bool)) { - skipping := true - i.iterate(start, func(c *Change) (isContinue bool) { - if skipping && c != skipBefore { - return true - } - skipping = false - return f(c) - }) -} - -func (i *iterator) iterate(start *Change, f func(c *Change) (isContinue bool)) { - if start == nil { - return - } - // reset - i.queue = i.queue[:0] - i.compBuf = i.compBuf[:0] - i.doneMap = make(map[*Change]struct{}) - i.queue = append(i.queue, start) - i.breakpoint = nil - i.f = f - - for len(i.queue) > 0 { - c := i.queue[0] - i.queue = i.queue[1:] - nl := len(c.Next) - if nl == 1 { - if !i.iterateLin(c) { - return - } - if i.breakpoint != nil { - i.toQueue(i.breakpoint) - i.breakpoint = nil - } - } else { - _, done := i.doneMap[c] - if !done { - if !f(c) { - return - } - i.doneMap[c] = struct{}{} - } - if nl != 0 { - for _, next := range c.Next { - i.toQueue(next) - } - } - } - } -} - -func (i *iterator) iterateLin(c *Change) bool { - for len(c.Next) == 1 { - _, done := i.doneMap[c] - if !done { - if !i.f(c) { - return false - } - i.doneMap[c] = struct{}{} - } - - c = c.Next[0] - if len(c.PreviousIds) > 1 { - break - } - } - if len(c.Next) == 0 && len(c.PreviousIds) <= 1 { - if !i.f(c) { - return false - } - i.doneMap[c] = struct{}{} - } else { - i.breakpoint = c - } - - return true -} - -func (i *iterator) comp(c1, c2 *Change) uint8 { - if c1.Id == c2.Id { - return 0 - } - i.compBuf = i.compBuf[:0] - i.compBuf = append(i.compBuf, c1.Next...) - var uniq = make(map[*Change]struct{}) - var appendUniqueToBuf = func(next []*Change) { - for _, n := range next { - if _, ok := uniq[n]; !ok { - i.compBuf = append(i.compBuf, n) - uniq[n] = struct{}{} - } - } - } - var used int - for len(i.compBuf)-used > 0 { - l := len(i.compBuf) - used - for _, n := range i.compBuf[used:] { - delete(uniq, n) - if n.Id == c2.Id { - return 1 - } else { - appendUniqueToBuf(n.Next) - } - } - used += l - } - return 2 -} - -func (i *iterator) toQueue(c *Change) { - var pos = -1 -For: - for idx, qc := range i.queue { - switch i.comp(c, qc) { - // exists - case 0: - return - // - case 1: - pos = idx - break For - } - } - if pos == -1 { - i.queue = append(i.queue, c) - } else if pos == 0 { - i.queue = append([]*Change{c}, i.queue...) - } else { - i.queue = append(i.queue[:pos], append([]*Change{c}, i.queue[pos:]...)...) - } -} diff --git a/pkg/acl/example/plaintextdocument/document.go b/pkg/acl/example/plaintextdocument/document.go deleted file mode 100644 index d97bf430..00000000 --- a/pkg/acl/example/plaintextdocument/document.go +++ /dev/null @@ -1,169 +0,0 @@ -package plaintextdocument - -import ( - "context" - "fmt" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account" - aclpb "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/acltree" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/testchanges/testchangepb" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage" - - "github.com/gogo/protobuf/proto" -) - -type PlainTextDocument interface { - Text() string - AddText(ctx context.Context, text string) error -} - -// TODO: this struct is not thread-safe, so use it wisely :-) -type plainTextDocument struct { - heads []string - aclTree acltree.ACLTree - state *DocumentState -} - -func (p *plainTextDocument) Text() string { - if p.state != nil { - return p.state.Text - } - return "" -} - -func (p *plainTextDocument) AddText(ctx context.Context, text string) error { - _, err := p.aclTree.AddContent(ctx, func(builder acltree.ChangeBuilder) error { - builder.AddChangeContent( - &testchangepb.PlainTextChangeData{ - Content: []*testchangepb.PlainTextChangeContent{ - createAppendTextChangeContent(text), - }, - }) - return nil - }) - return err -} - -func (p *plainTextDocument) Update(tree acltree.ACLTree) { - p.aclTree = tree - var err error - defer func() { - if err != nil { - fmt.Println("rebuild has returned error:", err) - } - }() - - prevHeads := p.heads - p.heads = tree.Heads() - startId := prevHeads[0] - tree.IterateFrom(startId, func(change *acltree.Change) (isContinue bool) { - if change.Id == startId { - return true - } - if change.DecryptedDocumentChange != nil { - p.state, err = p.state.ApplyChange(change.DecryptedDocumentChange, change.Id) - if err != nil { - return false - } - } - return true - }) -} - -func (p *plainTextDocument) Rebuild(tree acltree.ACLTree) { - p.aclTree = tree - p.heads = tree.Heads() - var startId string - var err error - defer func() { - if err != nil { - fmt.Println("rebuild has returned error:", err) - } - }() - - rootChange := tree.Root() - - if rootChange.DecryptedDocumentChange == nil { - err = fmt.Errorf("root doesn't have decrypted change") - return - } - - state, err := BuildDocumentStateFromChange(rootChange.DecryptedDocumentChange, rootChange.Id) - if err != nil { - return - } - - startId = rootChange.Id - tree.Iterate(func(change *acltree.Change) (isContinue bool) { - if startId == change.Id { - return true - } - if change.DecryptedDocumentChange != nil { - state, err = state.ApplyChange(change.DecryptedDocumentChange, change.Id) - if err != nil { - return false - } - } - return true - }) - if err != nil { - return - } - p.state = state -} - -func NewInMemoryPlainTextDocument(acc *account.AccountData, text string) (PlainTextDocument, error) { - return NewPlainTextDocument(acc, treestorage.NewInMemoryTreeStorage, text) -} - -func NewPlainTextDocument( - acc *account.AccountData, - create treestorage.CreatorFunc, - text string) (PlainTextDocument, error) { - changeBuilder := func(builder acltree.ChangeBuilder) error { - err := builder.UserAdd(acc.Identity, acc.EncKey.GetPublic(), aclpb.ACLChange_Admin) - if err != nil { - return err - } - builder.AddChangeContent(createInitialChangeContent(text)) - return nil - } - t, err := acltree.CreateNewTreeStorageWithACL( - acc, - changeBuilder, - create) - if err != nil { - return nil, err - } - - doc := &plainTextDocument{ - heads: nil, - aclTree: nil, - state: nil, - } - tree, err := acltree.BuildACLTree(t, acc, doc) - if err != nil { - return nil, err - } - doc.aclTree = tree - return doc, nil -} - -func createInitialChangeContent(text string) proto.Marshaler { - return &testchangepb.PlainTextChangeData{ - Content: []*testchangepb.PlainTextChangeContent{ - createAppendTextChangeContent(text), - }, - Snapshot: &testchangepb.PlainTextChangeSnapshot{Text: text}, - } -} - -func createAppendTextChangeContent(text string) *testchangepb.PlainTextChangeContent { - return &testchangepb.PlainTextChangeContent{ - Value: &testchangepb.PlainTextChangeContentValueOfTextAppend{ - TextAppend: &testchangepb.PlainTextChangeTextAppend{ - Text: text, - }, - }, - } -} diff --git a/pkg/acl/example/plaintextdocument/document_test.go b/pkg/acl/example/plaintextdocument/document_test.go deleted file mode 100644 index 7cabb4af..00000000 --- a/pkg/acl/example/plaintextdocument/document_test.go +++ /dev/null @@ -1,58 +0,0 @@ -package plaintextdocument - -import ( - "context" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/treestoragebuilder" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey" - "github.com/stretchr/testify/assert" - "testing" -) - -func TestDocument_NewPlainTextDocument(t *testing.T) { - keychain := treestoragebuilder.NewKeychain() - keychain.AddSigningKey("A") - keychain.AddEncryptionKey("A") - data := &account.AccountData{ - Identity: keychain.GetIdentity("A"), - SignKey: keychain.SigningKeys["A"], - EncKey: keychain.EncryptionKeys["A"], - Decoder: signingkey.NewEd25519PubKeyDecoder(), - } - - doc, err := NewPlainTextDocument(data, treestorage.NewInMemoryTreeStorage, "Some text") - if err != nil { - t.Fatalf("should not create document with error: %v", err) - } - assert.Equal(t, doc.Text(), "Some text") -} - -func TestDocument_PlainTextDocument_AddText(t *testing.T) { - keychain := treestoragebuilder.NewKeychain() - keychain.AddSigningKey("A") - keychain.AddEncryptionKey("A") - data := &account.AccountData{ - Identity: keychain.GetIdentity("A"), - SignKey: keychain.SigningKeys["A"], - EncKey: keychain.EncryptionKeys["A"], - Decoder: signingkey.NewEd25519PubKeyDecoder(), - } - - doc, err := NewPlainTextDocument(data, treestorage.NewInMemoryTreeStorage, "Some text") - if err != nil { - t.Fatalf("should not create document with error: %v", err) - } - - err = doc.AddText(context.Background(), "Next") - if err != nil { - t.Fatalf("should be able to add document: %v", err) - } - assert.Equal(t, doc.Text(), "Some text|Next") - - err = doc.AddText(context.Background(), "Shmext") - if err != nil { - t.Fatalf("should be able to add document: %v", err) - } - assert.Equal(t, doc.Text(), "Some text|Next|Shmext") -} diff --git a/pkg/acl/example/plaintextdocument/plaintextdocstate.go b/pkg/acl/example/plaintextdocument/plaintextdocstate.go deleted file mode 100644 index 3a3afec3..00000000 --- a/pkg/acl/example/plaintextdocument/plaintextdocstate.go +++ /dev/null @@ -1,59 +0,0 @@ -package plaintextdocument - -import ( - "fmt" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/testchanges/testchangepb" - - "github.com/gogo/protobuf/proto" -) - -type DocumentState struct { - LastChangeId string - Text string -} - -func NewDocumentState(text string, id string) *DocumentState { - return &DocumentState{ - LastChangeId: id, - Text: text, - } -} - -func BuildDocumentStateFromChange(change []byte, id string) (*DocumentState, error) { - var changesData testchangepb.PlainTextChangeData - err := proto.Unmarshal(change, &changesData) - if err != nil { - return nil, err - } - - if changesData.GetSnapshot() == nil { - return nil, fmt.Errorf("could not create state from empty snapshot") - } - return NewDocumentState(changesData.GetSnapshot().GetText(), id), nil -} - -func (p *DocumentState) ApplyChange(change []byte, id string) (*DocumentState, error) { - var changesData testchangepb.PlainTextChangeData - err := proto.Unmarshal(change, &changesData) - if err != nil { - return nil, err - } - - for _, content := range changesData.GetContent() { - err = p.applyChange(content) - if err != nil { - return nil, err - } - } - p.LastChangeId = id - return p, nil -} - -func (p *DocumentState) applyChange(ch *testchangepb.PlainTextChangeContent) error { - switch { - case ch.GetTextAppend() != nil: - text := ch.GetTextAppend().GetText() - p.Text += "|" + text - } - return nil -} diff --git a/pkg/acl/testutils/testchanges/testchangepb/protos/testdocumentchanges.proto b/pkg/acl/testutils/testchanges/testchangepb/protos/testdocumentchanges.proto deleted file mode 100644 index 59a97c38..00000000 --- a/pkg/acl/testutils/testchanges/testchangepb/protos/testdocumentchanges.proto +++ /dev/null @@ -1,26 +0,0 @@ -syntax = "proto3"; -package anytype; -option go_package = "testchangepb"; - -// TODO: move to separate package - -message PlainTextChange { - message Content { - oneof value { - TextAppend textAppend = 1; - } - } - - message TextAppend { - string text = 1; - } - - message Snapshot { - string text = 1; - } - - message Data { - repeated Content content = 1; - Snapshot snapshot = 2; - } -} diff --git a/pkg/acl/testutils/testchanges/testchangepb/testdocumentchanges.pb.go b/pkg/acl/testutils/testchanges/testchangepb/testdocumentchanges.pb.go deleted file mode 100644 index 874061c6..00000000 --- a/pkg/acl/testutils/testchanges/testchangepb/testdocumentchanges.pb.go +++ /dev/null @@ -1,1089 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: pkg/acl/testutils/testchanges/testchangepb/protos/testdocumentchanges.proto - -package testchangepb - -import ( - fmt "fmt" - proto "github.com/gogo/protobuf/proto" - io "io" - math "math" - math_bits "math/bits" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package - -type PlainTextChange struct { -} - -func (m *PlainTextChange) Reset() { *m = PlainTextChange{} } -func (m *PlainTextChange) String() string { return proto.CompactTextString(m) } -func (*PlainTextChange) ProtoMessage() {} -func (*PlainTextChange) Descriptor() ([]byte, []int) { - return fileDescriptor_c07268f9f08f2beb, []int{0} -} -func (m *PlainTextChange) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *PlainTextChange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_PlainTextChange.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *PlainTextChange) XXX_Merge(src proto.Message) { - xxx_messageInfo_PlainTextChange.Merge(m, src) -} -func (m *PlainTextChange) XXX_Size() int { - return m.Size() -} -func (m *PlainTextChange) XXX_DiscardUnknown() { - xxx_messageInfo_PlainTextChange.DiscardUnknown(m) -} - -var xxx_messageInfo_PlainTextChange proto.InternalMessageInfo - -type PlainTextChangeContent struct { - // Types that are valid to be assigned to Value: - // *PlainTextChangeContentValueOfTextAppend - Value IsPlainTextChangeContentValue `protobuf_oneof:"value"` -} - -func (m *PlainTextChangeContent) Reset() { *m = PlainTextChangeContent{} } -func (m *PlainTextChangeContent) String() string { return proto.CompactTextString(m) } -func (*PlainTextChangeContent) ProtoMessage() {} -func (*PlainTextChangeContent) Descriptor() ([]byte, []int) { - return fileDescriptor_c07268f9f08f2beb, []int{0, 0} -} -func (m *PlainTextChangeContent) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *PlainTextChangeContent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_PlainTextChangeContent.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *PlainTextChangeContent) XXX_Merge(src proto.Message) { - xxx_messageInfo_PlainTextChangeContent.Merge(m, src) -} -func (m *PlainTextChangeContent) XXX_Size() int { - return m.Size() -} -func (m *PlainTextChangeContent) XXX_DiscardUnknown() { - xxx_messageInfo_PlainTextChangeContent.DiscardUnknown(m) -} - -var xxx_messageInfo_PlainTextChangeContent proto.InternalMessageInfo - -type IsPlainTextChangeContentValue interface { - IsPlainTextChangeContentValue() - MarshalTo([]byte) (int, error) - Size() int -} - -type PlainTextChangeContentValueOfTextAppend struct { - TextAppend *PlainTextChangeTextAppend `protobuf:"bytes,1,opt,name=textAppend,proto3,oneof" json:"textAppend,omitempty"` -} - -func (*PlainTextChangeContentValueOfTextAppend) IsPlainTextChangeContentValue() {} - -func (m *PlainTextChangeContent) GetValue() IsPlainTextChangeContentValue { - if m != nil { - return m.Value - } - return nil -} - -func (m *PlainTextChangeContent) GetTextAppend() *PlainTextChangeTextAppend { - if x, ok := m.GetValue().(*PlainTextChangeContentValueOfTextAppend); ok { - return x.TextAppend - } - return nil -} - -// XXX_OneofWrappers is for the internal use of the proto package. -func (*PlainTextChangeContent) XXX_OneofWrappers() []interface{} { - return []interface{}{ - (*PlainTextChangeContentValueOfTextAppend)(nil), - } -} - -type PlainTextChangeTextAppend struct { - Text string `protobuf:"bytes,1,opt,name=text,proto3" json:"text,omitempty"` -} - -func (m *PlainTextChangeTextAppend) Reset() { *m = PlainTextChangeTextAppend{} } -func (m *PlainTextChangeTextAppend) String() string { return proto.CompactTextString(m) } -func (*PlainTextChangeTextAppend) ProtoMessage() {} -func (*PlainTextChangeTextAppend) Descriptor() ([]byte, []int) { - return fileDescriptor_c07268f9f08f2beb, []int{0, 1} -} -func (m *PlainTextChangeTextAppend) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *PlainTextChangeTextAppend) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_PlainTextChangeTextAppend.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *PlainTextChangeTextAppend) XXX_Merge(src proto.Message) { - xxx_messageInfo_PlainTextChangeTextAppend.Merge(m, src) -} -func (m *PlainTextChangeTextAppend) XXX_Size() int { - return m.Size() -} -func (m *PlainTextChangeTextAppend) XXX_DiscardUnknown() { - xxx_messageInfo_PlainTextChangeTextAppend.DiscardUnknown(m) -} - -var xxx_messageInfo_PlainTextChangeTextAppend proto.InternalMessageInfo - -func (m *PlainTextChangeTextAppend) GetText() string { - if m != nil { - return m.Text - } - return "" -} - -type PlainTextChangeSnapshot struct { - Text string `protobuf:"bytes,1,opt,name=text,proto3" json:"text,omitempty"` -} - -func (m *PlainTextChangeSnapshot) Reset() { *m = PlainTextChangeSnapshot{} } -func (m *PlainTextChangeSnapshot) String() string { return proto.CompactTextString(m) } -func (*PlainTextChangeSnapshot) ProtoMessage() {} -func (*PlainTextChangeSnapshot) Descriptor() ([]byte, []int) { - return fileDescriptor_c07268f9f08f2beb, []int{0, 2} -} -func (m *PlainTextChangeSnapshot) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *PlainTextChangeSnapshot) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_PlainTextChangeSnapshot.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *PlainTextChangeSnapshot) XXX_Merge(src proto.Message) { - xxx_messageInfo_PlainTextChangeSnapshot.Merge(m, src) -} -func (m *PlainTextChangeSnapshot) XXX_Size() int { - return m.Size() -} -func (m *PlainTextChangeSnapshot) XXX_DiscardUnknown() { - xxx_messageInfo_PlainTextChangeSnapshot.DiscardUnknown(m) -} - -var xxx_messageInfo_PlainTextChangeSnapshot proto.InternalMessageInfo - -func (m *PlainTextChangeSnapshot) GetText() string { - if m != nil { - return m.Text - } - return "" -} - -type PlainTextChangeData struct { - Content []*PlainTextChangeContent `protobuf:"bytes,1,rep,name=content,proto3" json:"content,omitempty"` - Snapshot *PlainTextChangeSnapshot `protobuf:"bytes,2,opt,name=snapshot,proto3" json:"snapshot,omitempty"` -} - -func (m *PlainTextChangeData) Reset() { *m = PlainTextChangeData{} } -func (m *PlainTextChangeData) String() string { return proto.CompactTextString(m) } -func (*PlainTextChangeData) ProtoMessage() {} -func (*PlainTextChangeData) Descriptor() ([]byte, []int) { - return fileDescriptor_c07268f9f08f2beb, []int{0, 3} -} -func (m *PlainTextChangeData) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *PlainTextChangeData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_PlainTextChangeData.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *PlainTextChangeData) XXX_Merge(src proto.Message) { - xxx_messageInfo_PlainTextChangeData.Merge(m, src) -} -func (m *PlainTextChangeData) XXX_Size() int { - return m.Size() -} -func (m *PlainTextChangeData) XXX_DiscardUnknown() { - xxx_messageInfo_PlainTextChangeData.DiscardUnknown(m) -} - -var xxx_messageInfo_PlainTextChangeData proto.InternalMessageInfo - -func (m *PlainTextChangeData) GetContent() []*PlainTextChangeContent { - if m != nil { - return m.Content - } - return nil -} - -func (m *PlainTextChangeData) GetSnapshot() *PlainTextChangeSnapshot { - if m != nil { - return m.Snapshot - } - return nil -} - -func init() { - proto.RegisterType((*PlainTextChange)(nil), "anytype.PlainTextChange") - proto.RegisterType((*PlainTextChangeContent)(nil), "anytype.PlainTextChange.Content") - proto.RegisterType((*PlainTextChangeTextAppend)(nil), "anytype.PlainTextChange.TextAppend") - proto.RegisterType((*PlainTextChangeSnapshot)(nil), "anytype.PlainTextChange.Snapshot") - proto.RegisterType((*PlainTextChangeData)(nil), "anytype.PlainTextChange.Data") -} - -func init() { - proto.RegisterFile("pkg/acl/testutils/testchanges/testchangepb/protos/testdocumentchanges.proto", fileDescriptor_c07268f9f08f2beb) -} - -var fileDescriptor_c07268f9f08f2beb = []byte{ - // 278 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xf2, 0x2e, 0xc8, 0x4e, 0xd7, - 0x4f, 0x4c, 0xce, 0xd1, 0x2f, 0x49, 0x2d, 0x2e, 0x29, 0x2d, 0xc9, 0xcc, 0x29, 0x06, 0xb3, 0x92, - 0x33, 0x12, 0xf3, 0xd2, 0x53, 0x91, 0xd9, 0x05, 0x49, 0xfa, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x10, - 0xb1, 0x94, 0xfc, 0xe4, 0xd2, 0xdc, 0xd4, 0x3c, 0x98, 0x3a, 0x3d, 0xb0, 0x94, 0x10, 0x7b, 0x62, - 0x5e, 0x65, 0x49, 0x65, 0x41, 0xaa, 0xd2, 0x26, 0x26, 0x2e, 0xfe, 0x80, 0x9c, 0xc4, 0xcc, 0xbc, - 0x90, 0xd4, 0x8a, 0x12, 0x67, 0xb0, 0x1a, 0xa9, 0x48, 0x2e, 0x76, 0xe7, 0xfc, 0xbc, 0x92, 0xd4, - 0xbc, 0x12, 0x21, 0x57, 0x2e, 0xae, 0x92, 0xd4, 0x8a, 0x12, 0xc7, 0x82, 0x82, 0xd4, 0xbc, 0x14, - 0x09, 0x46, 0x05, 0x46, 0x0d, 0x6e, 0x23, 0x65, 0x3d, 0xa8, 0x66, 0x3d, 0x34, 0x8d, 0x7a, 0x21, - 0x70, 0xa5, 0x1e, 0x0c, 0x41, 0x48, 0x1a, 0x9d, 0xd8, 0xb9, 0x58, 0xcb, 0x12, 0x73, 0x4a, 0x53, - 0xa5, 0x14, 0xb8, 0xb8, 0x10, 0x8a, 0x84, 0x84, 0xb8, 0x58, 0x40, 0x8a, 0xc0, 0xe6, 0x72, 0x06, - 0x81, 0xd9, 0x52, 0x72, 0x5c, 0x1c, 0xc1, 0x79, 0x89, 0x05, 0xc5, 0x19, 0xf9, 0x25, 0x58, 0xe5, - 0x1b, 0x19, 0xb9, 0x58, 0x5c, 0x12, 0x4b, 0x12, 0x85, 0xac, 0xb8, 0xd8, 0x93, 0x21, 0xae, 0x94, - 0x60, 0x54, 0x60, 0xd6, 0xe0, 0x36, 0x52, 0xc0, 0xe9, 0x2e, 0xa8, 0x6f, 0x82, 0x60, 0x1a, 0x84, - 0x6c, 0xb9, 0x38, 0x8a, 0xa1, 0x96, 0x48, 0x30, 0x81, 0x3d, 0xa5, 0x88, 0x53, 0x33, 0xcc, 0x35, - 0x41, 0x70, 0x2d, 0x4e, 0x6a, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, - 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, 0xdc, 0x78, 0x2c, 0xc7, 0x10, 0xc5, - 0x83, 0x1c, 0x0d, 0x49, 0x6c, 0xe0, 0xc0, 0x36, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0xfd, 0x73, - 0xe1, 0xf2, 0xbb, 0x01, 0x00, 0x00, -} - -func (m *PlainTextChange) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *PlainTextChange) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *PlainTextChange) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - return len(dAtA) - i, nil -} - -func (m *PlainTextChangeContent) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *PlainTextChangeContent) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *PlainTextChangeContent) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Value != nil { - { - size := m.Value.Size() - i -= size - if _, err := m.Value.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - } - } - return len(dAtA) - i, nil -} - -func (m *PlainTextChangeContentValueOfTextAppend) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *PlainTextChangeContentValueOfTextAppend) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.TextAppend != nil { - { - size, err := m.TextAppend.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTestdocumentchanges(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} -func (m *PlainTextChangeTextAppend) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *PlainTextChangeTextAppend) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *PlainTextChangeTextAppend) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Text) > 0 { - i -= len(m.Text) - copy(dAtA[i:], m.Text) - i = encodeVarintTestdocumentchanges(dAtA, i, uint64(len(m.Text))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *PlainTextChangeSnapshot) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *PlainTextChangeSnapshot) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *PlainTextChangeSnapshot) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Text) > 0 { - i -= len(m.Text) - copy(dAtA[i:], m.Text) - i = encodeVarintTestdocumentchanges(dAtA, i, uint64(len(m.Text))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *PlainTextChangeData) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *PlainTextChangeData) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *PlainTextChangeData) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Snapshot != nil { - { - size, err := m.Snapshot.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTestdocumentchanges(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if len(m.Content) > 0 { - for iNdEx := len(m.Content) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Content[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTestdocumentchanges(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - -func encodeVarintTestdocumentchanges(dAtA []byte, offset int, v uint64) int { - offset -= sovTestdocumentchanges(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *PlainTextChange) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - return n -} - -func (m *PlainTextChangeContent) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Value != nil { - n += m.Value.Size() - } - return n -} - -func (m *PlainTextChangeContentValueOfTextAppend) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.TextAppend != nil { - l = m.TextAppend.Size() - n += 1 + l + sovTestdocumentchanges(uint64(l)) - } - return n -} -func (m *PlainTextChangeTextAppend) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Text) - if l > 0 { - n += 1 + l + sovTestdocumentchanges(uint64(l)) - } - return n -} - -func (m *PlainTextChangeSnapshot) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Text) - if l > 0 { - n += 1 + l + sovTestdocumentchanges(uint64(l)) - } - return n -} - -func (m *PlainTextChangeData) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.Content) > 0 { - for _, e := range m.Content { - l = e.Size() - n += 1 + l + sovTestdocumentchanges(uint64(l)) - } - } - if m.Snapshot != nil { - l = m.Snapshot.Size() - n += 1 + l + sovTestdocumentchanges(uint64(l)) - } - return n -} - -func sovTestdocumentchanges(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozTestdocumentchanges(x uint64) (n int) { - return sovTestdocumentchanges(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *PlainTextChange) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTestdocumentchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: PlainTextChange: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PlainTextChange: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipTestdocumentchanges(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthTestdocumentchanges - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *PlainTextChangeContent) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTestdocumentchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Content: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Content: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TextAppend", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTestdocumentchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTestdocumentchanges - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTestdocumentchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &PlainTextChangeTextAppend{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Value = &PlainTextChangeContentValueOfTextAppend{v} - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipTestdocumentchanges(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthTestdocumentchanges - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *PlainTextChangeTextAppend) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTestdocumentchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: TextAppend: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: TextAppend: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Text", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTestdocumentchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTestdocumentchanges - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTestdocumentchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Text = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipTestdocumentchanges(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthTestdocumentchanges - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *PlainTextChangeSnapshot) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTestdocumentchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Snapshot: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Snapshot: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Text", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTestdocumentchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTestdocumentchanges - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTestdocumentchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Text = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipTestdocumentchanges(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthTestdocumentchanges - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *PlainTextChangeData) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTestdocumentchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Data: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Data: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Content", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTestdocumentchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTestdocumentchanges - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTestdocumentchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Content = append(m.Content, &PlainTextChangeContent{}) - if err := m.Content[len(m.Content)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Snapshot", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTestdocumentchanges - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTestdocumentchanges - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTestdocumentchanges - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Snapshot == nil { - m.Snapshot = &PlainTextChangeSnapshot{} - } - if err := m.Snapshot.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipTestdocumentchanges(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthTestdocumentchanges - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipTestdocumentchanges(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowTestdocumentchanges - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowTestdocumentchanges - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowTestdocumentchanges - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthTestdocumentchanges - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupTestdocumentchanges - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthTestdocumentchanges - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthTestdocumentchanges = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowTestdocumentchanges = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupTestdocumentchanges = fmt.Errorf("proto: unexpected end of group") -) diff --git a/pkg/acl/testutils/treestoragebuilder/keychain.go b/pkg/acl/testutils/treestoragebuilder/keychain.go deleted file mode 100644 index 5635f072..00000000 --- a/pkg/acl/testutils/treestoragebuilder/keychain.go +++ /dev/null @@ -1,149 +0,0 @@ -package treestoragebuilder - -import ( - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey" - "hash/fnv" - "strings" - - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/symmetric" -) - -type SymKey struct { - Hash uint64 - Key *symmetric.Key -} - -type Keychain struct { - SigningKeys map[string]signingkey.PrivKey - SigningKeysByIdentity map[string]signingkey.PrivKey - EncryptionKeys map[string]encryptionkey.PrivKey - ReadKeys map[string]*SymKey - ReadKeysByHash map[uint64]*SymKey - GeneratedIdentities map[string]string - coder signingkey.PubKeyDecoder -} - -func NewKeychain() *Keychain { - return &Keychain{ - SigningKeys: map[string]signingkey.PrivKey{}, - SigningKeysByIdentity: map[string]signingkey.PrivKey{}, - EncryptionKeys: map[string]encryptionkey.PrivKey{}, - GeneratedIdentities: map[string]string{}, - ReadKeys: map[string]*SymKey{}, - ReadKeysByHash: map[uint64]*SymKey{}, - coder: signingkey.NewEd25519PubKeyDecoder(), - } -} - -func (k *Keychain) ParseKeys(keys *Keys) { - for _, encKey := range keys.Enc { - k.AddEncryptionKey(encKey) - } - - for _, signKey := range keys.Sign { - k.AddSigningKey(signKey) - } - - for _, readKey := range keys.Read { - k.AddReadKey(readKey) - } -} - -func (k *Keychain) AddEncryptionKey(name string) { - if _, exists := k.EncryptionKeys[name]; exists { - return - } - newPrivKey, _, err := encryptionkey.GenerateRandomRSAKeyPair(2048) - if err != nil { - panic(err) - } - - k.EncryptionKeys[name] = newPrivKey -} - -func (k *Keychain) AddSigningKey(name string) { - if _, exists := k.SigningKeys[name]; exists { - return - } - newPrivKey, pubKey, err := signingkey.GenerateRandomEd25519KeyPair() - if err != nil { - panic(err) - } - - k.SigningKeys[name] = newPrivKey - res, err := k.coder.EncodeToString(pubKey) - if err != nil { - panic(err) - } - k.SigningKeysByIdentity[res] = newPrivKey - k.GeneratedIdentities[name] = res -} - -func (k *Keychain) AddReadKey(name string) { - if _, exists := k.ReadKeys[name]; exists { - return - } - key, _ := symmetric.NewRandom() - - hasher := fnv.New64() - hasher.Write(key.Bytes()) - - k.ReadKeys[name] = &SymKey{ - Hash: hasher.Sum64(), - Key: key, - } - k.ReadKeysByHash[hasher.Sum64()] = &SymKey{ - Hash: hasher.Sum64(), - Key: key, - } -} - -func (k *Keychain) AddKey(key string) { - parts := strings.Split(key, ".") - if len(parts) != 3 { - panic("cannot parse a key") - } - name := parts[2] - - switch parts[1] { - case "Sign": - k.AddSigningKey(name) - case "Enc": - k.AddEncryptionKey(name) - case "Read": - k.AddReadKey(name) - default: - panic("incorrect format") - } -} - -func (k *Keychain) GetKey(key string) interface{} { - parts := strings.Split(key, ".") - if len(parts) != 3 { - panic("cannot parse a key") - } - name := parts[2] - - switch parts[1] { - case "Sign": - if key, exists := k.SigningKeys[name]; exists { - return key - } - case "Enc": - if key, exists := k.EncryptionKeys[name]; exists { - return key - } - case "Read": - if key, exists := k.ReadKeys[name]; exists { - return key - } - default: - panic("incorrect format") - } - return nil -} - -func (k *Keychain) GetIdentity(name string) string { - return k.GeneratedIdentities[name] -} diff --git a/pkg/acl/testutils/treestoragebuilder/treestoragebuilder.go b/pkg/acl/testutils/treestoragebuilder/treestoragebuilder.go deleted file mode 100644 index f7bb65bd..00000000 --- a/pkg/acl/testutils/treestoragebuilder/treestoragebuilder.go +++ /dev/null @@ -1,539 +0,0 @@ -package treestoragebuilder - -import ( - "context" - "fmt" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb" - testpb "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/testchanges/testchangepb" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/yamltests" - storagepb "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice" - "io/ioutil" - "path" - - "github.com/gogo/protobuf/proto" - "gopkg.in/yaml.v3" -) - -const plainTextDocType uint16 = 1 - -type treeChange struct { - *aclpb.ACLChange - id string - readKey *SymKey - signKey signingkey.PrivKey - - changesDataDecrypted []byte -} - -type updateUseCase struct { - changes map[string]*treeChange -} - -type TreeStorageBuilder struct { - treeId string - allChanges map[string]*treeChange - updates map[string]*updateUseCase - heads []string - orphans []string - keychain *Keychain - header *storagepb.TreeHeader -} - -func NewTreeStorageBuilder(keychain *Keychain) *TreeStorageBuilder { - return &TreeStorageBuilder{ - allChanges: make(map[string]*treeChange), - updates: make(map[string]*updateUseCase), - keychain: keychain, - } -} - -func NewTreeStorageBuilderWithTestName(name string) (*TreeStorageBuilder, error) { - filePath := path.Join(yamltests.Path(), name) - return NewTreeStorageBuilderFromFile(filePath) -} - -func NewTreeStorageBuilderFromFile(file string) (*TreeStorageBuilder, error) { - content, err := ioutil.ReadFile(file) - if err != nil { - return nil, err - } - - ymlTree := YMLTree{} - err = yaml.Unmarshal(content, &ymlTree) - if err != nil { - return nil, err - } - - tb := NewTreeStorageBuilder(NewKeychain()) - tb.Parse(&ymlTree) - - return tb, nil -} - -func (t *TreeStorageBuilder) TreeID() (string, error) { - return t.treeId, nil -} - -func (t *TreeStorageBuilder) GetKeychain() *Keychain { - return t.keychain -} - -func (t *TreeStorageBuilder) Heads() ([]string, error) { - return t.heads, nil -} - -func (t *TreeStorageBuilder) AddRawChange(change *aclpb.RawChange) error { - aclChange := new(aclpb.ACLChange) - var err error - - if err = proto.Unmarshal(change.Payload, aclChange); err != nil { - return fmt.Errorf("could not unmarshall changes") - } - var changesData []byte - - // get correct readkey - readKey := t.keychain.ReadKeysByHash[aclChange.CurrentReadKeyHash] - if aclChange.ChangesData != nil { - changesData, err = readKey.Key.Decrypt(aclChange.ChangesData) - if err != nil { - return fmt.Errorf("failed to decrypt changes data: %w", err) - } - } - - // get correct signing key - signKey := t.keychain.SigningKeysByIdentity[aclChange.Identity] - - t.allChanges[change.Id] = &treeChange{ - ACLChange: aclChange, - id: change.Id, - readKey: readKey, - signKey: signKey, - changesDataDecrypted: changesData, - } - return nil -} - -func (t *TreeStorageBuilder) AddOrphans(orphans ...string) error { - t.orphans = append(t.orphans, orphans...) - return nil -} - -func (t *TreeStorageBuilder) AddChange(change aclchanges.Change) error { - aclChange := change.ProtoChange() - var err error - var changesData []byte - - // get correct readkey - readKey := t.keychain.ReadKeysByHash[aclChange.CurrentReadKeyHash] - if aclChange.ChangesData != nil { - changesData, err = readKey.Key.Decrypt(aclChange.ChangesData) - if err != nil { - return fmt.Errorf("failed to decrypt changes data: %w", err) - } - } - - // get correct signing key - signKey := t.keychain.SigningKeysByIdentity[aclChange.Identity] - - t.allChanges[change.CID()] = &treeChange{ - ACLChange: aclChange, - id: change.CID(), - readKey: readKey, - signKey: signKey, - changesDataDecrypted: changesData, - } - return nil -} - -func (t *TreeStorageBuilder) Orphans() ([]string, error) { - return t.orphans, nil -} - -func (t *TreeStorageBuilder) SetHeads(heads []string) error { - // we should copy here instead of just setting the value - t.heads = heads - return nil -} - -func (t *TreeStorageBuilder) RemoveOrphans(orphans ...string) error { - t.orphans = slice.Difference(t.orphans, orphans) - return nil -} - -func (t *TreeStorageBuilder) GetChange(ctx context.Context, recordID string) (*aclpb.RawChange, error) { - return t.getChange(recordID, t.allChanges), nil -} - -func (t *TreeStorageBuilder) GetUpdates(useCase string) []*aclpb.RawChange { - var res []*aclpb.RawChange - update := t.updates[useCase] - for _, ch := range update.changes { - rawCh := t.getChange(ch.id, update.changes) - res = append(res, rawCh) - } - return res -} - -func (t *TreeStorageBuilder) Header() (*storagepb.TreeHeader, error) { - return t.header, nil -} - -func (t *TreeStorageBuilder) getChange(changeId string, m map[string]*treeChange) *aclpb.RawChange { - rec := m[changeId] - - if rec.changesDataDecrypted != nil { - encrypted, err := rec.readKey.Key.Encrypt(rec.changesDataDecrypted) - if err != nil { - panic("should be able to encrypt data with read key!") - } - - rec.ChangesData = encrypted - } - - aclMarshaled, err := proto.Marshal(rec.ACLChange) - if err != nil { - panic("should be able to marshal final acl message!") - } - - signature, err := rec.signKey.Sign(aclMarshaled) - if err != nil { - panic("should be able to sign final acl message!") - } - - transformedRec := &aclpb.RawChange{ - Payload: aclMarshaled, - Signature: signature, - Id: changeId, - } - return transformedRec -} - -func (t *TreeStorageBuilder) Parse(tree *YMLTree) { - // Just to clarify - we are generating new identities for the ones that - // are specified in the yml file, because our identities should be Ed25519 - // the same thing is happening for the encryption keys - t.keychain.ParseKeys(&tree.Keys) - t.treeId = t.parseTreeId(tree.Description) - for _, ch := range tree.Changes { - newChange := t.parseChange(ch) - t.allChanges[newChange.id] = newChange - } - - t.parseGraph(tree) - t.parseOrphans(tree) - t.parseHeader(tree) - t.parseUpdates(tree.Updates) -} - -func (t *TreeStorageBuilder) parseChange(ch *Change) *treeChange { - newChange := &treeChange{ - id: ch.Id, - } - k := t.keychain.GetKey(ch.ReadKey).(*SymKey) - newChange.readKey = k - newChange.signKey = t.keychain.SigningKeys[ch.Identity] - aclChange := &aclpb.ACLChange{} - aclChange.Identity = t.keychain.GetIdentity(ch.Identity) - if len(ch.AclChanges) > 0 || ch.AclSnapshot != nil { - aclChange.AclData = &aclpb.ACLChangeACLData{} - if ch.AclSnapshot != nil { - aclChange.AclData.AclSnapshot = t.parseACLSnapshot(ch.AclSnapshot) - } - if ch.AclChanges != nil { - var aclChangeContents []*aclpb.ACLChangeACLContentValue - for _, ch := range ch.AclChanges { - aclChangeContent := t.parseACLChange(ch) - aclChangeContents = append(aclChangeContents, aclChangeContent) - } - aclChange.AclData.AclContent = aclChangeContents - } - } - if len(ch.Changes) > 0 || ch.Snapshot != nil { - changesData := &testpb.PlainTextChangeData{} - if ch.Snapshot != nil { - changesData.Snapshot = t.parseChangeSnapshot(ch.Snapshot) - } - if len(ch.Changes) > 0 { - var changeContents []*testpb.PlainTextChangeContent - for _, ch := range ch.Changes { - aclChangeContent := t.parseDocumentChange(ch) - changeContents = append(changeContents, aclChangeContent) - } - changesData.Content = changeContents - } - m, err := proto.Marshal(changesData) - if err != nil { - return nil - } - newChange.changesDataDecrypted = m - } - aclChange.CurrentReadKeyHash = k.Hash - newChange.ACLChange = aclChange - return newChange -} - -func (t *TreeStorageBuilder) parseTreeId(description *TreeDescription) string { - if description == nil { - panic("no author in tree") - } - return description.Author + ".tree.id" -} - -func (t *TreeStorageBuilder) parseChangeSnapshot(s *PlainTextSnapshot) *testpb.PlainTextChangeSnapshot { - return &testpb.PlainTextChangeSnapshot{ - Text: s.Text, - } -} - -func (t *TreeStorageBuilder) parseACLSnapshot(s *ACLSnapshot) *aclpb.ACLChangeACLSnapshot { - newState := &aclpb.ACLChangeACLState{} - for _, state := range s.UserStates { - aclUserState := &aclpb.ACLChangeUserState{} - aclUserState.Identity = t.keychain.GetIdentity(state.Identity) - - encKey := t.keychain. - GetKey(state.EncryptionKey).(encryptionkey.PrivKey) - rawKey, _ := encKey.GetPublic().Raw() - aclUserState.EncryptionKey = rawKey - - aclUserState.EncryptedReadKeys = t.encryptReadKeys(state.EncryptedReadKeys, encKey) - aclUserState.Permissions = t.convertPermission(state.Permissions) - newState.UserStates = append(newState.UserStates, aclUserState) - } - return &aclpb.ACLChangeACLSnapshot{ - AclState: newState, - } -} - -func (t *TreeStorageBuilder) parseDocumentChange(ch *PlainTextChange) (convCh *testpb.PlainTextChangeContent) { - switch { - case ch.TextAppend != nil: - convCh = &testpb.PlainTextChangeContent{ - Value: &testpb.PlainTextChangeContentValueOfTextAppend{ - TextAppend: &testpb.PlainTextChangeTextAppend{ - Text: ch.TextAppend.Text, - }, - }, - } - } - if convCh == nil { - panic("cannot have empty document change") - } - - return convCh -} - -func (t *TreeStorageBuilder) parseACLChange(ch *ACLChange) (convCh *aclpb.ACLChangeACLContentValue) { - switch { - case ch.UserAdd != nil: - add := ch.UserAdd - - encKey := t.keychain. - GetKey(add.EncryptionKey).(encryptionkey.PrivKey) - rawKey, _ := encKey.GetPublic().Raw() - - convCh = &aclpb.ACLChangeACLContentValue{ - Value: &aclpb.ACLChangeACLContentValueValueOfUserAdd{ - UserAdd: &aclpb.ACLChangeUserAdd{ - Identity: t.keychain.GetIdentity(add.Identity), - EncryptionKey: rawKey, - EncryptedReadKeys: t.encryptReadKeys(add.EncryptedReadKeys, encKey), - Permissions: t.convertPermission(add.Permission), - }, - }, - } - case ch.UserJoin != nil: - join := ch.UserJoin - - encKey := t.keychain. - GetKey(join.EncryptionKey).(encryptionkey.PrivKey) - rawKey, _ := encKey.GetPublic().Raw() - - idKey, _ := t.keychain.SigningKeys[join.Identity].GetPublic().Raw() - signKey := t.keychain.GetKey(join.AcceptSignature).(signingkey.PrivKey) - signature, err := signKey.Sign(idKey) - if err != nil { - panic(err) - } - - convCh = &aclpb.ACLChangeACLContentValue{ - Value: &aclpb.ACLChangeACLContentValueValueOfUserJoin{ - UserJoin: &aclpb.ACLChangeUserJoin{ - Identity: t.keychain.GetIdentity(join.Identity), - EncryptionKey: rawKey, - AcceptSignature: signature, - UserInviteId: join.InviteId, - EncryptedReadKeys: t.encryptReadKeys(join.EncryptedReadKeys, encKey), - }, - }, - } - case ch.UserInvite != nil: - invite := ch.UserInvite - rawAcceptKey, _ := t.keychain.GetKey(invite.AcceptKey).(signingkey.PrivKey).GetPublic().Raw() - encKey := t.keychain. - GetKey(invite.EncryptionKey).(encryptionkey.PrivKey) - rawEncKey, _ := encKey.GetPublic().Raw() - - convCh = &aclpb.ACLChangeACLContentValue{ - Value: &aclpb.ACLChangeACLContentValueValueOfUserInvite{ - UserInvite: &aclpb.ACLChangeUserInvite{ - AcceptPublicKey: rawAcceptKey, - EncryptPublicKey: rawEncKey, - EncryptedReadKeys: t.encryptReadKeys(invite.EncryptedReadKeys, encKey), - Permissions: t.convertPermission(invite.Permissions), - InviteId: invite.InviteId, - }, - }, - } - case ch.UserConfirm != nil: - confirm := ch.UserConfirm - - convCh = &aclpb.ACLChangeACLContentValue{ - Value: &aclpb.ACLChangeACLContentValueValueOfUserConfirm{ - UserConfirm: &aclpb.ACLChangeUserConfirm{ - Identity: t.keychain.GetIdentity(confirm.Identity), - UserAddId: confirm.UserAddId, - }, - }, - } - case ch.UserPermissionChange != nil: - permissionChange := ch.UserPermissionChange - - convCh = &aclpb.ACLChangeACLContentValue{ - Value: &aclpb.ACLChangeACLContentValueValueOfUserPermissionChange{ - UserPermissionChange: &aclpb.ACLChangeUserPermissionChange{ - Identity: t.keychain.GetIdentity(permissionChange.Identity), - Permissions: t.convertPermission(permissionChange.Permission), - }, - }, - } - case ch.UserRemove != nil: - remove := ch.UserRemove - - newReadKey := t.keychain.GetKey(remove.NewReadKey).(*SymKey) - - var replaces []*aclpb.ACLChangeReadKeyReplace - for _, id := range remove.IdentitiesLeft { - identity := t.keychain.GetIdentity(id) - encKey := t.keychain.EncryptionKeys[id] - rawEncKey, _ := encKey.GetPublic().Raw() - encReadKey, err := encKey.GetPublic().Encrypt(newReadKey.Key.Bytes()) - if err != nil { - panic(err) - } - replaces = append(replaces, &aclpb.ACLChangeReadKeyReplace{ - Identity: identity, - EncryptionKey: rawEncKey, - EncryptedReadKey: encReadKey, - }) - } - - convCh = &aclpb.ACLChangeACLContentValue{ - Value: &aclpb.ACLChangeACLContentValueValueOfUserRemove{ - UserRemove: &aclpb.ACLChangeUserRemove{ - Identity: t.keychain.GetIdentity(remove.RemovedIdentity), - ReadKeyReplaces: replaces, - }, - }, - } - } - if convCh == nil { - panic("cannot have empty acl change") - } - - return convCh -} - -func (t *TreeStorageBuilder) encryptReadKeys(keys []string, encKey encryptionkey.PrivKey) (enc [][]byte) { - for _, k := range keys { - realKey := t.keychain.GetKey(k).(*SymKey).Key.Bytes() - res, err := encKey.GetPublic().Encrypt(realKey) - if err != nil { - panic(err) - } - - enc = append(enc, res) - } - return -} - -func (t *TreeStorageBuilder) convertPermission(perm string) aclpb.ACLChangeUserPermissions { - switch perm { - case "admin": - return aclpb.ACLChange_Admin - case "writer": - return aclpb.ACLChange_Writer - case "reader": - return aclpb.ACLChange_Reader - default: - panic(fmt.Sprintf("incorrect permission: %s", perm)) - } -} - -func (t *TreeStorageBuilder) traverseFromHeads(f func(t *treeChange) error) error { - uniqMap := map[string]struct{}{} - stack := make([]string, len(t.orphans), 10) - copy(stack, t.orphans) - for len(stack) > 0 { - id := stack[len(stack)-1] - stack = stack[:len(stack)-1] - if _, exists := uniqMap[id]; exists { - continue - } - - ch := t.allChanges[id] - uniqMap[id] = struct{}{} - if err := f(ch); err != nil { - return err - } - - for _, prev := range ch.ACLChange.TreeHeadIds { - stack = append(stack, prev) - } - } - return nil -} - -func (t *TreeStorageBuilder) parseUpdates(updates []*Update) { - for _, update := range updates { - useCase := &updateUseCase{ - changes: map[string]*treeChange{}, - } - for _, ch := range update.Changes { - newChange := t.parseChange(ch) - useCase.changes[newChange.id] = newChange - } - for _, node := range update.Graph { - rec := useCase.changes[node.Id] - rec.AclHeadIds = node.ACLHeads - rec.TreeHeadIds = node.TreeHeads - rec.SnapshotBaseId = node.BaseSnapshot - } - - t.updates[update.UseCase] = useCase - } -} - -func (t *TreeStorageBuilder) parseGraph(tree *YMLTree) { - for _, node := range tree.Graph { - rec := t.allChanges[node.Id] - rec.AclHeadIds = node.ACLHeads - rec.TreeHeadIds = node.TreeHeads - rec.SnapshotBaseId = node.BaseSnapshot - } -} - -func (t *TreeStorageBuilder) parseOrphans(tree *YMLTree) { - t.orphans = tree.Orphans -} - -func (t *TreeStorageBuilder) parseHeader(tree *YMLTree) { - t.header = &storagepb.TreeHeader{ - FirstChangeId: tree.Header.FirstChangeId, - IsWorkspace: tree.Header.IsWorkspace, - } -} diff --git a/pkg/acl/testutils/treestoragebuilder/treestoragebuildergraph_nix.go b/pkg/acl/testutils/treestoragebuilder/treestoragebuildergraph_nix.go deleted file mode 100644 index 935fd711..00000000 --- a/pkg/acl/testutils/treestoragebuilder/treestoragebuildergraph_nix.go +++ /dev/null @@ -1,162 +0,0 @@ -//go:build (linux || darwin) && !android && !ios && !nographviz && (amd64 || arm64) -// +build linux darwin -// +build !android -// +build !ios -// +build !nographviz -// +build amd64 arm64 - -package treestoragebuilder - -import ( - "fmt" - testpb "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/testchanges/testchangepb" - - "github.com/gogo/protobuf/proto" - "strings" - "unicode" - - "github.com/awalterschulze/gographviz" -) - -// To quickly look at visualized string you can use https://dreampuf.github.io/GraphvizOnline - -type EdgeParameters struct { - style string - color string - label string -} - -func (t *TreeStorageBuilder) Graph() (string, error) { - // TODO: check updates on https://github.com/goccy/go-graphviz/issues/52 or make a fix yourself to use better library here - graph := gographviz.NewGraph() - graph.SetName("G") - graph.SetDir(true) - var nodes = make(map[string]struct{}) - - var addNodes = func(r *treeChange) error { - // TODO: revisit function after checking - - style := "solid" - if r.GetAclData() != nil { - style = "filled" - } else if r.changesDataDecrypted != nil { - style = "dashed" - } - - var chSymbs []string - if r.changesDataDecrypted != nil { - res := &testpb.PlainTextChangeData{} - err := proto.Unmarshal(r.changesDataDecrypted, res) - if err != nil { - return err - } - - for _, chc := range res.Content { - tp := fmt.Sprintf("%T", chc.Value) - tp = strings.Replace(tp, "ChangeContentValueOf", "", 1) - res := "" - for _, ts := range tp { - if unicode.IsUpper(ts) { - res += string(ts) - } - } - chSymbs = append(chSymbs, res) - } - } - if r.GetAclData() != nil { - for _, chc := range r.GetAclData().AclContent { - tp := fmt.Sprintf("%T", chc.Value) - tp = strings.Replace(tp, "ACLChangeACLContentValueValueOf", "", 1) - res := "" - for _, ts := range tp { - if unicode.IsUpper(ts) { - res += string(ts) - } - } - chSymbs = append(chSymbs, res) - } - } - - shortId := r.id - label := fmt.Sprintf("Id: %s\nChanges: %s\n", - shortId, - strings.Join(chSymbs, ","), - ) - e := graph.AddNode("G", "\""+r.id+"\"", map[string]string{ - "label": "\"" + label + "\"", - "style": "\"" + style + "\"", - }) - if e != nil { - return e - } - nodes[r.id] = struct{}{} - return nil - } - - var createEdge = func(firstId, secondId string, params EdgeParameters) error { - _, exists := nodes[firstId] - if !exists { - return fmt.Errorf("no such node") - } - _, exists = nodes[secondId] - if !exists { - return fmt.Errorf("no previous node") - } - - err := graph.AddEdge("\""+firstId+"\"", "\""+secondId+"\"", true, map[string]string{ - "color": params.color, - "style": params.style, - }) - if err != nil { - return err - } - - return nil - } - - var addLinks = func(t *treeChange) error { - for _, prevId := range t.AclHeadIds { - err := createEdge(t.id, prevId, EdgeParameters{ - style: "dashed", - color: "red", - }) - if err != nil { - return err - } - } - - for _, prevId := range t.TreeHeadIds { - err := createEdge(t.id, prevId, EdgeParameters{ - style: "dashed", - color: "blue", - }) - if err != nil { - return err - } - } - - if t.SnapshotBaseId != "" { - err := createEdge(t.id, t.SnapshotBaseId, EdgeParameters{ - style: "bold", - color: "blue", - }) - if err != nil { - return err - } - } - - return nil - } - - err := t.traverseFromHeads(addNodes) - if err != nil { - return "", err - } - - err = t.traverseFromHeads(addLinks) - if err != nil { - return "", err - } - - return graph.String(), nil -} diff --git a/pkg/acl/testutils/treestoragebuilder/ymlentities.go b/pkg/acl/testutils/treestoragebuilder/ymlentities.go deleted file mode 100644 index 0a873d99..00000000 --- a/pkg/acl/testutils/treestoragebuilder/ymlentities.go +++ /dev/null @@ -1,117 +0,0 @@ -package treestoragebuilder - -type TreeDescription struct { - Author string `yaml:"author"` -} - -type Keys struct { - Enc []string `yaml:"Enc"` - Sign []string `yaml:"Sign"` - Read []string `yaml:"Read"` -} - -type ACLSnapshot struct { - UserStates []struct { - Identity string `yaml:"identity"` - EncryptionKey string `yaml:"encryptionKey"` - EncryptedReadKeys []string `yaml:"encryptedReadKeys"` - Permissions string `yaml:"permission"` - IsConfirmed bool `yaml:"isConfirmed"` - } `yaml:"userStates"` -} - -type PlainTextSnapshot struct { - Text string `yaml:"text"` -} - -type ACLChange struct { - UserAdd *struct { - Identity string `yaml:"identity"` - EncryptionKey string `yaml:"encryptionKey"` - EncryptedReadKeys []string `yaml:"encryptedReadKeys"` - Permission string `yaml:"permission"` - } `yaml:"userAdd"` - - UserJoin *struct { - Identity string `yaml:"identity"` - EncryptionKey string `yaml:"encryptionKey"` - AcceptSignature string `yaml:"acceptSignature"` - InviteId string `yaml:"inviteId"` - EncryptedReadKeys []string `yaml:"encryptedReadKeys"` - } `yaml:"userJoin"` - - UserInvite *struct { - AcceptKey string `yaml:"acceptKey"` - EncryptionKey string `yaml:"encryptionKey"` - EncryptedReadKeys []string `yaml:"encryptedReadKeys"` - Permissions string `yaml:"permissions"` - InviteId string `yaml:"inviteId"` - } `yaml:"userInvite"` - - UserConfirm *struct { - Identity string `yaml:"identity"` - UserAddId string `yaml:"UserAddId"` - } `yaml:"userConfirm"` - - UserRemove *struct { - RemovedIdentity string `yaml:"removedIdentity"` - NewReadKey string `yaml:"newReadKey"` - IdentitiesLeft []string `yaml:"identitiesLeft"` - } `yaml:"userRemove"` - - UserPermissionChange *struct { - Identity string `yaml:"identity"` - Permission string `yaml:"permission"` - } -} - -type PlainTextChange struct { - TextAppend *struct { - Text string `yaml:"text"` - } `yaml:"textAppend"` -} - -type GraphNode struct { - Id string `yaml:"id"` - BaseSnapshot string `yaml:"baseSnapshot"` - AclSnapshot string `yaml:"aclSnapshot"` - ACLHeads []string `yaml:"aclHeads"` - TreeHeads []string `yaml:"treeHeads"` -} - -type Change struct { - Id string `yaml:"id"` - Identity string `yaml:"identity"` - - AclSnapshot *ACLSnapshot `yaml:"aclSnapshot"` - Snapshot *PlainTextSnapshot `yaml:"snapshot"` - AclChanges []*ACLChange `yaml:"aclChanges"` - Changes []*PlainTextChange `yaml:"changes"` - - ReadKey string `yaml:"readKey"` -} - -type Header struct { - FirstChangeId string `yaml:"firstChangeId"` - IsWorkspace bool `yaml:"isWorkspace"` -} - -type Update struct { - UseCase string `yaml:"useCase"` - Changes []*Change `yaml:"changes"` - Graph []*GraphNode `yaml:"graph"` -} - -type YMLTree struct { - Description *TreeDescription `yaml:"tree"` - Changes []*Change `yaml:"changes"` - Updates []*Update `yaml:"updates"` - - Keys Keys `yaml:"keys"` - - Graph []*GraphNode `yaml:"graph"` - - Heads []string `yaml:"heads"` - Orphans []string `yaml:"orphans"` - Header *Header `yaml:"header"` -} diff --git a/pkg/acl/testutils/treestoragebuilder/ymlentities_test.go b/pkg/acl/testutils/treestoragebuilder/ymlentities_test.go deleted file mode 100644 index 2ae2e716..00000000 --- a/pkg/acl/testutils/treestoragebuilder/ymlentities_test.go +++ /dev/null @@ -1,12 +0,0 @@ -package treestoragebuilder - -import ( - "fmt" - "testing" -) - -func Test_YamlParse(t *testing.T) { - tb, _ := NewTreeStorageBuilderWithTestName("userjoinexampleupdate.yml") - gr, _ := tb.Graph() - fmt.Println(gr) -} diff --git a/pkg/acl/testutils/yamltests/invalidsnapshotexample.yml b/pkg/acl/testutils/yamltests/invalidsnapshotexample.yml deleted file mode 100644 index f3eaf00c..00000000 --- a/pkg/acl/testutils/yamltests/invalidsnapshotexample.yml +++ /dev/null @@ -1,126 +0,0 @@ -tree: - author: A -changes: - - id: A.1.1 - identity: A - aclSnapshot: - userStates: - - identity: A - encryptionKey: key.Enc.A - encryptedReadKeys: [key.Read.1] - permission: admin - - identity: B - encryptionKey: key.Enc.B - encryptedReadKeys: [key.Read.1] - permission: admin - snapshot: - text: "some text" - aclChanges: - - userAdd: - identity: A - permission: admin - encryptionKey: key.Enc.A - encryptedReadKeys: [key.Read.1] - - userAdd: - identity: B - permission: admin - encryptionKey: key.Enc.B - encryptedReadKeys: [key.Read.1] - readKey: key.Read.1 - - id: A.1.2 - identity: A - aclSnapshot: - userStates: - - identity: A - encryptionKey: key.Enc.A - encryptedReadKeys: [key.Read.1] - permission: admin - - identity: B - encryptionKey: key.Enc.B - encryptedReadKeys: [key.Read.1] - permission: admin - - identity: D - encryptionKey: key.Enc.D - encryptedReadKeys: [ key.Read.1 ] - permission: admin - snapshot: - text: "some text" - aclChanges: - - userAdd: - identity: D - permission: admin - encryptionKey: key.Enc.D - encryptedReadKeys: [key.Read.1] - readKey: key.Read.1 - - id: A.1.3 - identity: A - aclChanges: - - userAdd: - identity: E - permission: admin - encryptionKey: key.Enc.E - encryptedReadKeys: [key.Read.1] - readKey: key.Read.1 - - id: B.1.1 - identity: B - aclChanges: - - userAdd: - identity: C - permission: admin - encryptionKey: key.Enc.C - encryptedReadKeys: [ key.Read.1 ] - readKey: key.Read.1 - - id: B.1.2 - identity: B - aclChanges: - - userAdd: - identity: F - permission: admin - encryptionKey: key.Enc.F - encryptedReadKeys: [ key.Read.1 ] - readKey: key.Read.1 -keys: - Enc: - - A - - B - - C - - D - - E - - F - Sign: - - A - - B - - C - - D - - E - - F - Read: - - 1 - - 2 -graph: - - id: A.1.1 - baseSnapshot: A.1.1 - aclSnapshot: A.1.1 - - id: A.1.2 - baseSnapshot: A.1.1 - aclHeads: [B.1.1] - treeHeads: [B.1.1] - - id: B.1.1 - baseSnapshot: A.1.1 - aclHeads: [A.1.1] - treeHeads: [A.1.1] - - id: B.1.2 - baseSnapshot: A.1.2 - aclHeads: [A.1.2] - treeHeads: [A.1.2] - - id: A.1.3 - baseSnapshot: A.1.2 - aclHeads: [A.1.2] - treeHeads: [A.1.2] -header: - firstChangeId: A.1.1 - isWorkspace: false -orphans: - - A.1.3 - - B.1.2 - diff --git a/pkg/acl/testutils/yamltests/userjoinexample.yml b/pkg/acl/testutils/yamltests/userjoinexample.yml deleted file mode 100644 index ff15f1f6..00000000 --- a/pkg/acl/testutils/yamltests/userjoinexample.yml +++ /dev/null @@ -1,107 +0,0 @@ -tree: - author: A -changes: - - id: A.1.1 - identity: A - aclSnapshot: - userStates: - - identity: A - encryptionKey: key.Enc.A - encryptedReadKeys: [key.Read.1] - permission: admin - snapshot: - text: "some text" - aclChanges: - - userAdd: - identity: A - permission: admin - encryptionKey: key.Enc.A - encryptedReadKeys: [key.Read.1] - changes: - - textAppend: - text: "some text" - readKey: key.Read.1 - - id: A.1.2 - identity: A - aclChanges: - - userInvite: - acceptKey: key.Sign.Onetime1 - encryptionKey: key.Enc.Onetime1 - encryptedReadKeys: [key.Read.1] - permissions: writer - inviteId: A.1.2 - - userAdd: - identity: C - permission: reader - encryptionKey: key.Enc.C - encryptedReadKeys: [ key.Read.1 ] - readKey: key.Read.1 - - id: A.1.3 - identity: A - changes: - - textAppend: - text: "second" - readKey: key.Read.1 - - id: B.1.1 - identity: B - aclChanges: - - userJoin: - identity: B - encryptionKey: key.Enc.B - acceptSignature: key.Sign.Onetime1 - inviteId: A.1.2 - encryptedReadKeys: [key.Read.1] - readKey: key.Read.1 - - id: B.1.2 - identity: B - changes: - - textAppend: - text: "first" - readKey: key.Read.1 - - id: C.1.1 - identity: C - changes: - - textAppend: - text: "third" - readKey: key.Read.1 -keys: - Enc: - - A - - B - - C - - Onetime1 - Sign: - - A - - B - - C - - Onetime1 - Read: - - 1 -graph: - - id: A.1.1 - baseSnapshot: A.1.1 - - id: A.1.2 - baseSnapshot: A.1.1 - aclHeads: [A.1.1] - treeHeads: [A.1.1] - - id: B.1.1 - baseSnapshot: A.1.1 - aclHeads: [A.1.2] - treeHeads: [A.1.2] - - id: B.1.2 - baseSnapshot: A.1.1 - aclHeads: [B.1.1] - treeHeads: [B.1.1] - - id: A.1.3 # this should be invalid, because it is based on one of the invalid changes - baseSnapshot: A.1.1 - aclHeads: [B.1.1] - treeHeads: [B.1.2, C.1.1] - - id: C.1.1 # this should be invalid, because C is a reader - baseSnapshot: A.1.1 - aclHeads: [B.1.1] - treeHeads: [B.1.1] -header: - firstChangeId: A.1.1 - isWorkspace: false -orphans: - - "A.1.3" diff --git a/pkg/acl/testutils/yamltests/userjoinexampleupdate.yml b/pkg/acl/testutils/yamltests/userjoinexampleupdate.yml deleted file mode 100644 index 1e7d2b01..00000000 --- a/pkg/acl/testutils/yamltests/userjoinexampleupdate.yml +++ /dev/null @@ -1,152 +0,0 @@ -tree: - author: A -changes: - - id: A.1.1 - identity: A - aclSnapshot: - userStates: - - identity: A - encryptionKey: key.Enc.A - encryptedReadKeys: [key.Read.1] - permission: admin - snapshot: - text: "some text" - aclChanges: - - userAdd: - identity: A - permission: admin - encryptionKey: key.Enc.A - encryptedReadKeys: [key.Read.1] - changes: - - textAppend: - text: "some text" - readKey: key.Read.1 - - id: A.1.2 - identity: A - aclChanges: - - userInvite: - acceptKey: key.Sign.Onetime1 - encryptionKey: key.Enc.Onetime1 - encryptedReadKeys: [key.Read.1] - permissions: writer - inviteId: A.1.2 - - userAdd: - identity: C - permission: reader - encryptionKey: key.Enc.C - encryptedReadKeys: [ key.Read.1 ] - readKey: key.Read.1 - - id: A.1.3 - identity: A - changes: - - textAppend: - text: "second" - readKey: key.Read.1 - - id: B.1.1 - identity: B - aclChanges: - - userJoin: - identity: B - encryptionKey: key.Enc.B - acceptSignature: key.Sign.Onetime1 - inviteId: A.1.2 - encryptedReadKeys: [key.Read.1] - readKey: key.Read.1 - - id: B.1.2 - identity: B - changes: - - textAppend: - text: "first" - readKey: key.Read.1 - - id: C.1.1 - identity: C - changes: - - textAppend: - text: "third" - readKey: key.Read.1 -keys: - Enc: - - A - - B - - C - - D - - Onetime1 - Sign: - - A - - B - - C - - D - - Onetime1 - Read: - - 1 -graph: - - id: A.1.1 - baseSnapshot: A.1.1 - - id: A.1.2 - baseSnapshot: A.1.1 - aclHeads: [A.1.1] - treeHeads: [A.1.1] - - id: B.1.1 - baseSnapshot: A.1.1 - aclHeads: [A.1.2] - treeHeads: [A.1.2] - - id: B.1.2 - baseSnapshot: A.1.1 - aclHeads: [B.1.1] - treeHeads: [B.1.1] - - id: A.1.3 # this should be invalid, because it is based on one of the invalid changes - baseSnapshot: A.1.1 - aclHeads: [B.1.1] - treeHeads: [B.1.2, C.1.1] - - id: C.1.1 # this should be invalid, because C is a reader - baseSnapshot: A.1.1 - aclHeads: [B.1.1] - treeHeads: [B.1.1] -header: - firstChangeId: A.1.1 - isWorkspace: false -orphans: - - "A.1.3" -updates: - - useCase: append - changes: - - id: B.1.3 - identity: B - changes: - - textAppend: - text: "second" - readKey: key.Read.1 - - id: A.1.4 - identity: A - aclChanges: - - userAdd: - identity: D - permission: writer - encryptionKey: key.Enc.D - encryptedReadKeys: [ key.Read.1 ] - readKey: key.Read.1 - graph: - - id: B.1.3 - baseSnapshot: A.1.1 - aclHeads: [ B.1.1 ] - treeHeads: [ B.1.2 ] - - id: A.1.4 - baseSnapshot: A.1.1 - aclHeads: [ B.1.1 ] - treeHeads: [ B.1.3 ] - - useCase: rebuild - changes: - - id: A.1.4 - identity: A - aclChanges: - - userAdd: - identity: D - permission: writer - encryptionKey: key.Enc.D - encryptedReadKeys: [ key.Read.1 ] - readKey: key.Read.1 - graph: - - id: A.1.4 - baseSnapshot: A.1.1 - aclHeads: [ A.1.1 ] - treeHeads: [ A.1.1 ] diff --git a/pkg/acl/testutils/yamltests/userremovebeforeexample.yml b/pkg/acl/testutils/yamltests/userremovebeforeexample.yml deleted file mode 100644 index 2cd58df4..00000000 --- a/pkg/acl/testutils/yamltests/userremovebeforeexample.yml +++ /dev/null @@ -1,109 +0,0 @@ -tree: - author: A -changes: - - id: A.1.1 - identity: A - aclSnapshot: - userStates: - - identity: A - encryptionKey: key.Enc.A - encryptedReadKeys: [key.Read.1] - permission: admin - - identity: B - encryptionKey: key.Enc.B - encryptedReadKeys: [key.Read.1] - permission: admin - snapshot: - text: "some text" - aclChanges: - - userAdd: - identity: A - permission: admin - encryptionKey: key.Enc.A - encryptedReadKeys: [key.Read.1] - - userAdd: - identity: B - permission: admin - encryptionKey: key.Enc.B - encryptedReadKeys: [key.Read.1] - changes: - - textAppend: - text: "some text" - readKey: key.Read.1 - - id: A.1.2 - identity: A - aclChanges: - - userRemove: - removedIdentity: B - newReadKey: key.Read.2 - identitiesLeft: [A, C] - readKey: key.Read.2 - - id: A.1.3 - identity: A - aclChanges: - - userAdd: - identity: E - permission: admin - encryptionKey: key.Enc.E - encryptedReadKeys: [key.Read.1, key.Read.2] - readKey: key.Read.2 - - id: B.1.1 - identity: B - aclChanges: - - userAdd: - identity: C - permission: admin - encryptionKey: key.Enc.C - encryptedReadKeys: [ key.Read.1 ] - readKey: key.Read.1 - - id: B.1.2 - identity: B - aclChanges: - - userAdd: - identity: D - permission: admin - encryptionKey: key.Enc.D - encryptedReadKeys: [ key.Read.1 ] - readKey: key.Read.1 -keys: - Enc: - - A - - B - - C - - D - - E - Sign: - - A - - B - - C - - D - - E - Read: - - 1 - - 2 -graph: - - id: A.1.1 - baseSnapshot: A.1.1 - aclSnapshot: A.1.1 - - id: A.1.2 - baseSnapshot: A.1.1 - aclHeads: [B.1.1] - treeHeads: [B.1.1] - - id: B.1.1 - baseSnapshot: A.1.1 - aclHeads: [A.1.1] - treeHeads: [A.1.1] - - id: B.1.2 - baseSnapshot: A.1.1 - aclHeads: [B.1.1] - treeHeads: [B.1.1] - - id: A.1.3 - baseSnapshot: A.1.1 - aclHeads: [A.1.2] - treeHeads: [A.1.2] -orphans: - - "A.1.3" - - "B.1.2" -header: - firstChangeId: A.1.1 - isWorkspace: false diff --git a/pkg/acl/testutils/yamltests/userremoveexample.yml b/pkg/acl/testutils/yamltests/userremoveexample.yml deleted file mode 100644 index c3da9fe2..00000000 --- a/pkg/acl/testutils/yamltests/userremoveexample.yml +++ /dev/null @@ -1,110 +0,0 @@ -tree: - author: A -changes: - - id: A.1.1 - identity: A - aclSnapshot: - userStates: - - identity: A - encryptionKey: key.Enc.A - encryptedReadKeys: [key.Read.1] - permission: admin - snapshot: - text: "some text" - aclChanges: - - userAdd: - identity: A - permission: admin - encryptionKey: key.Enc.A - encryptedReadKeys: [key.Read.1] - changes: - - textAppend: - text: "some text" - readKey: key.Read.1 - - id: A.1.2 - identity: A - aclChanges: - - userInvite: - acceptKey: key.Sign.Onetime1 - encryptionKey: key.Enc.Onetime1 - encryptedReadKeys: [key.Read.1] - permissions: writer - inviteId: A.1.2 - readKey: key.Read.1 - - id: A.1.3 - identity: A - aclChanges: - - userRemove: - removedIdentity: B - newReadKey: key.Read.2 - identitiesLeft: [A] - readKey: key.Read.2 - - id: A.1.4 - identity: A - changes: - - textAppend: - text: "first" - readKey: key.Read.2 - - id: B.1.1 - identity: B - aclChanges: - - userJoin: - identity: B - encryptionKey: key.Enc.B - acceptSignature: key.Sign.Onetime1 - inviteId: A.1.2 - encryptedReadKeys: [key.Read.1] - readKey: key.Read.1 - - id: B.1.2 - identity: B - changes: - - textAppend: - text: "second" - readKey: key.Read.1 -keys: - Enc: - - A - - B - - Onetime1 - Sign: - - A - - B - - Onetime1 - Read: - - 1 - - 2 -graph: - - id: A.1.1 - baseSnapshot: A.1.1 - aclSnapshot: A.1.1 - - id: A.1.2 - baseSnapshot: A.1.1 - aclSnapshot: A.1.1 - aclHeads: [A.1.1] - treeHeads: [A.1.1] - - id: B.1.1 - baseSnapshot: A.1.1 - aclSnapshot: A.1.1 - aclHeads: [A.1.2] - treeHeads: [A.1.2] - - id: B.1.2 - baseSnapshot: A.1.1 - aclSnapshot: A.1.1 - aclHeads: [B.1.1] - treeHeads: [B.1.1] - - id: A.1.3 - baseSnapshot: A.1.1 - aclSnapshot: A.1.1 - aclHeads: [B.1.1] - treeHeads: [B.1.1] - - id: A.1.4 - baseSnapshot: A.1.1 - aclSnapshot: A.1.1 - aclHeads: [A.1.3] - treeHeads: [A.1.3] -orphans: - - "A.1.4" - - "B.1.2" -header: - firstChangeId: A.1.1 - isWorkspace: false diff --git a/pkg/acl/testutils/yamltests/validsnapshotexample.yml b/pkg/acl/testutils/yamltests/validsnapshotexample.yml deleted file mode 100644 index c75cda0a..00000000 --- a/pkg/acl/testutils/yamltests/validsnapshotexample.yml +++ /dev/null @@ -1,133 +0,0 @@ -tree: - author: A -changes: - - id: A.1.1 - identity: A - aclSnapshot: - userStates: - - identity: A - encryptionKey: key.Enc.A - encryptedReadKeys: [key.Read.1] - permission: admin - - identity: B - encryptionKey: key.Enc.B - encryptedReadKeys: [key.Read.1] - permission: admin - snapshot: - text: "some text" - aclChanges: - - userAdd: - identity: A - permission: admin - encryptionKey: key.Enc.A - encryptedReadKeys: [key.Read.1] - - userAdd: - identity: B - permission: admin - encryptionKey: key.Enc.B - encryptedReadKeys: [key.Read.1] - readKey: key.Read.1 - changes: - - textAppend: - text: "some text" - - id: A.1.2 - identity: A - aclSnapshot: - userStates: - - identity: A - encryptionKey: key.Enc.A - encryptedReadKeys: [key.Read.1] - permission: admin - - identity: B - encryptionKey: key.Enc.B - encryptedReadKeys: [key.Read.1] - permission: admin - - identity: C - encryptionKey: key.Enc.C - encryptedReadKeys: [ key.Read.1 ] - permission: admin - - identity: D - encryptionKey: key.Enc.D - encryptedReadKeys: [ key.Read.1 ] - permission: admin - snapshot: - text: "some text" - aclChanges: - - userAdd: - identity: D - permission: admin - encryptionKey: key.Enc.D - encryptedReadKeys: [key.Read.1] - readKey: key.Read.1 - - id: A.1.3 - identity: A - aclChanges: - - userAdd: - identity: E - permission: admin - encryptionKey: key.Enc.E - encryptedReadKeys: [key.Read.1] - readKey: key.Read.1 - - id: B.1.1 - identity: B - aclChanges: - - userAdd: - identity: C - permission: admin - encryptionKey: key.Enc.C - encryptedReadKeys: [ key.Read.1 ] - readKey: key.Read.1 - - id: B.1.2 - identity: B - aclChanges: - - userAdd: - identity: F - permission: admin - encryptionKey: key.Enc.F - encryptedReadKeys: [ key.Read.1 ] - readKey: key.Read.1 -keys: - Enc: - - A - - B - - C - - D - - E - - F - Sign: - - A - - B - - C - - D - - E - - F - Read: - - 1 - - 2 -graph: - - id: A.1.1 - baseSnapshot: A.1.1 - aclSnapshot: A.1.1 - - id: A.1.2 - baseSnapshot: A.1.1 - aclHeads: [B.1.1] - treeHeads: [B.1.1] - - id: B.1.1 - baseSnapshot: A.1.1 - aclHeads: [A.1.1] - treeHeads: [A.1.1] - - id: B.1.2 - baseSnapshot: A.1.2 - aclHeads: [A.1.2] - treeHeads: [A.1.2] - - id: A.1.3 - baseSnapshot: A.1.2 - aclHeads: [A.1.2] - treeHeads: [A.1.2] -orphans: - - "A.1.3" - - "B.1.2" -header: - firstChangeId: A.1.1 - isWorkspace: false - diff --git a/pkg/acl/treestorage/inmemory.go b/pkg/acl/treestorage/inmemory.go deleted file mode 100644 index adfa9af8..00000000 --- a/pkg/acl/treestorage/inmemory.go +++ /dev/null @@ -1,163 +0,0 @@ -package treestorage - -import ( - "context" - "fmt" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice" - "github.com/gogo/protobuf/proto" - "sync" -) - -type inMemoryTreeStorage struct { - id string - header *treepb.TreeHeader - heads []string - orphans []string - changes map[string]*aclpb.RawChange - - sync.RWMutex -} - -type CreatorFunc = func(string, *treepb.TreeHeader, []*aclpb.RawChange) (TreeStorage, error) - -func NewInMemoryTreeStorage( - treeId string, - header *treepb.TreeHeader, - changes []*aclpb.RawChange) (TreeStorage, error) { - allChanges := make(map[string]*aclpb.RawChange) - var orphans []string - for _, ch := range changes { - allChanges[ch.Id] = ch - orphans = append(orphans, ch.Id) - } - - return &inMemoryTreeStorage{ - id: treeId, - header: header, - heads: nil, - orphans: orphans, - changes: allChanges, - RWMutex: sync.RWMutex{}, - }, nil -} - -func (t *inMemoryTreeStorage) TreeID() (string, error) { - t.RLock() - defer t.RUnlock() - return t.id, nil -} - -func (t *inMemoryTreeStorage) Header() (*treepb.TreeHeader, error) { - t.RLock() - defer t.RUnlock() - return t.header, nil -} - -func (t *inMemoryTreeStorage) Heads() ([]string, error) { - t.RLock() - defer t.RUnlock() - return t.heads, nil -} - -func (t *inMemoryTreeStorage) Orphans() ([]string, error) { - t.RLock() - defer t.RUnlock() - return t.orphans, nil -} - -func (t *inMemoryTreeStorage) SetHeads(heads []string) error { - t.Lock() - defer t.Unlock() - t.heads = t.heads[:0] - - for _, h := range heads { - t.heads = append(t.heads, h) - } - return nil -} - -func (t *inMemoryTreeStorage) RemoveOrphans(orphans ...string) error { - t.Lock() - defer t.Unlock() - t.orphans = slice.Difference(t.orphans, orphans) - return nil -} - -func (t *inMemoryTreeStorage) AddOrphans(orphans ...string) error { - t.Lock() - defer t.Unlock() - t.orphans = append(t.orphans, orphans...) - return nil -} - -func (t *inMemoryTreeStorage) AddRawChange(change *aclpb.RawChange) error { - t.Lock() - defer t.Unlock() - // TODO: better to do deep copy - t.changes[change.Id] = change - return nil -} - -func (t *inMemoryTreeStorage) AddChange(change aclchanges.Change) error { - t.Lock() - defer t.Unlock() - signature := change.Signature() - id := change.CID() - aclChange := change.ProtoChange() - - fullMarshalledChange, err := proto.Marshal(aclChange) - if err != nil { - return err - } - rawChange := &aclpb.RawChange{ - Payload: fullMarshalledChange, - Signature: signature, - Id: id, - } - t.changes[id] = rawChange - return nil -} - -func (t *inMemoryTreeStorage) GetChange(ctx context.Context, changeId string) (*aclpb.RawChange, error) { - t.RLock() - defer t.RUnlock() - if res, exists := t.changes[changeId]; exists { - return res, nil - } - return nil, fmt.Errorf("could not get change with id: %s", changeId) -} - -type inMemoryTreeStorageProvider struct { - trees map[string]TreeStorage - sync.RWMutex -} - -func (i *inMemoryTreeStorageProvider) TreeStorage(treeId string) (TreeStorage, error) { - i.RLock() - defer i.RUnlock() - if tree, exists := i.trees[treeId]; exists { - return tree, nil - } - return nil, ErrUnknownTreeId -} - -func (i *inMemoryTreeStorageProvider) CreateTreeStorage(treeId string, header *treepb.TreeHeader, changes []*aclpb.RawChange) (TreeStorage, error) { - i.Lock() - defer i.Unlock() - res, err := NewInMemoryTreeStorage(treeId, header, changes) - if err != nil { - return nil, err - } - - i.trees[treeId] = res - return res, nil -} - -func NewInMemoryTreeStorageProvider() Provider { - return &inMemoryTreeStorageProvider{ - trees: make(map[string]TreeStorage), - } -} diff --git a/pkg/acl/treestorage/provider.go b/pkg/acl/treestorage/provider.go deleted file mode 100644 index 41b472e9..00000000 --- a/pkg/acl/treestorage/provider.go +++ /dev/null @@ -1,14 +0,0 @@ -package treestorage - -import ( - "errors" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb" -) - -var ErrUnknownTreeId = errors.New("tree does not exist") - -type Provider interface { - TreeStorage(treeId string) (TreeStorage, error) - CreateTreeStorage(treeId string, header *treepb.TreeHeader, changes []*aclpb.RawChange) (TreeStorage, error) -} diff --git a/pkg/acl/treestorage/storage.go b/pkg/acl/treestorage/storage.go deleted file mode 100644 index df47d809..00000000 --- a/pkg/acl/treestorage/storage.go +++ /dev/null @@ -1,25 +0,0 @@ -package treestorage - -import ( - "context" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb" -) - -type TreeStorage interface { - TreeID() (string, error) - - Header() (*treepb.TreeHeader, error) - Heads() ([]string, error) - Orphans() ([]string, error) - SetHeads(heads []string) error - RemoveOrphans(orphan ...string) error - AddOrphans(orphan ...string) error - - AddRawChange(change *aclpb.RawChange) error - AddChange(change aclchanges.Change) error - - // TODO: have methods with raw changes also - GetChange(ctx context.Context, recordID string) (*aclpb.RawChange, error) -} diff --git a/pkg/acl/treestorage/treepb/protos/tree.proto b/pkg/acl/treestorage/treepb/protos/tree.proto deleted file mode 100644 index eb342673..00000000 --- a/pkg/acl/treestorage/treepb/protos/tree.proto +++ /dev/null @@ -1,9 +0,0 @@ -syntax = "proto3"; -package tree; -option go_package = "treepb"; - -message TreeHeader { - string firstChangeId = 1; - bool isWorkspace = 2; - // TODO: add user identity, signature and nano timestamp -} \ No newline at end of file diff --git a/pkg/acl/treestorage/treepb/tree.pb.go b/pkg/acl/treestorage/treepb/tree.pb.go deleted file mode 100644 index 7baa874c..00000000 --- a/pkg/acl/treestorage/treepb/tree.pb.go +++ /dev/null @@ -1,358 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: pkg/acl/treestorage/treepb/protos/tree.proto - -package treepb - -import ( - fmt "fmt" - proto "github.com/gogo/protobuf/proto" - io "io" - math "math" - math_bits "math/bits" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package - -type TreeHeader struct { - FirstChangeId string `protobuf:"bytes,1,opt,name=firstChangeId,proto3" json:"firstChangeId,omitempty"` - IsWorkspace bool `protobuf:"varint,2,opt,name=isWorkspace,proto3" json:"isWorkspace,omitempty"` -} - -func (m *TreeHeader) Reset() { *m = TreeHeader{} } -func (m *TreeHeader) String() string { return proto.CompactTextString(m) } -func (*TreeHeader) ProtoMessage() {} -func (*TreeHeader) Descriptor() ([]byte, []int) { - return fileDescriptor_e7d760b855878644, []int{0} -} -func (m *TreeHeader) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *TreeHeader) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_TreeHeader.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *TreeHeader) XXX_Merge(src proto.Message) { - xxx_messageInfo_TreeHeader.Merge(m, src) -} -func (m *TreeHeader) XXX_Size() int { - return m.Size() -} -func (m *TreeHeader) XXX_DiscardUnknown() { - xxx_messageInfo_TreeHeader.DiscardUnknown(m) -} - -var xxx_messageInfo_TreeHeader proto.InternalMessageInfo - -func (m *TreeHeader) GetFirstChangeId() string { - if m != nil { - return m.FirstChangeId - } - return "" -} - -func (m *TreeHeader) GetIsWorkspace() bool { - if m != nil { - return m.IsWorkspace - } - return false -} - -func init() { - proto.RegisterType((*TreeHeader)(nil), "tree.TreeHeader") -} - -func init() { - proto.RegisterFile("pkg/acl/treestorage/treepb/protos/tree.proto", fileDescriptor_e7d760b855878644) -} - -var fileDescriptor_e7d760b855878644 = []byte{ - // 165 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x29, 0xc8, 0x4e, 0xd7, - 0x4f, 0x4c, 0xce, 0xd1, 0x2f, 0x29, 0x4a, 0x4d, 0x2d, 0x2e, 0xc9, 0x2f, 0x4a, 0x4c, 0x4f, 0x05, - 0xb3, 0x0b, 0x92, 0xf4, 0x0b, 0x8a, 0xf2, 0x4b, 0xf2, 0x8b, 0xc1, 0x3c, 0x3d, 0x30, 0x5b, 0x88, - 0x05, 0xc4, 0x56, 0x0a, 0xe1, 0xe2, 0x0a, 0x29, 0x4a, 0x4d, 0xf5, 0x48, 0x4d, 0x4c, 0x49, 0x2d, - 0x12, 0x52, 0xe1, 0xe2, 0x4d, 0xcb, 0x2c, 0x2a, 0x2e, 0x71, 0xce, 0x48, 0xcc, 0x4b, 0x4f, 0xf5, - 0x4c, 0x91, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x42, 0x15, 0x14, 0x52, 0xe0, 0xe2, 0xce, 0x2c, - 0x0e, 0xcf, 0x2f, 0xca, 0x2e, 0x2e, 0x48, 0x4c, 0x4e, 0x95, 0x60, 0x52, 0x60, 0xd4, 0xe0, 0x08, - 0x42, 0x16, 0x72, 0x52, 0x38, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, - 0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, 0x63, 0x39, 0x86, 0x28, 0x36, - 0x88, 0x7b, 0x92, 0xd8, 0xc0, 0x8e, 0x30, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x09, 0x4f, 0xc6, - 0xec, 0xb4, 0x00, 0x00, 0x00, -} - -func (m *TreeHeader) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *TreeHeader) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *TreeHeader) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.IsWorkspace { - i-- - if m.IsWorkspace { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x10 - } - if len(m.FirstChangeId) > 0 { - i -= len(m.FirstChangeId) - copy(dAtA[i:], m.FirstChangeId) - i = encodeVarintTree(dAtA, i, uint64(len(m.FirstChangeId))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func encodeVarintTree(dAtA []byte, offset int, v uint64) int { - offset -= sovTree(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *TreeHeader) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.FirstChangeId) - if l > 0 { - n += 1 + l + sovTree(uint64(l)) - } - if m.IsWorkspace { - n += 2 - } - return n -} - -func sovTree(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozTree(x uint64) (n int) { - return sovTree(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *TreeHeader) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTree - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: TreeHeader: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: TreeHeader: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field FirstChangeId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTree - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTree - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTree - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.FirstChangeId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field IsWorkspace", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTree - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.IsWorkspace = bool(v != 0) - default: - iNdEx = preIndex - skippy, err := skipTree(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthTree - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipTree(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowTree - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowTree - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowTree - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthTree - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupTree - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthTree - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthTree = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowTree = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupTree = fmt.Errorf("proto: unexpected end of group") -) diff --git a/service/account/service.go b/service/account/service.go deleted file mode 100644 index ed66fe1e..00000000 --- a/service/account/service.go +++ /dev/null @@ -1,73 +0,0 @@ -package account - -import ( - "context" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app" - "github.com/anytypeio/go-anytype-infrastructure-experiments/config" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey" -) - -const CName = "account" - -type Service interface { - Account() *account.AccountData -} - -type service struct { - accountData *account.AccountData - peerId string -} - -func (s *service) Account() *account.AccountData { - return s.accountData -} - -type StaticAccount struct { - SigningKey string `yaml:"signingKey"` - EncryptionKey string `yaml:"encryptionKey"` -} - -func New() app.Component { - return &service{} -} - -func (s *service) Init(ctx context.Context, a *app.App) (err error) { - cfg := a.MustComponent(config.CName).(*config.Config) - - // decoding our keys - privateEncryptionDecoder := encryptionkey.NewRSAPrivKeyDecoder() - privateSigningDecoder := signingkey.NewEDPrivKeyDecoder() - publicSigningDecoder := signingkey.NewEDPubKeyDecoder() - acc := cfg.Account - - decodedEncryptionKey, err := privateEncryptionDecoder.DecodeFromString(acc.EncryptionKey) - if err != nil { - return err - } - decodedSigningKey, err := privateSigningDecoder.DecodeFromString(acc.SigningKey) - if err != nil { - return err - } - signKey := decodedSigningKey.(signingkey.PrivKey) - identity, err := publicSigningDecoder.EncodeToString(signKey.GetPublic()) - if err != nil { - return err - } - - // TODO: using acl lib format basically, but we should simplify this - s.accountData = &account.AccountData{ - Identity: identity, - SignKey: signKey, - EncKey: decodedEncryptionKey.(encryptionkey.PrivKey), - Decoder: signingkey.NewEd25519PubKeyDecoder(), - } - s.peerId = acc.PeerId - - return nil -} - -func (s *service) Name() (name string) { - return CName -} diff --git a/service/api/service.go b/service/api/service.go deleted file mode 100644 index 8ab7eb26..00000000 --- a/service/api/service.go +++ /dev/null @@ -1,135 +0,0 @@ -package api - -import ( - "context" - "fmt" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger" - "github.com/anytypeio/go-anytype-infrastructure-experiments/config" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/acltree" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/sync/document" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/treecache" - "go.uber.org/zap" - "io" - "net/http" - "time" -) - -const CName = "APIService" - -var log = logger.NewNamed("api") - -func New() app.Component { - return &service{} -} - -type service struct { - treeCache treecache.Service - documentService document.Service - srv *http.Server - cfg *config.Config -} - -func (s *service) Init(ctx context.Context, a *app.App) (err error) { - s.treeCache = a.MustComponent(treecache.CName).(treecache.Service) - s.documentService = a.MustComponent(document.CName).(document.Service) - s.cfg = a.MustComponent(config.CName).(*config.Config) - return nil -} - -func (s *service) Name() (name string) { - return CName -} - -func (s *service) Run(ctx context.Context) (err error) { - defer func() { - if err == nil { - log.With(zap.String("port", s.cfg.APIServer.Port)).Info("api server started running") - } - }() - - s.srv = &http.Server{ - Addr: fmt.Sprintf(":%s", s.cfg.APIServer.Port), - } - mux := http.NewServeMux() - mux.HandleFunc("/treeDump", s.treeDump) - mux.HandleFunc("/createDocument", s.createDocument) - mux.HandleFunc("/appendDocument", s.appendDocument) - s.srv.Handler = mux - - go s.runServer() - return nil -} - -func (s *service) runServer() { - err := s.srv.ListenAndServe() - if err != nil { - log.With(zap.Error(err)).Error("could not run api server") - } -} - -func (s *service) Close(ctx context.Context) (err error) { - return s.srv.Shutdown(ctx) -} - -func (s *service) treeDump(w http.ResponseWriter, req *http.Request) { - var ( - query = req.URL.Query() - treeId = query.Get("treeId") - dump string - err error - ) - err = s.treeCache.Do(context.Background(), treeId, func(tree acltree.ACLTree) error { - dump, err = tree.DebugDump() - if err != nil { - return err - } - return nil - }) - if err != nil { - sendText(w, http.StatusInternalServerError, err.Error()) - return - } - sendText(w, http.StatusOK, dump) -} - -func (s *service) createDocument(w http.ResponseWriter, req *http.Request) { - var ( - query = req.URL.Query() - text = query.Get("text") - ) - timeoutCtx, cancel := context.WithTimeout(context.Background(), time.Second*30) - treeId, err := s.documentService.CreateDocument(timeoutCtx, fmt.Sprintf("created document with id: %s", text)) - cancel() - if err != nil { - sendText(w, http.StatusInternalServerError, err.Error()) - return - } - sendText(w, http.StatusOK, treeId) -} - -func (s *service) appendDocument(w http.ResponseWriter, req *http.Request) { - var ( - query = req.URL.Query() - text = query.Get("text") - treeId = query.Get("treeId") - ) - timeoutCtx, cancel := context.WithTimeout(context.Background(), time.Second*30) - err := s.documentService.UpdateDocument(timeoutCtx, treeId, text) - cancel() - if err != nil { - sendText(w, http.StatusInternalServerError, err.Error()) - return - } - sendText(w, http.StatusOK, fmt.Sprintf("updated document with id: %s with text: %s", treeId, text)) -} - -func sendText(r http.ResponseWriter, code int, body string) { - r.Header().Set("Content-Type", "text/plain") - r.WriteHeader(code) - - _, err := io.WriteString(r, fmt.Sprintf("%s\n", body)) - if err != nil { - log.Error("writing response failed", zap.Error(err)) - } -} diff --git a/service/configuration/configuration.go b/service/configuration/configuration.go deleted file mode 100644 index 5701eca6..00000000 --- a/service/configuration/configuration.go +++ /dev/null @@ -1,77 +0,0 @@ -package configuration - -import ( - "context" - "fmt" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/peer" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/pool" - "github.com/anytypeio/go-chash" -) - -func New() Service { - return new(service) -} - -type Configuration interface { - // Id returns current configuration id - Id() string - // AllPeers returns all peers by spaceId except current account - AllPeers(ctx context.Context, spaceId string) (peers []peer.Peer, err error) - // OnePeer returns one of peer for spaceId - OnePeer(ctx context.Context, spaceId string) (p peer.Peer, err error) - // NodeIds returns list of peerId for given spaceId - NodeIds(spaceId string) []string - // IsResponsible checks if current account responsible for given spaceId - IsResponsible(spaceId string) bool -} - -type configuration struct { - id string - accountId string - pool pool.Pool - chash chash.CHash -} - -func (c *configuration) Id() string { - return c.id -} - -func (c *configuration) AllPeers(ctx context.Context, spaceId string) (peers []peer.Peer, err error) { - nodeIds := c.NodeIds(spaceId) - peers = make([]peer.Peer, 0, len(nodeIds)) - for _, id := range nodeIds { - p, e := c.pool.DialAndAddPeer(ctx, id) - if e == nil { - peers = append(peers, p) - } - } - if len(peers) == 0 { - return nil, fmt.Errorf("unable to connect to any node") - } - return -} - -func (c *configuration) OnePeer(ctx context.Context, spaceId string) (p peer.Peer, err error) { - nodeIds := c.NodeIds(spaceId) - return c.pool.GetOrDialOneOf(ctx, nodeIds) -} - -func (c *configuration) NodeIds(spaceId string) []string { - members := c.chash.GetMembers(spaceId) - res := make([]string, 0, len(members)) - for _, m := range members { - if m.Id() != c.accountId { - res = append(res, m.Id()) - } - } - return res -} - -func (c *configuration) IsResponsible(spaceId string) bool { - for _, m := range c.chash.GetMembers(spaceId) { - if m.Id() == c.accountId { - return true - } - } - return false -} diff --git a/service/configuration/service.go b/service/configuration/service.go deleted file mode 100644 index 9cd920f7..00000000 --- a/service/configuration/service.go +++ /dev/null @@ -1,73 +0,0 @@ -package configuration - -import ( - "context" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger" - "github.com/anytypeio/go-anytype-infrastructure-experiments/config" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/pool" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/node" - "github.com/anytypeio/go-chash" -) - -const CName = "configuration" - -const ( - partitionCount = 3000 - replicationFactor = 3 -) - -var log = logger.NewNamed(CName) - -type Service interface { - GetLast() Configuration - GetById(id string) Configuration - app.Component -} - -type service struct { - accountId string - pool pool.Pool - - last Configuration -} - -func (s *service) Init(ctx context.Context, a *app.App) (err error) { - conf := a.MustComponent(config.CName).(*config.Config) - s.accountId = conf.Account.PeerId - s.pool = a.MustComponent(pool.CName).(pool.Pool) - configNodes := a.MustComponent(node.CName).(node.Service).Nodes() - config := &configuration{ - id: "config", - accountId: s.accountId, - pool: s.pool, - } - if config.chash, err = chash.New(chash.Config{ - PartitionCount: partitionCount, - ReplicationFactor: replicationFactor, - }); err != nil { - return - } - members := make([]chash.Member, 0, len(configNodes)) - for _, n := range configNodes { - members = append(members, n) - } - if err = config.chash.AddMembers(members...); err != nil { - return - } - s.last = config - return -} - -func (s *service) Name() (name string) { - return CName -} - -func (s *service) GetLast() Configuration { - return s.last -} - -func (s *service) GetById(id string) Configuration { - //TODO implement me - panic("implement me") -} diff --git a/service/net/peer/peer.go b/service/net/peer/peer.go deleted file mode 100644 index 331b0982..00000000 --- a/service/net/peer/peer.go +++ /dev/null @@ -1,35 +0,0 @@ -package peer - -import ( - "context" - "github.com/anytypeio/go-anytype-infrastructure-experiments/syncproto" - "time" -) - -type Dir uint - -const ( - // DirInbound indicates peer created connection - DirInbound Dir = iota - // DirOutbound indicates that our host created connection - DirOutbound -) - -type Info struct { - Id string - Dir Dir - LastActiveUnix int64 -} - -func (i Info) LastActive() time.Time { - return time.Unix(i.LastActiveUnix, 0) -} - -type Peer interface { - Id() string - Info() Info - Recv() (*syncproto.Message, error) - Send(msg *syncproto.Message) (err error) - Context() context.Context - Close() error -} diff --git a/service/net/pool/handler/reply.go b/service/net/pool/handler/reply.go deleted file mode 100644 index 21dda1dd..00000000 --- a/service/net/pool/handler/reply.go +++ /dev/null @@ -1,32 +0,0 @@ -package handler - -import ( - "context" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/pool" - "github.com/gogo/protobuf/proto" - "go.uber.org/zap" -) - -var log = logger.NewNamed("replyHandler") - -type ReplyHandler interface { - Handle(ctx context.Context, req []byte) (rep proto.Marshaler, err error) -} - -type Reply struct { - ReplyHandler -} - -func (r Reply) Handle(ctx context.Context, msg *pool.Message) error { - rep, e := r.ReplyHandler.Handle(ctx, msg.GetData()) - if msg.GetHeader().RequestId == 0 { - if e != nil { - log.Error("handler returned error", zap.Error(e)) - } else if rep != nil { - log.Debug("sender didn't expect a reply, but the handler made") - } - return nil - } - return msg.ReplyType(msg.GetHeader().GetType(), rep) -} diff --git a/service/net/pool/message.go b/service/net/pool/message.go deleted file mode 100644 index 7535a55f..00000000 --- a/service/net/pool/message.go +++ /dev/null @@ -1,136 +0,0 @@ -package pool - -import ( - "fmt" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/peer" - "github.com/anytypeio/go-anytype-infrastructure-experiments/syncproto" - "github.com/gogo/protobuf/proto" - "go.uber.org/zap" - "gopkg.in/mgo.v2/bson" -) - -type Message struct { - *syncproto.Message - peer peer.Peer -} - -func (m *Message) Peer() peer.Peer { - return m.peer -} - -func (m *Message) Reply(data []byte) (err error) { - rep := &syncproto.Message{ - Header: &syncproto.Header{ - TraceId: m.GetHeader().TraceId, - ReplyId: m.GetHeader().RequestId, - Type: syncproto.MessageType_MessageTypeSync, - }, - Data: data, - } - return m.peer.Send(rep) -} - -func (m *Message) ReplyType(tp syncproto.MessageType, data proto.Marshaler) (err error) { - dataBytes, err := data.Marshal() - if err != nil { - return err - } - rep := &syncproto.Message{ - Header: &syncproto.Header{ - TraceId: m.GetHeader().TraceId, - ReplyId: m.GetHeader().RequestId, - Type: tp, - }, - Data: dataBytes, - } - return m.peer.Send(rep) -} - -func (m *Message) Ack() (err error) { - ack := &syncproto.System{ - Ack: &syncproto.SystemAck{}, - } - data, err := ack.Marshal() - if err != nil { - return - } - rep := &syncproto.Message{ - Header: &syncproto.Header{ - TraceId: m.GetHeader().TraceId, - ReplyId: m.GetHeader().RequestId, - Type: syncproto.MessageType_MessageTypeSystem, - DebugInfo: "Ack", - }, - Data: data, - } - err = m.peer.Send(rep) - if err != nil { - log.With( - zap.String("peerId", m.peer.Id()), - zap.String("header", rep.GetHeader().String())). - Error("failed sending ack to peer", zap.Error(err)) - } else { - log.With( - zap.String("peerId", m.peer.Id()), - zap.String("header", rep.GetHeader().String())). - Debug("sent ack to peer") - } - return -} - -func (m *Message) AckError(code syncproto.SystemErrorCode, description string) (err error) { - ack := &syncproto.System{ - Ack: &syncproto.SystemAck{ - Error: &syncproto.SystemError{ - Code: code, - Description: description, - }, - }, - } - data, err := ack.Marshal() - if err != nil { - return - } - rep := &syncproto.Message{ - Header: &syncproto.Header{ - TraceId: []byte(bson.NewObjectId()), - ReplyId: m.GetHeader().RequestId, - Type: syncproto.MessageType_MessageTypeSystem, - DebugInfo: "AckError", - }, - Data: data, - } - if err != nil { - log.With( - zap.String("peerId", m.peer.Id()), - zap.String("header", rep.GetHeader().String())). - Error("failed sending ackError to peer", zap.Error(err)) - } else { - log.With( - zap.String("peerId", m.peer.Id()), - zap.String("header", rep.GetHeader().String())). - Debug("sent ackError to peer") - } - return m.peer.Send(rep) -} - -func (m *Message) IsAck() (err error) { - if tp := m.GetHeader().GetType(); tp != syncproto.MessageType_MessageTypeSystem { - return fmt.Errorf("unexpected message type in response: %v, want System", tp) - } - sys := &syncproto.System{} - if err = sys.Unmarshal(m.GetData()); err != nil { - return - } - if ack := sys.Ack; ack != nil { - if ack.Error != nil { - return fmt.Errorf("response error: code=%d; descriptipon=%s", ack.Error.Code, ack.Error.Description) - } - return nil - } - return fmt.Errorf("received not ack response") -} - -func (m *Message) UnmarshalData(msg proto.Unmarshaler) error { - return msg.Unmarshal(m.Data) -} diff --git a/service/net/pool/peer.go b/service/net/pool/peer.go deleted file mode 100644 index 6a7a96d0..00000000 --- a/service/net/pool/peer.go +++ /dev/null @@ -1,28 +0,0 @@ -package pool - -import ( - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/peer" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice" -) - -type peerEntry struct { - peer peer.Peer - groupIds []string - ready chan struct{} -} - -func (pe *peerEntry) addGroup(groupId string) (ok bool) { - if slice.FindPos(pe.groupIds, groupId) != -1 { - return false - } - pe.groupIds = append(pe.groupIds, groupId) - return true -} - -func (pe *peerEntry) removeGroup(groupId string) (ok bool) { - if slice.FindPos(pe.groupIds, groupId) == -1 { - return false - } - pe.groupIds = slice.Remove(pe.groupIds, groupId) - return true -} diff --git a/service/net/pool/pool.go b/service/net/pool/pool.go deleted file mode 100644 index f9d122d7..00000000 --- a/service/net/pool/pool.go +++ /dev/null @@ -1,396 +0,0 @@ -package pool - -import ( - "context" - "errors" - "fmt" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/dialer" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/peer" - "github.com/anytypeio/go-anytype-infrastructure-experiments/syncproto" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice" - "go.uber.org/zap" - "math/rand" - "sync" - "sync/atomic" -) - -const ( - CName = "sync/peerPool" - maxSimultaneousOperationsPerStream = 10 -) - -var log = logger.NewNamed("peerPool") - -var ( - ErrPoolClosed = errors.New("peer pool is closed") - ErrPeerNotFound = errors.New("peer not found") -) - -func NewPool() Pool { - return &pool{closed: true} -} - -type Handler func(ctx context.Context, msg *Message) (err error) - -type Pool interface { - AddAndReadPeer(peer peer.Peer) (err error) - AddHandler(msgType syncproto.MessageType, h Handler) - AddPeerIdToGroup(peerId, groupId string) (err error) - RemovePeerIdFromGroup(peerId, groupId string) (err error) - DialAndAddPeer(ctx context.Context, id string) (peer.Peer, error) - GetOrDialOneOf(ctx context.Context, peerIds []string) (peer.Peer, error) - - SendAndWait(ctx context.Context, peerId string, msg *syncproto.Message) (err error) - SendAndWaitResponse(ctx context.Context, id string, s *syncproto.Message) (resp *Message, err error) - Broadcast(ctx context.Context, groupId string, msg *syncproto.Message) (err error) - - app.ComponentRunnable -} - -type pool struct { - peersById map[string]*peerEntry - waiters *waiters - handlers map[syncproto.MessageType][]Handler - peersIdsByGroup map[string][]string - - dialer dialer.Dialer - - closed bool - mu sync.RWMutex - wg *sync.WaitGroup -} - -func (p *pool) Init(ctx context.Context, a *app.App) (err error) { - p.peersById = map[string]*peerEntry{} - p.handlers = map[syncproto.MessageType][]Handler{} - p.peersIdsByGroup = map[string][]string{} - p.waiters = &waiters{waiters: map[uint64]*waiter{}} - p.dialer = a.MustComponent(dialer.CName).(dialer.Dialer) - p.wg = &sync.WaitGroup{} - return nil -} - -func (p *pool) Name() (name string) { - return CName -} - -func (p *pool) Run(ctx context.Context) (err error) { - p.closed = false - return nil -} - -func (p *pool) AddHandler(msgType syncproto.MessageType, h Handler) { - p.mu.Lock() - defer p.mu.Unlock() - if !p.closed { - // unable to add handler after Run - return - } - p.handlers[msgType] = append(p.handlers[msgType], h) -} - -func (p *pool) DialAndAddPeer(ctx context.Context, peerId string) (peer.Peer, error) { - p.mu.Lock() - defer p.mu.Unlock() - if p.closed { - return nil, ErrPoolClosed - } - return p.dialAndAdd(ctx, peerId) -} - -func (p *pool) dialAndAdd(ctx context.Context, peerId string) (peer.Peer, error) { - if peer, ok := p.peersById[peerId]; ok { - return peer.peer, nil - } - peer, err := p.dialer.Dial(ctx, peerId) - if err != nil { - return nil, err - } - p.peersById[peer.Id()] = &peerEntry{ - peer: peer, - } - p.wg.Add(1) - go p.readPeerLoop(peer) - return peer, nil -} - -func (p *pool) AddAndReadPeer(peer peer.Peer) (err error) { - p.mu.Lock() - if p.closed { - p.mu.Unlock() - return ErrPoolClosed - } - p.peersById[peer.Id()] = &peerEntry{ - peer: peer, - } - p.wg.Add(1) - p.mu.Unlock() - return p.readPeerLoop(peer) -} - -func (p *pool) AddPeerIdToGroup(peerId, groupId string) (err error) { - p.mu.Lock() - defer p.mu.Unlock() - peer, ok := p.peersById[peerId] - if !ok { - return ErrPeerNotFound - } - if slice.FindPos(peer.groupIds, groupId) != -1 { - return nil - } - peer.addGroup(groupId) - p.peersIdsByGroup[groupId] = append(p.peersIdsByGroup[groupId], peerId) - return -} - -func (p *pool) RemovePeerIdFromGroup(peerId, groupId string) (err error) { - p.mu.Lock() - defer p.mu.Unlock() - peer, ok := p.peersById[peerId] - if !ok { - return ErrPeerNotFound - } - if slice.FindPos(peer.groupIds, groupId) == -1 { - return nil - } - peer.removeGroup(groupId) - p.peersIdsByGroup[groupId] = slice.Remove(p.peersIdsByGroup[groupId], peerId) - return -} - -func (p *pool) SendAndWait(ctx context.Context, peerId string, msg *syncproto.Message) (err error) { - resp, err := p.SendAndWaitResponse(ctx, peerId, msg) - if err != nil { - return - } - return resp.IsAck() -} - -func (p *pool) SendAndWaitResponse(ctx context.Context, peerId string, msg *syncproto.Message) (resp *Message, err error) { - defer func() { - if err != nil { - log.With( - zap.String("peerId", peerId), - zap.String("header", msg.GetHeader().String())). - Error("failed sending message to peer", zap.Error(err)) - } else { - log.With( - zap.String("peerId", peerId), - zap.String("header", msg.GetHeader().String())). - Debug("sent message to peer") - } - }() - - p.mu.RLock() - peer := p.peersById[peerId] - p.mu.RUnlock() - if peer == nil { - err = ErrPeerNotFound - return - } - - repId := p.waiters.NewReplyId() - msg.GetHeader().RequestId = repId - ch := make(chan Reply, 1) - - p.waiters.Add(repId, &waiter{ch: ch}) - defer p.waiters.Remove(repId) - - if err = peer.peer.Send(msg); err != nil { - return - } - select { - case rep := <-ch: - if rep.Error != nil { - err = rep.Error - return - } - resp = rep.Message - return - case <-ctx.Done(): - log.Debug("context done in SendAndWait") - err = ctx.Err() - } - return -} - -func (p *pool) GetOrDialOneOf(ctx context.Context, peerIds []string) (peer.Peer, error) { - p.mu.RLock() - if p.closed { - p.mu.RUnlock() - return nil, ErrPoolClosed - } - for _, peerId := range peerIds { - peer, ok := p.peersById[peerId] - if ok { - p.mu.RUnlock() - return peer.peer, nil - } - } - p.mu.RUnlock() - rand.Shuffle(len(peerIds), func(i, j int) { - peerIds[i], peerIds[j] = peerIds[j], peerIds[i] - }) - p.mu.Lock() - defer p.mu.Unlock() - var lastErr error - for _, peerId := range peerIds { - peer, err := p.dialAndAdd(ctx, peerId) - if err != nil { - lastErr = err - continue - } else { - return peer, nil - } - } - return nil, lastErr -} - -func (p *pool) Broadcast(ctx context.Context, groupId string, msg *syncproto.Message) (err error) { - //TODO implement me - panic("implement me") -} - -func (p *pool) readPeerLoop(peer peer.Peer) (err error) { - defer p.wg.Done() - - limiter := make(chan struct{}, maxSimultaneousOperationsPerStream) - for i := 0; i < maxSimultaneousOperationsPerStream; i++ { - limiter <- struct{}{} - } -Loop: - for { - msg, err := peer.Recv() - if err != nil { - log.Debug("peer receive error", zap.Error(err), zap.String("peerId", peer.Id())) - break - } - select { - case <-limiter: - case <-peer.Context().Done(): - break Loop - } - go func() { - defer func() { - limiter <- struct{}{} - }() - p.handleMessage(peer, msg) - }() - } - if err = p.removePeer(peer.Id()); err != nil { - log.Error("remove peer error", zap.String("peerId", peer.Id()), zap.Error(err)) - } - return -} - -func (p *pool) removePeer(peerId string) (err error) { - p.mu.Lock() - defer p.mu.Unlock() - _, ok := p.peersById[peerId] - if !ok { - return ErrPeerNotFound - } - delete(p.peersById, peerId) - return -} - -func (p *pool) handleMessage(peer peer.Peer, msg *syncproto.Message) { - log.With(zap.String("peerId", peer.Id()), zap.String("header", msg.GetHeader().String())). - Debug("received message from peer") - replyId := msg.GetHeader().GetReplyId() - if replyId != 0 { - if !p.waiters.Send(replyId, Reply{ - PeerInfo: peer.Info(), - Message: &Message{ - Message: msg, - peer: peer, - }, - }) { - log.Debug("received reply with unknown (or expired) replyId", zap.Uint64("replyId", replyId), zap.String("header", msg.GetHeader().String())) - } - return - } - handlers := p.handlers[msg.GetHeader().GetType()] - if len(handlers) == 0 { - log.With(zap.String("peerId", peer.Id())).Debug("no handlers for such message") - return - } - - message := &Message{Message: msg, peer: peer} - - for _, h := range handlers { - if err := h(peer.Context(), message); err != nil { - log.Error("handle message error", zap.Error(err)) - } - } -} - -func (p *pool) Close(ctx context.Context) (err error) { - p.mu.Lock() - for _, peer := range p.peersById { - peer.peer.Close() - } - wg := p.wg - p.mu.Unlock() - if wg != nil { - wg.Wait() - } - return nil -} - -type waiter struct { - sent int - ch chan<- Reply -} - -type waiters struct { - waiters map[uint64]*waiter - replySeq uint64 - mu sync.Mutex -} - -func (w *waiters) Send(replyId uint64, r Reply) (ok bool) { - w.mu.Lock() - wait := w.waiters[replyId] - if wait == nil { - w.mu.Unlock() - return false - } - wait.sent++ - var lastMessage = wait.sent == cap(wait.ch) - if lastMessage { - delete(w.waiters, replyId) - } - w.mu.Unlock() - wait.ch <- r - if lastMessage { - close(wait.ch) - } - return true -} - -func (w *waiters) Add(replyId uint64, wait *waiter) { - w.mu.Lock() - w.waiters[replyId] = wait - w.mu.Unlock() -} - -func (w *waiters) Remove(id uint64) error { - w.mu.Lock() - defer w.mu.Unlock() - if _, ok := w.waiters[id]; ok { - delete(w.waiters, id) - return nil - } - return fmt.Errorf("waiter not found") -} - -func (w *waiters) NewReplyId() uint64 { - res := atomic.AddUint64(&w.replySeq, 1) - if res == 0 { - return w.NewReplyId() - } - return res -} diff --git a/service/net/pool/request.go b/service/net/pool/request.go deleted file mode 100644 index 8584f0dd..00000000 --- a/service/net/pool/request.go +++ /dev/null @@ -1,45 +0,0 @@ -package pool - -import "context" - -// 1. message for one peerId with ack -// pool.SendAndWait(ctx context,.C -// 2. message for many peers without ack (or group) - -type Request struct { - groupId string - oneOf []string - all []string - tryDial bool - needReply bool - pool *pool -} - -func (r *Request) GroupId(groupId string) *Request { - r.groupId = groupId - return r -} - -func (r *Request) All(peerIds ...string) *Request { - r.all = peerIds - return r -} - -func (r *Request) OneOf(peerIds ...string) *Request { - r.oneOf = peerIds - return r -} - -func (r *Request) TryDial(is bool) *Request { - r.tryDial = is - return r -} - -func (r *Request) NeedReply(is bool) *Request { - r.needReply = is - return r -} - -func (r *Request) Exec(ctx context.Context, msg *Message) *Results { - return nil -} diff --git a/service/net/pool/result.go b/service/net/pool/result.go deleted file mode 100644 index 94f1ac93..00000000 --- a/service/net/pool/result.go +++ /dev/null @@ -1,53 +0,0 @@ -package pool - -import ( - "context" - "fmt" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/peer" -) - -// Results of request collects replies and errors -// Must be closed after usage r.Close() -type Results struct { - ctx context.Context - cancel func() - waiterId uint64 - ch chan Reply - pool *pool -} - -// Iterate iterates over replies -// if callback will return a non-nil error then iteration stops -func (r *Results) Iterate(callback func(r Reply) (err error)) (err error) { - if r.ctx == nil || r.ch == nil { - return fmt.Errorf("results not initialized") - } - for { - select { - case <-r.ctx.Done(): - return r.ctx.Err() - case m, ok := <-r.ch: - if ok { - if err = callback(m); err != nil { - return err - } - } else { - return - } - } - } -} - -// Close cancels iteration and unregister reply handler in the pool -// Required to call to avoid memory leaks -func (r *Results) Close() (err error) { - r.cancel() - return r.pool.waiters.Remove(r.waiterId) -} - -// Reply presents the result of request executing can be error or result message -type Reply struct { - PeerInfo peer.Info - Error error - Message *Message -} diff --git a/service/net/rpc/encoding.go b/service/net/rpc/encoding.go deleted file mode 100644 index eb983b9d..00000000 --- a/service/net/rpc/encoding.go +++ /dev/null @@ -1,18 +0,0 @@ -package rpc - -import ( - "github.com/gogo/protobuf/proto" - "storj.io/drpc" -) - -var Encoding = enc{} - -type enc struct{} - -func (e enc) Marshal(msg drpc.Message) ([]byte, error) { - return msg.(proto.Marshaler).Marshal() -} - -func (e enc) Unmarshal(buf []byte, msg drpc.Message) error { - return msg.(proto.Unmarshaler).Unmarshal(buf) -} diff --git a/service/net/rpc/stream.go b/service/net/rpc/stream.go deleted file mode 100644 index c05691da..00000000 --- a/service/net/rpc/stream.go +++ /dev/null @@ -1,55 +0,0 @@ -package rpc - -import ( - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/peer" - "github.com/anytypeio/go-anytype-infrastructure-experiments/syncproto" - "github.com/libp2p/go-libp2p-core/sec" - "storj.io/drpc" - "sync/atomic" - "time" -) - -func PeerFromStream(sc sec.SecureConn, stream drpc.Stream, incoming bool) peer.Peer { - dp := &drpcPeer{ - sc: sc, - Stream: stream, - } - dp.info.Id = sc.RemotePeer().String() - if incoming { - dp.info.Dir = peer.DirInbound - } else { - dp.info.Dir = peer.DirOutbound - } - return dp -} - -type drpcPeer struct { - sc sec.SecureConn - info peer.Info - drpc.Stream -} - -func (d *drpcPeer) Id() string { - return d.info.Id -} - -func (d *drpcPeer) Info() peer.Info { - return d.info -} - -func (d *drpcPeer) Recv() (msg *syncproto.Message, err error) { - msg = &syncproto.Message{} - if err = d.Stream.MsgRecv(msg, Encoding); err != nil { - return - } - atomic.StoreInt64(&d.info.LastActiveUnix, time.Now().Unix()) - return -} - -func (d *drpcPeer) Send(msg *syncproto.Message) (err error) { - if err = d.Stream.MsgSend(msg, Encoding); err != nil { - return - } - atomic.StoreInt64(&d.info.LastActiveUnix, time.Now().Unix()) - return -} diff --git a/service/net/secure/context.go b/service/net/secure/context.go deleted file mode 100644 index c38da959..00000000 --- a/service/net/secure/context.go +++ /dev/null @@ -1,28 +0,0 @@ -package secure - -import ( - "context" - "errors" - "github.com/libp2p/go-libp2p-core/sec" -) - -var ( - ErrSecureConnNotFoundInContext = errors.New("secure connection not found in context") -) - -type contextKey uint - -const ( - contextKeySecureConn contextKey = iota -) - -func CtxSecureConn(ctx context.Context) (sec.SecureConn, error) { - if conn, ok := ctx.Value(contextKeySecureConn).(sec.SecureConn); ok { - return conn, nil - } - return nil, ErrSecureConnNotFoundInContext -} - -func ctxWithSecureConn(ctx context.Context, conn sec.SecureConn) context.Context { - return context.WithValue(ctx, contextKeySecureConn, conn) -} diff --git a/service/net/secure/service.go b/service/net/secure/service.go deleted file mode 100644 index 5c93862b..00000000 --- a/service/net/secure/service.go +++ /dev/null @@ -1,90 +0,0 @@ -package secure - -import ( - "context" - "fmt" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger" - "github.com/anytypeio/go-anytype-infrastructure-experiments/config" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/sec" - libp2ptls "github.com/libp2p/go-libp2p/p2p/security/tls" - "go.uber.org/zap" - "net" -) - -type HandshakeError error - -const CName = "net/secure" - -var log = logger.NewNamed(CName) - -func New() Service { - return &service{} -} - -type Service interface { - TLSListener(lis net.Listener) ContextListener - TLSConn(ctx context.Context, conn net.Conn) (sec.SecureConn, error) - app.Component -} - -type service struct { - key crypto.PrivKey -} - -func (s *service) Init(ctx context.Context, a *app.App) (err error) { - account := a.MustComponent(config.CName).(*config.Config).Account - decoder := signingkey.NewEDPrivKeyDecoder() - pkb, err := decoder.DecodeFromStringIntoBytes(account.SigningKey) - if err != nil { - return - } - if s.key, err = crypto.UnmarshalEd25519PrivateKey(pkb); err != nil { - return - } - - pid, err := peer.Decode(account.PeerId) - if err != nil { - return - } - - var testData = []byte("test data") - sign, err := s.key.Sign(testData) - if err != nil { - return - } - pubKey, err := pid.ExtractPublicKey() - if err != nil { - return - } - ok, err := pubKey.Verify(testData, sign) - if err != nil { - return - } - if !ok { - return fmt.Errorf("peerId and privateKey mismatched") - } - - log.Info("secure service init", zap.String("peerId", account.PeerId)) - - return nil -} - -func (s *service) Name() (name string) { - return CName -} - -func (s *service) TLSListener(lis net.Listener) ContextListener { - return newTLSListener(s.key, lis) -} - -func (s *service) TLSConn(ctx context.Context, conn net.Conn) (sec.SecureConn, error) { - tr, err := libp2ptls.New(s.key) - if err != nil { - return nil, err - } - return tr.SecureOutbound(ctx, conn, "") -} diff --git a/service/node/service.go b/service/node/service.go deleted file mode 100644 index 877c8860..00000000 --- a/service/node/service.go +++ /dev/null @@ -1,114 +0,0 @@ -package node - -import ( - "context" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger" - "github.com/anytypeio/go-anytype-infrastructure-experiments/config" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey" - "go.uber.org/zap" -) - -const CName = "NodesService" - -var log = logger.NewNamed("nodesservice") - -type Node struct { - Address string - PeerId string - SigningKey signingkey.PubKey - EncryptionKey encryptionkey.PubKey - SigningKeyString string - EncryptionKeyString string -} - -func (n *Node) Id() string { - return n.PeerId -} - -func (n *Node) Capacity() float64 { - return 1 -} - -func New() app.Component { - return &service{} -} - -type Service interface { - Nodes() []*Node -} - -type service struct { - nodes []*Node -} - -func (s *service) Init(ctx context.Context, a *app.App) (err error) { - cfg := a.MustComponent(config.CName).(*config.Config) - signDecoder := signingkey.NewEDPrivKeyDecoder() - rsaDecoder := encryptionkey.NewRSAPrivKeyDecoder() - - var filteredNodes []*Node - for _, n := range cfg.Nodes { - if n.PeerId == cfg.Account.PeerId { - continue - } - node, err := nodeFromConfigNode(n, n.PeerId, signDecoder, rsaDecoder) - if err != nil { - return err - } - log.With(zap.String("node", node.PeerId)).Debug("adding peer to known nodes") - filteredNodes = append(filteredNodes, node) - } - s.nodes = filteredNodes - return nil -} - -func (s *service) Name() (name string) { - return CName -} - -func (s *service) Run(ctx context.Context) (err error) { - return nil -} - -func (s *service) Close(ctx context.Context) (err error) { - return nil -} - -func (s *service) Nodes() []*Node { - return s.nodes -} - -func nodeFromConfigNode( - n config.Node, - peerId string, - privateSigningDecoder keys.Decoder, - privateEncryptionDecoder keys.Decoder) (*Node, error) { - decodedSigningKey, err := privateSigningDecoder.DecodeFromString(n.SigningKey) - if err != nil { - return nil, err - } - - decodedEncryptionKey, err := privateEncryptionDecoder.DecodeFromString(n.EncryptionKey) - if err != nil { - return nil, err - } - - encKeyString, err := privateEncryptionDecoder.EncodeToString(decodedEncryptionKey.(encryptionkey.PrivKey).GetPublic()) - if err != nil { - return nil, err - } - - signKeyString, err := privateSigningDecoder.EncodeToString(decodedSigningKey.(signingkey.PrivKey).GetPublic()) - - return &Node{ - Address: n.Address, - PeerId: peerId, - SigningKey: decodedSigningKey.(signingkey.PrivKey).GetPublic(), - EncryptionKey: decodedEncryptionKey.(encryptionkey.PrivKey).GetPublic(), - SigningKeyString: signKeyString, - EncryptionKeyString: encKeyString, - }, nil -} diff --git a/service/space/remotediff/remotediff.go b/service/space/remotediff/remotediff.go deleted file mode 100644 index 6ace7a33..00000000 --- a/service/space/remotediff/remotediff.go +++ /dev/null @@ -1,125 +0,0 @@ -package remotediff - -import ( - "context" - "fmt" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/ldiff" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/pool" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/space/spacesync" - "github.com/anytypeio/go-anytype-infrastructure-experiments/syncproto" -) - -func NewRemoteDiff(p pool.Pool, peerId, spaceId string) ldiff.Remote { - return remote{ - pool: p, - peerId: peerId, - spaceId: spaceId, - } -} - -type remote struct { - pool pool.Pool - peerId string - spaceId string -} - -func (r remote) Ranges(ctx context.Context, ranges []ldiff.Range, resBuf []ldiff.RangeResult) (results []ldiff.RangeResult, err error) { - results = resBuf[:0] - pbRanges := make([]*spacesync.DiffRangeRequestRange, 0, len(ranges)) - for _, rg := range ranges { - pbRanges = append(pbRanges, &spacesync.DiffRangeRequestRange{ - From: rg.From, - To: rg.To, - Limit: uint32(rg.Limit), - }) - } - req := &spacesync.Space{ - SpaceId: r.spaceId, - Message: &spacesync.SpaceContent{ - Value: &spacesync.SpaceContentValueOfDiffRange{ - DiffRange: &spacesync.DiffRange{ - Request: &spacesync.DiffRangeRequest{ - Ranges: pbRanges, - }, - }, - }, - }, - } - msg, err := req.Marshal() - if err != nil { - return - } - resp, err := r.pool.SendAndWaitResponse(ctx, r.peerId, &syncproto.Message{ - Header: &syncproto.Header{ - Type: syncproto.MessageType_MessageTypeSpace, - }, - Data: msg, - }) - if err != nil { - return - } - var spaceResp = &spacesync.Space{} - if err = resp.UnmarshalData(spaceResp); err != nil { - return - } - rangeResp := spaceResp.GetMessage().GetDiffRange().GetResponse() - if rangeResp != nil { - return nil, fmt.Errorf("got nil response") - } - for _, rr := range rangeResp.Results { - var elms []ldiff.Element - if len(rr.Elements) > 0 { - elms = make([]ldiff.Element, 0, len(rr.Elements)) - } - results = append(results, ldiff.RangeResult{ - Hash: rr.Hash, - Elements: elms, - Count: int(rr.Count), - }) - } - return -} - -func HandlerRangeRequest(ctx context.Context, d ldiff.Diff, diffRange *spacesync.DiffRange) (resp *spacesync.DiffRange, err error) { - req := diffRange.GetRequest() - if req != nil { - return nil, fmt.Errorf("received nil request") - } - - ranges := make([]ldiff.Range, 0, len(req.Ranges)) - for _, reqRange := range req.Ranges { - ranges = append(ranges, ldiff.Range{ - From: reqRange.From, - To: reqRange.To, - Limit: int(reqRange.Limit), - }) - } - res, err := d.Ranges(ctx, ranges, nil) - if err != nil { - return - } - - var rangeResp = &spacesync.DiffRangeResponse{ - Results: make([]*spacesync.DiffRangeResponseResult, len(res)), - } - for _, rangeRes := range res { - var elements []*spacesync.DiffRangeResponseResultElement - if len(rangeRes.Elements) > 0 { - elements = make([]*spacesync.DiffRangeResponseResultElement, 0, len(rangeRes.Elements)) - for _, el := range rangeRes.Elements { - elements = append(elements, &spacesync.DiffRangeResponseResultElement{ - Id: el.Id, - Head: el.Head, - }) - } - } - rangeResp.Results = append(rangeResp.Results, &spacesync.DiffRangeResponseResult{ - Hash: rangeRes.Hash, - Elements: elements, - Count: uint32(rangeRes.Count), - }) - } - return &spacesync.DiffRange{ - Response: rangeResp, - }, nil -} diff --git a/service/space/service.go b/service/space/service.go deleted file mode 100644 index 364ce91d..00000000 --- a/service/space/service.go +++ /dev/null @@ -1,92 +0,0 @@ -package space - -import ( - "context" - "fmt" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger" - "github.com/anytypeio/go-anytype-infrastructure-experiments/config" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/ocache" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/configuration" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/pool" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/pool/handler" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/space/spacesync" - "github.com/anytypeio/go-anytype-infrastructure-experiments/syncproto" - "github.com/gogo/protobuf/proto" - "time" -) - -const CName = "space" - -var log = logger.NewNamed(CName) - -func New() Service { - return new(service) -} - -type Service interface { - handler.ReplyHandler - app.ComponentRunnable -} - -type service struct { - conf config.Space - cache ocache.OCache - pool pool.Pool - confService configuration.Service -} - -func (s *service) Init(ctx context.Context, a *app.App) (err error) { - s.conf = a.MustComponent(config.CName).(*config.Config).Space - s.pool = a.MustComponent(pool.CName).(pool.Pool) - s.confService = a.MustComponent(configuration.CName).(configuration.Service) - ttlSec := time.Second * time.Duration(s.conf.GCTTL) - s.cache = ocache.New(s.loadSpace, ocache.WithTTL(ttlSec), ocache.WithGCPeriod(time.Minute)) - s.pool.AddHandler(syncproto.MessageType_MessageTypeSpace, handler.Reply{ReplyHandler: s}.Handle) - - return nil -} - -func (s *service) Name() (name string) { - return CName -} - -func (s *service) Run(ctx context.Context) (err error) { - return -} - -func (s *service) loadSpace(ctx context.Context, id string) (value ocache.Object, err error) { - // TODO: load from database here - sp := &space{s: s, id: id, conf: s.confService.GetLast()} - if err = sp.Run(ctx); err != nil { - return nil, err - } - return sp, nil -} - -func (s *service) get(ctx context.Context, id string) (Space, error) { - obj, err := s.cache.Get(ctx, id) - if err != nil { - return nil, err - } - return obj.(Space), nil -} - -func (s *service) Handle(ctx context.Context, data []byte) (resp proto.Marshaler, err error) { - var spaceReq = &spacesync.Space{} - if err = spaceReq.Unmarshal(data); err != nil { - return - } - if spaceReq.SpaceId != "" { - sp, err := s.get(ctx, spaceReq.SpaceId) - if err != nil { - return - } - return sp.Handle(ctx, spaceReq) - } - return nil, fmt.Errorf("unexpected space message") -} - -func (s *service) Close(ctx context.Context) (err error) { - return s.cache.Close() -} diff --git a/service/space/space.go b/service/space/space.go deleted file mode 100644 index 511d0632..00000000 --- a/service/space/space.go +++ /dev/null @@ -1,158 +0,0 @@ -package space - -import ( - "context" - "fmt" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/ldiff" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/configuration" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/space/remotediff" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/space/spacesync" - "go.uber.org/zap" - "math/rand" - "sync" - "time" -) - -type Space interface { - Id() string - Handle(ctx context.Context, msg *spacesync.Space) (repl *spacesync.Space, err error) - Close() error -} - -type space struct { - id string - conf configuration.Configuration - diff ldiff.Diff - diffHandler func() - syncCtx context.Context - syncCancel func() - syncLoopDone chan struct{} - s *service - mu sync.RWMutex -} - -func (s *space) Id() string { - return s.id -} - -func (s *space) Run(ctx context.Context) error { - s.diff = ldiff.New(16, 16) - s.syncCtx, s.syncCancel = context.WithCancel(context.Background()) - s.syncLoopDone = make(chan struct{}) - s.testFill() - go s.syncLoop() - return nil -} - -func (s *space) testFill() { - var n = 1000 - var els = make([]ldiff.Element, 0, n) - rand.Seed(time.Now().UnixNano()) - for i := 0; i < n; i++ { - if rand.Intn(n) > 2 { - id := fmt.Sprintf("%s.%d", s.id, n) - head := "head." + id - if rand.Intn(n) > 2 { - head += ".modified" - } - els = append(els, ldiff.Element{ - Id: id, - Head: head, - }) - } - } - s.diff.Set(els...) -} - -func (s *space) Handle(ctx context.Context, msg *spacesync.Space) (repl *spacesync.Space, err error) { - if diffRange := msg.GetMessage().GetDiffRange(); diffRange != nil { - resp, er := remotediff.HandlerRangeRequest(ctx, s.diff, diffRange) - if er != nil { - return nil, er - } - return &spacesync.Space{SpaceId: s.id, Message: &spacesync.SpaceContent{ - Value: &spacesync.SpaceContentValueOfDiffRange{ - DiffRange: resp, - }, - }}, nil - } - - /// - - /// - - /// - - return nil, fmt.Errorf("unexpected request") -} - -func (s *space) syncLoop() { - defer close(s.syncLoopDone) - doSync := func() { - ctx, cancel := context.WithTimeout(s.syncCtx, time.Minute) - defer cancel() - if err := s.sync(ctx); err != nil { - log.Error("periodic sync error", zap.Error(err), zap.String("spaceId", s.id)) - } - } - doSync() - if s.s.conf.SyncPeriod > 0 { - ticker := time.NewTicker(time.Second * time.Duration(s.s.conf.SyncPeriod)) - defer ticker.Stop() - for { - select { - case <-s.syncCtx.Done(): - case <-ticker.C: - doSync() - } - } - } -} - -func (s *space) sync(ctx context.Context) error { - peerIds, err := s.peerIds(ctx) - if err != nil { - return err - } - for _, peerId := range peerIds { - if err := s.syncWithPeer(ctx, peerId); err != nil { - log.Error("can't sync with peer", zap.String("peer", peerId), zap.Error(err)) - } - } - return nil -} - -func (s *space) syncWithPeer(ctx context.Context, peerId string) (err error) { - rdiff := remotediff.NewRemoteDiff(s.s.pool, peerId, s.id) - newIds, changedIds, removedIds, err := s.diff.Diff(ctx, rdiff) - if err != nil { - return nil - } - log.Info("sync done:", zap.Strings("newIds", newIds), zap.Strings("changedIds", changedIds), zap.Strings("removedIds", removedIds)) - return -} - -func (s *space) peerIds(ctx context.Context) (peerIds []string, err error) { - if s.conf.IsResponsible(s.id) { - peers, err := s.conf.AllPeers(ctx, s.id) - if err != nil { - return nil, err - } - for _, p := range peers { - peerIds = append(peerIds, p.Id()) - } - } else { - peer, err := s.conf.OnePeer(ctx, s.id) - if err != nil { - return nil, err - } - peerIds = append(peerIds, peer.Id()) - } - return -} - -func (s *space) Close() error { - s.syncCancel() - <-s.syncLoopDone - return nil -} diff --git a/service/space/spacesync/protos/spacesync.proto b/service/space/spacesync/protos/spacesync.proto deleted file mode 100644 index 8d46ca0a..00000000 --- a/service/space/spacesync/protos/spacesync.proto +++ /dev/null @@ -1,42 +0,0 @@ -syntax = "proto3"; -package anytype; -option go_package = "service/space/spacesync"; - -message Space { - string spaceId = 1; - - Content message = 2; - - message Content { - oneof value { - DiffRange diffRange = 1; - - } - } -} - -message DiffRange { - Request request = 1; - Response response = 2; - - message Request { - repeated Range ranges = 1; - message Range { - uint64 from = 1; - uint64 to = 2; - uint32 limit = 3; - } - } - message Response { - repeated Result results = 1; - message Result { - bytes hash = 1; - repeated Element elements = 2; - uint32 count = 3; - message Element { - string id = 1; - string head = 2; - } - } - } -} \ No newline at end of file diff --git a/service/space/spacesync/spacesync.pb.go b/service/space/spacesync/spacesync.pb.go deleted file mode 100644 index 530c11e3..00000000 --- a/service/space/spacesync/spacesync.pb.go +++ /dev/null @@ -1,1943 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: service/space/spacesync/protos/spacesync.proto - -package spacesync - -import ( - fmt "fmt" - proto "github.com/gogo/protobuf/proto" - io "io" - math "math" - math_bits "math/bits" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package - -type Space struct { - SpaceId string `protobuf:"bytes,1,opt,name=spaceId,proto3" json:"spaceId,omitempty"` - Message *SpaceContent `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` -} - -func (m *Space) Reset() { *m = Space{} } -func (m *Space) String() string { return proto.CompactTextString(m) } -func (*Space) ProtoMessage() {} -func (*Space) Descriptor() ([]byte, []int) { - return fileDescriptor_11d78c2fb7c80384, []int{0} -} -func (m *Space) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Space) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Space.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *Space) XXX_Merge(src proto.Message) { - xxx_messageInfo_Space.Merge(m, src) -} -func (m *Space) XXX_Size() int { - return m.Size() -} -func (m *Space) XXX_DiscardUnknown() { - xxx_messageInfo_Space.DiscardUnknown(m) -} - -var xxx_messageInfo_Space proto.InternalMessageInfo - -func (m *Space) GetSpaceId() string { - if m != nil { - return m.SpaceId - } - return "" -} - -func (m *Space) GetMessage() *SpaceContent { - if m != nil { - return m.Message - } - return nil -} - -type SpaceContent struct { - // Types that are valid to be assigned to Value: - // *SpaceContentValueOfDiffRange - Value IsSpaceContentValue `protobuf_oneof:"value"` -} - -func (m *SpaceContent) Reset() { *m = SpaceContent{} } -func (m *SpaceContent) String() string { return proto.CompactTextString(m) } -func (*SpaceContent) ProtoMessage() {} -func (*SpaceContent) Descriptor() ([]byte, []int) { - return fileDescriptor_11d78c2fb7c80384, []int{0, 0} -} -func (m *SpaceContent) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *SpaceContent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_SpaceContent.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *SpaceContent) XXX_Merge(src proto.Message) { - xxx_messageInfo_SpaceContent.Merge(m, src) -} -func (m *SpaceContent) XXX_Size() int { - return m.Size() -} -func (m *SpaceContent) XXX_DiscardUnknown() { - xxx_messageInfo_SpaceContent.DiscardUnknown(m) -} - -var xxx_messageInfo_SpaceContent proto.InternalMessageInfo - -type IsSpaceContentValue interface { - IsSpaceContentValue() - MarshalTo([]byte) (int, error) - Size() int -} - -type SpaceContentValueOfDiffRange struct { - DiffRange *DiffRange `protobuf:"bytes,1,opt,name=diffRange,proto3,oneof" json:"diffRange,omitempty"` -} - -func (*SpaceContentValueOfDiffRange) IsSpaceContentValue() {} - -func (m *SpaceContent) GetValue() IsSpaceContentValue { - if m != nil { - return m.Value - } - return nil -} - -func (m *SpaceContent) GetDiffRange() *DiffRange { - if x, ok := m.GetValue().(*SpaceContentValueOfDiffRange); ok { - return x.DiffRange - } - return nil -} - -// XXX_OneofWrappers is for the internal use of the proto package. -func (*SpaceContent) XXX_OneofWrappers() []interface{} { - return []interface{}{ - (*SpaceContentValueOfDiffRange)(nil), - } -} - -type DiffRange struct { - Request *DiffRangeRequest `protobuf:"bytes,1,opt,name=request,proto3" json:"request,omitempty"` - Response *DiffRangeResponse `protobuf:"bytes,2,opt,name=response,proto3" json:"response,omitempty"` -} - -func (m *DiffRange) Reset() { *m = DiffRange{} } -func (m *DiffRange) String() string { return proto.CompactTextString(m) } -func (*DiffRange) ProtoMessage() {} -func (*DiffRange) Descriptor() ([]byte, []int) { - return fileDescriptor_11d78c2fb7c80384, []int{1} -} -func (m *DiffRange) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *DiffRange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_DiffRange.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *DiffRange) XXX_Merge(src proto.Message) { - xxx_messageInfo_DiffRange.Merge(m, src) -} -func (m *DiffRange) XXX_Size() int { - return m.Size() -} -func (m *DiffRange) XXX_DiscardUnknown() { - xxx_messageInfo_DiffRange.DiscardUnknown(m) -} - -var xxx_messageInfo_DiffRange proto.InternalMessageInfo - -func (m *DiffRange) GetRequest() *DiffRangeRequest { - if m != nil { - return m.Request - } - return nil -} - -func (m *DiffRange) GetResponse() *DiffRangeResponse { - if m != nil { - return m.Response - } - return nil -} - -type DiffRangeRequest struct { - Ranges []*DiffRangeRequestRange `protobuf:"bytes,1,rep,name=ranges,proto3" json:"ranges,omitempty"` -} - -func (m *DiffRangeRequest) Reset() { *m = DiffRangeRequest{} } -func (m *DiffRangeRequest) String() string { return proto.CompactTextString(m) } -func (*DiffRangeRequest) ProtoMessage() {} -func (*DiffRangeRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_11d78c2fb7c80384, []int{1, 0} -} -func (m *DiffRangeRequest) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *DiffRangeRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_DiffRangeRequest.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *DiffRangeRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_DiffRangeRequest.Merge(m, src) -} -func (m *DiffRangeRequest) XXX_Size() int { - return m.Size() -} -func (m *DiffRangeRequest) XXX_DiscardUnknown() { - xxx_messageInfo_DiffRangeRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_DiffRangeRequest proto.InternalMessageInfo - -func (m *DiffRangeRequest) GetRanges() []*DiffRangeRequestRange { - if m != nil { - return m.Ranges - } - return nil -} - -type DiffRangeRequestRange struct { - From uint64 `protobuf:"varint,1,opt,name=from,proto3" json:"from,omitempty"` - To uint64 `protobuf:"varint,2,opt,name=to,proto3" json:"to,omitempty"` - Limit uint32 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"` -} - -func (m *DiffRangeRequestRange) Reset() { *m = DiffRangeRequestRange{} } -func (m *DiffRangeRequestRange) String() string { return proto.CompactTextString(m) } -func (*DiffRangeRequestRange) ProtoMessage() {} -func (*DiffRangeRequestRange) Descriptor() ([]byte, []int) { - return fileDescriptor_11d78c2fb7c80384, []int{1, 0, 0} -} -func (m *DiffRangeRequestRange) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *DiffRangeRequestRange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_DiffRangeRequestRange.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *DiffRangeRequestRange) XXX_Merge(src proto.Message) { - xxx_messageInfo_DiffRangeRequestRange.Merge(m, src) -} -func (m *DiffRangeRequestRange) XXX_Size() int { - return m.Size() -} -func (m *DiffRangeRequestRange) XXX_DiscardUnknown() { - xxx_messageInfo_DiffRangeRequestRange.DiscardUnknown(m) -} - -var xxx_messageInfo_DiffRangeRequestRange proto.InternalMessageInfo - -func (m *DiffRangeRequestRange) GetFrom() uint64 { - if m != nil { - return m.From - } - return 0 -} - -func (m *DiffRangeRequestRange) GetTo() uint64 { - if m != nil { - return m.To - } - return 0 -} - -func (m *DiffRangeRequestRange) GetLimit() uint32 { - if m != nil { - return m.Limit - } - return 0 -} - -type DiffRangeResponse struct { - Results []*DiffRangeResponseResult `protobuf:"bytes,1,rep,name=results,proto3" json:"results,omitempty"` -} - -func (m *DiffRangeResponse) Reset() { *m = DiffRangeResponse{} } -func (m *DiffRangeResponse) String() string { return proto.CompactTextString(m) } -func (*DiffRangeResponse) ProtoMessage() {} -func (*DiffRangeResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_11d78c2fb7c80384, []int{1, 1} -} -func (m *DiffRangeResponse) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *DiffRangeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_DiffRangeResponse.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *DiffRangeResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_DiffRangeResponse.Merge(m, src) -} -func (m *DiffRangeResponse) XXX_Size() int { - return m.Size() -} -func (m *DiffRangeResponse) XXX_DiscardUnknown() { - xxx_messageInfo_DiffRangeResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_DiffRangeResponse proto.InternalMessageInfo - -func (m *DiffRangeResponse) GetResults() []*DiffRangeResponseResult { - if m != nil { - return m.Results - } - return nil -} - -type DiffRangeResponseResult struct { - Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` - Elements []*DiffRangeResponseResultElement `protobuf:"bytes,2,rep,name=elements,proto3" json:"elements,omitempty"` - Count uint32 `protobuf:"varint,3,opt,name=count,proto3" json:"count,omitempty"` -} - -func (m *DiffRangeResponseResult) Reset() { *m = DiffRangeResponseResult{} } -func (m *DiffRangeResponseResult) String() string { return proto.CompactTextString(m) } -func (*DiffRangeResponseResult) ProtoMessage() {} -func (*DiffRangeResponseResult) Descriptor() ([]byte, []int) { - return fileDescriptor_11d78c2fb7c80384, []int{1, 1, 0} -} -func (m *DiffRangeResponseResult) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *DiffRangeResponseResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_DiffRangeResponseResult.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *DiffRangeResponseResult) XXX_Merge(src proto.Message) { - xxx_messageInfo_DiffRangeResponseResult.Merge(m, src) -} -func (m *DiffRangeResponseResult) XXX_Size() int { - return m.Size() -} -func (m *DiffRangeResponseResult) XXX_DiscardUnknown() { - xxx_messageInfo_DiffRangeResponseResult.DiscardUnknown(m) -} - -var xxx_messageInfo_DiffRangeResponseResult proto.InternalMessageInfo - -func (m *DiffRangeResponseResult) GetHash() []byte { - if m != nil { - return m.Hash - } - return nil -} - -func (m *DiffRangeResponseResult) GetElements() []*DiffRangeResponseResultElement { - if m != nil { - return m.Elements - } - return nil -} - -func (m *DiffRangeResponseResult) GetCount() uint32 { - if m != nil { - return m.Count - } - return 0 -} - -type DiffRangeResponseResultElement struct { - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Head string `protobuf:"bytes,2,opt,name=head,proto3" json:"head,omitempty"` -} - -func (m *DiffRangeResponseResultElement) Reset() { *m = DiffRangeResponseResultElement{} } -func (m *DiffRangeResponseResultElement) String() string { return proto.CompactTextString(m) } -func (*DiffRangeResponseResultElement) ProtoMessage() {} -func (*DiffRangeResponseResultElement) Descriptor() ([]byte, []int) { - return fileDescriptor_11d78c2fb7c80384, []int{1, 1, 0, 0} -} -func (m *DiffRangeResponseResultElement) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *DiffRangeResponseResultElement) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_DiffRangeResponseResultElement.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *DiffRangeResponseResultElement) XXX_Merge(src proto.Message) { - xxx_messageInfo_DiffRangeResponseResultElement.Merge(m, src) -} -func (m *DiffRangeResponseResultElement) XXX_Size() int { - return m.Size() -} -func (m *DiffRangeResponseResultElement) XXX_DiscardUnknown() { - xxx_messageInfo_DiffRangeResponseResultElement.DiscardUnknown(m) -} - -var xxx_messageInfo_DiffRangeResponseResultElement proto.InternalMessageInfo - -func (m *DiffRangeResponseResultElement) GetId() string { - if m != nil { - return m.Id - } - return "" -} - -func (m *DiffRangeResponseResultElement) GetHead() string { - if m != nil { - return m.Head - } - return "" -} - -func init() { - proto.RegisterType((*Space)(nil), "anytype.Space") - proto.RegisterType((*SpaceContent)(nil), "anytype.Space.Content") - proto.RegisterType((*DiffRange)(nil), "anytype.DiffRange") - proto.RegisterType((*DiffRangeRequest)(nil), "anytype.DiffRange.Request") - proto.RegisterType((*DiffRangeRequestRange)(nil), "anytype.DiffRange.Request.Range") - proto.RegisterType((*DiffRangeResponse)(nil), "anytype.DiffRange.Response") - proto.RegisterType((*DiffRangeResponseResult)(nil), "anytype.DiffRange.Response.Result") - proto.RegisterType((*DiffRangeResponseResultElement)(nil), "anytype.DiffRange.Response.Result.Element") -} - -func init() { - proto.RegisterFile("service/space/spacesync/protos/spacesync.proto", fileDescriptor_11d78c2fb7c80384) -} - -var fileDescriptor_11d78c2fb7c80384 = []byte{ - // 428 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x92, 0xbf, 0x8e, 0xd4, 0x30, - 0x10, 0xc6, 0xd7, 0xd9, 0x3f, 0xde, 0xcc, 0x02, 0x85, 0x85, 0x20, 0x0a, 0x52, 0x14, 0x6d, 0x15, - 0x21, 0xe1, 0x83, 0x80, 0x04, 0x05, 0x0d, 0x07, 0x9c, 0xa0, 0x35, 0x1d, 0x5d, 0xd8, 0x78, 0xef, - 0x22, 0x25, 0x76, 0x88, 0x9d, 0x93, 0xf6, 0x05, 0xa8, 0xe9, 0x79, 0x02, 0xde, 0x84, 0xf2, 0x4a, - 0x4a, 0xb4, 0xfb, 0x0a, 0x54, 0x54, 0x28, 0x93, 0x38, 0x57, 0xc0, 0x42, 0x13, 0xcd, 0x8c, 0x7f, - 0xdf, 0x97, 0x6f, 0x2c, 0x03, 0x37, 0xb2, 0xb9, 0x2c, 0x36, 0xf2, 0xc4, 0xd4, 0x99, 0xfb, 0x9a, - 0x9d, 0xda, 0x9c, 0xd4, 0x8d, 0xb6, 0xda, 0x5c, 0x0f, 0x38, 0x0e, 0x18, 0xcd, 0xd4, 0xce, 0xee, - 0x6a, 0xb9, 0xfe, 0x42, 0x60, 0xfe, 0xae, 0x3b, 0x64, 0x01, 0x50, 0xa4, 0xde, 0xe6, 0x01, 0x89, - 0x49, 0xe2, 0x0b, 0xd7, 0xb2, 0x87, 0x40, 0x2b, 0x69, 0x4c, 0x76, 0x2e, 0x03, 0x2f, 0x26, 0xc9, - 0x2a, 0xbd, 0xc3, 0x07, 0x39, 0x47, 0x29, 0x7f, 0xa9, 0x95, 0x95, 0xca, 0x0a, 0x87, 0x85, 0x67, - 0x40, 0x87, 0x19, 0x4b, 0xc1, 0xcf, 0x8b, 0xed, 0x56, 0x64, 0xea, 0x5c, 0xa2, 0xf1, 0x2a, 0x65, - 0xa3, 0xfc, 0x95, 0x3b, 0x79, 0x33, 0x11, 0xd7, 0xd8, 0x29, 0x85, 0xf9, 0x65, 0x56, 0xb6, 0x72, - 0xfd, 0x6b, 0x0a, 0xfe, 0xc8, 0xb0, 0x27, 0x40, 0x1b, 0xf9, 0xb1, 0x95, 0xc6, 0x0e, 0x46, 0xe1, - 0x9f, 0x46, 0x5c, 0xf4, 0x84, 0x70, 0x28, 0x7b, 0x0a, 0xcb, 0x46, 0x9a, 0x5a, 0x2b, 0xe3, 0xe2, - 0xdf, 0xfb, 0xab, 0xac, 0x47, 0xc4, 0x08, 0x87, 0x9f, 0x08, 0xd0, 0xc1, 0x8d, 0x3d, 0x83, 0x45, - 0xd3, 0x71, 0x26, 0x20, 0xf1, 0x34, 0x59, 0xa5, 0xf1, 0xf1, 0x3f, 0x73, 0xec, 0xc4, 0xc0, 0x87, - 0x2f, 0x60, 0xde, 0xa7, 0x67, 0x30, 0xdb, 0x36, 0xba, 0xc2, 0xe8, 0x33, 0x81, 0x35, 0xbb, 0x05, - 0x9e, 0xd5, 0x98, 0x6a, 0x26, 0x3c, 0xab, 0xd9, 0x6d, 0x98, 0x97, 0x45, 0x55, 0xd8, 0x60, 0x1a, - 0x93, 0xe4, 0xa6, 0xe8, 0x9b, 0xf0, 0x27, 0x81, 0xa5, 0xcb, 0xc7, 0x9e, 0x77, 0x97, 0x60, 0xda, - 0xd2, 0xba, 0x28, 0xeb, 0x7f, 0x6c, 0xd3, 0x15, 0x6d, 0x89, 0x97, 0x81, 0x92, 0xf0, 0x2b, 0x81, - 0x45, 0x3f, 0xeb, 0xf2, 0x5c, 0x64, 0xe6, 0x02, 0xf3, 0xdc, 0x10, 0x58, 0xb3, 0x33, 0x58, 0xca, - 0x52, 0x56, 0x52, 0x59, 0x13, 0x78, 0xe8, 0x7e, 0xff, 0xff, 0xee, 0xfc, 0x75, 0x2f, 0x11, 0xa3, - 0xb6, 0xdb, 0x63, 0xa3, 0x5b, 0x35, 0xee, 0x81, 0x4d, 0xf8, 0x00, 0xe8, 0x80, 0x76, 0x8b, 0x17, - 0xee, 0x9d, 0x79, 0x45, 0x8e, 0x61, 0x64, 0x96, 0xe3, 0x55, 0xf8, 0x02, 0xeb, 0xd3, 0x47, 0xdf, - 0xf6, 0x11, 0xb9, 0xda, 0x47, 0xe4, 0xc7, 0x3e, 0x22, 0x9f, 0x0f, 0xd1, 0xe4, 0xea, 0x10, 0x4d, - 0xbe, 0x1f, 0xa2, 0xc9, 0xfb, 0xbb, 0x47, 0x5e, 0xfb, 0x87, 0x05, 0xbe, 0xee, 0xc7, 0xbf, 0x03, - 0x00, 0x00, 0xff, 0xff, 0x12, 0x5a, 0x4f, 0xd6, 0x0f, 0x03, 0x00, 0x00, -} - -func (m *Space) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *Space) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Space) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Message != nil { - { - size, err := m.Message.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSpacesync(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if len(m.SpaceId) > 0 { - i -= len(m.SpaceId) - copy(dAtA[i:], m.SpaceId) - i = encodeVarintSpacesync(dAtA, i, uint64(len(m.SpaceId))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *SpaceContent) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *SpaceContent) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *SpaceContent) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Value != nil { - { - size := m.Value.Size() - i -= size - if _, err := m.Value.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - } - } - return len(dAtA) - i, nil -} - -func (m *SpaceContentValueOfDiffRange) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *SpaceContentValueOfDiffRange) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.DiffRange != nil { - { - size, err := m.DiffRange.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSpacesync(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} -func (m *DiffRange) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *DiffRange) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *DiffRange) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Response != nil { - { - size, err := m.Response.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSpacesync(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if m.Request != nil { - { - size, err := m.Request.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSpacesync(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *DiffRangeRequest) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *DiffRangeRequest) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *DiffRangeRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Ranges) > 0 { - for iNdEx := len(m.Ranges) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Ranges[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSpacesync(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - -func (m *DiffRangeRequestRange) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *DiffRangeRequestRange) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *DiffRangeRequestRange) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Limit != 0 { - i = encodeVarintSpacesync(dAtA, i, uint64(m.Limit)) - i-- - dAtA[i] = 0x18 - } - if m.To != 0 { - i = encodeVarintSpacesync(dAtA, i, uint64(m.To)) - i-- - dAtA[i] = 0x10 - } - if m.From != 0 { - i = encodeVarintSpacesync(dAtA, i, uint64(m.From)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - -func (m *DiffRangeResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *DiffRangeResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *DiffRangeResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Results) > 0 { - for iNdEx := len(m.Results) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Results[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSpacesync(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - -func (m *DiffRangeResponseResult) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *DiffRangeResponseResult) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *DiffRangeResponseResult) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Count != 0 { - i = encodeVarintSpacesync(dAtA, i, uint64(m.Count)) - i-- - dAtA[i] = 0x18 - } - if len(m.Elements) > 0 { - for iNdEx := len(m.Elements) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Elements[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSpacesync(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - if len(m.Hash) > 0 { - i -= len(m.Hash) - copy(dAtA[i:], m.Hash) - i = encodeVarintSpacesync(dAtA, i, uint64(len(m.Hash))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *DiffRangeResponseResultElement) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *DiffRangeResponseResultElement) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *DiffRangeResponseResultElement) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Head) > 0 { - i -= len(m.Head) - copy(dAtA[i:], m.Head) - i = encodeVarintSpacesync(dAtA, i, uint64(len(m.Head))) - i-- - dAtA[i] = 0x12 - } - if len(m.Id) > 0 { - i -= len(m.Id) - copy(dAtA[i:], m.Id) - i = encodeVarintSpacesync(dAtA, i, uint64(len(m.Id))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func encodeVarintSpacesync(dAtA []byte, offset int, v uint64) int { - offset -= sovSpacesync(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *Space) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.SpaceId) - if l > 0 { - n += 1 + l + sovSpacesync(uint64(l)) - } - if m.Message != nil { - l = m.Message.Size() - n += 1 + l + sovSpacesync(uint64(l)) - } - return n -} - -func (m *SpaceContent) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Value != nil { - n += m.Value.Size() - } - return n -} - -func (m *SpaceContentValueOfDiffRange) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.DiffRange != nil { - l = m.DiffRange.Size() - n += 1 + l + sovSpacesync(uint64(l)) - } - return n -} -func (m *DiffRange) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Request != nil { - l = m.Request.Size() - n += 1 + l + sovSpacesync(uint64(l)) - } - if m.Response != nil { - l = m.Response.Size() - n += 1 + l + sovSpacesync(uint64(l)) - } - return n -} - -func (m *DiffRangeRequest) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.Ranges) > 0 { - for _, e := range m.Ranges { - l = e.Size() - n += 1 + l + sovSpacesync(uint64(l)) - } - } - return n -} - -func (m *DiffRangeRequestRange) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.From != 0 { - n += 1 + sovSpacesync(uint64(m.From)) - } - if m.To != 0 { - n += 1 + sovSpacesync(uint64(m.To)) - } - if m.Limit != 0 { - n += 1 + sovSpacesync(uint64(m.Limit)) - } - return n -} - -func (m *DiffRangeResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.Results) > 0 { - for _, e := range m.Results { - l = e.Size() - n += 1 + l + sovSpacesync(uint64(l)) - } - } - return n -} - -func (m *DiffRangeResponseResult) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Hash) - if l > 0 { - n += 1 + l + sovSpacesync(uint64(l)) - } - if len(m.Elements) > 0 { - for _, e := range m.Elements { - l = e.Size() - n += 1 + l + sovSpacesync(uint64(l)) - } - } - if m.Count != 0 { - n += 1 + sovSpacesync(uint64(m.Count)) - } - return n -} - -func (m *DiffRangeResponseResultElement) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Id) - if l > 0 { - n += 1 + l + sovSpacesync(uint64(l)) - } - l = len(m.Head) - if l > 0 { - n += 1 + l + sovSpacesync(uint64(l)) - } - return n -} - -func sovSpacesync(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozSpacesync(x uint64) (n int) { - return sovSpacesync(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *Space) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSpacesync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Space: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Space: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SpaceId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSpacesync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSpacesync - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSpacesync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.SpaceId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSpacesync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSpacesync - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSpacesync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Message == nil { - m.Message = &SpaceContent{} - } - if err := m.Message.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSpacesync(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSpacesync - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *SpaceContent) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSpacesync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Content: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Content: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DiffRange", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSpacesync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSpacesync - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSpacesync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &DiffRange{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Value = &SpaceContentValueOfDiffRange{v} - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSpacesync(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSpacesync - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *DiffRange) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSpacesync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: DiffRange: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: DiffRange: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Request", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSpacesync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSpacesync - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSpacesync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Request == nil { - m.Request = &DiffRangeRequest{} - } - if err := m.Request.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Response", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSpacesync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSpacesync - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSpacesync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Response == nil { - m.Response = &DiffRangeResponse{} - } - if err := m.Response.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSpacesync(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSpacesync - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *DiffRangeRequest) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSpacesync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Request: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Request: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ranges", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSpacesync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSpacesync - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSpacesync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Ranges = append(m.Ranges, &DiffRangeRequestRange{}) - if err := m.Ranges[len(m.Ranges)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSpacesync(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSpacesync - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *DiffRangeRequestRange) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSpacesync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Range: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Range: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field From", wireType) - } - m.From = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSpacesync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.From |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field To", wireType) - } - m.To = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSpacesync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.To |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType) - } - m.Limit = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSpacesync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Limit |= uint32(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := skipSpacesync(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSpacesync - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *DiffRangeResponse) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSpacesync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Response: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Response: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Results", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSpacesync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSpacesync - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSpacesync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Results = append(m.Results, &DiffRangeResponseResult{}) - if err := m.Results[len(m.Results)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSpacesync(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSpacesync - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *DiffRangeResponseResult) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSpacesync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Result: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Result: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSpacesync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthSpacesync - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthSpacesync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Hash = append(m.Hash[:0], dAtA[iNdEx:postIndex]...) - if m.Hash == nil { - m.Hash = []byte{} - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Elements", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSpacesync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSpacesync - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSpacesync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Elements = append(m.Elements, &DiffRangeResponseResultElement{}) - if err := m.Elements[len(m.Elements)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Count", wireType) - } - m.Count = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSpacesync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Count |= uint32(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := skipSpacesync(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSpacesync - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *DiffRangeResponseResultElement) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSpacesync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Element: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Element: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSpacesync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSpacesync - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSpacesync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Id = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Head", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSpacesync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSpacesync - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSpacesync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Head = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSpacesync(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSpacesync - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipSpacesync(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowSpacesync - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowSpacesync - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowSpacesync - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthSpacesync - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupSpacesync - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthSpacesync - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthSpacesync = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowSpacesync = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupSpacesync = fmt.Errorf("proto: unexpected end of group") -) diff --git a/service/sync/document/service.go b/service/sync/document/service.go deleted file mode 100644 index b684e64b..00000000 --- a/service/sync/document/service.go +++ /dev/null @@ -1,188 +0,0 @@ -package document - -import ( - "context" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/acltree" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/testchanges/testchangepb" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/account" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/node" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/sync/message" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/treecache" - "github.com/anytypeio/go-anytype-infrastructure-experiments/syncproto" - "github.com/gogo/protobuf/proto" - "go.uber.org/zap" -) - -var CName = "DocumentService" - -var log = logger.NewNamed("documentservice") - -type service struct { - messageService message.Service - treeCache treecache.Service - account account.Service - // to create new documents we need to know all nodes - nodes []*node.Node -} - -type Service interface { - UpdateDocument(ctx context.Context, id, text string) error - CreateDocument(ctx context.Context, text string) (string, error) -} - -func New() app.Component { - return &service{} -} - -func (s *service) Init(ctx context.Context, a *app.App) (err error) { - s.account = a.MustComponent(account.CName).(account.Service) - s.messageService = a.MustComponent(message.CName).(message.Service) - s.treeCache = a.MustComponent(treecache.CName).(treecache.Service) - - nodesService := a.MustComponent(node.CName).(node.Service) - s.nodes = nodesService.Nodes() - - return nil -} - -func (s *service) Name() (name string) { - return CName -} - -func (s *service) Run(ctx context.Context) (err error) { - return nil -} - -func (s *service) Close(ctx context.Context) (err error) { - return nil -} - -func (s *service) UpdateDocument(ctx context.Context, id, text string) (err error) { - var ( - ch *aclpb.RawChange - header *treepb.TreeHeader - snapshotPath []string - heads []string - ) - log.With(zap.String("id", id), zap.String("text", text)). - Debug("updating document") - - err = s.treeCache.Do(ctx, id, func(tree acltree.ACLTree) error { - ch, err = tree.AddContent(ctx, func(builder acltree.ChangeBuilder) error { - builder.AddChangeContent( - &testchangepb.PlainTextChangeData{ - Content: []*testchangepb.PlainTextChangeContent{ - createAppendTextChangeContent(text), - }, - }) - return nil - }) - if err != nil { - return err - } - - id = tree.ID() - heads = tree.Heads() - header = tree.Header() - snapshotPath = tree.SnapshotPath() - return nil - }) - if err != nil { - return err - } - log.With( - zap.String("id", id), - zap.Strings("heads", heads), - zap.String("header", header.String())). - Debug("document updated in the database") - - return s.messageService.SendToSpaceAsync("", syncproto.WrapHeadUpdate(&syncproto.SyncHeadUpdate{ - Heads: heads, - Changes: []*aclpb.RawChange{ch}, - TreeId: id, - SnapshotPath: snapshotPath, - TreeHeader: header, - })) -} - -func (s *service) CreateDocument(ctx context.Context, text string) (id string, err error) { - acc := s.account.Account() - var ( - ch *aclpb.RawChange - header *treepb.TreeHeader - snapshotPath []string - heads []string - ) - - err = s.treeCache.Create(ctx, func(builder acltree.ChangeBuilder) error { - err := builder.UserAdd(acc.Identity, acc.EncKey.GetPublic(), aclpb.ACLChange_Admin) - if err != nil { - return err - } - // adding all predefined nodes to the document as admins - for _, n := range s.nodes { - err = builder.UserAdd(n.SigningKeyString, n.EncryptionKey, aclpb.ACLChange_Admin) - if err != nil { - return err - } - } - - builder.AddChangeContent(createInitialChangeContent(text)) - return nil - }, func(tree acltree.ACLTree) error { - id = tree.ID() - heads = tree.Heads() - header = tree.Header() - snapshotPath = tree.SnapshotPath() - ch, err = tree.Storage().GetChange(ctx, heads[0]) - if err != nil { - return err - } - log.With( - zap.String("id", id), - zap.Strings("heads", heads), - zap.String("header", header.String())). - Debug("document created in the database") - return nil - }) - if err != nil { - return "", err - } - log.With(zap.String("id", id), zap.String("text", text)). - Debug("creating document") - - err = s.messageService.SendToSpaceAsync("", syncproto.WrapHeadUpdate(&syncproto.SyncHeadUpdate{ - Heads: heads, - Changes: []*aclpb.RawChange{ch}, - TreeId: id, - SnapshotPath: snapshotPath, - TreeHeader: header, - })) - if err != nil { - return "", err - } - return id, err -} - -func createInitialChangeContent(text string) proto.Marshaler { - return &testchangepb.PlainTextChangeData{ - Content: []*testchangepb.PlainTextChangeContent{ - createAppendTextChangeContent(text), - }, - Snapshot: &testchangepb.PlainTextChangeSnapshot{Text: text}, - } -} - -func createAppendTextChangeContent(text string) *testchangepb.PlainTextChangeContent { - return &testchangepb.PlainTextChangeContent{ - Value: &testchangepb.PlainTextChangeContentValueOfTextAppend{ - TextAppend: &testchangepb.PlainTextChangeTextAppend{ - Text: text, - }, - }, - } -} diff --git a/service/sync/message/service.go b/service/sync/message/service.go deleted file mode 100644 index efe76900..00000000 --- a/service/sync/message/service.go +++ /dev/null @@ -1,122 +0,0 @@ -package message - -import ( - "context" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/net/pool" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/node" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/sync/requesthandler" - "github.com/anytypeio/go-anytype-infrastructure-experiments/syncproto" - "github.com/gogo/protobuf/proto" - "sync" - "time" -) - -var log = logger.NewNamed("messageservice") - -const CName = "MessageService" - -type service struct { - nodes []*node.Node - requestHandler requesthandler.RequestHandler - pool pool.Pool - sync.RWMutex -} - -func New() app.Component { - return &service{} -} - -type Service interface { - SendMessageAsync(peerId string, msg *syncproto.Sync) error - SendToSpaceAsync(spaceId string, msg *syncproto.Sync) error -} - -func (s *service) Init(ctx context.Context, a *app.App) (err error) { - s.requestHandler = a.MustComponent(requesthandler.CName).(requesthandler.RequestHandler) - s.nodes = a.MustComponent(node.CName).(node.Service).Nodes() - s.pool = a.MustComponent(pool.CName).(pool.Pool) - s.pool.AddHandler(syncproto.MessageType_MessageTypeSync, s.HandleMessage) - return nil -} - -func (s *service) Name() (name string) { - return CName -} - -func (s *service) Run(ctx context.Context) (err error) { - return nil -} - -func (s *service) Close(ctx context.Context) (err error) { - return nil -} - -func (s *service) HandleMessage(ctx context.Context, msg *pool.Message) (err error) { - defer func() { - if err != nil { - msg.AckError(syncproto.SystemError_UNKNOWN, err.Error()) - } else { - msg.Ack() - } - }() - - syncMsg := &syncproto.Sync{} - err = proto.Unmarshal(msg.Data, syncMsg) - if err != nil { - return - } - - timeoutCtx, cancel := context.WithTimeout(ctx, time.Second*30) - defer cancel() - err = s.requestHandler.HandleSyncMessage(timeoutCtx, msg.Peer().Id(), syncMsg) - return -} - -func (s *service) SendMessageAsync(peerId string, msg *syncproto.Sync) (err error) { - _, err = s.pool.DialAndAddPeer(context.Background(), peerId) - if err != nil { - return - } - - marshalled, err := proto.Marshal(msg) - if err != nil { - return - } - - go s.sendAsync(peerId, msgType(msg), marshalled) - return -} - -func (s *service) SendToSpaceAsync(spaceId string, msg *syncproto.Sync) error { - for _, rp := range s.nodes { - s.SendMessageAsync(rp.PeerId, msg) - } - return nil -} - -func (s *service) sendAsync(peerId string, msgTypeStr string, marshalled []byte) error { - ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) - defer cancel() - return s.pool.SendAndWait(ctx, peerId, &syncproto.Message{ - Header: &syncproto.Header{ - Type: syncproto.MessageType_MessageTypeSync, - DebugInfo: msgTypeStr, - }, - Data: marshalled, - }) -} - -func msgType(content *syncproto.Sync) string { - msg := content.GetMessage() - switch { - case msg.GetFullSyncRequest() != nil: - return "FullSyncRequest" - case msg.GetFullSyncResponse() != nil: - return "FullSyncResponse" - case msg.GetHeadUpdate() != nil: - return "HeadUpdate" - } - return "UnknownMessage" -} diff --git a/service/sync/requesthandler/requesthandler.go b/service/sync/requesthandler/requesthandler.go deleted file mode 100644 index 2eb70551..00000000 --- a/service/sync/requesthandler/requesthandler.go +++ /dev/null @@ -1,272 +0,0 @@ -package requesthandler - -import ( - "context" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/acltree" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/account" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/treecache" - "github.com/anytypeio/go-anytype-infrastructure-experiments/syncproto" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice" - "go.uber.org/zap" -) - -type requestHandler struct { - treeCache treecache.Service - account account.Service - messageService MessageSender -} - -var log = logger.NewNamed("requesthandler") - -func New() app.Component { - return &requestHandler{} -} - -type RequestHandler interface { - HandleSyncMessage(ctx context.Context, senderId string, request *syncproto.Sync) (err error) -} - -type MessageSender interface { - SendMessageAsync(peerId string, msg *syncproto.Sync) error - SendToSpaceAsync(spaceId string, msg *syncproto.Sync) error -} - -const CName = "SyncRequestHandler" - -func (r *requestHandler) Init(ctx context.Context, a *app.App) (err error) { - r.treeCache = a.MustComponent(treecache.CName).(treecache.Service) - r.account = a.MustComponent(account.CName).(account.Service) - r.messageService = a.MustComponent("MessageService").(MessageSender) - return nil -} - -func (r *requestHandler) Name() (name string) { - return CName -} - -func (r *requestHandler) Run(ctx context.Context) (err error) { - return nil -} - -func (r *requestHandler) Close(ctx context.Context) (err error) { - return nil -} - -func (r *requestHandler) HandleSyncMessage(ctx context.Context, senderId string, content *syncproto.Sync) error { - msg := content.GetMessage() - switch { - case msg.GetFullSyncRequest() != nil: - return r.HandleFullSyncRequest(ctx, senderId, msg.GetFullSyncRequest()) - case msg.GetFullSyncResponse() != nil: - return r.HandleFullSyncResponse(ctx, senderId, msg.GetFullSyncResponse()) - case msg.GetHeadUpdate() != nil: - return r.HandleHeadUpdate(ctx, senderId, msg.GetHeadUpdate()) - } - return nil -} - -func (r *requestHandler) HandleHeadUpdate(ctx context.Context, senderId string, update *syncproto.SyncHeadUpdate) (err error) { - var ( - fullRequest *syncproto.SyncFullRequest - snapshotPath []string - result acltree.AddResult - ) - log.With(zap.String("peerId", senderId), zap.String("treeId", update.TreeId)). - Debug("processing head update") - - err = r.treeCache.Do(ctx, update.TreeId, func(tree acltree.ACLTree) error { - // TODO: check if we already have those changes - result, err = tree.AddRawChanges(ctx, update.Changes...) - if err != nil { - return err - } - log.With(zap.Strings("update heads", update.Heads), zap.Strings("tree heads", tree.Heads())). - Debug("comparing heads after head update") - shouldFullSync := !slice.UnsortedEquals(update.Heads, tree.Heads()) - snapshotPath = tree.SnapshotPath() - if shouldFullSync { - fullRequest, err = r.prepareFullSyncRequest(update.TreeId, update.TreeHeader, update.SnapshotPath, tree) - if err != nil { - return err - } - } - return nil - }) - // if there are no such tree - if err == treestorage.ErrUnknownTreeId { - // TODO: maybe we can optimize this by sending the header and stuff right away, so when the tree is created we are able to add it on first request - fullRequest = &syncproto.SyncFullRequest{ - TreeId: update.TreeId, - TreeHeader: update.TreeHeader, - } - } - // if we have incompatible heads, or we haven't seen the tree at all - if fullRequest != nil { - return r.messageService.SendMessageAsync(senderId, syncproto.WrapFullRequest(fullRequest)) - } - // if error or nothing has changed - if err != nil || len(result.Added) == 0 { - return err - } - // otherwise sending heads update message - newUpdate := &syncproto.SyncHeadUpdate{ - Heads: result.Heads, - Changes: result.Added, - SnapshotPath: snapshotPath, - TreeId: update.TreeId, - TreeHeader: update.TreeHeader, - } - return r.messageService.SendToSpaceAsync("", syncproto.WrapHeadUpdate(newUpdate)) -} - -func (r *requestHandler) HandleFullSyncRequest(ctx context.Context, senderId string, request *syncproto.SyncFullRequest) (err error) { - var ( - fullResponse *syncproto.SyncFullResponse - snapshotPath []string - result acltree.AddResult - ) - log.With(zap.String("peerId", senderId), zap.String("treeId", request.TreeId)). - Debug("processing full sync request") - - err = r.treeCache.Do(ctx, request.TreeId, func(tree acltree.ACLTree) error { - // TODO: check if we already have those changes - // if we have non-empty request - if len(request.Heads) != 0 { - result, err = tree.AddRawChanges(ctx, request.Changes...) - if err != nil { - return err - } - } - snapshotPath = tree.SnapshotPath() - fullResponse, err = r.prepareFullSyncResponse(request.TreeId, request.SnapshotPath, request.Changes, tree) - if err != nil { - return err - } - return nil - }) - if err != nil { - return err - } - err = r.messageService.SendMessageAsync(senderId, syncproto.WrapFullResponse(fullResponse)) - // if error or nothing has changed - if err != nil || len(result.Added) == 0 { - return err - } - - // otherwise sending heads update message - newUpdate := &syncproto.SyncHeadUpdate{ - Heads: result.Heads, - Changes: result.Added, - SnapshotPath: snapshotPath, - TreeId: request.TreeId, - TreeHeader: request.TreeHeader, - } - return r.messageService.SendToSpaceAsync("", syncproto.WrapHeadUpdate(newUpdate)) -} - -func (r *requestHandler) HandleFullSyncResponse(ctx context.Context, senderId string, response *syncproto.SyncFullResponse) (err error) { - var ( - snapshotPath []string - result acltree.AddResult - ) - log.With(zap.String("peerId", senderId), zap.String("treeId", response.TreeId)). - Debug("processing full sync response") - - err = r.treeCache.Do(ctx, response.TreeId, func(tree acltree.ACLTree) error { - // TODO: check if we already have those changes - result, err = tree.AddRawChanges(ctx, response.Changes...) - if err != nil { - return err - } - snapshotPath = tree.SnapshotPath() - return nil - }) - // if error or nothing has changed - if (err != nil || len(result.Added) == 0) && err != treestorage.ErrUnknownTreeId { - return err - } - // if we have a new tree - if err == treestorage.ErrUnknownTreeId { - err = r.createTree(ctx, response) - if err != nil { - return err - } - result = acltree.AddResult{ - OldHeads: []string{}, - Heads: response.Heads, - Added: response.Changes, - } - } - // sending heads update message - newUpdate := &syncproto.SyncHeadUpdate{ - Heads: result.Heads, - Changes: result.Added, - SnapshotPath: snapshotPath, - TreeId: response.TreeId, - } - return r.messageService.SendToSpaceAsync("", syncproto.WrapHeadUpdate(newUpdate)) -} - -func (r *requestHandler) prepareFullSyncRequest(treeId string, header *treepb.TreeHeader, theirPath []string, tree acltree.ACLTree) (*syncproto.SyncFullRequest, error) { - ourChanges, err := tree.ChangesAfterCommonSnapshot(theirPath) - if err != nil { - return nil, err - } - return &syncproto.SyncFullRequest{ - Heads: tree.Heads(), - Changes: ourChanges, - TreeId: treeId, - SnapshotPath: tree.SnapshotPath(), - TreeHeader: header, - }, nil -} - -func (r *requestHandler) prepareFullSyncResponse( - treeId string, - theirPath []string, - theirChanges []*aclpb.RawChange, - tree acltree.ACLTree) (*syncproto.SyncFullResponse, error) { - // TODO: we can probably use the common snapshot calculated on the request step from previous peer - ourChanges, err := tree.ChangesAfterCommonSnapshot(theirPath) - if err != nil { - return nil, err - } - theirMap := make(map[string]struct{}) - for _, ch := range theirChanges { - theirMap[ch.Id] = struct{}{} - } - - // filtering our changes, so we will not send the same changes back - var final []*aclpb.RawChange - for _, ch := range ourChanges { - if _, exists := theirMap[ch.Id]; !exists { - final = append(final, ch) - } - } - log.With(zap.Int("len(changes)", len(final)), zap.String("id", treeId)). - Debug("preparing changes for tree") - - return &syncproto.SyncFullResponse{ - Heads: tree.Heads(), - Changes: final, - TreeId: treeId, - SnapshotPath: tree.SnapshotPath(), - TreeHeader: tree.Header(), - }, nil -} - -func (r *requestHandler) createTree(ctx context.Context, response *syncproto.SyncFullResponse) error { - return r.treeCache.Add( - ctx, - response.TreeId, - response.TreeHeader, - response.Changes, - func(tree acltree.ACLTree) error { - return nil - }) -} diff --git a/service/treecache/service.go b/service/treecache/service.go deleted file mode 100644 index 687300f0..00000000 --- a/service/treecache/service.go +++ /dev/null @@ -1,111 +0,0 @@ -package treecache - -import ( - "context" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app" - "github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/acltree" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/ocache" - "github.com/anytypeio/go-anytype-infrastructure-experiments/service/account" - "go.uber.org/zap" -) - -const CName = "treecache" - -// TODO: add context -type ACLTreeFunc = func(tree acltree.ACLTree) error -type ChangeBuildFunc = func(builder acltree.ChangeBuilder) error - -var log = logger.NewNamed("treecache") - -type Service interface { - Do(ctx context.Context, treeId string, f ACLTreeFunc) error - Add(ctx context.Context, treeId string, header *treepb.TreeHeader, changes []*aclpb.RawChange, f ACLTreeFunc) error - Create(ctx context.Context, build ChangeBuildFunc, f ACLTreeFunc) error -} - -type service struct { - treeProvider treestorage.Provider - account account.Service - cache ocache.OCache -} - -func New() app.ComponentRunnable { - return &service{} -} - -func (s *service) Create(ctx context.Context, build ChangeBuildFunc, f ACLTreeFunc) error { - acc := s.account.Account() - st, err := acltree.CreateNewTreeStorageWithACL(acc, build, s.treeProvider.CreateTreeStorage) - if err != nil { - return err - } - - id, err := st.TreeID() - if err != nil { - return err - } - - return s.Do(ctx, id, f) -} - -func (s *service) Do(ctx context.Context, treeId string, f ACLTreeFunc) error { - log. - With(zap.String("treeId", treeId)). - Debug("requesting tree from cache to perform operation") - - tree, err := s.cache.Get(ctx, treeId) - defer s.cache.Release(treeId) - if err != nil { - return err - } - aclTree := tree.(acltree.ACLTree) - aclTree.Lock() - defer aclTree.Unlock() - return f(tree.(acltree.ACLTree)) -} - -func (s *service) Add(ctx context.Context, treeId string, header *treepb.TreeHeader, changes []*aclpb.RawChange, f ACLTreeFunc) error { - log. - With(zap.String("treeId", treeId), zap.Int("len(changes)", len(changes))). - Debug("adding tree with changes") - - _, err := s.treeProvider.CreateTreeStorage(treeId, header, changes) - if err != nil { - return err - } - return s.Do(ctx, treeId, f) -} - -func (s *service) Init(ctx context.Context, a *app.App) (err error) { - s.cache = ocache.New(s.loadTree) - s.account = a.MustComponent(account.CName).(account.Service) - s.treeProvider = treestorage.NewInMemoryTreeStorageProvider() - // TODO: for test we should load some predefined keys - return nil -} - -func (s *service) Name() (name string) { - return CName -} - -func (s *service) Run(ctx context.Context) (err error) { - return nil -} - -func (s *service) Close(ctx context.Context) (err error) { - return s.cache.Close() -} - -func (s *service) loadTree(ctx context.Context, id string) (ocache.Object, error) { - tree, err := s.treeProvider.TreeStorage(id) - if err != nil { - return nil, err - } - // TODO: should probably accept nil listeners - aclTree, err := acltree.BuildACLTree(tree, s.account.Account(), acltree.NoOpListener{}) - return aclTree, err -} diff --git a/syncproto/helpers.go b/syncproto/helpers.go deleted file mode 100644 index e3059bda..00000000 --- a/syncproto/helpers.go +++ /dev/null @@ -1,19 +0,0 @@ -package syncproto - -func WrapHeadUpdate(update *SyncHeadUpdate) *Sync { - return &Sync{Message: &SyncContentValue{ - Value: &SyncContentValueValueOfHeadUpdate{HeadUpdate: update}, - }} -} - -func WrapFullRequest(request *SyncFullRequest) *Sync { - return &Sync{Message: &SyncContentValue{ - Value: &SyncContentValueValueOfFullSyncRequest{FullSyncRequest: request}, - }} -} - -func WrapFullResponse(response *SyncFullResponse) *Sync { - return &Sync{Message: &SyncContentValue{ - Value: &SyncContentValueValueOfFullSyncResponse{FullSyncResponse: response}, - }} -} diff --git a/syncproto/proto/sync.proto b/syncproto/proto/sync.proto deleted file mode 100644 index 79b2ef5a..00000000 --- a/syncproto/proto/sync.proto +++ /dev/null @@ -1,91 +0,0 @@ -syntax = "proto3"; -package anytype; -option go_package = "/syncproto"; - -import "pkg/acl/aclchanges/aclpb/protos/aclchanges.proto"; -import "pkg/acl/treestorage/treepb/protos/tree.proto"; - -message Message { - Header header = 1; - bytes data = 2; -} - -message Header { - bytes traceId = 1; - uint64 requestId = 2; - uint64 replyId = 3; - MessageType type = 4; - string debugInfo = 5; -} - -enum MessageType { - MessageTypeSystem = 0; - MessageTypeSpace = 1; - MessageTypeSync = 2; - MessageTypeFile = 3; -} - -message System { - Handshake handshake = 1; - Ping ping = 2; - Ack ack = 3; - - message Handshake { - string protocolVersion = 1; - } - message Ping { - uint64 unixTime = 1; - } - message Ack { - Error error = 2; - } - message Error { - Code code = 1; - string description = 2; - - enum Code { - UNKNOWN = 0; - UNSUPPORTED_PROTOCOL_VERSION = 10; - } - } -} - -message Sync { - string spaceId = 1; - ContentValue message = 2; - - message ContentValue { - oneof value { - HeadUpdate headUpdate = 1; - Full.Request fullSyncRequest = 2; - Full.Response fullSyncResponse = 3; - } - } - - message HeadUpdate { - repeated string heads = 1; - repeated acl.RawChange changes = 2; - string treeId = 3; - repeated string snapshotPath = 4; - tree.TreeHeader treeHeader = 5; - } - - message Full { - // here with send the request with all changes we have (we already know sender's snapshot path) - message Request { - repeated string heads = 1; - repeated acl.RawChange changes = 2; - string treeId = 3; - repeated string snapshotPath = 4; - tree.TreeHeader treeHeader = 5; - } - - message Response { - repeated string heads = 1; - repeated acl.RawChange changes = 2; - string treeId = 3; - repeated string snapshotPath = 4; - tree.TreeHeader treeHeader = 5; - } - } -} diff --git a/syncproto/sync.pb.go b/syncproto/sync.pb.go deleted file mode 100644 index 3b07151f..00000000 --- a/syncproto/sync.pb.go +++ /dev/null @@ -1,3765 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: syncproto/proto/sync.proto - -package syncproto - -import ( - fmt "fmt" - aclpb "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb" - treepb "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb" - proto "github.com/gogo/protobuf/proto" - io "io" - math "math" - math_bits "math/bits" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package - -type MessageType int32 - -const ( - MessageType_MessageTypeSystem MessageType = 0 - MessageType_MessageTypeSpace MessageType = 1 - MessageType_MessageTypeSync MessageType = 2 - MessageType_MessageTypeFile MessageType = 3 -) - -var MessageType_name = map[int32]string{ - 0: "MessageTypeSystem", - 1: "MessageTypeSpace", - 2: "MessageTypeSync", - 3: "MessageTypeFile", -} - -var MessageType_value = map[string]int32{ - "MessageTypeSystem": 0, - "MessageTypeSpace": 1, - "MessageTypeSync": 2, - "MessageTypeFile": 3, -} - -func (x MessageType) String() string { - return proto.EnumName(MessageType_name, int32(x)) -} - -func (MessageType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_4b28dfdd48a89166, []int{0} -} - -type SystemErrorCode int32 - -const ( - SystemError_UNKNOWN SystemErrorCode = 0 - SystemError_UNSUPPORTED_PROTOCOL_VERSION SystemErrorCode = 10 -) - -var SystemErrorCode_name = map[int32]string{ - 0: "UNKNOWN", - 10: "UNSUPPORTED_PROTOCOL_VERSION", -} - -var SystemErrorCode_value = map[string]int32{ - "UNKNOWN": 0, - "UNSUPPORTED_PROTOCOL_VERSION": 10, -} - -func (x SystemErrorCode) String() string { - return proto.EnumName(SystemErrorCode_name, int32(x)) -} - -func (SystemErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_4b28dfdd48a89166, []int{2, 3, 0} -} - -type Message struct { - Header *Header `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"` - Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` -} - -func (m *Message) Reset() { *m = Message{} } -func (m *Message) String() string { return proto.CompactTextString(m) } -func (*Message) ProtoMessage() {} -func (*Message) Descriptor() ([]byte, []int) { - return fileDescriptor_4b28dfdd48a89166, []int{0} -} -func (m *Message) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Message) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Message.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *Message) XXX_Merge(src proto.Message) { - xxx_messageInfo_Message.Merge(m, src) -} -func (m *Message) XXX_Size() int { - return m.Size() -} -func (m *Message) XXX_DiscardUnknown() { - xxx_messageInfo_Message.DiscardUnknown(m) -} - -var xxx_messageInfo_Message proto.InternalMessageInfo - -func (m *Message) GetHeader() *Header { - if m != nil { - return m.Header - } - return nil -} - -func (m *Message) GetData() []byte { - if m != nil { - return m.Data - } - return nil -} - -type Header struct { - TraceId []byte `protobuf:"bytes,1,opt,name=traceId,proto3" json:"traceId,omitempty"` - RequestId uint64 `protobuf:"varint,2,opt,name=requestId,proto3" json:"requestId,omitempty"` - ReplyId uint64 `protobuf:"varint,3,opt,name=replyId,proto3" json:"replyId,omitempty"` - Type MessageType `protobuf:"varint,4,opt,name=type,proto3,enum=anytype.MessageType" json:"type,omitempty"` - DebugInfo string `protobuf:"bytes,5,opt,name=debugInfo,proto3" json:"debugInfo,omitempty"` -} - -func (m *Header) Reset() { *m = Header{} } -func (m *Header) String() string { return proto.CompactTextString(m) } -func (*Header) ProtoMessage() {} -func (*Header) Descriptor() ([]byte, []int) { - return fileDescriptor_4b28dfdd48a89166, []int{1} -} -func (m *Header) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Header) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Header.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *Header) XXX_Merge(src proto.Message) { - xxx_messageInfo_Header.Merge(m, src) -} -func (m *Header) XXX_Size() int { - return m.Size() -} -func (m *Header) XXX_DiscardUnknown() { - xxx_messageInfo_Header.DiscardUnknown(m) -} - -var xxx_messageInfo_Header proto.InternalMessageInfo - -func (m *Header) GetTraceId() []byte { - if m != nil { - return m.TraceId - } - return nil -} - -func (m *Header) GetRequestId() uint64 { - if m != nil { - return m.RequestId - } - return 0 -} - -func (m *Header) GetReplyId() uint64 { - if m != nil { - return m.ReplyId - } - return 0 -} - -func (m *Header) GetType() MessageType { - if m != nil { - return m.Type - } - return MessageType_MessageTypeSystem -} - -func (m *Header) GetDebugInfo() string { - if m != nil { - return m.DebugInfo - } - return "" -} - -type System struct { - Handshake *SystemHandshake `protobuf:"bytes,1,opt,name=handshake,proto3" json:"handshake,omitempty"` - Ping *SystemPing `protobuf:"bytes,2,opt,name=ping,proto3" json:"ping,omitempty"` - Ack *SystemAck `protobuf:"bytes,3,opt,name=ack,proto3" json:"ack,omitempty"` -} - -func (m *System) Reset() { *m = System{} } -func (m *System) String() string { return proto.CompactTextString(m) } -func (*System) ProtoMessage() {} -func (*System) Descriptor() ([]byte, []int) { - return fileDescriptor_4b28dfdd48a89166, []int{2} -} -func (m *System) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *System) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_System.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *System) XXX_Merge(src proto.Message) { - xxx_messageInfo_System.Merge(m, src) -} -func (m *System) XXX_Size() int { - return m.Size() -} -func (m *System) XXX_DiscardUnknown() { - xxx_messageInfo_System.DiscardUnknown(m) -} - -var xxx_messageInfo_System proto.InternalMessageInfo - -func (m *System) GetHandshake() *SystemHandshake { - if m != nil { - return m.Handshake - } - return nil -} - -func (m *System) GetPing() *SystemPing { - if m != nil { - return m.Ping - } - return nil -} - -func (m *System) GetAck() *SystemAck { - if m != nil { - return m.Ack - } - return nil -} - -type SystemHandshake struct { - ProtocolVersion string `protobuf:"bytes,1,opt,name=protocolVersion,proto3" json:"protocolVersion,omitempty"` -} - -func (m *SystemHandshake) Reset() { *m = SystemHandshake{} } -func (m *SystemHandshake) String() string { return proto.CompactTextString(m) } -func (*SystemHandshake) ProtoMessage() {} -func (*SystemHandshake) Descriptor() ([]byte, []int) { - return fileDescriptor_4b28dfdd48a89166, []int{2, 0} -} -func (m *SystemHandshake) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *SystemHandshake) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_SystemHandshake.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *SystemHandshake) XXX_Merge(src proto.Message) { - xxx_messageInfo_SystemHandshake.Merge(m, src) -} -func (m *SystemHandshake) XXX_Size() int { - return m.Size() -} -func (m *SystemHandshake) XXX_DiscardUnknown() { - xxx_messageInfo_SystemHandshake.DiscardUnknown(m) -} - -var xxx_messageInfo_SystemHandshake proto.InternalMessageInfo - -func (m *SystemHandshake) GetProtocolVersion() string { - if m != nil { - return m.ProtocolVersion - } - return "" -} - -type SystemPing struct { - UnixTime uint64 `protobuf:"varint,1,opt,name=unixTime,proto3" json:"unixTime,omitempty"` -} - -func (m *SystemPing) Reset() { *m = SystemPing{} } -func (m *SystemPing) String() string { return proto.CompactTextString(m) } -func (*SystemPing) ProtoMessage() {} -func (*SystemPing) Descriptor() ([]byte, []int) { - return fileDescriptor_4b28dfdd48a89166, []int{2, 1} -} -func (m *SystemPing) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *SystemPing) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_SystemPing.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *SystemPing) XXX_Merge(src proto.Message) { - xxx_messageInfo_SystemPing.Merge(m, src) -} -func (m *SystemPing) XXX_Size() int { - return m.Size() -} -func (m *SystemPing) XXX_DiscardUnknown() { - xxx_messageInfo_SystemPing.DiscardUnknown(m) -} - -var xxx_messageInfo_SystemPing proto.InternalMessageInfo - -func (m *SystemPing) GetUnixTime() uint64 { - if m != nil { - return m.UnixTime - } - return 0 -} - -type SystemAck struct { - Error *SystemError `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` -} - -func (m *SystemAck) Reset() { *m = SystemAck{} } -func (m *SystemAck) String() string { return proto.CompactTextString(m) } -func (*SystemAck) ProtoMessage() {} -func (*SystemAck) Descriptor() ([]byte, []int) { - return fileDescriptor_4b28dfdd48a89166, []int{2, 2} -} -func (m *SystemAck) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *SystemAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_SystemAck.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *SystemAck) XXX_Merge(src proto.Message) { - xxx_messageInfo_SystemAck.Merge(m, src) -} -func (m *SystemAck) XXX_Size() int { - return m.Size() -} -func (m *SystemAck) XXX_DiscardUnknown() { - xxx_messageInfo_SystemAck.DiscardUnknown(m) -} - -var xxx_messageInfo_SystemAck proto.InternalMessageInfo - -func (m *SystemAck) GetError() *SystemError { - if m != nil { - return m.Error - } - return nil -} - -type SystemError struct { - Code SystemErrorCode `protobuf:"varint,1,opt,name=code,proto3,enum=anytype.SystemErrorCode" json:"code,omitempty"` - Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` -} - -func (m *SystemError) Reset() { *m = SystemError{} } -func (m *SystemError) String() string { return proto.CompactTextString(m) } -func (*SystemError) ProtoMessage() {} -func (*SystemError) Descriptor() ([]byte, []int) { - return fileDescriptor_4b28dfdd48a89166, []int{2, 3} -} -func (m *SystemError) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *SystemError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_SystemError.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *SystemError) XXX_Merge(src proto.Message) { - xxx_messageInfo_SystemError.Merge(m, src) -} -func (m *SystemError) XXX_Size() int { - return m.Size() -} -func (m *SystemError) XXX_DiscardUnknown() { - xxx_messageInfo_SystemError.DiscardUnknown(m) -} - -var xxx_messageInfo_SystemError proto.InternalMessageInfo - -func (m *SystemError) GetCode() SystemErrorCode { - if m != nil { - return m.Code - } - return SystemError_UNKNOWN -} - -func (m *SystemError) GetDescription() string { - if m != nil { - return m.Description - } - return "" -} - -type Sync struct { - SpaceId string `protobuf:"bytes,1,opt,name=spaceId,proto3" json:"spaceId,omitempty"` - Message *SyncContentValue `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` -} - -func (m *Sync) Reset() { *m = Sync{} } -func (m *Sync) String() string { return proto.CompactTextString(m) } -func (*Sync) ProtoMessage() {} -func (*Sync) Descriptor() ([]byte, []int) { - return fileDescriptor_4b28dfdd48a89166, []int{3} -} -func (m *Sync) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Sync) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Sync.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *Sync) XXX_Merge(src proto.Message) { - xxx_messageInfo_Sync.Merge(m, src) -} -func (m *Sync) XXX_Size() int { - return m.Size() -} -func (m *Sync) XXX_DiscardUnknown() { - xxx_messageInfo_Sync.DiscardUnknown(m) -} - -var xxx_messageInfo_Sync proto.InternalMessageInfo - -func (m *Sync) GetSpaceId() string { - if m != nil { - return m.SpaceId - } - return "" -} - -func (m *Sync) GetMessage() *SyncContentValue { - if m != nil { - return m.Message - } - return nil -} - -type SyncContentValue struct { - // Types that are valid to be assigned to Value: - // *SyncContentValueValueOfHeadUpdate - // *SyncContentValueValueOfFullSyncRequest - // *SyncContentValueValueOfFullSyncResponse - Value IsSyncContentValueValue `protobuf_oneof:"value"` -} - -func (m *SyncContentValue) Reset() { *m = SyncContentValue{} } -func (m *SyncContentValue) String() string { return proto.CompactTextString(m) } -func (*SyncContentValue) ProtoMessage() {} -func (*SyncContentValue) Descriptor() ([]byte, []int) { - return fileDescriptor_4b28dfdd48a89166, []int{3, 0} -} -func (m *SyncContentValue) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *SyncContentValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_SyncContentValue.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *SyncContentValue) XXX_Merge(src proto.Message) { - xxx_messageInfo_SyncContentValue.Merge(m, src) -} -func (m *SyncContentValue) XXX_Size() int { - return m.Size() -} -func (m *SyncContentValue) XXX_DiscardUnknown() { - xxx_messageInfo_SyncContentValue.DiscardUnknown(m) -} - -var xxx_messageInfo_SyncContentValue proto.InternalMessageInfo - -type IsSyncContentValueValue interface { - IsSyncContentValueValue() - MarshalTo([]byte) (int, error) - Size() int -} - -type SyncContentValueValueOfHeadUpdate struct { - HeadUpdate *SyncHeadUpdate `protobuf:"bytes,1,opt,name=headUpdate,proto3,oneof" json:"headUpdate,omitempty"` -} -type SyncContentValueValueOfFullSyncRequest struct { - FullSyncRequest *SyncFullRequest `protobuf:"bytes,2,opt,name=fullSyncRequest,proto3,oneof" json:"fullSyncRequest,omitempty"` -} -type SyncContentValueValueOfFullSyncResponse struct { - FullSyncResponse *SyncFullResponse `protobuf:"bytes,3,opt,name=fullSyncResponse,proto3,oneof" json:"fullSyncResponse,omitempty"` -} - -func (*SyncContentValueValueOfHeadUpdate) IsSyncContentValueValue() {} -func (*SyncContentValueValueOfFullSyncRequest) IsSyncContentValueValue() {} -func (*SyncContentValueValueOfFullSyncResponse) IsSyncContentValueValue() {} - -func (m *SyncContentValue) GetValue() IsSyncContentValueValue { - if m != nil { - return m.Value - } - return nil -} - -func (m *SyncContentValue) GetHeadUpdate() *SyncHeadUpdate { - if x, ok := m.GetValue().(*SyncContentValueValueOfHeadUpdate); ok { - return x.HeadUpdate - } - return nil -} - -func (m *SyncContentValue) GetFullSyncRequest() *SyncFullRequest { - if x, ok := m.GetValue().(*SyncContentValueValueOfFullSyncRequest); ok { - return x.FullSyncRequest - } - return nil -} - -func (m *SyncContentValue) GetFullSyncResponse() *SyncFullResponse { - if x, ok := m.GetValue().(*SyncContentValueValueOfFullSyncResponse); ok { - return x.FullSyncResponse - } - return nil -} - -// XXX_OneofWrappers is for the internal use of the proto package. -func (*SyncContentValue) XXX_OneofWrappers() []interface{} { - return []interface{}{ - (*SyncContentValueValueOfHeadUpdate)(nil), - (*SyncContentValueValueOfFullSyncRequest)(nil), - (*SyncContentValueValueOfFullSyncResponse)(nil), - } -} - -type SyncHeadUpdate struct { - Heads []string `protobuf:"bytes,1,rep,name=heads,proto3" json:"heads,omitempty"` - Changes []*aclpb.RawChange `protobuf:"bytes,2,rep,name=changes,proto3" json:"changes,omitempty"` - TreeId string `protobuf:"bytes,3,opt,name=treeId,proto3" json:"treeId,omitempty"` - SnapshotPath []string `protobuf:"bytes,4,rep,name=snapshotPath,proto3" json:"snapshotPath,omitempty"` - TreeHeader *treepb.TreeHeader `protobuf:"bytes,5,opt,name=treeHeader,proto3" json:"treeHeader,omitempty"` -} - -func (m *SyncHeadUpdate) Reset() { *m = SyncHeadUpdate{} } -func (m *SyncHeadUpdate) String() string { return proto.CompactTextString(m) } -func (*SyncHeadUpdate) ProtoMessage() {} -func (*SyncHeadUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_4b28dfdd48a89166, []int{3, 1} -} -func (m *SyncHeadUpdate) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *SyncHeadUpdate) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_SyncHeadUpdate.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *SyncHeadUpdate) XXX_Merge(src proto.Message) { - xxx_messageInfo_SyncHeadUpdate.Merge(m, src) -} -func (m *SyncHeadUpdate) XXX_Size() int { - return m.Size() -} -func (m *SyncHeadUpdate) XXX_DiscardUnknown() { - xxx_messageInfo_SyncHeadUpdate.DiscardUnknown(m) -} - -var xxx_messageInfo_SyncHeadUpdate proto.InternalMessageInfo - -func (m *SyncHeadUpdate) GetHeads() []string { - if m != nil { - return m.Heads - } - return nil -} - -func (m *SyncHeadUpdate) GetChanges() []*aclpb.RawChange { - if m != nil { - return m.Changes - } - return nil -} - -func (m *SyncHeadUpdate) GetTreeId() string { - if m != nil { - return m.TreeId - } - return "" -} - -func (m *SyncHeadUpdate) GetSnapshotPath() []string { - if m != nil { - return m.SnapshotPath - } - return nil -} - -func (m *SyncHeadUpdate) GetTreeHeader() *treepb.TreeHeader { - if m != nil { - return m.TreeHeader - } - return nil -} - -type SyncFull struct { -} - -func (m *SyncFull) Reset() { *m = SyncFull{} } -func (m *SyncFull) String() string { return proto.CompactTextString(m) } -func (*SyncFull) ProtoMessage() {} -func (*SyncFull) Descriptor() ([]byte, []int) { - return fileDescriptor_4b28dfdd48a89166, []int{3, 2} -} -func (m *SyncFull) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *SyncFull) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_SyncFull.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *SyncFull) XXX_Merge(src proto.Message) { - xxx_messageInfo_SyncFull.Merge(m, src) -} -func (m *SyncFull) XXX_Size() int { - return m.Size() -} -func (m *SyncFull) XXX_DiscardUnknown() { - xxx_messageInfo_SyncFull.DiscardUnknown(m) -} - -var xxx_messageInfo_SyncFull proto.InternalMessageInfo - -// here with send the request with all changes we have (we already know sender's snapshot path) -type SyncFullRequest struct { - Heads []string `protobuf:"bytes,1,rep,name=heads,proto3" json:"heads,omitempty"` - Changes []*aclpb.RawChange `protobuf:"bytes,2,rep,name=changes,proto3" json:"changes,omitempty"` - TreeId string `protobuf:"bytes,3,opt,name=treeId,proto3" json:"treeId,omitempty"` - SnapshotPath []string `protobuf:"bytes,4,rep,name=snapshotPath,proto3" json:"snapshotPath,omitempty"` - TreeHeader *treepb.TreeHeader `protobuf:"bytes,5,opt,name=treeHeader,proto3" json:"treeHeader,omitempty"` -} - -func (m *SyncFullRequest) Reset() { *m = SyncFullRequest{} } -func (m *SyncFullRequest) String() string { return proto.CompactTextString(m) } -func (*SyncFullRequest) ProtoMessage() {} -func (*SyncFullRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_4b28dfdd48a89166, []int{3, 2, 0} -} -func (m *SyncFullRequest) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *SyncFullRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_SyncFullRequest.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *SyncFullRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_SyncFullRequest.Merge(m, src) -} -func (m *SyncFullRequest) XXX_Size() int { - return m.Size() -} -func (m *SyncFullRequest) XXX_DiscardUnknown() { - xxx_messageInfo_SyncFullRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_SyncFullRequest proto.InternalMessageInfo - -func (m *SyncFullRequest) GetHeads() []string { - if m != nil { - return m.Heads - } - return nil -} - -func (m *SyncFullRequest) GetChanges() []*aclpb.RawChange { - if m != nil { - return m.Changes - } - return nil -} - -func (m *SyncFullRequest) GetTreeId() string { - if m != nil { - return m.TreeId - } - return "" -} - -func (m *SyncFullRequest) GetSnapshotPath() []string { - if m != nil { - return m.SnapshotPath - } - return nil -} - -func (m *SyncFullRequest) GetTreeHeader() *treepb.TreeHeader { - if m != nil { - return m.TreeHeader - } - return nil -} - -type SyncFullResponse struct { - Heads []string `protobuf:"bytes,1,rep,name=heads,proto3" json:"heads,omitempty"` - Changes []*aclpb.RawChange `protobuf:"bytes,2,rep,name=changes,proto3" json:"changes,omitempty"` - TreeId string `protobuf:"bytes,3,opt,name=treeId,proto3" json:"treeId,omitempty"` - SnapshotPath []string `protobuf:"bytes,4,rep,name=snapshotPath,proto3" json:"snapshotPath,omitempty"` - TreeHeader *treepb.TreeHeader `protobuf:"bytes,5,opt,name=treeHeader,proto3" json:"treeHeader,omitempty"` -} - -func (m *SyncFullResponse) Reset() { *m = SyncFullResponse{} } -func (m *SyncFullResponse) String() string { return proto.CompactTextString(m) } -func (*SyncFullResponse) ProtoMessage() {} -func (*SyncFullResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_4b28dfdd48a89166, []int{3, 2, 1} -} -func (m *SyncFullResponse) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *SyncFullResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_SyncFullResponse.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *SyncFullResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_SyncFullResponse.Merge(m, src) -} -func (m *SyncFullResponse) XXX_Size() int { - return m.Size() -} -func (m *SyncFullResponse) XXX_DiscardUnknown() { - xxx_messageInfo_SyncFullResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_SyncFullResponse proto.InternalMessageInfo - -func (m *SyncFullResponse) GetHeads() []string { - if m != nil { - return m.Heads - } - return nil -} - -func (m *SyncFullResponse) GetChanges() []*aclpb.RawChange { - if m != nil { - return m.Changes - } - return nil -} - -func (m *SyncFullResponse) GetTreeId() string { - if m != nil { - return m.TreeId - } - return "" -} - -func (m *SyncFullResponse) GetSnapshotPath() []string { - if m != nil { - return m.SnapshotPath - } - return nil -} - -func (m *SyncFullResponse) GetTreeHeader() *treepb.TreeHeader { - if m != nil { - return m.TreeHeader - } - return nil -} - -func init() { - proto.RegisterEnum("anytype.MessageType", MessageType_name, MessageType_value) - proto.RegisterEnum("anytype.SystemErrorCode", SystemErrorCode_name, SystemErrorCode_value) - proto.RegisterType((*Message)(nil), "anytype.Message") - proto.RegisterType((*Header)(nil), "anytype.Header") - proto.RegisterType((*System)(nil), "anytype.System") - proto.RegisterType((*SystemHandshake)(nil), "anytype.System.Handshake") - proto.RegisterType((*SystemPing)(nil), "anytype.System.Ping") - proto.RegisterType((*SystemAck)(nil), "anytype.System.Ack") - proto.RegisterType((*SystemError)(nil), "anytype.System.Error") - proto.RegisterType((*Sync)(nil), "anytype.Sync") - proto.RegisterType((*SyncContentValue)(nil), "anytype.Sync.ContentValue") - proto.RegisterType((*SyncHeadUpdate)(nil), "anytype.Sync.HeadUpdate") - proto.RegisterType((*SyncFull)(nil), "anytype.Sync.Full") - proto.RegisterType((*SyncFullRequest)(nil), "anytype.Sync.Full.Request") - proto.RegisterType((*SyncFullResponse)(nil), "anytype.Sync.Full.Response") -} - -func init() { proto.RegisterFile("syncproto/proto/sync.proto", fileDescriptor_4b28dfdd48a89166) } - -var fileDescriptor_4b28dfdd48a89166 = []byte{ - // 806 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x55, 0xd1, 0x6e, 0xe3, 0x44, - 0x14, 0xf5, 0x24, 0x4e, 0xbc, 0xbe, 0xae, 0x5a, 0x33, 0xdb, 0x45, 0xc6, 0xac, 0x22, 0x2b, 0x02, - 0x61, 0x01, 0x72, 0x57, 0x81, 0x15, 0x12, 0x6f, 0xbb, 0xa5, 0x51, 0x22, 0x20, 0x89, 0x26, 0x49, - 0x91, 0x78, 0x59, 0x4d, 0xed, 0xd9, 0x24, 0x8a, 0x3b, 0x36, 0x1e, 0x07, 0xc8, 0x5f, 0xec, 0x37, - 0xf0, 0x0d, 0x48, 0x20, 0xbe, 0x80, 0xc7, 0x7d, 0xe4, 0x11, 0xb5, 0x12, 0x1f, 0x01, 0x2f, 0x68, - 0xc6, 0x76, 0xe2, 0x66, 0xfb, 0x03, 0xfb, 0xd0, 0x66, 0xee, 0xb9, 0xe7, 0x5c, 0x9f, 0x1b, 0xdf, - 0xb9, 0x01, 0x57, 0x6c, 0x79, 0x98, 0x66, 0x49, 0x9e, 0x9c, 0x15, 0xff, 0x65, 0x1c, 0xa8, 0x23, - 0x36, 0x28, 0xdf, 0xe6, 0xdb, 0x94, 0xb9, 0x4f, 0xd2, 0xf5, 0xe2, 0x8c, 0x86, 0xb1, 0xfc, 0x0b, - 0x97, 0x94, 0x2f, 0x98, 0x90, 0xc7, 0xf4, 0xaa, 0xd0, 0x88, 0x1a, 0x5e, 0x48, 0xdd, 0x4f, 0x2b, - 0x45, 0x9e, 0x31, 0x26, 0xf2, 0x24, 0xa3, 0x0b, 0xa6, 0xce, 0x7b, 0x8d, 0x8c, 0x0a, 0x76, 0xb7, - 0x0f, 0xc6, 0xb7, 0x4c, 0x08, 0xba, 0x60, 0xf8, 0x23, 0x68, 0x2f, 0x19, 0x8d, 0x58, 0xe6, 0x20, - 0x0f, 0xf9, 0x56, 0xef, 0x24, 0x28, 0x4d, 0x04, 0x03, 0x05, 0x93, 0x32, 0x8d, 0x31, 0xe8, 0x11, - 0xcd, 0xa9, 0xd3, 0xf0, 0x90, 0x7f, 0x44, 0xd4, 0xb9, 0xfb, 0x0b, 0x82, 0x76, 0x41, 0xc3, 0x0e, - 0x18, 0x79, 0x46, 0x43, 0x36, 0x8c, 0x54, 0xa1, 0x23, 0x52, 0x85, 0xf8, 0x31, 0x98, 0x19, 0xfb, - 0x61, 0xc3, 0x44, 0x3e, 0x8c, 0x94, 0x5a, 0x27, 0x7b, 0x40, 0xea, 0x32, 0x96, 0xc6, 0xdb, 0x61, - 0xe4, 0x34, 0x55, 0xae, 0x0a, 0xb1, 0x0f, 0xba, 0xf4, 0xe1, 0xe8, 0x1e, 0xf2, 0x8f, 0x7b, 0xa7, - 0x3b, 0x5f, 0xa5, 0xf3, 0xd9, 0x36, 0x65, 0x44, 0x31, 0xe4, 0x13, 0x22, 0x76, 0xb5, 0x59, 0x0c, - 0xf9, 0xcb, 0xc4, 0x69, 0x79, 0xc8, 0x37, 0xc9, 0x1e, 0xe8, 0xfe, 0xda, 0x84, 0xf6, 0x74, 0x2b, - 0x72, 0x76, 0x8d, 0xbf, 0x00, 0x73, 0x49, 0x79, 0x24, 0x96, 0x74, 0xcd, 0xca, 0x7e, 0xdf, 0xdb, - 0xd5, 0x2d, 0x38, 0xc1, 0xa0, 0x22, 0x90, 0x3d, 0x57, 0x7a, 0x49, 0x57, 0x7c, 0xa1, 0xec, 0x5b, - 0x35, 0x2f, 0xa5, 0x66, 0xb2, 0xe2, 0x0b, 0xa2, 0x18, 0xf8, 0x43, 0x68, 0xd2, 0x70, 0xad, 0x7a, - 0xb1, 0x7a, 0x0f, 0x0f, 0x89, 0xcf, 0xc2, 0x35, 0x91, 0x79, 0xf7, 0x29, 0x98, 0x83, 0x5a, 0xf5, - 0x13, 0xf5, 0x5e, 0xc2, 0x24, 0xbe, 0x64, 0x99, 0x58, 0x25, 0x5c, 0x99, 0x33, 0xc9, 0x21, 0xec, - 0x76, 0x41, 0x97, 0xcf, 0xc2, 0x2e, 0x3c, 0xd8, 0xf0, 0xd5, 0xcf, 0xb3, 0xd5, 0x75, 0xd1, 0x87, - 0x4e, 0x76, 0xb1, 0xdb, 0x83, 0xe6, 0xb3, 0x70, 0x8d, 0x3f, 0x81, 0x16, 0xcb, 0xb2, 0x24, 0x2b, - 0x3d, 0x3f, 0x3a, 0xb4, 0x72, 0x21, 0x93, 0xa4, 0xe0, 0xb8, 0xaf, 0x10, 0xb4, 0x14, 0x80, 0x03, - 0xd0, 0xc3, 0x24, 0x2a, 0xaa, 0x1e, 0xf7, 0xdc, 0x7b, 0x55, 0xc1, 0x79, 0x12, 0x31, 0xa2, 0x78, - 0xd8, 0x03, 0x2b, 0x62, 0x22, 0xcc, 0x56, 0x69, 0x2e, 0x7d, 0x37, 0x94, 0xef, 0x3a, 0xd4, 0x7d, - 0x0a, 0xba, 0xe4, 0x63, 0x0b, 0x8c, 0xf9, 0xe8, 0xeb, 0xd1, 0xf8, 0xbb, 0x91, 0xad, 0x61, 0x0f, - 0x1e, 0xcf, 0x47, 0xd3, 0xf9, 0x64, 0x32, 0x26, 0xb3, 0x8b, 0xaf, 0x5e, 0x4c, 0xc8, 0x78, 0x36, - 0x3e, 0x1f, 0x7f, 0xf3, 0xe2, 0xf2, 0x82, 0x4c, 0x87, 0xe3, 0x91, 0x0d, 0xdd, 0x7f, 0xdb, 0xa0, - 0x4f, 0xb7, 0x3c, 0x94, 0x13, 0x22, 0xd2, 0xfd, 0x64, 0x99, 0xa4, 0x0a, 0xf1, 0xe7, 0x60, 0x5c, - 0x17, 0xc3, 0x50, 0x36, 0x59, 0xb7, 0xcb, 0xc3, 0xe0, 0x3c, 0xe1, 0x39, 0xe3, 0xf9, 0x25, 0x8d, - 0x37, 0x8c, 0x54, 0x54, 0xf7, 0x1f, 0x04, 0x47, 0xf5, 0x0c, 0xfe, 0x12, 0x40, 0xce, 0xf8, 0x3c, - 0x8d, 0x68, 0x5e, 0x8d, 0x85, 0x73, 0xb7, 0xd2, 0x60, 0x97, 0x1f, 0x68, 0xa4, 0xc6, 0xc6, 0x7d, - 0x38, 0x79, 0xb9, 0x89, 0x63, 0x49, 0x22, 0xc5, 0x4c, 0xdf, 0x6f, 0xa5, 0xbf, 0x89, 0xe3, 0xa0, - 0x64, 0x0c, 0x34, 0x72, 0x28, 0xc2, 0x43, 0xb0, 0xf7, 0x90, 0x48, 0x13, 0x2e, 0x58, 0x39, 0x43, - 0xef, 0xdf, 0x5b, 0xa8, 0xa0, 0x0c, 0x34, 0xf2, 0x86, 0xec, 0xb9, 0x01, 0xad, 0x1f, 0x65, 0x5f, - 0xee, 0x1f, 0x08, 0x60, 0x6f, 0x1c, 0x9f, 0x42, 0x4b, 0x1a, 0x17, 0x0e, 0xf2, 0x9a, 0xbe, 0x49, - 0x8a, 0x00, 0xfb, 0x60, 0x94, 0x9b, 0xc4, 0x69, 0x78, 0x4d, 0xdf, 0xea, 0x1d, 0x07, 0x34, 0x8c, - 0x03, 0x42, 0x7f, 0x3a, 0x57, 0x30, 0xa9, 0xd2, 0xf8, 0x5d, 0x68, 0xcb, 0x15, 0x52, 0x5e, 0x54, - 0x93, 0x94, 0x11, 0xee, 0xc2, 0x91, 0xe0, 0x34, 0x15, 0xcb, 0x24, 0x9f, 0xd0, 0x7c, 0xe9, 0xe8, - 0xaa, 0xfc, 0x1d, 0x0c, 0x3f, 0x01, 0x90, 0xec, 0x62, 0x57, 0xa8, 0x2b, 0x6a, 0xf5, 0xec, 0x40, - 0x6d, 0xa4, 0xd9, 0x0e, 0x27, 0x35, 0x8e, 0xfb, 0x5f, 0x03, 0x74, 0xd9, 0xab, 0xfb, 0x1b, 0x02, - 0xa3, 0xfa, 0x96, 0xde, 0xae, 0x16, 0x7e, 0x47, 0xf0, 0xa0, 0x7a, 0x2b, 0x6f, 0x97, 0xf5, 0x8f, - 0x23, 0xb0, 0x6a, 0x6b, 0x16, 0x3f, 0x82, 0x77, 0x6a, 0x61, 0xb1, 0x0a, 0x6c, 0x0d, 0x9f, 0x82, - 0x5d, 0x87, 0xe5, 0xad, 0xb4, 0x11, 0x7e, 0x08, 0x27, 0x77, 0xc8, 0x3c, 0xb4, 0x1b, 0x07, 0x60, - 0x7f, 0x15, 0x33, 0xbb, 0xf9, 0xfc, 0x83, 0x3f, 0x6f, 0x3a, 0xe8, 0xf5, 0x4d, 0x07, 0xfd, 0x7d, - 0xd3, 0x41, 0xaf, 0x6e, 0x3b, 0xda, 0xeb, 0xdb, 0x8e, 0xf6, 0xd7, 0x6d, 0x47, 0xfb, 0x1e, 0xce, - 0x76, 0x3f, 0x93, 0x57, 0x6d, 0xf5, 0xf1, 0xd9, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0x07, 0xa6, - 0xab, 0xcd, 0x3a, 0x07, 0x00, 0x00, -} - -func (m *Message) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *Message) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Message) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Data) > 0 { - i -= len(m.Data) - copy(dAtA[i:], m.Data) - i = encodeVarintSync(dAtA, i, uint64(len(m.Data))) - i-- - dAtA[i] = 0x12 - } - if m.Header != nil { - { - size, err := m.Header.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSync(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *Header) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *Header) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Header) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.DebugInfo) > 0 { - i -= len(m.DebugInfo) - copy(dAtA[i:], m.DebugInfo) - i = encodeVarintSync(dAtA, i, uint64(len(m.DebugInfo))) - i-- - dAtA[i] = 0x2a - } - if m.Type != 0 { - i = encodeVarintSync(dAtA, i, uint64(m.Type)) - i-- - dAtA[i] = 0x20 - } - if m.ReplyId != 0 { - i = encodeVarintSync(dAtA, i, uint64(m.ReplyId)) - i-- - dAtA[i] = 0x18 - } - if m.RequestId != 0 { - i = encodeVarintSync(dAtA, i, uint64(m.RequestId)) - i-- - dAtA[i] = 0x10 - } - if len(m.TraceId) > 0 { - i -= len(m.TraceId) - copy(dAtA[i:], m.TraceId) - i = encodeVarintSync(dAtA, i, uint64(len(m.TraceId))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *System) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *System) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *System) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Ack != nil { - { - size, err := m.Ack.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSync(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - if m.Ping != nil { - { - size, err := m.Ping.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSync(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if m.Handshake != nil { - { - size, err := m.Handshake.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSync(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *SystemHandshake) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *SystemHandshake) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *SystemHandshake) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.ProtocolVersion) > 0 { - i -= len(m.ProtocolVersion) - copy(dAtA[i:], m.ProtocolVersion) - i = encodeVarintSync(dAtA, i, uint64(len(m.ProtocolVersion))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *SystemPing) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *SystemPing) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *SystemPing) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.UnixTime != 0 { - i = encodeVarintSync(dAtA, i, uint64(m.UnixTime)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - -func (m *SystemAck) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *SystemAck) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *SystemAck) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Error != nil { - { - size, err := m.Error.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSync(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - return len(dAtA) - i, nil -} - -func (m *SystemError) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *SystemError) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *SystemError) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Description) > 0 { - i -= len(m.Description) - copy(dAtA[i:], m.Description) - i = encodeVarintSync(dAtA, i, uint64(len(m.Description))) - i-- - dAtA[i] = 0x12 - } - if m.Code != 0 { - i = encodeVarintSync(dAtA, i, uint64(m.Code)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - -func (m *Sync) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *Sync) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Sync) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Message != nil { - { - size, err := m.Message.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSync(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if len(m.SpaceId) > 0 { - i -= len(m.SpaceId) - copy(dAtA[i:], m.SpaceId) - i = encodeVarintSync(dAtA, i, uint64(len(m.SpaceId))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *SyncContentValue) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *SyncContentValue) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *SyncContentValue) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Value != nil { - { - size := m.Value.Size() - i -= size - if _, err := m.Value.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - } - } - return len(dAtA) - i, nil -} - -func (m *SyncContentValueValueOfHeadUpdate) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *SyncContentValueValueOfHeadUpdate) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.HeadUpdate != nil { - { - size, err := m.HeadUpdate.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSync(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} -func (m *SyncContentValueValueOfFullSyncRequest) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *SyncContentValueValueOfFullSyncRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.FullSyncRequest != nil { - { - size, err := m.FullSyncRequest.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSync(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - return len(dAtA) - i, nil -} -func (m *SyncContentValueValueOfFullSyncResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *SyncContentValueValueOfFullSyncResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.FullSyncResponse != nil { - { - size, err := m.FullSyncResponse.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSync(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - return len(dAtA) - i, nil -} -func (m *SyncHeadUpdate) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *SyncHeadUpdate) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *SyncHeadUpdate) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.TreeHeader != nil { - { - size, err := m.TreeHeader.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSync(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x2a - } - if len(m.SnapshotPath) > 0 { - for iNdEx := len(m.SnapshotPath) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.SnapshotPath[iNdEx]) - copy(dAtA[i:], m.SnapshotPath[iNdEx]) - i = encodeVarintSync(dAtA, i, uint64(len(m.SnapshotPath[iNdEx]))) - i-- - dAtA[i] = 0x22 - } - } - if len(m.TreeId) > 0 { - i -= len(m.TreeId) - copy(dAtA[i:], m.TreeId) - i = encodeVarintSync(dAtA, i, uint64(len(m.TreeId))) - i-- - dAtA[i] = 0x1a - } - if len(m.Changes) > 0 { - for iNdEx := len(m.Changes) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Changes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSync(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - if len(m.Heads) > 0 { - for iNdEx := len(m.Heads) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.Heads[iNdEx]) - copy(dAtA[i:], m.Heads[iNdEx]) - i = encodeVarintSync(dAtA, i, uint64(len(m.Heads[iNdEx]))) - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - -func (m *SyncFull) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *SyncFull) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *SyncFull) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - return len(dAtA) - i, nil -} - -func (m *SyncFullRequest) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *SyncFullRequest) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *SyncFullRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.TreeHeader != nil { - { - size, err := m.TreeHeader.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSync(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x2a - } - if len(m.SnapshotPath) > 0 { - for iNdEx := len(m.SnapshotPath) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.SnapshotPath[iNdEx]) - copy(dAtA[i:], m.SnapshotPath[iNdEx]) - i = encodeVarintSync(dAtA, i, uint64(len(m.SnapshotPath[iNdEx]))) - i-- - dAtA[i] = 0x22 - } - } - if len(m.TreeId) > 0 { - i -= len(m.TreeId) - copy(dAtA[i:], m.TreeId) - i = encodeVarintSync(dAtA, i, uint64(len(m.TreeId))) - i-- - dAtA[i] = 0x1a - } - if len(m.Changes) > 0 { - for iNdEx := len(m.Changes) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Changes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSync(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - if len(m.Heads) > 0 { - for iNdEx := len(m.Heads) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.Heads[iNdEx]) - copy(dAtA[i:], m.Heads[iNdEx]) - i = encodeVarintSync(dAtA, i, uint64(len(m.Heads[iNdEx]))) - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - -func (m *SyncFullResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *SyncFullResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *SyncFullResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.TreeHeader != nil { - { - size, err := m.TreeHeader.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSync(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x2a - } - if len(m.SnapshotPath) > 0 { - for iNdEx := len(m.SnapshotPath) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.SnapshotPath[iNdEx]) - copy(dAtA[i:], m.SnapshotPath[iNdEx]) - i = encodeVarintSync(dAtA, i, uint64(len(m.SnapshotPath[iNdEx]))) - i-- - dAtA[i] = 0x22 - } - } - if len(m.TreeId) > 0 { - i -= len(m.TreeId) - copy(dAtA[i:], m.TreeId) - i = encodeVarintSync(dAtA, i, uint64(len(m.TreeId))) - i-- - dAtA[i] = 0x1a - } - if len(m.Changes) > 0 { - for iNdEx := len(m.Changes) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Changes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSync(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - if len(m.Heads) > 0 { - for iNdEx := len(m.Heads) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.Heads[iNdEx]) - copy(dAtA[i:], m.Heads[iNdEx]) - i = encodeVarintSync(dAtA, i, uint64(len(m.Heads[iNdEx]))) - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - -func encodeVarintSync(dAtA []byte, offset int, v uint64) int { - offset -= sovSync(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *Message) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Header != nil { - l = m.Header.Size() - n += 1 + l + sovSync(uint64(l)) - } - l = len(m.Data) - if l > 0 { - n += 1 + l + sovSync(uint64(l)) - } - return n -} - -func (m *Header) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.TraceId) - if l > 0 { - n += 1 + l + sovSync(uint64(l)) - } - if m.RequestId != 0 { - n += 1 + sovSync(uint64(m.RequestId)) - } - if m.ReplyId != 0 { - n += 1 + sovSync(uint64(m.ReplyId)) - } - if m.Type != 0 { - n += 1 + sovSync(uint64(m.Type)) - } - l = len(m.DebugInfo) - if l > 0 { - n += 1 + l + sovSync(uint64(l)) - } - return n -} - -func (m *System) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Handshake != nil { - l = m.Handshake.Size() - n += 1 + l + sovSync(uint64(l)) - } - if m.Ping != nil { - l = m.Ping.Size() - n += 1 + l + sovSync(uint64(l)) - } - if m.Ack != nil { - l = m.Ack.Size() - n += 1 + l + sovSync(uint64(l)) - } - return n -} - -func (m *SystemHandshake) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.ProtocolVersion) - if l > 0 { - n += 1 + l + sovSync(uint64(l)) - } - return n -} - -func (m *SystemPing) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.UnixTime != 0 { - n += 1 + sovSync(uint64(m.UnixTime)) - } - return n -} - -func (m *SystemAck) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Error != nil { - l = m.Error.Size() - n += 1 + l + sovSync(uint64(l)) - } - return n -} - -func (m *SystemError) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Code != 0 { - n += 1 + sovSync(uint64(m.Code)) - } - l = len(m.Description) - if l > 0 { - n += 1 + l + sovSync(uint64(l)) - } - return n -} - -func (m *Sync) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.SpaceId) - if l > 0 { - n += 1 + l + sovSync(uint64(l)) - } - if m.Message != nil { - l = m.Message.Size() - n += 1 + l + sovSync(uint64(l)) - } - return n -} - -func (m *SyncContentValue) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Value != nil { - n += m.Value.Size() - } - return n -} - -func (m *SyncContentValueValueOfHeadUpdate) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.HeadUpdate != nil { - l = m.HeadUpdate.Size() - n += 1 + l + sovSync(uint64(l)) - } - return n -} -func (m *SyncContentValueValueOfFullSyncRequest) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.FullSyncRequest != nil { - l = m.FullSyncRequest.Size() - n += 1 + l + sovSync(uint64(l)) - } - return n -} -func (m *SyncContentValueValueOfFullSyncResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.FullSyncResponse != nil { - l = m.FullSyncResponse.Size() - n += 1 + l + sovSync(uint64(l)) - } - return n -} -func (m *SyncHeadUpdate) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.Heads) > 0 { - for _, s := range m.Heads { - l = len(s) - n += 1 + l + sovSync(uint64(l)) - } - } - if len(m.Changes) > 0 { - for _, e := range m.Changes { - l = e.Size() - n += 1 + l + sovSync(uint64(l)) - } - } - l = len(m.TreeId) - if l > 0 { - n += 1 + l + sovSync(uint64(l)) - } - if len(m.SnapshotPath) > 0 { - for _, s := range m.SnapshotPath { - l = len(s) - n += 1 + l + sovSync(uint64(l)) - } - } - if m.TreeHeader != nil { - l = m.TreeHeader.Size() - n += 1 + l + sovSync(uint64(l)) - } - return n -} - -func (m *SyncFull) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - return n -} - -func (m *SyncFullRequest) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.Heads) > 0 { - for _, s := range m.Heads { - l = len(s) - n += 1 + l + sovSync(uint64(l)) - } - } - if len(m.Changes) > 0 { - for _, e := range m.Changes { - l = e.Size() - n += 1 + l + sovSync(uint64(l)) - } - } - l = len(m.TreeId) - if l > 0 { - n += 1 + l + sovSync(uint64(l)) - } - if len(m.SnapshotPath) > 0 { - for _, s := range m.SnapshotPath { - l = len(s) - n += 1 + l + sovSync(uint64(l)) - } - } - if m.TreeHeader != nil { - l = m.TreeHeader.Size() - n += 1 + l + sovSync(uint64(l)) - } - return n -} - -func (m *SyncFullResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.Heads) > 0 { - for _, s := range m.Heads { - l = len(s) - n += 1 + l + sovSync(uint64(l)) - } - } - if len(m.Changes) > 0 { - for _, e := range m.Changes { - l = e.Size() - n += 1 + l + sovSync(uint64(l)) - } - } - l = len(m.TreeId) - if l > 0 { - n += 1 + l + sovSync(uint64(l)) - } - if len(m.SnapshotPath) > 0 { - for _, s := range m.SnapshotPath { - l = len(s) - n += 1 + l + sovSync(uint64(l)) - } - } - if m.TreeHeader != nil { - l = m.TreeHeader.Size() - n += 1 + l + sovSync(uint64(l)) - } - return n -} - -func sovSync(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozSync(x uint64) (n int) { - return sovSync(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *Message) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Message: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Message: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Header == nil { - m.Header = &Header{} - } - if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) - if m.Data == nil { - m.Data = []byte{} - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSync(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSync - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Header) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Header: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Header: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TraceId", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.TraceId = append(m.TraceId[:0], dAtA[iNdEx:postIndex]...) - if m.TraceId == nil { - m.TraceId = []byte{} - } - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field RequestId", wireType) - } - m.RequestId = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.RequestId |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ReplyId", wireType) - } - m.ReplyId = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.ReplyId |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - m.Type = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Type |= MessageType(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DebugInfo", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.DebugInfo = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSync(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSync - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *System) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: System: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: System: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Handshake", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Handshake == nil { - m.Handshake = &SystemHandshake{} - } - if err := m.Handshake.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ping", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Ping == nil { - m.Ping = &SystemPing{} - } - if err := m.Ping.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ack", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Ack == nil { - m.Ack = &SystemAck{} - } - if err := m.Ack.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSync(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSync - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *SystemHandshake) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Handshake: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Handshake: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProtocolVersion", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ProtocolVersion = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSync(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSync - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *SystemPing) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Ping: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Ping: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field UnixTime", wireType) - } - m.UnixTime = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.UnixTime |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := skipSync(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSync - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *SystemAck) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Ack: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Ack: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Error == nil { - m.Error = &SystemError{} - } - if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSync(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSync - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *SystemError) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Error: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Error: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Code", wireType) - } - m.Code = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Code |= SystemErrorCode(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Description = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSync(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSync - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Sync) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Sync: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Sync: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SpaceId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.SpaceId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Message == nil { - m.Message = &SyncContentValue{} - } - if err := m.Message.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSync(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSync - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *SyncContentValue) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ContentValue: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ContentValue: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field HeadUpdate", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &SyncHeadUpdate{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Value = &SyncContentValueValueOfHeadUpdate{v} - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field FullSyncRequest", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &SyncFullRequest{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Value = &SyncContentValueValueOfFullSyncRequest{v} - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field FullSyncResponse", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &SyncFullResponse{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Value = &SyncContentValueValueOfFullSyncResponse{v} - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSync(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSync - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *SyncHeadUpdate) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: HeadUpdate: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: HeadUpdate: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Heads", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Heads = append(m.Heads, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Changes", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Changes = append(m.Changes, &aclpb.RawChange{}) - if err := m.Changes[len(m.Changes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TreeId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.TreeId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SnapshotPath", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.SnapshotPath = append(m.SnapshotPath, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TreeHeader", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.TreeHeader == nil { - m.TreeHeader = &treepb.TreeHeader{} - } - if err := m.TreeHeader.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSync(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSync - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *SyncFull) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Full: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Full: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipSync(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSync - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *SyncFullRequest) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Request: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Request: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Heads", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Heads = append(m.Heads, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Changes", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Changes = append(m.Changes, &aclpb.RawChange{}) - if err := m.Changes[len(m.Changes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TreeId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.TreeId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SnapshotPath", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.SnapshotPath = append(m.SnapshotPath, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TreeHeader", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.TreeHeader == nil { - m.TreeHeader = &treepb.TreeHeader{} - } - if err := m.TreeHeader.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSync(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSync - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *SyncFullResponse) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Response: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Response: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Heads", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Heads = append(m.Heads, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Changes", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Changes = append(m.Changes, &aclpb.RawChange{}) - if err := m.Changes[len(m.Changes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TreeId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.TreeId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SnapshotPath", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.SnapshotPath = append(m.SnapshotPath, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TreeHeader", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSync - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.TreeHeader == nil { - m.TreeHeader = &treepb.TreeHeader{} - } - if err := m.TreeHeader.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSync(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSync - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipSync(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowSync - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowSync - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowSync - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthSync - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupSync - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthSync - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthSync = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowSync = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupSync = fmt.Errorf("proto: unexpected end of group") -) diff --git a/util/cmd/benchmarks/db/badger.go b/util/cmd/benchmarks/db/badger.go new file mode 100644 index 00000000..87bc01a2 --- /dev/null +++ b/util/cmd/benchmarks/db/badger.go @@ -0,0 +1,172 @@ +package db + +import ( + "fmt" + "github.com/dgraph-io/badger/v3" +) + +type badgerTree struct { + id string + spaceId string + db *badger.DB +} + +type badgerTransaction struct { + spaceId string + id string + txn *badger.Txn +} + +func (b *badgerTransaction) AddChange(key string, value []byte) (err error) { + badgerKey := fmt.Sprintf("space/%s/tree/%s/change/%s", b.spaceId, b.id, key) + return b.txn.Set([]byte(badgerKey), value) +} + +func (b *badgerTransaction) GetChange(key string) (val []byte, err error) { + badgerKey := fmt.Sprintf("space/%s/tree/%s/change/%s", b.spaceId, b.id, key) + it, err := b.txn.Get([]byte(badgerKey)) + if err != nil { + return + } + return it.ValueCopy(val) +} + +func (b *badgerTree) Perform(f func(txn Transaction) error) error { + return b.db.Update(func(txn *badger.Txn) error { + bTxn := &badgerTransaction{b.spaceId, b.id, txn} + return f(bTxn) + }) +} + +func (b *badgerTree) Id() string { + return b.id +} + +func (b *badgerTree) UpdateHead(head string) (err error) { + key := fmt.Sprintf("space/%s/tree/%s/heads", b.spaceId, b.id) + return b.db.Update(func(txn *badger.Txn) error { + return txn.Set([]byte(key), []byte(head)) + }) +} + +func (b *badgerTree) AddChange(key string, value []byte) (err error) { + badgerKey := fmt.Sprintf("space/%s/tree/%s/change/%s", b.spaceId, b.id, key) + return b.db.Update(func(txn *badger.Txn) error { + return txn.Set([]byte(badgerKey), value) + }) +} + +func (b *badgerTree) GetChange(key string) (val []byte, err error) { + badgerKey := fmt.Sprintf("space/%s/tree/%s/change/%s", b.spaceId, b.id, key) + err = b.db.View(func(txn *badger.Txn) error { + item, err := txn.Get([]byte(badgerKey)) + if err != nil { + return err + } + val, err = item.ValueCopy(val) + if err != nil { + return err + } + return nil + }) + return +} + +func (b *badgerTree) HasChange(key string) (has bool, err error) { + badgerKey := fmt.Sprintf("space/%s/tree/%s/change/%s", b.spaceId, b.id, key) + err = b.db.View(func(txn *badger.Txn) error { + _, err := txn.Get([]byte(badgerKey)) + return err + }) + if err != nil { + return + } + has = true + return +} + +type badgerSpace struct { + id string + db *badger.DB +} + +func (b *badgerSpace) Id() string { + return b.id +} + +func (b *badgerSpace) CreateTree(id string) (Tree, error) { + key := fmt.Sprintf("space/%s/tree/%s", b.id, id) + err := b.db.Update(func(txn *badger.Txn) error { + return txn.Set([]byte(key), []byte("exists")) + }) + if err != nil { + return nil, err + } + return &badgerTree{ + id: id, + spaceId: b.id, + db: b.db, + }, nil +} + +func (b *badgerSpace) GetTree(id string) (Tree, error) { + //TODO implement me + panic("implement me") +} + +func (b *badgerSpace) Close() error { + return nil +} + +type badgerSpaceCreator struct { + rootPath string + db *badger.DB +} + +func (b *badgerSpaceCreator) CreateSpace(id string) (Space, error) { + key := fmt.Sprintf("space/%s", id) + err := b.db.Update(func(txn *badger.Txn) error { + return txn.Set([]byte(key), []byte("exists")) + }) + if err != nil { + return nil, err + } + return &badgerSpace{ + id: id, + db: b.db, + }, nil +} + +func (b *badgerSpaceCreator) GetSpace(id string) (Space, error) { + key := fmt.Sprintf("space/%s", id) + err := b.db.Update(func(txn *badger.Txn) error { + _, err := txn.Get([]byte(key)) + if err != nil { + return err + } + return nil + }) + if err != nil { + return nil, err + } + return &badgerSpace{ + id: id, + db: b.db, + }, nil +} + +func (b *badgerSpaceCreator) Close() error { + return b.db.Close() +} + +func NewBadgerSpaceCreator() SpaceCreator { + rootPath := "badger.db.test" + db, err := badger.Open(badger.DefaultOptions(rootPath)) + if err != nil { + panic(err) + } + return &badgerSpaceCreator{ + rootPath: rootPath, + db: db, + } +} diff --git a/util/cmd/benchmarks/db/common.go b/util/cmd/benchmarks/db/common.go new file mode 100644 index 00000000..0443e3f6 --- /dev/null +++ b/util/cmd/benchmarks/db/common.go @@ -0,0 +1,30 @@ +package db + +type Transaction interface { + AddChange(key string, value []byte) (err error) + GetChange(key string) ([]byte, error) +} + +type Tree interface { + Id() string + UpdateHead(head string) (err error) + AddChange(key string, value []byte) (err error) + GetChange(key string) ([]byte, error) + HasChange(key string) (has bool, err error) + Perform(func(txn Transaction) error) error +} + +type Space interface { + Id() string + CreateTree(id string) (Tree, error) + GetTree(id string) (Tree, error) + Close() error +} + +type SpaceCreator interface { + CreateSpace(id string) (Space, error) + GetSpace(id string) (Space, error) + Close() error +} + +type SpaceCreatorFactory func() SpaceCreator diff --git a/util/cmd/benchmarks/db/pogreb.go b/util/cmd/benchmarks/db/pogreb.go new file mode 100644 index 00000000..2edca852 --- /dev/null +++ b/util/cmd/benchmarks/db/pogreb.go @@ -0,0 +1,95 @@ +package db + +import ( + "fmt" + "github.com/akrylysov/pogreb" + "path" + "time" +) + +type pogrebTree struct { + id string + db *pogreb.DB +} + +func (p *pogrebTree) Perform(f func(txn Transaction) error) error { + return f(p) +} + +func (p *pogrebTree) Id() string { + return p.id +} + +func (p *pogrebTree) UpdateHead(head string) (err error) { + return p.db.Put([]byte(fmt.Sprintf("t/%s/heads", p.id)), []byte(head)) +} + +func (p *pogrebTree) AddChange(key string, value []byte) (err error) { + changeKey := fmt.Sprintf("t/%s/%s", p.id, key) + return p.db.Put([]byte(changeKey), value) +} + +func (p *pogrebTree) GetChange(key string) (val []byte, err error) { + changeKey := fmt.Sprintf("t/%s/%s", p.id, key) + return p.db.Get([]byte(changeKey)) +} + +func (p *pogrebTree) HasChange(key string) (has bool, err error) { + changeKey := fmt.Sprintf("t/%s/%s", p.id, key) + return p.db.Has([]byte(changeKey)) +} + +type pogrebSpace struct { + id string + db *pogreb.DB +} + +func (p *pogrebSpace) Id() string { + return p.id +} + +func (p *pogrebSpace) CreateTree(id string) (Tree, error) { + return &pogrebTree{ + id: id, + db: p.db, + }, nil +} + +func (p *pogrebSpace) GetTree(id string) (Tree, error) { + return p.CreateTree(id) +} + +func (p *pogrebSpace) Close() error { + return p.db.Close() +} + +type pogrebSpaceCreator struct { + rootPath string +} + +func (p *pogrebSpaceCreator) CreateSpace(id string) (Space, error) { + dbPath := path.Join(p.rootPath, id) + db, err := pogreb.Open(dbPath, &pogreb.Options{ + BackgroundSyncInterval: time.Second * 30, + BackgroundCompactionInterval: time.Minute * 2, + }) + if err != nil { + return nil, err + } + return &pogrebSpace{ + id: id, + db: db, + }, nil +} + +func (p *pogrebSpaceCreator) GetSpace(id string) (Space, error) { + return p.CreateSpace(id) +} + +func (p *pogrebSpaceCreator) Close() error { + return nil +} + +func NewPogrebSpaceCreator() SpaceCreator { + return &pogrebSpaceCreator{rootPath: "db.test"} +} diff --git a/util/cmd/benchmarks/dbbench.go b/util/cmd/benchmarks/dbbench.go new file mode 100644 index 00000000..e5ff849a --- /dev/null +++ b/util/cmd/benchmarks/dbbench.go @@ -0,0 +1,190 @@ +package main + +import ( + "fmt" + "github.com/anytypeio/go-anytype-infrastructure-experiments/util/cmd/benchmarks/db" + "math/rand" + "net/http" + _ "net/http/pprof" + "os" + "os/signal" + "syscall" + "time" +) + +func main() { + go func() { + fmt.Println(http.ListenAndServe("localhost:6060", nil)) + }() + opts := options{ + numSpaces: 10, + numEntriesInSpace: 100, + numChangesInTree: 1000, + numHeadUpdates: 100, + defValueSize: 1000, + lenHeadUpdate: 1000, + } + fmt.Println("badger") + bench(db.NewBadgerSpaceCreator, opts) + fmt.Println("pogreb") + bench(db.NewPogrebSpaceCreator, opts) +} + +type options struct { + numSpaces int + numEntriesInSpace int + numChangesInTree int + numHeadUpdates int + defValueSize int + lenHeadUpdate int +} + +func bench(factory db.SpaceCreatorFactory, opts options) { + spaceIdKey := func(n int) string { + return fmt.Sprintf("space%d", n) + } + treeIdKey := func(n int) string { + return fmt.Sprintf("tree%d", n) + } + changeIdKey := func(n int) string { + return fmt.Sprintf("change%d", n) + } + + var byteSlice = func() []byte { + var buf = make([]byte, opts.defValueSize) + rand.Read(buf) + return buf + } + + var headUpdate = func() []byte { + var buf = make([]byte, opts.lenHeadUpdate) + rand.Read(buf) + return buf + } + + creator := factory() + // creating spaces + now := time.Now() + var spaces []db.Space + for i := 0; i < opts.numSpaces; i++ { + sp, err := creator.CreateSpace(spaceIdKey(i)) + if err != nil { + panic(err) + } + err = sp.Close() + if err != nil { + panic(err) + } + } + fmt.Println(opts.numSpaces, "spaces creation, spent ms", time.Now().Sub(now).Milliseconds()) + now = time.Now() + // creating trees + var trees []db.Tree + for i := 0; i < opts.numSpaces; i++ { + space, err := creator.GetSpace(spaceIdKey(i)) + if err != nil { + panic(err) + } + spaces = append(spaces, space) + for j := 0; j < opts.numEntriesInSpace; j++ { + tr, err := space.CreateTree(treeIdKey(j)) + if err != nil { + panic(err) + } + trees = append(trees, tr) + } + } + fmt.Println(opts.numSpaces*opts.numEntriesInSpace, "trees creation, spent ms", time.Now().Sub(now).Milliseconds()) + now = time.Now() + + // filling entries and updating heads + for _, t := range trees { + for i := 0; i < opts.numChangesInTree; i++ { + err := t.AddChange(changeIdKey(i), byteSlice()) + if err != nil { + panic(err) + } + } + //t.Perform(func(txn db.Transaction) error { + // for i := 0; i < opts.numChangesInTree; i++ { + // err := t.AddChange(changeIdKey(i), byteSlice()) + // if err != nil { + // panic(err) + // } + // } + // return nil + //}) + for i := 0; i < opts.numHeadUpdates; i++ { + err := t.UpdateHead(string(headUpdate())) + if err != nil { + panic(err) + } + } + } + total := opts.numSpaces * opts.numEntriesInSpace * opts.numChangesInTree + fmt.Println(total, "changes creation, spent ms", time.Now().Sub(now).Milliseconds()) + now = time.Now() + + // getting some values from tree + for _, t := range trees { + err := t.Perform(func(txn db.Transaction) error { + for i := 0; i < opts.numChangesInTree; i++ { + _, err := t.GetChange(changeIdKey(i)) + if err != nil { + return err + } + } + return nil + }) + if err != nil { + panic(err) + } + } + + fmt.Println(total, "changes getting perform, spent ms", time.Now().Sub(now).Milliseconds()) + now = time.Now() + + // getting some values from tree + for _, t := range trees { + for i := 0; i < opts.numChangesInTree; i++ { + res, err := t.GetChange(changeIdKey(i)) + if err != nil { + panic(err) + } + if res == nil { + panic("shouldn't be empty") + } + } + } + fmt.Println(total, "changes getting, spent ms", time.Now().Sub(now).Milliseconds()) + now = time.Now() + + // getting some values from tree + for _, t := range trees { + for i := 0; i < opts.numChangesInTree; i++ { + b, err := t.HasChange(changeIdKey(i)) + if err != nil { + panic(err) + } + if !b { + panic("should be able to check with has") + } + } + } + fmt.Println(total, "changes checking, spent ms", time.Now().Sub(now).Milliseconds()) + + exit := make(chan os.Signal, 1) + signal.Notify(exit, os.Interrupt, syscall.SIGKILL, syscall.SIGTERM, syscall.SIGQUIT) + sig := <-exit + for _, sp := range spaces { + err := sp.Close() + if err != nil { + panic(err) + } + } + err := creator.Close() + if err != nil { + panic(err) + } + fmt.Println(sig) +} diff --git a/util/cmd/nodesgen/gen.go b/util/cmd/nodesgen/gen.go new file mode 100644 index 00000000..ed659e48 --- /dev/null +++ b/util/cmd/nodesgen/gen.go @@ -0,0 +1,297 @@ +package main + +import ( + "flag" + "fmt" + config "github.com/anytypeio/go-anytype-infrastructure-experiments/common/config" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/encryptionkey" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/signingkey" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/peer" + cconfig "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/config" + "gopkg.in/yaml.v3" + "io/ioutil" + "os" +) + +var ( + flagNodeMap = flag.String("n", "util/cmd/nodesgen/nodemap.yml", "path to nodes map file") + flagEtcPath = flag.String("e", "etc", "path to etc directory") +) + +type NodesMap struct { + Nodes []struct { + Addresses []string `yaml:"grpcAddresses"` + APIPort string `yaml:"apiPort"` + } `yaml:"nodes"` + Consensus []struct { + Addresses []string `yaml:"grpcAddresses"` + } + Clients []struct { + Addresses []string `yaml:"grpcAddresses"` + APIPort string `yaml:"apiPort"` + } +} + +func main() { + nodesMap := &NodesMap{} + data, err := ioutil.ReadFile(*flagNodeMap) + if err != nil { + panic(err) + } + + err = yaml.Unmarshal(data, nodesMap) + if err != nil { + panic(err) + } + flag.Parse() + + var configs []config.Config + var nodes []config.Node + for _, n := range nodesMap.Nodes { + cfg, err := genNodeConfig(n.Addresses, n.APIPort) + if err != nil { + panic(fmt.Sprintf("could not generate the config file: %s", err.Error())) + } + configs = append(configs, cfg) + + node := config.Node{ + PeerId: cfg.Account.PeerId, + Address: cfg.GrpcServer.ListenAddrs[0], + SigningKey: cfg.Account.SigningKey, + EncryptionKey: cfg.Account.EncryptionKey, + } + nodes = append(nodes, node) + } + + var clientConfigs []config.Config + for _, c := range nodesMap.Clients { + cfg, err := genClientConfig(c.Addresses, c.APIPort) + if err != nil { + panic(fmt.Sprintf("could not generate the config file: %s", err.Error())) + } + clientConfigs = append(clientConfigs, cfg) + } + + var consConfigs []cconfig.Config + for _, n := range nodesMap.Consensus { + cfg, err := genConsensusConfig(n.Addresses) + if err != nil { + panic(fmt.Sprintf("could not generate the config file: %s", err.Error())) + } + consConfigs = append(consConfigs, cfg) + } + for idx := range configs { + configs[idx].Nodes = nodes + } + for idx := range clientConfigs { + clientConfigs[idx].Nodes = nodes + } + + // saving configs + configsPath := fmt.Sprintf("%s/configs", *flagEtcPath) + createDir := func() { + err := os.Mkdir(configsPath, os.ModePerm) + if err != nil { + panic(fmt.Sprintf("failed to create the configs directory: %v", err)) + } + } + if _, err := os.Stat(configsPath); os.IsNotExist(err) { + createDir() + } else { + err = os.RemoveAll(configsPath) + if err != nil { + panic(fmt.Sprintf("failed to remove the configs directory: %v", err)) + } + createDir() + } + for idx, cfg := range configs { + path := fmt.Sprintf("%s/node%d.yml", configsPath, idx+1) + bytes, err := yaml.Marshal(cfg) + if err != nil { + panic(fmt.Sprintf("could not marshal the keys: %v", err)) + } + + err = os.WriteFile(path, bytes, os.ModePerm) + if err != nil { + panic(fmt.Sprintf("could not write the config to file: %v", err)) + } + } + for idx, cfg := range clientConfigs { + path := fmt.Sprintf("%s/client%d.yml", configsPath, idx+1) + bytes, err := yaml.Marshal(cfg) + if err != nil { + panic(fmt.Sprintf("could not marshal the keys: %v", err)) + } + + err = os.WriteFile(path, bytes, os.ModePerm) + if err != nil { + panic(fmt.Sprintf("could not write the config to file: %v", err)) + } + } + for idx, cfg := range consConfigs { + path := fmt.Sprintf("%s/cons%d.yml", configsPath, idx+1) + bytes, err := yaml.Marshal(cfg) + if err != nil { + panic(fmt.Sprintf("could not marshal the keys: %v", err)) + } + + err = os.WriteFile(path, bytes, os.ModePerm) + if err != nil { + panic(fmt.Sprintf("could not write the config to file: %v", err)) + } + } +} + +func genNodeConfig(addresses []string, apiPort string) (config.Config, error) { + encKey, _, err := encryptionkey.GenerateRandomRSAKeyPair(2048) + if err != nil { + return config.Config{}, err + } + + signKey, _, err := signingkey.GenerateRandomEd25519KeyPair() + if err != nil { + return config.Config{}, err + } + + encEncKey, err := keys.EncodeKeyToString(encKey) + if err != nil { + return config.Config{}, err + } + + encSignKey, err := keys.EncodeKeyToString(signKey) + if err != nil { + return config.Config{}, err + } + + peerID, err := peer.IDFromSigningPubKey(signKey.GetPublic()) + if err != nil { + return config.Config{}, err + } + + return config.Config{ + Anytype: config.Anytype{SwarmKey: "/key/swarm/psk/1.0.0/base16/209992e611c27d5dce8fbd2e7389f6b51da9bee980992ef60739460b536139ec"}, + GrpcServer: config.GrpcServer{ + ListenAddrs: addresses, + TLS: false, + }, + Storage: config.Storage{Path: "db"}, + Account: config.Account{ + PeerId: peerID.String(), + PeerKey: encSignKey, + SigningKey: encSignKey, + EncryptionKey: encEncKey, + }, + APIServer: config.APIServer{ + Port: apiPort, + }, + Space: config.Space{ + GCTTL: 60, + SyncPeriod: 10, + }, + }, nil +} + +func genClientConfig(addresses []string, apiPort string) (config.Config, error) { + encKey, _, err := encryptionkey.GenerateRandomRSAKeyPair(2048) + if err != nil { + return config.Config{}, err + } + + signKey, _, err := signingkey.GenerateRandomEd25519KeyPair() + if err != nil { + return config.Config{}, err + } + + peerKey, _, err := signingkey.GenerateRandomEd25519KeyPair() + if err != nil { + return config.Config{}, err + } + + encEncKey, err := keys.EncodeKeyToString(encKey) + if err != nil { + return config.Config{}, err + } + + encSignKey, err := keys.EncodeKeyToString(signKey) + if err != nil { + return config.Config{}, err + } + + encPeerKey, err := keys.EncodeKeyToString(peerKey) + if err != nil { + return config.Config{}, err + } + + peerID, err := peer.IDFromSigningPubKey(peerKey.GetPublic()) + if err != nil { + return config.Config{}, err + } + + return config.Config{ + Anytype: config.Anytype{SwarmKey: "/key/swarm/psk/1.0.0/base16/209992e611c27d5dce8fbd2e7389f6b51da9bee980992ef60739460b536139ec"}, + GrpcServer: config.GrpcServer{ + ListenAddrs: addresses, + TLS: false, + }, + Storage: config.Storage{Path: "db"}, + Account: config.Account{ + PeerId: peerID.String(), + PeerKey: encPeerKey, + SigningKey: encSignKey, + EncryptionKey: encEncKey, + }, + APIServer: config.APIServer{ + Port: apiPort, + }, + Space: config.Space{ + GCTTL: 60, + SyncPeriod: 10, + }, + }, nil +} + +func genConsensusConfig(addresses []string) (cconfig.Config, error) { + encKey, _, err := encryptionkey.GenerateRandomRSAKeyPair(2048) + if err != nil { + return cconfig.Config{}, err + } + + signKey, _, err := signingkey.GenerateRandomEd25519KeyPair() + if err != nil { + return cconfig.Config{}, err + } + + encEncKey, err := keys.EncodeKeyToString(encKey) + if err != nil { + return cconfig.Config{}, err + } + + encSignKey, err := keys.EncodeKeyToString(signKey) + if err != nil { + return cconfig.Config{}, err + } + + peerID, err := peer.IDFromSigningPubKey(signKey.GetPublic()) + if err != nil { + return cconfig.Config{}, err + } + + return cconfig.Config{ + GrpcServer: config.GrpcServer{ + ListenAddrs: addresses, + TLS: false, + }, + Account: config.Account{ + PeerId: peerID.String(), + PeerKey: encSignKey, + SigningKey: encSignKey, + EncryptionKey: encEncKey, + }, + Mongo: cconfig.Mongo{ + Connect: "mongodb://localhost:27017/?w=majority", + Database: "consensus", + LogCollection: "log", + }, + }, nil +} diff --git a/util/cmd/nodesgen/nodemap.yml b/util/cmd/nodesgen/nodemap.yml new file mode 100644 index 00000000..7cd1f72a --- /dev/null +++ b/util/cmd/nodesgen/nodemap.yml @@ -0,0 +1,24 @@ +nodes: + - grpcAddresses: + - "127.0.0.1:4430" + apiPort: "8080" + - grpcAddresses: + - "127.0.0.1:4431" + apiPort: "8081" + - grpcAddresses: + - "127.0.0.1:4432" + apiPort: "8082" +consensus: + - grpcAddresses: + - "127.0.0.1:4530" + - grpcAddresses: + - "127.0.0.1:4531" + - grpcAddresses: + - "127.0.0.1:4532" +clients: + - grpcAddresses: + - "127.0.0.1:4630" + apiPort: "8090" + - grpcAddresses: + - "127.0.0.1:4631" + apiPort: "8091" diff --git a/util/crc16/crc16.go b/util/crc16/crc16.go deleted file mode 100644 index 810f4bed..00000000 --- a/util/crc16/crc16.go +++ /dev/null @@ -1,122 +0,0 @@ -// Package crc16 is implementation according to CCITT standards. -// -// Note by @antirez: this is actually the XMODEM CRC 16 algorithm, using the -// following parameters: -// -// Name : "XMODEM", also known as "ZMODEM", "CRC-16/ACORN" -// Width : 16 bit -// Poly : 1021 (That is actually x^16 + x^12 + x^5 + 1) -// Initialization : 0000 -// Reflect Input byte : False -// Reflect Output CRC : False -// Xor constant to output CRC : 0000 -// Output for "123456789" : 31C3 -// -// ported from the c++ code in the stellar-core codebase -// (https://github.com/stellar/stellar-core). The code is licensed -// as: -/* - * Copyright 2001-2010 Georges Menie (www.menie.org) - * Copyright 2010-2012 Salvatore Sanfilippo (adapted to Redis coding style) - * Copyright 2015 Stellar Development Foundation (ported to go) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the University of California, Berkeley nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package crc16 - -import ( - "bytes" - "encoding/binary" - "fmt" -) - -// ErrInvalidChecksum is returned when Validate determines either the checksum -// or the payload has been corrupted -var ErrInvalidChecksum = fmt.Errorf("invalid checksum") - -var crc16tab = [256]uint16{ - 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, - 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, - 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, - 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, - 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, - 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, - 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, - 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, - 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, - 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, - 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, - 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, - 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, - 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, - 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, - 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, - 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, - 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, - 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, - 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, - 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, - 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, - 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, - 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, - 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, - 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, - 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, - 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, - 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, - 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, - 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, - 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, -} - -// Checksum returns the 2-byte checksum for the provided data -func Checksum(data []byte) []byte { - var crc uint16 - var out bytes.Buffer - for _, b := range data { - crc = ((crc << 8) & 0xffff) ^ crc16tab[((crc>>8)^uint16(b))&0x00FF] - } - - err := binary.Write(&out, binary.LittleEndian, crc) - if err != nil { - panic(err) - } - - return out.Bytes() -} - -// Validate returns an error if the provided checksum does not match -// the calculated checksum of the provided data -func Validate(data []byte, expected []byte) error { - - actual := Checksum(data) - - // validate the provided checksum against the calculated - if !bytes.Equal(actual, expected) { - return ErrInvalidChecksum - } - - return nil -} diff --git a/util/go.mod b/util/go.mod new file mode 100644 index 00000000..917d8ea2 --- /dev/null +++ b/util/go.mod @@ -0,0 +1,58 @@ +module github.com/anytypeio/go-anytype-infrastructure-experiments/util + +go 1.19 + +replace github.com/anytypeio/go-anytype-infrastructure-experiments/common => ../common + +replace github.com/anytypeio/go-anytype-infrastructure-experiments/consensus => ../consensus + +require ( + github.com/akrylysov/pogreb v0.10.1 + github.com/anytypeio/go-anytype-infrastructure-experiments/common v0.0.0-00010101000000-000000000000 + github.com/anytypeio/go-anytype-infrastructure-experiments/consensus v0.0.0-00010101000000-000000000000 + github.com/dgraph-io/badger/v3 v3.2103.3 + gopkg.in/yaml.v3 v3.0.1 +) + +require ( + github.com/cespare/xxhash v1.1.0 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect + github.com/dgraph-io/ristretto v0.1.1 // indirect + github.com/dustin/go-humanize v1.0.0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // 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/flatbuffers v1.12.1 // indirect + github.com/ipfs/go-cid v0.3.2 // indirect + github.com/klauspost/compress v1.15.10 // indirect + github.com/klauspost/cpuid/v2 v2.1.1 // indirect + github.com/libp2p/go-buffer-pool v0.1.0 // indirect + github.com/libp2p/go-libp2p v0.23.2 // indirect + github.com/libp2p/go-libp2p-core v0.20.1 // indirect + github.com/libp2p/go-openssl v0.1.0 // indirect + github.com/mattn/go-pointer v0.0.1 // indirect + github.com/minio/sha256-simd v1.0.0 // indirect + github.com/mr-tron/base58 v1.2.0 // indirect + github.com/multiformats/go-base32 v0.1.0 // indirect + github.com/multiformats/go-base36 v0.1.0 // indirect + github.com/multiformats/go-multiaddr v0.7.0 // indirect + github.com/multiformats/go-multibase v0.1.1 // indirect + github.com/multiformats/go-multicodec v0.6.0 // indirect + github.com/multiformats/go-multihash v0.2.1 // indirect + github.com/multiformats/go-varint v0.0.6 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect + go.opencensus.io v0.23.0 // indirect + go.uber.org/atomic v1.10.0 // indirect + go.uber.org/multierr v1.8.0 // indirect + go.uber.org/zap v1.23.0 // indirect + golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect + golang.org/x/net v0.0.0-20220920183852-bf014ff85ad5 // indirect + golang.org/x/sys v0.0.0-20221010170243-090e33056c14 // indirect + google.golang.org/protobuf v1.28.1 // indirect + lukechampine.com/blake3 v1.1.7 // indirect +) diff --git a/util/go.sum b/util/go.sum new file mode 100644 index 00000000..cf3d6d42 --- /dev/null +++ b/util/go.sum @@ -0,0 +1,254 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/akrylysov/pogreb v0.10.1 h1:FqlR8VR7uCbJdfUob916tPM+idpKgeESDXOA1K0DK4w= +github.com/akrylysov/pogreb v0.10.1/go.mod h1:pNs6QmpQ1UlTJKDezuRWmaqkgUE2TuU0YTWyqJZ7+lI= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= +github.com/dgraph-io/badger/v3 v3.2103.3 h1:s63J1pisDhKpzWslXFe+ChuthuZptpwTE6qEKoczPb4= +github.com/dgraph-io/badger/v3 v3.2103.3/go.mod h1:4MPiseMeDQ3FNCYwRbbcBOGJLf5jsE0PPFzRiKjtcdw= +github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= +github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/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/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= +github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/ipfs/go-cid v0.3.2 h1:OGgOd+JCFM+y1DjWPmVH+2/4POtpDzwcr7VgnB7mZXc= +github.com/ipfs/go-cid v0.3.2/go.mod h1:gQ8pKqT/sUxGY+tIwy1RPpAojYu7jAyCp5Tz1svoupw= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.15.10 h1:Ai8UzuomSCDw90e1qNMtb15msBXsNpH6gzkkENQNcJo= +github.com/klauspost/compress v1.15.10/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= +github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.1.1 h1:t0wUqjowdm8ezddV5k0tLWVklVuvLJpoHeb4WBdydm0= +github.com/klauspost/cpuid/v2 v2.1.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= +github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= +github.com/libp2p/go-libp2p v0.23.2 h1:yqyTeKQJyofWXxEv/eEVUvOrGdt/9x+0PIQ4N1kaxmE= +github.com/libp2p/go-libp2p v0.23.2/go.mod h1:s9DEa5NLR4g+LZS+md5uGU4emjMWFiqkZr6hBTY8UxI= +github.com/libp2p/go-libp2p-core v0.20.1 h1:fQz4BJyIFmSZAiTbKV8qoYhEH5Dtv/cVhZbG3Ib/+Cw= +github.com/libp2p/go-libp2p-core v0.20.1/go.mod h1:6zR8H7CvQWgYLsbG4on6oLNSGcyKaYFSEYyDt51+bIY= +github.com/libp2p/go-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+Ooo= +github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= +github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= +github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= +github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= +github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= +github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= +github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4= +github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= +github.com/multiformats/go-multiaddr v0.7.0 h1:gskHcdaCyPtp9XskVwtvEeQOG465sCohbQIirSyqxrc= +github.com/multiformats/go-multiaddr v0.7.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs= +github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI= +github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8= +github.com/multiformats/go-multicodec v0.6.0 h1:KhH2kSuCARyuJraYMFxrNO3DqIaYhOdS039kbhgVwpE= +github.com/multiformats/go-multicodec v0.6.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw= +github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108= +github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= +github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY= +github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +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.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= +go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= +go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= +go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20220920183852-bf014ff85ad5 h1:KafLifaRFIuSJ5C+7CyFJOF9haxKNC1CEIDk8GX6X0k= +golang.org/x/net v0.0.0-20220920183852-bf014ff85ad5/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +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= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20221010170243-090e33056c14 h1:k5II8e6QD8mITdi+okbbmR/cIyEbeXLBhy5Ha4nevyc= +golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +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= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= +lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= diff --git a/util/keys/asymmetric/signingkey/signingkey.go b/util/keys/asymmetric/signingkey/signingkey.go deleted file mode 100644 index 30299eb4..00000000 --- a/util/keys/asymmetric/signingkey/signingkey.go +++ /dev/null @@ -1,24 +0,0 @@ -package signingkey - -import "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys" - -type PrivKey interface { - keys.Key - - Sign([]byte) ([]byte, error) - - GetPublic() PubKey -} - -type PubKey interface { - keys.Key - - Verify(data []byte, sig []byte) (bool, error) -} - -type PubKeyDecoder interface { - DecodeFromBytes(bytes []byte) (PubKey, error) - DecodeFromString(identity string) (PubKey, error) - DecodeFromStringIntoBytes(identity string) ([]byte, error) - EncodeToString(pubkey PubKey) (string, error) -} diff --git a/util/keys/decoder.go b/util/keys/decoder.go deleted file mode 100644 index 0b194794..00000000 --- a/util/keys/decoder.go +++ /dev/null @@ -1,38 +0,0 @@ -package keys - -import "github.com/anytypeio/go-anytype-infrastructure-experiments/util/strkey" - -type keyDecoder[T Key] struct { - create func([]byte) (T, error) -} - -func NewKeyDecoder[T Key](create func(bytes []byte) (T, error)) Decoder { - return &keyDecoder[T]{ - create: create, - } -} - -func (e *keyDecoder[T]) DecodeFromBytes(bytes []byte) (Key, error) { - return e.create(bytes) -} - -func (e *keyDecoder[T]) DecodeFromString(identity string) (Key, error) { - pubKeyRaw, err := strkey.Decode(0x5b, identity) - if err != nil { - return nil, err - } - - return e.DecodeFromBytes(pubKeyRaw) -} - -func (e *keyDecoder[T]) DecodeFromStringIntoBytes(identity string) ([]byte, error) { - return strkey.Decode(0x5b, identity) -} - -func (e *keyDecoder[T]) EncodeToString(key Key) (string, error) { - raw, err := key.Raw() - if err != nil { - return "", err - } - return strkey.Encode(0x5b, raw) -} diff --git a/util/strkey/strkey.go b/util/strkey/strkey.go deleted file mode 100644 index 0e766f12..00000000 --- a/util/strkey/strkey.go +++ /dev/null @@ -1,118 +0,0 @@ -package strkey - -import ( - "bytes" - "encoding/binary" - "fmt" - - "github.com/mr-tron/base58/base58" - - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/crc16" -) - -// ErrInvalidVersionByte is returned when the version byte from a provided -// strkey-encoded string is not one of the valid values. -var ErrInvalidVersionByte = fmt.Errorf("invalid version byte") - -// VersionByte represents one of the possible prefix values for a StrKey base -// string--the string the when encoded using base58 yields a final StrKey. -type VersionByte byte - -// Decode decodes the provided StrKey into a raw value, checking the checksum -// and ensuring the expected VersionByte (the version parameter) is the value -// actually encoded into the provided src string. -func Decode(expected VersionByte, src string) ([]byte, error) { - raw, err := decodeString(src) - if err != nil { - return nil, err - } - - // decode into components - version := VersionByte(raw[0]) - vp := raw[0 : len(raw)-2] - payload := raw[1 : len(raw)-2] - checksum := raw[len(raw)-2:] - - // ensure version byte is expected - if version != expected { - return nil, ErrInvalidVersionByte - } - - // ensure checksum is valid - if err := crc16.Validate(vp, checksum); err != nil { - return nil, err - } - - // if we made it through the gaunlet, return the decoded value - return payload, nil -} - -// MustDecode is like Decode, but panics on error -func MustDecode(expected VersionByte, src string) []byte { - d, err := Decode(expected, src) - if err != nil { - panic(err) - } - return d -} - -// Encode encodes the provided data to a StrKey, using the provided version -// byte. -func Encode(version VersionByte, src []byte) (string, error) { - var raw bytes.Buffer - - // write version byte - if err := binary.Write(&raw, binary.LittleEndian, version); err != nil { - return "", err - } - - // write payload - if _, err := raw.Write(src); err != nil { - return "", err - } - - // calculate and write checksum - checksum := crc16.Checksum(raw.Bytes()) - if _, err := raw.Write(checksum); err != nil { - return "", err - } - - result := base58.FastBase58Encoding(raw.Bytes()) - return result, nil -} - -// MustEncode is like Encode, but panics on error -func MustEncode(version VersionByte, src []byte) string { - e, err := Encode(version, src) - if err != nil { - panic(err) - } - return e -} - -// Version extracts and returns the version byte from the provided source -// string. -func Version(src string) (VersionByte, error) { - raw, err := decodeString(src) - if err != nil { - return VersionByte(0), err - } - - return VersionByte(raw[0]), nil -} - -// decodeString decodes a base58 string into the raw bytes, and ensures it could -// potentially be strkey encoded (i.e. it has both a version byte and a -// checksum, neither of which are explicitly checked by this func) -func decodeString(src string) ([]byte, error) { - raw, err := base58.FastBase58Decoding(src) - if err != nil { - return nil, fmt.Errorf("base58 decode failed: %s", err) - } - - if len(raw) < 3 { - return nil, fmt.Errorf("encoded value is %d bytes; minimum valid length is 3", len(raw)) - } - - return raw, nil -}