From b0fa43fb14ea9f0d8afa33e69cacb9ed8b16ad07 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Thu, 1 Jun 2023 10:28:32 +0200 Subject: [PATCH 001/123] WIP work on components --- app/app.go | 51 ++- app/app_test.go | 14 + commonspace/commongetter.go | 41 +- commonspace/{ => config}/config.go | 2 +- commonspace/deletionstate/deletionstate.go | 150 ++++++++ commonspace/headsync/diffsyncer.go | 27 +- commonspace/headsync/headsync.go | 166 ++++---- commonspace/headsync/util.go | 27 ++ commonspace/object/tree/synctree/synctree.go | 14 +- .../object/tree/synctree/synctree_test.go | 7 +- .../object/tree/synctree/synctreehandler.go | 14 +- .../tree/synctree/synctreehandler_test.go | 24 +- .../object/tree/synctree/treeremotegetter.go | 2 +- .../object/tree/synctree/utils_test.go | 22 +- commonspace/objectsync/msgpool.go | 142 ------- commonspace/objectsync/objectsync.go | 204 +++++----- commonspace/objectsync/syncclient.go | 78 ---- .../{ => syncclient}/requestfactory.go | 2 +- .../objectsync/syncclient/syncclient.go | 98 +++++ commonspace/objecttreebuilder/treebuilder.go | 191 ++++++++++ commonspace/requestsender/requestsender.go | 45 +++ commonspace/settings/deleter.go | 6 +- commonspace/settings/deletionmanager.go | 5 +- commonspace/settings/settings.go | 354 +++--------------- commonspace/settings/settingsobject.go | 329 ++++++++++++++++ ...ettings_test.go => settingsobject_test.go} | 0 .../settings/settingsstate/settingsstate.go | 1 + commonspace/space.go | 2 +- commonspace/spaceservice.go | 8 +- commonspace/spacestate/shareddata.go | 35 ++ commonspace/spaceutils_test.go | 5 +- commonspace/streamsender/streamsender.go | 14 + commonspace/syncstatus/noop.go | 36 +- commonspace/syncstatus/syncstatus.go | 65 ++-- 34 files changed, 1343 insertions(+), 838 deletions(-) rename commonspace/{ => config}/config.go (91%) create mode 100644 commonspace/deletionstate/deletionstate.go create mode 100644 commonspace/headsync/util.go delete mode 100644 commonspace/objectsync/msgpool.go delete mode 100644 commonspace/objectsync/syncclient.go rename commonspace/objectsync/{ => syncclient}/requestfactory.go (99%) create mode 100644 commonspace/objectsync/syncclient/syncclient.go create mode 100644 commonspace/objecttreebuilder/treebuilder.go create mode 100644 commonspace/requestsender/requestsender.go create mode 100644 commonspace/settings/settingsobject.go rename commonspace/settings/{settings_test.go => settingsobject_test.go} (100%) create mode 100644 commonspace/spacestate/shareddata.go create mode 100644 commonspace/streamsender/streamsender.go diff --git a/app/app.go b/app/app.go index a290a82b..b8be83a0 100644 --- a/app/app.go +++ b/app/app.go @@ -55,6 +55,7 @@ type ComponentStatable interface { // App is the central part of the application // It contains and manages all components type App struct { + parent *App components []Component mu sync.RWMutex startStat Stat @@ -109,15 +110,29 @@ func VersionDescription() string { return fmt.Sprintf("build on %s from %s at #%s(%s)", BuildDate, GitBranch, GitCommit, GitState) } +// ChildApp creates a child container which has access to parent's components +// It doesn't call Start on any of the parent's components +func (app *App) ChildApp() *App { + return &App{ + parent: app, + deviceState: app.deviceState, + anySyncVersion: app.AnySyncVersion(), + } +} + // Register adds service to registry // All components will be started in the order they were registered func (app *App) Register(s Component) *App { app.mu.Lock() defer app.mu.Unlock() - for _, es := range app.components { - if s.Name() == es.Name() { - panic(fmt.Errorf("component '%s' already registered", s.Name())) + current := app + for current != nil { + for _, es := range current.components { + if s.Name() == es.Name() { + panic(fmt.Errorf("component '%s' already registered", s.Name())) + } } + current = current.parent } app.components = append(app.components, s) return app @@ -128,10 +143,14 @@ func (app *App) Register(s Component) *App { func (app *App) Component(name string) Component { app.mu.RLock() defer app.mu.RUnlock() - for _, s := range app.components { - if s.Name() == name { - return s + current := app + for current != nil { + for _, s := range current.components { + if s.Name() == name { + return s + } } + current = current.parent } return nil } @@ -149,10 +168,14 @@ func (app *App) MustComponent(name string) Component { func MustComponent[i any](app *App) i { app.mu.RLock() defer app.mu.RUnlock() - for _, s := range app.components { - if v, ok := s.(i); ok { - return v + current := app + for current != nil { + for _, s := range current.components { + if v, ok := s.(i); ok { + return v + } } + current = current.parent } empty := new(i) panic(fmt.Errorf("component with interface %T is not found", empty)) @@ -162,9 +185,13 @@ func MustComponent[i any](app *App) i { func (app *App) ComponentNames() (names []string) { app.mu.RLock() defer app.mu.RUnlock() - names = make([]string, len(app.components)) - for i, c := range app.components { - names[i] = c.Name() + names = make([]string, 0, len(app.components)) + current := app + for current != nil { + for _, c := range current.components { + names = append(names, c.Name()) + } + current = current.parent } return } diff --git a/app/app_test.go b/app/app_test.go index cdc52445..7b5678d6 100644 --- a/app/app_test.go +++ b/app/app_test.go @@ -34,6 +34,20 @@ func TestAppServiceRegistry(t *testing.T) { names := app.ComponentNames() assert.Equal(t, names, []string{"c1", "r1", "s1"}) }) + t.Run("Child MustComponent", func(t *testing.T) { + app := app.ChildApp() + app.Register(newTestService(testTypeComponent, "x1", nil, nil)) + for _, name := range []string{"c1", "r1", "s1", "x1"} { + assert.NotPanics(t, func() { app.MustComponent(name) }, name) + } + assert.Panics(t, func() { app.MustComponent("not-registered") }) + }) + t.Run("Child ComponentNames", func(t *testing.T) { + app := app.ChildApp() + app.Register(newTestService(testTypeComponent, "x1", nil, nil)) + names := app.ComponentNames() + assert.Equal(t, names, []string{"x1", "c1", "r1", "s1"}) + }) } func TestAppStart(t *testing.T) { diff --git a/commonspace/commongetter.go b/commonspace/commongetter.go index 80476a14..93c9312d 100644 --- a/commonspace/commongetter.go +++ b/commonspace/commongetter.go @@ -2,32 +2,53 @@ package commonspace import ( "context" + "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/commonspace/object/syncobjectgetter" "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" "github.com/anyproto/any-sync/commonspace/object/treemanager" + "github.com/anyproto/any-sync/commonspace/spacestate" "sync/atomic" ) -type commonGetter struct { +type ObjectManager interface { + treemanager.TreeManager + AddObject(object syncobjectgetter.SyncObject) + GetObject(ctx context.Context, objectId string) (obj syncobjectgetter.SyncObject, err error) +} + +type objectManager struct { treemanager.TreeManager spaceId string reservedObjects []syncobjectgetter.SyncObject spaceIsClosed *atomic.Bool } -func newCommonGetter(spaceId string, getter treemanager.TreeManager, spaceIsClosed *atomic.Bool) *commonGetter { - return &commonGetter{ - TreeManager: getter, - spaceId: spaceId, - spaceIsClosed: spaceIsClosed, +func NewObjectManager(manager treemanager.TreeManager) ObjectManager { + return &objectManager{ + TreeManager: manager, } } -func (c *commonGetter) AddObject(object syncobjectgetter.SyncObject) { +func (c *objectManager) Init(a *app.App) (err error) { + state := a.MustComponent(spacestate.CName).(*spacestate.SpaceState) + c.spaceId = state.SpaceId + c.spaceIsClosed = state.SpaceIsClosed + return nil +} + +func (c *objectManager) Run(ctx context.Context) (err error) { + return nil +} + +func (c *objectManager) Close(ctx context.Context) (err error) { + return nil +} + +func (c *objectManager) AddObject(object syncobjectgetter.SyncObject) { c.reservedObjects = append(c.reservedObjects, object) } -func (c *commonGetter) GetTree(ctx context.Context, spaceId, treeId string) (objecttree.ObjectTree, error) { +func (c *objectManager) GetTree(ctx context.Context, spaceId, treeId string) (objecttree.ObjectTree, error) { if c.spaceIsClosed.Load() { return nil, ErrSpaceClosed } @@ -37,7 +58,7 @@ func (c *commonGetter) GetTree(ctx context.Context, spaceId, treeId string) (obj return c.TreeManager.GetTree(ctx, spaceId, treeId) } -func (c *commonGetter) getReservedObject(id string) syncobjectgetter.SyncObject { +func (c *objectManager) getReservedObject(id string) syncobjectgetter.SyncObject { for _, obj := range c.reservedObjects { if obj != nil && obj.Id() == id { return obj @@ -46,7 +67,7 @@ func (c *commonGetter) getReservedObject(id string) syncobjectgetter.SyncObject return nil } -func (c *commonGetter) GetObject(ctx context.Context, objectId string) (obj syncobjectgetter.SyncObject, err error) { +func (c *objectManager) GetObject(ctx context.Context, objectId string) (obj syncobjectgetter.SyncObject, err error) { if c.spaceIsClosed.Load() { return nil, ErrSpaceClosed } diff --git a/commonspace/config.go b/commonspace/config/config.go similarity index 91% rename from commonspace/config.go rename to commonspace/config/config.go index e5485068..cce4b548 100644 --- a/commonspace/config.go +++ b/commonspace/config/config.go @@ -1,4 +1,4 @@ -package commonspace +package config type ConfigGetter interface { GetSpace() Config diff --git a/commonspace/deletionstate/deletionstate.go b/commonspace/deletionstate/deletionstate.go new file mode 100644 index 00000000..96f062e3 --- /dev/null +++ b/commonspace/deletionstate/deletionstate.go @@ -0,0 +1,150 @@ +//go:generate mockgen -destination mock_settingsstate/mock_settingsstate.go github.com/anyproto/any-sync/commonspace/settings/settingsstate ObjectDeletionState,StateBuilder,ChangeFactory +package deletionstate + +import ( + "github.com/anyproto/any-sync/app" + "github.com/anyproto/any-sync/app/logger" + "github.com/anyproto/any-sync/commonspace/spacestate" + "github.com/anyproto/any-sync/commonspace/spacestorage" + "go.uber.org/zap" + "sync" +) + +var log = logger.NewNamed(CName) + +const CName = "common.commonspace.deletionstate" + +type StateUpdateObserver func(ids []string) + +type ObjectDeletionState interface { + app.Component + AddObserver(observer StateUpdateObserver) + Add(ids map[string]struct{}) + GetQueued() (ids []string) + Delete(id string) (err error) + Exists(id string) bool + Filter(ids []string) (filtered []string) +} + +type objectDeletionState struct { + sync.RWMutex + log logger.CtxLogger + queued map[string]struct{} + deleted map[string]struct{} + stateUpdateObservers []StateUpdateObserver + storage spacestorage.SpaceStorage +} + +func (st *objectDeletionState) Init(a *app.App) (err error) { + st.storage = a.MustComponent(spacestate.CName).(*spacestate.SpaceState).SpaceStorage + return nil +} + +func (st *objectDeletionState) Name() (name string) { + return CName +} + +func NewObjectDeletionState() ObjectDeletionState { + return &objectDeletionState{ + log: log, + queued: map[string]struct{}{}, + deleted: map[string]struct{}{}, + } +} + +func (st *objectDeletionState) AddObserver(observer StateUpdateObserver) { + st.Lock() + defer st.Unlock() + st.stateUpdateObservers = append(st.stateUpdateObservers, observer) +} + +func (st *objectDeletionState) Add(ids map[string]struct{}) { + var added []string + st.Lock() + defer func() { + st.Unlock() + for _, ob := range st.stateUpdateObservers { + ob(added) + } + }() + + for id := range ids { + if _, exists := st.deleted[id]; exists { + continue + } + if _, exists := st.queued[id]; exists { + continue + } + + var status string + status, err := st.storage.TreeDeletedStatus(id) + if err != nil { + st.log.Warn("failed to get deleted status", zap.String("treeId", id), zap.Error(err)) + continue + } + + switch status { + case spacestorage.TreeDeletedStatusQueued: + st.queued[id] = struct{}{} + case spacestorage.TreeDeletedStatusDeleted: + st.deleted[id] = struct{}{} + default: + err := st.storage.SetTreeDeletedStatus(id, spacestorage.TreeDeletedStatusQueued) + if err != nil { + st.log.Warn("failed to set deleted status", zap.String("treeId", id), zap.Error(err)) + continue + } + st.queued[id] = struct{}{} + } + added = append(added, id) + } +} + +func (st *objectDeletionState) GetQueued() (ids []string) { + st.RLock() + defer st.RUnlock() + ids = make([]string, 0, len(st.queued)) + for id := range st.queued { + ids = append(ids, id) + } + return +} + +func (st *objectDeletionState) Delete(id string) (err error) { + st.Lock() + defer st.Unlock() + delete(st.queued, id) + st.deleted[id] = struct{}{} + err = st.storage.SetTreeDeletedStatus(id, spacestorage.TreeDeletedStatusDeleted) + if err != nil { + return + } + return +} + +func (st *objectDeletionState) Exists(id string) bool { + st.RLock() + defer st.RUnlock() + return st.exists(id) +} + +func (st *objectDeletionState) Filter(ids []string) (filtered []string) { + st.RLock() + defer st.RUnlock() + for _, id := range ids { + if !st.exists(id) { + filtered = append(filtered, id) + } + } + return +} + +func (st *objectDeletionState) exists(id string) bool { + if _, exists := st.deleted[id]; exists { + return true + } + if _, exists := st.queued[id]; exists { + return true + } + return false +} diff --git a/commonspace/headsync/diffsyncer.go b/commonspace/headsync/diffsyncer.go index 8b59c743..70238d01 100644 --- a/commonspace/headsync/diffsyncer.go +++ b/commonspace/headsync/diffsyncer.go @@ -26,26 +26,17 @@ type DiffSyncer interface { Close() error } -func newDiffSyncer( - spaceId string, - diff ldiff.Diff, - peerManager peermanager.PeerManager, - cache treemanager.TreeManager, - storage spacestorage.SpaceStorage, - clientFactory spacesyncproto.ClientFactory, - syncStatus syncstatus.StatusUpdater, - credentialProvider credentialprovider.CredentialProvider, - log logger.CtxLogger) DiffSyncer { +func newDiffSyncer(hs *headSync) DiffSyncer { return &diffSyncer{ - diff: diff, - spaceId: spaceId, - treeManager: cache, - storage: storage, - peerManager: peerManager, - clientFactory: clientFactory, - credentialProvider: credentialProvider, + diff: hs.diff, + spaceId: hs.spaceId, + treeManager: hs.treeManager, + storage: hs.storage, + peerManager: hs.peerManager, + clientFactory: spacesyncproto.ClientFactoryFunc(spacesyncproto.NewDRPCSpaceSyncClient), + credentialProvider: hs.credentialProvider, log: log, - syncStatus: syncStatus, + syncStatus: hs.syncStatus, } } diff --git a/commonspace/headsync/headsync.go b/commonspace/headsync/headsync.go index ddca3e50..048569bb 100644 --- a/commonspace/headsync/headsync.go +++ b/commonspace/headsync/headsync.go @@ -1,14 +1,17 @@ -//go:generate mockgen -destination mock_headsync/mock_headsync.go github.com/anyproto/any-sync/commonspace/headsync DiffSyncer package headsync import ( "context" + "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/app/ldiff" "github.com/anyproto/any-sync/app/logger" + config2 "github.com/anyproto/any-sync/commonspace/config" "github.com/anyproto/any-sync/commonspace/credentialprovider" + "github.com/anyproto/any-sync/commonspace/headsync" "github.com/anyproto/any-sync/commonspace/object/treemanager" "github.com/anyproto/any-sync/commonspace/peermanager" "github.com/anyproto/any-sync/commonspace/settings/settingsstate" + "github.com/anyproto/any-sync/commonspace/spacestate" "github.com/anyproto/any-sync/commonspace/spacestorage" "github.com/anyproto/any-sync/commonspace/spacesyncproto" "github.com/anyproto/any-sync/commonspace/syncstatus" @@ -17,109 +20,114 @@ import ( "github.com/anyproto/any-sync/util/periodicsync" "go.uber.org/zap" "golang.org/x/exp/slices" - "strings" "sync/atomic" "time" ) +var log = logger.NewNamed(CName) + +const CName = "common.commonspace.headsync" + type TreeHeads struct { Id string Heads []string } type HeadSync interface { - Init(objectIds []string, deletionState settingsstate.ObjectDeletionState) - UpdateHeads(id string, heads []string) HandleRangeRequest(ctx context.Context, req *spacesyncproto.HeadSyncRequest) (resp *spacesyncproto.HeadSyncResponse, err error) RemoveObjects(ids []string) AllIds() []string DebugAllHeads() (res []TreeHeads) - - Close() (err error) } type headSync struct { spaceId string - periodicSync periodicsync.PeriodicSync - storage spacestorage.SpaceStorage - diff ldiff.Diff - log logger.CtxLogger - syncer DiffSyncer - configuration nodeconf.NodeConf spaceIsDeleted *atomic.Bool + syncPeriod int - syncPeriod int + periodicSync periodicsync.PeriodicSync + storage spacestorage.SpaceStorage + diff ldiff.Diff + log logger.CtxLogger + syncer headsync.DiffSyncer + configuration nodeconf.NodeConf + peerManager peermanager.PeerManager + treeManager treemanager.TreeManager + credentialProvider credentialprovider.CredentialProvider + syncStatus syncstatus.StatusProvider + deletionState settingsstate.ObjectDeletionState } -func NewHeadSync( - spaceId string, - spaceIsDeleted *atomic.Bool, - syncPeriod int, - configuration nodeconf.NodeConf, - storage spacestorage.SpaceStorage, - peerManager peermanager.PeerManager, - cache treemanager.TreeManager, - syncStatus syncstatus.StatusUpdater, - credentialProvider credentialprovider.CredentialProvider, - log logger.CtxLogger) HeadSync { +func New() *headSync { + return &headSync{} +} - diff := ldiff.New(16, 16) - l := log.With(zap.String("spaceId", spaceId)) - factory := spacesyncproto.ClientFactoryFunc(spacesyncproto.NewDRPCSpaceSyncClient) - syncer := newDiffSyncer(spaceId, diff, peerManager, cache, storage, factory, syncStatus, credentialProvider, l) +func (h *headSync) Init(a *app.App) (err error) { + shared := a.MustComponent(spacestate.CName).(*spacestate.SpaceState) + cfg := a.MustComponent("cfg").(config2.ConfigGetter) + h.spaceId = shared.SpaceId + h.spaceIsDeleted = shared.SpaceIsDeleted + h.syncPeriod = cfg.GetSpace().SyncPeriod + h.configuration = a.MustComponent(nodeconf.CName).(nodeconf.NodeConf) + h.log = log.With(zap.String("spaceId", h.spaceId)) + h.storage = a.MustComponent("spacestorage").(spacestorage.SpaceStorage) + h.diff = ldiff.New(16, 16) + h.peerManager = a.MustComponent(peermanager.CName).(peermanager.PeerManager) + h.credentialProvider = a.MustComponent(credentialprovider.CName).(credentialprovider.CredentialProvider) + h.syncStatus = a.MustComponent(syncstatus.CName).(syncstatus.StatusProvider) + h.treeManager = a.MustComponent(treemanager.CName).(treemanager.TreeManager) + h.deletionState = a.MustComponent("deletionstate").(settingsstate.ObjectDeletionState) + h.syncer = newDiffSyncer(h) sync := func(ctx context.Context) (err error) { // for clients cancelling the sync process - if spaceIsDeleted.Load() && !configuration.IsResponsible(spaceId) { + if h.spaceIsDeleted.Load() && !h.configuration.IsResponsible(h.spaceId) { return spacesyncproto.ErrSpaceIsDeleted } - return syncer.Sync(ctx) - } - periodicSync := periodicsync.NewPeriodicSync(syncPeriod, time.Minute, sync, l) - - return &headSync{ - spaceId: spaceId, - storage: storage, - syncer: syncer, - periodicSync: periodicSync, - diff: diff, - log: log, - syncPeriod: syncPeriod, - configuration: configuration, - spaceIsDeleted: spaceIsDeleted, + return h.syncer.Sync(ctx) } + h.periodicSync = periodicsync.NewPeriodicSync(h.syncPeriod, time.Minute, sync, h.log) + return nil } -func (d *headSync) Init(objectIds []string, deletionState settingsstate.ObjectDeletionState) { - d.fillDiff(objectIds) - d.syncer.Init(deletionState) - d.periodicSync.Run() +func (h *headSync) Name() (name string) { + return CName } -func (d *headSync) HandleRangeRequest(ctx context.Context, req *spacesyncproto.HeadSyncRequest) (resp *spacesyncproto.HeadSyncResponse, err error) { - if d.spaceIsDeleted.Load() { +func (h *headSync) Run(ctx context.Context) (err error) { + initialIds, err := h.storage.StoredIds() + if err != nil { + return + } + h.fillDiff(initialIds) + h.periodicSync.Run() + return +} + +func (h *headSync) HandleRangeRequest(ctx context.Context, req *spacesyncproto.HeadSyncRequest) (resp *spacesyncproto.HeadSyncResponse, err error) { + if h.spaceIsDeleted.Load() { peerId, err := peer.CtxPeerId(ctx) if err != nil { return nil, err } // stop receiving all request for sync from clients - if !slices.Contains(d.configuration.NodeIds(d.spaceId), peerId) { + if !slices.Contains(h.configuration.NodeIds(h.spaceId), peerId) { return nil, spacesyncproto.ErrSpaceIsDeleted } } - return HandleRangeRequest(ctx, d.diff, req) + return HandleRangeRequest(ctx, h.diff, req) } -func (d *headSync) UpdateHeads(id string, heads []string) { - d.syncer.UpdateHeads(id, heads) +func (h *headSync) UpdateHeads(id string, heads []string) { + h.syncer.UpdateHeads(id, heads) } -func (d *headSync) AllIds() []string { - return d.diff.Ids() +func (h *headSync) AllIds() []string { + return h.diff.Ids() } -func (d *headSync) DebugAllHeads() (res []TreeHeads) { - els := d.diff.Elements() +func (h *headSync) DebugAllHeads() (res []TreeHeads) { + els := h.diff.Elements() for _, el := range els { idHead := TreeHeads{ Id: el.Id, @@ -130,19 +138,19 @@ func (d *headSync) DebugAllHeads() (res []TreeHeads) { return } -func (d *headSync) RemoveObjects(ids []string) { - d.syncer.RemoveObjects(ids) +func (h *headSync) RemoveObjects(ids []string) { + h.syncer.RemoveObjects(ids) } -func (d *headSync) Close() (err error) { - d.periodicSync.Close() - return d.syncer.Close() +func (h *headSync) Close(ctx context.Context) (err error) { + h.periodicSync.Close() + return h.syncer.Close() } -func (d *headSync) fillDiff(objectIds []string) { +func (h *headSync) fillDiff(objectIds []string) { var els = make([]ldiff.Element, 0, len(objectIds)) for _, id := range objectIds { - st, err := d.storage.TreeStorage(id) + st, err := h.storage.TreeStorage(id) if err != nil { continue } @@ -155,32 +163,8 @@ func (d *headSync) fillDiff(objectIds []string) { Head: concatStrings(heads), }) } - d.diff.Set(els...) - if err := d.storage.WriteSpaceHash(d.diff.Hash()); err != nil { - d.log.Error("can't write space hash", zap.Error(err)) + h.diff.Set(els...) + if err := h.storage.WriteSpaceHash(h.diff.Hash()); err != nil { + h.log.Error("can't write space hash", zap.Error(err)) } } - -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() -} - -func splitString(str string) (res []string) { - const cidLen = 59 - for i := 0; i < len(str); i += cidLen { - res = append(res, str[i:i+cidLen]) - } - return -} diff --git a/commonspace/headsync/util.go b/commonspace/headsync/util.go new file mode 100644 index 00000000..549a77f2 --- /dev/null +++ b/commonspace/headsync/util.go @@ -0,0 +1,27 @@ +package headsync + +import "strings" + +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() +} + +func splitString(str string) (res []string) { + const cidLen = 59 + for i := 0; i < len(str); i += cidLen { + res = append(res, str[i:i+cidLen]) + } + return +} diff --git a/commonspace/object/tree/synctree/synctree.go b/commonspace/object/tree/synctree/synctree.go index 2a87030a..1a6d2497 100644 --- a/commonspace/object/tree/synctree/synctree.go +++ b/commonspace/object/tree/synctree/synctree.go @@ -4,6 +4,7 @@ package synctree import ( "context" "errors" + "github.com/anyproto/any-sync/commonspace/objectsync/syncclient" "time" "github.com/anyproto/any-sync/app/logger" @@ -11,7 +12,6 @@ import ( "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" "github.com/anyproto/any-sync/commonspace/object/tree/synctree/updatelistener" "github.com/anyproto/any-sync/commonspace/object/tree/treestorage" - "github.com/anyproto/any-sync/commonspace/objectsync" "github.com/anyproto/any-sync/commonspace/objectsync/synchandler" "github.com/anyproto/any-sync/commonspace/spacestorage" "github.com/anyproto/any-sync/commonspace/syncstatus" @@ -44,7 +44,7 @@ type SyncTree interface { type syncTree struct { objecttree.ObjectTree synchandler.SyncHandler - syncClient objectsync.SyncClient + syncClient syncclient.SyncClient syncStatus syncstatus.StatusUpdater notifiable HeadNotifiable listener updatelistener.UpdateListener @@ -61,7 +61,7 @@ type ResponsiblePeersGetter interface { type BuildDeps struct { SpaceId string - SyncClient objectsync.SyncClient + SyncClient syncclient.SyncClient Configuration nodeconf.NodeConf HeadNotifiable HeadNotifiable Listener updatelistener.UpdateListener @@ -119,7 +119,7 @@ func buildSyncTree(ctx context.Context, sendUpdate bool, deps BuildDeps) (t Sync if sendUpdate { headUpdate := syncTree.syncClient.CreateHeadUpdate(t, nil) // send to everybody, because everybody should know that the node or client got new tree - syncTree.syncClient.Broadcast(ctx, headUpdate) + syncTree.syncClient.Broadcast(headUpdate) } return } @@ -156,7 +156,7 @@ func (s *syncTree) AddContent(ctx context.Context, content objecttree.SignableCh } s.syncStatus.HeadsChange(s.Id(), res.Heads) headUpdate := s.syncClient.CreateHeadUpdate(s, res.Added) - s.syncClient.Broadcast(ctx, headUpdate) + s.syncClient.Broadcast(headUpdate) return } @@ -183,7 +183,7 @@ func (s *syncTree) AddRawChanges(ctx context.Context, changesPayload objecttree. s.notifiable.UpdateHeads(s.Id(), res.Heads) } headUpdate := s.syncClient.CreateHeadUpdate(s, res.Added) - s.syncClient.Broadcast(ctx, headUpdate) + s.syncClient.Broadcast(headUpdate) } return } @@ -239,7 +239,7 @@ func (s *syncTree) SyncWithPeer(ctx context.Context, peerId string) (err error) s.Lock() defer s.Unlock() headUpdate := s.syncClient.CreateHeadUpdate(s, nil) - return s.syncClient.SendWithReply(ctx, peerId, headUpdate.RootChange.Id, headUpdate, "") + return s.syncClient.SendUpdate(peerId, headUpdate.RootChange.Id, headUpdate) } func (s *syncTree) afterBuild() { diff --git a/commonspace/object/tree/synctree/synctree_test.go b/commonspace/object/tree/synctree/synctree_test.go index 9900e49b..5fe9b2e6 100644 --- a/commonspace/object/tree/synctree/synctree_test.go +++ b/commonspace/object/tree/synctree/synctree_test.go @@ -9,6 +9,7 @@ import ( "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" "github.com/anyproto/any-sync/commonspace/objectsync" "github.com/anyproto/any-sync/commonspace/objectsync/mock_objectsync" + "github.com/anyproto/any-sync/commonspace/objectsync/syncclient" "github.com/anyproto/any-sync/commonspace/syncstatus" "github.com/anyproto/any-sync/nodeconf" "github.com/golang/mock/gomock" @@ -18,7 +19,7 @@ import ( type syncTreeMatcher struct { objTree objecttree.ObjectTree - client objectsync.SyncClient + client syncclient.SyncClient listener updatelistener.UpdateListener } @@ -34,8 +35,8 @@ func (s syncTreeMatcher) String() string { return "" } -func syncClientFuncCreator(client objectsync.SyncClient) func(spaceId string, factory objectsync.RequestFactory, objectSync objectsync.ObjectSync, configuration nodeconf.NodeConf) objectsync.SyncClient { - return func(spaceId string, factory objectsync.RequestFactory, objectSync objectsync.ObjectSync, configuration nodeconf.NodeConf) objectsync.SyncClient { +func syncClientFuncCreator(client syncclient.SyncClient) func(spaceId string, factory syncclient.RequestFactory, objectSync objectsync.ObjectSync, configuration nodeconf.NodeConf) syncclient.SyncClient { + return func(spaceId string, factory syncclient.RequestFactory, objectSync objectsync.ObjectSync, configuration nodeconf.NodeConf) syncclient.SyncClient { return client } } diff --git a/commonspace/object/tree/synctree/synctreehandler.go b/commonspace/object/tree/synctree/synctreehandler.go index cdb0aa2a..942c0e2f 100644 --- a/commonspace/object/tree/synctree/synctreehandler.go +++ b/commonspace/object/tree/synctree/synctreehandler.go @@ -4,7 +4,7 @@ import ( "context" "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" - "github.com/anyproto/any-sync/commonspace/objectsync" + "github.com/anyproto/any-sync/commonspace/objectsync/syncclient" "github.com/anyproto/any-sync/commonspace/objectsync/synchandler" "github.com/anyproto/any-sync/commonspace/spacesyncproto" "github.com/anyproto/any-sync/commonspace/syncstatus" @@ -16,7 +16,7 @@ import ( type syncTreeHandler struct { objTree objecttree.ObjectTree - syncClient objectsync.SyncClient + syncClient syncclient.SyncClient syncStatus syncstatus.StatusUpdater handlerLock sync.Mutex spaceId string @@ -25,7 +25,7 @@ type syncTreeHandler struct { const maxQueueSize = 5 -func newSyncTreeHandler(spaceId string, objTree objecttree.ObjectTree, syncClient objectsync.SyncClient, syncStatus syncstatus.StatusUpdater) synchandler.SyncHandler { +func newSyncTreeHandler(spaceId string, objTree objecttree.ObjectTree, syncClient syncclient.SyncClient, syncStatus syncstatus.StatusUpdater) synchandler.SyncHandler { return &syncTreeHandler{ objTree: objTree, syncClient: syncClient, @@ -119,7 +119,7 @@ func (s *syncTreeHandler) handleHeadUpdate( return } - return s.syncClient.SendWithReply(ctx, senderId, treeId, fullRequest, replyId) + return s.syncClient.QueueRequest(ctx, senderId, treeId, fullRequest, replyId) } if s.alreadyHasHeads(objTree, update.Heads) { @@ -143,7 +143,7 @@ func (s *syncTreeHandler) handleHeadUpdate( return } - return s.syncClient.SendWithReply(ctx, senderId, treeId, fullRequest, replyId) + return s.syncClient.QueueRequest(ctx, senderId, treeId, fullRequest, replyId) } func (s *syncTreeHandler) handleFullSyncRequest( @@ -169,7 +169,7 @@ func (s *syncTreeHandler) handleFullSyncRequest( defer func() { if err != nil { log.ErrorCtx(ctx, "full sync request finished with error", zap.Error(err)) - s.syncClient.SendWithReply(ctx, senderId, treeId, treechangeproto.WrapError(treechangeproto.ErrFullSync, header), replyId) + s.syncClient.QueueRequest(ctx, senderId, treeId, treechangeproto.WrapError(treechangeproto.ErrFullSync, header), replyId) return } else if fullResponse != nil { cnt := fullResponse.Content.GetFullSyncResponse() @@ -192,7 +192,7 @@ func (s *syncTreeHandler) handleFullSyncRequest( return } - return s.syncClient.SendWithReply(ctx, senderId, treeId, fullResponse, replyId) + return s.syncClient.QueueRequest(ctx, senderId, treeId, fullResponse, replyId) } func (s *syncTreeHandler) handleFullSyncResponse( diff --git a/commonspace/object/tree/synctree/synctreehandler_test.go b/commonspace/object/tree/synctree/synctreehandler_test.go index c81ca5f4..dce08a93 100644 --- a/commonspace/object/tree/synctree/synctreehandler_test.go +++ b/commonspace/object/tree/synctree/synctreehandler_test.go @@ -3,8 +3,8 @@ package synctree import ( "context" "fmt" - "github.com/anyproto/any-sync/commonspace/objectsync" "github.com/anyproto/any-sync/commonspace/objectsync/mock_objectsync" + "github.com/anyproto/any-sync/commonspace/objectsync/syncclient" "sync" "testing" @@ -110,7 +110,7 @@ func TestSyncHandler_HandleHeadUpdate(t *testing.T) { SnapshotPath: []string{"h1"}, } treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) - objectMsg, _ := objectsync.MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + objectMsg, _ := syncclient.MarshallTreeMessage(treeMsg, "spaceId", treeId, "") fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId) fx.objectTreeMock.EXPECT().Heads().Return([]string{"h2"}).Times(2) @@ -139,7 +139,7 @@ func TestSyncHandler_HandleHeadUpdate(t *testing.T) { SnapshotPath: []string{"h1"}, } treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) - objectMsg, _ := objectsync.MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + objectMsg, _ := syncclient.MarshallTreeMessage(treeMsg, "spaceId", treeId, "") fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId) fx.objectTreeMock.EXPECT().Heads().Return([]string{"h2"}).AnyTimes() @@ -172,7 +172,7 @@ func TestSyncHandler_HandleHeadUpdate(t *testing.T) { SnapshotPath: []string{"h1"}, } treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) - objectMsg, _ := objectsync.MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + objectMsg, _ := syncclient.MarshallTreeMessage(treeMsg, "spaceId", treeId, "") fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId) fx.objectTreeMock.EXPECT().Heads().Return([]string{"h1"}).AnyTimes() @@ -193,7 +193,7 @@ func TestSyncHandler_HandleHeadUpdate(t *testing.T) { SnapshotPath: []string{"h1"}, } treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) - objectMsg, _ := objectsync.MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + objectMsg, _ := syncclient.MarshallTreeMessage(treeMsg, "spaceId", treeId, "") fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId) fx.objectTreeMock.EXPECT().Heads().Return([]string{"h2"}).AnyTimes() @@ -218,7 +218,7 @@ func TestSyncHandler_HandleHeadUpdate(t *testing.T) { SnapshotPath: []string{"h1"}, } treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) - objectMsg, _ := objectsync.MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + objectMsg, _ := syncclient.MarshallTreeMessage(treeMsg, "spaceId", treeId, "") fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId) fx.objectTreeMock.EXPECT().Heads().Return([]string{"h1"}).AnyTimes() @@ -251,7 +251,7 @@ func TestSyncHandler_HandleFullSyncRequest(t *testing.T) { SnapshotPath: []string{"h1"}, } treeMsg := treechangeproto.WrapFullRequest(fullSyncRequest, chWithId) - objectMsg, _ := objectsync.MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + objectMsg, _ := syncclient.MarshallTreeMessage(treeMsg, "spaceId", treeId, "") fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId) fx.objectTreeMock.EXPECT().Header().Return(nil) @@ -284,7 +284,7 @@ func TestSyncHandler_HandleFullSyncRequest(t *testing.T) { SnapshotPath: []string{"h1"}, } treeMsg := treechangeproto.WrapFullRequest(fullSyncRequest, chWithId) - objectMsg, _ := objectsync.MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + objectMsg, _ := syncclient.MarshallTreeMessage(treeMsg, "spaceId", treeId, "") fx.objectTreeMock.EXPECT(). Id().AnyTimes().Return(treeId) @@ -313,7 +313,7 @@ func TestSyncHandler_HandleFullSyncRequest(t *testing.T) { SnapshotPath: []string{"h1"}, } treeMsg := treechangeproto.WrapFullRequest(fullSyncRequest, chWithId) - objectMsg, _ := objectsync.MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + objectMsg, _ := syncclient.MarshallTreeMessage(treeMsg, "spaceId", treeId, "") objectMsg.RequestId = replyId fx.objectTreeMock.EXPECT(). @@ -340,7 +340,7 @@ func TestSyncHandler_HandleFullSyncRequest(t *testing.T) { SnapshotPath: []string{"h1"}, } treeMsg := treechangeproto.WrapFullRequest(fullSyncRequest, chWithId) - objectMsg, _ := objectsync.MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + objectMsg, _ := syncclient.MarshallTreeMessage(treeMsg, "spaceId", treeId, "") fx.objectTreeMock.EXPECT(). Id().AnyTimes().Return(treeId) @@ -381,7 +381,7 @@ func TestSyncHandler_HandleFullSyncResponse(t *testing.T) { SnapshotPath: []string{"h1"}, } treeMsg := treechangeproto.WrapFullResponse(fullSyncResponse, chWithId) - objectMsg, _ := objectsync.MarshallTreeMessage(treeMsg, "spaceId", treeId, replyId) + objectMsg, _ := syncclient.MarshallTreeMessage(treeMsg, "spaceId", treeId, replyId) fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId) fx.objectTreeMock.EXPECT(). @@ -414,7 +414,7 @@ func TestSyncHandler_HandleFullSyncResponse(t *testing.T) { SnapshotPath: []string{"h1"}, } treeMsg := treechangeproto.WrapFullResponse(fullSyncResponse, chWithId) - objectMsg, _ := objectsync.MarshallTreeMessage(treeMsg, "spaceId", treeId, replyId) + objectMsg, _ := syncclient.MarshallTreeMessage(treeMsg, "spaceId", treeId, replyId) fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId) fx.objectTreeMock.EXPECT(). diff --git a/commonspace/object/tree/synctree/treeremotegetter.go b/commonspace/object/tree/synctree/treeremotegetter.go index 3006ab5b..bee53231 100644 --- a/commonspace/object/tree/synctree/treeremotegetter.go +++ b/commonspace/object/tree/synctree/treeremotegetter.go @@ -47,7 +47,7 @@ func (t treeRemoteGetter) getPeers(ctx context.Context) (peerIds []string, err e func (t treeRemoteGetter) treeRequest(ctx context.Context, peerId string) (msg *treechangeproto.TreeSyncMessage, err error) { newTreeRequest := t.deps.SyncClient.CreateNewTreeRequest() - resp, err := t.deps.SyncClient.SendSync(ctx, peerId, t.treeId, newTreeRequest) + resp, err := t.deps.SyncClient.SendRequest(ctx, peerId, t.treeId, newTreeRequest) if err != nil { return } diff --git a/commonspace/object/tree/synctree/utils_test.go b/commonspace/object/tree/synctree/utils_test.go index 46936560..8f57a9f2 100644 --- a/commonspace/object/tree/synctree/utils_test.go +++ b/commonspace/object/tree/synctree/utils_test.go @@ -7,7 +7,7 @@ import ( "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" "github.com/anyproto/any-sync/commonspace/object/tree/treestorage" - "github.com/anyproto/any-sync/commonspace/objectsync" + "github.com/anyproto/any-sync/commonspace/objectsync/syncclient" "github.com/anyproto/any-sync/commonspace/objectsync/synchandler" "github.com/anyproto/any-sync/commonspace/spacesyncproto" "github.com/anyproto/any-sync/commonspace/syncstatus" @@ -89,14 +89,14 @@ type testSyncHandler struct { peerId string aclList list.AclList log *messageLog - syncClient objectsync.SyncClient + syncClient syncclient.SyncClient builder objecttree.BuildObjectTreeFunc } // createSyncHandler creates a sync handler when a tree is already created func createSyncHandler(peerId, spaceId string, objTree objecttree.ObjectTree, log *messageLog) *testSyncHandler { - factory := objectsync.NewRequestFactory() - syncClient := objectsync.NewSyncClient(spaceId, newTestMessagePool(peerId, log), factory) + factory := syncclient.NewRequestFactory() + syncClient := syncclient.NewSyncClient(spaceId, newTestMessagePool(peerId, log), factory) netTree := &broadcastTree{ ObjectTree: objTree, SyncClient: syncClient, @@ -107,8 +107,8 @@ func createSyncHandler(peerId, spaceId string, objTree objecttree.ObjectTree, lo // createEmptySyncHandler creates a sync handler when the tree will be provided later (this emulates the situation when we have no tree) func createEmptySyncHandler(peerId, spaceId string, builder objecttree.BuildObjectTreeFunc, aclList list.AclList, log *messageLog) *testSyncHandler { - factory := objectsync.NewRequestFactory() - syncClient := objectsync.NewSyncClient(spaceId, newTestMessagePool(peerId, log), factory) + factory := syncclient.NewRequestFactory() + syncClient := syncclient.NewSyncClient(spaceId, newTestMessagePool(peerId, log), factory) batcher := mb.New[protocolMsg](0) return &testSyncHandler{ @@ -140,9 +140,9 @@ func (h *testSyncHandler) HandleMessage(ctx context.Context, senderId string, re return } if unmarshalled.Content.GetFullSyncResponse() == nil { - newTreeRequest := objectsync.NewRequestFactory().CreateNewTreeRequest() + newTreeRequest := syncclient.NewRequestFactory().CreateNewTreeRequest() var objMsg *spacesyncproto.ObjectSyncMessage - objMsg, err = objectsync.MarshallTreeMessage(newTreeRequest, request.SpaceId, request.ObjectId, "") + objMsg, err = syncclient.MarshallTreeMessage(newTreeRequest, request.SpaceId, request.ObjectId, "") if err != nil { return } @@ -167,8 +167,8 @@ func (h *testSyncHandler) HandleMessage(ctx context.Context, senderId string, re } h.SyncHandler = newSyncTreeHandler(request.SpaceId, netTree, h.syncClient, syncstatus.NewNoOpSyncStatus()) var objMsg *spacesyncproto.ObjectSyncMessage - newTreeRequest := objectsync.NewRequestFactory().CreateHeadUpdate(netTree, res.Added) - objMsg, err = objectsync.MarshallTreeMessage(newTreeRequest, request.SpaceId, request.ObjectId, "") + newTreeRequest := syncclient.NewRequestFactory().CreateHeadUpdate(netTree, res.Added) + objMsg, err = syncclient.MarshallTreeMessage(newTreeRequest, request.SpaceId, request.ObjectId, "") if err != nil { return } @@ -278,7 +278,7 @@ func (m *testMessagePool) SendSync(ctx context.Context, peerId string, message * // it is a simplified version of SyncTree which is easier to use in the test environment type broadcastTree struct { objecttree.ObjectTree - objectsync.SyncClient + syncclient.SyncClient } func (b *broadcastTree) AddRawChanges(ctx context.Context, changes objecttree.RawChangesPayload) (objecttree.AddResult, error) { diff --git a/commonspace/objectsync/msgpool.go b/commonspace/objectsync/msgpool.go deleted file mode 100644 index 19098ace..00000000 --- a/commonspace/objectsync/msgpool.go +++ /dev/null @@ -1,142 +0,0 @@ -package objectsync - -import ( - "context" - "fmt" - "github.com/anyproto/any-sync/commonspace/objectsync/synchandler" - "github.com/anyproto/any-sync/commonspace/peermanager" - "github.com/anyproto/any-sync/commonspace/spacesyncproto" - "go.uber.org/zap" - "strconv" - "strings" - "sync" - "sync/atomic" - "time" -) - -type LastUsage interface { - LastUsage() time.Time -} - -// MessagePool can be made generic to work with different streams -type MessagePool interface { - LastUsage - synchandler.SyncHandler - peermanager.PeerManager - SendSync(ctx context.Context, peerId string, message *spacesyncproto.ObjectSyncMessage) (reply *spacesyncproto.ObjectSyncMessage, err error) -} - -type MessageHandler func(ctx context.Context, senderId string, message *spacesyncproto.ObjectSyncMessage) (err error) - -type responseWaiter struct { - ch chan *spacesyncproto.ObjectSyncMessage -} - -type messagePool struct { - sync.Mutex - peermanager.PeerManager - messageHandler MessageHandler - waiters map[string]responseWaiter - waitersMx sync.Mutex - counter atomic.Uint64 - lastUsage atomic.Int64 -} - -func newMessagePool(peerManager peermanager.PeerManager, messageHandler MessageHandler) MessagePool { - s := &messagePool{ - PeerManager: peerManager, - messageHandler: messageHandler, - waiters: make(map[string]responseWaiter), - } - return s -} - -func (s *messagePool) SendSync(ctx context.Context, peerId string, msg *spacesyncproto.ObjectSyncMessage) (reply *spacesyncproto.ObjectSyncMessage, err error) { - s.updateLastUsage() - if _, ok := ctx.Deadline(); !ok { - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(ctx, time.Minute) - defer cancel() - } - newCounter := s.counter.Add(1) - msg.RequestId = genReplyKey(peerId, msg.ObjectId, newCounter) - log.InfoCtx(ctx, "mpool sendSync", zap.String("requestId", msg.RequestId)) - s.waitersMx.Lock() - waiter := responseWaiter{ - ch: make(chan *spacesyncproto.ObjectSyncMessage, 1), - } - s.waiters[msg.RequestId] = waiter - s.waitersMx.Unlock() - - err = s.SendPeer(ctx, peerId, msg) - if err != nil { - return - } - select { - case <-ctx.Done(): - s.waitersMx.Lock() - delete(s.waiters, msg.RequestId) - s.waitersMx.Unlock() - - log.With(zap.String("requestId", msg.RequestId)).DebugCtx(ctx, "time elapsed when waiting") - err = fmt.Errorf("sendSync context error: %v", ctx.Err()) - case reply = <-waiter.ch: - // success - } - return -} - -func (s *messagePool) SendPeer(ctx context.Context, peerId string, msg *spacesyncproto.ObjectSyncMessage) (err error) { - s.updateLastUsage() - return s.PeerManager.SendPeer(ctx, peerId, msg) -} - -func (s *messagePool) Broadcast(ctx context.Context, msg *spacesyncproto.ObjectSyncMessage) (err error) { - s.updateLastUsage() - return s.PeerManager.Broadcast(ctx, msg) -} - -func (s *messagePool) HandleMessage(ctx context.Context, senderId string, msg *spacesyncproto.ObjectSyncMessage) (err error) { - s.updateLastUsage() - if msg.ReplyId != "" { - log.InfoCtx(ctx, "mpool receive reply", zap.String("replyId", msg.ReplyId)) - // we got reply, send it to waiter - if s.stopWaiter(msg) { - return - } - log.WarnCtx(ctx, "reply id does not exist", zap.String("replyId", msg.ReplyId)) - return - } - return s.messageHandler(ctx, senderId, msg) -} - -func (s *messagePool) LastUsage() time.Time { - return time.Unix(s.lastUsage.Load(), 0) -} - -func (s *messagePool) updateLastUsage() { - s.lastUsage.Store(time.Now().Unix()) -} - -func (s *messagePool) stopWaiter(msg *spacesyncproto.ObjectSyncMessage) bool { - s.waitersMx.Lock() - waiter, exists := s.waiters[msg.ReplyId] - if exists { - delete(s.waiters, msg.ReplyId) - s.waitersMx.Unlock() - waiter.ch <- msg - return true - } - s.waitersMx.Unlock() - return false -} - -func genReplyKey(peerId, treeId string, counter uint64) string { - b := &strings.Builder{} - b.WriteString(peerId) - b.WriteString(".") - b.WriteString(treeId) - b.WriteString(".") - b.WriteString(strconv.FormatUint(counter, 36)) - return b.String() -} diff --git a/commonspace/objectsync/objectsync.go b/commonspace/objectsync/objectsync.go index e56ee6ed..64ab66f6 100644 --- a/commonspace/objectsync/objectsync.go +++ b/commonspace/objectsync/objectsync.go @@ -4,15 +4,19 @@ package objectsync import ( "context" "fmt" - "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" - "github.com/gogo/protobuf/proto" + "github.com/anyproto/any-sync/app" + "github.com/anyproto/any-sync/commonspace/object/treemanager" + "github.com/anyproto/any-sync/commonspace/objectsync/syncclient" + "github.com/anyproto/any-sync/commonspace/spacestate" + "github.com/anyproto/any-sync/metric" + "github.com/anyproto/any-sync/net/peer" + "github.com/anyproto/any-sync/util/multiqueue" + "github.com/cheggaaa/mb/v3" "sync/atomic" "time" "github.com/anyproto/any-sync/app/logger" "github.com/anyproto/any-sync/commonspace/object/syncobjectgetter" - "github.com/anyproto/any-sync/commonspace/objectsync/synchandler" - "github.com/anyproto/any-sync/commonspace/peermanager" "github.com/anyproto/any-sync/commonspace/spacestorage" "github.com/anyproto/any-sync/commonspace/spacesyncproto" "github.com/anyproto/any-sync/nodeconf" @@ -20,63 +24,127 @@ import ( "golang.org/x/exp/slices" ) -var log = logger.NewNamed("common.commonspace.objectsync") +const CName = "common.commonspace.objectsync" + +var log = logger.NewNamed(CName) type ObjectSync interface { - LastUsage - synchandler.SyncHandler - SyncClient() SyncClient + app.ComponentRunnable +} - Close() (err error) +type HandleMessage struct { + Id uint64 + ReceiveTime time.Time + StartHandlingTime time.Time + Deadline time.Time + SenderId string + Message *spacesyncproto.ObjectSyncMessage + PeerCtx context.Context +} + +func (m HandleMessage) LogFields(fields ...zap.Field) []zap.Field { + return append(fields, + metric.SpaceId(m.Message.SpaceId), + metric.ObjectId(m.Message.ObjectId), + metric.QueueDur(m.StartHandlingTime.Sub(m.ReceiveTime)), + metric.TotalDur(time.Since(m.ReceiveTime)), + ) } type objectSync struct { spaceId string - messagePool MessagePool - syncClient SyncClient + syncClient syncclient.SyncClient objectGetter syncobjectgetter.SyncObjectGetter configuration nodeconf.NodeConf spaceStorage spacestorage.SpaceStorage + metric metric.Metric - syncCtx context.Context - cancelSync context.CancelFunc spaceIsDeleted *atomic.Bool + handleQueue multiqueue.MultiQueue[HandleMessage] } -func NewObjectSync( - spaceId string, - spaceIsDeleted *atomic.Bool, - configuration nodeconf.NodeConf, - peerManager peermanager.PeerManager, - objectGetter syncobjectgetter.SyncObjectGetter, - storage spacestorage.SpaceStorage) ObjectSync { - syncCtx, cancel := context.WithCancel(context.Background()) - os := &objectSync{ - objectGetter: objectGetter, - spaceStorage: storage, - spaceId: spaceId, - syncCtx: syncCtx, - cancelSync: cancel, - spaceIsDeleted: spaceIsDeleted, - configuration: configuration, +func (s *objectSync) Init(a *app.App) (err error) { + s.syncClient = a.MustComponent(syncclient.CName).(syncclient.SyncClient) + s.objectGetter = a.MustComponent(treemanager.CName).(treemanager.TreeManager).(syncobjectgetter.SyncObjectGetter) + s.configuration = a.MustComponent(nodeconf.CName).(nodeconf.NodeConf) + sharedData := a.MustComponent(spacestate.CName).(*spacestate.SpaceState) + s.metric = a.MustComponent(metric.CName).(metric.Metric) + s.spaceIsDeleted = sharedData.SpaceIsDeleted + s.spaceId = sharedData.SpaceId + s.handleQueue = multiqueue.New[HandleMessage](s.processHandleMessage, 100) + return nil +} + +func (s *objectSync) Name() (name string) { + return CName +} + +func (s *objectSync) Run(ctx context.Context) (err error) { + return nil +} + +func (s *objectSync) Close(ctx context.Context) (err error) { + return s.handleQueue.Close() +} + +func NewObjectSync() ObjectSync { + return &objectSync{} +} + +func (s *objectSync) HandleMessage(ctx context.Context, hm HandleMessage) (err error) { + threadId := hm.Message.ObjectId + hm.ReceiveTime = time.Now() + if hm.Message.ReplyId != "" { + threadId += hm.Message.ReplyId + defer func() { + _ = s.handleQueue.CloseThread(threadId) + }() + } + if hm.PeerCtx == nil { + hm.PeerCtx = ctx + } + err = s.handleQueue.Add(ctx, threadId, hm) + if err == mb.ErrOverflowed { + log.InfoCtx(ctx, "queue overflowed", zap.String("spaceId", s.spaceId), zap.String("objectId", threadId)) + // skip overflowed error + return nil } - os.messagePool = newMessagePool(peerManager, os.handleMessage) - os.syncClient = NewSyncClient(spaceId, os.messagePool, NewRequestFactory()) - return os -} - -func (s *objectSync) Close() (err error) { - s.cancelSync() return } -func (s *objectSync) LastUsage() time.Time { - return s.messagePool.LastUsage() -} +func (s *objectSync) processHandleMessage(msg HandleMessage) { + var err error + msg.StartHandlingTime = time.Now() + ctx := peer.CtxWithPeerId(context.Background(), msg.SenderId) + ctx = logger.CtxWithFields(ctx, zap.Uint64("msgId", msg.Id), zap.String("senderId", msg.SenderId)) + defer func() { + if s.metric == nil { + return + } + s.metric.RequestLog(msg.PeerCtx, "space.streamOp", msg.LogFields( + zap.Error(err), + )...) + }() -func (s *objectSync) HandleMessage(ctx context.Context, senderId string, message *spacesyncproto.ObjectSyncMessage) (err error) { - return s.messagePool.HandleMessage(ctx, senderId, message) + if !msg.Deadline.IsZero() { + now := time.Now() + if now.After(msg.Deadline) { + log.InfoCtx(ctx, "skip message: deadline exceed") + err = context.DeadlineExceeded + return + } + var cancel context.CancelFunc + ctx, cancel = context.WithDeadline(ctx, msg.Deadline) + defer cancel() + } + if err = s.handleMessage(ctx, msg.SenderId, msg.Message); err != nil { + if msg.Message.ObjectId != "" { + // cleanup thread on error + _ = s.handleQueue.CloseThread(msg.Message.ObjectId) + } + log.InfoCtx(ctx, "handleMessage error", zap.Error(err)) + } } func (s *objectSync) handleMessage(ctx context.Context, senderId string, msg *spacesyncproto.ObjectSyncMessage) (err error) { @@ -88,70 +156,16 @@ func (s *objectSync) handleMessage(ctx context.Context, senderId string, msg *sp log = log.With(zap.Bool("isDeleted", true)) // preventing sync with other clients if they are not just syncing the settings tree if !slices.Contains(s.configuration.NodeIds(s.spaceId), senderId) && msg.ObjectId != s.spaceStorage.SpaceSettingsId() { - s.unmarshallSendError(ctx, msg, spacesyncproto.ErrUnexpected, senderId, msg.ObjectId) return fmt.Errorf("can't perform operation with object, space is deleted") } } - log.DebugCtx(ctx, "handling message") - hasTree, err := s.spaceStorage.HasTree(msg.ObjectId) - if err != nil { - s.unmarshallSendError(ctx, msg, spacesyncproto.ErrUnexpected, senderId, msg.ObjectId) - return fmt.Errorf("falied to execute get operation on storage has tree: %w", err) - } - // in this case we will try to get it from remote, unless the sender also sent us the same request :-) - if !hasTree { - treeMsg := &treechangeproto.TreeSyncMessage{} - err = proto.Unmarshal(msg.Payload, treeMsg) - if err != nil { - s.sendError(ctx, nil, spacesyncproto.ErrUnexpected, senderId, msg.ObjectId, msg.RequestId) - return fmt.Errorf("failed to unmarshall tree sync message: %w", err) - } - // this means that we don't have the tree locally and therefore can't return it - if s.isEmptyFullSyncRequest(treeMsg) { - err = treechangeproto.ErrGetTree - s.sendError(ctx, nil, treechangeproto.ErrGetTree, senderId, msg.ObjectId, msg.RequestId) - return fmt.Errorf("failed to get tree from storage on full sync: %w", err) - } - } obj, err := s.objectGetter.GetObject(ctx, msg.ObjectId) if err != nil { - // TODO: write tests for object sync https://linear.app/anytype/issue/GO-1299/write-tests-for-commonspaceobjectsync - s.unmarshallSendError(ctx, msg, spacesyncproto.ErrUnexpected, senderId, msg.ObjectId) return fmt.Errorf("failed to get object from cache: %w", err) } - // TODO: unmarshall earlier err = obj.HandleMessage(ctx, senderId, msg) if err != nil { - s.unmarshallSendError(ctx, msg, spacesyncproto.ErrUnexpected, senderId, msg.ObjectId) return fmt.Errorf("failed to handle message: %w", err) } return } - -func (s *objectSync) SyncClient() SyncClient { - return s.syncClient -} - -func (s *objectSync) unmarshallSendError(ctx context.Context, msg *spacesyncproto.ObjectSyncMessage, respErr error, senderId, objectId string) { - unmarshalled := &treechangeproto.TreeSyncMessage{} - err := proto.Unmarshal(msg.Payload, unmarshalled) - if err != nil { - return - } - s.sendError(ctx, unmarshalled.RootChange, respErr, senderId, objectId, msg.RequestId) -} - -func (s *objectSync) sendError(ctx context.Context, root *treechangeproto.RawTreeChangeWithId, respErr error, senderId, objectId, replyId string) { - // we don't send errors if have no reply id, this can lead to bugs and also nobody needs this error - if replyId == "" { - return - } - resp := treechangeproto.WrapError(respErr, root) - if err := s.syncClient.SendWithReply(ctx, senderId, objectId, resp, replyId); err != nil { - log.InfoCtx(ctx, "failed to send error to client") - } -} - -func (s *objectSync) isEmptyFullSyncRequest(msg *treechangeproto.TreeSyncMessage) bool { - return msg.GetContent().GetFullSyncRequest() != nil && len(msg.GetContent().GetFullSyncRequest().GetHeads()) == 0 -} diff --git a/commonspace/objectsync/syncclient.go b/commonspace/objectsync/syncclient.go deleted file mode 100644 index aad712bd..00000000 --- a/commonspace/objectsync/syncclient.go +++ /dev/null @@ -1,78 +0,0 @@ -package objectsync - -import ( - "context" - "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" - "github.com/anyproto/any-sync/commonspace/spacesyncproto" - "go.uber.org/zap" -) - -type SyncClient interface { - RequestFactory - Broadcast(ctx context.Context, msg *treechangeproto.TreeSyncMessage) - SendWithReply(ctx context.Context, peerId, objectId string, msg *treechangeproto.TreeSyncMessage, replyId string) (err error) - SendSync(ctx context.Context, peerId, objectId string, msg *treechangeproto.TreeSyncMessage) (reply *spacesyncproto.ObjectSyncMessage, err error) - MessagePool() MessagePool -} - -type syncClient struct { - RequestFactory - spaceId string - messagePool MessagePool -} - -func NewSyncClient( - spaceId string, - messagePool MessagePool, - factory RequestFactory) SyncClient { - return &syncClient{ - messagePool: messagePool, - RequestFactory: factory, - spaceId: spaceId, - } -} - -func (s *syncClient) Broadcast(ctx context.Context, msg *treechangeproto.TreeSyncMessage) { - objMsg, err := MarshallTreeMessage(msg, s.spaceId, msg.RootChange.Id, "") - if err != nil { - return - } - err = s.messagePool.Broadcast(ctx, objMsg) - if err != nil { - log.DebugCtx(ctx, "broadcast error", zap.Error(err)) - } -} - -func (s *syncClient) SendSync(ctx context.Context, peerId, objectId string, msg *treechangeproto.TreeSyncMessage) (reply *spacesyncproto.ObjectSyncMessage, err error) { - objMsg, err := MarshallTreeMessage(msg, s.spaceId, objectId, "") - if err != nil { - return - } - return s.messagePool.SendSync(ctx, peerId, objMsg) -} - -func (s *syncClient) SendWithReply(ctx context.Context, peerId, objectId string, msg *treechangeproto.TreeSyncMessage, replyId string) (err error) { - objMsg, err := MarshallTreeMessage(msg, s.spaceId, objectId, replyId) - if err != nil { - return - } - return s.messagePool.SendPeer(ctx, peerId, objMsg) -} - -func (s *syncClient) MessagePool() MessagePool { - return s.messagePool -} - -func MarshallTreeMessage(message *treechangeproto.TreeSyncMessage, spaceId, objectId, replyId string) (objMsg *spacesyncproto.ObjectSyncMessage, err error) { - payload, err := message.Marshal() - if err != nil { - return - } - objMsg = &spacesyncproto.ObjectSyncMessage{ - ReplyId: replyId, - Payload: payload, - ObjectId: objectId, - SpaceId: spaceId, - } - return -} diff --git a/commonspace/objectsync/requestfactory.go b/commonspace/objectsync/syncclient/requestfactory.go similarity index 99% rename from commonspace/objectsync/requestfactory.go rename to commonspace/objectsync/syncclient/requestfactory.go index 1f4f3c7d..0d908179 100644 --- a/commonspace/objectsync/requestfactory.go +++ b/commonspace/objectsync/syncclient/requestfactory.go @@ -1,4 +1,4 @@ -package objectsync +package syncclient import ( "fmt" diff --git a/commonspace/objectsync/syncclient/syncclient.go b/commonspace/objectsync/syncclient/syncclient.go new file mode 100644 index 00000000..6041a2d0 --- /dev/null +++ b/commonspace/objectsync/syncclient/syncclient.go @@ -0,0 +1,98 @@ +package syncclient + +import ( + "context" + "github.com/anyproto/any-sync/app" + "github.com/anyproto/any-sync/app/logger" + "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" + "github.com/anyproto/any-sync/commonspace/requestsender" + "github.com/anyproto/any-sync/commonspace/spacestate" + "github.com/anyproto/any-sync/commonspace/spacesyncproto" + "github.com/anyproto/any-sync/commonspace/streamsender" + "go.uber.org/zap" +) + +const CName = "common.objectsync.syncclient" + +var log = logger.NewNamed(CName) + +type SyncClient interface { + app.Component + RequestFactory + Broadcast(msg *treechangeproto.TreeSyncMessage) + SendUpdate(peerId, objectId string, msg *treechangeproto.TreeSyncMessage) (err error) + QueueRequest(peerId, objectId string, msg *treechangeproto.TreeSyncMessage) (err error) + SendRequest(ctx context.Context, peerId, objectId string, msg *treechangeproto.TreeSyncMessage) (reply *spacesyncproto.ObjectSyncMessage, err error) +} + +type syncClient struct { + RequestFactory + spaceId string + requestSender requestsender.RequestSender + streamSender streamsender.StreamSender +} + +func NewSyncClient() SyncClient { + return &syncClient{} +} + +func (s *syncClient) Init(a *app.App) (err error) { + sharedState := a.MustComponent(spacestate.CName).(*spacestate.SpaceState) + s.spaceId = sharedState.SpaceId + s.requestSender = a.MustComponent(requestsender.CName).(requestsender.RequestSender) + s.streamSender = a.MustComponent(streamsender.CName).(streamsender.StreamSender) + return nil +} + +func (s *syncClient) Name() (name string) { + return CName +} + +func (s *syncClient) Broadcast(msg *treechangeproto.TreeSyncMessage) { + objMsg, err := MarshallTreeMessage(msg, s.spaceId, msg.RootChange.Id, "") + if err != nil { + return + } + err = s.streamSender.Broadcast(objMsg) + if err != nil { + log.Debug("broadcast error", zap.Error(err)) + } +} + +func (s *syncClient) SendUpdate(peerId, objectId string, msg *treechangeproto.TreeSyncMessage) (err error) { + objMsg, err := MarshallTreeMessage(msg, s.spaceId, objectId, "") + if err != nil { + return + } + return s.streamSender.SendPeer(peerId, objMsg) +} + +func (s *syncClient) SendRequest(ctx context.Context, peerId, objectId string, msg *treechangeproto.TreeSyncMessage) (reply *spacesyncproto.ObjectSyncMessage, err error) { + objMsg, err := MarshallTreeMessage(msg, s.spaceId, objectId, "") + if err != nil { + return + } + return s.requestSender.SendRequest(ctx, peerId, objMsg) +} + +func (s *syncClient) QueueRequest(peerId, objectId string, msg *treechangeproto.TreeSyncMessage) (err error) { + objMsg, err := MarshallTreeMessage(msg, s.spaceId, objectId, "") + if err != nil { + return + } + return s.requestSender.QueueRequest(peerId, objMsg) +} + +func MarshallTreeMessage(message *treechangeproto.TreeSyncMessage, spaceId, objectId, replyId string) (objMsg *spacesyncproto.ObjectSyncMessage, err error) { + payload, err := message.Marshal() + if err != nil { + return + } + objMsg = &spacesyncproto.ObjectSyncMessage{ + ReplyId: replyId, + Payload: payload, + ObjectId: objectId, + SpaceId: spaceId, + } + return +} diff --git a/commonspace/objecttreebuilder/treebuilder.go b/commonspace/objecttreebuilder/treebuilder.go new file mode 100644 index 00000000..f8bf346b --- /dev/null +++ b/commonspace/objecttreebuilder/treebuilder.go @@ -0,0 +1,191 @@ +package objecttreebuilder + +import ( + "context" + "errors" + "github.com/anyproto/any-sync/app" + "github.com/anyproto/any-sync/app/logger" + "github.com/anyproto/any-sync/commonspace/headsync" + "github.com/anyproto/any-sync/commonspace/object/acl/list" + "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" + "github.com/anyproto/any-sync/commonspace/object/tree/synctree" + "github.com/anyproto/any-sync/commonspace/object/tree/synctree/updatelistener" + "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" + "github.com/anyproto/any-sync/commonspace/object/tree/treestorage" + "github.com/anyproto/any-sync/commonspace/objectsync/syncclient" + "github.com/anyproto/any-sync/commonspace/peermanager" + "github.com/anyproto/any-sync/commonspace/spacestate" + "github.com/anyproto/any-sync/commonspace/spacestorage" + "github.com/anyproto/any-sync/commonspace/syncstatus" + "github.com/anyproto/any-sync/nodeconf" + "go.uber.org/zap" + "sync/atomic" +) + +type BuildTreeOpts struct { + Listener updatelistener.UpdateListener + WaitTreeRemoteSync bool + TreeBuilder objecttree.BuildObjectTreeFunc +} + +const CName = "common.commonspace.objecttreebuilder" + +var log = logger.NewNamed(CName) +var ErrSpaceClosed = errors.New("space is closed") + +type HistoryTreeOpts struct { + BeforeId string + Include bool + BuildFullTree bool +} + +type TreeBuilder interface { + app.Component + BuildTree(ctx context.Context, id string, opts BuildTreeOpts) (t objecttree.ObjectTree, err error) + BuildHistoryTree(ctx context.Context, id string, opts HistoryTreeOpts) (t objecttree.HistoryTree, err error) + CreateTree(ctx context.Context, payload objecttree.ObjectTreeCreatePayload) (res treestorage.TreeStorageCreatePayload, err error) + PutTree(ctx context.Context, payload treestorage.TreeStorageCreatePayload, listener updatelistener.UpdateListener) (t objecttree.ObjectTree, err error) + SetOnCloseHandler(handler func(id string)) +} + +type treeBuilder struct { + syncClient syncclient.SyncClient + configuration nodeconf.NodeConf + headsNotifiable synctree.HeadNotifiable + peerManager peermanager.PeerManager + spaceStorage spacestorage.SpaceStorage + syncStatus syncstatus.StatusUpdater + + log logger.CtxLogger + builder objecttree.BuildObjectTreeFunc + spaceId string + aclList list.AclList + treesUsed *atomic.Int32 + isClosed *atomic.Bool + onClose func(id string) +} + +func (t *treeBuilder) Init(a *app.App) (err error) { + state := a.MustComponent(spacestate.CName).(*spacestate.SpaceState) + t.spaceId = state.SpaceId + t.aclList = state.AclList + t.isClosed = state.SpaceIsClosed + t.spaceStorage = state.SpaceStorage + t.treesUsed = state.TreesUsed + t.builder = state.TreeBuilderFunc + t.configuration = a.MustComponent(nodeconf.CName).(nodeconf.NodeConf) + t.headsNotifiable = a.MustComponent(headsync.CName).(headsync.HeadSync) + t.spaceStorage = state.SpaceStorage + t.syncStatus = a.MustComponent(syncstatus.CName).(syncstatus.StatusUpdater) + t.peerManager = a.MustComponent(peermanager.CName).(peermanager.PeerManager) + t.log = log.With(zap.String("spaceId", t.spaceId)) + t.onClose = state.Actions.OnObjectDelete + return nil +} + +func (t *treeBuilder) Name() (name string) { + return CName +} + +func (t *treeBuilder) SetOnCloseHandler(handler func(id string)) { + t.onClose = handler +} + +func (t *treeBuilder) BuildTree(ctx context.Context, id string, opts BuildTreeOpts) (ot objecttree.ObjectTree, err error) { + if t.isClosed.Load() { + // TODO: change to real error + err = ErrSpaceClosed + return + } + treeBuilder := opts.TreeBuilder + if treeBuilder == nil { + treeBuilder = t.builder + } + deps := synctree.BuildDeps{ + SpaceId: t.spaceId, + SyncClient: t.syncClient, + Configuration: t.configuration, + HeadNotifiable: t.headsNotifiable, + Listener: opts.Listener, + AclList: t.aclList, + SpaceStorage: t.spaceStorage, + OnClose: t.onClose, + SyncStatus: t.syncStatus, + WaitTreeRemoteSync: opts.WaitTreeRemoteSync, + PeerGetter: t.peerManager, + BuildObjectTree: treeBuilder, + } + t.treesUsed.Add(1) + t.log.Debug("incrementing counter", zap.String("id", id), zap.Int32("trees", t.treesUsed.Load())) + if ot, err = synctree.BuildSyncTreeOrGetRemote(ctx, id, deps); err != nil { + t.treesUsed.Add(-1) + t.log.Debug("decrementing counter, load failed", zap.String("id", id), zap.Int32("trees", t.treesUsed.Load()), zap.Error(err)) + return nil, err + } + return +} + +func (t *treeBuilder) BuildHistoryTree(ctx context.Context, id string, opts HistoryTreeOpts) (ot objecttree.HistoryTree, err error) { + if t.isClosed.Load() { + // TODO: change to real error + err = ErrSpaceClosed + return + } + + params := objecttree.HistoryTreeParams{ + AclList: t.aclList, + BeforeId: opts.BeforeId, + IncludeBeforeId: opts.Include, + BuildFullTree: opts.BuildFullTree, + } + params.TreeStorage, err = t.spaceStorage.TreeStorage(id) + if err != nil { + return + } + return objecttree.BuildHistoryTree(params) +} + +func (t *treeBuilder) CreateTree(ctx context.Context, payload objecttree.ObjectTreeCreatePayload) (res treestorage.TreeStorageCreatePayload, err error) { + if t.isClosed.Load() { + err = ErrSpaceClosed + return + } + root, err := objecttree.CreateObjectTreeRoot(payload, t.aclList) + if err != nil { + return + } + + res = treestorage.TreeStorageCreatePayload{ + RootRawChange: root, + Changes: []*treechangeproto.RawTreeChangeWithId{root}, + Heads: []string{root.Id}, + } + return +} + +func (t *treeBuilder) PutTree(ctx context.Context, payload treestorage.TreeStorageCreatePayload, listener updatelistener.UpdateListener) (ot objecttree.ObjectTree, err error) { + if t.isClosed.Load() { + err = ErrSpaceClosed + return + } + deps := synctree.BuildDeps{ + SpaceId: t.spaceId, + SyncClient: t.syncClient, + Configuration: t.configuration, + HeadNotifiable: t.headsNotifiable, + Listener: listener, + AclList: t.aclList, + SpaceStorage: t.spaceStorage, + OnClose: t.onClose, + SyncStatus: t.syncStatus, + PeerGetter: t.peerManager, + BuildObjectTree: t.builder, + } + ot, err = synctree.PutSyncTree(ctx, payload, deps) + if err != nil { + return + } + t.treesUsed.Add(1) + t.log.Debug("incrementing counter", zap.String("id", payload.RootRawChange.Id), zap.Int32("trees", t.treesUsed.Load())) + return +} diff --git a/commonspace/requestsender/requestsender.go b/commonspace/requestsender/requestsender.go new file mode 100644 index 00000000..1ba166fb --- /dev/null +++ b/commonspace/requestsender/requestsender.go @@ -0,0 +1,45 @@ +package requestsender + +import ( + "context" + "github.com/anyproto/any-sync/app" + "github.com/anyproto/any-sync/app/logger" + "github.com/anyproto/any-sync/commonspace/spacesyncproto" +) + +const CName = "common.commonspace.requestsender" + +var log = logger.NewNamed(CName) + +type RequestSender interface { + app.ComponentRunnable + SendRequest(ctx context.Context, peerId string, msg *spacesyncproto.ObjectSyncMessage) (reply *spacesyncproto.ObjectSyncMessage, err error) + QueueRequest(peerId string, msg *spacesyncproto.ObjectSyncMessage) (err error) +} + +type requestSender struct { +} + +func (r *requestSender) Init(a *app.App) (err error) { + return +} + +func (r *requestSender) Name() (name string) { + return CName +} + +func (r *requestSender) Run(ctx context.Context) (err error) { + return nil +} + +func (r *requestSender) Close(ctx context.Context) (err error) { + return nil +} + +func (r *requestSender) SendRequest(ctx context.Context, peerId string, msg *spacesyncproto.ObjectSyncMessage) (reply *spacesyncproto.ObjectSyncMessage, err error) { + return nil, nil +} + +func (r *requestSender) QueueRequest(peerId string, msg *spacesyncproto.ObjectSyncMessage) (err error) { + return nil +} diff --git a/commonspace/settings/deleter.go b/commonspace/settings/deleter.go index 322308de..5d3bd5a1 100644 --- a/commonspace/settings/deleter.go +++ b/commonspace/settings/deleter.go @@ -2,9 +2,9 @@ package settings import ( "context" + "github.com/anyproto/any-sync/commonspace/deletionstate" "github.com/anyproto/any-sync/commonspace/object/tree/treestorage" "github.com/anyproto/any-sync/commonspace/object/treemanager" - "github.com/anyproto/any-sync/commonspace/settings/settingsstate" "github.com/anyproto/any-sync/commonspace/spacestorage" "go.uber.org/zap" ) @@ -15,11 +15,11 @@ type Deleter interface { type deleter struct { st spacestorage.SpaceStorage - state settingsstate.ObjectDeletionState + state deletionstate.ObjectDeletionState getter treemanager.TreeManager } -func newDeleter(st spacestorage.SpaceStorage, state settingsstate.ObjectDeletionState, getter treemanager.TreeManager) Deleter { +func newDeleter(st spacestorage.SpaceStorage, state deletionstate.ObjectDeletionState, getter treemanager.TreeManager) Deleter { return &deleter{st, state, getter} } diff --git a/commonspace/settings/deletionmanager.go b/commonspace/settings/deletionmanager.go index 2d3d47ff..2611d28c 100644 --- a/commonspace/settings/deletionmanager.go +++ b/commonspace/settings/deletionmanager.go @@ -2,6 +2,7 @@ package settings import ( "context" + "github.com/anyproto/any-sync/commonspace/deletionstate" "github.com/anyproto/any-sync/commonspace/object/treemanager" "github.com/anyproto/any-sync/commonspace/settings/settingsstate" "go.uber.org/zap" @@ -20,7 +21,7 @@ func newDeletionManager( settingsId string, isResponsible bool, treeManager treemanager.TreeManager, - deletionState settingsstate.ObjectDeletionState, + deletionState deletionstate.ObjectDeletionState, provider SpaceIdsProvider, onSpaceDelete func()) DeletionManager { return &deletionManager{ @@ -35,7 +36,7 @@ func newDeletionManager( } type deletionManager struct { - deletionState settingsstate.ObjectDeletionState + deletionState deletionstate.ObjectDeletionState provider SpaceIdsProvider treeManager treemanager.TreeManager spaceId string diff --git a/commonspace/settings/settings.go b/commonspace/settings/settings.go index 5c2b41cf..4e2177ae 100644 --- a/commonspace/settings/settings.go +++ b/commonspace/settings/settings.go @@ -1,328 +1,88 @@ -//go:generate mockgen -destination mock_settings/mock_settings.go github.com/anyproto/any-sync/commonspace/settings DeletionManager,Deleter,SpaceIdsProvider package settings import ( "context" - "errors" - "fmt" - "github.com/anyproto/any-sync/util/crypto" - "github.com/anyproto/any-sync/accountservice" - "github.com/anyproto/any-sync/app/logger" + "github.com/anyproto/any-sync/app" + "github.com/anyproto/any-sync/commonspace/deletionstate" + "github.com/anyproto/any-sync/commonspace/headsync" "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" "github.com/anyproto/any-sync/commonspace/object/tree/synctree" "github.com/anyproto/any-sync/commonspace/object/tree/synctree/updatelistener" - "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" "github.com/anyproto/any-sync/commonspace/object/treemanager" - "github.com/anyproto/any-sync/commonspace/settings/settingsstate" + "github.com/anyproto/any-sync/commonspace/objecttreebuilder" + "github.com/anyproto/any-sync/commonspace/spacestate" "github.com/anyproto/any-sync/commonspace/spacestorage" - "github.com/anyproto/any-sync/commonspace/spacesyncproto" "github.com/anyproto/any-sync/nodeconf" - "github.com/gogo/protobuf/proto" "go.uber.org/zap" - "golang.org/x/exp/slices" ) -var log = logger.NewNamed("common.commonspace.settings") +const CName = "common.commonspace.settings" -type SettingsObject interface { - synctree.SyncTree - Init(ctx context.Context) (err error) - DeleteObject(id string) (err error) - DeleteSpace(ctx context.Context, raw *treechangeproto.RawTreeChangeWithId) (err error) - SpaceDeleteRawChange() (raw *treechangeproto.RawTreeChangeWithId, err error) +type Settings interface { + app.ComponentRunnable } -var ( - ErrDeleteSelf = errors.New("cannot delete self") - ErrAlreadyDeleted = errors.New("the object is already deleted") - ErrObjDoesNotExist = errors.New("the object does not exist") - ErrCantDeleteSpace = errors.New("not able to delete space") -) +type settings struct { + account accountservice.Service + treeManager treemanager.TreeManager + storage spacestorage.SpaceStorage + configuration nodeconf.NodeConf + deletionState deletionstate.ObjectDeletionState + headsync headsync.HeadSync + spaceActions spacestate.SpaceActions + treeBuilder objecttreebuilder.TreeBuilder -var ( - DoSnapshot = objecttree.DoSnapshot - buildHistoryTree = func(objTree objecttree.ObjectTree) (objecttree.ReadableObjectTree, error) { - return objecttree.BuildHistoryTree(objecttree.HistoryTreeParams{ - TreeStorage: objTree.Storage(), - AclList: objTree.AclList(), - BuildFullTree: true, - }) - } -) - -type BuildTreeFunc func(ctx context.Context, id string, listener updatelistener.UpdateListener) (t synctree.SyncTree, err error) - -type Deps struct { - BuildFunc BuildTreeFunc - Account accountservice.Service - TreeManager treemanager.TreeManager - Store spacestorage.SpaceStorage - Configuration nodeconf.NodeConf - DeletionState settingsstate.ObjectDeletionState - Provider SpaceIdsProvider - OnSpaceDelete func() - // testing dependencies - builder settingsstate.StateBuilder - del Deleter - delManager DeletionManager - changeFactory settingsstate.ChangeFactory + settingsObject SettingsObject } -type settingsObject struct { - synctree.SyncTree - account accountservice.Service - spaceId string - treeManager treemanager.TreeManager - store spacestorage.SpaceStorage - builder settingsstate.StateBuilder - buildFunc BuildTreeFunc - loop *deleteLoop - - state *settingsstate.State - deletionState settingsstate.ObjectDeletionState - deletionManager DeletionManager - changeFactory settingsstate.ChangeFactory +func (s *settings) Run(ctx context.Context) (err error) { + return s.settingsObject.Init(ctx) } -func NewSettingsObject(deps Deps, spaceId string) (obj SettingsObject) { - var ( - deleter Deleter - deletionManager DeletionManager - builder settingsstate.StateBuilder - changeFactory settingsstate.ChangeFactory - ) - if deps.del == nil { - deleter = newDeleter(deps.Store, deps.DeletionState, deps.TreeManager) - } else { - deleter = deps.del - } - if deps.delManager == nil { - deletionManager = newDeletionManager( - spaceId, - deps.Store.SpaceSettingsId(), - deps.Configuration.IsResponsible(spaceId), - deps.TreeManager, - deps.DeletionState, - deps.Provider, - deps.OnSpaceDelete) - } else { - deletionManager = deps.delManager - } - if deps.builder == nil { - builder = settingsstate.NewStateBuilder() - } else { - builder = deps.builder - } - if deps.changeFactory == nil { - changeFactory = settingsstate.NewChangeFactory() - } else { - changeFactory = deps.changeFactory - } - - loop := newDeleteLoop(func() { - deleter.Delete() - }) - deps.DeletionState.AddObserver(func(ids []string) { - loop.notify() - }) - - s := &settingsObject{ - loop: loop, - spaceId: spaceId, - account: deps.Account, - deletionState: deps.DeletionState, - treeManager: deps.TreeManager, - store: deps.Store, - buildFunc: deps.BuildFunc, - builder: builder, - deletionManager: deletionManager, - changeFactory: changeFactory, - } - obj = s - return +func (s *settings) Close(ctx context.Context) (err error) { + return s.settingsObject.Close() } -func (s *settingsObject) updateIds(tr objecttree.ObjectTree) { - var err error - s.state, err = s.builder.Build(tr, s.state) - if err != nil { - log.Error("failed to build state", zap.Error(err)) - return - } - log.Debug("updating object state", zap.String("deleted by", s.state.DeleterId)) - if err = s.deletionManager.UpdateState(context.Background(), s.state); err != nil { - log.Error("failed to update state", zap.Error(err)) - } -} +func (s *settings) Init(a *app.App) (err error) { + s.account = a.MustComponent(accountservice.CName).(accountservice.Service) + s.treeManager = a.MustComponent(treemanager.CName).(treemanager.TreeManager) + s.headsync = a.MustComponent(headsync.CName).(headsync.HeadSync) + s.configuration = a.MustComponent(nodeconf.CName).(nodeconf.NodeConf) + s.deletionState = a.MustComponent(deletionstate.CName).(deletionstate.ObjectDeletionState) + s.treeBuilder = a.MustComponent(objecttreebuilder.CName).(objecttreebuilder.TreeBuilder) -// Update is called as part of UpdateListener interface -func (s *settingsObject) Update(tr objecttree.ObjectTree) { - s.updateIds(tr) -} + sharedState := a.MustComponent(spacestate.CName).(*spacestate.SpaceState) + s.spaceActions = sharedState.Actions + s.storage = sharedState.SpaceStorage -// Rebuild is called as part of UpdateListener interface (including when the object is built for the first time, e.g. on Init call) -func (s *settingsObject) Rebuild(tr objecttree.ObjectTree) { - // at initial build "s" may not contain the object tree, so it is safer to provide it from the function parameter - s.state = nil - s.updateIds(tr) -} - -func (s *settingsObject) Init(ctx context.Context) (err error) { - settingsId := s.store.SpaceSettingsId() - log.Debug("space settings id", zap.String("id", settingsId)) - s.SyncTree, err = s.buildFunc(ctx, settingsId, s) - if err != nil { - return - } - // TODO: remove this check when everybody updates - if err = s.checkHistoryState(ctx); err != nil { - return - } - s.loop.Run() - return -} - -func (s *settingsObject) checkHistoryState(ctx context.Context) (err error) { - historyTree, err := buildHistoryTree(s.SyncTree) - if err != nil { - return - } - fullState, err := s.builder.Build(historyTree, nil) - if err != nil { - return - } - if len(fullState.DeletedIds) != len(s.state.DeletedIds) { - log.WarnCtx(ctx, "state does not have all deleted ids", - zap.Int("fullstate ids", len(fullState.DeletedIds)), - zap.Int("state ids", len(fullState.DeletedIds))) - s.state = fullState - err = s.deletionManager.UpdateState(context.Background(), s.state) - if err != nil { + deps := Deps{ + BuildFunc: func(ctx context.Context, id string, listener updatelistener.UpdateListener) (t synctree.SyncTree, err error) { + res, err := s.treeBuilder.BuildTree(ctx, id, objecttreebuilder.BuildTreeOpts{ + Listener: listener, + WaitTreeRemoteSync: false, + // space settings document should not have empty data + TreeBuilder: objecttree.BuildObjectTree, + }) + log.Debug("building settings tree", zap.String("id", id), zap.String("spaceId", sharedState.SpaceId)) + if err != nil { + return + } + t = res.(synctree.SyncTree) return - } + }, + Account: s.account, + TreeManager: s.treeManager, + Store: s.storage, + Configuration: s.configuration, + DeletionState: s.deletionState, + Provider: s.headsync, + OnSpaceDelete: s.spaceActions.OnSpaceDelete, } - return + s.settingsObject = NewSettingsObject(deps, sharedState.SpaceId) + return nil } -func (s *settingsObject) Close() error { - s.loop.Close() - return s.SyncTree.Close() -} - -func (s *settingsObject) DeleteSpace(ctx context.Context, raw *treechangeproto.RawTreeChangeWithId) (err error) { - s.Lock() - defer s.Unlock() - defer func() { - log.Debug("finished adding delete change", zap.Error(err)) - }() - err = s.verifyDeleteSpace(raw) - if err != nil { - return - } - res, err := s.AddRawChanges(ctx, objecttree.RawChangesPayload{ - NewHeads: []string{raw.Id}, - RawChanges: []*treechangeproto.RawTreeChangeWithId{raw}, - }) - if err != nil { - return - } - if !slices.Contains(res.Heads, raw.Id) { - err = ErrCantDeleteSpace - return - } - return -} - -func (s *settingsObject) SpaceDeleteRawChange() (raw *treechangeproto.RawTreeChangeWithId, err error) { - accountData := s.account.Account() - data, err := s.changeFactory.CreateSpaceDeleteChange(accountData.PeerId, s.state, false) - if err != nil { - return - } - return s.PrepareChange(objecttree.SignableChangeContent{ - Data: data, - Key: accountData.SignKey, - IsSnapshot: false, - IsEncrypted: false, - }) -} - -func (s *settingsObject) DeleteObject(id string) (err error) { - s.Lock() - defer s.Unlock() - if s.Id() == id { - err = ErrDeleteSelf - return - } - if s.state.Exists(id) { - err = ErrAlreadyDeleted - return nil - } - _, err = s.store.TreeStorage(id) - if err != nil { - err = ErrObjDoesNotExist - return - } - isSnapshot := DoSnapshot(s.Len()) - res, err := s.changeFactory.CreateObjectDeleteChange(id, s.state, isSnapshot) - if err != nil { - return - } - - return s.addContent(res, isSnapshot) -} - -func (s *settingsObject) verifyDeleteSpace(raw *treechangeproto.RawTreeChangeWithId) (err error) { - data, err := s.UnpackChange(raw) - if err != nil { - return - } - return verifyDeleteContent(data, "") -} - -func (s *settingsObject) addContent(data []byte, isSnapshot bool) (err error) { - accountData := s.account.Account() - res, err := s.AddContent(context.Background(), objecttree.SignableChangeContent{ - Data: data, - Key: accountData.SignKey, - IsSnapshot: isSnapshot, - IsEncrypted: false, - }) - if err != nil { - return - } - if res.Mode == objecttree.Rebuild { - s.Rebuild(s) - } else { - s.Update(s) - } - return -} - -func VerifyDeleteChange(raw *treechangeproto.RawTreeChangeWithId, identity crypto.PubKey, peerId string) (err error) { - changeBuilder := objecttree.NewChangeBuilder(crypto.NewKeyStorage(), nil) - res, err := changeBuilder.Unmarshall(raw, true) - if err != nil { - return - } - if !res.Identity.Equals(identity) { - return fmt.Errorf("incorrect identity") - } - return verifyDeleteContent(res.Data, peerId) -} - -func verifyDeleteContent(data []byte, peerId string) (err error) { - content := &spacesyncproto.SettingsData{} - err = proto.Unmarshal(data, content) - if err != nil { - return - } - if len(content.GetContent()) != 1 || - content.GetContent()[0].GetSpaceDelete() == nil || - (peerId == "" && content.GetContent()[0].GetSpaceDelete().GetDeleterPeerId() == "") || - (peerId != "" && content.GetContent()[0].GetSpaceDelete().GetDeleterPeerId() != peerId) { - return fmt.Errorf("incorrect delete change payload") - } - return +func (s *settings) Name() (name string) { + return CName } diff --git a/commonspace/settings/settingsobject.go b/commonspace/settings/settingsobject.go new file mode 100644 index 00000000..e6fd0b39 --- /dev/null +++ b/commonspace/settings/settingsobject.go @@ -0,0 +1,329 @@ +//go:generate mockgen -destination mock_settings/mock_settings.go github.com/anyproto/any-sync/commonspace/settings DeletionManager,Deleter,SpaceIdsProvider +package settings + +import ( + "context" + "errors" + "fmt" + "github.com/anyproto/any-sync/commonspace/deletionstate" + "github.com/anyproto/any-sync/util/crypto" + + "github.com/anyproto/any-sync/accountservice" + "github.com/anyproto/any-sync/app/logger" + "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" + "github.com/anyproto/any-sync/commonspace/object/tree/synctree" + "github.com/anyproto/any-sync/commonspace/object/tree/synctree/updatelistener" + "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" + "github.com/anyproto/any-sync/commonspace/object/treemanager" + "github.com/anyproto/any-sync/commonspace/settings/settingsstate" + "github.com/anyproto/any-sync/commonspace/spacestorage" + "github.com/anyproto/any-sync/commonspace/spacesyncproto" + "github.com/anyproto/any-sync/nodeconf" + "github.com/gogo/protobuf/proto" + "go.uber.org/zap" + "golang.org/x/exp/slices" +) + +var log = logger.NewNamed("common.commonspace.settings") + +type SettingsObject interface { + synctree.SyncTree + Init(ctx context.Context) (err error) + DeleteObject(id string) (err error) + DeleteSpace(ctx context.Context, raw *treechangeproto.RawTreeChangeWithId) (err error) + SpaceDeleteRawChange() (raw *treechangeproto.RawTreeChangeWithId, err error) +} + +var ( + ErrDeleteSelf = errors.New("cannot delete self") + ErrAlreadyDeleted = errors.New("the object is already deleted") + ErrObjDoesNotExist = errors.New("the object does not exist") + ErrCantDeleteSpace = errors.New("not able to delete space") +) + +var ( + DoSnapshot = objecttree.DoSnapshot + buildHistoryTree = func(objTree objecttree.ObjectTree) (objecttree.ReadableObjectTree, error) { + return objecttree.BuildHistoryTree(objecttree.HistoryTreeParams{ + TreeStorage: objTree.Storage(), + AclList: objTree.AclList(), + BuildFullTree: true, + }) + } +) + +type BuildTreeFunc func(ctx context.Context, id string, listener updatelistener.UpdateListener) (t synctree.SyncTree, err error) + +type Deps struct { + BuildFunc BuildTreeFunc + Account accountservice.Service + TreeManager treemanager.TreeManager + Store spacestorage.SpaceStorage + Configuration nodeconf.NodeConf + DeletionState deletionstate.ObjectDeletionState + Provider SpaceIdsProvider + OnSpaceDelete func() + // testing dependencies + builder settingsstate.StateBuilder + del Deleter + delManager DeletionManager + changeFactory settingsstate.ChangeFactory +} + +type settingsObject struct { + synctree.SyncTree + account accountservice.Service + spaceId string + treeManager treemanager.TreeManager + store spacestorage.SpaceStorage + builder settingsstate.StateBuilder + buildFunc BuildTreeFunc + loop *deleteLoop + + state *settingsstate.State + deletionState deletionstate.ObjectDeletionState + deletionManager DeletionManager + changeFactory settingsstate.ChangeFactory +} + +func NewSettingsObject(deps Deps, spaceId string) (obj SettingsObject) { + var ( + deleter Deleter + deletionManager DeletionManager + builder settingsstate.StateBuilder + changeFactory settingsstate.ChangeFactory + ) + if deps.del == nil { + deleter = newDeleter(deps.Store, deps.DeletionState, deps.TreeManager) + } else { + deleter = deps.del + } + if deps.delManager == nil { + deletionManager = newDeletionManager( + spaceId, + deps.Store.SpaceSettingsId(), + deps.Configuration.IsResponsible(spaceId), + deps.TreeManager, + deps.DeletionState, + deps.Provider, + deps.OnSpaceDelete) + } else { + deletionManager = deps.delManager + } + if deps.builder == nil { + builder = settingsstate.NewStateBuilder() + } else { + builder = deps.builder + } + if deps.changeFactory == nil { + changeFactory = settingsstate.NewChangeFactory() + } else { + changeFactory = deps.changeFactory + } + + loop := newDeleteLoop(func() { + deleter.Delete() + }) + deps.DeletionState.AddObserver(func(ids []string) { + loop.notify() + }) + + s := &settingsObject{ + loop: loop, + spaceId: spaceId, + account: deps.Account, + deletionState: deps.DeletionState, + treeManager: deps.TreeManager, + store: deps.Store, + buildFunc: deps.BuildFunc, + builder: builder, + deletionManager: deletionManager, + changeFactory: changeFactory, + } + obj = s + return +} + +func (s *settingsObject) updateIds(tr objecttree.ObjectTree) { + var err error + s.state, err = s.builder.Build(tr, s.state) + if err != nil { + log.Error("failed to build state", zap.Error(err)) + return + } + log.Debug("updating object state", zap.String("deleted by", s.state.DeleterId)) + if err = s.deletionManager.UpdateState(context.Background(), s.state); err != nil { + log.Error("failed to update state", zap.Error(err)) + } +} + +// Update is called as part of UpdateListener interface +func (s *settingsObject) Update(tr objecttree.ObjectTree) { + s.updateIds(tr) +} + +// Rebuild is called as part of UpdateListener interface (including when the object is built for the first time, e.g. on Init call) +func (s *settingsObject) Rebuild(tr objecttree.ObjectTree) { + // at initial build "s" may not contain the object tree, so it is safer to provide it from the function parameter + s.state = nil + s.updateIds(tr) +} + +func (s *settingsObject) Init(ctx context.Context) (err error) { + settingsId := s.store.SpaceSettingsId() + log.Debug("space settings id", zap.String("id", settingsId)) + s.SyncTree, err = s.buildFunc(ctx, settingsId, s) + if err != nil { + return + } + // TODO: remove this check when everybody updates + if err = s.checkHistoryState(ctx); err != nil { + return + } + s.loop.Run() + return +} + +func (s *settingsObject) checkHistoryState(ctx context.Context) (err error) { + historyTree, err := buildHistoryTree(s.SyncTree) + if err != nil { + return + } + fullState, err := s.builder.Build(historyTree, nil) + if err != nil { + return + } + if len(fullState.DeletedIds) != len(s.state.DeletedIds) { + log.WarnCtx(ctx, "state does not have all deleted ids", + zap.Int("fullstate ids", len(fullState.DeletedIds)), + zap.Int("state ids", len(fullState.DeletedIds))) + s.state = fullState + err = s.deletionManager.UpdateState(context.Background(), s.state) + if err != nil { + return + } + } + return +} + +func (s *settingsObject) Close() error { + s.loop.Close() + return s.SyncTree.Close() +} + +func (s *settingsObject) DeleteSpace(ctx context.Context, raw *treechangeproto.RawTreeChangeWithId) (err error) { + s.Lock() + defer s.Unlock() + defer func() { + log.Debug("finished adding delete change", zap.Error(err)) + }() + err = s.verifyDeleteSpace(raw) + if err != nil { + return + } + res, err := s.AddRawChanges(ctx, objecttree.RawChangesPayload{ + NewHeads: []string{raw.Id}, + RawChanges: []*treechangeproto.RawTreeChangeWithId{raw}, + }) + if err != nil { + return + } + if !slices.Contains(res.Heads, raw.Id) { + err = ErrCantDeleteSpace + return + } + return +} + +func (s *settingsObject) SpaceDeleteRawChange() (raw *treechangeproto.RawTreeChangeWithId, err error) { + accountData := s.account.Account() + data, err := s.changeFactory.CreateSpaceDeleteChange(accountData.PeerId, s.state, false) + if err != nil { + return + } + return s.PrepareChange(objecttree.SignableChangeContent{ + Data: data, + Key: accountData.SignKey, + IsSnapshot: false, + IsEncrypted: false, + }) +} + +func (s *settingsObject) DeleteObject(id string) (err error) { + s.Lock() + defer s.Unlock() + if s.Id() == id { + err = ErrDeleteSelf + return + } + if s.state.Exists(id) { + err = ErrAlreadyDeleted + return nil + } + _, err = s.store.TreeStorage(id) + if err != nil { + err = ErrObjDoesNotExist + return + } + isSnapshot := DoSnapshot(s.Len()) + res, err := s.changeFactory.CreateObjectDeleteChange(id, s.state, isSnapshot) + if err != nil { + return + } + + return s.addContent(res, isSnapshot) +} + +func (s *settingsObject) verifyDeleteSpace(raw *treechangeproto.RawTreeChangeWithId) (err error) { + data, err := s.UnpackChange(raw) + if err != nil { + return + } + return verifyDeleteContent(data, "") +} + +func (s *settingsObject) addContent(data []byte, isSnapshot bool) (err error) { + accountData := s.account.Account() + res, err := s.AddContent(context.Background(), objecttree.SignableChangeContent{ + Data: data, + Key: accountData.SignKey, + IsSnapshot: isSnapshot, + IsEncrypted: false, + }) + if err != nil { + return + } + if res.Mode == objecttree.Rebuild { + s.Rebuild(s) + } else { + s.Update(s) + } + return +} + +func VerifyDeleteChange(raw *treechangeproto.RawTreeChangeWithId, identity crypto.PubKey, peerId string) (err error) { + changeBuilder := objecttree.NewChangeBuilder(crypto.NewKeyStorage(), nil) + res, err := changeBuilder.Unmarshall(raw, true) + if err != nil { + return + } + if !res.Identity.Equals(identity) { + return fmt.Errorf("incorrect identity") + } + return verifyDeleteContent(res.Data, peerId) +} + +func verifyDeleteContent(data []byte, peerId string) (err error) { + content := &spacesyncproto.SettingsData{} + err = proto.Unmarshal(data, content) + if err != nil { + return + } + if len(content.GetContent()) != 1 || + content.GetContent()[0].GetSpaceDelete() == nil || + (peerId == "" && content.GetContent()[0].GetSpaceDelete().GetDeleterPeerId() == "") || + (peerId != "" && content.GetContent()[0].GetSpaceDelete().GetDeleterPeerId() != peerId) { + return fmt.Errorf("incorrect delete change payload") + } + return +} diff --git a/commonspace/settings/settings_test.go b/commonspace/settings/settingsobject_test.go similarity index 100% rename from commonspace/settings/settings_test.go rename to commonspace/settings/settingsobject_test.go diff --git a/commonspace/settings/settingsstate/settingsstate.go b/commonspace/settings/settingsstate/settingsstate.go index 0b62c8d1..a6c8b0b6 100644 --- a/commonspace/settings/settingsstate/settingsstate.go +++ b/commonspace/settings/settingsstate/settingsstate.go @@ -1,3 +1,4 @@ +//go:generate mockgen -destination mock_settingsstate/mock_settingsstate.go github.com/anyproto/any-sync/commonspace/settings/settingsstate ObjectDeletionState,StateBuilder,ChangeFactory package settingsstate import "github.com/anyproto/any-sync/commonspace/spacesyncproto" diff --git a/commonspace/space.go b/commonspace/space.go index 70bf6e0c..d8574acf 100644 --- a/commonspace/space.go +++ b/commonspace/space.go @@ -130,7 +130,7 @@ type space struct { headSync headsync.HeadSync syncStatus syncstatus.StatusUpdater storage spacestorage.SpaceStorage - treeManager *commonGetter + treeManager *objectManager account accountservice.Service aclList *syncacl.SyncAcl configuration nodeconf.NodeConf diff --git a/commonspace/spaceservice.go b/commonspace/spaceservice.go index 0e770dc1..3657d423 100644 --- a/commonspace/spaceservice.go +++ b/commonspace/spaceservice.go @@ -5,6 +5,7 @@ import ( "github.com/anyproto/any-sync/accountservice" "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/app/logger" + "github.com/anyproto/any-sync/commonspace/config" "github.com/anyproto/any-sync/commonspace/credentialprovider" "github.com/anyproto/any-sync/commonspace/headsync" "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" @@ -45,7 +46,7 @@ type SpaceService interface { } type spaceService struct { - config Config + config config.Config account accountservice.Service configurationService nodeconf.Service storageProvider spacestorage.SpaceStorageProvider @@ -54,10 +55,11 @@ type spaceService struct { treeManager treemanager.TreeManager pool pool.Pool metric metric.Metric + app *app.App } func (s *spaceService) Init(a *app.App) (err error) { - s.config = a.MustComponent("config").(ConfigGetter).GetSpace() + s.config = a.MustComponent("config").(config.ConfigGetter).GetSpace() s.account = a.MustComponent(accountservice.CName).(accountservice.Service) s.storageProvider = a.MustComponent(spacestorage.CName).(spacestorage.SpaceStorageProvider) s.configurationService = a.MustComponent(nodeconf.CName).(nodeconf.Service) @@ -149,7 +151,7 @@ func (s *spaceService) NewSpace(ctx context.Context, id string) (Space, error) { return nil, err } spaceIsDeleted.Swap(isDeleted) - getter := newCommonGetter(st.Id(), s.treeManager, spaceIsClosed) + getter := NewObjectManager(st.Id(), s.treeManager, spaceIsClosed) syncStatus := syncstatus.NewNoOpSyncStatus() // this will work only for clients, not the best solution, but... if !lastConfiguration.IsResponsible(st.Id()) { diff --git a/commonspace/spacestate/shareddata.go b/commonspace/spacestate/shareddata.go new file mode 100644 index 00000000..bf231cb7 --- /dev/null +++ b/commonspace/spacestate/shareddata.go @@ -0,0 +1,35 @@ +package spacestate + +import ( + "github.com/anyproto/any-sync/app" + "github.com/anyproto/any-sync/commonspace/object/acl/list" + "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" + "github.com/anyproto/any-sync/commonspace/spacestorage" + "sync/atomic" +) + +const CName = "common.commonspace.shareddata" + +type SpaceActions interface { + OnObjectDelete(id string) + OnSpaceDelete() +} + +type SpaceState struct { + SpaceId string + SpaceIsDeleted *atomic.Bool + SpaceIsClosed *atomic.Bool + TreesUsed *atomic.Int32 + AclList list.AclList + SpaceStorage spacestorage.SpaceStorage + TreeBuilderFunc objecttree.BuildObjectTreeFunc + Actions SpaceActions +} + +func (s *SpaceState) Init(a *app.App) (err error) { + return nil +} + +func (s *SpaceState) Name() (name string) { + return CName +} diff --git a/commonspace/spaceutils_test.go b/commonspace/spaceutils_test.go index 000d571c..1b345279 100644 --- a/commonspace/spaceutils_test.go +++ b/commonspace/spaceutils_test.go @@ -6,6 +6,7 @@ import ( accountService "github.com/anyproto/any-sync/accountservice" "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/app/ocache" + "github.com/anyproto/any-sync/commonspace/config" "github.com/anyproto/any-sync/commonspace/credentialprovider" "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" "github.com/anyproto/any-sync/commonspace/object/treemanager" @@ -205,8 +206,8 @@ func (m *mockConfig) Name() (name string) { return "config" } -func (m *mockConfig) GetSpace() Config { - return Config{ +func (m *mockConfig) GetSpace() config.Config { + return config.Config{ GCTTL: 60, SyncPeriod: 20, KeepTreeDataInMemory: true, diff --git a/commonspace/streamsender/streamsender.go b/commonspace/streamsender/streamsender.go new file mode 100644 index 00000000..9482a81a --- /dev/null +++ b/commonspace/streamsender/streamsender.go @@ -0,0 +1,14 @@ +package streamsender + +import ( + "github.com/anyproto/any-sync/app" + "github.com/anyproto/any-sync/commonspace/spacesyncproto" +) + +const CName = "common.commonspace.streamsender" + +type StreamSender interface { + app.ComponentRunnable + SendPeer(peerId string, msg *spacesyncproto.ObjectSyncMessage) (err error) + Broadcast(msg *spacesyncproto.ObjectSyncMessage) (err error) +} diff --git a/commonspace/syncstatus/noop.go b/commonspace/syncstatus/noop.go index 586b90d2..10ef80ac 100644 --- a/commonspace/syncstatus/noop.go +++ b/commonspace/syncstatus/noop.go @@ -1,9 +1,32 @@ package syncstatus +import ( + "context" + "github.com/anyproto/any-sync/app" +) + +func NewNoOpSyncStatus() StatusProvider { + return &noOpSyncStatus{} +} + type noOpSyncStatus struct{} -func NewNoOpSyncStatus() StatusUpdater { - return &noOpSyncStatus{} +func (n *noOpSyncStatus) Init(a *app.App) (err error) { + return nil +} + +func (n *noOpSyncStatus) Name() (name string) { + return CName +} + +func (n *noOpSyncStatus) Watch(treeId string) (err error) { + return nil +} + +func (n *noOpSyncStatus) Unwatch(treeId string) { +} + +func (n *noOpSyncStatus) SetUpdateReceiver(updater UpdateReceiver) { } func (n *noOpSyncStatus) HeadsChange(treeId string, heads []string) { @@ -22,9 +45,10 @@ func (n *noOpSyncStatus) StateCounter() uint64 { func (n *noOpSyncStatus) RemoveAllExcept(senderId string, differentRemoteIds []string, stateCounter uint64) { } -func (n *noOpSyncStatus) Run() { -} - -func (n *noOpSyncStatus) Close() error { +func (n *noOpSyncStatus) Run(ctx context.Context) error { + return nil +} + +func (n *noOpSyncStatus) Close(ctx context.Context) error { return nil } diff --git a/commonspace/syncstatus/syncstatus.go b/commonspace/syncstatus/syncstatus.go index 91191573..edc12175 100644 --- a/commonspace/syncstatus/syncstatus.go +++ b/commonspace/syncstatus/syncstatus.go @@ -3,6 +3,8 @@ package syncstatus import ( "context" "fmt" + "github.com/anyproto/any-sync/app" + "github.com/anyproto/any-sync/commonspace/spacestate" "sync" "time" @@ -20,7 +22,9 @@ const ( syncTimeout = time.Second ) -var log = logger.NewNamed("common.commonspace.syncstatus") +var log = logger.NewNamed(CName) + +const CName = "common.commonspace.syncstatus" type UpdateReceiver interface { UpdateTree(ctx context.Context, treeId string, status SyncStatus) (err error) @@ -34,9 +38,6 @@ type StatusUpdater interface { SetNodesOnline(senderId string, online bool) StateCounter() uint64 RemoveAllExcept(senderId string, differentRemoteIds []string, stateCounter uint64) - - Run() - Close() error } type StatusWatcher interface { @@ -46,6 +47,7 @@ type StatusWatcher interface { } type StatusProvider interface { + app.ComponentRunnable StatusUpdater StatusWatcher } @@ -89,35 +91,27 @@ type syncStatusProvider struct { updateTimeout time.Duration } -type SyncStatusDeps struct { - UpdateIntervalSecs int - UpdateTimeout time.Duration - Configuration nodeconf.NodeConf - Storage spacestorage.SpaceStorage -} - -func DefaultDeps(configuration nodeconf.NodeConf, store spacestorage.SpaceStorage) SyncStatusDeps { - return SyncStatusDeps{ - UpdateIntervalSecs: syncUpdateInterval, - UpdateTimeout: syncTimeout, - Configuration: configuration, - Storage: store, - } -} - -func NewSyncStatusProvider(spaceId string, deps SyncStatusDeps) StatusProvider { +func NewSyncStatusProvider() StatusProvider { return &syncStatusProvider{ - spaceId: spaceId, - treeHeads: map[string]treeHeadsEntry{}, - watchers: map[string]struct{}{}, - updateIntervalSecs: deps.UpdateIntervalSecs, - updateTimeout: deps.UpdateTimeout, - configuration: deps.Configuration, - storage: deps.Storage, - stateCounter: 0, + treeHeads: map[string]treeHeadsEntry{}, + watchers: map[string]struct{}{}, } } +func (s *syncStatusProvider) Init(a *app.App) (err error) { + sharedState := a.MustComponent(spacestate.CName).(*spacestate.SpaceState) + s.updateIntervalSecs = syncUpdateInterval + s.updateTimeout = syncTimeout + s.configuration = a.MustComponent(nodeconf.CName).(nodeconf.NodeConf) + s.storage = sharedState.SpaceStorage + s.spaceId = sharedState.SpaceId + return +} + +func (s *syncStatusProvider) Name() (name string) { + return CName +} + func (s *syncStatusProvider) SetUpdateReceiver(updater UpdateReceiver) { s.Lock() defer s.Unlock() @@ -125,13 +119,14 @@ func (s *syncStatusProvider) SetUpdateReceiver(updater UpdateReceiver) { s.updateReceiver = updater } -func (s *syncStatusProvider) Run() { +func (s *syncStatusProvider) Run(ctx context.Context) error { s.periodicSync = periodicsync.NewPeriodicSync( s.updateIntervalSecs, s.updateTimeout, s.update, log) s.periodicSync.Run() + return nil } func (s *syncStatusProvider) HeadsChange(treeId string, heads []string) { @@ -257,11 +252,6 @@ func (s *syncStatusProvider) Unwatch(treeId string) { } } -func (s *syncStatusProvider) Close() (err error) { - s.periodicSync.Close() - return -} - func (s *syncStatusProvider) StateCounter() uint64 { s.Lock() defer s.Unlock() @@ -292,6 +282,11 @@ func (s *syncStatusProvider) RemoveAllExcept(senderId string, differentRemoteIds } } +func (s *syncStatusProvider) Close(ctx context.Context) error { + s.periodicSync.Close() + return nil +} + func (s *syncStatusProvider) isSenderResponsible(senderId string) bool { return slices.Contains(s.configuration.NodeIds(s.spaceId), senderId) } From eeb87dd14484bb9c35a41164c59e09305f021528 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Thu, 1 Jun 2023 14:07:16 +0200 Subject: [PATCH 002/123] WIP further space refactoring --- commonspace/deletionstate/deletionstate.go | 2 +- .../deletionstate_test.go | 4 +- commonspace/headsync/diffsyncer.go | 10 +- commonspace/headsync/headsync.go | 27 +- commonspace/object/acl/syncacl/syncacl.go | 5 +- .../object/tree/synctree/utils_test.go | 4 +- commonspace/objectsync/objectsync.go | 14 +- .../objectsync/syncclient/syncclient.go | 2 +- commonspace/objecttreebuilder/treebuilder.go | 26 +- commonspace/requestsender/requestsender.go | 4 + commonspace/settings/settings.go | 67 ++- .../settings/settingsstate/deletionstate.go | 135 ------ .../settings/settingsstate/settingsstate.go | 2 +- commonspace/space.go | 434 +++--------------- commonspace/spaceservice.go | 89 ++-- commonspace/spacestate/shareddata.go | 6 - commonspace/streamsender/streamsender.go | 25 +- 17 files changed, 248 insertions(+), 608 deletions(-) rename commonspace/{settings/settingsstate => deletionstate}/deletionstate_test.go (96%) delete mode 100644 commonspace/settings/settingsstate/deletionstate.go diff --git a/commonspace/deletionstate/deletionstate.go b/commonspace/deletionstate/deletionstate.go index 96f062e3..64da5417 100644 --- a/commonspace/deletionstate/deletionstate.go +++ b/commonspace/deletionstate/deletionstate.go @@ -44,7 +44,7 @@ func (st *objectDeletionState) Name() (name string) { return CName } -func NewObjectDeletionState() ObjectDeletionState { +func New() ObjectDeletionState { return &objectDeletionState{ log: log, queued: map[string]struct{}{}, diff --git a/commonspace/settings/settingsstate/deletionstate_test.go b/commonspace/deletionstate/deletionstate_test.go similarity index 96% rename from commonspace/settings/settingsstate/deletionstate_test.go rename to commonspace/deletionstate/deletionstate_test.go index ca2ea679..d95bcd9b 100644 --- a/commonspace/settings/settingsstate/deletionstate_test.go +++ b/commonspace/deletionstate/deletionstate_test.go @@ -1,4 +1,4 @@ -package settingsstate +package deletionstate import ( "github.com/anyproto/any-sync/app/logger" @@ -19,7 +19,7 @@ type fixture struct { func newFixture(t *testing.T) *fixture { ctrl := gomock.NewController(t) spaceStorage := mock_spacestorage.NewMockSpaceStorage(ctrl) - delState := NewObjectDeletionState(logger.NewNamed("test"), spaceStorage).(*objectDeletionState) + delState := New(logger.NewNamed("test"), spaceStorage).(*objectDeletionState) return &fixture{ ctrl: ctrl, delState: delState, diff --git a/commonspace/headsync/diffsyncer.go b/commonspace/headsync/diffsyncer.go index 70238d01..1529bf6f 100644 --- a/commonspace/headsync/diffsyncer.go +++ b/commonspace/headsync/diffsyncer.go @@ -6,9 +6,9 @@ import ( "github.com/anyproto/any-sync/app/ldiff" "github.com/anyproto/any-sync/app/logger" "github.com/anyproto/any-sync/commonspace/credentialprovider" + "github.com/anyproto/any-sync/commonspace/deletionstate" "github.com/anyproto/any-sync/commonspace/object/treemanager" "github.com/anyproto/any-sync/commonspace/peermanager" - "github.com/anyproto/any-sync/commonspace/settings/settingsstate" "github.com/anyproto/any-sync/commonspace/spacestorage" "github.com/anyproto/any-sync/commonspace/spacesyncproto" "github.com/anyproto/any-sync/commonspace/syncstatus" @@ -22,7 +22,7 @@ type DiffSyncer interface { Sync(ctx context.Context) error RemoveObjects(ids []string) UpdateHeads(id string, heads []string) - Init(deletionState settingsstate.ObjectDeletionState) + Init() Close() error } @@ -37,6 +37,7 @@ func newDiffSyncer(hs *headSync) DiffSyncer { credentialProvider: hs.credentialProvider, log: log, syncStatus: hs.syncStatus, + deletionState: hs.deletionState, } } @@ -48,14 +49,13 @@ type diffSyncer struct { storage spacestorage.SpaceStorage clientFactory spacesyncproto.ClientFactory log logger.CtxLogger - deletionState settingsstate.ObjectDeletionState + deletionState deletionstate.ObjectDeletionState credentialProvider credentialprovider.CredentialProvider syncStatus syncstatus.StatusUpdater treeSyncer treemanager.TreeSyncer } -func (d *diffSyncer) Init(deletionState settingsstate.ObjectDeletionState) { - d.deletionState = deletionState +func (d *diffSyncer) Init() { d.deletionState.AddObserver(d.RemoveObjects) d.treeSyncer = d.treeManager.NewTreeSyncer(d.spaceId, d.treeManager) } diff --git a/commonspace/headsync/headsync.go b/commonspace/headsync/headsync.go index 048569bb..0d761fd5 100644 --- a/commonspace/headsync/headsync.go +++ b/commonspace/headsync/headsync.go @@ -7,10 +7,9 @@ import ( "github.com/anyproto/any-sync/app/logger" config2 "github.com/anyproto/any-sync/commonspace/config" "github.com/anyproto/any-sync/commonspace/credentialprovider" - "github.com/anyproto/any-sync/commonspace/headsync" + "github.com/anyproto/any-sync/commonspace/deletionstate" "github.com/anyproto/any-sync/commonspace/object/treemanager" "github.com/anyproto/any-sync/commonspace/peermanager" - "github.com/anyproto/any-sync/commonspace/settings/settingsstate" "github.com/anyproto/any-sync/commonspace/spacestate" "github.com/anyproto/any-sync/commonspace/spacestorage" "github.com/anyproto/any-sync/commonspace/spacesyncproto" @@ -18,6 +17,7 @@ import ( "github.com/anyproto/any-sync/net/peer" "github.com/anyproto/any-sync/nodeconf" "github.com/anyproto/any-sync/util/periodicsync" + "github.com/anyproto/any-sync/util/slice" "go.uber.org/zap" "golang.org/x/exp/slices" "sync/atomic" @@ -34,11 +34,13 @@ type TreeHeads struct { } type HeadSync interface { + app.ComponentRunnable + ExternalIds() []string + DebugAllHeads() (res []TreeHeads) + AllIds() []string UpdateHeads(id string, heads []string) HandleRangeRequest(ctx context.Context, req *spacesyncproto.HeadSyncRequest) (resp *spacesyncproto.HeadSyncResponse, err error) RemoveObjects(ids []string) - AllIds() []string - DebugAllHeads() (res []TreeHeads) } type headSync struct { @@ -50,16 +52,16 @@ type headSync struct { storage spacestorage.SpaceStorage diff ldiff.Diff log logger.CtxLogger - syncer headsync.DiffSyncer + syncer DiffSyncer configuration nodeconf.NodeConf peerManager peermanager.PeerManager treeManager treemanager.TreeManager credentialProvider credentialprovider.CredentialProvider syncStatus syncstatus.StatusProvider - deletionState settingsstate.ObjectDeletionState + deletionState deletionstate.ObjectDeletionState } -func New() *headSync { +func New() HeadSync { return &headSync{} } @@ -77,7 +79,7 @@ func (h *headSync) Init(a *app.App) (err error) { h.credentialProvider = a.MustComponent(credentialprovider.CName).(credentialprovider.CredentialProvider) h.syncStatus = a.MustComponent(syncstatus.CName).(syncstatus.StatusProvider) h.treeManager = a.MustComponent(treemanager.CName).(treemanager.TreeManager) - h.deletionState = a.MustComponent("deletionstate").(settingsstate.ObjectDeletionState) + h.deletionState = a.MustComponent(deletionstate.CName).(deletionstate.ObjectDeletionState) h.syncer = newDiffSyncer(h) sync := func(ctx context.Context) (err error) { // for clients cancelling the sync process @@ -87,6 +89,8 @@ func (h *headSync) Init(a *app.App) (err error) { return h.syncer.Sync(ctx) } h.periodicSync = periodicsync.NewPeriodicSync(h.syncPeriod, time.Minute, sync, h.log) + // TODO: move to run? + h.syncer.Init() return nil } @@ -126,6 +130,13 @@ func (h *headSync) AllIds() []string { return h.diff.Ids() } +func (h *headSync) ExternalIds() []string { + settingsId := h.storage.SpaceSettingsId() + return slice.DiscardFromSlice(h.AllIds(), func(id string) bool { + return id == settingsId + }) +} + func (h *headSync) DebugAllHeads() (res []TreeHeads) { els := h.diff.Elements() for _, el := range els { diff --git a/commonspace/object/acl/syncacl/syncacl.go b/commonspace/object/acl/syncacl/syncacl.go index dd1e647e..cc728e4a 100644 --- a/commonspace/object/acl/syncacl/syncacl.go +++ b/commonspace/object/acl/syncacl/syncacl.go @@ -2,20 +2,17 @@ package syncacl import ( "github.com/anyproto/any-sync/commonspace/object/acl/list" - "github.com/anyproto/any-sync/commonspace/objectsync" "github.com/anyproto/any-sync/commonspace/objectsync/synchandler" ) type SyncAcl struct { list.AclList synchandler.SyncHandler - messagePool objectsync.MessagePool } -func NewSyncAcl(aclList list.AclList, messagePool objectsync.MessagePool) *SyncAcl { +func NewSyncAcl(aclList list.AclList) *SyncAcl { return &SyncAcl{ AclList: aclList, SyncHandler: nil, - messagePool: messagePool, } } diff --git a/commonspace/object/tree/synctree/utils_test.go b/commonspace/object/tree/synctree/utils_test.go index 8f57a9f2..a6d553a3 100644 --- a/commonspace/object/tree/synctree/utils_test.go +++ b/commonspace/object/tree/synctree/utils_test.go @@ -96,7 +96,7 @@ type testSyncHandler struct { // createSyncHandler creates a sync handler when a tree is already created func createSyncHandler(peerId, spaceId string, objTree objecttree.ObjectTree, log *messageLog) *testSyncHandler { factory := syncclient.NewRequestFactory() - syncClient := syncclient.NewSyncClient(spaceId, newTestMessagePool(peerId, log), factory) + syncClient := syncclient.New(spaceId, newTestMessagePool(peerId, log), factory) netTree := &broadcastTree{ ObjectTree: objTree, SyncClient: syncClient, @@ -108,7 +108,7 @@ func createSyncHandler(peerId, spaceId string, objTree objecttree.ObjectTree, lo // createEmptySyncHandler creates a sync handler when the tree will be provided later (this emulates the situation when we have no tree) func createEmptySyncHandler(peerId, spaceId string, builder objecttree.BuildObjectTreeFunc, aclList list.AclList, log *messageLog) *testSyncHandler { factory := syncclient.NewRequestFactory() - syncClient := syncclient.NewSyncClient(spaceId, newTestMessagePool(peerId, log), factory) + syncClient := syncclient.New(spaceId, newTestMessagePool(peerId, log), factory) batcher := mb.New[protocolMsg](0) return &testSyncHandler{ diff --git a/commonspace/objectsync/objectsync.go b/commonspace/objectsync/objectsync.go index 64ab66f6..0a836cff 100644 --- a/commonspace/objectsync/objectsync.go +++ b/commonspace/objectsync/objectsync.go @@ -29,6 +29,9 @@ const CName = "common.commonspace.objectsync" var log = logger.NewNamed(CName) type ObjectSync interface { + LastUsage() time.Time + HandleMessage(ctx context.Context, hm HandleMessage) (err error) + CloseThread(id string) (err error) app.ComponentRunnable } @@ -88,10 +91,15 @@ func (s *objectSync) Close(ctx context.Context) (err error) { return s.handleQueue.Close() } -func NewObjectSync() ObjectSync { +func New() ObjectSync { return &objectSync{} } +func (s *objectSync) LastUsage() time.Time { + // TODO: add time + return time.Time{} +} + func (s *objectSync) HandleMessage(ctx context.Context, hm HandleMessage) (err error) { threadId := hm.Message.ObjectId hm.ReceiveTime = time.Now() @@ -169,3 +177,7 @@ func (s *objectSync) handleMessage(ctx context.Context, senderId string, msg *sp } return } + +func (s *objectSync) CloseThread(id string) (err error) { + return s.handleQueue.CloseThread(id) +} diff --git a/commonspace/objectsync/syncclient/syncclient.go b/commonspace/objectsync/syncclient/syncclient.go index 6041a2d0..99360eab 100644 --- a/commonspace/objectsync/syncclient/syncclient.go +++ b/commonspace/objectsync/syncclient/syncclient.go @@ -32,7 +32,7 @@ type syncClient struct { streamSender streamsender.StreamSender } -func NewSyncClient() SyncClient { +func New() SyncClient { return &syncClient{} } diff --git a/commonspace/objecttreebuilder/treebuilder.go b/commonspace/objecttreebuilder/treebuilder.go index f8bf346b..cf15c49c 100644 --- a/commonspace/objecttreebuilder/treebuilder.go +++ b/commonspace/objecttreebuilder/treebuilder.go @@ -12,6 +12,7 @@ import ( "github.com/anyproto/any-sync/commonspace/object/tree/synctree/updatelistener" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" "github.com/anyproto/any-sync/commonspace/object/tree/treestorage" + "github.com/anyproto/any-sync/commonspace/objectsync" "github.com/anyproto/any-sync/commonspace/objectsync/syncclient" "github.com/anyproto/any-sync/commonspace/peermanager" "github.com/anyproto/any-sync/commonspace/spacestate" @@ -40,12 +41,19 @@ type HistoryTreeOpts struct { } type TreeBuilder interface { - app.Component BuildTree(ctx context.Context, id string, opts BuildTreeOpts) (t objecttree.ObjectTree, err error) BuildHistoryTree(ctx context.Context, id string, opts HistoryTreeOpts) (t objecttree.HistoryTree, err error) CreateTree(ctx context.Context, payload objecttree.ObjectTreeCreatePayload) (res treestorage.TreeStorageCreatePayload, err error) PutTree(ctx context.Context, payload treestorage.TreeStorageCreatePayload, listener updatelistener.UpdateListener) (t objecttree.ObjectTree, err error) - SetOnCloseHandler(handler func(id string)) +} + +type TreeBuilderComponent interface { + app.Component + TreeBuilder +} + +func New() TreeBuilderComponent { + return &treeBuilder{} } type treeBuilder struct { @@ -55,6 +63,7 @@ type treeBuilder struct { peerManager peermanager.PeerManager spaceStorage spacestorage.SpaceStorage syncStatus syncstatus.StatusUpdater + objectSync objectsync.ObjectSync log logger.CtxLogger builder objecttree.BuildObjectTreeFunc @@ -62,7 +71,6 @@ type treeBuilder struct { aclList list.AclList treesUsed *atomic.Int32 isClosed *atomic.Bool - onClose func(id string) } func (t *treeBuilder) Init(a *app.App) (err error) { @@ -78,8 +86,8 @@ func (t *treeBuilder) Init(a *app.App) (err error) { t.spaceStorage = state.SpaceStorage t.syncStatus = a.MustComponent(syncstatus.CName).(syncstatus.StatusUpdater) t.peerManager = a.MustComponent(peermanager.CName).(peermanager.PeerManager) + t.objectSync = a.MustComponent(objectsync.CName).(objectsync.ObjectSync) t.log = log.With(zap.String("spaceId", t.spaceId)) - t.onClose = state.Actions.OnObjectDelete return nil } @@ -87,10 +95,6 @@ func (t *treeBuilder) Name() (name string) { return CName } -func (t *treeBuilder) SetOnCloseHandler(handler func(id string)) { - t.onClose = handler -} - func (t *treeBuilder) BuildTree(ctx context.Context, id string, opts BuildTreeOpts) (ot objecttree.ObjectTree, err error) { if t.isClosed.Load() { // TODO: change to real error @@ -189,3 +193,9 @@ func (t *treeBuilder) PutTree(ctx context.Context, payload treestorage.TreeStora t.log.Debug("incrementing counter", zap.String("id", payload.RootRawChange.Id), zap.Int32("trees", t.treesUsed.Load())) return } + +func (t *treeBuilder) onClose(id string) { + t.treesUsed.Add(-1) + log.Debug("decrementing counter", zap.String("id", id), zap.Int32("trees", t.treesUsed.Load()), zap.String("spaceId", t.spaceId)) + _ = t.objectSync.CloseThread(id) +} diff --git a/commonspace/requestsender/requestsender.go b/commonspace/requestsender/requestsender.go index 1ba166fb..d7143b4a 100644 --- a/commonspace/requestsender/requestsender.go +++ b/commonspace/requestsender/requestsender.go @@ -17,6 +17,10 @@ type RequestSender interface { QueueRequest(peerId string, msg *spacesyncproto.ObjectSyncMessage) (err error) } +func New() RequestSender { + return &requestSender{} +} + type requestSender struct { } diff --git a/commonspace/settings/settings.go b/commonspace/settings/settings.go index 4e2177ae..95252388 100644 --- a/commonspace/settings/settings.go +++ b/commonspace/settings/settings.go @@ -9,52 +9,53 @@ import ( "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" "github.com/anyproto/any-sync/commonspace/object/tree/synctree" "github.com/anyproto/any-sync/commonspace/object/tree/synctree/updatelistener" + "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" "github.com/anyproto/any-sync/commonspace/object/treemanager" "github.com/anyproto/any-sync/commonspace/objecttreebuilder" "github.com/anyproto/any-sync/commonspace/spacestate" "github.com/anyproto/any-sync/commonspace/spacestorage" "github.com/anyproto/any-sync/nodeconf" "go.uber.org/zap" + "sync/atomic" ) const CName = "common.commonspace.settings" type Settings interface { + DeleteTree(ctx context.Context, id string) (err error) + SpaceDeleteRawChange(ctx context.Context) (raw *treechangeproto.RawTreeChangeWithId, err error) + DeleteSpace(ctx context.Context, deleteChange *treechangeproto.RawTreeChangeWithId) (err error) app.ComponentRunnable } +func New() Settings { + return &settings{} +} + type settings struct { - account accountservice.Service - treeManager treemanager.TreeManager - storage spacestorage.SpaceStorage - configuration nodeconf.NodeConf - deletionState deletionstate.ObjectDeletionState - headsync headsync.HeadSync - spaceActions spacestate.SpaceActions - treeBuilder objecttreebuilder.TreeBuilder + account accountservice.Service + treeManager treemanager.TreeManager + storage spacestorage.SpaceStorage + configuration nodeconf.NodeConf + deletionState deletionstate.ObjectDeletionState + headsync headsync.HeadSync + treeBuilder objecttreebuilder.TreeBuilderComponent + spaceIsDeleted *atomic.Bool settingsObject SettingsObject } -func (s *settings) Run(ctx context.Context) (err error) { - return s.settingsObject.Init(ctx) -} - -func (s *settings) Close(ctx context.Context) (err error) { - return s.settingsObject.Close() -} - func (s *settings) Init(a *app.App) (err error) { s.account = a.MustComponent(accountservice.CName).(accountservice.Service) s.treeManager = a.MustComponent(treemanager.CName).(treemanager.TreeManager) s.headsync = a.MustComponent(headsync.CName).(headsync.HeadSync) s.configuration = a.MustComponent(nodeconf.CName).(nodeconf.NodeConf) s.deletionState = a.MustComponent(deletionstate.CName).(deletionstate.ObjectDeletionState) - s.treeBuilder = a.MustComponent(objecttreebuilder.CName).(objecttreebuilder.TreeBuilder) + s.treeBuilder = a.MustComponent(objecttreebuilder.CName).(objecttreebuilder.TreeBuilderComponent) sharedState := a.MustComponent(spacestate.CName).(*spacestate.SpaceState) - s.spaceActions = sharedState.Actions s.storage = sharedState.SpaceStorage + s.spaceIsDeleted = sharedState.SpaceIsDeleted deps := Deps{ BuildFunc: func(ctx context.Context, id string, listener updatelistener.UpdateListener) (t synctree.SyncTree, err error) { @@ -77,7 +78,7 @@ func (s *settings) Init(a *app.App) (err error) { Configuration: s.configuration, DeletionState: s.deletionState, Provider: s.headsync, - OnSpaceDelete: s.spaceActions.OnSpaceDelete, + OnSpaceDelete: s.onSpaceDelete, } s.settingsObject = NewSettingsObject(deps, sharedState.SpaceId) return nil @@ -86,3 +87,31 @@ func (s *settings) Init(a *app.App) (err error) { func (s *settings) Name() (name string) { return CName } + +func (s *settings) Run(ctx context.Context) (err error) { + return s.settingsObject.Init(ctx) +} + +func (s *settings) Close(ctx context.Context) (err error) { + return s.settingsObject.Close() +} + +func (s *settings) DeleteTree(ctx context.Context, id string) (err error) { + return s.settingsObject.DeleteObject(id) +} + +func (s *settings) SpaceDeleteRawChange(ctx context.Context) (raw *treechangeproto.RawTreeChangeWithId, err error) { + return s.settingsObject.SpaceDeleteRawChange() +} + +func (s *settings) DeleteSpace(ctx context.Context, deleteChange *treechangeproto.RawTreeChangeWithId) (err error) { + return s.settingsObject.DeleteSpace(ctx, deleteChange) +} + +func (s *settings) onSpaceDelete() { + err := s.storage.SetSpaceDeleted() + if err != nil { + log.Warn("failed to set space deleted") + } + s.spaceIsDeleted.Swap(true) +} diff --git a/commonspace/settings/settingsstate/deletionstate.go b/commonspace/settings/settingsstate/deletionstate.go deleted file mode 100644 index f36f4fd0..00000000 --- a/commonspace/settings/settingsstate/deletionstate.go +++ /dev/null @@ -1,135 +0,0 @@ -//go:generate mockgen -destination mock_settingsstate/mock_settingsstate.go github.com/anyproto/any-sync/commonspace/settings/settingsstate ObjectDeletionState,StateBuilder,ChangeFactory -package settingsstate - -import ( - "github.com/anyproto/any-sync/app/logger" - "github.com/anyproto/any-sync/commonspace/spacestorage" - "go.uber.org/zap" - "sync" -) - -type StateUpdateObserver func(ids []string) - -type ObjectDeletionState interface { - AddObserver(observer StateUpdateObserver) - Add(ids map[string]struct{}) - GetQueued() (ids []string) - Delete(id string) (err error) - Exists(id string) bool - Filter(ids []string) (filtered []string) -} - -type objectDeletionState struct { - sync.RWMutex - log logger.CtxLogger - queued map[string]struct{} - deleted map[string]struct{} - stateUpdateObservers []StateUpdateObserver - storage spacestorage.SpaceStorage -} - -func NewObjectDeletionState(log logger.CtxLogger, storage spacestorage.SpaceStorage) ObjectDeletionState { - return &objectDeletionState{ - log: log, - queued: map[string]struct{}{}, - deleted: map[string]struct{}{}, - storage: storage, - } -} - -func (st *objectDeletionState) AddObserver(observer StateUpdateObserver) { - st.Lock() - defer st.Unlock() - st.stateUpdateObservers = append(st.stateUpdateObservers, observer) -} - -func (st *objectDeletionState) Add(ids map[string]struct{}) { - var added []string - st.Lock() - defer func() { - st.Unlock() - for _, ob := range st.stateUpdateObservers { - ob(added) - } - }() - - for id := range ids { - if _, exists := st.deleted[id]; exists { - continue - } - if _, exists := st.queued[id]; exists { - continue - } - - var status string - status, err := st.storage.TreeDeletedStatus(id) - if err != nil { - st.log.Warn("failed to get deleted status", zap.String("treeId", id), zap.Error(err)) - continue - } - - switch status { - case spacestorage.TreeDeletedStatusQueued: - st.queued[id] = struct{}{} - case spacestorage.TreeDeletedStatusDeleted: - st.deleted[id] = struct{}{} - default: - err := st.storage.SetTreeDeletedStatus(id, spacestorage.TreeDeletedStatusQueued) - if err != nil { - st.log.Warn("failed to set deleted status", zap.String("treeId", id), zap.Error(err)) - continue - } - st.queued[id] = struct{}{} - } - added = append(added, id) - } -} - -func (st *objectDeletionState) GetQueued() (ids []string) { - st.RLock() - defer st.RUnlock() - ids = make([]string, 0, len(st.queued)) - for id := range st.queued { - ids = append(ids, id) - } - return -} - -func (st *objectDeletionState) Delete(id string) (err error) { - st.Lock() - defer st.Unlock() - delete(st.queued, id) - st.deleted[id] = struct{}{} - err = st.storage.SetTreeDeletedStatus(id, spacestorage.TreeDeletedStatusDeleted) - if err != nil { - return - } - return -} - -func (st *objectDeletionState) Exists(id string) bool { - st.RLock() - defer st.RUnlock() - return st.exists(id) -} - -func (st *objectDeletionState) Filter(ids []string) (filtered []string) { - st.RLock() - defer st.RUnlock() - for _, id := range ids { - if !st.exists(id) { - filtered = append(filtered, id) - } - } - return -} - -func (st *objectDeletionState) exists(id string) bool { - if _, exists := st.deleted[id]; exists { - return true - } - if _, exists := st.queued[id]; exists { - return true - } - return false -} diff --git a/commonspace/settings/settingsstate/settingsstate.go b/commonspace/settings/settingsstate/settingsstate.go index a6c8b0b6..20619cb2 100644 --- a/commonspace/settings/settingsstate/settingsstate.go +++ b/commonspace/settings/settingsstate/settingsstate.go @@ -1,4 +1,4 @@ -//go:generate mockgen -destination mock_settingsstate/mock_settingsstate.go github.com/anyproto/any-sync/commonspace/settings/settingsstate ObjectDeletionState,StateBuilder,ChangeFactory +//go:generate mockgen -destination mock_settingsstate/mock_settingsstate.go github.com/anyproto/any-sync/commonspace/settings/settingsstate StateBuilder,ChangeFactory package settingsstate import "github.com/anyproto/any-sync/commonspace/spacesyncproto" diff --git a/commonspace/space.go b/commonspace/space.go index d8574acf..a5732e5b 100644 --- a/commonspace/space.go +++ b/commonspace/space.go @@ -3,36 +3,21 @@ package commonspace import ( "context" "errors" - "github.com/anyproto/any-sync/accountservice" - "github.com/anyproto/any-sync/app/logger" + "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/commonspace/headsync" - "github.com/anyproto/any-sync/commonspace/object/acl/list" - "github.com/anyproto/any-sync/commonspace/object/acl/syncacl" - "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" - "github.com/anyproto/any-sync/commonspace/object/tree/synctree" - "github.com/anyproto/any-sync/commonspace/object/tree/synctree/updatelistener" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" - "github.com/anyproto/any-sync/commonspace/object/tree/treestorage" "github.com/anyproto/any-sync/commonspace/objectsync" - "github.com/anyproto/any-sync/commonspace/peermanager" + "github.com/anyproto/any-sync/commonspace/objecttreebuilder" "github.com/anyproto/any-sync/commonspace/settings" - "github.com/anyproto/any-sync/commonspace/settings/settingsstate" + "github.com/anyproto/any-sync/commonspace/spacestate" "github.com/anyproto/any-sync/commonspace/spacestorage" "github.com/anyproto/any-sync/commonspace/spacesyncproto" "github.com/anyproto/any-sync/commonspace/syncstatus" - "github.com/anyproto/any-sync/metric" - "github.com/anyproto/any-sync/net/peer" - "github.com/anyproto/any-sync/nodeconf" "github.com/anyproto/any-sync/util/crypto" - "github.com/anyproto/any-sync/util/multiqueue" - "github.com/anyproto/any-sync/util/slice" - "github.com/cheggaaa/mb/v3" - "github.com/zeebo/errs" "go.uber.org/zap" "strconv" "strings" "sync" - "sync/atomic" "time" ) @@ -55,25 +40,6 @@ type SpaceCreatePayload struct { MasterKey crypto.PrivKey } -type HandleMessage struct { - Id uint64 - ReceiveTime time.Time - StartHandlingTime time.Time - Deadline time.Time - SenderId string - Message *spacesyncproto.ObjectSyncMessage - PeerCtx context.Context -} - -func (m HandleMessage) LogFields(fields ...zap.Field) []zap.Field { - return append(fields, - metric.SpaceId(m.Message.SpaceId), - metric.ObjectId(m.Message.ObjectId), - metric.QueueDur(m.StartHandlingTime.Sub(m.ReceiveTime)), - metric.TotalDur(time.Since(m.ReceiveTime)), - ) -} - type SpaceDerivePayload struct { SigningKey crypto.PrivKey MasterKey crypto.PrivKey @@ -97,145 +63,72 @@ type Space interface { Id() string Init(ctx context.Context) error - StoredIds() []string - DebugAllHeads() []headsync.TreeHeads - Description() (SpaceDescription, error) - - CreateTree(ctx context.Context, payload objecttree.ObjectTreeCreatePayload) (res treestorage.TreeStorageCreatePayload, err error) - PutTree(ctx context.Context, payload treestorage.TreeStorageCreatePayload, listener updatelistener.UpdateListener) (t objecttree.ObjectTree, err error) - BuildTree(ctx context.Context, id string, opts BuildTreeOpts) (t objecttree.ObjectTree, err error) - DeleteTree(ctx context.Context, id string) (err error) - BuildHistoryTree(ctx context.Context, id string, opts HistoryTreeOpts) (t objecttree.HistoryTree, err error) - - SpaceDeleteRawChange(ctx context.Context) (raw *treechangeproto.RawTreeChangeWithId, err error) - DeleteSpace(ctx context.Context, deleteChange *treechangeproto.RawTreeChangeWithId) (err error) - - HeadSync() headsync.HeadSync - ObjectSync() objectsync.ObjectSync + TreeBuilder() objecttreebuilder.TreeBuilder SyncStatus() syncstatus.StatusUpdater Storage() spacestorage.SpaceStorage - HandleMessage(ctx context.Context, msg HandleMessage) (err error) + DeleteTree(ctx context.Context, id string) (err error) + SpaceDeleteRawChange(ctx context.Context) (raw *treechangeproto.RawTreeChangeWithId, err error) + DeleteSpace(ctx context.Context, deleteChange *treechangeproto.RawTreeChangeWithId) (err error) + + HandleMessage(ctx context.Context, msg objectsync.HandleMessage) (err error) TryClose(objectTTL time.Duration) (close bool, err error) Close() error } type space struct { - id string mu sync.RWMutex header *spacesyncproto.RawSpaceHeaderWithId - objectSync objectsync.ObjectSync - headSync headsync.HeadSync - syncStatus syncstatus.StatusUpdater - storage spacestorage.SpaceStorage - treeManager *objectManager - account accountservice.Service - aclList *syncacl.SyncAcl - configuration nodeconf.NodeConf - settingsObject settings.SettingsObject - peerManager peermanager.PeerManager - treeBuilder objecttree.BuildObjectTreeFunc - metric metric.Metric + state *spacestate.SpaceState + app *app.App - handleQueue multiqueue.MultiQueue[HandleMessage] + treeBuilder objecttreebuilder.TreeBuilderComponent + headSync headsync.HeadSync + objectSync objectsync.ObjectSync + syncStatus syncstatus.StatusProvider + settings settings.Settings +} - isClosed *atomic.Bool - isDeleted *atomic.Bool - treesUsed *atomic.Int32 +func (s *space) DeleteTree(ctx context.Context, id string) (err error) { + return s.settings.DeleteTree(ctx, id) +} + +func (s *space) SpaceDeleteRawChange(ctx context.Context) (raw *treechangeproto.RawTreeChangeWithId, err error) { + return s.settings.SpaceDeleteRawChange(ctx) +} + +func (s *space) DeleteSpace(ctx context.Context, deleteChange *treechangeproto.RawTreeChangeWithId) (err error) { + return s.settings.DeleteSpace(ctx, deleteChange) +} + +func (s *space) HandleMessage(ctx context.Context, msg objectsync.HandleMessage) (err error) { + return s.objectSync.HandleMessage(ctx, msg) +} + +func (s *space) TreeBuilder() objecttreebuilder.TreeBuilder { + return s.treeBuilder } func (s *space) Id() string { - return s.id -} - -func (s *space) Description() (desc SpaceDescription, err error) { - root := s.aclList.Root() - settingsStorage, err := s.storage.TreeStorage(s.storage.SpaceSettingsId()) - if err != nil { - return - } - settingsRoot, err := settingsStorage.Root() - if err != nil { - return - } - - desc = SpaceDescription{ - SpaceHeader: s.header, - AclId: root.Id, - AclPayload: root.Payload, - SpaceSettingsId: settingsRoot.Id, - SpaceSettingsPayload: settingsRoot.RawChange, - } - return + return s.state.SpaceId } func (s *space) Init(ctx context.Context) (err error) { - log.With(zap.String("spaceId", s.id)).Debug("initializing space") - s.storage = newCommonStorage(s.storage) - - header, err := s.storage.SpaceHeader() + err = s.app.Start(ctx) if err != nil { return } - s.header = header - 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.objectSync.SyncClient().MessagePool()) - s.treeManager.AddObject(s.aclList) - - deletionState := settingsstate.NewObjectDeletionState(log, s.storage) - deps := settings.Deps{ - BuildFunc: func(ctx context.Context, id string, listener updatelistener.UpdateListener) (t synctree.SyncTree, err error) { - res, err := s.BuildTree(ctx, id, BuildTreeOpts{ - Listener: listener, - WaitTreeRemoteSync: false, - // space settings document should not have empty data - treeBuilder: objecttree.BuildObjectTree, - }) - log.Debug("building settings tree", zap.String("id", id), zap.String("spaceId", s.id)) - if err != nil { - return - } - t = res.(synctree.SyncTree) - return - }, - Account: s.account, - TreeManager: s.treeManager, - Store: s.storage, - DeletionState: deletionState, - Provider: s.headSync, - Configuration: s.configuration, - OnSpaceDelete: s.onSpaceDelete, - } - s.settingsObject = settings.NewSettingsObject(deps, s.id) - s.headSync.Init(initialIds, deletionState) - err = s.settingsObject.Init(ctx) - if err != nil { - return - } - s.treeManager.AddObject(s.settingsObject) - s.syncStatus.Run() - s.handleQueue = multiqueue.New[HandleMessage](s.handleMessage, 100) + s.treeBuilder = s.app.MustComponent(objecttreebuilder.CName).(objecttreebuilder.TreeBuilderComponent) + s.headSync = s.app.MustComponent(headsync.CName).(headsync.HeadSync) + s.syncStatus = s.app.MustComponent(syncstatus.CName).(syncstatus.StatusProvider) + s.settings = s.app.MustComponent(settings.CName).(settings.Settings) + s.objectSync = s.app.MustComponent(objectsync.CName).(objectsync.ObjectSync) return nil } -func (s *space) ObjectSync() objectsync.ObjectSync { - return s.objectSync -} - -func (s *space) HeadSync() headsync.HeadSync { +func (s *space) HeadSync() headsync.HeadSyncExternal { return s.headSync } @@ -244,249 +137,28 @@ func (s *space) SyncStatus() syncstatus.StatusUpdater { } func (s *space) Storage() spacestorage.SpaceStorage { - return s.storage -} - -func (s *space) StoredIds() []string { - return slice.DiscardFromSlice(s.headSync.AllIds(), func(id string) bool { - return id == s.settingsObject.Id() - }) -} - -func (s *space) DebugAllHeads() []headsync.TreeHeads { - return s.headSync.DebugAllHeads() -} - -func (s *space) CreateTree(ctx context.Context, payload objecttree.ObjectTreeCreatePayload) (res treestorage.TreeStorageCreatePayload, err error) { - if s.isClosed.Load() { - err = ErrSpaceClosed - return - } - root, err := objecttree.CreateObjectTreeRoot(payload, s.aclList) - if err != nil { - return - } - - res = treestorage.TreeStorageCreatePayload{ - RootRawChange: root, - Changes: []*treechangeproto.RawTreeChangeWithId{root}, - Heads: []string{root.Id}, - } - return -} - -func (s *space) PutTree(ctx context.Context, payload treestorage.TreeStorageCreatePayload, listener updatelistener.UpdateListener) (t objecttree.ObjectTree, err error) { - if s.isClosed.Load() { - err = ErrSpaceClosed - return - } - deps := synctree.BuildDeps{ - SpaceId: s.id, - SyncClient: s.objectSync.SyncClient(), - Configuration: s.configuration, - HeadNotifiable: s.headSync, - Listener: listener, - AclList: s.aclList, - SpaceStorage: s.storage, - OnClose: s.onObjectClose, - SyncStatus: s.syncStatus, - PeerGetter: s.peerManager, - BuildObjectTree: s.treeBuilder, - } - t, err = synctree.PutSyncTree(ctx, payload, deps) - if err != nil { - return - } - s.treesUsed.Add(1) - log.Debug("incrementing counter", zap.String("id", payload.RootRawChange.Id), zap.Int32("trees", s.treesUsed.Load()), zap.String("spaceId", s.id)) - return -} - -type BuildTreeOpts struct { - Listener updatelistener.UpdateListener - WaitTreeRemoteSync bool - treeBuilder objecttree.BuildObjectTreeFunc -} - -type HistoryTreeOpts struct { - BeforeId string - Include bool - BuildFullTree bool -} - -func (s *space) BuildTree(ctx context.Context, id string, opts BuildTreeOpts) (t objecttree.ObjectTree, err error) { - if s.isClosed.Load() { - err = ErrSpaceClosed - return - } - treeBuilder := opts.treeBuilder - if treeBuilder == nil { - treeBuilder = s.treeBuilder - } - deps := synctree.BuildDeps{ - SpaceId: s.id, - SyncClient: s.objectSync.SyncClient(), - Configuration: s.configuration, - HeadNotifiable: s.headSync, - Listener: opts.Listener, - AclList: s.aclList, - SpaceStorage: s.storage, - OnClose: s.onObjectClose, - SyncStatus: s.syncStatus, - WaitTreeRemoteSync: opts.WaitTreeRemoteSync, - PeerGetter: s.peerManager, - BuildObjectTree: treeBuilder, - } - s.treesUsed.Add(1) - log.Debug("incrementing counter", zap.String("id", id), zap.Int32("trees", s.treesUsed.Load()), zap.String("spaceId", s.id)) - if t, err = synctree.BuildSyncTreeOrGetRemote(ctx, id, deps); err != nil { - s.treesUsed.Add(-1) - log.Debug("decrementing counter, load failed", zap.String("id", id), zap.Int32("trees", s.treesUsed.Load()), zap.String("spaceId", s.id), zap.Error(err)) - return nil, err - } - return -} - -func (s *space) BuildHistoryTree(ctx context.Context, id string, opts HistoryTreeOpts) (t objecttree.HistoryTree, err error) { - if s.isClosed.Load() { - err = ErrSpaceClosed - return - } - - params := objecttree.HistoryTreeParams{ - AclList: s.aclList, - BeforeId: opts.BeforeId, - IncludeBeforeId: opts.Include, - BuildFullTree: opts.BuildFullTree, - } - params.TreeStorage, err = s.storage.TreeStorage(id) - if err != nil { - return - } - return objecttree.BuildHistoryTree(params) -} - -func (s *space) DeleteTree(ctx context.Context, id string) (err error) { - return s.settingsObject.DeleteObject(id) -} - -func (s *space) SpaceDeleteRawChange(ctx context.Context) (raw *treechangeproto.RawTreeChangeWithId, err error) { - return s.settingsObject.SpaceDeleteRawChange() -} - -func (s *space) DeleteSpace(ctx context.Context, deleteChange *treechangeproto.RawTreeChangeWithId) (err error) { - return s.settingsObject.DeleteSpace(ctx, deleteChange) -} - -func (s *space) HandleMessage(ctx context.Context, hm HandleMessage) (err error) { - threadId := hm.Message.ObjectId - hm.ReceiveTime = time.Now() - if hm.Message.ReplyId != "" { - threadId += hm.Message.ReplyId - defer func() { - _ = s.handleQueue.CloseThread(threadId) - }() - } - if hm.PeerCtx == nil { - hm.PeerCtx = ctx - } - err = s.handleQueue.Add(ctx, threadId, hm) - if err == mb.ErrOverflowed { - log.InfoCtx(ctx, "queue overflowed", zap.String("spaceId", s.id), zap.String("objectId", threadId)) - // skip overflowed error - return nil - } - return -} - -func (s *space) handleMessage(msg HandleMessage) { - var err error - msg.StartHandlingTime = time.Now() - ctx := peer.CtxWithPeerId(context.Background(), msg.SenderId) - ctx = logger.CtxWithFields(ctx, zap.Uint64("msgId", msg.Id), zap.String("senderId", msg.SenderId)) - defer func() { - if s.metric == nil { - return - } - s.metric.RequestLog(msg.PeerCtx, "space.streamOp", msg.LogFields( - zap.Error(err), - )...) - }() - - if !msg.Deadline.IsZero() { - now := time.Now() - if now.After(msg.Deadline) { - log.InfoCtx(ctx, "skip message: deadline exceed") - err = context.DeadlineExceeded - return - } - var cancel context.CancelFunc - ctx, cancel = context.WithDeadline(ctx, msg.Deadline) - defer cancel() - } - - if err = s.objectSync.HandleMessage(ctx, msg.SenderId, msg.Message); err != nil { - if msg.Message.ObjectId != "" { - // cleanup thread on error - _ = s.handleQueue.CloseThread(msg.Message.ObjectId) - } - log.InfoCtx(ctx, "handleMessage error", zap.Error(err)) - } -} - -func (s *space) onObjectClose(id string) { - s.treesUsed.Add(-1) - log.Debug("decrementing counter", zap.String("id", id), zap.Int32("trees", s.treesUsed.Load()), zap.String("spaceId", s.id)) - _ = s.handleQueue.CloseThread(id) -} - -func (s *space) onSpaceDelete() { - err := s.storage.SetSpaceDeleted() - if err != nil { - log.Debug("failed to set space deleted") - } - s.isDeleted.Swap(true) + return s.state.SpaceStorage } func (s *space) Close() error { - if s.isClosed.Swap(true) { - log.Warn("call space.Close on closed space", zap.String("id", s.id)) + if s.state.SpaceIsClosed.Swap(true) { + log.Warn("call space.Close on closed space", zap.String("id", s.state.SpaceId)) return nil } - log.With(zap.String("id", s.id)).Debug("space is closing") + log := log.With(zap.String("spaceId", s.state.SpaceId)) + log.Debug("space is closing") - var mError errs.Group - if err := s.handleQueue.Close(); err != nil { - mError.Add(err) - } - if err := s.headSync.Close(); err != nil { - mError.Add(err) - } - if err := s.objectSync.Close(); err != nil { - mError.Add(err) - } - if err := s.settingsObject.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) - } - if err := s.syncStatus.Close(); err != nil { - mError.Add(err) - } - log.With(zap.String("id", s.id)).Debug("space closed") - return mError.Err() + err := s.app.Close(context.Background()) + log.Debug("space closed") + return err } func (s *space) TryClose(objectTTL time.Duration) (close bool, err error) { if time.Now().Sub(s.objectSync.LastUsage()) < objectTTL { return false, nil } - locked := s.treesUsed.Load() > 1 - log.With(zap.Int32("trees used", s.treesUsed.Load()), zap.Bool("locked", locked), zap.String("spaceId", s.id)).Debug("space lock status check") + locked := s.state.TreesUsed.Load() > 1 + log.With(zap.Int32("trees used", s.state.TreesUsed.Load()), zap.Bool("locked", locked), zap.String("spaceId", s.state.SpaceId)).Debug("space lock status check") if locked { return false, nil } diff --git a/commonspace/spaceservice.go b/commonspace/spaceservice.go index 3657d423..796a3daf 100644 --- a/commonspace/spaceservice.go +++ b/commonspace/spaceservice.go @@ -7,15 +7,24 @@ import ( "github.com/anyproto/any-sync/app/logger" "github.com/anyproto/any-sync/commonspace/config" "github.com/anyproto/any-sync/commonspace/credentialprovider" + "github.com/anyproto/any-sync/commonspace/deletionstate" "github.com/anyproto/any-sync/commonspace/headsync" "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" + "github.com/anyproto/any-sync/commonspace/object/acl/list" + "github.com/anyproto/any-sync/commonspace/object/acl/syncacl" "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" "github.com/anyproto/any-sync/commonspace/object/treemanager" "github.com/anyproto/any-sync/commonspace/objectsync" + "github.com/anyproto/any-sync/commonspace/objectsync/syncclient" + "github.com/anyproto/any-sync/commonspace/objecttreebuilder" "github.com/anyproto/any-sync/commonspace/peermanager" + "github.com/anyproto/any-sync/commonspace/requestsender" + "github.com/anyproto/any-sync/commonspace/settings" + "github.com/anyproto/any-sync/commonspace/spacestate" "github.com/anyproto/any-sync/commonspace/spacestorage" "github.com/anyproto/any-sync/commonspace/spacesyncproto" + "github.com/anyproto/any-sync/commonspace/streamsender" "github.com/anyproto/any-sync/commonspace/syncstatus" "github.com/anyproto/any-sync/metric" "github.com/anyproto/any-sync/net/peer" @@ -73,6 +82,7 @@ func (s *spaceService) Init(a *app.App) (err error) { } s.pool = a.MustComponent(pool.CName).(pool.Pool) s.metric, _ = a.Component(metric.CName).(metric.Metric) + s.app = a return nil } @@ -140,8 +150,6 @@ func (s *spaceService) NewSpace(ctx context.Context, id string) (Space, error) { } } } - - lastConfiguration := s.configurationService var ( spaceIsClosed = &atomic.Bool{} spaceIsDeleted = &atomic.Bool{} @@ -151,42 +159,57 @@ func (s *spaceService) NewSpace(ctx context.Context, id string) (Space, error) { return nil, err } spaceIsDeleted.Swap(isDeleted) - getter := NewObjectManager(st.Id(), s.treeManager, spaceIsClosed) - syncStatus := syncstatus.NewNoOpSyncStatus() - // this will work only for clients, not the best solution, but... - if !lastConfiguration.IsResponsible(st.Id()) { - // TODO: move it to the client package and add possibility to inject StatusProvider from the client - syncStatus = syncstatus.NewSyncStatusProvider(st.Id(), syncstatus.DefaultDeps(lastConfiguration, st)) - } - var builder objecttree.BuildObjectTreeFunc - if s.config.KeepTreeDataInMemory { - builder = objecttree.BuildObjectTree - } else { - builder = objecttree.BuildEmptyDataObjectTree - } - - peerManager, err := s.peermanagerProvider.NewPeerManager(ctx, id) + aclStorage, err := st.AclStorage() if err != nil { return nil, err } + aclList, err := list.BuildAclListWithIdentity(s.account.Account(), aclStorage) + if err != nil { + return nil, err + } + aclList = syncacl.NewSyncAcl(aclList) + state := &spacestate.SpaceState{ + SpaceId: st.Id(), + SpaceIsDeleted: spaceIsDeleted, + SpaceIsClosed: spaceIsClosed, + TreesUsed: &atomic.Int32{}, + AclList: aclList, + SpaceStorage: st, + } + if s.config.KeepTreeDataInMemory { + state.TreeBuilderFunc = objecttree.BuildObjectTree + } else { + state.TreeBuilderFunc = objecttree.BuildEmptyDataObjectTree + } + var syncStatus syncstatus.StatusProvider + if !s.configurationService.IsResponsible(st.Id()) { + // TODO: move it to the client package and add possibility to inject StatusProvider from the client + syncStatus = syncstatus.NewSyncStatusProvider() + } else { + syncStatus = syncstatus.NewNoOpSyncStatus() + } + //lastConfiguration := s.configurationService + // + //peerManager, err := s.peermanagerProvider.NewPeerManager(ctx, id) + //if err != nil { + // return nil, err + //} + spaceApp := s.app.ChildApp() + spaceApp.Register(state). + Register(syncStatus). + Register(NewObjectManager(s.treeManager)). + Register(streamsender.New()). + Register(requestsender.New()). + Register(deletionstate.New()). + Register(settings.New()). + Register(syncclient.New()). + Register(objecttreebuilder.New()). + Register(objectsync.New()). + Register(headsync.New()) - headSync := headsync.NewHeadSync(id, spaceIsDeleted, s.config.SyncPeriod, lastConfiguration, st, peerManager, getter, syncStatus, s.credentialProvider, log) - objectSync := objectsync.NewObjectSync(id, spaceIsDeleted, lastConfiguration, peerManager, getter, st) sp := &space{ - id: id, - objectSync: objectSync, - headSync: headSync, - syncStatus: syncStatus, - treeManager: getter, - account: s.account, - configuration: lastConfiguration, - peerManager: peerManager, - storage: st, - treesUsed: &atomic.Int32{}, - treeBuilder: builder, - isClosed: spaceIsClosed, - isDeleted: spaceIsDeleted, - metric: s.metric, + state: state, + app: spaceApp, } return sp, nil } diff --git a/commonspace/spacestate/shareddata.go b/commonspace/spacestate/shareddata.go index bf231cb7..9d6eac2f 100644 --- a/commonspace/spacestate/shareddata.go +++ b/commonspace/spacestate/shareddata.go @@ -10,11 +10,6 @@ import ( const CName = "common.commonspace.shareddata" -type SpaceActions interface { - OnObjectDelete(id string) - OnSpaceDelete() -} - type SpaceState struct { SpaceId string SpaceIsDeleted *atomic.Bool @@ -23,7 +18,6 @@ type SpaceState struct { AclList list.AclList SpaceStorage spacestorage.SpaceStorage TreeBuilderFunc objecttree.BuildObjectTreeFunc - Actions SpaceActions } func (s *SpaceState) Init(a *app.App) (err error) { diff --git a/commonspace/streamsender/streamsender.go b/commonspace/streamsender/streamsender.go index 9482a81a..99a45f5c 100644 --- a/commonspace/streamsender/streamsender.go +++ b/commonspace/streamsender/streamsender.go @@ -8,7 +8,30 @@ import ( const CName = "common.commonspace.streamsender" type StreamSender interface { - app.ComponentRunnable + app.Component SendPeer(peerId string, msg *spacesyncproto.ObjectSyncMessage) (err error) Broadcast(msg *spacesyncproto.ObjectSyncMessage) (err error) } + +func New() StreamSender { + return &streamSender{} +} + +type streamSender struct { +} + +func (s *streamSender) Init(a *app.App) (err error) { + return +} + +func (s *streamSender) Name() (name string) { + return CName +} + +func (s *streamSender) SendPeer(peerId string, msg *spacesyncproto.ObjectSyncMessage) (err error) { + return nil +} + +func (s *streamSender) Broadcast(msg *spacesyncproto.ObjectSyncMessage) (err error) { + return nil +} From 796b66478bc8e2c33539510bb13e8d5adaa30d40 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Thu, 1 Jun 2023 22:55:37 +0200 Subject: [PATCH 003/123] Further components rearrange --- commonspace/headsync/headsync.go | 2 +- commonspace/object/acl/syncacl/syncacl.go | 35 ++++++++++++---- .../{commongetter.go => objectmanager.go} | 40 +++++++++++-------- commonspace/objectsync/objectsync.go | 1 + commonspace/objecttreebuilder/treebuilder.go | 6 +-- commonspace/peermanager/peermanager.go | 1 + commonspace/settings/settings.go | 7 +++- commonspace/space.go | 8 ++-- commonspace/spaceservice.go | 27 ++++--------- commonspace/spacestate/shareddata.go | 6 +-- commonspace/spacestorage/inmemorystorage.go | 9 +++++ commonspace/spacestorage/spacestorage.go | 2 +- commonspace/spacestorage/spacestorage_test.go | 1 - commonspace/syncstatus/syncstatus.go | 4 +- 14 files changed, 87 insertions(+), 62 deletions(-) rename commonspace/{commongetter.go => objectmanager.go} (53%) delete mode 100644 commonspace/spacestorage/spacestorage_test.go diff --git a/commonspace/headsync/headsync.go b/commonspace/headsync/headsync.go index 0d761fd5..cfa1ca4e 100644 --- a/commonspace/headsync/headsync.go +++ b/commonspace/headsync/headsync.go @@ -73,7 +73,7 @@ func (h *headSync) Init(a *app.App) (err error) { h.syncPeriod = cfg.GetSpace().SyncPeriod h.configuration = a.MustComponent(nodeconf.CName).(nodeconf.NodeConf) h.log = log.With(zap.String("spaceId", h.spaceId)) - h.storage = a.MustComponent("spacestorage").(spacestorage.SpaceStorage) + h.storage = a.MustComponent(spacestorage.CName).(spacestorage.SpaceStorage) h.diff = ldiff.New(16, 16) h.peerManager = a.MustComponent(peermanager.CName).(peermanager.PeerManager) h.credentialProvider = a.MustComponent(credentialprovider.CName).(credentialprovider.CredentialProvider) diff --git a/commonspace/object/acl/syncacl/syncacl.go b/commonspace/object/acl/syncacl/syncacl.go index cc728e4a..0824b74f 100644 --- a/commonspace/object/acl/syncacl/syncacl.go +++ b/commonspace/object/acl/syncacl/syncacl.go @@ -1,18 +1,39 @@ package syncacl import ( + "context" + "github.com/anyproto/any-sync/accountservice" + "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/commonspace/object/acl/list" - "github.com/anyproto/any-sync/commonspace/objectsync/synchandler" + "github.com/anyproto/any-sync/commonspace/spacestorage" + "github.com/anyproto/any-sync/commonspace/spacesyncproto" ) +const CName = "common.acl.syncacl" + +func New() *SyncAcl { + return &SyncAcl{} +} + type SyncAcl struct { list.AclList - synchandler.SyncHandler } -func NewSyncAcl(aclList list.AclList) *SyncAcl { - return &SyncAcl{ - AclList: aclList, - SyncHandler: nil, - } +func (s *SyncAcl) HandleMessage(ctx context.Context, senderId string, request *spacesyncproto.ObjectSyncMessage) (err error) { + return nil +} + +func (s *SyncAcl) Init(a *app.App) (err error) { + storage := a.MustComponent(spacestorage.CName).(spacestorage.SpaceStorage) + aclStorage, err := storage.AclStorage() + if err != nil { + return err + } + acc := a.MustComponent(accountservice.CName).(accountservice.Service) + s.AclList, err = list.BuildAclListWithIdentity(acc.Account(), aclStorage) + return err +} + +func (s *SyncAcl) Name() (name string) { + return CName } diff --git a/commonspace/commongetter.go b/commonspace/objectmanager.go similarity index 53% rename from commonspace/commongetter.go rename to commonspace/objectmanager.go index 93c9312d..b97533c8 100644 --- a/commonspace/commongetter.go +++ b/commonspace/objectmanager.go @@ -3,9 +3,11 @@ package commonspace import ( "context" "github.com/anyproto/any-sync/app" + "github.com/anyproto/any-sync/commonspace/object/acl/syncacl" "github.com/anyproto/any-sync/commonspace/object/syncobjectgetter" "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" "github.com/anyproto/any-sync/commonspace/object/treemanager" + "github.com/anyproto/any-sync/commonspace/settings" "github.com/anyproto/any-sync/commonspace/spacestate" "sync/atomic" ) @@ -29,37 +31,41 @@ func NewObjectManager(manager treemanager.TreeManager) ObjectManager { } } -func (c *objectManager) Init(a *app.App) (err error) { +func (o *objectManager) Init(a *app.App) (err error) { state := a.MustComponent(spacestate.CName).(*spacestate.SpaceState) - c.spaceId = state.SpaceId - c.spaceIsClosed = state.SpaceIsClosed + o.spaceId = state.SpaceId + o.spaceIsClosed = state.SpaceIsClosed + settingsObject := a.MustComponent(settings.CName).(settings.Settings).SettingsObject() + acl := a.MustComponent(syncacl.CName).(*syncacl.SyncAcl) + o.AddObject(settingsObject) + o.AddObject(acl) return nil } -func (c *objectManager) Run(ctx context.Context) (err error) { +func (o *objectManager) Run(ctx context.Context) (err error) { return nil } -func (c *objectManager) Close(ctx context.Context) (err error) { +func (o *objectManager) Close(ctx context.Context) (err error) { return nil } -func (c *objectManager) AddObject(object syncobjectgetter.SyncObject) { - c.reservedObjects = append(c.reservedObjects, object) +func (o *objectManager) AddObject(object syncobjectgetter.SyncObject) { + o.reservedObjects = append(o.reservedObjects, object) } -func (c *objectManager) GetTree(ctx context.Context, spaceId, treeId string) (objecttree.ObjectTree, error) { - if c.spaceIsClosed.Load() { +func (o *objectManager) GetTree(ctx context.Context, spaceId, treeId string) (objecttree.ObjectTree, error) { + if o.spaceIsClosed.Load() { return nil, ErrSpaceClosed } - if obj := c.getReservedObject(treeId); obj != nil { + if obj := o.getReservedObject(treeId); obj != nil { return obj.(objecttree.ObjectTree), nil } - return c.TreeManager.GetTree(ctx, spaceId, treeId) + return o.TreeManager.GetTree(ctx, spaceId, treeId) } -func (c *objectManager) getReservedObject(id string) syncobjectgetter.SyncObject { - for _, obj := range c.reservedObjects { +func (o *objectManager) getReservedObject(id string) syncobjectgetter.SyncObject { + for _, obj := range o.reservedObjects { if obj != nil && obj.Id() == id { return obj } @@ -67,14 +73,14 @@ func (c *objectManager) getReservedObject(id string) syncobjectgetter.SyncObject return nil } -func (c *objectManager) GetObject(ctx context.Context, objectId string) (obj syncobjectgetter.SyncObject, err error) { - if c.spaceIsClosed.Load() { +func (o *objectManager) GetObject(ctx context.Context, objectId string) (obj syncobjectgetter.SyncObject, err error) { + if o.spaceIsClosed.Load() { return nil, ErrSpaceClosed } - if obj := c.getReservedObject(objectId); obj != nil { + if obj := o.getReservedObject(objectId); obj != nil { return obj, nil } - t, err := c.TreeManager.GetTree(ctx, c.spaceId, objectId) + t, err := o.TreeManager.GetTree(ctx, o.spaceId, objectId) if err != nil { return } diff --git a/commonspace/objectsync/objectsync.go b/commonspace/objectsync/objectsync.go index 0a836cff..93b4d8de 100644 --- a/commonspace/objectsync/objectsync.go +++ b/commonspace/objectsync/objectsync.go @@ -69,6 +69,7 @@ type objectSync struct { func (s *objectSync) Init(a *app.App) (err error) { s.syncClient = a.MustComponent(syncclient.CName).(syncclient.SyncClient) + s.spaceStorage = a.MustComponent(spacestorage.CName).(spacestorage.SpaceStorage) s.objectGetter = a.MustComponent(treemanager.CName).(treemanager.TreeManager).(syncobjectgetter.SyncObjectGetter) s.configuration = a.MustComponent(nodeconf.CName).(nodeconf.NodeConf) sharedData := a.MustComponent(spacestate.CName).(*spacestate.SpaceState) diff --git a/commonspace/objecttreebuilder/treebuilder.go b/commonspace/objecttreebuilder/treebuilder.go index cf15c49c..01259887 100644 --- a/commonspace/objecttreebuilder/treebuilder.go +++ b/commonspace/objecttreebuilder/treebuilder.go @@ -7,6 +7,7 @@ import ( "github.com/anyproto/any-sync/app/logger" "github.com/anyproto/any-sync/commonspace/headsync" "github.com/anyproto/any-sync/commonspace/object/acl/list" + "github.com/anyproto/any-sync/commonspace/object/acl/syncacl" "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" "github.com/anyproto/any-sync/commonspace/object/tree/synctree" "github.com/anyproto/any-sync/commonspace/object/tree/synctree/updatelistener" @@ -76,14 +77,13 @@ type treeBuilder struct { func (t *treeBuilder) Init(a *app.App) (err error) { state := a.MustComponent(spacestate.CName).(*spacestate.SpaceState) t.spaceId = state.SpaceId - t.aclList = state.AclList t.isClosed = state.SpaceIsClosed - t.spaceStorage = state.SpaceStorage t.treesUsed = state.TreesUsed t.builder = state.TreeBuilderFunc + t.aclList = a.MustComponent(syncacl.CName).(*syncacl.SyncAcl) + t.spaceStorage = a.MustComponent(spacestorage.CName).(spacestorage.SpaceStorage) t.configuration = a.MustComponent(nodeconf.CName).(nodeconf.NodeConf) t.headsNotifiable = a.MustComponent(headsync.CName).(headsync.HeadSync) - t.spaceStorage = state.SpaceStorage t.syncStatus = a.MustComponent(syncstatus.CName).(syncstatus.StatusUpdater) t.peerManager = a.MustComponent(peermanager.CName).(peermanager.PeerManager) t.objectSync = a.MustComponent(objectsync.CName).(objectsync.ObjectSync) diff --git a/commonspace/peermanager/peermanager.go b/commonspace/peermanager/peermanager.go index a4075f32..095a7059 100644 --- a/commonspace/peermanager/peermanager.go +++ b/commonspace/peermanager/peermanager.go @@ -11,6 +11,7 @@ import ( const CName = "common.commonspace.peermanager" type PeerManager interface { + app.Component // SendPeer sends a message to a stream by peerId SendPeer(ctx context.Context, peerId string, msg *spacesyncproto.ObjectSyncMessage) (err error) // Broadcast sends a message to all subscribed peers diff --git a/commonspace/settings/settings.go b/commonspace/settings/settings.go index 95252388..c2a55407 100644 --- a/commonspace/settings/settings.go +++ b/commonspace/settings/settings.go @@ -25,6 +25,7 @@ type Settings interface { DeleteTree(ctx context.Context, id string) (err error) SpaceDeleteRawChange(ctx context.Context) (raw *treechangeproto.RawTreeChangeWithId, err error) DeleteSpace(ctx context.Context, deleteChange *treechangeproto.RawTreeChangeWithId) (err error) + SettingsObject() SettingsObject app.ComponentRunnable } @@ -54,7 +55,7 @@ func (s *settings) Init(a *app.App) (err error) { s.treeBuilder = a.MustComponent(objecttreebuilder.CName).(objecttreebuilder.TreeBuilderComponent) sharedState := a.MustComponent(spacestate.CName).(*spacestate.SpaceState) - s.storage = sharedState.SpaceStorage + s.storage = a.MustComponent(spacestorage.CName).(spacestorage.SpaceStorage) s.spaceIsDeleted = sharedState.SpaceIsDeleted deps := Deps{ @@ -115,3 +116,7 @@ func (s *settings) onSpaceDelete() { } s.spaceIsDeleted.Swap(true) } + +func (s *settings) SettingsObject() SettingsObject { + return s.settingsObject +} diff --git a/commonspace/space.go b/commonspace/space.go index a5732e5b..d870b732 100644 --- a/commonspace/space.go +++ b/commonspace/space.go @@ -89,6 +89,7 @@ type space struct { objectSync objectsync.ObjectSync syncStatus syncstatus.StatusProvider settings settings.Settings + storage spacestorage.SpaceStorage } func (s *space) DeleteTree(ctx context.Context, id string) (err error) { @@ -125,19 +126,16 @@ func (s *space) Init(ctx context.Context) (err error) { s.syncStatus = s.app.MustComponent(syncstatus.CName).(syncstatus.StatusProvider) s.settings = s.app.MustComponent(settings.CName).(settings.Settings) s.objectSync = s.app.MustComponent(objectsync.CName).(objectsync.ObjectSync) + s.storage = s.app.MustComponent(spacestorage.CName).(spacestorage.SpaceStorage) return nil } -func (s *space) HeadSync() headsync.HeadSyncExternal { - return s.headSync -} - func (s *space) SyncStatus() syncstatus.StatusUpdater { return s.syncStatus } func (s *space) Storage() spacestorage.SpaceStorage { - return s.state.SpaceStorage + return s.storage } func (s *space) Close() error { diff --git a/commonspace/spaceservice.go b/commonspace/spaceservice.go index 796a3daf..e157a37c 100644 --- a/commonspace/spaceservice.go +++ b/commonspace/spaceservice.go @@ -10,7 +10,6 @@ import ( "github.com/anyproto/any-sync/commonspace/deletionstate" "github.com/anyproto/any-sync/commonspace/headsync" "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" - "github.com/anyproto/any-sync/commonspace/object/acl/list" "github.com/anyproto/any-sync/commonspace/object/acl/syncacl" "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" @@ -159,22 +158,11 @@ func (s *spaceService) NewSpace(ctx context.Context, id string) (Space, error) { return nil, err } spaceIsDeleted.Swap(isDeleted) - aclStorage, err := st.AclStorage() - if err != nil { - return nil, err - } - aclList, err := list.BuildAclListWithIdentity(s.account.Account(), aclStorage) - if err != nil { - return nil, err - } - aclList = syncacl.NewSyncAcl(aclList) state := &spacestate.SpaceState{ SpaceId: st.Id(), SpaceIsDeleted: spaceIsDeleted, SpaceIsClosed: spaceIsClosed, TreesUsed: &atomic.Int32{}, - AclList: aclList, - SpaceStorage: st, } if s.config.KeepTreeDataInMemory { state.TreeBuilderFunc = objecttree.BuildObjectTree @@ -188,20 +176,21 @@ func (s *spaceService) NewSpace(ctx context.Context, id string) (Space, error) { } else { syncStatus = syncstatus.NewNoOpSyncStatus() } - //lastConfiguration := s.configurationService - // - //peerManager, err := s.peermanagerProvider.NewPeerManager(ctx, id) - //if err != nil { - // return nil, err - //} + peerManager, err := s.peermanagerProvider.NewPeerManager(ctx, id) + if err != nil { + return nil, err + } spaceApp := s.app.ChildApp() spaceApp.Register(state). + Register(peerManager). + Register(newCommonStorage(st)). + Register(syncacl.New()). Register(syncStatus). - Register(NewObjectManager(s.treeManager)). Register(streamsender.New()). Register(requestsender.New()). Register(deletionstate.New()). Register(settings.New()). + Register(NewObjectManager(s.treeManager)). Register(syncclient.New()). Register(objecttreebuilder.New()). Register(objectsync.New()). diff --git a/commonspace/spacestate/shareddata.go b/commonspace/spacestate/shareddata.go index 9d6eac2f..b2a53a50 100644 --- a/commonspace/spacestate/shareddata.go +++ b/commonspace/spacestate/shareddata.go @@ -2,21 +2,17 @@ package spacestate import ( "github.com/anyproto/any-sync/app" - "github.com/anyproto/any-sync/commonspace/object/acl/list" "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" - "github.com/anyproto/any-sync/commonspace/spacestorage" "sync/atomic" ) -const CName = "common.commonspace.shareddata" +const CName = "common.commonspace.spacestate" type SpaceState struct { SpaceId string SpaceIsDeleted *atomic.Bool SpaceIsClosed *atomic.Bool TreesUsed *atomic.Int32 - AclList list.AclList - SpaceStorage spacestorage.SpaceStorage TreeBuilderFunc objecttree.BuildObjectTreeFunc } diff --git a/commonspace/spacestorage/inmemorystorage.go b/commonspace/spacestorage/inmemorystorage.go index b728a8a6..db1d1166 100644 --- a/commonspace/spacestorage/inmemorystorage.go +++ b/commonspace/spacestorage/inmemorystorage.go @@ -1,6 +1,7 @@ package spacestorage import ( + "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" "github.com/anyproto/any-sync/commonspace/object/acl/liststorage" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" @@ -21,6 +22,14 @@ type InMemorySpaceStorage struct { sync.Mutex } +func (i *InMemorySpaceStorage) Init(a *app.App) (err error) { + return nil +} + +func (i *InMemorySpaceStorage) Name() (name string) { + return CName +} + func NewInMemorySpaceStorage(payload SpaceStorageCreatePayload) (SpaceStorage, error) { aclStorage, err := liststorage.NewInMemoryAclListStorage(payload.AclWithId.Id, []*aclrecordproto.RawAclRecordWithId{payload.AclWithId}) if err != nil { diff --git a/commonspace/spacestorage/spacestorage.go b/commonspace/spacestorage/spacestorage.go index cecd3736..a4ffaecb 100644 --- a/commonspace/spacestorage/spacestorage.go +++ b/commonspace/spacestorage/spacestorage.go @@ -27,8 +27,8 @@ const ( TreeDeletedStatusDeleted = "deleted" ) -// TODO: consider moving to some file with all common interfaces etc type SpaceStorage interface { + app.Component Id() string SetSpaceDeleted() error IsSpaceDeleted() (bool, error) diff --git a/commonspace/spacestorage/spacestorage_test.go b/commonspace/spacestorage/spacestorage_test.go deleted file mode 100644 index 7ca39ae0..00000000 --- a/commonspace/spacestorage/spacestorage_test.go +++ /dev/null @@ -1 +0,0 @@ -package spacestorage diff --git a/commonspace/syncstatus/syncstatus.go b/commonspace/syncstatus/syncstatus.go index edc12175..2049c42b 100644 --- a/commonspace/syncstatus/syncstatus.go +++ b/commonspace/syncstatus/syncstatus.go @@ -102,9 +102,9 @@ func (s *syncStatusProvider) Init(a *app.App) (err error) { sharedState := a.MustComponent(spacestate.CName).(*spacestate.SpaceState) s.updateIntervalSecs = syncUpdateInterval s.updateTimeout = syncTimeout - s.configuration = a.MustComponent(nodeconf.CName).(nodeconf.NodeConf) - s.storage = sharedState.SpaceStorage s.spaceId = sharedState.SpaceId + s.configuration = a.MustComponent(nodeconf.CName).(nodeconf.NodeConf) + s.storage = a.MustComponent(spacestorage.CName).(spacestorage.SpaceStorage) return } From 815bc7927d633fbe0b573835ecfbf72110dd2e75 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Fri, 2 Jun 2023 00:59:33 +0200 Subject: [PATCH 004/123] Wire up the stuff --- .../credentialprovider/credentialprovider.go | 10 +++++++++ commonspace/deletion_test.go | 14 ++++++------ commonspace/deletionstate/deletionstate.go | 3 +-- commonspace/headsync/headsync.go | 8 +++---- commonspace/object/acl/syncacl/syncacl.go | 2 +- .../object/tree/synctree/synctreehandler.go | 9 ++++---- .../{ => objectmanager}/objectmanager.go | 15 +++++++++++-- commonspace/objectsync/objectsync.go | 10 +++++---- commonspace/objecttreebuilder/treebuilder.go | 4 ++-- commonspace/peermanager/peermanager.go | 5 ++++- commonspace/settings/settings.go | 4 ++-- commonspace/space.go | 7 +----- commonspace/spaceservice.go | 22 ++++--------------- commonspace/spacestorage/inmemoryprovider.go | 2 +- commonspace/spacestorage/inmemorystorage.go | 2 +- commonspace/spacestorage/spacestorage.go | 5 ++++- commonspace/spaceutils_test.go | 16 ++++++++++++-- commonspace/syncstatus/syncstatus.go | 2 +- 18 files changed, 81 insertions(+), 59 deletions(-) rename commonspace/{ => objectmanager}/objectmanager.go (90%) diff --git a/commonspace/credentialprovider/credentialprovider.go b/commonspace/credentialprovider/credentialprovider.go index ce570904..5f12b065 100644 --- a/commonspace/credentialprovider/credentialprovider.go +++ b/commonspace/credentialprovider/credentialprovider.go @@ -3,6 +3,7 @@ package credentialprovider import ( "context" + "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/commonspace/spacesyncproto" ) @@ -13,12 +14,21 @@ func NewNoOp() CredentialProvider { } type CredentialProvider interface { + app.Component GetCredential(ctx context.Context, spaceHeader *spacesyncproto.RawSpaceHeaderWithId) ([]byte, error) } type noOpProvider struct { } +func (n noOpProvider) Init(a *app.App) (err error) { + return nil +} + +func (n noOpProvider) Name() (name string) { + return CName +} + func (n noOpProvider) GetCredential(ctx context.Context, spaceHeader *spacesyncproto.RawSpaceHeaderWithId) ([]byte, error) { return nil, nil } diff --git a/commonspace/deletion_test.go b/commonspace/deletion_test.go index 64d6fa11..6862a472 100644 --- a/commonspace/deletion_test.go +++ b/commonspace/deletion_test.go @@ -79,7 +79,7 @@ func TestSpaceDeleteIds(t *testing.T) { // creating a tree bytes := make([]byte, 32) rand.Read(bytes) - doc, err := spc.CreateTree(ctx, objecttree.ObjectTreeCreatePayload{ + doc, err := spc.TreeBuilder().CreateTree(ctx, objecttree.ObjectTreeCreatePayload{ PrivKey: acc.SignKey, ChangeType: "some", SpaceId: spc.Id(), @@ -88,7 +88,7 @@ func TestSpaceDeleteIds(t *testing.T) { Timestamp: time.Now().Unix(), }) require.NoError(t, err) - tr, err := spc.PutTree(ctx, doc, nil) + tr, err := spc.TreeBuilder().PutTree(ctx, doc, nil) require.NoError(t, err) ids = append(ids, tr.Id()) tr.Close() @@ -106,7 +106,7 @@ func TestSpaceDeleteIds(t *testing.T) { func createTree(t *testing.T, ctx context.Context, spc Space, acc *accountdata.AccountKeys) string { bytes := make([]byte, 32) rand.Read(bytes) - doc, err := spc.CreateTree(ctx, objecttree.ObjectTreeCreatePayload{ + doc, err := spc.TreeBuilder().CreateTree(ctx, objecttree.ObjectTreeCreatePayload{ PrivKey: acc.SignKey, ChangeType: "some", SpaceId: spc.Id(), @@ -115,7 +115,7 @@ func createTree(t *testing.T, ctx context.Context, spc Space, acc *accountdata.A Timestamp: time.Now().Unix(), }) require.NoError(t, err) - tr, err := spc.PutTree(ctx, doc, nil) + tr, err := spc.TreeBuilder().PutTree(ctx, doc, nil) require.NoError(t, err) tr.Close() return tr.Id() @@ -149,7 +149,7 @@ func TestSpaceDeleteIdsIncorrectSnapshot(t *testing.T) { err = spc.Init(ctx) require.NoError(t, err) - settingsObject := spc.(*space).settingsObject + settingsObject := spc.(*space).app.MustComponent(settings.CName).(settings.Settings).SettingsObject() var ids []string for i := 0; i < totalObjs; i++ { id := createTree(t, ctx, spc, acc) @@ -193,7 +193,7 @@ func TestSpaceDeleteIdsIncorrectSnapshot(t *testing.T) { require.Equal(t, len(ids), len(fx.treeManager.deletedIds)) // checking that new snapshot will contain all the changes - settingsObject = spc.(*space).settingsObject + settingsObject = spc.(*space).app.MustComponent(settings.CName).(settings.Settings).SettingsObject() settings.DoSnapshot = func(treeLen int) bool { return true } @@ -231,7 +231,7 @@ func TestSpaceDeleteIdsMarkDeleted(t *testing.T) { err = spc.Init(ctx) require.NoError(t, err) - settingsObject := spc.(*space).settingsObject + settingsObject := spc.(*space).app.MustComponent(settings.CName).(settings.Settings).SettingsObject() var ids []string for i := 0; i < totalObjs; i++ { id := createTree(t, ctx, spc, acc) diff --git a/commonspace/deletionstate/deletionstate.go b/commonspace/deletionstate/deletionstate.go index 64da5417..109a5ea2 100644 --- a/commonspace/deletionstate/deletionstate.go +++ b/commonspace/deletionstate/deletionstate.go @@ -4,7 +4,6 @@ package deletionstate import ( "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/app/logger" - "github.com/anyproto/any-sync/commonspace/spacestate" "github.com/anyproto/any-sync/commonspace/spacestorage" "go.uber.org/zap" "sync" @@ -36,7 +35,7 @@ type objectDeletionState struct { } func (st *objectDeletionState) Init(a *app.App) (err error) { - st.storage = a.MustComponent(spacestate.CName).(*spacestate.SpaceState).SpaceStorage + st.storage = a.MustComponent(spacestorage.StorageName).(spacestorage.SpaceStorage) return nil } diff --git a/commonspace/headsync/headsync.go b/commonspace/headsync/headsync.go index cfa1ca4e..cc5faefd 100644 --- a/commonspace/headsync/headsync.go +++ b/commonspace/headsync/headsync.go @@ -67,18 +67,18 @@ func New() HeadSync { func (h *headSync) Init(a *app.App) (err error) { shared := a.MustComponent(spacestate.CName).(*spacestate.SpaceState) - cfg := a.MustComponent("cfg").(config2.ConfigGetter) + cfg := a.MustComponent("config").(config2.ConfigGetter) h.spaceId = shared.SpaceId h.spaceIsDeleted = shared.SpaceIsDeleted h.syncPeriod = cfg.GetSpace().SyncPeriod h.configuration = a.MustComponent(nodeconf.CName).(nodeconf.NodeConf) h.log = log.With(zap.String("spaceId", h.spaceId)) - h.storage = a.MustComponent(spacestorage.CName).(spacestorage.SpaceStorage) + h.storage = a.MustComponent(spacestorage.StorageName).(spacestorage.SpaceStorage) h.diff = ldiff.New(16, 16) - h.peerManager = a.MustComponent(peermanager.CName).(peermanager.PeerManager) + h.peerManager = a.MustComponent(peermanager.ManagerName).(peermanager.PeerManager) h.credentialProvider = a.MustComponent(credentialprovider.CName).(credentialprovider.CredentialProvider) h.syncStatus = a.MustComponent(syncstatus.CName).(syncstatus.StatusProvider) - h.treeManager = a.MustComponent(treemanager.CName).(treemanager.TreeManager) + h.treeManager = app.MustComponent[treemanager.TreeManager](a) h.deletionState = a.MustComponent(deletionstate.CName).(deletionstate.ObjectDeletionState) h.syncer = newDiffSyncer(h) sync := func(ctx context.Context) (err error) { diff --git a/commonspace/object/acl/syncacl/syncacl.go b/commonspace/object/acl/syncacl/syncacl.go index 0824b74f..f3bc57a5 100644 --- a/commonspace/object/acl/syncacl/syncacl.go +++ b/commonspace/object/acl/syncacl/syncacl.go @@ -24,7 +24,7 @@ func (s *SyncAcl) HandleMessage(ctx context.Context, senderId string, request *s } func (s *SyncAcl) Init(a *app.App) (err error) { - storage := a.MustComponent(spacestorage.CName).(spacestorage.SpaceStorage) + storage := a.MustComponent(spacestorage.StorageName).(spacestorage.SpaceStorage) aclStorage, err := storage.AclStorage() if err != nil { return err diff --git a/commonspace/object/tree/synctree/synctreehandler.go b/commonspace/object/tree/synctree/synctreehandler.go index 942c0e2f..a8f98f62 100644 --- a/commonspace/object/tree/synctree/synctreehandler.go +++ b/commonspace/object/tree/synctree/synctreehandler.go @@ -25,6 +25,7 @@ type syncTreeHandler struct { const maxQueueSize = 5 +// TODO: Make sync and async message handling func newSyncTreeHandler(spaceId string, objTree objecttree.ObjectTree, syncClient syncclient.SyncClient, syncStatus syncstatus.StatusUpdater) synchandler.SyncHandler { return &syncTreeHandler{ objTree: objTree, @@ -119,7 +120,7 @@ func (s *syncTreeHandler) handleHeadUpdate( return } - return s.syncClient.QueueRequest(ctx, senderId, treeId, fullRequest, replyId) + return s.syncClient.QueueRequest(senderId, treeId, fullRequest) } if s.alreadyHasHeads(objTree, update.Heads) { @@ -143,7 +144,7 @@ func (s *syncTreeHandler) handleHeadUpdate( return } - return s.syncClient.QueueRequest(ctx, senderId, treeId, fullRequest, replyId) + return s.syncClient.QueueRequest(senderId, treeId, fullRequest) } func (s *syncTreeHandler) handleFullSyncRequest( @@ -169,7 +170,7 @@ func (s *syncTreeHandler) handleFullSyncRequest( defer func() { if err != nil { log.ErrorCtx(ctx, "full sync request finished with error", zap.Error(err)) - s.syncClient.QueueRequest(ctx, senderId, treeId, treechangeproto.WrapError(treechangeproto.ErrFullSync, header), replyId) + s.syncClient.QueueRequest(senderId, treeId, treechangeproto.WrapError(treechangeproto.ErrFullSync, header)) return } else if fullResponse != nil { cnt := fullResponse.Content.GetFullSyncResponse() @@ -192,7 +193,7 @@ func (s *syncTreeHandler) handleFullSyncRequest( return } - return s.syncClient.QueueRequest(ctx, senderId, treeId, fullResponse, replyId) + return s.syncClient.QueueRequest(senderId, treeId, fullResponse) } func (s *syncTreeHandler) handleFullSyncResponse( diff --git a/commonspace/objectmanager.go b/commonspace/objectmanager/objectmanager.go similarity index 90% rename from commonspace/objectmanager.go rename to commonspace/objectmanager/objectmanager.go index b97533c8..2ce6d3dc 100644 --- a/commonspace/objectmanager.go +++ b/commonspace/objectmanager/objectmanager.go @@ -1,7 +1,8 @@ -package commonspace +package objectmanager import ( "context" + "errors" "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/commonspace/object/acl/syncacl" "github.com/anyproto/any-sync/commonspace/object/syncobjectgetter" @@ -12,6 +13,12 @@ import ( "sync/atomic" ) +var ( + ErrSpaceClosed = errors.New("space is closed") +) + +const CName = "common.commonspace.objectmanager" + type ObjectManager interface { treemanager.TreeManager AddObject(object syncobjectgetter.SyncObject) @@ -25,7 +32,7 @@ type objectManager struct { spaceIsClosed *atomic.Bool } -func NewObjectManager(manager treemanager.TreeManager) ObjectManager { +func New(manager treemanager.TreeManager) ObjectManager { return &objectManager{ TreeManager: manager, } @@ -54,6 +61,10 @@ func (o *objectManager) AddObject(object syncobjectgetter.SyncObject) { o.reservedObjects = append(o.reservedObjects, object) } +func (o *objectManager) Name() string { + return CName +} + func (o *objectManager) GetTree(ctx context.Context, spaceId, treeId string) (objecttree.ObjectTree, error) { if o.spaceIsClosed.Load() { return nil, ErrSpaceClosed diff --git a/commonspace/objectsync/objectsync.go b/commonspace/objectsync/objectsync.go index 93b4d8de..dae786df 100644 --- a/commonspace/objectsync/objectsync.go +++ b/commonspace/objectsync/objectsync.go @@ -5,7 +5,6 @@ import ( "context" "fmt" "github.com/anyproto/any-sync/app" - "github.com/anyproto/any-sync/commonspace/object/treemanager" "github.com/anyproto/any-sync/commonspace/objectsync/syncclient" "github.com/anyproto/any-sync/commonspace/spacestate" "github.com/anyproto/any-sync/metric" @@ -69,11 +68,14 @@ type objectSync struct { func (s *objectSync) Init(a *app.App) (err error) { s.syncClient = a.MustComponent(syncclient.CName).(syncclient.SyncClient) - s.spaceStorage = a.MustComponent(spacestorage.CName).(spacestorage.SpaceStorage) - s.objectGetter = a.MustComponent(treemanager.CName).(treemanager.TreeManager).(syncobjectgetter.SyncObjectGetter) + s.spaceStorage = a.MustComponent(spacestorage.StorageName).(spacestorage.SpaceStorage) + s.objectGetter = app.MustComponent[syncobjectgetter.SyncObjectGetter](a) s.configuration = a.MustComponent(nodeconf.CName).(nodeconf.NodeConf) sharedData := a.MustComponent(spacestate.CName).(*spacestate.SpaceState) - s.metric = a.MustComponent(metric.CName).(metric.Metric) + mc := a.Component(metric.CName) + if mc != nil { + s.metric = mc.(metric.Metric) + } s.spaceIsDeleted = sharedData.SpaceIsDeleted s.spaceId = sharedData.SpaceId s.handleQueue = multiqueue.New[HandleMessage](s.processHandleMessage, 100) diff --git a/commonspace/objecttreebuilder/treebuilder.go b/commonspace/objecttreebuilder/treebuilder.go index 01259887..e63aca65 100644 --- a/commonspace/objecttreebuilder/treebuilder.go +++ b/commonspace/objecttreebuilder/treebuilder.go @@ -81,11 +81,11 @@ func (t *treeBuilder) Init(a *app.App) (err error) { t.treesUsed = state.TreesUsed t.builder = state.TreeBuilderFunc t.aclList = a.MustComponent(syncacl.CName).(*syncacl.SyncAcl) - t.spaceStorage = a.MustComponent(spacestorage.CName).(spacestorage.SpaceStorage) + t.spaceStorage = a.MustComponent(spacestorage.StorageName).(spacestorage.SpaceStorage) t.configuration = a.MustComponent(nodeconf.CName).(nodeconf.NodeConf) t.headsNotifiable = a.MustComponent(headsync.CName).(headsync.HeadSync) t.syncStatus = a.MustComponent(syncstatus.CName).(syncstatus.StatusUpdater) - t.peerManager = a.MustComponent(peermanager.CName).(peermanager.PeerManager) + t.peerManager = a.MustComponent(peermanager.ManagerName).(peermanager.PeerManager) t.objectSync = a.MustComponent(objectsync.CName).(objectsync.ObjectSync) t.log = log.With(zap.String("spaceId", t.spaceId)) return nil diff --git a/commonspace/peermanager/peermanager.go b/commonspace/peermanager/peermanager.go index 095a7059..c69e59b3 100644 --- a/commonspace/peermanager/peermanager.go +++ b/commonspace/peermanager/peermanager.go @@ -8,7 +8,10 @@ import ( "github.com/anyproto/any-sync/net/peer" ) -const CName = "common.commonspace.peermanager" +const ( + ProviderName = "common.commonspace.peermanagerprovider" + ManagerName = "common.commonspace.peermanager" +) type PeerManager interface { app.Component diff --git a/commonspace/settings/settings.go b/commonspace/settings/settings.go index c2a55407..dbc93ccc 100644 --- a/commonspace/settings/settings.go +++ b/commonspace/settings/settings.go @@ -48,14 +48,14 @@ type settings struct { func (s *settings) Init(a *app.App) (err error) { s.account = a.MustComponent(accountservice.CName).(accountservice.Service) - s.treeManager = a.MustComponent(treemanager.CName).(treemanager.TreeManager) + s.treeManager = app.MustComponent[treemanager.TreeManager](a) s.headsync = a.MustComponent(headsync.CName).(headsync.HeadSync) s.configuration = a.MustComponent(nodeconf.CName).(nodeconf.NodeConf) s.deletionState = a.MustComponent(deletionstate.CName).(deletionstate.ObjectDeletionState) s.treeBuilder = a.MustComponent(objecttreebuilder.CName).(objecttreebuilder.TreeBuilderComponent) sharedState := a.MustComponent(spacestate.CName).(*spacestate.SpaceState) - s.storage = a.MustComponent(spacestorage.CName).(spacestorage.SpaceStorage) + s.storage = a.MustComponent(spacestorage.StorageName).(spacestorage.SpaceStorage) s.spaceIsDeleted = sharedState.SpaceIsDeleted deps := Deps{ diff --git a/commonspace/space.go b/commonspace/space.go index d870b732..793e7333 100644 --- a/commonspace/space.go +++ b/commonspace/space.go @@ -2,7 +2,6 @@ package commonspace import ( "context" - "errors" "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/commonspace/headsync" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" @@ -21,10 +20,6 @@ import ( "time" ) -var ( - ErrSpaceClosed = errors.New("space is closed") -) - type SpaceCreatePayload struct { // SigningKey is the signing key of the owner SigningKey crypto.PrivKey @@ -126,7 +121,7 @@ func (s *space) Init(ctx context.Context) (err error) { s.syncStatus = s.app.MustComponent(syncstatus.CName).(syncstatus.StatusProvider) s.settings = s.app.MustComponent(settings.CName).(settings.Settings) s.objectSync = s.app.MustComponent(objectsync.CName).(objectsync.ObjectSync) - s.storage = s.app.MustComponent(spacestorage.CName).(spacestorage.SpaceStorage) + s.storage = s.app.MustComponent(spacestorage.StorageName).(spacestorage.SpaceStorage) return nil } diff --git a/commonspace/spaceservice.go b/commonspace/spaceservice.go index e157a37c..49b38963 100644 --- a/commonspace/spaceservice.go +++ b/commonspace/spaceservice.go @@ -14,6 +14,7 @@ import ( "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" "github.com/anyproto/any-sync/commonspace/object/treemanager" + "github.com/anyproto/any-sync/commonspace/objectmanager" "github.com/anyproto/any-sync/commonspace/objectsync" "github.com/anyproto/any-sync/commonspace/objectsync/syncclient" "github.com/anyproto/any-sync/commonspace/objecttreebuilder" @@ -24,7 +25,6 @@ import ( "github.com/anyproto/any-sync/commonspace/spacestorage" "github.com/anyproto/any-sync/commonspace/spacesyncproto" "github.com/anyproto/any-sync/commonspace/streamsender" - "github.com/anyproto/any-sync/commonspace/syncstatus" "github.com/anyproto/any-sync/metric" "github.com/anyproto/any-sync/net/peer" "github.com/anyproto/any-sync/net/pool" @@ -69,16 +69,10 @@ type spaceService struct { func (s *spaceService) Init(a *app.App) (err error) { s.config = a.MustComponent("config").(config.ConfigGetter).GetSpace() s.account = a.MustComponent(accountservice.CName).(accountservice.Service) - s.storageProvider = a.MustComponent(spacestorage.CName).(spacestorage.SpaceStorageProvider) + s.storageProvider = a.MustComponent(spacestorage.ProviderName).(spacestorage.SpaceStorageProvider) s.configurationService = a.MustComponent(nodeconf.CName).(nodeconf.Service) s.treeManager = a.MustComponent(treemanager.CName).(treemanager.TreeManager) - s.peermanagerProvider = a.MustComponent(peermanager.CName).(peermanager.PeerManagerProvider) - credProvider := a.Component(credentialprovider.CName) - if credProvider != nil { - s.credentialProvider = credProvider.(credentialprovider.CredentialProvider) - } else { - s.credentialProvider = credentialprovider.NewNoOp() - } + s.peermanagerProvider = a.MustComponent(peermanager.ProviderName).(peermanager.PeerManagerProvider) s.pool = a.MustComponent(pool.CName).(pool.Pool) s.metric, _ = a.Component(metric.CName).(metric.Metric) s.app = a @@ -169,13 +163,6 @@ func (s *spaceService) NewSpace(ctx context.Context, id string) (Space, error) { } else { state.TreeBuilderFunc = objecttree.BuildEmptyDataObjectTree } - var syncStatus syncstatus.StatusProvider - if !s.configurationService.IsResponsible(st.Id()) { - // TODO: move it to the client package and add possibility to inject StatusProvider from the client - syncStatus = syncstatus.NewSyncStatusProvider() - } else { - syncStatus = syncstatus.NewNoOpSyncStatus() - } peerManager, err := s.peermanagerProvider.NewPeerManager(ctx, id) if err != nil { return nil, err @@ -185,12 +172,11 @@ func (s *spaceService) NewSpace(ctx context.Context, id string) (Space, error) { Register(peerManager). Register(newCommonStorage(st)). Register(syncacl.New()). - Register(syncStatus). Register(streamsender.New()). Register(requestsender.New()). Register(deletionstate.New()). Register(settings.New()). - Register(NewObjectManager(s.treeManager)). + Register(objectmanager.New(s.treeManager)). Register(syncclient.New()). Register(objecttreebuilder.New()). Register(objectsync.New()). diff --git a/commonspace/spacestorage/inmemoryprovider.go b/commonspace/spacestorage/inmemoryprovider.go index 3ddfe02a..1cceb53c 100644 --- a/commonspace/spacestorage/inmemoryprovider.go +++ b/commonspace/spacestorage/inmemoryprovider.go @@ -22,7 +22,7 @@ func (i *InMemorySpaceStorageProvider) Init(a *app.App) (err error) { } func (i *InMemorySpaceStorageProvider) Name() (name string) { - return CName + return ProviderName } func (i *InMemorySpaceStorageProvider) WaitSpaceStorage(ctx context.Context, id string) (SpaceStorage, error) { diff --git a/commonspace/spacestorage/inmemorystorage.go b/commonspace/spacestorage/inmemorystorage.go index db1d1166..bc2846fb 100644 --- a/commonspace/spacestorage/inmemorystorage.go +++ b/commonspace/spacestorage/inmemorystorage.go @@ -27,7 +27,7 @@ func (i *InMemorySpaceStorage) Init(a *app.App) (err error) { } func (i *InMemorySpaceStorage) Name() (name string) { - return CName + return StorageName } func NewInMemorySpaceStorage(payload SpaceStorageCreatePayload) (SpaceStorage, error) { diff --git a/commonspace/spacestorage/spacestorage.go b/commonspace/spacestorage/spacestorage.go index a4ffaecb..b6b73fdc 100644 --- a/commonspace/spacestorage/spacestorage.go +++ b/commonspace/spacestorage/spacestorage.go @@ -12,7 +12,10 @@ import ( "github.com/anyproto/any-sync/commonspace/spacesyncproto" ) -const CName = "common.commonspace.spacestorage" +const ( + ProviderName = "common.commonspace.spacestorageprovider" + StorageName = "common.commonspace.spacestorage" +) var ( ErrSpaceStorageExists = errors.New("space storage exists") diff --git a/commonspace/spaceutils_test.go b/commonspace/spaceutils_test.go index 1b345279..f26f4881 100644 --- a/commonspace/spaceutils_test.go +++ b/commonspace/spaceutils_test.go @@ -10,9 +10,11 @@ import ( "github.com/anyproto/any-sync/commonspace/credentialprovider" "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" "github.com/anyproto/any-sync/commonspace/object/treemanager" + "github.com/anyproto/any-sync/commonspace/objecttreebuilder" "github.com/anyproto/any-sync/commonspace/peermanager" "github.com/anyproto/any-sync/commonspace/spacestorage" "github.com/anyproto/any-sync/commonspace/spacesyncproto" + "github.com/anyproto/any-sync/commonspace/syncstatus" "github.com/anyproto/any-sync/net/peer" "github.com/anyproto/any-sync/net/pool" "github.com/anyproto/any-sync/nodeconf" @@ -129,6 +131,14 @@ func (m *mockConf) NodeTypes(nodeId string) []nodeconf.NodeType { type mockPeerManager struct { } +func (p *mockPeerManager) Init(a *app.App) (err error) { + return nil +} + +func (p *mockPeerManager) Name() (name string) { + return peermanager.ManagerName +} + func (p *mockPeerManager) SendPeer(ctx context.Context, peerId string, msg *spacesyncproto.ObjectSyncMessage) (err error) { return nil } @@ -153,7 +163,7 @@ func (m *mockPeerManagerProvider) Init(a *app.App) (err error) { } func (m *mockPeerManagerProvider) Name() (name string) { - return peermanager.CName + return peermanager.ProviderName } func (m *mockPeerManagerProvider) NewPeerManager(ctx context.Context, spaceId string) (sm peermanager.PeerManager, err error) { @@ -250,7 +260,7 @@ func (t *mockTreeManager) MarkTreeDeleted(ctx context.Context, spaceId, treeId s func (t *mockTreeManager) Init(a *app.App) (err error) { t.cache = ocache.New(func(ctx context.Context, id string) (value ocache.Object, err error) { - return t.space.BuildTree(ctx, id, BuildTreeOpts{}) + return t.space.TreeBuilder().BuildTree(ctx, id, objecttreebuilder.BuildTreeOpts{}) }, ocache.WithGCPeriod(time.Minute), ocache.WithTTL(time.Duration(60)*time.Second)) @@ -325,6 +335,8 @@ func newFixture(t *testing.T) *spaceFixture { } fx.app.Register(fx.account). Register(fx.config). + Register(syncstatus.NewNoOpSyncStatus()). + Register(credentialprovider.NewNoOp()). Register(fx.configurationService). Register(fx.storageProvider). Register(fx.peermanagerProvider). diff --git a/commonspace/syncstatus/syncstatus.go b/commonspace/syncstatus/syncstatus.go index 2049c42b..acdbc298 100644 --- a/commonspace/syncstatus/syncstatus.go +++ b/commonspace/syncstatus/syncstatus.go @@ -104,7 +104,7 @@ func (s *syncStatusProvider) Init(a *app.App) (err error) { s.updateTimeout = syncTimeout s.spaceId = sharedState.SpaceId s.configuration = a.MustComponent(nodeconf.CName).(nodeconf.NodeConf) - s.storage = a.MustComponent(spacestorage.CName).(spacestorage.SpaceStorage) + s.storage = a.MustComponent(spacestorage.StorageName).(spacestorage.SpaceStorage) return } From a89a325d6c8095164d3daea7f6ed3f844897090a Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Fri, 2 Jun 2023 01:08:56 +0200 Subject: [PATCH 005/123] Fix sync client --- commonspace/objectsync/syncclient/syncclient.go | 4 +++- commonspace/objecttreebuilder/treebuilder.go | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/commonspace/objectsync/syncclient/syncclient.go b/commonspace/objectsync/syncclient/syncclient.go index 99360eab..69cf4224 100644 --- a/commonspace/objectsync/syncclient/syncclient.go +++ b/commonspace/objectsync/syncclient/syncclient.go @@ -33,7 +33,9 @@ type syncClient struct { } func New() SyncClient { - return &syncClient{} + return &syncClient{ + RequestFactory: &requestFactory{}, + } } func (s *syncClient) Init(a *app.App) (err error) { diff --git a/commonspace/objecttreebuilder/treebuilder.go b/commonspace/objecttreebuilder/treebuilder.go index e63aca65..f77c6ff5 100644 --- a/commonspace/objecttreebuilder/treebuilder.go +++ b/commonspace/objecttreebuilder/treebuilder.go @@ -87,6 +87,7 @@ func (t *treeBuilder) Init(a *app.App) (err error) { t.syncStatus = a.MustComponent(syncstatus.CName).(syncstatus.StatusUpdater) t.peerManager = a.MustComponent(peermanager.ManagerName).(peermanager.PeerManager) t.objectSync = a.MustComponent(objectsync.CName).(objectsync.ObjectSync) + t.syncClient = a.MustComponent(syncclient.CName).(syncclient.SyncClient) t.log = log.With(zap.String("spaceId", t.spaceId)) return nil } From 748681d7654ac2db573945d79a4518ca67ed8d99 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Sat, 3 Jun 2023 15:57:55 +0200 Subject: [PATCH 006/123] WIP rearrange components --- app/app.go | 10 +- app/app_test.go | 5 + commonspace/deletionstate/deletionstate.go | 2 +- commonspace/headsync/headsync.go | 6 +- commonspace/object/acl/syncacl/syncacl.go | 6 +- .../tree/synctree}/requestfactory.go | 2 +- .../tree/synctree}/syncclient.go | 46 ++-- .../object/tree/synctree/syncprotocol.go | 152 ++++++++++++ commonspace/object/tree/synctree/synctree.go | 5 +- .../object/tree/synctree/synctree_test.go | 7 +- .../object/tree/synctree/synctreehandler.go | 230 ++++-------------- .../tree/synctree/synctreehandler_test.go | 23 +- .../object/tree/synctree/utils_test.go | 21 +- commonspace/objectmanager/objectmanager.go | 4 +- commonspace/objectsync/objectsync.go | 10 +- .../objectsync/synchandler/synchhandler.go | 3 +- commonspace/objecttreebuilder/treebuilder.go | 12 +- commonspace/peermanager/peermanager.go | 3 +- commonspace/requestmanager/requestmanager.go | 49 ++++ commonspace/requestsender/requestsender.go | 49 ---- commonspace/settings/settings.go | 2 +- commonspace/space.go | 2 +- commonspace/spaceservice.go | 12 +- commonspace/spacestorage/inmemoryprovider.go | 2 +- commonspace/spacestorage/inmemorystorage.go | 2 +- commonspace/spacestorage/spacestorage.go | 5 +- commonspace/spaceutils_test.go | 4 +- commonspace/streamsender/streamsender.go | 37 --- commonspace/syncstatus/syncstatus.go | 2 +- 29 files changed, 338 insertions(+), 375 deletions(-) rename commonspace/{objectsync/syncclient => object/tree/synctree}/requestfactory.go (99%) rename commonspace/{objectsync/syncclient => object/tree/synctree}/syncclient.go (64%) create mode 100644 commonspace/object/tree/synctree/syncprotocol.go create mode 100644 commonspace/requestmanager/requestmanager.go delete mode 100644 commonspace/requestsender/requestsender.go delete mode 100644 commonspace/streamsender/streamsender.go diff --git a/app/app.go b/app/app.go index b8be83a0..89e7ab46 100644 --- a/app/app.go +++ b/app/app.go @@ -125,14 +125,10 @@ func (app *App) ChildApp() *App { func (app *App) Register(s Component) *App { app.mu.Lock() defer app.mu.Unlock() - current := app - for current != nil { - for _, es := range current.components { - if s.Name() == es.Name() { - panic(fmt.Errorf("component '%s' already registered", s.Name())) - } + for _, es := range app.components { + if s.Name() == es.Name() { + panic(fmt.Errorf("component '%s' already registered", s.Name())) } - current = current.parent } app.components = append(app.components, s) return app diff --git a/app/app_test.go b/app/app_test.go index 7b5678d6..0c122b24 100644 --- a/app/app_test.go +++ b/app/app_test.go @@ -48,6 +48,11 @@ func TestAppServiceRegistry(t *testing.T) { names := app.ComponentNames() assert.Equal(t, names, []string{"x1", "c1", "r1", "s1"}) }) + t.Run("Child override", func(t *testing.T) { + app := app.ChildApp() + app.Register(newTestService(testTypeRunnable, "s1", nil, nil)) + _ = app.MustComponent("s1").(*testRunnable) + }) } func TestAppStart(t *testing.T) { diff --git a/commonspace/deletionstate/deletionstate.go b/commonspace/deletionstate/deletionstate.go index 109a5ea2..692ba627 100644 --- a/commonspace/deletionstate/deletionstate.go +++ b/commonspace/deletionstate/deletionstate.go @@ -35,7 +35,7 @@ type objectDeletionState struct { } func (st *objectDeletionState) Init(a *app.App) (err error) { - st.storage = a.MustComponent(spacestorage.StorageName).(spacestorage.SpaceStorage) + st.storage = a.MustComponent(spacestorage.CName).(spacestorage.SpaceStorage) return nil } diff --git a/commonspace/headsync/headsync.go b/commonspace/headsync/headsync.go index cc5faefd..3f5bcd25 100644 --- a/commonspace/headsync/headsync.go +++ b/commonspace/headsync/headsync.go @@ -73,12 +73,12 @@ func (h *headSync) Init(a *app.App) (err error) { h.syncPeriod = cfg.GetSpace().SyncPeriod h.configuration = a.MustComponent(nodeconf.CName).(nodeconf.NodeConf) h.log = log.With(zap.String("spaceId", h.spaceId)) - h.storage = a.MustComponent(spacestorage.StorageName).(spacestorage.SpaceStorage) + h.storage = a.MustComponent(spacestorage.CName).(spacestorage.SpaceStorage) h.diff = ldiff.New(16, 16) - h.peerManager = a.MustComponent(peermanager.ManagerName).(peermanager.PeerManager) + h.peerManager = a.MustComponent(peermanager.CName).(peermanager.PeerManager) h.credentialProvider = a.MustComponent(credentialprovider.CName).(credentialprovider.CredentialProvider) h.syncStatus = a.MustComponent(syncstatus.CName).(syncstatus.StatusProvider) - h.treeManager = app.MustComponent[treemanager.TreeManager](a) + h.treeManager = a.MustComponent(treemanager.CName).(treemanager.TreeManager) h.deletionState = a.MustComponent(deletionstate.CName).(deletionstate.ObjectDeletionState) h.syncer = newDiffSyncer(h) sync := func(ctx context.Context) (err error) { diff --git a/commonspace/object/acl/syncacl/syncacl.go b/commonspace/object/acl/syncacl/syncacl.go index f3bc57a5..426b16cd 100644 --- a/commonspace/object/acl/syncacl/syncacl.go +++ b/commonspace/object/acl/syncacl/syncacl.go @@ -19,12 +19,16 @@ type SyncAcl struct { list.AclList } +func (s *SyncAcl) HandleRequest(ctx context.Context, senderId string, request *spacesyncproto.ObjectSyncMessage) (response *spacesyncproto.ObjectSyncMessage, err error) { + return nil, nil +} + func (s *SyncAcl) HandleMessage(ctx context.Context, senderId string, request *spacesyncproto.ObjectSyncMessage) (err error) { return nil } func (s *SyncAcl) Init(a *app.App) (err error) { - storage := a.MustComponent(spacestorage.StorageName).(spacestorage.SpaceStorage) + storage := a.MustComponent(spacestorage.CName).(spacestorage.SpaceStorage) aclStorage, err := storage.AclStorage() if err != nil { return err diff --git a/commonspace/objectsync/syncclient/requestfactory.go b/commonspace/object/tree/synctree/requestfactory.go similarity index 99% rename from commonspace/objectsync/syncclient/requestfactory.go rename to commonspace/object/tree/synctree/requestfactory.go index 0d908179..8d91add8 100644 --- a/commonspace/objectsync/syncclient/requestfactory.go +++ b/commonspace/object/tree/synctree/requestfactory.go @@ -1,4 +1,4 @@ -package syncclient +package synctree import ( "fmt" diff --git a/commonspace/objectsync/syncclient/syncclient.go b/commonspace/object/tree/synctree/syncclient.go similarity index 64% rename from commonspace/objectsync/syncclient/syncclient.go rename to commonspace/object/tree/synctree/syncclient.go index 69cf4224..13909b3b 100644 --- a/commonspace/objectsync/syncclient/syncclient.go +++ b/commonspace/object/tree/synctree/syncclient.go @@ -1,23 +1,15 @@ -package syncclient +package synctree import ( "context" - "github.com/anyproto/any-sync/app" - "github.com/anyproto/any-sync/app/logger" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" - "github.com/anyproto/any-sync/commonspace/requestsender" - "github.com/anyproto/any-sync/commonspace/spacestate" + "github.com/anyproto/any-sync/commonspace/peermanager" + "github.com/anyproto/any-sync/commonspace/requestmanager" "github.com/anyproto/any-sync/commonspace/spacesyncproto" - "github.com/anyproto/any-sync/commonspace/streamsender" "go.uber.org/zap" ) -const CName = "common.objectsync.syncclient" - -var log = logger.NewNamed(CName) - type SyncClient interface { - app.Component RequestFactory Broadcast(msg *treechangeproto.TreeSyncMessage) SendUpdate(peerId, objectId string, msg *treechangeproto.TreeSyncMessage) (err error) @@ -27,35 +19,25 @@ type SyncClient interface { type syncClient struct { RequestFactory - spaceId string - requestSender requestsender.RequestSender - streamSender streamsender.StreamSender + spaceId string + requestManager requestmanager.RequestManager + peerManager peermanager.PeerManager } -func New() SyncClient { +func NewSyncClient(spaceId string, requestManager requestmanager.RequestManager, peerManager peermanager.PeerManager) SyncClient { return &syncClient{ RequestFactory: &requestFactory{}, + spaceId: spaceId, + requestManager: requestManager, + peerManager: peerManager, } } - -func (s *syncClient) Init(a *app.App) (err error) { - sharedState := a.MustComponent(spacestate.CName).(*spacestate.SpaceState) - s.spaceId = sharedState.SpaceId - s.requestSender = a.MustComponent(requestsender.CName).(requestsender.RequestSender) - s.streamSender = a.MustComponent(streamsender.CName).(streamsender.StreamSender) - return nil -} - -func (s *syncClient) Name() (name string) { - return CName -} - func (s *syncClient) Broadcast(msg *treechangeproto.TreeSyncMessage) { objMsg, err := MarshallTreeMessage(msg, s.spaceId, msg.RootChange.Id, "") if err != nil { return } - err = s.streamSender.Broadcast(objMsg) + err = s.peerManager.Broadcast(context.Background(), objMsg) if err != nil { log.Debug("broadcast error", zap.Error(err)) } @@ -66,7 +48,7 @@ func (s *syncClient) SendUpdate(peerId, objectId string, msg *treechangeproto.Tr if err != nil { return } - return s.streamSender.SendPeer(peerId, objMsg) + return s.peerManager.SendPeer(context.Background(), peerId, objMsg) } func (s *syncClient) SendRequest(ctx context.Context, peerId, objectId string, msg *treechangeproto.TreeSyncMessage) (reply *spacesyncproto.ObjectSyncMessage, err error) { @@ -74,7 +56,7 @@ func (s *syncClient) SendRequest(ctx context.Context, peerId, objectId string, m if err != nil { return } - return s.requestSender.SendRequest(ctx, peerId, objMsg) + return s.requestManager.SendRequest(ctx, peerId, objMsg) } func (s *syncClient) QueueRequest(peerId, objectId string, msg *treechangeproto.TreeSyncMessage) (err error) { @@ -82,7 +64,7 @@ func (s *syncClient) QueueRequest(peerId, objectId string, msg *treechangeproto. if err != nil { return } - return s.requestSender.QueueRequest(peerId, objMsg) + return s.requestManager.QueueRequest(peerId, objMsg) } func MarshallTreeMessage(message *treechangeproto.TreeSyncMessage, spaceId, objectId, replyId string) (objMsg *spacesyncproto.ObjectSyncMessage, err error) { diff --git a/commonspace/object/tree/synctree/syncprotocol.go b/commonspace/object/tree/synctree/syncprotocol.go new file mode 100644 index 00000000..be759259 --- /dev/null +++ b/commonspace/object/tree/synctree/syncprotocol.go @@ -0,0 +1,152 @@ +package synctree + +import ( + "context" + "github.com/anyproto/any-sync/app/logger" + "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" + "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" + "github.com/anyproto/any-sync/util/slice" + "go.uber.org/zap" +) + +type TreeSyncProtocol interface { + HeadUpdate(ctx context.Context, senderId string, update *treechangeproto.TreeHeadUpdate) (request *treechangeproto.TreeSyncMessage, err error) + FullSyncRequest(ctx context.Context, senderId string, request *treechangeproto.TreeFullSyncRequest) (response *treechangeproto.TreeSyncMessage, err error) + FullSyncResponse(ctx context.Context, senderId string, response *treechangeproto.TreeFullSyncResponse) (err error) +} + +type treeSyncProtocol struct { + log logger.CtxLogger + spaceId string + objTree objecttree.ObjectTree + reqFactory RequestFactory +} + +func newTreeSyncProtocol(spaceId string, objTree objecttree.ObjectTree, reqFactory RequestFactory) *treeSyncProtocol { + return &treeSyncProtocol{ + log: log.With(zap.String("spaceId", spaceId), zap.String("treeId", objTree.Id())), + spaceId: spaceId, + objTree: objTree, + reqFactory: reqFactory, + } +} + +func (t *treeSyncProtocol) HeadUpdate(ctx context.Context, senderId string, update *treechangeproto.TreeHeadUpdate) (fullRequest *treechangeproto.TreeSyncMessage, err error) { + var ( + isEmptyUpdate = len(update.Changes) == 0 + objTree = t.objTree + ) + log := t.log.With( + zap.String("senderId", senderId), + zap.Strings("update heads", update.Heads), + zap.Int("len(update changes)", len(update.Changes))) + log.DebugCtx(ctx, "received head update message") + + defer func() { + if err != nil { + log.ErrorCtx(ctx, "head update finished with error", zap.Error(err)) + } else if fullRequest != nil { + cnt := fullRequest.Content.GetFullSyncRequest() + log = log.With(zap.Strings("request heads", cnt.Heads), zap.Int("len(request changes)", len(cnt.Changes))) + log.DebugCtx(ctx, "returning full sync request") + } else { + if !isEmptyUpdate { + log.DebugCtx(ctx, "head update finished correctly") + } + } + }() + + // isEmptyUpdate is sent when the tree is brought up from cache + if isEmptyUpdate { + headEquals := slice.UnsortedEquals(objTree.Heads(), update.Heads) + log.DebugCtx(ctx, "is empty update", zap.String("treeId", objTree.Id()), zap.Bool("headEquals", headEquals)) + if headEquals { + return + } + + // we need to sync in any case + fullRequest, err = t.reqFactory.CreateFullSyncRequest(objTree, update.Heads, update.SnapshotPath) + return + } + + if t.alreadyHasHeads(objTree, update.Heads) { + return + } + + _, err = objTree.AddRawChanges(ctx, objecttree.RawChangesPayload{ + NewHeads: update.Heads, + RawChanges: update.Changes, + }) + if err != nil { + return + } + + if t.alreadyHasHeads(objTree, update.Heads) { + return + } + + fullRequest, err = t.reqFactory.CreateFullSyncRequest(objTree, update.Heads, update.SnapshotPath) + return +} + +func (t *treeSyncProtocol) FullSyncRequest(ctx context.Context, senderId string, request *treechangeproto.TreeFullSyncRequest) (fullResponse *treechangeproto.TreeSyncMessage, err error) { + var ( + objTree = t.objTree + ) + log := t.log.With(zap.String("senderId", senderId), + zap.Strings("request heads", request.Heads), + zap.Int("len(request changes)", len(request.Changes))) + log.DebugCtx(ctx, "received full sync request message") + + defer func() { + if err != nil { + log.ErrorCtx(ctx, "full sync request finished with error", zap.Error(err)) + } else if fullResponse != nil { + cnt := fullResponse.Content.GetFullSyncResponse() + log = log.With(zap.Strings("response heads", cnt.Heads), zap.Int("len(response changes)", len(cnt.Changes))) + log.DebugCtx(ctx, "full sync response sent") + } + }() + + if len(request.Changes) != 0 && !t.alreadyHasHeads(objTree, request.Heads) { + _, err = objTree.AddRawChanges(ctx, objecttree.RawChangesPayload{ + NewHeads: request.Heads, + RawChanges: request.Changes, + }) + if err != nil { + return + } + } + fullResponse, err = t.reqFactory.CreateFullSyncResponse(objTree, request.Heads, request.SnapshotPath) + return +} + +func (t *treeSyncProtocol) FullSyncResponse(ctx context.Context, senderId string, response *treechangeproto.TreeFullSyncResponse) (err error) { + var ( + objTree = t.objTree + ) + log := log.With( + zap.Strings("heads", response.Heads), + zap.Int("len(changes)", len(response.Changes))) + log.DebugCtx(ctx, "received full sync response message") + defer func() { + if err != nil { + log.ErrorCtx(ctx, "full sync response failed", zap.Error(err)) + } else { + log.DebugCtx(ctx, "full sync response succeeded") + } + }() + if t.alreadyHasHeads(objTree, response.Heads) { + return + } + + _, err = objTree.AddRawChanges(ctx, objecttree.RawChangesPayload{ + NewHeads: response.Heads, + RawChanges: response.Changes, + }) + return +} + +func (t *treeSyncProtocol) alreadyHasHeads(ot objecttree.ObjectTree, heads []string) bool { + return slice.UnsortedEquals(ot.Heads(), heads) || ot.HasChanges(heads...) +} diff --git a/commonspace/object/tree/synctree/synctree.go b/commonspace/object/tree/synctree/synctree.go index 1a6d2497..4c694880 100644 --- a/commonspace/object/tree/synctree/synctree.go +++ b/commonspace/object/tree/synctree/synctree.go @@ -4,7 +4,6 @@ package synctree import ( "context" "errors" - "github.com/anyproto/any-sync/commonspace/objectsync/syncclient" "time" "github.com/anyproto/any-sync/app/logger" @@ -44,7 +43,7 @@ type SyncTree interface { type syncTree struct { objecttree.ObjectTree synchandler.SyncHandler - syncClient syncclient.SyncClient + syncClient SyncClient syncStatus syncstatus.StatusUpdater notifiable HeadNotifiable listener updatelistener.UpdateListener @@ -61,7 +60,7 @@ type ResponsiblePeersGetter interface { type BuildDeps struct { SpaceId string - SyncClient syncclient.SyncClient + SyncClient SyncClient Configuration nodeconf.NodeConf HeadNotifiable HeadNotifiable Listener updatelistener.UpdateListener diff --git a/commonspace/object/tree/synctree/synctree_test.go b/commonspace/object/tree/synctree/synctree_test.go index 5fe9b2e6..0c12bd34 100644 --- a/commonspace/object/tree/synctree/synctree_test.go +++ b/commonspace/object/tree/synctree/synctree_test.go @@ -9,7 +9,6 @@ import ( "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" "github.com/anyproto/any-sync/commonspace/objectsync" "github.com/anyproto/any-sync/commonspace/objectsync/mock_objectsync" - "github.com/anyproto/any-sync/commonspace/objectsync/syncclient" "github.com/anyproto/any-sync/commonspace/syncstatus" "github.com/anyproto/any-sync/nodeconf" "github.com/golang/mock/gomock" @@ -19,7 +18,7 @@ import ( type syncTreeMatcher struct { objTree objecttree.ObjectTree - client syncclient.SyncClient + client SyncClient listener updatelistener.UpdateListener } @@ -35,8 +34,8 @@ func (s syncTreeMatcher) String() string { return "" } -func syncClientFuncCreator(client syncclient.SyncClient) func(spaceId string, factory syncclient.RequestFactory, objectSync objectsync.ObjectSync, configuration nodeconf.NodeConf) syncclient.SyncClient { - return func(spaceId string, factory syncclient.RequestFactory, objectSync objectsync.ObjectSync, configuration nodeconf.NodeConf) syncclient.SyncClient { +func syncClientFuncCreator(client SyncClient) func(spaceId string, factory RequestFactory, objectSync objectsync.ObjectSync, configuration nodeconf.NodeConf) SyncClient { + return func(spaceId string, factory RequestFactory, objectSync objectsync.ObjectSync, configuration nodeconf.NodeConf) SyncClient { return client } } diff --git a/commonspace/object/tree/synctree/synctreehandler.go b/commonspace/object/tree/synctree/synctreehandler.go index a8f98f62..5953ca97 100644 --- a/commonspace/object/tree/synctree/synctreehandler.go +++ b/commonspace/object/tree/synctree/synctreehandler.go @@ -2,40 +2,64 @@ package synctree import ( "context" + "errors" "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" - "github.com/anyproto/any-sync/commonspace/objectsync/syncclient" "github.com/anyproto/any-sync/commonspace/objectsync/synchandler" "github.com/anyproto/any-sync/commonspace/spacesyncproto" "github.com/anyproto/any-sync/commonspace/syncstatus" - "github.com/anyproto/any-sync/util/slice" "github.com/gogo/protobuf/proto" - "go.uber.org/zap" "sync" ) +var ( + ErrMessageIsRequest = errors.New("message is request") + ErrMessageIsNotRequest = errors.New("message is not request") +) + type syncTreeHandler struct { - objTree objecttree.ObjectTree - syncClient syncclient.SyncClient - syncStatus syncstatus.StatusUpdater - handlerLock sync.Mutex - spaceId string - queue ReceiveQueue + objTree objecttree.ObjectTree + syncClient SyncClient + syncProtocol TreeSyncProtocol + syncStatus syncstatus.StatusUpdater + handlerLock sync.Mutex + spaceId string + queue ReceiveQueue } const maxQueueSize = 5 -// TODO: Make sync and async message handling -func newSyncTreeHandler(spaceId string, objTree objecttree.ObjectTree, syncClient syncclient.SyncClient, syncStatus syncstatus.StatusUpdater) synchandler.SyncHandler { +func newSyncTreeHandler(spaceId string, objTree objecttree.ObjectTree, syncClient SyncClient, syncStatus syncstatus.StatusUpdater) synchandler.SyncHandler { return &syncTreeHandler{ - objTree: objTree, - syncClient: syncClient, - syncStatus: syncStatus, - spaceId: spaceId, - queue: newReceiveQueue(maxQueueSize), + objTree: objTree, + syncProtocol: newTreeSyncProtocol(spaceId, objTree, syncClient), + syncClient: syncClient, + syncStatus: syncStatus, + spaceId: spaceId, + queue: newReceiveQueue(maxQueueSize), } } +func (s *syncTreeHandler) HandleRequest(ctx context.Context, senderId string, request *spacesyncproto.ObjectSyncMessage) (response *spacesyncproto.ObjectSyncMessage, err error) { + unmarshalled := &treechangeproto.TreeSyncMessage{} + err = proto.Unmarshal(request.Payload, unmarshalled) + if err != nil { + return + } + fullSyncRequest := unmarshalled.GetContent().GetFullSyncRequest() + if fullSyncRequest == nil { + err = ErrMessageIsNotRequest + return + } + s.syncStatus.HeadsReceive(senderId, request.ObjectId, treechangeproto.GetHeads(unmarshalled)) + treeResp, err := s.syncProtocol.FullSyncRequest(ctx, senderId, fullSyncRequest) + if err != nil { + return + } + response, err = MarshallTreeMessage(treeResp, s.spaceId, request.ObjectId, "") + return +} + func (s *syncTreeHandler) HandleMessage(ctx context.Context, senderId string, msg *spacesyncproto.ObjectSyncMessage) (err error) { unmarshalled := &treechangeproto.TreeSyncMessage{} err = proto.Unmarshal(msg.Payload, unmarshalled) @@ -55,181 +79,27 @@ func (s *syncTreeHandler) HandleMessage(ctx context.Context, senderId string, ms func (s *syncTreeHandler) handleMessage(ctx context.Context, senderId string) (err error) { s.objTree.Lock() defer s.objTree.Unlock() - msg, replyId, err := s.queue.GetMessage(senderId) + msg, _, err := s.queue.GetMessage(senderId) if err != nil { return } defer s.queue.ClearQueue(senderId) + treeId := s.objTree.Id() content := msg.GetContent() switch { case content.GetHeadUpdate() != nil: - return s.handleHeadUpdate(ctx, senderId, content.GetHeadUpdate(), replyId) + var syncReq *treechangeproto.TreeSyncMessage + syncReq, err = s.syncProtocol.HeadUpdate(ctx, senderId, content.GetHeadUpdate()) + if err != nil { + return + } + return s.syncClient.QueueRequest(senderId, treeId, syncReq) case content.GetFullSyncRequest() != nil: - return s.handleFullSyncRequest(ctx, senderId, content.GetFullSyncRequest(), replyId) + return ErrMessageIsRequest case content.GetFullSyncResponse() != nil: - return s.handleFullSyncResponse(ctx, senderId, content.GetFullSyncResponse()) + return s.syncProtocol.FullSyncResponse(ctx, senderId, content.GetFullSyncResponse()) } return } - -func (s *syncTreeHandler) handleHeadUpdate( - ctx context.Context, - senderId string, - update *treechangeproto.TreeHeadUpdate, - replyId string) (err error) { - var ( - fullRequest *treechangeproto.TreeSyncMessage - isEmptyUpdate = len(update.Changes) == 0 - objTree = s.objTree - treeId = objTree.Id() - ) - log := log.With( - zap.Strings("update heads", update.Heads), - zap.String("treeId", treeId), - zap.String("spaceId", s.spaceId), - zap.Int("len(update changes)", len(update.Changes))) - log.DebugCtx(ctx, "received head update message") - - defer func() { - if err != nil { - log.ErrorCtx(ctx, "head update finished with error", zap.Error(err)) - } else if fullRequest != nil { - cnt := fullRequest.Content.GetFullSyncRequest() - log = log.With(zap.Strings("request heads", cnt.Heads), zap.Int("len(request changes)", len(cnt.Changes))) - log.DebugCtx(ctx, "sending full sync request") - } else { - if !isEmptyUpdate { - log.DebugCtx(ctx, "head update finished correctly") - } - } - }() - - // isEmptyUpdate is sent when the tree is brought up from cache - if isEmptyUpdate { - headEquals := slice.UnsortedEquals(objTree.Heads(), update.Heads) - log.DebugCtx(ctx, "is empty update", zap.String("treeId", objTree.Id()), zap.Bool("headEquals", headEquals)) - if headEquals { - return - } - - // we need to sync in any case - fullRequest, err = s.syncClient.CreateFullSyncRequest(objTree, update.Heads, update.SnapshotPath) - if err != nil { - return - } - - return s.syncClient.QueueRequest(senderId, treeId, fullRequest) - } - - if s.alreadyHasHeads(objTree, update.Heads) { - return - } - - _, err = objTree.AddRawChanges(ctx, objecttree.RawChangesPayload{ - NewHeads: update.Heads, - RawChanges: update.Changes, - }) - if err != nil { - return - } - - if s.alreadyHasHeads(objTree, update.Heads) { - return - } - - fullRequest, err = s.syncClient.CreateFullSyncRequest(objTree, update.Heads, update.SnapshotPath) - if err != nil { - return - } - - return s.syncClient.QueueRequest(senderId, treeId, fullRequest) -} - -func (s *syncTreeHandler) handleFullSyncRequest( - ctx context.Context, - senderId string, - request *treechangeproto.TreeFullSyncRequest, - replyId string) (err error) { - var ( - fullResponse *treechangeproto.TreeSyncMessage - header = s.objTree.Header() - objTree = s.objTree - treeId = s.objTree.Id() - ) - - log := log.With(zap.String("senderId", senderId), - zap.Strings("request heads", request.Heads), - zap.String("treeId", treeId), - zap.String("replyId", replyId), - zap.String("spaceId", s.spaceId), - zap.Int("len(request changes)", len(request.Changes))) - log.DebugCtx(ctx, "received full sync request message") - - defer func() { - if err != nil { - log.ErrorCtx(ctx, "full sync request finished with error", zap.Error(err)) - s.syncClient.QueueRequest(senderId, treeId, treechangeproto.WrapError(treechangeproto.ErrFullSync, header)) - return - } else if fullResponse != nil { - cnt := fullResponse.Content.GetFullSyncResponse() - log = log.With(zap.Strings("response heads", cnt.Heads), zap.Int("len(response changes)", len(cnt.Changes))) - log.DebugCtx(ctx, "full sync response sent") - } - }() - - if len(request.Changes) != 0 && !s.alreadyHasHeads(objTree, request.Heads) { - _, err = objTree.AddRawChanges(ctx, objecttree.RawChangesPayload{ - NewHeads: request.Heads, - RawChanges: request.Changes, - }) - if err != nil { - return - } - } - fullResponse, err = s.syncClient.CreateFullSyncResponse(objTree, request.Heads, request.SnapshotPath) - if err != nil { - return - } - - return s.syncClient.QueueRequest(senderId, treeId, fullResponse) -} - -func (s *syncTreeHandler) handleFullSyncResponse( - ctx context.Context, - senderId string, - response *treechangeproto.TreeFullSyncResponse) (err error) { - var ( - objTree = s.objTree - treeId = s.objTree.Id() - ) - log := log.With( - zap.Strings("heads", response.Heads), - zap.String("treeId", treeId), - zap.String("spaceId", s.spaceId), - zap.Int("len(changes)", len(response.Changes))) - log.DebugCtx(ctx, "received full sync response message") - - defer func() { - if err != nil { - log.ErrorCtx(ctx, "full sync response failed", zap.Error(err)) - } else { - log.DebugCtx(ctx, "full sync response succeeded") - } - }() - - if s.alreadyHasHeads(objTree, response.Heads) { - return - } - - _, err = objTree.AddRawChanges(ctx, objecttree.RawChangesPayload{ - NewHeads: response.Heads, - RawChanges: response.Changes, - }) - return -} - -func (s *syncTreeHandler) alreadyHasHeads(t objecttree.ObjectTree, heads []string) bool { - return slice.UnsortedEquals(t.Heads(), heads) || t.HasChanges(heads...) -} diff --git a/commonspace/object/tree/synctree/synctreehandler_test.go b/commonspace/object/tree/synctree/synctreehandler_test.go index dce08a93..4a65aad5 100644 --- a/commonspace/object/tree/synctree/synctreehandler_test.go +++ b/commonspace/object/tree/synctree/synctreehandler_test.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "github.com/anyproto/any-sync/commonspace/objectsync/mock_objectsync" - "github.com/anyproto/any-sync/commonspace/objectsync/syncclient" "sync" "testing" @@ -110,7 +109,7 @@ func TestSyncHandler_HandleHeadUpdate(t *testing.T) { SnapshotPath: []string{"h1"}, } treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) - objectMsg, _ := syncclient.MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "") fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId) fx.objectTreeMock.EXPECT().Heads().Return([]string{"h2"}).Times(2) @@ -139,7 +138,7 @@ func TestSyncHandler_HandleHeadUpdate(t *testing.T) { SnapshotPath: []string{"h1"}, } treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) - objectMsg, _ := syncclient.MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "") fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId) fx.objectTreeMock.EXPECT().Heads().Return([]string{"h2"}).AnyTimes() @@ -172,7 +171,7 @@ func TestSyncHandler_HandleHeadUpdate(t *testing.T) { SnapshotPath: []string{"h1"}, } treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) - objectMsg, _ := syncclient.MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "") fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId) fx.objectTreeMock.EXPECT().Heads().Return([]string{"h1"}).AnyTimes() @@ -193,7 +192,7 @@ func TestSyncHandler_HandleHeadUpdate(t *testing.T) { SnapshotPath: []string{"h1"}, } treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) - objectMsg, _ := syncclient.MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "") fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId) fx.objectTreeMock.EXPECT().Heads().Return([]string{"h2"}).AnyTimes() @@ -218,7 +217,7 @@ func TestSyncHandler_HandleHeadUpdate(t *testing.T) { SnapshotPath: []string{"h1"}, } treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) - objectMsg, _ := syncclient.MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "") fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId) fx.objectTreeMock.EXPECT().Heads().Return([]string{"h1"}).AnyTimes() @@ -251,7 +250,7 @@ func TestSyncHandler_HandleFullSyncRequest(t *testing.T) { SnapshotPath: []string{"h1"}, } treeMsg := treechangeproto.WrapFullRequest(fullSyncRequest, chWithId) - objectMsg, _ := syncclient.MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "") fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId) fx.objectTreeMock.EXPECT().Header().Return(nil) @@ -284,7 +283,7 @@ func TestSyncHandler_HandleFullSyncRequest(t *testing.T) { SnapshotPath: []string{"h1"}, } treeMsg := treechangeproto.WrapFullRequest(fullSyncRequest, chWithId) - objectMsg, _ := syncclient.MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "") fx.objectTreeMock.EXPECT(). Id().AnyTimes().Return(treeId) @@ -313,7 +312,7 @@ func TestSyncHandler_HandleFullSyncRequest(t *testing.T) { SnapshotPath: []string{"h1"}, } treeMsg := treechangeproto.WrapFullRequest(fullSyncRequest, chWithId) - objectMsg, _ := syncclient.MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "") objectMsg.RequestId = replyId fx.objectTreeMock.EXPECT(). @@ -340,7 +339,7 @@ func TestSyncHandler_HandleFullSyncRequest(t *testing.T) { SnapshotPath: []string{"h1"}, } treeMsg := treechangeproto.WrapFullRequest(fullSyncRequest, chWithId) - objectMsg, _ := syncclient.MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "") fx.objectTreeMock.EXPECT(). Id().AnyTimes().Return(treeId) @@ -381,7 +380,7 @@ func TestSyncHandler_HandleFullSyncResponse(t *testing.T) { SnapshotPath: []string{"h1"}, } treeMsg := treechangeproto.WrapFullResponse(fullSyncResponse, chWithId) - objectMsg, _ := syncclient.MarshallTreeMessage(treeMsg, "spaceId", treeId, replyId) + objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, replyId) fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId) fx.objectTreeMock.EXPECT(). @@ -414,7 +413,7 @@ func TestSyncHandler_HandleFullSyncResponse(t *testing.T) { SnapshotPath: []string{"h1"}, } treeMsg := treechangeproto.WrapFullResponse(fullSyncResponse, chWithId) - objectMsg, _ := syncclient.MarshallTreeMessage(treeMsg, "spaceId", treeId, replyId) + objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, replyId) fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId) fx.objectTreeMock.EXPECT(). diff --git a/commonspace/object/tree/synctree/utils_test.go b/commonspace/object/tree/synctree/utils_test.go index a6d553a3..6c295f9c 100644 --- a/commonspace/object/tree/synctree/utils_test.go +++ b/commonspace/object/tree/synctree/utils_test.go @@ -7,7 +7,6 @@ import ( "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" "github.com/anyproto/any-sync/commonspace/object/tree/treestorage" - "github.com/anyproto/any-sync/commonspace/objectsync/syncclient" "github.com/anyproto/any-sync/commonspace/objectsync/synchandler" "github.com/anyproto/any-sync/commonspace/spacesyncproto" "github.com/anyproto/any-sync/commonspace/syncstatus" @@ -89,14 +88,14 @@ type testSyncHandler struct { peerId string aclList list.AclList log *messageLog - syncClient syncclient.SyncClient + syncClient SyncClient builder objecttree.BuildObjectTreeFunc } // createSyncHandler creates a sync handler when a tree is already created func createSyncHandler(peerId, spaceId string, objTree objecttree.ObjectTree, log *messageLog) *testSyncHandler { - factory := syncclient.NewRequestFactory() - syncClient := syncclient.New(spaceId, newTestMessagePool(peerId, log), factory) + factory := NewRequestFactory() + syncClient := NewSyncClient(spaceId, newTestMessagePool(peerId, log), factory) netTree := &broadcastTree{ ObjectTree: objTree, SyncClient: syncClient, @@ -107,8 +106,8 @@ func createSyncHandler(peerId, spaceId string, objTree objecttree.ObjectTree, lo // createEmptySyncHandler creates a sync handler when the tree will be provided later (this emulates the situation when we have no tree) func createEmptySyncHandler(peerId, spaceId string, builder objecttree.BuildObjectTreeFunc, aclList list.AclList, log *messageLog) *testSyncHandler { - factory := syncclient.NewRequestFactory() - syncClient := syncclient.New(spaceId, newTestMessagePool(peerId, log), factory) + factory := NewRequestFactory() + syncClient := NewSyncClient(spaceId, newTestMessagePool(peerId, log), factory) batcher := mb.New[protocolMsg](0) return &testSyncHandler{ @@ -140,9 +139,9 @@ func (h *testSyncHandler) HandleMessage(ctx context.Context, senderId string, re return } if unmarshalled.Content.GetFullSyncResponse() == nil { - newTreeRequest := syncclient.NewRequestFactory().CreateNewTreeRequest() + newTreeRequest := NewRequestFactory().CreateNewTreeRequest() var objMsg *spacesyncproto.ObjectSyncMessage - objMsg, err = syncclient.MarshallTreeMessage(newTreeRequest, request.SpaceId, request.ObjectId, "") + objMsg, err = MarshallTreeMessage(newTreeRequest, request.SpaceId, request.ObjectId, "") if err != nil { return } @@ -167,8 +166,8 @@ func (h *testSyncHandler) HandleMessage(ctx context.Context, senderId string, re } h.SyncHandler = newSyncTreeHandler(request.SpaceId, netTree, h.syncClient, syncstatus.NewNoOpSyncStatus()) var objMsg *spacesyncproto.ObjectSyncMessage - newTreeRequest := syncclient.NewRequestFactory().CreateHeadUpdate(netTree, res.Added) - objMsg, err = syncclient.MarshallTreeMessage(newTreeRequest, request.SpaceId, request.ObjectId, "") + newTreeRequest := NewRequestFactory().CreateHeadUpdate(netTree, res.Added) + objMsg, err = MarshallTreeMessage(newTreeRequest, request.SpaceId, request.ObjectId, "") if err != nil { return } @@ -278,7 +277,7 @@ func (m *testMessagePool) SendSync(ctx context.Context, peerId string, message * // it is a simplified version of SyncTree which is easier to use in the test environment type broadcastTree struct { objecttree.ObjectTree - syncclient.SyncClient + SyncClient } func (b *broadcastTree) AddRawChanges(ctx context.Context, changes objecttree.RawChangesPayload) (objecttree.AddResult, error) { diff --git a/commonspace/objectmanager/objectmanager.go b/commonspace/objectmanager/objectmanager.go index 2ce6d3dc..49637818 100644 --- a/commonspace/objectmanager/objectmanager.go +++ b/commonspace/objectmanager/objectmanager.go @@ -17,8 +17,6 @@ var ( ErrSpaceClosed = errors.New("space is closed") ) -const CName = "common.commonspace.objectmanager" - type ObjectManager interface { treemanager.TreeManager AddObject(object syncobjectgetter.SyncObject) @@ -62,7 +60,7 @@ func (o *objectManager) AddObject(object syncobjectgetter.SyncObject) { } func (o *objectManager) Name() string { - return CName + return treemanager.CName } func (o *objectManager) GetTree(ctx context.Context, spaceId, treeId string) (objecttree.ObjectTree, error) { diff --git a/commonspace/objectsync/objectsync.go b/commonspace/objectsync/objectsync.go index dae786df..44e5308c 100644 --- a/commonspace/objectsync/objectsync.go +++ b/commonspace/objectsync/objectsync.go @@ -5,7 +5,6 @@ import ( "context" "fmt" "github.com/anyproto/any-sync/app" - "github.com/anyproto/any-sync/commonspace/objectsync/syncclient" "github.com/anyproto/any-sync/commonspace/spacestate" "github.com/anyproto/any-sync/metric" "github.com/anyproto/any-sync/net/peer" @@ -30,6 +29,7 @@ var log = logger.NewNamed(CName) type ObjectSync interface { LastUsage() time.Time HandleMessage(ctx context.Context, hm HandleMessage) (err error) + HandleRequest(ctx context.Context, hm HandleMessage) (resp *spacesyncproto.ObjectSyncMessage, err error) CloseThread(id string) (err error) app.ComponentRunnable } @@ -56,7 +56,6 @@ func (m HandleMessage) LogFields(fields ...zap.Field) []zap.Field { type objectSync struct { spaceId string - syncClient syncclient.SyncClient objectGetter syncobjectgetter.SyncObjectGetter configuration nodeconf.NodeConf spaceStorage spacestorage.SpaceStorage @@ -67,8 +66,7 @@ type objectSync struct { } func (s *objectSync) Init(a *app.App) (err error) { - s.syncClient = a.MustComponent(syncclient.CName).(syncclient.SyncClient) - s.spaceStorage = a.MustComponent(spacestorage.StorageName).(spacestorage.SpaceStorage) + s.spaceStorage = a.MustComponent(spacestorage.CName).(spacestorage.SpaceStorage) s.objectGetter = app.MustComponent[syncobjectgetter.SyncObjectGetter](a) s.configuration = a.MustComponent(nodeconf.CName).(nodeconf.NodeConf) sharedData := a.MustComponent(spacestate.CName).(*spacestate.SpaceState) @@ -103,6 +101,10 @@ func (s *objectSync) LastUsage() time.Time { return time.Time{} } +func (s *objectSync) HandleRequest(ctx context.Context, hm HandleMessage) (resp *spacesyncproto.ObjectSyncMessage, err error) { + +} + func (s *objectSync) HandleMessage(ctx context.Context, hm HandleMessage) (err error) { threadId := hm.Message.ObjectId hm.ReceiveTime = time.Now() diff --git a/commonspace/objectsync/synchandler/synchhandler.go b/commonspace/objectsync/synchandler/synchhandler.go index 35aebb1e..090118cd 100644 --- a/commonspace/objectsync/synchandler/synchhandler.go +++ b/commonspace/objectsync/synchandler/synchhandler.go @@ -6,5 +6,6 @@ import ( ) type SyncHandler interface { - HandleMessage(ctx context.Context, senderId string, request *spacesyncproto.ObjectSyncMessage) (err error) + HandleMessage(ctx context.Context, senderId string, message *spacesyncproto.ObjectSyncMessage) (err error) + HandleRequest(ctx context.Context, senderId string, request *spacesyncproto.ObjectSyncMessage) (response *spacesyncproto.ObjectSyncMessage, err error) } diff --git a/commonspace/objecttreebuilder/treebuilder.go b/commonspace/objecttreebuilder/treebuilder.go index f77c6ff5..15f9bdbf 100644 --- a/commonspace/objecttreebuilder/treebuilder.go +++ b/commonspace/objecttreebuilder/treebuilder.go @@ -14,8 +14,8 @@ import ( "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" "github.com/anyproto/any-sync/commonspace/object/tree/treestorage" "github.com/anyproto/any-sync/commonspace/objectsync" - "github.com/anyproto/any-sync/commonspace/objectsync/syncclient" "github.com/anyproto/any-sync/commonspace/peermanager" + "github.com/anyproto/any-sync/commonspace/requestmanager" "github.com/anyproto/any-sync/commonspace/spacestate" "github.com/anyproto/any-sync/commonspace/spacestorage" "github.com/anyproto/any-sync/commonspace/syncstatus" @@ -58,10 +58,11 @@ func New() TreeBuilderComponent { } type treeBuilder struct { - syncClient syncclient.SyncClient + syncClient synctree.SyncClient configuration nodeconf.NodeConf headsNotifiable synctree.HeadNotifiable peerManager peermanager.PeerManager + requestManager requestmanager.RequestManager spaceStorage spacestorage.SpaceStorage syncStatus syncstatus.StatusUpdater objectSync objectsync.ObjectSync @@ -81,14 +82,15 @@ func (t *treeBuilder) Init(a *app.App) (err error) { t.treesUsed = state.TreesUsed t.builder = state.TreeBuilderFunc t.aclList = a.MustComponent(syncacl.CName).(*syncacl.SyncAcl) - t.spaceStorage = a.MustComponent(spacestorage.StorageName).(spacestorage.SpaceStorage) + t.spaceStorage = a.MustComponent(spacestorage.CName).(spacestorage.SpaceStorage) t.configuration = a.MustComponent(nodeconf.CName).(nodeconf.NodeConf) t.headsNotifiable = a.MustComponent(headsync.CName).(headsync.HeadSync) t.syncStatus = a.MustComponent(syncstatus.CName).(syncstatus.StatusUpdater) - t.peerManager = a.MustComponent(peermanager.ManagerName).(peermanager.PeerManager) + t.peerManager = a.MustComponent(peermanager.CName).(peermanager.PeerManager) + t.requestManager = a.MustComponent(requestmanager.CName).(requestmanager.RequestManager) t.objectSync = a.MustComponent(objectsync.CName).(objectsync.ObjectSync) - t.syncClient = a.MustComponent(syncclient.CName).(syncclient.SyncClient) t.log = log.With(zap.String("spaceId", t.spaceId)) + t.syncClient = synctree.NewSyncClient(t.spaceId, t.requestManager, t.peerManager) return nil } diff --git a/commonspace/peermanager/peermanager.go b/commonspace/peermanager/peermanager.go index c69e59b3..0a5750bf 100644 --- a/commonspace/peermanager/peermanager.go +++ b/commonspace/peermanager/peermanager.go @@ -9,8 +9,7 @@ import ( ) const ( - ProviderName = "common.commonspace.peermanagerprovider" - ManagerName = "common.commonspace.peermanager" + CName = "common.commonspace.peermanager" ) type PeerManager interface { diff --git a/commonspace/requestmanager/requestmanager.go b/commonspace/requestmanager/requestmanager.go new file mode 100644 index 00000000..e77b4bdb --- /dev/null +++ b/commonspace/requestmanager/requestmanager.go @@ -0,0 +1,49 @@ +package requestmanager + +import ( + "context" + "github.com/anyproto/any-sync/app" + "github.com/anyproto/any-sync/app/logger" + "github.com/anyproto/any-sync/commonspace/spacesyncproto" +) + +const CName = "common.commonspace.requestmanager" + +var log = logger.NewNamed(CName) + +type RequestManager interface { + app.ComponentRunnable + SendRequest(ctx context.Context, peerId string, msg *spacesyncproto.ObjectSyncMessage) (reply *spacesyncproto.ObjectSyncMessage, err error) + QueueRequest(peerId string, msg *spacesyncproto.ObjectSyncMessage) (err error) +} + +func New() RequestManager { + return &requestManager{} +} + +type requestManager struct { +} + +func (r *requestManager) Init(a *app.App) (err error) { + return +} + +func (r *requestManager) Name() (name string) { + return CName +} + +func (r *requestManager) Run(ctx context.Context) (err error) { + return nil +} + +func (r *requestManager) Close(ctx context.Context) (err error) { + return nil +} + +func (r *requestManager) SendRequest(ctx context.Context, peerId string, msg *spacesyncproto.ObjectSyncMessage) (reply *spacesyncproto.ObjectSyncMessage, err error) { + return nil, nil +} + +func (r *requestManager) QueueRequest(peerId string, msg *spacesyncproto.ObjectSyncMessage) (err error) { + return nil +} diff --git a/commonspace/requestsender/requestsender.go b/commonspace/requestsender/requestsender.go deleted file mode 100644 index d7143b4a..00000000 --- a/commonspace/requestsender/requestsender.go +++ /dev/null @@ -1,49 +0,0 @@ -package requestsender - -import ( - "context" - "github.com/anyproto/any-sync/app" - "github.com/anyproto/any-sync/app/logger" - "github.com/anyproto/any-sync/commonspace/spacesyncproto" -) - -const CName = "common.commonspace.requestsender" - -var log = logger.NewNamed(CName) - -type RequestSender interface { - app.ComponentRunnable - SendRequest(ctx context.Context, peerId string, msg *spacesyncproto.ObjectSyncMessage) (reply *spacesyncproto.ObjectSyncMessage, err error) - QueueRequest(peerId string, msg *spacesyncproto.ObjectSyncMessage) (err error) -} - -func New() RequestSender { - return &requestSender{} -} - -type requestSender struct { -} - -func (r *requestSender) Init(a *app.App) (err error) { - return -} - -func (r *requestSender) Name() (name string) { - return CName -} - -func (r *requestSender) Run(ctx context.Context) (err error) { - return nil -} - -func (r *requestSender) Close(ctx context.Context) (err error) { - return nil -} - -func (r *requestSender) SendRequest(ctx context.Context, peerId string, msg *spacesyncproto.ObjectSyncMessage) (reply *spacesyncproto.ObjectSyncMessage, err error) { - return nil, nil -} - -func (r *requestSender) QueueRequest(peerId string, msg *spacesyncproto.ObjectSyncMessage) (err error) { - return nil -} diff --git a/commonspace/settings/settings.go b/commonspace/settings/settings.go index dbc93ccc..eab41709 100644 --- a/commonspace/settings/settings.go +++ b/commonspace/settings/settings.go @@ -55,7 +55,7 @@ func (s *settings) Init(a *app.App) (err error) { s.treeBuilder = a.MustComponent(objecttreebuilder.CName).(objecttreebuilder.TreeBuilderComponent) sharedState := a.MustComponent(spacestate.CName).(*spacestate.SpaceState) - s.storage = a.MustComponent(spacestorage.StorageName).(spacestorage.SpaceStorage) + s.storage = a.MustComponent(spacestorage.CName).(spacestorage.SpaceStorage) s.spaceIsDeleted = sharedState.SpaceIsDeleted deps := Deps{ diff --git a/commonspace/space.go b/commonspace/space.go index 793e7333..02e6d8a9 100644 --- a/commonspace/space.go +++ b/commonspace/space.go @@ -121,7 +121,7 @@ func (s *space) Init(ctx context.Context) (err error) { s.syncStatus = s.app.MustComponent(syncstatus.CName).(syncstatus.StatusProvider) s.settings = s.app.MustComponent(settings.CName).(settings.Settings) s.objectSync = s.app.MustComponent(objectsync.CName).(objectsync.ObjectSync) - s.storage = s.app.MustComponent(spacestorage.StorageName).(spacestorage.SpaceStorage) + s.storage = s.app.MustComponent(spacestorage.CName).(spacestorage.SpaceStorage) return nil } diff --git a/commonspace/spaceservice.go b/commonspace/spaceservice.go index 49b38963..ad536e80 100644 --- a/commonspace/spaceservice.go +++ b/commonspace/spaceservice.go @@ -16,15 +16,13 @@ import ( "github.com/anyproto/any-sync/commonspace/object/treemanager" "github.com/anyproto/any-sync/commonspace/objectmanager" "github.com/anyproto/any-sync/commonspace/objectsync" - "github.com/anyproto/any-sync/commonspace/objectsync/syncclient" "github.com/anyproto/any-sync/commonspace/objecttreebuilder" "github.com/anyproto/any-sync/commonspace/peermanager" - "github.com/anyproto/any-sync/commonspace/requestsender" + "github.com/anyproto/any-sync/commonspace/requestmanager" "github.com/anyproto/any-sync/commonspace/settings" "github.com/anyproto/any-sync/commonspace/spacestate" "github.com/anyproto/any-sync/commonspace/spacestorage" "github.com/anyproto/any-sync/commonspace/spacesyncproto" - "github.com/anyproto/any-sync/commonspace/streamsender" "github.com/anyproto/any-sync/metric" "github.com/anyproto/any-sync/net/peer" "github.com/anyproto/any-sync/net/pool" @@ -69,10 +67,10 @@ type spaceService struct { func (s *spaceService) Init(a *app.App) (err error) { s.config = a.MustComponent("config").(config.ConfigGetter).GetSpace() s.account = a.MustComponent(accountservice.CName).(accountservice.Service) - s.storageProvider = a.MustComponent(spacestorage.ProviderName).(spacestorage.SpaceStorageProvider) + s.storageProvider = a.MustComponent(spacestorage.CName).(spacestorage.SpaceStorageProvider) s.configurationService = a.MustComponent(nodeconf.CName).(nodeconf.Service) s.treeManager = a.MustComponent(treemanager.CName).(treemanager.TreeManager) - s.peermanagerProvider = a.MustComponent(peermanager.ProviderName).(peermanager.PeerManagerProvider) + s.peermanagerProvider = a.MustComponent(peermanager.CName).(peermanager.PeerManagerProvider) s.pool = a.MustComponent(pool.CName).(pool.Pool) s.metric, _ = a.Component(metric.CName).(metric.Metric) s.app = a @@ -172,12 +170,10 @@ func (s *spaceService) NewSpace(ctx context.Context, id string) (Space, error) { Register(peerManager). Register(newCommonStorage(st)). Register(syncacl.New()). - Register(streamsender.New()). - Register(requestsender.New()). + Register(requestmanager.New()). Register(deletionstate.New()). Register(settings.New()). Register(objectmanager.New(s.treeManager)). - Register(syncclient.New()). Register(objecttreebuilder.New()). Register(objectsync.New()). Register(headsync.New()) diff --git a/commonspace/spacestorage/inmemoryprovider.go b/commonspace/spacestorage/inmemoryprovider.go index 1cceb53c..3ddfe02a 100644 --- a/commonspace/spacestorage/inmemoryprovider.go +++ b/commonspace/spacestorage/inmemoryprovider.go @@ -22,7 +22,7 @@ func (i *InMemorySpaceStorageProvider) Init(a *app.App) (err error) { } func (i *InMemorySpaceStorageProvider) Name() (name string) { - return ProviderName + return CName } func (i *InMemorySpaceStorageProvider) WaitSpaceStorage(ctx context.Context, id string) (SpaceStorage, error) { diff --git a/commonspace/spacestorage/inmemorystorage.go b/commonspace/spacestorage/inmemorystorage.go index bc2846fb..db1d1166 100644 --- a/commonspace/spacestorage/inmemorystorage.go +++ b/commonspace/spacestorage/inmemorystorage.go @@ -27,7 +27,7 @@ func (i *InMemorySpaceStorage) Init(a *app.App) (err error) { } func (i *InMemorySpaceStorage) Name() (name string) { - return StorageName + return CName } func NewInMemorySpaceStorage(payload SpaceStorageCreatePayload) (SpaceStorage, error) { diff --git a/commonspace/spacestorage/spacestorage.go b/commonspace/spacestorage/spacestorage.go index b6b73fdc..a4ffaecb 100644 --- a/commonspace/spacestorage/spacestorage.go +++ b/commonspace/spacestorage/spacestorage.go @@ -12,10 +12,7 @@ import ( "github.com/anyproto/any-sync/commonspace/spacesyncproto" ) -const ( - ProviderName = "common.commonspace.spacestorageprovider" - StorageName = "common.commonspace.spacestorage" -) +const CName = "common.commonspace.spacestorage" var ( ErrSpaceStorageExists = errors.New("space storage exists") diff --git a/commonspace/spaceutils_test.go b/commonspace/spaceutils_test.go index f26f4881..261a48a3 100644 --- a/commonspace/spaceutils_test.go +++ b/commonspace/spaceutils_test.go @@ -136,7 +136,7 @@ func (p *mockPeerManager) Init(a *app.App) (err error) { } func (p *mockPeerManager) Name() (name string) { - return peermanager.ManagerName + return peermanager.CName } func (p *mockPeerManager) SendPeer(ctx context.Context, peerId string, msg *spacesyncproto.ObjectSyncMessage) (err error) { @@ -163,7 +163,7 @@ func (m *mockPeerManagerProvider) Init(a *app.App) (err error) { } func (m *mockPeerManagerProvider) Name() (name string) { - return peermanager.ProviderName + return peermanager.CName } func (m *mockPeerManagerProvider) NewPeerManager(ctx context.Context, spaceId string) (sm peermanager.PeerManager, err error) { diff --git a/commonspace/streamsender/streamsender.go b/commonspace/streamsender/streamsender.go deleted file mode 100644 index 99a45f5c..00000000 --- a/commonspace/streamsender/streamsender.go +++ /dev/null @@ -1,37 +0,0 @@ -package streamsender - -import ( - "github.com/anyproto/any-sync/app" - "github.com/anyproto/any-sync/commonspace/spacesyncproto" -) - -const CName = "common.commonspace.streamsender" - -type StreamSender interface { - app.Component - SendPeer(peerId string, msg *spacesyncproto.ObjectSyncMessage) (err error) - Broadcast(msg *spacesyncproto.ObjectSyncMessage) (err error) -} - -func New() StreamSender { - return &streamSender{} -} - -type streamSender struct { -} - -func (s *streamSender) Init(a *app.App) (err error) { - return -} - -func (s *streamSender) Name() (name string) { - return CName -} - -func (s *streamSender) SendPeer(peerId string, msg *spacesyncproto.ObjectSyncMessage) (err error) { - return nil -} - -func (s *streamSender) Broadcast(msg *spacesyncproto.ObjectSyncMessage) (err error) { - return nil -} diff --git a/commonspace/syncstatus/syncstatus.go b/commonspace/syncstatus/syncstatus.go index acdbc298..2049c42b 100644 --- a/commonspace/syncstatus/syncstatus.go +++ b/commonspace/syncstatus/syncstatus.go @@ -104,7 +104,7 @@ func (s *syncStatusProvider) Init(a *app.App) (err error) { s.updateTimeout = syncTimeout s.spaceId = sharedState.SpaceId s.configuration = a.MustComponent(nodeconf.CName).(nodeconf.NodeConf) - s.storage = a.MustComponent(spacestorage.StorageName).(spacestorage.SpaceStorage) + s.storage = a.MustComponent(spacestorage.CName).(spacestorage.SpaceStorage) return } From 990cbc58b648f85261d7760a51e7a574772e0e8b Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Sat, 3 Jun 2023 22:41:03 +0200 Subject: [PATCH 007/123] Add sync requests handling --- commonspace/objectsync/objectsync.go | 64 ++++++++++++++++++++++++---- commonspace/space.go | 5 +++ 2 files changed, 61 insertions(+), 8 deletions(-) diff --git a/commonspace/objectsync/objectsync.go b/commonspace/objectsync/objectsync.go index 44e5308c..9e3c3eba 100644 --- a/commonspace/objectsync/objectsync.go +++ b/commonspace/objectsync/objectsync.go @@ -5,11 +5,13 @@ import ( "context" "fmt" "github.com/anyproto/any-sync/app" + "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" "github.com/anyproto/any-sync/commonspace/spacestate" "github.com/anyproto/any-sync/metric" "github.com/anyproto/any-sync/net/peer" "github.com/anyproto/any-sync/util/multiqueue" "github.com/cheggaaa/mb/v3" + "github.com/gogo/protobuf/proto" "sync/atomic" "time" @@ -102,18 +104,12 @@ func (s *objectSync) LastUsage() time.Time { } func (s *objectSync) HandleRequest(ctx context.Context, hm HandleMessage) (resp *spacesyncproto.ObjectSyncMessage, err error) { - + return s.handleRequest(ctx, hm.SenderId, hm.Message) } func (s *objectSync) HandleMessage(ctx context.Context, hm HandleMessage) (err error) { threadId := hm.Message.ObjectId hm.ReceiveTime = time.Now() - if hm.Message.ReplyId != "" { - threadId += hm.Message.ReplyId - defer func() { - _ = s.handleQueue.CloseThread(threadId) - }() - } if hm.PeerCtx == nil { hm.PeerCtx = ctx } @@ -160,6 +156,29 @@ func (s *objectSync) processHandleMessage(msg HandleMessage) { } } +func (s *objectSync) handleRequest(ctx context.Context, senderId string, msg *spacesyncproto.ObjectSyncMessage) (response *spacesyncproto.ObjectSyncMessage, err error) { + log := log.With( + zap.String("objectId", msg.ObjectId), + zap.String("requestId", msg.RequestId), + zap.String("replyId", msg.ReplyId)) + if s.spaceIsDeleted.Load() { + log = log.With(zap.Bool("isDeleted", true)) + // preventing sync with other clients if they are not just syncing the settings tree + if !slices.Contains(s.configuration.NodeIds(s.spaceId), senderId) && msg.ObjectId != s.spaceStorage.SpaceSettingsId() { + return nil, spacesyncproto.ErrSpaceIsDeleted + } + } + err = s.checkEmptyFullSync(log, msg) + if err != nil { + return nil, err + } + obj, err := s.objectGetter.GetObject(ctx, msg.ObjectId) + if err != nil { + return nil, treechangeproto.ErrGetTree + } + return obj.HandleRequest(ctx, senderId, msg) +} + func (s *objectSync) handleMessage(ctx context.Context, senderId string, msg *spacesyncproto.ObjectSyncMessage) (err error) { log := log.With( zap.String("objectId", msg.ObjectId), @@ -169,9 +188,13 @@ func (s *objectSync) handleMessage(ctx context.Context, senderId string, msg *sp log = log.With(zap.Bool("isDeleted", true)) // preventing sync with other clients if they are not just syncing the settings tree if !slices.Contains(s.configuration.NodeIds(s.spaceId), senderId) && msg.ObjectId != s.spaceStorage.SpaceSettingsId() { - return fmt.Errorf("can't perform operation with object, space is deleted") + return spacesyncproto.ErrSpaceIsDeleted } } + err = s.checkEmptyFullSync(log, msg) + if err != nil { + return err + } obj, err := s.objectGetter.GetObject(ctx, msg.ObjectId) if err != nil { return fmt.Errorf("failed to get object from cache: %w", err) @@ -186,3 +209,28 @@ func (s *objectSync) handleMessage(ctx context.Context, senderId string, msg *sp func (s *objectSync) CloseThread(id string) (err error) { return s.handleQueue.CloseThread(id) } + +func (s *objectSync) checkEmptyFullSync(log logger.CtxLogger, msg *spacesyncproto.ObjectSyncMessage) (err error) { + hasTree, err := s.spaceStorage.HasTree(msg.ObjectId) + if err != nil { + log.Warn("failed to execute get operation on storage has tree", zap.Error(err)) + return spacesyncproto.ErrUnexpected + } + // in this case we will try to get it from remote, unless the sender also sent us the same request :-) + if !hasTree { + treeMsg := &treechangeproto.TreeSyncMessage{} + err = proto.Unmarshal(msg.Payload, treeMsg) + if err != nil { + return nil + } + // this means that we don't have the tree locally and therefore can't return it + if s.isEmptyFullSyncRequest(treeMsg) { + return treechangeproto.ErrGetTree + } + } + return +} + +func (s *objectSync) isEmptyFullSyncRequest(msg *treechangeproto.TreeSyncMessage) bool { + return msg.GetContent().GetFullSyncRequest() != nil && len(msg.GetContent().GetFullSyncRequest().GetHeads()) == 0 +} diff --git a/commonspace/space.go b/commonspace/space.go index 02e6d8a9..32b1b04d 100644 --- a/commonspace/space.go +++ b/commonspace/space.go @@ -67,6 +67,7 @@ type Space interface { DeleteSpace(ctx context.Context, deleteChange *treechangeproto.RawTreeChangeWithId) (err error) HandleMessage(ctx context.Context, msg objectsync.HandleMessage) (err error) + HandleRequest(ctx context.Context, msg objectsync.HandleMessage) (resp *spacesyncproto.ObjectSyncMessage, err error) TryClose(objectTTL time.Duration) (close bool, err error) Close() error @@ -103,6 +104,10 @@ func (s *space) HandleMessage(ctx context.Context, msg objectsync.HandleMessage) return s.objectSync.HandleMessage(ctx, msg) } +func (s *space) HandleRequest(ctx context.Context, msg objectsync.HandleMessage) (resp *spacesyncproto.ObjectSyncMessage, err error) { + return s.objectSync.HandleRequest(ctx, msg) +} + func (s *space) TreeBuilder() objecttreebuilder.TreeBuilder { return s.treeBuilder } From ce63951ae6659533c858212ff1821deb4ce7b8f4 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Sat, 3 Jun 2023 22:48:16 +0200 Subject: [PATCH 008/123] Update proto files --- .../spacesyncproto/protos/spacesync.proto | 2 + commonspace/spacesyncproto/spacesync.pb.go | 136 +++++++++--------- .../spacesyncproto/spacesync_drpc.pb.go | 42 +++++- 3 files changed, 111 insertions(+), 69 deletions(-) diff --git a/commonspace/spacesyncproto/protos/spacesync.proto b/commonspace/spacesyncproto/protos/spacesync.proto index d5b461cf..f7f44ae4 100644 --- a/commonspace/spacesyncproto/protos/spacesync.proto +++ b/commonspace/spacesyncproto/protos/spacesync.proto @@ -23,6 +23,8 @@ service SpaceSync { rpc SpacePull(SpacePullRequest) returns (SpacePullResponse); // ObjectSyncStream opens object sync stream with node or client rpc ObjectSyncStream(stream ObjectSyncMessage) returns (stream ObjectSyncMessage); + // ObjectSync sends object sync message and synchronously gets response message + rpc ObjectSync(ObjectSyncMessage) returns (ObjectSyncMessage); } // HeadSyncRange presenting a request for one range diff --git a/commonspace/spacesyncproto/spacesync.pb.go b/commonspace/spacesyncproto/spacesync.pb.go index 33caed5b..80571bf6 100644 --- a/commonspace/spacesyncproto/spacesync.pb.go +++ b/commonspace/spacesyncproto/spacesync.pb.go @@ -1254,75 +1254,75 @@ func init() { } var fileDescriptor_80e49f1f4ac27799 = []byte{ - // 1077 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0xcd, 0x6e, 0xdb, 0x46, - 0x10, 0x16, 0xe9, 0x5f, 0x8d, 0x65, 0x99, 0xd9, 0x28, 0x89, 0xaa, 0x18, 0x8a, 0xb0, 0x28, 0x0a, - 0x23, 0x07, 0x27, 0xb1, 0x8b, 0x02, 0x49, 0xdb, 0x43, 0x62, 0x3b, 0x0d, 0x51, 0x24, 0x36, 0x56, + // 1083 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0xcd, 0x6e, 0xdb, 0x46, + 0x10, 0x16, 0xe9, 0x5f, 0x8d, 0x65, 0x85, 0xd9, 0x28, 0x89, 0xaa, 0x18, 0x8a, 0xb0, 0x28, 0x0a, + 0x23, 0x07, 0x27, 0xb1, 0x8b, 0x02, 0x49, 0xdb, 0x43, 0x62, 0x3b, 0x35, 0x51, 0x24, 0x36, 0x56, 0x0d, 0x0a, 0x14, 0xc8, 0x61, 0x4d, 0x8e, 0x2d, 0xb6, 0x14, 0xc9, 0x72, 0x57, 0x89, 0x75, 0xec, - 0xa9, 0xd7, 0x9e, 0xdb, 0x07, 0xe8, 0x0b, 0xf4, 0x21, 0x7a, 0x4c, 0x6f, 0x3d, 0x16, 0xf6, 0x8b, - 0x14, 0xbb, 0x5c, 0xfe, 0xc8, 0xa2, 0x02, 0xe4, 0x22, 0xed, 0x7e, 0x33, 0xf3, 0xcd, 0xdf, 0xee, - 0x0e, 0xe1, 0x91, 0x17, 0x8f, 0xc7, 0x71, 0x24, 0x12, 0xee, 0xe1, 0x03, 0xfd, 0x2b, 0xa6, 0x91, - 0x97, 0xa4, 0xb1, 0x8c, 0x1f, 0xe8, 0x5f, 0x51, 0xa2, 0xbb, 0x1a, 0x20, 0xcd, 0x02, 0xa0, 0x2e, - 0x6c, 0xbe, 0x40, 0xee, 0x0f, 0xa7, 0x91, 0xc7, 0x78, 0x74, 0x8e, 0x84, 0xc0, 0xf2, 0x59, 0x1a, - 0x8f, 0xbb, 0xd6, 0xc0, 0xda, 0x59, 0x66, 0x7a, 0x4d, 0xda, 0x60, 0xcb, 0xb8, 0x6b, 0x6b, 0xc4, - 0x96, 0x31, 0xe9, 0xc0, 0x4a, 0x18, 0x8c, 0x03, 0xd9, 0x5d, 0x1a, 0x58, 0x3b, 0x9b, 0x2c, 0xdb, - 0xd0, 0x0b, 0x68, 0x17, 0x54, 0x28, 0x26, 0xa1, 0x54, 0x5c, 0x23, 0x2e, 0x46, 0x9a, 0xab, 0xc5, - 0xf4, 0x9a, 0x7c, 0x05, 0xeb, 0x18, 0xe2, 0x18, 0x23, 0x29, 0xba, 0xf6, 0x60, 0x69, 0x67, 0x63, - 0x6f, 0xb0, 0x5b, 0xc6, 0x37, 0x4b, 0x70, 0x94, 0x29, 0xb2, 0xc2, 0x42, 0x79, 0xf6, 0xe2, 0x49, - 0x54, 0x78, 0xd6, 0x1b, 0xfa, 0x25, 0xdc, 0xaa, 0x35, 0x54, 0x81, 0x07, 0xbe, 0x76, 0xdf, 0x64, - 0x76, 0xe0, 0xeb, 0x80, 0x90, 0xfb, 0x3a, 0x95, 0x26, 0xd3, 0x6b, 0xfa, 0x06, 0xb6, 0x4a, 0xe3, - 0x9f, 0x27, 0x28, 0x24, 0xe9, 0xc2, 0x9a, 0x0e, 0xc9, 0xcd, 0x6d, 0xf3, 0x2d, 0x79, 0x08, 0xab, - 0xa9, 0x2a, 0x53, 0x1e, 0x7b, 0xb7, 0x2e, 0x76, 0xa5, 0xc0, 0x8c, 0x1e, 0xfd, 0x06, 0x9c, 0x4a, - 0x6c, 0x49, 0x1c, 0x09, 0x24, 0xfb, 0xb0, 0x96, 0xea, 0x38, 0x45, 0xd7, 0xd2, 0x34, 0x9f, 0x2c, - 0x2c, 0x01, 0xcb, 0x35, 0xe9, 0x1f, 0x16, 0xdc, 0x38, 0x3e, 0xfd, 0x11, 0x3d, 0xa9, 0xa4, 0x2f, - 0x51, 0x08, 0x7e, 0x8e, 0x1f, 0x08, 0x75, 0x1b, 0x9a, 0x69, 0x96, 0x8f, 0x9b, 0x27, 0x5c, 0x02, - 0xca, 0x2e, 0xc5, 0x24, 0x9c, 0xba, 0xbe, 0x2e, 0x65, 0x93, 0xe5, 0x5b, 0x25, 0x49, 0xf8, 0x34, - 0x8c, 0xb9, 0xdf, 0x5d, 0xd6, 0x7d, 0xcb, 0xb7, 0xa4, 0x07, 0xeb, 0xb1, 0x0e, 0xc0, 0xf5, 0xbb, - 0x2b, 0xda, 0xa8, 0xd8, 0x53, 0x04, 0x67, 0xa8, 0x1c, 0x9f, 0x4c, 0xc4, 0x28, 0x2f, 0xe3, 0xa3, - 0x92, 0x49, 0xc5, 0xb6, 0xb1, 0x77, 0xa7, 0x92, 0x66, 0xa6, 0x9d, 0x89, 0x4b, 0x17, 0x7d, 0x80, - 0x83, 0x14, 0x7d, 0x8c, 0x64, 0xc0, 0x43, 0x1d, 0x75, 0x8b, 0x55, 0x10, 0x7a, 0x13, 0x6e, 0x54, - 0xdc, 0x64, 0xe5, 0xa4, 0xb4, 0xf0, 0x1d, 0x86, 0xb9, 0xef, 0x6b, 0x9d, 0xa7, 0xcf, 0x0b, 0x43, - 0xa5, 0x63, 0xfa, 0xf0, 0xf1, 0x01, 0xd2, 0x5f, 0x6c, 0x68, 0x55, 0x25, 0xe4, 0x29, 0x6c, 0x68, - 0x1b, 0xd5, 0x36, 0x4c, 0x0d, 0xcf, 0xbd, 0x0a, 0x0f, 0xe3, 0xef, 0x86, 0xa5, 0xc2, 0xf7, 0x81, - 0x1c, 0xb9, 0x3e, 0xab, 0xda, 0xa8, 0xa4, 0xb9, 0x17, 0x1a, 0xc2, 0x3c, 0xe9, 0x12, 0x21, 0x14, - 0x5a, 0xe5, 0xae, 0x68, 0xd8, 0x0c, 0x46, 0xf6, 0xa0, 0xa3, 0x29, 0x87, 0x28, 0x65, 0x10, 0x9d, - 0x8b, 0x93, 0x99, 0x16, 0xd6, 0xca, 0xc8, 0x17, 0x70, 0xbb, 0x0e, 0x2f, 0xba, 0xbb, 0x40, 0x4a, - 0xff, 0xb1, 0x60, 0xa3, 0x92, 0x92, 0x3a, 0x17, 0x81, 0x6e, 0x90, 0x9c, 0x9a, 0xab, 0x5e, 0xec, - 0xd5, 0x29, 0x94, 0xc1, 0x18, 0x85, 0xe4, 0xe3, 0x44, 0xa7, 0xb6, 0xc4, 0x4a, 0x40, 0x49, 0xb5, - 0x8f, 0xef, 0xa6, 0x09, 0x9a, 0xb4, 0x4a, 0x80, 0x7c, 0x06, 0x6d, 0x75, 0x28, 0x03, 0x8f, 0xcb, - 0x20, 0x8e, 0xbe, 0xc5, 0xa9, 0xce, 0x66, 0x99, 0x5d, 0x43, 0xd5, 0xad, 0x16, 0x88, 0x59, 0xd4, - 0x2d, 0xa6, 0xd7, 0x64, 0x17, 0x48, 0xa5, 0xc4, 0x79, 0x35, 0x56, 0xb5, 0x46, 0x8d, 0x84, 0x9e, - 0x40, 0x7b, 0xb6, 0x51, 0x64, 0x30, 0xdf, 0xd8, 0xd6, 0x6c, 0xdf, 0x54, 0xf4, 0xc1, 0x79, 0xc4, - 0xe5, 0x24, 0x45, 0xd3, 0xb6, 0x12, 0xa0, 0x87, 0xd0, 0xa9, 0x6b, 0xbd, 0xbe, 0x97, 0xfc, 0xdd, - 0x0c, 0x6b, 0x09, 0x98, 0x73, 0x6b, 0x17, 0xe7, 0xf6, 0x77, 0x0b, 0x3a, 0xc3, 0x6a, 0x1b, 0x0e, - 0xe2, 0x48, 0xaa, 0xa7, 0xed, 0x6b, 0x68, 0x65, 0x97, 0xef, 0x10, 0x43, 0x94, 0x58, 0x73, 0x80, - 0x8f, 0x2b, 0xe2, 0x17, 0x0d, 0x36, 0xa3, 0x4e, 0x9e, 0x98, 0xec, 0x8c, 0xb5, 0xad, 0xad, 0x6f, - 0x5f, 0x3f, 0xfe, 0x85, 0x71, 0x55, 0xf9, 0xd9, 0x1a, 0xac, 0xbc, 0xe5, 0xe1, 0x04, 0x69, 0x1f, - 0x5a, 0x55, 0x27, 0x73, 0x97, 0x6e, 0xdf, 0x9c, 0x13, 0x23, 0xfe, 0x14, 0x36, 0x7d, 0xbd, 0x4a, - 0x4f, 0x10, 0xd3, 0xe2, 0xc5, 0x9a, 0x05, 0xe9, 0x1b, 0xb8, 0x35, 0x93, 0xf0, 0x30, 0xe2, 0x89, - 0x18, 0xc5, 0x52, 0x5d, 0x93, 0x4c, 0xd3, 0x77, 0xfd, 0xec, 0xe1, 0x6c, 0xb2, 0x0a, 0x32, 0x4f, - 0x6f, 0xd7, 0xd1, 0xff, 0x6a, 0x41, 0x2b, 0xa7, 0x3e, 0xe4, 0x92, 0x93, 0xc7, 0xb0, 0xe6, 0x65, - 0x35, 0x35, 0x8f, 0xf1, 0xbd, 0xeb, 0x55, 0xb8, 0x56, 0x7a, 0x96, 0xeb, 0xab, 0x59, 0x26, 0x4c, - 0x74, 0xa6, 0x82, 0x83, 0x45, 0xb6, 0x79, 0x16, 0xac, 0xb0, 0xa0, 0x3f, 0x99, 0x27, 0x69, 0x38, - 0x39, 0x15, 0x5e, 0x1a, 0x24, 0xea, 0x38, 0xab, 0xbb, 0x64, 0x1e, 0xf0, 0x3c, 0xc5, 0x62, 0x4f, - 0x9e, 0xc0, 0x2a, 0xf7, 0x94, 0x96, 0x76, 0xd6, 0xde, 0xa3, 0x73, 0xce, 0x2a, 0x4c, 0x4f, 0xb5, - 0x26, 0x33, 0x16, 0xf7, 0xff, 0xb4, 0x60, 0xfd, 0x28, 0x4d, 0x0f, 0x62, 0x1f, 0x05, 0x69, 0x03, - 0xbc, 0x8e, 0xf0, 0x22, 0x41, 0x4f, 0xa2, 0xef, 0x34, 0x88, 0x63, 0xde, 0xb4, 0x97, 0x81, 0x10, - 0x41, 0x74, 0xee, 0x58, 0x64, 0xcb, 0x74, 0xee, 0xe8, 0x22, 0x10, 0x52, 0x38, 0x36, 0xb9, 0x09, - 0x5b, 0x1a, 0x78, 0x15, 0x4b, 0x37, 0x3a, 0xe0, 0xde, 0x08, 0x9d, 0x25, 0x42, 0xa0, 0xad, 0x41, - 0x57, 0x64, 0x1d, 0xf6, 0x9d, 0x65, 0xd2, 0x85, 0x8e, 0xae, 0xb4, 0x78, 0x15, 0x4b, 0xf3, 0xd0, - 0x06, 0xa7, 0x21, 0x3a, 0x2b, 0xa4, 0x03, 0x0e, 0x43, 0x0f, 0x83, 0x44, 0xba, 0xc2, 0x8d, 0xde, - 0xf2, 0x30, 0xf0, 0x9d, 0x55, 0xe5, 0xe9, 0x28, 0x4d, 0xe3, 0xf4, 0xf8, 0xec, 0x4c, 0xa0, 0x74, - 0xfc, 0xfb, 0x8f, 0xe1, 0xce, 0x82, 0x64, 0xc8, 0x26, 0x34, 0x0d, 0x7a, 0x8a, 0x4e, 0x43, 0x99, - 0xbe, 0x8e, 0x44, 0x01, 0x58, 0x7b, 0x7f, 0xd9, 0xd0, 0xcc, 0x6c, 0xa7, 0x91, 0x47, 0x0e, 0x60, - 0x3d, 0x9f, 0xa5, 0xa4, 0x57, 0x3b, 0x60, 0xf5, 0xa8, 0xe8, 0xdd, 0xad, 0x1f, 0xbe, 0xd9, 0x88, - 0x78, 0x6e, 0x18, 0xd5, 0xc0, 0x21, 0x77, 0xe7, 0xc6, 0x43, 0x39, 0xed, 0x7a, 0xdb, 0xf5, 0xc2, - 0x39, 0x9e, 0x30, 0xac, 0xe3, 0x29, 0x26, 0x57, 0x1d, 0x4f, 0x65, 0x64, 0x31, 0x70, 0xca, 0x8f, - 0x80, 0xa1, 0x4c, 0x91, 0x8f, 0xc9, 0xf6, 0xdc, 0xa5, 0xaf, 0x7c, 0x21, 0xf4, 0x3e, 0x28, 0xdd, - 0xb1, 0x1e, 0x5a, 0xcf, 0x3e, 0xff, 0xfb, 0xb2, 0x6f, 0xbd, 0xbf, 0xec, 0x5b, 0xff, 0x5d, 0xf6, - 0xad, 0xdf, 0xae, 0xfa, 0x8d, 0xf7, 0x57, 0xfd, 0xc6, 0xbf, 0x57, 0xfd, 0xc6, 0x0f, 0xbd, 0xc5, - 0xdf, 0x96, 0xa7, 0xab, 0xfa, 0x6f, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd3, 0x01, 0xff, - 0xb5, 0x80, 0x0a, 0x00, 0x00, + 0xa9, 0xd7, 0x9e, 0xdb, 0x07, 0xe8, 0xab, 0xf4, 0x98, 0xde, 0x7a, 0x2c, 0xec, 0xf7, 0x28, 0x8a, + 0x5d, 0x2e, 0x7f, 0x64, 0x51, 0x01, 0x8a, 0x5e, 0xa4, 0xdd, 0x6f, 0x66, 0xbe, 0xf9, 0xdb, 0xdd, + 0x21, 0x3c, 0xf6, 0xe2, 0xf1, 0x38, 0x8e, 0x44, 0xc2, 0x3d, 0x7c, 0xa8, 0x7f, 0xc5, 0x34, 0xf2, + 0x92, 0x34, 0x96, 0xf1, 0x43, 0xfd, 0x2b, 0x4a, 0x74, 0x47, 0x03, 0xa4, 0x59, 0x00, 0xd4, 0x85, + 0xcd, 0x23, 0xe4, 0xfe, 0x70, 0x1a, 0x79, 0x8c, 0x47, 0xe7, 0x48, 0x08, 0x2c, 0x9f, 0xa5, 0xf1, + 0xb8, 0x6b, 0x0d, 0xac, 0xed, 0x65, 0xa6, 0xd7, 0xa4, 0x0d, 0xb6, 0x8c, 0xbb, 0xb6, 0x46, 0x6c, + 0x19, 0x93, 0x0e, 0xac, 0x84, 0xc1, 0x38, 0x90, 0xdd, 0xa5, 0x81, 0xb5, 0xbd, 0xc9, 0xb2, 0x0d, + 0xbd, 0x80, 0x76, 0x41, 0x85, 0x62, 0x12, 0x4a, 0xc5, 0x35, 0xe2, 0x62, 0xa4, 0xb9, 0x5a, 0x4c, + 0xaf, 0xc9, 0x17, 0xb0, 0x8e, 0x21, 0x8e, 0x31, 0x92, 0xa2, 0x6b, 0x0f, 0x96, 0xb6, 0x37, 0x76, + 0x07, 0x3b, 0x65, 0x7c, 0xb3, 0x04, 0x87, 0x99, 0x22, 0x2b, 0x2c, 0x94, 0x67, 0x2f, 0x9e, 0x44, + 0x85, 0x67, 0xbd, 0xa1, 0x9f, 0xc3, 0xed, 0x5a, 0x43, 0x15, 0x78, 0xe0, 0x6b, 0xf7, 0x4d, 0x66, + 0x07, 0xbe, 0x0e, 0x08, 0xb9, 0xaf, 0x53, 0x69, 0x32, 0xbd, 0xa6, 0x6f, 0xe0, 0x46, 0x69, 0xfc, + 0xe3, 0x04, 0x85, 0x24, 0x5d, 0x58, 0xd3, 0x21, 0xb9, 0xb9, 0x6d, 0xbe, 0x25, 0x8f, 0x60, 0x35, + 0x55, 0x65, 0xca, 0x63, 0xef, 0xd6, 0xc5, 0xae, 0x14, 0x98, 0xd1, 0xa3, 0x5f, 0x81, 0x53, 0x89, + 0x2d, 0x89, 0x23, 0x81, 0x64, 0x0f, 0xd6, 0x52, 0x1d, 0xa7, 0xe8, 0x5a, 0x9a, 0xe6, 0xa3, 0x85, + 0x25, 0x60, 0xb9, 0x26, 0xfd, 0xcd, 0x82, 0x9b, 0xc7, 0xa7, 0xdf, 0xa3, 0x27, 0x95, 0xf4, 0x25, + 0x0a, 0xc1, 0xcf, 0xf1, 0x03, 0xa1, 0x6e, 0x41, 0x33, 0xcd, 0xf2, 0x71, 0xf3, 0x84, 0x4b, 0x40, + 0xd9, 0xa5, 0x98, 0x84, 0x53, 0xd7, 0xd7, 0xa5, 0x6c, 0xb2, 0x7c, 0xab, 0x24, 0x09, 0x9f, 0x86, + 0x31, 0xf7, 0xbb, 0xcb, 0xba, 0x6f, 0xf9, 0x96, 0xf4, 0x60, 0x3d, 0xd6, 0x01, 0xb8, 0x7e, 0x77, + 0x45, 0x1b, 0x15, 0x7b, 0x8a, 0xe0, 0x0c, 0x95, 0xe3, 0x93, 0x89, 0x18, 0xe5, 0x65, 0x7c, 0x5c, + 0x32, 0xa9, 0xd8, 0x36, 0x76, 0xef, 0x56, 0xd2, 0xcc, 0xb4, 0x33, 0x71, 0xe9, 0xa2, 0x0f, 0xb0, + 0x9f, 0xa2, 0x8f, 0x91, 0x0c, 0x78, 0xa8, 0xa3, 0x6e, 0xb1, 0x0a, 0x42, 0x6f, 0xc1, 0xcd, 0x8a, + 0x9b, 0xac, 0x9c, 0x94, 0x16, 0xbe, 0xc3, 0x30, 0xf7, 0x7d, 0xad, 0xf3, 0xf4, 0x45, 0x61, 0xa8, + 0x74, 0x4c, 0x1f, 0xfe, 0x7b, 0x80, 0xf4, 0x27, 0x1b, 0x5a, 0x55, 0x09, 0x79, 0x06, 0x1b, 0xda, + 0x46, 0xb5, 0x0d, 0x53, 0xc3, 0x73, 0xbf, 0xc2, 0xc3, 0xf8, 0xbb, 0x61, 0xa9, 0xf0, 0x6d, 0x20, + 0x47, 0xae, 0xcf, 0xaa, 0x36, 0x2a, 0x69, 0xee, 0x85, 0x86, 0x30, 0x4f, 0xba, 0x44, 0x08, 0x85, + 0x56, 0xb9, 0x2b, 0x1a, 0x36, 0x83, 0x91, 0x5d, 0xe8, 0x68, 0xca, 0x21, 0x4a, 0x19, 0x44, 0xe7, + 0xe2, 0x64, 0xa6, 0x85, 0xb5, 0x32, 0xf2, 0x19, 0xdc, 0xa9, 0xc3, 0x8b, 0xee, 0x2e, 0x90, 0xd2, + 0x3f, 0x2d, 0xd8, 0xa8, 0xa4, 0xa4, 0xce, 0x45, 0xa0, 0x1b, 0x24, 0xa7, 0xe6, 0xaa, 0x17, 0x7b, + 0x75, 0x0a, 0x65, 0x30, 0x46, 0x21, 0xf9, 0x38, 0xd1, 0xa9, 0x2d, 0xb1, 0x12, 0x50, 0x52, 0xed, + 0xe3, 0x9b, 0x69, 0x82, 0x26, 0xad, 0x12, 0x20, 0x9f, 0x40, 0x5b, 0x1d, 0xca, 0xc0, 0xe3, 0x32, + 0x88, 0xa3, 0xaf, 0x71, 0xaa, 0xb3, 0x59, 0x66, 0xd7, 0x50, 0x75, 0xab, 0x05, 0x62, 0x16, 0x75, + 0x8b, 0xe9, 0x35, 0xd9, 0x01, 0x52, 0x29, 0x71, 0x5e, 0x8d, 0x55, 0xad, 0x51, 0x23, 0xa1, 0x27, + 0xd0, 0x9e, 0x6d, 0x14, 0x19, 0xcc, 0x37, 0xb6, 0x35, 0xdb, 0x37, 0x15, 0x7d, 0x70, 0x1e, 0x71, + 0x39, 0x49, 0xd1, 0xb4, 0xad, 0x04, 0xe8, 0x01, 0x74, 0xea, 0x5a, 0xaf, 0xef, 0x25, 0x7f, 0x37, + 0xc3, 0x5a, 0x02, 0xe6, 0xdc, 0xda, 0xc5, 0xb9, 0xfd, 0xd5, 0x82, 0xce, 0xb0, 0xda, 0x86, 0xfd, + 0x38, 0x92, 0xea, 0x69, 0xfb, 0x12, 0x5a, 0xd9, 0xe5, 0x3b, 0xc0, 0x10, 0x25, 0xd6, 0x1c, 0xe0, + 0xe3, 0x8a, 0xf8, 0xa8, 0xc1, 0x66, 0xd4, 0xc9, 0x53, 0x93, 0x9d, 0xb1, 0xb6, 0xb5, 0xf5, 0x9d, + 0xeb, 0xc7, 0xbf, 0x30, 0xae, 0x2a, 0x3f, 0x5f, 0x83, 0x95, 0xb7, 0x3c, 0x9c, 0x20, 0xed, 0x43, + 0xab, 0xea, 0x64, 0xee, 0xd2, 0xed, 0x99, 0x73, 0x62, 0xc4, 0x1f, 0xc3, 0xa6, 0xaf, 0x57, 0xe9, + 0x09, 0x62, 0x5a, 0xbc, 0x58, 0xb3, 0x20, 0x7d, 0x03, 0xb7, 0x67, 0x12, 0x1e, 0x46, 0x3c, 0x11, + 0xa3, 0x58, 0xaa, 0x6b, 0x92, 0x69, 0xfa, 0xae, 0x9f, 0x3d, 0x9c, 0x4d, 0x56, 0x41, 0xe6, 0xe9, + 0xed, 0x3a, 0xfa, 0x9f, 0x2d, 0x68, 0xe5, 0xd4, 0x07, 0x5c, 0x72, 0xf2, 0x04, 0xd6, 0xbc, 0xac, + 0xa6, 0xe6, 0x31, 0xbe, 0x7f, 0xbd, 0x0a, 0xd7, 0x4a, 0xcf, 0x72, 0x7d, 0x35, 0xcb, 0x84, 0x89, + 0xce, 0x54, 0x70, 0xb0, 0xc8, 0x36, 0xcf, 0x82, 0x15, 0x16, 0xf4, 0x07, 0xf3, 0x24, 0x0d, 0x27, + 0xa7, 0xc2, 0x4b, 0x83, 0x44, 0x1d, 0x67, 0x75, 0x97, 0xcc, 0x03, 0x9e, 0xa7, 0x58, 0xec, 0xc9, + 0x53, 0x58, 0xe5, 0x9e, 0xd2, 0xd2, 0xce, 0xda, 0xbb, 0x74, 0xce, 0x59, 0x85, 0xe9, 0x99, 0xd6, + 0x64, 0xc6, 0xe2, 0xc1, 0xef, 0x16, 0xac, 0x1f, 0xa6, 0xe9, 0x7e, 0xec, 0xa3, 0x20, 0x6d, 0x80, + 0xd7, 0x11, 0x5e, 0x24, 0xe8, 0x49, 0xf4, 0x9d, 0x06, 0x71, 0xcc, 0x9b, 0xf6, 0x32, 0x10, 0x22, + 0x88, 0xce, 0x1d, 0x8b, 0xdc, 0x30, 0x9d, 0x3b, 0xbc, 0x08, 0x84, 0x14, 0x8e, 0x4d, 0x6e, 0xc1, + 0x0d, 0x0d, 0xbc, 0x8a, 0xa5, 0x1b, 0xed, 0x73, 0x6f, 0x84, 0xce, 0x12, 0x21, 0xd0, 0xd6, 0xa0, + 0x2b, 0xb2, 0x0e, 0xfb, 0xce, 0x32, 0xe9, 0x42, 0x47, 0x57, 0x5a, 0xbc, 0x8a, 0xa5, 0x79, 0x68, + 0x83, 0xd3, 0x10, 0x9d, 0x15, 0xd2, 0x01, 0x87, 0xa1, 0x87, 0x41, 0x22, 0x5d, 0xe1, 0x46, 0x6f, + 0x79, 0x18, 0xf8, 0xce, 0xaa, 0xf2, 0x74, 0x98, 0xa6, 0x71, 0x7a, 0x7c, 0x76, 0x26, 0x50, 0x3a, + 0xfe, 0x83, 0x27, 0x70, 0x77, 0x41, 0x32, 0x64, 0x13, 0x9a, 0x06, 0x3d, 0x45, 0xa7, 0xa1, 0x4c, + 0x5f, 0x47, 0xa2, 0x00, 0xac, 0xdd, 0x7f, 0x6c, 0x68, 0x66, 0xb6, 0xd3, 0xc8, 0x23, 0xfb, 0xb0, + 0x9e, 0xcf, 0x52, 0xd2, 0xab, 0x1d, 0xb0, 0x7a, 0x54, 0xf4, 0xee, 0xd5, 0x0f, 0xdf, 0x6c, 0x44, + 0xbc, 0x30, 0x8c, 0x6a, 0xe0, 0x90, 0x7b, 0x73, 0xe3, 0xa1, 0x9c, 0x76, 0xbd, 0xad, 0x7a, 0xe1, + 0x1c, 0x4f, 0x18, 0xd6, 0xf1, 0x14, 0x93, 0xab, 0x8e, 0xa7, 0x32, 0xb2, 0x18, 0x38, 0xe5, 0x47, + 0xc0, 0x50, 0xa6, 0xc8, 0xc7, 0x64, 0x6b, 0xee, 0xd2, 0x57, 0xbe, 0x10, 0x7a, 0x1f, 0x94, 0x6e, + 0x5b, 0x8f, 0x2c, 0x72, 0x04, 0x50, 0x0a, 0xfe, 0x0f, 0xdb, 0xf3, 0x4f, 0xff, 0xb8, 0xec, 0x5b, + 0xef, 0x2f, 0xfb, 0xd6, 0xdf, 0x97, 0x7d, 0xeb, 0x97, 0xab, 0x7e, 0xe3, 0xfd, 0x55, 0xbf, 0xf1, + 0xd7, 0x55, 0xbf, 0xf1, 0x5d, 0x6f, 0xf1, 0x57, 0xea, 0xe9, 0xaa, 0xfe, 0xdb, 0xfb, 0x37, 0x00, + 0x00, 0xff, 0xff, 0xb6, 0xe1, 0x84, 0x46, 0xca, 0x0a, 0x00, 0x00, } func (m *HeadSyncRange) Marshal() (dAtA []byte, err error) { diff --git a/commonspace/spacesyncproto/spacesync_drpc.pb.go b/commonspace/spacesyncproto/spacesync_drpc.pb.go index 2c82a645..f9c7abae 100644 --- a/commonspace/spacesyncproto/spacesync_drpc.pb.go +++ b/commonspace/spacesyncproto/spacesync_drpc.pb.go @@ -44,6 +44,7 @@ type DRPCSpaceSyncClient interface { SpacePush(ctx context.Context, in *SpacePushRequest) (*SpacePushResponse, error) SpacePull(ctx context.Context, in *SpacePullRequest) (*SpacePullResponse, error) ObjectSyncStream(ctx context.Context) (DRPCSpaceSync_ObjectSyncStreamClient, error) + ObjectSync(ctx context.Context, in *ObjectSyncMessage) (*ObjectSyncMessage, error) } type drpcSpaceSyncClient struct { @@ -118,11 +119,21 @@ func (x *drpcSpaceSync_ObjectSyncStreamClient) RecvMsg(m *ObjectSyncMessage) err return x.MsgRecv(m, drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto{}) } +func (c *drpcSpaceSyncClient) ObjectSync(ctx context.Context, in *ObjectSyncMessage) (*ObjectSyncMessage, error) { + out := new(ObjectSyncMessage) + err := c.cc.Invoke(ctx, "/spacesync.SpaceSync/ObjectSync", drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto{}, in, out) + if err != nil { + return nil, err + } + return out, nil +} + type DRPCSpaceSyncServer interface { HeadSync(context.Context, *HeadSyncRequest) (*HeadSyncResponse, error) SpacePush(context.Context, *SpacePushRequest) (*SpacePushResponse, error) SpacePull(context.Context, *SpacePullRequest) (*SpacePullResponse, error) ObjectSyncStream(DRPCSpaceSync_ObjectSyncStreamStream) error + ObjectSync(context.Context, *ObjectSyncMessage) (*ObjectSyncMessage, error) } type DRPCSpaceSyncUnimplementedServer struct{} @@ -143,9 +154,13 @@ func (s *DRPCSpaceSyncUnimplementedServer) ObjectSyncStream(DRPCSpaceSync_Object return drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) } +func (s *DRPCSpaceSyncUnimplementedServer) ObjectSync(context.Context, *ObjectSyncMessage) (*ObjectSyncMessage, error) { + return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) +} + type DRPCSpaceSyncDescription struct{} -func (DRPCSpaceSyncDescription) NumMethods() int { return 4 } +func (DRPCSpaceSyncDescription) NumMethods() int { return 5 } func (DRPCSpaceSyncDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver, interface{}, bool) { switch n { @@ -184,6 +199,15 @@ func (DRPCSpaceSyncDescription) Method(n int) (string, drpc.Encoding, drpc.Recei &drpcSpaceSync_ObjectSyncStreamStream{in1.(drpc.Stream)}, ) }, DRPCSpaceSyncServer.ObjectSyncStream, true + case 4: + return "/spacesync.SpaceSync/ObjectSync", drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto{}, + func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { + return srv.(DRPCSpaceSyncServer). + ObjectSync( + ctx, + in1.(*ObjectSyncMessage), + ) + }, DRPCSpaceSyncServer.ObjectSync, true default: return "", nil, nil, nil, false } @@ -266,3 +290,19 @@ func (x *drpcSpaceSync_ObjectSyncStreamStream) Recv() (*ObjectSyncMessage, error func (x *drpcSpaceSync_ObjectSyncStreamStream) RecvMsg(m *ObjectSyncMessage) error { return x.MsgRecv(m, drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto{}) } + +type DRPCSpaceSync_ObjectSyncStream interface { + drpc.Stream + SendAndClose(*ObjectSyncMessage) error +} + +type drpcSpaceSync_ObjectSyncStream struct { + drpc.Stream +} + +func (x *drpcSpaceSync_ObjectSyncStream) SendAndClose(m *ObjectSyncMessage) error { + if err := x.MsgSend(m, drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto{}); err != nil { + return err + } + return x.CloseSend() +} From b85f545fa3f43d9267424fc983df2ec74c9425f0 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Sun, 4 Jun 2023 11:17:56 +0200 Subject: [PATCH 009/123] Update connections on space level --- commonspace/headsync/diffsyncer.go | 8 +++++++- commonspace/spaceservice.go | 9 +++++++-- commonspace/spaceutils_test.go | 4 ++++ go.mod | 2 +- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/commonspace/headsync/diffsyncer.go b/commonspace/headsync/diffsyncer.go index 1529bf6f..a0539681 100644 --- a/commonspace/headsync/diffsyncer.go +++ b/commonspace/headsync/diffsyncer.go @@ -106,8 +106,14 @@ func (d *diffSyncer) Sync(ctx context.Context) error { func (d *diffSyncer) syncWithPeer(ctx context.Context, p peer.Peer) (err error) { ctx = logger.CtxWithFields(ctx, zap.String("peerId", p.Id())) + conn, err := p.AcquireDrpcConn(ctx) + if err != nil { + return + } + defer p.ReleaseDrpcConn(conn) + var ( - cl = d.clientFactory.Client(p) + cl = d.clientFactory.Client(conn) rdiff = NewRemoteDiff(d.spaceId, cl) stateCounter = d.syncStatus.StateCounter() ) diff --git a/commonspace/spaceservice.go b/commonspace/spaceservice.go index ad536e80..dee912ee 100644 --- a/commonspace/spaceservice.go +++ b/commonspace/spaceservice.go @@ -28,6 +28,7 @@ import ( "github.com/anyproto/any-sync/net/pool" "github.com/anyproto/any-sync/net/rpc/rpcerr" "github.com/anyproto/any-sync/nodeconf" + "storj.io/drpc" "sync/atomic" ) @@ -222,8 +223,12 @@ func (s *spaceService) getSpaceStorageFromRemote(ctx context.Context, id string) return } - cl := spacesyncproto.NewDRPCSpaceSyncClient(p) - res, err := cl.SpacePull(ctx, &spacesyncproto.SpacePullRequest{Id: id}) + var res *spacesyncproto.SpacePullResponse + err = p.DoDrpc(ctx, func(conn drpc.Conn) error { + cl := spacesyncproto.NewDRPCSpaceSyncClient(conn) + res, err = cl.SpacePull(ctx, &spacesyncproto.SpacePullRequest{Id: id}) + return err + }) if err != nil { err = rpcerr.Unwrap(err) return diff --git a/commonspace/spaceutils_test.go b/commonspace/spaceutils_test.go index 261a48a3..848d3c89 100644 --- a/commonspace/spaceutils_test.go +++ b/commonspace/spaceutils_test.go @@ -177,6 +177,10 @@ func (m *mockPeerManagerProvider) NewPeerManager(ctx context.Context, spaceId st type mockPool struct { } +func (m *mockPool) AddPeer(ctx context.Context, p peer.Peer) (err error) { + return nil +} + func (m *mockPool) Init(a *app.App) (err error) { return nil } diff --git a/go.mod b/go.mod index 5dd9ad82..1b5b3b2e 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,6 @@ require ( github.com/stretchr/testify v1.8.3 github.com/tyler-smith/go-bip39 v1.1.0 github.com/zeebo/blake3 v0.2.3 - github.com/zeebo/errs v1.3.0 go.uber.org/atomic v1.11.0 go.uber.org/zap v1.24.0 golang.org/x/crypto v0.9.0 @@ -103,6 +102,7 @@ require ( github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158 // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect + github.com/zeebo/errs v1.3.0 // indirect go.opentelemetry.io/otel v1.7.0 // indirect go.opentelemetry.io/otel/trace v1.7.0 // indirect go.uber.org/multierr v1.11.0 // indirect From aff2061bd1be6180bfa33d23a2ac978443f523da Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Sun, 4 Jun 2023 19:01:33 +0200 Subject: [PATCH 010/123] WIP request manager --- commonspace/objectsync/objectsync.go | 12 +-- commonspace/requestmanager/requestmanager.go | 77 ++++++++++++++++++-- 2 files changed, 76 insertions(+), 13 deletions(-) diff --git a/commonspace/objectsync/objectsync.go b/commonspace/objectsync/objectsync.go index 9e3c3eba..f4dc7c1b 100644 --- a/commonspace/objectsync/objectsync.go +++ b/commonspace/objectsync/objectsync.go @@ -104,6 +104,8 @@ func (s *objectSync) LastUsage() time.Time { } func (s *objectSync) HandleRequest(ctx context.Context, hm HandleMessage) (resp *spacesyncproto.ObjectSyncMessage, err error) { + hm.ReceiveTime = time.Now() + hm.StartHandlingTime = hm.ReceiveTime return s.handleRequest(ctx, hm.SenderId, hm.Message) } @@ -157,10 +159,7 @@ func (s *objectSync) processHandleMessage(msg HandleMessage) { } func (s *objectSync) handleRequest(ctx context.Context, senderId string, msg *spacesyncproto.ObjectSyncMessage) (response *spacesyncproto.ObjectSyncMessage, err error) { - log := log.With( - zap.String("objectId", msg.ObjectId), - zap.String("requestId", msg.RequestId), - zap.String("replyId", msg.ReplyId)) + log := log.With(zap.String("objectId", msg.ObjectId)) if s.spaceIsDeleted.Load() { log = log.With(zap.Bool("isDeleted", true)) // preventing sync with other clients if they are not just syncing the settings tree @@ -180,10 +179,7 @@ func (s *objectSync) handleRequest(ctx context.Context, senderId string, msg *sp } func (s *objectSync) handleMessage(ctx context.Context, senderId string, msg *spacesyncproto.ObjectSyncMessage) (err error) { - log := log.With( - zap.String("objectId", msg.ObjectId), - zap.String("requestId", msg.RequestId), - zap.String("replyId", msg.ReplyId)) + log := log.With(zap.String("objectId", msg.ObjectId)) if s.spaceIsDeleted.Load() { log = log.With(zap.Bool("isDeleted", true)) // preventing sync with other clients if they are not just syncing the settings tree diff --git a/commonspace/requestmanager/requestmanager.go b/commonspace/requestmanager/requestmanager.go index e77b4bdb..18eeff45 100644 --- a/commonspace/requestmanager/requestmanager.go +++ b/commonspace/requestmanager/requestmanager.go @@ -4,7 +4,14 @@ import ( "context" "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/app/logger" + "github.com/anyproto/any-sync/commonspace/objectsync" "github.com/anyproto/any-sync/commonspace/spacesyncproto" + "github.com/anyproto/any-sync/net/peer" + "github.com/anyproto/any-sync/net/pool" + "github.com/anyproto/any-sync/net/streampool" + "go.uber.org/zap" + "storj.io/drpc" + "sync" ) const CName = "common.commonspace.requestmanager" @@ -18,13 +25,32 @@ type RequestManager interface { } func New() RequestManager { - return &requestManager{} + return &requestManager{ + workers: 10, + queueSize: 300, + pools: map[string]*streampool.ExecPool{}, + } +} + +type MessageHandler interface { + HandleMessage(ctx context.Context, hm objectsync.HandleMessage) (err error) } type requestManager struct { + sync.Mutex + pools map[string]*streampool.ExecPool + peerPool pool.Pool + workers int + queueSize int + handler MessageHandler + ctx context.Context + cancel context.CancelFunc } func (r *requestManager) Init(a *app.App) (err error) { + r.ctx, r.cancel = context.WithCancel(context.Background()) + r.handler = a.MustComponent(objectsync.CName).(MessageHandler) + r.peerPool = a.MustComponent(pool.CName).(pool.Pool) return } @@ -37,13 +63,54 @@ func (r *requestManager) Run(ctx context.Context) (err error) { } func (r *requestManager) Close(ctx context.Context) (err error) { + r.Lock() + defer r.Unlock() + r.cancel() + for _, p := range r.pools { + _ = p.Close() + } return nil } -func (r *requestManager) SendRequest(ctx context.Context, peerId string, msg *spacesyncproto.ObjectSyncMessage) (reply *spacesyncproto.ObjectSyncMessage, err error) { - return nil, nil +func (r *requestManager) SendRequest(ctx context.Context, peerId string, req *spacesyncproto.ObjectSyncMessage) (reply *spacesyncproto.ObjectSyncMessage, err error) { + return r.doRequest(ctx, peerId, req) } -func (r *requestManager) QueueRequest(peerId string, msg *spacesyncproto.ObjectSyncMessage) (err error) { - return nil +func (r *requestManager) QueueRequest(peerId string, req *spacesyncproto.ObjectSyncMessage) (err error) { + r.Lock() + defer r.Unlock() + pl, exists := r.pools[peerId] + if !exists { + pl := streampool.NewExecPool(r.workers, r.queueSize) + r.pools[peerId] = pl + } + // TODO: for later think when many clients are there, + // we need to close pools for inactive clients + return pl.TryAdd(func() { + ctx := r.ctx + resp, err := r.doRequest(ctx, peerId, req) + if err != nil { + log.Warn("failed to send request", zap.Error(err)) + return + } + ctx = peer.CtxWithPeerId(ctx, peerId) + _ = r.handler.HandleMessage(ctx, objectsync.HandleMessage{ + SenderId: peerId, + Message: resp, + PeerCtx: ctx, + }) + }) +} + +func (r *requestManager) doRequest(ctx context.Context, peerId string, msg *spacesyncproto.ObjectSyncMessage) (resp *spacesyncproto.ObjectSyncMessage, err error) { + pr, err := r.peerPool.Get(ctx, peerId) + if err != nil { + return + } + err = pr.DoDrpc(ctx, func(conn drpc.Conn) error { + cl := spacesyncproto.NewDRPCSpaceSyncClient(conn) + resp, err = cl.ObjectSync(ctx, msg) + return err + }) + return } From 85a093dd4a99072764ee811613d6f7776cc50867 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Mon, 5 Jun 2023 15:09:17 +0200 Subject: [PATCH 011/123] Change space methods (handle requests) --- commonspace/objectsync/objectsync.go | 12 ++++--- commonspace/requestmanager/requestmanager.go | 1 + commonspace/space.go | 38 ++++++++++++++++++-- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/commonspace/objectsync/objectsync.go b/commonspace/objectsync/objectsync.go index f4dc7c1b..386cbb15 100644 --- a/commonspace/objectsync/objectsync.go +++ b/commonspace/objectsync/objectsync.go @@ -31,7 +31,7 @@ var log = logger.NewNamed(CName) type ObjectSync interface { LastUsage() time.Time HandleMessage(ctx context.Context, hm HandleMessage) (err error) - HandleRequest(ctx context.Context, hm HandleMessage) (resp *spacesyncproto.ObjectSyncMessage, err error) + HandleRequest(ctx context.Context, req *spacesyncproto.ObjectSyncMessage) (resp *spacesyncproto.ObjectSyncMessage, err error) CloseThread(id string) (err error) app.ComponentRunnable } @@ -103,10 +103,12 @@ func (s *objectSync) LastUsage() time.Time { return time.Time{} } -func (s *objectSync) HandleRequest(ctx context.Context, hm HandleMessage) (resp *spacesyncproto.ObjectSyncMessage, err error) { - hm.ReceiveTime = time.Now() - hm.StartHandlingTime = hm.ReceiveTime - return s.handleRequest(ctx, hm.SenderId, hm.Message) +func (s *objectSync) HandleRequest(ctx context.Context, req *spacesyncproto.ObjectSyncMessage) (resp *spacesyncproto.ObjectSyncMessage, err error) { + peerId, err := peer.CtxPeerId(ctx) + if err != nil { + return nil, err + } + return s.handleRequest(ctx, peerId, req) } func (s *objectSync) HandleMessage(ctx context.Context, hm HandleMessage) (err error) { diff --git a/commonspace/requestmanager/requestmanager.go b/commonspace/requestmanager/requestmanager.go index 18eeff45..f28ae3ef 100644 --- a/commonspace/requestmanager/requestmanager.go +++ b/commonspace/requestmanager/requestmanager.go @@ -73,6 +73,7 @@ func (r *requestManager) Close(ctx context.Context) (err error) { } func (r *requestManager) SendRequest(ctx context.Context, peerId string, req *spacesyncproto.ObjectSyncMessage) (reply *spacesyncproto.ObjectSyncMessage, err error) { + // TODO: limit concurrent sends? return r.doRequest(ctx, peerId, req) } diff --git a/commonspace/space.go b/commonspace/space.go index 32b1b04d..9fd25449 100644 --- a/commonspace/space.go +++ b/commonspace/space.go @@ -4,6 +4,8 @@ import ( "context" "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/commonspace/headsync" + "github.com/anyproto/any-sync/commonspace/object/acl/list" + "github.com/anyproto/any-sync/commonspace/object/acl/syncacl" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" "github.com/anyproto/any-sync/commonspace/objectsync" "github.com/anyproto/any-sync/commonspace/objecttreebuilder" @@ -58,6 +60,8 @@ type Space interface { Id() string Init(ctx context.Context) error + Description() (desc SpaceDescription, err error) + TreeBuilder() objecttreebuilder.TreeBuilder SyncStatus() syncstatus.StatusUpdater Storage() spacestorage.SpaceStorage @@ -67,7 +71,8 @@ type Space interface { DeleteSpace(ctx context.Context, deleteChange *treechangeproto.RawTreeChangeWithId) (err error) HandleMessage(ctx context.Context, msg objectsync.HandleMessage) (err error) - HandleRequest(ctx context.Context, msg objectsync.HandleMessage) (resp *spacesyncproto.ObjectSyncMessage, err error) + HandleSyncRequest(ctx context.Context, req *spacesyncproto.ObjectSyncMessage) (resp *spacesyncproto.ObjectSyncMessage, err error) + HandleRangeRequest(ctx context.Context, req *spacesyncproto.HeadSyncRequest) (resp *spacesyncproto.HeadSyncResponse, err error) TryClose(objectTTL time.Duration) (close bool, err error) Close() error @@ -86,6 +91,28 @@ type space struct { syncStatus syncstatus.StatusProvider settings settings.Settings storage spacestorage.SpaceStorage + aclList list.AclList +} + +func (s *space) Description() (desc SpaceDescription, err error) { + root := s.aclList.Root() + settingsStorage, err := s.storage.TreeStorage(s.storage.SpaceSettingsId()) + if err != nil { + return + } + settingsRoot, err := settingsStorage.Root() + if err != nil { + return + } + + desc = SpaceDescription{ + SpaceHeader: s.header, + AclId: root.Id, + AclPayload: root.Payload, + SpaceSettingsId: settingsRoot.Id, + SpaceSettingsPayload: settingsRoot.RawChange, + } + return } func (s *space) DeleteTree(ctx context.Context, id string) (err error) { @@ -104,8 +131,12 @@ func (s *space) HandleMessage(ctx context.Context, msg objectsync.HandleMessage) return s.objectSync.HandleMessage(ctx, msg) } -func (s *space) HandleRequest(ctx context.Context, msg objectsync.HandleMessage) (resp *spacesyncproto.ObjectSyncMessage, err error) { - return s.objectSync.HandleRequest(ctx, msg) +func (s *space) HandleSyncRequest(ctx context.Context, req *spacesyncproto.ObjectSyncMessage) (resp *spacesyncproto.ObjectSyncMessage, err error) { + return s.objectSync.HandleRequest(ctx, req) +} + +func (s *space) HandleRangeRequest(ctx context.Context, req *spacesyncproto.HeadSyncRequest) (resp *spacesyncproto.HeadSyncResponse, err error) { + return s.headSync.HandleRangeRequest(ctx, req) } func (s *space) TreeBuilder() objecttreebuilder.TreeBuilder { @@ -127,6 +158,7 @@ func (s *space) Init(ctx context.Context) (err error) { s.settings = s.app.MustComponent(settings.CName).(settings.Settings) s.objectSync = s.app.MustComponent(objectsync.CName).(objectsync.ObjectSync) s.storage = s.app.MustComponent(spacestorage.CName).(spacestorage.SpaceStorage) + s.aclList = s.app.MustComponent(syncacl.CName).(list.AclList) return nil } From 69e607eddb1f2eaedc4ebc46d855b8a7c83da430 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Mon, 5 Jun 2023 15:16:38 +0200 Subject: [PATCH 012/123] Expose more methods --- commonspace/space.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/commonspace/space.go b/commonspace/space.go index 9fd25449..66457a99 100644 --- a/commonspace/space.go +++ b/commonspace/space.go @@ -60,6 +60,8 @@ type Space interface { Id() string Init(ctx context.Context) error + StoredIds() []string + DebugAllHeads() []headsync.TreeHeads Description() (desc SpaceDescription, err error) TreeBuilder() objecttreebuilder.TreeBuilder @@ -115,6 +117,14 @@ func (s *space) Description() (desc SpaceDescription, err error) { return } +func (s *space) StoredIds() []string { + return s.headSync.ExternalIds() +} + +func (s *space) DebugAllHeads() []headsync.TreeHeads { + return s.headSync.DebugAllHeads() +} + func (s *space) DeleteTree(ctx context.Context, id string) (err error) { return s.settings.DeleteTree(ctx, id) } From 66775873c77d639616115616d0f64d04331fda90 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Mon, 5 Jun 2023 20:44:27 +0200 Subject: [PATCH 013/123] Add syncstatusprovider --- commonspace/headsync/headsync.go | 4 +-- commonspace/space.go | 4 +-- commonspace/spaceservice.go | 29 ++++++++++++-------- commonspace/spaceutils_test.go | 21 +++++++++++++- commonspace/syncstatus/noop.go | 2 +- commonspace/syncstatus/syncstatus.go | 41 ++++++++++++++++------------ 6 files changed, 65 insertions(+), 36 deletions(-) diff --git a/commonspace/headsync/headsync.go b/commonspace/headsync/headsync.go index 3f5bcd25..b838bd8b 100644 --- a/commonspace/headsync/headsync.go +++ b/commonspace/headsync/headsync.go @@ -57,7 +57,7 @@ type headSync struct { peerManager peermanager.PeerManager treeManager treemanager.TreeManager credentialProvider credentialprovider.CredentialProvider - syncStatus syncstatus.StatusProvider + syncStatus syncstatus.StatusService deletionState deletionstate.ObjectDeletionState } @@ -77,7 +77,7 @@ func (h *headSync) Init(a *app.App) (err error) { h.diff = ldiff.New(16, 16) h.peerManager = a.MustComponent(peermanager.CName).(peermanager.PeerManager) h.credentialProvider = a.MustComponent(credentialprovider.CName).(credentialprovider.CredentialProvider) - h.syncStatus = a.MustComponent(syncstatus.CName).(syncstatus.StatusProvider) + h.syncStatus = a.MustComponent(syncstatus.CName).(syncstatus.StatusService) h.treeManager = a.MustComponent(treemanager.CName).(treemanager.TreeManager) h.deletionState = a.MustComponent(deletionstate.CName).(deletionstate.ObjectDeletionState) h.syncer = newDiffSyncer(h) diff --git a/commonspace/space.go b/commonspace/space.go index 66457a99..d2bbc68b 100644 --- a/commonspace/space.go +++ b/commonspace/space.go @@ -90,7 +90,7 @@ type space struct { treeBuilder objecttreebuilder.TreeBuilderComponent headSync headsync.HeadSync objectSync objectsync.ObjectSync - syncStatus syncstatus.StatusProvider + syncStatus syncstatus.StatusService settings settings.Settings storage spacestorage.SpaceStorage aclList list.AclList @@ -164,7 +164,7 @@ func (s *space) Init(ctx context.Context) (err error) { } s.treeBuilder = s.app.MustComponent(objecttreebuilder.CName).(objecttreebuilder.TreeBuilderComponent) s.headSync = s.app.MustComponent(headsync.CName).(headsync.HeadSync) - s.syncStatus = s.app.MustComponent(syncstatus.CName).(syncstatus.StatusProvider) + s.syncStatus = s.app.MustComponent(syncstatus.CName).(syncstatus.StatusService) s.settings = s.app.MustComponent(settings.CName).(settings.Settings) s.objectSync = s.app.MustComponent(objectsync.CName).(objectsync.ObjectSync) s.storage = s.app.MustComponent(spacestorage.CName).(spacestorage.SpaceStorage) diff --git a/commonspace/spaceservice.go b/commonspace/spaceservice.go index dee912ee..3e441aea 100644 --- a/commonspace/spaceservice.go +++ b/commonspace/spaceservice.go @@ -23,6 +23,7 @@ import ( "github.com/anyproto/any-sync/commonspace/spacestate" "github.com/anyproto/any-sync/commonspace/spacestorage" "github.com/anyproto/any-sync/commonspace/spacesyncproto" + "github.com/anyproto/any-sync/commonspace/syncstatus" "github.com/anyproto/any-sync/metric" "github.com/anyproto/any-sync/net/peer" "github.com/anyproto/any-sync/net/pool" @@ -53,16 +54,17 @@ type SpaceService interface { } type spaceService struct { - config config.Config - account accountservice.Service - configurationService nodeconf.Service - storageProvider spacestorage.SpaceStorageProvider - peermanagerProvider peermanager.PeerManagerProvider - credentialProvider credentialprovider.CredentialProvider - treeManager treemanager.TreeManager - pool pool.Pool - metric metric.Metric - app *app.App + config config.Config + account accountservice.Service + configurationService nodeconf.Service + storageProvider spacestorage.SpaceStorageProvider + peerManagerProvider peermanager.PeerManagerProvider + credentialProvider credentialprovider.CredentialProvider + statusServiceProvider syncstatus.StatusServiceProvider + treeManager treemanager.TreeManager + pool pool.Pool + metric metric.Metric + app *app.App } func (s *spaceService) Init(a *app.App) (err error) { @@ -71,7 +73,8 @@ func (s *spaceService) Init(a *app.App) (err error) { s.storageProvider = a.MustComponent(spacestorage.CName).(spacestorage.SpaceStorageProvider) s.configurationService = a.MustComponent(nodeconf.CName).(nodeconf.Service) s.treeManager = a.MustComponent(treemanager.CName).(treemanager.TreeManager) - s.peermanagerProvider = a.MustComponent(peermanager.CName).(peermanager.PeerManagerProvider) + s.peerManagerProvider = a.MustComponent(peermanager.CName).(peermanager.PeerManagerProvider) + s.statusServiceProvider = a.MustComponent(syncstatus.CName).(syncstatus.StatusServiceProvider) s.pool = a.MustComponent(pool.CName).(pool.Pool) s.metric, _ = a.Component(metric.CName).(metric.Metric) s.app = a @@ -162,14 +165,16 @@ func (s *spaceService) NewSpace(ctx context.Context, id string) (Space, error) { } else { state.TreeBuilderFunc = objecttree.BuildEmptyDataObjectTree } - peerManager, err := s.peermanagerProvider.NewPeerManager(ctx, id) + peerManager, err := s.peerManagerProvider.NewPeerManager(ctx, id) if err != nil { return nil, err } + statusService := s.statusServiceProvider.NewStatusService() spaceApp := s.app.ChildApp() spaceApp.Register(state). Register(peerManager). Register(newCommonStorage(st)). + Register(statusService). Register(syncacl.New()). Register(requestmanager.New()). Register(deletionstate.New()). diff --git a/commonspace/spaceutils_test.go b/commonspace/spaceutils_test.go index 848d3c89..c1d40f5c 100644 --- a/commonspace/spaceutils_test.go +++ b/commonspace/spaceutils_test.go @@ -170,6 +170,25 @@ func (m *mockPeerManagerProvider) NewPeerManager(ctx context.Context, spaceId st return &mockPeerManager{}, nil } +// +// Mock StatusServiceProvider +// + +type mockStatusServiceProvider struct { +} + +func (m *mockStatusServiceProvider) Init(a *app.App) (err error) { + return nil +} + +func (m *mockStatusServiceProvider) Name() (name string) { + return syncstatus.CName +} + +func (m *mockStatusServiceProvider) NewStatusService() syncstatus.StatusService { + return syncstatus.NewNoOpSyncStatus() +} + // // Mock Pool // @@ -339,8 +358,8 @@ func newFixture(t *testing.T) *spaceFixture { } fx.app.Register(fx.account). Register(fx.config). - Register(syncstatus.NewNoOpSyncStatus()). Register(credentialprovider.NewNoOp()). + Register(&mockStatusServiceProvider{}). Register(fx.configurationService). Register(fx.storageProvider). Register(fx.peermanagerProvider). diff --git a/commonspace/syncstatus/noop.go b/commonspace/syncstatus/noop.go index 10ef80ac..79424d3f 100644 --- a/commonspace/syncstatus/noop.go +++ b/commonspace/syncstatus/noop.go @@ -5,7 +5,7 @@ import ( "github.com/anyproto/any-sync/app" ) -func NewNoOpSyncStatus() StatusProvider { +func NewNoOpSyncStatus() StatusService { return &noOpSyncStatus{} } diff --git a/commonspace/syncstatus/syncstatus.go b/commonspace/syncstatus/syncstatus.go index 2049c42b..32c287fa 100644 --- a/commonspace/syncstatus/syncstatus.go +++ b/commonspace/syncstatus/syncstatus.go @@ -46,7 +46,12 @@ type StatusWatcher interface { SetUpdateReceiver(updater UpdateReceiver) } -type StatusProvider interface { +type StatusServiceProvider interface { + app.Component + NewStatusService() StatusService +} + +type StatusService interface { app.ComponentRunnable StatusUpdater StatusWatcher @@ -72,7 +77,7 @@ type treeStatus struct { heads []string } -type syncStatusProvider struct { +type syncStatusService struct { sync.Mutex configuration nodeconf.NodeConf periodicSync periodicsync.PeriodicSync @@ -91,14 +96,14 @@ type syncStatusProvider struct { updateTimeout time.Duration } -func NewSyncStatusProvider() StatusProvider { - return &syncStatusProvider{ +func NewSyncStatusProvider() StatusService { + return &syncStatusService{ treeHeads: map[string]treeHeadsEntry{}, watchers: map[string]struct{}{}, } } -func (s *syncStatusProvider) Init(a *app.App) (err error) { +func (s *syncStatusService) Init(a *app.App) (err error) { sharedState := a.MustComponent(spacestate.CName).(*spacestate.SpaceState) s.updateIntervalSecs = syncUpdateInterval s.updateTimeout = syncTimeout @@ -108,18 +113,18 @@ func (s *syncStatusProvider) Init(a *app.App) (err error) { return } -func (s *syncStatusProvider) Name() (name string) { +func (s *syncStatusService) Name() (name string) { return CName } -func (s *syncStatusProvider) SetUpdateReceiver(updater UpdateReceiver) { +func (s *syncStatusService) SetUpdateReceiver(updater UpdateReceiver) { s.Lock() defer s.Unlock() s.updateReceiver = updater } -func (s *syncStatusProvider) Run(ctx context.Context) error { +func (s *syncStatusService) Run(ctx context.Context) error { s.periodicSync = periodicsync.NewPeriodicSync( s.updateIntervalSecs, s.updateTimeout, @@ -129,7 +134,7 @@ func (s *syncStatusProvider) Run(ctx context.Context) error { return nil } -func (s *syncStatusProvider) HeadsChange(treeId string, heads []string) { +func (s *syncStatusService) HeadsChange(treeId string, heads []string) { s.Lock() defer s.Unlock() @@ -144,7 +149,7 @@ func (s *syncStatusProvider) HeadsChange(treeId string, heads []string) { s.stateCounter++ } -func (s *syncStatusProvider) SetNodesOnline(senderId string, online bool) { +func (s *syncStatusService) SetNodesOnline(senderId string, online bool) { if !s.isSenderResponsible(senderId) { return } @@ -155,7 +160,7 @@ func (s *syncStatusProvider) SetNodesOnline(senderId string, online bool) { s.nodesOnline = online } -func (s *syncStatusProvider) update(ctx context.Context) (err error) { +func (s *syncStatusService) update(ctx context.Context) (err error) { s.treeStatusBuf = s.treeStatusBuf[:0] s.Lock() @@ -184,7 +189,7 @@ func (s *syncStatusProvider) update(ctx context.Context) (err error) { return } -func (s *syncStatusProvider) HeadsReceive(senderId, treeId string, heads []string) { +func (s *syncStatusService) HeadsReceive(senderId, treeId string, heads []string) { s.Lock() defer s.Unlock() @@ -213,7 +218,7 @@ func (s *syncStatusProvider) HeadsReceive(senderId, treeId string, heads []strin s.treeHeads[treeId] = curTreeHeads } -func (s *syncStatusProvider) Watch(treeId string) (err error) { +func (s *syncStatusService) Watch(treeId string) (err error) { s.Lock() defer s.Unlock() _, ok := s.treeHeads[treeId] @@ -243,7 +248,7 @@ func (s *syncStatusProvider) Watch(treeId string) (err error) { return } -func (s *syncStatusProvider) Unwatch(treeId string) { +func (s *syncStatusService) Unwatch(treeId string) { s.Lock() defer s.Unlock() @@ -252,14 +257,14 @@ func (s *syncStatusProvider) Unwatch(treeId string) { } } -func (s *syncStatusProvider) StateCounter() uint64 { +func (s *syncStatusService) StateCounter() uint64 { s.Lock() defer s.Unlock() return s.stateCounter } -func (s *syncStatusProvider) RemoveAllExcept(senderId string, differentRemoteIds []string, stateCounter uint64) { +func (s *syncStatusService) RemoveAllExcept(senderId string, differentRemoteIds []string, stateCounter uint64) { // if sender is not a responsible node, then this should have no effect if !s.isSenderResponsible(senderId) { return @@ -282,11 +287,11 @@ func (s *syncStatusProvider) RemoveAllExcept(senderId string, differentRemoteIds } } -func (s *syncStatusProvider) Close(ctx context.Context) error { +func (s *syncStatusService) Close(ctx context.Context) error { s.periodicSync.Close() return nil } -func (s *syncStatusProvider) isSenderResponsible(senderId string) bool { +func (s *syncStatusService) isSenderResponsible(senderId string) bool { return slices.Contains(s.configuration.NodeIds(s.spaceId), senderId) } From e96524f7024ee1f8a46881e96ce6b63f64ae54d1 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Tue, 6 Jun 2023 10:43:43 +0200 Subject: [PATCH 014/123] Yamux setaccepter --- net/peerservice/peerservice.go | 1 + 1 file changed, 1 insertion(+) diff --git a/net/peerservice/peerservice.go b/net/peerservice/peerservice.go index e0691733..eda1d8c8 100644 --- a/net/peerservice/peerservice.go +++ b/net/peerservice/peerservice.go @@ -49,6 +49,7 @@ func (p *peerService) Init(a *app.App) (err error) { p.pool = a.MustComponent(pool.CName).(pool.Pool) p.server = a.MustComponent(server.CName).(server.DRPCServer) p.peerAddrs = map[string][]string{} + p.yamux.SetAccepter(p) return nil } From 67d535362fbebfff6592493b1fb36d2fdcf2d8a0 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Tue, 6 Jun 2023 17:18:59 +0200 Subject: [PATCH 015/123] Different fixes --- .../object/tree/synctree/synctreehandler.go | 2 +- commonspace/payloads.go | 18 ++++++++---------- commonspace/requestmanager/requestmanager.go | 3 ++- commonspace/space.go | 3 ++- commonspace/spacestorage/inmemorystorage.go | 13 +++++++++---- commonspace/spacestorage/spacestorage.go | 4 +--- net/streampool/streampool.go | 2 ++ 7 files changed, 25 insertions(+), 20 deletions(-) diff --git a/commonspace/object/tree/synctree/synctreehandler.go b/commonspace/object/tree/synctree/synctreehandler.go index 5953ca97..43e764cc 100644 --- a/commonspace/object/tree/synctree/synctreehandler.go +++ b/commonspace/object/tree/synctree/synctreehandler.go @@ -92,7 +92,7 @@ func (s *syncTreeHandler) handleMessage(ctx context.Context, senderId string) (e case content.GetHeadUpdate() != nil: var syncReq *treechangeproto.TreeSyncMessage syncReq, err = s.syncProtocol.HeadUpdate(ctx, senderId, content.GetHeadUpdate()) - if err != nil { + if err != nil || syncReq == nil { return } return s.syncClient.QueueRequest(senderId, treeId, syncReq) diff --git a/commonspace/payloads.go b/commonspace/payloads.go index 5d2284d0..8d1c334c 100644 --- a/commonspace/payloads.go +++ b/commonspace/payloads.go @@ -214,14 +214,15 @@ func validateSpaceStorageCreatePayload(payload spacestorage.SpaceStorageCreatePa } func ValidateSpaceHeader(rawHeaderWithId *spacesyncproto.RawSpaceHeaderWithId, identity crypto.PubKey) (err error) { + if rawHeaderWithId == nil { + return spacestorage.ErrIncorrectSpaceHeader + } sepIdx := strings.Index(rawHeaderWithId.Id, ".") if sepIdx == -1 { - err = spacestorage.ErrIncorrectSpaceHeader - return + return spacestorage.ErrIncorrectSpaceHeader } if !cidutil.VerifyCid(rawHeaderWithId.RawHeader, rawHeaderWithId.Id[:sepIdx]) { - err = objecttree.ErrIncorrectCid - return + return objecttree.ErrIncorrectCid } var rawSpaceHeader spacesyncproto.RawSpaceHeader err = proto.Unmarshal(rawHeaderWithId.RawHeader, &rawSpaceHeader) @@ -239,19 +240,16 @@ func ValidateSpaceHeader(rawHeaderWithId *spacesyncproto.RawSpaceHeaderWithId, i } res, err := payloadIdentity.Verify(rawSpaceHeader.SpaceHeader, rawSpaceHeader.Signature) if err != nil || !res { - err = spacestorage.ErrIncorrectSpaceHeader - return + return spacestorage.ErrIncorrectSpaceHeader } if rawHeaderWithId.Id[sepIdx+1:] != strconv.FormatUint(header.ReplicationKey, 36) { - err = spacestorage.ErrIncorrectSpaceHeader - return + return spacestorage.ErrIncorrectSpaceHeader } if identity == nil { return } if !payloadIdentity.Equals(identity) { - err = ErrIncorrectIdentity - return + return ErrIncorrectIdentity } return } diff --git a/commonspace/requestmanager/requestmanager.go b/commonspace/requestmanager/requestmanager.go index f28ae3ef..ac4351c0 100644 --- a/commonspace/requestmanager/requestmanager.go +++ b/commonspace/requestmanager/requestmanager.go @@ -82,8 +82,9 @@ func (r *requestManager) QueueRequest(peerId string, req *spacesyncproto.ObjectS defer r.Unlock() pl, exists := r.pools[peerId] if !exists { - pl := streampool.NewExecPool(r.workers, r.queueSize) + pl = streampool.NewExecPool(r.workers, r.queueSize) r.pools[peerId] = pl + pl.Run() } // TODO: for later think when many clients are there, // we need to close pools for inactive clients diff --git a/commonspace/space.go b/commonspace/space.go index d2bbc68b..ef5119de 100644 --- a/commonspace/space.go +++ b/commonspace/space.go @@ -169,7 +169,8 @@ func (s *space) Init(ctx context.Context) (err error) { s.objectSync = s.app.MustComponent(objectsync.CName).(objectsync.ObjectSync) s.storage = s.app.MustComponent(spacestorage.CName).(spacestorage.SpaceStorage) s.aclList = s.app.MustComponent(syncacl.CName).(list.AclList) - return nil + s.header, err = s.storage.SpaceHeader() + return } func (s *space) SyncStatus() syncstatus.StatusUpdater { diff --git a/commonspace/spacestorage/inmemorystorage.go b/commonspace/spacestorage/inmemorystorage.go index db1d1166..096f5a84 100644 --- a/commonspace/spacestorage/inmemorystorage.go +++ b/commonspace/spacestorage/inmemorystorage.go @@ -1,6 +1,7 @@ package spacestorage import ( + "context" "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" "github.com/anyproto/any-sync/commonspace/object/acl/liststorage" @@ -22,6 +23,14 @@ type InMemorySpaceStorage struct { sync.Mutex } +func (i *InMemorySpaceStorage) Run(ctx context.Context) (err error) { + return nil +} + +func (i *InMemorySpaceStorage) Close(ctx context.Context) (err error) { + return nil +} + func (i *InMemorySpaceStorage) Init(a *app.App) (err error) { return nil } @@ -157,10 +166,6 @@ func (i *InMemorySpaceStorage) ReadSpaceHash() (hash string, err error) { return i.spaceHash, nil } -func (i *InMemorySpaceStorage) Close() error { - return nil -} - func (i *InMemorySpaceStorage) AllTrees() map[string]treestorage.TreeStorage { i.Lock() defer i.Unlock() diff --git a/commonspace/spacestorage/spacestorage.go b/commonspace/spacestorage/spacestorage.go index a4ffaecb..e2807f5a 100644 --- a/commonspace/spacestorage/spacestorage.go +++ b/commonspace/spacestorage/spacestorage.go @@ -28,7 +28,7 @@ const ( ) type SpaceStorage interface { - app.Component + app.ComponentRunnable Id() string SetSpaceDeleted() error IsSpaceDeleted() (bool, error) @@ -44,8 +44,6 @@ type SpaceStorage interface { CreateTreeStorage(payload treestorage.TreeStorageCreatePayload) (treestorage.TreeStorage, error) WriteSpaceHash(hash string) error ReadSpaceHash() (hash string, err error) - - Close() error } type SpaceStorageCreatePayload struct { diff --git a/net/streampool/streampool.go b/net/streampool/streampool.go index 50a020b3..54c513b9 100644 --- a/net/streampool/streampool.go +++ b/net/streampool/streampool.go @@ -250,6 +250,8 @@ func (s *streamPool) openStream(ctx context.Context, p peer.Peer) *openingProces close(op.ch) delete(s.opening, p.Id()) }() + // in case there was no peerId in context + ctx := peer.CtxWithPeerId(ctx, p.Id()) // open new stream and add to pool st, tags, err := s.handler.OpenStream(ctx, p) if err != nil { From 3a2f9fe6f5bc39611fb47a12f9b7ae14c0f0621c Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Tue, 6 Jun 2023 20:10:44 +0200 Subject: [PATCH 016/123] WIP synctree tests rewrite --- .../synctree/mock_synctree/mock_synctree.go | 234 +++++++++++++++++- ...ol_test.go => protocolintegration_test.go} | 0 commonspace/object/tree/synctree/synctree.go | 2 +- .../object/tree/synctree/synctree_test.go | 10 +- .../object/tree/synctree/synctreehandler.go | 2 + .../tree/synctree/synctreehandler_test.go | 6 +- .../{syncprotocol.go => treesyncprotocol.go} | 0 .../tree/synctree/treesyncprotocol_test.go | 83 +++++++ .../object/tree/synctree/utils_test.go | 201 ++++++++------- .../mock_objectsync/mock_objectsync.go | 15 -- 10 files changed, 432 insertions(+), 121 deletions(-) rename commonspace/object/tree/synctree/{syncprotocol_test.go => protocolintegration_test.go} (100%) rename commonspace/object/tree/synctree/{syncprotocol.go => treesyncprotocol.go} (100%) create mode 100644 commonspace/object/tree/synctree/treesyncprotocol_test.go diff --git a/commonspace/object/tree/synctree/mock_synctree/mock_synctree.go b/commonspace/object/tree/synctree/mock_synctree/mock_synctree.go index 0f9d40ba..ca4789f1 100644 --- a/commonspace/object/tree/synctree/mock_synctree/mock_synctree.go +++ b/commonspace/object/tree/synctree/mock_synctree/mock_synctree.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/anyproto/any-sync/commonspace/object/tree/synctree (interfaces: SyncTree,ReceiveQueue,HeadNotifiable) +// Source: github.com/anyproto/any-sync/commonspace/object/tree/synctree (interfaces: SyncTree,ReceiveQueue,HeadNotifiable,SyncClient,RequestFactory) // Package mock_synctree is a generated GoMock package. package mock_synctree @@ -186,6 +186,21 @@ func (mr *MockSyncTreeMockRecorder) HandleMessage(arg0, arg1, arg2 interface{}) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleMessage", reflect.TypeOf((*MockSyncTree)(nil).HandleMessage), arg0, arg1, arg2) } +// HandleRequest mocks base method. +func (m *MockSyncTree) HandleRequest(arg0 context.Context, arg1 string, arg2 *spacesyncproto.ObjectSyncMessage) (*spacesyncproto.ObjectSyncMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HandleRequest", arg0, arg1, arg2) + ret0, _ := ret[0].(*spacesyncproto.ObjectSyncMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// HandleRequest indicates an expected call of HandleRequest. +func (mr *MockSyncTreeMockRecorder) HandleRequest(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleRequest", reflect.TypeOf((*MockSyncTree)(nil).HandleRequest), arg0, arg1, arg2) +} + // HasChanges mocks base method. func (m *MockSyncTree) HasChanges(arg0 ...string) bool { m.ctrl.T.Helper() @@ -590,3 +605,220 @@ func (mr *MockHeadNotifiableMockRecorder) UpdateHeads(arg0, arg1 interface{}) *g mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateHeads", reflect.TypeOf((*MockHeadNotifiable)(nil).UpdateHeads), arg0, arg1) } + +// 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 +} + +// Broadcast mocks base method. +func (m *MockSyncClient) Broadcast(arg0 *treechangeproto.TreeSyncMessage) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Broadcast", arg0) +} + +// Broadcast indicates an expected call of Broadcast. +func (mr *MockSyncClientMockRecorder) Broadcast(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Broadcast", reflect.TypeOf((*MockSyncClient)(nil).Broadcast), arg0) +} + +// CreateFullSyncRequest mocks base method. +func (m *MockSyncClient) CreateFullSyncRequest(arg0 objecttree.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 objecttree.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 objecttree.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)) +} + +// QueueRequest mocks base method. +func (m *MockSyncClient) QueueRequest(arg0, arg1 string, arg2 *treechangeproto.TreeSyncMessage) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "QueueRequest", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// QueueRequest indicates an expected call of QueueRequest. +func (mr *MockSyncClientMockRecorder) QueueRequest(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueueRequest", reflect.TypeOf((*MockSyncClient)(nil).QueueRequest), arg0, arg1, arg2) +} + +// SendRequest mocks base method. +func (m *MockSyncClient) SendRequest(arg0 context.Context, arg1, arg2 string, arg3 *treechangeproto.TreeSyncMessage) (*spacesyncproto.ObjectSyncMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SendRequest", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(*spacesyncproto.ObjectSyncMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SendRequest indicates an expected call of SendRequest. +func (mr *MockSyncClientMockRecorder) SendRequest(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendRequest", reflect.TypeOf((*MockSyncClient)(nil).SendRequest), arg0, arg1, arg2, arg3) +} + +// SendUpdate mocks base method. +func (m *MockSyncClient) SendUpdate(arg0, arg1 string, arg2 *treechangeproto.TreeSyncMessage) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SendUpdate", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// SendUpdate indicates an expected call of SendUpdate. +func (mr *MockSyncClientMockRecorder) SendUpdate(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendUpdate", reflect.TypeOf((*MockSyncClient)(nil).SendUpdate), arg0, arg1, arg2) +} + +// MockRequestFactory is a mock of RequestFactory interface. +type MockRequestFactory struct { + ctrl *gomock.Controller + recorder *MockRequestFactoryMockRecorder +} + +// MockRequestFactoryMockRecorder is the mock recorder for MockRequestFactory. +type MockRequestFactoryMockRecorder struct { + mock *MockRequestFactory +} + +// NewMockRequestFactory creates a new mock instance. +func NewMockRequestFactory(ctrl *gomock.Controller) *MockRequestFactory { + mock := &MockRequestFactory{ctrl: ctrl} + mock.recorder = &MockRequestFactoryMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockRequestFactory) EXPECT() *MockRequestFactoryMockRecorder { + return m.recorder +} + +// CreateFullSyncRequest mocks base method. +func (m *MockRequestFactory) CreateFullSyncRequest(arg0 objecttree.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 *MockRequestFactoryMockRecorder) CreateFullSyncRequest(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateFullSyncRequest", reflect.TypeOf((*MockRequestFactory)(nil).CreateFullSyncRequest), arg0, arg1, arg2) +} + +// CreateFullSyncResponse mocks base method. +func (m *MockRequestFactory) CreateFullSyncResponse(arg0 objecttree.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 *MockRequestFactoryMockRecorder) CreateFullSyncResponse(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateFullSyncResponse", reflect.TypeOf((*MockRequestFactory)(nil).CreateFullSyncResponse), arg0, arg1, arg2) +} + +// CreateHeadUpdate mocks base method. +func (m *MockRequestFactory) CreateHeadUpdate(arg0 objecttree.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 *MockRequestFactoryMockRecorder) CreateHeadUpdate(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateHeadUpdate", reflect.TypeOf((*MockRequestFactory)(nil).CreateHeadUpdate), arg0, arg1) +} + +// CreateNewTreeRequest mocks base method. +func (m *MockRequestFactory) 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 *MockRequestFactoryMockRecorder) CreateNewTreeRequest() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateNewTreeRequest", reflect.TypeOf((*MockRequestFactory)(nil).CreateNewTreeRequest)) +} diff --git a/commonspace/object/tree/synctree/syncprotocol_test.go b/commonspace/object/tree/synctree/protocolintegration_test.go similarity index 100% rename from commonspace/object/tree/synctree/syncprotocol_test.go rename to commonspace/object/tree/synctree/protocolintegration_test.go diff --git a/commonspace/object/tree/synctree/synctree.go b/commonspace/object/tree/synctree/synctree.go index 4c694880..f8558992 100644 --- a/commonspace/object/tree/synctree/synctree.go +++ b/commonspace/object/tree/synctree/synctree.go @@ -1,4 +1,4 @@ -//go:generate mockgen -destination mock_synctree/mock_synctree.go github.com/anyproto/any-sync/commonspace/object/tree/synctree SyncTree,ReceiveQueue,HeadNotifiable +//go:generate mockgen -destination mock_synctree/mock_synctree.go github.com/anyproto/any-sync/commonspace/object/tree/synctree SyncTree,ReceiveQueue,HeadNotifiable,SyncClient,RequestFactory package synctree import ( diff --git a/commonspace/object/tree/synctree/synctree_test.go b/commonspace/object/tree/synctree/synctree_test.go index 0c12bd34..76791c59 100644 --- a/commonspace/object/tree/synctree/synctree_test.go +++ b/commonspace/object/tree/synctree/synctree_test.go @@ -4,11 +4,11 @@ import ( "context" "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" "github.com/anyproto/any-sync/commonspace/object/tree/objecttree/mock_objecttree" + "github.com/anyproto/any-sync/commonspace/object/tree/synctree/mock_synctree" "github.com/anyproto/any-sync/commonspace/object/tree/synctree/updatelistener" "github.com/anyproto/any-sync/commonspace/object/tree/synctree/updatelistener/mock_updatelistener" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" "github.com/anyproto/any-sync/commonspace/objectsync" - "github.com/anyproto/any-sync/commonspace/objectsync/mock_objectsync" "github.com/anyproto/any-sync/commonspace/syncstatus" "github.com/anyproto/any-sync/nodeconf" "github.com/golang/mock/gomock" @@ -46,7 +46,7 @@ func Test_BuildSyncTree(t *testing.T) { defer ctrl.Finish() updateListenerMock := mock_updatelistener.NewMockUpdateListener(ctrl) - syncClientMock := mock_objectsync.NewMockSyncClient(ctrl) + syncClientMock := mock_synctree.NewMockSyncClient(ctrl) objTreeMock := newTestObjMock(mock_objecttree.NewMockObjectTree(ctrl)) tr := &syncTree{ ObjectTree: objTreeMock, @@ -73,7 +73,7 @@ func Test_BuildSyncTree(t *testing.T) { updateListenerMock.EXPECT().Update(tr) syncClientMock.EXPECT().CreateHeadUpdate(gomock.Eq(tr), gomock.Eq(changes)).Return(headUpdate) - syncClientMock.EXPECT().Broadcast(gomock.Any(), gomock.Eq(headUpdate)) + syncClientMock.EXPECT().Broadcast(gomock.Eq(headUpdate)) res, err := tr.AddRawChanges(ctx, payload) require.NoError(t, err) require.Equal(t, expectedRes, res) @@ -95,7 +95,7 @@ func Test_BuildSyncTree(t *testing.T) { updateListenerMock.EXPECT().Rebuild(tr) syncClientMock.EXPECT().CreateHeadUpdate(gomock.Eq(tr), gomock.Eq(changes)).Return(headUpdate) - syncClientMock.EXPECT().Broadcast(gomock.Any(), gomock.Eq(headUpdate)) + syncClientMock.EXPECT().Broadcast(gomock.Eq(headUpdate)) res, err := tr.AddRawChanges(ctx, payload) require.NoError(t, err) require.Equal(t, expectedRes, res) @@ -133,7 +133,7 @@ func Test_BuildSyncTree(t *testing.T) { Return(expectedRes, nil) syncClientMock.EXPECT().CreateHeadUpdate(gomock.Eq(tr), gomock.Eq(changes)).Return(headUpdate) - syncClientMock.EXPECT().Broadcast(gomock.Any(), gomock.Eq(headUpdate)) + syncClientMock.EXPECT().Broadcast(gomock.Eq(headUpdate)) res, err := tr.AddContent(ctx, content) require.NoError(t, err) require.Equal(t, expectedRes, res) diff --git a/commonspace/object/tree/synctree/synctreehandler.go b/commonspace/object/tree/synctree/synctreehandler.go index 43e764cc..154330f3 100644 --- a/commonspace/object/tree/synctree/synctreehandler.go +++ b/commonspace/object/tree/synctree/synctreehandler.go @@ -52,6 +52,8 @@ func (s *syncTreeHandler) HandleRequest(ctx context.Context, senderId string, re return } s.syncStatus.HeadsReceive(senderId, request.ObjectId, treechangeproto.GetHeads(unmarshalled)) + s.objTree.Lock() + defer s.objTree.Unlock() treeResp, err := s.syncProtocol.FullSyncRequest(ctx, senderId, fullSyncRequest) if err != nil { return diff --git a/commonspace/object/tree/synctree/synctreehandler_test.go b/commonspace/object/tree/synctree/synctreehandler_test.go index 4a65aad5..f029b092 100644 --- a/commonspace/object/tree/synctree/synctreehandler_test.go +++ b/commonspace/object/tree/synctree/synctreehandler_test.go @@ -63,19 +63,17 @@ type syncHandlerFixture struct { func newSyncHandlerFixture(t *testing.T) *syncHandlerFixture { ctrl := gomock.NewController(t) - syncClientMock := mock_objectsync.NewMockSyncClient(ctrl) objectTreeMock := newTestObjMock(mock_objecttree.NewMockObjectTree(ctrl)) receiveQueue := newReceiveQueue(5) syncHandler := &syncTreeHandler{ - objTree: objectTreeMock, - syncClient: syncClientMock, + objTree: objectTreeMock, + //syncClient: syncClientMock, queue: receiveQueue, syncStatus: syncstatus.NewNoOpSyncStatus(), } return &syncHandlerFixture{ ctrl: ctrl, - syncClientMock: syncClientMock, objectTreeMock: objectTreeMock, receiveQueueMock: receiveQueue, syncHandler: syncHandler, diff --git a/commonspace/object/tree/synctree/syncprotocol.go b/commonspace/object/tree/synctree/treesyncprotocol.go similarity index 100% rename from commonspace/object/tree/synctree/syncprotocol.go rename to commonspace/object/tree/synctree/treesyncprotocol.go diff --git a/commonspace/object/tree/synctree/treesyncprotocol_test.go b/commonspace/object/tree/synctree/treesyncprotocol_test.go new file mode 100644 index 00000000..19080908 --- /dev/null +++ b/commonspace/object/tree/synctree/treesyncprotocol_test.go @@ -0,0 +1,83 @@ +package synctree + +import ( + "context" + "github.com/anyproto/any-sync/app/logger" + "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" + "github.com/anyproto/any-sync/commonspace/object/tree/objecttree/mock_objecttree" + "github.com/anyproto/any-sync/commonspace/object/tree/synctree/mock_synctree" + "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + "testing" +) + +type treeSyncProtocolFixture struct { + log logger.CtxLogger + spaceId string + senderId string + treeId string + objectTreeMock *testObjTreeMock + reqFactory *mock_synctree.MockRequestFactory + ctrl *gomock.Controller + syncProtocol TreeSyncProtocol +} + +func newSyncProtocolFixture(t *testing.T) *treeSyncProtocolFixture { + ctrl := gomock.NewController(t) + objTree := &testObjTreeMock{ + MockObjectTree: mock_objecttree.NewMockObjectTree(ctrl), + } + spaceId := "spaceId" + reqFactory := mock_synctree.NewMockRequestFactory(ctrl) + objTree.EXPECT().Id().Return("treeId") + syncProtocol := newTreeSyncProtocol(spaceId, objTree, reqFactory) + return &treeSyncProtocolFixture{ + log: log, + spaceId: spaceId, + senderId: "senderId", + treeId: "treeId", + objectTreeMock: objTree, + reqFactory: reqFactory, + ctrl: ctrl, + syncProtocol: syncProtocol, + } +} + +func (fx *treeSyncProtocolFixture) finish() { + fx.ctrl.Finish() +} + +func TestTreeSyncProtocol_HeadUpdate(t *testing.T) { + ctx := context.Background() + //fullRequest := &treechangeproto.TreeSyncMessage{ + // Content: &treechangeproto.TreeSyncContentValue{ + // Value: &treechangeproto.TreeSyncContentValue_FullSyncRequest{ + // FullSyncRequest: &treechangeproto.TreeFullSyncRequest{}, + // }, + // }, + //} + t.Run("head update non empty all heads added", func(t *testing.T) { + fx := newSyncProtocolFixture(t) + chWithId := &treechangeproto.RawTreeChangeWithId{} + headUpdate := &treechangeproto.TreeHeadUpdate{ + Heads: []string{"h1"}, + Changes: []*treechangeproto.RawTreeChangeWithId{chWithId}, + SnapshotPath: []string{"h1"}, + } + fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId) + fx.objectTreeMock.EXPECT().Heads().Return([]string{"h2"}).Times(2) + fx.objectTreeMock.EXPECT().HasChanges(gomock.Eq([]string{"h1"})).Return(false) + fx.objectTreeMock.EXPECT(). + AddRawChanges(gomock.Any(), gomock.Eq(objecttree.RawChangesPayload{ + NewHeads: []string{"h1"}, + RawChanges: []*treechangeproto.RawTreeChangeWithId{chWithId}, + })). + Return(objecttree.AddResult{}, nil) + fx.objectTreeMock.EXPECT().HasChanges(gomock.Eq([]string{"h1"})).Return(true) + + res, err := fx.syncProtocol.HeadUpdate(ctx, fx.senderId, headUpdate) + require.NoError(t, err) + require.Nil(t, res) + }) +} diff --git a/commonspace/object/tree/synctree/utils_test.go b/commonspace/object/tree/synctree/utils_test.go index 6c295f9c..3ac8152a 100644 --- a/commonspace/object/tree/synctree/utils_test.go +++ b/commonspace/object/tree/synctree/utils_test.go @@ -3,6 +3,7 @@ package synctree import ( "context" "fmt" + "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/commonspace/object/acl/list" "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" @@ -81,51 +82,124 @@ func (m *messageLog) addMessage(msg protocolMsg) { m.batcher.Add(context.Background(), msg) } +type requestPeerManager struct { + peerId string + handlers map[string]*testSyncHandler + log *messageLog +} + +func newRequestPeerManager(peerId string, log *messageLog) *requestPeerManager { + return &requestPeerManager{ + peerId: peerId, + handlers: map[string]*testSyncHandler{}, + log: log, + } +} + +func (r *requestPeerManager) addHandler(peerId string, handler *testSyncHandler) { + r.handlers[peerId] = handler +} + +func (r *requestPeerManager) Run(ctx context.Context) (err error) { + return nil +} + +func (r *requestPeerManager) Close(ctx context.Context) (err error) { + return nil +} + +func (r *requestPeerManager) SendRequest(ctx context.Context, peerId string, msg *spacesyncproto.ObjectSyncMessage) (reply *spacesyncproto.ObjectSyncMessage, err error) { + panic("should not be called") +} + +func (r *requestPeerManager) QueueRequest(peerId string, msg *spacesyncproto.ObjectSyncMessage) (err error) { + pMsg := protocolMsg{ + msg: msg, + senderId: r.peerId, + receiverId: peerId, + } + r.log.addMessage(pMsg) + return r.handlers[peerId].send(context.Background(), pMsg) +} + +func (r *requestPeerManager) Init(a *app.App) (err error) { + return +} + +func (r *requestPeerManager) Name() (name string) { + return +} + +func (r *requestPeerManager) SendPeer(ctx context.Context, peerId string, msg *spacesyncproto.ObjectSyncMessage) (err error) { + pMsg := protocolMsg{ + msg: msg, + senderId: r.peerId, + receiverId: peerId, + } + r.log.addMessage(pMsg) + return r.handlers[peerId].send(context.Background(), pMsg) +} + +func (r *requestPeerManager) Broadcast(ctx context.Context, msg *spacesyncproto.ObjectSyncMessage) (err error) { + for _, handler := range r.handlers { + pMsg := protocolMsg{ + msg: msg, + senderId: r.peerId, + receiverId: handler.peerId, + } + r.log.addMessage(pMsg) + handler.send(context.Background(), pMsg) + } + return +} + +func (r *requestPeerManager) GetResponsiblePeers(ctx context.Context) (peers []peer.Peer, err error) { + return nil, nil +} + // testSyncHandler is the wrapper around individual tree to test sync protocol type testSyncHandler struct { synchandler.SyncHandler - batcher *mb.MB[protocolMsg] - peerId string - aclList list.AclList - log *messageLog - syncClient SyncClient - builder objecttree.BuildObjectTreeFunc + batcher *mb.MB[protocolMsg] + peerId string + aclList list.AclList + log *messageLog + syncClient SyncClient + builder objecttree.BuildObjectTreeFunc + peerManager *requestPeerManager } // createSyncHandler creates a sync handler when a tree is already created func createSyncHandler(peerId, spaceId string, objTree objecttree.ObjectTree, log *messageLog) *testSyncHandler { - factory := NewRequestFactory() - syncClient := NewSyncClient(spaceId, newTestMessagePool(peerId, log), factory) + peerManager := newRequestPeerManager(peerId, log) + syncClient := NewSyncClient(spaceId, peerManager, peerManager) netTree := &broadcastTree{ ObjectTree: objTree, SyncClient: syncClient, } handler := newSyncTreeHandler(spaceId, netTree, syncClient, syncstatus.NewNoOpSyncStatus()) - return newTestSyncHandler(peerId, handler) + return &testSyncHandler{ + SyncHandler: handler, + batcher: mb.New[protocolMsg](0), + peerId: peerId, + peerManager: peerManager, + } } // createEmptySyncHandler creates a sync handler when the tree will be provided later (this emulates the situation when we have no tree) func createEmptySyncHandler(peerId, spaceId string, builder objecttree.BuildObjectTreeFunc, aclList list.AclList, log *messageLog) *testSyncHandler { - factory := NewRequestFactory() - syncClient := NewSyncClient(spaceId, newTestMessagePool(peerId, log), factory) + peerManager := newRequestPeerManager(peerId, log) + syncClient := NewSyncClient(spaceId, peerManager, peerManager) batcher := mb.New[protocolMsg](0) return &testSyncHandler{ - batcher: batcher, - peerId: peerId, - aclList: aclList, - log: log, - syncClient: syncClient, - builder: builder, - } -} - -func newTestSyncHandler(peerId string, syncHandler synchandler.SyncHandler) *testSyncHandler { - batcher := mb.New[protocolMsg](0) - return &testSyncHandler{ - SyncHandler: syncHandler, batcher: batcher, peerId: peerId, + aclList: aclList, + log: log, + syncClient: syncClient, + builder: builder, + peerManager: peerManager, } } @@ -140,12 +214,7 @@ func (h *testSyncHandler) HandleMessage(ctx context.Context, senderId string, re } if unmarshalled.Content.GetFullSyncResponse() == nil { newTreeRequest := NewRequestFactory().CreateNewTreeRequest() - var objMsg *spacesyncproto.ObjectSyncMessage - objMsg, err = MarshallTreeMessage(newTreeRequest, request.SpaceId, request.ObjectId, "") - if err != nil { - return - } - return h.manager().SendPeer(context.Background(), senderId, objMsg) + return h.syncClient.QueueRequest(senderId, request.ObjectId, newTreeRequest) } fullSyncResponse := unmarshalled.Content.GetFullSyncResponse() treeStorage, _ := treestorage.NewInMemoryTreeStorage(unmarshalled.RootChange, []string{unmarshalled.RootChange.Id}, nil) @@ -165,20 +234,16 @@ func (h *testSyncHandler) HandleMessage(ctx context.Context, senderId string, re return } h.SyncHandler = newSyncTreeHandler(request.SpaceId, netTree, h.syncClient, syncstatus.NewNoOpSyncStatus()) - var objMsg *spacesyncproto.ObjectSyncMessage - newTreeRequest := NewRequestFactory().CreateHeadUpdate(netTree, res.Added) - objMsg, err = MarshallTreeMessage(newTreeRequest, request.SpaceId, request.ObjectId, "") - if err != nil { - return - } - return h.manager().Broadcast(context.Background(), objMsg) + headUpdate := NewRequestFactory().CreateHeadUpdate(netTree, res.Added) + h.syncClient.Broadcast(headUpdate) + return nil } -func (h *testSyncHandler) manager() *testMessagePool { +func (h *testSyncHandler) manager() *requestPeerManager { if h.SyncHandler != nil { - return h.SyncHandler.(*syncTreeHandler).syncClient.MessagePool().(*testMessagePool) + return h.manager() } - return h.syncClient.MessagePool().(*testMessagePool) + return h.peerManager } func (h *testSyncHandler) tree() *broadcastTree { @@ -219,60 +284,6 @@ func (h *testSyncHandler) run(ctx context.Context, t *testing.T, wg *sync.WaitGr }() } -// testMessagePool captures all other handlers and sends messages to them -type testMessagePool struct { - peerId string - handlers map[string]*testSyncHandler - log *messageLog -} - -func newTestMessagePool(peerId string, log *messageLog) *testMessagePool { - return &testMessagePool{handlers: map[string]*testSyncHandler{}, peerId: peerId, log: log} -} - -func (m *testMessagePool) addHandler(peerId string, handler *testSyncHandler) { - m.handlers[peerId] = handler -} - -func (m *testMessagePool) SendPeer(ctx context.Context, peerId string, msg *spacesyncproto.ObjectSyncMessage) (err error) { - pMsg := protocolMsg{ - msg: msg, - senderId: m.peerId, - receiverId: peerId, - } - m.log.addMessage(pMsg) - return m.handlers[peerId].send(context.Background(), pMsg) -} - -func (m *testMessagePool) Broadcast(ctx context.Context, msg *spacesyncproto.ObjectSyncMessage) (err error) { - for _, handler := range m.handlers { - pMsg := protocolMsg{ - msg: msg, - senderId: m.peerId, - receiverId: handler.peerId, - } - m.log.addMessage(pMsg) - handler.send(context.Background(), pMsg) - } - return -} - -func (m *testMessagePool) GetResponsiblePeers(ctx context.Context) (peers []peer.Peer, err error) { - panic("should not be called") -} - -func (m *testMessagePool) LastUsage() time.Time { - panic("should not be called") -} - -func (m *testMessagePool) HandleMessage(ctx context.Context, senderId string, request *spacesyncproto.ObjectSyncMessage) (err error) { - panic("should not be called") -} - -func (m *testMessagePool) SendSync(ctx context.Context, peerId string, message *spacesyncproto.ObjectSyncMessage) (reply *spacesyncproto.ObjectSyncMessage, err error) { - panic("should not be called") -} - // broadcastTree is the tree that broadcasts changes to everyone when changes are added // it is a simplified version of SyncTree which is easier to use in the test environment type broadcastTree struct { @@ -286,7 +297,7 @@ func (b *broadcastTree) AddRawChanges(ctx context.Context, changes objecttree.Ra return objecttree.AddResult{}, err } upd := b.SyncClient.CreateHeadUpdate(b.ObjectTree, res.Added) - b.SyncClient.Broadcast(ctx, upd) + b.SyncClient.Broadcast(upd) return res, nil } diff --git a/commonspace/objectsync/mock_objectsync/mock_objectsync.go b/commonspace/objectsync/mock_objectsync/mock_objectsync.go index 5aee48e8..e11f04a9 100644 --- a/commonspace/objectsync/mock_objectsync/mock_objectsync.go +++ b/commonspace/objectsync/mock_objectsync/mock_objectsync.go @@ -10,7 +10,6 @@ import ( objecttree "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" treechangeproto "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" - objectsync "github.com/anyproto/any-sync/commonspace/objectsync" spacesyncproto "github.com/anyproto/any-sync/commonspace/spacesyncproto" gomock "github.com/golang/mock/gomock" ) @@ -108,20 +107,6 @@ func (mr *MockSyncClientMockRecorder) CreateNewTreeRequest() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateNewTreeRequest", reflect.TypeOf((*MockSyncClient)(nil).CreateNewTreeRequest)) } -// MessagePool mocks base method. -func (m *MockSyncClient) MessagePool() objectsync.MessagePool { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "MessagePool") - ret0, _ := ret[0].(objectsync.MessagePool) - return ret0 -} - -// MessagePool indicates an expected call of MessagePool. -func (mr *MockSyncClientMockRecorder) MessagePool() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MessagePool", reflect.TypeOf((*MockSyncClient)(nil).MessagePool)) -} - // SendSync mocks base method. func (m *MockSyncClient) SendSync(arg0 context.Context, arg1, arg2 string, arg3 *treechangeproto.TreeSyncMessage) (*spacesyncproto.ObjectSyncMessage, error) { m.ctrl.T.Helper() From b18bb02176bdc6b9efddd77ad64202fb87458687 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Tue, 6 Jun 2023 20:50:53 +0200 Subject: [PATCH 017/123] TreeSyncProtocol tests --- .../tree/synctree/treesyncprotocol_test.go | 226 +++++++++++++++++- 1 file changed, 218 insertions(+), 8 deletions(-) diff --git a/commonspace/object/tree/synctree/treesyncprotocol_test.go b/commonspace/object/tree/synctree/treesyncprotocol_test.go index 19080908..c80dbe35 100644 --- a/commonspace/object/tree/synctree/treesyncprotocol_test.go +++ b/commonspace/object/tree/synctree/treesyncprotocol_test.go @@ -2,6 +2,7 @@ package synctree import ( "context" + "fmt" "github.com/anyproto/any-sync/app/logger" "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" "github.com/anyproto/any-sync/commonspace/object/tree/objecttree/mock_objecttree" @@ -44,21 +45,23 @@ func newSyncProtocolFixture(t *testing.T) *treeSyncProtocolFixture { } } -func (fx *treeSyncProtocolFixture) finish() { +func (fx *treeSyncProtocolFixture) stop() { fx.ctrl.Finish() } func TestTreeSyncProtocol_HeadUpdate(t *testing.T) { ctx := context.Background() - //fullRequest := &treechangeproto.TreeSyncMessage{ - // Content: &treechangeproto.TreeSyncContentValue{ - // Value: &treechangeproto.TreeSyncContentValue_FullSyncRequest{ - // FullSyncRequest: &treechangeproto.TreeFullSyncRequest{}, - // }, - // }, - //} + fullRequest := &treechangeproto.TreeSyncMessage{ + Content: &treechangeproto.TreeSyncContentValue{ + Value: &treechangeproto.TreeSyncContentValue_FullSyncRequest{ + FullSyncRequest: &treechangeproto.TreeFullSyncRequest{}, + }, + }, + } + t.Run("head update non empty all heads added", func(t *testing.T) { fx := newSyncProtocolFixture(t) + defer fx.stop() chWithId := &treechangeproto.RawTreeChangeWithId{} headUpdate := &treechangeproto.TreeHeadUpdate{ Heads: []string{"h1"}, @@ -80,4 +83,211 @@ func TestTreeSyncProtocol_HeadUpdate(t *testing.T) { require.NoError(t, err) require.Nil(t, res) }) + + t.Run("head update non empty equal heads", func(t *testing.T) { + fx := newSyncProtocolFixture(t) + defer fx.stop() + chWithId := &treechangeproto.RawTreeChangeWithId{} + headUpdate := &treechangeproto.TreeHeadUpdate{ + Heads: []string{"h1"}, + Changes: []*treechangeproto.RawTreeChangeWithId{chWithId}, + SnapshotPath: []string{"h1"}, + } + + fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId) + fx.objectTreeMock.EXPECT().Heads().Return([]string{"h1"}).AnyTimes() + + res, err := fx.syncProtocol.HeadUpdate(ctx, fx.senderId, headUpdate) + require.NoError(t, err) + require.Nil(t, res) + }) + + t.Run("head update empty", func(t *testing.T) { + fx := newSyncProtocolFixture(t) + defer fx.stop() + headUpdate := &treechangeproto.TreeHeadUpdate{ + Heads: []string{"h1"}, + Changes: nil, + SnapshotPath: []string{"h1"}, + } + + fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId) + fx.objectTreeMock.EXPECT().Heads().Return([]string{"h2"}).AnyTimes() + fx.reqFactory.EXPECT(). + CreateFullSyncRequest(gomock.Eq(fx.objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). + Return(fullRequest, nil) + + res, err := fx.syncProtocol.HeadUpdate(ctx, fx.senderId, headUpdate) + require.NoError(t, err) + require.Equal(t, fullRequest, res) + }) + + t.Run("head update empty equal heads", func(t *testing.T) { + fx := newSyncProtocolFixture(t) + defer fx.stop() + headUpdate := &treechangeproto.TreeHeadUpdate{ + Heads: []string{"h1"}, + Changes: nil, + SnapshotPath: []string{"h1"}, + } + + fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId) + fx.objectTreeMock.EXPECT().Heads().Return([]string{"h1"}).AnyTimes() + + res, err := fx.syncProtocol.HeadUpdate(ctx, fx.senderId, headUpdate) + require.NoError(t, err) + require.Nil(t, res) + }) +} + +func TestTreeSyncProtocol_FullSyncRequest(t *testing.T) { + ctx := context.Background() + fullResponse := &treechangeproto.TreeSyncMessage{ + Content: &treechangeproto.TreeSyncContentValue{ + Value: &treechangeproto.TreeSyncContentValue_FullSyncResponse{ + FullSyncResponse: &treechangeproto.TreeFullSyncResponse{}, + }, + }, + } + + t.Run("full sync request with change", func(t *testing.T) { + fx := newSyncProtocolFixture(t) + defer fx.stop() + chWithId := &treechangeproto.RawTreeChangeWithId{} + fullSyncRequest := &treechangeproto.TreeFullSyncRequest{ + Heads: []string{"h1"}, + Changes: []*treechangeproto.RawTreeChangeWithId{chWithId}, + SnapshotPath: []string{"h1"}, + } + + fx.objectTreeMock.EXPECT().Heads().Return([]string{"h2"}).AnyTimes() + fx.objectTreeMock.EXPECT().HasChanges(gomock.Eq([]string{"h1"})).Return(false) + fx.objectTreeMock.EXPECT(). + AddRawChanges(gomock.Any(), gomock.Eq(objecttree.RawChangesPayload{ + NewHeads: []string{"h1"}, + RawChanges: []*treechangeproto.RawTreeChangeWithId{chWithId}, + })). + Return(objecttree.AddResult{}, nil) + fx.reqFactory.EXPECT(). + CreateFullSyncResponse(gomock.Eq(fx.objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). + Return(fullResponse, nil) + + res, err := fx.syncProtocol.FullSyncRequest(ctx, fx.senderId, fullSyncRequest) + require.NoError(t, err) + require.Equal(t, fullResponse, res) + }) + + t.Run("full sync request with change same heads", func(t *testing.T) { + fx := newSyncProtocolFixture(t) + defer fx.stop() + chWithId := &treechangeproto.RawTreeChangeWithId{} + fullSyncRequest := &treechangeproto.TreeFullSyncRequest{ + Heads: []string{"h1"}, + Changes: []*treechangeproto.RawTreeChangeWithId{chWithId}, + SnapshotPath: []string{"h1"}, + } + + fx.objectTreeMock.EXPECT(). + Heads(). + Return([]string{"h1"}).AnyTimes() + fx.reqFactory.EXPECT(). + CreateFullSyncResponse(gomock.Eq(fx.objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). + Return(fullResponse, nil) + + res, err := fx.syncProtocol.FullSyncRequest(ctx, fx.senderId, fullSyncRequest) + require.NoError(t, err) + require.Equal(t, fullResponse, res) + }) + + t.Run("full sync request without changes", func(t *testing.T) { + fx := newSyncProtocolFixture(t) + defer fx.stop() + fullSyncRequest := &treechangeproto.TreeFullSyncRequest{ + Heads: []string{"h1"}, + SnapshotPath: []string{"h1"}, + } + + fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId) + fx.reqFactory.EXPECT(). + CreateFullSyncResponse(gomock.Eq(fx.objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). + Return(fullResponse, nil) + + res, err := fx.syncProtocol.FullSyncRequest(ctx, fx.senderId, fullSyncRequest) + require.NoError(t, err) + require.Equal(t, fullResponse, res) + }) + + t.Run("full sync request with change, raw changes error", func(t *testing.T) { + fx := newSyncProtocolFixture(t) + defer fx.stop() + chWithId := &treechangeproto.RawTreeChangeWithId{} + fullSyncRequest := &treechangeproto.TreeFullSyncRequest{ + Heads: []string{"h1"}, + Changes: []*treechangeproto.RawTreeChangeWithId{chWithId}, + SnapshotPath: []string{"h1"}, + } + + fx.objectTreeMock.EXPECT().Heads().Return([]string{"h2"}).AnyTimes() + fx.objectTreeMock.EXPECT().HasChanges(gomock.Eq([]string{"h1"})).Return(false) + fx.objectTreeMock.EXPECT(). + AddRawChanges(gomock.Any(), gomock.Eq(objecttree.RawChangesPayload{ + NewHeads: []string{"h1"}, + RawChanges: []*treechangeproto.RawTreeChangeWithId{chWithId}, + })). + Return(objecttree.AddResult{}, fmt.Errorf("addRawChanges error")) + + _, err := fx.syncProtocol.FullSyncRequest(ctx, fx.senderId, fullSyncRequest) + require.Error(t, err) + }) +} + +func TestTreeSyncProtocol_FullSyncResponse(t *testing.T) { + ctx := context.Background() + + t.Run("full sync response with change", func(t *testing.T) { + fx := newSyncProtocolFixture(t) + defer fx.stop() + chWithId := &treechangeproto.RawTreeChangeWithId{} + fullSyncResponse := &treechangeproto.TreeFullSyncResponse{ + Heads: []string{"h1"}, + Changes: []*treechangeproto.RawTreeChangeWithId{chWithId}, + SnapshotPath: []string{"h1"}, + } + + fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId) + fx.objectTreeMock.EXPECT(). + Heads(). + Return([]string{"h2"}).AnyTimes() + fx.objectTreeMock.EXPECT(). + HasChanges(gomock.Eq([]string{"h1"})). + Return(false) + fx.objectTreeMock.EXPECT(). + AddRawChanges(gomock.Any(), gomock.Eq(objecttree.RawChangesPayload{ + NewHeads: []string{"h1"}, + RawChanges: []*treechangeproto.RawTreeChangeWithId{chWithId}, + })). + Return(objecttree.AddResult{}, nil) + + err := fx.syncProtocol.FullSyncResponse(ctx, fx.senderId, fullSyncResponse) + require.NoError(t, err) + }) + + t.Run("full sync response with same heads", func(t *testing.T) { + fx := newSyncProtocolFixture(t) + defer fx.stop() + chWithId := &treechangeproto.RawTreeChangeWithId{} + fullSyncResponse := &treechangeproto.TreeFullSyncResponse{ + Heads: []string{"h1"}, + Changes: []*treechangeproto.RawTreeChangeWithId{chWithId}, + SnapshotPath: []string{"h1"}, + } + + fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId) + fx.objectTreeMock.EXPECT(). + Heads(). + Return([]string{"h1"}).AnyTimes() + + err := fx.syncProtocol.FullSyncResponse(ctx, fx.senderId, fullSyncResponse) + require.NoError(t, err) + }) } From 100e7e04c362da2b066b36c59a9396f6bcc27ddc Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Tue, 6 Jun 2023 21:49:23 +0200 Subject: [PATCH 018/123] SyncTreeHandler tests --- .../synctree/mock_synctree/mock_synctree.go | 69 ++- commonspace/object/tree/synctree/synctree.go | 2 +- .../tree/synctree/synctreehandler_test.go | 411 +++++------------- 3 files changed, 173 insertions(+), 309 deletions(-) diff --git a/commonspace/object/tree/synctree/mock_synctree/mock_synctree.go b/commonspace/object/tree/synctree/mock_synctree/mock_synctree.go index ca4789f1..792dbee7 100644 --- a/commonspace/object/tree/synctree/mock_synctree/mock_synctree.go +++ b/commonspace/object/tree/synctree/mock_synctree/mock_synctree.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/anyproto/any-sync/commonspace/object/tree/synctree (interfaces: SyncTree,ReceiveQueue,HeadNotifiable,SyncClient,RequestFactory) +// Source: github.com/anyproto/any-sync/commonspace/object/tree/synctree (interfaces: SyncTree,ReceiveQueue,HeadNotifiable,SyncClient,RequestFactory,TreeSyncProtocol) // Package mock_synctree is a generated GoMock package. package mock_synctree @@ -822,3 +822,70 @@ func (mr *MockRequestFactoryMockRecorder) CreateNewTreeRequest() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateNewTreeRequest", reflect.TypeOf((*MockRequestFactory)(nil).CreateNewTreeRequest)) } + +// MockTreeSyncProtocol is a mock of TreeSyncProtocol interface. +type MockTreeSyncProtocol struct { + ctrl *gomock.Controller + recorder *MockTreeSyncProtocolMockRecorder +} + +// MockTreeSyncProtocolMockRecorder is the mock recorder for MockTreeSyncProtocol. +type MockTreeSyncProtocolMockRecorder struct { + mock *MockTreeSyncProtocol +} + +// NewMockTreeSyncProtocol creates a new mock instance. +func NewMockTreeSyncProtocol(ctrl *gomock.Controller) *MockTreeSyncProtocol { + mock := &MockTreeSyncProtocol{ctrl: ctrl} + mock.recorder = &MockTreeSyncProtocolMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockTreeSyncProtocol) EXPECT() *MockTreeSyncProtocolMockRecorder { + return m.recorder +} + +// FullSyncRequest mocks base method. +func (m *MockTreeSyncProtocol) FullSyncRequest(arg0 context.Context, arg1 string, arg2 *treechangeproto.TreeFullSyncRequest) (*treechangeproto.TreeSyncMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FullSyncRequest", arg0, arg1, arg2) + ret0, _ := ret[0].(*treechangeproto.TreeSyncMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// FullSyncRequest indicates an expected call of FullSyncRequest. +func (mr *MockTreeSyncProtocolMockRecorder) FullSyncRequest(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FullSyncRequest", reflect.TypeOf((*MockTreeSyncProtocol)(nil).FullSyncRequest), arg0, arg1, arg2) +} + +// FullSyncResponse mocks base method. +func (m *MockTreeSyncProtocol) FullSyncResponse(arg0 context.Context, arg1 string, arg2 *treechangeproto.TreeFullSyncResponse) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FullSyncResponse", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// FullSyncResponse indicates an expected call of FullSyncResponse. +func (mr *MockTreeSyncProtocolMockRecorder) FullSyncResponse(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FullSyncResponse", reflect.TypeOf((*MockTreeSyncProtocol)(nil).FullSyncResponse), arg0, arg1, arg2) +} + +// HeadUpdate mocks base method. +func (m *MockTreeSyncProtocol) HeadUpdate(arg0 context.Context, arg1 string, arg2 *treechangeproto.TreeHeadUpdate) (*treechangeproto.TreeSyncMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HeadUpdate", arg0, arg1, arg2) + ret0, _ := ret[0].(*treechangeproto.TreeSyncMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// HeadUpdate indicates an expected call of HeadUpdate. +func (mr *MockTreeSyncProtocolMockRecorder) HeadUpdate(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HeadUpdate", reflect.TypeOf((*MockTreeSyncProtocol)(nil).HeadUpdate), arg0, arg1, arg2) +} diff --git a/commonspace/object/tree/synctree/synctree.go b/commonspace/object/tree/synctree/synctree.go index f8558992..cd6ff7a2 100644 --- a/commonspace/object/tree/synctree/synctree.go +++ b/commonspace/object/tree/synctree/synctree.go @@ -1,4 +1,4 @@ -//go:generate mockgen -destination mock_synctree/mock_synctree.go github.com/anyproto/any-sync/commonspace/object/tree/synctree SyncTree,ReceiveQueue,HeadNotifiable,SyncClient,RequestFactory +//go:generate mockgen -destination mock_synctree/mock_synctree.go github.com/anyproto/any-sync/commonspace/object/tree/synctree SyncTree,ReceiveQueue,HeadNotifiable,SyncClient,RequestFactory,TreeSyncProtocol package synctree import ( diff --git a/commonspace/object/tree/synctree/synctreehandler_test.go b/commonspace/object/tree/synctree/synctreehandler_test.go index f029b092..f03f5ff1 100644 --- a/commonspace/object/tree/synctree/synctreehandler_test.go +++ b/commonspace/object/tree/synctree/synctreehandler_test.go @@ -2,19 +2,15 @@ package synctree import ( "context" - "fmt" - "github.com/anyproto/any-sync/commonspace/objectsync/mock_objectsync" + "github.com/anyproto/any-sync/commonspace/object/tree/synctree/mock_synctree" + "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" + "github.com/stretchr/testify/require" "sync" "testing" - "github.com/anyproto/any-sync/app/logger" - "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" "github.com/anyproto/any-sync/commonspace/object/tree/objecttree/mock_objecttree" - "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" "github.com/anyproto/any-sync/commonspace/syncstatus" "github.com/golang/mock/gomock" - "github.com/stretchr/testify/require" - "go.uber.org/zap" ) type testObjTreeMock struct { @@ -54,9 +50,13 @@ func (t *testObjTreeMock) TryRLock() bool { type syncHandlerFixture struct { ctrl *gomock.Controller - syncClientMock *mock_objectsync.MockSyncClient + syncClientMock *mock_synctree.MockSyncClient objectTreeMock *testObjTreeMock receiveQueueMock ReceiveQueue + syncProtocolMock *mock_synctree.MockTreeSyncProtocol + spaceId string + senderId string + treeId string syncHandler *syncTreeHandler } @@ -64,19 +64,29 @@ type syncHandlerFixture struct { func newSyncHandlerFixture(t *testing.T) *syncHandlerFixture { ctrl := gomock.NewController(t) objectTreeMock := newTestObjMock(mock_objecttree.NewMockObjectTree(ctrl)) + syncClientMock := mock_synctree.NewMockSyncClient(ctrl) + syncProtocolMock := mock_synctree.NewMockTreeSyncProtocol(ctrl) + spaceId := "spaceId" receiveQueue := newReceiveQueue(5) syncHandler := &syncTreeHandler{ - objTree: objectTreeMock, - //syncClient: syncClientMock, - queue: receiveQueue, - syncStatus: syncstatus.NewNoOpSyncStatus(), + objTree: objectTreeMock, + syncClient: syncClientMock, + syncProtocol: syncProtocolMock, + spaceId: spaceId, + queue: receiveQueue, + syncStatus: syncstatus.NewNoOpSyncStatus(), } return &syncHandlerFixture{ ctrl: ctrl, objectTreeMock: objectTreeMock, receiveQueueMock: receiveQueue, + syncProtocolMock: syncProtocolMock, + syncClientMock: syncClientMock, syncHandler: syncHandler, + spaceId: spaceId, + senderId: "senderId", + treeId: "treeId", } } @@ -84,341 +94,128 @@ func (fx *syncHandlerFixture) stop() { fx.ctrl.Finish() } -func TestSyncHandler_HandleHeadUpdate(t *testing.T) { +func TestSyncTreeHandler_HandleMessage(t *testing.T) { ctx := context.Background() - log = logger.CtxLogger{Logger: zap.NewNop()} - fullRequest := &treechangeproto.TreeSyncMessage{ - Content: &treechangeproto.TreeSyncContentValue{ - Value: &treechangeproto.TreeSyncContentValue_FullSyncRequest{ - FullSyncRequest: &treechangeproto.TreeFullSyncRequest{}, - }, - }, - } - t.Run("head update non empty all heads added", func(t *testing.T) { + t.Run("handle head update message", func(t *testing.T) { fx := newSyncHandlerFixture(t) defer fx.stop() treeId := "treeId" - senderId := "senderId" chWithId := &treechangeproto.RawTreeChangeWithId{} - headUpdate := &treechangeproto.TreeHeadUpdate{ - Heads: []string{"h1"}, - Changes: []*treechangeproto.RawTreeChangeWithId{chWithId}, - SnapshotPath: []string{"h1"}, - } + headUpdate := &treechangeproto.TreeHeadUpdate{} treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "") - fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId) - fx.objectTreeMock.EXPECT().Heads().Return([]string{"h2"}).Times(2) - fx.objectTreeMock.EXPECT().HasChanges(gomock.Eq([]string{"h1"})).Return(false) - fx.objectTreeMock.EXPECT(). - AddRawChanges(gomock.Any(), gomock.Eq(objecttree.RawChangesPayload{ - NewHeads: []string{"h1"}, - RawChanges: []*treechangeproto.RawTreeChangeWithId{chWithId}, - })). - Return(objecttree.AddResult{}, nil) - fx.objectTreeMock.EXPECT().HasChanges(gomock.Eq([]string{"h1"})).Return(true) + syncReq := &treechangeproto.TreeSyncMessage{} + fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId) + fx.syncProtocolMock.EXPECT().HeadUpdate(ctx, fx.senderId, gomock.Any()).Return(syncReq, nil) + fx.syncClientMock.EXPECT().QueueRequest(fx.senderId, fx.treeId, syncReq).Return(nil) - err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) + err := fx.syncHandler.HandleMessage(ctx, fx.senderId, objectMsg) require.NoError(t, err) }) - t.Run("head update non empty heads not added", func(t *testing.T) { + t.Run("handle head update message, empty sync request", func(t *testing.T) { fx := newSyncHandlerFixture(t) defer fx.stop() treeId := "treeId" - senderId := "senderId" chWithId := &treechangeproto.RawTreeChangeWithId{} - headUpdate := &treechangeproto.TreeHeadUpdate{ - Heads: []string{"h1"}, - Changes: []*treechangeproto.RawTreeChangeWithId{chWithId}, - SnapshotPath: []string{"h1"}, - } + headUpdate := &treechangeproto.TreeHeadUpdate{} treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "") - fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId) - fx.objectTreeMock.EXPECT().Heads().Return([]string{"h2"}).AnyTimes() - fx.objectTreeMock.EXPECT().HasChanges(gomock.Eq([]string{"h1"})).Return(false) - fx.objectTreeMock.EXPECT(). - AddRawChanges(gomock.Any(), gomock.Eq(objecttree.RawChangesPayload{ - NewHeads: []string{"h1"}, - RawChanges: []*treechangeproto.RawTreeChangeWithId{chWithId}, - })). - Return(objecttree.AddResult{}, nil) - fx.objectTreeMock.EXPECT().HasChanges(gomock.Eq([]string{"h1"})).Return(false) - fx.syncClientMock.EXPECT(). - CreateFullSyncRequest(gomock.Eq(fx.objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). - Return(fullRequest, nil) - fx.syncClientMock.EXPECT().SendWithReply(gomock.Any(), gomock.Eq(senderId), gomock.Eq(treeId), gomock.Eq(fullRequest), gomock.Eq("")) + fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId) + fx.syncProtocolMock.EXPECT().HeadUpdate(ctx, fx.senderId, gomock.Any()).Return(nil, nil) - err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) + err := fx.syncHandler.HandleMessage(ctx, fx.senderId, objectMsg) require.NoError(t, err) }) - t.Run("head update non empty equal heads", func(t *testing.T) { + t.Run("handle full sync request returns error", func(t *testing.T) { fx := newSyncHandlerFixture(t) defer fx.stop() 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) + fullRequest := &treechangeproto.TreeFullSyncRequest{} + treeMsg := treechangeproto.WrapFullRequest(fullRequest, chWithId) objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "") - fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId) - fx.objectTreeMock.EXPECT().Heads().Return([]string{"h1"}).AnyTimes() + fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId) - err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) - require.NoError(t, err) + err := fx.syncHandler.HandleMessage(ctx, fx.senderId, objectMsg) + require.Equal(t, err, ErrMessageIsRequest) }) - t.Run("head update empty", func(t *testing.T) { + t.Run("handle full sync response", func(t *testing.T) { fx := newSyncHandlerFixture(t) defer fx.stop() 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, "spaceId", treeId, "") - - fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId) - fx.objectTreeMock.EXPECT().Heads().Return([]string{"h2"}).AnyTimes() - fx.syncClientMock.EXPECT(). - CreateFullSyncRequest(gomock.Eq(fx.objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). - Return(fullRequest, nil) - fx.syncClientMock.EXPECT().SendWithReply(gomock.Any(), gomock.Eq(senderId), gomock.Eq(treeId), gomock.Eq(fullRequest), gomock.Eq("")) - - err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) - require.NoError(t, err) - }) - - t.Run("head update empty equal heads", func(t *testing.T) { - fx := newSyncHandlerFixture(t) - defer fx.stop() - 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, "spaceId", treeId, "") - - fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId) - fx.objectTreeMock.EXPECT().Heads().Return([]string{"h1"}).AnyTimes() - - err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) - require.NoError(t, err) - }) -} - -func TestSyncHandler_HandleFullSyncRequest(t *testing.T) { - ctx := context.Background() - log = logger.CtxLogger{Logger: zap.NewNop()} - fullResponse := &treechangeproto.TreeSyncMessage{ - Content: &treechangeproto.TreeSyncContentValue{ - Value: &treechangeproto.TreeSyncContentValue_FullSyncResponse{ - FullSyncResponse: &treechangeproto.TreeFullSyncResponse{}, - }, - }, - } - - t.Run("full sync request with change", func(t *testing.T) { - fx := newSyncHandlerFixture(t) - defer fx.stop() - 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, "spaceId", treeId, "") - - fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId) - fx.objectTreeMock.EXPECT().Header().Return(nil) - fx.objectTreeMock.EXPECT().Heads().Return([]string{"h2"}).AnyTimes() - fx.objectTreeMock.EXPECT().HasChanges(gomock.Eq([]string{"h1"})).Return(false) - fx.objectTreeMock.EXPECT(). - AddRawChanges(gomock.Any(), gomock.Eq(objecttree.RawChangesPayload{ - NewHeads: []string{"h1"}, - RawChanges: []*treechangeproto.RawTreeChangeWithId{chWithId}, - })). - Return(objecttree.AddResult{}, nil) - fx.syncClientMock.EXPECT(). - CreateFullSyncResponse(gomock.Eq(fx.objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). - Return(fullResponse, nil) - fx.syncClientMock.EXPECT().SendWithReply(gomock.Any(), gomock.Eq(senderId), gomock.Eq(treeId), gomock.Eq(fullResponse), gomock.Eq("")) - - err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) - require.NoError(t, err) - }) - - t.Run("full sync request with change same heads", func(t *testing.T) { - fx := newSyncHandlerFixture(t) - defer fx.stop() - 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, "spaceId", treeId, "") - - fx.objectTreeMock.EXPECT(). - Id().AnyTimes().Return(treeId) - fx.objectTreeMock.EXPECT().Header().Return(nil) - fx.objectTreeMock.EXPECT(). - Heads(). - Return([]string{"h1"}).AnyTimes() - fx.syncClientMock.EXPECT(). - CreateFullSyncResponse(gomock.Eq(fx.objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). - Return(fullResponse, nil) - fx.syncClientMock.EXPECT().SendWithReply(gomock.Any(), gomock.Eq(senderId), gomock.Eq(treeId), gomock.Eq(fullResponse), gomock.Eq("")) - - err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) - require.NoError(t, err) - }) - - t.Run("full sync request without change but with reply id", func(t *testing.T) { - fx := newSyncHandlerFixture(t) - defer fx.stop() - 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, "spaceId", treeId, "") - objectMsg.RequestId = replyId - - fx.objectTreeMock.EXPECT(). - Id().AnyTimes().Return(treeId) - fx.objectTreeMock.EXPECT().Header().Return(nil) - fx.syncClientMock.EXPECT(). - CreateFullSyncResponse(gomock.Eq(fx.objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). - Return(fullResponse, nil) - fx.syncClientMock.EXPECT().SendWithReply(gomock.Any(), gomock.Eq(senderId), gomock.Eq(treeId), gomock.Eq(fullResponse), gomock.Eq(replyId)) - - err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) - require.NoError(t, err) - }) - - t.Run("full sync request with add raw changes error", func(t *testing.T) { - fx := newSyncHandlerFixture(t) - defer fx.stop() - 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, "spaceId", treeId, "") - - fx.objectTreeMock.EXPECT(). - Id().AnyTimes().Return(treeId) - fx.objectTreeMock.EXPECT().Header().Return(nil) - fx.objectTreeMock.EXPECT(). - Heads(). - Return([]string{"h2"}) - fx.objectTreeMock.EXPECT(). - HasChanges(gomock.Eq([]string{"h1"})). - Return(false) - fx.objectTreeMock.EXPECT(). - AddRawChanges(gomock.Any(), gomock.Eq(objecttree.RawChangesPayload{ - NewHeads: []string{"h1"}, - RawChanges: []*treechangeproto.RawTreeChangeWithId{chWithId}, - })). - Return(objecttree.AddResult{}, fmt.Errorf("")) - fx.syncClientMock.EXPECT().SendWithReply(gomock.Any(), gomock.Eq(senderId), gomock.Eq(treeId), gomock.Any(), gomock.Eq("")) - - err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) - require.Error(t, err) - }) -} - -func TestSyncHandler_HandleFullSyncResponse(t *testing.T) { - ctx := context.Background() - log = logger.CtxLogger{Logger: zap.NewNop()} - - t.Run("full sync response with change", func(t *testing.T) { - fx := newSyncHandlerFixture(t) - defer fx.stop() - treeId := "treeId" - senderId := "senderId" - replyId := "replyId" - chWithId := &treechangeproto.RawTreeChangeWithId{} - fullSyncResponse := &treechangeproto.TreeFullSyncResponse{ - Heads: []string{"h1"}, - Changes: []*treechangeproto.RawTreeChangeWithId{chWithId}, - SnapshotPath: []string{"h1"}, - } + fullSyncResponse := &treechangeproto.TreeFullSyncResponse{} treeMsg := treechangeproto.WrapFullResponse(fullSyncResponse, chWithId) - objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, replyId) + objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "") - fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId) - fx.objectTreeMock.EXPECT(). - Heads(). - Return([]string{"h2"}).AnyTimes() - fx.objectTreeMock.EXPECT(). - HasChanges(gomock.Eq([]string{"h1"})). - Return(false) - fx.objectTreeMock.EXPECT(). - AddRawChanges(gomock.Any(), gomock.Eq(objecttree.RawChangesPayload{ - NewHeads: []string{"h1"}, - RawChanges: []*treechangeproto.RawTreeChangeWithId{chWithId}, - })). - Return(objecttree.AddResult{}, nil) + fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId) + fx.syncProtocolMock.EXPECT().FullSyncResponse(ctx, fx.senderId, gomock.Any()).Return(nil) - err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) - require.NoError(t, err) - }) - - t.Run("full sync response with same heads", func(t *testing.T) { - fx := newSyncHandlerFixture(t) - defer fx.stop() - 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, "spaceId", treeId, replyId) - - fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(treeId) - fx.objectTreeMock.EXPECT(). - Heads(). - Return([]string{"h1"}).AnyTimes() - - err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) + err := fx.syncHandler.HandleMessage(ctx, fx.senderId, objectMsg) require.NoError(t, err) }) } + +func TestSyncTreeHandler_HandleRequest(t *testing.T) { + ctx := context.Background() + + t.Run("handle request", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() + treeId := "treeId" + chWithId := &treechangeproto.RawTreeChangeWithId{} + fullRequest := &treechangeproto.TreeFullSyncRequest{} + treeMsg := treechangeproto.WrapFullRequest(fullRequest, chWithId) + objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + + syncResp := &treechangeproto.TreeSyncMessage{} + fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId) + fx.syncProtocolMock.EXPECT().FullSyncRequest(ctx, fx.senderId, gomock.Any()).Return(syncResp, nil) + + res, err := fx.syncHandler.HandleRequest(ctx, fx.senderId, objectMsg) + require.NoError(t, err) + require.NotNil(t, res) + }) + + t.Run("handle request", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() + treeId := "treeId" + chWithId := &treechangeproto.RawTreeChangeWithId{} + fullRequest := &treechangeproto.TreeFullSyncRequest{} + treeMsg := treechangeproto.WrapFullRequest(fullRequest, chWithId) + objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + + syncResp := &treechangeproto.TreeSyncMessage{} + fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId) + fx.syncProtocolMock.EXPECT().FullSyncRequest(ctx, fx.senderId, gomock.Any()).Return(syncResp, nil) + + res, err := fx.syncHandler.HandleRequest(ctx, fx.senderId, objectMsg) + require.NoError(t, err) + require.NotNil(t, res) + }) + + t.Run("handle other message", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() + treeId := "treeId" + chWithId := &treechangeproto.RawTreeChangeWithId{} + fullResponse := &treechangeproto.TreeFullSyncResponse{} + responseMsg := treechangeproto.WrapFullResponse(fullResponse, chWithId) + headUpdate := &treechangeproto.TreeHeadUpdate{} + headUpdateMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) + for _, msg := range []*treechangeproto.TreeSyncMessage{responseMsg, headUpdateMsg} { + objectMsg, _ := MarshallTreeMessage(msg, "spaceId", treeId, "") + + _, err := fx.syncHandler.HandleRequest(ctx, fx.senderId, objectMsg) + require.Equal(t, err, ErrMessageIsNotRequest) + } + }) +} From 8310cb3c05550ee941d17a941a6b7acf53bc677f Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Tue, 6 Jun 2023 22:08:06 +0200 Subject: [PATCH 019/123] Fix sync protocol integration tests --- .../object/tree/synctree/utils_test.go | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/commonspace/object/tree/synctree/utils_test.go b/commonspace/object/tree/synctree/utils_test.go index 3ac8152a..6aab234b 100644 --- a/commonspace/object/tree/synctree/utils_test.go +++ b/commonspace/object/tree/synctree/utils_test.go @@ -240,9 +240,6 @@ func (h *testSyncHandler) HandleMessage(ctx context.Context, senderId string, re } func (h *testSyncHandler) manager() *requestPeerManager { - if h.SyncHandler != nil { - return h.manager() - } return h.peerManager } @@ -275,10 +272,18 @@ func (h *testSyncHandler) run(ctx context.Context, t *testing.T, wg *sync.WaitGr h.tree().Unlock() continue } - err = h.HandleMessage(ctx, res.senderId, res.msg) - if err != nil { - fmt.Println("error handling message", err.Error()) - continue + if res.description().name == "FullSyncRequest" { + resp, err := h.HandleRequest(ctx, res.senderId, res.msg) + if err != nil { + fmt.Println("error handling request", err.Error()) + continue + } + h.peerManager.SendPeer(ctx, res.senderId, resp) + } else { + err = h.HandleMessage(ctx, res.senderId, res.msg) + if err != nil { + fmt.Println("error handling message", err.Error()) + } } } }() From 2f5e0dd6c8b6b9057b32b4f5504385a8d116c94a Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Wed, 7 Jun 2023 11:30:27 +0200 Subject: [PATCH 020/123] WIP headsync tests revive --- .../mock_credentialprovider.go | 29 ++ commonspace/deletionstate/deletionstate.go | 2 +- .../mock_deletionstate/mock_deletionstate.go | 144 ++++++ commonspace/headsync/diffsyncer_test.go | 456 +++++++++--------- commonspace/headsync/headsync.go | 5 +- commonspace/headsync/headsync_test.go | 189 ++++++-- .../headsync/mock_headsync/mock_headsync.go | 9 +- .../mock_objectsync/mock_objectsync.go | 179 +++---- commonspace/objectsync/objectsync.go | 2 +- .../mock_objecttreebuilder.go | 99 ++++ commonspace/objecttreebuilder/treebuilder.go | 1 + .../mock_peermanager/mock_peermanager.go | 29 ++ .../requestmanager/requestmanager_test.go | 1 + .../mock_settingsstate/mock_settingsstate.go | 105 +--- .../mock_spacestorage/mock_spacestorage.go | 52 +- .../mock_spacesyncproto.go | 15 + 16 files changed, 839 insertions(+), 478 deletions(-) create mode 100644 commonspace/deletionstate/mock_deletionstate/mock_deletionstate.go create mode 100644 commonspace/objecttreebuilder/mock_objecttreebuilder/mock_objecttreebuilder.go create mode 100644 commonspace/requestmanager/requestmanager_test.go diff --git a/commonspace/credentialprovider/mock_credentialprovider/mock_credentialprovider.go b/commonspace/credentialprovider/mock_credentialprovider/mock_credentialprovider.go index a1f8dd97..77faf28e 100644 --- a/commonspace/credentialprovider/mock_credentialprovider/mock_credentialprovider.go +++ b/commonspace/credentialprovider/mock_credentialprovider/mock_credentialprovider.go @@ -8,6 +8,7 @@ import ( context "context" reflect "reflect" + app "github.com/anyproto/any-sync/app" spacesyncproto "github.com/anyproto/any-sync/commonspace/spacesyncproto" gomock "github.com/golang/mock/gomock" ) @@ -49,3 +50,31 @@ func (mr *MockCredentialProviderMockRecorder) GetCredential(arg0, arg1 interface mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCredential", reflect.TypeOf((*MockCredentialProvider)(nil).GetCredential), arg0, arg1) } + +// Init mocks base method. +func (m *MockCredentialProvider) 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 *MockCredentialProviderMockRecorder) Init(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockCredentialProvider)(nil).Init), arg0) +} + +// Name mocks base method. +func (m *MockCredentialProvider) 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 *MockCredentialProviderMockRecorder) Name() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockCredentialProvider)(nil).Name)) +} diff --git a/commonspace/deletionstate/deletionstate.go b/commonspace/deletionstate/deletionstate.go index 692ba627..f7d1d9a7 100644 --- a/commonspace/deletionstate/deletionstate.go +++ b/commonspace/deletionstate/deletionstate.go @@ -1,4 +1,4 @@ -//go:generate mockgen -destination mock_settingsstate/mock_settingsstate.go github.com/anyproto/any-sync/commonspace/settings/settingsstate ObjectDeletionState,StateBuilder,ChangeFactory +//go:generate mockgen -destination mock_deletionstate/mock_deletionstate.go github.com/anyproto/any-sync/commonspace/deletionstate ObjectDeletionState package deletionstate import ( diff --git a/commonspace/deletionstate/mock_deletionstate/mock_deletionstate.go b/commonspace/deletionstate/mock_deletionstate/mock_deletionstate.go new file mode 100644 index 00000000..c4e9fefb --- /dev/null +++ b/commonspace/deletionstate/mock_deletionstate/mock_deletionstate.go @@ -0,0 +1,144 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/anyproto/any-sync/commonspace/deletionstate (interfaces: ObjectDeletionState) + +// Package mock_deletionstate is a generated GoMock package. +package mock_deletionstate + +import ( + reflect "reflect" + + app "github.com/anyproto/any-sync/app" + deletionstate "github.com/anyproto/any-sync/commonspace/deletionstate" + gomock "github.com/golang/mock/gomock" +) + +// MockObjectDeletionState is a mock of ObjectDeletionState interface. +type MockObjectDeletionState struct { + ctrl *gomock.Controller + recorder *MockObjectDeletionStateMockRecorder +} + +// MockObjectDeletionStateMockRecorder is the mock recorder for MockObjectDeletionState. +type MockObjectDeletionStateMockRecorder struct { + mock *MockObjectDeletionState +} + +// NewMockObjectDeletionState creates a new mock instance. +func NewMockObjectDeletionState(ctrl *gomock.Controller) *MockObjectDeletionState { + mock := &MockObjectDeletionState{ctrl: ctrl} + mock.recorder = &MockObjectDeletionStateMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockObjectDeletionState) EXPECT() *MockObjectDeletionStateMockRecorder { + return m.recorder +} + +// Add mocks base method. +func (m *MockObjectDeletionState) Add(arg0 map[string]struct{}) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Add", arg0) +} + +// Add indicates an expected call of Add. +func (mr *MockObjectDeletionStateMockRecorder) Add(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Add", reflect.TypeOf((*MockObjectDeletionState)(nil).Add), arg0) +} + +// AddObserver mocks base method. +func (m *MockObjectDeletionState) AddObserver(arg0 deletionstate.StateUpdateObserver) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddObserver", arg0) +} + +// AddObserver indicates an expected call of AddObserver. +func (mr *MockObjectDeletionStateMockRecorder) AddObserver(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddObserver", reflect.TypeOf((*MockObjectDeletionState)(nil).AddObserver), arg0) +} + +// Delete mocks base method. +func (m *MockObjectDeletionState) Delete(arg0 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Delete", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Delete indicates an expected call of Delete. +func (mr *MockObjectDeletionStateMockRecorder) Delete(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockObjectDeletionState)(nil).Delete), arg0) +} + +// Exists mocks base method. +func (m *MockObjectDeletionState) Exists(arg0 string) bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Exists", arg0) + ret0, _ := ret[0].(bool) + return ret0 +} + +// Exists indicates an expected call of Exists. +func (mr *MockObjectDeletionStateMockRecorder) Exists(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Exists", reflect.TypeOf((*MockObjectDeletionState)(nil).Exists), arg0) +} + +// Filter mocks base method. +func (m *MockObjectDeletionState) Filter(arg0 []string) []string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Filter", arg0) + ret0, _ := ret[0].([]string) + return ret0 +} + +// Filter indicates an expected call of Filter. +func (mr *MockObjectDeletionStateMockRecorder) Filter(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Filter", reflect.TypeOf((*MockObjectDeletionState)(nil).Filter), arg0) +} + +// GetQueued mocks base method. +func (m *MockObjectDeletionState) GetQueued() []string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetQueued") + ret0, _ := ret[0].([]string) + return ret0 +} + +// GetQueued indicates an expected call of GetQueued. +func (mr *MockObjectDeletionStateMockRecorder) GetQueued() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetQueued", reflect.TypeOf((*MockObjectDeletionState)(nil).GetQueued)) +} + +// Init mocks base method. +func (m *MockObjectDeletionState) 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 *MockObjectDeletionStateMockRecorder) Init(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockObjectDeletionState)(nil).Init), arg0) +} + +// Name mocks base method. +func (m *MockObjectDeletionState) 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 *MockObjectDeletionStateMockRecorder) Name() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockObjectDeletionState)(nil).Name)) +} diff --git a/commonspace/headsync/diffsyncer_test.go b/commonspace/headsync/diffsyncer_test.go index fb1ad49c..d805c9f6 100644 --- a/commonspace/headsync/diffsyncer_test.go +++ b/commonspace/headsync/diffsyncer_test.go @@ -1,243 +1,235 @@ package headsync import ( - "bytes" - "context" - "fmt" - "github.com/anyproto/any-sync/app/ldiff" - "github.com/anyproto/any-sync/app/ldiff/mock_ldiff" - "github.com/anyproto/any-sync/app/logger" - "github.com/anyproto/any-sync/commonspace/credentialprovider/mock_credentialprovider" - "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" - "github.com/anyproto/any-sync/commonspace/object/acl/liststorage/mock_liststorage" - "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" - mock_treestorage "github.com/anyproto/any-sync/commonspace/object/tree/treestorage/mock_treestorage" - "github.com/anyproto/any-sync/commonspace/object/treemanager/mock_treemanager" - "github.com/anyproto/any-sync/commonspace/peermanager/mock_peermanager" - "github.com/anyproto/any-sync/commonspace/settings/settingsstate/mock_settingsstate" - "github.com/anyproto/any-sync/commonspace/spacestorage/mock_spacestorage" - "github.com/anyproto/any-sync/commonspace/spacesyncproto" - "github.com/anyproto/any-sync/commonspace/spacesyncproto/mock_spacesyncproto" - "github.com/anyproto/any-sync/commonspace/syncstatus" - "github.com/anyproto/any-sync/net/peer" "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 - settingsId string - credential []byte - spaceHeader *spacesyncproto.RawSpaceHeaderWithId +func (fx *headSyncFixture) initDiffSyncer(t *testing.T) { + fx.init(t) + fx.diffSyncer = newDiffSyncer(fx.headSync) + fx.deletionStateMock.EXPECT().AddObserver(gomock.Any()) + fx.treeManagerMock.EXPECT().NewTreeSyncer(fx.spaceState.SpaceId, fx.treeManagerMock).Return(fx.treeSyncerMock) + fx.diffSyncer.Init() } -func (p pushSpaceRequestMatcher) Matches(x interface{}) bool { - res, ok := x.(*spacesyncproto.SpacePushRequest) - if !ok { - return false - } - - return res.Payload.AclPayloadId == p.aclRootId && res.Payload.SpaceHeader == p.spaceHeader && res.Payload.SpaceSettingsPayloadId == p.settingsId && bytes.Equal(p.credential, res.Credential) +func TestDiffSyncer(t *testing.T) { + fx := newHeadSyncFixture(t) + fx.initDiffSyncer(t) + defer fx.stop() } -func (p pushSpaceRequestMatcher) String() string { - return "" -} - -type mockPeer struct{} - -func (m mockPeer) Addr() string { - return "" -} - -func (m mockPeer) TryClose(objectTTL time.Duration) (res bool, err error) { - return true, m.Close() -} - -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, - settingsId string, - credential []byte, - spaceHeader *spacesyncproto.RawSpaceHeaderWithId) *pushSpaceRequestMatcher { - return &pushSpaceRequestMatcher{ - spaceId: spaceId, - aclRootId: aclRootId, - settingsId: settingsId, - credential: credential, - spaceHeader: spaceHeader, - } -} - -func TestDiffSyncer_Sync(t *testing.T) { - // setup - ctx := context.Background() - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - diffMock := mock_ldiff.NewMockDiff(ctrl) - peerManagerMock := mock_peermanager.NewMockPeerManager(ctrl) - cacheMock := mock_treemanager.NewMockTreeManager(ctrl) - stMock := mock_spacestorage.NewMockSpaceStorage(ctrl) - clientMock := mock_spacesyncproto.NewMockDRPCSpaceSyncClient(ctrl) - factory := spacesyncproto.ClientFactoryFunc(func(cc drpc.Conn) spacesyncproto.DRPCSpaceSyncClient { - return clientMock - }) - treeSyncerMock := mock_treemanager.NewMockTreeSyncer(ctrl) - credentialProvider := mock_credentialprovider.NewMockCredentialProvider(ctrl) - delState := mock_settingsstate.NewMockObjectDeletionState(ctrl) - spaceId := "spaceId" - aclRootId := "aclRootId" - l := logger.NewNamed(spaceId) - diffSyncer := newDiffSyncer(spaceId, diffMock, peerManagerMock, cacheMock, stMock, factory, syncstatus.NewNoOpSyncStatus(), credentialProvider, l) - delState.EXPECT().AddObserver(gomock.Any()) - cacheMock.EXPECT().NewTreeSyncer(spaceId, gomock.Any()).Return(treeSyncerMock) - diffSyncer.Init(delState) - - t.Run("diff syncer sync", func(t *testing.T) { - mPeer := mockPeer{} - peerManagerMock.EXPECT(). - GetResponsiblePeers(gomock.Any()). - Return([]peer.Peer{mPeer}, nil) - diffMock.EXPECT(). - Diff(gomock.Any(), gomock.Eq(NewRemoteDiff(spaceId, clientMock))). - Return([]string{"new"}, []string{"changed"}, nil, nil) - delState.EXPECT().Filter([]string{"new"}).Return([]string{"new"}).Times(1) - delState.EXPECT().Filter([]string{"changed"}).Return([]string{"changed"}).Times(1) - delState.EXPECT().Filter(nil).Return(nil).Times(1) - treeSyncerMock.EXPECT().SyncAll(gomock.Any(), mPeer.Id(), []string{"changed"}, []string{"new"}).Return(nil) - require.NoError(t, diffSyncer.Sync(ctx)) - }) - - t.Run("diff syncer sync conf error", func(t *testing.T) { - peerManagerMock.EXPECT(). - GetResponsiblePeers(gomock.Any()). - Return(nil, fmt.Errorf("some error")) - - require.Error(t, diffSyncer.Sync(ctx)) - }) - - t.Run("deletion state remove objects", func(t *testing.T) { - deletedId := "id" - delState.EXPECT().Exists(deletedId).Return(true) - - // this should not result in any mock being called - diffSyncer.UpdateHeads(deletedId, []string{"someHead"}) - }) - - t.Run("update heads updates diff", func(t *testing.T) { - newId := "newId" - newHeads := []string{"h1", "h2"} - hash := "hash" - diffMock.EXPECT().Set(ldiff.Element{ - Id: newId, - Head: concatStrings(newHeads), - }) - diffMock.EXPECT().Hash().Return(hash) - delState.EXPECT().Exists(newId).Return(false) - stMock.EXPECT().WriteSpaceHash(hash) - diffSyncer.UpdateHeads(newId, newHeads) - }) - - t.Run("diff syncer sync space missing", func(t *testing.T) { - aclStorageMock := mock_liststorage.NewMockListStorage(ctrl) - settingsStorage := mock_treestorage.NewMockTreeStorage(ctrl) - settingsId := "settingsId" - aclRoot := &aclrecordproto.RawAclRecordWithId{ - Id: aclRootId, - } - settingsRoot := &treechangeproto.RawTreeChangeWithId{ - Id: settingsId, - } - spaceHeader := &spacesyncproto.RawSpaceHeaderWithId{} - spaceSettingsId := "spaceSettingsId" - credential := []byte("credential") - - peerManagerMock.EXPECT(). - GetResponsiblePeers(gomock.Any()). - Return([]peer.Peer{mockPeer{}}, nil) - diffMock.EXPECT(). - Diff(gomock.Any(), gomock.Eq(NewRemoteDiff(spaceId, clientMock))). - Return(nil, nil, nil, spacesyncproto.ErrSpaceMissing) - - stMock.EXPECT().AclStorage().Return(aclStorageMock, nil) - stMock.EXPECT().SpaceHeader().Return(spaceHeader, nil) - stMock.EXPECT().SpaceSettingsId().Return(spaceSettingsId) - stMock.EXPECT().TreeStorage(spaceSettingsId).Return(settingsStorage, nil) - - settingsStorage.EXPECT().Root().Return(settingsRoot, nil) - aclStorageMock.EXPECT(). - Root(). - Return(aclRoot, nil) - credentialProvider.EXPECT(). - GetCredential(gomock.Any(), spaceHeader). - Return(credential, nil) - clientMock.EXPECT(). - SpacePush(gomock.Any(), newPushSpaceRequestMatcher(spaceId, aclRootId, settingsId, credential, spaceHeader)). - Return(nil, nil) - peerManagerMock.EXPECT().SendPeer(gomock.Any(), "mockId", gomock.Any()) - - require.NoError(t, diffSyncer.Sync(ctx)) - }) - - t.Run("diff syncer sync unexpected", func(t *testing.T) { - peerManagerMock.EXPECT(). - GetResponsiblePeers(gomock.Any()). - Return([]peer.Peer{mockPeer{}}, nil) - diffMock.EXPECT(). - Diff(gomock.Any(), gomock.Eq(NewRemoteDiff(spaceId, clientMock))). - Return(nil, nil, nil, spacesyncproto.ErrUnexpected) - - require.NoError(t, diffSyncer.Sync(ctx)) - }) - - t.Run("diff syncer sync space is deleted error", func(t *testing.T) { - mPeer := mockPeer{} - peerManagerMock.EXPECT(). - GetResponsiblePeers(gomock.Any()). - Return([]peer.Peer{mPeer}, nil) - diffMock.EXPECT(). - Diff(gomock.Any(), gomock.Eq(NewRemoteDiff(spaceId, clientMock))). - Return(nil, nil, nil, spacesyncproto.ErrSpaceIsDeleted) - stMock.EXPECT().SpaceSettingsId().Return("settingsId") - treeSyncerMock.EXPECT().SyncAll(gomock.Any(), mPeer.Id(), []string{"settingsId"}, nil).Return(nil) - - require.NoError(t, diffSyncer.Sync(ctx)) - }) -} +// +//type pushSpaceRequestMatcher struct { +// spaceId string +// aclRootId string +// settingsId string +// credential []byte +// spaceHeader *spacesyncproto.RawSpaceHeaderWithId +//} +// +//func (p pushSpaceRequestMatcher) Matches(x interface{}) bool { +// res, ok := x.(*spacesyncproto.SpacePushRequest) +// if !ok { +// return false +// } +// +// return res.Payload.AclPayloadId == p.aclRootId && res.Payload.SpaceHeader == p.spaceHeader && res.Payload.SpaceSettingsPayloadId == p.settingsId && bytes.Equal(p.credential, res.Credential) +//} +// +//func (p pushSpaceRequestMatcher) String() string { +// return "" +//} +// +//type mockPeer struct{} +// +//func (m mockPeer) Addr() string { +// return "" +//} +// +//func (m mockPeer) TryClose(objectTTL time.Duration) (res bool, err error) { +// return true, m.Close() +//} +// +//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, +// settingsId string, +// credential []byte, +// spaceHeader *spacesyncproto.RawSpaceHeaderWithId) *pushSpaceRequestMatcher { +// return &pushSpaceRequestMatcher{ +// spaceId: spaceId, +// aclRootId: aclRootId, +// settingsId: settingsId, +// credential: credential, +// spaceHeader: spaceHeader, +// } +//} +// +//func TestDiffSyncer_Sync(t *testing.T) { +// // setup +// ctx := context.Background() +// ctrl := gomock.NewController(t) +// defer ctrl.Finish() +// +// diffMock := mock_ldiff.NewMockDiff(ctrl) +// peerManagerMock := mock_peermanager.NewMockPeerManager(ctrl) +// cacheMock := mock_treemanager.NewMockTreeManager(ctrl) +// stMock := mock_spacestorage.NewMockSpaceStorage(ctrl) +// clientMock := mock_spacesyncproto.NewMockDRPCSpaceSyncClient(ctrl) +// factory := spacesyncproto.ClientFactoryFunc(func(cc drpc.Conn) spacesyncproto.DRPCSpaceSyncClient { +// return clientMock +// }) +// treeSyncerMock := mock_treemanager.NewMockTreeSyncer(ctrl) +// credentialProvider := mock_credentialprovider.NewMockCredentialProvider(ctrl) +// delState := mock_settingsstate.NewMockObjectDeletionState(ctrl) +// spaceId := "spaceId" +// aclRootId := "aclRootId" +// l := logger.NewNamed(spaceId) +// diffSyncer := newDiffSyncer(spaceId, diffMock, peerManagerMock, cacheMock, stMock, factory, syncstatus.NewNoOpSyncStatus(), credentialProvider, l) +// delState.EXPECT().AddObserver(gomock.Any()) +// cacheMock.EXPECT().NewTreeSyncer(spaceId, gomock.Any()).Return(treeSyncerMock) +// diffSyncer.Init(delState) +// +// t.Run("diff syncer sync", func(t *testing.T) { +// mPeer := mockPeer{} +// peerManagerMock.EXPECT(). +// GetResponsiblePeers(gomock.Any()). +// Return([]peer.Peer{mPeer}, nil) +// diffMock.EXPECT(). +// Diff(gomock.Any(), gomock.Eq(NewRemoteDiff(spaceId, clientMock))). +// Return([]string{"new"}, []string{"changed"}, nil, nil) +// delState.EXPECT().Filter([]string{"new"}).Return([]string{"new"}).Times(1) +// delState.EXPECT().Filter([]string{"changed"}).Return([]string{"changed"}).Times(1) +// delState.EXPECT().Filter(nil).Return(nil).Times(1) +// treeSyncerMock.EXPECT().SyncAll(gomock.Any(), mPeer.Id(), []string{"changed"}, []string{"new"}).Return(nil) +// require.NoError(t, diffSyncer.Sync(ctx)) +// }) +// +// t.Run("diff syncer sync conf error", func(t *testing.T) { +// peerManagerMock.EXPECT(). +// GetResponsiblePeers(gomock.Any()). +// Return(nil, fmt.Errorf("some error")) +// +// require.Error(t, diffSyncer.Sync(ctx)) +// }) +// +// t.Run("deletion state remove objects", func(t *testing.T) { +// deletedId := "id" +// delState.EXPECT().Exists(deletedId).Return(true) +// +// // this should not result in any mock being called +// diffSyncer.UpdateHeads(deletedId, []string{"someHead"}) +// }) +// +// t.Run("update heads updates diff", func(t *testing.T) { +// newId := "newId" +// newHeads := []string{"h1", "h2"} +// hash := "hash" +// diffMock.EXPECT().Set(ldiff.Element{ +// Id: newId, +// Head: concatStrings(newHeads), +// }) +// diffMock.EXPECT().Hash().Return(hash) +// delState.EXPECT().Exists(newId).Return(false) +// stMock.EXPECT().WriteSpaceHash(hash) +// diffSyncer.UpdateHeads(newId, newHeads) +// }) +// +// t.Run("diff syncer sync space missing", func(t *testing.T) { +// aclStorageMock := mock_liststorage.NewMockListStorage(ctrl) +// settingsStorage := mock_treestorage.NewMockTreeStorage(ctrl) +// settingsId := "settingsId" +// aclRoot := &aclrecordproto.RawAclRecordWithId{ +// Id: aclRootId, +// } +// settingsRoot := &treechangeproto.RawTreeChangeWithId{ +// Id: settingsId, +// } +// spaceHeader := &spacesyncproto.RawSpaceHeaderWithId{} +// spaceSettingsId := "spaceSettingsId" +// credential := []byte("credential") +// +// peerManagerMock.EXPECT(). +// GetResponsiblePeers(gomock.Any()). +// Return([]peer.Peer{mockPeer{}}, nil) +// diffMock.EXPECT(). +// Diff(gomock.Any(), gomock.Eq(NewRemoteDiff(spaceId, clientMock))). +// Return(nil, nil, nil, spacesyncproto.ErrSpaceMissing) +// +// stMock.EXPECT().AclStorage().Return(aclStorageMock, nil) +// stMock.EXPECT().SpaceHeader().Return(spaceHeader, nil) +// stMock.EXPECT().SpaceSettingsId().Return(spaceSettingsId) +// stMock.EXPECT().TreeStorage(spaceSettingsId).Return(settingsStorage, nil) +// +// settingsStorage.EXPECT().Root().Return(settingsRoot, nil) +// aclStorageMock.EXPECT(). +// Root(). +// Return(aclRoot, nil) +// credentialProvider.EXPECT(). +// GetCredential(gomock.Any(), spaceHeader). +// Return(credential, nil) +// clientMock.EXPECT(). +// SpacePush(gomock.Any(), newPushSpaceRequestMatcher(spaceId, aclRootId, settingsId, credential, spaceHeader)). +// Return(nil, nil) +// peerManagerMock.EXPECT().SendPeer(gomock.Any(), "mockId", gomock.Any()) +// +// require.NoError(t, diffSyncer.Sync(ctx)) +// }) +// +// t.Run("diff syncer sync unexpected", func(t *testing.T) { +// peerManagerMock.EXPECT(). +// GetResponsiblePeers(gomock.Any()). +// Return([]peer.Peer{mockPeer{}}, nil) +// diffMock.EXPECT(). +// Diff(gomock.Any(), gomock.Eq(NewRemoteDiff(spaceId, clientMock))). +// Return(nil, nil, nil, spacesyncproto.ErrUnexpected) +// +// require.NoError(t, diffSyncer.Sync(ctx)) +// }) +// +// t.Run("diff syncer sync space is deleted error", func(t *testing.T) { +// mPeer := mockPeer{} +// peerManagerMock.EXPECT(). +// GetResponsiblePeers(gomock.Any()). +// Return([]peer.Peer{mPeer}, nil) +// diffMock.EXPECT(). +// Diff(gomock.Any(), gomock.Eq(NewRemoteDiff(spaceId, clientMock))). +// Return(nil, nil, nil, spacesyncproto.ErrSpaceIsDeleted) +// stMock.EXPECT().SpaceSettingsId().Return("settingsId") +// treeSyncerMock.EXPECT().SyncAll(gomock.Any(), mPeer.Id(), []string{"settingsId"}, nil).Return(nil) +// +// require.NoError(t, diffSyncer.Sync(ctx)) +// }) +//} diff --git a/commonspace/headsync/headsync.go b/commonspace/headsync/headsync.go index b838bd8b..18ed7357 100644 --- a/commonspace/headsync/headsync.go +++ b/commonspace/headsync/headsync.go @@ -1,3 +1,4 @@ +//go:generate mockgen -destination mock_headsync/mock_headsync.go github.com/anyproto/any-sync/commonspace/headsync DiffSyncer package headsync import ( @@ -65,6 +66,8 @@ func New() HeadSync { return &headSync{} } +var createDiffSyncer = newDiffSyncer + func (h *headSync) Init(a *app.App) (err error) { shared := a.MustComponent(spacestate.CName).(*spacestate.SpaceState) cfg := a.MustComponent("config").(config2.ConfigGetter) @@ -80,7 +83,7 @@ func (h *headSync) Init(a *app.App) (err error) { h.syncStatus = a.MustComponent(syncstatus.CName).(syncstatus.StatusService) h.treeManager = a.MustComponent(treemanager.CName).(treemanager.TreeManager) h.deletionState = a.MustComponent(deletionstate.CName).(deletionstate.ObjectDeletionState) - h.syncer = newDiffSyncer(h) + h.syncer = createDiffSyncer(h) sync := func(ctx context.Context) (err error) { // for clients cancelling the sync process if h.spaceIsDeleted.Load() && !h.configuration.IsResponsible(h.spaceId) { diff --git a/commonspace/headsync/headsync_test.go b/commonspace/headsync/headsync_test.go index ae2c419a..cdb4b293 100644 --- a/commonspace/headsync/headsync_test.go +++ b/commonspace/headsync/headsync_test.go @@ -1,71 +1,164 @@ package headsync import ( - "github.com/anyproto/any-sync/app/ldiff" - "github.com/anyproto/any-sync/app/ldiff/mock_ldiff" - "github.com/anyproto/any-sync/app/logger" + "context" + "github.com/anyproto/any-sync/app" + "github.com/anyproto/any-sync/commonspace/config" + "github.com/anyproto/any-sync/commonspace/credentialprovider" + "github.com/anyproto/any-sync/commonspace/credentialprovider/mock_credentialprovider" + "github.com/anyproto/any-sync/commonspace/deletionstate" + "github.com/anyproto/any-sync/commonspace/deletionstate/mock_deletionstate" "github.com/anyproto/any-sync/commonspace/headsync/mock_headsync" "github.com/anyproto/any-sync/commonspace/object/tree/treestorage/mock_treestorage" - "github.com/anyproto/any-sync/commonspace/settings/settingsstate/mock_settingsstate" + "github.com/anyproto/any-sync/commonspace/object/treemanager" + "github.com/anyproto/any-sync/commonspace/object/treemanager/mock_treemanager" + "github.com/anyproto/any-sync/commonspace/peermanager" + "github.com/anyproto/any-sync/commonspace/peermanager/mock_peermanager" + "github.com/anyproto/any-sync/commonspace/spacestate" + "github.com/anyproto/any-sync/commonspace/spacestorage" "github.com/anyproto/any-sync/commonspace/spacestorage/mock_spacestorage" - "github.com/anyproto/any-sync/util/periodicsync/mock_periodicsync" + "github.com/anyproto/any-sync/commonspace/syncstatus" + "github.com/anyproto/any-sync/nodeconf" + "github.com/anyproto/any-sync/nodeconf/mock_nodeconf" "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + "sync/atomic" "testing" ) -func TestDiffService(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() +type mockConfig struct { +} - spaceId := "spaceId" - l := logger.NewNamed("sync") - pSyncMock := mock_periodicsync.NewMockPeriodicSync(ctrl) - storageMock := mock_spacestorage.NewMockSpaceStorage(ctrl) - treeStorageMock := mock_treestorage.NewMockTreeStorage(ctrl) - diffMock := mock_ldiff.NewMockDiff(ctrl) - syncer := mock_headsync.NewMockDiffSyncer(ctrl) - delState := mock_settingsstate.NewMockObjectDeletionState(ctrl) - syncPeriod := 1 - initId := "initId" +func (m mockConfig) Init(a *app.App) (err error) { + return nil +} - service := &headSync{ - spaceId: spaceId, - storage: storageMock, - periodicSync: pSyncMock, - syncer: syncer, - diff: diffMock, - log: l, - syncPeriod: syncPeriod, +func (m mockConfig) Name() (name string) { + return "config" +} + +func (m mockConfig) GetSpace() config.Config { + return config.Config{} +} + +type headSyncFixture struct { + spaceState *spacestate.SpaceState + ctrl *gomock.Controller + app *app.App + + configurationMock *mock_nodeconf.MockService + storageMock *mock_spacestorage.MockSpaceStorage + peerManagerMock *mock_peermanager.MockPeerManager + credentialProviderMock *mock_credentialprovider.MockCredentialProvider + syncStatus syncstatus.StatusService + treeManagerMock *mock_treemanager.MockTreeManager + deletionStateMock *mock_deletionstate.MockObjectDeletionState + diffSyncerMock *mock_headsync.MockDiffSyncer + treeSyncerMock *mock_treemanager.MockTreeSyncer + headSync *headSync + diffSyncer DiffSyncer +} + +func newHeadSyncFixture(t *testing.T) *headSyncFixture { + spaceState := &spacestate.SpaceState{ + SpaceId: "spaceId", + SpaceIsDeleted: &atomic.Bool{}, } + ctrl := gomock.NewController(t) + configurationMock := mock_nodeconf.NewMockService(ctrl) + configurationMock.EXPECT().Name().AnyTimes().Return(nodeconf.CName) + storageMock := mock_spacestorage.NewMockSpaceStorage(ctrl) + storageMock.EXPECT().Name().AnyTimes().Return(spacestorage.CName) + peerManagerMock := mock_peermanager.NewMockPeerManager(ctrl) + peerManagerMock.EXPECT().Name().AnyTimes().Return(peermanager.CName) + credentialProviderMock := mock_credentialprovider.NewMockCredentialProvider(ctrl) + credentialProviderMock.EXPECT().Name().AnyTimes().Return(credentialprovider.CName) + syncStatus := syncstatus.NewNoOpSyncStatus() + treeManagerMock := mock_treemanager.NewMockTreeManager(ctrl) + treeManagerMock.EXPECT().Name().AnyTimes().Return(treemanager.CName) + deletionStateMock := mock_deletionstate.NewMockObjectDeletionState(ctrl) + deletionStateMock.EXPECT().Name().AnyTimes().Return(deletionstate.CName) + diffSyncerMock := mock_headsync.NewMockDiffSyncer(ctrl) + treeSyncerMock := mock_treemanager.NewMockTreeSyncer(ctrl) + hs := &headSync{} + a := &app.App{} + a.Register(spaceState). + Register(mockConfig{}). + Register(configurationMock). + Register(storageMock). + Register(peerManagerMock). + Register(credentialProviderMock). + Register(syncStatus). + Register(treeManagerMock). + Register(deletionStateMock). + Register(hs) + return &headSyncFixture{ + spaceState: spaceState, + ctrl: ctrl, + app: a, + configurationMock: configurationMock, + storageMock: storageMock, + peerManagerMock: peerManagerMock, + credentialProviderMock: credentialProviderMock, + syncStatus: syncStatus, + treeManagerMock: treeManagerMock, + deletionStateMock: deletionStateMock, + headSync: hs, + diffSyncerMock: diffSyncerMock, + treeSyncerMock: treeSyncerMock, + } +} - t.Run("init", func(t *testing.T) { - storageMock.EXPECT().TreeStorage(initId).Return(treeStorageMock, nil) - treeStorageMock.EXPECT().Heads().Return([]string{"h1", "h2"}, nil) - syncer.EXPECT().Init(delState) - diffMock.EXPECT().Set(ldiff.Element{ - Id: initId, - Head: "h1h2", - }) - hash := "123" - diffMock.EXPECT().Hash().Return(hash) - storageMock.EXPECT().WriteSpaceHash(hash) - pSyncMock.EXPECT().Run() - service.Init([]string{initId}, delState) +func (fx *headSyncFixture) init(t *testing.T) { + createDiffSyncer = func(hs *headSync) DiffSyncer { + return fx.diffSyncerMock + } + fx.diffSyncerMock.EXPECT().Init() + err := fx.headSync.Init(fx.app) + require.NoError(t, err) +} + +func (fx *headSyncFixture) stop() { + fx.ctrl.Finish() +} + +func TestHeadSync(t *testing.T) { + ctx := context.Background() + + t.Run("run close", func(t *testing.T) { + fx := newHeadSyncFixture(t) + fx.init(t) + defer fx.stop() + + ids := []string{"id1"} + treeMock := mock_treestorage.NewMockTreeStorage(fx.ctrl) + fx.storageMock.EXPECT().StoredIds().Return(ids, nil) + fx.storageMock.EXPECT().TreeStorage(ids[0]).Return(treeMock, nil) + treeMock.EXPECT().Heads().Return([]string{"h1"}, nil) + fx.storageMock.EXPECT().WriteSpaceHash(gomock.Any()).Return(nil) + fx.diffSyncerMock.EXPECT().Sync(gomock.Any()).Return(nil) + fx.diffSyncerMock.EXPECT().Close().Return(nil) + err := fx.headSync.Run(ctx) + require.NoError(t, err) + err = fx.headSync.Close(ctx) + require.NoError(t, err) }) t.Run("update heads", func(t *testing.T) { - syncer.EXPECT().UpdateHeads(initId, []string{"h1", "h2"}) - service.UpdateHeads(initId, []string{"h1", "h2"}) + fx := newHeadSyncFixture(t) + fx.init(t) + defer fx.stop() + + fx.diffSyncerMock.EXPECT().UpdateHeads("id1", []string{"h1"}) + fx.headSync.UpdateHeads("id1", []string{"h1"}) }) t.Run("remove objects", func(t *testing.T) { - syncer.EXPECT().RemoveObjects([]string{"h1", "h2"}) - service.RemoveObjects([]string{"h1", "h2"}) - }) + fx := newHeadSyncFixture(t) + fx.init(t) + defer fx.stop() - t.Run("close", func(t *testing.T) { - pSyncMock.EXPECT().Close() - syncer.EXPECT().Close() - service.Close() + fx.diffSyncerMock.EXPECT().RemoveObjects([]string{"id1"}) + fx.headSync.RemoveObjects([]string{"id1"}) }) } diff --git a/commonspace/headsync/mock_headsync/mock_headsync.go b/commonspace/headsync/mock_headsync/mock_headsync.go index 7df2fe64..46b16aab 100644 --- a/commonspace/headsync/mock_headsync/mock_headsync.go +++ b/commonspace/headsync/mock_headsync/mock_headsync.go @@ -8,7 +8,6 @@ import ( context "context" reflect "reflect" - settingsstate "github.com/anyproto/any-sync/commonspace/settings/settingsstate" gomock "github.com/golang/mock/gomock" ) @@ -50,15 +49,15 @@ func (mr *MockDiffSyncerMockRecorder) Close() *gomock.Call { } // Init mocks base method. -func (m *MockDiffSyncer) Init(arg0 settingsstate.ObjectDeletionState) { +func (m *MockDiffSyncer) Init() { m.ctrl.T.Helper() - m.ctrl.Call(m, "Init", arg0) + m.ctrl.Call(m, "Init") } // Init indicates an expected call of Init. -func (mr *MockDiffSyncerMockRecorder) Init(arg0 interface{}) *gomock.Call { +func (mr *MockDiffSyncerMockRecorder) Init() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockDiffSyncer)(nil).Init), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockDiffSyncer)(nil).Init)) } // RemoveObjects mocks base method. diff --git a/commonspace/objectsync/mock_objectsync/mock_objectsync.go b/commonspace/objectsync/mock_objectsync/mock_objectsync.go index e11f04a9..2858c6f9 100644 --- a/commonspace/objectsync/mock_objectsync/mock_objectsync.go +++ b/commonspace/objectsync/mock_objectsync/mock_objectsync.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/anyproto/any-sync/commonspace/objectsync (interfaces: SyncClient) +// Source: github.com/anyproto/any-sync/commonspace/objectsync (interfaces: ObjectSync) // Package mock_objectsync is a generated GoMock package. package mock_objectsync @@ -7,131 +7,146 @@ package mock_objectsync import ( context "context" reflect "reflect" + time "time" - objecttree "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" - treechangeproto "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" + app "github.com/anyproto/any-sync/app" + objectsync "github.com/anyproto/any-sync/commonspace/objectsync" spacesyncproto "github.com/anyproto/any-sync/commonspace/spacesyncproto" gomock "github.com/golang/mock/gomock" ) -// MockSyncClient is a mock of SyncClient interface. -type MockSyncClient struct { +// MockObjectSync is a mock of ObjectSync interface. +type MockObjectSync struct { ctrl *gomock.Controller - recorder *MockSyncClientMockRecorder + recorder *MockObjectSyncMockRecorder } -// MockSyncClientMockRecorder is the mock recorder for MockSyncClient. -type MockSyncClientMockRecorder struct { - mock *MockSyncClient +// MockObjectSyncMockRecorder is the mock recorder for MockObjectSync. +type MockObjectSyncMockRecorder struct { + mock *MockObjectSync } -// NewMockSyncClient creates a new mock instance. -func NewMockSyncClient(ctrl *gomock.Controller) *MockSyncClient { - mock := &MockSyncClient{ctrl: ctrl} - mock.recorder = &MockSyncClientMockRecorder{mock} +// NewMockObjectSync creates a new mock instance. +func NewMockObjectSync(ctrl *gomock.Controller) *MockObjectSync { + mock := &MockObjectSync{ctrl: ctrl} + mock.recorder = &MockObjectSyncMockRecorder{mock} return mock } // EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockSyncClient) EXPECT() *MockSyncClientMockRecorder { +func (m *MockObjectSync) EXPECT() *MockObjectSyncMockRecorder { return m.recorder } -// Broadcast mocks base method. -func (m *MockSyncClient) Broadcast(arg0 context.Context, arg1 *treechangeproto.TreeSyncMessage) { +// Close mocks base method. +func (m *MockObjectSync) Close(arg0 context.Context) error { m.ctrl.T.Helper() - m.ctrl.Call(m, "Broadcast", arg0, arg1) -} - -// Broadcast indicates an expected call of Broadcast. -func (mr *MockSyncClientMockRecorder) Broadcast(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Broadcast", reflect.TypeOf((*MockSyncClient)(nil).Broadcast), arg0, arg1) -} - -// CreateFullSyncRequest mocks base method. -func (m *MockSyncClient) CreateFullSyncRequest(arg0 objecttree.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 objecttree.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 objecttree.ObjectTree, arg1 []*treechangeproto.RawTreeChangeWithId) *treechangeproto.TreeSyncMessage { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreateHeadUpdate", arg0, arg1) - ret0, _ := ret[0].(*treechangeproto.TreeSyncMessage) + ret := m.ctrl.Call(m, "Close", arg0) + ret0, _ := ret[0].(error) return ret0 } -// CreateHeadUpdate indicates an expected call of CreateHeadUpdate. -func (mr *MockSyncClientMockRecorder) CreateHeadUpdate(arg0, arg1 interface{}) *gomock.Call { +// Close indicates an expected call of Close. +func (mr *MockObjectSyncMockRecorder) Close(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateHeadUpdate", reflect.TypeOf((*MockSyncClient)(nil).CreateHeadUpdate), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockObjectSync)(nil).Close), arg0) } -// CreateNewTreeRequest mocks base method. -func (m *MockSyncClient) CreateNewTreeRequest() *treechangeproto.TreeSyncMessage { +// CloseThread mocks base method. +func (m *MockObjectSync) CloseThread(arg0 string) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreateNewTreeRequest") - ret0, _ := ret[0].(*treechangeproto.TreeSyncMessage) + ret := m.ctrl.Call(m, "CloseThread", arg0) + ret0, _ := ret[0].(error) return ret0 } -// CreateNewTreeRequest indicates an expected call of CreateNewTreeRequest. -func (mr *MockSyncClientMockRecorder) CreateNewTreeRequest() *gomock.Call { +// CloseThread indicates an expected call of CloseThread. +func (mr *MockObjectSyncMockRecorder) CloseThread(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateNewTreeRequest", reflect.TypeOf((*MockSyncClient)(nil).CreateNewTreeRequest)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseThread", reflect.TypeOf((*MockObjectSync)(nil).CloseThread), arg0) } -// SendSync mocks base method. -func (m *MockSyncClient) SendSync(arg0 context.Context, arg1, arg2 string, arg3 *treechangeproto.TreeSyncMessage) (*spacesyncproto.ObjectSyncMessage, error) { +// HandleMessage mocks base method. +func (m *MockObjectSync) HandleMessage(arg0 context.Context, arg1 objectsync.HandleMessage) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SendSync", arg0, arg1, arg2, arg3) + ret := m.ctrl.Call(m, "HandleMessage", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// HandleMessage indicates an expected call of HandleMessage. +func (mr *MockObjectSyncMockRecorder) HandleMessage(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleMessage", reflect.TypeOf((*MockObjectSync)(nil).HandleMessage), arg0, arg1) +} + +// HandleRequest mocks base method. +func (m *MockObjectSync) HandleRequest(arg0 context.Context, arg1 *spacesyncproto.ObjectSyncMessage) (*spacesyncproto.ObjectSyncMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HandleRequest", arg0, arg1) ret0, _ := ret[0].(*spacesyncproto.ObjectSyncMessage) ret1, _ := ret[1].(error) return ret0, ret1 } -// SendSync indicates an expected call of SendSync. -func (mr *MockSyncClientMockRecorder) SendSync(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +// HandleRequest indicates an expected call of HandleRequest. +func (mr *MockObjectSyncMockRecorder) HandleRequest(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendSync", reflect.TypeOf((*MockSyncClient)(nil).SendSync), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleRequest", reflect.TypeOf((*MockObjectSync)(nil).HandleRequest), arg0, arg1) } -// SendWithReply mocks base method. -func (m *MockSyncClient) SendWithReply(arg0 context.Context, arg1, arg2 string, arg3 *treechangeproto.TreeSyncMessage, arg4 string) error { +// Init mocks base method. +func (m *MockObjectSync) Init(arg0 *app.App) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SendWithReply", arg0, arg1, arg2, arg3, arg4) + ret := m.ctrl.Call(m, "Init", arg0) ret0, _ := ret[0].(error) return ret0 } -// SendWithReply indicates an expected call of SendWithReply. -func (mr *MockSyncClientMockRecorder) SendWithReply(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { +// Init indicates an expected call of Init. +func (mr *MockObjectSyncMockRecorder) Init(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendWithReply", reflect.TypeOf((*MockSyncClient)(nil).SendWithReply), arg0, arg1, arg2, arg3, arg4) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockObjectSync)(nil).Init), arg0) +} + +// LastUsage mocks base method. +func (m *MockObjectSync) LastUsage() time.Time { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "LastUsage") + ret0, _ := ret[0].(time.Time) + return ret0 +} + +// LastUsage indicates an expected call of LastUsage. +func (mr *MockObjectSyncMockRecorder) LastUsage() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LastUsage", reflect.TypeOf((*MockObjectSync)(nil).LastUsage)) +} + +// Name mocks base method. +func (m *MockObjectSync) 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 *MockObjectSyncMockRecorder) Name() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockObjectSync)(nil).Name)) +} + +// Run mocks base method. +func (m *MockObjectSync) 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 *MockObjectSyncMockRecorder) Run(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockObjectSync)(nil).Run), arg0) } diff --git a/commonspace/objectsync/objectsync.go b/commonspace/objectsync/objectsync.go index 386cbb15..d2febaee 100644 --- a/commonspace/objectsync/objectsync.go +++ b/commonspace/objectsync/objectsync.go @@ -1,4 +1,4 @@ -//go:generate mockgen -destination mock_objectsync/mock_objectsync.go github.com/anyproto/any-sync/commonspace/objectsync SyncClient +//go:generate mockgen -destination mock_objectsync/mock_objectsync.go github.com/anyproto/any-sync/commonspace/objectsync ObjectSync package objectsync import ( diff --git a/commonspace/objecttreebuilder/mock_objecttreebuilder/mock_objecttreebuilder.go b/commonspace/objecttreebuilder/mock_objecttreebuilder/mock_objecttreebuilder.go new file mode 100644 index 00000000..d7cca965 --- /dev/null +++ b/commonspace/objecttreebuilder/mock_objecttreebuilder/mock_objecttreebuilder.go @@ -0,0 +1,99 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/anyproto/any-sync/commonspace/objecttreebuilder (interfaces: TreeBuilder) + +// Package mock_objecttreebuilder is a generated GoMock package. +package mock_objecttreebuilder + +import ( + context "context" + reflect "reflect" + + objecttree "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" + updatelistener "github.com/anyproto/any-sync/commonspace/object/tree/synctree/updatelistener" + treestorage "github.com/anyproto/any-sync/commonspace/object/tree/treestorage" + objecttreebuilder "github.com/anyproto/any-sync/commonspace/objecttreebuilder" + gomock "github.com/golang/mock/gomock" +) + +// MockTreeBuilder is a mock of TreeBuilder interface. +type MockTreeBuilder struct { + ctrl *gomock.Controller + recorder *MockTreeBuilderMockRecorder +} + +// MockTreeBuilderMockRecorder is the mock recorder for MockTreeBuilder. +type MockTreeBuilderMockRecorder struct { + mock *MockTreeBuilder +} + +// NewMockTreeBuilder creates a new mock instance. +func NewMockTreeBuilder(ctrl *gomock.Controller) *MockTreeBuilder { + mock := &MockTreeBuilder{ctrl: ctrl} + mock.recorder = &MockTreeBuilderMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockTreeBuilder) EXPECT() *MockTreeBuilderMockRecorder { + return m.recorder +} + +// BuildHistoryTree mocks base method. +func (m *MockTreeBuilder) BuildHistoryTree(arg0 context.Context, arg1 string, arg2 objecttreebuilder.HistoryTreeOpts) (objecttree.HistoryTree, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BuildHistoryTree", arg0, arg1, arg2) + ret0, _ := ret[0].(objecttree.HistoryTree) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// BuildHistoryTree indicates an expected call of BuildHistoryTree. +func (mr *MockTreeBuilderMockRecorder) BuildHistoryTree(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BuildHistoryTree", reflect.TypeOf((*MockTreeBuilder)(nil).BuildHistoryTree), arg0, arg1, arg2) +} + +// BuildTree mocks base method. +func (m *MockTreeBuilder) BuildTree(arg0 context.Context, arg1 string, arg2 objecttreebuilder.BuildTreeOpts) (objecttree.ObjectTree, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BuildTree", arg0, arg1, arg2) + ret0, _ := ret[0].(objecttree.ObjectTree) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// BuildTree indicates an expected call of BuildTree. +func (mr *MockTreeBuilderMockRecorder) BuildTree(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BuildTree", reflect.TypeOf((*MockTreeBuilder)(nil).BuildTree), arg0, arg1, arg2) +} + +// CreateTree mocks base method. +func (m *MockTreeBuilder) CreateTree(arg0 context.Context, arg1 objecttree.ObjectTreeCreatePayload) (treestorage.TreeStorageCreatePayload, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateTree", arg0, arg1) + ret0, _ := ret[0].(treestorage.TreeStorageCreatePayload) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateTree indicates an expected call of CreateTree. +func (mr *MockTreeBuilderMockRecorder) CreateTree(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateTree", reflect.TypeOf((*MockTreeBuilder)(nil).CreateTree), arg0, arg1) +} + +// PutTree mocks base method. +func (m *MockTreeBuilder) PutTree(arg0 context.Context, arg1 treestorage.TreeStorageCreatePayload, arg2 updatelistener.UpdateListener) (objecttree.ObjectTree, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PutTree", arg0, arg1, arg2) + ret0, _ := ret[0].(objecttree.ObjectTree) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PutTree indicates an expected call of PutTree. +func (mr *MockTreeBuilderMockRecorder) PutTree(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutTree", reflect.TypeOf((*MockTreeBuilder)(nil).PutTree), arg0, arg1, arg2) +} diff --git a/commonspace/objecttreebuilder/treebuilder.go b/commonspace/objecttreebuilder/treebuilder.go index 15f9bdbf..058efe16 100644 --- a/commonspace/objecttreebuilder/treebuilder.go +++ b/commonspace/objecttreebuilder/treebuilder.go @@ -1,3 +1,4 @@ +//go:generate mockgen -destination mock_objecttreebuilder/mock_objecttreebuilder.go github.com/anyproto/any-sync/commonspace/objecttreebuilder TreeBuilder package objecttreebuilder import ( diff --git a/commonspace/peermanager/mock_peermanager/mock_peermanager.go b/commonspace/peermanager/mock_peermanager/mock_peermanager.go index a77e0ab1..210fb319 100644 --- a/commonspace/peermanager/mock_peermanager/mock_peermanager.go +++ b/commonspace/peermanager/mock_peermanager/mock_peermanager.go @@ -8,6 +8,7 @@ import ( context "context" reflect "reflect" + app "github.com/anyproto/any-sync/app" spacesyncproto "github.com/anyproto/any-sync/commonspace/spacesyncproto" peer "github.com/anyproto/any-sync/net/peer" gomock "github.com/golang/mock/gomock" @@ -65,6 +66,34 @@ func (mr *MockPeerManagerMockRecorder) GetResponsiblePeers(arg0 interface{}) *go return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetResponsiblePeers", reflect.TypeOf((*MockPeerManager)(nil).GetResponsiblePeers), arg0) } +// Init mocks base method. +func (m *MockPeerManager) 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 *MockPeerManagerMockRecorder) Init(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockPeerManager)(nil).Init), arg0) +} + +// Name mocks base method. +func (m *MockPeerManager) 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 *MockPeerManagerMockRecorder) Name() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockPeerManager)(nil).Name)) +} + // SendPeer mocks base method. func (m *MockPeerManager) SendPeer(arg0 context.Context, arg1 string, arg2 *spacesyncproto.ObjectSyncMessage) error { m.ctrl.T.Helper() diff --git a/commonspace/requestmanager/requestmanager_test.go b/commonspace/requestmanager/requestmanager_test.go new file mode 100644 index 00000000..e5e89798 --- /dev/null +++ b/commonspace/requestmanager/requestmanager_test.go @@ -0,0 +1 @@ +package requestmanager diff --git a/commonspace/settings/settingsstate/mock_settingsstate/mock_settingsstate.go b/commonspace/settings/settingsstate/mock_settingsstate/mock_settingsstate.go index 0bc9bf23..2bb898cf 100644 --- a/commonspace/settings/settingsstate/mock_settingsstate/mock_settingsstate.go +++ b/commonspace/settings/settingsstate/mock_settingsstate/mock_settingsstate.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/anyproto/any-sync/commonspace/settings/settingsstate (interfaces: ObjectDeletionState,StateBuilder,ChangeFactory) +// Source: github.com/anyproto/any-sync/commonspace/settings/settingsstate (interfaces: StateBuilder,ChangeFactory) // Package mock_settingsstate is a generated GoMock package. package mock_settingsstate @@ -12,109 +12,6 @@ import ( gomock "github.com/golang/mock/gomock" ) -// MockObjectDeletionState is a mock of ObjectDeletionState interface. -type MockObjectDeletionState struct { - ctrl *gomock.Controller - recorder *MockObjectDeletionStateMockRecorder -} - -// MockObjectDeletionStateMockRecorder is the mock recorder for MockObjectDeletionState. -type MockObjectDeletionStateMockRecorder struct { - mock *MockObjectDeletionState -} - -// NewMockObjectDeletionState creates a new mock instance. -func NewMockObjectDeletionState(ctrl *gomock.Controller) *MockObjectDeletionState { - mock := &MockObjectDeletionState{ctrl: ctrl} - mock.recorder = &MockObjectDeletionStateMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockObjectDeletionState) EXPECT() *MockObjectDeletionStateMockRecorder { - return m.recorder -} - -// Add mocks base method. -func (m *MockObjectDeletionState) Add(arg0 map[string]struct{}) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "Add", arg0) -} - -// Add indicates an expected call of Add. -func (mr *MockObjectDeletionStateMockRecorder) Add(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Add", reflect.TypeOf((*MockObjectDeletionState)(nil).Add), arg0) -} - -// AddObserver mocks base method. -func (m *MockObjectDeletionState) AddObserver(arg0 settingsstate.StateUpdateObserver) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddObserver", arg0) -} - -// AddObserver indicates an expected call of AddObserver. -func (mr *MockObjectDeletionStateMockRecorder) AddObserver(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddObserver", reflect.TypeOf((*MockObjectDeletionState)(nil).AddObserver), arg0) -} - -// Delete mocks base method. -func (m *MockObjectDeletionState) Delete(arg0 string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Delete", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Delete indicates an expected call of Delete. -func (mr *MockObjectDeletionStateMockRecorder) Delete(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockObjectDeletionState)(nil).Delete), arg0) -} - -// Exists mocks base method. -func (m *MockObjectDeletionState) Exists(arg0 string) bool { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Exists", arg0) - ret0, _ := ret[0].(bool) - return ret0 -} - -// Exists indicates an expected call of Exists. -func (mr *MockObjectDeletionStateMockRecorder) Exists(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Exists", reflect.TypeOf((*MockObjectDeletionState)(nil).Exists), arg0) -} - -// Filter mocks base method. -func (m *MockObjectDeletionState) Filter(arg0 []string) []string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Filter", arg0) - ret0, _ := ret[0].([]string) - return ret0 -} - -// Filter indicates an expected call of Filter. -func (mr *MockObjectDeletionStateMockRecorder) Filter(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Filter", reflect.TypeOf((*MockObjectDeletionState)(nil).Filter), arg0) -} - -// GetQueued mocks base method. -func (m *MockObjectDeletionState) GetQueued() []string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetQueued") - ret0, _ := ret[0].([]string) - return ret0 -} - -// GetQueued indicates an expected call of GetQueued. -func (mr *MockObjectDeletionStateMockRecorder) GetQueued() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetQueued", reflect.TypeOf((*MockObjectDeletionState)(nil).GetQueued)) -} - // MockStateBuilder is a mock of StateBuilder interface. type MockStateBuilder struct { ctrl *gomock.Controller diff --git a/commonspace/spacestorage/mock_spacestorage/mock_spacestorage.go b/commonspace/spacestorage/mock_spacestorage/mock_spacestorage.go index a8410488..bc7f448c 100644 --- a/commonspace/spacestorage/mock_spacestorage/mock_spacestorage.go +++ b/commonspace/spacestorage/mock_spacestorage/mock_spacestorage.go @@ -5,8 +5,10 @@ package mock_spacestorage import ( + context "context" reflect "reflect" + app "github.com/anyproto/any-sync/app" liststorage "github.com/anyproto/any-sync/commonspace/object/acl/liststorage" treechangeproto "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" treestorage "github.com/anyproto/any-sync/commonspace/object/tree/treestorage" @@ -53,17 +55,17 @@ func (mr *MockSpaceStorageMockRecorder) AclStorage() *gomock.Call { } // Close mocks base method. -func (m *MockSpaceStorage) Close() error { +func (m *MockSpaceStorage) Close(arg0 context.Context) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Close") + ret := m.ctrl.Call(m, "Close", arg0) ret0, _ := ret[0].(error) return ret0 } // Close indicates an expected call of Close. -func (mr *MockSpaceStorageMockRecorder) Close() *gomock.Call { +func (mr *MockSpaceStorageMockRecorder) Close(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockSpaceStorage)(nil).Close)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockSpaceStorage)(nil).Close), arg0) } // CreateTreeStorage mocks base method. @@ -110,6 +112,20 @@ func (mr *MockSpaceStorageMockRecorder) Id() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Id", reflect.TypeOf((*MockSpaceStorage)(nil).Id)) } +// Init mocks base method. +func (m *MockSpaceStorage) 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 *MockSpaceStorageMockRecorder) Init(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockSpaceStorage)(nil).Init), arg0) +} + // IsSpaceDeleted mocks base method. func (m *MockSpaceStorage) IsSpaceDeleted() (bool, error) { m.ctrl.T.Helper() @@ -125,6 +141,20 @@ func (mr *MockSpaceStorageMockRecorder) IsSpaceDeleted() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsSpaceDeleted", reflect.TypeOf((*MockSpaceStorage)(nil).IsSpaceDeleted)) } +// Name mocks base method. +func (m *MockSpaceStorage) 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 *MockSpaceStorageMockRecorder) Name() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockSpaceStorage)(nil).Name)) +} + // ReadSpaceHash mocks base method. func (m *MockSpaceStorage) ReadSpaceHash() (string, error) { m.ctrl.T.Helper() @@ -140,6 +170,20 @@ func (mr *MockSpaceStorageMockRecorder) ReadSpaceHash() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadSpaceHash", reflect.TypeOf((*MockSpaceStorage)(nil).ReadSpaceHash)) } +// Run mocks base method. +func (m *MockSpaceStorage) 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 *MockSpaceStorageMockRecorder) Run(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockSpaceStorage)(nil).Run), arg0) +} + // SetSpaceDeleted mocks base method. func (m *MockSpaceStorage) SetSpaceDeleted() error { m.ctrl.T.Helper() diff --git a/commonspace/spacesyncproto/mock_spacesyncproto/mock_spacesyncproto.go b/commonspace/spacesyncproto/mock_spacesyncproto/mock_spacesyncproto.go index db8313a2..8d8a1111 100644 --- a/commonspace/spacesyncproto/mock_spacesyncproto/mock_spacesyncproto.go +++ b/commonspace/spacesyncproto/mock_spacesyncproto/mock_spacesyncproto.go @@ -65,6 +65,21 @@ func (mr *MockDRPCSpaceSyncClientMockRecorder) HeadSync(arg0, arg1 interface{}) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HeadSync", reflect.TypeOf((*MockDRPCSpaceSyncClient)(nil).HeadSync), arg0, arg1) } +// ObjectSync mocks base method. +func (m *MockDRPCSpaceSyncClient) ObjectSync(arg0 context.Context, arg1 *spacesyncproto.ObjectSyncMessage) (*spacesyncproto.ObjectSyncMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ObjectSync", arg0, arg1) + ret0, _ := ret[0].(*spacesyncproto.ObjectSyncMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ObjectSync indicates an expected call of ObjectSync. +func (mr *MockDRPCSpaceSyncClientMockRecorder) ObjectSync(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ObjectSync", reflect.TypeOf((*MockDRPCSpaceSyncClient)(nil).ObjectSync), arg0, arg1) +} + // ObjectSyncStream mocks base method. func (m *MockDRPCSpaceSyncClient) ObjectSyncStream(arg0 context.Context) (spacesyncproto.DRPCSpaceSync_ObjectSyncStreamClient, error) { m.ctrl.T.Helper() From 4ef617b1f21872cb04d3ccb2d3bbecde82bb0643 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Wed, 7 Jun 2023 13:06:37 +0200 Subject: [PATCH 021/123] More headsync tests --- commonspace/headsync/diffsyncer_test.go | 69 +++++++++++++++++++++++-- commonspace/headsync/headsync_test.go | 21 ++++++-- 2 files changed, 83 insertions(+), 7 deletions(-) diff --git a/commonspace/headsync/diffsyncer_test.go b/commonspace/headsync/diffsyncer_test.go index d805c9f6..4c6fcdc9 100644 --- a/commonspace/headsync/diffsyncer_test.go +++ b/commonspace/headsync/diffsyncer_test.go @@ -1,13 +1,57 @@ package headsync import ( + "context" + "github.com/anyproto/any-sync/commonspace/spacesyncproto" + "github.com/anyproto/any-sync/net/peer" "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + "storj.io/drpc" "testing" + "time" ) +type mockPeer struct { +} + +func (m mockPeer) Id() string { + return "peerId" +} + +func (m mockPeer) Context() context.Context { + return context.Background() +} + +func (m mockPeer) AcquireDrpcConn(ctx context.Context) (drpc.Conn, error) { + return nil, nil +} + +func (m mockPeer) ReleaseDrpcConn(conn drpc.Conn) { + return +} + +func (m mockPeer) DoDrpc(ctx context.Context, do func(conn drpc.Conn) error) error { + return nil +} + +func (m mockPeer) IsClosed() bool { + return false +} + +func (m mockPeer) TryClose(objectTTL time.Duration) (res bool, err error) { + return false, err +} + +func (m mockPeer) Close() (err error) { + return nil +} + func (fx *headSyncFixture) initDiffSyncer(t *testing.T) { fx.init(t) - fx.diffSyncer = newDiffSyncer(fx.headSync) + fx.diffSyncer = newDiffSyncer(fx.headSync).(*diffSyncer) + fx.diffSyncer.clientFactory = spacesyncproto.ClientFactoryFunc(func(cc drpc.Conn) spacesyncproto.DRPCSpaceSyncClient { + return fx.clientMock + }) fx.deletionStateMock.EXPECT().AddObserver(gomock.Any()) fx.treeManagerMock.EXPECT().NewTreeSyncer(fx.spaceState.SpaceId, fx.treeManagerMock).Return(fx.treeSyncerMock) fx.diffSyncer.Init() @@ -17,6 +61,22 @@ func TestDiffSyncer(t *testing.T) { fx := newHeadSyncFixture(t) fx.initDiffSyncer(t) defer fx.stop() + ctx := context.Background() + + t.Run("diff syncer sync", func(t *testing.T) { + mPeer := mockPeer{} + fx.peerManagerMock.EXPECT(). + GetResponsiblePeers(gomock.Any()). + Return([]peer.Peer{mPeer}, nil) + fx.diffMock.EXPECT(). + Diff(gomock.Any(), gomock.Eq(NewRemoteDiff(fx.spaceState.SpaceId, fx.clientMock))). + Return([]string{"new"}, []string{"changed"}, nil, nil) + fx.deletionStateMock.EXPECT().Filter([]string{"new"}).Return([]string{"new"}).Times(1) + fx.deletionStateMock.EXPECT().Filter([]string{"changed"}).Return([]string{"changed"}).Times(1) + fx.deletionStateMock.EXPECT().Filter(nil).Return(nil).Times(1) + fx.treeSyncerMock.EXPECT().SyncAll(gomock.Any(), mPeer.Id(), []string{"changed"}, []string{"new"}).Return(nil) + require.NoError(t, fx.diffSyncer.Sync(ctx)) + }) } // @@ -99,9 +159,9 @@ func TestDiffSyncer(t *testing.T) { // //func TestDiffSyncer_Sync(t *testing.T) { // // setup -// ctx := context.Background() -// ctrl := gomock.NewController(t) -// defer ctrl.Finish() +// fx := newHeadSyncFixture(t) +// fx.initDiffSyncer(t) +// defer fx.stop() // // diffMock := mock_ldiff.NewMockDiff(ctrl) // peerManagerMock := mock_peermanager.NewMockPeerManager(ctrl) @@ -136,6 +196,7 @@ func TestDiffSyncer(t *testing.T) { // treeSyncerMock.EXPECT().SyncAll(gomock.Any(), mPeer.Id(), []string{"changed"}, []string{"new"}).Return(nil) // require.NoError(t, diffSyncer.Sync(ctx)) // }) +//} // // t.Run("diff syncer sync conf error", func(t *testing.T) { // peerManagerMock.EXPECT(). diff --git a/commonspace/headsync/headsync_test.go b/commonspace/headsync/headsync_test.go index cdb4b293..4f14d084 100644 --- a/commonspace/headsync/headsync_test.go +++ b/commonspace/headsync/headsync_test.go @@ -3,6 +3,8 @@ package headsync import ( "context" "github.com/anyproto/any-sync/app" + "github.com/anyproto/any-sync/app/ldiff" + "github.com/anyproto/any-sync/app/ldiff/mock_ldiff" "github.com/anyproto/any-sync/commonspace/config" "github.com/anyproto/any-sync/commonspace/credentialprovider" "github.com/anyproto/any-sync/commonspace/credentialprovider/mock_credentialprovider" @@ -17,6 +19,7 @@ import ( "github.com/anyproto/any-sync/commonspace/spacestate" "github.com/anyproto/any-sync/commonspace/spacestorage" "github.com/anyproto/any-sync/commonspace/spacestorage/mock_spacestorage" + "github.com/anyproto/any-sync/commonspace/spacesyncproto/mock_spacesyncproto" "github.com/anyproto/any-sync/commonspace/syncstatus" "github.com/anyproto/any-sync/nodeconf" "github.com/anyproto/any-sync/nodeconf/mock_nodeconf" @@ -55,8 +58,10 @@ type headSyncFixture struct { deletionStateMock *mock_deletionstate.MockObjectDeletionState diffSyncerMock *mock_headsync.MockDiffSyncer treeSyncerMock *mock_treemanager.MockTreeSyncer + diffMock *mock_ldiff.MockDiff + clientMock *mock_spacesyncproto.MockDRPCSpaceSyncClient headSync *headSync - diffSyncer DiffSyncer + diffSyncer *diffSyncer } func newHeadSyncFixture(t *testing.T) *headSyncFixture { @@ -80,6 +85,8 @@ func newHeadSyncFixture(t *testing.T) *headSyncFixture { deletionStateMock.EXPECT().Name().AnyTimes().Return(deletionstate.CName) diffSyncerMock := mock_headsync.NewMockDiffSyncer(ctrl) treeSyncerMock := mock_treemanager.NewMockTreeSyncer(ctrl) + diffMock := mock_ldiff.NewMockDiff(ctrl) + clientMock := mock_spacesyncproto.NewMockDRPCSpaceSyncClient(ctrl) hs := &headSync{} a := &app.App{} a.Register(spaceState). @@ -106,6 +113,8 @@ func newHeadSyncFixture(t *testing.T) *headSyncFixture { headSync: hs, diffSyncerMock: diffSyncerMock, treeSyncerMock: treeSyncerMock, + diffMock: diffMock, + clientMock: clientMock, } } @@ -116,6 +125,7 @@ func (fx *headSyncFixture) init(t *testing.T) { fx.diffSyncerMock.EXPECT().Init() err := fx.headSync.Init(fx.app) require.NoError(t, err) + fx.headSync.diff = fx.diffMock } func (fx *headSyncFixture) stop() { @@ -134,8 +144,13 @@ func TestHeadSync(t *testing.T) { treeMock := mock_treestorage.NewMockTreeStorage(fx.ctrl) fx.storageMock.EXPECT().StoredIds().Return(ids, nil) fx.storageMock.EXPECT().TreeStorage(ids[0]).Return(treeMock, nil) - treeMock.EXPECT().Heads().Return([]string{"h1"}, nil) - fx.storageMock.EXPECT().WriteSpaceHash(gomock.Any()).Return(nil) + treeMock.EXPECT().Heads().Return([]string{"h1", "h2"}, nil) + fx.diffMock.EXPECT().Set(ldiff.Element{ + Id: "id1", + Head: "h1h2", + }) + fx.diffMock.EXPECT().Hash().Return("hash") + fx.storageMock.EXPECT().WriteSpaceHash("hash").Return(nil) fx.diffSyncerMock.EXPECT().Sync(gomock.Any()).Return(nil) fx.diffSyncerMock.EXPECT().Close().Return(nil) err := fx.headSync.Run(ctx) From e7a61fb06bf527446ced8ecd8fc9a4fd07102fdd Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Wed, 7 Jun 2023 13:32:14 +0200 Subject: [PATCH 022/123] mod tidy --- go.mod | 4 ---- go.sum | 14 -------------- 2 files changed, 18 deletions(-) diff --git a/go.mod b/go.mod index 116ef5df..7c9c44d2 100644 --- a/go.mod +++ b/go.mod @@ -55,7 +55,6 @@ require ( github.com/fogleman/gg v1.3.0 // indirect github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect @@ -99,8 +98,6 @@ require ( github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.44.0 // indirect github.com/prometheus/procfs v0.10.0 // indirect - github.com/quic-go/qtls-go1-19 v0.3.2 // indirect - github.com/quic-go/qtls-go1-20 v0.2.2 // indirect github.com/quic-go/quic-go v0.35.1 // indirect github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect @@ -110,7 +107,6 @@ require ( go.opentelemetry.io/otel/trace v1.7.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/image v0.6.0 // indirect - golang.org/x/mod v0.10.0 // indirect golang.org/x/sync v0.2.0 // indirect golang.org/x/sys v0.8.0 // indirect golang.org/x/tools v0.9.3 // indirect diff --git a/go.sum b/go.sum index 5f84c9c4..04c9a7c6 100644 --- a/go.sum +++ b/go.sum @@ -47,7 +47,6 @@ github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV 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/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/goccy/go-graphviz v0.1.1 h1:MGrsnzBxTyt7KG8FhHsFPDTGvF7UaQMmSa6A610DqPg= @@ -68,8 +67,6 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= -github.com/google/pprof v0.0.0-20230510103437-eeec1cb781c3 h1:2XF1Vzq06X+inNqgJ9tRnGuw+ZVCB3FazXODD6JE1R8= -github.com/google/pprof v0.0.0-20230510103437-eeec1cb781c3/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs= github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= @@ -247,9 +244,6 @@ github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXS github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5 h1:BvoENQQU+fZ9uukda/RzCAL/191HHwJA5b13R6diVlY= -github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q= -github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k= github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss= github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= @@ -273,11 +267,7 @@ github.com/prometheus/procfs v0.10.0 h1:UkG7GPYkO4UZyLnyXjaWYcgOSONqwdBqFUT95ugm github.com/prometheus/procfs v0.10.0/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc86Z5U= -github.com/quic-go/qtls-go1-19 v0.3.2/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E= -github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= -github.com/quic-go/quic-go v0.34.0 h1:OvOJ9LFjTySgwOTYUZmNoq0FzVicP8YujpV0kB7m2lU= -github.com/quic-go/quic-go v0.34.0/go.mod h1:+4CVgVppm0FNjpG3UcX8Joi/frKOH7/ciD5yGcwOO1g= github.com/quic-go/quic-go v0.35.1 h1:b0kzj6b/cQAf05cT0CkQubHM31wiA+xH3IBkxP62poo= github.com/quic-go/quic-go v0.35.1/go.mod h1:+4CVgVppm0FNjpG3UcX8Joi/frKOH7/ciD5yGcwOO1g= github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= @@ -295,7 +285,6 @@ github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 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.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= @@ -364,7 +353,6 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= -golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 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= @@ -427,8 +415,6 @@ 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/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= -golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM= golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 564c636391576f6a096afdc686e5b9d84218f973 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Wed, 7 Jun 2023 14:09:29 +0200 Subject: [PATCH 023/123] Fix diffsyncer tests --- commonspace/headsync/diffsyncer_test.go | 165 +++++++++++++++++++++++- 1 file changed, 162 insertions(+), 3 deletions(-) diff --git a/commonspace/headsync/diffsyncer_test.go b/commonspace/headsync/diffsyncer_test.go index 4c6fcdc9..b49c2178 100644 --- a/commonspace/headsync/diffsyncer_test.go +++ b/commonspace/headsync/diffsyncer_test.go @@ -1,7 +1,14 @@ package headsync import ( + "bytes" "context" + "fmt" + "github.com/anyproto/any-sync/app/ldiff" + "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" + "github.com/anyproto/any-sync/commonspace/object/acl/liststorage/mock_liststorage" + "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" + "github.com/anyproto/any-sync/commonspace/object/tree/treestorage/mock_treestorage" "github.com/anyproto/any-sync/commonspace/spacesyncproto" "github.com/anyproto/any-sync/net/peer" "github.com/golang/mock/gomock" @@ -11,6 +18,42 @@ import ( "time" ) +type pushSpaceRequestMatcher struct { + spaceId string + aclRootId string + settingsId string + credential []byte + spaceHeader *spacesyncproto.RawSpaceHeaderWithId +} + +func newPushSpaceRequestMatcher( + spaceId string, + aclRootId string, + settingsId string, + credential []byte, + spaceHeader *spacesyncproto.RawSpaceHeaderWithId) *pushSpaceRequestMatcher { + return &pushSpaceRequestMatcher{ + spaceId: spaceId, + aclRootId: aclRootId, + settingsId: settingsId, + credential: credential, + spaceHeader: spaceHeader, + } +} + +func (p pushSpaceRequestMatcher) Matches(x interface{}) bool { + res, ok := x.(*spacesyncproto.SpacePushRequest) + if !ok { + return false + } + + return res.Payload.AclPayloadId == p.aclRootId && res.Payload.SpaceHeader == p.spaceHeader && res.Payload.SpaceSettingsPayloadId == p.settingsId && bytes.Equal(p.credential, res.Credential) +} + +func (p pushSpaceRequestMatcher) String() string { + return "" +} + type mockPeer struct { } @@ -58,12 +101,12 @@ func (fx *headSyncFixture) initDiffSyncer(t *testing.T) { } func TestDiffSyncer(t *testing.T) { - fx := newHeadSyncFixture(t) - fx.initDiffSyncer(t) - defer fx.stop() ctx := context.Background() t.Run("diff syncer sync", func(t *testing.T) { + fx := newHeadSyncFixture(t) + fx.initDiffSyncer(t) + defer fx.stop() mPeer := mockPeer{} fx.peerManagerMock.EXPECT(). GetResponsiblePeers(gomock.Any()). @@ -77,6 +120,122 @@ func TestDiffSyncer(t *testing.T) { fx.treeSyncerMock.EXPECT().SyncAll(gomock.Any(), mPeer.Id(), []string{"changed"}, []string{"new"}).Return(nil) require.NoError(t, fx.diffSyncer.Sync(ctx)) }) + + t.Run("diff syncer sync conf error", func(t *testing.T) { + fx := newHeadSyncFixture(t) + fx.initDiffSyncer(t) + defer fx.stop() + ctx := context.Background() + fx.peerManagerMock.EXPECT(). + GetResponsiblePeers(gomock.Any()). + Return(nil, fmt.Errorf("some error")) + + require.Error(t, fx.diffSyncer.Sync(ctx)) + }) + + t.Run("deletion state remove objects", func(t *testing.T) { + fx := newHeadSyncFixture(t) + fx.initDiffSyncer(t) + defer fx.stop() + deletedId := "id" + fx.deletionStateMock.EXPECT().Exists(deletedId).Return(true) + + // this should not result in any mock being called + fx.diffSyncer.UpdateHeads(deletedId, []string{"someHead"}) + }) + + t.Run("update heads updates diff", func(t *testing.T) { + fx := newHeadSyncFixture(t) + fx.initDiffSyncer(t) + defer fx.stop() + newId := "newId" + newHeads := []string{"h1", "h2"} + hash := "hash" + fx.diffMock.EXPECT().Set(ldiff.Element{ + Id: newId, + Head: concatStrings(newHeads), + }) + fx.diffMock.EXPECT().Hash().Return(hash) + fx.deletionStateMock.EXPECT().Exists(newId).Return(false) + fx.storageMock.EXPECT().WriteSpaceHash(hash) + fx.diffSyncer.UpdateHeads(newId, newHeads) + }) + + t.Run("diff syncer sync space missing", func(t *testing.T) { + fx := newHeadSyncFixture(t) + fx.initDiffSyncer(t) + defer fx.stop() + aclStorageMock := mock_liststorage.NewMockListStorage(fx.ctrl) + settingsStorage := mock_treestorage.NewMockTreeStorage(fx.ctrl) + settingsId := "settingsId" + aclRootId := "aclRootId" + aclRoot := &aclrecordproto.RawAclRecordWithId{ + Id: aclRootId, + } + settingsRoot := &treechangeproto.RawTreeChangeWithId{ + Id: settingsId, + } + spaceHeader := &spacesyncproto.RawSpaceHeaderWithId{} + spaceSettingsId := "spaceSettingsId" + credential := []byte("credential") + + fx.peerManagerMock.EXPECT(). + GetResponsiblePeers(gomock.Any()). + Return([]peer.Peer{mockPeer{}}, nil) + fx.diffMock.EXPECT(). + Diff(gomock.Any(), gomock.Eq(NewRemoteDiff(fx.spaceState.SpaceId, fx.clientMock))). + Return(nil, nil, nil, spacesyncproto.ErrSpaceMissing) + + fx.storageMock.EXPECT().AclStorage().Return(aclStorageMock, nil) + fx.storageMock.EXPECT().SpaceHeader().Return(spaceHeader, nil) + fx.storageMock.EXPECT().SpaceSettingsId().Return(spaceSettingsId) + fx.storageMock.EXPECT().TreeStorage(spaceSettingsId).Return(settingsStorage, nil) + + settingsStorage.EXPECT().Root().Return(settingsRoot, nil) + aclStorageMock.EXPECT(). + Root(). + Return(aclRoot, nil) + fx.credentialProviderMock.EXPECT(). + GetCredential(gomock.Any(), spaceHeader). + Return(credential, nil) + fx.clientMock.EXPECT(). + SpacePush(gomock.Any(), newPushSpaceRequestMatcher(fx.spaceState.SpaceId, aclRootId, settingsId, credential, spaceHeader)). + Return(nil, nil) + fx.peerManagerMock.EXPECT().SendPeer(gomock.Any(), "peerId", gomock.Any()) + + require.NoError(t, fx.diffSyncer.Sync(ctx)) + }) + + t.Run("diff syncer sync unexpected", func(t *testing.T) { + fx := newHeadSyncFixture(t) + fx.initDiffSyncer(t) + defer fx.stop() + fx.peerManagerMock.EXPECT(). + GetResponsiblePeers(gomock.Any()). + Return([]peer.Peer{mockPeer{}}, nil) + fx.diffMock.EXPECT(). + Diff(gomock.Any(), gomock.Eq(NewRemoteDiff(fx.spaceState.SpaceId, fx.clientMock))). + Return(nil, nil, nil, spacesyncproto.ErrUnexpected) + + require.NoError(t, fx.diffSyncer.Sync(ctx)) + }) + + t.Run("diff syncer sync space is deleted error", func(t *testing.T) { + fx := newHeadSyncFixture(t) + fx.initDiffSyncer(t) + defer fx.stop() + mPeer := mockPeer{} + fx.peerManagerMock.EXPECT(). + GetResponsiblePeers(gomock.Any()). + Return([]peer.Peer{mPeer}, nil) + fx.diffMock.EXPECT(). + Diff(gomock.Any(), gomock.Eq(NewRemoteDiff(fx.spaceState.SpaceId, fx.clientMock))). + Return(nil, nil, nil, spacesyncproto.ErrSpaceIsDeleted) + fx.storageMock.EXPECT().SpaceSettingsId().Return("settingsId") + fx.treeSyncerMock.EXPECT().SyncAll(gomock.Any(), mPeer.Id(), []string{"settingsId"}, nil).Return(nil) + + require.NoError(t, fx.diffSyncer.Sync(ctx)) + }) } // From 485c9dd768b755d29d4373fb167ac6cea69598a1 Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Wed, 7 Jun 2023 14:49:44 +0200 Subject: [PATCH 024/123] yamux default timeouts --- net/transport/yamux/yamux.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/transport/yamux/yamux.go b/net/transport/yamux/yamux.go index 18558604..47cb8c52 100644 --- a/net/transport/yamux/yamux.go +++ b/net/transport/yamux/yamux.go @@ -42,6 +42,12 @@ type yamuxTransport struct { func (y *yamuxTransport) Init(a *app.App) (err error) { y.secure = a.MustComponent(secureservice.CName).(secureservice.SecureService) y.conf = a.MustComponent("config").(configGetter).GetYamux() + if y.conf.DialTimeoutSec <= 0 { + y.conf.DialTimeoutSec = 10 + } + if y.conf.WriteTimeoutSec <= 0 { + y.conf.WriteTimeoutSec = 10 + } y.yamuxConf = yamux.DefaultConfig() y.yamuxConf.EnableKeepAlive = false y.yamuxConf.StreamOpenTimeout = time.Duration(y.conf.DialTimeoutSec) * time.Second From 51eb5b1a42b94d5ccd178c44665c054c92cc804d Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Wed, 7 Jun 2023 18:05:13 +0200 Subject: [PATCH 025/123] Fix settings and deletion tests --- commonspace/deletion_test.go | 9 +- .../deletionstate/deletionstate_test.go | 4 +- commonspace/headsync/diffsyncer_test.go | 216 ------------------ commonspace/settings/deleter_test.go | 4 +- commonspace/settings/deletionmanager_test.go | 6 +- commonspace/settings/settingsobject_test.go | 5 +- commonspace/spaceutils_test.go | 4 +- 7 files changed, 21 insertions(+), 227 deletions(-) diff --git a/commonspace/deletion_test.go b/commonspace/deletion_test.go index 6862a472..33745884 100644 --- a/commonspace/deletion_test.go +++ b/commonspace/deletion_test.go @@ -73,7 +73,8 @@ func TestSpaceDeleteIds(t *testing.T) { fx.treeManager.space = spc err = spc.Init(ctx) require.NoError(t, err) - + close(fx.treeManager.waitLoad) + var ids []string for i := 0; i < totalObjs; i++ { // creating a tree @@ -147,6 +148,7 @@ func TestSpaceDeleteIdsIncorrectSnapshot(t *testing.T) { // adding space to tree manager fx.treeManager.space = spc err = spc.Init(ctx) + close(fx.treeManager.waitLoad) require.NoError(t, err) settingsObject := spc.(*space).app.MustComponent(settings.CName).(settings.Settings).SettingsObject() @@ -183,10 +185,12 @@ func TestSpaceDeleteIdsIncorrectSnapshot(t *testing.T) { spc, err = fx.spaceService.NewSpace(ctx, sp) require.NoError(t, err) require.NotNil(t, spc) + fx.treeManager.waitLoad = make(chan struct{}) fx.treeManager.space = spc fx.treeManager.deletedIds = nil err = spc.Init(ctx) require.NoError(t, err) + close(fx.treeManager.waitLoad) // waiting until everything is deleted time.Sleep(3 * time.Second) @@ -230,6 +234,7 @@ func TestSpaceDeleteIdsMarkDeleted(t *testing.T) { fx.treeManager.space = spc err = spc.Init(ctx) require.NoError(t, err) + close(fx.treeManager.waitLoad) settingsObject := spc.(*space).app.MustComponent(settings.CName).(settings.Settings).SettingsObject() var ids []string @@ -259,10 +264,12 @@ func TestSpaceDeleteIdsMarkDeleted(t *testing.T) { require.NoError(t, err) require.NotNil(t, spc) fx.treeManager.space = spc + fx.treeManager.waitLoad = make(chan struct{}) fx.treeManager.deletedIds = nil fx.treeManager.markedIds = nil err = spc.Init(ctx) require.NoError(t, err) + close(fx.treeManager.waitLoad) // waiting until everything is deleted time.Sleep(3 * time.Second) diff --git a/commonspace/deletionstate/deletionstate_test.go b/commonspace/deletionstate/deletionstate_test.go index d95bcd9b..e5489bd8 100644 --- a/commonspace/deletionstate/deletionstate_test.go +++ b/commonspace/deletionstate/deletionstate_test.go @@ -1,7 +1,6 @@ package deletionstate import ( - "github.com/anyproto/any-sync/app/logger" "github.com/anyproto/any-sync/commonspace/spacestorage" "github.com/anyproto/any-sync/commonspace/spacestorage/mock_spacestorage" "github.com/golang/mock/gomock" @@ -19,7 +18,8 @@ type fixture struct { func newFixture(t *testing.T) *fixture { ctrl := gomock.NewController(t) spaceStorage := mock_spacestorage.NewMockSpaceStorage(ctrl) - delState := New(logger.NewNamed("test"), spaceStorage).(*objectDeletionState) + delState := New().(*objectDeletionState) + delState.storage = spaceStorage return &fixture{ ctrl: ctrl, delState: delState, diff --git a/commonspace/headsync/diffsyncer_test.go b/commonspace/headsync/diffsyncer_test.go index b49c2178..7cdb870a 100644 --- a/commonspace/headsync/diffsyncer_test.go +++ b/commonspace/headsync/diffsyncer_test.go @@ -237,219 +237,3 @@ func TestDiffSyncer(t *testing.T) { require.NoError(t, fx.diffSyncer.Sync(ctx)) }) } - -// -//type pushSpaceRequestMatcher struct { -// spaceId string -// aclRootId string -// settingsId string -// credential []byte -// spaceHeader *spacesyncproto.RawSpaceHeaderWithId -//} -// -//func (p pushSpaceRequestMatcher) Matches(x interface{}) bool { -// res, ok := x.(*spacesyncproto.SpacePushRequest) -// if !ok { -// return false -// } -// -// return res.Payload.AclPayloadId == p.aclRootId && res.Payload.SpaceHeader == p.spaceHeader && res.Payload.SpaceSettingsPayloadId == p.settingsId && bytes.Equal(p.credential, res.Credential) -//} -// -//func (p pushSpaceRequestMatcher) String() string { -// return "" -//} -// -//type mockPeer struct{} -// -//func (m mockPeer) Addr() string { -// return "" -//} -// -//func (m mockPeer) TryClose(objectTTL time.Duration) (res bool, err error) { -// return true, m.Close() -//} -// -//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, -// settingsId string, -// credential []byte, -// spaceHeader *spacesyncproto.RawSpaceHeaderWithId) *pushSpaceRequestMatcher { -// return &pushSpaceRequestMatcher{ -// spaceId: spaceId, -// aclRootId: aclRootId, -// settingsId: settingsId, -// credential: credential, -// spaceHeader: spaceHeader, -// } -//} -// -//func TestDiffSyncer_Sync(t *testing.T) { -// // setup -// fx := newHeadSyncFixture(t) -// fx.initDiffSyncer(t) -// defer fx.stop() -// -// diffMock := mock_ldiff.NewMockDiff(ctrl) -// peerManagerMock := mock_peermanager.NewMockPeerManager(ctrl) -// cacheMock := mock_treemanager.NewMockTreeManager(ctrl) -// stMock := mock_spacestorage.NewMockSpaceStorage(ctrl) -// clientMock := mock_spacesyncproto.NewMockDRPCSpaceSyncClient(ctrl) -// factory := spacesyncproto.ClientFactoryFunc(func(cc drpc.Conn) spacesyncproto.DRPCSpaceSyncClient { -// return clientMock -// }) -// treeSyncerMock := mock_treemanager.NewMockTreeSyncer(ctrl) -// credentialProvider := mock_credentialprovider.NewMockCredentialProvider(ctrl) -// delState := mock_settingsstate.NewMockObjectDeletionState(ctrl) -// spaceId := "spaceId" -// aclRootId := "aclRootId" -// l := logger.NewNamed(spaceId) -// diffSyncer := newDiffSyncer(spaceId, diffMock, peerManagerMock, cacheMock, stMock, factory, syncstatus.NewNoOpSyncStatus(), credentialProvider, l) -// delState.EXPECT().AddObserver(gomock.Any()) -// cacheMock.EXPECT().NewTreeSyncer(spaceId, gomock.Any()).Return(treeSyncerMock) -// diffSyncer.Init(delState) -// -// t.Run("diff syncer sync", func(t *testing.T) { -// mPeer := mockPeer{} -// peerManagerMock.EXPECT(). -// GetResponsiblePeers(gomock.Any()). -// Return([]peer.Peer{mPeer}, nil) -// diffMock.EXPECT(). -// Diff(gomock.Any(), gomock.Eq(NewRemoteDiff(spaceId, clientMock))). -// Return([]string{"new"}, []string{"changed"}, nil, nil) -// delState.EXPECT().Filter([]string{"new"}).Return([]string{"new"}).Times(1) -// delState.EXPECT().Filter([]string{"changed"}).Return([]string{"changed"}).Times(1) -// delState.EXPECT().Filter(nil).Return(nil).Times(1) -// treeSyncerMock.EXPECT().SyncAll(gomock.Any(), mPeer.Id(), []string{"changed"}, []string{"new"}).Return(nil) -// require.NoError(t, diffSyncer.Sync(ctx)) -// }) -//} -// -// t.Run("diff syncer sync conf error", func(t *testing.T) { -// peerManagerMock.EXPECT(). -// GetResponsiblePeers(gomock.Any()). -// Return(nil, fmt.Errorf("some error")) -// -// require.Error(t, diffSyncer.Sync(ctx)) -// }) -// -// t.Run("deletion state remove objects", func(t *testing.T) { -// deletedId := "id" -// delState.EXPECT().Exists(deletedId).Return(true) -// -// // this should not result in any mock being called -// diffSyncer.UpdateHeads(deletedId, []string{"someHead"}) -// }) -// -// t.Run("update heads updates diff", func(t *testing.T) { -// newId := "newId" -// newHeads := []string{"h1", "h2"} -// hash := "hash" -// diffMock.EXPECT().Set(ldiff.Element{ -// Id: newId, -// Head: concatStrings(newHeads), -// }) -// diffMock.EXPECT().Hash().Return(hash) -// delState.EXPECT().Exists(newId).Return(false) -// stMock.EXPECT().WriteSpaceHash(hash) -// diffSyncer.UpdateHeads(newId, newHeads) -// }) -// -// t.Run("diff syncer sync space missing", func(t *testing.T) { -// aclStorageMock := mock_liststorage.NewMockListStorage(ctrl) -// settingsStorage := mock_treestorage.NewMockTreeStorage(ctrl) -// settingsId := "settingsId" -// aclRoot := &aclrecordproto.RawAclRecordWithId{ -// Id: aclRootId, -// } -// settingsRoot := &treechangeproto.RawTreeChangeWithId{ -// Id: settingsId, -// } -// spaceHeader := &spacesyncproto.RawSpaceHeaderWithId{} -// spaceSettingsId := "spaceSettingsId" -// credential := []byte("credential") -// -// peerManagerMock.EXPECT(). -// GetResponsiblePeers(gomock.Any()). -// Return([]peer.Peer{mockPeer{}}, nil) -// diffMock.EXPECT(). -// Diff(gomock.Any(), gomock.Eq(NewRemoteDiff(spaceId, clientMock))). -// Return(nil, nil, nil, spacesyncproto.ErrSpaceMissing) -// -// stMock.EXPECT().AclStorage().Return(aclStorageMock, nil) -// stMock.EXPECT().SpaceHeader().Return(spaceHeader, nil) -// stMock.EXPECT().SpaceSettingsId().Return(spaceSettingsId) -// stMock.EXPECT().TreeStorage(spaceSettingsId).Return(settingsStorage, nil) -// -// settingsStorage.EXPECT().Root().Return(settingsRoot, nil) -// aclStorageMock.EXPECT(). -// Root(). -// Return(aclRoot, nil) -// credentialProvider.EXPECT(). -// GetCredential(gomock.Any(), spaceHeader). -// Return(credential, nil) -// clientMock.EXPECT(). -// SpacePush(gomock.Any(), newPushSpaceRequestMatcher(spaceId, aclRootId, settingsId, credential, spaceHeader)). -// Return(nil, nil) -// peerManagerMock.EXPECT().SendPeer(gomock.Any(), "mockId", gomock.Any()) -// -// require.NoError(t, diffSyncer.Sync(ctx)) -// }) -// -// t.Run("diff syncer sync unexpected", func(t *testing.T) { -// peerManagerMock.EXPECT(). -// GetResponsiblePeers(gomock.Any()). -// Return([]peer.Peer{mockPeer{}}, nil) -// diffMock.EXPECT(). -// Diff(gomock.Any(), gomock.Eq(NewRemoteDiff(spaceId, clientMock))). -// Return(nil, nil, nil, spacesyncproto.ErrUnexpected) -// -// require.NoError(t, diffSyncer.Sync(ctx)) -// }) -// -// t.Run("diff syncer sync space is deleted error", func(t *testing.T) { -// mPeer := mockPeer{} -// peerManagerMock.EXPECT(). -// GetResponsiblePeers(gomock.Any()). -// Return([]peer.Peer{mPeer}, nil) -// diffMock.EXPECT(). -// Diff(gomock.Any(), gomock.Eq(NewRemoteDiff(spaceId, clientMock))). -// Return(nil, nil, nil, spacesyncproto.ErrSpaceIsDeleted) -// stMock.EXPECT().SpaceSettingsId().Return("settingsId") -// treeSyncerMock.EXPECT().SyncAll(gomock.Any(), mPeer.Id(), []string{"settingsId"}, nil).Return(nil) -// -// require.NoError(t, diffSyncer.Sync(ctx)) -// }) -//} diff --git a/commonspace/settings/deleter_test.go b/commonspace/settings/deleter_test.go index 54feed56..e4a32e84 100644 --- a/commonspace/settings/deleter_test.go +++ b/commonspace/settings/deleter_test.go @@ -2,9 +2,9 @@ package settings import ( "fmt" + "github.com/anyproto/any-sync/commonspace/deletionstate/mock_deletionstate" "github.com/anyproto/any-sync/commonspace/object/tree/treestorage" "github.com/anyproto/any-sync/commonspace/object/treemanager/mock_treemanager" - "github.com/anyproto/any-sync/commonspace/settings/settingsstate/mock_settingsstate" "github.com/anyproto/any-sync/commonspace/spacestorage/mock_spacestorage" "github.com/golang/mock/gomock" "testing" @@ -14,7 +14,7 @@ func TestDeleter_Delete(t *testing.T) { ctrl := gomock.NewController(t) treeManager := mock_treemanager.NewMockTreeManager(ctrl) st := mock_spacestorage.NewMockSpaceStorage(ctrl) - delState := mock_settingsstate.NewMockObjectDeletionState(ctrl) + delState := mock_deletionstate.NewMockObjectDeletionState(ctrl) deleter := newDeleter(st, delState, treeManager) diff --git a/commonspace/settings/deletionmanager_test.go b/commonspace/settings/deletionmanager_test.go index 9e6b4f05..69e8830d 100644 --- a/commonspace/settings/deletionmanager_test.go +++ b/commonspace/settings/deletionmanager_test.go @@ -2,10 +2,10 @@ package settings import ( "context" + "github.com/anyproto/any-sync/commonspace/deletionstate/mock_deletionstate" "github.com/anyproto/any-sync/commonspace/object/treemanager/mock_treemanager" "github.com/anyproto/any-sync/commonspace/settings/mock_settings" "github.com/anyproto/any-sync/commonspace/settings/settingsstate" - "github.com/anyproto/any-sync/commonspace/settings/settingsstate/mock_settingsstate" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" "testing" @@ -26,7 +26,7 @@ func TestDeletionManager_UpdateState_NotResponsible(t *testing.T) { onDeleted := func() { deleted = true } - delState := mock_settingsstate.NewMockObjectDeletionState(ctrl) + delState := mock_deletionstate.NewMockObjectDeletionState(ctrl) treeManager := mock_treemanager.NewMockTreeManager(ctrl) delState.EXPECT().Add(state.DeletedIds) @@ -58,7 +58,7 @@ func TestDeletionManager_UpdateState_Responsible(t *testing.T) { onDeleted := func() { deleted = true } - delState := mock_settingsstate.NewMockObjectDeletionState(ctrl) + delState := mock_deletionstate.NewMockObjectDeletionState(ctrl) treeManager := mock_treemanager.NewMockTreeManager(ctrl) provider := mock_settings.NewMockSpaceIdsProvider(ctrl) diff --git a/commonspace/settings/settingsobject_test.go b/commonspace/settings/settingsobject_test.go index 31956c81..9d83d9cd 100644 --- a/commonspace/settings/settingsobject_test.go +++ b/commonspace/settings/settingsobject_test.go @@ -3,6 +3,7 @@ package settings import ( "context" "github.com/anyproto/any-sync/accountservice/mock_accountservice" + "github.com/anyproto/any-sync/commonspace/deletionstate/mock_deletionstate" "github.com/anyproto/any-sync/commonspace/object/accountdata" "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" "github.com/anyproto/any-sync/commonspace/object/tree/objecttree/mock_objecttree" @@ -54,7 +55,7 @@ type settingsFixture struct { deleter *mock_settings.MockDeleter syncTree *mock_synctree.MockSyncTree historyTree *mock_objecttree.MockObjectTree - delState *mock_settingsstate.MockObjectDeletionState + delState *mock_deletionstate.MockObjectDeletionState account *mock_accountservice.MockService } @@ -66,7 +67,7 @@ func newSettingsFixture(t *testing.T) *settingsFixture { acc := mock_accountservice.NewMockService(ctrl) treeManager := mock_treemanager.NewMockTreeManager(ctrl) st := mock_spacestorage.NewMockSpaceStorage(ctrl) - delState := mock_settingsstate.NewMockObjectDeletionState(ctrl) + delState := mock_deletionstate.NewMockObjectDeletionState(ctrl) delManager := mock_settings.NewMockDeletionManager(ctrl) stateBuilder := mock_settingsstate.NewMockStateBuilder(ctrl) changeFactory := mock_settingsstate.NewMockChangeFactory(ctrl) diff --git a/commonspace/spaceutils_test.go b/commonspace/spaceutils_test.go index c1d40f5c..cc82cecd 100644 --- a/commonspace/spaceutils_test.go +++ b/commonspace/spaceutils_test.go @@ -270,6 +270,7 @@ type mockTreeManager struct { cache ocache.OCache deletedIds []string markedIds []string + waitLoad chan struct{} } func (t *mockTreeManager) NewTreeSyncer(spaceId string, treeManager treemanager.TreeManager) treemanager.TreeSyncer { @@ -283,6 +284,7 @@ func (t *mockTreeManager) MarkTreeDeleted(ctx context.Context, spaceId, treeId s func (t *mockTreeManager) Init(a *app.App) (err error) { t.cache = ocache.New(func(ctx context.Context, id string) (value ocache.Object, err error) { + <-t.waitLoad return t.space.TreeBuilder().BuildTree(ctx, id, objecttreebuilder.BuildTreeOpts{}) }, ocache.WithGCPeriod(time.Minute), @@ -352,7 +354,7 @@ func newFixture(t *testing.T) *spaceFixture { configurationService: &mockConf{}, storageProvider: spacestorage.NewInMemorySpaceStorageProvider(), peermanagerProvider: &mockPeerManagerProvider{}, - treeManager: &mockTreeManager{}, + treeManager: &mockTreeManager{waitLoad: make(chan struct{})}, pool: &mockPool{}, spaceService: New(), } From 4d1494a17ab1eb1c1a751b098e05cf5f3f3c82af Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Wed, 7 Jun 2023 19:31:15 +0200 Subject: [PATCH 026/123] Add mocks and some requestmanager tests --- commonspace/requestmanager/requestmanager.go | 48 +++--- .../requestmanager/requestmanager_test.go | 96 +++++++++++ net/peer/mock_peer/mock_peer.go | 149 ++++++++++++++++++ net/peer/peer.go | 1 + net/pool/mock_pool/mock_pool.go | 80 ++++++++++ net/pool/pool.go | 1 + 6 files changed, 355 insertions(+), 20 deletions(-) create mode 100644 net/peer/mock_peer/mock_peer.go create mode 100644 net/pool/mock_pool/mock_pool.go diff --git a/commonspace/requestmanager/requestmanager.go b/commonspace/requestmanager/requestmanager.go index ac4351c0..d72ea394 100644 --- a/commonspace/requestmanager/requestmanager.go +++ b/commonspace/requestmanager/requestmanager.go @@ -38,19 +38,21 @@ type MessageHandler interface { type requestManager struct { sync.Mutex - pools map[string]*streampool.ExecPool - peerPool pool.Pool - workers int - queueSize int - handler MessageHandler - ctx context.Context - cancel context.CancelFunc + pools map[string]*streampool.ExecPool + peerPool pool.Pool + workers int + queueSize int + handler MessageHandler + ctx context.Context + cancel context.CancelFunc + clientFactory spacesyncproto.ClientFactory } func (r *requestManager) Init(a *app.App) (err error) { r.ctx, r.cancel = context.WithCancel(context.Background()) r.handler = a.MustComponent(objectsync.CName).(MessageHandler) r.peerPool = a.MustComponent(pool.CName).(pool.Pool) + r.clientFactory = spacesyncproto.ClientFactoryFunc(spacesyncproto.NewDRPCSpaceSyncClient) return } @@ -89,18 +91,24 @@ func (r *requestManager) QueueRequest(peerId string, req *spacesyncproto.ObjectS // TODO: for later think when many clients are there, // we need to close pools for inactive clients return pl.TryAdd(func() { - ctx := r.ctx - resp, err := r.doRequest(ctx, peerId, req) - if err != nil { - log.Warn("failed to send request", zap.Error(err)) - return - } - ctx = peer.CtxWithPeerId(ctx, peerId) - _ = r.handler.HandleMessage(ctx, objectsync.HandleMessage{ - SenderId: peerId, - Message: resp, - PeerCtx: ctx, - }) + doRequestAndHandle(r, peerId, req) + }) +} + +var doRequestAndHandle = (*requestManager).requestAndHandle + +func (r *requestManager) requestAndHandle(peerId string, req *spacesyncproto.ObjectSyncMessage) { + ctx := r.ctx + resp, err := r.doRequest(ctx, peerId, req) + if err != nil { + log.Warn("failed to send request", zap.Error(err)) + return + } + ctx = peer.CtxWithPeerId(ctx, peerId) + _ = r.handler.HandleMessage(ctx, objectsync.HandleMessage{ + SenderId: peerId, + Message: resp, + PeerCtx: ctx, }) } @@ -110,7 +118,7 @@ func (r *requestManager) doRequest(ctx context.Context, peerId string, msg *spac return } err = pr.DoDrpc(ctx, func(conn drpc.Conn) error { - cl := spacesyncproto.NewDRPCSpaceSyncClient(conn) + cl := r.clientFactory.Client(conn) resp, err = cl.ObjectSync(ctx, msg) return err }) diff --git a/commonspace/requestmanager/requestmanager_test.go b/commonspace/requestmanager/requestmanager_test.go index e5e89798..1bdaa884 100644 --- a/commonspace/requestmanager/requestmanager_test.go +++ b/commonspace/requestmanager/requestmanager_test.go @@ -1 +1,97 @@ package requestmanager + +import ( + "context" + "github.com/anyproto/any-sync/commonspace/objectsync" + "github.com/anyproto/any-sync/commonspace/objectsync/mock_objectsync" + "github.com/anyproto/any-sync/commonspace/spacesyncproto" + "github.com/anyproto/any-sync/commonspace/spacesyncproto/mock_spacesyncproto" + "github.com/anyproto/any-sync/net/peer" + "github.com/anyproto/any-sync/net/peer/mock_peer" + "github.com/anyproto/any-sync/net/pool/mock_pool" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + "storj.io/drpc" + "storj.io/drpc/drpcconn" + "testing" +) + +type fixture struct { + requestManager *requestManager + messageHandlerMock *mock_objectsync.MockObjectSync + peerPoolMock *mock_pool.MockPool + clientMock *mock_spacesyncproto.MockDRPCSpaceSyncClient + ctrl *gomock.Controller +} + +func newFixture(t *testing.T) *fixture { + ctrl := gomock.NewController(t) + manager := New().(*requestManager) + peerPoolMock := mock_pool.NewMockPool(ctrl) + messageHandlerMock := mock_objectsync.NewMockObjectSync(ctrl) + clientMock := mock_spacesyncproto.NewMockDRPCSpaceSyncClient(ctrl) + manager.peerPool = peerPoolMock + manager.handler = messageHandlerMock + manager.clientFactory = spacesyncproto.ClientFactoryFunc(func(cc drpc.Conn) spacesyncproto.DRPCSpaceSyncClient { + return clientMock + }) + manager.ctx, manager.cancel = context.WithCancel(context.Background()) + return &fixture{ + requestManager: manager, + messageHandlerMock: messageHandlerMock, + peerPoolMock: peerPoolMock, + clientMock: clientMock, + ctrl: ctrl, + } +} + +func (fx *fixture) stop() { + fx.ctrl.Finish() +} + +func TestRequestManager_Request(t *testing.T) { + ctx := context.Background() + + t.Run("send request", func(t *testing.T) { + fx := newFixture(t) + defer fx.stop() + + peerId := "peerId" + peerMock := mock_peer.NewMockPeer(fx.ctrl) + conn := &drpcconn.Conn{} + msg := &spacesyncproto.ObjectSyncMessage{} + resp := &spacesyncproto.ObjectSyncMessage{} + fx.peerPoolMock.EXPECT().Get(ctx, peerId).Return(peerMock, nil) + fx.clientMock.EXPECT().ObjectSync(ctx, msg).Return(resp, nil) + peerMock.EXPECT().DoDrpc(ctx, gomock.Any()).DoAndReturn(func(ctx context.Context, drpcHandler func(conn drpc.Conn) error) { + drpcHandler(conn) + }).Return(nil) + res, err := fx.requestManager.SendRequest(ctx, peerId, msg) + require.NoError(t, err) + require.Equal(t, resp, res) + }) + + t.Run("request and handle", func(t *testing.T) { + fx := newFixture(t) + defer fx.stop() + ctx = fx.requestManager.ctx + + peerId := "peerId" + peerMock := mock_peer.NewMockPeer(fx.ctrl) + conn := &drpcconn.Conn{} + msg := &spacesyncproto.ObjectSyncMessage{} + resp := &spacesyncproto.ObjectSyncMessage{} + fx.peerPoolMock.EXPECT().Get(ctx, peerId).Return(peerMock, nil) + fx.clientMock.EXPECT().ObjectSync(ctx, msg).Return(resp, nil) + peerMock.EXPECT().DoDrpc(ctx, gomock.Any()).DoAndReturn(func(ctx context.Context, drpcHandler func(conn drpc.Conn) error) { + drpcHandler(conn) + }).Return(nil) + fx.messageHandlerMock.EXPECT().HandleMessage(gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, msg objectsync.HandleMessage) { + require.Equal(t, peerId, msg.SenderId) + require.Equal(t, resp, msg.Message) + pId, _ := peer.CtxPeerId(msg.PeerCtx) + require.Equal(t, peerId, pId) + }).Return(nil) + fx.requestManager.requestAndHandle(peerId, msg) + }) +} diff --git a/net/peer/mock_peer/mock_peer.go b/net/peer/mock_peer/mock_peer.go new file mode 100644 index 00000000..dc0a5b6a --- /dev/null +++ b/net/peer/mock_peer/mock_peer.go @@ -0,0 +1,149 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/anyproto/any-sync/net/peer (interfaces: Peer) + +// Package mock_peer is a generated GoMock package. +package mock_peer + +import ( + context "context" + reflect "reflect" + time "time" + + gomock "github.com/golang/mock/gomock" + drpc "storj.io/drpc" +) + +// MockPeer is a mock of Peer interface. +type MockPeer struct { + ctrl *gomock.Controller + recorder *MockPeerMockRecorder +} + +// MockPeerMockRecorder is the mock recorder for MockPeer. +type MockPeerMockRecorder struct { + mock *MockPeer +} + +// NewMockPeer creates a new mock instance. +func NewMockPeer(ctrl *gomock.Controller) *MockPeer { + mock := &MockPeer{ctrl: ctrl} + mock.recorder = &MockPeerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockPeer) EXPECT() *MockPeerMockRecorder { + return m.recorder +} + +// AcquireDrpcConn mocks base method. +func (m *MockPeer) AcquireDrpcConn(arg0 context.Context) (drpc.Conn, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AcquireDrpcConn", arg0) + ret0, _ := ret[0].(drpc.Conn) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// AcquireDrpcConn indicates an expected call of AcquireDrpcConn. +func (mr *MockPeerMockRecorder) AcquireDrpcConn(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcquireDrpcConn", reflect.TypeOf((*MockPeer)(nil).AcquireDrpcConn), arg0) +} + +// Close mocks base method. +func (m *MockPeer) 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 *MockPeerMockRecorder) Close() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockPeer)(nil).Close)) +} + +// Context mocks base method. +func (m *MockPeer) Context() context.Context { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Context") + ret0, _ := ret[0].(context.Context) + return ret0 +} + +// Context indicates an expected call of Context. +func (mr *MockPeerMockRecorder) Context() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockPeer)(nil).Context)) +} + +// DoDrpc mocks base method. +func (m *MockPeer) DoDrpc(arg0 context.Context, arg1 func(drpc.Conn) error) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DoDrpc", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// DoDrpc indicates an expected call of DoDrpc. +func (mr *MockPeerMockRecorder) DoDrpc(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DoDrpc", reflect.TypeOf((*MockPeer)(nil).DoDrpc), arg0, arg1) +} + +// Id mocks base method. +func (m *MockPeer) 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 *MockPeerMockRecorder) Id() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Id", reflect.TypeOf((*MockPeer)(nil).Id)) +} + +// IsClosed mocks base method. +func (m *MockPeer) IsClosed() bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IsClosed") + ret0, _ := ret[0].(bool) + return ret0 +} + +// IsClosed indicates an expected call of IsClosed. +func (mr *MockPeerMockRecorder) IsClosed() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsClosed", reflect.TypeOf((*MockPeer)(nil).IsClosed)) +} + +// ReleaseDrpcConn mocks base method. +func (m *MockPeer) ReleaseDrpcConn(arg0 drpc.Conn) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "ReleaseDrpcConn", arg0) +} + +// ReleaseDrpcConn indicates an expected call of ReleaseDrpcConn. +func (mr *MockPeerMockRecorder) ReleaseDrpcConn(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReleaseDrpcConn", reflect.TypeOf((*MockPeer)(nil).ReleaseDrpcConn), arg0) +} + +// TryClose mocks base method. +func (m *MockPeer) TryClose(arg0 time.Duration) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TryClose", arg0) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// TryClose indicates an expected call of TryClose. +func (mr *MockPeerMockRecorder) TryClose(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TryClose", reflect.TypeOf((*MockPeer)(nil).TryClose), arg0) +} diff --git a/net/peer/peer.go b/net/peer/peer.go index 7f42260c..300243c4 100644 --- a/net/peer/peer.go +++ b/net/peer/peer.go @@ -1,3 +1,4 @@ +//go:generate mockgen -destination mock_peer/mock_peer.go github.com/anyproto/any-sync/net/peer Peer package peer import ( diff --git a/net/pool/mock_pool/mock_pool.go b/net/pool/mock_pool/mock_pool.go new file mode 100644 index 00000000..be884903 --- /dev/null +++ b/net/pool/mock_pool/mock_pool.go @@ -0,0 +1,80 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/anyproto/any-sync/net/pool (interfaces: Pool) + +// Package mock_pool is a generated GoMock package. +package mock_pool + +import ( + context "context" + reflect "reflect" + + peer "github.com/anyproto/any-sync/net/peer" + gomock "github.com/golang/mock/gomock" +) + +// MockPool is a mock of Pool interface. +type MockPool struct { + ctrl *gomock.Controller + recorder *MockPoolMockRecorder +} + +// MockPoolMockRecorder is the mock recorder for MockPool. +type MockPoolMockRecorder struct { + mock *MockPool +} + +// NewMockPool creates a new mock instance. +func NewMockPool(ctrl *gomock.Controller) *MockPool { + mock := &MockPool{ctrl: ctrl} + mock.recorder = &MockPoolMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockPool) EXPECT() *MockPoolMockRecorder { + return m.recorder +} + +// AddPeer mocks base method. +func (m *MockPool) AddPeer(arg0 context.Context, arg1 peer.Peer) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AddPeer", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// AddPeer indicates an expected call of AddPeer. +func (mr *MockPoolMockRecorder) AddPeer(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddPeer", reflect.TypeOf((*MockPool)(nil).AddPeer), arg0, arg1) +} + +// Get mocks base method. +func (m *MockPool) Get(arg0 context.Context, arg1 string) (peer.Peer, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Get", arg0, arg1) + ret0, _ := ret[0].(peer.Peer) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Get indicates an expected call of Get. +func (mr *MockPoolMockRecorder) Get(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockPool)(nil).Get), arg0, arg1) +} + +// GetOneOf mocks base method. +func (m *MockPool) GetOneOf(arg0 context.Context, arg1 []string) (peer.Peer, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetOneOf", arg0, arg1) + ret0, _ := ret[0].(peer.Peer) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetOneOf indicates an expected call of GetOneOf. +func (mr *MockPoolMockRecorder) GetOneOf(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOneOf", reflect.TypeOf((*MockPool)(nil).GetOneOf), arg0, arg1) +} diff --git a/net/pool/pool.go b/net/pool/pool.go index 37f8328e..7e936e1b 100644 --- a/net/pool/pool.go +++ b/net/pool/pool.go @@ -1,3 +1,4 @@ +//go:generate mockgen -destination mock_pool/mock_pool.go github.com/anyproto/any-sync/net/pool Pool package pool import ( From 6c9d1b0e8409f5e983ea1e3cf640279aaf413a88 Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Wed, 7 Jun 2023 20:45:32 +0200 Subject: [PATCH 027/123] rpctest pool --- net/rpc/rpctest/pool.go | 60 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 net/rpc/rpctest/pool.go diff --git a/net/rpc/rpctest/pool.go b/net/rpc/rpctest/pool.go new file mode 100644 index 00000000..0e2b5d1b --- /dev/null +++ b/net/rpc/rpctest/pool.go @@ -0,0 +1,60 @@ +package rpctest + +import ( + "context" + "github.com/anyproto/any-sync/app" + "github.com/anyproto/any-sync/net" + "github.com/anyproto/any-sync/net/peer" + "github.com/anyproto/any-sync/net/pool" + "sync" +) + +func NewTestPool() *TestPool { + return &TestPool{peers: map[string]peer.Peer{}} +} + +type TestPool struct { + peers map[string]peer.Peer + mu sync.Mutex +} + +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 +} + +func (t *TestPool) Get(ctx context.Context, id string) (peer.Peer, error) { + t.mu.Lock() + defer t.mu.Unlock() + if p, ok := t.peers[id]; ok { + return p, nil + } + return nil, net.ErrUnableToConnect +} + +func (t *TestPool) GetOneOf(ctx context.Context, peerIds []string) (peer.Peer, error) { + for _, id := range peerIds { + if p, err := t.Get(ctx, id); err == nil { + return p, nil + } + } + return nil, net.ErrUnableToConnect +} + +func (t *TestPool) AddPeer(ctx context.Context, p peer.Peer) (err error) { + t.mu.Lock() + defer t.mu.Unlock() + t.peers[p.Id()] = p + return nil +} From 065ff1198371f71e07cebd40380407ecd792724d Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Wed, 7 Jun 2023 20:50:26 +0200 Subject: [PATCH 028/123] bump proto version as 1 --- net/secureservice/secureservice.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/net/secureservice/secureservice.go b/net/secureservice/secureservice.go index 1e5d3231..d20d7109 100644 --- a/net/secureservice/secureservice.go +++ b/net/secureservice/secureservice.go @@ -21,6 +21,12 @@ const CName = "common.net.secure" var log = logger.NewNamed(CName) +const ( + // ProtoVersion 0 - first any-sync version with raw tcp connections + // ProtoVersion 1 - version with yamux over tcp and quic + ProtoVersion = 1 +) + func New() SecureService { return &secureService{} } @@ -70,6 +76,8 @@ func (s *secureService) Init(a *app.App) (err error) { return } + s.protoVersion = ProtoVersion + log.Info("secure service init", zap.String("peerId", account.Account().PeerId)) return nil } From 5a6661eab18068f922193799d2dd131f517909f0 Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Wed, 7 Jun 2023 20:52:09 +0200 Subject: [PATCH 029/123] cleanup net config --- net/config.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/net/config.go b/net/config.go index 333261dd..d1634d2c 100644 --- a/net/config.go +++ b/net/config.go @@ -11,14 +11,9 @@ type ConfigGetter interface { } type Config struct { - Server ServerConfig `yaml:"server"` Stream StreamConfig `yaml:"stream"` } -type ServerConfig struct { - ListenAddrs []string `yaml:"listenAddrs"` -} - type StreamConfig struct { TimeoutMilliseconds int `yaml:"timeoutMilliseconds"` MaxMsgSizeMb int `yaml:"maxMsgSizeMb"` From c8c0839a57a232dc8d976966701300bd6325996b Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Wed, 7 Jun 2023 21:48:13 +0200 Subject: [PATCH 030/123] Add request manager tests --- .../requestmanager/requestmanager_test.go | 94 ++++++++++++++++++- net/streampool/sendpool.go | 8 +- 2 files changed, 100 insertions(+), 2 deletions(-) diff --git a/commonspace/requestmanager/requestmanager_test.go b/commonspace/requestmanager/requestmanager_test.go index 1bdaa884..35d497fc 100644 --- a/commonspace/requestmanager/requestmanager_test.go +++ b/commonspace/requestmanager/requestmanager_test.go @@ -13,7 +13,9 @@ import ( "github.com/stretchr/testify/require" "storj.io/drpc" "storj.io/drpc/drpcconn" + "sync" "testing" + "time" ) type fixture struct { @@ -49,7 +51,7 @@ func (fx *fixture) stop() { fx.ctrl.Finish() } -func TestRequestManager_Request(t *testing.T) { +func TestRequestManager_SyncRequest(t *testing.T) { ctx := context.Background() t.Run("send request", func(t *testing.T) { @@ -95,3 +97,93 @@ func TestRequestManager_Request(t *testing.T) { fx.requestManager.requestAndHandle(peerId, msg) }) } + +func TestRequestManager_QueueRequest(t *testing.T) { + t.Run("max concurrent reqs for peer, independent reqs for other peer", func(t *testing.T) { + // testing 2 concurrent requests to one peer and simultaneous to another peer + fx := newFixture(t) + defer fx.stop() + fx.requestManager.workers = 2 + msgRelease := make(chan struct{}) + msgWait := make(chan struct{}) + msgs := sync.Map{} + doRequestAndHandle = func(manager *requestManager, peerId string, req *spacesyncproto.ObjectSyncMessage) { + msgs.Store(req.ObjectId, struct{}{}) + <-msgWait + <-msgRelease + } + otherPeer := "otherPeer" + msg1 := &spacesyncproto.ObjectSyncMessage{ObjectId: "id1"} + msg2 := &spacesyncproto.ObjectSyncMessage{ObjectId: "id2"} + msg3 := &spacesyncproto.ObjectSyncMessage{ObjectId: "id3"} + otherMsg1 := &spacesyncproto.ObjectSyncMessage{ObjectId: "otherId1"} + + // sending requests to first peer + peerId := "peerId" + err := fx.requestManager.QueueRequest(peerId, msg1) + require.NoError(t, err) + err = fx.requestManager.QueueRequest(peerId, msg2) + require.NoError(t, err) + err = fx.requestManager.QueueRequest(peerId, msg3) + require.NoError(t, err) + + // waiting until all the messages are loaded + msgWait <- struct{}{} + msgWait <- struct{}{} + _, ok := msgs.Load("id1") + require.True(t, ok) + _, ok = msgs.Load("id2") + require.True(t, ok) + // third message should not be read + _, ok = msgs.Load("id3") + require.False(t, ok) + + // request for other peer should pass + err = fx.requestManager.QueueRequest(otherPeer, otherMsg1) + require.NoError(t, err) + msgWait <- struct{}{} + + _, ok = msgs.Load("otherId1") + require.True(t, ok) + close(msgRelease) + }) + + t.Run("no requests after close", func(t *testing.T) { + fx := newFixture(t) + defer fx.stop() + fx.requestManager.workers = 1 + msgRelease := make(chan struct{}) + msgWait := make(chan struct{}) + msgs := sync.Map{} + doRequestAndHandle = func(manager *requestManager, peerId string, req *spacesyncproto.ObjectSyncMessage) { + msgs.Store(req.ObjectId, struct{}{}) + <-msgWait + <-msgRelease + } + msg1 := &spacesyncproto.ObjectSyncMessage{ObjectId: "id1"} + msg2 := &spacesyncproto.ObjectSyncMessage{ObjectId: "id2"} + + // sending requests to first peer + peerId := "peerId" + err := fx.requestManager.QueueRequest(peerId, msg1) + require.NoError(t, err) + err = fx.requestManager.QueueRequest(peerId, msg2) + require.NoError(t, err) + + // waiting until all the message is loaded + msgWait <- struct{}{} + _, ok := msgs.Load("id1") + require.True(t, ok) + _, ok = msgs.Load("id2") + require.False(t, ok) + + fx.requestManager.Close(context.Background()) + close(msgRelease) + // waiting to know if the second one is not taken + // because the manager is now closed + time.Sleep(100 * time.Millisecond) + _, ok = msgs.Load("id2") + require.False(t, ok) + + }) +} diff --git a/net/streampool/sendpool.go b/net/streampool/sendpool.go index 0bff0765..642aeb9a 100644 --- a/net/streampool/sendpool.go +++ b/net/streampool/sendpool.go @@ -10,7 +10,10 @@ import ( // workers - how many processes will execute tasks // maxSize - limit for queue size func NewExecPool(workers, maxSize int) *ExecPool { + ctx, cancel := context.WithCancel(context.Background()) ss := &ExecPool{ + ctx: ctx, + cancel: cancel, workers: workers, batch: mb.New[func()](maxSize), } @@ -19,6 +22,8 @@ func NewExecPool(workers, maxSize int) *ExecPool { // ExecPool needed for parallel execution of the incoming send tasks type ExecPool struct { + ctx context.Context + cancel context.CancelFunc workers int batch *mb.MB[func()] } @@ -39,7 +44,7 @@ func (ss *ExecPool) Run() { func (ss *ExecPool) sendLoop() { for { - f, err := ss.batch.WaitOne(context.Background()) + f, err := ss.batch.WaitOne(ss.ctx) if err != nil { log.Debug("close send loop", zap.Error(err)) return @@ -49,5 +54,6 @@ func (ss *ExecPool) sendLoop() { } func (ss *ExecPool) Close() (err error) { + ss.cancel() return ss.batch.Close() } From 318a49c526efeaad5267d6105f6e16c24a3d24bb Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Wed, 7 Jun 2023 22:05:05 +0200 Subject: [PATCH 031/123] Change objectsync injection --- commonspace/objectsync/objectsync.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/commonspace/objectsync/objectsync.go b/commonspace/objectsync/objectsync.go index d2febaee..0ec7f344 100644 --- a/commonspace/objectsync/objectsync.go +++ b/commonspace/objectsync/objectsync.go @@ -6,6 +6,7 @@ import ( "fmt" "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" + "github.com/anyproto/any-sync/commonspace/object/treemanager" "github.com/anyproto/any-sync/commonspace/spacestate" "github.com/anyproto/any-sync/metric" "github.com/anyproto/any-sync/net/peer" @@ -69,7 +70,7 @@ type objectSync struct { func (s *objectSync) Init(a *app.App) (err error) { s.spaceStorage = a.MustComponent(spacestorage.CName).(spacestorage.SpaceStorage) - s.objectGetter = app.MustComponent[syncobjectgetter.SyncObjectGetter](a) + s.objectGetter = a.MustComponent(treemanager.CName).(syncobjectgetter.SyncObjectGetter) s.configuration = a.MustComponent(nodeconf.CName).(nodeconf.NodeConf) sharedData := a.MustComponent(spacestate.CName).(*spacestate.SpaceState) mc := a.Component(metric.CName) From c7828d0671dda3361576235afdfa1c59c20fffb0 Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Thu, 8 Jun 2023 12:35:29 +0200 Subject: [PATCH 032/123] move server config to drpc config --- net/config.go | 13 ------------- net/rpc/drpcconfig.go | 13 +++++++++++++ net/rpc/server/drpcserver.go | 6 +++--- 3 files changed, 16 insertions(+), 16 deletions(-) create mode 100644 net/rpc/drpcconfig.go diff --git a/net/config.go b/net/config.go index d1634d2c..64863419 100644 --- a/net/config.go +++ b/net/config.go @@ -5,16 +5,3 @@ import "errors" var ( ErrUnableToConnect = errors.New("unable to connect") ) - -type ConfigGetter interface { - GetNet() Config -} - -type Config struct { - Stream StreamConfig `yaml:"stream"` -} - -type StreamConfig struct { - TimeoutMilliseconds int `yaml:"timeoutMilliseconds"` - MaxMsgSizeMb int `yaml:"maxMsgSizeMb"` -} diff --git a/net/rpc/drpcconfig.go b/net/rpc/drpcconfig.go new file mode 100644 index 00000000..551313f6 --- /dev/null +++ b/net/rpc/drpcconfig.go @@ -0,0 +1,13 @@ +package rpc + +type ConfigGetter interface { + GetDrpc() Config +} + +type Config struct { + Stream StreamConfig `yaml:"stream"` +} + +type StreamConfig struct { + MaxMsgSizeMb int `yaml:"maxMsgSizeMb"` +} diff --git a/net/rpc/server/drpcserver.go b/net/rpc/server/drpcserver.go index 2b061515..48b3bfed 100644 --- a/net/rpc/server/drpcserver.go +++ b/net/rpc/server/drpcserver.go @@ -5,7 +5,7 @@ import ( "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/app/logger" "github.com/anyproto/any-sync/metric" - anyNet "github.com/anyproto/any-sync/net" + "github.com/anyproto/any-sync/net/rpc" "go.uber.org/zap" "net" "storj.io/drpc" @@ -32,7 +32,7 @@ type DRPCServer interface { type drpcServer struct { drpcServer *drpcserver.Server *drpcmux.Mux - config anyNet.Config + config rpc.Config metric metric.Metric } @@ -43,7 +43,7 @@ func (s *drpcServer) Name() (name string) { } func (s *drpcServer) Init(a *app.App) (err error) { - s.config = a.MustComponent("config").(anyNet.ConfigGetter).GetNet() + s.config = a.MustComponent("config").(rpc.ConfigGetter).GetDrpc() s.metric, _ = a.Component(metric.CName).(metric.Metric) s.Mux = drpcmux.New() From 33cbdd06a664bcdd5283577c9f776aaa77cde6e0 Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Thu, 8 Jun 2023 13:10:30 +0200 Subject: [PATCH 033/123] drpc conn config --- net/peer/peer.go | 13 ++++++++++++- net/peer/peer_test.go | 5 +++++ net/rpc/rpctest/server.go | 5 +++++ net/rpc/server/drpcserver.go | 10 +++++++++- 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/net/peer/peer.go b/net/peer/peer.go index 300243c4..bd0d9b34 100644 --- a/net/peer/peer.go +++ b/net/peer/peer.go @@ -6,6 +6,7 @@ import ( "github.com/anyproto/any-sync/app/logger" "github.com/anyproto/any-sync/app/ocache" "github.com/anyproto/any-sync/net/connutil" + "github.com/anyproto/any-sync/net/rpc" "github.com/anyproto/any-sync/net/secureservice/handshake" "github.com/anyproto/any-sync/net/secureservice/handshake/handshakeproto" "github.com/anyproto/any-sync/net/transport" @@ -14,6 +15,9 @@ import ( "net" "storj.io/drpc" "storj.io/drpc/drpcconn" + "storj.io/drpc/drpcmanager" + "storj.io/drpc/drpcstream" + "storj.io/drpc/drpcwire" "sync" "time" ) @@ -22,6 +26,7 @@ var log = logger.NewNamed("common.net.peer") type connCtrl interface { ServeConn(ctx context.Context, conn net.Conn) (err error) + DrpcConfig() rpc.Config } func NewPeer(mc transport.MultiConn, ctrl connCtrl) (p Peer, err error) { @@ -127,8 +132,14 @@ func (p *peer) openDrpcConn(ctx context.Context) (dconn *subConn, err error) { return nil, err } tconn := connutil.NewLastUsageConn(conn) + bufSize := p.ctrl.DrpcConfig().Stream.MaxMsgSizeMb * (1 << 20) return &subConn{ - Conn: drpcconn.New(tconn), + Conn: drpcconn.NewWithOptions(conn, drpcconn.Options{ + Manager: drpcmanager.Options{ + Reader: drpcwire.ReaderOptions{MaximumBufferSize: bufSize}, + Stream: drpcstream.Options{MaximumBufferSize: bufSize}, + }, + }), LastUsageConn: tconn, }, nil } diff --git a/net/peer/peer_test.go b/net/peer/peer_test.go index ac1ff28b..c0046923 100644 --- a/net/peer/peer_test.go +++ b/net/peer/peer_test.go @@ -2,6 +2,7 @@ package peer import ( "context" + "github.com/anyproto/any-sync/net/rpc" "github.com/anyproto/any-sync/net/secureservice/handshake" "github.com/anyproto/any-sync/net/secureservice/handshake/handshakeproto" "github.com/anyproto/any-sync/net/transport/mock_transport" @@ -176,6 +177,10 @@ type testCtrl struct { closeCh chan struct{} } +func (t *testCtrl) DrpcConfig() rpc.Config { + return rpc.Config{Stream: rpc.StreamConfig{MaxMsgSizeMb: 10}} +} + func (t *testCtrl) ServeConn(ctx context.Context, conn net.Conn) (err error) { t.serveConn <- conn <-t.closeCh diff --git a/net/rpc/rpctest/server.go b/net/rpc/rpctest/server.go index 053187f4..5c03f3e4 100644 --- a/net/rpc/rpctest/server.go +++ b/net/rpc/rpctest/server.go @@ -3,6 +3,7 @@ package rpctest import ( "context" "github.com/anyproto/any-sync/app" + "github.com/anyproto/any-sync/net/rpc" "github.com/anyproto/any-sync/net/rpc/server" "net" "storj.io/drpc/drpcmux" @@ -41,3 +42,7 @@ func (ts *TestServer) Close(ctx context.Context) (err error) { func (s *TestServer) ServeConn(ctx context.Context, conn net.Conn) (err error) { return s.Server.ServeOne(ctx, conn) } + +func (s *TestServer) DrpcConfig() rpc.Config { + return rpc.Config{Stream: rpc.StreamConfig{MaxMsgSizeMb: 10}} +} diff --git a/net/rpc/server/drpcserver.go b/net/rpc/server/drpcserver.go index 48b3bfed..8fc112ca 100644 --- a/net/rpc/server/drpcserver.go +++ b/net/rpc/server/drpcserver.go @@ -12,6 +12,7 @@ import ( "storj.io/drpc/drpcmanager" "storj.io/drpc/drpcmux" "storj.io/drpc/drpcserver" + "storj.io/drpc/drpcstream" "storj.io/drpc/drpcwire" ) @@ -25,6 +26,7 @@ func New() DRPCServer { type DRPCServer interface { ServeConn(ctx context.Context, conn net.Conn) (err error) + DrpcConfig() rpc.Config app.Component drpc.Mux } @@ -52,8 +54,10 @@ func (s *drpcServer) Init(a *app.App) (err error) { if s.metric != nil { handler = s.metric.WrapDRPCHandler(s) } + bufSize := s.config.Stream.MaxMsgSizeMb * (1 << 20) s.drpcServer = drpcserver.NewWithOptions(handler, drpcserver.Options{Manager: drpcmanager.Options{ - Reader: drpcwire.ReaderOptions{MaximumBufferSize: s.config.Stream.MaxMsgSizeMb * (1 << 20)}, + Reader: drpcwire.ReaderOptions{MaximumBufferSize: bufSize}, + Stream: drpcstream.Options{MaximumBufferSize: bufSize}, }}) return } @@ -63,3 +67,7 @@ func (s *drpcServer) ServeConn(ctx context.Context, conn net.Conn) (err error) { l.Debug("drpc serve peer") return s.drpcServer.ServeOne(ctx, conn) } + +func (s *drpcServer) DrpcConfig() rpc.Config { + return s.config +} From f9cb0c2dbb6c4f82c5bfad17f9b6d9208bcbc67a Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Thu, 8 Jun 2023 13:27:01 +0200 Subject: [PATCH 034/123] debug server --- net/rpc/debugserver/config.go | 9 +++++ net/rpc/debugserver/debugserver.go | 63 ++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 net/rpc/debugserver/config.go create mode 100644 net/rpc/debugserver/debugserver.go diff --git a/net/rpc/debugserver/config.go b/net/rpc/debugserver/config.go new file mode 100644 index 00000000..53342ece --- /dev/null +++ b/net/rpc/debugserver/config.go @@ -0,0 +1,9 @@ +package debugserver + +type configGetter interface { + GetDebugServer() Config +} + +type Config struct { + ListenAddr string `yaml:"listenAddr"` +} diff --git a/net/rpc/debugserver/debugserver.go b/net/rpc/debugserver/debugserver.go new file mode 100644 index 00000000..619d56a2 --- /dev/null +++ b/net/rpc/debugserver/debugserver.go @@ -0,0 +1,63 @@ +package debugserver + +import ( + "context" + "github.com/anyproto/any-sync/app" + "github.com/anyproto/any-sync/net/rpc" + "net" + "storj.io/drpc" + "storj.io/drpc/drpcmanager" + "storj.io/drpc/drpcmux" + "storj.io/drpc/drpcserver" + "storj.io/drpc/drpcstream" + "storj.io/drpc/drpcwire" +) + +const CName = "net.rpc.debugserver" + +type DebugServer interface { + app.ComponentRunnable + drpc.Mux +} + +type debugServer struct { + drpcServer *drpcserver.Server + *drpcmux.Mux + drpcConf rpc.Config + config Config + runCtx context.Context + runCtxCancel context.CancelFunc +} + +func (d *debugServer) Init(a *app.App) (err error) { + d.drpcConf = a.MustComponent("config").(rpc.ConfigGetter).GetDrpc() + d.config = a.MustComponent("config").(configGetter).GetDebugServer() + d.Mux = drpcmux.New() + bufSize := d.drpcConf.Stream.MaxMsgSizeMb * (1 << 20) + d.drpcServer = drpcserver.NewWithOptions(d, drpcserver.Options{Manager: drpcmanager.Options{ + Reader: drpcwire.ReaderOptions{MaximumBufferSize: bufSize}, + Stream: drpcstream.Options{MaximumBufferSize: bufSize}, + }}) + return nil +} + +func (d *debugServer) Name() (name string) { + return CName +} + +func (d *debugServer) Run(ctx context.Context) (err error) { + lis, err := net.Listen("tpc", d.config.ListenAddr) + if err != nil { + return + } + d.runCtx, d.runCtxCancel = context.WithCancel(context.Background()) + go d.drpcServer.Serve(d.runCtx, lis) + return +} + +func (d *debugServer) Close(ctx context.Context) (err error) { + if d.runCtx != nil { + d.runCtxCancel() + } + return nil +} From 85cf6b8332d76840d177625093b8f288c73998dd Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Thu, 8 Jun 2023 13:38:00 +0200 Subject: [PATCH 035/123] debug server fixes --- net/rpc/debugserver/debugserver.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/net/rpc/debugserver/debugserver.go b/net/rpc/debugserver/debugserver.go index 619d56a2..4a313ea8 100644 --- a/net/rpc/debugserver/debugserver.go +++ b/net/rpc/debugserver/debugserver.go @@ -15,6 +15,10 @@ import ( const CName = "net.rpc.debugserver" +func New() DebugServer { + return &debugServer{} +} + type DebugServer interface { app.ComponentRunnable drpc.Mux @@ -46,7 +50,10 @@ func (d *debugServer) Name() (name string) { } func (d *debugServer) Run(ctx context.Context) (err error) { - lis, err := net.Listen("tpc", d.config.ListenAddr) + if d.config.ListenAddr == "" { + return + } + lis, err := net.Listen("tcp", d.config.ListenAddr) if err != nil { return } From 24ce490524d7ffd6886caf8165e167da492fb681 Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Thu, 8 Jun 2023 14:36:14 +0200 Subject: [PATCH 036/123] yamux: AddListener method --- net/transport/yamux/yamux.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/net/transport/yamux/yamux.go b/net/transport/yamux/yamux.go index 47cb8c52..d47d16cc 100644 --- a/net/transport/yamux/yamux.go +++ b/net/transport/yamux/yamux.go @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/yamux" "go.uber.org/zap" "net" + "sync" "time" ) @@ -25,6 +26,7 @@ func New() Yamux { // Yamux implements transport.Transport with tcp+yamux type Yamux interface { transport.Transport + AddListener(lis net.Listener) app.ComponentRunnable } @@ -37,6 +39,7 @@ type yamuxTransport struct { listCtx context.Context listCtxCancel context.CancelFunc yamuxConf *yamux.Config + mu sync.Mutex } func (y *yamuxTransport) Init(a *app.App) (err error) { @@ -63,6 +66,8 @@ func (y *yamuxTransport) Run(ctx context.Context) (err error) { if y.accepter == nil { return fmt.Errorf("can't run service without accepter") } + y.mu.Lock() + defer y.mu.Unlock() for _, listAddr := range y.conf.ListenAddrs { list, err := net.Listen("tcp", listAddr) if err != nil { @@ -81,6 +86,13 @@ func (y *yamuxTransport) SetAccepter(accepter transport.Accepter) { y.accepter = accepter } +func (y *yamuxTransport) AddListener(lis net.Listener) { + y.mu.Lock() + defer y.mu.Unlock() + y.listeners = append(y.listeners, lis) + go y.acceptLoop(y.listCtx, lis) +} + func (y *yamuxTransport) Dial(ctx context.Context, addr string) (mc transport.MultiConn, err error) { dialTimeout := time.Duration(y.conf.DialTimeoutSec) * time.Second conn, err := net.DialTimeout("tcp", addr, dialTimeout) From 15326da736ee9b37550cfa7081409ca2a7ac47e4 Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Thu, 8 Jun 2023 14:37:54 +0200 Subject: [PATCH 037/123] yamux: move listCtx to Init --- net/transport/yamux/yamux.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/transport/yamux/yamux.go b/net/transport/yamux/yamux.go index d47d16cc..9a0245a9 100644 --- a/net/transport/yamux/yamux.go +++ b/net/transport/yamux/yamux.go @@ -55,6 +55,7 @@ func (y *yamuxTransport) Init(a *app.App) (err error) { y.yamuxConf.EnableKeepAlive = false y.yamuxConf.StreamOpenTimeout = time.Duration(y.conf.DialTimeoutSec) * time.Second y.yamuxConf.ConnectionWriteTimeout = time.Duration(y.conf.WriteTimeoutSec) * time.Second + y.listCtx, y.listCtxCancel = context.WithCancel(context.Background()) return } @@ -75,7 +76,6 @@ func (y *yamuxTransport) Run(ctx context.Context) (err error) { } y.listeners = append(y.listeners, list) } - y.listCtx, y.listCtxCancel = context.WithCancel(context.Background()) for _, list := range y.listeners { go y.acceptLoop(y.listCtx, list) } From 35c29a48421434a121f86bd1127a7786c204df6f Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Thu, 8 Jun 2023 21:07:03 +0200 Subject: [PATCH 038/123] Add WithServer for TestPool --- net/rpc/rpctest/pool.go | 24 ++++++++++++++++++++---- net/rpc/rpctest/server.go | 31 +++++++++++++++++++++++++++---- 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/net/rpc/rpctest/pool.go b/net/rpc/rpctest/pool.go index 0e2b5d1b..fc70d16b 100644 --- a/net/rpc/rpctest/pool.go +++ b/net/rpc/rpctest/pool.go @@ -16,6 +16,7 @@ func NewTestPool() *TestPool { type TestPool struct { peers map[string]peer.Peer mu sync.Mutex + ts *TestServer } func (t *TestPool) Init(a *app.App) (err error) { @@ -26,6 +27,13 @@ func (t *TestPool) Name() (name string) { return pool.CName } +func (t *TestPool) WithServer(ts *TestServer) *TestPool { + t.mu.Lock() + defer t.mu.Unlock() + t.ts = ts + return t +} + func (t *TestPool) Run(ctx context.Context) (err error) { return nil } @@ -40,16 +48,24 @@ func (t *TestPool) Get(ctx context.Context, id string) (peer.Peer, error) { if p, ok := t.peers[id]; ok { return p, nil } - return nil, net.ErrUnableToConnect + if t.ts == nil { + return nil, net.ErrUnableToConnect + } + return t.ts.Dial(id) } func (t *TestPool) GetOneOf(ctx context.Context, peerIds []string) (peer.Peer, error) { - for _, id := range peerIds { - if p, err := t.Get(ctx, id); err == nil { + t.mu.Lock() + defer t.mu.Unlock() + for _, peerId := range peerIds { + if p, ok := t.peers[peerId]; ok { return p, nil } } - return nil, net.ErrUnableToConnect + if t.ts == nil || len(peerIds) == 0 { + return nil, net.ErrUnableToConnect + } + return t.ts.Dial(peerIds[0]) } func (t *TestPool) AddPeer(ctx context.Context, p peer.Peer) (err error) { diff --git a/net/rpc/rpctest/server.go b/net/rpc/rpctest/server.go index 5c03f3e4..de6bf68b 100644 --- a/net/rpc/rpctest/server.go +++ b/net/rpc/rpctest/server.go @@ -3,6 +3,7 @@ package rpctest import ( "context" "github.com/anyproto/any-sync/app" + "github.com/anyproto/any-sync/net/peer" "github.com/anyproto/any-sync/net/rpc" "github.com/anyproto/any-sync/net/rpc/server" "net" @@ -10,6 +11,17 @@ import ( "storj.io/drpc/drpcserver" ) +type mockCtrl struct { +} + +func (m mockCtrl) ServeConn(ctx context.Context, conn net.Conn) (err error) { + return nil +} + +func (m mockCtrl) DrpcConfig() rpc.Config { + return rpc.Config{} +} + func NewTestServer() *TestServer { ts := &TestServer{ Mux: drpcmux.New(), @@ -23,19 +35,19 @@ type TestServer struct { *drpcserver.Server } -func (ts *TestServer) Init(a *app.App) (err error) { +func (s *TestServer) Init(a *app.App) (err error) { return nil } -func (ts *TestServer) Name() (name string) { +func (s *TestServer) Name() (name string) { return server.CName } -func (ts *TestServer) Run(ctx context.Context) (err error) { +func (s *TestServer) Run(ctx context.Context) (err error) { return nil } -func (ts *TestServer) Close(ctx context.Context) (err error) { +func (s *TestServer) Close(ctx context.Context) (err error) { return nil } @@ -46,3 +58,14 @@ func (s *TestServer) ServeConn(ctx context.Context, conn net.Conn) (err error) { func (s *TestServer) DrpcConfig() rpc.Config { return rpc.Config{Stream: rpc.StreamConfig{MaxMsgSizeMb: 10}} } + +func (s *TestServer) Dial(peerId string) (clientPeer peer.Peer, err error) { + mcS, mcC := MultiConnPair(peerId+"server", peerId) + // NewPeer runs the accept loop + _, err = peer.NewPeer(mcS, s) + if err != nil { + return + } + // and we ourselves don't call server methods on accept + return peer.NewPeer(mcC, mockCtrl{}) +} From b0c0e4b26e50d964f32abf8f4265e77f6f4d12ea Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Fri, 9 Jun 2023 17:10:25 +0200 Subject: [PATCH 039/123] Fix proto version --- net/secureservice/secureservice.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/secureservice/secureservice.go b/net/secureservice/secureservice.go index d20d7109..4c62bcdb 100644 --- a/net/secureservice/secureservice.go +++ b/net/secureservice/secureservice.go @@ -3,6 +3,9 @@ package secureservice import ( "context" "crypto/tls" + "io" + "net" + commonaccount "github.com/anyproto/any-sync/accountservice" "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/app/logger" @@ -13,8 +16,6 @@ import ( "github.com/libp2p/go-libp2p/core/crypto" libp2ptls "github.com/libp2p/go-libp2p/p2p/security/tls" "go.uber.org/zap" - "io" - "net" ) const CName = "common.net.secure" @@ -52,6 +53,7 @@ type secureService struct { } func (s *secureService) Init(a *app.App) (err error) { + s.protoVersion = ProtoVersion account := a.MustComponent(commonaccount.CName).(commonaccount.Service) peerKey, err := account.Account().PeerKey.Raw() if err != nil { @@ -76,8 +78,6 @@ func (s *secureService) Init(a *app.App) (err error) { return } - s.protoVersion = ProtoVersion - log.Info("secure service init", zap.String("peerId", account.Account().PeerId)) return nil } From e97e6b68c6c0f80c416a75da18bad2c1ec3ba907 Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Fri, 9 Jun 2023 19:14:23 +0200 Subject: [PATCH 040/123] peer: gc active sub conn --- net/peer/peer.go | 7 +++++++ net/peer/peer_test.go | 13 +++++++++++++ 2 files changed, 20 insertions(+) diff --git a/net/peer/peer.go b/net/peer/peer.go index bd0d9b34..2a2c50b0 100644 --- a/net/peer/peer.go +++ b/net/peer/peer.go @@ -222,8 +222,15 @@ func (p *peer) gc(ttl time.Duration) { select { case <-act.Closed(): delete(p.active, act) + continue default: } + if act.LastUsage().Before(minLastUsage) { + log.Warn("close active connection because no activity", zap.String("peerId", p.id), zap.String("addr", p.Addr())) + _ = act.Close() + delete(p.active, act) + continue + } } } diff --git a/net/peer/peer_test.go b/net/peer/peer_test.go index c0046923..67d0f65d 100644 --- a/net/peer/peer_test.go +++ b/net/peer/peer_test.go @@ -105,6 +105,7 @@ func TestPeer_TryClose(t *testing.T) { }() defer out2.Close() fx.mc.EXPECT().Open(gomock.Any()).Return(in2, nil) + fx.mc.EXPECT().Addr().Return("") dc2, err := fx.AcquireDrpcConn(ctx) require.NoError(t, err) _ = dc2.Close() @@ -118,6 +119,18 @@ func TestPeer_TryClose(t *testing.T) { fx.mc.EXPECT().Open(gomock.Any()).Return(in3, nil) dc3, err := fx.AcquireDrpcConn(ctx) require.NoError(t, err) + + // make another active, should be removed by ttl + in4, out4 := net.Pipe() + go func() { + handshake.IncomingProtoHandshake(ctx, out4, defaultProtoChecker) + }() + defer out4.Close() + fx.mc.EXPECT().Open(gomock.Any()).Return(in4, nil) + dc4, err := fx.AcquireDrpcConn(ctx) + require.NoError(t, err) + defer dc4.Close() + fx.ReleaseDrpcConn(dc3) _ = dc3.Close() fx.ReleaseDrpcConn(dc) From 89afc03218203d0e41c85e9f6f90c2c6c938e851 Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Fri, 9 Jun 2023 19:28:09 +0200 Subject: [PATCH 041/123] fix HandshakeIncompatibleVersion test --- net/secureservice/secureservice.go | 4 +++- net/secureservice/secureservice_test.go | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/net/secureservice/secureservice.go b/net/secureservice/secureservice.go index 4c62bcdb..4487e9bc 100644 --- a/net/secureservice/secureservice.go +++ b/net/secureservice/secureservice.go @@ -53,7 +53,9 @@ type secureService struct { } func (s *secureService) Init(a *app.App) (err error) { - s.protoVersion = ProtoVersion + if s.protoVersion == 0 { + s.protoVersion = ProtoVersion + } account := a.MustComponent(commonaccount.CName).(commonaccount.Service) peerKey, err := account.Account().PeerKey.Raw() if err != nil { diff --git a/net/secureservice/secureservice_test.go b/net/secureservice/secureservice_test.go index 6aee985d..86735f66 100644 --- a/net/secureservice/secureservice_test.go +++ b/net/secureservice/secureservice_test.go @@ -57,7 +57,7 @@ func TestHandshake(t *testing.T) { func TestHandshakeIncompatibleVersion(t *testing.T) { nc := testnodeconf.GenNodeConfig(2) - fxS := newFixture(t, nc, nc.GetAccountService(0), 0) + fxS := newFixture(t, nc, nc.GetAccountService(0), 1) defer fxS.Finish(t) sc, cc := net.Pipe() @@ -72,7 +72,7 @@ func TestHandshakeIncompatibleVersion(t *testing.T) { ar.ctx, ar.err = fxS.SecureInbound(ctx, sc) resCh <- ar }() - fxC := newFixture(t, nc, nc.GetAccountService(1), 1) + fxC := newFixture(t, nc, nc.GetAccountService(1), 2) defer fxC.Finish(t) _, err := fxC.SecureOutbound(ctx, cc) require.Equal(t, handshake.ErrIncompatibleVersion, err) From 40cd112a2a29f2bd7850b3b5da980e22df6dae92 Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Mon, 12 Jun 2023 15:58:23 +0200 Subject: [PATCH 042/123] app.VersionName --- app/app.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/app.go b/app/app.go index 89e7ab46..c0230e52 100644 --- a/app/app.go +++ b/app/app.go @@ -61,6 +61,7 @@ type App struct { startStat Stat stopStat Stat deviceState int + versionName string anySyncVersion string } @@ -78,6 +79,17 @@ func (app *App) Version() string { return GitSummary } +func (app *App) SetVersionName(v string) { + app.versionName = v +} + +func (app *App) VersionName() string { + if app.versionName != "" { + return app.versionName + } + return AppName + ":" + GitSummary + "/any-sync:" + app.anySyncVersion +} + type Stat struct { SpentMsPerComp map[string]int64 SpentMsTotal int64 From cb0396c40f089b18e112733a37cadc742bb35eb2 Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Mon, 12 Jun 2023 16:01:17 +0200 Subject: [PATCH 043/123] comments --- app/app.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/app.go b/app/app.go index c0230e52..ea374649 100644 --- a/app/app.go +++ b/app/app.go @@ -79,10 +79,12 @@ func (app *App) Version() string { return GitSummary } +// SetVersionName sets the custom application version func (app *App) SetVersionName(v string) { app.versionName = v } +// VersionName returns a string with the settled app version or auto-generated version if it didn't set func (app *App) VersionName() string { if app.versionName != "" { return app.versionName From d6df4b700179af67cfaebb6b6a40c828b5265c77 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jun 2023 16:05:59 +0000 Subject: [PATCH 044/123] Bump github.com/ipfs/go-merkledag from 0.10.0 to 0.11.0 Bumps [github.com/ipfs/go-merkledag](https://github.com/ipfs/go-merkledag) from 0.10.0 to 0.11.0. - [Release notes](https://github.com/ipfs/go-merkledag/releases) - [Commits](https://github.com/ipfs/go-merkledag/compare/v0.10.0...v0.11.0) --- updated-dependencies: - dependency-name: github.com/ipfs/go-merkledag dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 9 +++------ go.sum | 53 +++++++---------------------------------------------- 2 files changed, 10 insertions(+), 52 deletions(-) diff --git a/go.mod b/go.mod index 0581372a..43edb597 100644 --- a/go.mod +++ b/go.mod @@ -22,8 +22,8 @@ require ( github.com/ipfs/go-ipfs-blockstore v1.3.1 github.com/ipfs/go-ipfs-chunker v0.0.6 github.com/ipfs/go-ipfs-exchange-interface v0.2.1 - github.com/ipfs/go-ipld-format v0.4.0 - github.com/ipfs/go-merkledag v0.10.0 + github.com/ipfs/go-ipld-format v0.5.0 + github.com/ipfs/go-merkledag v0.11.0 github.com/ipfs/go-unixfs v0.4.6 github.com/libp2p/go-libp2p v0.27.5 github.com/mr-tron/base58 v1.2.0 @@ -66,8 +66,7 @@ require ( github.com/ipfs/go-ipfs-files v0.2.0 // 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-cbor v0.0.6 // indirect - github.com/ipfs/go-ipld-legacy v0.1.1 // indirect + github.com/ipfs/go-ipld-legacy v0.2.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 @@ -100,7 +99,6 @@ require ( github.com/quic-go/quic-go v0.35.1 // indirect github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect - github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158 // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/zeebo/errs v1.3.0 // indirect go.opentelemetry.io/otel v1.7.0 // indirect @@ -110,7 +108,6 @@ require ( golang.org/x/sync v0.2.0 // indirect golang.org/x/sys v0.8.0 // indirect golang.org/x/tools v0.9.3 // indirect - golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/protobuf v1.30.0 // indirect lukechampine.com/blake3 v1.2.1 // indirect ) diff --git a/go.sum b/go.sum index 04c9a7c6..bc5e5497 100644 --- a/go.sum +++ b/go.sum @@ -38,7 +38,6 @@ github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= 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/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= -github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -61,8 +60,6 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -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.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= @@ -74,7 +71,6 @@ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ 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= @@ -93,17 +89,12 @@ github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbG github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= -github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo= github.com/ipfs/go-block-format v0.1.2/go.mod h1:mACVcrxarQKstUU3Yf/RdwbC4DzPV6++rO2a3d+a/KE= github.com/ipfs/go-blockservice v0.5.2 h1:in9Bc+QcXwd1apOVM7Un9t8tixPKdaHQFdLSUM1Xgk8= github.com/ipfs/go-blockservice v0.5.2/go.mod h1:VpMblFEqG67A/H2sHKAemeH9vlURVavlysbdUI632yk= 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.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= github.com/ipfs/go-datastore v0.5.0/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk= @@ -132,21 +123,18 @@ github.com/ipfs/go-ipfs-routing v0.3.0 h1:9W/W3N+g+y4ZDeffSgqhgo7BsBSJwPMcyssET9 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.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-ipld-format v0.5.0 h1:WyEle9K96MSrvr47zZHKKcDxJ/vlpET6PSiQsAFO+Ds= +github.com/ipfs/go-ipld-format v0.5.0/go.mod h1:ImdZqJQaEouMjCvqCe0ORUS+uoBmf7Hf+EO/jh+nk3M= +github.com/ipfs/go-ipld-legacy v0.2.1 h1:mDFtrBpmU7b//LzLSypVrXsD8QxkEWxu5qVxN99/+tk= +github.com/ipfs/go-ipld-legacy v0.2.1/go.mod h1:782MOUghNzMO2DER0FlBR94mllfdCJCkTtDtPM51otM= 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.10.0 h1:IUQhj/kzTZfam4e+LnaEpoiZ9vZF6ldimVlby+6OXL4= -github.com/ipfs/go-merkledag v0.10.0/go.mod h1:zkVav8KiYlmbzUzNM6kENzkdP5+qR7+2mCwxkQ6GIj8= +github.com/ipfs/go-merkledag v0.11.0 h1:DgzwK5hprESOzS4O1t/wi6JDpyVQdvm9Bs59N/jqfBY= +github.com/ipfs/go-merkledag v0.11.0/go.mod h1:Q4f/1ezvBiJV0YCIXvt51W/9/kqJGH4I1LsA7+djsM4= 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.8.0 h1:JyNO144tfu9bx6Hpo119zvbEL9iQ760FHOiJYsUjqaU= @@ -156,7 +144,6 @@ github.com/ipfs/go-verifcid v0.0.1 h1:m2HI7zIuR5TFyQ1b79Da5N9dnnCP1vcu2QqawmWlK2 github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= -github.com/ipld/go-ipld-prime v0.9.1-0.20210324083106-dc342a9917db/go.mod h1:KvBLMr4PX1gWptgkzRjVZCrLmSGcZCb/jioOQwCqZN8= github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= @@ -165,9 +152,7 @@ github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABo github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= -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/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE= 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.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= @@ -179,12 +164,10 @@ github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8t github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= 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.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 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= @@ -210,14 +193,12 @@ github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1 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/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/multiformats/go-multiaddr v0.9.0 h1:3h4V1LHIk5w4hJHekMKWALPXErDfz/sggzwC/NcqbDQ= @@ -225,22 +206,17 @@ github.com/multiformats/go-multiaddr v0.9.0/go.mod h1:mI67Lb1EeTOYb8GQfL/7wpIZwc 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.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= 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.2 h1:Uu7LWs/PmWby1gkj1S1DXx3zyd3aVabA4FiMKn/2tAc= github.com/multiformats/go-multihash v0.2.2/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= -github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5 h1:BvoENQQU+fZ9uukda/RzCAL/191HHwJA5b13R6diVlY= @@ -253,8 +229,6 @@ 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/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI= @@ -275,10 +249,7 @@ github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2Gk github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= 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/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= @@ -292,11 +263,7 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/warpfork/go-testmark v0.11.0 h1:J6LnV8KpceDvo7spaNU4+DauH2n1x+6RaO2rJrmpQ9U= -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 h1:WXhVOwj2USAXB5oMDwRl3piOux2XMV9TANaYxXHdkoE= -github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= 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/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -337,7 +304,6 @@ golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= @@ -376,11 +342,9 @@ golang.org/x/sync v0.2.0/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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/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-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -392,7 +356,6 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= golang.org/x/sys v0.8.0/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/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -404,7 +367,6 @@ golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= 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= @@ -420,7 +382,6 @@ golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= 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/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= From ab6ecaa462636cad2ac56f551c08c9a0820957eb Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Mon, 12 Jun 2023 18:42:30 +0200 Subject: [PATCH 045/123] write deadline + check conn for close --- net/peer/peer.go | 6 ++++++ net/transport/yamux/conn.go | 2 ++ net/transport/yamux/yamux.go | 4 ++-- net/transport/yamux/yamux_test.go | 21 +++++++++++++++++++++ 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/net/peer/peer.go b/net/peer/peer.go index 2a2c50b0..4e584f2c 100644 --- a/net/peer/peer.go +++ b/net/peer/peer.go @@ -95,6 +95,12 @@ func (p *peer) AcquireDrpcConn(ctx context.Context) (drpc.Conn, error) { idx := len(p.inactive) - 1 res := p.inactive[idx] p.inactive = p.inactive[:idx] + select { + case <-res.Closed(): + p.mu.Unlock() + return p.AcquireDrpcConn(ctx) + default: + } p.active[res] = struct{}{} p.mu.Unlock() return res, nil diff --git a/net/transport/yamux/conn.go b/net/transport/yamux/conn.go index c752d22d..a3406bfa 100644 --- a/net/transport/yamux/conn.go +++ b/net/transport/yamux/conn.go @@ -29,6 +29,7 @@ func (y *yamuxConn) Open(ctx context.Context) (conn net.Conn, err error) { if conn, err = y.Session.Open(); err != nil { return } + conn = connutil.NewTimeout(conn, time.Second*10) return } @@ -51,5 +52,6 @@ func (y *yamuxConn) Accept() (conn net.Conn, err error) { } return } + conn = connutil.NewTimeout(conn, time.Second*10) return } diff --git a/net/transport/yamux/yamux.go b/net/transport/yamux/yamux.go index 9a0245a9..2722a76c 100644 --- a/net/transport/yamux/yamux.go +++ b/net/transport/yamux/yamux.go @@ -106,7 +106,7 @@ func (y *yamuxTransport) Dial(ctx context.Context, addr string) (mc transport.Mu _ = conn.Close() return nil, err } - luc := connutil.NewLastUsageConn(conn) + luc := connutil.NewLastUsageConn(connutil.NewTimeout(conn, time.Duration(y.conf.WriteTimeoutSec)*time.Second)) sess, err := yamux.Client(luc, y.yamuxConf) if err != nil { return @@ -152,7 +152,7 @@ func (y *yamuxTransport) accept(conn net.Conn) { log.Warn("incoming connection handshake error", zap.Error(err)) return } - luc := connutil.NewLastUsageConn(conn) + luc := connutil.NewLastUsageConn(connutil.NewTimeout(conn, time.Duration(y.conf.WriteTimeoutSec)*time.Second)) sess, err := yamux.Server(luc, y.yamuxConf) if err != nil { log.Warn("incoming connection yamux session error", zap.Error(err)) diff --git a/net/transport/yamux/yamux_test.go b/net/transport/yamux/yamux_test.go index 02e1c322..8946c969 100644 --- a/net/transport/yamux/yamux_test.go +++ b/net/transport/yamux/yamux_test.go @@ -66,6 +66,27 @@ func TestYamuxTransport_Dial(t *testing.T) { assert.NoError(t, copyErr) } +func TestSubConnWrite(t *testing.T) { + fxS := newFixture(t) + defer fxS.finish(t) + fxC := newFixture(t) + defer fxC.finish(t) + mc, err := fxC.Dial(ctx, fxS.addr) + require.NoError(t, err) + + mcS := <-fxS.accepter.mcs + _ = mcS + + //time.Sleep(time.Second) + conn, err := mc.Open(ctx) + require.NoError(t, err) + //mc.Close() + + n, err := conn.Write([]byte("123")) + require.NoError(t, err) + require.Equal(t, n, 3) +} + // no deadline - 69100 rps // common write deadline - 66700 rps // subconn write deadline - 67100 rps From 767f868a36a5810fdb786df0dacf100e2b703a90 Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Mon, 12 Jun 2023 18:55:40 +0200 Subject: [PATCH 046/123] remove test test --- net/transport/yamux/yamux_test.go | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/net/transport/yamux/yamux_test.go b/net/transport/yamux/yamux_test.go index 8946c969..02e1c322 100644 --- a/net/transport/yamux/yamux_test.go +++ b/net/transport/yamux/yamux_test.go @@ -66,27 +66,6 @@ func TestYamuxTransport_Dial(t *testing.T) { assert.NoError(t, copyErr) } -func TestSubConnWrite(t *testing.T) { - fxS := newFixture(t) - defer fxS.finish(t) - fxC := newFixture(t) - defer fxC.finish(t) - mc, err := fxC.Dial(ctx, fxS.addr) - require.NoError(t, err) - - mcS := <-fxS.accepter.mcs - _ = mcS - - //time.Sleep(time.Second) - conn, err := mc.Open(ctx) - require.NoError(t, err) - //mc.Close() - - n, err := conn.Write([]byte("123")) - require.NoError(t, err) - require.Equal(t, n, 3) -} - // no deadline - 69100 rps // common write deadline - 66700 rps // subconn write deadline - 67100 rps From 05b479e5faa7a7ee2caed71c97f92a077e77021f Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Tue, 13 Jun 2023 13:28:19 +0200 Subject: [PATCH 047/123] yamux keep-alive config + remove write deadline for sub conns --- net/transport/yamux/config.go | 7 ++++--- net/transport/yamux/conn.go | 2 -- net/transport/yamux/yamux.go | 10 +++++++++- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/net/transport/yamux/config.go b/net/transport/yamux/config.go index 2afce5fd..48ea710a 100644 --- a/net/transport/yamux/config.go +++ b/net/transport/yamux/config.go @@ -5,7 +5,8 @@ type configGetter interface { } type Config struct { - ListenAddrs []string `yaml:"listenAddrs"` - WriteTimeoutSec int `yaml:"writeTimeoutSec"` - DialTimeoutSec int `yaml:"dialTimeoutSec"` + ListenAddrs []string `yaml:"listenAddrs"` + WriteTimeoutSec int `yaml:"writeTimeoutSec"` + DialTimeoutSec int `yaml:"dialTimeoutSec"` + KeepAlivePeriodSec int `yaml:"keepAlivePeriodSec"` } diff --git a/net/transport/yamux/conn.go b/net/transport/yamux/conn.go index a3406bfa..c752d22d 100644 --- a/net/transport/yamux/conn.go +++ b/net/transport/yamux/conn.go @@ -29,7 +29,6 @@ func (y *yamuxConn) Open(ctx context.Context) (conn net.Conn, err error) { if conn, err = y.Session.Open(); err != nil { return } - conn = connutil.NewTimeout(conn, time.Second*10) return } @@ -52,6 +51,5 @@ func (y *yamuxConn) Accept() (conn net.Conn, err error) { } return } - conn = connutil.NewTimeout(conn, time.Second*10) return } diff --git a/net/transport/yamux/yamux.go b/net/transport/yamux/yamux.go index 2722a76c..1aa8420f 100644 --- a/net/transport/yamux/yamux.go +++ b/net/transport/yamux/yamux.go @@ -51,8 +51,16 @@ func (y *yamuxTransport) Init(a *app.App) (err error) { if y.conf.WriteTimeoutSec <= 0 { y.conf.WriteTimeoutSec = 10 } + y.yamuxConf = yamux.DefaultConfig() - y.yamuxConf.EnableKeepAlive = false + if y.conf.KeepAlivePeriodSec < 0 { + y.yamuxConf.EnableKeepAlive = false + } else { + y.yamuxConf.EnableKeepAlive = true + if y.conf.KeepAlivePeriodSec != 0 { + y.yamuxConf.KeepAliveInterval = time.Duration(y.conf.KeepAlivePeriodSec) * time.Second + } + } y.yamuxConf.StreamOpenTimeout = time.Duration(y.conf.DialTimeoutSec) * time.Second y.yamuxConf.ConnectionWriteTimeout = time.Duration(y.conf.WriteTimeoutSec) * time.Second y.listCtx, y.listCtxCancel = context.WithCancel(context.Background()) From 733027d79842283672aa6eaa3097f7978fe3774f Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Tue, 13 Jun 2023 13:40:13 +0200 Subject: [PATCH 048/123] remove multiconn.LastUsage + fix peer gc --- Makefile | 1 + net/peer/peer.go | 14 +++++++++----- net/peer/peer_test.go | 10 +++------- net/transport/mock_transport/mock_transport.go | 15 --------------- net/transport/transport.go | 3 --- 5 files changed, 13 insertions(+), 30 deletions(-) diff --git a/Makefile b/Makefile index aa0fa75f..94227398 100644 --- a/Makefile +++ b/Makefile @@ -25,6 +25,7 @@ deps: go mod download go build -o deps storj.io/drpc/cmd/protoc-gen-go-drpc go build -o deps github.com/gogo/protobuf/protoc-gen-gogofaster + go build -o deps github.com/golang/mock/mockgen test: go test ./... --cover diff --git a/net/peer/peer.go b/net/peer/peer.go index 4e584f2c..c8a54a43 100644 --- a/net/peer/peer.go +++ b/net/peer/peer.go @@ -35,6 +35,7 @@ func NewPeer(mc transport.MultiConn, ctrl connCtrl) (p Peer, err error) { active: map[*subConn]struct{}{}, MultiConn: mc, ctrl: ctrl, + created: time.Now(), } if pr.id, err = CtxPeerId(ctx); err != nil { return @@ -74,6 +75,8 @@ type peer struct { mu sync.Mutex + created time.Time + transport.MultiConn } @@ -190,14 +193,14 @@ func (p *peer) serve(conn net.Conn) (err error) { } func (p *peer) TryClose(objectTTL time.Duration) (res bool, err error) { - p.gc(objectTTL) - if time.Now().Sub(p.LastUsage()) < objectTTL { - return false, nil + aliveCount := p.gc(objectTTL) + if aliveCount == 0 && p.created.Add(time.Minute).Before(time.Now()) { + return true, p.Close() } - return true, p.Close() + return false, nil } -func (p *peer) gc(ttl time.Duration) { +func (p *peer) gc(ttl time.Duration) (aliveCount int) { p.mu.Lock() defer p.mu.Unlock() minLastUsage := time.Now().Add(-ttl) @@ -238,6 +241,7 @@ func (p *peer) gc(ttl time.Duration) { continue } } + return len(p.active) + len(p.inactive) } func (p *peer) Close() (err error) { diff --git a/net/peer/peer_test.go b/net/peer/peer_test.go index 67d0f65d..ac06f8d6 100644 --- a/net/peer/peer_test.go +++ b/net/peer/peer_test.go @@ -64,11 +64,9 @@ func TestPeerAccept(t *testing.T) { } func TestPeer_TryClose(t *testing.T) { - t.Run("ttl", func(t *testing.T) { + t.Run("not close in first minute", func(t *testing.T) { fx := newFixture(t, "p1") defer fx.finish() - lu := time.Now() - fx.mc.EXPECT().LastUsage().Return(lu) res, err := fx.TryClose(time.Second) require.NoError(t, err) assert.False(t, res) @@ -76,8 +74,7 @@ func TestPeer_TryClose(t *testing.T) { t.Run("close", func(t *testing.T) { fx := newFixture(t, "p1") defer fx.finish() - lu := time.Now().Add(-time.Second * 2) - fx.mc.EXPECT().LastUsage().Return(lu) + fx.peer.created = fx.peer.created.Add(-time.Minute * 2) res, err := fx.TryClose(time.Second) require.NoError(t, err) assert.True(t, res) @@ -85,8 +82,7 @@ func TestPeer_TryClose(t *testing.T) { t.Run("gc", func(t *testing.T) { fx := newFixture(t, "p1") defer fx.finish() - now := time.Now() - fx.mc.EXPECT().LastUsage().Return(now.Add(time.Millisecond * 100)) + //now := time.Now() // make one inactive in, out := net.Pipe() diff --git a/net/transport/mock_transport/mock_transport.go b/net/transport/mock_transport/mock_transport.go index 43f5572c..e0428014 100644 --- a/net/transport/mock_transport/mock_transport.go +++ b/net/transport/mock_transport/mock_transport.go @@ -8,7 +8,6 @@ import ( context "context" net "net" reflect "reflect" - time "time" transport "github.com/anyproto/any-sync/net/transport" gomock "github.com/golang/mock/gomock" @@ -158,20 +157,6 @@ func (mr *MockMultiConnMockRecorder) IsClosed() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsClosed", reflect.TypeOf((*MockMultiConn)(nil).IsClosed)) } -// LastUsage mocks base method. -func (m *MockMultiConn) LastUsage() time.Time { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "LastUsage") - ret0, _ := ret[0].(time.Time) - return ret0 -} - -// LastUsage indicates an expected call of LastUsage. -func (mr *MockMultiConnMockRecorder) LastUsage() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LastUsage", reflect.TypeOf((*MockMultiConn)(nil).LastUsage)) -} - // Open mocks base method. func (m *MockMultiConn) Open(arg0 context.Context) (net.Conn, error) { m.ctrl.T.Helper() diff --git a/net/transport/transport.go b/net/transport/transport.go index 2dab5348..9d36435a 100644 --- a/net/transport/transport.go +++ b/net/transport/transport.go @@ -5,7 +5,6 @@ import ( "context" "errors" "net" - "time" ) var ( @@ -29,8 +28,6 @@ type MultiConn interface { Accept() (conn net.Conn, err error) // Open opens new sub connection Open(ctx context.Context) (conn net.Conn, err error) - // LastUsage returns the time of the last connection activity - LastUsage() time.Time // Addr returns remote peer address Addr() string // IsClosed returns true when connection is closed From c3ebc8981c5cc72c824149a6d691519bdef33656 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Jun 2023 11:49:19 +0000 Subject: [PATCH 049/123] Bump github.com/multiformats/go-multihash from 0.2.2 to 0.2.3 Bumps [github.com/multiformats/go-multihash](https://github.com/multiformats/go-multihash) from 0.2.2 to 0.2.3. - [Release notes](https://github.com/multiformats/go-multihash/releases) - [Commits](https://github.com/multiformats/go-multihash/compare/v0.2.2...v0.2.3) --- updated-dependencies: - dependency-name: github.com/multiformats/go-multihash dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 43edb597..96353770 100644 --- a/go.mod +++ b/go.mod @@ -28,7 +28,7 @@ require ( github.com/libp2p/go-libp2p v0.27.5 github.com/mr-tron/base58 v1.2.0 github.com/multiformats/go-multibase v0.2.0 - github.com/multiformats/go-multihash v0.2.2 + github.com/multiformats/go-multihash v0.2.3 github.com/prometheus/client_golang v1.15.1 github.com/stretchr/testify v1.8.4 github.com/tyler-smith/go-bip39 v1.1.0 diff --git a/go.sum b/go.sum index bc5e5497..bff0699f 100644 --- a/go.sum +++ b/go.sum @@ -212,8 +212,8 @@ github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3 github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= -github.com/multiformats/go-multihash v0.2.2 h1:Uu7LWs/PmWby1gkj1S1DXx3zyd3aVabA4FiMKn/2tAc= -github.com/multiformats/go-multihash v0.2.2/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= +github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= +github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= From 2aaa8f4a0c2fa905baf56c50422458c343d8e08f Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Tue, 13 Jun 2023 15:21:11 +0200 Subject: [PATCH 050/123] Change retry logic and add tests --- commonspace/object/tree/synctree/synctree.go | 26 ++-- .../object/tree/synctree/treeremotegetter.go | 43 +++--- .../tree/synctree/treeremotegetter_test.go | 142 ++++++++++++++++++ commonspace/objecttreebuilder/treebuilder.go | 34 +++-- commonspace/requestmanager/requestmanager.go | 3 +- commonspace/settings/settings.go | 6 +- 6 files changed, 202 insertions(+), 52 deletions(-) create mode 100644 commonspace/object/tree/synctree/treeremotegetter_test.go diff --git a/commonspace/object/tree/synctree/synctree.go b/commonspace/object/tree/synctree/synctree.go index cd6ff7a2..a21121bf 100644 --- a/commonspace/object/tree/synctree/synctree.go +++ b/commonspace/object/tree/synctree/synctree.go @@ -59,19 +59,19 @@ type ResponsiblePeersGetter interface { } type BuildDeps struct { - SpaceId string - SyncClient SyncClient - Configuration nodeconf.NodeConf - HeadNotifiable HeadNotifiable - Listener updatelistener.UpdateListener - AclList list.AclList - SpaceStorage spacestorage.SpaceStorage - TreeStorage treestorage.TreeStorage - OnClose func(id string) - SyncStatus syncstatus.StatusUpdater - PeerGetter ResponsiblePeersGetter - BuildObjectTree objecttree.BuildObjectTreeFunc - WaitTreeRemoteSync bool + SpaceId string + SyncClient SyncClient + Configuration nodeconf.NodeConf + HeadNotifiable HeadNotifiable + Listener updatelistener.UpdateListener + AclList list.AclList + SpaceStorage spacestorage.SpaceStorage + TreeStorage treestorage.TreeStorage + OnClose func(id string) + SyncStatus syncstatus.StatusUpdater + PeerGetter ResponsiblePeersGetter + BuildObjectTree objecttree.BuildObjectTreeFunc + RetryTimeout time.Duration } func BuildSyncTreeOrGetRemote(ctx context.Context, id string, deps BuildDeps) (t SyncTree, err error) { diff --git a/commonspace/object/tree/synctree/treeremotegetter.go b/commonspace/object/tree/synctree/treeremotegetter.go index bee53231..843a37b4 100644 --- a/commonspace/object/tree/synctree/treeremotegetter.go +++ b/commonspace/object/tree/synctree/treeremotegetter.go @@ -2,7 +2,10 @@ package synctree import ( "context" + "errors" "fmt" + "time" + "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" "github.com/anyproto/any-sync/commonspace/object/tree/treestorage" @@ -11,7 +14,13 @@ import ( "github.com/anyproto/any-sync/net/rpc/rpcerr" "github.com/gogo/protobuf/proto" "go.uber.org/zap" - "time" +) + +var ( + newRequestTimeout = 1 * time.Second + + ErrRetryTimeout = errors.New("failed to retry request") + ErrNoResponsiblePeers = errors.New("no responsible peers") ) type treeRemoteGetter struct { @@ -57,36 +66,32 @@ func (t treeRemoteGetter) treeRequest(ctx context.Context, peerId string) (msg * return } -func (t treeRemoteGetter) treeRequestLoop(ctx context.Context, wait bool) (msg *treechangeproto.TreeSyncMessage, err error) { +func (t treeRemoteGetter) treeRequestLoop(ctx context.Context, retryTimeout time.Duration) (msg *treechangeproto.TreeSyncMessage, err error) { peerIdx := 0 -Loop: + reconnectCtx, cancel := context.WithTimeout(ctx, retryTimeout) + defer cancel() for { - select { - case <-ctx.Done(): - return nil, fmt.Errorf("waiting for object %s interrupted, context closed", t.treeId) - default: - break - } availablePeers, err := t.getPeers(ctx) if err != nil { - if !wait { + if retryTimeout == 0 { return nil, err } - select { - // wait for peers to connect - case <-time.After(1 * time.Second): - continue Loop - case <-ctx.Done(): - return nil, fmt.Errorf("waiting for object %s interrupted, context closed", t.treeId) - } + goto Wait } peerIdx = peerIdx % len(availablePeers) msg, err = t.treeRequest(ctx, availablePeers[peerIdx]) - if err == nil || !wait { + if err == nil || retryTimeout == 0 { return msg, err } peerIdx++ + Wait: + select { + case <-time.After(newRequestTimeout): + break + case <-reconnectCtx.Done(): + return nil, ErrRetryTimeout + } } } @@ -109,7 +114,7 @@ func (t treeRemoteGetter) getTree(ctx context.Context) (treeStorage treestorage. } isRemote = true - resp, err := t.treeRequestLoop(ctx, t.deps.WaitTreeRemoteSync) + resp, err := t.treeRequestLoop(ctx, t.deps.RetryTimeout) if err != nil { return } diff --git a/commonspace/object/tree/synctree/treeremotegetter_test.go b/commonspace/object/tree/synctree/treeremotegetter_test.go new file mode 100644 index 00000000..1594f491 --- /dev/null +++ b/commonspace/object/tree/synctree/treeremotegetter_test.go @@ -0,0 +1,142 @@ +package synctree + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/anyproto/any-sync/commonspace/object/tree/synctree/mock_synctree" + "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" + "github.com/anyproto/any-sync/commonspace/peermanager/mock_peermanager" + "github.com/anyproto/any-sync/commonspace/spacesyncproto" + "github.com/anyproto/any-sync/net/peer" + "github.com/anyproto/any-sync/net/peer/mock_peer" + "github.com/gogo/protobuf/proto" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" +) + +type treeRemoteGetterFixture struct { + ctrl *gomock.Controller + + treeGetter treeRemoteGetter + syncClientMock *mock_synctree.MockSyncClient + peerGetterMock *mock_peermanager.MockPeerManager +} + +func newTreeRemoteGetterFixture(t *testing.T) *treeRemoteGetterFixture { + ctrl := gomock.NewController(t) + syncClientMock := mock_synctree.NewMockSyncClient(ctrl) + peerGetterMock := mock_peermanager.NewMockPeerManager(ctrl) + treeGetter := treeRemoteGetter{ + deps: BuildDeps{ + SyncClient: syncClientMock, + PeerGetter: peerGetterMock, + }, + treeId: "treeId", + } + return &treeRemoteGetterFixture{ + ctrl: ctrl, + treeGetter: treeGetter, + syncClientMock: syncClientMock, + peerGetterMock: peerGetterMock, + } +} + +func (fx *treeRemoteGetterFixture) stop() { + fx.ctrl.Finish() +} + +func TestTreeRemoteGetter(t *testing.T) { + newRequestTimeout = 20 * time.Millisecond + retryTimeout := 2 * newRequestTimeout + ctx := context.Background() + peerId := "peerId" + treeRequest := &treechangeproto.TreeSyncMessage{} + treeResponse := &treechangeproto.TreeSyncMessage{ + RootChange: &treechangeproto.RawTreeChangeWithId{Id: "id"}, + } + marshalled, _ := proto.Marshal(treeResponse) + objectResponse := &spacesyncproto.ObjectSyncMessage{ + Payload: marshalled, + } + + t.Run("request works", func(t *testing.T) { + fx := newTreeRemoteGetterFixture(t) + defer fx.stop() + mockPeer := mock_peer.NewMockPeer(fx.ctrl) + mockPeer.EXPECT().Id().AnyTimes().Return(peerId) + fx.peerGetterMock.EXPECT().GetResponsiblePeers(ctx).Return([]peer.Peer{mockPeer}, nil) + fx.syncClientMock.EXPECT().CreateNewTreeRequest().Return(treeRequest) + fx.syncClientMock.EXPECT().SendRequest(ctx, peerId, fx.treeGetter.treeId, treeRequest).Return(objectResponse, nil) + resp, err := fx.treeGetter.treeRequestLoop(ctx, 0) + require.NoError(t, err) + require.Equal(t, "id", resp.RootChange.Id) + }) + + t.Run("request peerId from context", func(t *testing.T) { + fx := newTreeRemoteGetterFixture(t) + defer fx.stop() + ctx := peer.CtxWithPeerId(ctx, peerId) + fx.syncClientMock.EXPECT().CreateNewTreeRequest().Return(treeRequest) + fx.syncClientMock.EXPECT().SendRequest(ctx, peerId, fx.treeGetter.treeId, treeRequest).Return(objectResponse, nil) + resp, err := fx.treeGetter.treeRequestLoop(ctx, 0) + require.NoError(t, err) + require.Equal(t, "id", resp.RootChange.Id) + }) + + t.Run("request fails", func(t *testing.T) { + fx := newTreeRemoteGetterFixture(t) + defer fx.stop() + mockPeer := mock_peer.NewMockPeer(fx.ctrl) + mockPeer.EXPECT().Id().AnyTimes().Return(peerId) + fx.peerGetterMock.EXPECT().GetResponsiblePeers(ctx).Return([]peer.Peer{mockPeer}, nil) + fx.syncClientMock.EXPECT().CreateNewTreeRequest().Return(treeRequest) + fx.syncClientMock.EXPECT().SendRequest(ctx, peerId, fx.treeGetter.treeId, treeRequest).Return(nil, fmt.Errorf("failed")) + _, err := fx.treeGetter.treeRequestLoop(ctx, 0) + require.Error(t, err) + require.NotEqual(t, ErrRetryTimeout, err) + }) + + t.Run("retry request success", func(t *testing.T) { + fx := newTreeRemoteGetterFixture(t) + defer fx.stop() + mockPeer := mock_peer.NewMockPeer(fx.ctrl) + mockPeer.EXPECT().Id().AnyTimes().Return(peerId) + fx.peerGetterMock.EXPECT().GetResponsiblePeers(ctx).AnyTimes().Return([]peer.Peer{mockPeer}, nil) + fx.syncClientMock.EXPECT().CreateNewTreeRequest().AnyTimes().Return(treeRequest) + fx.syncClientMock.EXPECT().SendRequest(ctx, peerId, fx.treeGetter.treeId, treeRequest).Times(1).Return(nil, fmt.Errorf("some")) + fx.syncClientMock.EXPECT().SendRequest(ctx, peerId, fx.treeGetter.treeId, treeRequest).Times(1).Return(objectResponse, nil) + resp, err := fx.treeGetter.treeRequestLoop(ctx, retryTimeout) + require.NoError(t, err) + require.Equal(t, "id", resp.RootChange.Id) + }) + + t.Run("retry get peers success", func(t *testing.T) { + fx := newTreeRemoteGetterFixture(t) + defer fx.stop() + mockPeer := mock_peer.NewMockPeer(fx.ctrl) + mockPeer.EXPECT().Id().AnyTimes().Return(peerId) + fx.peerGetterMock.EXPECT().GetResponsiblePeers(ctx).Times(1).Return([]peer.Peer{}, nil) + fx.peerGetterMock.EXPECT().GetResponsiblePeers(ctx).Times(1).Return([]peer.Peer{mockPeer}, nil) + fx.syncClientMock.EXPECT().CreateNewTreeRequest().AnyTimes().Return(treeRequest) + fx.syncClientMock.EXPECT().SendRequest(ctx, peerId, fx.treeGetter.treeId, treeRequest).Times(1).Return(objectResponse, nil) + resp, err := fx.treeGetter.treeRequestLoop(ctx, retryTimeout) + require.NoError(t, err) + require.Equal(t, "id", resp.RootChange.Id) + }) + + t.Run("retry request fail", func(t *testing.T) { + fx := newTreeRemoteGetterFixture(t) + defer fx.stop() + treeRequest := &treechangeproto.TreeSyncMessage{} + mockPeer := mock_peer.NewMockPeer(fx.ctrl) + mockPeer.EXPECT().Id().AnyTimes().Return(peerId) + fx.peerGetterMock.EXPECT().GetResponsiblePeers(ctx).AnyTimes().Return([]peer.Peer{mockPeer}, nil) + fx.syncClientMock.EXPECT().CreateNewTreeRequest().AnyTimes().Return(treeRequest) + fx.syncClientMock.EXPECT().SendRequest(ctx, peerId, fx.treeGetter.treeId, treeRequest).AnyTimes().Return(nil, fmt.Errorf("some")) + _, err := fx.treeGetter.treeRequestLoop(ctx, retryTimeout) + require.Equal(t, ErrRetryTimeout, err) + }) +} diff --git a/commonspace/objecttreebuilder/treebuilder.go b/commonspace/objecttreebuilder/treebuilder.go index 058efe16..9b7f9ab0 100644 --- a/commonspace/objecttreebuilder/treebuilder.go +++ b/commonspace/objecttreebuilder/treebuilder.go @@ -4,6 +4,9 @@ package objecttreebuilder import ( "context" "errors" + "sync/atomic" + "time" + "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/app/logger" "github.com/anyproto/any-sync/commonspace/headsync" @@ -22,13 +25,12 @@ import ( "github.com/anyproto/any-sync/commonspace/syncstatus" "github.com/anyproto/any-sync/nodeconf" "go.uber.org/zap" - "sync/atomic" ) type BuildTreeOpts struct { - Listener updatelistener.UpdateListener - WaitTreeRemoteSync bool - TreeBuilder objecttree.BuildObjectTreeFunc + Listener updatelistener.UpdateListener + RetryTimeout time.Duration + TreeBuilder objecttree.BuildObjectTreeFunc } const CName = "common.commonspace.objecttreebuilder" @@ -110,18 +112,18 @@ func (t *treeBuilder) BuildTree(ctx context.Context, id string, opts BuildTreeOp treeBuilder = t.builder } deps := synctree.BuildDeps{ - SpaceId: t.spaceId, - SyncClient: t.syncClient, - Configuration: t.configuration, - HeadNotifiable: t.headsNotifiable, - Listener: opts.Listener, - AclList: t.aclList, - SpaceStorage: t.spaceStorage, - OnClose: t.onClose, - SyncStatus: t.syncStatus, - WaitTreeRemoteSync: opts.WaitTreeRemoteSync, - PeerGetter: t.peerManager, - BuildObjectTree: treeBuilder, + SpaceId: t.spaceId, + SyncClient: t.syncClient, + Configuration: t.configuration, + HeadNotifiable: t.headsNotifiable, + Listener: opts.Listener, + AclList: t.aclList, + SpaceStorage: t.spaceStorage, + OnClose: t.onClose, + SyncStatus: t.syncStatus, + RetryTimeout: opts.RetryTimeout, + PeerGetter: t.peerManager, + BuildObjectTree: treeBuilder, } t.treesUsed.Add(1) t.log.Debug("incrementing counter", zap.String("id", id), zap.Int32("trees", t.treesUsed.Load())) diff --git a/commonspace/requestmanager/requestmanager.go b/commonspace/requestmanager/requestmanager.go index d72ea394..ea7a2b05 100644 --- a/commonspace/requestmanager/requestmanager.go +++ b/commonspace/requestmanager/requestmanager.go @@ -2,6 +2,8 @@ package requestmanager import ( "context" + "sync" + "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/app/logger" "github.com/anyproto/any-sync/commonspace/objectsync" @@ -11,7 +13,6 @@ import ( "github.com/anyproto/any-sync/net/streampool" "go.uber.org/zap" "storj.io/drpc" - "sync" ) const CName = "common.commonspace.requestmanager" diff --git a/commonspace/settings/settings.go b/commonspace/settings/settings.go index eab41709..c993c715 100644 --- a/commonspace/settings/settings.go +++ b/commonspace/settings/settings.go @@ -2,6 +2,8 @@ package settings import ( "context" + "sync/atomic" + "github.com/anyproto/any-sync/accountservice" "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/commonspace/deletionstate" @@ -16,7 +18,6 @@ import ( "github.com/anyproto/any-sync/commonspace/spacestorage" "github.com/anyproto/any-sync/nodeconf" "go.uber.org/zap" - "sync/atomic" ) const CName = "common.commonspace.settings" @@ -61,8 +62,7 @@ func (s *settings) Init(a *app.App) (err error) { deps := Deps{ BuildFunc: func(ctx context.Context, id string, listener updatelistener.UpdateListener) (t synctree.SyncTree, err error) { res, err := s.treeBuilder.BuildTree(ctx, id, objecttreebuilder.BuildTreeOpts{ - Listener: listener, - WaitTreeRemoteSync: false, + Listener: listener, // space settings document should not have empty data TreeBuilder: objecttree.BuildObjectTree, }) From 5c884afcf1853d43b5fad6facd78d16dfed56f33 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Tue, 13 Jun 2023 15:22:46 +0200 Subject: [PATCH 051/123] Make error typed --- commonspace/object/tree/synctree/treeremotegetter.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/commonspace/object/tree/synctree/treeremotegetter.go b/commonspace/object/tree/synctree/treeremotegetter.go index 843a37b4..b592c24b 100644 --- a/commonspace/object/tree/synctree/treeremotegetter.go +++ b/commonspace/object/tree/synctree/treeremotegetter.go @@ -3,7 +3,6 @@ package synctree import ( "context" "errors" - "fmt" "time" "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" @@ -45,7 +44,7 @@ func (t treeRemoteGetter) getPeers(ctx context.Context) (peerIds []string, err e return } if len(respPeers) == 0 { - err = fmt.Errorf("no responsible peers") + err = ErrNoResponsiblePeers return } for _, p := range respPeers { From 6eda884686dc4c05a821ac5a3c7e2ee55a20cbe9 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Tue, 13 Jun 2023 15:26:42 +0200 Subject: [PATCH 052/123] Remove goto --- .../object/tree/synctree/treeremotegetter.go | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/commonspace/object/tree/synctree/treeremotegetter.go b/commonspace/object/tree/synctree/treeremotegetter.go index b592c24b..2687776c 100644 --- a/commonspace/object/tree/synctree/treeremotegetter.go +++ b/commonspace/object/tree/synctree/treeremotegetter.go @@ -75,16 +75,14 @@ func (t treeRemoteGetter) treeRequestLoop(ctx context.Context, retryTimeout time if retryTimeout == 0 { return nil, err } - goto Wait + } else { + peerIdx = peerIdx % len(availablePeers) + msg, err = t.treeRequest(ctx, availablePeers[peerIdx]) + if err == nil || retryTimeout == 0 { + return msg, err + } + peerIdx++ } - - peerIdx = peerIdx % len(availablePeers) - msg, err = t.treeRequest(ctx, availablePeers[peerIdx]) - if err == nil || retryTimeout == 0 { - return msg, err - } - peerIdx++ - Wait: select { case <-time.After(newRequestTimeout): break From c753da8defdaa5a738dbdda223da33ada26899aa Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Tue, 13 Jun 2023 15:30:10 +0200 Subject: [PATCH 053/123] client version to handshake --- net/peer/context.go | 14 +++ net/secureservice/credential.go | 35 ++++-- net/secureservice/credential_test.go | 8 +- net/secureservice/handshake/credential.go | 61 +++++---- .../handshake/credential_test.go | 87 ++++++------- net/secureservice/handshake/handshake.go | 8 +- .../handshake/handshakeproto/handshake.pb.go | 116 +++++++++++++----- .../handshakeproto/protos/handshake.proto | 1 + net/secureservice/secureservice.go | 10 +- 9 files changed, 219 insertions(+), 121 deletions(-) diff --git a/net/peer/context.go b/net/peer/context.go index ada3bab2..856f5cff 100644 --- a/net/peer/context.go +++ b/net/peer/context.go @@ -14,6 +14,7 @@ const ( contextKeyPeerId contextKey = iota contextKeyIdentity contextKeyPeerAddr + contextKeyPeerClientVersion ) var ( @@ -50,6 +51,19 @@ func CtxWithPeerAddr(ctx context.Context, addr string) context.Context { return context.WithValue(ctx, contextKeyPeerAddr, addr) } +// CtxPeerClientVersion returns peer client version +func CtxPeerClientVersion(ctx context.Context) string { + if p, ok := ctx.Value(contextKeyPeerClientVersion).(string); ok { + return p + } + return "" +} + +// CtxWithClientVersion sets peer clientVersion to the context +func CtxWithClientVersion(ctx context.Context, addr string) context.Context { + return context.WithValue(ctx, contextKeyPeerClientVersion, addr) +} + // CtxIdentity returns identity from context func CtxIdentity(ctx context.Context) ([]byte, error) { if identity, ok := ctx.Value(contextKeyIdentity).([]byte); ok { diff --git a/net/secureservice/credential.go b/net/secureservice/credential.go index 9d992430..b4c9bcc8 100644 --- a/net/secureservice/credential.go +++ b/net/secureservice/credential.go @@ -22,11 +22,15 @@ func (n noVerifyChecker) MakeCredentials(remotePeerId string) *handshakeproto.Cr return n.cred } -func (n noVerifyChecker) CheckCredential(remotePeerId string, cred *handshakeproto.Credentials) (identity []byte, err error) { +func (n noVerifyChecker) CheckCredential(remotePeerId string, cred *handshakeproto.Credentials) (result handshake.Result, err error) { if cred.Version != n.cred.Version { - return nil, handshake.ErrIncompatibleVersion + err = handshake.ErrIncompatibleVersion + return } - return nil, nil + return handshake.Result{ + ProtoVersion: cred.Version, + ClientVersion: cred.ClientVersion, + }, nil } func newPeerSignVerifier(protoVersion uint32, account *accountdata.AccountKeys) handshake.CredentialChecker { @@ -60,27 +64,36 @@ func (p *peerSignVerifier) MakeCredentials(remotePeerId string) *handshakeproto. } } -func (p *peerSignVerifier) CheckCredential(remotePeerId string, cred *handshakeproto.Credentials) (identity []byte, err error) { +func (p *peerSignVerifier) CheckCredential(remotePeerId string, cred *handshakeproto.Credentials) (result handshake.Result, err error) { if cred.Version != p.protoVersion { - return nil, handshake.ErrIncompatibleVersion + err = handshake.ErrIncompatibleVersion + return } if cred.Type != handshakeproto.CredentialsType_SignedPeerIds { - return nil, handshake.ErrSkipVerifyNotAllowed + err = handshake.ErrSkipVerifyNotAllowed + return } var msg = &handshakeproto.PayloadSignedPeerIds{} if err = msg.Unmarshal(cred.Payload); err != nil { - return nil, handshake.ErrUnexpectedPayload + err = handshake.ErrUnexpectedPayload + return } pubKey, err := crypto.UnmarshalEd25519PublicKeyProto(msg.Identity) if err != nil { - return nil, handshake.ErrInvalidCredentials + err = handshake.ErrInvalidCredentials + return } ok, err := pubKey.Verify([]byte((remotePeerId + p.account.PeerId)), msg.Sign) if err != nil { - return nil, err + return } if !ok { - return nil, handshake.ErrInvalidCredentials + err = handshake.ErrInvalidCredentials + return } - return msg.Identity, nil + return handshake.Result{ + Identity: msg.Identity, + ProtoVersion: cred.Version, + ClientVersion: cred.ClientVersion, + }, nil } diff --git a/net/secureservice/credential_test.go b/net/secureservice/credential_test.go index 50b24ece..067cb86d 100644 --- a/net/secureservice/credential_test.go +++ b/net/secureservice/credential_test.go @@ -23,13 +23,13 @@ func TestPeerSignVerifier_CheckCredential(t *testing.T) { cr1 := cc1.MakeCredentials(c1) cr2 := cc2.MakeCredentials(c2) - id1, err := cc1.CheckCredential(c1, cr2) + res, err := cc1.CheckCredential(c1, cr2) assert.NoError(t, err) - assert.Equal(t, identity2, id1) + assert.Equal(t, identity2, res.Identity) - id2, err := cc2.CheckCredential(c2, cr1) + res2, err := cc2.CheckCredential(c2, cr1) assert.NoError(t, err) - assert.Equal(t, identity1, id2) + assert.Equal(t, identity1, res2.Identity) _, err = cc1.CheckCredential(c1, cr1) assert.EqualError(t, err, handshake.ErrInvalidCredentials.Error()) diff --git a/net/secureservice/handshake/credential.go b/net/secureservice/handshake/credential.go index 8a4760a0..4ad46c51 100644 --- a/net/secureservice/handshake/credential.go +++ b/net/secureservice/handshake/credential.go @@ -6,30 +6,31 @@ import ( "io" ) -func OutgoingHandshake(ctx context.Context, conn io.ReadWriteCloser, peerId string, cc CredentialChecker) (identity []byte, err error) { +func OutgoingHandshake(ctx context.Context, conn io.ReadWriteCloser, peerId string, cc CredentialChecker) (result Result, err error) { if ctx == nil { ctx = context.Background() } h := newHandshake() done := make(chan struct{}) var ( - resIdentity []byte - resErr error + res Result + resErr error ) go func() { defer close(done) - resIdentity, resErr = outgoingHandshake(h, conn, peerId, cc) + res, resErr = outgoingHandshake(h, conn, peerId, cc) }() select { case <-done: - return resIdentity, resErr + return res, resErr case <-ctx.Done(): _ = conn.Close() - return nil, ctx.Err() + err = ctx.Err() + return } } -func outgoingHandshake(h *handshake, conn io.ReadWriteCloser, peerId string, cc CredentialChecker) (identity []byte, err error) { +func outgoingHandshake(h *handshake, conn io.ReadWriteCloser, peerId string, cc CredentialChecker) (result Result, err error) { defer h.release() h.conn = conn localCred := cc.MakeCredentials(peerId) @@ -44,58 +45,62 @@ func outgoingHandshake(h *handshake, conn io.ReadWriteCloser, peerId string, cc } if msg.ack != nil { if msg.ack.Error == handshakeproto.Error_InvalidCredentials { - return nil, ErrPeerDeclinedCredentials + err = ErrPeerDeclinedCredentials + return } - return nil, HandshakeError{e: msg.ack.Error} + err = HandshakeError{e: msg.ack.Error} + return } - if identity, err = cc.CheckCredential(peerId, msg.cred); err != nil { + if result, err = cc.CheckCredential(peerId, msg.cred); err != nil { h.tryWriteErrAndClose(err) return } if err = h.writeAck(handshakeproto.Error_Null); err != nil { h.tryWriteErrAndClose(err) - return nil, err + return } msg, err = h.readMsg(msgTypeAck) if err != nil { h.tryWriteErrAndClose(err) - return nil, err + return } if msg.ack.Error == handshakeproto.Error_Null { - return identity, nil + return result, nil } else { _ = h.conn.Close() - return nil, HandshakeError{e: msg.ack.Error} + err = HandshakeError{e: msg.ack.Error} + return } } -func IncomingHandshake(ctx context.Context, conn io.ReadWriteCloser, peerId string, cc CredentialChecker) (identity []byte, err error) { +func IncomingHandshake(ctx context.Context, conn io.ReadWriteCloser, peerId string, cc CredentialChecker) (result Result, err error) { if ctx == nil { ctx = context.Background() } h := newHandshake() done := make(chan struct{}) var ( - resIdentity []byte - resError error + res Result + resError error ) go func() { defer close(done) - resIdentity, resError = incomingHandshake(h, conn, peerId, cc) + res, resError = incomingHandshake(h, conn, peerId, cc) }() select { case <-done: - return resIdentity, resError + return res, resError case <-ctx.Done(): _ = conn.Close() - return nil, ctx.Err() + err = ctx.Err() + return } } -func incomingHandshake(h *handshake, conn io.ReadWriteCloser, peerId string, cc CredentialChecker) (identity []byte, err error) { +func incomingHandshake(h *handshake, conn io.ReadWriteCloser, peerId string, cc CredentialChecker) (result Result, err error) { defer h.release() h.conn = conn @@ -104,30 +109,32 @@ func incomingHandshake(h *handshake, conn io.ReadWriteCloser, peerId string, cc h.tryWriteErrAndClose(err) return } - if identity, err = cc.CheckCredential(peerId, msg.cred); err != nil { + if result, err = cc.CheckCredential(peerId, msg.cred); err != nil { h.tryWriteErrAndClose(err) return } if err = h.writeCredentials(cc.MakeCredentials(peerId)); err != nil { h.tryWriteErrAndClose(err) - return nil, err + return } msg, err = h.readMsg(msgTypeAck) if err != nil { h.tryWriteErrAndClose(err) - return nil, err + return } if msg.ack.Error != handshakeproto.Error_Null { if msg.ack.Error == handshakeproto.Error_InvalidCredentials { - return nil, ErrPeerDeclinedCredentials + err = ErrPeerDeclinedCredentials + return } - return nil, HandshakeError{e: msg.ack.Error} + err = HandshakeError{e: msg.ack.Error} + return } if err = h.writeAck(handshakeproto.Error_Null); err != nil { h.tryWriteErrAndClose(err) - return nil, err + return } return } diff --git a/net/secureservice/handshake/credential_test.go b/net/secureservice/handshake/credential_test.go index 49865848..fe6687a6 100644 --- a/net/secureservice/handshake/credential_test.go +++ b/net/secureservice/handshake/credential_test.go @@ -15,15 +15,19 @@ import ( ) var noVerifyChecker = &testCredChecker{ - makeCred: &handshakeproto.Credentials{Type: handshakeproto.CredentialsType_SkipVerify}, - checkCred: func(peerId string, cred *handshakeproto.Credentials) (identity []byte, err error) { - return []byte("identity"), nil + makeCred: &handshakeproto.Credentials{Type: handshakeproto.CredentialsType_SkipVerify, ClientVersion: "test:v1.0"}, + checkCred: func(peerId string, cred *handshakeproto.Credentials) (res Result, err error) { + return Result{ + Identity: []byte("identity"), + ProtoVersion: cred.Version, + ClientVersion: cred.ClientVersion, + }, nil }, } type handshakeRes struct { - identity []byte - err error + res Result + err error } func TestOutgoingHandshake(t *testing.T) { @@ -32,7 +36,7 @@ func TestOutgoingHandshake(t *testing.T) { var handshakeResCh = make(chan handshakeRes, 1) go func() { identity, err := OutgoingHandshake(nil, c1, "", noVerifyChecker) - handshakeResCh <- handshakeRes{identity: identity, err: err} + handshakeResCh <- handshakeRes{res: identity, err: err} }() h := newHandshake() h.conn = c2 @@ -50,7 +54,7 @@ func TestOutgoingHandshake(t *testing.T) { // send ack require.NoError(t, h.writeAck(handshakeproto.Error_Null)) res := <-handshakeResCh - assert.NotEmpty(t, res.identity) + assert.NotEmpty(t, res.res) assert.NoError(t, res.err) }) t.Run("write cred err", func(t *testing.T) { @@ -58,7 +62,7 @@ func TestOutgoingHandshake(t *testing.T) { var handshakeResCh = make(chan handshakeRes, 1) go func() { identity, err := OutgoingHandshake(nil, c1, "", noVerifyChecker) - handshakeResCh <- handshakeRes{identity: identity, err: err} + handshakeResCh <- handshakeRes{res: identity, err: err} }() _ = c2.Close() res := <-handshakeResCh @@ -69,7 +73,7 @@ func TestOutgoingHandshake(t *testing.T) { var handshakeResCh = make(chan handshakeRes, 1) go func() { identity, err := OutgoingHandshake(nil, c1, "", noVerifyChecker) - handshakeResCh <- handshakeRes{identity: identity, err: err} + handshakeResCh <- handshakeRes{res: identity, err: err} }() h := newHandshake() h.conn = c2 @@ -85,7 +89,7 @@ func TestOutgoingHandshake(t *testing.T) { var handshakeResCh = make(chan handshakeRes, 1) go func() { identity, err := OutgoingHandshake(nil, c1, "", noVerifyChecker) - handshakeResCh <- handshakeRes{identity: identity, err: err} + handshakeResCh <- handshakeRes{res: identity, err: err} }() h := newHandshake() h.conn = c2 @@ -101,7 +105,7 @@ func TestOutgoingHandshake(t *testing.T) { var handshakeResCh = make(chan handshakeRes, 1) go func() { identity, err := OutgoingHandshake(nil, c1, "", &testCredChecker{makeCred: noVerifyChecker.makeCred, checkErr: ErrInvalidCredentials}) - handshakeResCh <- handshakeRes{identity: identity, err: err} + handshakeResCh <- handshakeRes{res: identity, err: err} }() h := newHandshake() h.conn = c2 @@ -120,7 +124,7 @@ func TestOutgoingHandshake(t *testing.T) { var handshakeResCh = make(chan handshakeRes, 1) go func() { identity, err := OutgoingHandshake(nil, c1, "", noVerifyChecker) - handshakeResCh <- handshakeRes{identity: identity, err: err} + handshakeResCh <- handshakeRes{res: identity, err: err} }() h := newHandshake() h.conn = c2 @@ -138,7 +142,7 @@ func TestOutgoingHandshake(t *testing.T) { var handshakeResCh = make(chan handshakeRes, 1) go func() { identity, err := OutgoingHandshake(nil, c1, "", noVerifyChecker) - handshakeResCh <- handshakeRes{identity: identity, err: err} + handshakeResCh <- handshakeRes{res: identity, err: err} }() h := newHandshake() h.conn = c2 @@ -159,7 +163,7 @@ func TestOutgoingHandshake(t *testing.T) { var handshakeResCh = make(chan handshakeRes, 1) go func() { identity, err := OutgoingHandshake(nil, c1, "", noVerifyChecker) - handshakeResCh <- handshakeRes{identity: identity, err: err} + handshakeResCh <- handshakeRes{res: identity, err: err} }() h := newHandshake() h.conn = c2 @@ -172,9 +176,7 @@ func TestOutgoingHandshake(t *testing.T) { _, err = h.readMsg(msgTypeAck) require.NoError(t, err) // write cred instead ack - require.NoError(t, h.writeCredentials(noVerifyChecker.MakeCredentials(""))) - _, err = h.readMsg(msgTypeAck) - require.Error(t, err) + _ = h.writeCredentials(noVerifyChecker.MakeCredentials("")) res := <-handshakeResCh require.Error(t, res.err) }) @@ -183,7 +185,7 @@ func TestOutgoingHandshake(t *testing.T) { var handshakeResCh = make(chan handshakeRes, 1) go func() { identity, err := OutgoingHandshake(nil, c1, "", noVerifyChecker) - handshakeResCh <- handshakeRes{identity: identity, err: err} + handshakeResCh <- handshakeRes{res: identity, err: err} }() h := newHandshake() h.conn = c2 @@ -211,7 +213,7 @@ func TestOutgoingHandshake(t *testing.T) { var handshakeResCh = make(chan handshakeRes, 1) go func() { identity, err := OutgoingHandshake(ctx, c1, "", noVerifyChecker) - handshakeResCh <- handshakeRes{identity: identity, err: err} + handshakeResCh <- handshakeRes{res: identity, err: err} }() h := newHandshake() h.conn = c2 @@ -234,7 +236,7 @@ func TestIncomingHandshake(t *testing.T) { var handshakeResCh = make(chan handshakeRes, 1) go func() { identity, err := IncomingHandshake(nil, c1, "", noVerifyChecker) - handshakeResCh <- handshakeRes{identity: identity, err: err} + handshakeResCh <- handshakeRes{res: identity, err: err} }() h := newHandshake() h.conn = c2 @@ -252,7 +254,7 @@ func TestIncomingHandshake(t *testing.T) { require.NoError(t, err) assert.Equal(t, handshakeproto.Error_Null, msg.ack.Error) res := <-handshakeResCh - assert.NotEmpty(t, res.identity) + assert.NotEmpty(t, res.res) require.NoError(t, res.err) }) t.Run("write cred err", func(t *testing.T) { @@ -260,7 +262,7 @@ func TestIncomingHandshake(t *testing.T) { var handshakeResCh = make(chan handshakeRes, 1) go func() { identity, err := IncomingHandshake(nil, c1, "", noVerifyChecker) - handshakeResCh <- handshakeRes{identity: identity, err: err} + handshakeResCh <- handshakeRes{res: identity, err: err} }() _ = c2.Close() res := <-handshakeResCh @@ -271,7 +273,7 @@ func TestIncomingHandshake(t *testing.T) { var handshakeResCh = make(chan handshakeRes, 1) go func() { identity, err := IncomingHandshake(nil, c1, "", noVerifyChecker) - handshakeResCh <- handshakeRes{identity: identity, err: err} + handshakeResCh <- handshakeRes{res: identity, err: err} }() h := newHandshake() h.conn = c2 @@ -286,7 +288,7 @@ func TestIncomingHandshake(t *testing.T) { var handshakeResCh = make(chan handshakeRes, 1) go func() { identity, err := IncomingHandshake(nil, c1, "", noVerifyChecker) - handshakeResCh <- handshakeRes{identity: identity, err: err} + handshakeResCh <- handshakeRes{res: identity, err: err} }() h := newHandshake() h.conn = c2 @@ -300,7 +302,7 @@ func TestIncomingHandshake(t *testing.T) { var handshakeResCh = make(chan handshakeRes, 1) go func() { identity, err := IncomingHandshake(nil, c1, "", &testCredChecker{makeCred: noVerifyChecker.makeCred, checkErr: ErrInvalidCredentials}) - handshakeResCh <- handshakeRes{identity: identity, err: err} + handshakeResCh <- handshakeRes{res: identity, err: err} }() h := newHandshake() h.conn = c2 @@ -320,7 +322,7 @@ func TestIncomingHandshake(t *testing.T) { var handshakeResCh = make(chan handshakeRes, 1) go func() { identity, err := IncomingHandshake(nil, c1, "", &testCredChecker{makeCred: noVerifyChecker.makeCred, checkErr: ErrIncompatibleVersion}) - handshakeResCh <- handshakeRes{identity: identity, err: err} + handshakeResCh <- handshakeRes{res: identity, err: err} }() h := newHandshake() h.conn = c2 @@ -340,7 +342,7 @@ func TestIncomingHandshake(t *testing.T) { var handshakeResCh = make(chan handshakeRes, 1) go func() { identity, err := IncomingHandshake(nil, c1, "", noVerifyChecker) - handshakeResCh <- handshakeRes{identity: identity, err: err} + handshakeResCh <- handshakeRes{res: identity, err: err} }() h := newHandshake() h.conn = c2 @@ -350,7 +352,7 @@ func TestIncomingHandshake(t *testing.T) { _, err := h.readMsg(msgTypeCred) require.NoError(t, err) // write cred instead ack - require.NoError(t, h.writeCredentials(noVerifyChecker.MakeCredentials(""))) + _ = h.writeCredentials(noVerifyChecker.MakeCredentials("")) // expect EOF _, err = h.readMsg(msgTypeAck) require.Error(t, err) @@ -362,7 +364,7 @@ func TestIncomingHandshake(t *testing.T) { var handshakeResCh = make(chan handshakeRes, 1) go func() { identity, err := IncomingHandshake(nil, c1, "", noVerifyChecker) - handshakeResCh <- handshakeRes{identity: identity, err: err} + handshakeResCh <- handshakeRes{res: identity, err: err} }() h := newHandshake() h.conn = c2 @@ -381,7 +383,7 @@ func TestIncomingHandshake(t *testing.T) { var handshakeResCh = make(chan handshakeRes, 1) go func() { identity, err := IncomingHandshake(nil, c1, "", noVerifyChecker) - handshakeResCh <- handshakeRes{identity: identity, err: err} + handshakeResCh <- handshakeRes{res: identity, err: err} }() h := newHandshake() h.conn = c2 @@ -403,7 +405,7 @@ func TestIncomingHandshake(t *testing.T) { var handshakeResCh = make(chan handshakeRes, 1) go func() { identity, err := IncomingHandshake(nil, c1, "", noVerifyChecker) - handshakeResCh <- handshakeRes{identity: identity, err: err} + handshakeResCh <- handshakeRes{res: identity, err: err} }() h := newHandshake() h.conn = c2 @@ -425,7 +427,7 @@ func TestIncomingHandshake(t *testing.T) { var handshakeResCh = make(chan handshakeRes, 1) go func() { identity, err := IncomingHandshake(nil, c1, "", noVerifyChecker) - handshakeResCh <- handshakeRes{identity: identity, err: err} + handshakeResCh <- handshakeRes{res: identity, err: err} }() h := newHandshake() h.conn = c2 @@ -448,7 +450,7 @@ func TestIncomingHandshake(t *testing.T) { var handshakeResCh = make(chan handshakeRes, 1) go func() { identity, err := IncomingHandshake(ctx, c1, "", noVerifyChecker) - handshakeResCh <- handshakeRes{identity: identity, err: err} + handshakeResCh <- handshakeRes{res: identity, err: err} }() h := newHandshake() h.conn = c2 @@ -472,7 +474,7 @@ func TestNotAHandshakeMessage(t *testing.T) { var handshakeResCh = make(chan handshakeRes, 1) go func() { identity, err := IncomingHandshake(nil, c1, "", noVerifyChecker) - handshakeResCh <- handshakeRes{identity: identity, err: err} + handshakeResCh <- handshakeRes{res: identity, err: err} }() h := newHandshake() h.conn = c2 @@ -491,20 +493,20 @@ func TestEndToEnd(t *testing.T) { st := time.Now() go func() { identity, err := OutgoingHandshake(nil, c1, "", noVerifyChecker) - outResCh <- handshakeRes{identity: identity, err: err} + outResCh <- handshakeRes{res: identity, err: err} }() go func() { identity, err := IncomingHandshake(nil, c2, "", noVerifyChecker) - inResCh <- handshakeRes{identity: identity, err: err} + inResCh <- handshakeRes{res: identity, err: err} }() outRes := <-outResCh assert.NoError(t, outRes.err) - assert.NotEmpty(t, outRes.identity) + assert.NotEmpty(t, outRes.res) inRes := <-inResCh assert.NoError(t, inRes.err) - assert.NotEmpty(t, inRes.identity) + assert.NotEmpty(t, inRes.res) t.Log("dur", time.Since(st)) } @@ -548,7 +550,7 @@ func BenchmarkHandshake(b *testing.B) { type testCredChecker struct { makeCred *handshakeproto.Credentials - checkCred func(peerId string, cred *handshakeproto.Credentials) (identity []byte, err error) + checkCred func(peerId string, cred *handshakeproto.Credentials) (res Result, err error) checkErr error } @@ -556,14 +558,15 @@ func (t *testCredChecker) MakeCredentials(peerId string) *handshakeproto.Credent return t.makeCred } -func (t *testCredChecker) CheckCredential(peerId string, cred *handshakeproto.Credentials) (identity []byte, err error) { +func (t *testCredChecker) CheckCredential(peerId string, cred *handshakeproto.Credentials) (res Result, err error) { if t.checkErr != nil { - return nil, t.checkErr + err = t.checkErr + return } if t.checkCred != nil { return t.checkCred(peerId, cred) } - return nil, nil + return } func newConnPair(t require.TestingT) (sc1, sc2 *secConn) { diff --git a/net/secureservice/handshake/handshake.go b/net/secureservice/handshake/handshake.go index 42aa2a8c..8a8af38c 100644 --- a/net/secureservice/handshake/handshake.go +++ b/net/secureservice/handshake/handshake.go @@ -64,7 +64,13 @@ var handshakePool = &sync.Pool{New: func() any { type CredentialChecker interface { MakeCredentials(remotePeerId string) *handshakeproto.Credentials - CheckCredential(remotePeerId string, cred *handshakeproto.Credentials) (identity []byte, err error) + CheckCredential(remotePeerId string, cred *handshakeproto.Credentials) (result Result, err error) +} + +type Result struct { + Identity []byte + ProtoVersion uint32 + ClientVersion string } func newHandshake() *handshake { diff --git a/net/secureservice/handshake/handshakeproto/handshake.pb.go b/net/secureservice/handshake/handshakeproto/handshake.pb.go index e9d6dfcb..b632c376 100644 --- a/net/secureservice/handshake/handshakeproto/handshake.pb.go +++ b/net/secureservice/handshake/handshakeproto/handshake.pb.go @@ -115,9 +115,10 @@ func (ProtoType) EnumDescriptor() ([]byte, []int) { } type Credentials struct { - Type CredentialsType `protobuf:"varint,1,opt,name=type,proto3,enum=anyHandshake.CredentialsType" json:"type,omitempty"` - Payload []byte `protobuf:"bytes,2,opt,name=payload,proto3" json:"payload,omitempty"` - Version uint32 `protobuf:"varint,3,opt,name=version,proto3" json:"version,omitempty"` + Type CredentialsType `protobuf:"varint,1,opt,name=type,proto3,enum=anyHandshake.CredentialsType" json:"type,omitempty"` + Payload []byte `protobuf:"bytes,2,opt,name=payload,proto3" json:"payload,omitempty"` + Version uint32 `protobuf:"varint,3,opt,name=version,proto3" json:"version,omitempty"` + ClientVersion string `protobuf:"bytes,4,opt,name=clientVersion,proto3" json:"clientVersion,omitempty"` } func (m *Credentials) Reset() { *m = Credentials{} } @@ -174,6 +175,13 @@ func (m *Credentials) GetVersion() uint32 { return 0 } +func (m *Credentials) GetClientVersion() string { + if m != nil { + return m.ClientVersion + } + return "" +} + type PayloadSignedPeerIds struct { // account identity Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` @@ -331,35 +339,36 @@ func init() { } var fileDescriptor_60283fc75f020893 = []byte{ - // 439 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xcf, 0x6e, 0xd3, 0x40, - 0x10, 0xc6, 0xbd, 0x4d, 0xdc, 0x96, 0x21, 0x2d, 0xdb, 0x6d, 0x4a, 0x2d, 0x24, 0xac, 0x28, 0xa7, - 0x10, 0x89, 0x84, 0x7f, 0xe2, 0x1e, 0x9a, 0x22, 0x72, 0xa9, 0x22, 0x17, 0x7a, 0xe0, 0xb6, 0xf5, - 0x0e, 0xed, 0x2a, 0xcb, 0xda, 0xda, 0xdd, 0x86, 0xfa, 0x2d, 0x78, 0x14, 0x1e, 0x83, 0x63, 0x8f, - 0x1c, 0x51, 0xf2, 0x22, 0xc8, 0x9b, 0xa4, 0x71, 0x38, 0xf5, 0x62, 0xef, 0xcc, 0xfc, 0xc6, 0xdf, - 0x7c, 0xe3, 0x85, 0x81, 0x46, 0xd7, 0xb7, 0x98, 0xde, 0x18, 0xb4, 0x68, 0xa6, 0x32, 0xc5, 0xfe, - 0x35, 0xd7, 0xc2, 0x5e, 0xf3, 0x49, 0xe5, 0x94, 0x9b, 0xcc, 0x65, 0x7d, 0xff, 0xb4, 0xeb, 0x6c, - 0xcf, 0x27, 0x58, 0x83, 0xeb, 0xe2, 0xd3, 0x2a, 0xd7, 0x76, 0xf0, 0xf8, 0xc4, 0xa0, 0x40, 0xed, - 0x24, 0x57, 0x96, 0xbd, 0x86, 0xba, 0x2b, 0x72, 0x8c, 0x48, 0x8b, 0x74, 0xf6, 0xdf, 0x3c, 0xef, - 0x55, 0xd9, 0x5e, 0x05, 0xfc, 0x5c, 0xe4, 0x98, 0x78, 0x94, 0x45, 0xb0, 0x93, 0xf3, 0x42, 0x65, - 0x5c, 0x44, 0x5b, 0x2d, 0xd2, 0x69, 0x24, 0xab, 0xb0, 0xac, 0x4c, 0xd1, 0x58, 0x99, 0xe9, 0xa8, - 0xd6, 0x22, 0x9d, 0xbd, 0x64, 0x15, 0xb6, 0x3f, 0x42, 0x73, 0xbc, 0x80, 0xce, 0xe5, 0x95, 0x46, - 0x31, 0x46, 0x34, 0x23, 0x61, 0xd9, 0x33, 0xd8, 0x95, 0x5e, 0xc2, 0x15, 0x7e, 0x84, 0x46, 0x72, - 0x1f, 0x33, 0x06, 0x75, 0x2b, 0xaf, 0xf4, 0x52, 0xc4, 0x9f, 0xdb, 0xaf, 0xa0, 0x36, 0x48, 0x27, - 0xec, 0x05, 0x84, 0x68, 0x4c, 0x66, 0x96, 0x63, 0x1f, 0x6e, 0x8e, 0x7d, 0x5a, 0x96, 0x92, 0x05, - 0xd1, 0x7e, 0x0f, 0xe1, 0xd8, 0xaf, 0xe1, 0x25, 0x84, 0x7e, 0x1f, 0xcb, 0x9e, 0xe3, 0xcd, 0x1e, - 0xcf, 0x78, 0x93, 0x0b, 0xaa, 0xfb, 0x0e, 0x9e, 0xfc, 0x67, 0x9f, 0xed, 0x03, 0x9c, 0x4f, 0x64, - 0x7e, 0x81, 0x46, 0x7e, 0x2b, 0x68, 0xc0, 0x0e, 0x60, 0x6f, 0xc3, 0x0d, 0x25, 0xdd, 0x5f, 0x04, - 0x42, 0x2f, 0xcf, 0x76, 0xa1, 0x7e, 0x76, 0xa3, 0x14, 0x0d, 0xca, 0xb6, 0x2f, 0x1a, 0x6f, 0x73, - 0x4c, 0x1d, 0x0a, 0x4a, 0xd8, 0x53, 0x60, 0x23, 0x3d, 0xe5, 0x4a, 0x8a, 0x8a, 0x00, 0xdd, 0x62, - 0x47, 0x70, 0xb0, 0xe6, 0x96, 0xdb, 0xa2, 0x35, 0x16, 0x41, 0x73, 0xad, 0x7a, 0x96, 0xb9, 0x81, - 0x52, 0xd9, 0x0f, 0x14, 0xb4, 0xce, 0x9a, 0x40, 0x87, 0xc8, 0x85, 0x92, 0x1a, 0x4f, 0x6f, 0x53, - 0x44, 0x81, 0x82, 0x86, 0xec, 0x18, 0x0e, 0x47, 0x3a, 0xcd, 0xbe, 0xe7, 0xdc, 0xc9, 0x4b, 0x85, - 0x17, 0x8b, 0x3f, 0x40, 0xb7, 0xcb, 0xef, 0x57, 0x0b, 0xde, 0x31, 0xdd, 0xe9, 0x1e, 0xc1, 0xa3, - 0x7b, 0xf3, 0xe5, 0xd4, 0xc3, 0x64, 0x7c, 0x42, 0x83, 0x0f, 0xc3, 0xdf, 0xb3, 0x98, 0xdc, 0xcd, - 0x62, 0xf2, 0x77, 0x16, 0x93, 0x9f, 0xf3, 0x38, 0xb8, 0x9b, 0xc7, 0xc1, 0x9f, 0x79, 0x1c, 0x7c, - 0xed, 0x3e, 0xfc, 0x4a, 0x5e, 0x6e, 0xfb, 0xd7, 0xdb, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x53, - 0x32, 0xf7, 0x79, 0xc7, 0x02, 0x00, 0x00, + // 457 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0x4d, 0x6f, 0xd3, 0x40, + 0x10, 0xf5, 0x36, 0x71, 0x3f, 0x86, 0xa4, 0x6c, 0xb7, 0x29, 0xb5, 0x90, 0xb0, 0xa2, 0x88, 0x43, + 0x88, 0x44, 0xc2, 0x97, 0xb8, 0x87, 0xa6, 0x88, 0x5c, 0xaa, 0xc8, 0x85, 0x1e, 0xb8, 0x6d, 0xbd, + 0x43, 0xbb, 0xca, 0xb2, 0xb6, 0xd6, 0xdb, 0x50, 0xff, 0x0b, 0xce, 0xfc, 0x0a, 0x7e, 0x06, 0xc7, + 0x1e, 0x39, 0xa2, 0xe4, 0x8f, 0x20, 0x6f, 0x9c, 0xc6, 0xe1, 0xc4, 0xc5, 0xde, 0x99, 0xf7, 0x66, + 0xe7, 0xbd, 0x67, 0xc3, 0x50, 0xa3, 0x1d, 0x64, 0x18, 0xdf, 0x18, 0xcc, 0xd0, 0xcc, 0x64, 0x8c, + 0x83, 0x6b, 0xae, 0x45, 0x76, 0xcd, 0xa7, 0x95, 0x53, 0x6a, 0x12, 0x9b, 0x0c, 0xdc, 0x33, 0x5b, + 0x77, 0xfb, 0xae, 0xc1, 0x1a, 0x5c, 0xe7, 0x1f, 0x56, 0xbd, 0xce, 0x0f, 0x02, 0x0f, 0x4e, 0x0c, + 0x0a, 0xd4, 0x56, 0x72, 0x95, 0xb1, 0x97, 0x50, 0xb7, 0x79, 0x8a, 0x01, 0x69, 0x93, 0xee, 0xfe, + 0xab, 0x27, 0xfd, 0x2a, 0xb9, 0x5f, 0x21, 0x7e, 0xcc, 0x53, 0x8c, 0x1c, 0x95, 0x05, 0xb0, 0x93, + 0xf2, 0x5c, 0x25, 0x5c, 0x04, 0x5b, 0x6d, 0xd2, 0x6d, 0x44, 0xab, 0xb2, 0x40, 0x66, 0x68, 0x32, + 0x99, 0xe8, 0xa0, 0xd6, 0x26, 0xdd, 0x66, 0xb4, 0x2a, 0xd9, 0x53, 0x68, 0xc6, 0x4a, 0xa2, 0xb6, + 0x17, 0x25, 0x5e, 0x6f, 0x93, 0xee, 0x5e, 0xb4, 0xd9, 0xec, 0xbc, 0x87, 0xd6, 0x64, 0x79, 0xd5, + 0xb9, 0xbc, 0xd2, 0x28, 0x26, 0x88, 0x66, 0x2c, 0x32, 0xf6, 0x18, 0x76, 0xa5, 0x13, 0x62, 0x73, + 0x27, 0xb4, 0x11, 0xdd, 0xd7, 0x8c, 0x41, 0x3d, 0x93, 0x57, 0xba, 0x94, 0xe2, 0xce, 0x9d, 0x17, + 0x50, 0x1b, 0xc6, 0x53, 0xf6, 0x0c, 0x7c, 0x34, 0x26, 0x31, 0xa5, 0xb9, 0xc3, 0x4d, 0x73, 0xa7, + 0x05, 0x14, 0x2d, 0x19, 0x9d, 0xb7, 0xe0, 0x4f, 0x5c, 0x5a, 0xcf, 0xc1, 0x77, 0xb1, 0x95, 0x33, + 0xc7, 0x9b, 0x33, 0x8e, 0xe3, 0xa2, 0x58, 0xb2, 0x7a, 0x6f, 0xe0, 0xe1, 0x3f, 0x21, 0xb1, 0x7d, + 0x80, 0xf3, 0xa9, 0x4c, 0x2f, 0xd0, 0xc8, 0x2f, 0x39, 0xf5, 0xd8, 0x01, 0x34, 0x37, 0xdc, 0x50, + 0xd2, 0xfb, 0x49, 0xc0, 0x77, 0xeb, 0xd9, 0x2e, 0xd4, 0xcf, 0x6e, 0x94, 0xa2, 0x5e, 0x31, 0xf6, + 0x49, 0xe3, 0x6d, 0x8a, 0xb1, 0x45, 0x41, 0x09, 0x7b, 0x04, 0x6c, 0xac, 0x67, 0x5c, 0x49, 0x51, + 0x59, 0x40, 0xb7, 0xd8, 0x11, 0x1c, 0xac, 0x79, 0x65, 0x5a, 0xb4, 0xc6, 0x02, 0x68, 0xad, 0xb7, + 0x9e, 0x25, 0x76, 0xa8, 0x54, 0xf2, 0x0d, 0x05, 0xad, 0xb3, 0x16, 0xd0, 0x11, 0x72, 0xa1, 0xa4, + 0xc6, 0xd3, 0xdb, 0x18, 0x51, 0xa0, 0xa0, 0x3e, 0x3b, 0x86, 0xc3, 0xb1, 0x8e, 0x93, 0xaf, 0x29, + 0xb7, 0xf2, 0x52, 0x61, 0xf9, 0x05, 0xe8, 0x76, 0x71, 0x7f, 0x15, 0x70, 0x8e, 0xe9, 0x4e, 0xef, + 0x08, 0xf6, 0xee, 0xcd, 0x17, 0xaa, 0x47, 0xd1, 0xe4, 0x84, 0x7a, 0xef, 0x46, 0xbf, 0xe6, 0x21, + 0xb9, 0x9b, 0x87, 0xe4, 0xcf, 0x3c, 0x24, 0xdf, 0x17, 0xa1, 0x77, 0xb7, 0x08, 0xbd, 0xdf, 0x8b, + 0xd0, 0xfb, 0xdc, 0xfb, 0xff, 0x3f, 0xf7, 0x72, 0xdb, 0xbd, 0x5e, 0xff, 0x0d, 0x00, 0x00, 0xff, + 0xff, 0xe2, 0xfa, 0x40, 0x67, 0xee, 0x02, 0x00, 0x00, } func (m *Credentials) Marshal() (dAtA []byte, err error) { @@ -382,6 +391,13 @@ func (m *Credentials) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.ClientVersion) > 0 { + i -= len(m.ClientVersion) + copy(dAtA[i:], m.ClientVersion) + i = encodeVarintHandshake(dAtA, i, uint64(len(m.ClientVersion))) + i-- + dAtA[i] = 0x22 + } if m.Version != 0 { i = encodeVarintHandshake(dAtA, i, uint64(m.Version)) i-- @@ -522,6 +538,10 @@ func (m *Credentials) Size() (n int) { if m.Version != 0 { n += 1 + sovHandshake(uint64(m.Version)) } + l = len(m.ClientVersion) + if l > 0 { + n += 1 + l + sovHandshake(uint64(l)) + } return n } @@ -673,6 +693,38 @@ func (m *Credentials) Unmarshal(dAtA []byte) error { break } } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ClientVersion", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHandshake + } + 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 ErrInvalidLengthHandshake + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthHandshake + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ClientVersion = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipHandshake(dAtA[iNdEx:]) diff --git a/net/secureservice/handshake/handshakeproto/protos/handshake.proto b/net/secureservice/handshake/handshakeproto/protos/handshake.proto index 1ea66b28..87189e24 100644 --- a/net/secureservice/handshake/handshakeproto/protos/handshake.proto +++ b/net/secureservice/handshake/handshakeproto/protos/handshake.proto @@ -39,6 +39,7 @@ message Credentials { CredentialsType type = 1; bytes payload = 2; uint32 version = 3; + string clientVersion = 4; } enum CredentialsType { diff --git a/net/secureservice/secureservice.go b/net/secureservice/secureservice.go index 4487e9bc..842b04a7 100644 --- a/net/secureservice/secureservice.go +++ b/net/secureservice/secureservice.go @@ -99,13 +99,14 @@ func (s *secureService) SecureInbound(ctx context.Context, conn net.Conn) (cctx } func (s *secureService) HandshakeInbound(ctx context.Context, conn io.ReadWriteCloser, peerId string) (cctx context.Context, err error) { - identity, err := handshake.IncomingHandshake(ctx, conn, peerId, s.inboundChecker) + res, err := handshake.IncomingHandshake(ctx, conn, peerId, s.inboundChecker) if err != nil { return nil, err } cctx = context.Background() cctx = peer.CtxWithPeerId(cctx, peerId) - cctx = peer.CtxWithIdentity(cctx, identity) + cctx = peer.CtxWithIdentity(cctx, res.Identity) + cctx = peer.CtxWithClientVersion(cctx, res.ClientVersion) return } @@ -122,13 +123,14 @@ func (s *secureService) SecureOutbound(ctx context.Context, conn net.Conn) (cctx } else { checker = s.noVerifyChecker } - identity, err := handshake.OutgoingHandshake(ctx, sc, sc.RemotePeer().String(), checker) + res, err := handshake.OutgoingHandshake(ctx, sc, sc.RemotePeer().String(), checker) if err != nil { return nil, err } cctx = context.Background() cctx = peer.CtxWithPeerId(cctx, sc.RemotePeer().String()) - cctx = peer.CtxWithIdentity(cctx, identity) + cctx = peer.CtxWithIdentity(cctx, res.Identity) + cctx = peer.CtxWithClientVersion(cctx, res.ClientVersion) return cctx, nil } From 38090ee68fe25ad7f564206564ce9ef561ba7b21 Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Tue, 13 Jun 2023 15:32:46 +0200 Subject: [PATCH 054/123] provide client version to rpc log --- metric/log.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/metric/log.go b/metric/log.go index e854a82a..0fd487c2 100644 --- a/metric/log.go +++ b/metric/log.go @@ -31,6 +31,10 @@ func PeerId(val string) zap.Field { return zap.String("peerId", val) } +func PeerVersion(val string) zap.Field { + return zap.String("peerVersion", val) +} + func Identity(val string) zap.Field { return zap.String("identity", val) } @@ -61,5 +65,5 @@ func (m *metric) RequestLog(ctx context.Context, rpc string, fields ...zap.Field if ak != nil { acc = ak.Account() } - m.rpcLog.Info("", append(fields, m.appField, PeerId(peerId), Identity(acc), Method(rpc))...) + m.rpcLog.Info("", append(fields, m.appField, PeerId(peerId), Identity(acc), Method(rpc), PeerVersion(peer.CtxPeerClientVersion(ctx)))...) } From 0ca2fe5e7eb7cffa8be2140769d899d75748efb6 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Tue, 13 Jun 2023 15:36:23 +0200 Subject: [PATCH 055/123] Change naming --- commonspace/object/tree/synctree/treeremotegetter.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/commonspace/object/tree/synctree/treeremotegetter.go b/commonspace/object/tree/synctree/treeremotegetter.go index 2687776c..cbc2b0ad 100644 --- a/commonspace/object/tree/synctree/treeremotegetter.go +++ b/commonspace/object/tree/synctree/treeremotegetter.go @@ -67,7 +67,7 @@ func (t treeRemoteGetter) treeRequest(ctx context.Context, peerId string) (msg * func (t treeRemoteGetter) treeRequestLoop(ctx context.Context, retryTimeout time.Duration) (msg *treechangeproto.TreeSyncMessage, err error) { peerIdx := 0 - reconnectCtx, cancel := context.WithTimeout(ctx, retryTimeout) + retryCtx, cancel := context.WithTimeout(ctx, retryTimeout) defer cancel() for { availablePeers, err := t.getPeers(ctx) @@ -86,7 +86,7 @@ func (t treeRemoteGetter) treeRequestLoop(ctx context.Context, retryTimeout time select { case <-time.After(newRequestTimeout): break - case <-reconnectCtx.Done(): + case <-retryCtx.Done(): return nil, ErrRetryTimeout } } From be58956bec9d578094cba92bb099a951e2a9bf69 Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Tue, 13 Jun 2023 15:39:22 +0200 Subject: [PATCH 056/123] provide client version in secureservice --- net/secureservice/credential.go | 27 +++++++++++++++++---------- net/secureservice/credential_test.go | 8 ++++---- net/secureservice/secureservice.go | 4 ++-- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/net/secureservice/credential.go b/net/secureservice/credential.go index b4c9bcc8..5a5ac7d9 100644 --- a/net/secureservice/credential.go +++ b/net/secureservice/credential.go @@ -8,9 +8,13 @@ import ( "go.uber.org/zap" ) -func newNoVerifyChecker(protoVersion uint32) handshake.CredentialChecker { +func newNoVerifyChecker(protoVersion uint32, clientVersion string) handshake.CredentialChecker { return &noVerifyChecker{ - cred: &handshakeproto.Credentials{Type: handshakeproto.CredentialsType_SkipVerify, Version: protoVersion}, + cred: &handshakeproto.Credentials{ + Type: handshakeproto.CredentialsType_SkipVerify, + Version: protoVersion, + ClientVersion: clientVersion, + }, } } @@ -33,16 +37,18 @@ func (n noVerifyChecker) CheckCredential(remotePeerId string, cred *handshakepro }, nil } -func newPeerSignVerifier(protoVersion uint32, account *accountdata.AccountKeys) handshake.CredentialChecker { +func newPeerSignVerifier(protoVersion uint32, clientVersion string, account *accountdata.AccountKeys) handshake.CredentialChecker { return &peerSignVerifier{ - protoVersion: protoVersion, - account: account, + protoVersion: protoVersion, + clientVersion: clientVersion, + account: account, } } type peerSignVerifier struct { - protoVersion uint32 - account *accountdata.AccountKeys + protoVersion uint32 + clientVersion string + account *accountdata.AccountKeys } func (p *peerSignVerifier) MakeCredentials(remotePeerId string) *handshakeproto.Credentials { @@ -58,9 +64,10 @@ func (p *peerSignVerifier) MakeCredentials(remotePeerId string) *handshakeproto. } payload, _ := msg.Marshal() return &handshakeproto.Credentials{ - Type: handshakeproto.CredentialsType_SignedPeerIds, - Payload: payload, - Version: p.protoVersion, + Type: handshakeproto.CredentialsType_SignedPeerIds, + Payload: payload, + Version: p.protoVersion, + ClientVersion: p.clientVersion, } } diff --git a/net/secureservice/credential_test.go b/net/secureservice/credential_test.go index 067cb86d..78222c87 100644 --- a/net/secureservice/credential_test.go +++ b/net/secureservice/credential_test.go @@ -15,8 +15,8 @@ func TestPeerSignVerifier_CheckCredential(t *testing.T) { identity1, _ := a1.SignKey.GetPublic().Marshall() identity2, _ := a2.SignKey.GetPublic().Marshall() - cc1 := newPeerSignVerifier(0, a1) - cc2 := newPeerSignVerifier(0, a2) + cc1 := newPeerSignVerifier(0, "test:v1", a1) + cc2 := newPeerSignVerifier(0, "test:v1", a2) c1 := a2.PeerId c2 := a1.PeerId @@ -40,8 +40,8 @@ func TestIncompatibleVersion(t *testing.T) { a2 := newTestAccData(t) _, _ = a1.SignKey.GetPublic().Marshall() - cc1 := newPeerSignVerifier(0, a1) - cc2 := newPeerSignVerifier(1, a2) + cc1 := newPeerSignVerifier(0, "test:v1", a1) + cc2 := newPeerSignVerifier(1, "test:v1", a2) c1 := a2.PeerId c2 := a1.PeerId diff --git a/net/secureservice/secureservice.go b/net/secureservice/secureservice.go index 842b04a7..f5a1aa78 100644 --- a/net/secureservice/secureservice.go +++ b/net/secureservice/secureservice.go @@ -64,8 +64,8 @@ func (s *secureService) Init(a *app.App) (err error) { if s.key, err = crypto.UnmarshalEd25519PrivateKey(peerKey); err != nil { return } - s.noVerifyChecker = newNoVerifyChecker(s.protoVersion) - s.peerSignVerifier = newPeerSignVerifier(s.protoVersion, account.Account()) + s.noVerifyChecker = newNoVerifyChecker(s.protoVersion, a.VersionName()) + s.peerSignVerifier = newPeerSignVerifier(s.protoVersion, a.VersionName(), account.Account()) s.nodeconf = a.MustComponent(nodeconf.CName).(nodeconf.Service) From 060c6d12316e63060f73179218ca1ecca860a614 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Tue, 13 Jun 2023 18:14:13 +0200 Subject: [PATCH 057/123] Retry fail on treechangeproto.ErrGetTree --- .../object/tree/synctree/treeremotegetter.go | 15 +++++---------- .../object/tree/synctree/treeremotegetter_test.go | 12 ++++++++++++ 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/commonspace/object/tree/synctree/treeremotegetter.go b/commonspace/object/tree/synctree/treeremotegetter.go index cbc2b0ad..2c1476ae 100644 --- a/commonspace/object/tree/synctree/treeremotegetter.go +++ b/commonspace/object/tree/synctree/treeremotegetter.go @@ -78,7 +78,9 @@ func (t treeRemoteGetter) treeRequestLoop(ctx context.Context, retryTimeout time } else { peerIdx = peerIdx % len(availablePeers) msg, err = t.treeRequest(ctx, availablePeers[peerIdx]) - if err == nil || retryTimeout == 0 { + // if no error or it doesn't make sense to retry + err = rpcerr.Unwrap(err) + if err == nil || err == treechangeproto.ErrGetTree || retryTimeout == 0 { return msg, err } peerIdx++ @@ -115,18 +117,11 @@ func (t treeRemoteGetter) getTree(ctx context.Context) (treeStorage treestorage. if err != nil { return } - switch { - case resp.GetContent().GetErrorResponse() != nil: - errResp := resp.GetContent().GetErrorResponse() - err = rpcerr.Err(errResp.ErrCode) - return - case resp.GetContent().GetFullSyncResponse() == nil: + fullSyncResp := resp.GetContent().GetFullSyncResponse() + if fullSyncResp == nil { err = treechangeproto.ErrUnexpected return - default: - break } - fullSyncResp := resp.GetContent().GetFullSyncResponse() payload := treestorage.TreeStorageCreatePayload{ RootRawChange: resp.RootChange, diff --git a/commonspace/object/tree/synctree/treeremotegetter_test.go b/commonspace/object/tree/synctree/treeremotegetter_test.go index 1594f491..6b719e93 100644 --- a/commonspace/object/tree/synctree/treeremotegetter_test.go +++ b/commonspace/object/tree/synctree/treeremotegetter_test.go @@ -113,6 +113,18 @@ func TestTreeRemoteGetter(t *testing.T) { require.Equal(t, "id", resp.RootChange.Id) }) + t.Run("no retry request if error get tree", func(t *testing.T) { + fx := newTreeRemoteGetterFixture(t) + defer fx.stop() + mockPeer := mock_peer.NewMockPeer(fx.ctrl) + mockPeer.EXPECT().Id().AnyTimes().Return(peerId) + fx.peerGetterMock.EXPECT().GetResponsiblePeers(ctx).AnyTimes().Return([]peer.Peer{mockPeer}, nil) + fx.syncClientMock.EXPECT().CreateNewTreeRequest().AnyTimes().Return(treeRequest) + fx.syncClientMock.EXPECT().SendRequest(ctx, peerId, fx.treeGetter.treeId, treeRequest).Times(1).Return(nil, treechangeproto.ErrGetTree) + _, err := fx.treeGetter.treeRequestLoop(ctx, retryTimeout) + require.Equal(t, treechangeproto.ErrGetTree, err) + }) + t.Run("retry get peers success", func(t *testing.T) { fx := newTreeRemoteGetterFixture(t) defer fx.stop() From cc3da7e66b404bec5ea047e3b5ef0984faf817c7 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Tue, 13 Jun 2023 19:00:01 +0200 Subject: [PATCH 058/123] Simplify tree remote getter --- commonspace/object/tree/synctree/synctree.go | 1 - .../object/tree/synctree/treeremotegetter.go | 39 ++-------- .../tree/synctree/treeremotegetter_test.go | 75 +------------------ commonspace/objecttreebuilder/treebuilder.go | 7 +- commonspace/requestmanager/requestmanager.go | 2 + 5 files changed, 15 insertions(+), 109 deletions(-) diff --git a/commonspace/object/tree/synctree/synctree.go b/commonspace/object/tree/synctree/synctree.go index a21121bf..52c33ed5 100644 --- a/commonspace/object/tree/synctree/synctree.go +++ b/commonspace/object/tree/synctree/synctree.go @@ -71,7 +71,6 @@ type BuildDeps struct { SyncStatus syncstatus.StatusUpdater PeerGetter ResponsiblePeersGetter BuildObjectTree objecttree.BuildObjectTreeFunc - RetryTimeout time.Duration } func BuildSyncTreeOrGetRemote(ctx context.Context, id string, deps BuildDeps) (t SyncTree, err error) { diff --git a/commonspace/object/tree/synctree/treeremotegetter.go b/commonspace/object/tree/synctree/treeremotegetter.go index 2c1476ae..64cd1d9c 100644 --- a/commonspace/object/tree/synctree/treeremotegetter.go +++ b/commonspace/object/tree/synctree/treeremotegetter.go @@ -3,22 +3,17 @@ package synctree import ( "context" "errors" - "time" "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" "github.com/anyproto/any-sync/commonspace/object/tree/treestorage" "github.com/anyproto/any-sync/commonspace/spacestorage" "github.com/anyproto/any-sync/net/peer" - "github.com/anyproto/any-sync/net/rpc/rpcerr" "github.com/gogo/protobuf/proto" "go.uber.org/zap" ) var ( - newRequestTimeout = 1 * time.Second - - ErrRetryTimeout = errors.New("failed to retry request") ErrNoResponsiblePeers = errors.New("no responsible peers") ) @@ -65,33 +60,13 @@ func (t treeRemoteGetter) treeRequest(ctx context.Context, peerId string) (msg * return } -func (t treeRemoteGetter) treeRequestLoop(ctx context.Context, retryTimeout time.Duration) (msg *treechangeproto.TreeSyncMessage, err error) { - peerIdx := 0 - retryCtx, cancel := context.WithTimeout(ctx, retryTimeout) - defer cancel() - for { - availablePeers, err := t.getPeers(ctx) - if err != nil { - if retryTimeout == 0 { - return nil, err - } - } else { - peerIdx = peerIdx % len(availablePeers) - msg, err = t.treeRequest(ctx, availablePeers[peerIdx]) - // if no error or it doesn't make sense to retry - err = rpcerr.Unwrap(err) - if err == nil || err == treechangeproto.ErrGetTree || retryTimeout == 0 { - return msg, err - } - peerIdx++ - } - select { - case <-time.After(newRequestTimeout): - break - case <-retryCtx.Done(): - return nil, ErrRetryTimeout - } +func (t treeRemoteGetter) treeRequestLoop(ctx context.Context) (msg *treechangeproto.TreeSyncMessage, err error) { + availablePeers, err := t.getPeers(ctx) + if err != nil { + return } + // in future we will try to load from different peers + return t.treeRequest(ctx, availablePeers[0]) } func (t treeRemoteGetter) getTree(ctx context.Context) (treeStorage treestorage.TreeStorage, isRemote bool, err error) { @@ -113,7 +88,7 @@ func (t treeRemoteGetter) getTree(ctx context.Context) (treeStorage treestorage. } isRemote = true - resp, err := t.treeRequestLoop(ctx, t.deps.RetryTimeout) + resp, err := t.treeRequestLoop(ctx) if err != nil { return } diff --git a/commonspace/object/tree/synctree/treeremotegetter_test.go b/commonspace/object/tree/synctree/treeremotegetter_test.go index 6b719e93..60452b1a 100644 --- a/commonspace/object/tree/synctree/treeremotegetter_test.go +++ b/commonspace/object/tree/synctree/treeremotegetter_test.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "testing" - "time" "github.com/anyproto/any-sync/commonspace/object/tree/synctree/mock_synctree" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" @@ -49,8 +48,6 @@ func (fx *treeRemoteGetterFixture) stop() { } func TestTreeRemoteGetter(t *testing.T) { - newRequestTimeout = 20 * time.Millisecond - retryTimeout := 2 * newRequestTimeout ctx := context.Background() peerId := "peerId" treeRequest := &treechangeproto.TreeSyncMessage{} @@ -70,18 +67,7 @@ func TestTreeRemoteGetter(t *testing.T) { fx.peerGetterMock.EXPECT().GetResponsiblePeers(ctx).Return([]peer.Peer{mockPeer}, nil) fx.syncClientMock.EXPECT().CreateNewTreeRequest().Return(treeRequest) fx.syncClientMock.EXPECT().SendRequest(ctx, peerId, fx.treeGetter.treeId, treeRequest).Return(objectResponse, nil) - resp, err := fx.treeGetter.treeRequestLoop(ctx, 0) - require.NoError(t, err) - require.Equal(t, "id", resp.RootChange.Id) - }) - - t.Run("request peerId from context", func(t *testing.T) { - fx := newTreeRemoteGetterFixture(t) - defer fx.stop() - ctx := peer.CtxWithPeerId(ctx, peerId) - fx.syncClientMock.EXPECT().CreateNewTreeRequest().Return(treeRequest) - fx.syncClientMock.EXPECT().SendRequest(ctx, peerId, fx.treeGetter.treeId, treeRequest).Return(objectResponse, nil) - resp, err := fx.treeGetter.treeRequestLoop(ctx, 0) + resp, err := fx.treeGetter.treeRequestLoop(ctx) require.NoError(t, err) require.Equal(t, "id", resp.RootChange.Id) }) @@ -89,66 +75,13 @@ func TestTreeRemoteGetter(t *testing.T) { t.Run("request fails", func(t *testing.T) { fx := newTreeRemoteGetterFixture(t) defer fx.stop() + treeRequest := &treechangeproto.TreeSyncMessage{} mockPeer := mock_peer.NewMockPeer(fx.ctrl) mockPeer.EXPECT().Id().AnyTimes().Return(peerId) fx.peerGetterMock.EXPECT().GetResponsiblePeers(ctx).Return([]peer.Peer{mockPeer}, nil) fx.syncClientMock.EXPECT().CreateNewTreeRequest().Return(treeRequest) - fx.syncClientMock.EXPECT().SendRequest(ctx, peerId, fx.treeGetter.treeId, treeRequest).Return(nil, fmt.Errorf("failed")) - _, err := fx.treeGetter.treeRequestLoop(ctx, 0) - require.Error(t, err) - require.NotEqual(t, ErrRetryTimeout, err) - }) - - t.Run("retry request success", func(t *testing.T) { - fx := newTreeRemoteGetterFixture(t) - defer fx.stop() - mockPeer := mock_peer.NewMockPeer(fx.ctrl) - mockPeer.EXPECT().Id().AnyTimes().Return(peerId) - fx.peerGetterMock.EXPECT().GetResponsiblePeers(ctx).AnyTimes().Return([]peer.Peer{mockPeer}, nil) - fx.syncClientMock.EXPECT().CreateNewTreeRequest().AnyTimes().Return(treeRequest) - fx.syncClientMock.EXPECT().SendRequest(ctx, peerId, fx.treeGetter.treeId, treeRequest).Times(1).Return(nil, fmt.Errorf("some")) - fx.syncClientMock.EXPECT().SendRequest(ctx, peerId, fx.treeGetter.treeId, treeRequest).Times(1).Return(objectResponse, nil) - resp, err := fx.treeGetter.treeRequestLoop(ctx, retryTimeout) - require.NoError(t, err) - require.Equal(t, "id", resp.RootChange.Id) - }) - - t.Run("no retry request if error get tree", func(t *testing.T) { - fx := newTreeRemoteGetterFixture(t) - defer fx.stop() - mockPeer := mock_peer.NewMockPeer(fx.ctrl) - mockPeer.EXPECT().Id().AnyTimes().Return(peerId) - fx.peerGetterMock.EXPECT().GetResponsiblePeers(ctx).AnyTimes().Return([]peer.Peer{mockPeer}, nil) - fx.syncClientMock.EXPECT().CreateNewTreeRequest().AnyTimes().Return(treeRequest) - fx.syncClientMock.EXPECT().SendRequest(ctx, peerId, fx.treeGetter.treeId, treeRequest).Times(1).Return(nil, treechangeproto.ErrGetTree) - _, err := fx.treeGetter.treeRequestLoop(ctx, retryTimeout) - require.Equal(t, treechangeproto.ErrGetTree, err) - }) - - t.Run("retry get peers success", func(t *testing.T) { - fx := newTreeRemoteGetterFixture(t) - defer fx.stop() - mockPeer := mock_peer.NewMockPeer(fx.ctrl) - mockPeer.EXPECT().Id().AnyTimes().Return(peerId) - fx.peerGetterMock.EXPECT().GetResponsiblePeers(ctx).Times(1).Return([]peer.Peer{}, nil) - fx.peerGetterMock.EXPECT().GetResponsiblePeers(ctx).Times(1).Return([]peer.Peer{mockPeer}, nil) - fx.syncClientMock.EXPECT().CreateNewTreeRequest().AnyTimes().Return(treeRequest) - fx.syncClientMock.EXPECT().SendRequest(ctx, peerId, fx.treeGetter.treeId, treeRequest).Times(1).Return(objectResponse, nil) - resp, err := fx.treeGetter.treeRequestLoop(ctx, retryTimeout) - require.NoError(t, err) - require.Equal(t, "id", resp.RootChange.Id) - }) - - t.Run("retry request fail", func(t *testing.T) { - fx := newTreeRemoteGetterFixture(t) - defer fx.stop() - treeRequest := &treechangeproto.TreeSyncMessage{} - mockPeer := mock_peer.NewMockPeer(fx.ctrl) - mockPeer.EXPECT().Id().AnyTimes().Return(peerId) - fx.peerGetterMock.EXPECT().GetResponsiblePeers(ctx).AnyTimes().Return([]peer.Peer{mockPeer}, nil) - fx.syncClientMock.EXPECT().CreateNewTreeRequest().AnyTimes().Return(treeRequest) fx.syncClientMock.EXPECT().SendRequest(ctx, peerId, fx.treeGetter.treeId, treeRequest).AnyTimes().Return(nil, fmt.Errorf("some")) - _, err := fx.treeGetter.treeRequestLoop(ctx, retryTimeout) - require.Equal(t, ErrRetryTimeout, err) + _, err := fx.treeGetter.treeRequestLoop(ctx) + require.Error(t, err) }) } diff --git a/commonspace/objecttreebuilder/treebuilder.go b/commonspace/objecttreebuilder/treebuilder.go index 9b7f9ab0..640416a7 100644 --- a/commonspace/objecttreebuilder/treebuilder.go +++ b/commonspace/objecttreebuilder/treebuilder.go @@ -5,7 +5,6 @@ import ( "context" "errors" "sync/atomic" - "time" "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/app/logger" @@ -28,9 +27,8 @@ import ( ) type BuildTreeOpts struct { - Listener updatelistener.UpdateListener - RetryTimeout time.Duration - TreeBuilder objecttree.BuildObjectTreeFunc + Listener updatelistener.UpdateListener + TreeBuilder objecttree.BuildObjectTreeFunc } const CName = "common.commonspace.objecttreebuilder" @@ -121,7 +119,6 @@ func (t *treeBuilder) BuildTree(ctx context.Context, id string, opts BuildTreeOp SpaceStorage: t.spaceStorage, OnClose: t.onClose, SyncStatus: t.syncStatus, - RetryTimeout: opts.RetryTimeout, PeerGetter: t.peerManager, BuildObjectTree: treeBuilder, } diff --git a/commonspace/requestmanager/requestmanager.go b/commonspace/requestmanager/requestmanager.go index ea7a2b05..7a6dd019 100644 --- a/commonspace/requestmanager/requestmanager.go +++ b/commonspace/requestmanager/requestmanager.go @@ -10,6 +10,7 @@ import ( "github.com/anyproto/any-sync/commonspace/spacesyncproto" "github.com/anyproto/any-sync/net/peer" "github.com/anyproto/any-sync/net/pool" + "github.com/anyproto/any-sync/net/rpc/rpcerr" "github.com/anyproto/any-sync/net/streampool" "go.uber.org/zap" "storj.io/drpc" @@ -123,5 +124,6 @@ func (r *requestManager) doRequest(ctx context.Context, peerId string, msg *spac resp, err = cl.ObjectSync(ctx, msg) return err }) + err = rpcerr.Unwrap(err) return } From 69f2cb8b1d847f5479a62f088f76837fb4933dd5 Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Tue, 13 Jun 2023 19:02:50 +0200 Subject: [PATCH 059/123] app.VersionName fix any-sync version --- app/app.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/app.go b/app/app.go index ea374649..21f2f52c 100644 --- a/app/app.go +++ b/app/app.go @@ -89,7 +89,7 @@ func (app *App) VersionName() string { if app.versionName != "" { return app.versionName } - return AppName + ":" + GitSummary + "/any-sync:" + app.anySyncVersion + return AppName + ":" + GitSummary + "/any-sync:" + app.AnySyncVersion() } type Stat struct { From 31f001478319023a9e8ea92600e5aef781bf8a85 Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Tue, 13 Jun 2023 19:06:10 +0200 Subject: [PATCH 060/123] add peer addr to cctx --- net/transport/yamux/conn.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/transport/yamux/conn.go b/net/transport/yamux/conn.go index c752d22d..0013f2bb 100644 --- a/net/transport/yamux/conn.go +++ b/net/transport/yamux/conn.go @@ -3,6 +3,7 @@ package yamux import ( "context" "github.com/anyproto/any-sync/net/connutil" + "github.com/anyproto/any-sync/net/peer" "github.com/anyproto/any-sync/net/transport" "github.com/hashicorp/yamux" "net" @@ -10,6 +11,7 @@ import ( ) func NewMultiConn(cctx context.Context, luConn *connutil.LastUsageConn, addr string, sess *yamux.Session) transport.MultiConn { + cctx = peer.CtxWithPeerAddr(cctx, sess.RemoteAddr().String()) return &yamuxConn{ ctx: cctx, luConn: luConn, From d35ac55ee147fe3c1f9bc96ea37edc0a877411ca Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Wed, 14 Jun 2023 11:55:59 +0200 Subject: [PATCH 061/123] validate rpc method name --- metric/drpc.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/metric/drpc.go b/metric/drpc.go index b81ed863..23640a8c 100644 --- a/metric/drpc.go +++ b/metric/drpc.go @@ -2,8 +2,10 @@ package metric import ( "github.com/prometheus/client_golang/prometheus" + "go.uber.org/zap" "storj.io/drpc" "time" + "unicode/utf8" ) type prometheusDRPC struct { @@ -14,7 +16,11 @@ type prometheusDRPC struct { 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()) + if utf8.ValidString(rpc) { + ph.SummaryVec.WithLabelValues(rpc).Observe(time.Since(st).Seconds()) + } else { + log.WarnCtx(stream.Context(), "invalid rpc string", zap.String("rpc", rpc)) + } }() return ph.Handler.HandleRPC(stream, rpc) } From 646f7fbedcf3577410628de9aa9e295e9ead43ac Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Wed, 14 Jun 2023 12:01:52 +0200 Subject: [PATCH 062/123] remove mockgen from deps --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index 94227398..aa0fa75f 100644 --- a/Makefile +++ b/Makefile @@ -25,7 +25,6 @@ deps: go mod download go build -o deps storj.io/drpc/cmd/protoc-gen-go-drpc go build -o deps github.com/gogo/protobuf/protoc-gen-gogofaster - go build -o deps github.com/golang/mock/mockgen test: go test ./... --cover From 18716eebb42dc95d8175bb22a072f46e83ec8303 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Thu, 15 Jun 2023 13:08:03 +0200 Subject: [PATCH 063/123] Cancel on cache close --- app/ocache/entry.go | 18 +++++++++++++++++- app/ocache/ocache.go | 9 +++++++-- app/ocache/ocache_test.go | 19 +++++++++++++++++++ 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/app/ocache/entry.go b/app/ocache/entry.go index fbe60e26..f95af1cc 100644 --- a/app/ocache/entry.go +++ b/app/ocache/entry.go @@ -2,9 +2,10 @@ package ocache import ( "context" - "go.uber.org/zap" "sync" "time" + + "go.uber.org/zap" ) type entryState int @@ -25,6 +26,7 @@ type entry struct { value Object close chan struct{} mx sync.Mutex + cancel context.CancelFunc } func newEntry(id string, value Object, state entryState) *entry { @@ -49,6 +51,20 @@ func (e *entry) isClosing() bool { return e.state == entryStateClosed || e.state == entryStateClosing } +func (e *entry) setCancel(cancel context.CancelFunc) { + e.mx.Lock() + defer e.mx.Unlock() + e.cancel = cancel +} + +func (e *entry) cancelLoad() { + e.mx.Lock() + defer e.mx.Unlock() + if e.cancel != nil { + e.cancel() + } +} + func (e *entry) waitLoad(ctx context.Context, id string) (value Object, err error) { select { case <-ctx.Done(): diff --git a/app/ocache/ocache.go b/app/ocache/ocache.go index 4f130b89..c3bc9a0a 100644 --- a/app/ocache/ocache.go +++ b/app/ocache/ocache.go @@ -3,10 +3,11 @@ package ocache import ( "context" "errors" - "github.com/anyproto/any-sync/app/logger" - "go.uber.org/zap" "sync" "time" + + "github.com/anyproto/any-sync/app/logger" + "go.uber.org/zap" ) var ( @@ -157,7 +158,10 @@ func (c *oCache) Pick(ctx context.Context, id string) (value Object, err error) func (c *oCache) load(ctx context.Context, id string, e *entry) { defer close(e.load) + ctx, cancel := context.WithCancel(ctx) + e.setCancel(cancel) value, err := c.loadFunc(ctx, id) + cancel() c.mu.Lock() defer c.mu.Unlock() @@ -315,6 +319,7 @@ func (c *oCache) Close() (err error) { close(c.closeCh) var toClose []*entry for _, e := range c.data { + e.cancelLoad() toClose = append(toClose, e) } c.mu.Unlock() diff --git a/app/ocache/ocache_test.go b/app/ocache/ocache_test.go index d78345b0..85a9c551 100644 --- a/app/ocache/ocache_test.go +++ b/app/ocache/ocache_test.go @@ -386,6 +386,25 @@ func Test_OCache_Remove(t *testing.T) { }) } +func TestOCacheCancelWhenRemove(t *testing.T) { + c := New(func(ctx context.Context, id string) (value Object, err error) { + select { + case <-ctx.Done(): + return nil, ctx.Err() + } + }, WithTTL(time.Millisecond*10)) + stopLoad := make(chan struct{}) + var err error + go func() { + _, err = c.Get(context.TODO(), "id") + stopLoad <- struct{}{} + }() + time.Sleep(time.Millisecond * 10) + c.Close() + <-stopLoad + require.Equal(t, context.Canceled, err) +} + func TestOCacheFuzzy(t *testing.T) { t.Run("test many objects gc, get and remove simultaneously, close after", func(t *testing.T) { tryCloseIds := make(map[string]bool) From 16be33fc96cd27f73b2be9054d31e3771845cb22 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Mon, 19 Jun 2023 10:41:16 +0200 Subject: [PATCH 064/123] Change Add to TryAdd --- commonspace/object/tree/synctree/treesyncprotocol.go | 1 + net/streampool/stream.go | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/commonspace/object/tree/synctree/treesyncprotocol.go b/commonspace/object/tree/synctree/treesyncprotocol.go index be759259..d27d4e15 100644 --- a/commonspace/object/tree/synctree/treesyncprotocol.go +++ b/commonspace/object/tree/synctree/treesyncprotocol.go @@ -2,6 +2,7 @@ package synctree import ( "context" + "github.com/anyproto/any-sync/app/logger" "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" diff --git a/net/streampool/stream.go b/net/streampool/stream.go index 1d59af4b..ad75f24c 100644 --- a/net/streampool/stream.go +++ b/net/streampool/stream.go @@ -2,11 +2,12 @@ package streampool import ( "context" + "sync/atomic" + "github.com/anyproto/any-sync/app/logger" "github.com/cheggaaa/mb/v3" "go.uber.org/zap" "storj.io/drpc" - "sync/atomic" ) type stream struct { @@ -22,7 +23,7 @@ type stream struct { } func (sr *stream) write(msg drpc.Message) (err error) { - return sr.queue.Add(sr.stream.Context(), msg) + return sr.queue.TryAdd(sr.stream.Context(), msg) } func (sr *stream) readLoop() error { From a9889a6245630e0a8876bec416c26c8fe0edf85a Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Mon, 19 Jun 2023 11:10:56 +0200 Subject: [PATCH 065/123] TryAdd correctly --- net/streampool/stream.go | 2 +- net/streampool/streampool_test.go | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/net/streampool/stream.go b/net/streampool/stream.go index ad75f24c..2c4c959b 100644 --- a/net/streampool/stream.go +++ b/net/streampool/stream.go @@ -23,7 +23,7 @@ type stream struct { } func (sr *stream) write(msg drpc.Message) (err error) { - return sr.queue.TryAdd(sr.stream.Context(), msg) + return sr.queue.TryAdd(msg) } func (sr *stream) readLoop() error { diff --git a/net/streampool/streampool_test.go b/net/streampool/streampool_test.go index d4a05de3..30575019 100644 --- a/net/streampool/streampool_test.go +++ b/net/streampool/streampool_test.go @@ -2,18 +2,19 @@ package streampool import ( "fmt" + "sort" + "sync" + "sync/atomic" + "testing" + "time" + "github.com/anyproto/any-sync/net/peer" "github.com/anyproto/any-sync/net/rpc/rpctest" "github.com/anyproto/any-sync/net/streampool/testservice" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/net/context" - "sort" "storj.io/drpc" - "sync" - "sync/atomic" - "testing" - "time" ) var ctx = context.Background() From e9668c73a8b9194a156cc82f9dce476837269570 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Jun 2023 16:04:53 +0000 Subject: [PATCH 066/123] Bump github.com/libp2p/go-libp2p from 0.27.5 to 0.28.0 Bumps [github.com/libp2p/go-libp2p](https://github.com/libp2p/go-libp2p) from 0.27.5 to 0.28.0. - [Release notes](https://github.com/libp2p/go-libp2p/releases) - [Changelog](https://github.com/libp2p/go-libp2p/blob/master/CHANGELOG.md) - [Commits](https://github.com/libp2p/go-libp2p/compare/v0.27.5...v0.28.0) --- updated-dependencies: - dependency-name: github.com/libp2p/go-libp2p dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 13 +++---------- go.sum | 23 +++++++---------------- 2 files changed, 10 insertions(+), 26 deletions(-) diff --git a/go.mod b/go.mod index 96353770..11d26fac 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,7 @@ require ( github.com/ipfs/go-ipld-format v0.5.0 github.com/ipfs/go-merkledag v0.11.0 github.com/ipfs/go-unixfs v0.4.6 - github.com/libp2p/go-libp2p v0.27.5 + github.com/libp2p/go-libp2p v0.28.0 github.com/mr-tron/base58 v1.2.0 github.com/multiformats/go-multibase v0.2.0 github.com/multiformats/go-multihash v0.2.3 @@ -44,7 +44,6 @@ require ( require ( github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect - github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 // indirect @@ -56,9 +55,7 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect - github.com/huin/goupnp v1.2.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect @@ -75,20 +72,17 @@ require ( github.com/ipld/go-ipld-prime v0.20.0 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect - github.com/klauspost/compress v1.16.5 // indirect - github.com/klauspost/cpuid/v2 v2.2.4 // indirect + github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/miekg/dns v1.1.54 // indirect - github.com/minio/sha256-simd v1.0.0 // indirect + github.com/minio/sha256-simd v1.0.1 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/multiformats/go-multiaddr v0.9.0 // indirect github.com/multiformats/go-multicodec v0.9.0 // indirect github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect - github.com/onsi/ginkgo/v2 v2.9.7 // 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 @@ -97,7 +91,6 @@ require ( github.com/prometheus/common v0.44.0 // indirect github.com/prometheus/procfs v0.10.0 // indirect github.com/quic-go/quic-go v0.35.1 // indirect - github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/zeebo/errs v1.3.0 // indirect diff --git a/go.sum b/go.sum index bff0699f..51a95ad7 100644 --- a/go.sum +++ b/go.sum @@ -13,7 +13,6 @@ github.com/anyproto/go-slip21 v1.0.0 h1:CI7lUqTIwmPOEGVAj4jyNLoICvueh++0U2HoAi3m github.com/anyproto/go-slip21 v1.0.0/go.mod h1:gbIJt7HAdr5DuT4f2pFTKCBSUWYsm/fysHBNqgsuxT0= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= -github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= 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/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= @@ -65,7 +64,6 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8 github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs= -github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= 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= @@ -82,7 +80,6 @@ github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0Jr 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.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= -github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= 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.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= @@ -156,11 +153,9 @@ github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpR 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.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= -github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= -github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= -github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= +github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -171,13 +166,13 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 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-libp2p v0.27.5 h1:KwA7pXKXpz8hG6Cr1fMA7UkgleogcwQj0sxl5qquWRg= -github.com/libp2p/go-libp2p v0.27.5/go.mod h1:oMfQGTb9CHnrOuSM6yMmyK2lXz3qIhnkn2+oK3B1Y2g= +github.com/libp2p/go-libp2p v0.28.0 h1:zO8cY98nJiPzZpFv5w5gqqb8aVzt4ukQ0nVOSaaKhJ8= +github.com/libp2p/go-libp2p v0.28.0/go.mod h1:s3Xabc9LSwOcnv9UD4nORnXKTsWkPMkIMB/JIGXVnzk= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= -github.com/libp2p/go-nat v0.1.0 h1:MfVsH6DLcpa04Xr+p8hmVRG4juse0s3J8HyNWYHffXg= +github.com/libp2p/go-nat v0.2.0 h1:Tyz+bUFAYqGyJ/ppPPymMGbIgNRH+WqC5QrT5fKrrGk= github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= @@ -186,12 +181,11 @@ github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI= -github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= 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/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= +github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= 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= @@ -221,7 +215,6 @@ github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/n github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5 h1:BvoENQQU+fZ9uukda/RzCAL/191HHwJA5b13R6diVlY= github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss= -github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0= 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= @@ -245,7 +238,6 @@ github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8G github.com/quic-go/quic-go v0.35.1 h1:b0kzj6b/cQAf05cT0CkQubHM31wiA+xH3IBkxP62poo= github.com/quic-go/quic-go v0.35.1/go.mod h1:+4CVgVppm0FNjpG3UcX8Joi/frKOH7/ciD5yGcwOO1g= github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= -github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= @@ -350,7 +342,6 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc 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-20220520151302-bc2c85ada10a/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-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= From 1d4447f12644e2ffcca57415d9c9865e98d678aa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Jun 2023 16:05:09 +0000 Subject: [PATCH 067/123] Bump golang.org/x/net from 0.10.0 to 0.11.0 Bumps [golang.org/x/net](https://github.com/golang/net) from 0.10.0 to 0.11.0. - [Commits](https://github.com/golang/net/compare/v0.10.0...v0.11.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 6 +++--- go.sum | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index 96353770..b88c8dc1 100644 --- a/go.mod +++ b/go.mod @@ -35,9 +35,9 @@ require ( github.com/zeebo/blake3 v0.2.3 go.uber.org/atomic v1.11.0 go.uber.org/zap v1.24.0 - golang.org/x/crypto v0.9.0 + golang.org/x/crypto v0.10.0 golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 - golang.org/x/net v0.10.0 + golang.org/x/net v0.11.0 gopkg.in/yaml.v3 v3.0.1 storj.io/drpc v0.0.33 ) @@ -106,7 +106,7 @@ require ( go.uber.org/multierr v1.11.0 // indirect golang.org/x/image v0.6.0 // indirect golang.org/x/sync v0.2.0 // indirect - golang.org/x/sys v0.8.0 // indirect + golang.org/x/sys v0.9.0 // indirect golang.org/x/tools v0.9.3 // indirect google.golang.org/protobuf v1.30.0 // indirect lukechampine.com/blake3 v1.2.1 // indirect diff --git a/go.sum b/go.sum index bff0699f..81c16865 100644 --- a/go.sum +++ b/go.sum @@ -305,8 +305,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/image v0.6.0 h1:bR8b5okrPI3g/gyZakLZHeWxAR8Dn5CyxXv1hLH5g/4= @@ -328,8 +328,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= +golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/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= @@ -354,8 +354,8 @@ golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= +golang.org/x/sys v0.9.0/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/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -364,7 +364,7 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= 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-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= From d3636604d7f9ad62800f35d3b53de7e6a1b263c6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Jun 2023 16:05:27 +0000 Subject: [PATCH 068/123] Bump github.com/prometheus/client_golang from 1.15.1 to 1.16.0 Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.15.1 to 1.16.0. - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.15.1...v1.16.0) --- updated-dependencies: - dependency-name: github.com/prometheus/client_golang dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 96353770..d814eb7f 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( github.com/mr-tron/base58 v1.2.0 github.com/multiformats/go-multibase v0.2.0 github.com/multiformats/go-multihash v0.2.3 - github.com/prometheus/client_golang v1.15.1 + github.com/prometheus/client_golang v1.16.0 github.com/stretchr/testify v1.8.4 github.com/tyler-smith/go-bip39 v1.1.0 github.com/zeebo/blake3 v0.2.3 @@ -95,7 +95,7 @@ require ( github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e // indirect github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.44.0 // indirect - github.com/prometheus/procfs v0.10.0 // indirect + github.com/prometheus/procfs v0.10.1 // indirect github.com/quic-go/quic-go v0.35.1 // indirect github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect diff --git a/go.sum b/go.sum index bff0699f..0a5c4a98 100644 --- a/go.sum +++ b/go.sum @@ -231,14 +231,14 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 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/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI= -github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= +github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= +github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= -github.com/prometheus/procfs v0.10.0 h1:UkG7GPYkO4UZyLnyXjaWYcgOSONqwdBqFUT95ugmt6I= -github.com/prometheus/procfs v0.10.0/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= +github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= +github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc86Z5U= github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E= From 8e7df9eae5b1dfc07af2530e97b5eae27468f6be Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Tue, 20 Jun 2023 12:02:05 +0200 Subject: [PATCH 069/123] Sync updates --- .../tree/synctree/protocolintegration_test.go | 7 +- commonspace/object/tree/synctree/synctree.go | 17 +++- .../object/tree/synctree/synctreehandler.go | 90 +++++++++++++------ .../tree/synctree/synctreehandler_test.go | 90 +++++++++++-------- commonspace/objectsync/objectsync.go | 7 +- 5 files changed, 138 insertions(+), 73 deletions(-) diff --git a/commonspace/object/tree/synctree/protocolintegration_test.go b/commonspace/object/tree/synctree/protocolintegration_test.go index 944d6684..4b880c24 100644 --- a/commonspace/object/tree/synctree/protocolintegration_test.go +++ b/commonspace/object/tree/synctree/protocolintegration_test.go @@ -2,6 +2,10 @@ package synctree import ( "context" + "math/rand" + "testing" + "time" + "github.com/anyproto/any-sync/commonspace/object/accountdata" "github.com/anyproto/any-sync/commonspace/object/acl/list" "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" @@ -10,9 +14,6 @@ import ( "github.com/anyproto/any-sync/util/slice" "github.com/gogo/protobuf/proto" "github.com/stretchr/testify/require" - "math/rand" - "testing" - "time" ) func TestEmptyClientGetsFullHistory(t *testing.T) { diff --git a/commonspace/object/tree/synctree/synctree.go b/commonspace/object/tree/synctree/synctree.go index 52c33ed5..0d4712df 100644 --- a/commonspace/object/tree/synctree/synctree.go +++ b/commonspace/object/tree/synctree/synctree.go @@ -205,18 +205,27 @@ func (s *syncTree) Delete() (err error) { } func (s *syncTree) TryClose(objectTTL time.Duration) (bool, error) { - return true, s.Close() + if !s.TryLock() { + return false, nil + } + log.Debug("closing sync tree", zap.String("id", s.Id())) + return true, s.close() } func (s *syncTree) Close() (err error) { log.Debug("closing sync tree", zap.String("id", s.Id())) + s.Lock() + return s.close() +} + +func (s *syncTree) close() (err error) { + defer s.Unlock() defer func() { log.Debug("closed sync tree", zap.Error(err), zap.String("id", s.Id())) }() - s.Lock() - defer s.Unlock() if s.isClosed { - return ErrSyncTreeClosed + err = ErrSyncTreeClosed + return } s.onClose(s.Id()) s.isClosed = true diff --git a/commonspace/object/tree/synctree/synctreehandler.go b/commonspace/object/tree/synctree/synctreehandler.go index 154330f3..8f133c66 100644 --- a/commonspace/object/tree/synctree/synctreehandler.go +++ b/commonspace/object/tree/synctree/synctreehandler.go @@ -3,18 +3,21 @@ package synctree import ( "context" "errors" + "sync" + "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" "github.com/anyproto/any-sync/commonspace/objectsync/synchandler" "github.com/anyproto/any-sync/commonspace/spacesyncproto" "github.com/anyproto/any-sync/commonspace/syncstatus" + "github.com/anyproto/any-sync/util/slice" "github.com/gogo/protobuf/proto" - "sync" ) var ( ErrMessageIsRequest = errors.New("message is request") ErrMessageIsNotRequest = errors.New("message is not request") + ErrMoreThanOneRequest = errors.New("more than one request for same peer") ) type syncTreeHandler struct { @@ -22,21 +25,23 @@ type syncTreeHandler struct { syncClient SyncClient syncProtocol TreeSyncProtocol syncStatus syncstatus.StatusUpdater - handlerLock sync.Mutex spaceId string - queue ReceiveQueue + + handlerLock sync.Mutex + pendingRequests map[string]struct{} + heads []string } const maxQueueSize = 5 func newSyncTreeHandler(spaceId string, objTree objecttree.ObjectTree, syncClient SyncClient, syncStatus syncstatus.StatusUpdater) synchandler.SyncHandler { return &syncTreeHandler{ - objTree: objTree, - syncProtocol: newTreeSyncProtocol(spaceId, objTree, syncClient), - syncClient: syncClient, - syncStatus: syncStatus, - spaceId: spaceId, - queue: newReceiveQueue(maxQueueSize), + objTree: objTree, + syncProtocol: newTreeSyncProtocol(spaceId, objTree, syncClient), + syncClient: syncClient, + syncStatus: syncStatus, + spaceId: spaceId, + pendingRequests: make(map[string]struct{}), } } @@ -48,17 +53,35 @@ func (s *syncTreeHandler) HandleRequest(ctx context.Context, senderId string, re } fullSyncRequest := unmarshalled.GetContent().GetFullSyncRequest() if fullSyncRequest == nil { - err = ErrMessageIsNotRequest - return + return nil, ErrMessageIsNotRequest } - s.syncStatus.HeadsReceive(senderId, request.ObjectId, treechangeproto.GetHeads(unmarshalled)) + // setting pending requests + s.handlerLock.Lock() + _, exists := s.pendingRequests[senderId] + if exists { + s.handlerLock.Unlock() + return nil, ErrMoreThanOneRequest + } + s.pendingRequests[senderId] = struct{}{} + s.handlerLock.Unlock() + + response, err = s.handleRequest(ctx, senderId, fullSyncRequest) + + // removing pending requests + s.handlerLock.Lock() + delete(s.pendingRequests, senderId) + s.handlerLock.Unlock() + return +} + +func (s *syncTreeHandler) handleRequest(ctx context.Context, senderId string, fullSyncRequest *treechangeproto.TreeFullSyncRequest) (response *spacesyncproto.ObjectSyncMessage, err error) { s.objTree.Lock() defer s.objTree.Unlock() treeResp, err := s.syncProtocol.FullSyncRequest(ctx, senderId, fullSyncRequest) if err != nil { return } - response, err = MarshallTreeMessage(treeResp, s.spaceId, request.ObjectId, "") + response, err = MarshallTreeMessage(treeResp, s.spaceId, s.objTree.Id(), "") return } @@ -68,28 +91,41 @@ func (s *syncTreeHandler) HandleMessage(ctx context.Context, senderId string, ms if err != nil { return } - s.syncStatus.HeadsReceive(senderId, msg.ObjectId, treechangeproto.GetHeads(unmarshalled)) - - queueFull := s.queue.AddMessage(senderId, unmarshalled, msg.RequestId) - if queueFull { + heads := treechangeproto.GetHeads(unmarshalled) + s.syncStatus.HeadsReceive(senderId, msg.ObjectId, heads) + s.handlerLock.Lock() + // if the update has same heads then returning not to hang on a lock + if unmarshalled.GetContent().GetHeadUpdate() != nil && slice.UnsortedEquals(heads, s.heads) { + s.handlerLock.Unlock() return } - - return s.handleMessage(ctx, senderId) + s.handlerLock.Unlock() + return s.handleMessage(ctx, unmarshalled, senderId) } -func (s *syncTreeHandler) handleMessage(ctx context.Context, senderId string) (err error) { +func (s *syncTreeHandler) handleMessage(ctx context.Context, msg *treechangeproto.TreeSyncMessage, senderId string) (err error) { s.objTree.Lock() defer s.objTree.Unlock() - msg, _, err := s.queue.GetMessage(senderId) - if err != nil { - return - } + var ( + copyHeads = make([]string, 0, len(s.objTree.Heads())) + treeId = s.objTree.Id() + content = msg.GetContent() + ) - defer s.queue.ClearQueue(senderId) + // getting old heads + copyHeads = append(copyHeads, s.objTree.Heads()...) + defer func() { + // checking if something changed + if !slice.UnsortedEquals(copyHeads, s.objTree.Heads()) { + s.handlerLock.Lock() + defer s.handlerLock.Unlock() + s.heads = s.heads[:0] + for _, h := range s.objTree.Heads() { + s.heads = append(s.heads, h) + } + } + }() - treeId := s.objTree.Id() - content := msg.GetContent() switch { case content.GetHeadUpdate() != nil: var syncReq *treechangeproto.TreeSyncMessage diff --git a/commonspace/object/tree/synctree/synctreehandler_test.go b/commonspace/object/tree/synctree/synctreehandler_test.go index f03f5ff1..84f3b237 100644 --- a/commonspace/object/tree/synctree/synctreehandler_test.go +++ b/commonspace/object/tree/synctree/synctreehandler_test.go @@ -2,15 +2,15 @@ package synctree import ( "context" - "github.com/anyproto/any-sync/commonspace/object/tree/synctree/mock_synctree" - "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" - "github.com/stretchr/testify/require" "sync" "testing" "github.com/anyproto/any-sync/commonspace/object/tree/objecttree/mock_objecttree" + "github.com/anyproto/any-sync/commonspace/object/tree/synctree/mock_synctree" + "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" "github.com/anyproto/any-sync/commonspace/syncstatus" "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" ) type testObjTreeMock struct { @@ -52,7 +52,6 @@ type syncHandlerFixture struct { ctrl *gomock.Controller syncClientMock *mock_synctree.MockSyncClient objectTreeMock *testObjTreeMock - receiveQueueMock ReceiveQueue syncProtocolMock *mock_synctree.MockTreeSyncProtocol spaceId string senderId string @@ -67,20 +66,18 @@ func newSyncHandlerFixture(t *testing.T) *syncHandlerFixture { syncClientMock := mock_synctree.NewMockSyncClient(ctrl) syncProtocolMock := mock_synctree.NewMockTreeSyncProtocol(ctrl) spaceId := "spaceId" - receiveQueue := newReceiveQueue(5) syncHandler := &syncTreeHandler{ - objTree: objectTreeMock, - syncClient: syncClientMock, - syncProtocol: syncProtocolMock, - spaceId: spaceId, - queue: receiveQueue, - syncStatus: syncstatus.NewNoOpSyncStatus(), + objTree: objectTreeMock, + syncClient: syncClientMock, + syncProtocol: syncProtocolMock, + spaceId: spaceId, + syncStatus: syncstatus.NewNoOpSyncStatus(), + pendingRequests: map[string]struct{}{}, } return &syncHandlerFixture{ ctrl: ctrl, objectTreeMock: objectTreeMock, - receiveQueueMock: receiveQueue, syncProtocolMock: syncProtocolMock, syncClientMock: syncClientMock, syncHandler: syncHandler, @@ -97,38 +94,68 @@ func (fx *syncHandlerFixture) stop() { func TestSyncTreeHandler_HandleMessage(t *testing.T) { ctx := context.Background() - t.Run("handle head update message", func(t *testing.T) { + t.Run("handle head update message, heads not equal, request returned", func(t *testing.T) { fx := newSyncHandlerFixture(t) defer fx.stop() treeId := "treeId" chWithId := &treechangeproto.RawTreeChangeWithId{} - headUpdate := &treechangeproto.TreeHeadUpdate{} + headUpdate := &treechangeproto.TreeHeadUpdate{ + Heads: []string{"h3"}, + } treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "") syncReq := &treechangeproto.TreeSyncMessage{} + fx.syncHandler.heads = []string{"h2"} fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId) + fx.objectTreeMock.EXPECT().Heads().Times(2).Return([]string{"h2"}) + fx.objectTreeMock.EXPECT().Heads().Times(2).Return([]string{"h3"}) fx.syncProtocolMock.EXPECT().HeadUpdate(ctx, fx.senderId, gomock.Any()).Return(syncReq, nil) fx.syncClientMock.EXPECT().QueueRequest(fx.senderId, fx.treeId, syncReq).Return(nil) err := fx.syncHandler.HandleMessage(ctx, fx.senderId, objectMsg) require.NoError(t, err) + require.Equal(t, []string{"h3"}, fx.syncHandler.heads) }) - t.Run("handle head update message, empty sync request", func(t *testing.T) { + t.Run("handle head update message, heads equal", func(t *testing.T) { fx := newSyncHandlerFixture(t) defer fx.stop() treeId := "treeId" chWithId := &treechangeproto.RawTreeChangeWithId{} - headUpdate := &treechangeproto.TreeHeadUpdate{} + headUpdate := &treechangeproto.TreeHeadUpdate{ + Heads: []string{"h1"}, + } treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + fx.syncHandler.heads = []string{"h1"} fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId) + + err := fx.syncHandler.HandleMessage(ctx, fx.senderId, objectMsg) + require.NoError(t, err) + }) + + t.Run("handle head update message, empty sync request returned", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() + treeId := "treeId" + chWithId := &treechangeproto.RawTreeChangeWithId{} + headUpdate := &treechangeproto.TreeHeadUpdate{ + Heads: []string{"h3"}, + } + treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) + objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + + fx.syncHandler.heads = []string{"h2"} + fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId) + fx.objectTreeMock.EXPECT().Heads().Times(2).Return([]string{"h2"}) + fx.objectTreeMock.EXPECT().Heads().Times(2).Return([]string{"h3"}) fx.syncProtocolMock.EXPECT().HeadUpdate(ctx, fx.senderId, gomock.Any()).Return(nil, nil) err := fx.syncHandler.HandleMessage(ctx, fx.senderId, objectMsg) require.NoError(t, err) + require.Equal(t, []string{"h3"}, fx.syncHandler.heads) }) t.Run("handle full sync request returns error", func(t *testing.T) { @@ -136,11 +163,15 @@ func TestSyncTreeHandler_HandleMessage(t *testing.T) { defer fx.stop() treeId := "treeId" chWithId := &treechangeproto.RawTreeChangeWithId{} - fullRequest := &treechangeproto.TreeFullSyncRequest{} + fullRequest := &treechangeproto.TreeFullSyncRequest{ + Heads: []string{"h3"}, + } treeMsg := treechangeproto.WrapFullRequest(fullRequest, chWithId) objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + fx.syncHandler.heads = []string{"h2"} fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId) + fx.objectTreeMock.EXPECT().Heads().Times(3).Return([]string{"h2"}) err := fx.syncHandler.HandleMessage(ctx, fx.senderId, objectMsg) require.Equal(t, err, ErrMessageIsRequest) @@ -151,11 +182,16 @@ func TestSyncTreeHandler_HandleMessage(t *testing.T) { defer fx.stop() treeId := "treeId" chWithId := &treechangeproto.RawTreeChangeWithId{} - fullSyncResponse := &treechangeproto.TreeFullSyncResponse{} + fullSyncResponse := &treechangeproto.TreeFullSyncResponse{ + Heads: []string{"h3"}, + } treeMsg := treechangeproto.WrapFullResponse(fullSyncResponse, chWithId) objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + fx.syncHandler.heads = []string{"h2"} fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId) + fx.objectTreeMock.EXPECT().Heads().Times(2).Return([]string{"h2"}) + fx.objectTreeMock.EXPECT().Heads().Times(2).Return([]string{"h3"}) fx.syncProtocolMock.EXPECT().FullSyncResponse(ctx, fx.senderId, gomock.Any()).Return(nil) err := fx.syncHandler.HandleMessage(ctx, fx.senderId, objectMsg) @@ -184,24 +220,6 @@ func TestSyncTreeHandler_HandleRequest(t *testing.T) { require.NotNil(t, res) }) - t.Run("handle request", func(t *testing.T) { - fx := newSyncHandlerFixture(t) - defer fx.stop() - treeId := "treeId" - chWithId := &treechangeproto.RawTreeChangeWithId{} - fullRequest := &treechangeproto.TreeFullSyncRequest{} - treeMsg := treechangeproto.WrapFullRequest(fullRequest, chWithId) - objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "") - - syncResp := &treechangeproto.TreeSyncMessage{} - fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId) - fx.syncProtocolMock.EXPECT().FullSyncRequest(ctx, fx.senderId, gomock.Any()).Return(syncResp, nil) - - res, err := fx.syncHandler.HandleRequest(ctx, fx.senderId, objectMsg) - require.NoError(t, err) - require.NotNil(t, res) - }) - t.Run("handle other message", func(t *testing.T) { fx := newSyncHandlerFixture(t) defer fx.stop() diff --git a/commonspace/objectsync/objectsync.go b/commonspace/objectsync/objectsync.go index 0ec7f344..f8125aa8 100644 --- a/commonspace/objectsync/objectsync.go +++ b/commonspace/objectsync/objectsync.go @@ -4,6 +4,9 @@ package objectsync import ( "context" "fmt" + "sync/atomic" + "time" + "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" "github.com/anyproto/any-sync/commonspace/object/treemanager" @@ -13,8 +16,6 @@ import ( "github.com/anyproto/any-sync/util/multiqueue" "github.com/cheggaaa/mb/v3" "github.com/gogo/protobuf/proto" - "sync/atomic" - "time" "github.com/anyproto/any-sync/app/logger" "github.com/anyproto/any-sync/commonspace/object/syncobjectgetter" @@ -79,7 +80,7 @@ func (s *objectSync) Init(a *app.App) (err error) { } s.spaceIsDeleted = sharedData.SpaceIsDeleted s.spaceId = sharedData.SpaceId - s.handleQueue = multiqueue.New[HandleMessage](s.processHandleMessage, 100) + s.handleQueue = multiqueue.New[HandleMessage](s.processHandleMessage, 30) return nil } From fa178d7c26da611e806d7c73e3b4424595ecf392 Mon Sep 17 00:00:00 2001 From: Sergey Date: Wed, 21 Jun 2023 13:50:50 +0500 Subject: [PATCH 070/123] Add app.IterateComponents method. This method helps to create debugging HTTP handlers in Heart --- app/app.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/app.go b/app/app.go index 21f2f52c..2295cdbf 100644 --- a/app/app.go +++ b/app/app.go @@ -262,6 +262,14 @@ func (app *App) Start(ctx context.Context) (err error) { return } +func (app *App) IterateComponents(fn func(Component)) { + app.mu.RLock() + defer app.mu.RUnlock() + for _, s := range app.components { + fn(s) + } +} + func stackAllGoroutines() []byte { buf := make([]byte, 1024) for { From 4eb2245669887ca51304a72a942eaa22fd5ede31 Mon Sep 17 00:00:00 2001 From: Sergey Date: Wed, 21 Jun 2023 17:54:38 +0500 Subject: [PATCH 071/123] IterateComponents: Add test and comment --- app/app.go | 1 + app/app_test.go | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/app/app.go b/app/app.go index 2295cdbf..5aeda7f3 100644 --- a/app/app.go +++ b/app/app.go @@ -262,6 +262,7 @@ func (app *App) Start(ctx context.Context) (err error) { return } +// IterateComponents iterates over all registered components. It's safe for concurrent use. func (app *App) IterateComponents(fn func(Component)) { app.mu.RLock() defer app.mu.RUnlock() diff --git a/app/app_test.go b/app/app_test.go index 0c122b24..5882feab 100644 --- a/app/app_test.go +++ b/app/app_test.go @@ -55,6 +55,21 @@ func TestAppServiceRegistry(t *testing.T) { }) } +func TestApp_IterateComponents(t *testing.T) { + app := new(App) + + app.Register(newTestService(testTypeRunnable, "c1", nil, nil)) + app.Register(newTestService(testTypeRunnable, "r1", nil, nil)) + app.Register(newTestService(testTypeComponent, "s1", nil, nil)) + + var got []string + app.IterateComponents(func(s Component) { + got = append(got, s.Name()) + }) + + assert.ElementsMatch(t, []string{"c1", "r1", "s1"}, got) +} + func TestAppStart(t *testing.T) { t.Run("SuccessStartStop", func(t *testing.T) { app := new(App) From 718a5b04dc5c84405a09b7ea493781d95c9cf385 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Wed, 21 Jun 2023 19:42:12 +0200 Subject: [PATCH 072/123] Update proto --- commonfile/fileproto/file_drpc.pb.go | 2 +- .../object/acl/aclrecordproto/aclrecord.pb.go | 4622 ++++++++--------- .../acl/aclrecordproto/protos/aclrecord.proto | 127 +- commonspace/object/acl/list/aclstate.go | 87 +- commonspace/object/acl/list/models.go | 28 +- commonspace/object/acl/list/validator.go | 5 + .../object/tree/objecttree/objecttree.go | 8 +- .../tree/objecttree/objecttreevalidator.go | 12 +- .../spacesyncproto/spacesync_drpc.pb.go | 6 +- .../coordinatorproto/coordinator_drpc.pb.go | 2 +- net/peer/peer.go | 14 +- .../testservice/testservice_drpc.pb.go | 6 +- 12 files changed, 2426 insertions(+), 2493 deletions(-) create mode 100644 commonspace/object/acl/list/validator.go diff --git a/commonfile/fileproto/file_drpc.pb.go b/commonfile/fileproto/file_drpc.pb.go index a03c22cd..2f9ee69d 100644 --- a/commonfile/fileproto/file_drpc.pb.go +++ b/commonfile/fileproto/file_drpc.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-go-drpc. DO NOT EDIT. -// protoc-gen-go-drpc version: v0.0.33 +// protoc-gen-go-drpc version: v0.0.32 // source: commonfile/fileproto/protos/file.proto package fileproto diff --git a/commonspace/object/acl/aclrecordproto/aclrecord.pb.go b/commonspace/object/acl/aclrecordproto/aclrecord.pb.go index 6842e829..8d185378 100644 --- a/commonspace/object/acl/aclrecordproto/aclrecord.pb.go +++ b/commonspace/object/acl/aclrecordproto/aclrecord.pb.go @@ -22,24 +22,31 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +// AclUserPermissions contains different possible user roles type AclUserPermissions int32 const ( - AclUserPermissions_Admin AclUserPermissions = 0 - AclUserPermissions_Writer AclUserPermissions = 1 - AclUserPermissions_Reader AclUserPermissions = 2 + AclUserPermissions_None AclUserPermissions = 0 + AclUserPermissions_Owner AclUserPermissions = 1 + AclUserPermissions_Admin AclUserPermissions = 2 + AclUserPermissions_Writer AclUserPermissions = 3 + AclUserPermissions_Reader AclUserPermissions = 4 ) var AclUserPermissions_name = map[int32]string{ - 0: "Admin", - 1: "Writer", - 2: "Reader", + 0: "None", + 1: "Owner", + 2: "Admin", + 3: "Writer", + 4: "Reader", } var AclUserPermissions_value = map[string]int32{ - "Admin": 0, - "Writer": 1, - "Reader": 2, + "None": 0, + "Owner": 1, + "Admin": 2, + "Writer": 3, + "Reader": 4, } func (x AclUserPermissions) String() string { @@ -50,6 +57,7 @@ func (AclUserPermissions) EnumDescriptor() ([]byte, []int) { return fileDescriptor_c8e9f754f34e929b, []int{0} } +// RawAclRecord is a proto message containing the acl payload in bytes, signature of the account who added it and signature of the acceptor 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"` @@ -118,6 +126,7 @@ func (m *RawAclRecord) GetAcceptorSignature() []byte { return nil } +// RawAclRecordWithId is a raw record and the id for convenience 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"` @@ -170,12 +179,12 @@ func (m *RawAclRecordWithId) GetId() string { return "" } +// AclRecord is a record containing the acl data 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"` - ReadKeyId string `protobuf:"bytes,4,opt,name=readKeyId,proto3" json:"readKeyId,omitempty"` - Timestamp int64 `protobuf:"varint,5,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + Timestamp int64 `protobuf:"varint,4,opt,name=timestamp,proto3" json:"timestamp,omitempty"` } func (m *AclRecord) Reset() { *m = AclRecord{} } @@ -232,13 +241,6 @@ func (m *AclRecord) GetData() []byte { return nil } -func (m *AclRecord) GetReadKeyId() string { - if m != nil { - return m.ReadKeyId - } - return "" -} - func (m *AclRecord) GetTimestamp() int64 { if m != nil { return m.Timestamp @@ -246,6 +248,7 @@ func (m *AclRecord) GetTimestamp() int64 { return 0 } +// AclRoot is a root of access control list type AclRoot struct { Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` MasterKey []byte `protobuf:"bytes,2,opt,name=masterKey,proto3" json:"masterKey,omitempty"` @@ -330,14 +333,478 @@ func (m *AclRoot) GetIdentitySignature() []byte { return nil } +// AclAccountInvite contains the public invite key, the private part of which is sent to the user directly +type AclAccountInvite struct { + InviteKey []byte `protobuf:"bytes,1,opt,name=inviteKey,proto3" json:"inviteKey,omitempty"` +} + +func (m *AclAccountInvite) Reset() { *m = AclAccountInvite{} } +func (m *AclAccountInvite) String() string { return proto.CompactTextString(m) } +func (*AclAccountInvite) ProtoMessage() {} +func (*AclAccountInvite) Descriptor() ([]byte, []int) { + return fileDescriptor_c8e9f754f34e929b, []int{4} +} +func (m *AclAccountInvite) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AclAccountInvite) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AclAccountInvite.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 *AclAccountInvite) XXX_Merge(src proto.Message) { + xxx_messageInfo_AclAccountInvite.Merge(m, src) +} +func (m *AclAccountInvite) XXX_Size() int { + return m.Size() +} +func (m *AclAccountInvite) XXX_DiscardUnknown() { + xxx_messageInfo_AclAccountInvite.DiscardUnknown(m) +} + +var xxx_messageInfo_AclAccountInvite proto.InternalMessageInfo + +func (m *AclAccountInvite) GetInviteKey() []byte { + if m != nil { + return m.InviteKey + } + return nil +} + +// AclAccountRequestJoin contains the reference to the invite record and the data of the person who wants to join, confirmed by the private invite key +type AclAccountRequestJoin struct { + InviteIdentity []byte `protobuf:"bytes,1,opt,name=inviteIdentity,proto3" json:"inviteIdentity,omitempty"` + InviteRecordId string `protobuf:"bytes,2,opt,name=inviteRecordId,proto3" json:"inviteRecordId,omitempty"` + InviteIdentitySignature []byte `protobuf:"bytes,3,opt,name=inviteIdentitySignature,proto3" json:"inviteIdentitySignature,omitempty"` +} + +func (m *AclAccountRequestJoin) Reset() { *m = AclAccountRequestJoin{} } +func (m *AclAccountRequestJoin) String() string { return proto.CompactTextString(m) } +func (*AclAccountRequestJoin) ProtoMessage() {} +func (*AclAccountRequestJoin) Descriptor() ([]byte, []int) { + return fileDescriptor_c8e9f754f34e929b, []int{5} +} +func (m *AclAccountRequestJoin) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AclAccountRequestJoin) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AclAccountRequestJoin.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 *AclAccountRequestJoin) XXX_Merge(src proto.Message) { + xxx_messageInfo_AclAccountRequestJoin.Merge(m, src) +} +func (m *AclAccountRequestJoin) XXX_Size() int { + return m.Size() +} +func (m *AclAccountRequestJoin) XXX_DiscardUnknown() { + xxx_messageInfo_AclAccountRequestJoin.DiscardUnknown(m) +} + +var xxx_messageInfo_AclAccountRequestJoin proto.InternalMessageInfo + +func (m *AclAccountRequestJoin) GetInviteIdentity() []byte { + if m != nil { + return m.InviteIdentity + } + return nil +} + +func (m *AclAccountRequestJoin) GetInviteRecordId() string { + if m != nil { + return m.InviteRecordId + } + return "" +} + +func (m *AclAccountRequestJoin) GetInviteIdentitySignature() []byte { + if m != nil { + return m.InviteIdentitySignature + } + return nil +} + +// AclAccountRequestAccept contains the reference to join record and all read keys, encrypted with the identity of the requestor +type AclAccountRequestAccept struct { + Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` + RequestRecordId string `protobuf:"bytes,2,opt,name=requestRecordId,proto3" json:"requestRecordId,omitempty"` + EncryptedReadKeys []byte `protobuf:"bytes,3,opt,name=encryptedReadKeys,proto3" json:"encryptedReadKeys,omitempty"` +} + +func (m *AclAccountRequestAccept) Reset() { *m = AclAccountRequestAccept{} } +func (m *AclAccountRequestAccept) String() string { return proto.CompactTextString(m) } +func (*AclAccountRequestAccept) ProtoMessage() {} +func (*AclAccountRequestAccept) Descriptor() ([]byte, []int) { + return fileDescriptor_c8e9f754f34e929b, []int{6} +} +func (m *AclAccountRequestAccept) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AclAccountRequestAccept) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AclAccountRequestAccept.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 *AclAccountRequestAccept) XXX_Merge(src proto.Message) { + xxx_messageInfo_AclAccountRequestAccept.Merge(m, src) +} +func (m *AclAccountRequestAccept) XXX_Size() int { + return m.Size() +} +func (m *AclAccountRequestAccept) XXX_DiscardUnknown() { + xxx_messageInfo_AclAccountRequestAccept.DiscardUnknown(m) +} + +var xxx_messageInfo_AclAccountRequestAccept proto.InternalMessageInfo + +func (m *AclAccountRequestAccept) GetIdentity() []byte { + if m != nil { + return m.Identity + } + return nil +} + +func (m *AclAccountRequestAccept) GetRequestRecordId() string { + if m != nil { + return m.RequestRecordId + } + return "" +} + +func (m *AclAccountRequestAccept) GetEncryptedReadKeys() []byte { + if m != nil { + return m.EncryptedReadKeys + } + return nil +} + +// AclAccountInviteRevoke revokes the invite record +type AclAccountInviteRevoke struct { + InviteRecordId string `protobuf:"bytes,1,opt,name=inviteRecordId,proto3" json:"inviteRecordId,omitempty"` +} + +func (m *AclAccountInviteRevoke) Reset() { *m = AclAccountInviteRevoke{} } +func (m *AclAccountInviteRevoke) String() string { return proto.CompactTextString(m) } +func (*AclAccountInviteRevoke) ProtoMessage() {} +func (*AclAccountInviteRevoke) Descriptor() ([]byte, []int) { + return fileDescriptor_c8e9f754f34e929b, []int{7} +} +func (m *AclAccountInviteRevoke) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AclAccountInviteRevoke) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AclAccountInviteRevoke.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 *AclAccountInviteRevoke) XXX_Merge(src proto.Message) { + xxx_messageInfo_AclAccountInviteRevoke.Merge(m, src) +} +func (m *AclAccountInviteRevoke) XXX_Size() int { + return m.Size() +} +func (m *AclAccountInviteRevoke) XXX_DiscardUnknown() { + xxx_messageInfo_AclAccountInviteRevoke.DiscardUnknown(m) +} + +var xxx_messageInfo_AclAccountInviteRevoke proto.InternalMessageInfo + +func (m *AclAccountInviteRevoke) GetInviteRecordId() string { + if m != nil { + return m.InviteRecordId + } + return "" +} + +// AclReadKeys are all read keys in Acl +type AclReadKeys struct { + ReadKey [][]byte `protobuf:"bytes,1,rep,name=readKey,proto3" json:"readKey,omitempty"` +} + +func (m *AclReadKeys) Reset() { *m = AclReadKeys{} } +func (m *AclReadKeys) String() string { return proto.CompactTextString(m) } +func (*AclReadKeys) ProtoMessage() {} +func (*AclReadKeys) Descriptor() ([]byte, []int) { + return fileDescriptor_c8e9f754f34e929b, []int{8} +} +func (m *AclReadKeys) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AclReadKeys) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AclReadKeys.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 *AclReadKeys) XXX_Merge(src proto.Message) { + xxx_messageInfo_AclReadKeys.Merge(m, src) +} +func (m *AclReadKeys) XXX_Size() int { + return m.Size() +} +func (m *AclReadKeys) XXX_DiscardUnknown() { + xxx_messageInfo_AclReadKeys.DiscardUnknown(m) +} + +var xxx_messageInfo_AclReadKeys proto.InternalMessageInfo + +func (m *AclReadKeys) GetReadKey() [][]byte { + if m != nil { + return m.ReadKey + } + return nil +} + +// AclEncryptedReadKeys are all keys for specific identity +type AclEncryptedReadKeys struct { + Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` + EncryptedReadKeys []byte `protobuf:"bytes,2,opt,name=encryptedReadKeys,proto3" json:"encryptedReadKeys,omitempty"` +} + +func (m *AclEncryptedReadKeys) Reset() { *m = AclEncryptedReadKeys{} } +func (m *AclEncryptedReadKeys) String() string { return proto.CompactTextString(m) } +func (*AclEncryptedReadKeys) ProtoMessage() {} +func (*AclEncryptedReadKeys) Descriptor() ([]byte, []int) { + return fileDescriptor_c8e9f754f34e929b, []int{9} +} +func (m *AclEncryptedReadKeys) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AclEncryptedReadKeys) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AclEncryptedReadKeys.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 *AclEncryptedReadKeys) XXX_Merge(src proto.Message) { + xxx_messageInfo_AclEncryptedReadKeys.Merge(m, src) +} +func (m *AclEncryptedReadKeys) XXX_Size() int { + return m.Size() +} +func (m *AclEncryptedReadKeys) XXX_DiscardUnknown() { + xxx_messageInfo_AclEncryptedReadKeys.DiscardUnknown(m) +} + +var xxx_messageInfo_AclEncryptedReadKeys proto.InternalMessageInfo + +func (m *AclEncryptedReadKeys) GetIdentity() []byte { + if m != nil { + return m.Identity + } + return nil +} + +func (m *AclEncryptedReadKeys) GetEncryptedReadKeys() []byte { + if m != nil { + return m.EncryptedReadKeys + } + return nil +} + +// AclAccountPermissionChange changes permissions of specific account +type AclAccountPermissionChange 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 *AclAccountPermissionChange) Reset() { *m = AclAccountPermissionChange{} } +func (m *AclAccountPermissionChange) String() string { return proto.CompactTextString(m) } +func (*AclAccountPermissionChange) ProtoMessage() {} +func (*AclAccountPermissionChange) Descriptor() ([]byte, []int) { + return fileDescriptor_c8e9f754f34e929b, []int{10} +} +func (m *AclAccountPermissionChange) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AclAccountPermissionChange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AclAccountPermissionChange.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 *AclAccountPermissionChange) XXX_Merge(src proto.Message) { + xxx_messageInfo_AclAccountPermissionChange.Merge(m, src) +} +func (m *AclAccountPermissionChange) XXX_Size() int { + return m.Size() +} +func (m *AclAccountPermissionChange) XXX_DiscardUnknown() { + xxx_messageInfo_AclAccountPermissionChange.DiscardUnknown(m) +} + +var xxx_messageInfo_AclAccountPermissionChange proto.InternalMessageInfo + +func (m *AclAccountPermissionChange) GetIdentity() []byte { + if m != nil { + return m.Identity + } + return nil +} + +func (m *AclAccountPermissionChange) GetPermissions() AclUserPermissions { + if m != nil { + return m.Permissions + } + return AclUserPermissions_None +} + +// AclReadKeyChange changes the key for a space +type AclReadKeyChange struct { + AccountKeys []*AclEncryptedReadKeys `protobuf:"bytes,1,rep,name=accountKeys,proto3" json:"accountKeys,omitempty"` +} + +func (m *AclReadKeyChange) Reset() { *m = AclReadKeyChange{} } +func (m *AclReadKeyChange) String() string { return proto.CompactTextString(m) } +func (*AclReadKeyChange) ProtoMessage() {} +func (*AclReadKeyChange) Descriptor() ([]byte, []int) { + return fileDescriptor_c8e9f754f34e929b, []int{11} +} +func (m *AclReadKeyChange) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AclReadKeyChange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AclReadKeyChange.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 *AclReadKeyChange) XXX_Merge(src proto.Message) { + xxx_messageInfo_AclReadKeyChange.Merge(m, src) +} +func (m *AclReadKeyChange) XXX_Size() int { + return m.Size() +} +func (m *AclReadKeyChange) XXX_DiscardUnknown() { + xxx_messageInfo_AclReadKeyChange.DiscardUnknown(m) +} + +var xxx_messageInfo_AclReadKeyChange proto.InternalMessageInfo + +func (m *AclReadKeyChange) GetAccountKeys() []*AclEncryptedReadKeys { + if m != nil { + return m.AccountKeys + } + return nil +} + +// AclAccountRemove removes an account and changes read key for space +type AclAccountRemove struct { + Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` + AccountKeys []*AclEncryptedReadKeys `protobuf:"bytes,2,rep,name=accountKeys,proto3" json:"accountKeys,omitempty"` +} + +func (m *AclAccountRemove) Reset() { *m = AclAccountRemove{} } +func (m *AclAccountRemove) String() string { return proto.CompactTextString(m) } +func (*AclAccountRemove) ProtoMessage() {} +func (*AclAccountRemove) Descriptor() ([]byte, []int) { + return fileDescriptor_c8e9f754f34e929b, []int{12} +} +func (m *AclAccountRemove) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AclAccountRemove) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AclAccountRemove.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 *AclAccountRemove) XXX_Merge(src proto.Message) { + xxx_messageInfo_AclAccountRemove.Merge(m, src) +} +func (m *AclAccountRemove) XXX_Size() int { + return m.Size() +} +func (m *AclAccountRemove) XXX_DiscardUnknown() { + xxx_messageInfo_AclAccountRemove.DiscardUnknown(m) +} + +var xxx_messageInfo_AclAccountRemove proto.InternalMessageInfo + +func (m *AclAccountRemove) GetIdentity() []byte { + if m != nil { + return m.Identity + } + return nil +} + +func (m *AclAccountRemove) GetAccountKeys() []*AclEncryptedReadKeys { + if m != nil { + return m.AccountKeys + } + return nil +} + +// AclContentValue contains possible values for Acl type AclContentValue struct { // Types that are valid to be assigned to Value: // - // *AclContentValue_UserAdd - // *AclContentValue_UserRemove - // *AclContentValue_UserPermissionChange - // *AclContentValue_UserInvite - // *AclContentValue_UserJoin + // *AclContentValue_Invite + // *AclContentValue_InviteRevoke + // *AclContentValue_RequestJoin + // *AclContentValue_RequestAccept + // *AclContentValue_PermissionChange + // *AclContentValue_AccountRemove + // *AclContentValue_ReadKeyChange Value isAclContentValue_Value `protobuf_oneof:"value"` } @@ -345,7 +812,7 @@ 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_c8e9f754f34e929b, []int{4} + return fileDescriptor_c8e9f754f34e929b, []int{13} } func (m *AclContentValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -380,27 +847,35 @@ type isAclContentValue_Value interface { Size() int } -type AclContentValue_UserAdd struct { - UserAdd *AclUserAdd `protobuf:"bytes,1,opt,name=userAdd,proto3,oneof" json:"userAdd,omitempty"` +type AclContentValue_Invite struct { + Invite *AclAccountInvite `protobuf:"bytes,1,opt,name=invite,proto3,oneof" json:"invite,omitempty"` } -type AclContentValue_UserRemove struct { - UserRemove *AclUserRemove `protobuf:"bytes,2,opt,name=userRemove,proto3,oneof" json:"userRemove,omitempty"` +type AclContentValue_InviteRevoke struct { + InviteRevoke *AclAccountInviteRevoke `protobuf:"bytes,2,opt,name=inviteRevoke,proto3,oneof" json:"inviteRevoke,omitempty"` } -type AclContentValue_UserPermissionChange struct { - UserPermissionChange *AclUserPermissionChange `protobuf:"bytes,3,opt,name=userPermissionChange,proto3,oneof" json:"userPermissionChange,omitempty"` +type AclContentValue_RequestJoin struct { + RequestJoin *AclAccountRequestJoin `protobuf:"bytes,3,opt,name=requestJoin,proto3,oneof" json:"requestJoin,omitempty"` } -type AclContentValue_UserInvite struct { - UserInvite *AclUserInvite `protobuf:"bytes,4,opt,name=userInvite,proto3,oneof" json:"userInvite,omitempty"` +type AclContentValue_RequestAccept struct { + RequestAccept *AclAccountRequestAccept `protobuf:"bytes,4,opt,name=requestAccept,proto3,oneof" json:"requestAccept,omitempty"` } -type AclContentValue_UserJoin struct { - UserJoin *AclUserJoin `protobuf:"bytes,5,opt,name=userJoin,proto3,oneof" json:"userJoin,omitempty"` +type AclContentValue_PermissionChange struct { + PermissionChange *AclAccountPermissionChange `protobuf:"bytes,5,opt,name=permissionChange,proto3,oneof" json:"permissionChange,omitempty"` +} +type AclContentValue_AccountRemove struct { + AccountRemove *AclAccountRemove `protobuf:"bytes,6,opt,name=accountRemove,proto3,oneof" json:"accountRemove,omitempty"` +} +type AclContentValue_ReadKeyChange struct { + ReadKeyChange *AclReadKeyChange `protobuf:"bytes,7,opt,name=readKeyChange,proto3,oneof" json:"readKeyChange,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 (*AclContentValue_Invite) isAclContentValue_Value() {} +func (*AclContentValue_InviteRevoke) isAclContentValue_Value() {} +func (*AclContentValue_RequestJoin) isAclContentValue_Value() {} +func (*AclContentValue_RequestAccept) isAclContentValue_Value() {} +func (*AclContentValue_PermissionChange) isAclContentValue_Value() {} +func (*AclContentValue_AccountRemove) isAclContentValue_Value() {} +func (*AclContentValue_ReadKeyChange) isAclContentValue_Value() {} func (m *AclContentValue) GetValue() isAclContentValue_Value { if m != nil { @@ -409,37 +884,51 @@ func (m *AclContentValue) GetValue() isAclContentValue_Value { return nil } -func (m *AclContentValue) GetUserAdd() *AclUserAdd { - if x, ok := m.GetValue().(*AclContentValue_UserAdd); ok { - return x.UserAdd +func (m *AclContentValue) GetInvite() *AclAccountInvite { + if x, ok := m.GetValue().(*AclContentValue_Invite); ok { + return x.Invite } return nil } -func (m *AclContentValue) GetUserRemove() *AclUserRemove { - if x, ok := m.GetValue().(*AclContentValue_UserRemove); ok { - return x.UserRemove +func (m *AclContentValue) GetInviteRevoke() *AclAccountInviteRevoke { + if x, ok := m.GetValue().(*AclContentValue_InviteRevoke); ok { + return x.InviteRevoke } return nil } -func (m *AclContentValue) GetUserPermissionChange() *AclUserPermissionChange { - if x, ok := m.GetValue().(*AclContentValue_UserPermissionChange); ok { - return x.UserPermissionChange +func (m *AclContentValue) GetRequestJoin() *AclAccountRequestJoin { + if x, ok := m.GetValue().(*AclContentValue_RequestJoin); ok { + return x.RequestJoin } return nil } -func (m *AclContentValue) GetUserInvite() *AclUserInvite { - if x, ok := m.GetValue().(*AclContentValue_UserInvite); ok { - return x.UserInvite +func (m *AclContentValue) GetRequestAccept() *AclAccountRequestAccept { + if x, ok := m.GetValue().(*AclContentValue_RequestAccept); ok { + return x.RequestAccept } return nil } -func (m *AclContentValue) GetUserJoin() *AclUserJoin { - if x, ok := m.GetValue().(*AclContentValue_UserJoin); ok { - return x.UserJoin +func (m *AclContentValue) GetPermissionChange() *AclAccountPermissionChange { + if x, ok := m.GetValue().(*AclContentValue_PermissionChange); ok { + return x.PermissionChange + } + return nil +} + +func (m *AclContentValue) GetAccountRemove() *AclAccountRemove { + if x, ok := m.GetValue().(*AclContentValue_AccountRemove); ok { + return x.AccountRemove + } + return nil +} + +func (m *AclContentValue) GetReadKeyChange() *AclReadKeyChange { + if x, ok := m.GetValue().(*AclContentValue_ReadKeyChange); ok { + return x.ReadKeyChange } return nil } @@ -447,14 +936,17 @@ func (m *AclContentValue) GetUserJoin() *AclUserJoin { // 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), + (*AclContentValue_Invite)(nil), + (*AclContentValue_InviteRevoke)(nil), + (*AclContentValue_RequestJoin)(nil), + (*AclContentValue_RequestAccept)(nil), + (*AclContentValue_PermissionChange)(nil), + (*AclContentValue_AccountRemove)(nil), + (*AclContentValue_ReadKeyChange)(nil), } } +// AclData contains different acl content type AclData struct { AclContent []*AclContentValue `protobuf:"bytes,1,rep,name=aclContent,proto3" json:"aclContent,omitempty"` } @@ -463,7 +955,7 @@ 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_c8e9f754f34e929b, []int{5} + return fileDescriptor_c8e9f754f34e929b, []int{14} } func (m *AclData) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -499,462 +991,6 @@ func (m *AclData) GetAclContent() []*AclContentValue { return nil } -type AclState struct { - ReadKeyIds []string `protobuf:"bytes,1,rep,name=readKeyIds,proto3" json:"readKeyIds,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_c8e9f754f34e929b, []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) GetReadKeyIds() []string { - if m != nil { - return m.ReadKeyIds - } - 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"` - Permissions AclUserPermissions `protobuf:"varint,2,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_c8e9f754f34e929b, []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) 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"` - EncryptedReadKeys [][]byte `protobuf:"bytes,2,rep,name=encryptedReadKeys,proto3" json:"encryptedReadKeys,omitempty"` - Permissions AclUserPermissions `protobuf:"varint,3,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_c8e9f754f34e929b, []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) 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"` - EncryptedReadKeys [][]byte `protobuf:"bytes,2,rep,name=encryptedReadKeys,proto3" json:"encryptedReadKeys,omitempty"` - Permissions AclUserPermissions `protobuf:"varint,3,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_c8e9f754f34e929b, []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) 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"` - AcceptSignature []byte `protobuf:"bytes,2,opt,name=acceptSignature,proto3" json:"acceptSignature,omitempty"` - AcceptPubKey []byte `protobuf:"bytes,3,opt,name=acceptPubKey,proto3" json:"acceptPubKey,omitempty"` - EncryptedReadKeys [][]byte `protobuf:"bytes,4,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_c8e9f754f34e929b, []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) 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_c8e9f754f34e929b, []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"` - EncryptedReadKey []byte `protobuf:"bytes,2,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_c8e9f754f34e929b, []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) 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_c8e9f754f34e929b, []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,1,opt,name=content,proto3" json:"content,omitempty"` } @@ -963,7 +999,7 @@ 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_c8e9f754f34e929b, []int{14} + return fileDescriptor_c8e9f754f34e929b, []int{15} } func (m *AclSyncMessage) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1011,7 +1047,7 @@ 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_c8e9f754f34e929b, []int{15} + return fileDescriptor_c8e9f754f34e929b, []int{16} } func (m *AclSyncContentValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1081,7 +1117,7 @@ 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_c8e9f754f34e929b, []int{16} + return fileDescriptor_c8e9f754f34e929b, []int{17} } func (m *AclAddRecords) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1123,17 +1159,17 @@ func init() { proto.RegisterType((*RawAclRecordWithId)(nil), "aclrecord.RawAclRecordWithId") proto.RegisterType((*AclRecord)(nil), "aclrecord.AclRecord") proto.RegisterType((*AclRoot)(nil), "aclrecord.AclRoot") + proto.RegisterType((*AclAccountInvite)(nil), "aclrecord.AclAccountInvite") + proto.RegisterType((*AclAccountRequestJoin)(nil), "aclrecord.AclAccountRequestJoin") + proto.RegisterType((*AclAccountRequestAccept)(nil), "aclrecord.AclAccountRequestAccept") + proto.RegisterType((*AclAccountInviteRevoke)(nil), "aclrecord.AclAccountInviteRevoke") + proto.RegisterType((*AclReadKeys)(nil), "aclrecord.AclReadKeys") + proto.RegisterType((*AclEncryptedReadKeys)(nil), "aclrecord.AclEncryptedReadKeys") + proto.RegisterType((*AclAccountPermissionChange)(nil), "aclrecord.AclAccountPermissionChange") + proto.RegisterType((*AclReadKeyChange)(nil), "aclrecord.AclReadKeyChange") + proto.RegisterType((*AclAccountRemove)(nil), "aclrecord.AclAccountRemove") 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") @@ -1144,65 +1180,64 @@ func init() { } var fileDescriptor_c8e9f754f34e929b = []byte{ - // 914 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0x4f, 0x6f, 0x1b, 0x45, - 0x14, 0xf7, 0xd8, 0x49, 0x9c, 0x7d, 0x36, 0x89, 0x33, 0x40, 0xbb, 0x8a, 0x82, 0x15, 0xad, 0x84, - 0x14, 0x55, 0x55, 0x22, 0x0c, 0x52, 0xaa, 0x08, 0x51, 0xb9, 0xa5, 0xc8, 0x6e, 0x84, 0x54, 0x4d, - 0x80, 0xa2, 0x72, 0x9a, 0xcc, 0x8e, 0xd2, 0xa5, 0xeb, 0xdd, 0xd5, 0xcc, 0xd8, 0xc8, 0x9f, 0x02, - 0x6e, 0x5c, 0xb9, 0x20, 0xf1, 0x51, 0x38, 0xf6, 0x12, 0x89, 0x23, 0x4a, 0x3e, 0x03, 0x77, 0x34, - 0x33, 0xde, 0xff, 0xce, 0x0a, 0x0e, 0x70, 0x48, 0xbc, 0xf3, 0xde, 0x6f, 0x66, 0x7e, 0xef, 0xf7, - 0xfe, 0xec, 0xc2, 0xa7, 0x2c, 0x9e, 0xcd, 0xe2, 0x48, 0x26, 0x94, 0xf1, 0x93, 0xf8, 0xf2, 0x7b, - 0xce, 0xd4, 0x09, 0x65, 0xa1, 0xfe, 0x13, 0x9c, 0xc5, 0xc2, 0x4f, 0x44, 0xac, 0xe2, 0x13, 0xf3, - 0x5f, 0xe6, 0xd6, 0x63, 0x63, 0xc0, 0x4e, 0x66, 0xf0, 0x7e, 0x41, 0xd0, 0x27, 0xf4, 0x87, 0x31, - 0x0b, 0x89, 0x31, 0x60, 0x17, 0xba, 0x09, 0x5d, 0x86, 0x31, 0xf5, 0x5d, 0x74, 0x88, 0x8e, 0xfa, - 0x24, 0x5d, 0xe2, 0x03, 0x70, 0x64, 0x70, 0x15, 0x51, 0x35, 0x17, 0xdc, 0x6d, 0x1b, 0x5f, 0x6e, - 0xc0, 0x0f, 0x60, 0x40, 0x19, 0xe3, 0x89, 0x8a, 0xc5, 0xd4, 0xe7, 0x91, 0x0a, 0xd4, 0xd2, 0xed, - 0x18, 0x50, 0xcd, 0x8e, 0x1f, 0xc2, 0x5e, 0x6a, 0xbb, 0xc8, 0x4e, 0xdc, 0x30, 0xe0, 0xba, 0xc3, - 0xfb, 0x0c, 0x70, 0x91, 0xe1, 0xcb, 0x40, 0xbd, 0x9e, 0x36, 0xf1, 0xdc, 0x81, 0x76, 0xe0, 0x1b, - 0x82, 0x0e, 0x69, 0x07, 0xbe, 0xf7, 0x23, 0x02, 0x27, 0x8f, 0xef, 0x1e, 0x6c, 0x25, 0x82, 0x2f, - 0xa6, 0x76, 0x9b, 0x43, 0x56, 0x2b, 0xbc, 0x0f, 0xdb, 0x41, 0xca, 0xdb, 0x06, 0x97, 0xad, 0x31, - 0x86, 0x0d, 0x9f, 0x2a, 0xba, 0x8a, 0xc7, 0x3c, 0x6b, 0x35, 0x04, 0xa7, 0xfe, 0x39, 0x5f, 0x4e, - 0x7d, 0xc3, 0xdd, 0x21, 0xb9, 0x41, 0x7b, 0x55, 0x30, 0xe3, 0x52, 0xd1, 0x59, 0xe2, 0x6e, 0x1e, - 0xa2, 0xa3, 0x0e, 0xc9, 0x0d, 0xde, 0x35, 0x82, 0xae, 0x66, 0x14, 0xc7, 0xaa, 0x74, 0x2f, 0xaa, - 0xdc, 0x7b, 0x00, 0xce, 0x8c, 0x4a, 0xc5, 0xc5, 0x39, 0x4f, 0x49, 0xe5, 0x06, 0xad, 0x80, 0xc9, - 0xff, 0xd4, 0x37, 0xc4, 0x1c, 0x92, 0x2e, 0x75, 0x2e, 0x78, 0xc4, 0xc4, 0x32, 0x51, 0xdc, 0x27, - 0x96, 0xd3, 0x4a, 0xde, 0x9a, 0xbd, 0x99, 0xa9, 0xce, 0x54, 0xca, 0x26, 0xcf, 0xd4, 0x96, 0xcd, - 0x54, 0xcd, 0xe1, 0x5d, 0xb7, 0x61, 0x77, 0xcc, 0xc2, 0xa7, 0x71, 0xa4, 0x78, 0xa4, 0xbe, 0xa1, - 0xe1, 0x9c, 0xe3, 0x8f, 0xa0, 0x3b, 0x97, 0x5c, 0x8c, 0x7d, 0x2b, 0x78, 0x6f, 0xf4, 0xfe, 0x71, - 0x5e, 0x8e, 0x63, 0x16, 0x7e, 0x6d, 0x9d, 0x93, 0x16, 0x49, 0x71, 0xf8, 0x0c, 0x40, 0x3f, 0x12, - 0x3e, 0x8b, 0x17, 0xb6, 0xd2, 0x7a, 0x23, 0xb7, 0xbe, 0xcb, 0xfa, 0x27, 0x2d, 0x52, 0x40, 0xe3, - 0x6f, 0xe1, 0x3d, 0xbd, 0x7a, 0xc1, 0xc5, 0x2c, 0x90, 0x32, 0x88, 0xa3, 0xa7, 0xaf, 0x69, 0x74, - 0xc5, 0x8d, 0x42, 0xbd, 0x91, 0x57, 0x3f, 0xa5, 0x8a, 0x9c, 0xb4, 0xc8, 0xda, 0x13, 0x52, 0x56, - 0xd3, 0x68, 0x11, 0x28, 0x5b, 0xad, 0x6b, 0x59, 0x59, 0x7f, 0xca, 0xca, 0xae, 0xf0, 0x27, 0xb0, - 0xad, 0x57, 0xcf, 0xe3, 0x20, 0x32, 0x1a, 0xf7, 0x46, 0xf7, 0xea, 0x3b, 0xb5, 0x77, 0xd2, 0x22, - 0x19, 0xf2, 0x49, 0x17, 0x36, 0x17, 0x5a, 0x43, 0xef, 0x99, 0x29, 0x97, 0xcf, 0x75, 0xd9, 0x9d, - 0x01, 0xd0, 0x4c, 0x61, 0x17, 0x1d, 0x76, 0x8e, 0x7a, 0xa3, 0xfd, 0xf2, 0x59, 0x45, 0xf9, 0x49, - 0x01, 0xed, 0xfd, 0x85, 0x60, 0x7b, 0xcc, 0xc2, 0x0b, 0x45, 0x15, 0xc7, 0x43, 0x80, 0xac, 0x5c, - 0xa5, 0x39, 0xc8, 0x21, 0x05, 0x0b, 0x3e, 0xb5, 0xe1, 0x1a, 0xb0, 0x74, 0xdb, 0xe6, 0xa2, 0xfb, - 0x75, 0xd2, 0xc6, 0x4f, 0x0a, 0x50, 0x7c, 0x06, 0xdd, 0xc0, 0x44, 0x2d, 0xdd, 0x8e, 0xd9, 0x75, - 0x58, 0xde, 0x65, 0x60, 0xc7, 0x56, 0x18, 0xf9, 0x2c, 0x52, 0x62, 0x49, 0xd2, 0x0d, 0xfb, 0x5f, - 0x41, 0xbf, 0xe8, 0xc0, 0x03, 0xe8, 0xbc, 0xe1, 0xcb, 0x55, 0xa7, 0xea, 0x47, 0x7c, 0xbc, 0xd2, - 0xe4, 0xee, 0xb2, 0xb0, 0x07, 0x10, 0x0b, 0x3b, 0x6b, 0x3f, 0x42, 0xde, 0x1b, 0xe8, 0x17, 0xd9, - 0x36, 0xb6, 0xdc, 0x63, 0xe8, 0x25, 0x59, 0xe6, 0xa5, 0xb9, 0x65, 0x67, 0xf4, 0x41, 0x53, 0xd9, - 0x48, 0x52, 0xdc, 0xe1, 0xfd, 0x8c, 0x00, 0xf2, 0xb2, 0x6e, 0xbc, 0xeb, 0x21, 0xec, 0x55, 0xdb, - 0xd1, 0x2a, 0xdd, 0x27, 0x75, 0x47, 0x95, 0x59, 0xe7, 0x5f, 0x33, 0xfb, 0x0d, 0xc1, 0x3b, 0x25, - 0x8d, 0xf0, 0x11, 0xec, 0xda, 0x71, 0xfb, 0x62, 0x7e, 0x19, 0x06, 0xec, 0x9c, 0xa7, 0x1c, 0xab, - 0xe6, 0xff, 0x9b, 0xea, 0xaf, 0x08, 0x7a, 0x85, 0xae, 0x68, 0x54, 0x31, 0x0b, 0xe2, 0xa2, 0xf2, - 0x72, 0xaa, 0x9a, 0xb1, 0x07, 0xfd, 0x2c, 0x2e, 0x1d, 0xab, 0x1d, 0xe7, 0x25, 0xdb, 0xfa, 0x40, - 0x37, 0xee, 0x08, 0xd4, 0x93, 0x99, 0xa2, 0xab, 0xf1, 0xd3, 0x44, 0xf4, 0x0b, 0xd8, 0x5d, 0xf5, - 0x17, 0xe1, 0x49, 0x48, 0x59, 0xd6, 0x56, 0x07, 0x65, 0x65, 0x48, 0x09, 0x44, 0xaa, 0x9b, 0xbc, - 0xef, 0x60, 0xaf, 0x86, 0x6a, 0xbc, 0x78, 0xdd, 0xeb, 0xa0, 0xbd, 0xfe, 0x75, 0xe0, 0x2d, 0xe0, - 0xfe, 0x1d, 0x83, 0xf1, 0xbf, 0x6d, 0x9b, 0xe7, 0xb0, 0xa3, 0x67, 0xc3, 0x32, 0x62, 0x5f, 0x72, - 0x29, 0xe9, 0x15, 0xc7, 0x8f, 0xa0, 0xcb, 0xb2, 0x31, 0xa7, 0x7b, 0x7d, 0x58, 0x99, 0x23, 0xcb, - 0x88, 0x95, 0x46, 0x5d, 0x0a, 0xf7, 0x5e, 0xc1, 0xbb, 0x6b, 0xfc, 0x66, 0x74, 0xfa, 0xbe, 0xfd, - 0x0c, 0x90, 0xab, 0x33, 0x2b, 0xf3, 0x63, 0x9c, 0xf9, 0xf5, 0x00, 0xcf, 0xd1, 0xf9, 0x28, 0x9e, - 0x98, 0x8c, 0xe7, 0x38, 0x7c, 0x0a, 0x5d, 0x91, 0x1d, 0xa9, 0xb3, 0x59, 0x8c, 0xba, 0xfe, 0xdd, - 0x42, 0x52, 0xf4, 0x83, 0x53, 0xc0, 0x75, 0x51, 0xb0, 0x03, 0x9b, 0x63, 0x7f, 0x16, 0x44, 0x83, - 0x16, 0x06, 0xd8, 0x7a, 0x29, 0x02, 0xc5, 0xc5, 0x00, 0xe9, 0x67, 0x9d, 0x21, 0x2e, 0x06, 0xed, - 0x27, 0x8f, 0x7f, 0xbf, 0x19, 0xa2, 0xb7, 0x37, 0x43, 0xf4, 0xe7, 0xcd, 0x10, 0xfd, 0x74, 0x3b, - 0x6c, 0xbd, 0xbd, 0x1d, 0xb6, 0xfe, 0xb8, 0x1d, 0xb6, 0x5e, 0x7d, 0xf8, 0x8f, 0xbe, 0x0a, 0x2f, - 0xb7, 0xcc, 0xcf, 0xc7, 0x7f, 0x07, 0x00, 0x00, 0xff, 0xff, 0x2e, 0x3b, 0x3f, 0x0a, 0x45, 0x0a, - 0x00, 0x00, + // 912 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xdd, 0x6e, 0x1b, 0x45, + 0x14, 0xde, 0x75, 0x1c, 0xbb, 0x3e, 0x9b, 0xa4, 0xcb, 0x00, 0xad, 0x15, 0x8a, 0x09, 0x23, 0x15, + 0xaa, 0x0a, 0x35, 0xc8, 0x08, 0x51, 0x21, 0x44, 0xd9, 0xa6, 0x15, 0x76, 0xf8, 0xd5, 0x44, 0xa5, + 0x52, 0xaf, 0x98, 0xce, 0x8e, 0xd2, 0x85, 0xdd, 0x9d, 0xcd, 0xec, 0xc4, 0x95, 0x9f, 0x01, 0x21, + 0xf1, 0x08, 0xf0, 0x36, 0x5c, 0xf6, 0x06, 0x89, 0x4b, 0x94, 0xbc, 0x08, 0x9a, 0x99, 0x5d, 0xef, + 0x9f, 0x63, 0x21, 0x2e, 0x12, 0xcf, 0x9c, 0xf9, 0xce, 0x77, 0xbe, 0xf3, 0x33, 0x63, 0xc3, 0x67, + 0x4c, 0x24, 0x89, 0x48, 0xf3, 0x8c, 0x32, 0x7e, 0x28, 0x9e, 0xff, 0xc4, 0x99, 0x3a, 0xa4, 0x2c, + 0xd6, 0x7f, 0x92, 0x33, 0x21, 0xc3, 0x4c, 0x0a, 0x25, 0x0e, 0xcd, 0xff, 0xbc, 0xb2, 0xde, 0x33, + 0x06, 0x34, 0x5a, 0x19, 0xf0, 0xef, 0x2e, 0xec, 0x10, 0xfa, 0x32, 0x60, 0x31, 0x31, 0x06, 0x34, + 0x86, 0x61, 0x46, 0x97, 0xb1, 0xa0, 0xe1, 0xd8, 0x3d, 0x70, 0xef, 0xec, 0x90, 0x72, 0x8b, 0x6e, + 0xc1, 0x28, 0x8f, 0x4e, 0x53, 0xaa, 0xce, 0x25, 0x1f, 0xf7, 0xcc, 0x59, 0x65, 0x40, 0x77, 0xc1, + 0xa7, 0x8c, 0xf1, 0x4c, 0x09, 0x39, 0x0f, 0x79, 0xaa, 0x22, 0xb5, 0x1c, 0x6f, 0x19, 0x50, 0xc7, + 0x8e, 0x3e, 0x80, 0xd7, 0x4a, 0xdb, 0xc9, 0x8a, 0xb1, 0x6f, 0xc0, 0xdd, 0x03, 0xfc, 0x39, 0xa0, + 0xba, 0xc2, 0xa7, 0x91, 0x7a, 0x31, 0xdf, 0xa4, 0x73, 0x0f, 0x7a, 0x51, 0x68, 0x04, 0x8e, 0x48, + 0x2f, 0x0a, 0xf1, 0x19, 0x8c, 0xaa, 0xf4, 0x6e, 0xc0, 0x20, 0x93, 0x7c, 0x31, 0xb7, 0x5e, 0x23, + 0x52, 0xec, 0xd0, 0x3e, 0x5c, 0x8b, 0x4a, 0xd9, 0x36, 0xb7, 0xd5, 0x1e, 0x21, 0xe8, 0x87, 0x54, + 0xd1, 0x22, 0x1d, 0xb3, 0xd6, 0xc5, 0x50, 0x51, 0xc2, 0x73, 0x45, 0x93, 0xcc, 0x48, 0xdf, 0x22, + 0x95, 0x01, 0xff, 0xe5, 0xc2, 0x50, 0xc7, 0x14, 0x42, 0x35, 0x98, 0xdd, 0x16, 0xf3, 0x2d, 0x18, + 0x25, 0x34, 0x57, 0x5c, 0x7e, 0xc5, 0xcb, 0xb0, 0x95, 0x41, 0xa7, 0x68, 0x1a, 0x3c, 0x0f, 0x4d, + 0xe8, 0x11, 0x29, 0xb7, 0xba, 0xd8, 0x3c, 0x65, 0x72, 0x99, 0x29, 0x1e, 0x12, 0x4e, 0x43, 0xed, + 0x6e, 0xeb, 0xd7, 0xb1, 0x37, 0x95, 0x6e, 0xb7, 0x94, 0xea, 0x56, 0x94, 0x6a, 0xaa, 0x56, 0x0c, + 0x6c, 0x2b, 0x3a, 0x07, 0xf8, 0x43, 0xf0, 0x03, 0x16, 0x07, 0x8c, 0x89, 0xf3, 0x54, 0xcd, 0xd3, + 0x45, 0xa4, 0xb8, 0xe6, 0x8f, 0xcc, 0x4a, 0x8b, 0xb0, 0x09, 0x56, 0x06, 0xfc, 0x87, 0x0b, 0x6f, + 0x56, 0x2e, 0x84, 0x9f, 0x9d, 0xf3, 0x5c, 0x1d, 0x8b, 0x28, 0x45, 0xef, 0xc1, 0x9e, 0x85, 0xcd, + 0x9b, 0xd5, 0x69, 0x59, 0x2b, 0x9c, 0xed, 0xe0, 0xbc, 0x6c, 0x6d, 0xcb, 0x8a, 0xee, 0xc3, 0xcd, + 0xa6, 0x67, 0x95, 0x8f, 0x6d, 0xdc, 0x55, 0xc7, 0xf8, 0x57, 0x17, 0x6e, 0x76, 0x34, 0x06, 0x66, + 0x0e, 0x37, 0x76, 0xef, 0x0e, 0x5c, 0x97, 0x16, 0xdc, 0x92, 0xd6, 0x36, 0xeb, 0x2a, 0xb7, 0xfb, + 0x92, 0x17, 0xaa, 0xba, 0x07, 0xf8, 0x0b, 0xb8, 0xd1, 0xae, 0x32, 0xe1, 0x0b, 0xf1, 0x33, 0x5f, + 0x53, 0x0b, 0x77, 0x5d, 0x2d, 0xf0, 0xfb, 0xe0, 0x99, 0x91, 0xb7, 0x84, 0x7a, 0x90, 0x64, 0x31, + 0x25, 0xee, 0xc1, 0x96, 0xbe, 0x2b, 0xc5, 0x16, 0xff, 0x08, 0x6f, 0x04, 0x2c, 0x7e, 0xdc, 0x96, + 0xb0, 0x31, 0xed, 0xb5, 0xc9, 0xf4, 0xae, 0x4a, 0x66, 0x09, 0xfb, 0x55, 0x32, 0xdf, 0x73, 0x99, + 0x44, 0x79, 0x1e, 0x89, 0xf4, 0xe8, 0x05, 0x4d, 0x4f, 0xf9, 0xc6, 0x38, 0x0f, 0xc0, 0xcb, 0x56, + 0x78, 0x1b, 0x61, 0x6f, 0xfa, 0xf6, 0xbd, 0xea, 0x31, 0x0b, 0x58, 0xfc, 0x24, 0xe7, 0xb2, 0x22, + 0xcd, 0x49, 0xdd, 0x03, 0x3f, 0x31, 0xd3, 0x5a, 0x28, 0x29, 0x02, 0x06, 0xe0, 0x51, 0xab, 0xc5, + 0xc8, 0xd6, 0xe5, 0xf0, 0xa6, 0xef, 0x34, 0x49, 0x3b, 0xe5, 0x20, 0x75, 0x1f, 0x7c, 0x56, 0xbf, + 0x04, 0x84, 0x27, 0x62, 0xb1, 0x39, 0x8f, 0x56, 0xc8, 0xde, 0xff, 0x08, 0xf9, 0x4b, 0x1f, 0xae, + 0x07, 0x2c, 0x3e, 0x12, 0xa9, 0xe2, 0xa9, 0xfa, 0x81, 0xc6, 0xe7, 0x1c, 0x7d, 0x0c, 0x03, 0xdb, + 0x75, 0x13, 0xd0, 0x9b, 0xbe, 0xd5, 0x64, 0x6c, 0x8c, 0xcf, 0xcc, 0x21, 0x05, 0x18, 0x7d, 0x09, + 0x3b, 0x51, 0x6d, 0xa4, 0x4c, 0x59, 0xbd, 0xe9, 0xbb, 0x1b, 0x9c, 0x2d, 0x70, 0xe6, 0x90, 0x86, + 0x23, 0x7a, 0x04, 0x9e, 0xac, 0xae, 0xb3, 0x99, 0x66, 0x6f, 0x7a, 0xb0, 0x96, 0xa7, 0x76, 0xed, + 0x67, 0x0e, 0xa9, 0xbb, 0xa1, 0x63, 0xd8, 0x95, 0xf5, 0x0b, 0x67, 0x9e, 0x31, 0x6f, 0x8a, 0x37, + 0xf1, 0x58, 0xe4, 0xcc, 0x21, 0x4d, 0x57, 0x74, 0x02, 0x7e, 0xd6, 0x1a, 0x30, 0xf3, 0xe0, 0x79, + 0xd3, 0xdb, 0x6b, 0xe9, 0xda, 0xd3, 0x38, 0x73, 0x48, 0x87, 0x00, 0x1d, 0xc1, 0x2e, 0xad, 0xb7, + 0xda, 0x3c, 0x8e, 0x57, 0x55, 0xdb, 0x42, 0xb4, 0xb2, 0x86, 0x8f, 0x26, 0x91, 0xf5, 0x31, 0x1c, + 0x0f, 0xd7, 0x91, 0x34, 0x26, 0xd5, 0xa6, 0x57, 0x33, 0x3c, 0x1c, 0xc2, 0xf6, 0x42, 0x77, 0x1e, + 0x3f, 0x36, 0x5f, 0x2e, 0x8f, 0xf4, 0xd7, 0xd0, 0xa7, 0x00, 0x74, 0x35, 0x17, 0xc5, 0x34, 0xef, + 0x37, 0x59, 0xeb, 0x43, 0x43, 0x6a, 0x68, 0x7c, 0x0c, 0x7b, 0x01, 0x8b, 0x4f, 0x96, 0x29, 0xfb, + 0x86, 0xe7, 0x39, 0x3d, 0xe5, 0xe8, 0x3e, 0x0c, 0xd9, 0x8a, 0x4a, 0x0b, 0x9c, 0x34, 0xa9, 0x34, + 0xb6, 0x41, 0x57, 0xc2, 0xf1, 0x33, 0x78, 0x7d, 0xcd, 0xb9, 0x91, 0x17, 0x86, 0xf6, 0x59, 0xca, + 0x0b, 0xce, 0x71, 0xab, 0x72, 0xab, 0xf3, 0x99, 0x43, 0x6a, 0xe8, 0x2a, 0xdd, 0x19, 0xec, 0x36, + 0x70, 0xe8, 0x13, 0xfd, 0x9c, 0x95, 0x94, 0x3a, 0xe3, 0xfa, 0xa3, 0xd0, 0xfd, 0xa9, 0x40, 0x4a, + 0xf4, 0xdd, 0xaf, 0x01, 0x75, 0xdf, 0x0c, 0x74, 0x0d, 0xfa, 0xdf, 0x8a, 0x94, 0xfb, 0x0e, 0x1a, + 0xc1, 0xf6, 0x77, 0x2f, 0x53, 0x2e, 0x7d, 0x57, 0x2f, 0x83, 0x30, 0x89, 0x52, 0xbf, 0x87, 0x00, + 0x06, 0x4f, 0x65, 0xa4, 0xb8, 0xf4, 0xb7, 0xf4, 0x5a, 0x77, 0x89, 0x4b, 0xbf, 0xff, 0xf0, 0xc1, + 0x9f, 0x17, 0x13, 0xf7, 0xd5, 0xc5, 0xc4, 0xfd, 0xe7, 0x62, 0xe2, 0xfe, 0x76, 0x39, 0x71, 0x5e, + 0x5d, 0x4e, 0x9c, 0xbf, 0x2f, 0x27, 0xce, 0xb3, 0xdb, 0xff, 0xe9, 0xd7, 0xd9, 0xf3, 0x81, 0xf9, + 0xf8, 0xe8, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x51, 0x62, 0x48, 0x8d, 0xcd, 0x09, 0x00, 0x00, } func (m *RawAclRecord) Marshal() (dAtA []byte, err error) { @@ -1316,14 +1351,7 @@ func (m *AclRecord) MarshalToSizedBuffer(dAtA []byte) (int, error) { if m.Timestamp != 0 { i = encodeVarintAclrecord(dAtA, i, uint64(m.Timestamp)) i-- - dAtA[i] = 0x28 - } - if len(m.ReadKeyId) > 0 { - i -= len(m.ReadKeyId) - copy(dAtA[i:], m.ReadKeyId) - i = encodeVarintAclrecord(dAtA, i, uint64(len(m.ReadKeyId))) - i-- - dAtA[i] = 0x22 + dAtA[i] = 0x20 } if len(m.Data) > 0 { i -= len(m.Data) @@ -1412,6 +1440,339 @@ func (m *AclRoot) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *AclAccountInvite) 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 *AclAccountInvite) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AclAccountInvite) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.InviteKey) > 0 { + i -= len(m.InviteKey) + copy(dAtA[i:], m.InviteKey) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.InviteKey))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *AclAccountRequestJoin) 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 *AclAccountRequestJoin) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AclAccountRequestJoin) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.InviteIdentitySignature) > 0 { + i -= len(m.InviteIdentitySignature) + copy(dAtA[i:], m.InviteIdentitySignature) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.InviteIdentitySignature))) + i-- + dAtA[i] = 0x1a + } + if len(m.InviteRecordId) > 0 { + i -= len(m.InviteRecordId) + copy(dAtA[i:], m.InviteRecordId) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.InviteRecordId))) + i-- + dAtA[i] = 0x12 + } + if len(m.InviteIdentity) > 0 { + i -= len(m.InviteIdentity) + copy(dAtA[i:], m.InviteIdentity) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.InviteIdentity))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *AclAccountRequestAccept) 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 *AclAccountRequestAccept) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AclAccountRequestAccept) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.EncryptedReadKeys) > 0 { + i -= len(m.EncryptedReadKeys) + copy(dAtA[i:], m.EncryptedReadKeys) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.EncryptedReadKeys))) + i-- + dAtA[i] = 0x1a + } + if len(m.RequestRecordId) > 0 { + i -= len(m.RequestRecordId) + copy(dAtA[i:], m.RequestRecordId) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.RequestRecordId))) + 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 *AclAccountInviteRevoke) 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 *AclAccountInviteRevoke) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AclAccountInviteRevoke) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.InviteRecordId) > 0 { + i -= len(m.InviteRecordId) + copy(dAtA[i:], m.InviteRecordId) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.InviteRecordId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *AclReadKeys) 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 *AclReadKeys) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AclReadKeys) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ReadKey) > 0 { + for iNdEx := len(m.ReadKey) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.ReadKey[iNdEx]) + copy(dAtA[i:], m.ReadKey[iNdEx]) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.ReadKey[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *AclEncryptedReadKeys) 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 *AclEncryptedReadKeys) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AclEncryptedReadKeys) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.EncryptedReadKeys) > 0 { + i -= len(m.EncryptedReadKeys) + copy(dAtA[i:], m.EncryptedReadKeys) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.EncryptedReadKeys))) + 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 *AclAccountPermissionChange) 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 *AclAccountPermissionChange) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AclAccountPermissionChange) 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 *AclReadKeyChange) 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 *AclReadKeyChange) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AclReadKeyChange) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.AccountKeys) > 0 { + for iNdEx := len(m.AccountKeys) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.AccountKeys[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 *AclAccountRemove) 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 *AclAccountRemove) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AclAccountRemove) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.AccountKeys) > 0 { + for iNdEx := len(m.AccountKeys) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.AccountKeys[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 *AclContentValue) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1444,16 +1805,16 @@ func (m *AclContentValue) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *AclContentValue_UserAdd) MarshalTo(dAtA []byte) (int, error) { +func (m *AclContentValue_Invite) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *AclContentValue_UserAdd) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *AclContentValue_Invite) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) - if m.UserAdd != nil { + if m.Invite != nil { { - size, err := m.UserAdd.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.Invite.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -1465,16 +1826,16 @@ func (m *AclContentValue_UserAdd) MarshalToSizedBuffer(dAtA []byte) (int, error) } return len(dAtA) - i, nil } -func (m *AclContentValue_UserRemove) MarshalTo(dAtA []byte) (int, error) { +func (m *AclContentValue_InviteRevoke) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *AclContentValue_UserRemove) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *AclContentValue_InviteRevoke) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) - if m.UserRemove != nil { + if m.InviteRevoke != nil { { - size, err := m.UserRemove.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.InviteRevoke.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -1486,16 +1847,16 @@ func (m *AclContentValue_UserRemove) MarshalToSizedBuffer(dAtA []byte) (int, err } return len(dAtA) - i, nil } -func (m *AclContentValue_UserPermissionChange) MarshalTo(dAtA []byte) (int, error) { +func (m *AclContentValue_RequestJoin) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *AclContentValue_UserPermissionChange) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *AclContentValue_RequestJoin) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) - if m.UserPermissionChange != nil { + if m.RequestJoin != nil { { - size, err := m.UserPermissionChange.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.RequestJoin.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -1507,16 +1868,16 @@ func (m *AclContentValue_UserPermissionChange) MarshalToSizedBuffer(dAtA []byte) } return len(dAtA) - i, nil } -func (m *AclContentValue_UserInvite) MarshalTo(dAtA []byte) (int, error) { +func (m *AclContentValue_RequestAccept) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *AclContentValue_UserInvite) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *AclContentValue_RequestAccept) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) - if m.UserInvite != nil { + if m.RequestAccept != nil { { - size, err := m.UserInvite.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.RequestAccept.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -1528,16 +1889,16 @@ func (m *AclContentValue_UserInvite) MarshalToSizedBuffer(dAtA []byte) (int, err } return len(dAtA) - i, nil } -func (m *AclContentValue_UserJoin) MarshalTo(dAtA []byte) (int, error) { +func (m *AclContentValue_PermissionChange) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *AclContentValue_UserJoin) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *AclContentValue_PermissionChange) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) - if m.UserJoin != nil { + if m.PermissionChange != nil { { - size, err := m.UserJoin.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.PermissionChange.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -1549,6 +1910,48 @@ func (m *AclContentValue_UserJoin) MarshalToSizedBuffer(dAtA []byte) (int, error } return len(dAtA) - i, nil } +func (m *AclContentValue_AccountRemove) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AclContentValue_AccountRemove) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.AccountRemove != nil { + { + size, err := m.AccountRemove.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAclrecord(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + return len(dAtA) - i, nil +} +func (m *AclContentValue_ReadKeyChange) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AclContentValue_ReadKeyChange) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.ReadKeyChange != nil { + { + size, err := m.ReadKeyChange.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAclrecord(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + } + return len(dAtA) - i, nil +} func (m *AclData) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1586,370 +1989,6 @@ func (m *AclData) MarshalToSizedBuffer(dAtA []byte) (int, error) { 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.ReadKeyIds) > 0 { - for iNdEx := len(m.ReadKeyIds) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.ReadKeyIds[iNdEx]) - copy(dAtA[i:], m.ReadKeyIds[iNdEx]) - i = encodeVarintAclrecord(dAtA, i, uint64(len(m.ReadKeyIds[iNdEx]))) - 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] = 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 *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] = 0x18 - } - 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] = 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] = 0x18 - } - 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] = 0x12 - } - } - 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] = 0x22 - } - } - 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] = 0x1a - } - 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] = 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] = 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) @@ -2146,10 +2185,6 @@ func (m *AclRecord) Size() (n int) { if l > 0 { n += 1 + l + sovAclrecord(uint64(l)) } - l = len(m.ReadKeyId) - if l > 0 { - n += 1 + l + sovAclrecord(uint64(l)) - } if m.Timestamp != 0 { n += 1 + sovAclrecord(uint64(m.Timestamp)) } @@ -2188,6 +2223,156 @@ func (m *AclRoot) Size() (n int) { return n } +func (m *AclAccountInvite) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.InviteKey) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + return n +} + +func (m *AclAccountRequestJoin) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.InviteIdentity) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + l = len(m.InviteRecordId) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + l = len(m.InviteIdentitySignature) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + return n +} + +func (m *AclAccountRequestAccept) 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.RequestRecordId) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + l = len(m.EncryptedReadKeys) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + return n +} + +func (m *AclAccountInviteRevoke) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.InviteRecordId) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + return n +} + +func (m *AclReadKeys) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.ReadKey) > 0 { + for _, b := range m.ReadKey { + l = len(b) + n += 1 + l + sovAclrecord(uint64(l)) + } + } + return n +} + +func (m *AclEncryptedReadKeys) 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.EncryptedReadKeys) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + return n +} + +func (m *AclAccountPermissionChange) 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 *AclReadKeyChange) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.AccountKeys) > 0 { + for _, e := range m.AccountKeys { + l = e.Size() + n += 1 + l + sovAclrecord(uint64(l)) + } + } + return n +} + +func (m *AclAccountRemove) 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.AccountKeys) > 0 { + for _, e := range m.AccountKeys { + l = e.Size() + n += 1 + l + sovAclrecord(uint64(l)) + } + } + return n +} + func (m *AclContentValue) Size() (n int) { if m == nil { return 0 @@ -2200,62 +2385,86 @@ func (m *AclContentValue) Size() (n int) { return n } -func (m *AclContentValue_UserAdd) Size() (n int) { +func (m *AclContentValue_Invite) Size() (n int) { if m == nil { return 0 } var l int _ = l - if m.UserAdd != nil { - l = m.UserAdd.Size() + if m.Invite != nil { + l = m.Invite.Size() n += 1 + l + sovAclrecord(uint64(l)) } return n } -func (m *AclContentValue_UserRemove) Size() (n int) { +func (m *AclContentValue_InviteRevoke) Size() (n int) { if m == nil { return 0 } var l int _ = l - if m.UserRemove != nil { - l = m.UserRemove.Size() + if m.InviteRevoke != nil { + l = m.InviteRevoke.Size() n += 1 + l + sovAclrecord(uint64(l)) } return n } -func (m *AclContentValue_UserPermissionChange) Size() (n int) { +func (m *AclContentValue_RequestJoin) Size() (n int) { if m == nil { return 0 } var l int _ = l - if m.UserPermissionChange != nil { - l = m.UserPermissionChange.Size() + if m.RequestJoin != nil { + l = m.RequestJoin.Size() n += 1 + l + sovAclrecord(uint64(l)) } return n } -func (m *AclContentValue_UserInvite) Size() (n int) { +func (m *AclContentValue_RequestAccept) Size() (n int) { if m == nil { return 0 } var l int _ = l - if m.UserInvite != nil { - l = m.UserInvite.Size() + if m.RequestAccept != nil { + l = m.RequestAccept.Size() n += 1 + l + sovAclrecord(uint64(l)) } return n } -func (m *AclContentValue_UserJoin) Size() (n int) { +func (m *AclContentValue_PermissionChange) Size() (n int) { if m == nil { return 0 } var l int _ = l - if m.UserJoin != nil { - l = m.UserJoin.Size() + if m.PermissionChange != nil { + l = m.PermissionChange.Size() + n += 1 + l + sovAclrecord(uint64(l)) + } + return n +} +func (m *AclContentValue_AccountRemove) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.AccountRemove != nil { + l = m.AccountRemove.Size() + n += 1 + l + sovAclrecord(uint64(l)) + } + return n +} +func (m *AclContentValue_ReadKeyChange) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ReadKeyChange != nil { + l = m.ReadKeyChange.Size() n += 1 + l + sovAclrecord(uint64(l)) } return n @@ -2275,179 +2484,6 @@ func (m *AclData) Size() (n int) { return n } -func (m *AclState) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.ReadKeyIds) > 0 { - for _, s := range m.ReadKeyIds { - l = len(s) - n += 1 + l + sovAclrecord(uint64(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)) - } - 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)) - } - 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 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.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.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 @@ -2938,38 +2974,6 @@ func (m *AclRecord) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ReadKeyId", 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.ReadKeyId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) } @@ -3246,6 +3250,977 @@ func (m *AclRoot) Unmarshal(dAtA []byte) error { } return nil } +func (m *AclAccountInvite) 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: AclAccountInvite: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AclAccountInvite: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InviteKey", 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.InviteKey = append(m.InviteKey[:0], dAtA[iNdEx:postIndex]...) + if m.InviteKey == nil { + m.InviteKey = []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 *AclAccountRequestJoin) 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: AclAccountRequestJoin: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AclAccountRequestJoin: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InviteIdentity", 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.InviteIdentity = append(m.InviteIdentity[:0], dAtA[iNdEx:postIndex]...) + if m.InviteIdentity == nil { + m.InviteIdentity = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InviteRecordId", 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.InviteRecordId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InviteIdentitySignature", 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.InviteIdentitySignature = append(m.InviteIdentitySignature[:0], dAtA[iNdEx:postIndex]...) + if m.InviteIdentitySignature == nil { + m.InviteIdentitySignature = []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 *AclAccountRequestAccept) 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: AclAccountRequestAccept: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AclAccountRequestAccept: 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 RequestRecordId", 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.RequestRecordId = string(dAtA[iNdEx:postIndex]) + 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[:0], dAtA[iNdEx:postIndex]...) + if m.EncryptedReadKeys == nil { + m.EncryptedReadKeys = []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 *AclAccountInviteRevoke) 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: AclAccountInviteRevoke: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AclAccountInviteRevoke: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InviteRecordId", 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.InviteRecordId = 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 *AclReadKeys) 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: AclReadKeys: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AclReadKeys: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ReadKey", 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.ReadKey = append(m.ReadKey, make([]byte, postIndex-iNdEx)) + copy(m.ReadKey[len(m.ReadKey)-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 *AclEncryptedReadKeys) 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: AclEncryptedReadKeys: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AclEncryptedReadKeys: 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 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[:0], dAtA[iNdEx:postIndex]...) + if m.EncryptedReadKeys == nil { + m.EncryptedReadKeys = []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 *AclAccountPermissionChange) 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: AclAccountPermissionChange: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AclAccountPermissionChange: 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 *AclReadKeyChange) 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: AclReadKeyChange: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AclReadKeyChange: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AccountKeys", 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.AccountKeys = append(m.AccountKeys, &AclEncryptedReadKeys{}) + if err := m.AccountKeys[len(m.AccountKeys)-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 *AclAccountRemove) 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: AclAccountRemove: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AclAccountRemove: 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 AccountKeys", 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.AccountKeys = append(m.AccountKeys, &AclEncryptedReadKeys{}) + if err := m.AccountKeys[len(m.AccountKeys)-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 *AclContentValue) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -3277,7 +4252,7 @@ func (m *AclContentValue) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserAdd", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Invite", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -3304,15 +4279,15 @@ func (m *AclContentValue) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - v := &AclUserAdd{} + v := &AclAccountInvite{} if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } - m.Value = &AclContentValue_UserAdd{v} + m.Value = &AclContentValue_Invite{v} iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserRemove", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field InviteRevoke", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -3339,15 +4314,15 @@ func (m *AclContentValue) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - v := &AclUserRemove{} + v := &AclAccountInviteRevoke{} if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } - m.Value = &AclContentValue_UserRemove{v} + m.Value = &AclContentValue_InviteRevoke{v} iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserPermissionChange", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RequestJoin", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -3374,15 +4349,15 @@ func (m *AclContentValue) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - v := &AclUserPermissionChange{} + v := &AclAccountRequestJoin{} if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } - m.Value = &AclContentValue_UserPermissionChange{v} + m.Value = &AclContentValue_RequestJoin{v} iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserInvite", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RequestAccept", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -3409,15 +4384,15 @@ func (m *AclContentValue) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - v := &AclUserInvite{} + v := &AclAccountRequestAccept{} if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } - m.Value = &AclContentValue_UserInvite{v} + m.Value = &AclContentValue_RequestAccept{v} iNdEx = postIndex case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserJoin", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PermissionChange", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -3444,11 +4419,81 @@ func (m *AclContentValue) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - v := &AclUserJoin{} + v := &AclAccountPermissionChange{} if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } - m.Value = &AclContentValue_UserJoin{v} + m.Value = &AclContentValue_PermissionChange{v} + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AccountRemove", 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 := &AclAccountRemove{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Value = &AclContentValue_AccountRemove{v} + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ReadKeyChange", 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 := &AclReadKeyChange{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Value = &AclContentValue_ReadKeyChange{v} iNdEx = postIndex default: iNdEx = preIndex @@ -3555,1147 +4600,6 @@ func (m *AclData) Unmarshal(dAtA []byte) error { } 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 != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ReadKeyIds", 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.ReadKeyIds = append(m.ReadKeyIds, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - 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 != 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 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 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 *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 != 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 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 *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 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 3: - 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 4: - 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 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 diff --git a/commonspace/object/acl/aclrecordproto/protos/aclrecord.proto b/commonspace/object/acl/aclrecordproto/protos/aclrecord.proto index c90cf116..2ca06396 100644 --- a/commonspace/object/acl/aclrecordproto/protos/aclrecord.proto +++ b/commonspace/object/acl/aclrecordproto/protos/aclrecord.proto @@ -2,6 +2,7 @@ syntax = "proto3"; package aclrecord; option go_package = "commonspace/object/acl/aclrecordproto"; +// RawAclRecord is a proto message containing the acl payload in bytes, signature of the account who added it and signature of the acceptor message RawAclRecord { bytes payload = 1; bytes signature = 2; @@ -9,19 +10,21 @@ message RawAclRecord { bytes acceptorSignature = 4; } +// RawAclRecordWithId is a raw record and the id for convenience message RawAclRecordWithId { bytes payload = 1; string id = 2; } +// AclRecord is a record containing the acl data message AclRecord { string prevId = 1; bytes identity = 2; bytes data = 3; - string readKeyId = 4; - int64 timestamp = 5; + int64 timestamp = 4; } +// AclRoot is a root of access control list message AclRoot { bytes identity = 1; bytes masterKey = 2; @@ -31,69 +34,83 @@ message AclRoot { bytes identitySignature = 6; } +// AclAccountInvite contains the public invite key, the private part of which is sent to the user directly +message AclAccountInvite { + bytes inviteKey = 1; +} + +// AclAccountRequestJoin contains the reference to the invite record and the data of the person who wants to join, confirmed by the private invite key +message AclAccountRequestJoin { + bytes inviteIdentity = 1; + string inviteRecordId = 2; + bytes inviteIdentitySignature = 3; +} + +// AclAccountRequestAccept contains the reference to join record and all read keys, encrypted with the identity of the requestor +message AclAccountRequestAccept { + bytes identity = 1; + string requestRecordId = 2; + bytes encryptedReadKeys = 3; +} + +// AclAccountInviteRevoke revokes the invite record +message AclAccountInviteRevoke { + string inviteRecordId = 1; +} + +// AclReadKeys are all read keys in Acl +message AclReadKeys { + repeated bytes readKey = 1; +} + +// AclEncryptedReadKeys are all keys for specific identity +message AclEncryptedReadKeys { + bytes identity = 1; + bytes encryptedReadKeys = 2; +} + +// AclAccountPermissionChange changes permissions of specific account +message AclAccountPermissionChange { + bytes identity = 1; + AclUserPermissions permissions = 2; +} + +// AclReadKeyChange changes the key for a space +message AclReadKeyChange { + repeated AclEncryptedReadKeys accountKeys = 1; +} + +// AclAccountRemove removes an account and changes read key for space +message AclAccountRemove { + bytes identity = 1; + repeated AclEncryptedReadKeys accountKeys = 2; +} + +// AclContentValue contains possible values for Acl message AclContentValue { oneof value { - AclUserAdd userAdd = 1; - AclUserRemove userRemove = 2; - AclUserPermissionChange userPermissionChange = 3; - AclUserInvite userInvite = 4; - AclUserJoin userJoin = 5; + AclAccountInvite invite = 1; + AclAccountInviteRevoke inviteRevoke = 2; + AclAccountRequestJoin requestJoin = 3; + AclAccountRequestAccept requestAccept = 4; + AclAccountPermissionChange permissionChange = 5; + AclAccountRemove accountRemove = 6; + AclReadKeyChange readKeyChange = 7; } } +// AclData contains different acl content message AclData { repeated AclContentValue aclContent = 1; } -message AclState { - repeated string readKeyIds = 1; - repeated AclUserState userStates = 2; - map invites = 3; -} - -message AclUserState { - bytes identity = 1; - AclUserPermissions permissions = 2; -} - -message AclUserAdd { - bytes identity = 1; - repeated bytes encryptedReadKeys = 2; - AclUserPermissions permissions = 3; -} - -message AclUserInvite { - bytes acceptPublicKey = 1; - repeated bytes encryptedReadKeys = 2; - AclUserPermissions permissions = 3; -} - -message AclUserJoin { - bytes identity = 1; - bytes acceptSignature = 2; - bytes acceptPubKey = 3; - repeated bytes encryptedReadKeys = 4; -} - -message AclUserRemove { - bytes identity = 1; - repeated AclReadKeyReplace readKeyReplaces = 2; -} - -message AclReadKeyReplace { - bytes identity = 1; - bytes encryptedReadKey = 2; -} - -message AclUserPermissionChange { - bytes identity = 1; - AclUserPermissions permissions = 2; -} - +// AclUserPermissions contains different possible user roles enum AclUserPermissions { - Admin = 0; - Writer = 1; - Reader = 2; + None = 0; + Owner = 1; + Admin = 2; + Writer = 3; + Reader = 4; } message AclSyncMessage { diff --git a/commonspace/object/acl/list/aclstate.go b/commonspace/object/acl/list/aclstate.go index a780c315..dde9ae23 100644 --- a/commonspace/object/acl/list/aclstate.go +++ b/commonspace/object/acl/list/aclstate.go @@ -3,6 +3,7 @@ package list import ( "errors" "fmt" + "github.com/anyproto/any-sync/app/logger" "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" "github.com/anyproto/any-sync/util/crypto" @@ -23,6 +24,7 @@ var ( ErrOldInvite = errors.New("invite is too old") ErrInsufficientPermissions = errors.New("insufficient permissions") ErrNoReadKey = errors.New("acl state doesn't have a read key") + ErrNoInvite = errors.New("can't delete invite record") ErrInvalidSignature = errors.New("signature is invalid") ErrIncorrectRoot = errors.New("incorrect root") ErrIncorrectRecordSequence = errors.New("incorrect prev id of a record") @@ -39,6 +41,7 @@ type AclState struct { userReadKeys map[string]crypto.SymKey userStates map[string]AclUserState statesAtRecord map[string][]AclUserState + inviteKeys map[string]crypto.PubKey key crypto.PrivKey pubKey crypto.PubKey keyStore crypto.KeyStorage @@ -110,17 +113,18 @@ func (st *AclState) applyRecord(record *AclRecord) (err error) { err = ErrIncorrectRecordSequence return } + // if the record is root record if record.Id == st.id { err = st.applyRoot(record) if err != nil { return } st.statesAtRecord[record.Id] = []AclUserState{ - {PubKey: record.Identity, Permissions: aclrecordproto.AclUserPermissions_Admin}, + st.userStates[mapKeyFromPubKey(record.Identity)], } return } - + // if the model is not cached if record.Model == nil { aclData := &aclrecordproto.AclData{} err = proto.Unmarshal(record.Data, aclData) @@ -129,18 +133,16 @@ func (st *AclState) applyRecord(record *AclRecord) (err error) { } record.Model = aclData } - + // applying records contents err = st.applyChangeData(record) if err != nil { return } - - // getting all states for users at record + // getting all states for users at record and saving them var states []AclUserState for _, state := range st.userStates { states = append(states, state) } - st.statesAtRecord[record.Id] = states return } @@ -156,7 +158,7 @@ func (st *AclState) applyRoot(record *AclRecord) (err error) { // adding user to the list userState := AclUserState{ PubKey: record.Identity, - Permissions: aclrecordproto.AclUserPermissions_Admin, + Permissions: AclPermissions(aclrecordproto.AclUserPermissions_Admin), } st.currentReadKeyId = record.ReadKeyId st.userStates[mapKeyFromPubKey(record.Identity)] = userState @@ -181,54 +183,35 @@ func (st *AclState) saveReadKeyFromRoot(record *AclRecord) (err error) { return } } - st.userReadKeys[record.Id] = readKey return } func (st *AclState) applyChangeData(record *AclRecord) (err error) { - defer func() { - if err != nil { - return - } - if record.ReadKeyId != st.currentReadKeyId { - st.totalReadKeys++ - st.currentReadKeyId = record.ReadKeyId - } - }() model := record.Model.(*aclrecordproto.AclData) - if !st.isUserJoin(model) { - // we check signature when we add this to the List, so no need to do it here - if _, exists := st.userStates[mapKeyFromPubKey(record.Identity)]; !exists { - err = ErrNoSuchUser - return - } - - // only Admins can do non-user join changes - if !st.HasPermission(record.Identity, aclrecordproto.AclUserPermissions_Admin) { - // TODO: add string encoding - err = fmt.Errorf("user %s must have admin permissions", record.Identity.Account()) - return - } + if !st.isUserJoin(model) && !st.Permissions(record.Identity).CanManageAccounts() { + return ErrInsufficientPermissions } - for _, ch := range model.GetAclContent() { if err = st.applyChangeContent(ch, record.Id); err != nil { log.Info("error while applying changes: %v; ignore", zap.Error(err)) return err } } - + if record.ReadKeyId != st.currentReadKeyId { + st.totalReadKeys++ + st.currentReadKeyId = record.ReadKeyId + } return nil } func (st *AclState) applyChangeContent(ch *aclrecordproto.AclContentValue, recordId string) error { switch { - case ch.GetUserPermissionChange() != nil: - return st.applyUserPermissionChange(ch.GetUserPermissionChange(), recordId) - case ch.GetUserAdd() != nil: - return st.applyUserAdd(ch.GetUserAdd(), recordId) - case ch.GetUserRemove() != nil: + case ch.GetPermissionChange() != nil: + return st.applyPermissionChange(ch.GetPermissionChange(), recordId) + case ch.GetInvite() != nil: + return st.applyInvite(ch.GetInvite(), recordId) + case ch.GetInviteRevoke() != nil: return st.applyUserRemove(ch.GetUserRemove(), recordId) case ch.GetUserInvite() != nil: return st.applyUserInvite(ch.GetUserInvite(), recordId) @@ -239,7 +222,7 @@ func (st *AclState) applyChangeContent(ch *aclrecordproto.AclContentValue, recor } } -func (st *AclState) applyUserPermissionChange(ch *aclrecordproto.AclUserPermissionChange, recordId string) error { +func (st *AclState) applyPermissionChange(ch *aclrecordproto.AclAccountPermissionChange, recordId string) error { chIdentity, err := st.keyStore.PubKeyFromProto(ch.Identity) if err != nil { return err @@ -248,13 +231,22 @@ func (st *AclState) applyUserPermissionChange(ch *aclrecordproto.AclUserPermissi if !exists { return ErrNoSuchUser } - - state.Permissions = ch.Permissions + state.Permissions = AclPermissions(ch.Permissions) return nil } -func (st *AclState) applyUserInvite(ch *aclrecordproto.AclUserInvite, recordId string) error { - // TODO: check old code and bring it back :-) +func (st *AclState) applyInvite(ch *aclrecordproto.AclAccountInvite, recordId string) error { + inviteKey, err := st.keyStore.PubKeyFromProto(ch.InviteKey) + if err != nil { + return err + } + st.inviteKeys[recordId] = inviteKey + return nil +} + +func (st *AclState) applyInviteRevoke(ch *aclrecordproto.AclAccountInviteRevoke, recordId string) error { + + delete(st.inviteKeys, ch.InviteRecordId) return nil } @@ -283,13 +275,12 @@ func (st *AclState) decryptReadKey(msg []byte) (crypto.SymKey, error) { return key, nil } -func (st *AclState) HasPermission(identity crypto.PubKey, permission aclrecordproto.AclUserPermissions) bool { +func (st *AclState) Permissions(identity crypto.PubKey) AclPermissions { state, exists := st.userStates[mapKeyFromPubKey(identity)] if !exists { - return false + return AclPermissions(aclrecordproto.AclUserPermissions_None) } - - return state.Permissions == permission + return state.Permissions } func (st *AclState) isUserJoin(data *aclrecordproto.AclData) bool { @@ -297,10 +288,6 @@ func (st *AclState) isUserJoin(data *aclrecordproto.AclData) bool { return data.GetAclContent() != nil && data.GetAclContent()[0].GetUserJoin() != nil } -func (st *AclState) isUserAdd(data *aclrecordproto.AclData, identity []byte) bool { - return false -} - func (st *AclState) UserStates() map[string]AclUserState { return st.userStates } diff --git a/commonspace/object/acl/list/models.go b/commonspace/object/acl/list/models.go index 7375c7c6..97b19ac5 100644 --- a/commonspace/object/acl/list/models.go +++ b/commonspace/object/acl/list/models.go @@ -18,5 +18,31 @@ type AclRecord struct { type AclUserState struct { PubKey crypto.PubKey - Permissions aclrecordproto.AclUserPermissions + Permissions AclPermissions +} + +type AclPermissions aclrecordproto.AclUserPermissions + +func (p AclPermissions) CanWrite() bool { + switch aclrecordproto.AclUserPermissions(p) { + case aclrecordproto.AclUserPermissions_Admin: + return true + case aclrecordproto.AclUserPermissions_Writer: + return true + case aclrecordproto.AclUserPermissions_Owner: + return true + default: + return false + } +} + +func (p AclPermissions) CanManageAccounts() bool { + switch aclrecordproto.AclUserPermissions(p) { + case aclrecordproto.AclUserPermissions_Admin: + return true + case aclrecordproto.AclUserPermissions_Owner: + return true + default: + return false + } } diff --git a/commonspace/object/acl/list/validator.go b/commonspace/object/acl/list/validator.go new file mode 100644 index 00000000..b4972732 --- /dev/null +++ b/commonspace/object/acl/list/validator.go @@ -0,0 +1,5 @@ +package list + +type Validator interface { + Validate() +} diff --git a/commonspace/object/tree/objecttree/objecttree.go b/commonspace/object/tree/objecttree/objecttree.go index 56a72ff9..2733530f 100644 --- a/commonspace/object/tree/objecttree/objecttree.go +++ b/commonspace/object/tree/objecttree/objecttree.go @@ -4,11 +4,11 @@ package objecttree import ( "context" "errors" - "github.com/anyproto/any-sync/util/crypto" "sync" "time" - "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" + "github.com/anyproto/any-sync/util/crypto" + "github.com/anyproto/any-sync/commonspace/object/acl/list" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" "github.com/anyproto/any-sync/commonspace/object/tree/treestorage" @@ -248,9 +248,7 @@ func (ot *objectTree) prepareBuilderContent(content SignableChangeContent) (cnt pubKey = content.Key.GetPublic() readKeyId string ) - canWrite := state.HasPermission(pubKey, aclrecordproto.AclUserPermissions_Writer) || - state.HasPermission(pubKey, aclrecordproto.AclUserPermissions_Admin) - if !canWrite { + if !state.Permissions(pubKey).CanWrite() { err = list.ErrInsufficientPermissions return } diff --git a/commonspace/object/tree/objecttree/objecttreevalidator.go b/commonspace/object/tree/objecttree/objecttreevalidator.go index 59b74d58..7515042b 100644 --- a/commonspace/object/tree/objecttree/objecttreevalidator.go +++ b/commonspace/object/tree/objecttree/objecttreevalidator.go @@ -3,7 +3,7 @@ package objecttree import ( "context" "fmt" - "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" + "github.com/anyproto/any-sync/commonspace/object/acl/list" "github.com/anyproto/any-sync/commonspace/object/tree/treestorage" "github.com/anyproto/any-sync/util/slice" @@ -52,20 +52,18 @@ func (v *objectTreeValidator) ValidateNewChanges(tree *Tree, aclList list.AclLis func (v *objectTreeValidator) validateChange(tree *Tree, aclList list.AclList, c *Change) (err error) { var ( - perm list.AclUserState - state = aclList.AclState() + userState list.AclUserState + state = aclList.AclState() ) // checking if the user could write - perm, err = state.StateAtRecord(c.AclHeadId, c.Identity) + userState, err = state.StateAtRecord(c.AclHeadId, c.Identity) if err != nil { return } - - if perm.Permissions != aclrecordproto.AclUserPermissions_Writer && perm.Permissions != aclrecordproto.AclUserPermissions_Admin { + if !userState.Permissions.CanWrite() { err = list.ErrInsufficientPermissions return } - if c.Id == tree.RootId() { return } diff --git a/commonspace/spacesyncproto/spacesync_drpc.pb.go b/commonspace/spacesyncproto/spacesync_drpc.pb.go index 11e5d715..f9c7abae 100644 --- a/commonspace/spacesyncproto/spacesync_drpc.pb.go +++ b/commonspace/spacesyncproto/spacesync_drpc.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-go-drpc. DO NOT EDIT. -// protoc-gen-go-drpc version: v0.0.33 +// protoc-gen-go-drpc version: v0.0.32 // source: commonspace/spacesyncproto/protos/spacesync.proto package spacesyncproto @@ -103,10 +103,6 @@ type drpcSpaceSync_ObjectSyncStreamClient struct { drpc.Stream } -func (x *drpcSpaceSync_ObjectSyncStreamClient) GetStream() drpc.Stream { - return x.Stream -} - func (x *drpcSpaceSync_ObjectSyncStreamClient) Send(m *ObjectSyncMessage) error { return x.MsgSend(m, drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto{}) } diff --git a/coordinator/coordinatorproto/coordinator_drpc.pb.go b/coordinator/coordinatorproto/coordinator_drpc.pb.go index 0ed69ea2..75e73a7b 100644 --- a/coordinator/coordinatorproto/coordinator_drpc.pb.go +++ b/coordinator/coordinatorproto/coordinator_drpc.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-go-drpc. DO NOT EDIT. -// protoc-gen-go-drpc version: v0.0.33 +// protoc-gen-go-drpc version: v0.0.32 // source: coordinator/coordinatorproto/protos/coordinator.proto package coordinatorproto diff --git a/net/peer/peer.go b/net/peer/peer.go index c8a54a43..6b6a7666 100644 --- a/net/peer/peer.go +++ b/net/peer/peer.go @@ -3,6 +3,11 @@ package peer import ( "context" + "io" + "net" + "sync" + "time" + "github.com/anyproto/any-sync/app/logger" "github.com/anyproto/any-sync/app/ocache" "github.com/anyproto/any-sync/net/connutil" @@ -11,15 +16,11 @@ import ( "github.com/anyproto/any-sync/net/secureservice/handshake/handshakeproto" "github.com/anyproto/any-sync/net/transport" "go.uber.org/zap" - "io" - "net" "storj.io/drpc" "storj.io/drpc/drpcconn" "storj.io/drpc/drpcmanager" "storj.io/drpc/drpcstream" "storj.io/drpc/drpcwire" - "sync" - "time" ) var log = logger.NewNamed("common.net.peer") @@ -200,6 +201,11 @@ func (p *peer) TryClose(objectTTL time.Duration) (res bool, err error) { return false, nil } +// 70 stream -> 1 subconn +// 62 request -> 1 subconn +// 2600 subconn (2400 non active -> 5 min) + +// 2 5min connect func (p *peer) gc(ttl time.Duration) (aliveCount int) { p.mu.Lock() defer p.mu.Unlock() diff --git a/net/streampool/testservice/testservice_drpc.pb.go b/net/streampool/testservice/testservice_drpc.pb.go index cfe5bce9..f50fdbe7 100644 --- a/net/streampool/testservice/testservice_drpc.pb.go +++ b/net/streampool/testservice/testservice_drpc.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-go-drpc. DO NOT EDIT. -// protoc-gen-go-drpc version: v0.0.33 +// protoc-gen-go-drpc version: v0.0.32 // source: net/streampool/testservice/protos/testservice.proto package testservice @@ -72,10 +72,6 @@ type drpcTest_TestStreamClient struct { drpc.Stream } -func (x *drpcTest_TestStreamClient) GetStream() drpc.Stream { - return x.Stream -} - func (x *drpcTest_TestStreamClient) Send(m *StreamMessage) error { return x.MsgSend(m, drpcEncoding_File_net_streampool_testservice_protos_testservice_proto{}) } From 2c573138e6aa19d03b230b3798d05a32d5503a92 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Thu, 22 Jun 2023 19:22:56 +0200 Subject: [PATCH 073/123] Correctly removing changes which we don't need to send --- .../object/tree/objecttree/rawloader.go | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/commonspace/object/tree/objecttree/rawloader.go b/commonspace/object/tree/objecttree/rawloader.go index 894a6494..e3d7df25 100644 --- a/commonspace/object/tree/objecttree/rawloader.go +++ b/commonspace/object/tree/objecttree/rawloader.go @@ -2,10 +2,11 @@ package objecttree import ( "context" + "time" + "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" "github.com/anyproto/any-sync/commonspace/object/tree/treestorage" "github.com/anyproto/any-sync/util/slice" - "time" ) type rawChangeLoader struct { @@ -22,6 +23,7 @@ type rawCacheEntry struct { change *Change rawChange *treechangeproto.RawTreeChangeWithId position int + removed bool } func newStorageLoader(treeStorage treestorage.TreeStorage, changeBuilder ChangeBuilder) *rawChangeLoader { @@ -126,7 +128,6 @@ func (r *rawChangeLoader) loadFromStorage(commonSnapshot string, heads, breakpoi if err != nil { continue } - entry.position = -1 r.cache[b] = entry existingBreakpoints = append(existingBreakpoints, b) } @@ -135,8 +136,7 @@ func (r *rawChangeLoader) loadFromStorage(commonSnapshot string, heads, breakpoi dfs := func( commonSnapshot string, heads []string, - startCounter int, - shouldVisit func(counter int, mapExists bool) bool, + shouldVisit func(entry rawCacheEntry, mapExists bool) bool, visit func(entry rawCacheEntry) rawCacheEntry) bool { // resetting stack @@ -150,7 +150,7 @@ func (r *rawChangeLoader) loadFromStorage(commonSnapshot string, heads, breakpoi r.idStack = r.idStack[:len(r.idStack)-1] entry, exists := r.cache[id] - if !shouldVisit(entry.position, exists) { + if !shouldVisit(entry, exists) { continue } if id == commonSnapshot { @@ -159,7 +159,6 @@ func (r *rawChangeLoader) loadFromStorage(commonSnapshot string, heads, breakpoi } if !exists { entry, err = r.loadEntry(id) - entry.position = -1 if err != nil { continue } @@ -174,7 +173,7 @@ func (r *rawChangeLoader) loadFromStorage(commonSnapshot string, heads, breakpoi break } prevEntry, exists := r.cache[prev] - if !shouldVisit(prevEntry.position, exists) { + if !shouldVisit(prevEntry, exists) { continue } r.idStack = append(r.idStack, prev) @@ -187,8 +186,8 @@ func (r *rawChangeLoader) loadFromStorage(commonSnapshot string, heads, breakpoi r.idStack = append(r.idStack, heads...) var buffer []*treechangeproto.RawTreeChangeWithId - rootVisited := dfs(commonSnapshot, heads, 0, - func(counter int, mapExists bool) bool { + rootVisited := dfs(commonSnapshot, heads, + func(_ rawCacheEntry, mapExists bool) bool { return !mapExists }, func(entry rawCacheEntry) rawCacheEntry { @@ -213,11 +212,13 @@ func (r *rawChangeLoader) loadFromStorage(commonSnapshot string, heads, breakpoi } // marking all visited as nil - dfs(commonSnapshot, existingBreakpoints, len(buffer), - func(counter int, mapExists bool) bool { - return !mapExists || counter < len(buffer) + dfs(commonSnapshot, existingBreakpoints, + func(entry rawCacheEntry, mapExists bool) bool { + // only going through already loaded changes + return mapExists && !entry.removed }, func(entry rawCacheEntry) rawCacheEntry { + entry.removed = true if entry.position != -1 { buffer[entry.position] = nil } @@ -248,6 +249,7 @@ func (r *rawChangeLoader) loadEntry(id string) (entry rawCacheEntry, err error) entry = rawCacheEntry{ change: change, rawChange: rawChange, + position: -1, } return } From f9bab4d51dfb06f2dab172ffd2ce4b4a8d321ad6 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Fri, 23 Jun 2023 14:50:09 +0200 Subject: [PATCH 074/123] Add content validator --- .../object/acl/aclrecordproto/aclrecord.pb.go | 444 +++++++++++++++--- .../acl/aclrecordproto/protos/aclrecord.proto | 7 + commonspace/object/acl/list/aclstate.go | 39 +- commonspace/object/acl/list/models.go | 5 + commonspace/object/acl/list/validator.go | 146 +++++- 5 files changed, 555 insertions(+), 86 deletions(-) diff --git a/commonspace/object/acl/aclrecordproto/aclrecord.pb.go b/commonspace/object/acl/aclrecordproto/aclrecord.pb.go index 8d185378..d7abb519 100644 --- a/commonspace/object/acl/aclrecordproto/aclrecord.pb.go +++ b/commonspace/object/acl/aclrecordproto/aclrecord.pb.go @@ -383,6 +383,7 @@ type AclAccountRequestJoin struct { InviteIdentity []byte `protobuf:"bytes,1,opt,name=inviteIdentity,proto3" json:"inviteIdentity,omitempty"` InviteRecordId string `protobuf:"bytes,2,opt,name=inviteRecordId,proto3" json:"inviteRecordId,omitempty"` InviteIdentitySignature []byte `protobuf:"bytes,3,opt,name=inviteIdentitySignature,proto3" json:"inviteIdentitySignature,omitempty"` + Metadata []byte `protobuf:"bytes,4,opt,name=metadata,proto3" json:"metadata,omitempty"` } func (m *AclAccountRequestJoin) Reset() { *m = AclAccountRequestJoin{} } @@ -439,6 +440,13 @@ func (m *AclAccountRequestJoin) GetInviteIdentitySignature() []byte { return nil } +func (m *AclAccountRequestJoin) GetMetadata() []byte { + if m != nil { + return m.Metadata + } + return nil +} + // AclAccountRequestAccept contains the reference to join record and all read keys, encrypted with the identity of the requestor type AclAccountRequestAccept struct { Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` @@ -500,6 +508,51 @@ func (m *AclAccountRequestAccept) GetEncryptedReadKeys() []byte { return nil } +// AclAccountRequestDecline contains the reference to join record +type AclAccountRequestDecline struct { + RequestRecordId string `protobuf:"bytes,1,opt,name=requestRecordId,proto3" json:"requestRecordId,omitempty"` +} + +func (m *AclAccountRequestDecline) Reset() { *m = AclAccountRequestDecline{} } +func (m *AclAccountRequestDecline) String() string { return proto.CompactTextString(m) } +func (*AclAccountRequestDecline) ProtoMessage() {} +func (*AclAccountRequestDecline) Descriptor() ([]byte, []int) { + return fileDescriptor_c8e9f754f34e929b, []int{7} +} +func (m *AclAccountRequestDecline) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AclAccountRequestDecline) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AclAccountRequestDecline.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 *AclAccountRequestDecline) XXX_Merge(src proto.Message) { + xxx_messageInfo_AclAccountRequestDecline.Merge(m, src) +} +func (m *AclAccountRequestDecline) XXX_Size() int { + return m.Size() +} +func (m *AclAccountRequestDecline) XXX_DiscardUnknown() { + xxx_messageInfo_AclAccountRequestDecline.DiscardUnknown(m) +} + +var xxx_messageInfo_AclAccountRequestDecline proto.InternalMessageInfo + +func (m *AclAccountRequestDecline) GetRequestRecordId() string { + if m != nil { + return m.RequestRecordId + } + return "" +} + // AclAccountInviteRevoke revokes the invite record type AclAccountInviteRevoke struct { InviteRecordId string `protobuf:"bytes,1,opt,name=inviteRecordId,proto3" json:"inviteRecordId,omitempty"` @@ -509,7 +562,7 @@ func (m *AclAccountInviteRevoke) Reset() { *m = AclAccountInviteRevoke{} func (m *AclAccountInviteRevoke) String() string { return proto.CompactTextString(m) } func (*AclAccountInviteRevoke) ProtoMessage() {} func (*AclAccountInviteRevoke) Descriptor() ([]byte, []int) { - return fileDescriptor_c8e9f754f34e929b, []int{7} + return fileDescriptor_c8e9f754f34e929b, []int{8} } func (m *AclAccountInviteRevoke) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -554,7 +607,7 @@ func (m *AclReadKeys) Reset() { *m = AclReadKeys{} } func (m *AclReadKeys) String() string { return proto.CompactTextString(m) } func (*AclReadKeys) ProtoMessage() {} func (*AclReadKeys) Descriptor() ([]byte, []int) { - return fileDescriptor_c8e9f754f34e929b, []int{8} + return fileDescriptor_c8e9f754f34e929b, []int{9} } func (m *AclReadKeys) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -600,7 +653,7 @@ func (m *AclEncryptedReadKeys) Reset() { *m = AclEncryptedReadKeys{} } func (m *AclEncryptedReadKeys) String() string { return proto.CompactTextString(m) } func (*AclEncryptedReadKeys) ProtoMessage() {} func (*AclEncryptedReadKeys) Descriptor() ([]byte, []int) { - return fileDescriptor_c8e9f754f34e929b, []int{9} + return fileDescriptor_c8e9f754f34e929b, []int{10} } func (m *AclEncryptedReadKeys) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -653,7 +706,7 @@ func (m *AclAccountPermissionChange) Reset() { *m = AclAccountPermission func (m *AclAccountPermissionChange) String() string { return proto.CompactTextString(m) } func (*AclAccountPermissionChange) ProtoMessage() {} func (*AclAccountPermissionChange) Descriptor() ([]byte, []int) { - return fileDescriptor_c8e9f754f34e929b, []int{10} + return fileDescriptor_c8e9f754f34e929b, []int{11} } func (m *AclAccountPermissionChange) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -705,7 +758,7 @@ func (m *AclReadKeyChange) Reset() { *m = AclReadKeyChange{} } func (m *AclReadKeyChange) String() string { return proto.CompactTextString(m) } func (*AclReadKeyChange) ProtoMessage() {} func (*AclReadKeyChange) Descriptor() ([]byte, []int) { - return fileDescriptor_c8e9f754f34e929b, []int{11} + return fileDescriptor_c8e9f754f34e929b, []int{12} } func (m *AclReadKeyChange) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -751,7 +804,7 @@ func (m *AclAccountRemove) Reset() { *m = AclAccountRemove{} } func (m *AclAccountRemove) String() string { return proto.CompactTextString(m) } func (*AclAccountRemove) ProtoMessage() {} func (*AclAccountRemove) Descriptor() ([]byte, []int) { - return fileDescriptor_c8e9f754f34e929b, []int{12} + return fileDescriptor_c8e9f754f34e929b, []int{13} } func (m *AclAccountRemove) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -805,6 +858,7 @@ type AclContentValue struct { // *AclContentValue_PermissionChange // *AclContentValue_AccountRemove // *AclContentValue_ReadKeyChange + // *AclContentValue_RequestDecline Value isAclContentValue_Value `protobuf_oneof:"value"` } @@ -812,7 +866,7 @@ 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_c8e9f754f34e929b, []int{13} + return fileDescriptor_c8e9f754f34e929b, []int{14} } func (m *AclContentValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -868,6 +922,9 @@ type AclContentValue_AccountRemove struct { type AclContentValue_ReadKeyChange struct { ReadKeyChange *AclReadKeyChange `protobuf:"bytes,7,opt,name=readKeyChange,proto3,oneof" json:"readKeyChange,omitempty"` } +type AclContentValue_RequestDecline struct { + RequestDecline *AclAccountRequestDecline `protobuf:"bytes,8,opt,name=requestDecline,proto3,oneof" json:"requestDecline,omitempty"` +} func (*AclContentValue_Invite) isAclContentValue_Value() {} func (*AclContentValue_InviteRevoke) isAclContentValue_Value() {} @@ -876,6 +933,7 @@ func (*AclContentValue_RequestAccept) isAclContentValue_Value() {} func (*AclContentValue_PermissionChange) isAclContentValue_Value() {} func (*AclContentValue_AccountRemove) isAclContentValue_Value() {} func (*AclContentValue_ReadKeyChange) isAclContentValue_Value() {} +func (*AclContentValue_RequestDecline) isAclContentValue_Value() {} func (m *AclContentValue) GetValue() isAclContentValue_Value { if m != nil { @@ -933,6 +991,13 @@ func (m *AclContentValue) GetReadKeyChange() *AclReadKeyChange { return nil } +func (m *AclContentValue) GetRequestDecline() *AclAccountRequestDecline { + if x, ok := m.GetValue().(*AclContentValue_RequestDecline); ok { + return x.RequestDecline + } + return nil +} + // XXX_OneofWrappers is for the internal use of the proto package. func (*AclContentValue) XXX_OneofWrappers() []interface{} { return []interface{}{ @@ -943,6 +1008,7 @@ func (*AclContentValue) XXX_OneofWrappers() []interface{} { (*AclContentValue_PermissionChange)(nil), (*AclContentValue_AccountRemove)(nil), (*AclContentValue_ReadKeyChange)(nil), + (*AclContentValue_RequestDecline)(nil), } } @@ -955,7 +1021,7 @@ 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_c8e9f754f34e929b, []int{14} + return fileDescriptor_c8e9f754f34e929b, []int{15} } func (m *AclData) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -999,7 +1065,7 @@ 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_c8e9f754f34e929b, []int{15} + return fileDescriptor_c8e9f754f34e929b, []int{16} } func (m *AclSyncMessage) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1047,7 +1113,7 @@ 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_c8e9f754f34e929b, []int{16} + return fileDescriptor_c8e9f754f34e929b, []int{17} } func (m *AclSyncContentValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1117,7 +1183,7 @@ 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_c8e9f754f34e929b, []int{17} + return fileDescriptor_c8e9f754f34e929b, []int{18} } func (m *AclAddRecords) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1162,6 +1228,7 @@ func init() { proto.RegisterType((*AclAccountInvite)(nil), "aclrecord.AclAccountInvite") proto.RegisterType((*AclAccountRequestJoin)(nil), "aclrecord.AclAccountRequestJoin") proto.RegisterType((*AclAccountRequestAccept)(nil), "aclrecord.AclAccountRequestAccept") + proto.RegisterType((*AclAccountRequestDecline)(nil), "aclrecord.AclAccountRequestDecline") proto.RegisterType((*AclAccountInviteRevoke)(nil), "aclrecord.AclAccountInviteRevoke") proto.RegisterType((*AclReadKeys)(nil), "aclrecord.AclReadKeys") proto.RegisterType((*AclEncryptedReadKeys)(nil), "aclrecord.AclEncryptedReadKeys") @@ -1180,64 +1247,67 @@ func init() { } var fileDescriptor_c8e9f754f34e929b = []byte{ - // 912 bytes of a gzipped FileDescriptorProto + // 958 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xdd, 0x6e, 0x1b, 0x45, - 0x14, 0xde, 0x75, 0x1c, 0xbb, 0x3e, 0x9b, 0xa4, 0xcb, 0x00, 0xad, 0x15, 0x8a, 0x09, 0x23, 0x15, - 0xaa, 0x0a, 0x35, 0xc8, 0x08, 0x51, 0x21, 0x44, 0xd9, 0xa6, 0x15, 0x76, 0xf8, 0xd5, 0x44, 0xa5, - 0x52, 0xaf, 0x98, 0xce, 0x8e, 0xd2, 0x85, 0xdd, 0x9d, 0xcd, 0xec, 0xc4, 0x95, 0x9f, 0x01, 0x21, - 0xf1, 0x08, 0xf0, 0x36, 0x5c, 0xf6, 0x06, 0x89, 0x4b, 0x94, 0xbc, 0x08, 0x9a, 0x99, 0x5d, 0xef, - 0x9f, 0x63, 0x21, 0x2e, 0x12, 0xcf, 0x9c, 0xf9, 0xce, 0x77, 0xbe, 0xf3, 0x33, 0x63, 0xc3, 0x67, - 0x4c, 0x24, 0x89, 0x48, 0xf3, 0x8c, 0x32, 0x7e, 0x28, 0x9e, 0xff, 0xc4, 0x99, 0x3a, 0xa4, 0x2c, - 0xd6, 0x7f, 0x92, 0x33, 0x21, 0xc3, 0x4c, 0x0a, 0x25, 0x0e, 0xcd, 0xff, 0xbc, 0xb2, 0xde, 0x33, - 0x06, 0x34, 0x5a, 0x19, 0xf0, 0xef, 0x2e, 0xec, 0x10, 0xfa, 0x32, 0x60, 0x31, 0x31, 0x06, 0x34, - 0x86, 0x61, 0x46, 0x97, 0xb1, 0xa0, 0xe1, 0xd8, 0x3d, 0x70, 0xef, 0xec, 0x90, 0x72, 0x8b, 0x6e, - 0xc1, 0x28, 0x8f, 0x4e, 0x53, 0xaa, 0xce, 0x25, 0x1f, 0xf7, 0xcc, 0x59, 0x65, 0x40, 0x77, 0xc1, - 0xa7, 0x8c, 0xf1, 0x4c, 0x09, 0x39, 0x0f, 0x79, 0xaa, 0x22, 0xb5, 0x1c, 0x6f, 0x19, 0x50, 0xc7, - 0x8e, 0x3e, 0x80, 0xd7, 0x4a, 0xdb, 0xc9, 0x8a, 0xb1, 0x6f, 0xc0, 0xdd, 0x03, 0xfc, 0x39, 0xa0, - 0xba, 0xc2, 0xa7, 0x91, 0x7a, 0x31, 0xdf, 0xa4, 0x73, 0x0f, 0x7a, 0x51, 0x68, 0x04, 0x8e, 0x48, - 0x2f, 0x0a, 0xf1, 0x19, 0x8c, 0xaa, 0xf4, 0x6e, 0xc0, 0x20, 0x93, 0x7c, 0x31, 0xb7, 0x5e, 0x23, - 0x52, 0xec, 0xd0, 0x3e, 0x5c, 0x8b, 0x4a, 0xd9, 0x36, 0xb7, 0xd5, 0x1e, 0x21, 0xe8, 0x87, 0x54, - 0xd1, 0x22, 0x1d, 0xb3, 0xd6, 0xc5, 0x50, 0x51, 0xc2, 0x73, 0x45, 0x93, 0xcc, 0x48, 0xdf, 0x22, - 0x95, 0x01, 0xff, 0xe5, 0xc2, 0x50, 0xc7, 0x14, 0x42, 0x35, 0x98, 0xdd, 0x16, 0xf3, 0x2d, 0x18, - 0x25, 0x34, 0x57, 0x5c, 0x7e, 0xc5, 0xcb, 0xb0, 0x95, 0x41, 0xa7, 0x68, 0x1a, 0x3c, 0x0f, 0x4d, - 0xe8, 0x11, 0x29, 0xb7, 0xba, 0xd8, 0x3c, 0x65, 0x72, 0x99, 0x29, 0x1e, 0x12, 0x4e, 0x43, 0xed, - 0x6e, 0xeb, 0xd7, 0xb1, 0x37, 0x95, 0x6e, 0xb7, 0x94, 0xea, 0x56, 0x94, 0x6a, 0xaa, 0x56, 0x0c, - 0x6c, 0x2b, 0x3a, 0x07, 0xf8, 0x43, 0xf0, 0x03, 0x16, 0x07, 0x8c, 0x89, 0xf3, 0x54, 0xcd, 0xd3, - 0x45, 0xa4, 0xb8, 0xe6, 0x8f, 0xcc, 0x4a, 0x8b, 0xb0, 0x09, 0x56, 0x06, 0xfc, 0x87, 0x0b, 0x6f, - 0x56, 0x2e, 0x84, 0x9f, 0x9d, 0xf3, 0x5c, 0x1d, 0x8b, 0x28, 0x45, 0xef, 0xc1, 0x9e, 0x85, 0xcd, - 0x9b, 0xd5, 0x69, 0x59, 0x2b, 0x9c, 0xed, 0xe0, 0xbc, 0x6c, 0x6d, 0xcb, 0x8a, 0xee, 0xc3, 0xcd, - 0xa6, 0x67, 0x95, 0x8f, 0x6d, 0xdc, 0x55, 0xc7, 0xf8, 0x57, 0x17, 0x6e, 0x76, 0x34, 0x06, 0x66, - 0x0e, 0x37, 0x76, 0xef, 0x0e, 0x5c, 0x97, 0x16, 0xdc, 0x92, 0xd6, 0x36, 0xeb, 0x2a, 0xb7, 0xfb, - 0x92, 0x17, 0xaa, 0xba, 0x07, 0xf8, 0x0b, 0xb8, 0xd1, 0xae, 0x32, 0xe1, 0x0b, 0xf1, 0x33, 0x5f, - 0x53, 0x0b, 0x77, 0x5d, 0x2d, 0xf0, 0xfb, 0xe0, 0x99, 0x91, 0xb7, 0x84, 0x7a, 0x90, 0x64, 0x31, - 0x25, 0xee, 0xc1, 0x96, 0xbe, 0x2b, 0xc5, 0x16, 0xff, 0x08, 0x6f, 0x04, 0x2c, 0x7e, 0xdc, 0x96, - 0xb0, 0x31, 0xed, 0xb5, 0xc9, 0xf4, 0xae, 0x4a, 0x66, 0x09, 0xfb, 0x55, 0x32, 0xdf, 0x73, 0x99, - 0x44, 0x79, 0x1e, 0x89, 0xf4, 0xe8, 0x05, 0x4d, 0x4f, 0xf9, 0xc6, 0x38, 0x0f, 0xc0, 0xcb, 0x56, - 0x78, 0x1b, 0x61, 0x6f, 0xfa, 0xf6, 0xbd, 0xea, 0x31, 0x0b, 0x58, 0xfc, 0x24, 0xe7, 0xb2, 0x22, - 0xcd, 0x49, 0xdd, 0x03, 0x3f, 0x31, 0xd3, 0x5a, 0x28, 0x29, 0x02, 0x06, 0xe0, 0x51, 0xab, 0xc5, - 0xc8, 0xd6, 0xe5, 0xf0, 0xa6, 0xef, 0x34, 0x49, 0x3b, 0xe5, 0x20, 0x75, 0x1f, 0x7c, 0x56, 0xbf, - 0x04, 0x84, 0x27, 0x62, 0xb1, 0x39, 0x8f, 0x56, 0xc8, 0xde, 0xff, 0x08, 0xf9, 0x4b, 0x1f, 0xae, - 0x07, 0x2c, 0x3e, 0x12, 0xa9, 0xe2, 0xa9, 0xfa, 0x81, 0xc6, 0xe7, 0x1c, 0x7d, 0x0c, 0x03, 0xdb, - 0x75, 0x13, 0xd0, 0x9b, 0xbe, 0xd5, 0x64, 0x6c, 0x8c, 0xcf, 0xcc, 0x21, 0x05, 0x18, 0x7d, 0x09, - 0x3b, 0x51, 0x6d, 0xa4, 0x4c, 0x59, 0xbd, 0xe9, 0xbb, 0x1b, 0x9c, 0x2d, 0x70, 0xe6, 0x90, 0x86, - 0x23, 0x7a, 0x04, 0x9e, 0xac, 0xae, 0xb3, 0x99, 0x66, 0x6f, 0x7a, 0xb0, 0x96, 0xa7, 0x76, 0xed, - 0x67, 0x0e, 0xa9, 0xbb, 0xa1, 0x63, 0xd8, 0x95, 0xf5, 0x0b, 0x67, 0x9e, 0x31, 0x6f, 0x8a, 0x37, - 0xf1, 0x58, 0xe4, 0xcc, 0x21, 0x4d, 0x57, 0x74, 0x02, 0x7e, 0xd6, 0x1a, 0x30, 0xf3, 0xe0, 0x79, - 0xd3, 0xdb, 0x6b, 0xe9, 0xda, 0xd3, 0x38, 0x73, 0x48, 0x87, 0x00, 0x1d, 0xc1, 0x2e, 0xad, 0xb7, - 0xda, 0x3c, 0x8e, 0x57, 0x55, 0xdb, 0x42, 0xb4, 0xb2, 0x86, 0x8f, 0x26, 0x91, 0xf5, 0x31, 0x1c, - 0x0f, 0xd7, 0x91, 0x34, 0x26, 0xd5, 0xa6, 0x57, 0x33, 0x3c, 0x1c, 0xc2, 0xf6, 0x42, 0x77, 0x1e, - 0x3f, 0x36, 0x5f, 0x2e, 0x8f, 0xf4, 0xd7, 0xd0, 0xa7, 0x00, 0x74, 0x35, 0x17, 0xc5, 0x34, 0xef, - 0x37, 0x59, 0xeb, 0x43, 0x43, 0x6a, 0x68, 0x7c, 0x0c, 0x7b, 0x01, 0x8b, 0x4f, 0x96, 0x29, 0xfb, - 0x86, 0xe7, 0x39, 0x3d, 0xe5, 0xe8, 0x3e, 0x0c, 0xd9, 0x8a, 0x4a, 0x0b, 0x9c, 0x34, 0xa9, 0x34, - 0xb6, 0x41, 0x57, 0xc2, 0xf1, 0x33, 0x78, 0x7d, 0xcd, 0xb9, 0x91, 0x17, 0x86, 0xf6, 0x59, 0xca, - 0x0b, 0xce, 0x71, 0xab, 0x72, 0xab, 0xf3, 0x99, 0x43, 0x6a, 0xe8, 0x2a, 0xdd, 0x19, 0xec, 0x36, - 0x70, 0xe8, 0x13, 0xfd, 0x9c, 0x95, 0x94, 0x3a, 0xe3, 0xfa, 0xa3, 0xd0, 0xfd, 0xa9, 0x40, 0x4a, - 0xf4, 0xdd, 0xaf, 0x01, 0x75, 0xdf, 0x0c, 0x74, 0x0d, 0xfa, 0xdf, 0x8a, 0x94, 0xfb, 0x0e, 0x1a, - 0xc1, 0xf6, 0x77, 0x2f, 0x53, 0x2e, 0x7d, 0x57, 0x2f, 0x83, 0x30, 0x89, 0x52, 0xbf, 0x87, 0x00, - 0x06, 0x4f, 0x65, 0xa4, 0xb8, 0xf4, 0xb7, 0xf4, 0x5a, 0x77, 0x89, 0x4b, 0xbf, 0xff, 0xf0, 0xc1, - 0x9f, 0x17, 0x13, 0xf7, 0xd5, 0xc5, 0xc4, 0xfd, 0xe7, 0x62, 0xe2, 0xfe, 0x76, 0x39, 0x71, 0x5e, - 0x5d, 0x4e, 0x9c, 0xbf, 0x2f, 0x27, 0xce, 0xb3, 0xdb, 0xff, 0xe9, 0xd7, 0xd9, 0xf3, 0x81, 0xf9, - 0xf8, 0xe8, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x51, 0x62, 0x48, 0x8d, 0xcd, 0x09, 0x00, 0x00, + 0x14, 0xde, 0x75, 0x1c, 0x3b, 0x3e, 0x9b, 0xb8, 0x66, 0x80, 0xd6, 0x0a, 0xc5, 0x84, 0x45, 0x85, + 0xaa, 0x42, 0x0d, 0x32, 0x42, 0x54, 0x08, 0x51, 0xb6, 0x49, 0x85, 0x1d, 0x28, 0xa0, 0x89, 0x4a, + 0xa5, 0x5e, 0x31, 0x9d, 0x1d, 0xa5, 0x0b, 0xbb, 0x3b, 0x9b, 0xd9, 0xb1, 0x2b, 0x3f, 0x04, 0x12, + 0x8f, 0xc0, 0x8b, 0x70, 0xcf, 0x65, 0x6e, 0x90, 0x10, 0x57, 0x28, 0x79, 0x11, 0x34, 0x33, 0xbb, + 0xde, 0xdf, 0x58, 0x88, 0x8b, 0xc4, 0x33, 0x67, 0xce, 0xf9, 0xce, 0x77, 0x7e, 0x6d, 0xf8, 0x9c, + 0xf2, 0x28, 0xe2, 0x71, 0x9a, 0x10, 0xca, 0x0e, 0xf9, 0x8b, 0x9f, 0x18, 0x95, 0x87, 0x84, 0x86, + 0xea, 0x4f, 0x30, 0xca, 0x85, 0x9f, 0x08, 0x2e, 0xf9, 0xa1, 0xfe, 0x9f, 0x16, 0xd2, 0xfb, 0x5a, + 0x80, 0x06, 0x6b, 0x81, 0xfb, 0x9b, 0x0d, 0xbb, 0x98, 0xbc, 0xf2, 0x68, 0x88, 0xb5, 0x00, 0x8d, + 0xa1, 0x9f, 0x90, 0x55, 0xc8, 0x89, 0x3f, 0xb6, 0x0f, 0xec, 0xbb, 0xbb, 0x38, 0xbf, 0xa2, 0xdb, + 0x30, 0x48, 0x83, 0xb3, 0x98, 0xc8, 0x85, 0x60, 0xe3, 0x8e, 0x7e, 0x2b, 0x04, 0xe8, 0x1e, 0x8c, + 0x08, 0xa5, 0x2c, 0x91, 0x5c, 0xcc, 0x7d, 0x16, 0xcb, 0x40, 0xae, 0xc6, 0x5b, 0x5a, 0xa9, 0x21, + 0x47, 0x1f, 0xc2, 0x6b, 0xb9, 0xec, 0x74, 0x8d, 0xd8, 0xd5, 0xca, 0xcd, 0x07, 0xf7, 0x0b, 0x40, + 0x65, 0x86, 0xcf, 0x02, 0xf9, 0x72, 0xbe, 0x89, 0xe7, 0x10, 0x3a, 0x81, 0xaf, 0x09, 0x0e, 0x70, + 0x27, 0xf0, 0xdd, 0x73, 0x18, 0x14, 0xe1, 0xdd, 0x84, 0x5e, 0x22, 0xd8, 0x72, 0x6e, 0xac, 0x06, + 0x38, 0xbb, 0xa1, 0x7d, 0xd8, 0x09, 0x72, 0xda, 0x26, 0xb6, 0xf5, 0x1d, 0x21, 0xe8, 0xfa, 0x44, + 0x92, 0x2c, 0x1c, 0x7d, 0x56, 0xc9, 0x90, 0x41, 0xc4, 0x52, 0x49, 0xa2, 0x44, 0x53, 0xdf, 0xc2, + 0x85, 0xc0, 0xfd, 0xd3, 0x86, 0xbe, 0xf2, 0xc9, 0xb9, 0xac, 0x20, 0xdb, 0x35, 0xe4, 0xdb, 0x30, + 0x88, 0x48, 0x2a, 0x99, 0xf8, 0x9a, 0xe5, 0x6e, 0x0b, 0x81, 0x0a, 0x51, 0x17, 0x78, 0xee, 0x6b, + 0xd7, 0x03, 0x9c, 0x5f, 0x55, 0xb2, 0x59, 0x4c, 0xc5, 0x2a, 0x91, 0xcc, 0xc7, 0x8c, 0xf8, 0xca, + 0xdc, 0xe4, 0xaf, 0x21, 0xaf, 0x32, 0xdd, 0xae, 0x31, 0x55, 0xa5, 0xc8, 0xd9, 0x14, 0xa5, 0xe8, + 0x99, 0x52, 0x34, 0x1e, 0xdc, 0x8f, 0x60, 0xe4, 0xd1, 0xd0, 0xa3, 0x94, 0x2f, 0x62, 0x39, 0x8f, + 0x97, 0x81, 0x64, 0x0a, 0x3f, 0xd0, 0x27, 0x45, 0xc2, 0x04, 0x58, 0x08, 0xdc, 0xdf, 0x6d, 0x78, + 0xb3, 0x30, 0xc1, 0xec, 0x7c, 0xc1, 0x52, 0x79, 0xc2, 0x83, 0x18, 0xbd, 0x0f, 0x43, 0xa3, 0x36, + 0xaf, 0x66, 0xa7, 0x26, 0x2d, 0xf4, 0x4c, 0x05, 0xe7, 0x79, 0x69, 0x6b, 0x52, 0xf4, 0x00, 0x6e, + 0x55, 0x2d, 0x8b, 0x78, 0x4c, 0xe1, 0xae, 0x7b, 0x56, 0x15, 0x8a, 0x98, 0x24, 0xba, 0xc6, 0x26, + 0x8b, 0xeb, 0xbb, 0xfb, 0x8b, 0x0d, 0xb7, 0x1a, 0xfc, 0x3d, 0xdd, 0xa3, 0x1b, 0x2b, 0x7b, 0x17, + 0x6e, 0x08, 0xa3, 0x5c, 0xa3, 0x5d, 0x17, 0xab, 0x0a, 0xd4, 0x6b, 0x96, 0x66, 0x8c, 0x9b, 0x0f, + 0xee, 0x31, 0x8c, 0x1b, 0x74, 0x8e, 0x19, 0x0d, 0x83, 0x98, 0xb5, 0xf9, 0xb4, 0x5b, 0x7d, 0xba, + 0x5f, 0xc2, 0xcd, 0x7a, 0x1d, 0x31, 0x5b, 0xf2, 0x9f, 0x59, 0x4b, 0xb6, 0xed, 0xb6, 0x6c, 0xbb, + 0x1f, 0x80, 0xa3, 0x87, 0xca, 0xd0, 0x52, 0xad, 0x2a, 0xb2, 0x3e, 0xb4, 0x0f, 0xb6, 0xd4, 0x34, + 0x66, 0x57, 0xf7, 0x47, 0x78, 0xc3, 0xa3, 0xe1, 0xe3, 0x7a, 0x20, 0x1b, 0x93, 0xd7, 0x9a, 0x92, + 0xce, 0x75, 0x29, 0x59, 0xc1, 0x7e, 0x11, 0xcc, 0xf7, 0x4c, 0x44, 0x41, 0x9a, 0x06, 0x3c, 0x3e, + 0x7a, 0x49, 0xe2, 0x33, 0xb6, 0xd1, 0xcf, 0x43, 0x70, 0x92, 0xb5, 0xbe, 0xf1, 0x30, 0x9c, 0xbe, + 0x7d, 0xbf, 0x58, 0x97, 0x1e, 0x0d, 0x9f, 0xa6, 0x4c, 0x14, 0xa0, 0x29, 0x2e, 0x5b, 0xb8, 0x4f, + 0xf5, 0x3c, 0x64, 0x4c, 0x32, 0x87, 0x1e, 0x38, 0xc4, 0x70, 0xd1, 0xb4, 0x55, 0x3a, 0x9c, 0xe9, + 0x3b, 0x55, 0xd0, 0x46, 0x3a, 0x70, 0xd9, 0xc6, 0x3d, 0x2f, 0x8f, 0x19, 0x66, 0x11, 0x5f, 0x6e, + 0x8e, 0xa3, 0xe6, 0xb2, 0xf3, 0x3f, 0x5c, 0xfe, 0xdd, 0x85, 0x1b, 0x1e, 0x0d, 0x8f, 0x78, 0x2c, + 0x59, 0x2c, 0x7f, 0x20, 0xe1, 0x82, 0xa1, 0x4f, 0xa0, 0x67, 0xaa, 0xae, 0x1d, 0x3a, 0xd3, 0xb7, + 0xaa, 0x88, 0x95, 0xf6, 0x99, 0x59, 0x38, 0x53, 0x46, 0x5f, 0xc1, 0x6e, 0x50, 0x6a, 0x29, 0x9d, + 0x56, 0x67, 0xfa, 0xee, 0x06, 0x63, 0xa3, 0x38, 0xb3, 0x70, 0xc5, 0x10, 0x1d, 0x83, 0x23, 0x8a, + 0x85, 0xa1, 0x67, 0xc2, 0x99, 0x1e, 0xb4, 0xe2, 0x94, 0x16, 0xcb, 0xcc, 0xc2, 0x65, 0x33, 0x74, + 0x02, 0x7b, 0xa2, 0x3c, 0xb6, 0x7a, 0xc4, 0x9d, 0xa9, 0xbb, 0x09, 0xc7, 0x68, 0xce, 0x2c, 0x5c, + 0x35, 0x45, 0xa7, 0x30, 0x4a, 0x6a, 0x0d, 0xa6, 0x57, 0xaa, 0x33, 0xbd, 0xd3, 0x0a, 0x57, 0xef, + 0xc6, 0x99, 0x85, 0x1b, 0x00, 0xe8, 0x08, 0xf6, 0x48, 0xb9, 0xd4, 0x7a, 0xfd, 0x5e, 0x97, 0x6d, + 0xa3, 0xa2, 0x98, 0x55, 0x6c, 0x14, 0x88, 0x28, 0xb7, 0xe1, 0xb8, 0xdf, 0x06, 0x52, 0xe9, 0x54, + 0x13, 0x5e, 0xb9, 0x75, 0x9f, 0xc0, 0x50, 0x54, 0x56, 0xca, 0x78, 0x47, 0xa3, 0xbc, 0xb7, 0x29, + 0x57, 0x99, 0xea, 0xcc, 0xc2, 0x35, 0xe3, 0x47, 0x7d, 0xd8, 0x5e, 0xaa, 0x46, 0x72, 0x1f, 0xeb, + 0x6f, 0xc3, 0x63, 0xf5, 0xbd, 0xf9, 0x19, 0x00, 0x59, 0xb7, 0x59, 0x36, 0x1c, 0xfb, 0x55, 0xf8, + 0x72, 0x0f, 0xe2, 0x92, 0xb6, 0x7b, 0x02, 0x43, 0x8f, 0x86, 0xa7, 0xab, 0x98, 0x3e, 0x61, 0x69, + 0x4a, 0xce, 0x18, 0x7a, 0x00, 0x7d, 0xba, 0x86, 0x52, 0x4c, 0x27, 0x55, 0x28, 0xa5, 0x5b, 0x81, + 0xcb, 0xd5, 0xdd, 0xe7, 0xf0, 0x7a, 0xcb, 0xbb, 0xa6, 0xe7, 0xfb, 0x66, 0xcb, 0xa5, 0x19, 0xe6, + 0xb8, 0x16, 0xfd, 0xfa, 0x7d, 0x66, 0xe1, 0x92, 0x76, 0x11, 0xee, 0x0c, 0xf6, 0x2a, 0x7a, 0xe8, + 0x53, 0xb5, 0x1d, 0x73, 0x48, 0x15, 0x71, 0x79, 0xc7, 0x34, 0x7f, 0xdb, 0xe0, 0x5c, 0xfb, 0xde, + 0x37, 0x80, 0x9a, 0x2b, 0x08, 0xed, 0x40, 0xf7, 0x5b, 0x1e, 0xb3, 0x91, 0x85, 0x06, 0xb0, 0xfd, + 0xdd, 0xab, 0x98, 0x89, 0x91, 0xad, 0x8e, 0x9e, 0x1f, 0x05, 0xf1, 0xa8, 0x83, 0x00, 0x7a, 0xcf, + 0x44, 0x20, 0x99, 0x18, 0x6d, 0xa9, 0xb3, 0x2a, 0x3a, 0x13, 0xa3, 0xee, 0xa3, 0x87, 0x7f, 0x5c, + 0x4e, 0xec, 0x8b, 0xcb, 0x89, 0xfd, 0xcf, 0xe5, 0xc4, 0xfe, 0xf5, 0x6a, 0x62, 0x5d, 0x5c, 0x4d, + 0xac, 0xbf, 0xae, 0x26, 0xd6, 0xf3, 0x3b, 0xff, 0xe9, 0xe7, 0xe4, 0x8b, 0x9e, 0xfe, 0xf8, 0xf8, + 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7b, 0xb3, 0x39, 0x6c, 0x7e, 0x0a, 0x00, 0x00, } func (m *RawAclRecord) Marshal() (dAtA []byte, err error) { @@ -1490,6 +1560,13 @@ func (m *AclAccountRequestJoin) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.Metadata) > 0 { + i -= len(m.Metadata) + copy(dAtA[i:], m.Metadata) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.Metadata))) + i-- + dAtA[i] = 0x22 + } if len(m.InviteIdentitySignature) > 0 { i -= len(m.InviteIdentitySignature) copy(dAtA[i:], m.InviteIdentitySignature) @@ -1558,6 +1635,36 @@ func (m *AclAccountRequestAccept) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } +func (m *AclAccountRequestDecline) 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 *AclAccountRequestDecline) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AclAccountRequestDecline) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.RequestRecordId) > 0 { + i -= len(m.RequestRecordId) + copy(dAtA[i:], m.RequestRecordId) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.RequestRecordId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *AclAccountInviteRevoke) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1952,6 +2059,27 @@ func (m *AclContentValue_ReadKeyChange) MarshalToSizedBuffer(dAtA []byte) (int, } return len(dAtA) - i, nil } +func (m *AclContentValue_RequestDecline) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AclContentValue_RequestDecline) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.RequestDecline != nil { + { + size, err := m.RequestDecline.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAclrecord(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x42 + } + return len(dAtA) - i, nil +} func (m *AclData) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -2254,6 +2382,10 @@ func (m *AclAccountRequestJoin) Size() (n int) { if l > 0 { n += 1 + l + sovAclrecord(uint64(l)) } + l = len(m.Metadata) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } return n } @@ -2278,6 +2410,19 @@ func (m *AclAccountRequestAccept) Size() (n int) { return n } +func (m *AclAccountRequestDecline) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.RequestRecordId) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + return n +} + func (m *AclAccountInviteRevoke) Size() (n int) { if m == nil { return 0 @@ -2469,6 +2614,18 @@ func (m *AclContentValue_ReadKeyChange) Size() (n int) { } return n } +func (m *AclContentValue_RequestDecline) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.RequestDecline != nil { + l = m.RequestDecline.Size() + n += 1 + l + sovAclrecord(uint64(l)) + } + return n +} func (m *AclData) Size() (n int) { if m == nil { return 0 @@ -3463,6 +3620,40 @@ func (m *AclAccountRequestJoin) Unmarshal(dAtA []byte) error { m.InviteIdentitySignature = []byte{} } iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", 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.Metadata = append(m.Metadata[:0], dAtA[iNdEx:postIndex]...) + if m.Metadata == nil { + m.Metadata = []byte{} + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipAclrecord(dAtA[iNdEx:]) @@ -3634,6 +3825,88 @@ func (m *AclAccountRequestAccept) Unmarshal(dAtA []byte) error { } return nil } +func (m *AclAccountRequestDecline) 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: AclAccountRequestDecline: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AclAccountRequestDecline: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RequestRecordId", 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.RequestRecordId = 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 *AclAccountInviteRevoke) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -4495,6 +4768,41 @@ func (m *AclContentValue) Unmarshal(dAtA []byte) error { } m.Value = &AclContentValue_ReadKeyChange{v} iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RequestDecline", 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 := &AclAccountRequestDecline{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Value = &AclContentValue_RequestDecline{v} + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipAclrecord(dAtA[iNdEx:]) diff --git a/commonspace/object/acl/aclrecordproto/protos/aclrecord.proto b/commonspace/object/acl/aclrecordproto/protos/aclrecord.proto index 2ca06396..7219aecd 100644 --- a/commonspace/object/acl/aclrecordproto/protos/aclrecord.proto +++ b/commonspace/object/acl/aclrecordproto/protos/aclrecord.proto @@ -44,6 +44,7 @@ message AclAccountRequestJoin { bytes inviteIdentity = 1; string inviteRecordId = 2; bytes inviteIdentitySignature = 3; + bytes metadata = 4; } // AclAccountRequestAccept contains the reference to join record and all read keys, encrypted with the identity of the requestor @@ -53,6 +54,11 @@ message AclAccountRequestAccept { bytes encryptedReadKeys = 3; } +// AclAccountRequestDecline contains the reference to join record +message AclAccountRequestDecline { + string requestRecordId = 1; +} + // AclAccountInviteRevoke revokes the invite record message AclAccountInviteRevoke { string inviteRecordId = 1; @@ -96,6 +102,7 @@ message AclContentValue { AclAccountPermissionChange permissionChange = 5; AclAccountRemove accountRemove = 6; AclReadKeyChange readKeyChange = 7; + AclAccountRequestDecline requestDecline = 8; } } diff --git a/commonspace/object/acl/list/aclstate.go b/commonspace/object/acl/list/aclstate.go index dde9ae23..496b865d 100644 --- a/commonspace/object/acl/list/aclstate.go +++ b/commonspace/object/acl/list/aclstate.go @@ -14,20 +14,22 @@ import ( var log = logger.NewNamedSugared("common.commonspace.acllist") var ( - ErrNoSuchUser = errors.New("no such user") - ErrFailedToDecrypt = errors.New("failed to decrypt key") - ErrUserRemoved = errors.New("user was removed from the document") - ErrDocumentForbidden = errors.New("your user was forbidden access to the document") - ErrUserAlreadyExists = errors.New("user already exists") - ErrNoSuchRecord = errors.New("no such record") - ErrNoSuchInvite = errors.New("no such invite") - ErrOldInvite = errors.New("invite is too old") - ErrInsufficientPermissions = errors.New("insufficient permissions") - ErrNoReadKey = errors.New("acl state doesn't have a read key") - ErrNoInvite = errors.New("can't delete invite record") - ErrInvalidSignature = errors.New("signature is invalid") - ErrIncorrectRoot = errors.New("incorrect root") - ErrIncorrectRecordSequence = errors.New("incorrect prev id of a record") + ErrNoSuchAccount = errors.New("no such account") + ErrIncorrectInviteKey = errors.New("incorrect invite key") + ErrIncorrectIdentity = errors.New("incorrect identity") + ErrFailedToDecrypt = errors.New("failed to decrypt key") + ErrUserRemoved = errors.New("user was removed from the document") + ErrDocumentForbidden = errors.New("your user was forbidden access to the document") + ErrUserAlreadyExists = errors.New("user already exists") + ErrNoSuchRecord = errors.New("no such record") + ErrNoSuchRequest = errors.New("no such request") + ErrNoSuchInvite = errors.New("no such invite") + ErrInsufficientPermissions = errors.New("insufficient permissions") + ErrIncorrectNumberOfAccounts = errors.New("incorrect number of accounts") + ErrNoReadKey = errors.New("acl state doesn't have a read key") + ErrInvalidSignature = errors.New("signature is invalid") + ErrIncorrectRoot = errors.New("incorrect root") + ErrIncorrectRecordSequence = errors.New("incorrect prev id of a record") ) type UserPermissionPair struct { @@ -42,6 +44,7 @@ type AclState struct { userStates map[string]AclUserState statesAtRecord map[string][]AclUserState inviteKeys map[string]crypto.PubKey + requestRecords map[string]RequestRecord key crypto.PrivKey pubKey crypto.PubKey keyStore crypto.KeyStorage @@ -60,6 +63,8 @@ func newAclStateWithKeys( userReadKeys: make(map[string]crypto.SymKey), userStates: make(map[string]AclUserState), statesAtRecord: make(map[string][]AclUserState), + inviteKeys: make(map[string]crypto.PubKey), + requestRecords: make(map[string]RequestRecord), }, nil } @@ -69,6 +74,8 @@ func newAclState(id string) *AclState { userReadKeys: make(map[string]crypto.SymKey), userStates: make(map[string]AclUserState), statesAtRecord: make(map[string][]AclUserState), + inviteKeys: make(map[string]crypto.PubKey), + requestRecords: make(map[string]RequestRecord), } } @@ -100,7 +107,7 @@ func (st *AclState) StateAtRecord(id string, pubKey crypto.PubKey) (AclUserState return perm, nil } } - return AclUserState{}, ErrNoSuchUser + return AclUserState{}, ErrNoSuchAccount } func (st *AclState) applyRecord(record *AclRecord) (err error) { @@ -229,7 +236,7 @@ func (st *AclState) applyPermissionChange(ch *aclrecordproto.AclAccountPermissio } state, exists := st.userStates[mapKeyFromPubKey(chIdentity)] if !exists { - return ErrNoSuchUser + return ErrNoSuchAccount } state.Permissions = AclPermissions(ch.Permissions) return nil diff --git a/commonspace/object/acl/list/models.go b/commonspace/object/acl/list/models.go index 97b19ac5..6ec52b28 100644 --- a/commonspace/object/acl/list/models.go +++ b/commonspace/object/acl/list/models.go @@ -16,6 +16,11 @@ type AclRecord struct { Signature []byte } +type RequestRecord struct { + RequestIdentity crypto.PubKey + RequestMetadata []byte +} + type AclUserState struct { PubKey crypto.PubKey Permissions AclPermissions diff --git a/commonspace/object/acl/list/validator.go b/commonspace/object/acl/list/validator.go index b4972732..6fa8be20 100644 --- a/commonspace/object/acl/list/validator.go +++ b/commonspace/object/acl/list/validator.go @@ -1,5 +1,147 @@ package list -type Validator interface { - Validate() +import ( + "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" + "github.com/anyproto/any-sync/util/crypto" +) + +type ContentValidator interface { + ValidatePermissionChange(ch *aclrecordproto.AclAccountPermissionChange, id string, authorIdentity crypto.PubKey) (err error) + ValidateInvite(ch *aclrecordproto.AclAccountInvite, id string, authorIdentity crypto.PubKey) (err error) + ValidateInviteRevoke(ch *aclrecordproto.AclAccountInviteRevoke, id string, authorIdentity crypto.PubKey) (err error) + ValidateRequestJoin(ch *aclrecordproto.AclAccountRequestJoin, id string, authorIdentity crypto.PubKey) (err error) + ValidateRequestAccept(ch *aclrecordproto.AclAccountRequestAccept, id string, authorIdentity crypto.PubKey) (err error) + ValidateRequestDecline(ch *aclrecordproto.AclAccountRequestDecline, id string, authorIdentity crypto.PubKey) (err error) + ValidateRemove(ch *aclrecordproto.AclAccountRemove, id string, authorIdentity crypto.PubKey) (err error) + ValidateReadKeyChange(ch *aclrecordproto.AclReadKeyChange, id string, authorIdentity crypto.PubKey) (err error) +} + +type contentValidator struct { + keyStore crypto.KeyStorage + aclState *AclState +} + +func (c *contentValidator) ValidatePermissionChange(ch *aclrecordproto.AclAccountPermissionChange, id string, authorIdentity crypto.PubKey) (err error) { + if !c.aclState.Permissions(authorIdentity).CanManageAccounts() { + return ErrInsufficientPermissions + } + chIdentity, err := c.keyStore.PubKeyFromProto(ch.Identity) + if err != nil { + return err + } + _, exists := c.aclState.userStates[mapKeyFromPubKey(chIdentity)] + if !exists { + return ErrNoSuchAccount + } + return +} + +func (c *contentValidator) ValidateInvite(ch *aclrecordproto.AclAccountInvite, id string, authorIdentity crypto.PubKey) (err error) { + if !c.aclState.Permissions(authorIdentity).CanManageAccounts() { + return ErrInsufficientPermissions + } + _, err = c.keyStore.PubKeyFromProto(ch.InviteKey) + return +} + +func (c *contentValidator) ValidateInviteRevoke(ch *aclrecordproto.AclAccountInviteRevoke, id string, authorIdentity crypto.PubKey) (err error) { + if !c.aclState.Permissions(authorIdentity).CanManageAccounts() { + return ErrInsufficientPermissions + } + _, exists := c.aclState.inviteKeys[ch.InviteRecordId] + if !exists { + return ErrNoSuchInvite + } + return +} + +func (c *contentValidator) ValidateRequestJoin(ch *aclrecordproto.AclAccountRequestJoin, id string, authorIdentity crypto.PubKey) (err error) { + inviteKey, exists := c.aclState.inviteKeys[ch.InviteRecordId] + if !exists { + return ErrNoSuchInvite + } + inviteIdentity, err := c.keyStore.PubKeyFromProto(ch.InviteIdentity) + if err != nil { + return + } + if !authorIdentity.Equals(inviteIdentity) { + return ErrIncorrectIdentity + } + rawInviteIdentity, err := inviteIdentity.Raw() + if err != nil { + return err + } + ok, err := inviteKey.Verify(rawInviteIdentity, ch.InviteIdentitySignature) + if err != nil { + return ErrInvalidSignature + } + if !ok { + return ErrInvalidSignature + } + return +} + +func (c *contentValidator) ValidateRequestAccept(ch *aclrecordproto.AclAccountRequestAccept, id string, authorIdentity crypto.PubKey) (err error) { + if !c.aclState.Permissions(authorIdentity).CanManageAccounts() { + return ErrInsufficientPermissions + } + record, exists := c.aclState.requestRecords[ch.RequestRecordId] + if !exists { + return ErrNoSuchRequest + } + acceptIdentity, err := c.keyStore.PubKeyFromProto(ch.Identity) + if err != nil { + return + } + if !acceptIdentity.Equals(record.RequestIdentity) { + return ErrIncorrectIdentity + } + return +} + +func (c *contentValidator) ValidateRequestDecline(ch *aclrecordproto.AclAccountRequestDecline, id string, authorIdentity crypto.PubKey) (err error) { + if !c.aclState.Permissions(authorIdentity).CanManageAccounts() { + return ErrInsufficientPermissions + } + _, exists := c.aclState.requestRecords[ch.RequestRecordId] + if !exists { + return ErrNoSuchRequest + } + return +} + +func (c *contentValidator) ValidateRemove(ch *aclrecordproto.AclAccountRemove, id string, authorIdentity crypto.PubKey) (err error) { + if !c.aclState.Permissions(authorIdentity).CanManageAccounts() { + return ErrInsufficientPermissions + } + identity, err := c.keyStore.PubKeyFromProto(ch.Identity) + if err != nil { + return + } + _, exists := c.aclState.userStates[mapKeyFromPubKey(identity)] + if !exists { + return ErrNoSuchAccount + } + return c.validateAccountReadKeys(ch.AccountKeys) +} + +func (c *contentValidator) ValidateReadKeyChange(ch *aclrecordproto.AclReadKeyChange, id string, authorIdentity crypto.PubKey) (err error) { + return c.validateAccountReadKeys(ch.AccountKeys) +} + +func (c *contentValidator) validateAccountReadKeys(accountKeys []*aclrecordproto.AclEncryptedReadKeys) (err error) { + if len(accountKeys) != len(c.aclState.userStates) { + return ErrIncorrectNumberOfAccounts + } + for _, encKeys := range accountKeys { + identity, err := c.keyStore.PubKeyFromProto(encKeys.Identity) + if err != nil { + return err + } + _, exists := c.aclState.userStates[mapKeyFromPubKey(identity)] + if !exists { + return ErrNoSuchAccount + } + } + return } From 7577c14d5f3570af9c9d19d2b3ec23c420c4d0e7 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Fri, 23 Jun 2023 16:16:26 +0200 Subject: [PATCH 075/123] Add state apply changes --- .../object/acl/aclrecordproto/aclrecord.pb.go | 407 ++++++++++++------ .../acl/aclrecordproto/protos/aclrecord.proto | 13 +- .../object/acl/list/aclrecordbuilder.go | 5 +- commonspace/object/acl/list/aclstate.go | 179 ++++++-- commonspace/object/acl/list/models.go | 6 +- commonspace/object/acl/list/validator.go | 5 +- 6 files changed, 428 insertions(+), 187 deletions(-) diff --git a/commonspace/object/acl/aclrecordproto/aclrecord.pb.go b/commonspace/object/acl/aclrecordproto/aclrecord.pb.go index d7abb519..9bb5eab4 100644 --- a/commonspace/object/acl/aclrecordproto/aclrecord.pb.go +++ b/commonspace/object/acl/aclrecordproto/aclrecord.pb.go @@ -449,9 +449,10 @@ func (m *AclAccountRequestJoin) GetMetadata() []byte { // AclAccountRequestAccept contains the reference to join record and all read keys, encrypted with the identity of the requestor type AclAccountRequestAccept struct { - Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` - RequestRecordId string `protobuf:"bytes,2,opt,name=requestRecordId,proto3" json:"requestRecordId,omitempty"` - EncryptedReadKeys []byte `protobuf:"bytes,3,opt,name=encryptedReadKeys,proto3" json:"encryptedReadKeys,omitempty"` + Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` + RequestRecordId string `protobuf:"bytes,2,opt,name=requestRecordId,proto3" json:"requestRecordId,omitempty"` + EncryptedReadKeys []byte `protobuf:"bytes,3,opt,name=encryptedReadKeys,proto3" json:"encryptedReadKeys,omitempty"` + Permissions AclUserPermissions `protobuf:"varint,4,opt,name=permissions,proto3,enum=aclrecord.AclUserPermissions" json:"permissions,omitempty"` } func (m *AclAccountRequestAccept) Reset() { *m = AclAccountRequestAccept{} } @@ -508,6 +509,13 @@ func (m *AclAccountRequestAccept) GetEncryptedReadKeys() []byte { return nil } +func (m *AclAccountRequestAccept) GetPermissions() AclUserPermissions { + if m != nil { + return m.Permissions + } + return AclUserPermissions_None +} + // AclAccountRequestDecline contains the reference to join record type AclAccountRequestDecline struct { RequestRecordId string `protobuf:"bytes,1,opt,name=requestRecordId,proto3" json:"requestRecordId,omitempty"` @@ -600,7 +608,7 @@ func (m *AclAccountInviteRevoke) GetInviteRecordId() string { // AclReadKeys are all read keys in Acl type AclReadKeys struct { - ReadKey [][]byte `protobuf:"bytes,1,rep,name=readKey,proto3" json:"readKey,omitempty"` + ReadKeys map[string][]byte `protobuf:"bytes,1,rep,name=readKeys,proto3" json:"readKeys,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (m *AclReadKeys) Reset() { *m = AclReadKeys{} } @@ -636,31 +644,31 @@ func (m *AclReadKeys) XXX_DiscardUnknown() { var xxx_messageInfo_AclReadKeys proto.InternalMessageInfo -func (m *AclReadKeys) GetReadKey() [][]byte { +func (m *AclReadKeys) GetReadKeys() map[string][]byte { if m != nil { - return m.ReadKey + return m.ReadKeys } return nil } -// AclEncryptedReadKeys are all keys for specific identity -type AclEncryptedReadKeys struct { - Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` - EncryptedReadKeys []byte `protobuf:"bytes,2,opt,name=encryptedReadKeys,proto3" json:"encryptedReadKeys,omitempty"` +// AclEncryptedReadKeys are new key for specific identity +type AclEncryptedReadKey struct { + Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` + EncryptedReadKey []byte `protobuf:"bytes,2,opt,name=encryptedReadKey,proto3" json:"encryptedReadKey,omitempty"` } -func (m *AclEncryptedReadKeys) Reset() { *m = AclEncryptedReadKeys{} } -func (m *AclEncryptedReadKeys) String() string { return proto.CompactTextString(m) } -func (*AclEncryptedReadKeys) ProtoMessage() {} -func (*AclEncryptedReadKeys) Descriptor() ([]byte, []int) { +func (m *AclEncryptedReadKey) Reset() { *m = AclEncryptedReadKey{} } +func (m *AclEncryptedReadKey) String() string { return proto.CompactTextString(m) } +func (*AclEncryptedReadKey) ProtoMessage() {} +func (*AclEncryptedReadKey) Descriptor() ([]byte, []int) { return fileDescriptor_c8e9f754f34e929b, []int{10} } -func (m *AclEncryptedReadKeys) XXX_Unmarshal(b []byte) error { +func (m *AclEncryptedReadKey) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *AclEncryptedReadKeys) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *AclEncryptedReadKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_AclEncryptedReadKeys.Marshal(b, m, deterministic) + return xxx_messageInfo_AclEncryptedReadKey.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -670,28 +678,28 @@ func (m *AclEncryptedReadKeys) XXX_Marshal(b []byte, deterministic bool) ([]byte return b[:n], nil } } -func (m *AclEncryptedReadKeys) XXX_Merge(src proto.Message) { - xxx_messageInfo_AclEncryptedReadKeys.Merge(m, src) +func (m *AclEncryptedReadKey) XXX_Merge(src proto.Message) { + xxx_messageInfo_AclEncryptedReadKey.Merge(m, src) } -func (m *AclEncryptedReadKeys) XXX_Size() int { +func (m *AclEncryptedReadKey) XXX_Size() int { return m.Size() } -func (m *AclEncryptedReadKeys) XXX_DiscardUnknown() { - xxx_messageInfo_AclEncryptedReadKeys.DiscardUnknown(m) +func (m *AclEncryptedReadKey) XXX_DiscardUnknown() { + xxx_messageInfo_AclEncryptedReadKey.DiscardUnknown(m) } -var xxx_messageInfo_AclEncryptedReadKeys proto.InternalMessageInfo +var xxx_messageInfo_AclEncryptedReadKey proto.InternalMessageInfo -func (m *AclEncryptedReadKeys) GetIdentity() []byte { +func (m *AclEncryptedReadKey) GetIdentity() []byte { if m != nil { return m.Identity } return nil } -func (m *AclEncryptedReadKeys) GetEncryptedReadKeys() []byte { +func (m *AclEncryptedReadKey) GetEncryptedReadKey() []byte { if m != nil { - return m.EncryptedReadKeys + return m.EncryptedReadKey } return nil } @@ -751,7 +759,7 @@ func (m *AclAccountPermissionChange) GetPermissions() AclUserPermissions { // AclReadKeyChange changes the key for a space type AclReadKeyChange struct { - AccountKeys []*AclEncryptedReadKeys `protobuf:"bytes,1,rep,name=accountKeys,proto3" json:"accountKeys,omitempty"` + AccountKeys []*AclEncryptedReadKey `protobuf:"bytes,1,rep,name=accountKeys,proto3" json:"accountKeys,omitempty"` } func (m *AclReadKeyChange) Reset() { *m = AclReadKeyChange{} } @@ -787,7 +795,7 @@ func (m *AclReadKeyChange) XXX_DiscardUnknown() { var xxx_messageInfo_AclReadKeyChange proto.InternalMessageInfo -func (m *AclReadKeyChange) GetAccountKeys() []*AclEncryptedReadKeys { +func (m *AclReadKeyChange) GetAccountKeys() []*AclEncryptedReadKey { if m != nil { return m.AccountKeys } @@ -796,8 +804,8 @@ func (m *AclReadKeyChange) GetAccountKeys() []*AclEncryptedReadKeys { // AclAccountRemove removes an account and changes read key for space type AclAccountRemove struct { - Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` - AccountKeys []*AclEncryptedReadKeys `protobuf:"bytes,2,rep,name=accountKeys,proto3" json:"accountKeys,omitempty"` + Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` + AccountKeys []*AclEncryptedReadKey `protobuf:"bytes,2,rep,name=accountKeys,proto3" json:"accountKeys,omitempty"` } func (m *AclAccountRemove) Reset() { *m = AclAccountRemove{} } @@ -840,7 +848,7 @@ func (m *AclAccountRemove) GetIdentity() []byte { return nil } -func (m *AclAccountRemove) GetAccountKeys() []*AclEncryptedReadKeys { +func (m *AclAccountRemove) GetAccountKeys() []*AclEncryptedReadKey { if m != nil { return m.AccountKeys } @@ -1231,7 +1239,8 @@ func init() { proto.RegisterType((*AclAccountRequestDecline)(nil), "aclrecord.AclAccountRequestDecline") proto.RegisterType((*AclAccountInviteRevoke)(nil), "aclrecord.AclAccountInviteRevoke") proto.RegisterType((*AclReadKeys)(nil), "aclrecord.AclReadKeys") - proto.RegisterType((*AclEncryptedReadKeys)(nil), "aclrecord.AclEncryptedReadKeys") + proto.RegisterMapType((map[string][]byte)(nil), "aclrecord.AclReadKeys.ReadKeysEntry") + proto.RegisterType((*AclEncryptedReadKey)(nil), "aclrecord.AclEncryptedReadKey") proto.RegisterType((*AclAccountPermissionChange)(nil), "aclrecord.AclAccountPermissionChange") proto.RegisterType((*AclReadKeyChange)(nil), "aclrecord.AclReadKeyChange") proto.RegisterType((*AclAccountRemove)(nil), "aclrecord.AclAccountRemove") @@ -1247,67 +1256,70 @@ func init() { } var fileDescriptor_c8e9f754f34e929b = []byte{ - // 958 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xdd, 0x6e, 0x1b, 0x45, - 0x14, 0xde, 0x75, 0x1c, 0x3b, 0x3e, 0x9b, 0xb8, 0x66, 0x80, 0xd6, 0x0a, 0xc5, 0x84, 0x45, 0x85, - 0xaa, 0x42, 0x0d, 0x32, 0x42, 0x54, 0x08, 0x51, 0xb6, 0x49, 0x85, 0x1d, 0x28, 0xa0, 0x89, 0x4a, - 0xa5, 0x5e, 0x31, 0x9d, 0x1d, 0xa5, 0x0b, 0xbb, 0x3b, 0x9b, 0xd9, 0xb1, 0x2b, 0x3f, 0x04, 0x12, - 0x8f, 0xc0, 0x8b, 0x70, 0xcf, 0x65, 0x6e, 0x90, 0x10, 0x57, 0x28, 0x79, 0x11, 0x34, 0x33, 0xbb, - 0xde, 0xdf, 0x58, 0x88, 0x8b, 0xc4, 0x33, 0x67, 0xce, 0xf9, 0xce, 0x77, 0x7e, 0x6d, 0xf8, 0x9c, - 0xf2, 0x28, 0xe2, 0x71, 0x9a, 0x10, 0xca, 0x0e, 0xf9, 0x8b, 0x9f, 0x18, 0x95, 0x87, 0x84, 0x86, - 0xea, 0x4f, 0x30, 0xca, 0x85, 0x9f, 0x08, 0x2e, 0xf9, 0xa1, 0xfe, 0x9f, 0x16, 0xd2, 0xfb, 0x5a, - 0x80, 0x06, 0x6b, 0x81, 0xfb, 0x9b, 0x0d, 0xbb, 0x98, 0xbc, 0xf2, 0x68, 0x88, 0xb5, 0x00, 0x8d, - 0xa1, 0x9f, 0x90, 0x55, 0xc8, 0x89, 0x3f, 0xb6, 0x0f, 0xec, 0xbb, 0xbb, 0x38, 0xbf, 0xa2, 0xdb, - 0x30, 0x48, 0x83, 0xb3, 0x98, 0xc8, 0x85, 0x60, 0xe3, 0x8e, 0x7e, 0x2b, 0x04, 0xe8, 0x1e, 0x8c, - 0x08, 0xa5, 0x2c, 0x91, 0x5c, 0xcc, 0x7d, 0x16, 0xcb, 0x40, 0xae, 0xc6, 0x5b, 0x5a, 0xa9, 0x21, - 0x47, 0x1f, 0xc2, 0x6b, 0xb9, 0xec, 0x74, 0x8d, 0xd8, 0xd5, 0xca, 0xcd, 0x07, 0xf7, 0x0b, 0x40, - 0x65, 0x86, 0xcf, 0x02, 0xf9, 0x72, 0xbe, 0x89, 0xe7, 0x10, 0x3a, 0x81, 0xaf, 0x09, 0x0e, 0x70, - 0x27, 0xf0, 0xdd, 0x73, 0x18, 0x14, 0xe1, 0xdd, 0x84, 0x5e, 0x22, 0xd8, 0x72, 0x6e, 0xac, 0x06, - 0x38, 0xbb, 0xa1, 0x7d, 0xd8, 0x09, 0x72, 0xda, 0x26, 0xb6, 0xf5, 0x1d, 0x21, 0xe8, 0xfa, 0x44, - 0x92, 0x2c, 0x1c, 0x7d, 0x56, 0xc9, 0x90, 0x41, 0xc4, 0x52, 0x49, 0xa2, 0x44, 0x53, 0xdf, 0xc2, - 0x85, 0xc0, 0xfd, 0xd3, 0x86, 0xbe, 0xf2, 0xc9, 0xb9, 0xac, 0x20, 0xdb, 0x35, 0xe4, 0xdb, 0x30, - 0x88, 0x48, 0x2a, 0x99, 0xf8, 0x9a, 0xe5, 0x6e, 0x0b, 0x81, 0x0a, 0x51, 0x17, 0x78, 0xee, 0x6b, - 0xd7, 0x03, 0x9c, 0x5f, 0x55, 0xb2, 0x59, 0x4c, 0xc5, 0x2a, 0x91, 0xcc, 0xc7, 0x8c, 0xf8, 0xca, - 0xdc, 0xe4, 0xaf, 0x21, 0xaf, 0x32, 0xdd, 0xae, 0x31, 0x55, 0xa5, 0xc8, 0xd9, 0x14, 0xa5, 0xe8, - 0x99, 0x52, 0x34, 0x1e, 0xdc, 0x8f, 0x60, 0xe4, 0xd1, 0xd0, 0xa3, 0x94, 0x2f, 0x62, 0x39, 0x8f, - 0x97, 0x81, 0x64, 0x0a, 0x3f, 0xd0, 0x27, 0x45, 0xc2, 0x04, 0x58, 0x08, 0xdc, 0xdf, 0x6d, 0x78, - 0xb3, 0x30, 0xc1, 0xec, 0x7c, 0xc1, 0x52, 0x79, 0xc2, 0x83, 0x18, 0xbd, 0x0f, 0x43, 0xa3, 0x36, - 0xaf, 0x66, 0xa7, 0x26, 0x2d, 0xf4, 0x4c, 0x05, 0xe7, 0x79, 0x69, 0x6b, 0x52, 0xf4, 0x00, 0x6e, - 0x55, 0x2d, 0x8b, 0x78, 0x4c, 0xe1, 0xae, 0x7b, 0x56, 0x15, 0x8a, 0x98, 0x24, 0xba, 0xc6, 0x26, - 0x8b, 0xeb, 0xbb, 0xfb, 0x8b, 0x0d, 0xb7, 0x1a, 0xfc, 0x3d, 0xdd, 0xa3, 0x1b, 0x2b, 0x7b, 0x17, - 0x6e, 0x08, 0xa3, 0x5c, 0xa3, 0x5d, 0x17, 0xab, 0x0a, 0xd4, 0x6b, 0x96, 0x66, 0x8c, 0x9b, 0x0f, - 0xee, 0x31, 0x8c, 0x1b, 0x74, 0x8e, 0x19, 0x0d, 0x83, 0x98, 0xb5, 0xf9, 0xb4, 0x5b, 0x7d, 0xba, - 0x5f, 0xc2, 0xcd, 0x7a, 0x1d, 0x31, 0x5b, 0xf2, 0x9f, 0x59, 0x4b, 0xb6, 0xed, 0xb6, 0x6c, 0xbb, - 0x1f, 0x80, 0xa3, 0x87, 0xca, 0xd0, 0x52, 0xad, 0x2a, 0xb2, 0x3e, 0xb4, 0x0f, 0xb6, 0xd4, 0x34, - 0x66, 0x57, 0xf7, 0x47, 0x78, 0xc3, 0xa3, 0xe1, 0xe3, 0x7a, 0x20, 0x1b, 0x93, 0xd7, 0x9a, 0x92, - 0xce, 0x75, 0x29, 0x59, 0xc1, 0x7e, 0x11, 0xcc, 0xf7, 0x4c, 0x44, 0x41, 0x9a, 0x06, 0x3c, 0x3e, - 0x7a, 0x49, 0xe2, 0x33, 0xb6, 0xd1, 0xcf, 0x43, 0x70, 0x92, 0xb5, 0xbe, 0xf1, 0x30, 0x9c, 0xbe, - 0x7d, 0xbf, 0x58, 0x97, 0x1e, 0x0d, 0x9f, 0xa6, 0x4c, 0x14, 0xa0, 0x29, 0x2e, 0x5b, 0xb8, 0x4f, - 0xf5, 0x3c, 0x64, 0x4c, 0x32, 0x87, 0x1e, 0x38, 0xc4, 0x70, 0xd1, 0xb4, 0x55, 0x3a, 0x9c, 0xe9, - 0x3b, 0x55, 0xd0, 0x46, 0x3a, 0x70, 0xd9, 0xc6, 0x3d, 0x2f, 0x8f, 0x19, 0x66, 0x11, 0x5f, 0x6e, - 0x8e, 0xa3, 0xe6, 0xb2, 0xf3, 0x3f, 0x5c, 0xfe, 0xdd, 0x85, 0x1b, 0x1e, 0x0d, 0x8f, 0x78, 0x2c, - 0x59, 0x2c, 0x7f, 0x20, 0xe1, 0x82, 0xa1, 0x4f, 0xa0, 0x67, 0xaa, 0xae, 0x1d, 0x3a, 0xd3, 0xb7, - 0xaa, 0x88, 0x95, 0xf6, 0x99, 0x59, 0x38, 0x53, 0x46, 0x5f, 0xc1, 0x6e, 0x50, 0x6a, 0x29, 0x9d, - 0x56, 0x67, 0xfa, 0xee, 0x06, 0x63, 0xa3, 0x38, 0xb3, 0x70, 0xc5, 0x10, 0x1d, 0x83, 0x23, 0x8a, - 0x85, 0xa1, 0x67, 0xc2, 0x99, 0x1e, 0xb4, 0xe2, 0x94, 0x16, 0xcb, 0xcc, 0xc2, 0x65, 0x33, 0x74, - 0x02, 0x7b, 0xa2, 0x3c, 0xb6, 0x7a, 0xc4, 0x9d, 0xa9, 0xbb, 0x09, 0xc7, 0x68, 0xce, 0x2c, 0x5c, - 0x35, 0x45, 0xa7, 0x30, 0x4a, 0x6a, 0x0d, 0xa6, 0x57, 0xaa, 0x33, 0xbd, 0xd3, 0x0a, 0x57, 0xef, - 0xc6, 0x99, 0x85, 0x1b, 0x00, 0xe8, 0x08, 0xf6, 0x48, 0xb9, 0xd4, 0x7a, 0xfd, 0x5e, 0x97, 0x6d, - 0xa3, 0xa2, 0x98, 0x55, 0x6c, 0x14, 0x88, 0x28, 0xb7, 0xe1, 0xb8, 0xdf, 0x06, 0x52, 0xe9, 0x54, - 0x13, 0x5e, 0xb9, 0x75, 0x9f, 0xc0, 0x50, 0x54, 0x56, 0xca, 0x78, 0x47, 0xa3, 0xbc, 0xb7, 0x29, - 0x57, 0x99, 0xea, 0xcc, 0xc2, 0x35, 0xe3, 0x47, 0x7d, 0xd8, 0x5e, 0xaa, 0x46, 0x72, 0x1f, 0xeb, - 0x6f, 0xc3, 0x63, 0xf5, 0xbd, 0xf9, 0x19, 0x00, 0x59, 0xb7, 0x59, 0x36, 0x1c, 0xfb, 0x55, 0xf8, - 0x72, 0x0f, 0xe2, 0x92, 0xb6, 0x7b, 0x02, 0x43, 0x8f, 0x86, 0xa7, 0xab, 0x98, 0x3e, 0x61, 0x69, - 0x4a, 0xce, 0x18, 0x7a, 0x00, 0x7d, 0xba, 0x86, 0x52, 0x4c, 0x27, 0x55, 0x28, 0xa5, 0x5b, 0x81, - 0xcb, 0xd5, 0xdd, 0xe7, 0xf0, 0x7a, 0xcb, 0xbb, 0xa6, 0xe7, 0xfb, 0x66, 0xcb, 0xa5, 0x19, 0xe6, - 0xb8, 0x16, 0xfd, 0xfa, 0x7d, 0x66, 0xe1, 0x92, 0x76, 0x11, 0xee, 0x0c, 0xf6, 0x2a, 0x7a, 0xe8, - 0x53, 0xb5, 0x1d, 0x73, 0x48, 0x15, 0x71, 0x79, 0xc7, 0x34, 0x7f, 0xdb, 0xe0, 0x5c, 0xfb, 0xde, - 0x37, 0x80, 0x9a, 0x2b, 0x08, 0xed, 0x40, 0xf7, 0x5b, 0x1e, 0xb3, 0x91, 0x85, 0x06, 0xb0, 0xfd, - 0xdd, 0xab, 0x98, 0x89, 0x91, 0xad, 0x8e, 0x9e, 0x1f, 0x05, 0xf1, 0xa8, 0x83, 0x00, 0x7a, 0xcf, - 0x44, 0x20, 0x99, 0x18, 0x6d, 0xa9, 0xb3, 0x2a, 0x3a, 0x13, 0xa3, 0xee, 0xa3, 0x87, 0x7f, 0x5c, - 0x4e, 0xec, 0x8b, 0xcb, 0x89, 0xfd, 0xcf, 0xe5, 0xc4, 0xfe, 0xf5, 0x6a, 0x62, 0x5d, 0x5c, 0x4d, - 0xac, 0xbf, 0xae, 0x26, 0xd6, 0xf3, 0x3b, 0xff, 0xe9, 0xe7, 0xe4, 0x8b, 0x9e, 0xfe, 0xf8, 0xf8, - 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7b, 0xb3, 0x39, 0x6c, 0x7e, 0x0a, 0x00, 0x00, + // 1005 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0xdf, 0x6e, 0x1b, 0xc5, + 0x17, 0xde, 0xb5, 0x1d, 0x3b, 0x3e, 0x9b, 0xb8, 0xfe, 0xcd, 0x0f, 0x5a, 0x2b, 0x14, 0x2b, 0x2c, + 0x14, 0x45, 0x15, 0x4a, 0x90, 0x11, 0x22, 0x2a, 0x88, 0x66, 0x9b, 0x44, 0xd8, 0x81, 0x02, 0x9a, + 0x00, 0x95, 0x2a, 0x71, 0x31, 0x9d, 0x1d, 0xa5, 0x4b, 0xf7, 0x5f, 0x67, 0x27, 0xae, 0xfc, 0x0e, + 0x5c, 0xf0, 0x08, 0xbc, 0x08, 0xf7, 0x5c, 0xa1, 0xde, 0x20, 0x21, 0xae, 0x50, 0xf2, 0x22, 0x68, + 0x66, 0xf6, 0xff, 0x6e, 0x2d, 0x7a, 0xd1, 0x66, 0xe6, 0xcc, 0x39, 0xdf, 0x7c, 0xe7, 0x7c, 0x67, + 0xce, 0x1a, 0x3e, 0xa3, 0x51, 0x10, 0x44, 0x61, 0x12, 0x13, 0xca, 0x0e, 0xa2, 0x27, 0x3f, 0x31, + 0x2a, 0x0e, 0x08, 0xf5, 0xe5, 0x3f, 0xce, 0x68, 0xc4, 0xdd, 0x98, 0x47, 0x22, 0x3a, 0x50, 0xff, + 0x27, 0x85, 0x75, 0x5f, 0x19, 0xd0, 0x30, 0x37, 0xd8, 0xbf, 0x9a, 0xb0, 0x85, 0xc9, 0x0b, 0x87, + 0xfa, 0x58, 0x19, 0xd0, 0x04, 0x06, 0x31, 0x59, 0xf9, 0x11, 0x71, 0x27, 0xe6, 0xae, 0xb9, 0xb7, + 0x85, 0xb3, 0x2d, 0xba, 0x0d, 0xc3, 0xc4, 0xbb, 0x08, 0x89, 0xb8, 0xe4, 0x6c, 0xd2, 0x51, 0x67, + 0x85, 0x01, 0xdd, 0x85, 0x31, 0xa1, 0x94, 0xc5, 0x22, 0xe2, 0x0b, 0x97, 0x85, 0xc2, 0x13, 0xab, + 0x49, 0x57, 0x39, 0x35, 0xec, 0xe8, 0x03, 0xf8, 0x5f, 0x66, 0x3b, 0xcf, 0x11, 0x7b, 0xca, 0xb9, + 0x79, 0x60, 0x7f, 0x0e, 0xa8, 0xcc, 0xf0, 0x91, 0x27, 0x9e, 0x2e, 0xd6, 0xf1, 0x1c, 0x41, 0xc7, + 0x73, 0x15, 0xc1, 0x21, 0xee, 0x78, 0xae, 0xfd, 0x1c, 0x86, 0x45, 0x7a, 0x37, 0xa1, 0x1f, 0x73, + 0xb6, 0x5c, 0xe8, 0xa8, 0x21, 0x4e, 0x77, 0x68, 0x07, 0x36, 0xbd, 0x8c, 0xb6, 0xce, 0x2d, 0xdf, + 0x23, 0x04, 0x3d, 0x97, 0x08, 0x92, 0xa6, 0xa3, 0xd6, 0xb2, 0x18, 0xc2, 0x0b, 0x58, 0x22, 0x48, + 0x10, 0x2b, 0xea, 0x5d, 0x5c, 0x18, 0xec, 0x3f, 0x4d, 0x18, 0xc8, 0x3b, 0xa3, 0x48, 0x54, 0x90, + 0xcd, 0x1a, 0xf2, 0x6d, 0x18, 0x06, 0x24, 0x11, 0x8c, 0x7f, 0xc9, 0xb2, 0x6b, 0x0b, 0x83, 0x4c, + 0x51, 0x09, 0xbc, 0x70, 0xd5, 0xd5, 0x43, 0x9c, 0x6d, 0x65, 0xb1, 0x59, 0x48, 0xf9, 0x2a, 0x16, + 0xcc, 0xc5, 0x8c, 0xb8, 0x32, 0x5c, 0xd7, 0xaf, 0x61, 0xaf, 0x32, 0xdd, 0xa8, 0x31, 0x95, 0x52, + 0x64, 0x6c, 0x0a, 0x29, 0xfa, 0x5a, 0x8a, 0xc6, 0x81, 0xfd, 0x21, 0x8c, 0x1d, 0xea, 0x3b, 0x94, + 0x46, 0x97, 0xa1, 0x58, 0x84, 0x4b, 0x4f, 0x30, 0x89, 0xef, 0xa9, 0x95, 0x24, 0xa1, 0x13, 0x2c, + 0x0c, 0xf6, 0x6f, 0x26, 0xbc, 0x59, 0x84, 0x60, 0xf6, 0xfc, 0x92, 0x25, 0xe2, 0x2c, 0xf2, 0x42, + 0xf4, 0x3e, 0x8c, 0xb4, 0xdb, 0xa2, 0x5a, 0x9d, 0x9a, 0xb5, 0xf0, 0xd3, 0x0a, 0x2e, 0x32, 0x69, + 0x6b, 0x56, 0x74, 0x08, 0xb7, 0xaa, 0x91, 0x45, 0x3e, 0x5a, 0xb8, 0x57, 0x1d, 0x4b, 0x85, 0x02, + 0x26, 0x88, 0xd2, 0x58, 0x57, 0x31, 0xdf, 0xdb, 0x7f, 0x98, 0x70, 0xab, 0xc1, 0xdf, 0x51, 0x3d, + 0xba, 0x56, 0xd9, 0x3d, 0xb8, 0xc1, 0xb5, 0x73, 0x8d, 0x76, 0xdd, 0x2c, 0x15, 0xa8, 0x6b, 0x96, + 0xa4, 0x8c, 0x9b, 0x07, 0xe8, 0x3e, 0x58, 0x31, 0xe3, 0x81, 0x97, 0x24, 0x5e, 0x14, 0x26, 0x8a, + 0xee, 0x68, 0xf6, 0xf6, 0x7e, 0xf1, 0xc2, 0x1d, 0xea, 0x7f, 0x9f, 0x30, 0xfe, 0x6d, 0xe1, 0x84, + 0xcb, 0x11, 0xf6, 0x09, 0x4c, 0x1a, 0xf9, 0x9c, 0x30, 0xea, 0x7b, 0x21, 0x6b, 0x23, 0x6d, 0xb6, + 0x92, 0xb6, 0x8f, 0xe0, 0x66, 0xbd, 0x11, 0x30, 0x5b, 0x46, 0xcf, 0x58, 0x8b, 0x5c, 0x66, 0x9b, + 0x5c, 0xf6, 0xcf, 0x26, 0x58, 0xea, 0x59, 0xa6, 0x89, 0x1d, 0xc1, 0x26, 0xcf, 0xb2, 0x37, 0x77, + 0xbb, 0x7b, 0xd6, 0xec, 0xbd, 0x6a, 0x56, 0x99, 0xe7, 0x7e, 0xb6, 0x38, 0x0d, 0x05, 0x5f, 0xe1, + 0x3c, 0x6a, 0xe7, 0x53, 0xd8, 0xae, 0x1c, 0xa1, 0x31, 0x74, 0x9f, 0xa5, 0x3d, 0x39, 0xc4, 0x72, + 0x89, 0xde, 0x80, 0x8d, 0x25, 0xf1, 0x2f, 0xb3, 0xf1, 0xa5, 0x37, 0xf7, 0x3a, 0x87, 0xa6, 0xfd, + 0x23, 0xfc, 0xdf, 0xa1, 0xfe, 0x69, 0xfd, 0xf1, 0xac, 0x93, 0xb8, 0xed, 0x11, 0x76, 0xda, 0x1f, + 0xa1, 0xbd, 0x82, 0x9d, 0xa2, 0x5e, 0x85, 0x36, 0xc7, 0x4f, 0x49, 0x78, 0xc1, 0xd6, 0xde, 0x52, + 0x13, 0xbc, 0xf3, 0xda, 0x82, 0x7f, 0xa7, 0xde, 0x6c, 0x4a, 0x24, 0xbd, 0xf0, 0x08, 0x2c, 0xa2, + 0xb9, 0x94, 0xea, 0x3d, 0xad, 0x82, 0xd6, 0x6b, 0x81, 0xcb, 0x21, 0x76, 0x5c, 0x9e, 0x04, 0x98, + 0x05, 0xd1, 0x72, 0x7d, 0x1a, 0xb5, 0x1b, 0x3b, 0xaf, 0x7f, 0xe3, 0xdf, 0x3d, 0xb8, 0xe1, 0x50, + 0xff, 0x38, 0x0a, 0x05, 0x0b, 0xc5, 0x0f, 0x52, 0x39, 0xf4, 0x31, 0xf4, 0x75, 0x5b, 0xa9, 0xfb, + 0xac, 0xd9, 0x5b, 0x55, 0xc0, 0x4a, 0x7f, 0xce, 0x0d, 0x9c, 0x3a, 0xa3, 0x2f, 0x60, 0xcb, 0x2b, + 0xf5, 0xac, 0x2a, 0xaa, 0x35, 0x7b, 0x67, 0x4d, 0xb0, 0x76, 0x9c, 0x1b, 0xb8, 0x12, 0x88, 0x4e, + 0xc0, 0xe2, 0xc5, 0x48, 0x53, 0xaf, 0xd6, 0x9a, 0xed, 0xb6, 0xe2, 0x94, 0x46, 0xdf, 0xdc, 0xc0, + 0xe5, 0x30, 0x74, 0x06, 0xdb, 0xbc, 0x3c, 0x58, 0xd4, 0xab, 0xb6, 0x66, 0xf6, 0x3a, 0x1c, 0xed, + 0x39, 0x37, 0x70, 0x35, 0x14, 0x9d, 0xc3, 0x38, 0xae, 0xb5, 0x97, 0x1a, 0xfa, 0xd6, 0xec, 0x4e, + 0x2b, 0x5c, 0xbd, 0x17, 0xe7, 0x06, 0x6e, 0x00, 0xa0, 0x63, 0xd8, 0x26, 0x65, 0xa5, 0xd5, 0x07, + 0xe2, 0x55, 0xd5, 0xd6, 0x2e, 0x92, 0x59, 0x25, 0x46, 0x82, 0xf0, 0x72, 0x13, 0x4e, 0x06, 0x6d, + 0x20, 0x95, 0x3e, 0xd5, 0xe9, 0x95, 0x1b, 0xf7, 0x21, 0x8c, 0x78, 0x65, 0x66, 0x4d, 0x36, 0x15, + 0xca, 0xbb, 0xeb, 0x6a, 0x95, 0xba, 0xce, 0x0d, 0x5c, 0x0b, 0x7e, 0x30, 0x48, 0xe7, 0x81, 0x7d, + 0xaa, 0xbe, 0xd7, 0x27, 0xf2, 0xcb, 0x7e, 0x0f, 0x80, 0xe4, 0x6d, 0x96, 0x3e, 0x8d, 0x9d, 0x2a, + 0x7c, 0xb9, 0x07, 0x71, 0xc9, 0xdb, 0x3e, 0x83, 0x91, 0x43, 0xfd, 0xf3, 0x55, 0x48, 0x1f, 0xb2, + 0x24, 0x21, 0x17, 0x0c, 0x1d, 0xc2, 0x80, 0xe6, 0x50, 0x66, 0xb3, 0xe7, 0xa5, 0x6f, 0x05, 0x2e, + 0x73, 0xb7, 0x1f, 0xab, 0x89, 0x54, 0x3f, 0x57, 0xf4, 0x5c, 0x57, 0x8f, 0xd1, 0x24, 0xc5, 0x9c, + 0xd4, 0xb2, 0xcf, 0xcf, 0xe7, 0x06, 0x2e, 0x79, 0x17, 0xe9, 0xce, 0x61, 0xbb, 0xe2, 0x87, 0x3e, + 0x81, 0x01, 0xcf, 0x21, 0x65, 0xc6, 0xe5, 0x09, 0xd3, 0xfc, 0xf5, 0x85, 0x33, 0xef, 0xbb, 0x5f, + 0x01, 0x6a, 0x0e, 0x20, 0xb4, 0x09, 0xbd, 0xaf, 0xa3, 0x90, 0x8d, 0x0d, 0x34, 0x84, 0x8d, 0x6f, + 0x5e, 0x84, 0x8c, 0x8f, 0x4d, 0xb9, 0x74, 0xdc, 0xc0, 0x0b, 0xc7, 0x1d, 0x04, 0xd0, 0x7f, 0xc4, + 0x3d, 0xc1, 0xf8, 0xb8, 0x2b, 0xd7, 0x52, 0x74, 0xc6, 0xc7, 0xbd, 0x07, 0xf7, 0x7f, 0xbf, 0x9a, + 0x9a, 0x2f, 0xaf, 0xa6, 0xe6, 0x3f, 0x57, 0x53, 0xf3, 0x97, 0xeb, 0xa9, 0xf1, 0xf2, 0x7a, 0x6a, + 0xfc, 0x75, 0x3d, 0x35, 0x1e, 0xdf, 0xf9, 0x4f, 0x3f, 0x78, 0x9f, 0xf4, 0xd5, 0x9f, 0x8f, 0xfe, + 0x0d, 0x00, 0x00, 0xff, 0xff, 0xf9, 0x8e, 0x57, 0x42, 0x20, 0x0b, 0x00, 0x00, } func (m *RawAclRecord) Marshal() (dAtA []byte, err error) { @@ -1611,6 +1623,11 @@ func (m *AclAccountRequestAccept) MarshalToSizedBuffer(dAtA []byte) (int, error) _ = 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 { i -= len(m.EncryptedReadKeys) copy(dAtA[i:], m.EncryptedReadKeys) @@ -1715,11 +1732,23 @@ func (m *AclReadKeys) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.ReadKey) > 0 { - for iNdEx := len(m.ReadKey) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.ReadKey[iNdEx]) - copy(dAtA[i:], m.ReadKey[iNdEx]) - i = encodeVarintAclrecord(dAtA, i, uint64(len(m.ReadKey[iNdEx]))) + if len(m.ReadKeys) > 0 { + for k := range m.ReadKeys { + v := m.ReadKeys[k] + baseI := i + if len(v) > 0 { + i -= len(v) + copy(dAtA[i:], v) + i = encodeVarintAclrecord(dAtA, i, uint64(len(v))) + 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] = 0xa } @@ -1727,7 +1756,7 @@ func (m *AclReadKeys) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *AclEncryptedReadKeys) Marshal() (dAtA []byte, err error) { +func (m *AclEncryptedReadKey) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1737,20 +1766,20 @@ func (m *AclEncryptedReadKeys) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *AclEncryptedReadKeys) MarshalTo(dAtA []byte) (int, error) { +func (m *AclEncryptedReadKey) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *AclEncryptedReadKeys) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *AclEncryptedReadKey) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.EncryptedReadKeys) > 0 { - i -= len(m.EncryptedReadKeys) - copy(dAtA[i:], m.EncryptedReadKeys) - i = encodeVarintAclrecord(dAtA, i, uint64(len(m.EncryptedReadKeys))) + 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] = 0x12 } @@ -2407,6 +2436,9 @@ func (m *AclAccountRequestAccept) Size() (n int) { if l > 0 { n += 1 + l + sovAclrecord(uint64(l)) } + if m.Permissions != 0 { + n += 1 + sovAclrecord(uint64(m.Permissions)) + } return n } @@ -2442,16 +2474,22 @@ func (m *AclReadKeys) Size() (n int) { } var l int _ = l - if len(m.ReadKey) > 0 { - for _, b := range m.ReadKey { - l = len(b) - n += 1 + l + sovAclrecord(uint64(l)) + if len(m.ReadKeys) > 0 { + for k, v := range m.ReadKeys { + _ = k + _ = v + l = 0 + if len(v) > 0 { + l = 1 + len(v) + sovAclrecord(uint64(len(v))) + } + mapEntrySize := 1 + len(k) + sovAclrecord(uint64(len(k))) + l + n += mapEntrySize + 1 + sovAclrecord(uint64(mapEntrySize)) } } return n } -func (m *AclEncryptedReadKeys) Size() (n int) { +func (m *AclEncryptedReadKey) Size() (n int) { if m == nil { return 0 } @@ -2461,7 +2499,7 @@ func (m *AclEncryptedReadKeys) Size() (n int) { if l > 0 { n += 1 + l + sovAclrecord(uint64(l)) } - l = len(m.EncryptedReadKeys) + l = len(m.EncryptedReadKey) if l > 0 { n += 1 + l + sovAclrecord(uint64(l)) } @@ -3804,6 +3842,25 @@ func (m *AclAccountRequestAccept) Unmarshal(dAtA []byte) error { m.EncryptedReadKeys = []byte{} } 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:]) @@ -4020,9 +4077,9 @@ func (m *AclReadKeys) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ReadKey", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ReadKeys", wireType) } - var byteLen int + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowAclrecord @@ -4032,23 +4089,119 @@ func (m *AclReadKeys) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + if msglen < 0 { return ErrInvalidLengthAclrecord } - postIndex := iNdEx + byteLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthAclrecord } if postIndex > l { return io.ErrUnexpectedEOF } - m.ReadKey = append(m.ReadKey, make([]byte, postIndex-iNdEx)) - copy(m.ReadKey[len(m.ReadKey)-1], dAtA[iNdEx:postIndex]) + if m.ReadKeys == nil { + m.ReadKeys = make(map[string][]byte) + } + var mapkey string + mapvalue := []byte{} + 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 mapbyteLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapbyteLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intMapbyteLen := int(mapbyteLen) + if intMapbyteLen < 0 { + return ErrInvalidLengthAclrecord + } + postbytesIndex := iNdEx + intMapbyteLen + if postbytesIndex < 0 { + return ErrInvalidLengthAclrecord + } + if postbytesIndex > l { + return io.ErrUnexpectedEOF + } + mapvalue = make([]byte, mapbyteLen) + copy(mapvalue, dAtA[iNdEx:postbytesIndex]) + iNdEx = postbytesIndex + } 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.ReadKeys[mapkey] = mapvalue iNdEx = postIndex default: iNdEx = preIndex @@ -4071,7 +4224,7 @@ func (m *AclReadKeys) Unmarshal(dAtA []byte) error { } return nil } -func (m *AclEncryptedReadKeys) Unmarshal(dAtA []byte) error { +func (m *AclEncryptedReadKey) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4094,10 +4247,10 @@ func (m *AclEncryptedReadKeys) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AclEncryptedReadKeys: wiretype end group for non-group") + return fmt.Errorf("proto: AclEncryptedReadKey: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AclEncryptedReadKeys: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AclEncryptedReadKey: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -4136,7 +4289,7 @@ func (m *AclEncryptedReadKeys) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field EncryptedReadKeys", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field EncryptedReadKey", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { @@ -4163,9 +4316,9 @@ func (m *AclEncryptedReadKeys) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.EncryptedReadKeys = append(m.EncryptedReadKeys[:0], dAtA[iNdEx:postIndex]...) - if m.EncryptedReadKeys == nil { - m.EncryptedReadKeys = []byte{} + m.EncryptedReadKey = append(m.EncryptedReadKey[:0], dAtA[iNdEx:postIndex]...) + if m.EncryptedReadKey == nil { + m.EncryptedReadKey = []byte{} } iNdEx = postIndex default: @@ -4350,7 +4503,7 @@ func (m *AclReadKeyChange) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.AccountKeys = append(m.AccountKeys, &AclEncryptedReadKeys{}) + m.AccountKeys = append(m.AccountKeys, &AclEncryptedReadKey{}) if err := m.AccountKeys[len(m.AccountKeys)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } @@ -4468,7 +4621,7 @@ func (m *AclAccountRemove) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.AccountKeys = append(m.AccountKeys, &AclEncryptedReadKeys{}) + m.AccountKeys = append(m.AccountKeys, &AclEncryptedReadKey{}) if err := m.AccountKeys[len(m.AccountKeys)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } diff --git a/commonspace/object/acl/aclrecordproto/protos/aclrecord.proto b/commonspace/object/acl/aclrecordproto/protos/aclrecord.proto index 7219aecd..1fa11e59 100644 --- a/commonspace/object/acl/aclrecordproto/protos/aclrecord.proto +++ b/commonspace/object/acl/aclrecordproto/protos/aclrecord.proto @@ -52,6 +52,7 @@ message AclAccountRequestAccept { bytes identity = 1; string requestRecordId = 2; bytes encryptedReadKeys = 3; + AclUserPermissions permissions = 4; } // AclAccountRequestDecline contains the reference to join record @@ -66,13 +67,13 @@ message AclAccountInviteRevoke { // AclReadKeys are all read keys in Acl message AclReadKeys { - repeated bytes readKey = 1; + map readKeys = 1; } -// AclEncryptedReadKeys are all keys for specific identity -message AclEncryptedReadKeys { +// AclEncryptedReadKeys are new key for specific identity +message AclEncryptedReadKey { bytes identity = 1; - bytes encryptedReadKeys = 2; + bytes encryptedReadKey = 2; } // AclAccountPermissionChange changes permissions of specific account @@ -83,13 +84,13 @@ message AclAccountPermissionChange { // AclReadKeyChange changes the key for a space message AclReadKeyChange { - repeated AclEncryptedReadKeys accountKeys = 1; + repeated AclEncryptedReadKey accountKeys = 1; } // AclAccountRemove removes an account and changes read key for space message AclAccountRemove { bytes identity = 1; - repeated AclEncryptedReadKeys accountKeys = 2; + repeated AclEncryptedReadKey accountKeys = 2; } // AclContentValue contains possible values for Acl diff --git a/commonspace/object/acl/list/aclrecordbuilder.go b/commonspace/object/acl/list/aclrecordbuilder.go index a1e89560..686ef3fa 100644 --- a/commonspace/object/acl/list/aclrecordbuilder.go +++ b/commonspace/object/acl/list/aclrecordbuilder.go @@ -1,11 +1,12 @@ package list import ( + "time" + "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" "github.com/anyproto/any-sync/util/cidutil" "github.com/anyproto/any-sync/util/crypto" "github.com/gogo/protobuf/proto" - "time" ) type RootContent struct { @@ -53,7 +54,6 @@ func (a *aclRecordBuilder) Unmarshall(rawIdRecord *aclrecordproto.RawAclRecordWi } rec = &AclRecord{ Id: rawIdRecord.Id, - ReadKeyId: rawIdRecord.Id, Timestamp: aclRoot.Timestamp, Signature: rawRec.Signature, Identity: pubKey, @@ -72,7 +72,6 @@ func (a *aclRecordBuilder) Unmarshall(rawIdRecord *aclrecordproto.RawAclRecordWi rec = &AclRecord{ Id: rawIdRecord.Id, PrevId: aclRecord.PrevId, - ReadKeyId: aclRecord.ReadKeyId, Timestamp: aclRecord.Timestamp, Data: aclRecord.Data, Signature: rawRec.Signature, diff --git a/commonspace/object/acl/list/aclstate.go b/commonspace/object/acl/list/aclstate.go index 496b865d..6f0c917b 100644 --- a/commonspace/object/acl/list/aclstate.go +++ b/commonspace/object/acl/list/aclstate.go @@ -2,7 +2,6 @@ package list import ( "errors" - "fmt" "github.com/anyproto/any-sync/app/logger" "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" @@ -15,12 +14,9 @@ var log = logger.NewNamedSugared("common.commonspace.acllist") var ( ErrNoSuchAccount = errors.New("no such account") - ErrIncorrectInviteKey = errors.New("incorrect invite key") + ErrUnexpectedContentType = errors.New("unexpected content type") ErrIncorrectIdentity = errors.New("incorrect identity") ErrFailedToDecrypt = errors.New("failed to decrypt key") - ErrUserRemoved = errors.New("user was removed from the document") - ErrDocumentForbidden = errors.New("your user was forbidden access to the document") - ErrUserAlreadyExists = errors.New("user already exists") ErrNoSuchRecord = errors.New("no such record") ErrNoSuchRequest = errors.New("no such request") ErrNoSuchInvite = errors.New("no such invite") @@ -50,13 +46,14 @@ type AclState struct { keyStore crypto.KeyStorage totalReadKeys int - lastRecordId string + lastRecordId string + contentValidator ContentValidator } func newAclStateWithKeys( id string, key crypto.PrivKey) (*AclState, error) { - return &AclState{ + st := &AclState{ id: id, key: key, pubKey: key.GetPublic(), @@ -65,18 +62,30 @@ func newAclStateWithKeys( statesAtRecord: make(map[string][]AclUserState), inviteKeys: make(map[string]crypto.PubKey), requestRecords: make(map[string]RequestRecord), - }, nil + keyStore: crypto.NewKeyStorage(), + } + st.contentValidator = &contentValidator{ + keyStore: st.keyStore, + aclState: st, + } + return st, nil } func newAclState(id string) *AclState { - return &AclState{ + st := &AclState{ id: id, userReadKeys: make(map[string]crypto.SymKey), userStates: make(map[string]AclUserState), statesAtRecord: make(map[string][]AclUserState), inviteKeys: make(map[string]crypto.PubKey), requestRecords: make(map[string]RequestRecord), + keyStore: crypto.NewKeyStorage(), } + st.contentValidator = &contentValidator{ + keyStore: st.keyStore, + aclState: st, + } + return st } func (st *AclState) CurrentReadKeyId() string { @@ -167,7 +176,7 @@ func (st *AclState) applyRoot(record *AclRecord) (err error) { PubKey: record.Identity, Permissions: AclPermissions(aclrecordproto.AclUserPermissions_Admin), } - st.currentReadKeyId = record.ReadKeyId + st.currentReadKeyId = record.Id st.userStates[mapKeyFromPubKey(record.Identity)] = userState st.totalReadKeys++ return @@ -196,76 +205,162 @@ func (st *AclState) saveReadKeyFromRoot(record *AclRecord) (err error) { func (st *AclState) applyChangeData(record *AclRecord) (err error) { model := record.Model.(*aclrecordproto.AclData) - if !st.isUserJoin(model) && !st.Permissions(record.Identity).CanManageAccounts() { - return ErrInsufficientPermissions - } for _, ch := range model.GetAclContent() { - if err = st.applyChangeContent(ch, record.Id); err != nil { + if err = st.applyChangeContent(ch, record.Id, record.Identity); err != nil { log.Info("error while applying changes: %v; ignore", zap.Error(err)) return err } } - if record.ReadKeyId != st.currentReadKeyId { - st.totalReadKeys++ - st.currentReadKeyId = record.ReadKeyId - } return nil } -func (st *AclState) applyChangeContent(ch *aclrecordproto.AclContentValue, recordId string) error { +func (st *AclState) applyChangeContent(ch *aclrecordproto.AclContentValue, recordId string, authorIdentity crypto.PubKey) error { switch { case ch.GetPermissionChange() != nil: - return st.applyPermissionChange(ch.GetPermissionChange(), recordId) + return st.applyPermissionChange(ch.GetPermissionChange(), recordId, authorIdentity) case ch.GetInvite() != nil: - return st.applyInvite(ch.GetInvite(), recordId) + return st.applyInvite(ch.GetInvite(), recordId, authorIdentity) case ch.GetInviteRevoke() != nil: - return st.applyUserRemove(ch.GetUserRemove(), recordId) - case ch.GetUserInvite() != nil: - return st.applyUserInvite(ch.GetUserInvite(), recordId) - case ch.GetUserJoin() != nil: - return st.applyUserJoin(ch.GetUserJoin(), recordId) + return st.applyInviteRevoke(ch.GetInviteRevoke(), recordId, authorIdentity) + case ch.GetRequestJoin() != nil: + return st.applyRequestJoin(ch.GetRequestJoin(), recordId, authorIdentity) + case ch.GetRequestAccept() != nil: + return st.applyRequestAccept(ch.GetRequestAccept(), recordId, authorIdentity) + case ch.GetRequestDecline() != nil: + return st.applyRequestDecline(ch.GetRequestDecline(), recordId, authorIdentity) + case ch.GetAccountRemove() != nil: + return st.applyAccountRemove(ch.GetAccountRemove(), recordId, authorIdentity) + case ch.GetReadKeyChange() != nil: + return st.applyReadKeyChange(ch.GetReadKeyChange(), recordId, authorIdentity) default: - return fmt.Errorf("unexpected change type: %v", ch) + return ErrUnexpectedContentType } } -func (st *AclState) applyPermissionChange(ch *aclrecordproto.AclAccountPermissionChange, recordId string) error { +func (st *AclState) applyPermissionChange(ch *aclrecordproto.AclAccountPermissionChange, recordId string, authorIdentity crypto.PubKey) error { chIdentity, err := st.keyStore.PubKeyFromProto(ch.Identity) if err != nil { return err } - state, exists := st.userStates[mapKeyFromPubKey(chIdentity)] - if !exists { - return ErrNoSuchAccount + err = st.contentValidator.ValidatePermissionChange(ch, recordId, authorIdentity) + if err != nil { + return err } + stringKey := mapKeyFromPubKey(chIdentity) + state, _ := st.userStates[stringKey] state.Permissions = AclPermissions(ch.Permissions) + st.userStates[stringKey] = state return nil } -func (st *AclState) applyInvite(ch *aclrecordproto.AclAccountInvite, recordId string) error { +func (st *AclState) applyInvite(ch *aclrecordproto.AclAccountInvite, recordId string, authorIdentity crypto.PubKey) error { inviteKey, err := st.keyStore.PubKeyFromProto(ch.InviteKey) if err != nil { return err } + err = st.contentValidator.ValidateInvite(ch, recordId, authorIdentity) + if err != nil { + return err + } st.inviteKeys[recordId] = inviteKey return nil } -func (st *AclState) applyInviteRevoke(ch *aclrecordproto.AclAccountInviteRevoke, recordId string) error { - +func (st *AclState) applyInviteRevoke(ch *aclrecordproto.AclAccountInviteRevoke, recordId string, authorIdentity crypto.PubKey) error { + err := st.contentValidator.ValidateInviteRevoke(ch, recordId, authorIdentity) + if err != nil { + return err + } delete(st.inviteKeys, ch.InviteRecordId) return nil } -func (st *AclState) applyUserJoin(ch *aclrecordproto.AclUserJoin, recordId string) error { +func (st *AclState) applyRequestJoin(ch *aclrecordproto.AclAccountRequestJoin, recordId string, authorIdentity crypto.PubKey) error { + err := st.contentValidator.ValidateRequestJoin(ch, recordId, authorIdentity) + if err != nil { + return err + } + st.requestRecords[recordId] = RequestRecord{ + RequestIdentity: authorIdentity, + RequestMetadata: ch.Metadata, + } return nil } -func (st *AclState) applyUserAdd(ch *aclrecordproto.AclUserAdd, recordId string) error { +func (st *AclState) applyRequestAccept(ch *aclrecordproto.AclAccountRequestAccept, recordId string, authorIdentity crypto.PubKey) error { + err := st.contentValidator.ValidateRequestAccept(ch, recordId, authorIdentity) + if err != nil { + return err + } + acceptIdentity, err := st.keyStore.PubKeyFromProto(ch.Identity) + if err != nil { + return err + } + record, _ := st.requestRecords[ch.RequestRecordId] + st.userStates[mapKeyFromPubKey(acceptIdentity)] = AclUserState{ + PubKey: acceptIdentity, + Permissions: AclPermissions(ch.Permissions), + RequestMetadata: record.RequestMetadata, + } + if !st.pubKey.Equals(acceptIdentity) { + return nil + } + res, err := st.key.Decrypt(ch.EncryptedReadKeys) + if err != nil { + return err + } + keys := &aclrecordproto.AclReadKeys{} + err = proto.Unmarshal(res, keys) + if err != nil { + return err + } + for recordId, key := range keys.ReadKeys { + sym, err := crypto.UnmarshallAESKey(key) + if err != nil { + return err + } + st.userReadKeys[recordId] = sym + } return nil } -func (st *AclState) applyUserRemove(ch *aclrecordproto.AclUserRemove, recordId string) error { +func (st *AclState) applyRequestDecline(ch *aclrecordproto.AclAccountRequestDecline, recordId string, authorIdentity crypto.PubKey) error { + err := st.contentValidator.ValidateRequestDecline(ch, recordId, authorIdentity) + if err != nil { + return err + } + delete(st.requestRecords, ch.RequestRecordId) + return nil +} + +func (st *AclState) applyAccountRemove(ch *aclrecordproto.AclAccountRemove, recordId string, authorIdentity crypto.PubKey) error { + err := st.contentValidator.ValidateRemove(ch, recordId, authorIdentity) + if err != nil { + return err + } + return st.updateReadKey(ch.AccountKeys, recordId) +} + +func (st *AclState) applyReadKeyChange(ch *aclrecordproto.AclReadKeyChange, recordId string, authorIdentity crypto.PubKey) error { + err := st.contentValidator.ValidateReadKeyChange(ch, recordId, authorIdentity) + if err != nil { + return err + } + return st.updateReadKey(ch.AccountKeys, recordId) +} + +func (st *AclState) updateReadKey(keys []*aclrecordproto.AclEncryptedReadKey, recordId string) error { + for _, accKey := range keys { + identity, _ := st.keyStore.PubKeyFromProto(accKey.Identity) + if st.pubKey.Equals(identity) { + res, err := st.decryptReadKey(accKey.EncryptedReadKey) + if err != nil { + return err + } + st.userReadKeys[recordId] = res + } + } + st.currentReadKeyId = recordId return nil } @@ -274,7 +369,6 @@ func (st *AclState) decryptReadKey(msg []byte) (crypto.SymKey, error) { if err != nil { return nil, ErrFailedToDecrypt } - key, err := crypto.UnmarshallAESKey(decrypted) if err != nil { return nil, ErrFailedToDecrypt @@ -290,19 +384,10 @@ func (st *AclState) Permissions(identity crypto.PubKey) AclPermissions { return state.Permissions } -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) UserStates() map[string]AclUserState { return st.userStates } -func (st *AclState) Invite(acceptPubKey []byte) (invite *aclrecordproto.AclUserInvite, err error) { - return -} - func (st *AclState) LastRecordId() string { return st.lastRecordId } diff --git a/commonspace/object/acl/list/models.go b/commonspace/object/acl/list/models.go index 6ec52b28..b0583a39 100644 --- a/commonspace/object/acl/list/models.go +++ b/commonspace/object/acl/list/models.go @@ -8,7 +8,6 @@ import ( type AclRecord struct { Id string PrevId string - ReadKeyId string Timestamp int64 Data []byte Identity crypto.PubKey @@ -22,8 +21,9 @@ type RequestRecord struct { } type AclUserState struct { - PubKey crypto.PubKey - Permissions AclPermissions + PubKey crypto.PubKey + Permissions AclPermissions + RequestMetadata []byte } type AclPermissions aclrecordproto.AclUserPermissions diff --git a/commonspace/object/acl/list/validator.go b/commonspace/object/acl/list/validator.go index 6fa8be20..51dfa575 100644 --- a/commonspace/object/acl/list/validator.go +++ b/commonspace/object/acl/list/validator.go @@ -96,6 +96,9 @@ func (c *contentValidator) ValidateRequestAccept(ch *aclrecordproto.AclAccountRe if !acceptIdentity.Equals(record.RequestIdentity) { return ErrIncorrectIdentity } + if ch.Permissions == aclrecordproto.AclUserPermissions_Owner { + return ErrInsufficientPermissions + } return } @@ -129,7 +132,7 @@ func (c *contentValidator) ValidateReadKeyChange(ch *aclrecordproto.AclReadKeyCh return c.validateAccountReadKeys(ch.AccountKeys) } -func (c *contentValidator) validateAccountReadKeys(accountKeys []*aclrecordproto.AclEncryptedReadKeys) (err error) { +func (c *contentValidator) validateAccountReadKeys(accountKeys []*aclrecordproto.AclEncryptedReadKey) (err error) { if len(accountKeys) != len(c.aclState.userStates) { return ErrIncorrectNumberOfAccounts } From 894f4db1ff05e61e392cb6807f33f269c9d3dc2a Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Fri, 23 Jun 2023 16:54:55 +0200 Subject: [PATCH 076/123] peer sub connections throtling + fixes --- net/peer/limiter.go | 18 +++ net/peer/peer.go | 59 ++++++++- net/peer/peer_test.go | 118 ++++++++++++++---- .../rpctest/multiconntest/multiconntest.go | 29 +++++ net/rpc/rpctest/peer.go | 22 +--- net/transport/transport.go | 4 + net/transport/yamux/conn.go | 3 +- 7 files changed, 207 insertions(+), 46 deletions(-) create mode 100644 net/peer/limiter.go create mode 100644 net/rpc/rpctest/multiconntest/multiconntest.go diff --git a/net/peer/limiter.go b/net/peer/limiter.go new file mode 100644 index 00000000..4c8e1589 --- /dev/null +++ b/net/peer/limiter.go @@ -0,0 +1,18 @@ +package peer + +import ( + "time" +) + +type limiter struct { + startThreshold int + slowDownStep time.Duration +} + +func (l limiter) wait(count int) <-chan time.Time { + if count > l.startThreshold { + wait := l.slowDownStep * time.Duration(count-l.startThreshold) + return time.After(wait) + } + return nil +} diff --git a/net/peer/peer.go b/net/peer/peer.go index c8a54a43..b96162f7 100644 --- a/net/peer/peer.go +++ b/net/peer/peer.go @@ -19,6 +19,7 @@ import ( "storj.io/drpc/drpcstream" "storj.io/drpc/drpcwire" "sync" + "sync/atomic" "time" ) @@ -35,8 +36,15 @@ func NewPeer(mc transport.MultiConn, ctrl connCtrl) (p Peer, err error) { active: map[*subConn]struct{}{}, MultiConn: mc, ctrl: ctrl, - created: time.Now(), + limiter: limiter{ + // start throttling after 10 sub conns + startThreshold: 10, + slowDownStep: time.Millisecond * 100, + }, + subConnRelease: make(chan drpc.Conn), + created: time.Now(), } + pr.acceptCtx, pr.acceptCtxCancel = context.WithCancel(context.Background()) if pr.id, err = CtxPeerId(ctx); err != nil { return } @@ -70,13 +78,21 @@ type peer struct { ctrl connCtrl // drpc conn pool - inactive []*subConn - active map[*subConn]struct{} + // outgoing + inactive []*subConn + active map[*subConn]struct{} + subConnRelease chan drpc.Conn + + incomingCount atomic.Int32 + acceptCtx context.Context + + acceptCtxCancel context.CancelFunc + + limiter limiter mu sync.Mutex created time.Time - transport.MultiConn } @@ -87,7 +103,18 @@ func (p *peer) Id() string { func (p *peer) AcquireDrpcConn(ctx context.Context) (drpc.Conn, error) { p.mu.Lock() if len(p.inactive) == 0 { + wait := p.limiter.wait(len(p.active)) p.mu.Unlock() + if wait != nil { + // throttle new connection opening + select { + case <-ctx.Done(): + return nil, ctx.Err() + case dconn := <-p.subConnRelease: + return dconn, nil + case <-wait: + } + } dconn, err := p.openDrpcConn(ctx) if err != nil { return nil, err @@ -110,6 +137,21 @@ func (p *peer) AcquireDrpcConn(ctx context.Context) (drpc.Conn, error) { } func (p *peer) ReleaseDrpcConn(conn drpc.Conn) { + // do nothing if it's closed connection + select { + case <-conn.Closed(): + return + default: + } + + // try to send this connection to acquire if anyone is waiting for it + select { + case p.subConnRelease <- conn: + return + default: + } + + // return to pool p.mu.Lock() defer p.mu.Unlock() sc, ok := conn.(*subConn) @@ -162,12 +204,21 @@ func (p *peer) acceptLoop() { } }() for { + if wait := p.limiter.wait(int(p.incomingCount.Load())); wait != nil { + select { + case <-wait: + case <-p.acceptCtx.Done(): + return + } + } conn, err := p.Accept() if err != nil { exitErr = err return } go func() { + p.incomingCount.Add(1) + defer p.incomingCount.Add(-1) serveErr := p.serve(conn) if serveErr != io.EOF && serveErr != transport.ErrConnClosed { log.InfoCtx(p.Context(), "serve connection error", zap.Error(serveErr)) diff --git a/net/peer/peer_test.go b/net/peer/peer_test.go index ac06f8d6..7aa8428c 100644 --- a/net/peer/peer_test.go +++ b/net/peer/peer_test.go @@ -12,6 +12,8 @@ import ( "io" "net" _ "net/http/pprof" + "storj.io/drpc" + "storj.io/drpc/drpcconn" "testing" "time" ) @@ -19,32 +21,86 @@ import ( var ctx = context.Background() func TestPeer_AcquireDrpcConn(t *testing.T) { + t.Run("generic", func(t *testing.T) { + fx := newFixture(t, "p1") + defer fx.finish() + in, out := net.Pipe() + go func() { + handshake.IncomingProtoHandshake(ctx, out, defaultProtoChecker) + }() + defer out.Close() + fx.mc.EXPECT().Open(gomock.Any()).Return(in, nil) + dc, err := fx.AcquireDrpcConn(ctx) + require.NoError(t, err) + assert.NotEmpty(t, dc) + defer dc.Close() + + assert.Len(t, fx.active, 1) + assert.Len(t, fx.inactive, 0) + + fx.ReleaseDrpcConn(dc) + + assert.Len(t, fx.active, 0) + assert.Len(t, fx.inactive, 1) + + dc, err = fx.AcquireDrpcConn(ctx) + require.NoError(t, err) + assert.NotEmpty(t, dc) + assert.Len(t, fx.active, 1) + assert.Len(t, fx.inactive, 0) + }) + t.Run("closed sub conn", func(t *testing.T) { + fx := newFixture(t, "p1") + defer fx.finish() + + closedIn, _ := net.Pipe() + dc := drpcconn.New(closedIn) + fx.ReleaseDrpcConn(&subConn{Conn: dc}) + dc.Close() + + in, out := net.Pipe() + go func() { + handshake.IncomingProtoHandshake(ctx, out, defaultProtoChecker) + }() + defer out.Close() + fx.mc.EXPECT().Open(gomock.Any()).Return(in, nil) + _, err := fx.AcquireDrpcConn(ctx) + require.NoError(t, err) + }) +} + +func TestPeer_DrpcConn_OpenThrottling(t *testing.T) { fx := newFixture(t, "p1") defer fx.finish() - in, out := net.Pipe() + + acquire := func() (func(), drpc.Conn, error) { + in, out := net.Pipe() + go func() { + _, err := handshake.IncomingProtoHandshake(ctx, out, defaultProtoChecker) + require.NoError(t, err) + }() + + fx.mc.EXPECT().Open(gomock.Any()).Return(in, nil) + dconn, err := fx.AcquireDrpcConn(ctx) + return func() { out.Close() }, dconn, err + } + + var conCount = fx.limiter.startThreshold + 3 + var conns []drpc.Conn + for i := 0; i < conCount; i++ { + cc, dc, err := acquire() + require.NoError(t, err) + defer cc() + conns = append(conns, dc) + } + go func() { - handshake.IncomingProtoHandshake(ctx, out, defaultProtoChecker) + time.Sleep(fx.limiter.slowDownStep) + fx.ReleaseDrpcConn(conns[0]) + conns = conns[1:] }() - defer out.Close() - fx.mc.EXPECT().Open(gomock.Any()).Return(in, nil) - dc, err := fx.AcquireDrpcConn(ctx) + _, err := fx.AcquireDrpcConn(ctx) require.NoError(t, err) - assert.NotEmpty(t, dc) - defer dc.Close() - - assert.Len(t, fx.active, 1) - assert.Len(t, fx.inactive, 0) - - fx.ReleaseDrpcConn(dc) - - assert.Len(t, fx.active, 0) - assert.Len(t, fx.inactive, 1) - - dc, err = fx.AcquireDrpcConn(ctx) - require.NoError(t, err) - assert.NotEmpty(t, dc) - assert.Len(t, fx.active, 1) - assert.Len(t, fx.inactive, 0) } func TestPeerAccept(t *testing.T) { @@ -63,6 +119,26 @@ func TestPeerAccept(t *testing.T) { assert.NoError(t, <-outHandshakeCh) } +func TestPeer_DrpcConn_AcceptThrottling(t *testing.T) { + fx := newFixture(t, "p1") + defer fx.finish() + + var conCount = fx.limiter.startThreshold + 3 + for i := 0; i < conCount; i++ { + in, out := net.Pipe() + defer out.Close() + + var outHandshakeCh = make(chan error) + go func() { + outHandshakeCh <- handshake.OutgoingProtoHandshake(ctx, out, handshakeproto.ProtoType_DRPC) + }() + fx.acceptCh <- acceptedConn{conn: in} + cn := <-fx.testCtrl.serveConn + assert.Equal(t, in, cn) + assert.NoError(t, <-outHandshakeCh) + } +} + func TestPeer_TryClose(t *testing.T) { t.Run("not close in first minute", func(t *testing.T) { fx := newFixture(t, "p1") diff --git a/net/rpc/rpctest/multiconntest/multiconntest.go b/net/rpc/rpctest/multiconntest/multiconntest.go new file mode 100644 index 00000000..a99d1083 --- /dev/null +++ b/net/rpc/rpctest/multiconntest/multiconntest.go @@ -0,0 +1,29 @@ +package multiconntest + +import ( + "context" + "github.com/anyproto/any-sync/net/connutil" + "github.com/anyproto/any-sync/net/transport" + yamux2 "github.com/anyproto/any-sync/net/transport/yamux" + "github.com/hashicorp/yamux" + "net" +) + +func MultiConnPair(peerServCtx, peerClientCtx context.Context) (serv, client transport.MultiConn) { + sc, cc := net.Pipe() + var servConn = make(chan transport.MultiConn, 1) + go func() { + sess, err := yamux.Server(sc, yamux.DefaultConfig()) + if err != nil { + panic(err) + } + servConn <- yamux2.NewMultiConn(peerServCtx, connutil.NewLastUsageConn(sc), "", sess) + }() + sess, err := yamux.Client(cc, yamux.DefaultConfig()) + if err != nil { + panic(err) + } + client = yamux2.NewMultiConn(peerClientCtx, connutil.NewLastUsageConn(cc), "", sess) + serv = <-servConn + return +} diff --git a/net/rpc/rpctest/peer.go b/net/rpc/rpctest/peer.go index a5fef8be..902547bb 100644 --- a/net/rpc/rpctest/peer.go +++ b/net/rpc/rpctest/peer.go @@ -2,29 +2,11 @@ package rpctest import ( "context" - "github.com/anyproto/any-sync/net/connutil" "github.com/anyproto/any-sync/net/peer" + "github.com/anyproto/any-sync/net/rpc/rpctest/multiconntest" "github.com/anyproto/any-sync/net/transport" - yamux2 "github.com/anyproto/any-sync/net/transport/yamux" - "github.com/hashicorp/yamux" - "net" ) func MultiConnPair(peerIdServ, peerIdClient string) (serv, client transport.MultiConn) { - sc, cc := net.Pipe() - var servConn = make(chan transport.MultiConn, 1) - go func() { - sess, err := yamux.Server(sc, yamux.DefaultConfig()) - if err != nil { - panic(err) - } - servConn <- yamux2.NewMultiConn(peer.CtxWithPeerId(context.Background(), peerIdServ), connutil.NewLastUsageConn(sc), "", sess) - }() - sess, err := yamux.Client(cc, yamux.DefaultConfig()) - if err != nil { - panic(err) - } - client = yamux2.NewMultiConn(peer.CtxWithPeerId(context.Background(), peerIdClient), connutil.NewLastUsageConn(cc), "", sess) - serv = <-servConn - return + return multiconntest.MultiConnPair(peer.CtxWithPeerId(context.Background(), peerIdServ), peer.CtxWithPeerId(context.Background(), peerIdClient)) } diff --git a/net/transport/transport.go b/net/transport/transport.go index 9d36435a..7310ccb2 100644 --- a/net/transport/transport.go +++ b/net/transport/transport.go @@ -20,6 +20,10 @@ type Transport interface { Dial(ctx context.Context, addr string) (mc MultiConn, err error) } +type SubConn interface { + net.Conn +} + // MultiConn is an object of multiplexing connection containing handshake info type MultiConn interface { // Context returns the connection context that contains handshake details diff --git a/net/transport/yamux/conn.go b/net/transport/yamux/conn.go index 0013f2bb..6a473796 100644 --- a/net/transport/yamux/conn.go +++ b/net/transport/yamux/conn.go @@ -6,6 +6,7 @@ import ( "github.com/anyproto/any-sync/net/peer" "github.com/anyproto/any-sync/net/transport" "github.com/hashicorp/yamux" + "io" "net" "time" ) @@ -48,7 +49,7 @@ func (y *yamuxConn) Addr() string { func (y *yamuxConn) Accept() (conn net.Conn, err error) { if conn, err = y.Session.Accept(); err != nil { - if err == yamux.ErrSessionShutdown { + if err == yamux.ErrSessionShutdown || err == io.EOF { err = transport.ErrConnClosed } return From 49c3178f65631eecb4920f2450b27d5f8e8236c0 Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Fri, 23 Jun 2023 16:57:51 +0200 Subject: [PATCH 077/123] cleanup --- net/transport/transport.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/net/transport/transport.go b/net/transport/transport.go index 7310ccb2..9d36435a 100644 --- a/net/transport/transport.go +++ b/net/transport/transport.go @@ -20,10 +20,6 @@ type Transport interface { Dial(ctx context.Context, addr string) (mc MultiConn, err error) } -type SubConn interface { - net.Conn -} - // MultiConn is an object of multiplexing connection containing handshake info type MultiConn interface { // Context returns the connection context that contains handshake details From e929d5431d1b48b34c84d3b2c875b359c8be2ea1 Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Fri, 23 Jun 2023 17:39:13 +0200 Subject: [PATCH 078/123] correct throttle counting --- net/peer/peer.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/net/peer/peer.go b/net/peer/peer.go index b96162f7..9ff7f023 100644 --- a/net/peer/peer.go +++ b/net/peer/peer.go @@ -79,9 +79,10 @@ type peer struct { // drpc conn pool // outgoing - inactive []*subConn - active map[*subConn]struct{} - subConnRelease chan drpc.Conn + inactive []*subConn + active map[*subConn]struct{} + subConnRelease chan drpc.Conn + openingWaitCount atomic.Int32 incomingCount atomic.Int32 acceptCtx context.Context @@ -103,9 +104,11 @@ func (p *peer) Id() string { func (p *peer) AcquireDrpcConn(ctx context.Context) (drpc.Conn, error) { p.mu.Lock() if len(p.inactive) == 0 { - wait := p.limiter.wait(len(p.active)) + wait := p.limiter.wait(len(p.active) + int(p.openingWaitCount.Load())) p.mu.Unlock() if wait != nil { + p.openingWaitCount.Add(1) + defer p.openingWaitCount.Add(-1) // throttle new connection opening select { case <-ctx.Done(): From 291b8daf5fad2c1a5d40f7c3eb069085ca7f5c4e Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Fri, 23 Jun 2023 17:47:29 +0200 Subject: [PATCH 079/123] fix blinking test --- net/transport/yamux/yamux_test.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/net/transport/yamux/yamux_test.go b/net/transport/yamux/yamux_test.go index 02e1c322..b71f15a9 100644 --- a/net/transport/yamux/yamux_test.go +++ b/net/transport/yamux/yamux_test.go @@ -30,8 +30,12 @@ func TestYamuxTransport_Dial(t *testing.T) { mcC, err := fxC.Dial(ctx, fxS.addr) require.NoError(t, err) - require.Len(t, fxS.accepter.mcs, 1) - mcS := <-fxS.accepter.mcs + var mcS transport.MultiConn + select { + case mcS = <-fxS.accepter.mcs: + case <-time.After(time.Second * 5): + require.True(t, false, "timeout") + } var ( sData string From f0ffc9b7bfd868d28d9b5e699e93df625b58906b Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Fri, 23 Jun 2023 18:27:59 +0200 Subject: [PATCH 080/123] descrease net.pool ttl --- net/pool/poolservice.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/pool/poolservice.go b/net/pool/poolservice.go index 2f84e5d0..0c574eb4 100644 --- a/net/pool/poolservice.go +++ b/net/pool/poolservice.go @@ -49,8 +49,8 @@ func (p *poolService) Init(a *app.App) (err error) { return p.dialer.Dial(ctx, id) }, ocache.WithLogger(log.Sugar()), - ocache.WithGCPeriod(time.Minute), - ocache.WithTTL(time.Minute*5), + ocache.WithGCPeriod(time.Minute/2), + ocache.WithTTL(time.Minute), ocache.WithPrometheus(p.metricReg, "netpool", "outgoing"), ) p.pool.incoming = ocache.New( @@ -58,8 +58,8 @@ func (p *poolService) Init(a *app.App) (err error) { return nil, ocache.ErrNotExists }, ocache.WithLogger(log.Sugar()), - ocache.WithGCPeriod(time.Minute), - ocache.WithTTL(time.Minute*5), + ocache.WithGCPeriod(time.Minute/2), + ocache.WithTTL(time.Minute), ocache.WithPrometheus(p.metricReg, "netpool", "incoming"), ) return nil From f943991bc0d17b353a682f2083d6ffd82fc474ea Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Fri, 23 Jun 2023 18:32:13 +0200 Subject: [PATCH 081/123] yamux bench test: open sub conn --- net/transport/yamux/yamux_test.go | 61 ++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/net/transport/yamux/yamux_test.go b/net/transport/yamux/yamux_test.go index b71f15a9..9b209054 100644 --- a/net/transport/yamux/yamux_test.go +++ b/net/transport/yamux/yamux_test.go @@ -73,11 +73,11 @@ func TestYamuxTransport_Dial(t *testing.T) { // no deadline - 69100 rps // common write deadline - 66700 rps // subconn write deadline - 67100 rps -func TestWriteBench(t *testing.T) { +func TestWriteBenchReuse(t *testing.T) { t.Skip() var ( numSubConn = 10 - numWrites = 100000 + numWrites = 10000 ) fxS := newFixture(t) @@ -128,6 +128,63 @@ func TestWriteBench(t *testing.T) { t.Logf("%.2f req per sec", float64(numWrites*numSubConn)/dur.Seconds()) } +func TestWriteBenchNew(t *testing.T) { + t.Skip() + var ( + numSubConn = 10 + numWrites = 10000 + ) + + fxS := newFixture(t) + defer fxS.finish(t) + fxC := newFixture(t) + defer fxC.finish(t) + + mcC, err := fxC.Dial(ctx, fxS.addr) + require.NoError(t, err) + mcS := <-fxS.accepter.mcs + + go func() { + for i := 0; i < numSubConn; i++ { + require.NoError(t, err) + go func() { + var b = make([]byte, 1024) + for { + conn, _ := mcS.Accept() + n, _ := conn.Read(b) + if n > 0 { + conn.Write(b[:n]) + } else { + _ = conn.Close() + break + } + conn.Close() + } + }() + } + }() + + var wg sync.WaitGroup + wg.Add(numSubConn) + st := time.Now() + for i := 0; i < numSubConn; i++ { + go func() { + defer wg.Done() + for j := 0; j < numWrites; j++ { + sc, err := mcC.Open(ctx) + require.NoError(t, err) + var b = []byte("some data some data some data some data some data some data some data some data some data") + sc.Write(b) + sc.Read(b) + sc.Close() + } + }() + } + wg.Wait() + dur := time.Since(st) + t.Logf("%.2f req per sec", float64(numWrites*numSubConn)/dur.Seconds()) +} + type fixture struct { *yamuxTransport a *app.App From 81aadfde7e82e2aaa290ef2000d0b455e7806dd6 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Mon, 26 Jun 2023 10:10:14 +0200 Subject: [PATCH 082/123] Add validate method in list --- .../object/acl/list/aclrecordbuilder.go | 45 +++++++++++- commonspace/object/acl/list/aclstate.go | 24 ++++--- commonspace/object/acl/list/list.go | 28 ++++++-- commonspace/object/acl/list/validator.go | 70 ++++++++++++++----- 4 files changed, 133 insertions(+), 34 deletions(-) diff --git a/commonspace/object/acl/list/aclrecordbuilder.go b/commonspace/object/acl/list/aclrecordbuilder.go index 686ef3fa..f94553c1 100644 --- a/commonspace/object/acl/list/aclrecordbuilder.go +++ b/commonspace/object/acl/list/aclrecordbuilder.go @@ -17,7 +17,8 @@ type RootContent struct { } type AclRecordBuilder interface { - Unmarshall(rawIdRecord *aclrecordproto.RawAclRecordWithId) (rec *AclRecord, err error) + UnmarshallWithId(rawIdRecord *aclrecordproto.RawAclRecordWithId) (rec *AclRecord, err error) + Unmarshall(rawRecord *aclrecordproto.RawAclRecord) (rec *AclRecord, err error) BuildRoot(content RootContent) (rec *aclrecordproto.RawAclRecordWithId, err error) } @@ -33,7 +34,41 @@ func NewAclRecordBuilder(id string, keyStorage crypto.KeyStorage) AclRecordBuild } } -func (a *aclRecordBuilder) Unmarshall(rawIdRecord *aclrecordproto.RawAclRecordWithId) (rec *AclRecord, err error) { +func (a *aclRecordBuilder) Unmarshall(rawRecord *aclrecordproto.RawAclRecord) (rec *AclRecord, err error) { + aclRecord := &aclrecordproto.AclRecord{} + err = proto.Unmarshal(rawRecord.Payload, aclRecord) + if err != nil { + return + } + pubKey, err := a.keyStorage.PubKeyFromProto(aclRecord.Identity) + if err != nil { + return + } + aclData := &aclrecordproto.AclData{} + err = proto.Unmarshal(rawRecord.Payload, aclData) + if err != nil { + return + } + rec = &AclRecord{ + PrevId: aclRecord.PrevId, + Timestamp: aclRecord.Timestamp, + Data: aclRecord.Data, + Signature: rawRecord.Signature, + Identity: pubKey, + Model: aclData, + } + res, err := pubKey.Verify(rawRecord.Payload, rawRecord.Signature) + if err != nil { + return + } + if !res { + err = ErrInvalidSignature + return + } + return +} + +func (a *aclRecordBuilder) UnmarshallWithId(rawIdRecord *aclrecordproto.RawAclRecordWithId) (rec *AclRecord, err error) { var ( rawRec = &aclrecordproto.RawAclRecord{} pubKey crypto.PubKey @@ -69,6 +104,11 @@ func (a *aclRecordBuilder) Unmarshall(rawIdRecord *aclrecordproto.RawAclRecordWi if err != nil { return } + aclData := &aclrecordproto.AclData{} + err = proto.Unmarshal(rawRec.Payload, aclData) + if err != nil { + return + } rec = &AclRecord{ Id: rawIdRecord.Id, PrevId: aclRecord.PrevId, @@ -76,6 +116,7 @@ func (a *aclRecordBuilder) Unmarshall(rawIdRecord *aclrecordproto.RawAclRecordWi Data: aclRecord.Data, Signature: rawRec.Signature, Identity: pubKey, + Model: aclData, } } diff --git a/commonspace/object/acl/list/aclstate.go b/commonspace/object/acl/list/aclstate.go index 6f0c917b..52fe894b 100644 --- a/commonspace/object/acl/list/aclstate.go +++ b/commonspace/object/acl/list/aclstate.go @@ -88,6 +88,10 @@ func newAclState(id string) *AclState { return st } +func (st *AclState) Validator() ContentValidator { + return st.contentValidator +} + func (st *AclState) CurrentReadKeyId() string { return st.currentReadKeyId } @@ -242,7 +246,7 @@ func (st *AclState) applyPermissionChange(ch *aclrecordproto.AclAccountPermissio if err != nil { return err } - err = st.contentValidator.ValidatePermissionChange(ch, recordId, authorIdentity) + err = st.contentValidator.ValidatePermissionChange(ch, authorIdentity) if err != nil { return err } @@ -258,7 +262,7 @@ func (st *AclState) applyInvite(ch *aclrecordproto.AclAccountInvite, recordId st if err != nil { return err } - err = st.contentValidator.ValidateInvite(ch, recordId, authorIdentity) + err = st.contentValidator.ValidateInvite(ch, authorIdentity) if err != nil { return err } @@ -267,7 +271,7 @@ func (st *AclState) applyInvite(ch *aclrecordproto.AclAccountInvite, recordId st } func (st *AclState) applyInviteRevoke(ch *aclrecordproto.AclAccountInviteRevoke, recordId string, authorIdentity crypto.PubKey) error { - err := st.contentValidator.ValidateInviteRevoke(ch, recordId, authorIdentity) + err := st.contentValidator.ValidateInviteRevoke(ch, authorIdentity) if err != nil { return err } @@ -276,7 +280,7 @@ func (st *AclState) applyInviteRevoke(ch *aclrecordproto.AclAccountInviteRevoke, } func (st *AclState) applyRequestJoin(ch *aclrecordproto.AclAccountRequestJoin, recordId string, authorIdentity crypto.PubKey) error { - err := st.contentValidator.ValidateRequestJoin(ch, recordId, authorIdentity) + err := st.contentValidator.ValidateRequestJoin(ch, authorIdentity) if err != nil { return err } @@ -288,7 +292,7 @@ func (st *AclState) applyRequestJoin(ch *aclrecordproto.AclAccountRequestJoin, r } func (st *AclState) applyRequestAccept(ch *aclrecordproto.AclAccountRequestAccept, recordId string, authorIdentity crypto.PubKey) error { - err := st.contentValidator.ValidateRequestAccept(ch, recordId, authorIdentity) + err := st.contentValidator.ValidateRequestAccept(ch, authorIdentity) if err != nil { return err } @@ -314,18 +318,18 @@ func (st *AclState) applyRequestAccept(ch *aclrecordproto.AclAccountRequestAccep if err != nil { return err } - for recordId, key := range keys.ReadKeys { + for keyId, key := range keys.ReadKeys { sym, err := crypto.UnmarshallAESKey(key) if err != nil { return err } - st.userReadKeys[recordId] = sym + st.userReadKeys[keyId] = sym } return nil } func (st *AclState) applyRequestDecline(ch *aclrecordproto.AclAccountRequestDecline, recordId string, authorIdentity crypto.PubKey) error { - err := st.contentValidator.ValidateRequestDecline(ch, recordId, authorIdentity) + err := st.contentValidator.ValidateRequestDecline(ch, authorIdentity) if err != nil { return err } @@ -334,7 +338,7 @@ func (st *AclState) applyRequestDecline(ch *aclrecordproto.AclAccountRequestDecl } func (st *AclState) applyAccountRemove(ch *aclrecordproto.AclAccountRemove, recordId string, authorIdentity crypto.PubKey) error { - err := st.contentValidator.ValidateRemove(ch, recordId, authorIdentity) + err := st.contentValidator.ValidateRemove(ch, authorIdentity) if err != nil { return err } @@ -342,7 +346,7 @@ func (st *AclState) applyAccountRemove(ch *aclrecordproto.AclAccountRemove, reco } func (st *AclState) applyReadKeyChange(ch *aclrecordproto.AclReadKeyChange, recordId string, authorIdentity crypto.PubKey) error { - err := st.contentValidator.ValidateReadKeyChange(ch, recordId, authorIdentity) + err := st.contentValidator.ValidateReadKeyChange(ch, authorIdentity) if err != nil { return err } diff --git a/commonspace/object/acl/list/list.go b/commonspace/object/acl/list/list.go index 6c31c9de..b3bf8cd0 100644 --- a/commonspace/object/acl/list/list.go +++ b/commonspace/object/acl/list/list.go @@ -5,11 +5,12 @@ import ( "context" "errors" "fmt" + "sync" + "github.com/anyproto/any-sync/commonspace/object/accountdata" "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" "github.com/anyproto/any-sync/commonspace/object/acl/liststorage" "github.com/anyproto/any-sync/util/crypto" - "sync" ) type IterFunc = func(record *AclRecord) (IsContinue bool) @@ -33,8 +34,11 @@ type AclList interface { Get(id string) (*AclRecord, error) Iterate(iterFunc IterFunc) IterateFrom(startId string, iterFunc IterFunc) - KeyStorage() crypto.KeyStorage + KeyStorage() crypto.KeyStorage + RecordBuilder() AclRecordBuilder + + ValidateRawRecord(record *aclrecordproto.RawAclRecord) (err error) AddRawRecord(rawRec *aclrecordproto.RawAclRecordWithId) (added bool, err error) Close() (err error) @@ -77,7 +81,7 @@ func build(id string, keyStorage crypto.KeyStorage, stateBuilder *aclStateBuilde return } - record, err := recBuilder.Unmarshall(rawRecordWithId) + record, err := recBuilder.UnmarshallWithId(rawRecordWithId) if err != nil { return } @@ -89,7 +93,7 @@ func build(id string, keyStorage crypto.KeyStorage, stateBuilder *aclStateBuilde return } - record, err = recBuilder.Unmarshall(rawRecordWithId) + record, err = recBuilder.UnmarshallWithId(rawRecordWithId) if err != nil { return } @@ -132,15 +136,27 @@ func build(id string, keyStorage crypto.KeyStorage, stateBuilder *aclStateBuilde return } +func (a *aclList) RecordBuilder() AclRecordBuilder { + return a.recordBuilder +} + func (a *aclList) Records() []*AclRecord { return a.records } +func (a *aclList) ValidateRawRecord(rawRec *aclrecordproto.RawAclRecord) (err error) { + record, err := a.recordBuilder.Unmarshall(rawRec) + if err != nil { + return + } + return a.aclState.Validator().ValidateAclRecordContents(record) +} + func (a *aclList) AddRawRecord(rawRec *aclrecordproto.RawAclRecordWithId) (added bool, err error) { if _, ok := a.indexes[rawRec.Id]; ok { return } - record, err := a.recordBuilder.Unmarshall(rawRec) + record, err := a.recordBuilder.UnmarshallWithId(rawRec) if err != nil { return } @@ -159,7 +175,7 @@ func (a *aclList) AddRawRecord(rawRec *aclrecordproto.RawAclRecordWithId) (added } func (a *aclList) IsValidNext(rawRec *aclrecordproto.RawAclRecordWithId) (err error) { - _, err = a.recordBuilder.Unmarshall(rawRec) + _, err = a.recordBuilder.UnmarshallWithId(rawRec) if err != nil { return } diff --git a/commonspace/object/acl/list/validator.go b/commonspace/object/acl/list/validator.go index 51dfa575..75e0e251 100644 --- a/commonspace/object/acl/list/validator.go +++ b/commonspace/object/acl/list/validator.go @@ -6,14 +6,15 @@ import ( ) type ContentValidator interface { - ValidatePermissionChange(ch *aclrecordproto.AclAccountPermissionChange, id string, authorIdentity crypto.PubKey) (err error) - ValidateInvite(ch *aclrecordproto.AclAccountInvite, id string, authorIdentity crypto.PubKey) (err error) - ValidateInviteRevoke(ch *aclrecordproto.AclAccountInviteRevoke, id string, authorIdentity crypto.PubKey) (err error) - ValidateRequestJoin(ch *aclrecordproto.AclAccountRequestJoin, id string, authorIdentity crypto.PubKey) (err error) - ValidateRequestAccept(ch *aclrecordproto.AclAccountRequestAccept, id string, authorIdentity crypto.PubKey) (err error) - ValidateRequestDecline(ch *aclrecordproto.AclAccountRequestDecline, id string, authorIdentity crypto.PubKey) (err error) - ValidateRemove(ch *aclrecordproto.AclAccountRemove, id string, authorIdentity crypto.PubKey) (err error) - ValidateReadKeyChange(ch *aclrecordproto.AclReadKeyChange, id string, authorIdentity crypto.PubKey) (err error) + ValidateAclRecordContents(ch *AclRecord) (err error) + ValidatePermissionChange(ch *aclrecordproto.AclAccountPermissionChange, authorIdentity crypto.PubKey) (err error) + ValidateInvite(ch *aclrecordproto.AclAccountInvite, authorIdentity crypto.PubKey) (err error) + ValidateInviteRevoke(ch *aclrecordproto.AclAccountInviteRevoke, authorIdentity crypto.PubKey) (err error) + ValidateRequestJoin(ch *aclrecordproto.AclAccountRequestJoin, authorIdentity crypto.PubKey) (err error) + ValidateRequestAccept(ch *aclrecordproto.AclAccountRequestAccept, authorIdentity crypto.PubKey) (err error) + ValidateRequestDecline(ch *aclrecordproto.AclAccountRequestDecline, authorIdentity crypto.PubKey) (err error) + ValidateRemove(ch *aclrecordproto.AclAccountRemove, authorIdentity crypto.PubKey) (err error) + ValidateReadKeyChange(ch *aclrecordproto.AclReadKeyChange, authorIdentity crypto.PubKey) (err error) } type contentValidator struct { @@ -21,7 +22,44 @@ type contentValidator struct { aclState *AclState } -func (c *contentValidator) ValidatePermissionChange(ch *aclrecordproto.AclAccountPermissionChange, id string, authorIdentity crypto.PubKey) (err error) { +func (c *contentValidator) ValidateAclRecordContents(ch *AclRecord) (err error) { + if ch.PrevId != c.aclState.lastRecordId { + return ErrIncorrectRecordSequence + } + aclData := ch.Model.(*aclrecordproto.AclData) + for _, content := range aclData.AclContent { + err = c.validateAclRecordContent(content, ch.Identity) + if err != nil { + return + } + } + return +} + +func (c *contentValidator) validateAclRecordContent(ch *aclrecordproto.AclContentValue, authorIdentity crypto.PubKey) (err error) { + switch { + case ch.GetPermissionChange() != nil: + return c.ValidatePermissionChange(ch.GetPermissionChange(), authorIdentity) + case ch.GetInvite() != nil: + return c.ValidateInvite(ch.GetInvite(), authorIdentity) + case ch.GetInviteRevoke() != nil: + return c.ValidateInviteRevoke(ch.GetInviteRevoke(), authorIdentity) + case ch.GetRequestJoin() != nil: + return c.ValidateRequestJoin(ch.GetRequestJoin(), authorIdentity) + case ch.GetRequestAccept() != nil: + return c.ValidateRequestAccept(ch.GetRequestAccept(), authorIdentity) + case ch.GetRequestDecline() != nil: + return c.ValidateRequestDecline(ch.GetRequestDecline(), authorIdentity) + case ch.GetAccountRemove() != nil: + return c.ValidateRemove(ch.GetAccountRemove(), authorIdentity) + case ch.GetReadKeyChange() != nil: + return c.ValidateReadKeyChange(ch.GetReadKeyChange(), authorIdentity) + default: + return ErrUnexpectedContentType + } +} + +func (c *contentValidator) ValidatePermissionChange(ch *aclrecordproto.AclAccountPermissionChange, authorIdentity crypto.PubKey) (err error) { if !c.aclState.Permissions(authorIdentity).CanManageAccounts() { return ErrInsufficientPermissions } @@ -36,7 +74,7 @@ func (c *contentValidator) ValidatePermissionChange(ch *aclrecordproto.AclAccoun return } -func (c *contentValidator) ValidateInvite(ch *aclrecordproto.AclAccountInvite, id string, authorIdentity crypto.PubKey) (err error) { +func (c *contentValidator) ValidateInvite(ch *aclrecordproto.AclAccountInvite, authorIdentity crypto.PubKey) (err error) { if !c.aclState.Permissions(authorIdentity).CanManageAccounts() { return ErrInsufficientPermissions } @@ -44,7 +82,7 @@ func (c *contentValidator) ValidateInvite(ch *aclrecordproto.AclAccountInvite, i return } -func (c *contentValidator) ValidateInviteRevoke(ch *aclrecordproto.AclAccountInviteRevoke, id string, authorIdentity crypto.PubKey) (err error) { +func (c *contentValidator) ValidateInviteRevoke(ch *aclrecordproto.AclAccountInviteRevoke, authorIdentity crypto.PubKey) (err error) { if !c.aclState.Permissions(authorIdentity).CanManageAccounts() { return ErrInsufficientPermissions } @@ -55,7 +93,7 @@ func (c *contentValidator) ValidateInviteRevoke(ch *aclrecordproto.AclAccountInv return } -func (c *contentValidator) ValidateRequestJoin(ch *aclrecordproto.AclAccountRequestJoin, id string, authorIdentity crypto.PubKey) (err error) { +func (c *contentValidator) ValidateRequestJoin(ch *aclrecordproto.AclAccountRequestJoin, authorIdentity crypto.PubKey) (err error) { inviteKey, exists := c.aclState.inviteKeys[ch.InviteRecordId] if !exists { return ErrNoSuchInvite @@ -81,7 +119,7 @@ func (c *contentValidator) ValidateRequestJoin(ch *aclrecordproto.AclAccountRequ return } -func (c *contentValidator) ValidateRequestAccept(ch *aclrecordproto.AclAccountRequestAccept, id string, authorIdentity crypto.PubKey) (err error) { +func (c *contentValidator) ValidateRequestAccept(ch *aclrecordproto.AclAccountRequestAccept, authorIdentity crypto.PubKey) (err error) { if !c.aclState.Permissions(authorIdentity).CanManageAccounts() { return ErrInsufficientPermissions } @@ -102,7 +140,7 @@ func (c *contentValidator) ValidateRequestAccept(ch *aclrecordproto.AclAccountRe return } -func (c *contentValidator) ValidateRequestDecline(ch *aclrecordproto.AclAccountRequestDecline, id string, authorIdentity crypto.PubKey) (err error) { +func (c *contentValidator) ValidateRequestDecline(ch *aclrecordproto.AclAccountRequestDecline, authorIdentity crypto.PubKey) (err error) { if !c.aclState.Permissions(authorIdentity).CanManageAccounts() { return ErrInsufficientPermissions } @@ -113,7 +151,7 @@ func (c *contentValidator) ValidateRequestDecline(ch *aclrecordproto.AclAccountR return } -func (c *contentValidator) ValidateRemove(ch *aclrecordproto.AclAccountRemove, id string, authorIdentity crypto.PubKey) (err error) { +func (c *contentValidator) ValidateRemove(ch *aclrecordproto.AclAccountRemove, authorIdentity crypto.PubKey) (err error) { if !c.aclState.Permissions(authorIdentity).CanManageAccounts() { return ErrInsufficientPermissions } @@ -128,7 +166,7 @@ func (c *contentValidator) ValidateRemove(ch *aclrecordproto.AclAccountRemove, i return c.validateAccountReadKeys(ch.AccountKeys) } -func (c *contentValidator) ValidateReadKeyChange(ch *aclrecordproto.AclReadKeyChange, id string, authorIdentity crypto.PubKey) (err error) { +func (c *contentValidator) ValidateReadKeyChange(ch *aclrecordproto.AclReadKeyChange, authorIdentity crypto.PubKey) (err error) { return c.validateAccountReadKeys(ch.AccountKeys) } From 62f23b72298702fb33ba283bac7f2d761316c093 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Mon, 26 Jun 2023 11:43:17 +0200 Subject: [PATCH 083/123] Update record builder to build new payloads --- .../object/acl/list/aclrecordbuilder.go | 303 +++++++++++++++++- commonspace/object/acl/list/aclstate.go | 3 + commonspace/object/acl/list/list.go | 4 +- commonspace/object/acl/list/listutils.go | 2 +- commonspace/object/acl/list/models.go | 8 + 5 files changed, 312 insertions(+), 8 deletions(-) diff --git a/commonspace/object/acl/list/aclrecordbuilder.go b/commonspace/object/acl/list/aclrecordbuilder.go index f94553c1..86b94c5c 100644 --- a/commonspace/object/acl/list/aclrecordbuilder.go +++ b/commonspace/object/acl/list/aclrecordbuilder.go @@ -3,6 +3,7 @@ package list import ( "time" + "github.com/anyproto/any-sync/commonspace/object/accountdata" "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" "github.com/anyproto/any-sync/util/cidutil" "github.com/anyproto/any-sync/util/crypto" @@ -16,24 +17,316 @@ type RootContent struct { EncryptedReadKey []byte } +type RequestJoinPayload struct { + InviteRecordId string + InviteKey crypto.PrivKey + Metadata []byte +} + +type RequestAcceptPayload struct { + RequestRecordId string + Permissions AclPermissions +} + +type PermissionChangePayload struct { + Identity crypto.PubKey + Permissions AclPermissions +} + +type AccountRemovePayload struct { + Identity crypto.PubKey + ReadKey crypto.SymKey +} + +type InviteResult struct { + InviteRec *aclrecordproto.RawAclRecord + InviteKey crypto.PrivKey +} + type AclRecordBuilder interface { UnmarshallWithId(rawIdRecord *aclrecordproto.RawAclRecordWithId) (rec *AclRecord, err error) Unmarshall(rawRecord *aclrecordproto.RawAclRecord) (rec *AclRecord, err error) + BuildRoot(content RootContent) (rec *aclrecordproto.RawAclRecordWithId, err error) + BuildInvite() (res InviteResult, err error) + BuildInviteRevoke(inviteRecordId string) (rawRecord *aclrecordproto.RawAclRecord, err error) + BuildRequestJoin(payload RequestJoinPayload) (rawRecord *aclrecordproto.RawAclRecord, err error) + BuildRequestAccept(payload RequestAcceptPayload) (rawRecord *aclrecordproto.RawAclRecord, err error) + BuildRequestDecline(requestRecordId string) (rawRecord *aclrecordproto.RawAclRecord, err error) + BuildPermissionChange(payload PermissionChangePayload) (rawRecord *aclrecordproto.RawAclRecord, err error) + BuildReadKeyChange(newKey crypto.SymKey) (rawRecord *aclrecordproto.RawAclRecord, err error) + BuildAccountRemove(payload AccountRemovePayload) (rawRecord *aclrecordproto.RawAclRecord, err error) } type aclRecordBuilder struct { - id string - keyStorage crypto.KeyStorage + id string + keyStorage crypto.KeyStorage + accountKeys *accountdata.AccountKeys + state *AclState } -func NewAclRecordBuilder(id string, keyStorage crypto.KeyStorage) AclRecordBuilder { +func NewAclRecordBuilder(id string, keyStorage crypto.KeyStorage, keys *accountdata.AccountKeys) AclRecordBuilder { return &aclRecordBuilder{ - id: id, - keyStorage: keyStorage, + id: id, + keyStorage: keyStorage, + accountKeys: keys, } } +func (a *aclRecordBuilder) buildRecord(aclContent *aclrecordproto.AclContentValue) (rawRec *aclrecordproto.RawAclRecord, err error) { + aclData := &aclrecordproto.AclData{AclContent: []*aclrecordproto.AclContentValue{ + aclContent, + }} + marshalledData, err := aclData.Marshal() + if err != nil { + return + } + protoKey, err := a.accountKeys.SignKey.GetPublic().Marshall() + if err != nil { + return + } + rec := &aclrecordproto.AclRecord{ + PrevId: a.state.lastRecordId, + Identity: protoKey, + Data: marshalledData, + Timestamp: time.Now().Unix(), + } + marshalledRec, err := rec.Marshal() + if err != nil { + return + } + signature, err := a.accountKeys.SignKey.Sign(marshalledRec) + if err != nil { + return + } + rawRec = &aclrecordproto.RawAclRecord{ + Payload: marshalledRec, + Signature: signature, + } + return +} + +func (a *aclRecordBuilder) BuildInvite() (res InviteResult, err error) { + if !a.state.Permissions(a.state.pubKey).CanManageAccounts() { + err = ErrInsufficientPermissions + return + } + privKey, pubKey, err := crypto.GenerateRandomEd25519KeyPair() + if err != nil { + return + } + invitePubKey, err := pubKey.Marshall() + if err != nil { + return + } + inviteRec := &aclrecordproto.AclAccountInvite{InviteKey: invitePubKey} + content := &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_Invite{Invite: inviteRec}} + rawRec, err := a.buildRecord(content) + if err != nil { + return + } + res.InviteKey = privKey + res.InviteRec = rawRec + return +} + +func (a *aclRecordBuilder) BuildInviteRevoke(inviteRecordId string) (rawRecord *aclrecordproto.RawAclRecord, err error) { + if !a.state.Permissions(a.state.pubKey).CanManageAccounts() { + err = ErrInsufficientPermissions + return + } + _, exists := a.state.inviteKeys[inviteRecordId] + if !exists { + err = ErrNoSuchInvite + return + } + revokeRec := &aclrecordproto.AclAccountInviteRevoke{InviteRecordId: inviteRecordId} + content := &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_InviteRevoke{InviteRevoke: revokeRec}} + return a.buildRecord(content) +} + +func (a *aclRecordBuilder) BuildRequestJoin(payload RequestJoinPayload) (rawRecord *aclrecordproto.RawAclRecord, err error) { + key, exists := a.state.inviteKeys[payload.InviteRecordId] + if !exists { + err = ErrNoSuchInvite + return + } + if !payload.InviteKey.GetPublic().Equals(key) { + err = ErrIncorrectInviteKey + } + rawIdentity, err := a.accountKeys.SignKey.GetPublic().Raw() + if err != nil { + return + } + signature, err := payload.InviteKey.Sign(rawIdentity) + if err != nil { + return + } + joinRec := &aclrecordproto.AclAccountRequestJoin{ + InviteIdentity: rawIdentity, + InviteRecordId: payload.InviteRecordId, + InviteIdentitySignature: signature, + Metadata: payload.Metadata, + } + content := &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_RequestJoin{RequestJoin: joinRec}} + return a.buildRecord(content) +} + +func (a *aclRecordBuilder) BuildRequestAccept(payload RequestAcceptPayload) (rawRecord *aclrecordproto.RawAclRecord, err error) { + if !a.state.Permissions(a.state.pubKey).CanManageAccounts() { + err = ErrInsufficientPermissions + return + } + request, exists := a.state.requestRecords[payload.RequestRecordId] + if !exists { + err = ErrNoSuchRequest + return + } + readKeys := map[string][]byte{} + for keyId, key := range a.state.userReadKeys { + rawKey, err := key.Raw() + if err != nil { + return nil, err + } + readKeys[keyId] = rawKey + } + aclKeys := &aclrecordproto.AclReadKeys{ReadKeys: readKeys} + marshalledKeys, err := aclKeys.Marshal() + if err != nil { + return + } + requestIdentityProto, err := request.RequestIdentity.Marshall() + if err != nil { + return + } + encKeys, err := request.RequestIdentity.Encrypt(marshalledKeys) + if err != nil { + return + } + acceptRec := &aclrecordproto.AclAccountRequestAccept{ + Identity: requestIdentityProto, + RequestRecordId: payload.RequestRecordId, + EncryptedReadKeys: encKeys, + Permissions: aclrecordproto.AclUserPermissions(payload.Permissions), + } + content := &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_RequestAccept{RequestAccept: acceptRec}} + return a.buildRecord(content) +} + +func (a *aclRecordBuilder) BuildRequestDecline(requestRecordId string) (rawRecord *aclrecordproto.RawAclRecord, err error) { + if !a.state.Permissions(a.state.pubKey).CanManageAccounts() { + err = ErrInsufficientPermissions + return + } + _, exists := a.state.requestRecords[requestRecordId] + if !exists { + err = ErrNoSuchRequest + return + } + declineRec := &aclrecordproto.AclAccountRequestDecline{RequestRecordId: requestRecordId} + content := &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_RequestDecline{RequestDecline: declineRec}} + return a.buildRecord(content) +} + +func (a *aclRecordBuilder) BuildPermissionChange(payload PermissionChangePayload) (rawRecord *aclrecordproto.RawAclRecord, err error) { + if !a.state.Permissions(a.state.pubKey).CanManageAccounts() { + err = ErrInsufficientPermissions + return + } + if payload.Identity.Equals(a.state.pubKey) || payload.Permissions.IsOwner() { + err = ErrIncorrectPermissions + return + } + protoIdentity, err := payload.Identity.Marshall() + if err != nil { + return + } + permissionRec := &aclrecordproto.AclAccountPermissionChange{ + Identity: protoIdentity, + Permissions: aclrecordproto.AclUserPermissions(payload.Permissions), + } + content := &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_PermissionChange{PermissionChange: permissionRec}} + return a.buildRecord(content) +} + +func (a *aclRecordBuilder) BuildReadKeyChange(newKey crypto.SymKey) (rawRecord *aclrecordproto.RawAclRecord, err error) { + if !a.state.Permissions(a.state.pubKey).CanManageAccounts() { + err = ErrInsufficientPermissions + return + } + rawKey, err := newKey.Raw() + if err != nil { + return + } + if len(rawKey) != crypto.KeyBytes { + err = ErrIncorrectReadKey + return + } + var aclReadKeys []*aclrecordproto.AclEncryptedReadKey + for _, st := range a.state.userStates { + protoIdentity, err := st.PubKey.Marshall() + if err != nil { + return nil, err + } + enc, err := st.PubKey.Encrypt(rawKey) + if err != nil { + return nil, err + } + aclReadKeys = append(aclReadKeys, &aclrecordproto.AclEncryptedReadKey{ + Identity: protoIdentity, + EncryptedReadKey: enc, + }) + } + readRec := &aclrecordproto.AclReadKeyChange{AccountKeys: aclReadKeys} + content := &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_ReadKeyChange{ReadKeyChange: readRec}} + return a.buildRecord(content) +} + +func (a *aclRecordBuilder) BuildAccountRemove(payload AccountRemovePayload) (rawRecord *aclrecordproto.RawAclRecord, err error) { + permissions := a.state.Permissions(payload.Identity) + if !a.state.Permissions(a.state.pubKey).CanManageAccounts() || permissions.IsOwner() { + err = ErrInsufficientPermissions + return + } + if permissions.NoPermissions() { + err = ErrNoSuchAccount + return + } + rawKey, err := payload.ReadKey.Raw() + if err != nil { + return + } + if len(rawKey) != crypto.KeyBytes { + err = ErrIncorrectReadKey + return + } + var aclReadKeys []*aclrecordproto.AclEncryptedReadKey + for _, st := range a.state.userStates { + if st.PubKey.Equals(payload.Identity) { + continue + } + protoIdentity, err := st.PubKey.Marshall() + if err != nil { + return nil, err + } + enc, err := st.PubKey.Encrypt(rawKey) + if err != nil { + return nil, err + } + aclReadKeys = append(aclReadKeys, &aclrecordproto.AclEncryptedReadKey{ + Identity: protoIdentity, + EncryptedReadKey: enc, + }) + } + protoIdentity, err := payload.Identity.Marshall() + if err != nil { + return + } + removeRec := &aclrecordproto.AclAccountRemove{AccountKeys: aclReadKeys, Identity: protoIdentity} + content := &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_AccountRemove{AccountRemove: removeRec}} + return a.buildRecord(content) +} + func (a *aclRecordBuilder) Unmarshall(rawRecord *aclrecordproto.RawAclRecord) (rec *AclRecord, err error) { aclRecord := &aclrecordproto.AclRecord{} err = proto.Unmarshal(rawRecord.Payload, aclRecord) diff --git a/commonspace/object/acl/list/aclstate.go b/commonspace/object/acl/list/aclstate.go index 52fe894b..de484a13 100644 --- a/commonspace/object/acl/list/aclstate.go +++ b/commonspace/object/acl/list/aclstate.go @@ -16,13 +16,16 @@ var ( ErrNoSuchAccount = errors.New("no such account") ErrUnexpectedContentType = errors.New("unexpected content type") ErrIncorrectIdentity = errors.New("incorrect identity") + ErrIncorrectInviteKey = errors.New("incorrect invite key") ErrFailedToDecrypt = errors.New("failed to decrypt key") ErrNoSuchRecord = errors.New("no such record") ErrNoSuchRequest = errors.New("no such request") ErrNoSuchInvite = errors.New("no such invite") ErrInsufficientPermissions = errors.New("insufficient permissions") + ErrIncorrectPermissions = errors.New("incorrect permissions") ErrIncorrectNumberOfAccounts = errors.New("incorrect number of accounts") ErrNoReadKey = errors.New("acl state doesn't have a read key") + ErrIncorrectReadKey = errors.New("incorrect read key") ErrInvalidSignature = errors.New("signature is invalid") ErrIncorrectRoot = errors.New("incorrect root") ErrIncorrectRecordSequence = errors.New("incorrect prev id of a record") diff --git a/commonspace/object/acl/list/list.go b/commonspace/object/acl/list/list.go index b3bf8cd0..cfcd3c3f 100644 --- a/commonspace/object/acl/list/list.go +++ b/commonspace/object/acl/list/list.go @@ -62,12 +62,12 @@ type aclList struct { func BuildAclListWithIdentity(acc *accountdata.AccountKeys, storage liststorage.ListStorage) (AclList, error) { builder := newAclStateBuilderWithIdentity(acc) keyStorage := crypto.NewKeyStorage() - return build(storage.Id(), keyStorage, builder, NewAclRecordBuilder(storage.Id(), keyStorage), storage) + return build(storage.Id(), keyStorage, builder, NewAclRecordBuilder(storage.Id(), keyStorage, acc), storage) } func BuildAclList(storage liststorage.ListStorage) (AclList, error) { keyStorage := crypto.NewKeyStorage() - return build(storage.Id(), keyStorage, newAclStateBuilder(), NewAclRecordBuilder(storage.Id(), crypto.NewKeyStorage()), storage) + return build(storage.Id(), keyStorage, newAclStateBuilder(), NewAclRecordBuilder(storage.Id(), crypto.NewKeyStorage(), nil), storage) } func build(id string, keyStorage crypto.KeyStorage, stateBuilder *aclStateBuilder, recBuilder AclRecordBuilder, storage liststorage.ListStorage) (list AclList, err error) { diff --git a/commonspace/object/acl/list/listutils.go b/commonspace/object/acl/list/listutils.go index 59e87888..64e43176 100644 --- a/commonspace/object/acl/list/listutils.go +++ b/commonspace/object/acl/list/listutils.go @@ -8,7 +8,7 @@ import ( ) func NewTestDerivedAcl(spaceId string, keys *accountdata.AccountKeys) (AclList, error) { - builder := NewAclRecordBuilder("", crypto.NewKeyStorage()) + builder := NewAclRecordBuilder("", crypto.NewKeyStorage(), keys) masterKey, _, err := crypto.GenerateRandomEd25519KeyPair() if err != nil { return nil, err diff --git a/commonspace/object/acl/list/models.go b/commonspace/object/acl/list/models.go index b0583a39..90db6e91 100644 --- a/commonspace/object/acl/list/models.go +++ b/commonspace/object/acl/list/models.go @@ -28,6 +28,14 @@ type AclUserState struct { type AclPermissions aclrecordproto.AclUserPermissions +func (p AclPermissions) NoPermissions() bool { + return aclrecordproto.AclUserPermissions(p) == aclrecordproto.AclUserPermissions_None +} + +func (p AclPermissions) IsOwner() bool { + return aclrecordproto.AclUserPermissions(p) == aclrecordproto.AclUserPermissions_Owner +} + func (p AclPermissions) CanWrite() bool { switch aclrecordproto.AclUserPermissions(p) { case aclrecordproto.AclUserPermissions_Admin: From b768dedd56ecf4a7784ede5fc91d886c0a2fc092 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Jun 2023 16:03:40 +0000 Subject: [PATCH 084/123] Bump github.com/libp2p/go-libp2p from 0.28.0 to 0.28.1 Bumps [github.com/libp2p/go-libp2p](https://github.com/libp2p/go-libp2p) from 0.28.0 to 0.28.1. - [Release notes](https://github.com/libp2p/go-libp2p/releases) - [Changelog](https://github.com/libp2p/go-libp2p/blob/master/CHANGELOG.md) - [Commits](https://github.com/libp2p/go-libp2p/compare/v0.28.0...v0.28.1) --- updated-dependencies: - dependency-name: github.com/libp2p/go-libp2p dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 7d036e80..925e5cd6 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,7 @@ require ( github.com/ipfs/go-ipld-format v0.5.0 github.com/ipfs/go-merkledag v0.11.0 github.com/ipfs/go-unixfs v0.4.6 - github.com/libp2p/go-libp2p v0.28.0 + github.com/libp2p/go-libp2p v0.28.1 github.com/mr-tron/base58 v1.2.0 github.com/multiformats/go-multibase v0.2.0 github.com/multiformats/go-multihash v0.2.3 diff --git a/go.sum b/go.sum index 6f95ef34..e36885d7 100644 --- a/go.sum +++ b/go.sum @@ -166,8 +166,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 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-libp2p v0.28.0 h1:zO8cY98nJiPzZpFv5w5gqqb8aVzt4ukQ0nVOSaaKhJ8= -github.com/libp2p/go-libp2p v0.28.0/go.mod h1:s3Xabc9LSwOcnv9UD4nORnXKTsWkPMkIMB/JIGXVnzk= +github.com/libp2p/go-libp2p v0.28.1 h1:YurK+ZAI6cKfASLJBVFkpVBdl3wGhFi6fusOt725ii8= +github.com/libp2p/go-libp2p v0.28.1/go.mod h1:s3Xabc9LSwOcnv9UD4nORnXKTsWkPMkIMB/JIGXVnzk= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= @@ -214,6 +214,7 @@ github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXS github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5 h1:BvoENQQU+fZ9uukda/RzCAL/191HHwJA5b13R6diVlY= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss= 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= From 061522eec2709a1724862550465813a9f1a60c95 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Mon, 26 Jun 2023 19:38:54 +0200 Subject: [PATCH 085/123] Update protocol --- .../object/acl/aclrecordproto/aclrecord.pb.go | 424 ++++++++---------- .../acl/aclrecordproto/protos/aclrecord.proto | 9 +- .../object/acl/list/aclrecordbuilder.go | 19 +- commonspace/object/acl/list/aclstate.go | 19 +- net/peer/peer.go | 5 - 5 files changed, 205 insertions(+), 271 deletions(-) diff --git a/commonspace/object/acl/aclrecordproto/aclrecord.pb.go b/commonspace/object/acl/aclrecordproto/aclrecord.pb.go index 9bb5eab4..8ab2e12f 100644 --- a/commonspace/object/acl/aclrecordproto/aclrecord.pb.go +++ b/commonspace/object/acl/aclrecordproto/aclrecord.pb.go @@ -449,10 +449,10 @@ func (m *AclAccountRequestJoin) GetMetadata() []byte { // AclAccountRequestAccept contains the reference to join record and all read keys, encrypted with the identity of the requestor type AclAccountRequestAccept struct { - Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` - RequestRecordId string `protobuf:"bytes,2,opt,name=requestRecordId,proto3" json:"requestRecordId,omitempty"` - EncryptedReadKeys []byte `protobuf:"bytes,3,opt,name=encryptedReadKeys,proto3" json:"encryptedReadKeys,omitempty"` - Permissions AclUserPermissions `protobuf:"varint,4,opt,name=permissions,proto3,enum=aclrecord.AclUserPermissions" json:"permissions,omitempty"` + Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` + RequestRecordId string `protobuf:"bytes,2,opt,name=requestRecordId,proto3" json:"requestRecordId,omitempty"` + EncryptedReadKeys []*AclReadKeyWithRecord `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 *AclAccountRequestAccept) Reset() { *m = AclAccountRequestAccept{} } @@ -502,7 +502,7 @@ func (m *AclAccountRequestAccept) GetRequestRecordId() string { return "" } -func (m *AclAccountRequestAccept) GetEncryptedReadKeys() []byte { +func (m *AclAccountRequestAccept) GetEncryptedReadKeys() []*AclReadKeyWithRecord { if m != nil { return m.EncryptedReadKeys } @@ -606,23 +606,24 @@ func (m *AclAccountInviteRevoke) GetInviteRecordId() string { return "" } -// AclReadKeys are all read keys in Acl -type AclReadKeys struct { - ReadKeys map[string][]byte `protobuf:"bytes,1,rep,name=readKeys,proto3" json:"readKeys,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +// AclReadKeys are a read key with record id +type AclReadKeyWithRecord struct { + RecordId string `protobuf:"bytes,1,opt,name=recordId,proto3" json:"recordId,omitempty"` + EncryptedReadKey []byte `protobuf:"bytes,2,opt,name=encryptedReadKey,proto3" json:"encryptedReadKey,omitempty"` } -func (m *AclReadKeys) Reset() { *m = AclReadKeys{} } -func (m *AclReadKeys) String() string { return proto.CompactTextString(m) } -func (*AclReadKeys) ProtoMessage() {} -func (*AclReadKeys) Descriptor() ([]byte, []int) { +func (m *AclReadKeyWithRecord) Reset() { *m = AclReadKeyWithRecord{} } +func (m *AclReadKeyWithRecord) String() string { return proto.CompactTextString(m) } +func (*AclReadKeyWithRecord) ProtoMessage() {} +func (*AclReadKeyWithRecord) Descriptor() ([]byte, []int) { return fileDescriptor_c8e9f754f34e929b, []int{9} } -func (m *AclReadKeys) XXX_Unmarshal(b []byte) error { +func (m *AclReadKeyWithRecord) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *AclReadKeys) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *AclReadKeyWithRecord) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_AclReadKeys.Marshal(b, m, deterministic) + return xxx_messageInfo_AclReadKeyWithRecord.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -632,21 +633,28 @@ func (m *AclReadKeys) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) return b[:n], nil } } -func (m *AclReadKeys) XXX_Merge(src proto.Message) { - xxx_messageInfo_AclReadKeys.Merge(m, src) +func (m *AclReadKeyWithRecord) XXX_Merge(src proto.Message) { + xxx_messageInfo_AclReadKeyWithRecord.Merge(m, src) } -func (m *AclReadKeys) XXX_Size() int { +func (m *AclReadKeyWithRecord) XXX_Size() int { return m.Size() } -func (m *AclReadKeys) XXX_DiscardUnknown() { - xxx_messageInfo_AclReadKeys.DiscardUnknown(m) +func (m *AclReadKeyWithRecord) XXX_DiscardUnknown() { + xxx_messageInfo_AclReadKeyWithRecord.DiscardUnknown(m) } -var xxx_messageInfo_AclReadKeys proto.InternalMessageInfo +var xxx_messageInfo_AclReadKeyWithRecord proto.InternalMessageInfo -func (m *AclReadKeys) GetReadKeys() map[string][]byte { +func (m *AclReadKeyWithRecord) GetRecordId() string { if m != nil { - return m.ReadKeys + return m.RecordId + } + return "" +} + +func (m *AclReadKeyWithRecord) GetEncryptedReadKey() []byte { + if m != nil { + return m.EncryptedReadKey } return nil } @@ -1238,8 +1246,7 @@ func init() { proto.RegisterType((*AclAccountRequestAccept)(nil), "aclrecord.AclAccountRequestAccept") proto.RegisterType((*AclAccountRequestDecline)(nil), "aclrecord.AclAccountRequestDecline") proto.RegisterType((*AclAccountInviteRevoke)(nil), "aclrecord.AclAccountInviteRevoke") - proto.RegisterType((*AclReadKeys)(nil), "aclrecord.AclReadKeys") - proto.RegisterMapType((map[string][]byte)(nil), "aclrecord.AclReadKeys.ReadKeysEntry") + proto.RegisterType((*AclReadKeyWithRecord)(nil), "aclrecord.AclReadKeyWithRecord") proto.RegisterType((*AclEncryptedReadKey)(nil), "aclrecord.AclEncryptedReadKey") proto.RegisterType((*AclAccountPermissionChange)(nil), "aclrecord.AclAccountPermissionChange") proto.RegisterType((*AclReadKeyChange)(nil), "aclrecord.AclReadKeyChange") @@ -1256,70 +1263,69 @@ func init() { } var fileDescriptor_c8e9f754f34e929b = []byte{ - // 1005 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0xdf, 0x6e, 0x1b, 0xc5, - 0x17, 0xde, 0xb5, 0x1d, 0x3b, 0x3e, 0x9b, 0xb8, 0xfe, 0xcd, 0x0f, 0x5a, 0x2b, 0x14, 0x2b, 0x2c, - 0x14, 0x45, 0x15, 0x4a, 0x90, 0x11, 0x22, 0x2a, 0x88, 0x66, 0x9b, 0x44, 0xd8, 0x81, 0x02, 0x9a, - 0x00, 0x95, 0x2a, 0x71, 0x31, 0x9d, 0x1d, 0xa5, 0x4b, 0xf7, 0x5f, 0x67, 0x27, 0xae, 0xfc, 0x0e, - 0x5c, 0xf0, 0x08, 0xbc, 0x08, 0xf7, 0x5c, 0xa1, 0xde, 0x20, 0x21, 0xae, 0x50, 0xf2, 0x22, 0x68, - 0x66, 0xf6, 0xff, 0x6e, 0x2d, 0x7a, 0xd1, 0x66, 0xe6, 0xcc, 0x39, 0xdf, 0x7c, 0xe7, 0x7c, 0x67, - 0xce, 0x1a, 0x3e, 0xa3, 0x51, 0x10, 0x44, 0x61, 0x12, 0x13, 0xca, 0x0e, 0xa2, 0x27, 0x3f, 0x31, - 0x2a, 0x0e, 0x08, 0xf5, 0xe5, 0x3f, 0xce, 0x68, 0xc4, 0xdd, 0x98, 0x47, 0x22, 0x3a, 0x50, 0xff, - 0x27, 0x85, 0x75, 0x5f, 0x19, 0xd0, 0x30, 0x37, 0xd8, 0xbf, 0x9a, 0xb0, 0x85, 0xc9, 0x0b, 0x87, - 0xfa, 0x58, 0x19, 0xd0, 0x04, 0x06, 0x31, 0x59, 0xf9, 0x11, 0x71, 0x27, 0xe6, 0xae, 0xb9, 0xb7, - 0x85, 0xb3, 0x2d, 0xba, 0x0d, 0xc3, 0xc4, 0xbb, 0x08, 0x89, 0xb8, 0xe4, 0x6c, 0xd2, 0x51, 0x67, - 0x85, 0x01, 0xdd, 0x85, 0x31, 0xa1, 0x94, 0xc5, 0x22, 0xe2, 0x0b, 0x97, 0x85, 0xc2, 0x13, 0xab, - 0x49, 0x57, 0x39, 0x35, 0xec, 0xe8, 0x03, 0xf8, 0x5f, 0x66, 0x3b, 0xcf, 0x11, 0x7b, 0xca, 0xb9, - 0x79, 0x60, 0x7f, 0x0e, 0xa8, 0xcc, 0xf0, 0x91, 0x27, 0x9e, 0x2e, 0xd6, 0xf1, 0x1c, 0x41, 0xc7, - 0x73, 0x15, 0xc1, 0x21, 0xee, 0x78, 0xae, 0xfd, 0x1c, 0x86, 0x45, 0x7a, 0x37, 0xa1, 0x1f, 0x73, - 0xb6, 0x5c, 0xe8, 0xa8, 0x21, 0x4e, 0x77, 0x68, 0x07, 0x36, 0xbd, 0x8c, 0xb6, 0xce, 0x2d, 0xdf, - 0x23, 0x04, 0x3d, 0x97, 0x08, 0x92, 0xa6, 0xa3, 0xd6, 0xb2, 0x18, 0xc2, 0x0b, 0x58, 0x22, 0x48, - 0x10, 0x2b, 0xea, 0x5d, 0x5c, 0x18, 0xec, 0x3f, 0x4d, 0x18, 0xc8, 0x3b, 0xa3, 0x48, 0x54, 0x90, - 0xcd, 0x1a, 0xf2, 0x6d, 0x18, 0x06, 0x24, 0x11, 0x8c, 0x7f, 0xc9, 0xb2, 0x6b, 0x0b, 0x83, 0x4c, - 0x51, 0x09, 0xbc, 0x70, 0xd5, 0xd5, 0x43, 0x9c, 0x6d, 0x65, 0xb1, 0x59, 0x48, 0xf9, 0x2a, 0x16, - 0xcc, 0xc5, 0x8c, 0xb8, 0x32, 0x5c, 0xd7, 0xaf, 0x61, 0xaf, 0x32, 0xdd, 0xa8, 0x31, 0x95, 0x52, - 0x64, 0x6c, 0x0a, 0x29, 0xfa, 0x5a, 0x8a, 0xc6, 0x81, 0xfd, 0x21, 0x8c, 0x1d, 0xea, 0x3b, 0x94, - 0x46, 0x97, 0xa1, 0x58, 0x84, 0x4b, 0x4f, 0x30, 0x89, 0xef, 0xa9, 0x95, 0x24, 0xa1, 0x13, 0x2c, - 0x0c, 0xf6, 0x6f, 0x26, 0xbc, 0x59, 0x84, 0x60, 0xf6, 0xfc, 0x92, 0x25, 0xe2, 0x2c, 0xf2, 0x42, - 0xf4, 0x3e, 0x8c, 0xb4, 0xdb, 0xa2, 0x5a, 0x9d, 0x9a, 0xb5, 0xf0, 0xd3, 0x0a, 0x2e, 0x32, 0x69, - 0x6b, 0x56, 0x74, 0x08, 0xb7, 0xaa, 0x91, 0x45, 0x3e, 0x5a, 0xb8, 0x57, 0x1d, 0x4b, 0x85, 0x02, - 0x26, 0x88, 0xd2, 0x58, 0x57, 0x31, 0xdf, 0xdb, 0x7f, 0x98, 0x70, 0xab, 0xc1, 0xdf, 0x51, 0x3d, - 0xba, 0x56, 0xd9, 0x3d, 0xb8, 0xc1, 0xb5, 0x73, 0x8d, 0x76, 0xdd, 0x2c, 0x15, 0xa8, 0x6b, 0x96, - 0xa4, 0x8c, 0x9b, 0x07, 0xe8, 0x3e, 0x58, 0x31, 0xe3, 0x81, 0x97, 0x24, 0x5e, 0x14, 0x26, 0x8a, - 0xee, 0x68, 0xf6, 0xf6, 0x7e, 0xf1, 0xc2, 0x1d, 0xea, 0x7f, 0x9f, 0x30, 0xfe, 0x6d, 0xe1, 0x84, - 0xcb, 0x11, 0xf6, 0x09, 0x4c, 0x1a, 0xf9, 0x9c, 0x30, 0xea, 0x7b, 0x21, 0x6b, 0x23, 0x6d, 0xb6, - 0x92, 0xb6, 0x8f, 0xe0, 0x66, 0xbd, 0x11, 0x30, 0x5b, 0x46, 0xcf, 0x58, 0x8b, 0x5c, 0x66, 0x9b, - 0x5c, 0xf6, 0xcf, 0x26, 0x58, 0xea, 0x59, 0xa6, 0x89, 0x1d, 0xc1, 0x26, 0xcf, 0xb2, 0x37, 0x77, - 0xbb, 0x7b, 0xd6, 0xec, 0xbd, 0x6a, 0x56, 0x99, 0xe7, 0x7e, 0xb6, 0x38, 0x0d, 0x05, 0x5f, 0xe1, - 0x3c, 0x6a, 0xe7, 0x53, 0xd8, 0xae, 0x1c, 0xa1, 0x31, 0x74, 0x9f, 0xa5, 0x3d, 0x39, 0xc4, 0x72, - 0x89, 0xde, 0x80, 0x8d, 0x25, 0xf1, 0x2f, 0xb3, 0xf1, 0xa5, 0x37, 0xf7, 0x3a, 0x87, 0xa6, 0xfd, - 0x23, 0xfc, 0xdf, 0xa1, 0xfe, 0x69, 0xfd, 0xf1, 0xac, 0x93, 0xb8, 0xed, 0x11, 0x76, 0xda, 0x1f, - 0xa1, 0xbd, 0x82, 0x9d, 0xa2, 0x5e, 0x85, 0x36, 0xc7, 0x4f, 0x49, 0x78, 0xc1, 0xd6, 0xde, 0x52, - 0x13, 0xbc, 0xf3, 0xda, 0x82, 0x7f, 0xa7, 0xde, 0x6c, 0x4a, 0x24, 0xbd, 0xf0, 0x08, 0x2c, 0xa2, - 0xb9, 0x94, 0xea, 0x3d, 0xad, 0x82, 0xd6, 0x6b, 0x81, 0xcb, 0x21, 0x76, 0x5c, 0x9e, 0x04, 0x98, - 0x05, 0xd1, 0x72, 0x7d, 0x1a, 0xb5, 0x1b, 0x3b, 0xaf, 0x7f, 0xe3, 0xdf, 0x3d, 0xb8, 0xe1, 0x50, - 0xff, 0x38, 0x0a, 0x05, 0x0b, 0xc5, 0x0f, 0x52, 0x39, 0xf4, 0x31, 0xf4, 0x75, 0x5b, 0xa9, 0xfb, - 0xac, 0xd9, 0x5b, 0x55, 0xc0, 0x4a, 0x7f, 0xce, 0x0d, 0x9c, 0x3a, 0xa3, 0x2f, 0x60, 0xcb, 0x2b, - 0xf5, 0xac, 0x2a, 0xaa, 0x35, 0x7b, 0x67, 0x4d, 0xb0, 0x76, 0x9c, 0x1b, 0xb8, 0x12, 0x88, 0x4e, - 0xc0, 0xe2, 0xc5, 0x48, 0x53, 0xaf, 0xd6, 0x9a, 0xed, 0xb6, 0xe2, 0x94, 0x46, 0xdf, 0xdc, 0xc0, - 0xe5, 0x30, 0x74, 0x06, 0xdb, 0xbc, 0x3c, 0x58, 0xd4, 0xab, 0xb6, 0x66, 0xf6, 0x3a, 0x1c, 0xed, - 0x39, 0x37, 0x70, 0x35, 0x14, 0x9d, 0xc3, 0x38, 0xae, 0xb5, 0x97, 0x1a, 0xfa, 0xd6, 0xec, 0x4e, - 0x2b, 0x5c, 0xbd, 0x17, 0xe7, 0x06, 0x6e, 0x00, 0xa0, 0x63, 0xd8, 0x26, 0x65, 0xa5, 0xd5, 0x07, - 0xe2, 0x55, 0xd5, 0xd6, 0x2e, 0x92, 0x59, 0x25, 0x46, 0x82, 0xf0, 0x72, 0x13, 0x4e, 0x06, 0x6d, - 0x20, 0x95, 0x3e, 0xd5, 0xe9, 0x95, 0x1b, 0xf7, 0x21, 0x8c, 0x78, 0x65, 0x66, 0x4d, 0x36, 0x15, - 0xca, 0xbb, 0xeb, 0x6a, 0x95, 0xba, 0xce, 0x0d, 0x5c, 0x0b, 0x7e, 0x30, 0x48, 0xe7, 0x81, 0x7d, - 0xaa, 0xbe, 0xd7, 0x27, 0xf2, 0xcb, 0x7e, 0x0f, 0x80, 0xe4, 0x6d, 0x96, 0x3e, 0x8d, 0x9d, 0x2a, - 0x7c, 0xb9, 0x07, 0x71, 0xc9, 0xdb, 0x3e, 0x83, 0x91, 0x43, 0xfd, 0xf3, 0x55, 0x48, 0x1f, 0xb2, - 0x24, 0x21, 0x17, 0x0c, 0x1d, 0xc2, 0x80, 0xe6, 0x50, 0x66, 0xb3, 0xe7, 0xa5, 0x6f, 0x05, 0x2e, - 0x73, 0xb7, 0x1f, 0xab, 0x89, 0x54, 0x3f, 0x57, 0xf4, 0x5c, 0x57, 0x8f, 0xd1, 0x24, 0xc5, 0x9c, - 0xd4, 0xb2, 0xcf, 0xcf, 0xe7, 0x06, 0x2e, 0x79, 0x17, 0xe9, 0xce, 0x61, 0xbb, 0xe2, 0x87, 0x3e, - 0x81, 0x01, 0xcf, 0x21, 0x65, 0xc6, 0xe5, 0x09, 0xd3, 0xfc, 0xf5, 0x85, 0x33, 0xef, 0xbb, 0x5f, - 0x01, 0x6a, 0x0e, 0x20, 0xb4, 0x09, 0xbd, 0xaf, 0xa3, 0x90, 0x8d, 0x0d, 0x34, 0x84, 0x8d, 0x6f, - 0x5e, 0x84, 0x8c, 0x8f, 0x4d, 0xb9, 0x74, 0xdc, 0xc0, 0x0b, 0xc7, 0x1d, 0x04, 0xd0, 0x7f, 0xc4, - 0x3d, 0xc1, 0xf8, 0xb8, 0x2b, 0xd7, 0x52, 0x74, 0xc6, 0xc7, 0xbd, 0x07, 0xf7, 0x7f, 0xbf, 0x9a, - 0x9a, 0x2f, 0xaf, 0xa6, 0xe6, 0x3f, 0x57, 0x53, 0xf3, 0x97, 0xeb, 0xa9, 0xf1, 0xf2, 0x7a, 0x6a, - 0xfc, 0x75, 0x3d, 0x35, 0x1e, 0xdf, 0xf9, 0x4f, 0x3f, 0x78, 0x9f, 0xf4, 0xd5, 0x9f, 0x8f, 0xfe, - 0x0d, 0x00, 0x00, 0xff, 0xff, 0xf9, 0x8e, 0x57, 0x42, 0x20, 0x0b, 0x00, 0x00, + // 977 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0xdd, 0x6e, 0x1b, 0x45, + 0x14, 0xde, 0x75, 0x1c, 0x3b, 0x3e, 0x9b, 0xb8, 0xee, 0x00, 0xed, 0x2a, 0x14, 0x13, 0x16, 0x15, + 0x45, 0x15, 0x6a, 0x90, 0x11, 0xa2, 0x42, 0x88, 0xd6, 0x4d, 0x2a, 0xec, 0x40, 0x00, 0x4d, 0x80, + 0x4a, 0x95, 0x40, 0x9a, 0xce, 0x8e, 0xd2, 0x85, 0xfd, 0xeb, 0xec, 0xc4, 0x95, 0xdf, 0x82, 0x47, + 0xe0, 0x45, 0xb8, 0xe7, 0xb2, 0x37, 0x48, 0x88, 0x2b, 0x94, 0x3c, 0x00, 0xaf, 0x80, 0x66, 0xc6, + 0xfb, 0x37, 0xbb, 0xb5, 0x9a, 0x8b, 0xc4, 0x3b, 0x67, 0xce, 0xf9, 0xe6, 0x9c, 0xf3, 0x7d, 0x73, + 0x76, 0xe1, 0x73, 0x9a, 0x44, 0x51, 0x12, 0x67, 0x29, 0xa1, 0xec, 0x20, 0x79, 0xfa, 0x0b, 0xa3, + 0xe2, 0x80, 0xd0, 0x50, 0xfe, 0x71, 0x46, 0x13, 0xee, 0xa7, 0x3c, 0x11, 0xc9, 0x81, 0xfa, 0x9f, + 0x95, 0xd6, 0xbb, 0xca, 0x80, 0x06, 0x85, 0xc1, 0xfb, 0xdd, 0x86, 0x6d, 0x4c, 0x5e, 0x4c, 0x69, + 0x88, 0x95, 0x01, 0xb9, 0xd0, 0x4f, 0xc9, 0x32, 0x4c, 0x88, 0xef, 0xda, 0x7b, 0xf6, 0xfe, 0x36, + 0xce, 0x97, 0xe8, 0x16, 0x0c, 0xb2, 0xe0, 0x2c, 0x26, 0xe2, 0x9c, 0x33, 0xb7, 0xa3, 0xf6, 0x4a, + 0x03, 0xba, 0x03, 0x23, 0x42, 0x29, 0x4b, 0x45, 0xc2, 0xe7, 0x3e, 0x8b, 0x45, 0x20, 0x96, 0xee, + 0x86, 0x72, 0x6a, 0xd8, 0xd1, 0x87, 0x70, 0x3d, 0xb7, 0x9d, 0x16, 0x88, 0x5d, 0xe5, 0xdc, 0xdc, + 0xf0, 0xbe, 0x00, 0x54, 0xcd, 0xf0, 0x71, 0x20, 0x9e, 0xcd, 0xd7, 0xe5, 0x39, 0x84, 0x4e, 0xe0, + 0xab, 0x04, 0x07, 0xb8, 0x13, 0xf8, 0xde, 0x73, 0x18, 0x94, 0xe5, 0xdd, 0x80, 0x5e, 0xca, 0xd9, + 0x62, 0xae, 0xa3, 0x06, 0x78, 0xb5, 0x42, 0xbb, 0xb0, 0x15, 0xe4, 0x69, 0xeb, 0xda, 0x8a, 0x35, + 0x42, 0xd0, 0xf5, 0x89, 0x20, 0xab, 0x72, 0xd4, 0xb3, 0x6c, 0x86, 0x08, 0x22, 0x96, 0x09, 0x12, + 0xa5, 0x2a, 0xf5, 0x0d, 0x5c, 0x1a, 0xbc, 0xbf, 0x6c, 0xe8, 0xcb, 0x33, 0x93, 0x44, 0xd4, 0x90, + 0x6d, 0x03, 0xf9, 0x16, 0x0c, 0x22, 0x92, 0x09, 0xc6, 0xbf, 0x62, 0xf9, 0xb1, 0xa5, 0x41, 0x96, + 0xa8, 0x08, 0x9e, 0xfb, 0xea, 0xe8, 0x01, 0xce, 0x97, 0xb2, 0xd9, 0x2c, 0xa6, 0x7c, 0x99, 0x0a, + 0xe6, 0x63, 0x46, 0x7c, 0x19, 0xae, 0xfb, 0xd7, 0xb0, 0xd7, 0x33, 0xdd, 0x34, 0x32, 0x95, 0x54, + 0xe4, 0xd9, 0x94, 0x54, 0xf4, 0x34, 0x15, 0x8d, 0x0d, 0xef, 0x23, 0x18, 0x4d, 0x69, 0x38, 0xa5, + 0x34, 0x39, 0x8f, 0xc5, 0x3c, 0x5e, 0x04, 0x82, 0x49, 0xfc, 0x40, 0x3d, 0xc9, 0x24, 0x74, 0x81, + 0xa5, 0xc1, 0xfb, 0xc3, 0x86, 0xb7, 0xca, 0x10, 0xcc, 0x9e, 0x9f, 0xb3, 0x4c, 0x1c, 0x27, 0x41, + 0x8c, 0x3e, 0x80, 0xa1, 0x76, 0x9b, 0xd7, 0xbb, 0x63, 0x58, 0x4b, 0x3f, 0xcd, 0xe0, 0x3c, 0xa7, + 0xd6, 0xb0, 0xa2, 0x7b, 0x70, 0xb3, 0x1e, 0x59, 0xd6, 0xa3, 0x89, 0x7b, 0xd5, 0xb6, 0x64, 0x28, + 0x62, 0x82, 0x28, 0x8e, 0x75, 0x17, 0x8b, 0xb5, 0xf7, 0x9f, 0x0d, 0x37, 0x1b, 0xf9, 0x4f, 0x95, + 0x46, 0xd7, 0x32, 0xbb, 0x0f, 0xd7, 0xb8, 0x76, 0x36, 0xd2, 0x36, 0xcd, 0xe8, 0x04, 0xae, 0x9b, + 0x9c, 0x65, 0xee, 0xc6, 0xde, 0xc6, 0xbe, 0x33, 0x79, 0xf7, 0x6e, 0x79, 0x73, 0x95, 0x84, 0xd5, + 0xae, 0xbc, 0x00, 0x3a, 0x1a, 0x37, 0x23, 0xd1, 0x7d, 0x70, 0x52, 0xc6, 0xa3, 0x20, 0xcb, 0x82, + 0x24, 0xce, 0x54, 0x3d, 0xc3, 0xc9, 0x3b, 0x75, 0xa0, 0x1f, 0x32, 0xc6, 0xbf, 0x2b, 0x9d, 0x70, + 0x35, 0xc2, 0x3b, 0x02, 0xb7, 0x51, 0xf0, 0x11, 0xa3, 0x61, 0x10, 0xb3, 0xb6, 0xaa, 0xec, 0xd6, + 0xaa, 0xbc, 0x07, 0x70, 0xc3, 0x54, 0x0a, 0x66, 0x8b, 0xe4, 0x57, 0xd6, 0xc2, 0xa7, 0xdd, 0xc6, + 0xa7, 0xf7, 0x33, 0xbc, 0xd9, 0x56, 0xb3, 0xec, 0x3a, 0xaf, 0x47, 0x16, 0xeb, 0xd6, 0x7b, 0xd1, + 0x69, 0xbf, 0x17, 0xde, 0x4f, 0xf0, 0xc6, 0x94, 0x86, 0x8f, 0xcc, 0xeb, 0xb2, 0x8e, 0xd4, 0xab, + 0xc0, 0x2f, 0x61, 0xb7, 0x6c, 0x40, 0xd9, 0xec, 0xc3, 0x67, 0x24, 0x3e, 0x63, 0x6b, 0x4f, 0x31, + 0x18, 0xec, 0x5c, 0x99, 0xc1, 0xef, 0xd5, 0x2d, 0x5d, 0x25, 0xb2, 0x3a, 0xf0, 0x01, 0x38, 0x44, + 0xe7, 0xa2, 0xf4, 0x65, 0x2b, 0x7d, 0x8d, 0xeb, 0xa0, 0x66, 0x2f, 0x70, 0x35, 0xc4, 0x4b, 0xab, + 0x77, 0x1f, 0xb3, 0x28, 0x59, 0xac, 0x2f, 0xc3, 0x38, 0xb1, 0x73, 0xf5, 0x13, 0xff, 0xe9, 0xc2, + 0xb5, 0x29, 0x0d, 0x0f, 0x93, 0x58, 0xb0, 0x58, 0xfc, 0x48, 0xc2, 0x73, 0x86, 0x3e, 0x81, 0x9e, + 0xd6, 0x89, 0x3a, 0xcf, 0x99, 0xbc, 0x5d, 0x07, 0xac, 0x09, 0x6e, 0x66, 0xe1, 0x95, 0x33, 0xfa, + 0x12, 0xb6, 0x83, 0x8a, 0x08, 0x55, 0x53, 0x9d, 0xc9, 0x7b, 0x6b, 0x82, 0xb5, 0xe3, 0xcc, 0xc2, + 0xb5, 0x40, 0x74, 0x04, 0x0e, 0x2f, 0x87, 0x98, 0x9a, 0x2c, 0xce, 0x64, 0xaf, 0x15, 0xa7, 0x32, + 0xec, 0x66, 0x16, 0xae, 0x86, 0xa1, 0x63, 0xd8, 0xe1, 0xd5, 0x51, 0xa2, 0xae, 0xa9, 0x33, 0xf1, + 0xd6, 0xe1, 0x68, 0xcf, 0x99, 0x85, 0xeb, 0xa1, 0xe8, 0x14, 0x46, 0xa9, 0x21, 0x2f, 0x35, 0xe6, + 0x9d, 0xc9, 0xed, 0x56, 0x38, 0x53, 0x8b, 0x33, 0x0b, 0x37, 0x00, 0xd0, 0x21, 0xec, 0x90, 0x2a, + 0xd3, 0xea, 0x95, 0xf0, 0xaa, 0x6e, 0x6b, 0x17, 0x99, 0x59, 0x2d, 0x46, 0x82, 0xf0, 0xaa, 0x08, + 0xdd, 0x7e, 0x1b, 0x48, 0x4d, 0xa7, 0xba, 0xbc, 0xaa, 0x70, 0x4f, 0x60, 0xc8, 0x6b, 0x43, 0xc8, + 0xdd, 0x52, 0x28, 0xef, 0xaf, 0xeb, 0xd5, 0xca, 0x75, 0x66, 0x61, 0x23, 0xf8, 0x61, 0x1f, 0x36, + 0x17, 0x52, 0x48, 0xde, 0x23, 0xf5, 0x86, 0x3e, 0x92, 0xef, 0xf2, 0xcf, 0x00, 0x48, 0x21, 0xb3, + 0xd5, 0xd5, 0xd8, 0xad, 0xc3, 0x57, 0x35, 0x88, 0x2b, 0xde, 0xde, 0x31, 0x0c, 0xa7, 0x34, 0x3c, + 0x5d, 0xc6, 0xf4, 0x84, 0x65, 0x19, 0x39, 0x63, 0xe8, 0x1e, 0xf4, 0x69, 0x01, 0x65, 0x37, 0x35, + 0x2f, 0x7d, 0x6b, 0x70, 0xb9, 0xbb, 0xf7, 0x44, 0x4d, 0x24, 0x73, 0x5f, 0xa5, 0xe7, 0xfb, 0x7a, + 0xfa, 0x65, 0x2b, 0x4c, 0xd7, 0xa8, 0xbe, 0xd8, 0x9f, 0x59, 0xb8, 0xe2, 0x5d, 0x96, 0x3b, 0x83, + 0x9d, 0x9a, 0x1f, 0xfa, 0x14, 0xfa, 0xbc, 0x80, 0x94, 0x15, 0x57, 0x27, 0x4c, 0xf3, 0x7b, 0x0b, + 0xe7, 0xde, 0x77, 0xbe, 0x06, 0xd4, 0x1c, 0x40, 0x68, 0x0b, 0xba, 0xdf, 0x24, 0x31, 0x1b, 0x59, + 0x68, 0x00, 0x9b, 0xdf, 0xbe, 0x88, 0x19, 0x1f, 0xd9, 0xf2, 0x71, 0xea, 0x47, 0x41, 0x3c, 0xea, + 0x20, 0x80, 0xde, 0x63, 0x1e, 0x08, 0xc6, 0x47, 0x1b, 0xf2, 0x59, 0x92, 0xce, 0xf8, 0xa8, 0xfb, + 0xf0, 0xfe, 0x9f, 0x17, 0x63, 0xfb, 0xe5, 0xc5, 0xd8, 0xfe, 0xf7, 0x62, 0x6c, 0xff, 0x76, 0x39, + 0xb6, 0x5e, 0x5e, 0x8e, 0xad, 0xbf, 0x2f, 0xc7, 0xd6, 0x93, 0xdb, 0xaf, 0xf5, 0x89, 0xfb, 0xb4, + 0xa7, 0x7e, 0x3e, 0xfe, 0x3f, 0x00, 0x00, 0xff, 0xff, 0x93, 0x1c, 0x33, 0x3f, 0x12, 0x0b, 0x00, + 0x00, } func (m *RawAclRecord) Marshal() (dAtA []byte, err error) { @@ -1629,11 +1635,18 @@ func (m *AclAccountRequestAccept) MarshalToSizedBuffer(dAtA []byte) (int, error) dAtA[i] = 0x20 } if len(m.EncryptedReadKeys) > 0 { - i -= len(m.EncryptedReadKeys) - copy(dAtA[i:], m.EncryptedReadKeys) - i = encodeVarintAclrecord(dAtA, i, uint64(len(m.EncryptedReadKeys))) - i-- - dAtA[i] = 0x1a + for iNdEx := len(m.EncryptedReadKeys) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.EncryptedReadKeys[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAclrecord(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } } if len(m.RequestRecordId) > 0 { i -= len(m.RequestRecordId) @@ -1712,7 +1725,7 @@ func (m *AclAccountInviteRevoke) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } -func (m *AclReadKeys) Marshal() (dAtA []byte, err error) { +func (m *AclReadKeyWithRecord) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1722,36 +1735,29 @@ func (m *AclReadKeys) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *AclReadKeys) MarshalTo(dAtA []byte) (int, error) { +func (m *AclReadKeyWithRecord) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *AclReadKeys) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *AclReadKeyWithRecord) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.ReadKeys) > 0 { - for k := range m.ReadKeys { - v := m.ReadKeys[k] - baseI := i - if len(v) > 0 { - i -= len(v) - copy(dAtA[i:], v) - i = encodeVarintAclrecord(dAtA, i, uint64(len(v))) - 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] = 0xa - } + 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] = 0x12 + } + if len(m.RecordId) > 0 { + i -= len(m.RecordId) + copy(dAtA[i:], m.RecordId) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.RecordId))) + i-- + dAtA[i] = 0xa } return len(dAtA) - i, nil } @@ -2432,9 +2438,11 @@ func (m *AclAccountRequestAccept) Size() (n int) { if l > 0 { n += 1 + l + sovAclrecord(uint64(l)) } - l = len(m.EncryptedReadKeys) - if l > 0 { - n += 1 + l + sovAclrecord(uint64(l)) + if len(m.EncryptedReadKeys) > 0 { + for _, e := range m.EncryptedReadKeys { + l = e.Size() + n += 1 + l + sovAclrecord(uint64(l)) + } } if m.Permissions != 0 { n += 1 + sovAclrecord(uint64(m.Permissions)) @@ -2468,23 +2476,19 @@ func (m *AclAccountInviteRevoke) Size() (n int) { return n } -func (m *AclReadKeys) Size() (n int) { +func (m *AclReadKeyWithRecord) Size() (n int) { if m == nil { return 0 } var l int _ = l - if len(m.ReadKeys) > 0 { - for k, v := range m.ReadKeys { - _ = k - _ = v - l = 0 - if len(v) > 0 { - l = 1 + len(v) + sovAclrecord(uint64(len(v))) - } - mapEntrySize := 1 + len(k) + sovAclrecord(uint64(len(k))) + l - n += mapEntrySize + 1 + sovAclrecord(uint64(mapEntrySize)) - } + l = len(m.RecordId) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) + } + l = len(m.EncryptedReadKey) + if l > 0 { + n += 1 + l + sovAclrecord(uint64(l)) } return n } @@ -3812,7 +3816,7 @@ func (m *AclAccountRequestAccept) Unmarshal(dAtA []byte) error { if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field EncryptedReadKeys", wireType) } - var byteLen int + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowAclrecord @@ -3822,24 +3826,24 @@ func (m *AclAccountRequestAccept) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + if msglen < 0 { return ErrInvalidLengthAclrecord } - postIndex := iNdEx + byteLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthAclrecord } if postIndex > l { return io.ErrUnexpectedEOF } - m.EncryptedReadKeys = append(m.EncryptedReadKeys[:0], dAtA[iNdEx:postIndex]...) - if m.EncryptedReadKeys == nil { - m.EncryptedReadKeys = []byte{} + m.EncryptedReadKeys = append(m.EncryptedReadKeys, &AclReadKeyWithRecord{}) + if err := m.EncryptedReadKeys[len(m.EncryptedReadKeys)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex case 4: @@ -4046,7 +4050,7 @@ func (m *AclAccountInviteRevoke) Unmarshal(dAtA []byte) error { } return nil } -func (m *AclReadKeys) Unmarshal(dAtA []byte) error { +func (m *AclReadKeyWithRecord) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4069,17 +4073,17 @@ func (m *AclReadKeys) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AclReadKeys: wiretype end group for non-group") + return fmt.Errorf("proto: AclReadKeyWithRecord: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AclReadKeys: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AclReadKeyWithRecord: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ReadKeys", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RecordId", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowAclrecord @@ -4089,119 +4093,57 @@ func (m *AclReadKeys) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthAclrecord } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthAclrecord } if postIndex > l { return io.ErrUnexpectedEOF } - if m.ReadKeys == nil { - m.ReadKeys = make(map[string][]byte) + m.RecordId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EncryptedReadKey", wireType) } - var mapkey string - mapvalue := []byte{} - 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 - } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclrecord } - 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 mapbyteLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAclrecord - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - mapbyteLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intMapbyteLen := int(mapbyteLen) - if intMapbyteLen < 0 { - return ErrInvalidLengthAclrecord - } - postbytesIndex := iNdEx + intMapbyteLen - if postbytesIndex < 0 { - return ErrInvalidLengthAclrecord - } - if postbytesIndex > l { - return io.ErrUnexpectedEOF - } - mapvalue = make([]byte, mapbyteLen) - copy(mapvalue, dAtA[iNdEx:postbytesIndex]) - iNdEx = postbytesIndex - } 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 + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break } } - m.ReadKeys[mapkey] = mapvalue + 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 diff --git a/commonspace/object/acl/aclrecordproto/protos/aclrecord.proto b/commonspace/object/acl/aclrecordproto/protos/aclrecord.proto index 1fa11e59..5215ae7a 100644 --- a/commonspace/object/acl/aclrecordproto/protos/aclrecord.proto +++ b/commonspace/object/acl/aclrecordproto/protos/aclrecord.proto @@ -51,7 +51,7 @@ message AclAccountRequestJoin { message AclAccountRequestAccept { bytes identity = 1; string requestRecordId = 2; - bytes encryptedReadKeys = 3; + repeated AclReadKeyWithRecord encryptedReadKeys = 3; AclUserPermissions permissions = 4; } @@ -65,9 +65,10 @@ message AclAccountInviteRevoke { string inviteRecordId = 1; } -// AclReadKeys are all read keys in Acl -message AclReadKeys { - map readKeys = 1; +// AclReadKeys are a read key with record id +message AclReadKeyWithRecord { + string recordId = 1; + bytes encryptedReadKey = 2; } // AclEncryptedReadKeys are new key for specific identity diff --git a/commonspace/object/acl/list/aclrecordbuilder.go b/commonspace/object/acl/list/aclrecordbuilder.go index 86b94c5c..b038a0c5 100644 --- a/commonspace/object/acl/list/aclrecordbuilder.go +++ b/commonspace/object/acl/list/aclrecordbuilder.go @@ -182,16 +182,21 @@ func (a *aclRecordBuilder) BuildRequestAccept(payload RequestAcceptPayload) (raw err = ErrNoSuchRequest return } - readKeys := map[string][]byte{} + var encryptedReadKeys []*aclrecordproto.AclReadKeyWithRecord for keyId, key := range a.state.userReadKeys { rawKey, err := key.Raw() if err != nil { return nil, err } - readKeys[keyId] = rawKey + enc, err := request.RequestIdentity.Encrypt(rawKey) + if err != nil { + return nil, err + } + encryptedReadKeys = append(encryptedReadKeys, &aclrecordproto.AclReadKeyWithRecord{ + RecordId: keyId, + EncryptedReadKey: enc, + }) } - aclKeys := &aclrecordproto.AclReadKeys{ReadKeys: readKeys} - marshalledKeys, err := aclKeys.Marshal() if err != nil { return } @@ -199,14 +204,10 @@ func (a *aclRecordBuilder) BuildRequestAccept(payload RequestAcceptPayload) (raw if err != nil { return } - encKeys, err := request.RequestIdentity.Encrypt(marshalledKeys) - if err != nil { - return - } acceptRec := &aclrecordproto.AclAccountRequestAccept{ Identity: requestIdentityProto, RequestRecordId: payload.RequestRecordId, - EncryptedReadKeys: encKeys, + EncryptedReadKeys: encryptedReadKeys, Permissions: aclrecordproto.AclUserPermissions(payload.Permissions), } content := &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_RequestAccept{RequestAccept: acceptRec}} diff --git a/commonspace/object/acl/list/aclstate.go b/commonspace/object/acl/list/aclstate.go index de484a13..7f4c64d9 100644 --- a/commonspace/object/acl/list/aclstate.go +++ b/commonspace/object/acl/list/aclstate.go @@ -312,21 +312,16 @@ func (st *AclState) applyRequestAccept(ch *aclrecordproto.AclAccountRequestAccep if !st.pubKey.Equals(acceptIdentity) { return nil } - res, err := st.key.Decrypt(ch.EncryptedReadKeys) - if err != nil { - return err - } - keys := &aclrecordproto.AclReadKeys{} - err = proto.Unmarshal(res, keys) - if err != nil { - return err - } - for keyId, key := range keys.ReadKeys { - sym, err := crypto.UnmarshallAESKey(key) + for _, key := range ch.EncryptedReadKeys { + decrypted, err := st.key.Decrypt(key.EncryptedReadKey) if err != nil { return err } - st.userReadKeys[keyId] = sym + sym, err := crypto.UnmarshallAESKey(decrypted) + if err != nil { + return err + } + st.userReadKeys[key.RecordId] = sym } return nil } diff --git a/net/peer/peer.go b/net/peer/peer.go index 6b6a7666..5bd81a8b 100644 --- a/net/peer/peer.go +++ b/net/peer/peer.go @@ -201,11 +201,6 @@ func (p *peer) TryClose(objectTTL time.Duration) (res bool, err error) { return false, nil } -// 70 stream -> 1 subconn -// 62 request -> 1 subconn -// 2600 subconn (2400 non active -> 5 min) - -// 2 5min connect func (p *peer) gc(ttl time.Duration) (aliveCount int) { p.mu.Lock() defer p.mu.Unlock() From 0ffbb6fa5ae94f625993c7f50fd8d37248aebd4e Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Tue, 27 Jun 2023 19:44:44 +0200 Subject: [PATCH 086/123] Rework ACL structures --- .../object/acl/aclrecordproto/aclrecord.pb.go | 390 +++++++++++++----- .../acl/aclrecordproto/protos/aclrecord.proto | 7 +- .../object/acl/list/aclrecordbuilder.go | 59 ++- commonspace/object/acl/list/aclstate.go | 91 ++-- commonspace/object/acl/list/list.go | 61 ++- commonspace/object/acl/list/listutils.go | 2 +- commonspace/object/acl/list/models.go | 7 + commonspace/object/acl/list/validator.go | 41 +- commonspace/object/acl/syncacl/syncacl.go | 3 +- .../object/tree/exporter/treeimport.go | 2 +- commonspace/payloads.go | 15 +- util/crypto/ed25519_test.go | 3 +- util/strkey/strkey_test.go | 3 +- 13 files changed, 516 insertions(+), 168 deletions(-) diff --git a/commonspace/object/acl/aclrecordproto/aclrecord.pb.go b/commonspace/object/acl/aclrecordproto/aclrecord.pb.go index 8ab2e12f..2d264f05 100644 --- a/commonspace/object/acl/aclrecordproto/aclrecord.pb.go +++ b/commonspace/object/acl/aclrecordproto/aclrecord.pb.go @@ -812,7 +812,7 @@ func (m *AclReadKeyChange) GetAccountKeys() []*AclEncryptedReadKey { // AclAccountRemove removes an account and changes read key for space type AclAccountRemove struct { - Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` + Identities [][]byte `protobuf:"bytes,1,rep,name=identities,proto3" json:"identities,omitempty"` AccountKeys []*AclEncryptedReadKey `protobuf:"bytes,2,rep,name=accountKeys,proto3" json:"accountKeys,omitempty"` } @@ -849,9 +849,9 @@ func (m *AclAccountRemove) XXX_DiscardUnknown() { var xxx_messageInfo_AclAccountRemove proto.InternalMessageInfo -func (m *AclAccountRemove) GetIdentity() []byte { +func (m *AclAccountRemove) GetIdentities() [][]byte { if m != nil { - return m.Identity + return m.Identities } return nil } @@ -863,6 +863,43 @@ func (m *AclAccountRemove) GetAccountKeys() []*AclEncryptedReadKey { return nil } +// AclAccountRequestRemove adds a request to remove an account +type AclAccountRequestRemove struct { +} + +func (m *AclAccountRequestRemove) Reset() { *m = AclAccountRequestRemove{} } +func (m *AclAccountRequestRemove) String() string { return proto.CompactTextString(m) } +func (*AclAccountRequestRemove) ProtoMessage() {} +func (*AclAccountRequestRemove) Descriptor() ([]byte, []int) { + return fileDescriptor_c8e9f754f34e929b, []int{14} +} +func (m *AclAccountRequestRemove) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AclAccountRequestRemove) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AclAccountRequestRemove.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 *AclAccountRequestRemove) XXX_Merge(src proto.Message) { + xxx_messageInfo_AclAccountRequestRemove.Merge(m, src) +} +func (m *AclAccountRequestRemove) XXX_Size() int { + return m.Size() +} +func (m *AclAccountRequestRemove) XXX_DiscardUnknown() { + xxx_messageInfo_AclAccountRequestRemove.DiscardUnknown(m) +} + +var xxx_messageInfo_AclAccountRequestRemove proto.InternalMessageInfo + // AclContentValue contains possible values for Acl type AclContentValue struct { // Types that are valid to be assigned to Value: @@ -875,6 +912,7 @@ type AclContentValue struct { // *AclContentValue_AccountRemove // *AclContentValue_ReadKeyChange // *AclContentValue_RequestDecline + // *AclContentValue_AccountRequestRemove Value isAclContentValue_Value `protobuf_oneof:"value"` } @@ -882,7 +920,7 @@ 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_c8e9f754f34e929b, []int{14} + return fileDescriptor_c8e9f754f34e929b, []int{15} } func (m *AclContentValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -941,15 +979,19 @@ type AclContentValue_ReadKeyChange struct { type AclContentValue_RequestDecline struct { RequestDecline *AclAccountRequestDecline `protobuf:"bytes,8,opt,name=requestDecline,proto3,oneof" json:"requestDecline,omitempty"` } +type AclContentValue_AccountRequestRemove struct { + AccountRequestRemove *AclAccountRequestRemove `protobuf:"bytes,9,opt,name=accountRequestRemove,proto3,oneof" json:"accountRequestRemove,omitempty"` +} -func (*AclContentValue_Invite) isAclContentValue_Value() {} -func (*AclContentValue_InviteRevoke) isAclContentValue_Value() {} -func (*AclContentValue_RequestJoin) isAclContentValue_Value() {} -func (*AclContentValue_RequestAccept) isAclContentValue_Value() {} -func (*AclContentValue_PermissionChange) isAclContentValue_Value() {} -func (*AclContentValue_AccountRemove) isAclContentValue_Value() {} -func (*AclContentValue_ReadKeyChange) isAclContentValue_Value() {} -func (*AclContentValue_RequestDecline) isAclContentValue_Value() {} +func (*AclContentValue_Invite) isAclContentValue_Value() {} +func (*AclContentValue_InviteRevoke) isAclContentValue_Value() {} +func (*AclContentValue_RequestJoin) isAclContentValue_Value() {} +func (*AclContentValue_RequestAccept) isAclContentValue_Value() {} +func (*AclContentValue_PermissionChange) isAclContentValue_Value() {} +func (*AclContentValue_AccountRemove) isAclContentValue_Value() {} +func (*AclContentValue_ReadKeyChange) isAclContentValue_Value() {} +func (*AclContentValue_RequestDecline) isAclContentValue_Value() {} +func (*AclContentValue_AccountRequestRemove) isAclContentValue_Value() {} func (m *AclContentValue) GetValue() isAclContentValue_Value { if m != nil { @@ -1014,6 +1056,13 @@ func (m *AclContentValue) GetRequestDecline() *AclAccountRequestDecline { return nil } +func (m *AclContentValue) GetAccountRequestRemove() *AclAccountRequestRemove { + if x, ok := m.GetValue().(*AclContentValue_AccountRequestRemove); ok { + return x.AccountRequestRemove + } + return nil +} + // XXX_OneofWrappers is for the internal use of the proto package. func (*AclContentValue) XXX_OneofWrappers() []interface{} { return []interface{}{ @@ -1025,6 +1074,7 @@ func (*AclContentValue) XXX_OneofWrappers() []interface{} { (*AclContentValue_AccountRemove)(nil), (*AclContentValue_ReadKeyChange)(nil), (*AclContentValue_RequestDecline)(nil), + (*AclContentValue_AccountRequestRemove)(nil), } } @@ -1037,7 +1087,7 @@ 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_c8e9f754f34e929b, []int{15} + return fileDescriptor_c8e9f754f34e929b, []int{16} } func (m *AclData) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1081,7 +1131,7 @@ 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_c8e9f754f34e929b, []int{16} + return fileDescriptor_c8e9f754f34e929b, []int{17} } func (m *AclSyncMessage) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1129,7 +1179,7 @@ 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_c8e9f754f34e929b, []int{17} + return fileDescriptor_c8e9f754f34e929b, []int{18} } func (m *AclSyncContentValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1199,7 +1249,7 @@ 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_c8e9f754f34e929b, []int{18} + return fileDescriptor_c8e9f754f34e929b, []int{19} } func (m *AclAddRecords) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1251,6 +1301,7 @@ func init() { proto.RegisterType((*AclAccountPermissionChange)(nil), "aclrecord.AclAccountPermissionChange") proto.RegisterType((*AclReadKeyChange)(nil), "aclrecord.AclReadKeyChange") proto.RegisterType((*AclAccountRemove)(nil), "aclrecord.AclAccountRemove") + proto.RegisterType((*AclAccountRequestRemove)(nil), "aclrecord.AclAccountRequestRemove") proto.RegisterType((*AclContentValue)(nil), "aclrecord.AclContentValue") proto.RegisterType((*AclData)(nil), "aclrecord.AclData") proto.RegisterType((*AclSyncMessage)(nil), "aclrecord.AclSyncMessage") @@ -1263,69 +1314,70 @@ func init() { } var fileDescriptor_c8e9f754f34e929b = []byte{ - // 977 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0xdd, 0x6e, 0x1b, 0x45, - 0x14, 0xde, 0x75, 0x1c, 0x3b, 0x3e, 0x9b, 0xb8, 0xee, 0x00, 0xed, 0x2a, 0x14, 0x13, 0x16, 0x15, - 0x45, 0x15, 0x6a, 0x90, 0x11, 0xa2, 0x42, 0x88, 0xd6, 0x4d, 0x2a, 0xec, 0x40, 0x00, 0x4d, 0x80, - 0x4a, 0x95, 0x40, 0x9a, 0xce, 0x8e, 0xd2, 0x85, 0xfd, 0xeb, 0xec, 0xc4, 0x95, 0xdf, 0x82, 0x47, - 0xe0, 0x45, 0xb8, 0xe7, 0xb2, 0x37, 0x48, 0x88, 0x2b, 0x94, 0x3c, 0x00, 0xaf, 0x80, 0x66, 0xc6, - 0xfb, 0x37, 0xbb, 0xb5, 0x9a, 0x8b, 0xc4, 0x3b, 0x67, 0xce, 0xf9, 0xe6, 0x9c, 0xf3, 0x7d, 0x73, - 0x76, 0xe1, 0x73, 0x9a, 0x44, 0x51, 0x12, 0x67, 0x29, 0xa1, 0xec, 0x20, 0x79, 0xfa, 0x0b, 0xa3, - 0xe2, 0x80, 0xd0, 0x50, 0xfe, 0x71, 0x46, 0x13, 0xee, 0xa7, 0x3c, 0x11, 0xc9, 0x81, 0xfa, 0x9f, - 0x95, 0xd6, 0xbb, 0xca, 0x80, 0x06, 0x85, 0xc1, 0xfb, 0xdd, 0x86, 0x6d, 0x4c, 0x5e, 0x4c, 0x69, - 0x88, 0x95, 0x01, 0xb9, 0xd0, 0x4f, 0xc9, 0x32, 0x4c, 0x88, 0xef, 0xda, 0x7b, 0xf6, 0xfe, 0x36, - 0xce, 0x97, 0xe8, 0x16, 0x0c, 0xb2, 0xe0, 0x2c, 0x26, 0xe2, 0x9c, 0x33, 0xb7, 0xa3, 0xf6, 0x4a, - 0x03, 0xba, 0x03, 0x23, 0x42, 0x29, 0x4b, 0x45, 0xc2, 0xe7, 0x3e, 0x8b, 0x45, 0x20, 0x96, 0xee, - 0x86, 0x72, 0x6a, 0xd8, 0xd1, 0x87, 0x70, 0x3d, 0xb7, 0x9d, 0x16, 0x88, 0x5d, 0xe5, 0xdc, 0xdc, - 0xf0, 0xbe, 0x00, 0x54, 0xcd, 0xf0, 0x71, 0x20, 0x9e, 0xcd, 0xd7, 0xe5, 0x39, 0x84, 0x4e, 0xe0, - 0xab, 0x04, 0x07, 0xb8, 0x13, 0xf8, 0xde, 0x73, 0x18, 0x94, 0xe5, 0xdd, 0x80, 0x5e, 0xca, 0xd9, - 0x62, 0xae, 0xa3, 0x06, 0x78, 0xb5, 0x42, 0xbb, 0xb0, 0x15, 0xe4, 0x69, 0xeb, 0xda, 0x8a, 0x35, - 0x42, 0xd0, 0xf5, 0x89, 0x20, 0xab, 0x72, 0xd4, 0xb3, 0x6c, 0x86, 0x08, 0x22, 0x96, 0x09, 0x12, - 0xa5, 0x2a, 0xf5, 0x0d, 0x5c, 0x1a, 0xbc, 0xbf, 0x6c, 0xe8, 0xcb, 0x33, 0x93, 0x44, 0xd4, 0x90, - 0x6d, 0x03, 0xf9, 0x16, 0x0c, 0x22, 0x92, 0x09, 0xc6, 0xbf, 0x62, 0xf9, 0xb1, 0xa5, 0x41, 0x96, - 0xa8, 0x08, 0x9e, 0xfb, 0xea, 0xe8, 0x01, 0xce, 0x97, 0xb2, 0xd9, 0x2c, 0xa6, 0x7c, 0x99, 0x0a, - 0xe6, 0x63, 0x46, 0x7c, 0x19, 0xae, 0xfb, 0xd7, 0xb0, 0xd7, 0x33, 0xdd, 0x34, 0x32, 0x95, 0x54, - 0xe4, 0xd9, 0x94, 0x54, 0xf4, 0x34, 0x15, 0x8d, 0x0d, 0xef, 0x23, 0x18, 0x4d, 0x69, 0x38, 0xa5, - 0x34, 0x39, 0x8f, 0xc5, 0x3c, 0x5e, 0x04, 0x82, 0x49, 0xfc, 0x40, 0x3d, 0xc9, 0x24, 0x74, 0x81, - 0xa5, 0xc1, 0xfb, 0xc3, 0x86, 0xb7, 0xca, 0x10, 0xcc, 0x9e, 0x9f, 0xb3, 0x4c, 0x1c, 0x27, 0x41, - 0x8c, 0x3e, 0x80, 0xa1, 0x76, 0x9b, 0xd7, 0xbb, 0x63, 0x58, 0x4b, 0x3f, 0xcd, 0xe0, 0x3c, 0xa7, - 0xd6, 0xb0, 0xa2, 0x7b, 0x70, 0xb3, 0x1e, 0x59, 0xd6, 0xa3, 0x89, 0x7b, 0xd5, 0xb6, 0x64, 0x28, - 0x62, 0x82, 0x28, 0x8e, 0x75, 0x17, 0x8b, 0xb5, 0xf7, 0x9f, 0x0d, 0x37, 0x1b, 0xf9, 0x4f, 0x95, - 0x46, 0xd7, 0x32, 0xbb, 0x0f, 0xd7, 0xb8, 0x76, 0x36, 0xd2, 0x36, 0xcd, 0xe8, 0x04, 0xae, 0x9b, - 0x9c, 0x65, 0xee, 0xc6, 0xde, 0xc6, 0xbe, 0x33, 0x79, 0xf7, 0x6e, 0x79, 0x73, 0x95, 0x84, 0xd5, - 0xae, 0xbc, 0x00, 0x3a, 0x1a, 0x37, 0x23, 0xd1, 0x7d, 0x70, 0x52, 0xc6, 0xa3, 0x20, 0xcb, 0x82, - 0x24, 0xce, 0x54, 0x3d, 0xc3, 0xc9, 0x3b, 0x75, 0xa0, 0x1f, 0x32, 0xc6, 0xbf, 0x2b, 0x9d, 0x70, - 0x35, 0xc2, 0x3b, 0x02, 0xb7, 0x51, 0xf0, 0x11, 0xa3, 0x61, 0x10, 0xb3, 0xb6, 0xaa, 0xec, 0xd6, - 0xaa, 0xbc, 0x07, 0x70, 0xc3, 0x54, 0x0a, 0x66, 0x8b, 0xe4, 0x57, 0xd6, 0xc2, 0xa7, 0xdd, 0xc6, - 0xa7, 0xf7, 0x33, 0xbc, 0xd9, 0x56, 0xb3, 0xec, 0x3a, 0xaf, 0x47, 0x16, 0xeb, 0xd6, 0x7b, 0xd1, - 0x69, 0xbf, 0x17, 0xde, 0x4f, 0xf0, 0xc6, 0x94, 0x86, 0x8f, 0xcc, 0xeb, 0xb2, 0x8e, 0xd4, 0xab, - 0xc0, 0x2f, 0x61, 0xb7, 0x6c, 0x40, 0xd9, 0xec, 0xc3, 0x67, 0x24, 0x3e, 0x63, 0x6b, 0x4f, 0x31, - 0x18, 0xec, 0x5c, 0x99, 0xc1, 0xef, 0xd5, 0x2d, 0x5d, 0x25, 0xb2, 0x3a, 0xf0, 0x01, 0x38, 0x44, - 0xe7, 0xa2, 0xf4, 0x65, 0x2b, 0x7d, 0x8d, 0xeb, 0xa0, 0x66, 0x2f, 0x70, 0x35, 0xc4, 0x4b, 0xab, - 0x77, 0x1f, 0xb3, 0x28, 0x59, 0xac, 0x2f, 0xc3, 0x38, 0xb1, 0x73, 0xf5, 0x13, 0xff, 0xe9, 0xc2, - 0xb5, 0x29, 0x0d, 0x0f, 0x93, 0x58, 0xb0, 0x58, 0xfc, 0x48, 0xc2, 0x73, 0x86, 0x3e, 0x81, 0x9e, - 0xd6, 0x89, 0x3a, 0xcf, 0x99, 0xbc, 0x5d, 0x07, 0xac, 0x09, 0x6e, 0x66, 0xe1, 0x95, 0x33, 0xfa, - 0x12, 0xb6, 0x83, 0x8a, 0x08, 0x55, 0x53, 0x9d, 0xc9, 0x7b, 0x6b, 0x82, 0xb5, 0xe3, 0xcc, 0xc2, - 0xb5, 0x40, 0x74, 0x04, 0x0e, 0x2f, 0x87, 0x98, 0x9a, 0x2c, 0xce, 0x64, 0xaf, 0x15, 0xa7, 0x32, - 0xec, 0x66, 0x16, 0xae, 0x86, 0xa1, 0x63, 0xd8, 0xe1, 0xd5, 0x51, 0xa2, 0xae, 0xa9, 0x33, 0xf1, - 0xd6, 0xe1, 0x68, 0xcf, 0x99, 0x85, 0xeb, 0xa1, 0xe8, 0x14, 0x46, 0xa9, 0x21, 0x2f, 0x35, 0xe6, - 0x9d, 0xc9, 0xed, 0x56, 0x38, 0x53, 0x8b, 0x33, 0x0b, 0x37, 0x00, 0xd0, 0x21, 0xec, 0x90, 0x2a, - 0xd3, 0xea, 0x95, 0xf0, 0xaa, 0x6e, 0x6b, 0x17, 0x99, 0x59, 0x2d, 0x46, 0x82, 0xf0, 0xaa, 0x08, - 0xdd, 0x7e, 0x1b, 0x48, 0x4d, 0xa7, 0xba, 0xbc, 0xaa, 0x70, 0x4f, 0x60, 0xc8, 0x6b, 0x43, 0xc8, - 0xdd, 0x52, 0x28, 0xef, 0xaf, 0xeb, 0xd5, 0xca, 0x75, 0x66, 0x61, 0x23, 0xf8, 0x61, 0x1f, 0x36, - 0x17, 0x52, 0x48, 0xde, 0x23, 0xf5, 0x86, 0x3e, 0x92, 0xef, 0xf2, 0xcf, 0x00, 0x48, 0x21, 0xb3, - 0xd5, 0xd5, 0xd8, 0xad, 0xc3, 0x57, 0x35, 0x88, 0x2b, 0xde, 0xde, 0x31, 0x0c, 0xa7, 0x34, 0x3c, - 0x5d, 0xc6, 0xf4, 0x84, 0x65, 0x19, 0x39, 0x63, 0xe8, 0x1e, 0xf4, 0x69, 0x01, 0x65, 0x37, 0x35, - 0x2f, 0x7d, 0x6b, 0x70, 0xb9, 0xbb, 0xf7, 0x44, 0x4d, 0x24, 0x73, 0x5f, 0xa5, 0xe7, 0xfb, 0x7a, - 0xfa, 0x65, 0x2b, 0x4c, 0xd7, 0xa8, 0xbe, 0xd8, 0x9f, 0x59, 0xb8, 0xe2, 0x5d, 0x96, 0x3b, 0x83, - 0x9d, 0x9a, 0x1f, 0xfa, 0x14, 0xfa, 0xbc, 0x80, 0x94, 0x15, 0x57, 0x27, 0x4c, 0xf3, 0x7b, 0x0b, - 0xe7, 0xde, 0x77, 0xbe, 0x06, 0xd4, 0x1c, 0x40, 0x68, 0x0b, 0xba, 0xdf, 0x24, 0x31, 0x1b, 0x59, - 0x68, 0x00, 0x9b, 0xdf, 0xbe, 0x88, 0x19, 0x1f, 0xd9, 0xf2, 0x71, 0xea, 0x47, 0x41, 0x3c, 0xea, - 0x20, 0x80, 0xde, 0x63, 0x1e, 0x08, 0xc6, 0x47, 0x1b, 0xf2, 0x59, 0x92, 0xce, 0xf8, 0xa8, 0xfb, - 0xf0, 0xfe, 0x9f, 0x17, 0x63, 0xfb, 0xe5, 0xc5, 0xd8, 0xfe, 0xf7, 0x62, 0x6c, 0xff, 0x76, 0x39, - 0xb6, 0x5e, 0x5e, 0x8e, 0xad, 0xbf, 0x2f, 0xc7, 0xd6, 0x93, 0xdb, 0xaf, 0xf5, 0x89, 0xfb, 0xb4, - 0xa7, 0x7e, 0x3e, 0xfe, 0x3f, 0x00, 0x00, 0xff, 0xff, 0x93, 0x1c, 0x33, 0x3f, 0x12, 0x0b, 0x00, - 0x00, + // 1008 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0xdd, 0x6e, 0xdc, 0x44, + 0x14, 0xb6, 0x37, 0xc9, 0x6e, 0x7c, 0x9c, 0x6c, 0xb7, 0x43, 0x69, 0x4d, 0x28, 0x4b, 0x30, 0x2a, + 0x8a, 0x2a, 0xd4, 0xa0, 0x45, 0x88, 0x0a, 0x21, 0xda, 0x6d, 0x52, 0xb1, 0x1b, 0x08, 0xa0, 0x09, + 0x50, 0x54, 0x09, 0xa4, 0xe9, 0x78, 0x94, 0x1a, 0xfc, 0xd7, 0xf1, 0x64, 0xab, 0x7d, 0x0b, 0x1e, + 0x81, 0x87, 0xe0, 0x96, 0x7b, 0x2e, 0x7b, 0x83, 0xc4, 0x25, 0x4a, 0x1e, 0x80, 0x57, 0x40, 0x33, + 0xe3, 0x7f, 0xbb, 0x4b, 0x73, 0x91, 0xac, 0xe7, 0xcc, 0x39, 0xdf, 0xf9, 0xfb, 0xce, 0xb1, 0xe1, + 0x53, 0x1a, 0x87, 0x61, 0x1c, 0xa5, 0x09, 0xa1, 0x6c, 0x3f, 0x7e, 0xf2, 0x33, 0xa3, 0x62, 0x9f, + 0xd0, 0x40, 0xfe, 0x71, 0x46, 0x63, 0xee, 0x25, 0x3c, 0x16, 0xf1, 0xbe, 0xfa, 0x9f, 0x96, 0xd2, + 0x3b, 0x4a, 0x80, 0xac, 0x42, 0xe0, 0xfe, 0x66, 0xc2, 0x16, 0x26, 0xcf, 0xa7, 0x34, 0xc0, 0x4a, + 0x80, 0x1c, 0x18, 0x24, 0x64, 0x19, 0xc4, 0xc4, 0x73, 0xcc, 0x5d, 0x73, 0x6f, 0x0b, 0xe7, 0x47, + 0x74, 0x13, 0xac, 0xd4, 0x3f, 0x8d, 0x88, 0x38, 0xe3, 0xcc, 0xe9, 0xa9, 0xbb, 0x52, 0x80, 0x6e, + 0xc3, 0x88, 0x50, 0xca, 0x12, 0x11, 0xf3, 0xb9, 0xc7, 0x22, 0xe1, 0x8b, 0xa5, 0xb3, 0xa6, 0x94, + 0x5a, 0x72, 0xf4, 0x3e, 0x5c, 0xcd, 0x65, 0x27, 0x05, 0xe2, 0xba, 0x52, 0x6e, 0x5f, 0xb8, 0x9f, + 0x01, 0xaa, 0x46, 0xf8, 0xc8, 0x17, 0x4f, 0xe7, 0xab, 0xe2, 0x1c, 0x42, 0xcf, 0xf7, 0x54, 0x80, + 0x16, 0xee, 0xf9, 0x9e, 0xfb, 0x0c, 0xac, 0x32, 0xbd, 0xeb, 0xd0, 0x4f, 0x38, 0x5b, 0xcc, 0xb5, + 0x95, 0x85, 0xb3, 0x13, 0xda, 0x81, 0x4d, 0x3f, 0x0f, 0x5b, 0xe7, 0x56, 0x9c, 0x11, 0x82, 0x75, + 0x8f, 0x08, 0x92, 0xa5, 0xa3, 0x9e, 0x65, 0x31, 0x84, 0x1f, 0xb2, 0x54, 0x90, 0x30, 0x51, 0xa1, + 0xaf, 0xe1, 0x52, 0xe0, 0xfe, 0x65, 0xc2, 0x40, 0xfa, 0x8c, 0x63, 0x51, 0x43, 0x36, 0x1b, 0xc8, + 0x37, 0xc1, 0x0a, 0x49, 0x2a, 0x18, 0xff, 0x82, 0xe5, 0x6e, 0x4b, 0x81, 0x4c, 0x51, 0x35, 0x78, + 0xee, 0x29, 0xd7, 0x16, 0xce, 0x8f, 0xb2, 0xd8, 0x2c, 0xa2, 0x7c, 0x99, 0x08, 0xe6, 0x61, 0x46, + 0x3c, 0x69, 0xae, 0xeb, 0xd7, 0x92, 0xd7, 0x23, 0xdd, 0x68, 0x44, 0x2a, 0x5b, 0x91, 0x47, 0x53, + 0xb6, 0xa2, 0xaf, 0x5b, 0xd1, 0xba, 0x70, 0x3f, 0x80, 0xd1, 0x94, 0x06, 0x53, 0x4a, 0xe3, 0xb3, + 0x48, 0xcc, 0xa3, 0x85, 0x2f, 0x98, 0xc4, 0xf7, 0xd5, 0x93, 0x0c, 0x42, 0x27, 0x58, 0x0a, 0xdc, + 0x3f, 0x4c, 0x78, 0xbd, 0x34, 0xc1, 0xec, 0xd9, 0x19, 0x4b, 0xc5, 0x51, 0xec, 0x47, 0xe8, 0x3d, + 0x18, 0x6a, 0xb5, 0x79, 0xbd, 0x3a, 0x0d, 0x69, 0xa9, 0xa7, 0x3b, 0x38, 0xcf, 0x5b, 0xdb, 0x90, + 0xa2, 0xbb, 0x70, 0xa3, 0x6e, 0x59, 0xe6, 0xa3, 0x1b, 0xf7, 0xb2, 0x6b, 0xd9, 0xa1, 0x90, 0x09, + 0xa2, 0x7a, 0xac, 0xab, 0x58, 0x9c, 0xdd, 0x7f, 0x4d, 0xb8, 0xd1, 0x8a, 0x7f, 0xaa, 0x38, 0xba, + 0xb2, 0xb3, 0x7b, 0x70, 0x85, 0x6b, 0xe5, 0x46, 0xd8, 0x4d, 0x31, 0x3a, 0x86, 0xab, 0xcd, 0x9e, + 0xa5, 0xce, 0xda, 0xee, 0xda, 0x9e, 0x3d, 0x79, 0xfb, 0x4e, 0x39, 0xb9, 0x8a, 0xc2, 0xea, 0x56, + 0x0e, 0x80, 0xb6, 0xc6, 0x6d, 0x4b, 0x74, 0x0f, 0xec, 0x84, 0xf1, 0xd0, 0x4f, 0x53, 0x3f, 0x8e, + 0x52, 0x95, 0xcf, 0x70, 0xf2, 0x56, 0x1d, 0xe8, 0xbb, 0x94, 0xf1, 0x6f, 0x4a, 0x25, 0x5c, 0xb5, + 0x70, 0x0f, 0xc1, 0x69, 0x25, 0x7c, 0xc8, 0x68, 0xe0, 0x47, 0xac, 0x2b, 0x2b, 0xb3, 0x33, 0x2b, + 0xf7, 0x3e, 0x5c, 0x6f, 0x32, 0x05, 0xb3, 0x45, 0xfc, 0x0b, 0xeb, 0xe8, 0xa7, 0xd9, 0xd5, 0x4f, + 0xf7, 0x27, 0xb8, 0xd6, 0x95, 0xb3, 0xac, 0x3a, 0xaf, 0x5b, 0x16, 0xe7, 0xce, 0xb9, 0xe8, 0x75, + 0xcf, 0x85, 0xfb, 0x23, 0xbc, 0x36, 0xa5, 0xc1, 0xc3, 0xe6, 0xb8, 0xac, 0x6a, 0xea, 0x65, 0xe0, + 0x97, 0xb0, 0x53, 0x16, 0xa0, 0x2c, 0xf6, 0xc1, 0x53, 0x12, 0x9d, 0xb2, 0x95, 0x5e, 0x1a, 0x1d, + 0xec, 0x5d, 0xba, 0x83, 0xdf, 0xaa, 0x29, 0xcd, 0x02, 0xc9, 0x1c, 0xde, 0x07, 0x9b, 0xe8, 0x58, + 0x14, 0xbf, 0x4c, 0xc5, 0xaf, 0x71, 0x1d, 0xb4, 0x59, 0x0b, 0x5c, 0x35, 0x71, 0x45, 0x75, 0xf6, + 0x31, 0x0b, 0xe3, 0x05, 0x43, 0x63, 0x80, 0x2c, 0x6c, 0x9f, 0x69, 0xd0, 0x2d, 0x5c, 0x91, 0x34, + 0xbd, 0xf6, 0x2e, 0xef, 0xf5, 0x8d, 0x8e, 0xf1, 0xd3, 0xce, 0xdd, 0xdf, 0x37, 0xe0, 0xca, 0x94, + 0x06, 0x07, 0x71, 0x24, 0x58, 0x24, 0xbe, 0x27, 0xc1, 0x19, 0x43, 0x1f, 0x41, 0x5f, 0xd3, 0x48, + 0x55, 0xd5, 0x9e, 0xbc, 0x59, 0xf7, 0x55, 0xe3, 0xe3, 0xcc, 0xc0, 0x99, 0x32, 0xfa, 0x1c, 0xb6, + 0xfc, 0x0a, 0x47, 0x55, 0xcd, 0xed, 0xc9, 0x3b, 0x2b, 0x8c, 0xb5, 0xe2, 0xcc, 0xc0, 0x35, 0x43, + 0x74, 0x08, 0x36, 0x2f, 0x77, 0x9c, 0x5a, 0x3c, 0xf6, 0x64, 0xb7, 0x13, 0xa7, 0xb2, 0x0b, 0x67, + 0x06, 0xae, 0x9a, 0xa1, 0x23, 0xd8, 0xe6, 0xd5, 0x4d, 0xa3, 0xa6, 0xd8, 0x9e, 0xb8, 0xab, 0x70, + 0xb4, 0xe6, 0xcc, 0xc0, 0x75, 0x53, 0x74, 0x02, 0xa3, 0xa4, 0xc1, 0x3e, 0xf5, 0x16, 0xb0, 0x27, + 0xb7, 0x3a, 0xe1, 0x9a, 0x54, 0x9d, 0x19, 0xb8, 0x05, 0x80, 0x0e, 0x60, 0x9b, 0x54, 0x89, 0xa0, + 0xde, 0x18, 0x2f, 0xab, 0xb6, 0x56, 0x91, 0x91, 0xd5, 0x6c, 0x24, 0x08, 0xaf, 0x72, 0xd4, 0x19, + 0x74, 0x81, 0xd4, 0x68, 0xac, 0xd3, 0xab, 0xf2, 0xfa, 0x18, 0x86, 0xbc, 0xb6, 0xa3, 0x9c, 0x4d, + 0x85, 0xf2, 0xee, 0xaa, 0x5a, 0x65, 0xaa, 0x33, 0x03, 0x37, 0x8c, 0xd1, 0x0f, 0x70, 0x8d, 0x74, + 0x70, 0xcd, 0xb1, 0xfe, 0xbf, 0x01, 0x45, 0x9a, 0x9d, 0x08, 0x0f, 0x06, 0xb0, 0xb1, 0x90, 0x14, + 0x75, 0x1f, 0xaa, 0x4f, 0x83, 0x43, 0xf9, 0x11, 0xf1, 0x09, 0x00, 0x29, 0x08, 0x9c, 0xcd, 0xe4, + 0x4e, 0xdd, 0x47, 0x95, 0xdd, 0xb8, 0xa2, 0xed, 0x1e, 0xc1, 0x70, 0x4a, 0x83, 0x93, 0x65, 0x44, + 0x8f, 0x59, 0x9a, 0x92, 0x53, 0x86, 0xee, 0xc2, 0x80, 0x16, 0x50, 0x66, 0x7b, 0xd0, 0xa4, 0x6e, + 0x0d, 0x2e, 0x57, 0x77, 0x1f, 0xab, 0x55, 0xd8, 0xbc, 0x57, 0xe1, 0x79, 0x9e, 0x5e, 0xbb, 0x69, + 0x86, 0xe9, 0x34, 0x4a, 0x50, 0xdc, 0xcf, 0x0c, 0x5c, 0xd1, 0x2e, 0xd3, 0x9d, 0xc1, 0x76, 0x4d, + 0x0f, 0x7d, 0x0c, 0x03, 0x5e, 0x40, 0xca, 0x8c, 0xab, 0xab, 0xad, 0xfd, 0xa1, 0x87, 0x73, 0xed, + 0xdb, 0x5f, 0x02, 0x6a, 0x6f, 0x3e, 0xb4, 0x09, 0xeb, 0x5f, 0xc5, 0x11, 0x1b, 0x19, 0xc8, 0x82, + 0x8d, 0xaf, 0x9f, 0x47, 0x8c, 0x8f, 0x4c, 0xf9, 0x38, 0xf5, 0x42, 0x3f, 0x1a, 0xf5, 0x10, 0x40, + 0xff, 0x11, 0xf7, 0x05, 0xe3, 0xa3, 0x35, 0xf9, 0x2c, 0xe9, 0xc4, 0xf8, 0x68, 0xfd, 0xc1, 0xbd, + 0x3f, 0xcf, 0xc7, 0xe6, 0x8b, 0xf3, 0xb1, 0xf9, 0xcf, 0xf9, 0xd8, 0xfc, 0xf5, 0x62, 0x6c, 0xbc, + 0xb8, 0x18, 0x1b, 0x7f, 0x5f, 0x8c, 0x8d, 0xc7, 0xb7, 0x5e, 0xe9, 0xdb, 0xfa, 0x49, 0x5f, 0xfd, + 0x7c, 0xf8, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1d, 0x52, 0x8e, 0xdb, 0x8b, 0x0b, 0x00, 0x00, } func (m *RawAclRecord) Marshal() (dAtA []byte, err error) { @@ -1905,16 +1957,41 @@ func (m *AclAccountRemove) MarshalToSizedBuffer(dAtA []byte) (int, error) { 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 + if len(m.Identities) > 0 { + for iNdEx := len(m.Identities) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Identities[iNdEx]) + copy(dAtA[i:], m.Identities[iNdEx]) + i = encodeVarintAclrecord(dAtA, i, uint64(len(m.Identities[iNdEx]))) + i-- + dAtA[i] = 0xa + } } return len(dAtA) - i, nil } +func (m *AclAccountRequestRemove) 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 *AclAccountRequestRemove) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AclAccountRequestRemove) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + func (m *AclContentValue) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -2115,6 +2192,27 @@ func (m *AclContentValue_RequestDecline) MarshalToSizedBuffer(dAtA []byte) (int, } return len(dAtA) - i, nil } +func (m *AclContentValue_AccountRequestRemove) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AclContentValue_AccountRequestRemove) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.AccountRequestRemove != nil { + { + size, err := m.AccountRequestRemove.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAclrecord(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x4a + } + return len(dAtA) - i, nil +} func (m *AclData) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -2547,9 +2645,11 @@ func (m *AclAccountRemove) Size() (n int) { } var l int _ = l - l = len(m.Identity) - if l > 0 { - n += 1 + l + sovAclrecord(uint64(l)) + if len(m.Identities) > 0 { + for _, b := range m.Identities { + l = len(b) + n += 1 + l + sovAclrecord(uint64(l)) + } } if len(m.AccountKeys) > 0 { for _, e := range m.AccountKeys { @@ -2560,6 +2660,15 @@ func (m *AclAccountRemove) Size() (n int) { return n } +func (m *AclAccountRequestRemove) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + func (m *AclContentValue) Size() (n int) { if m == nil { return 0 @@ -2668,6 +2777,18 @@ func (m *AclContentValue_RequestDecline) Size() (n int) { } return n } +func (m *AclContentValue_AccountRequestRemove) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.AccountRequestRemove != nil { + l = m.AccountRequestRemove.Size() + n += 1 + l + sovAclrecord(uint64(l)) + } + return n +} func (m *AclData) Size() (n int) { if m == nil { return 0 @@ -4502,7 +4623,7 @@ func (m *AclAccountRemove) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Identity", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Identities", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { @@ -4529,10 +4650,8 @@ func (m *AclAccountRemove) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Identity = append(m.Identity[:0], dAtA[iNdEx:postIndex]...) - if m.Identity == nil { - m.Identity = []byte{} - } + m.Identities = append(m.Identities, make([]byte, postIndex-iNdEx)) + copy(m.Identities[len(m.Identities)-1], dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { @@ -4589,6 +4708,56 @@ func (m *AclAccountRemove) Unmarshal(dAtA []byte) error { } return nil } +func (m *AclAccountRequestRemove) 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: AclAccountRequestRemove: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AclAccountRequestRemove: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + 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 @@ -4898,6 +5067,41 @@ func (m *AclContentValue) Unmarshal(dAtA []byte) error { } m.Value = &AclContentValue_RequestDecline{v} iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AccountRequestRemove", 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 := &AclAccountRequestRemove{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Value = &AclContentValue_AccountRequestRemove{v} + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipAclrecord(dAtA[iNdEx:]) diff --git a/commonspace/object/acl/aclrecordproto/protos/aclrecord.proto b/commonspace/object/acl/aclrecordproto/protos/aclrecord.proto index 5215ae7a..a1f2c49c 100644 --- a/commonspace/object/acl/aclrecordproto/protos/aclrecord.proto +++ b/commonspace/object/acl/aclrecordproto/protos/aclrecord.proto @@ -90,10 +90,14 @@ message AclReadKeyChange { // AclAccountRemove removes an account and changes read key for space message AclAccountRemove { - bytes identity = 1; + repeated bytes identities = 1; repeated AclEncryptedReadKey accountKeys = 2; } +// AclAccountRequestRemove adds a request to remove an account +message AclAccountRequestRemove { +} + // AclContentValue contains possible values for Acl message AclContentValue { oneof value { @@ -105,6 +109,7 @@ message AclContentValue { AclAccountRemove accountRemove = 6; AclReadKeyChange readKeyChange = 7; AclAccountRequestDecline requestDecline = 8; + AclAccountRequestRemove accountRequestRemove = 9; } } diff --git a/commonspace/object/acl/list/aclrecordbuilder.go b/commonspace/object/acl/list/aclrecordbuilder.go index b038a0c5..cae3a2b8 100644 --- a/commonspace/object/acl/list/aclrecordbuilder.go +++ b/commonspace/object/acl/list/aclrecordbuilder.go @@ -34,8 +34,8 @@ type PermissionChangePayload struct { } type AccountRemovePayload struct { - Identity crypto.PubKey - ReadKey crypto.SymKey + Identities []crypto.PubKey + ReadKey crypto.SymKey } type InviteResult struct { @@ -53,6 +53,7 @@ type AclRecordBuilder interface { BuildRequestJoin(payload RequestJoinPayload) (rawRecord *aclrecordproto.RawAclRecord, err error) BuildRequestAccept(payload RequestAcceptPayload) (rawRecord *aclrecordproto.RawAclRecord, err error) BuildRequestDecline(requestRecordId string) (rawRecord *aclrecordproto.RawAclRecord, err error) + BuildRequestRemove() (rawRecord *aclrecordproto.RawAclRecord, err error) BuildPermissionChange(payload PermissionChangePayload) (rawRecord *aclrecordproto.RawAclRecord, err error) BuildReadKeyChange(newKey crypto.SymKey) (rawRecord *aclrecordproto.RawAclRecord, err error) BuildAccountRemove(payload AccountRemovePayload) (rawRecord *aclrecordproto.RawAclRecord, err error) @@ -230,12 +231,13 @@ func (a *aclRecordBuilder) BuildRequestDecline(requestRecordId string) (rawRecor } func (a *aclRecordBuilder) BuildPermissionChange(payload PermissionChangePayload) (rawRecord *aclrecordproto.RawAclRecord, err error) { - if !a.state.Permissions(a.state.pubKey).CanManageAccounts() { + permissions := a.state.Permissions(a.state.pubKey) + if !permissions.CanManageAccounts() || payload.Identity.Equals(a.state.pubKey) { err = ErrInsufficientPermissions return } - if payload.Identity.Equals(a.state.pubKey) || payload.Permissions.IsOwner() { - err = ErrIncorrectPermissions + if payload.Permissions.IsOwner() { + err = ErrIsOwner return } protoIdentity, err := payload.Identity.Marshall() @@ -284,13 +286,19 @@ func (a *aclRecordBuilder) BuildReadKeyChange(newKey crypto.SymKey) (rawRecord * } func (a *aclRecordBuilder) BuildAccountRemove(payload AccountRemovePayload) (rawRecord *aclrecordproto.RawAclRecord, err error) { - permissions := a.state.Permissions(payload.Identity) - if !a.state.Permissions(a.state.pubKey).CanManageAccounts() || permissions.IsOwner() { - err = ErrInsufficientPermissions - return + deletedMap := map[string]struct{}{} + for _, key := range payload.Identities { + permissions := a.state.Permissions(key) + if permissions.IsOwner() { + return nil, ErrInsufficientPermissions + } + if permissions.NoPermissions() { + return nil, ErrNoSuchAccount + } + deletedMap[mapKeyFromPubKey(key)] = struct{}{} } - if permissions.NoPermissions() { - err = ErrNoSuchAccount + if !a.state.Permissions(a.state.pubKey).CanManageAccounts() { + err = ErrInsufficientPermissions return } rawKey, err := payload.ReadKey.Raw() @@ -303,7 +311,7 @@ func (a *aclRecordBuilder) BuildAccountRemove(payload AccountRemovePayload) (raw } var aclReadKeys []*aclrecordproto.AclEncryptedReadKey for _, st := range a.state.userStates { - if st.PubKey.Equals(payload.Identity) { + if _, exists := deletedMap[mapKeyFromPubKey(st.PubKey)]; exists { continue } protoIdentity, err := st.PubKey.Marshall() @@ -319,12 +327,31 @@ func (a *aclRecordBuilder) BuildAccountRemove(payload AccountRemovePayload) (raw EncryptedReadKey: enc, }) } - protoIdentity, err := payload.Identity.Marshall() - if err != nil { + var marshalledIdentities [][]byte + for _, key := range payload.Identities { + protoIdentity, err := key.Marshall() + if err != nil { + return nil, err + } + marshalledIdentities = append(marshalledIdentities, protoIdentity) + } + removeRec := &aclrecordproto.AclAccountRemove{AccountKeys: aclReadKeys, Identities: marshalledIdentities} + content := &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_AccountRemove{AccountRemove: removeRec}} + return a.buildRecord(content) +} + +func (a *aclRecordBuilder) BuildRequestRemove() (rawRecord *aclrecordproto.RawAclRecord, err error) { + permissions := a.state.Permissions(a.state.pubKey) + if permissions.NoPermissions() { + err = ErrNoSuchAccount return } - removeRec := &aclrecordproto.AclAccountRemove{AccountKeys: aclReadKeys, Identity: protoIdentity} - content := &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_AccountRemove{AccountRemove: removeRec}} + if permissions.IsOwner() { + err = ErrIsOwner + return + } + removeRec := &aclrecordproto.AclAccountRequestRemove{} + content := &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_AccountRequestRemove{AccountRequestRemove: removeRec}} return a.buildRecord(content) } diff --git a/commonspace/object/acl/list/aclstate.go b/commonspace/object/acl/list/aclstate.go index 7f4c64d9..44336458 100644 --- a/commonspace/object/acl/list/aclstate.go +++ b/commonspace/object/acl/list/aclstate.go @@ -14,6 +14,7 @@ var log = logger.NewNamedSugared("common.commonspace.acllist") var ( ErrNoSuchAccount = errors.New("no such account") + ErrPendingRequest = errors.New("already exists pending request") ErrUnexpectedContentType = errors.New("unexpected content type") ErrIncorrectIdentity = errors.New("incorrect identity") ErrIncorrectInviteKey = errors.New("incorrect invite key") @@ -22,7 +23,7 @@ var ( ErrNoSuchRequest = errors.New("no such request") ErrNoSuchInvite = errors.New("no such invite") ErrInsufficientPermissions = errors.New("insufficient permissions") - ErrIncorrectPermissions = errors.New("incorrect permissions") + ErrIsOwner = errors.New("can't be made by owner") ErrIncorrectNumberOfAccounts = errors.New("incorrect number of accounts") ErrNoReadKey = errors.New("acl state doesn't have a read key") ErrIncorrectReadKey = errors.New("incorrect read key") @@ -39,15 +40,24 @@ type UserPermissionPair struct { type AclState struct { id string currentReadKeyId string - userReadKeys map[string]crypto.SymKey - userStates map[string]AclUserState - statesAtRecord map[string][]AclUserState - inviteKeys map[string]crypto.PubKey - requestRecords map[string]RequestRecord - key crypto.PrivKey - pubKey crypto.PubKey - keyStore crypto.KeyStorage - totalReadKeys int + // userReadKeys is a map recordId -> read key which tells us about every read key + userReadKeys map[string]crypto.SymKey + // userStates is a map pubKey -> state which defines current user state + userStates map[string]AclUserState + // statesAtRecord is a map recordId -> state which define user state at particular record + // probably this can grow rather large at some point, so we can maybe optimise later to have: + // - map pubKey -> []recordIds (where recordIds is an array where such identity permissions were changed) + statesAtRecord map[string][]AclUserState + // inviteKeys is a map recordId -> invite + inviteKeys map[string]crypto.PubKey + // requestRecords is a map recordId -> RequestRecord + requestRecords map[string]RequestRecord + // pendingRequests is a map pubKey -> RequestType + pendingRequests map[string]RequestType + key crypto.PrivKey + pubKey crypto.PubKey + keyStore crypto.KeyStorage + totalReadKeys int lastRecordId string contentValidator ContentValidator @@ -57,15 +67,16 @@ func newAclStateWithKeys( id string, key crypto.PrivKey) (*AclState, error) { st := &AclState{ - id: id, - key: key, - pubKey: key.GetPublic(), - userReadKeys: make(map[string]crypto.SymKey), - userStates: make(map[string]AclUserState), - statesAtRecord: make(map[string][]AclUserState), - inviteKeys: make(map[string]crypto.PubKey), - requestRecords: make(map[string]RequestRecord), - keyStore: crypto.NewKeyStorage(), + id: id, + key: key, + pubKey: key.GetPublic(), + userReadKeys: make(map[string]crypto.SymKey), + userStates: make(map[string]AclUserState), + statesAtRecord: make(map[string][]AclUserState), + inviteKeys: make(map[string]crypto.PubKey), + requestRecords: make(map[string]RequestRecord), + pendingRequests: make(map[string]RequestType), + keyStore: crypto.NewKeyStorage(), } st.contentValidator = &contentValidator{ keyStore: st.keyStore, @@ -76,13 +87,14 @@ func newAclStateWithKeys( func newAclState(id string) *AclState { st := &AclState{ - id: id, - userReadKeys: make(map[string]crypto.SymKey), - userStates: make(map[string]AclUserState), - statesAtRecord: make(map[string][]AclUserState), - inviteKeys: make(map[string]crypto.PubKey), - requestRecords: make(map[string]RequestRecord), - keyStore: crypto.NewKeyStorage(), + id: id, + userReadKeys: make(map[string]crypto.SymKey), + userStates: make(map[string]AclUserState), + statesAtRecord: make(map[string][]AclUserState), + inviteKeys: make(map[string]crypto.PubKey), + requestRecords: make(map[string]RequestRecord), + pendingRequests: make(map[string]RequestType), + keyStore: crypto.NewKeyStorage(), } st.contentValidator = &contentValidator{ keyStore: st.keyStore, @@ -239,6 +251,8 @@ func (st *AclState) applyChangeContent(ch *aclrecordproto.AclContentValue, recor return st.applyAccountRemove(ch.GetAccountRemove(), recordId, authorIdentity) case ch.GetReadKeyChange() != nil: return st.applyReadKeyChange(ch.GetReadKeyChange(), recordId, authorIdentity) + case ch.GetAccountRequestRemove() != nil: + return st.applyRequestRemove(ch.GetAccountRequestRemove(), recordId, authorIdentity) default: return ErrUnexpectedContentType } @@ -287,6 +301,7 @@ func (st *AclState) applyRequestJoin(ch *aclrecordproto.AclAccountRequestJoin, r if err != nil { return err } + st.pendingRequests[mapKeyFromPubKey(authorIdentity)] = RequestTypeJoin st.requestRecords[recordId] = RequestRecord{ RequestIdentity: authorIdentity, RequestMetadata: ch.Metadata, @@ -309,6 +324,7 @@ func (st *AclState) applyRequestAccept(ch *aclrecordproto.AclAccountRequestAccep Permissions: AclPermissions(ch.Permissions), RequestMetadata: record.RequestMetadata, } + delete(st.pendingRequests, mapKeyFromPubKey(st.requestRecords[ch.RequestRecordId].RequestIdentity)) if !st.pubKey.Equals(acceptIdentity) { return nil } @@ -331,15 +347,34 @@ func (st *AclState) applyRequestDecline(ch *aclrecordproto.AclAccountRequestDecl if err != nil { return err } + delete(st.pendingRequests, mapKeyFromPubKey(st.requestRecords[ch.RequestRecordId].RequestIdentity)) delete(st.requestRecords, ch.RequestRecordId) return nil } -func (st *AclState) applyAccountRemove(ch *aclrecordproto.AclAccountRemove, recordId string, authorIdentity crypto.PubKey) error { - err := st.contentValidator.ValidateRemove(ch, authorIdentity) +func (st *AclState) applyRequestRemove(ch *aclrecordproto.AclAccountRequestRemove, recordId string, authorIdentity crypto.PubKey) error { + err := st.contentValidator.ValidateRequestRemove(ch, authorIdentity) if err != nil { return err } + st.pendingRequests[mapKeyFromPubKey(authorIdentity)] = RequestTypeRemove + return nil +} + +func (st *AclState) applyAccountRemove(ch *aclrecordproto.AclAccountRemove, recordId string, authorIdentity crypto.PubKey) error { + err := st.contentValidator.ValidateAccountRemove(ch, authorIdentity) + if err != nil { + return err + } + for _, rawIdentity := range ch.Identities { + identity, err := st.keyStore.PubKeyFromProto(rawIdentity) + if err != nil { + return err + } + idKey := mapKeyFromPubKey(identity) + delete(st.userStates, idKey) + delete(st.pendingRequests, idKey) + } return st.updateReadKey(ch.AccountKeys, recordId) } diff --git a/commonspace/object/acl/list/list.go b/commonspace/object/acl/list/list.go index cfcd3c3f..5ae2af33 100644 --- a/commonspace/object/acl/list/list.go +++ b/commonspace/object/acl/list/list.go @@ -23,6 +23,17 @@ type RWLocker interface { RUnlock() } +type AcceptorVerifier interface { + VerifyAcceptor(rec *aclrecordproto.RawAclRecord) (err error) +} + +type NoOpAcceptorVerifier struct { +} + +func (n NoOpAcceptorVerifier) VerifyAcceptor(rec *aclrecordproto.RawAclRecord) (err error) { + return nil +} + type AclList interface { RWLocker Id() string @@ -32,6 +43,7 @@ type AclList interface { IsAfter(first string, second string) (bool, error) Head() *AclRecord Get(id string) (*AclRecord, error) + GetIndex(idx int) (*AclRecord, error) Iterate(iterFunc IterFunc) IterateFrom(startId string, iterFunc IterFunc) @@ -59,18 +71,43 @@ type aclList struct { sync.RWMutex } -func BuildAclListWithIdentity(acc *accountdata.AccountKeys, storage liststorage.ListStorage) (AclList, error) { - builder := newAclStateBuilderWithIdentity(acc) - keyStorage := crypto.NewKeyStorage() - return build(storage.Id(), keyStorage, builder, NewAclRecordBuilder(storage.Id(), keyStorage, acc), storage) +type internalDeps struct { + storage liststorage.ListStorage + keyStorage crypto.KeyStorage + stateBuilder *aclStateBuilder + recordBuilder AclRecordBuilder + acceptorVerifier AcceptorVerifier } -func BuildAclList(storage liststorage.ListStorage) (AclList, error) { +func BuildAclListWithIdentity(acc *accountdata.AccountKeys, storage liststorage.ListStorage, verifier AcceptorVerifier) (AclList, error) { keyStorage := crypto.NewKeyStorage() - return build(storage.Id(), keyStorage, newAclStateBuilder(), NewAclRecordBuilder(storage.Id(), crypto.NewKeyStorage(), nil), storage) + deps := internalDeps{ + storage: storage, + keyStorage: keyStorage, + stateBuilder: newAclStateBuilderWithIdentity(acc), + recordBuilder: NewAclRecordBuilder(storage.Id(), keyStorage, acc), + } + return build(deps) } -func build(id string, keyStorage crypto.KeyStorage, stateBuilder *aclStateBuilder, recBuilder AclRecordBuilder, storage liststorage.ListStorage) (list AclList, err error) { +func BuildAclList(storage liststorage.ListStorage, verifier AcceptorVerifier) (AclList, error) { + keyStorage := crypto.NewKeyStorage() + deps := internalDeps{ + storage: storage, + keyStorage: keyStorage, + stateBuilder: newAclStateBuilder(), + recordBuilder: NewAclRecordBuilder(storage.Id(), keyStorage, nil), + } + return build(deps) +} + +func build(deps internalDeps) (list AclList, err error) { + var ( + storage = deps.storage + id = deps.storage.Id() + recBuilder = deps.recordBuilder + stateBuilder = deps.stateBuilder + ) head, err := storage.Head() if err != nil { return @@ -215,11 +252,19 @@ func (a *aclList) Head() *AclRecord { func (a *aclList) Get(id string) (*AclRecord, error) { recIdx, ok := a.indexes[id] if !ok { - return nil, fmt.Errorf("no such record") + return nil, ErrNoSuchRecord } return a.records[recIdx], nil } +func (a *aclList) GetIndex(idx int) (*AclRecord, error) { + // TODO: when we add snapshots we will have to monitor record num in snapshots + if idx < 0 || idx >= len(a.records) { + return nil, ErrNoSuchRecord + } + return a.records[idx], nil +} + func (a *aclList) Iterate(iterFunc IterFunc) { for _, rec := range a.records { if !iterFunc(rec) { diff --git a/commonspace/object/acl/list/listutils.go b/commonspace/object/acl/list/listutils.go index 64e43176..9f7d7331 100644 --- a/commonspace/object/acl/list/listutils.go +++ b/commonspace/object/acl/list/listutils.go @@ -27,5 +27,5 @@ func NewTestDerivedAcl(spaceId string, keys *accountdata.AccountKeys) (AclList, if err != nil { return nil, err } - return BuildAclListWithIdentity(keys, st) + return BuildAclListWithIdentity(keys, st, NoOpAcceptorVerifier{}) } diff --git a/commonspace/object/acl/list/models.go b/commonspace/object/acl/list/models.go index 90db6e91..27238202 100644 --- a/commonspace/object/acl/list/models.go +++ b/commonspace/object/acl/list/models.go @@ -26,6 +26,13 @@ type AclUserState struct { RequestMetadata []byte } +type RequestType int + +const ( + RequestTypeRemove RequestType = iota + RequestTypeJoin +) + type AclPermissions aclrecordproto.AclUserPermissions func (p AclPermissions) NoPermissions() bool { diff --git a/commonspace/object/acl/list/validator.go b/commonspace/object/acl/list/validator.go index 75e0e251..9b667fda 100644 --- a/commonspace/object/acl/list/validator.go +++ b/commonspace/object/acl/list/validator.go @@ -13,7 +13,8 @@ type ContentValidator interface { ValidateRequestJoin(ch *aclrecordproto.AclAccountRequestJoin, authorIdentity crypto.PubKey) (err error) ValidateRequestAccept(ch *aclrecordproto.AclAccountRequestAccept, authorIdentity crypto.PubKey) (err error) ValidateRequestDecline(ch *aclrecordproto.AclAccountRequestDecline, authorIdentity crypto.PubKey) (err error) - ValidateRemove(ch *aclrecordproto.AclAccountRemove, authorIdentity crypto.PubKey) (err error) + ValidateAccountRemove(ch *aclrecordproto.AclAccountRemove, authorIdentity crypto.PubKey) (err error) + ValidateRequestRemove(ch *aclrecordproto.AclAccountRequestRemove, authorIdentity crypto.PubKey) (err error) ValidateReadKeyChange(ch *aclrecordproto.AclReadKeyChange, authorIdentity crypto.PubKey) (err error) } @@ -51,7 +52,9 @@ func (c *contentValidator) validateAclRecordContent(ch *aclrecordproto.AclConten case ch.GetRequestDecline() != nil: return c.ValidateRequestDecline(ch.GetRequestDecline(), authorIdentity) case ch.GetAccountRemove() != nil: - return c.ValidateRemove(ch.GetAccountRemove(), authorIdentity) + return c.ValidateAccountRemove(ch.GetAccountRemove(), authorIdentity) + case ch.GetAccountRequestRemove() != nil: + return c.ValidateRequestRemove(ch.GetAccountRequestRemove(), authorIdentity) case ch.GetReadKeyChange() != nil: return c.ValidateReadKeyChange(ch.GetReadKeyChange(), authorIdentity) default: @@ -102,6 +105,9 @@ func (c *contentValidator) ValidateRequestJoin(ch *aclrecordproto.AclAccountRequ if err != nil { return } + if _, exists := c.aclState.pendingRequests[mapKeyFromPubKey(inviteIdentity)]; exists { + return ErrPendingRequest + } if !authorIdentity.Equals(inviteIdentity) { return ErrIncorrectIdentity } @@ -151,21 +157,36 @@ func (c *contentValidator) ValidateRequestDecline(ch *aclrecordproto.AclAccountR return } -func (c *contentValidator) ValidateRemove(ch *aclrecordproto.AclAccountRemove, authorIdentity crypto.PubKey) (err error) { +func (c *contentValidator) ValidateAccountRemove(ch *aclrecordproto.AclAccountRemove, authorIdentity crypto.PubKey) (err error) { if !c.aclState.Permissions(authorIdentity).CanManageAccounts() { return ErrInsufficientPermissions } - identity, err := c.keyStore.PubKeyFromProto(ch.Identity) - if err != nil { - return - } - _, exists := c.aclState.userStates[mapKeyFromPubKey(identity)] - if !exists { - return ErrNoSuchAccount + for _, rawIdentity := range ch.Identities { + identity, err := c.keyStore.PubKeyFromProto(rawIdentity) + if err != nil { + return err + } + permissions := c.aclState.Permissions(identity) + if permissions.NoPermissions() { + return ErrNoSuchAccount + } + if permissions.IsOwner() { + return ErrInsufficientPermissions + } } return c.validateAccountReadKeys(ch.AccountKeys) } +func (c *contentValidator) ValidateRequestRemove(ch *aclrecordproto.AclAccountRequestRemove, authorIdentity crypto.PubKey) (err error) { + if c.aclState.Permissions(authorIdentity).NoPermissions() { + return ErrInsufficientPermissions + } + if _, exists := c.aclState.pendingRequests[mapKeyFromPubKey(authorIdentity)]; exists { + return ErrPendingRequest + } + return +} + func (c *contentValidator) ValidateReadKeyChange(ch *aclrecordproto.AclReadKeyChange, authorIdentity crypto.PubKey) (err error) { return c.validateAccountReadKeys(ch.AccountKeys) } diff --git a/commonspace/object/acl/syncacl/syncacl.go b/commonspace/object/acl/syncacl/syncacl.go index 426b16cd..360e0646 100644 --- a/commonspace/object/acl/syncacl/syncacl.go +++ b/commonspace/object/acl/syncacl/syncacl.go @@ -2,6 +2,7 @@ package syncacl import ( "context" + "github.com/anyproto/any-sync/accountservice" "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/commonspace/object/acl/list" @@ -34,7 +35,7 @@ func (s *SyncAcl) Init(a *app.App) (err error) { return err } acc := a.MustComponent(accountservice.CName).(accountservice.Service) - s.AclList, err = list.BuildAclListWithIdentity(acc.Account(), aclStorage) + s.AclList, err = list.BuildAclListWithIdentity(acc.Account(), aclStorage, list.NoOpAcceptorVerifier{}) return err } diff --git a/commonspace/object/tree/exporter/treeimport.go b/commonspace/object/tree/exporter/treeimport.go index 2e83ab11..25ffa499 100644 --- a/commonspace/object/tree/exporter/treeimport.go +++ b/commonspace/object/tree/exporter/treeimport.go @@ -15,7 +15,7 @@ type TreeImportParams struct { } func ImportHistoryTree(params TreeImportParams) (tree objecttree.ReadableObjectTree, err error) { - aclList, err := list.BuildAclList(params.ListStorage) + aclList, err := list.BuildAclList(params.ListStorage, list.NoOpAcceptorVerifier{}) if err != nil { return } diff --git a/commonspace/payloads.go b/commonspace/payloads.go index 8d1c334c..6cc572be 100644 --- a/commonspace/payloads.go +++ b/commonspace/payloads.go @@ -2,6 +2,12 @@ package commonspace import ( "errors" + "hash/fnv" + "math/rand" + "strconv" + "strings" + "time" + "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" "github.com/anyproto/any-sync/commonspace/object/acl/list" "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" @@ -11,11 +17,6 @@ import ( "github.com/anyproto/any-sync/util/cidutil" "github.com/anyproto/any-sync/util/crypto" "github.com/gogo/protobuf/proto" - "hash/fnv" - "math/rand" - "strconv" - "strings" - "time" ) const ( @@ -71,7 +72,7 @@ func storagePayloadForSpaceCreate(payload SpaceCreatePayload) (storagePayload sp // building acl root keyStorage := crypto.NewKeyStorage() - aclBuilder := list.NewAclRecordBuilder("", keyStorage) + aclBuilder := list.NewAclRecordBuilder("", keyStorage, nil) aclRoot, err := aclBuilder.BuildRoot(list.RootContent{ PrivKey: payload.SigningKey, MasterKey: payload.MasterKey, @@ -158,7 +159,7 @@ func storagePayloadForSpaceDerive(payload SpaceDerivePayload) (storagePayload sp // building acl root keyStorage := crypto.NewKeyStorage() - aclBuilder := list.NewAclRecordBuilder("", keyStorage) + aclBuilder := list.NewAclRecordBuilder("", keyStorage, nil) aclRoot, err := aclBuilder.BuildRoot(list.RootContent{ PrivKey: payload.SigningKey, MasterKey: payload.MasterKey, diff --git a/util/crypto/ed25519_test.go b/util/crypto/ed25519_test.go index 92565723..6b571699 100644 --- a/util/crypto/ed25519_test.go +++ b/util/crypto/ed25519_test.go @@ -2,8 +2,9 @@ package crypto import ( "crypto/rand" - "github.com/stretchr/testify/require" "testing" + + "github.com/stretchr/testify/require" ) func Test_EncryptDecrypt(t *testing.T) { diff --git a/util/strkey/strkey_test.go b/util/strkey/strkey_test.go index 07fc2a64..d33f49d8 100644 --- a/util/strkey/strkey_test.go +++ b/util/strkey/strkey_test.go @@ -1,9 +1,10 @@ package strkey import ( + "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "testing" ) func TestDecode(t *testing.T) { From a092f7b4a16b2ea256d5f146fe66c5e3ff6a7ee7 Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Tue, 27 Jun 2023 22:09:52 +0200 Subject: [PATCH 087/123] consensus client --- Makefile | 1 + consensus/consensusclient/client.go | 240 ++ consensus/consensusclient/client_test.go | 236 ++ .../mock_consensusclient.go | 150 ++ consensus/consensusclient/stream.go | 70 + consensus/consensusproto/consensus.pb.go | 1957 +++++++++++++++++ consensus/consensusproto/consensus_drpc.pb.go | 232 ++ .../consensusproto/consensuserr/errors.go | 16 + .../consensusproto/protos/consensus.proto | 60 + 9 files changed, 2962 insertions(+) create mode 100644 consensus/consensusclient/client.go create mode 100644 consensus/consensusclient/client_test.go create mode 100644 consensus/consensusclient/mock_consensusclient/mock_consensusclient.go create mode 100644 consensus/consensusclient/stream.go create mode 100644 consensus/consensusproto/consensus.pb.go create mode 100644 consensus/consensusproto/consensus_drpc.pb.go create mode 100644 consensus/consensusproto/consensuserr/errors.go create mode 100644 consensus/consensusproto/protos/consensus.proto diff --git a/Makefile b/Makefile index aa0fa75f..003fbbf7 100644 --- a/Makefile +++ b/Makefile @@ -20,6 +20,7 @@ proto: protoc --gogofaster_out=$(PKGMAP):. --go-drpc_out=protolib=github.com/gogo/protobuf:. net/streampool/testservice/protos/*.proto protoc --gogofaster_out=:. net/secureservice/handshake/handshakeproto/protos/*.proto protoc --gogofaster_out=$(PKGMAP):. --go-drpc_out=protolib=github.com/gogo/protobuf:. coordinator/coordinatorproto/protos/*.proto + protoc --gogofaster_out=:. --go-drpc_out=protolib=github.com/gogo/protobuf:. consensus/consensusproto/protos/*.proto deps: go mod download diff --git a/consensus/consensusclient/client.go b/consensus/consensusclient/client.go new file mode 100644 index 00000000..cd3c411a --- /dev/null +++ b/consensus/consensusclient/client.go @@ -0,0 +1,240 @@ +//go:generate mockgen -destination mock_consensusclient/mock_consensusclient.go github.com/anyproto/any-sync/consensus/consensusclient Service +package consensusclient + +import ( + "context" + "errors" + "github.com/anyproto/any-sync/app" + "github.com/anyproto/any-sync/app/logger" + "github.com/anyproto/any-sync/consensus/consensusproto" + "github.com/anyproto/any-sync/net/pool" + "github.com/anyproto/any-sync/net/rpc/rpcerr" + "github.com/anyproto/any-sync/nodeconf" + "go.uber.org/zap" + "sync" + "time" +) + +const CName = "consensus.consensusclient" + +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) doClient(ctx context.Context, fn func(cl consensusproto.DRPCConsensusClient) error) error { + peer, err := s.pool.GetOneOf(ctx, s.nodeconf.ConsensusPeers()) + if err != nil { + return err + } + dc, err := peer.AcquireDrpcConn(ctx) + if err != nil { + return err + } + defer peer.ReleaseDrpcConn(dc) + return fn(consensusproto.NewDRPCConsensusClient(dc)) +} + +func (s *service) AddLog(ctx context.Context, clog *consensusproto.Log) (err error) { + return s.doClient(ctx, func(cl consensusproto.DRPCConsensusClient) error { + if _, err = cl.LogAdd(ctx, &consensusproto.LogAddRequest{ + Log: clog, + }); err != nil { + return rpcerr.Unwrap(err) + } + return nil + }) +} + +func (s *service) AddRecord(ctx context.Context, logId []byte, clog *consensusproto.Record) (err error) { + return s.doClient(ctx, func(cl consensusproto.DRPCConsensusClient) error { + if _, err = cl.RecordAdd(ctx, &consensusproto.RecordAddRequest{ + LogId: logId, + Record: clog, + }); err != nil { + return rpcerr.Unwrap(err) + } + return nil + }) +} + +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) { + pr, err := s.pool.GetOneOf(ctx, s.nodeconf.ConsensusPeers()) + if err != nil { + return nil, err + } + dc, err := pr.AcquireDrpcConn(ctx) + if err != nil { + return nil, err + } + rpcStream, err := consensusproto.NewDRPCConsensusClient(dc).LogWatch(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..a212a635 --- /dev/null +++ b/consensus/consensusclient/client_test.go @@ -0,0 +1,236 @@ +package consensusclient + +import ( + "context" + "fmt" + "github.com/anyproto/any-sync/app" + "github.com/anyproto/any-sync/consensus/consensusproto" + "github.com/anyproto/any-sync/consensus/consensusproto/consensuserr" + "github.com/anyproto/any-sync/net/pool" + "github.com/anyproto/any-sync/net/rpc/rpctest" + "github.com/anyproto/any-sync/nodeconf" + "github.com/anyproto/any-sync/nodeconf/mock_nodeconf" + "github.com/anyproto/any-sync/testutil/accounttest" + "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.LogWatchEvent{ + 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_LogWatchStream), + releaseStream: make(chan error), + }, + } + fx.nodeconf = mock_nodeconf.NewMockService(fx.ctrl) + fx.nodeconf.EXPECT().Name().Return(nodeconf.CName).AnyTimes() + fx.nodeconf.EXPECT().Init(gomock.Any()).AnyTimes() + fx.nodeconf.EXPECT().Run(gomock.Any()).AnyTimes() + fx.nodeconf.EXPECT().Close(gomock.Any()).AnyTimes() + fx.nodeconf.EXPECT().ConsensusPeers().Return([]string{"c1", "c2", "c3"}).AnyTimes() + + fx.drpcTS = rpctest.NewTestServer() + require.NoError(t, consensusproto.DRPCRegisterConsensus(fx.drpcTS.Mux, fx.testServer)) + fx.a.Register(fx.Service). + Register(&accounttest.AccountTestService{}). + Register(fx.nodeconf). + Register(rpctest.NewTestPool().WithServer(fx.drpcTS)) + + return fx +} + +type fixture struct { + Service + a *app.App + ctrl *gomock.Controller + testServer *testServer + drpcTS *rpctest.TestServer + nodeconf *mock_nodeconf.MockService +} + +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_LogWatchStream + addLog func(ctx context.Context, req *consensusproto.LogAddRequest) error + addRecord func(ctx context.Context, req *consensusproto.RecordAddRequest) error + releaseStream chan error + watchErrOnce bool +} + +func (t *testServer) LogAdd(ctx context.Context, req *consensusproto.LogAddRequest) (*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) RecordAdd(ctx context.Context, req *consensusproto.RecordAddRequest) (*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) LogWatch(stream consensusproto.DRPCConsensus_LogWatchStream) 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_LogWatchStream { + 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..d103635a --- /dev/null +++ b/consensus/consensusclient/mock_consensusclient/mock_consensusclient.go @@ -0,0 +1,150 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/anyproto/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/anyproto/any-sync/app" + consensusclient "github.com/anyproto/any-sync-consensusnode/consensusclient" + consensusproto "github.com/anyproto/any-sync-consensusnode/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..679dcd74 --- /dev/null +++ b/consensus/consensusclient/stream.go @@ -0,0 +1,70 @@ +package consensusclient + +import ( + "context" + "github.com/anyproto/any-sync/consensus/consensusproto" + "github.com/cheggaaa/mb/v3" + "sync" +) + +func runStream(rpcStream consensusproto.DRPCConsensus_LogWatchClient) *stream { + st := &stream{ + rpcStream: rpcStream, + mb: mb.New[*consensusproto.LogWatchEvent](100), + } + go st.readStream() + return st +} + +type stream struct { + rpcStream consensusproto.DRPCConsensus_LogWatchClient + mb *mb.MB[*consensusproto.LogWatchEvent] + mu sync.Mutex + err error +} + +func (s *stream) WatchIds(logIds [][]byte) (err error) { + return s.rpcStream.Send(&consensusproto.LogWatchRequest{ + WatchIds: logIds, + }) +} + +func (s *stream) UnwatchIds(logIds [][]byte) (err error) { + return s.rpcStream.Send(&consensusproto.LogWatchRequest{ + UnwatchIds: logIds, + }) +} + +func (s *stream) WaitLogs() []*consensusproto.LogWatchEvent { + events, _ := s.mb.Wait(context.TODO()) + return events +} + +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(s.rpcStream.Context(), 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..9cb94880 --- /dev/null +++ b/consensus/consensusproto/consensus.pb.go @@ -0,0 +1,1957 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: consensus/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_b8d7f1c16b400059, []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_b8d7f1c16b400059, []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_b8d7f1c16b400059, []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_b8d7f1c16b400059, []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 LogAddRequest struct { + Log *Log `protobuf:"bytes,1,opt,name=log,proto3" json:"log,omitempty"` +} + +func (m *LogAddRequest) Reset() { *m = LogAddRequest{} } +func (m *LogAddRequest) String() string { return proto.CompactTextString(m) } +func (*LogAddRequest) ProtoMessage() {} +func (*LogAddRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_b8d7f1c16b400059, []int{3} +} +func (m *LogAddRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LogAddRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_LogAddRequest.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 *LogAddRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_LogAddRequest.Merge(m, src) +} +func (m *LogAddRequest) XXX_Size() int { + return m.Size() +} +func (m *LogAddRequest) XXX_DiscardUnknown() { + xxx_messageInfo_LogAddRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_LogAddRequest proto.InternalMessageInfo + +func (m *LogAddRequest) GetLog() *Log { + if m != nil { + return m.Log + } + return nil +} + +type RecordAddRequest 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 *RecordAddRequest) Reset() { *m = RecordAddRequest{} } +func (m *RecordAddRequest) String() string { return proto.CompactTextString(m) } +func (*RecordAddRequest) ProtoMessage() {} +func (*RecordAddRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_b8d7f1c16b400059, []int{4} +} +func (m *RecordAddRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RecordAddRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RecordAddRequest.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 *RecordAddRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_RecordAddRequest.Merge(m, src) +} +func (m *RecordAddRequest) XXX_Size() int { + return m.Size() +} +func (m *RecordAddRequest) XXX_DiscardUnknown() { + xxx_messageInfo_RecordAddRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_RecordAddRequest proto.InternalMessageInfo + +func (m *RecordAddRequest) GetLogId() []byte { + if m != nil { + return m.LogId + } + return nil +} + +func (m *RecordAddRequest) GetRecord() *Record { + if m != nil { + return m.Record + } + return nil +} + +type LogWatchRequest 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 *LogWatchRequest) Reset() { *m = LogWatchRequest{} } +func (m *LogWatchRequest) String() string { return proto.CompactTextString(m) } +func (*LogWatchRequest) ProtoMessage() {} +func (*LogWatchRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_b8d7f1c16b400059, []int{5} +} +func (m *LogWatchRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LogWatchRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_LogWatchRequest.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 *LogWatchRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_LogWatchRequest.Merge(m, src) +} +func (m *LogWatchRequest) XXX_Size() int { + return m.Size() +} +func (m *LogWatchRequest) XXX_DiscardUnknown() { + xxx_messageInfo_LogWatchRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_LogWatchRequest proto.InternalMessageInfo + +func (m *LogWatchRequest) GetWatchIds() [][]byte { + if m != nil { + return m.WatchIds + } + return nil +} + +func (m *LogWatchRequest) GetUnwatchIds() [][]byte { + if m != nil { + return m.UnwatchIds + } + return nil +} + +type LogWatchEvent 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 *LogWatchEvent) Reset() { *m = LogWatchEvent{} } +func (m *LogWatchEvent) String() string { return proto.CompactTextString(m) } +func (*LogWatchEvent) ProtoMessage() {} +func (*LogWatchEvent) Descriptor() ([]byte, []int) { + return fileDescriptor_b8d7f1c16b400059, []int{6} +} +func (m *LogWatchEvent) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LogWatchEvent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_LogWatchEvent.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 *LogWatchEvent) XXX_Merge(src proto.Message) { + xxx_messageInfo_LogWatchEvent.Merge(m, src) +} +func (m *LogWatchEvent) XXX_Size() int { + return m.Size() +} +func (m *LogWatchEvent) XXX_DiscardUnknown() { + xxx_messageInfo_LogWatchEvent.DiscardUnknown(m) +} + +var xxx_messageInfo_LogWatchEvent proto.InternalMessageInfo + +func (m *LogWatchEvent) GetLogId() []byte { + if m != nil { + return m.LogId + } + return nil +} + +func (m *LogWatchEvent) GetRecords() []*Record { + if m != nil { + return m.Records + } + return nil +} + +func (m *LogWatchEvent) GetError() *Err { + if m != nil { + return m.Error + } + return nil +} + +type Err struct { + Error ErrCodes `protobuf:"varint,1,opt,name=error,proto3,enum=consensusProto.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_b8d7f1c16b400059, []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("consensusProto.ErrCodes", ErrCodes_name, ErrCodes_value) + proto.RegisterType((*Log)(nil), "consensusProto.Log") + proto.RegisterType((*Record)(nil), "consensusProto.Record") + proto.RegisterType((*Ok)(nil), "consensusProto.Ok") + proto.RegisterType((*LogAddRequest)(nil), "consensusProto.LogAddRequest") + proto.RegisterType((*RecordAddRequest)(nil), "consensusProto.RecordAddRequest") + proto.RegisterType((*LogWatchRequest)(nil), "consensusProto.LogWatchRequest") + proto.RegisterType((*LogWatchEvent)(nil), "consensusProto.LogWatchEvent") + proto.RegisterType((*Err)(nil), "consensusProto.Err") +} + +func init() { + proto.RegisterFile("consensus/consensusproto/protos/consensus.proto", fileDescriptor_b8d7f1c16b400059) +} + +var fileDescriptor_b8d7f1c16b400059 = []byte{ + // 511 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x53, 0xc1, 0x6e, 0xd3, 0x40, + 0x10, 0xcd, 0xda, 0x6d, 0x9a, 0x4c, 0xda, 0xd4, 0x1a, 0x50, 0x65, 0x45, 0xaa, 0xb1, 0x2c, 0x21, + 0x05, 0x0e, 0x69, 0x65, 0x04, 0x17, 0x4e, 0x25, 0x32, 0x28, 0x92, 0x69, 0x90, 0xa5, 0x0a, 0xc4, + 0x89, 0xe0, 0xdd, 0x18, 0xab, 0x96, 0x37, 0xec, 0x3a, 0x25, 0x5c, 0xf9, 0x02, 0x3e, 0x84, 0x0f, + 0xe1, 0xd8, 0x23, 0x12, 0x17, 0x94, 0xfc, 0x08, 0xf2, 0x3a, 0x4e, 0x4d, 0x71, 0x84, 0xb8, 0xd8, + 0x7e, 0xef, 0xcd, 0xcc, 0xbe, 0x9d, 0x19, 0xc3, 0x49, 0xc8, 0x53, 0xc9, 0x52, 0x39, 0x97, 0x37, + 0x5f, 0x33, 0xc1, 0x33, 0x7e, 0xa2, 0x9e, 0x15, 0x76, 0xa0, 0x08, 0xec, 0x6e, 0x88, 0x57, 0x39, + 0x76, 0x5e, 0x80, 0xee, 0xf3, 0x08, 0xbb, 0xa0, 0xc5, 0xd4, 0x24, 0x36, 0xe9, 0xef, 0x07, 0x5a, + 0x4c, 0xf1, 0x14, 0xf6, 0x04, 0x0b, 0xb9, 0xa0, 0xd2, 0xd4, 0x6c, 0xbd, 0xdf, 0x71, 0x8f, 0x06, + 0x7f, 0x26, 0x0e, 0x02, 0x25, 0x07, 0x65, 0x98, 0x93, 0x40, 0xb3, 0xa0, 0xfe, 0xaa, 0x75, 0x04, + 0xcd, 0x99, 0x60, 0x57, 0x23, 0x6a, 0x6a, 0x8a, 0x5b, 0x23, 0x34, 0x61, 0x6f, 0x36, 0xf9, 0x9c, + 0xf0, 0x09, 0x35, 0x75, 0x25, 0x94, 0x10, 0x6d, 0xe8, 0x84, 0x82, 0x4d, 0x32, 0x46, 0x2f, 0xd2, + 0x78, 0x61, 0xee, 0xd8, 0xa4, 0xbf, 0x13, 0x54, 0x29, 0x67, 0x07, 0xb4, 0xf1, 0xa5, 0xf3, 0x04, + 0x0e, 0x7c, 0x1e, 0x9d, 0x51, 0x1a, 0xb0, 0x8f, 0x73, 0x26, 0x33, 0xbc, 0x0f, 0x7a, 0xc2, 0x23, + 0x75, 0x76, 0xc7, 0xbd, 0x73, 0xdb, 0xb2, 0xcf, 0xa3, 0x20, 0xd7, 0x9d, 0x37, 0x60, 0x14, 0x5e, + 0x2b, 0xa9, 0x77, 0x61, 0x37, 0xe1, 0xd1, 0xa8, 0x34, 0x5e, 0x00, 0x1c, 0x40, 0xb3, 0xb8, 0xa0, + 0xf2, 0xbe, 0xbd, 0x0d, 0xeb, 0x28, 0xe7, 0x25, 0x1c, 0xfa, 0x3c, 0x7a, 0x3d, 0xc9, 0xc2, 0x0f, + 0x65, 0xe1, 0x1e, 0xb4, 0x3e, 0xe5, 0x78, 0x44, 0xa5, 0x49, 0x6c, 0xbd, 0xbf, 0x1f, 0x6c, 0x30, + 0x5a, 0x00, 0xf3, 0x74, 0xa3, 0x6a, 0x4a, 0xad, 0x30, 0xce, 0x17, 0xa2, 0x6e, 0xa8, 0xea, 0x79, + 0x57, 0x2c, 0xdd, 0x66, 0xf3, 0xbf, 0xc7, 0x85, 0x0f, 0x60, 0x97, 0x09, 0xc1, 0x85, 0x6a, 0x7d, + 0x4d, 0xaf, 0x3c, 0x21, 0x82, 0x22, 0xc2, 0x79, 0x0c, 0xba, 0x27, 0x04, 0x0e, 0xca, 0x8c, 0xfc, + 0xe4, 0xae, 0x6b, 0xd6, 0x64, 0x0c, 0x39, 0x65, 0x72, 0x9d, 0xf6, 0xf0, 0x1d, 0xb4, 0x4a, 0x0a, + 0xbb, 0x00, 0x17, 0x29, 0x5b, 0xcc, 0x58, 0x98, 0x31, 0x6a, 0x34, 0xf0, 0x00, 0xda, 0x3e, 0x8f, + 0xbc, 0x45, 0x2c, 0x33, 0x69, 0x10, 0x3c, 0x84, 0x8e, 0xcf, 0xa3, 0x73, 0x9e, 0x3d, 0xe7, 0xf3, + 0x94, 0x1a, 0x1a, 0x22, 0x74, 0x0b, 0xc3, 0x43, 0x9e, 0x4e, 0x93, 0x38, 0xcc, 0x0c, 0x1d, 0x0d, + 0xe8, 0x78, 0x79, 0xe1, 0xf1, 0x74, 0x2a, 0x59, 0x66, 0x7c, 0xd3, 0xdc, 0x9f, 0x04, 0xda, 0xc3, + 0xd2, 0x04, 0x3e, 0x85, 0x66, 0xb1, 0x0c, 0x78, 0x5c, 0x33, 0xf8, 0x9b, 0x49, 0xf7, 0xf0, 0xb6, + 0x3c, 0xbe, 0xc4, 0x33, 0x68, 0x6f, 0x36, 0x02, 0xed, 0xfa, 0xe6, 0xfd, 0xa3, 0xc4, 0x39, 0xb4, + 0xca, 0x51, 0xe1, 0xbd, 0x1a, 0x07, 0xd5, 0xa5, 0xe8, 0x1d, 0x6f, 0x0b, 0x50, 0x53, 0xee, 0x93, + 0x53, 0xf2, 0xcc, 0xfd, 0xbe, 0xb4, 0xc8, 0xf5, 0xd2, 0x22, 0xbf, 0x96, 0x16, 0xf9, 0xba, 0xb2, + 0x1a, 0xd7, 0x2b, 0xab, 0xf1, 0x63, 0x65, 0x35, 0xde, 0x9a, 0xdb, 0x7e, 0xfa, 0xf7, 0x4d, 0xf5, + 0x7a, 0xf4, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x8c, 0x81, 0x82, 0x9d, 0x17, 0x04, 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 *LogAddRequest) 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 *LogAddRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *LogAddRequest) 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 *RecordAddRequest) 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 *RecordAddRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RecordAddRequest) 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 *LogWatchRequest) 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 *LogWatchRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *LogWatchRequest) 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 *LogWatchEvent) 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 *LogWatchEvent) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *LogWatchEvent) 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 *LogAddRequest) 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 *RecordAddRequest) 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 *LogWatchRequest) 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 *LogWatchEvent) 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 *LogAddRequest) 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: LogAddRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LogAddRequest: 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 *RecordAddRequest) 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: RecordAddRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RecordAddRequest: 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 *LogWatchRequest) 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: LogWatchRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LogWatchRequest: 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 *LogWatchEvent) 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: LogWatchEvent: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LogWatchEvent: 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..be8927c6 --- /dev/null +++ b/consensus/consensusproto/consensus_drpc.pb.go @@ -0,0 +1,232 @@ +// Code generated by protoc-gen-go-drpc. DO NOT EDIT. +// protoc-gen-go-drpc version: v0.0.33 +// source: consensus/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_consensus_consensusproto_protos_consensus_proto struct{} + +func (drpcEncoding_File_consensus_consensusproto_protos_consensus_proto) Marshal(msg drpc.Message) ([]byte, error) { + return proto.Marshal(msg.(proto.Message)) +} + +func (drpcEncoding_File_consensus_consensusproto_protos_consensus_proto) Unmarshal(buf []byte, msg drpc.Message) error { + return proto.Unmarshal(buf, msg.(proto.Message)) +} + +func (drpcEncoding_File_consensus_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_consensus_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 + + LogAdd(ctx context.Context, in *LogAddRequest) (*Ok, error) + RecordAdd(ctx context.Context, in *RecordAddRequest) (*Ok, error) + LogWatch(ctx context.Context) (DRPCConsensus_LogWatchClient, 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) LogAdd(ctx context.Context, in *LogAddRequest) (*Ok, error) { + out := new(Ok) + err := c.cc.Invoke(ctx, "/consensusProto.Consensus/LogAdd", drpcEncoding_File_consensus_consensusproto_protos_consensus_proto{}, in, out) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *drpcConsensusClient) RecordAdd(ctx context.Context, in *RecordAddRequest) (*Ok, error) { + out := new(Ok) + err := c.cc.Invoke(ctx, "/consensusProto.Consensus/RecordAdd", drpcEncoding_File_consensus_consensusproto_protos_consensus_proto{}, in, out) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *drpcConsensusClient) LogWatch(ctx context.Context) (DRPCConsensus_LogWatchClient, error) { + stream, err := c.cc.NewStream(ctx, "/consensusProto.Consensus/LogWatch", drpcEncoding_File_consensus_consensusproto_protos_consensus_proto{}) + if err != nil { + return nil, err + } + x := &drpcConsensus_LogWatchClient{stream} + return x, nil +} + +type DRPCConsensus_LogWatchClient interface { + drpc.Stream + Send(*LogWatchRequest) error + Recv() (*LogWatchEvent, error) +} + +type drpcConsensus_LogWatchClient struct { + drpc.Stream +} + +func (x *drpcConsensus_LogWatchClient) GetStream() drpc.Stream { + return x.Stream +} + +func (x *drpcConsensus_LogWatchClient) Send(m *LogWatchRequest) error { + return x.MsgSend(m, drpcEncoding_File_consensus_consensusproto_protos_consensus_proto{}) +} + +func (x *drpcConsensus_LogWatchClient) Recv() (*LogWatchEvent, error) { + m := new(LogWatchEvent) + if err := x.MsgRecv(m, drpcEncoding_File_consensus_consensusproto_protos_consensus_proto{}); err != nil { + return nil, err + } + return m, nil +} + +func (x *drpcConsensus_LogWatchClient) RecvMsg(m *LogWatchEvent) error { + return x.MsgRecv(m, drpcEncoding_File_consensus_consensusproto_protos_consensus_proto{}) +} + +type DRPCConsensusServer interface { + LogAdd(context.Context, *LogAddRequest) (*Ok, error) + RecordAdd(context.Context, *RecordAddRequest) (*Ok, error) + LogWatch(DRPCConsensus_LogWatchStream) error +} + +type DRPCConsensusUnimplementedServer struct{} + +func (s *DRPCConsensusUnimplementedServer) LogAdd(context.Context, *LogAddRequest) (*Ok, error) { + return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) +} + +func (s *DRPCConsensusUnimplementedServer) RecordAdd(context.Context, *RecordAddRequest) (*Ok, error) { + return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) +} + +func (s *DRPCConsensusUnimplementedServer) LogWatch(DRPCConsensus_LogWatchStream) 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 "/consensusProto.Consensus/LogAdd", drpcEncoding_File_consensus_consensusproto_protos_consensus_proto{}, + func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { + return srv.(DRPCConsensusServer). + LogAdd( + ctx, + in1.(*LogAddRequest), + ) + }, DRPCConsensusServer.LogAdd, true + case 1: + return "/consensusProto.Consensus/RecordAdd", drpcEncoding_File_consensus_consensusproto_protos_consensus_proto{}, + func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { + return srv.(DRPCConsensusServer). + RecordAdd( + ctx, + in1.(*RecordAddRequest), + ) + }, DRPCConsensusServer.RecordAdd, true + case 2: + return "/consensusProto.Consensus/LogWatch", drpcEncoding_File_consensus_consensusproto_protos_consensus_proto{}, + func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { + return nil, srv.(DRPCConsensusServer). + LogWatch( + &drpcConsensus_LogWatchStream{in1.(drpc.Stream)}, + ) + }, DRPCConsensusServer.LogWatch, true + default: + return "", nil, nil, nil, false + } +} + +func DRPCRegisterConsensus(mux drpc.Mux, impl DRPCConsensusServer) error { + return mux.Register(impl, DRPCConsensusDescription{}) +} + +type DRPCConsensus_LogAddStream interface { + drpc.Stream + SendAndClose(*Ok) error +} + +type drpcConsensus_LogAddStream struct { + drpc.Stream +} + +func (x *drpcConsensus_LogAddStream) SendAndClose(m *Ok) error { + if err := x.MsgSend(m, drpcEncoding_File_consensus_consensusproto_protos_consensus_proto{}); err != nil { + return err + } + return x.CloseSend() +} + +type DRPCConsensus_RecordAddStream interface { + drpc.Stream + SendAndClose(*Ok) error +} + +type drpcConsensus_RecordAddStream struct { + drpc.Stream +} + +func (x *drpcConsensus_RecordAddStream) SendAndClose(m *Ok) error { + if err := x.MsgSend(m, drpcEncoding_File_consensus_consensusproto_protos_consensus_proto{}); err != nil { + return err + } + return x.CloseSend() +} + +type DRPCConsensus_LogWatchStream interface { + drpc.Stream + Send(*LogWatchEvent) error + Recv() (*LogWatchRequest, error) +} + +type drpcConsensus_LogWatchStream struct { + drpc.Stream +} + +func (x *drpcConsensus_LogWatchStream) Send(m *LogWatchEvent) error { + return x.MsgSend(m, drpcEncoding_File_consensus_consensusproto_protos_consensus_proto{}) +} + +func (x *drpcConsensus_LogWatchStream) Recv() (*LogWatchRequest, error) { + m := new(LogWatchRequest) + if err := x.MsgRecv(m, drpcEncoding_File_consensus_consensusproto_protos_consensus_proto{}); err != nil { + return nil, err + } + return m, nil +} + +func (x *drpcConsensus_LogWatchStream) RecvMsg(m *LogWatchRequest) error { + return x.MsgRecv(m, drpcEncoding_File_consensus_consensusproto_protos_consensus_proto{}) +} diff --git a/consensus/consensusproto/consensuserr/errors.go b/consensus/consensusproto/consensuserr/errors.go new file mode 100644 index 00000000..a7ba9f96 --- /dev/null +++ b/consensus/consensusproto/consensuserr/errors.go @@ -0,0 +1,16 @@ +package consensuserr + +import ( + "fmt" + "github.com/anyproto/any-sync/consensus/consensusproto" + "github.com/anyproto/any-sync/net/rpc/rpcerr" +) + +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..d28cf1de --- /dev/null +++ b/consensus/consensusproto/protos/consensus.proto @@ -0,0 +1,60 @@ +syntax = "proto3"; +package consensusProto; + +option go_package = "consensus/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 LogAdd(LogAddRequest) returns (Ok); + // AddRecord adds new record to log + rpc RecordAdd(RecordAddRequest) returns (Ok); + // WatchLog fetches log and subscribes for a changes + rpc LogWatch(stream LogWatchRequest) returns (stream LogWatchEvent); +} + +message Ok {} + +message LogAddRequest { + Log log = 1; +} + +message RecordAddRequest { + bytes logId = 1; + Record record = 2; +} + +message LogWatchRequest { + repeated bytes watchIds = 1; + repeated bytes unwatchIds = 2; +} + +message LogWatchEvent { + bytes logId = 1; + repeated Record records = 2; + Err error = 3; +} + +message Err { + ErrCodes error = 1; +} \ No newline at end of file From 8770da4abf1adae8a9f92c031422a95e7a2c8bed Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Wed, 28 Jun 2023 10:11:21 +0200 Subject: [PATCH 088/123] fix race in proto handshake --- net/secureservice/handshake/proto.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/net/secureservice/handshake/proto.go b/net/secureservice/handshake/proto.go index 45e95ab5..6cd82110 100644 --- a/net/secureservice/handshake/proto.go +++ b/net/secureservice/handshake/proto.go @@ -11,19 +11,20 @@ type ProtoChecker struct { AllowedProtoTypes []handshakeproto.ProtoType } -func OutgoingProtoHandshake(ctx context.Context, conn net.Conn, pt handshakeproto.ProtoType) (err error) { +func OutgoingProtoHandshake(ctx context.Context, conn net.Conn, pt handshakeproto.ProtoType) error { if ctx == nil { ctx = context.Background() } h := newHandshake() done := make(chan struct{}) + var err error go func() { defer close(done) err = outgoingProtoHandshake(h, conn, pt) }() select { case <-done: - return + return err case <-ctx.Done(): _ = conn.Close() return ctx.Err() @@ -54,19 +55,23 @@ func outgoingProtoHandshake(h *handshake, conn net.Conn, pt handshakeproto.Proto return HandshakeError{e: msg.ack.Error} } -func IncomingProtoHandshake(ctx context.Context, conn net.Conn, pt ProtoChecker) (protoType handshakeproto.ProtoType, err error) { +func IncomingProtoHandshake(ctx context.Context, conn net.Conn, pt ProtoChecker) (handshakeproto.ProtoType, error) { if ctx == nil { ctx = context.Background() } h := newHandshake() done := make(chan struct{}) + var ( + protoType handshakeproto.ProtoType + err error + ) go func() { defer close(done) protoType, err = incomingProtoHandshake(h, conn, pt) }() select { case <-done: - return + return protoType, err case <-ctx.Done(): _ = conn.Close() return 0, ctx.Err() From ffd613a5fc4f26f77abb34037f1018b5a816bc12 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Wed, 28 Jun 2023 11:59:13 +0200 Subject: [PATCH 089/123] Fix requestmanager test --- commonspace/requestmanager/requestmanager_test.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/commonspace/requestmanager/requestmanager_test.go b/commonspace/requestmanager/requestmanager_test.go index 35d497fc..68c0e78c 100644 --- a/commonspace/requestmanager/requestmanager_test.go +++ b/commonspace/requestmanager/requestmanager_test.go @@ -2,6 +2,10 @@ package requestmanager import ( "context" + "sync" + "testing" + "time" + "github.com/anyproto/any-sync/commonspace/objectsync" "github.com/anyproto/any-sync/commonspace/objectsync/mock_objectsync" "github.com/anyproto/any-sync/commonspace/spacesyncproto" @@ -13,9 +17,6 @@ import ( "github.com/stretchr/testify/require" "storj.io/drpc" "storj.io/drpc/drpcconn" - "sync" - "testing" - "time" ) type fixture struct { @@ -146,6 +147,7 @@ func TestRequestManager_QueueRequest(t *testing.T) { _, ok = msgs.Load("otherId1") require.True(t, ok) close(msgRelease) + fx.requestManager.Close(context.Background()) }) t.Run("no requests after close", func(t *testing.T) { @@ -181,9 +183,9 @@ func TestRequestManager_QueueRequest(t *testing.T) { close(msgRelease) // waiting to know if the second one is not taken // because the manager is now closed - time.Sleep(100 * time.Millisecond) + time.Sleep(200 * time.Millisecond) _, ok = msgs.Load("id2") require.False(t, ok) - + fx.requestManager.Close(context.Background()) }) } From 39f41c52d103659f1cd427b86d424ad0002502fb Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Wed, 28 Jun 2023 14:55:17 +0200 Subject: [PATCH 090/123] Add invite test --- .../object/acl/list/aclrecordbuilder.go | 8 +- commonspace/object/acl/list/aclstate.go | 2 +- commonspace/object/acl/list/list.go | 14 ++- commonspace/object/acl/list/list_test.go | 99 ++++++++++++++++++- commonspace/object/acl/list/listutils.go | 10 ++ 5 files changed, 123 insertions(+), 10 deletions(-) diff --git a/commonspace/object/acl/list/aclrecordbuilder.go b/commonspace/object/acl/list/aclrecordbuilder.go index cae3a2b8..3fe15ff2 100644 --- a/commonspace/object/acl/list/aclrecordbuilder.go +++ b/commonspace/object/acl/list/aclrecordbuilder.go @@ -163,8 +163,12 @@ func (a *aclRecordBuilder) BuildRequestJoin(payload RequestJoinPayload) (rawReco if err != nil { return } + protoIdentity, err := a.accountKeys.SignKey.GetPublic().Marshall() + if err != nil { + return + } joinRec := &aclrecordproto.AclAccountRequestJoin{ - InviteIdentity: rawIdentity, + InviteIdentity: protoIdentity, InviteRecordId: payload.InviteRecordId, InviteIdentitySignature: signature, Metadata: payload.Metadata, @@ -426,7 +430,7 @@ func (a *aclRecordBuilder) UnmarshallWithId(rawIdRecord *aclrecordproto.RawAclRe return } aclData := &aclrecordproto.AclData{} - err = proto.Unmarshal(rawRec.Payload, aclData) + err = proto.Unmarshal(aclRecord.Data, aclData) if err != nil { return } diff --git a/commonspace/object/acl/list/aclstate.go b/commonspace/object/acl/list/aclstate.go index 44336458..0e2a6568 100644 --- a/commonspace/object/acl/list/aclstate.go +++ b/commonspace/object/acl/list/aclstate.go @@ -193,7 +193,7 @@ func (st *AclState) applyRoot(record *AclRecord) (err error) { // adding user to the list userState := AclUserState{ PubKey: record.Identity, - Permissions: AclPermissions(aclrecordproto.AclUserPermissions_Admin), + Permissions: AclPermissions(aclrecordproto.AclUserPermissions_Owner), } st.currentReadKeyId = record.Id st.userStates[mapKeyFromPubKey(record.Identity)] = userState diff --git a/commonspace/object/acl/list/list.go b/commonspace/object/acl/list/list.go index 5ae2af33..86ee570f 100644 --- a/commonspace/object/acl/list/list.go +++ b/commonspace/object/acl/list/list.go @@ -15,7 +15,10 @@ import ( type IterFunc = func(record *AclRecord) (IsContinue bool) -var ErrIncorrectCID = errors.New("incorrect CID") +var ( + ErrIncorrectCID = errors.New("incorrect CID") + ErrRecordAlreadyExists = errors.New("record already exists") +) type RWLocker interface { sync.Locker @@ -51,7 +54,7 @@ type AclList interface { RecordBuilder() AclRecordBuilder ValidateRawRecord(record *aclrecordproto.RawAclRecord) (err error) - AddRawRecord(rawRec *aclrecordproto.RawAclRecordWithId) (added bool, err error) + AddRawRecord(rawRec *aclrecordproto.RawAclRecordWithId) (err error) Close() (err error) } @@ -160,6 +163,7 @@ func build(deps internalDeps) (list AclList, err error) { return } + recBuilder.(*aclRecordBuilder).state = state list = &aclList{ root: rootWithId, records: records, @@ -189,9 +193,9 @@ func (a *aclList) ValidateRawRecord(rawRec *aclrecordproto.RawAclRecord) (err er return a.aclState.Validator().ValidateAclRecordContents(record) } -func (a *aclList) AddRawRecord(rawRec *aclrecordproto.RawAclRecordWithId) (added bool, err error) { +func (a *aclList) AddRawRecord(rawRec *aclrecordproto.RawAclRecordWithId) (err error) { if _, ok := a.indexes[rawRec.Id]; ok { - return + return ErrRecordAlreadyExists } record, err := a.recordBuilder.UnmarshallWithId(rawRec) if err != nil { @@ -208,7 +212,7 @@ func (a *aclList) AddRawRecord(rawRec *aclrecordproto.RawAclRecordWithId) (added if err = a.storage.SetHead(rawRec.Id); err != nil { return } - return true, nil + return } func (a *aclList) IsValidNext(rawRec *aclrecordproto.RawAclRecordWithId) (err error) { diff --git a/commonspace/object/acl/list/list_test.go b/commonspace/object/acl/list/list_test.go index 19229ace..9f1ca77d 100644 --- a/commonspace/object/acl/list/list_test.go +++ b/commonspace/object/acl/list/list_test.go @@ -2,11 +2,56 @@ package list import ( "fmt" - "github.com/anyproto/any-sync/commonspace/object/accountdata" - "github.com/stretchr/testify/require" "testing" + + "github.com/anyproto/any-sync/commonspace/object/accountdata" + "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" + "github.com/anyproto/any-sync/util/cidutil" + "github.com/stretchr/testify/require" ) +func wrapRecord(rawRec *aclrecordproto.RawAclRecord) *aclrecordproto.RawAclRecordWithId { + payload, err := rawRec.Marshal() + if err != nil { + panic(err) + } + id, err := cidutil.NewCidFromBytes(payload) + if err != nil { + panic(err) + } + return &aclrecordproto.RawAclRecordWithId{ + Payload: payload, + Id: id, + } +} + +type aclFixture struct { + ownerKeys *accountdata.AccountKeys + accountKeys *accountdata.AccountKeys + ownerAcl *aclList + accountAcl *aclList + spaceId string +} + +func newFixture(t *testing.T) *aclFixture { + ownerKeys, err := accountdata.NewRandom() + require.NoError(t, err) + accountKeys, err := accountdata.NewRandom() + require.NoError(t, err) + spaceId := "spaceId" + ownerAcl, err := NewTestDerivedAcl(spaceId, ownerKeys) + require.NoError(t, err) + accountAcl, err := NewTestAclWithRoot(accountKeys, ownerAcl.Root()) + require.NoError(t, err) + return &aclFixture{ + ownerKeys: ownerKeys, + accountKeys: accountKeys, + ownerAcl: ownerAcl.(*aclList), + accountAcl: accountAcl.(*aclList), + spaceId: spaceId, + } +} + func TestAclList_BuildRoot(t *testing.T) { randomKeys, err := accountdata.NewRandom() require.NoError(t, err) @@ -14,3 +59,53 @@ func TestAclList_BuildRoot(t *testing.T) { require.NoError(t, err) fmt.Println(randomAcl.Id()) } + +func TestAclList_InvitePipeline(t *testing.T) { + fx := newFixture(t) + var ( + ownerAcl = fx.ownerAcl + ownerState = fx.ownerAcl.aclState + accountAcl = fx.accountAcl + accountState = fx.accountAcl.aclState + ) + // building invite + inv, err := ownerAcl.RecordBuilder().BuildInvite() + require.NoError(t, err) + inviteRec := wrapRecord(inv.InviteRec) + err = ownerAcl.AddRawRecord(inviteRec) + require.NoError(t, err) + err = accountAcl.AddRawRecord(inviteRec) + require.NoError(t, err) + + // building request join + requestJoin, err := accountAcl.RecordBuilder().BuildRequestJoin(RequestJoinPayload{ + InviteRecordId: inviteRec.Id, + InviteKey: inv.InviteKey, + }) + require.NoError(t, err) + requestJoinRec := wrapRecord(requestJoin) + err = ownerAcl.AddRawRecord(requestJoinRec) + require.NoError(t, err) + err = accountAcl.AddRawRecord(requestJoinRec) + require.NoError(t, err) + + // building request accept + requestAccept, err := ownerAcl.RecordBuilder().BuildRequestAccept(RequestAcceptPayload{ + RequestRecordId: requestJoinRec.Id, + Permissions: AclPermissions(aclrecordproto.AclUserPermissions_Writer), + }) + require.NoError(t, err) + requestAcceptRec := wrapRecord(requestAccept) + err = ownerAcl.AddRawRecord(requestAcceptRec) + require.NoError(t, err) + err = accountAcl.AddRawRecord(requestAcceptRec) + require.NoError(t, err) + + // checking acl state + require.True(t, ownerState.Permissions(ownerState.pubKey).IsOwner()) + require.True(t, ownerState.Permissions(accountState.pubKey).CanWrite()) + require.Equal(t, 0, len(ownerState.pendingRequests)) + require.Equal(t, 0, len(accountState.pendingRequests)) + require.True(t, accountState.Permissions(ownerState.pubKey).IsOwner()) + require.True(t, accountState.Permissions(accountState.pubKey).CanWrite()) +} diff --git a/commonspace/object/acl/list/listutils.go b/commonspace/object/acl/list/listutils.go index 9f7d7331..10513ecb 100644 --- a/commonspace/object/acl/list/listutils.go +++ b/commonspace/object/acl/list/listutils.go @@ -29,3 +29,13 @@ func NewTestDerivedAcl(spaceId string, keys *accountdata.AccountKeys) (AclList, } return BuildAclListWithIdentity(keys, st, NoOpAcceptorVerifier{}) } + +func NewTestAclWithRoot(keys *accountdata.AccountKeys, root *aclrecordproto.RawAclRecordWithId) (AclList, error) { + st, err := liststorage.NewInMemoryAclListStorage(root.Id, []*aclrecordproto.RawAclRecordWithId{ + root, + }) + if err != nil { + return nil, err + } + return BuildAclListWithIdentity(keys, st, NoOpAcceptorVerifier{}) +} From 3f08fcb5559ded9ee2ceee8e5479eb805b2d4165 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Wed, 28 Jun 2023 15:43:35 +0200 Subject: [PATCH 091/123] Add account remove test --- .../object/acl/list/aclrecordbuilder.go | 8 ++- commonspace/object/acl/list/aclstate.go | 1 + commonspace/object/acl/list/list.go | 27 +++---- commonspace/object/acl/list/list_test.go | 71 ++++++++++++++----- commonspace/object/acl/list/listutils.go | 2 +- commonspace/object/acl/list/validator.go | 17 +++-- commonspace/payloads.go | 4 +- 7 files changed, 86 insertions(+), 44 deletions(-) diff --git a/commonspace/object/acl/list/aclrecordbuilder.go b/commonspace/object/acl/list/aclrecordbuilder.go index 3fe15ff2..1c0e0dd3 100644 --- a/commonspace/object/acl/list/aclrecordbuilder.go +++ b/commonspace/object/acl/list/aclrecordbuilder.go @@ -63,14 +63,16 @@ type aclRecordBuilder struct { id string keyStorage crypto.KeyStorage accountKeys *accountdata.AccountKeys + verifier AcceptorVerifier state *AclState } -func NewAclRecordBuilder(id string, keyStorage crypto.KeyStorage, keys *accountdata.AccountKeys) AclRecordBuilder { +func NewAclRecordBuilder(id string, keyStorage crypto.KeyStorage, keys *accountdata.AccountKeys, verifier AcceptorVerifier) AclRecordBuilder { return &aclRecordBuilder{ id: id, keyStorage: keyStorage, accountKeys: keys, + verifier: verifier, } } @@ -420,6 +422,10 @@ func (a *aclRecordBuilder) UnmarshallWithId(rawIdRecord *aclrecordproto.RawAclRe Model: aclRoot, } } else { + err = a.verifier.VerifyAcceptor(rawRec) + if err != nil { + return + } aclRecord := &aclrecordproto.AclRecord{} err = proto.Unmarshal(rawRec.Payload, aclRecord) if err != nil { diff --git a/commonspace/object/acl/list/aclstate.go b/commonspace/object/acl/list/aclstate.go index 0e2a6568..65dfea0a 100644 --- a/commonspace/object/acl/list/aclstate.go +++ b/commonspace/object/acl/list/aclstate.go @@ -25,6 +25,7 @@ var ( ErrInsufficientPermissions = errors.New("insufficient permissions") ErrIsOwner = errors.New("can't be made by owner") ErrIncorrectNumberOfAccounts = errors.New("incorrect number of accounts") + ErrDuplicateAccounts = errors.New("duplicate accounts") ErrNoReadKey = errors.New("acl state doesn't have a read key") ErrIncorrectReadKey = errors.New("incorrect read key") ErrInvalidSignature = errors.New("signature is invalid") diff --git a/commonspace/object/acl/list/list.go b/commonspace/object/acl/list/list.go index 86ee570f..cedf772c 100644 --- a/commonspace/object/acl/list/list.go +++ b/commonspace/object/acl/list/list.go @@ -85,10 +85,11 @@ type internalDeps struct { func BuildAclListWithIdentity(acc *accountdata.AccountKeys, storage liststorage.ListStorage, verifier AcceptorVerifier) (AclList, error) { keyStorage := crypto.NewKeyStorage() deps := internalDeps{ - storage: storage, - keyStorage: keyStorage, - stateBuilder: newAclStateBuilderWithIdentity(acc), - recordBuilder: NewAclRecordBuilder(storage.Id(), keyStorage, acc), + storage: storage, + keyStorage: keyStorage, + stateBuilder: newAclStateBuilderWithIdentity(acc), + recordBuilder: NewAclRecordBuilder(storage.Id(), keyStorage, acc, verifier), + acceptorVerifier: verifier, } return build(deps) } @@ -96,10 +97,11 @@ func BuildAclListWithIdentity(acc *accountdata.AccountKeys, storage liststorage. func BuildAclList(storage liststorage.ListStorage, verifier AcceptorVerifier) (AclList, error) { keyStorage := crypto.NewKeyStorage() deps := internalDeps{ - storage: storage, - keyStorage: keyStorage, - stateBuilder: newAclStateBuilder(), - recordBuilder: NewAclRecordBuilder(storage.Id(), keyStorage, nil), + storage: storage, + keyStorage: keyStorage, + stateBuilder: newAclStateBuilder(), + recordBuilder: NewAclRecordBuilder(storage.Id(), keyStorage, nil, verifier), + acceptorVerifier: verifier, } return build(deps) } @@ -215,15 +217,6 @@ func (a *aclList) AddRawRecord(rawRec *aclrecordproto.RawAclRecordWithId) (err e return } -func (a *aclList) IsValidNext(rawRec *aclrecordproto.RawAclRecordWithId) (err error) { - _, err = a.recordBuilder.UnmarshallWithId(rawRec) - if err != nil { - return - } - // TODO: change state and add "check" method for records - return -} - func (a *aclList) Id() string { return a.id } diff --git a/commonspace/object/acl/list/list_test.go b/commonspace/object/acl/list/list_test.go index 9f1ca77d..070e97d6 100644 --- a/commonspace/object/acl/list/list_test.go +++ b/commonspace/object/acl/list/list_test.go @@ -7,6 +7,7 @@ import ( "github.com/anyproto/any-sync/commonspace/object/accountdata" "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" "github.com/anyproto/any-sync/util/cidutil" + "github.com/anyproto/any-sync/util/crypto" "github.com/stretchr/testify/require" ) @@ -52,16 +53,14 @@ func newFixture(t *testing.T) *aclFixture { } } -func TestAclList_BuildRoot(t *testing.T) { - randomKeys, err := accountdata.NewRandom() +func (fx *aclFixture) addRec(t *testing.T, rec *aclrecordproto.RawAclRecordWithId) { + err := fx.ownerAcl.AddRawRecord(rec) require.NoError(t, err) - randomAcl, err := NewTestDerivedAcl("spaceId", randomKeys) + err = fx.accountAcl.AddRawRecord(rec) require.NoError(t, err) - fmt.Println(randomAcl.Id()) } -func TestAclList_InvitePipeline(t *testing.T) { - fx := newFixture(t) +func (fx *aclFixture) inviteAccount(t *testing.T, perms AclPermissions) { var ( ownerAcl = fx.ownerAcl ownerState = fx.ownerAcl.aclState @@ -72,10 +71,7 @@ func TestAclList_InvitePipeline(t *testing.T) { inv, err := ownerAcl.RecordBuilder().BuildInvite() require.NoError(t, err) inviteRec := wrapRecord(inv.InviteRec) - err = ownerAcl.AddRawRecord(inviteRec) - require.NoError(t, err) - err = accountAcl.AddRawRecord(inviteRec) - require.NoError(t, err) + fx.addRec(t, inviteRec) // building request join requestJoin, err := accountAcl.RecordBuilder().BuildRequestJoin(RequestJoinPayload{ @@ -84,22 +80,16 @@ func TestAclList_InvitePipeline(t *testing.T) { }) require.NoError(t, err) requestJoinRec := wrapRecord(requestJoin) - err = ownerAcl.AddRawRecord(requestJoinRec) - require.NoError(t, err) - err = accountAcl.AddRawRecord(requestJoinRec) - require.NoError(t, err) + fx.addRec(t, requestJoinRec) // building request accept requestAccept, err := ownerAcl.RecordBuilder().BuildRequestAccept(RequestAcceptPayload{ RequestRecordId: requestJoinRec.Id, - Permissions: AclPermissions(aclrecordproto.AclUserPermissions_Writer), + Permissions: perms, }) require.NoError(t, err) requestAcceptRec := wrapRecord(requestAccept) - err = ownerAcl.AddRawRecord(requestAcceptRec) - require.NoError(t, err) - err = accountAcl.AddRawRecord(requestAcceptRec) - require.NoError(t, err) + fx.addRec(t, requestAcceptRec) // checking acl state require.True(t, ownerState.Permissions(ownerState.pubKey).IsOwner()) @@ -109,3 +99,46 @@ func TestAclList_InvitePipeline(t *testing.T) { require.True(t, accountState.Permissions(ownerState.pubKey).IsOwner()) require.True(t, accountState.Permissions(accountState.pubKey).CanWrite()) } + +func TestAclList_BuildRoot(t *testing.T) { + randomKeys, err := accountdata.NewRandom() + require.NoError(t, err) + randomAcl, err := NewTestDerivedAcl("spaceId", randomKeys) + require.NoError(t, err) + fmt.Println(randomAcl.Id()) +} + +func TestAclList_InvitePipeline(t *testing.T) { + fx := newFixture(t) + fx.inviteAccount(t, AclPermissions(aclrecordproto.AclUserPermissions_Writer)) +} + +func TestAclList_Remove(t *testing.T) { + fx := newFixture(t) + var ( + ownerState = fx.ownerAcl.aclState + accountState = fx.accountAcl.aclState + ) + fx.inviteAccount(t, AclPermissions(aclrecordproto.AclUserPermissions_Writer)) + + newReadKey := crypto.NewAES() + remove, err := fx.ownerAcl.RecordBuilder().BuildAccountRemove(AccountRemovePayload{ + Identities: []crypto.PubKey{fx.accountKeys.SignKey.GetPublic()}, + ReadKey: newReadKey, + }) + require.NoError(t, err) + removeRec := wrapRecord(remove) + fx.addRec(t, removeRec) + + // checking acl state + require.True(t, ownerState.Permissions(ownerState.pubKey).IsOwner()) + require.True(t, ownerState.Permissions(accountState.pubKey).NoPermissions()) + require.True(t, ownerState.userReadKeys[removeRec.Id].Equals(newReadKey)) + require.NotNil(t, ownerState.userReadKeys[fx.ownerAcl.Id()]) + require.Equal(t, 0, len(ownerState.pendingRequests)) + require.Equal(t, 0, len(accountState.pendingRequests)) + require.True(t, accountState.Permissions(ownerState.pubKey).IsOwner()) + require.True(t, accountState.Permissions(accountState.pubKey).NoPermissions()) + require.Nil(t, accountState.userReadKeys[removeRec.Id]) + require.NotNil(t, accountState.userReadKeys[fx.ownerAcl.Id()]) +} diff --git a/commonspace/object/acl/list/listutils.go b/commonspace/object/acl/list/listutils.go index 10513ecb..d337dcc5 100644 --- a/commonspace/object/acl/list/listutils.go +++ b/commonspace/object/acl/list/listutils.go @@ -8,7 +8,7 @@ import ( ) func NewTestDerivedAcl(spaceId string, keys *accountdata.AccountKeys) (AclList, error) { - builder := NewAclRecordBuilder("", crypto.NewKeyStorage(), keys) + builder := NewAclRecordBuilder("", crypto.NewKeyStorage(), keys, NoOpAcceptorVerifier{}) masterKey, _, err := crypto.GenerateRandomEd25519KeyPair() if err != nil { return nil, err diff --git a/commonspace/object/acl/list/validator.go b/commonspace/object/acl/list/validator.go index 9b667fda..1296789c 100644 --- a/commonspace/object/acl/list/validator.go +++ b/commonspace/object/acl/list/validator.go @@ -161,11 +161,15 @@ func (c *contentValidator) ValidateAccountRemove(ch *aclrecordproto.AclAccountRe if !c.aclState.Permissions(authorIdentity).CanManageAccounts() { return ErrInsufficientPermissions } + seenIdentities := map[string]struct{}{} for _, rawIdentity := range ch.Identities { identity, err := c.keyStore.PubKeyFromProto(rawIdentity) if err != nil { return err } + if identity.Equals(authorIdentity) { + return ErrInsufficientPermissions + } permissions := c.aclState.Permissions(identity) if permissions.NoPermissions() { return ErrNoSuchAccount @@ -173,8 +177,13 @@ func (c *contentValidator) ValidateAccountRemove(ch *aclrecordproto.AclAccountRe if permissions.IsOwner() { return ErrInsufficientPermissions } + idKey := mapKeyFromPubKey(identity) + if _, exists := seenIdentities[idKey]; exists { + return ErrDuplicateAccounts + } + seenIdentities[mapKeyFromPubKey(identity)] = struct{}{} } - return c.validateAccountReadKeys(ch.AccountKeys) + return c.validateAccountReadKeys(ch.AccountKeys, len(c.aclState.userStates)-len(ch.Identities)) } func (c *contentValidator) ValidateRequestRemove(ch *aclrecordproto.AclAccountRequestRemove, authorIdentity crypto.PubKey) (err error) { @@ -188,11 +197,11 @@ func (c *contentValidator) ValidateRequestRemove(ch *aclrecordproto.AclAccountRe } func (c *contentValidator) ValidateReadKeyChange(ch *aclrecordproto.AclReadKeyChange, authorIdentity crypto.PubKey) (err error) { - return c.validateAccountReadKeys(ch.AccountKeys) + return c.validateAccountReadKeys(ch.AccountKeys, len(c.aclState.userStates)) } -func (c *contentValidator) validateAccountReadKeys(accountKeys []*aclrecordproto.AclEncryptedReadKey) (err error) { - if len(accountKeys) != len(c.aclState.userStates) { +func (c *contentValidator) validateAccountReadKeys(accountKeys []*aclrecordproto.AclEncryptedReadKey, usersNum int) (err error) { + if len(accountKeys) != usersNum { return ErrIncorrectNumberOfAccounts } for _, encKeys := range accountKeys { diff --git a/commonspace/payloads.go b/commonspace/payloads.go index 6cc572be..b3c9835b 100644 --- a/commonspace/payloads.go +++ b/commonspace/payloads.go @@ -72,7 +72,7 @@ func storagePayloadForSpaceCreate(payload SpaceCreatePayload) (storagePayload sp // building acl root keyStorage := crypto.NewKeyStorage() - aclBuilder := list.NewAclRecordBuilder("", keyStorage, nil) + aclBuilder := list.NewAclRecordBuilder("", keyStorage, nil, list.NoOpAcceptorVerifier{}) aclRoot, err := aclBuilder.BuildRoot(list.RootContent{ PrivKey: payload.SigningKey, MasterKey: payload.MasterKey, @@ -159,7 +159,7 @@ func storagePayloadForSpaceDerive(payload SpaceDerivePayload) (storagePayload sp // building acl root keyStorage := crypto.NewKeyStorage() - aclBuilder := list.NewAclRecordBuilder("", keyStorage, nil) + aclBuilder := list.NewAclRecordBuilder("", keyStorage, nil, list.NoOpAcceptorVerifier{}) aclRoot, err := aclBuilder.BuildRoot(list.RootContent{ PrivKey: payload.SigningKey, MasterKey: payload.MasterKey, From e5b4f62e487b9c6799026221ddba272dfccef56f Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Wed, 28 Jun 2023 17:35:45 +0200 Subject: [PATCH 092/123] fix nodes online --- commonspace/syncstatus/syncstatus.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/commonspace/syncstatus/syncstatus.go b/commonspace/syncstatus/syncstatus.go index 32c287fa..9c580fe6 100644 --- a/commonspace/syncstatus/syncstatus.go +++ b/commonspace/syncstatus/syncstatus.go @@ -3,11 +3,12 @@ package syncstatus import ( "context" "fmt" - "github.com/anyproto/any-sync/app" - "github.com/anyproto/any-sync/commonspace/spacestate" "sync" "time" + "github.com/anyproto/any-sync/app" + "github.com/anyproto/any-sync/commonspace/spacestate" + "github.com/anyproto/any-sync/app/logger" "github.com/anyproto/any-sync/commonspace/object/tree/treestorage" "github.com/anyproto/any-sync/commonspace/spacestorage" @@ -178,8 +179,9 @@ func (s *syncStatusService) update(ctx context.Context) (err error) { } s.treeStatusBuf = append(s.treeStatusBuf, treeStatus{treeId, treeHeads.syncStatus, treeHeads.heads}) } + nodesOnline := s.nodesOnline s.Unlock() - s.updateReceiver.UpdateNodeConnection(s.nodesOnline) + s.updateReceiver.UpdateNodeConnection(nodesOnline) for _, entry := range s.treeStatusBuf { err = s.updateReceiver.UpdateTree(ctx, entry.treeId, entry.status) if err != nil { From 02b326cc9025421d0e981137fdd5bef34c2fcd7f Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Wed, 28 Jun 2023 21:34:50 +0200 Subject: [PATCH 093/123] Add lastIteratedId when setting merged heads --- .../object/tree/objecttree/objecttree_test.go | 7 +++++-- commonspace/object/tree/objecttree/tree.go | 1 + commonspace/object/tree/objecttree/tree_test.go | 15 ++++++++++++++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/commonspace/object/tree/objecttree/objecttree_test.go b/commonspace/object/tree/objecttree/objecttree_test.go index 0dd255f8..1ac1a844 100644 --- a/commonspace/object/tree/objecttree/objecttree_test.go +++ b/commonspace/object/tree/objecttree/objecttree_test.go @@ -3,6 +3,9 @@ package objecttree import ( "context" "fmt" + "testing" + "time" + "github.com/anyproto/any-sync/commonspace/object/accountdata" "github.com/anyproto/any-sync/commonspace/object/acl/list" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" @@ -10,8 +13,6 @@ import ( "github.com/gogo/protobuf/proto" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "testing" - "time" ) type testTreeContext struct { @@ -123,6 +124,7 @@ func TestObjectTree(t *testing.T) { require.NoError(t, err) require.GreaterOrEqual(t, start.Unix(), ch.Timestamp) require.LessOrEqual(t, end.Unix(), ch.Timestamp) + require.Equal(t, res.Added[0].Id, oTree.(*objectTree).tree.lastIteratedHeadId) }) t.Run("timestamp is set correctly", func(t *testing.T) { someTs := time.Now().Add(time.Hour).Unix() @@ -139,6 +141,7 @@ func TestObjectTree(t *testing.T) { ch, err := oTree.(*objectTree).changeBuilder.Unmarshall(res.Added[0], true) require.NoError(t, err) require.Equal(t, ch.Timestamp, someTs) + require.Equal(t, res.Added[0].Id, oTree.(*objectTree).tree.lastIteratedHeadId) }) }) diff --git a/commonspace/object/tree/objecttree/tree.go b/commonspace/object/tree/objecttree/tree.go index 51a3b444..1a070e4c 100644 --- a/commonspace/object/tree/objecttree/tree.go +++ b/commonspace/object/tree/objecttree/tree.go @@ -82,6 +82,7 @@ func (t *Tree) AddMergedHead(c *Change) error { } } t.headIds = []string{c.Id} + t.lastIteratedHeadId = c.Id return nil } diff --git a/commonspace/object/tree/objecttree/tree_test.go b/commonspace/object/tree/objecttree/tree_test.go index 4bda3527..3fe0649c 100644 --- a/commonspace/object/tree/objecttree/tree_test.go +++ b/commonspace/object/tree/objecttree/tree_test.go @@ -2,10 +2,12 @@ package objecttree import ( "fmt" - "github.com/stretchr/testify/assert" "math/rand" "testing" "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func newChange(id string, snapshotId string, prevIds ...string) *Change { @@ -26,6 +28,17 @@ func newSnapshot(id, snapshotId string, prevIds ...string) *Change { } } +func TestTree_AddMergedHead(t *testing.T) { + tr := new(Tree) + _, _ = tr.Add( + newSnapshot("root", ""), + newChange("one", "root", "root"), + ) + require.Equal(t, tr.lastIteratedHeadId, "one") + tr.AddMergedHead(newChange("two", "root", "one")) + require.Equal(t, tr.lastIteratedHeadId, "two") +} + func TestTree_Add(t *testing.T) { t.Run("add first el", func(t *testing.T) { tr := new(Tree) From f4cbbfa37464e3c632033bd9c534f00a1e70b861 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Thu, 29 Jun 2023 00:57:24 +0200 Subject: [PATCH 094/123] Update tests --- .../object/acl/list/aclrecordbuilder.go | 2 +- .../object/acl/list/aclrecordbuilder_test.go | 9 - commonspace/object/acl/list/aclstate.go | 39 ++++- commonspace/object/acl/list/list_test.go | 164 ++++++++++++++++++ commonspace/object/acl/list/models.go | 1 + 5 files changed, 196 insertions(+), 19 deletions(-) delete mode 100644 commonspace/object/acl/list/aclrecordbuilder_test.go diff --git a/commonspace/object/acl/list/aclrecordbuilder.go b/commonspace/object/acl/list/aclrecordbuilder.go index 1c0e0dd3..a949bd99 100644 --- a/commonspace/object/acl/list/aclrecordbuilder.go +++ b/commonspace/object/acl/list/aclrecordbuilder.go @@ -372,7 +372,7 @@ func (a *aclRecordBuilder) Unmarshall(rawRecord *aclrecordproto.RawAclRecord) (r return } aclData := &aclrecordproto.AclData{} - err = proto.Unmarshal(rawRecord.Payload, aclData) + err = proto.Unmarshal(aclRecord.Data, aclData) if err != nil { return } diff --git a/commonspace/object/acl/list/aclrecordbuilder_test.go b/commonspace/object/acl/list/aclrecordbuilder_test.go deleted file mode 100644 index 27a75a28..00000000 --- a/commonspace/object/acl/list/aclrecordbuilder_test.go +++ /dev/null @@ -1,9 +0,0 @@ -package list - -import ( - "testing" -) - -func TestAclRecordBuilder_BuildUserJoin(t *testing.T) { - return -} diff --git a/commonspace/object/acl/list/aclstate.go b/commonspace/object/acl/list/aclstate.go index 65dfea0a..f11a99bd 100644 --- a/commonspace/object/acl/list/aclstate.go +++ b/commonspace/object/acl/list/aclstate.go @@ -53,8 +53,8 @@ type AclState struct { inviteKeys map[string]crypto.PubKey // requestRecords is a map recordId -> RequestRecord requestRecords map[string]RequestRecord - // pendingRequests is a map pubKey -> RequestType - pendingRequests map[string]RequestType + // pendingRequests is a map pubKey -> recordId + pendingRequests map[string]string key crypto.PrivKey pubKey crypto.PubKey keyStore crypto.KeyStorage @@ -76,7 +76,7 @@ func newAclStateWithKeys( statesAtRecord: make(map[string][]AclUserState), inviteKeys: make(map[string]crypto.PubKey), requestRecords: make(map[string]RequestRecord), - pendingRequests: make(map[string]RequestType), + pendingRequests: make(map[string]string), keyStore: crypto.NewKeyStorage(), } st.contentValidator = &contentValidator{ @@ -94,7 +94,7 @@ func newAclState(id string) *AclState { statesAtRecord: make(map[string][]AclUserState), inviteKeys: make(map[string]crypto.PubKey), requestRecords: make(map[string]RequestRecord), - pendingRequests: make(map[string]RequestType), + pendingRequests: make(map[string]string), keyStore: crypto.NewKeyStorage(), } st.contentValidator = &contentValidator{ @@ -113,7 +113,7 @@ func (st *AclState) CurrentReadKeyId() string { } func (st *AclState) CurrentReadKey() (crypto.SymKey, error) { - key, exists := st.userReadKeys[st.currentReadKeyId] + key, exists := st.userReadKeys[st.CurrentReadKeyId()] if !exists { return nil, ErrNoReadKey } @@ -302,10 +302,11 @@ func (st *AclState) applyRequestJoin(ch *aclrecordproto.AclAccountRequestJoin, r if err != nil { return err } - st.pendingRequests[mapKeyFromPubKey(authorIdentity)] = RequestTypeJoin + st.pendingRequests[mapKeyFromPubKey(authorIdentity)] = recordId st.requestRecords[recordId] = RequestRecord{ RequestIdentity: authorIdentity, RequestMetadata: ch.Metadata, + Type: RequestTypeJoin, } return nil } @@ -358,7 +359,11 @@ func (st *AclState) applyRequestRemove(ch *aclrecordproto.AclAccountRequestRemov if err != nil { return err } - st.pendingRequests[mapKeyFromPubKey(authorIdentity)] = RequestTypeRemove + st.requestRecords[recordId] = RequestRecord{ + RequestIdentity: authorIdentity, + Type: RequestTypeRemove, + } + st.pendingRequests[mapKeyFromPubKey(authorIdentity)] = recordId return nil } @@ -422,8 +427,24 @@ func (st *AclState) Permissions(identity crypto.PubKey) AclPermissions { return state.Permissions } -func (st *AclState) UserStates() map[string]AclUserState { - return st.userStates +func (st *AclState) JoinRecords() (records []RequestRecord) { + for _, recId := range st.pendingRequests { + rec := st.requestRecords[recId] + if rec.Type == RequestTypeJoin { + records = append(records, rec) + } + } + return +} + +func (st *AclState) RemoveRecords() (records []RequestRecord) { + for _, recId := range st.pendingRequests { + rec := st.requestRecords[recId] + if rec.Type == RequestTypeRemove { + records = append(records, rec) + } + } + return } func (st *AclState) LastRecordId() string { diff --git a/commonspace/object/acl/list/list_test.go b/commonspace/object/acl/list/list_test.go index 070e97d6..17a4a9ec 100644 --- a/commonspace/object/acl/list/list_test.go +++ b/commonspace/object/acl/list/list_test.go @@ -88,6 +88,9 @@ func (fx *aclFixture) inviteAccount(t *testing.T, perms AclPermissions) { Permissions: perms, }) require.NoError(t, err) + // validate + err = ownerAcl.ValidateRawRecord(requestAccept) + require.NoError(t, err) requestAcceptRec := wrapRecord(requestAccept) fx.addRec(t, requestAcceptRec) @@ -98,6 +101,12 @@ func (fx *aclFixture) inviteAccount(t *testing.T, perms AclPermissions) { require.Equal(t, 0, len(accountState.pendingRequests)) require.True(t, accountState.Permissions(ownerState.pubKey).IsOwner()) require.True(t, accountState.Permissions(accountState.pubKey).CanWrite()) + + _, err = ownerState.StateAtRecord(requestJoinRec.Id, accountState.pubKey) + require.Equal(t, ErrNoSuchAccount, err) + stateAtRec, err := ownerState.StateAtRecord(requestAcceptRec.Id, accountState.pubKey) + require.NoError(t, err) + require.True(t, stateAtRec.Permissions == perms) } func TestAclList_BuildRoot(t *testing.T) { @@ -113,6 +122,67 @@ func TestAclList_InvitePipeline(t *testing.T) { fx.inviteAccount(t, AclPermissions(aclrecordproto.AclUserPermissions_Writer)) } +func TestAclList_InviteRevoke(t *testing.T) { + fx := newFixture(t) + var ( + ownerState = fx.ownerAcl.aclState + accountState = fx.accountAcl.aclState + ) + // building invite + inv, err := fx.ownerAcl.RecordBuilder().BuildInvite() + require.NoError(t, err) + inviteRec := wrapRecord(inv.InviteRec) + fx.addRec(t, inviteRec) + + // building invite revoke + inviteRevoke, err := fx.ownerAcl.RecordBuilder().BuildInviteRevoke(ownerState.lastRecordId) + require.NoError(t, err) + inviteRevokeRec := wrapRecord(inviteRevoke) + fx.addRec(t, inviteRevokeRec) + + // checking acl state + require.True(t, ownerState.Permissions(ownerState.pubKey).IsOwner()) + require.True(t, ownerState.Permissions(accountState.pubKey).NoPermissions()) + require.Empty(t, ownerState.inviteKeys) + require.Empty(t, accountState.inviteKeys) +} + +func TestAclList_RequestDecline(t *testing.T) { + fx := newFixture(t) + var ( + ownerAcl = fx.ownerAcl + ownerState = fx.ownerAcl.aclState + accountAcl = fx.accountAcl + accountState = fx.accountAcl.aclState + ) + // building invite + inv, err := ownerAcl.RecordBuilder().BuildInvite() + require.NoError(t, err) + inviteRec := wrapRecord(inv.InviteRec) + fx.addRec(t, inviteRec) + + // building request join + requestJoin, err := accountAcl.RecordBuilder().BuildRequestJoin(RequestJoinPayload{ + InviteRecordId: inviteRec.Id, + InviteKey: inv.InviteKey, + }) + require.NoError(t, err) + requestJoinRec := wrapRecord(requestJoin) + fx.addRec(t, requestJoinRec) + + // building request decline + requestDecline, err := ownerAcl.RecordBuilder().BuildRequestDecline(ownerState.lastRecordId) + require.NoError(t, err) + requestDeclineRec := wrapRecord(requestDecline) + fx.addRec(t, requestDeclineRec) + + // checking acl state + require.True(t, ownerState.Permissions(ownerState.pubKey).IsOwner()) + require.True(t, ownerState.Permissions(accountState.pubKey).NoPermissions()) + require.Empty(t, ownerState.pendingRequests) + require.Empty(t, accountState.pendingRequests) +} + func TestAclList_Remove(t *testing.T) { fx := newFixture(t) var ( @@ -142,3 +212,97 @@ func TestAclList_Remove(t *testing.T) { require.Nil(t, accountState.userReadKeys[removeRec.Id]) require.NotNil(t, accountState.userReadKeys[fx.ownerAcl.Id()]) } + +func TestAclList_ReadKeyChange(t *testing.T) { + fx := newFixture(t) + var ( + ownerState = fx.ownerAcl.aclState + accountState = fx.accountAcl.aclState + ) + fx.inviteAccount(t, AclPermissions(aclrecordproto.AclUserPermissions_Admin)) + + newReadKey := crypto.NewAES() + readKeyChange, err := fx.ownerAcl.RecordBuilder().BuildReadKeyChange(newReadKey) + require.NoError(t, err) + readKeyRec := wrapRecord(readKeyChange) + fx.addRec(t, readKeyRec) + + // checking acl state + require.True(t, ownerState.Permissions(ownerState.pubKey).IsOwner()) + require.True(t, ownerState.Permissions(accountState.pubKey).CanManageAccounts()) + require.True(t, ownerState.userReadKeys[readKeyRec.Id].Equals(newReadKey)) + require.True(t, accountState.userReadKeys[readKeyRec.Id].Equals(newReadKey)) + require.NotNil(t, ownerState.userReadKeys[fx.ownerAcl.Id()]) + require.NotNil(t, accountState.userReadKeys[fx.ownerAcl.Id()]) + readKey, err := ownerState.CurrentReadKey() + require.NoError(t, err) + require.True(t, newReadKey.Equals(readKey)) + require.Equal(t, 0, len(ownerState.pendingRequests)) + require.Equal(t, 0, len(accountState.pendingRequests)) +} + +func TestAclList_PermissionChange(t *testing.T) { + fx := newFixture(t) + var ( + ownerState = fx.ownerAcl.aclState + accountState = fx.accountAcl.aclState + ) + fx.inviteAccount(t, AclPermissions(aclrecordproto.AclUserPermissions_Admin)) + + permissionChange, err := fx.ownerAcl.RecordBuilder().BuildPermissionChange(PermissionChangePayload{ + Identity: fx.accountKeys.SignKey.GetPublic(), + Permissions: AclPermissions(aclrecordproto.AclUserPermissions_Writer), + }) + require.NoError(t, err) + permissionChangeRec := wrapRecord(permissionChange) + fx.addRec(t, permissionChangeRec) + + // checking acl state + require.True(t, ownerState.Permissions(ownerState.pubKey).IsOwner()) + require.True(t, ownerState.Permissions(accountState.pubKey) == AclPermissions(aclrecordproto.AclUserPermissions_Writer)) + require.True(t, accountState.Permissions(ownerState.pubKey).IsOwner()) + require.True(t, accountState.Permissions(accountState.pubKey) == AclPermissions(aclrecordproto.AclUserPermissions_Writer)) + require.NotNil(t, ownerState.userReadKeys[fx.ownerAcl.Id()]) + require.NotNil(t, accountState.userReadKeys[fx.ownerAcl.Id()]) + require.Equal(t, 0, len(ownerState.pendingRequests)) + require.Equal(t, 0, len(accountState.pendingRequests)) +} + +func TestAclList_RequestRemove(t *testing.T) { + fx := newFixture(t) + var ( + ownerState = fx.ownerAcl.aclState + accountState = fx.accountAcl.aclState + ) + fx.inviteAccount(t, AclPermissions(aclrecordproto.AclUserPermissions_Writer)) + + removeRequest, err := fx.accountAcl.RecordBuilder().BuildRequestRemove() + require.NoError(t, err) + removeRequestRec := wrapRecord(removeRequest) + fx.addRec(t, removeRequestRec) + + recs := fx.accountAcl.AclState().RemoveRecords() + require.Len(t, recs, 1) + require.True(t, accountState.pubKey.Equals(recs[0].RequestIdentity)) + + newReadKey := crypto.NewAES() + remove, err := fx.ownerAcl.RecordBuilder().BuildAccountRemove(AccountRemovePayload{ + Identities: []crypto.PubKey{recs[0].RequestIdentity}, + ReadKey: newReadKey, + }) + require.NoError(t, err) + removeRec := wrapRecord(remove) + fx.addRec(t, removeRec) + + // checking acl state + require.True(t, ownerState.Permissions(ownerState.pubKey).IsOwner()) + require.True(t, ownerState.Permissions(accountState.pubKey).NoPermissions()) + require.True(t, ownerState.userReadKeys[removeRec.Id].Equals(newReadKey)) + require.NotNil(t, ownerState.userReadKeys[fx.ownerAcl.Id()]) + require.Equal(t, 0, len(ownerState.pendingRequests)) + require.Equal(t, 0, len(accountState.pendingRequests)) + require.True(t, accountState.Permissions(ownerState.pubKey).IsOwner()) + require.True(t, accountState.Permissions(accountState.pubKey).NoPermissions()) + require.Nil(t, accountState.userReadKeys[removeRec.Id]) + require.NotNil(t, accountState.userReadKeys[fx.ownerAcl.Id()]) +} diff --git a/commonspace/object/acl/list/models.go b/commonspace/object/acl/list/models.go index 27238202..1f958303 100644 --- a/commonspace/object/acl/list/models.go +++ b/commonspace/object/acl/list/models.go @@ -18,6 +18,7 @@ type AclRecord struct { type RequestRecord struct { RequestIdentity crypto.PubKey RequestMetadata []byte + Type RequestType } type AclUserState struct { From 68cda47ede5a682a5783d4eb83fdc3c12d65067b Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Thu, 29 Jun 2023 01:00:52 +0200 Subject: [PATCH 095/123] Update list mock --- .../object/acl/list/mock_list/mock_list.go | 50 +++++++++++++++++-- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/commonspace/object/acl/list/mock_list/mock_list.go b/commonspace/object/acl/list/mock_list/mock_list.go index b81f0f80..84ad11c1 100644 --- a/commonspace/object/acl/list/mock_list/mock_list.go +++ b/commonspace/object/acl/list/mock_list/mock_list.go @@ -51,12 +51,11 @@ func (mr *MockAclListMockRecorder) AclState() *gomock.Call { } // AddRawRecord mocks base method. -func (m *MockAclList) AddRawRecord(arg0 *aclrecordproto.RawAclRecordWithId) (bool, error) { +func (m *MockAclList) AddRawRecord(arg0 *aclrecordproto.RawAclRecordWithId) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AddRawRecord", arg0) - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 + ret0, _ := ret[0].(error) + return ret0 } // AddRawRecord indicates an expected call of AddRawRecord. @@ -94,6 +93,21 @@ func (mr *MockAclListMockRecorder) Get(arg0 interface{}) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockAclList)(nil).Get), arg0) } +// GetIndex mocks base method. +func (m *MockAclList) GetIndex(arg0 int) (*list.AclRecord, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetIndex", arg0) + ret0, _ := ret[0].(*list.AclRecord) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetIndex indicates an expected call of GetIndex. +func (mr *MockAclListMockRecorder) GetIndex(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetIndex", reflect.TypeOf((*MockAclList)(nil).GetIndex), arg0) +} + // Head mocks base method. func (m *MockAclList) Head() *list.AclRecord { m.ctrl.T.Helper() @@ -211,6 +225,20 @@ func (mr *MockAclListMockRecorder) RUnlock() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RUnlock", reflect.TypeOf((*MockAclList)(nil).RUnlock)) } +// RecordBuilder mocks base method. +func (m *MockAclList) RecordBuilder() list.AclRecordBuilder { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RecordBuilder") + ret0, _ := ret[0].(list.AclRecordBuilder) + return ret0 +} + +// RecordBuilder indicates an expected call of RecordBuilder. +func (mr *MockAclListMockRecorder) RecordBuilder() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecordBuilder", reflect.TypeOf((*MockAclList)(nil).RecordBuilder)) +} + // Records mocks base method. func (m *MockAclList) Records() []*list.AclRecord { m.ctrl.T.Helper() @@ -250,3 +278,17 @@ func (mr *MockAclListMockRecorder) Unlock() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Unlock", reflect.TypeOf((*MockAclList)(nil).Unlock)) } + +// ValidateRawRecord mocks base method. +func (m *MockAclList) ValidateRawRecord(arg0 *aclrecordproto.RawAclRecord) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ValidateRawRecord", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// ValidateRawRecord indicates an expected call of ValidateRawRecord. +func (mr *MockAclListMockRecorder) ValidateRawRecord(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateRawRecord", reflect.TypeOf((*MockAclList)(nil).ValidateRawRecord), arg0) +} From 5ffc175f4f3e153e52b0021f0ee4dff747ea22bd Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Thu, 29 Jun 2023 01:05:43 +0200 Subject: [PATCH 096/123] Remove time from test --- commonspace/requestmanager/requestmanager_test.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/commonspace/requestmanager/requestmanager_test.go b/commonspace/requestmanager/requestmanager_test.go index 68c0e78c..f04a4407 100644 --- a/commonspace/requestmanager/requestmanager_test.go +++ b/commonspace/requestmanager/requestmanager_test.go @@ -4,7 +4,6 @@ import ( "context" "sync" "testing" - "time" "github.com/anyproto/any-sync/commonspace/objectsync" "github.com/anyproto/any-sync/commonspace/objectsync/mock_objectsync" @@ -181,11 +180,7 @@ func TestRequestManager_QueueRequest(t *testing.T) { fx.requestManager.Close(context.Background()) close(msgRelease) - // waiting to know if the second one is not taken - // because the manager is now closed - time.Sleep(200 * time.Millisecond) _, ok = msgs.Load("id2") require.False(t, ok) - fx.requestManager.Close(context.Background()) }) } From 02dd4783bc543e5eebe86ddcbc7d7979325c6b40 Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Thu, 29 Jun 2023 14:37:52 +0200 Subject: [PATCH 097/123] fix mock --- .../mock_consensusclient/mock_consensusclient.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/consensus/consensusclient/mock_consensusclient/mock_consensusclient.go b/consensus/consensusclient/mock_consensusclient/mock_consensusclient.go index d103635a..f97c1c4f 100644 --- a/consensus/consensusclient/mock_consensusclient/mock_consensusclient.go +++ b/consensus/consensusclient/mock_consensusclient/mock_consensusclient.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/anyproto/go-anytype-infrastructure-experiments/consensus/consensusclient (interfaces: Service) +// Source: github.com/anyproto/any-sync/consensus/consensusclient (interfaces: Service) // Package mock_consensusclient is a generated GoMock package. package mock_consensusclient @@ -9,8 +9,8 @@ import ( reflect "reflect" app "github.com/anyproto/any-sync/app" - consensusclient "github.com/anyproto/any-sync-consensusnode/consensusclient" - consensusproto "github.com/anyproto/any-sync-consensusnode/consensusproto" + consensusclient "github.com/anyproto/any-sync/consensus/consensusclient" + consensusproto "github.com/anyproto/any-sync/consensus/consensusproto" gomock "github.com/golang/mock/gomock" ) From 50f94e7518e4f3cd030b7b2b9f0b85c0bcb91808 Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Thu, 29 Jun 2023 14:51:42 +0200 Subject: [PATCH 098/123] consensus: change err offset --- consensus/consensusproto/consensus.pb.go | 66 +++++++++---------- .../consensusproto/protos/consensus.proto | 2 +- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/consensus/consensusproto/consensus.pb.go b/consensus/consensusproto/consensus.pb.go index 9cb94880..e70f8b37 100644 --- a/consensus/consensusproto/consensus.pb.go +++ b/consensus/consensusproto/consensus.pb.go @@ -29,7 +29,7 @@ const ( ErrCodes_LogExists ErrCodes = 1 ErrCodes_LogNotFound ErrCodes = 2 ErrCodes_RecordConflict ErrCodes = 3 - ErrCodes_ErrorOffset ErrCodes = 300 + ErrCodes_ErrorOffset ErrCodes = 400 ) var ErrCodes_name = map[int32]string{ @@ -37,7 +37,7 @@ var ErrCodes_name = map[int32]string{ 1: "LogExists", 2: "LogNotFound", 3: "RecordConflict", - 300: "ErrorOffset", + 400: "ErrorOffset", } var ErrCodes_value = map[string]int32{ @@ -45,7 +45,7 @@ var ErrCodes_value = map[string]int32{ "LogExists": 1, "LogNotFound": 2, "RecordConflict": 3, - "ErrorOffset": 300, + "ErrorOffset": 400, } func (x ErrCodes) String() string { @@ -481,39 +481,39 @@ func init() { } var fileDescriptor_b8d7f1c16b400059 = []byte{ - // 511 bytes of a gzipped FileDescriptorProto + // 510 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x53, 0xc1, 0x6e, 0xd3, 0x40, 0x10, 0xcd, 0xda, 0x6d, 0x9a, 0x4c, 0xda, 0xd4, 0x1a, 0x50, 0x65, 0x45, 0xaa, 0xb1, 0x2c, 0x21, 0x05, 0x0e, 0x69, 0x65, 0x04, 0x17, 0x4e, 0x25, 0x32, 0x28, 0x92, 0x69, 0x90, 0xa5, 0x0a, 0xc4, - 0x89, 0xe0, 0xdd, 0x18, 0xab, 0x96, 0x37, 0xec, 0x3a, 0x25, 0x5c, 0xf9, 0x02, 0x3e, 0x84, 0x0f, - 0xe1, 0xd8, 0x23, 0x12, 0x17, 0x94, 0xfc, 0x08, 0xf2, 0x3a, 0x4e, 0x4d, 0x71, 0x84, 0xb8, 0xd8, - 0x7e, 0xef, 0xcd, 0xcc, 0xbe, 0x9d, 0x19, 0xc3, 0x49, 0xc8, 0x53, 0xc9, 0x52, 0x39, 0x97, 0x37, - 0x5f, 0x33, 0xc1, 0x33, 0x7e, 0xa2, 0x9e, 0x15, 0x76, 0xa0, 0x08, 0xec, 0x6e, 0x88, 0x57, 0x39, - 0x76, 0x5e, 0x80, 0xee, 0xf3, 0x08, 0xbb, 0xa0, 0xc5, 0xd4, 0x24, 0x36, 0xe9, 0xef, 0x07, 0x5a, - 0x4c, 0xf1, 0x14, 0xf6, 0x04, 0x0b, 0xb9, 0xa0, 0xd2, 0xd4, 0x6c, 0xbd, 0xdf, 0x71, 0x8f, 0x06, - 0x7f, 0x26, 0x0e, 0x02, 0x25, 0x07, 0x65, 0x98, 0x93, 0x40, 0xb3, 0xa0, 0xfe, 0xaa, 0x75, 0x04, - 0xcd, 0x99, 0x60, 0x57, 0x23, 0x6a, 0x6a, 0x8a, 0x5b, 0x23, 0x34, 0x61, 0x6f, 0x36, 0xf9, 0x9c, - 0xf0, 0x09, 0x35, 0x75, 0x25, 0x94, 0x10, 0x6d, 0xe8, 0x84, 0x82, 0x4d, 0x32, 0x46, 0x2f, 0xd2, - 0x78, 0x61, 0xee, 0xd8, 0xa4, 0xbf, 0x13, 0x54, 0x29, 0x67, 0x07, 0xb4, 0xf1, 0xa5, 0xf3, 0x04, - 0x0e, 0x7c, 0x1e, 0x9d, 0x51, 0x1a, 0xb0, 0x8f, 0x73, 0x26, 0x33, 0xbc, 0x0f, 0x7a, 0xc2, 0x23, - 0x75, 0x76, 0xc7, 0xbd, 0x73, 0xdb, 0xb2, 0xcf, 0xa3, 0x20, 0xd7, 0x9d, 0x37, 0x60, 0x14, 0x5e, - 0x2b, 0xa9, 0x77, 0x61, 0x37, 0xe1, 0xd1, 0xa8, 0x34, 0x5e, 0x00, 0x1c, 0x40, 0xb3, 0xb8, 0xa0, - 0xf2, 0xbe, 0xbd, 0x0d, 0xeb, 0x28, 0xe7, 0x25, 0x1c, 0xfa, 0x3c, 0x7a, 0x3d, 0xc9, 0xc2, 0x0f, - 0x65, 0xe1, 0x1e, 0xb4, 0x3e, 0xe5, 0x78, 0x44, 0xa5, 0x49, 0x6c, 0xbd, 0xbf, 0x1f, 0x6c, 0x30, - 0x5a, 0x00, 0xf3, 0x74, 0xa3, 0x6a, 0x4a, 0xad, 0x30, 0xce, 0x17, 0xa2, 0x6e, 0xa8, 0xea, 0x79, - 0x57, 0x2c, 0xdd, 0x66, 0xf3, 0xbf, 0xc7, 0x85, 0x0f, 0x60, 0x97, 0x09, 0xc1, 0x85, 0x6a, 0x7d, - 0x4d, 0xaf, 0x3c, 0x21, 0x82, 0x22, 0xc2, 0x79, 0x0c, 0xba, 0x27, 0x04, 0x0e, 0xca, 0x8c, 0xfc, - 0xe4, 0xae, 0x6b, 0xd6, 0x64, 0x0c, 0x39, 0x65, 0x72, 0x9d, 0xf6, 0xf0, 0x1d, 0xb4, 0x4a, 0x0a, - 0xbb, 0x00, 0x17, 0x29, 0x5b, 0xcc, 0x58, 0x98, 0x31, 0x6a, 0x34, 0xf0, 0x00, 0xda, 0x3e, 0x8f, - 0xbc, 0x45, 0x2c, 0x33, 0x69, 0x10, 0x3c, 0x84, 0x8e, 0xcf, 0xa3, 0x73, 0x9e, 0x3d, 0xe7, 0xf3, - 0x94, 0x1a, 0x1a, 0x22, 0x74, 0x0b, 0xc3, 0x43, 0x9e, 0x4e, 0x93, 0x38, 0xcc, 0x0c, 0x1d, 0x0d, - 0xe8, 0x78, 0x79, 0xe1, 0xf1, 0x74, 0x2a, 0x59, 0x66, 0x7c, 0xd3, 0xdc, 0x9f, 0x04, 0xda, 0xc3, - 0xd2, 0x04, 0x3e, 0x85, 0x66, 0xb1, 0x0c, 0x78, 0x5c, 0x33, 0xf8, 0x9b, 0x49, 0xf7, 0xf0, 0xb6, - 0x3c, 0xbe, 0xc4, 0x33, 0x68, 0x6f, 0x36, 0x02, 0xed, 0xfa, 0xe6, 0xfd, 0xa3, 0xc4, 0x39, 0xb4, - 0xca, 0x51, 0xe1, 0xbd, 0x1a, 0x07, 0xd5, 0xa5, 0xe8, 0x1d, 0x6f, 0x0b, 0x50, 0x53, 0xee, 0x93, - 0x53, 0xf2, 0xcc, 0xfd, 0xbe, 0xb4, 0xc8, 0xf5, 0xd2, 0x22, 0xbf, 0x96, 0x16, 0xf9, 0xba, 0xb2, - 0x1a, 0xd7, 0x2b, 0xab, 0xf1, 0x63, 0x65, 0x35, 0xde, 0x9a, 0xdb, 0x7e, 0xfa, 0xf7, 0x4d, 0xf5, - 0x7a, 0xf4, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x8c, 0x81, 0x82, 0x9d, 0x17, 0x04, 0x00, 0x00, + 0x89, 0xe0, 0xdd, 0x18, 0xab, 0x96, 0x37, 0xec, 0x3a, 0x25, 0x5c, 0xf9, 0x82, 0x7e, 0x16, 0xc7, + 0x1e, 0x91, 0xb8, 0xa0, 0xe4, 0x47, 0x90, 0xd7, 0x71, 0x6a, 0x8a, 0x23, 0xc4, 0xc5, 0xf6, 0x7b, + 0x6f, 0x66, 0xf6, 0xed, 0xcc, 0x18, 0x4e, 0x42, 0x9e, 0x4a, 0x96, 0xca, 0xb9, 0xbc, 0xfd, 0x9a, + 0x09, 0x9e, 0xf1, 0x13, 0xf5, 0xac, 0xb0, 0x03, 0x45, 0x60, 0x77, 0x43, 0xbc, 0xc9, 0xb1, 0xf3, + 0x0a, 0x74, 0x9f, 0x47, 0xd8, 0x05, 0x2d, 0xa6, 0x26, 0xb1, 0x49, 0x7f, 0x3f, 0xd0, 0x62, 0x8a, + 0xa7, 0xb0, 0x27, 0x58, 0xc8, 0x05, 0x95, 0xa6, 0x66, 0xeb, 0xfd, 0x8e, 0x7b, 0x34, 0xf8, 0x33, + 0x71, 0x10, 0x28, 0x39, 0x28, 0xc3, 0x9c, 0x04, 0x9a, 0x05, 0xf5, 0x57, 0xad, 0x23, 0x68, 0xce, + 0x04, 0xbb, 0x1a, 0x51, 0x53, 0x53, 0xdc, 0x1a, 0xa1, 0x09, 0x7b, 0xb3, 0xc9, 0xd7, 0x84, 0x4f, + 0xa8, 0xa9, 0x2b, 0xa1, 0x84, 0x68, 0x43, 0x27, 0x14, 0x6c, 0x92, 0x31, 0x7a, 0x91, 0xc6, 0x0b, + 0x73, 0xc7, 0x26, 0xfd, 0x9d, 0xa0, 0x4a, 0x39, 0x3b, 0xa0, 0x8d, 0x2f, 0x9d, 0x67, 0x70, 0xe0, + 0xf3, 0xe8, 0x8c, 0xd2, 0x80, 0x7d, 0x9e, 0x33, 0x99, 0xe1, 0x43, 0xd0, 0x13, 0x1e, 0xa9, 0xb3, + 0x3b, 0xee, 0xbd, 0xbb, 0x96, 0x7d, 0x1e, 0x05, 0xb9, 0xee, 0xbc, 0x03, 0xa3, 0xf0, 0x5a, 0x49, + 0xbd, 0x0f, 0xbb, 0x09, 0x8f, 0x46, 0xa5, 0xf1, 0x02, 0xe0, 0x00, 0x9a, 0xc5, 0x05, 0x95, 0xf7, + 0xed, 0x6d, 0x58, 0x47, 0x39, 0xaf, 0xe1, 0xd0, 0xe7, 0xd1, 0xdb, 0x49, 0x16, 0x7e, 0x2a, 0x0b, + 0xf7, 0xa0, 0xf5, 0x25, 0xc7, 0x23, 0x2a, 0x4d, 0x62, 0xeb, 0xfd, 0xfd, 0x60, 0x83, 0xd1, 0x02, + 0x98, 0xa7, 0x1b, 0x55, 0x53, 0x6a, 0x85, 0x71, 0xbe, 0x11, 0x75, 0x43, 0x55, 0xcf, 0xbb, 0x62, + 0xe9, 0x36, 0x9b, 0xff, 0x3d, 0x2e, 0x7c, 0x04, 0xbb, 0x4c, 0x08, 0x2e, 0x54, 0xeb, 0x6b, 0x7a, + 0xe5, 0x09, 0x11, 0x14, 0x11, 0xce, 0x53, 0xd0, 0x3d, 0x21, 0x70, 0x50, 0x66, 0xe4, 0x27, 0x77, + 0x5d, 0xb3, 0x26, 0x63, 0xc8, 0x29, 0x93, 0xeb, 0xb4, 0xc7, 0x1f, 0xa0, 0x55, 0x52, 0xd8, 0x05, + 0xb8, 0x48, 0xd9, 0x62, 0xc6, 0xc2, 0x8c, 0x51, 0xa3, 0x81, 0x07, 0xd0, 0xf6, 0x79, 0xe4, 0x2d, + 0x62, 0x99, 0x49, 0x83, 0xe0, 0x21, 0x74, 0x7c, 0x1e, 0x9d, 0xf3, 0xec, 0x25, 0x9f, 0xa7, 0xd4, + 0xd0, 0x10, 0xa1, 0x5b, 0x18, 0x1e, 0xf2, 0x74, 0x9a, 0xc4, 0x61, 0x66, 0xe8, 0x68, 0x40, 0xc7, + 0xcb, 0x0b, 0x8f, 0xa7, 0x53, 0xc9, 0x32, 0xe3, 0x5a, 0x77, 0x7f, 0x12, 0x68, 0x0f, 0x4b, 0x13, + 0xf8, 0x1c, 0x9a, 0xc5, 0x32, 0xe0, 0x71, 0xcd, 0xe0, 0x6f, 0x27, 0xdd, 0xc3, 0xbb, 0xf2, 0xf8, + 0x12, 0xcf, 0xa0, 0xbd, 0xd9, 0x08, 0xb4, 0xeb, 0x9b, 0xf7, 0x8f, 0x12, 0xe7, 0xd0, 0x2a, 0x47, + 0x85, 0x0f, 0x6a, 0x1c, 0x54, 0x97, 0xa2, 0x77, 0xbc, 0x2d, 0x40, 0x4d, 0xb9, 0x4f, 0x4e, 0xc9, + 0x0b, 0xf7, 0xfb, 0xd2, 0x22, 0x37, 0x4b, 0x8b, 0xfc, 0x5a, 0x5a, 0xe4, 0x7a, 0x65, 0x35, 0x6e, + 0x56, 0x56, 0xe3, 0xc7, 0xca, 0x6a, 0xbc, 0x37, 0xb7, 0xfd, 0xf4, 0x1f, 0x9b, 0xea, 0xf5, 0xe4, + 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfc, 0xa9, 0xeb, 0x7b, 0x17, 0x04, 0x00, 0x00, } func (m *Log) Marshal() (dAtA []byte, err error) { diff --git a/consensus/consensusproto/protos/consensus.proto b/consensus/consensusproto/protos/consensus.proto index d28cf1de..438da9f4 100644 --- a/consensus/consensusproto/protos/consensus.proto +++ b/consensus/consensusproto/protos/consensus.proto @@ -8,7 +8,7 @@ enum ErrCodes { LogExists = 1; LogNotFound = 2; RecordConflict = 3; - ErrorOffset = 300; + ErrorOffset = 400; } From 59cf8b46fd0d1b16e264566ac4d594165e407e86 Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Thu, 29 Jun 2023 14:52:47 +0200 Subject: [PATCH 099/123] consensus: change err offset --- consensus/consensusproto/consensus.pb.go | 66 +++++++++---------- .../consensusproto/protos/consensus.proto | 2 +- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/consensus/consensusproto/consensus.pb.go b/consensus/consensusproto/consensus.pb.go index e70f8b37..19361350 100644 --- a/consensus/consensusproto/consensus.pb.go +++ b/consensus/consensusproto/consensus.pb.go @@ -29,7 +29,7 @@ const ( ErrCodes_LogExists ErrCodes = 1 ErrCodes_LogNotFound ErrCodes = 2 ErrCodes_RecordConflict ErrCodes = 3 - ErrCodes_ErrorOffset ErrCodes = 400 + ErrCodes_ErrorOffset ErrCodes = 500 ) var ErrCodes_name = map[int32]string{ @@ -37,7 +37,7 @@ var ErrCodes_name = map[int32]string{ 1: "LogExists", 2: "LogNotFound", 3: "RecordConflict", - 400: "ErrorOffset", + 500: "ErrorOffset", } var ErrCodes_value = map[string]int32{ @@ -45,7 +45,7 @@ var ErrCodes_value = map[string]int32{ "LogExists": 1, "LogNotFound": 2, "RecordConflict": 3, - "ErrorOffset": 400, + "ErrorOffset": 500, } func (x ErrCodes) String() string { @@ -481,39 +481,39 @@ func init() { } var fileDescriptor_b8d7f1c16b400059 = []byte{ - // 510 bytes of a gzipped FileDescriptorProto + // 511 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x53, 0xc1, 0x6e, 0xd3, 0x40, 0x10, 0xcd, 0xda, 0x6d, 0x9a, 0x4c, 0xda, 0xd4, 0x1a, 0x50, 0x65, 0x45, 0xaa, 0xb1, 0x2c, 0x21, 0x05, 0x0e, 0x69, 0x65, 0x04, 0x17, 0x4e, 0x25, 0x32, 0x28, 0x92, 0x69, 0x90, 0xa5, 0x0a, 0xc4, - 0x89, 0xe0, 0xdd, 0x18, 0xab, 0x96, 0x37, 0xec, 0x3a, 0x25, 0x5c, 0xf9, 0x82, 0x7e, 0x16, 0xc7, - 0x1e, 0x91, 0xb8, 0xa0, 0xe4, 0x47, 0x90, 0xd7, 0x71, 0x6a, 0x8a, 0x23, 0xc4, 0xc5, 0xf6, 0x7b, - 0x6f, 0x66, 0xf6, 0xed, 0xcc, 0x18, 0x4e, 0x42, 0x9e, 0x4a, 0x96, 0xca, 0xb9, 0xbc, 0xfd, 0x9a, - 0x09, 0x9e, 0xf1, 0x13, 0xf5, 0xac, 0xb0, 0x03, 0x45, 0x60, 0x77, 0x43, 0xbc, 0xc9, 0xb1, 0xf3, - 0x0a, 0x74, 0x9f, 0x47, 0xd8, 0x05, 0x2d, 0xa6, 0x26, 0xb1, 0x49, 0x7f, 0x3f, 0xd0, 0x62, 0x8a, - 0xa7, 0xb0, 0x27, 0x58, 0xc8, 0x05, 0x95, 0xa6, 0x66, 0xeb, 0xfd, 0x8e, 0x7b, 0x34, 0xf8, 0x33, - 0x71, 0x10, 0x28, 0x39, 0x28, 0xc3, 0x9c, 0x04, 0x9a, 0x05, 0xf5, 0x57, 0xad, 0x23, 0x68, 0xce, - 0x04, 0xbb, 0x1a, 0x51, 0x53, 0x53, 0xdc, 0x1a, 0xa1, 0x09, 0x7b, 0xb3, 0xc9, 0xd7, 0x84, 0x4f, - 0xa8, 0xa9, 0x2b, 0xa1, 0x84, 0x68, 0x43, 0x27, 0x14, 0x6c, 0x92, 0x31, 0x7a, 0x91, 0xc6, 0x0b, - 0x73, 0xc7, 0x26, 0xfd, 0x9d, 0xa0, 0x4a, 0x39, 0x3b, 0xa0, 0x8d, 0x2f, 0x9d, 0x67, 0x70, 0xe0, - 0xf3, 0xe8, 0x8c, 0xd2, 0x80, 0x7d, 0x9e, 0x33, 0x99, 0xe1, 0x43, 0xd0, 0x13, 0x1e, 0xa9, 0xb3, - 0x3b, 0xee, 0xbd, 0xbb, 0x96, 0x7d, 0x1e, 0x05, 0xb9, 0xee, 0xbc, 0x03, 0xa3, 0xf0, 0x5a, 0x49, - 0xbd, 0x0f, 0xbb, 0x09, 0x8f, 0x46, 0xa5, 0xf1, 0x02, 0xe0, 0x00, 0x9a, 0xc5, 0x05, 0x95, 0xf7, - 0xed, 0x6d, 0x58, 0x47, 0x39, 0xaf, 0xe1, 0xd0, 0xe7, 0xd1, 0xdb, 0x49, 0x16, 0x7e, 0x2a, 0x0b, - 0xf7, 0xa0, 0xf5, 0x25, 0xc7, 0x23, 0x2a, 0x4d, 0x62, 0xeb, 0xfd, 0xfd, 0x60, 0x83, 0xd1, 0x02, - 0x98, 0xa7, 0x1b, 0x55, 0x53, 0x6a, 0x85, 0x71, 0xbe, 0x11, 0x75, 0x43, 0x55, 0xcf, 0xbb, 0x62, - 0xe9, 0x36, 0x9b, 0xff, 0x3d, 0x2e, 0x7c, 0x04, 0xbb, 0x4c, 0x08, 0x2e, 0x54, 0xeb, 0x6b, 0x7a, - 0xe5, 0x09, 0x11, 0x14, 0x11, 0xce, 0x53, 0xd0, 0x3d, 0x21, 0x70, 0x50, 0x66, 0xe4, 0x27, 0x77, - 0x5d, 0xb3, 0x26, 0x63, 0xc8, 0x29, 0x93, 0xeb, 0xb4, 0xc7, 0x1f, 0xa0, 0x55, 0x52, 0xd8, 0x05, - 0xb8, 0x48, 0xd9, 0x62, 0xc6, 0xc2, 0x8c, 0x51, 0xa3, 0x81, 0x07, 0xd0, 0xf6, 0x79, 0xe4, 0x2d, - 0x62, 0x99, 0x49, 0x83, 0xe0, 0x21, 0x74, 0x7c, 0x1e, 0x9d, 0xf3, 0xec, 0x25, 0x9f, 0xa7, 0xd4, - 0xd0, 0x10, 0xa1, 0x5b, 0x18, 0x1e, 0xf2, 0x74, 0x9a, 0xc4, 0x61, 0x66, 0xe8, 0x68, 0x40, 0xc7, - 0xcb, 0x0b, 0x8f, 0xa7, 0x53, 0xc9, 0x32, 0xe3, 0x5a, 0x77, 0x7f, 0x12, 0x68, 0x0f, 0x4b, 0x13, - 0xf8, 0x1c, 0x9a, 0xc5, 0x32, 0xe0, 0x71, 0xcd, 0xe0, 0x6f, 0x27, 0xdd, 0xc3, 0xbb, 0xf2, 0xf8, - 0x12, 0xcf, 0xa0, 0xbd, 0xd9, 0x08, 0xb4, 0xeb, 0x9b, 0xf7, 0x8f, 0x12, 0xe7, 0xd0, 0x2a, 0x47, - 0x85, 0x0f, 0x6a, 0x1c, 0x54, 0x97, 0xa2, 0x77, 0xbc, 0x2d, 0x40, 0x4d, 0xb9, 0x4f, 0x4e, 0xc9, - 0x0b, 0xf7, 0xfb, 0xd2, 0x22, 0x37, 0x4b, 0x8b, 0xfc, 0x5a, 0x5a, 0xe4, 0x7a, 0x65, 0x35, 0x6e, - 0x56, 0x56, 0xe3, 0xc7, 0xca, 0x6a, 0xbc, 0x37, 0xb7, 0xfd, 0xf4, 0x1f, 0x9b, 0xea, 0xf5, 0xe4, - 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfc, 0xa9, 0xeb, 0x7b, 0x17, 0x04, 0x00, 0x00, + 0x89, 0xe0, 0xdd, 0x18, 0xab, 0x96, 0x37, 0xec, 0x3a, 0x25, 0x5c, 0xf9, 0x02, 0x3e, 0x8b, 0x63, + 0x8f, 0x48, 0x5c, 0x50, 0xf2, 0x0b, 0x7c, 0x00, 0xf2, 0x3a, 0x4e, 0x4d, 0x71, 0x84, 0xb8, 0xd8, + 0x7e, 0xef, 0xcd, 0xcc, 0xbe, 0x9d, 0x19, 0xc3, 0x49, 0xc8, 0x53, 0xc9, 0x52, 0x39, 0x97, 0x37, + 0x5f, 0x33, 0xc1, 0x33, 0x7e, 0xa2, 0x9e, 0x15, 0x76, 0xa0, 0x08, 0xec, 0x6e, 0x88, 0x57, 0x39, + 0x76, 0x5e, 0x80, 0xee, 0xf3, 0x08, 0xbb, 0xa0, 0xc5, 0xd4, 0x24, 0x36, 0xe9, 0xef, 0x07, 0x5a, + 0x4c, 0xf1, 0x14, 0xf6, 0x04, 0x0b, 0xb9, 0xa0, 0xd2, 0xd4, 0x6c, 0xbd, 0xdf, 0x71, 0x8f, 0x06, + 0x7f, 0x26, 0x0e, 0x02, 0x25, 0x07, 0x65, 0x98, 0x93, 0x40, 0xb3, 0xa0, 0xfe, 0xaa, 0x75, 0x04, + 0xcd, 0x99, 0x60, 0x57, 0x23, 0x6a, 0x6a, 0x8a, 0x5b, 0x23, 0x34, 0x61, 0x6f, 0x36, 0xf9, 0x9c, + 0xf0, 0x09, 0x35, 0x75, 0x25, 0x94, 0x10, 0x6d, 0xe8, 0x84, 0x82, 0x4d, 0x32, 0x46, 0x2f, 0xd2, + 0x78, 0x61, 0xee, 0xd8, 0xa4, 0xbf, 0x13, 0x54, 0x29, 0x67, 0x07, 0xb4, 0xf1, 0xa5, 0xf3, 0x04, + 0x0e, 0x7c, 0x1e, 0x9d, 0x51, 0x1a, 0xb0, 0x8f, 0x73, 0x26, 0x33, 0xbc, 0x0f, 0x7a, 0xc2, 0x23, + 0x75, 0x76, 0xc7, 0xbd, 0x73, 0xdb, 0xb2, 0xcf, 0xa3, 0x20, 0xd7, 0x9d, 0x37, 0x60, 0x14, 0x5e, + 0x2b, 0xa9, 0x77, 0x61, 0x37, 0xe1, 0xd1, 0xa8, 0x34, 0x5e, 0x00, 0x1c, 0x40, 0xb3, 0xb8, 0xa0, + 0xf2, 0xbe, 0xbd, 0x0d, 0xeb, 0x28, 0xe7, 0x25, 0x1c, 0xfa, 0x3c, 0x7a, 0x3d, 0xc9, 0xc2, 0x0f, + 0x65, 0xe1, 0x1e, 0xb4, 0x3e, 0xe5, 0x78, 0x44, 0xa5, 0x49, 0x6c, 0xbd, 0xbf, 0x1f, 0x6c, 0x30, + 0x5a, 0x00, 0xf3, 0x74, 0xa3, 0x6a, 0x4a, 0xad, 0x30, 0xce, 0x17, 0xa2, 0x6e, 0xa8, 0xea, 0x79, + 0x57, 0x2c, 0xdd, 0x66, 0xf3, 0xbf, 0xc7, 0x85, 0x0f, 0x60, 0x97, 0x09, 0xc1, 0x85, 0x6a, 0x7d, + 0x4d, 0xaf, 0x3c, 0x21, 0x82, 0x22, 0xc2, 0x79, 0x0c, 0xba, 0x27, 0x04, 0x0e, 0xca, 0x8c, 0xfc, + 0xe4, 0xae, 0x6b, 0xd6, 0x64, 0x0c, 0x39, 0x65, 0x72, 0x9d, 0xf6, 0xf0, 0x1d, 0xb4, 0x4a, 0x0a, + 0xbb, 0x00, 0x17, 0x29, 0x5b, 0xcc, 0x58, 0x98, 0x31, 0x6a, 0x34, 0xf0, 0x00, 0xda, 0x3e, 0x8f, + 0xbc, 0x45, 0x2c, 0x33, 0x69, 0x10, 0x3c, 0x84, 0x8e, 0xcf, 0xa3, 0x73, 0x9e, 0x3d, 0xe7, 0xf3, + 0x94, 0x1a, 0x1a, 0x22, 0x74, 0x0b, 0xc3, 0x43, 0x9e, 0x4e, 0x93, 0x38, 0xcc, 0x0c, 0x1d, 0x0d, + 0xe8, 0x78, 0x79, 0xe1, 0xf1, 0x74, 0x2a, 0x59, 0x66, 0xfc, 0xd2, 0xdd, 0x1f, 0x04, 0xda, 0xc3, + 0xd2, 0x04, 0x3e, 0x85, 0x66, 0xb1, 0x0c, 0x78, 0x5c, 0x33, 0xf8, 0x9b, 0x49, 0xf7, 0xf0, 0xb6, + 0x3c, 0xbe, 0xc4, 0x33, 0x68, 0x6f, 0x36, 0x02, 0xed, 0xfa, 0xe6, 0xfd, 0xa3, 0xc4, 0x39, 0xb4, + 0xca, 0x51, 0xe1, 0xbd, 0x1a, 0x07, 0xd5, 0xa5, 0xe8, 0x1d, 0x6f, 0x0b, 0x50, 0x53, 0xee, 0x93, + 0x53, 0xf2, 0xcc, 0xfd, 0xb6, 0xb4, 0xc8, 0xf5, 0xd2, 0x22, 0x3f, 0x97, 0x16, 0xf9, 0xba, 0xb2, + 0x1a, 0xd7, 0x2b, 0xab, 0xf1, 0x7d, 0x65, 0x35, 0xde, 0x9a, 0xdb, 0x7e, 0xfa, 0xf7, 0x4d, 0xf5, + 0x7a, 0xf4, 0x3b, 0x00, 0x00, 0xff, 0xff, 0xc1, 0x7f, 0xa3, 0x95, 0x17, 0x04, 0x00, 0x00, } func (m *Log) Marshal() (dAtA []byte, err error) { diff --git a/consensus/consensusproto/protos/consensus.proto b/consensus/consensusproto/protos/consensus.proto index 438da9f4..6be8103c 100644 --- a/consensus/consensusproto/protos/consensus.proto +++ b/consensus/consensusproto/protos/consensus.proto @@ -8,7 +8,7 @@ enum ErrCodes { LogExists = 1; LogNotFound = 2; RecordConflict = 3; - ErrorOffset = 400; + ErrorOffset = 500; } From 92cbfb1cb39e00f3bfab9994fba6bf175d448110 Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Fri, 30 Jun 2023 19:42:07 +0200 Subject: [PATCH 100/123] change consensus proto and client --- consensus/consensusclient/client.go | 11 +- consensus/consensusclient/client_test.go | 15 +- .../mock_consensusclient.go | 7 +- consensus/consensusproto/consensus.pb.go | 837 +++++++++++++++--- consensus/consensusproto/consensus_drpc.pb.go | 14 +- .../consensusproto/protos/consensus.proto | 35 +- 6 files changed, 779 insertions(+), 140 deletions(-) diff --git a/consensus/consensusclient/client.go b/consensus/consensusclient/client.go index cd3c411a..ff5882a7 100644 --- a/consensus/consensusclient/client.go +++ b/consensus/consensusclient/client.go @@ -30,7 +30,7 @@ func New() Service { // Watcher watches new events by specified logId type Watcher interface { - AddConsensusRecords(recs []*consensusproto.Record) + AddConsensusRecords(recs []*consensusproto.RawRecordWithId) AddConsensusError(err error) } @@ -38,7 +38,7 @@ 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) + AddRecord(ctx context.Context, logId []byte, clog *consensusproto.RawRecord) (record *consensusproto.RawRecordWithId, 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 @@ -97,9 +97,9 @@ func (s *service) AddLog(ctx context.Context, clog *consensusproto.Log) (err err }) } -func (s *service) AddRecord(ctx context.Context, logId []byte, clog *consensusproto.Record) (err error) { - return s.doClient(ctx, func(cl consensusproto.DRPCConsensusClient) error { - if _, err = cl.RecordAdd(ctx, &consensusproto.RecordAddRequest{ +func (s *service) AddRecord(ctx context.Context, logId []byte, clog *consensusproto.RawRecord) (record *consensusproto.RawRecordWithId, err error) { + err = s.doClient(ctx, func(cl consensusproto.DRPCConsensusClient) error { + if record, err = cl.RecordAdd(ctx, &consensusproto.RecordAddRequest{ LogId: logId, Record: clog, }); err != nil { @@ -107,6 +107,7 @@ func (s *service) AddRecord(ctx context.Context, logId []byte, clog *consensuspr } return nil }) + return } func (s *service) Watch(logId []byte, w Watcher) (err error) { diff --git a/consensus/consensusclient/client_test.go b/consensus/consensusclient/client_test.go index a212a635..fd21695c 100644 --- a/consensus/consensusclient/client_test.go +++ b/consensus/consensusclient/client_test.go @@ -11,6 +11,7 @@ import ( "github.com/anyproto/any-sync/nodeconf" "github.com/anyproto/any-sync/nodeconf/mock_nodeconf" "github.com/anyproto/any-sync/testutil/accounttest" + "github.com/anyproto/any-sync/util/cidutil" "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -118,7 +119,9 @@ func TestService_AddLog(t *testing.T) { func TestService_AddRecord(t *testing.T) { fx := newFixture(t).run(t) defer fx.Finish() - assert.NoError(t, fx.AddRecord(ctx, []byte{'1'}, &consensusproto.Record{})) + rec, err := fx.AddRecord(ctx, []byte{'1'}, &consensusproto.RawRecord{}) + require.NoError(t, err) + assert.NotEmpty(t, rec) } var ctx = context.Background() @@ -186,13 +189,15 @@ func (t *testServer) LogAdd(ctx context.Context, req *consensusproto.LogAddReque return &consensusproto.Ok{}, nil } -func (t *testServer) RecordAdd(ctx context.Context, req *consensusproto.RecordAddRequest) (*consensusproto.Ok, error) { +func (t *testServer) RecordAdd(ctx context.Context, req *consensusproto.RecordAddRequest) (*consensusproto.RawRecordWithId, error) { if t.addRecord != nil { if err := t.addRecord(ctx, req); err != nil { return nil, err } } - return &consensusproto.Ok{}, nil + data, _ := req.Record.Marshal() + id, _ := cidutil.NewCidFromBytes(data) + return &consensusproto.RawRecordWithId{Id: id, Payload: data}, nil } func (t *testServer) LogWatch(stream consensusproto.DRPCConsensus_LogWatchStream) error { @@ -215,13 +220,13 @@ func (t *testServer) waitStream(test *testing.T) consensusproto.DRPCConsensus_Lo } type testWatcher struct { - recs [][]*consensusproto.Record + recs [][]*consensusproto.RawRecordWithId err error ready chan struct{} once sync.Once } -func (t *testWatcher) AddConsensusRecords(recs []*consensusproto.Record) { +func (t *testWatcher) AddConsensusRecords(recs []*consensusproto.RawRecordWithId) { t.recs = append(t.recs, recs) 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 index f97c1c4f..95087515 100644 --- a/consensus/consensusclient/mock_consensusclient/mock_consensusclient.go +++ b/consensus/consensusclient/mock_consensusclient/mock_consensusclient.go @@ -52,11 +52,12 @@ func (mr *MockServiceMockRecorder) AddLog(arg0, arg1 interface{}) *gomock.Call { } // AddRecord mocks base method. -func (m *MockService) AddRecord(arg0 context.Context, arg1 []byte, arg2 *consensusproto.Record) error { +func (m *MockService) AddRecord(arg0 context.Context, arg1 []byte, arg2 *consensusproto.RawRecord) (*consensusproto.RawRecordWithId, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AddRecord", arg0, arg1, arg2) - ret0, _ := ret[0].(error) - return ret0 + ret0, _ := ret[0].(*consensusproto.RawRecordWithId) + ret1, _ := ret[1].(error) + return ret0, ret1 } // AddRecord indicates an expected call of AddRecord. diff --git a/consensus/consensusproto/consensus.pb.go b/consensus/consensusproto/consensus.pb.go index 19361350..4e81e61c 100644 --- a/consensus/consensusproto/consensus.pb.go +++ b/consensus/consensusproto/consensus.pb.go @@ -57,8 +57,9 @@ func (ErrCodes) EnumDescriptor() ([]byte, []int) { } 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"` + Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Payload []byte `protobuf:"bytes,2,opt,name=payload,proto3" json:"payload,omitempty"` + Records []*RawRecordWithId `protobuf:"bytes,3,rep,name=records,proto3" json:"records,omitempty"` } func (m *Log) Reset() { *m = Log{} } @@ -101,25 +102,155 @@ func (m *Log) GetId() []byte { return nil } -func (m *Log) GetRecords() []*Record { +func (m *Log) GetPayload() []byte { + if m != nil { + return m.Payload + } + return nil +} + +func (m *Log) GetRecords() []*RawRecordWithId { if m != nil { return m.Records } return nil } +// RawRecord is a proto message containing the payload in bytes, signature of the account who added it and signature of the acceptor +type RawRecord 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 *RawRecord) Reset() { *m = RawRecord{} } +func (m *RawRecord) String() string { return proto.CompactTextString(m) } +func (*RawRecord) ProtoMessage() {} +func (*RawRecord) Descriptor() ([]byte, []int) { + return fileDescriptor_b8d7f1c16b400059, []int{1} +} +func (m *RawRecord) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RawRecord) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RawRecord.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 *RawRecord) XXX_Merge(src proto.Message) { + xxx_messageInfo_RawRecord.Merge(m, src) +} +func (m *RawRecord) XXX_Size() int { + return m.Size() +} +func (m *RawRecord) XXX_DiscardUnknown() { + xxx_messageInfo_RawRecord.DiscardUnknown(m) +} + +var xxx_messageInfo_RawRecord proto.InternalMessageInfo + +func (m *RawRecord) GetPayload() []byte { + if m != nil { + return m.Payload + } + return nil +} + +func (m *RawRecord) GetSignature() []byte { + if m != nil { + return m.Signature + } + return nil +} + +func (m *RawRecord) GetAcceptorIdentity() []byte { + if m != nil { + return m.AcceptorIdentity + } + return nil +} + +func (m *RawRecord) GetAcceptorSignature() []byte { + if m != nil { + return m.AcceptorSignature + } + return nil +} + +// RawRecordWithId is a raw record and the id for convenience +type RawRecordWithId 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 *RawRecordWithId) Reset() { *m = RawRecordWithId{} } +func (m *RawRecordWithId) String() string { return proto.CompactTextString(m) } +func (*RawRecordWithId) ProtoMessage() {} +func (*RawRecordWithId) Descriptor() ([]byte, []int) { + return fileDescriptor_b8d7f1c16b400059, []int{2} +} +func (m *RawRecordWithId) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RawRecordWithId) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RawRecordWithId.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 *RawRecordWithId) XXX_Merge(src proto.Message) { + xxx_messageInfo_RawRecordWithId.Merge(m, src) +} +func (m *RawRecordWithId) XXX_Size() int { + return m.Size() +} +func (m *RawRecordWithId) XXX_DiscardUnknown() { + xxx_messageInfo_RawRecordWithId.DiscardUnknown(m) +} + +var xxx_messageInfo_RawRecordWithId proto.InternalMessageInfo + +func (m *RawRecordWithId) GetPayload() []byte { + if m != nil { + return m.Payload + } + return nil +} + +func (m *RawRecordWithId) GetId() string { + if m != nil { + return m.Id + } + return "" +} + +// Record is a record containing a data 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"` + 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"` + Timestamp int64 `protobuf:"varint,4,opt,name=timestamp,proto3" json:"timestamp,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_b8d7f1c16b400059, []int{1} + return fileDescriptor_b8d7f1c16b400059, []int{3} } func (m *Record) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -148,30 +279,30 @@ func (m *Record) XXX_DiscardUnknown() { var xxx_messageInfo_Record proto.InternalMessageInfo -func (m *Record) GetId() []byte { - if m != nil { - return m.Id - } - return nil -} - -func (m *Record) GetPrevId() []byte { +func (m *Record) GetPrevId() string { if m != nil { return m.PrevId } - return nil + return "" } -func (m *Record) GetPayload() []byte { +func (m *Record) GetIdentity() []byte { if m != nil { - return m.Payload + return m.Identity } return nil } -func (m *Record) GetCreatedUnix() uint64 { +func (m *Record) GetData() []byte { if m != nil { - return m.CreatedUnix + return m.Data + } + return nil +} + +func (m *Record) GetTimestamp() int64 { + if m != nil { + return m.Timestamp } return 0 } @@ -183,7 +314,7 @@ 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_b8d7f1c16b400059, []int{2} + return fileDescriptor_b8d7f1c16b400059, []int{4} } func (m *Ok) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -220,7 +351,7 @@ func (m *LogAddRequest) Reset() { *m = LogAddRequest{} } func (m *LogAddRequest) String() string { return proto.CompactTextString(m) } func (*LogAddRequest) ProtoMessage() {} func (*LogAddRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_b8d7f1c16b400059, []int{3} + return fileDescriptor_b8d7f1c16b400059, []int{5} } func (m *LogAddRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -257,15 +388,15 @@ func (m *LogAddRequest) GetLog() *Log { } type RecordAddRequest 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"` + LogId []byte `protobuf:"bytes,1,opt,name=logId,proto3" json:"logId,omitempty"` + Record *RawRecord `protobuf:"bytes,2,opt,name=record,proto3" json:"record,omitempty"` } func (m *RecordAddRequest) Reset() { *m = RecordAddRequest{} } func (m *RecordAddRequest) String() string { return proto.CompactTextString(m) } func (*RecordAddRequest) ProtoMessage() {} func (*RecordAddRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_b8d7f1c16b400059, []int{4} + return fileDescriptor_b8d7f1c16b400059, []int{6} } func (m *RecordAddRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -301,7 +432,7 @@ func (m *RecordAddRequest) GetLogId() []byte { return nil } -func (m *RecordAddRequest) GetRecord() *Record { +func (m *RecordAddRequest) GetRecord() *RawRecord { if m != nil { return m.Record } @@ -317,7 +448,7 @@ func (m *LogWatchRequest) Reset() { *m = LogWatchRequest{} } func (m *LogWatchRequest) String() string { return proto.CompactTextString(m) } func (*LogWatchRequest) ProtoMessage() {} func (*LogWatchRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_b8d7f1c16b400059, []int{5} + return fileDescriptor_b8d7f1c16b400059, []int{7} } func (m *LogWatchRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -361,16 +492,16 @@ func (m *LogWatchRequest) GetUnwatchIds() [][]byte { } type LogWatchEvent 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"` + LogId []byte `protobuf:"bytes,1,opt,name=logId,proto3" json:"logId,omitempty"` + Records []*RawRecordWithId `protobuf:"bytes,2,rep,name=records,proto3" json:"records,omitempty"` + Error *Err `protobuf:"bytes,3,opt,name=error,proto3" json:"error,omitempty"` } func (m *LogWatchEvent) Reset() { *m = LogWatchEvent{} } func (m *LogWatchEvent) String() string { return proto.CompactTextString(m) } func (*LogWatchEvent) ProtoMessage() {} func (*LogWatchEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_b8d7f1c16b400059, []int{6} + return fileDescriptor_b8d7f1c16b400059, []int{8} } func (m *LogWatchEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -406,7 +537,7 @@ func (m *LogWatchEvent) GetLogId() []byte { return nil } -func (m *LogWatchEvent) GetRecords() []*Record { +func (m *LogWatchEvent) GetRecords() []*RawRecordWithId { if m != nil { return m.Records } @@ -428,7 +559,7 @@ 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_b8d7f1c16b400059, []int{7} + return fileDescriptor_b8d7f1c16b400059, []int{9} } func (m *Err) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -467,6 +598,8 @@ func (m *Err) GetError() ErrCodes { func init() { proto.RegisterEnum("consensusProto.ErrCodes", ErrCodes_name, ErrCodes_value) proto.RegisterType((*Log)(nil), "consensusProto.Log") + proto.RegisterType((*RawRecord)(nil), "consensusProto.RawRecord") + proto.RegisterType((*RawRecordWithId)(nil), "consensusProto.RawRecordWithId") proto.RegisterType((*Record)(nil), "consensusProto.Record") proto.RegisterType((*Ok)(nil), "consensusProto.Ok") proto.RegisterType((*LogAddRequest)(nil), "consensusProto.LogAddRequest") @@ -481,39 +614,46 @@ func init() { } var fileDescriptor_b8d7f1c16b400059 = []byte{ - // 511 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x53, 0xc1, 0x6e, 0xd3, 0x40, - 0x10, 0xcd, 0xda, 0x6d, 0x9a, 0x4c, 0xda, 0xd4, 0x1a, 0x50, 0x65, 0x45, 0xaa, 0xb1, 0x2c, 0x21, - 0x05, 0x0e, 0x69, 0x65, 0x04, 0x17, 0x4e, 0x25, 0x32, 0x28, 0x92, 0x69, 0x90, 0xa5, 0x0a, 0xc4, - 0x89, 0xe0, 0xdd, 0x18, 0xab, 0x96, 0x37, 0xec, 0x3a, 0x25, 0x5c, 0xf9, 0x02, 0x3e, 0x8b, 0x63, - 0x8f, 0x48, 0x5c, 0x50, 0xf2, 0x0b, 0x7c, 0x00, 0xf2, 0x3a, 0x4e, 0x4d, 0x71, 0x84, 0xb8, 0xd8, - 0x7e, 0xef, 0xcd, 0xcc, 0xbe, 0x9d, 0x19, 0xc3, 0x49, 0xc8, 0x53, 0xc9, 0x52, 0x39, 0x97, 0x37, - 0x5f, 0x33, 0xc1, 0x33, 0x7e, 0xa2, 0x9e, 0x15, 0x76, 0xa0, 0x08, 0xec, 0x6e, 0x88, 0x57, 0x39, - 0x76, 0x5e, 0x80, 0xee, 0xf3, 0x08, 0xbb, 0xa0, 0xc5, 0xd4, 0x24, 0x36, 0xe9, 0xef, 0x07, 0x5a, - 0x4c, 0xf1, 0x14, 0xf6, 0x04, 0x0b, 0xb9, 0xa0, 0xd2, 0xd4, 0x6c, 0xbd, 0xdf, 0x71, 0x8f, 0x06, - 0x7f, 0x26, 0x0e, 0x02, 0x25, 0x07, 0x65, 0x98, 0x93, 0x40, 0xb3, 0xa0, 0xfe, 0xaa, 0x75, 0x04, - 0xcd, 0x99, 0x60, 0x57, 0x23, 0x6a, 0x6a, 0x8a, 0x5b, 0x23, 0x34, 0x61, 0x6f, 0x36, 0xf9, 0x9c, - 0xf0, 0x09, 0x35, 0x75, 0x25, 0x94, 0x10, 0x6d, 0xe8, 0x84, 0x82, 0x4d, 0x32, 0x46, 0x2f, 0xd2, - 0x78, 0x61, 0xee, 0xd8, 0xa4, 0xbf, 0x13, 0x54, 0x29, 0x67, 0x07, 0xb4, 0xf1, 0xa5, 0xf3, 0x04, - 0x0e, 0x7c, 0x1e, 0x9d, 0x51, 0x1a, 0xb0, 0x8f, 0x73, 0x26, 0x33, 0xbc, 0x0f, 0x7a, 0xc2, 0x23, - 0x75, 0x76, 0xc7, 0xbd, 0x73, 0xdb, 0xb2, 0xcf, 0xa3, 0x20, 0xd7, 0x9d, 0x37, 0x60, 0x14, 0x5e, - 0x2b, 0xa9, 0x77, 0x61, 0x37, 0xe1, 0xd1, 0xa8, 0x34, 0x5e, 0x00, 0x1c, 0x40, 0xb3, 0xb8, 0xa0, - 0xf2, 0xbe, 0xbd, 0x0d, 0xeb, 0x28, 0xe7, 0x25, 0x1c, 0xfa, 0x3c, 0x7a, 0x3d, 0xc9, 0xc2, 0x0f, - 0x65, 0xe1, 0x1e, 0xb4, 0x3e, 0xe5, 0x78, 0x44, 0xa5, 0x49, 0x6c, 0xbd, 0xbf, 0x1f, 0x6c, 0x30, - 0x5a, 0x00, 0xf3, 0x74, 0xa3, 0x6a, 0x4a, 0xad, 0x30, 0xce, 0x17, 0xa2, 0x6e, 0xa8, 0xea, 0x79, - 0x57, 0x2c, 0xdd, 0x66, 0xf3, 0xbf, 0xc7, 0x85, 0x0f, 0x60, 0x97, 0x09, 0xc1, 0x85, 0x6a, 0x7d, - 0x4d, 0xaf, 0x3c, 0x21, 0x82, 0x22, 0xc2, 0x79, 0x0c, 0xba, 0x27, 0x04, 0x0e, 0xca, 0x8c, 0xfc, - 0xe4, 0xae, 0x6b, 0xd6, 0x64, 0x0c, 0x39, 0x65, 0x72, 0x9d, 0xf6, 0xf0, 0x1d, 0xb4, 0x4a, 0x0a, - 0xbb, 0x00, 0x17, 0x29, 0x5b, 0xcc, 0x58, 0x98, 0x31, 0x6a, 0x34, 0xf0, 0x00, 0xda, 0x3e, 0x8f, - 0xbc, 0x45, 0x2c, 0x33, 0x69, 0x10, 0x3c, 0x84, 0x8e, 0xcf, 0xa3, 0x73, 0x9e, 0x3d, 0xe7, 0xf3, - 0x94, 0x1a, 0x1a, 0x22, 0x74, 0x0b, 0xc3, 0x43, 0x9e, 0x4e, 0x93, 0x38, 0xcc, 0x0c, 0x1d, 0x0d, - 0xe8, 0x78, 0x79, 0xe1, 0xf1, 0x74, 0x2a, 0x59, 0x66, 0xfc, 0xd2, 0xdd, 0x1f, 0x04, 0xda, 0xc3, - 0xd2, 0x04, 0x3e, 0x85, 0x66, 0xb1, 0x0c, 0x78, 0x5c, 0x33, 0xf8, 0x9b, 0x49, 0xf7, 0xf0, 0xb6, - 0x3c, 0xbe, 0xc4, 0x33, 0x68, 0x6f, 0x36, 0x02, 0xed, 0xfa, 0xe6, 0xfd, 0xa3, 0xc4, 0x39, 0xb4, - 0xca, 0x51, 0xe1, 0xbd, 0x1a, 0x07, 0xd5, 0xa5, 0xe8, 0x1d, 0x6f, 0x0b, 0x50, 0x53, 0xee, 0x93, - 0x53, 0xf2, 0xcc, 0xfd, 0xb6, 0xb4, 0xc8, 0xf5, 0xd2, 0x22, 0x3f, 0x97, 0x16, 0xf9, 0xba, 0xb2, - 0x1a, 0xd7, 0x2b, 0xab, 0xf1, 0x7d, 0x65, 0x35, 0xde, 0x9a, 0xdb, 0x7e, 0xfa, 0xf7, 0x4d, 0xf5, - 0x7a, 0xf4, 0x3b, 0x00, 0x00, 0xff, 0xff, 0xc1, 0x7f, 0xa3, 0x95, 0x17, 0x04, 0x00, 0x00, + // 618 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xcf, 0x6e, 0xd3, 0x4e, + 0x10, 0xce, 0xda, 0x6d, 0x1a, 0x4f, 0x7e, 0x4d, 0xfd, 0x1b, 0x10, 0x32, 0x11, 0x75, 0x23, 0x4b, + 0x48, 0xa5, 0x42, 0x29, 0x04, 0x81, 0x84, 0x7a, 0x82, 0x2a, 0x48, 0x91, 0x42, 0x8b, 0x8c, 0x50, + 0x25, 0xb8, 0x60, 0xbc, 0x5b, 0xd7, 0x34, 0xf5, 0x86, 0xdd, 0x4d, 0xff, 0x3c, 0x03, 0x17, 0x5e, + 0x80, 0xf7, 0xe1, 0xd8, 0x23, 0x47, 0xd4, 0x5e, 0x78, 0x00, 0x1e, 0x00, 0x79, 0x1d, 0x3b, 0x6e, + 0x9a, 0x80, 0xb8, 0x24, 0x3b, 0xdf, 0xfc, 0xfb, 0x66, 0xe6, 0x93, 0x61, 0x33, 0xe4, 0x89, 0x64, + 0x89, 0x1c, 0xc9, 0xc9, 0x6b, 0x28, 0xb8, 0xe2, 0x9b, 0xfa, 0xb7, 0x84, 0xb6, 0x35, 0x80, 0x8d, + 0x02, 0x78, 0x95, 0xda, 0xde, 0x47, 0x30, 0xfb, 0x3c, 0xc2, 0x06, 0x18, 0x31, 0x75, 0x48, 0x8b, + 0xac, 0xff, 0xe7, 0x1b, 0x31, 0x45, 0x07, 0x96, 0x86, 0xc1, 0xd9, 0x80, 0x07, 0xd4, 0x31, 0x34, + 0x98, 0x9b, 0xf8, 0x14, 0x96, 0x04, 0x0b, 0xb9, 0xa0, 0xd2, 0x31, 0x5b, 0xe6, 0x7a, 0xbd, 0xb3, + 0xd6, 0xbe, 0x5a, 0xb2, 0xed, 0x07, 0x27, 0xbe, 0x8e, 0xd8, 0x8b, 0xd5, 0x41, 0x8f, 0xfa, 0x79, + 0xbc, 0xf7, 0x95, 0x80, 0x55, 0x38, 0xcb, 0x2d, 0xc8, 0xd5, 0x16, 0x77, 0xc0, 0x92, 0x71, 0x94, + 0x04, 0x6a, 0x24, 0xd8, 0xb8, 0xfd, 0x04, 0xc0, 0x0d, 0xb0, 0x83, 0x30, 0x64, 0x43, 0xc5, 0x45, + 0x8f, 0xb2, 0x44, 0xc5, 0xea, 0xcc, 0x31, 0x75, 0xd0, 0x35, 0x1c, 0xef, 0xc3, 0xff, 0x39, 0xf6, + 0xba, 0xa8, 0xb8, 0xa0, 0x83, 0xaf, 0x3b, 0xbc, 0x2d, 0x58, 0x99, 0xe2, 0xfe, 0x07, 0x92, 0xd9, + 0xc6, 0x52, 0x76, 0x56, 0xba, 0x31, 0x2f, 0x81, 0xea, 0x78, 0xb0, 0x5b, 0x50, 0x1d, 0x0a, 0x76, + 0xdc, 0xcb, 0x52, 0x2c, 0x7f, 0x6c, 0x61, 0x13, 0x6a, 0x71, 0x4e, 0x38, 0x9b, 0xaa, 0xb0, 0x11, + 0x61, 0x81, 0x06, 0x2a, 0x18, 0x0f, 0xa2, 0xdf, 0xe9, 0x1a, 0x54, 0x7c, 0xc4, 0xa4, 0x0a, 0x8e, + 0x86, 0x9a, 0xb4, 0xe9, 0x4f, 0x00, 0x6f, 0x01, 0x8c, 0xdd, 0x43, 0xef, 0x09, 0x2c, 0xf7, 0x79, + 0xf4, 0x8c, 0x52, 0x9f, 0x7d, 0x1a, 0x31, 0xa9, 0xf0, 0x2e, 0x98, 0x03, 0x1e, 0xe9, 0xce, 0xf5, + 0xce, 0x8d, 0xe9, 0xd3, 0xf4, 0x79, 0xe4, 0xa7, 0x7e, 0xef, 0x1d, 0xd8, 0x19, 0xdb, 0x52, 0xea, + 0x4d, 0x58, 0x1c, 0xf0, 0xa8, 0x97, 0x4f, 0x9a, 0x19, 0xf8, 0x10, 0xaa, 0xd9, 0xfd, 0x34, 0xe7, + 0x7a, 0xe7, 0xf6, 0xdc, 0x73, 0xfb, 0xe3, 0x40, 0xef, 0x25, 0xac, 0xf4, 0x79, 0xb4, 0x17, 0xa8, + 0xf0, 0x20, 0xaf, 0xdd, 0x84, 0xda, 0x49, 0x6a, 0xf7, 0xa8, 0x74, 0x48, 0xcb, 0x4c, 0x67, 0xcf, + 0x6d, 0x74, 0x01, 0x46, 0x49, 0xe1, 0x35, 0xb4, 0xb7, 0x84, 0x78, 0x9f, 0x89, 0x1e, 0x52, 0xd7, + 0xeb, 0x1e, 0xb3, 0x64, 0x1e, 0xd3, 0x92, 0x32, 0x8d, 0x7f, 0x53, 0x26, 0xde, 0x83, 0x45, 0x26, + 0x04, 0x17, 0x7a, 0xff, 0x33, 0xf6, 0xd6, 0x15, 0xc2, 0xcf, 0x22, 0xbc, 0xc7, 0x60, 0x76, 0x85, + 0xc0, 0x76, 0x9e, 0x91, 0x52, 0x68, 0x74, 0x9c, 0x19, 0x19, 0xdb, 0x9c, 0x32, 0x39, 0x4e, 0xdb, + 0x78, 0x0f, 0xb5, 0x1c, 0xc2, 0x06, 0xc0, 0x9b, 0x84, 0x9d, 0x0e, 0x59, 0xa8, 0x18, 0xb5, 0x2b, + 0xb8, 0x0c, 0x56, 0x9f, 0x47, 0xdd, 0xd3, 0x58, 0x2a, 0x69, 0x13, 0x5c, 0x81, 0x7a, 0x9f, 0x47, + 0x3b, 0x5c, 0xbd, 0xe0, 0xa3, 0x84, 0xda, 0x06, 0x22, 0x34, 0x32, 0xda, 0xdb, 0x3c, 0xd9, 0x1f, + 0xc4, 0xa1, 0xb2, 0x4d, 0xb4, 0xa1, 0xde, 0x4d, 0x0b, 0xef, 0xee, 0xef, 0x4b, 0xa6, 0xec, 0x5f, + 0x66, 0xe7, 0x27, 0x01, 0x6b, 0x3b, 0x27, 0x81, 0x5b, 0x50, 0xcd, 0x84, 0x81, 0xab, 0x33, 0x44, + 0x30, 0xb9, 0x7a, 0x13, 0xa7, 0xdd, 0xbb, 0x87, 0xb8, 0x03, 0x56, 0xa1, 0x0e, 0x6c, 0x5d, 0xdb, + 0xe2, 0x94, 0x70, 0x9a, 0x7f, 0xdb, 0x33, 0xee, 0x40, 0x2d, 0x3f, 0x20, 0xae, 0xcd, 0xa0, 0x53, + 0x96, 0x4a, 0x73, 0x75, 0x5e, 0x80, 0xbe, 0xfd, 0x3a, 0x79, 0x40, 0x9e, 0x77, 0xbe, 0x5d, 0xb8, + 0xe4, 0xfc, 0xc2, 0x25, 0x3f, 0x2e, 0x5c, 0xf2, 0xe5, 0xd2, 0xad, 0x9c, 0x5f, 0xba, 0x95, 0xef, + 0x97, 0x6e, 0xe5, 0xad, 0x33, 0xef, 0x7b, 0xf8, 0xa1, 0xaa, 0xff, 0x1e, 0xfd, 0x0e, 0x00, 0x00, + 0xff, 0xff, 0xbc, 0x83, 0xcb, 0xc1, 0x32, 0x05, 0x00, 0x00, } func (m *Log) Marshal() (dAtA []byte, err error) { @@ -547,9 +687,16 @@ func (m *Log) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintConsensus(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x12 + dAtA[i] = 0x1a } } + 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] = 0x12 + } if len(m.Id) > 0 { i -= len(m.Id) copy(dAtA[i:], m.Id) @@ -560,6 +707,94 @@ func (m *Log) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *RawRecord) 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 *RawRecord) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RawRecord) 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 = encodeVarintConsensus(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 = encodeVarintConsensus(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 = encodeVarintConsensus(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 = encodeVarintConsensus(dAtA, i, uint64(len(m.Payload))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *RawRecordWithId) 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 *RawRecordWithId) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RawRecordWithId) 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 = encodeVarintConsensus(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 = encodeVarintConsensus(dAtA, i, uint64(len(m.Payload))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *Record) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -580,30 +815,30 @@ func (m *Record) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.CreatedUnix != 0 { - i = encodeVarintConsensus(dAtA, i, uint64(m.CreatedUnix)) + if m.Timestamp != 0 { + i = encodeVarintConsensus(dAtA, i, uint64(m.Timestamp)) 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))) + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = encodeVarintConsensus(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 = encodeVarintConsensus(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 = 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 @@ -855,6 +1090,10 @@ func (m *Log) Size() (n int) { if l > 0 { n += 1 + l + sovConsensus(uint64(l)) } + l = len(m.Payload) + if l > 0 { + n += 1 + l + sovConsensus(uint64(l)) + } if len(m.Records) > 0 { for _, e := range m.Records { l = e.Size() @@ -864,26 +1103,68 @@ func (m *Log) Size() (n int) { return n } +func (m *RawRecord) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Payload) + if l > 0 { + n += 1 + l + sovConsensus(uint64(l)) + } + l = len(m.Signature) + if l > 0 { + n += 1 + l + sovConsensus(uint64(l)) + } + l = len(m.AcceptorIdentity) + if l > 0 { + n += 1 + l + sovConsensus(uint64(l)) + } + l = len(m.AcceptorSignature) + if l > 0 { + n += 1 + l + sovConsensus(uint64(l)) + } + return n +} + +func (m *RawRecordWithId) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Payload) + if l > 0 { + n += 1 + l + sovConsensus(uint64(l)) + } + l = len(m.Id) + if l > 0 { + 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) + l = len(m.Identity) if l > 0 { n += 1 + l + sovConsensus(uint64(l)) } - if m.CreatedUnix != 0 { - n += 1 + sovConsensus(uint64(m.CreatedUnix)) + l = len(m.Data) + if l > 0 { + n += 1 + l + sovConsensus(uint64(l)) + } + if m.Timestamp != 0 { + n += 1 + sovConsensus(uint64(m.Timestamp)) } return n } @@ -1053,6 +1334,40 @@ func (m *Log) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 2: + 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 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Records", wireType) } @@ -1081,7 +1396,7 @@ func (m *Log) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Records = append(m.Records, &Record{}) + m.Records = append(m.Records, &RawRecordWithId{}) if err := m.Records[len(m.Records)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } @@ -1107,6 +1422,308 @@ func (m *Log) Unmarshal(dAtA []byte) error { } return nil } +func (m *RawRecord) 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: RawRecord: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RawRecord: 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 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 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 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.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 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.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 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.AcceptorSignature = append(m.AcceptorSignature[:0], dAtA[iNdEx:postIndex]...) + if m.AcceptorSignature == nil { + m.AcceptorSignature = []byte{} + } + 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 *RawRecordWithId) 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: RawRecordWithId: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RawRecordWithId: 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 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 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 ErrIntOverflowConsensus + } + 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 ErrInvalidLengthConsensus + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthConsensus + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Id = string(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 *Record) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -1138,9 +1755,9 @@ func (m *Record) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PrevId", wireType) } - var byteLen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowConsensus @@ -1150,29 +1767,27 @@ func (m *Record) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthConsensus } - postIndex := iNdEx + byteLen + postIndex := iNdEx + intStringLen 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{} - } + m.PrevId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PrevId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Identity", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { @@ -1199,14 +1814,14 @@ func (m *Record) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.PrevId = append(m.PrevId[:0], dAtA[iNdEx:postIndex]...) - if m.PrevId == nil { - m.PrevId = []byte{} + 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 Payload", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { @@ -1233,16 +1848,16 @@ func (m *Record) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Payload = append(m.Payload[:0], dAtA[iNdEx:postIndex]...) - if m.Payload == nil { - m.Payload = []byte{} + 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 CreatedUnix", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) } - m.CreatedUnix = 0 + m.Timestamp = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowConsensus @@ -1252,7 +1867,7 @@ func (m *Record) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.CreatedUnix |= uint64(b&0x7F) << shift + m.Timestamp |= int64(b&0x7F) << shift if b < 0x80 { break } @@ -1507,7 +2122,7 @@ func (m *RecordAddRequest) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Record == nil { - m.Record = &Record{} + m.Record = &RawRecord{} } if err := m.Record.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -1740,7 +2355,7 @@ func (m *LogWatchEvent) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Records = append(m.Records, &Record{}) + m.Records = append(m.Records, &RawRecordWithId{}) if err := m.Records[len(m.Records)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } diff --git a/consensus/consensusproto/consensus_drpc.pb.go b/consensus/consensusproto/consensus_drpc.pb.go index be8927c6..b0b00dad 100644 --- a/consensus/consensusproto/consensus_drpc.pb.go +++ b/consensus/consensusproto/consensus_drpc.pb.go @@ -41,7 +41,7 @@ type DRPCConsensusClient interface { DRPCConn() drpc.Conn LogAdd(ctx context.Context, in *LogAddRequest) (*Ok, error) - RecordAdd(ctx context.Context, in *RecordAddRequest) (*Ok, error) + RecordAdd(ctx context.Context, in *RecordAddRequest) (*RawRecordWithId, error) LogWatch(ctx context.Context) (DRPCConsensus_LogWatchClient, error) } @@ -64,8 +64,8 @@ func (c *drpcConsensusClient) LogAdd(ctx context.Context, in *LogAddRequest) (*O return out, nil } -func (c *drpcConsensusClient) RecordAdd(ctx context.Context, in *RecordAddRequest) (*Ok, error) { - out := new(Ok) +func (c *drpcConsensusClient) RecordAdd(ctx context.Context, in *RecordAddRequest) (*RawRecordWithId, error) { + out := new(RawRecordWithId) err := c.cc.Invoke(ctx, "/consensusProto.Consensus/RecordAdd", drpcEncoding_File_consensus_consensusproto_protos_consensus_proto{}, in, out) if err != nil { return nil, err @@ -114,7 +114,7 @@ func (x *drpcConsensus_LogWatchClient) RecvMsg(m *LogWatchEvent) error { type DRPCConsensusServer interface { LogAdd(context.Context, *LogAddRequest) (*Ok, error) - RecordAdd(context.Context, *RecordAddRequest) (*Ok, error) + RecordAdd(context.Context, *RecordAddRequest) (*RawRecordWithId, error) LogWatch(DRPCConsensus_LogWatchStream) error } @@ -124,7 +124,7 @@ func (s *DRPCConsensusUnimplementedServer) LogAdd(context.Context, *LogAddReques return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) } -func (s *DRPCConsensusUnimplementedServer) RecordAdd(context.Context, *RecordAddRequest) (*Ok, error) { +func (s *DRPCConsensusUnimplementedServer) RecordAdd(context.Context, *RecordAddRequest) (*RawRecordWithId, error) { return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) } @@ -191,14 +191,14 @@ func (x *drpcConsensus_LogAddStream) SendAndClose(m *Ok) error { type DRPCConsensus_RecordAddStream interface { drpc.Stream - SendAndClose(*Ok) error + SendAndClose(*RawRecordWithId) error } type drpcConsensus_RecordAddStream struct { drpc.Stream } -func (x *drpcConsensus_RecordAddStream) SendAndClose(m *Ok) error { +func (x *drpcConsensus_RecordAddStream) SendAndClose(m *RawRecordWithId) error { if err := x.MsgSend(m, drpcEncoding_File_consensus_consensusproto_protos_consensus_proto{}); err != nil { return err } diff --git a/consensus/consensusproto/protos/consensus.proto b/consensus/consensusproto/protos/consensus.proto index 6be8103c..55918519 100644 --- a/consensus/consensusproto/protos/consensus.proto +++ b/consensus/consensusproto/protos/consensus.proto @@ -14,21 +14,38 @@ enum ErrCodes { message Log { bytes id = 1; - repeated Record records = 2; + bytes payload = 2; + repeated RawRecordWithId records = 3; } -message Record { - bytes id = 1; - bytes prevId = 2; - bytes payload = 3; - uint64 createdUnix = 4; +// RawRecord is a proto message containing the payload in bytes, signature of the account who added it and signature of the acceptor +message RawRecord { + bytes payload = 1; + bytes signature = 2; + bytes acceptorIdentity = 3; + bytes acceptorSignature = 4; } +// RawRecordWithId is a raw record and the id for convenience +message RawRecordWithId { + bytes payload = 1; + string id = 2; +} + +// Record is a record containing a data +message Record { + string prevId = 1; + bytes identity = 2; + bytes data = 3; + int64 timestamp = 4; +} + + service Consensus { // AddLog adds new log to consensus rpc LogAdd(LogAddRequest) returns (Ok); // AddRecord adds new record to log - rpc RecordAdd(RecordAddRequest) returns (Ok); + rpc RecordAdd(RecordAddRequest) returns (RawRecordWithId); // WatchLog fetches log and subscribes for a changes rpc LogWatch(stream LogWatchRequest) returns (stream LogWatchEvent); } @@ -41,7 +58,7 @@ message LogAddRequest { message RecordAddRequest { bytes logId = 1; - Record record = 2; + RawRecord record = 2; } message LogWatchRequest { @@ -51,7 +68,7 @@ message LogWatchRequest { message LogWatchEvent { bytes logId = 1; - repeated Record records = 2; + repeated RawRecordWithId records = 2; Err error = 3; } From 822e7f374d7e5220685e7871c452279a7c009a55 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Sat, 1 Jul 2023 13:17:18 +0200 Subject: [PATCH 101/123] Change to consensus proto --- commonfile/fileproto/file_drpc.pb.go | 2 +- commonspace/headsync/diffsyncer_test.go | 9 +- .../object/acl/aclrecordproto/aclrecord.pb.go | 1611 +---------------- .../acl/aclrecordproto/protos/aclrecord.proto | 37 - .../object/acl/list/aclrecordbuilder.go | 69 +- commonspace/object/acl/list/list.go | 20 +- commonspace/object/acl/list/list_test.go | 7 +- commonspace/object/acl/list/listutils.go | 8 +- .../object/acl/list/mock_list/mock_list.go | 10 +- .../object/acl/liststorage/inmemory.go | 18 +- .../object/acl/liststorage/liststorage.go | 11 +- .../mock_liststorage/mock_liststorage.go | 12 +- .../object/acl/syncacl/syncaclhandler.go | 19 +- commonspace/payloads.go | 5 +- commonspace/payloads_test.go | 28 +- commonspace/spaceservice.go | 9 +- commonspace/spacestorage/inmemorystorage.go | 6 +- commonspace/spacestorage/spacestorage.go | 5 +- .../spacesyncproto/spacesync_drpc.pb.go | 6 +- .../coordinatorproto/coordinator_drpc.pb.go | 2 +- .../testservice/testservice_drpc.pb.go | 6 +- 21 files changed, 197 insertions(+), 1703 deletions(-) diff --git a/commonfile/fileproto/file_drpc.pb.go b/commonfile/fileproto/file_drpc.pb.go index 2f9ee69d..a03c22cd 100644 --- a/commonfile/fileproto/file_drpc.pb.go +++ b/commonfile/fileproto/file_drpc.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-go-drpc. DO NOT EDIT. -// protoc-gen-go-drpc version: v0.0.32 +// protoc-gen-go-drpc version: v0.0.33 // source: commonfile/fileproto/protos/file.proto package fileproto diff --git a/commonspace/headsync/diffsyncer_test.go b/commonspace/headsync/diffsyncer_test.go index 7cdb870a..6603dd98 100644 --- a/commonspace/headsync/diffsyncer_test.go +++ b/commonspace/headsync/diffsyncer_test.go @@ -4,18 +4,19 @@ import ( "bytes" "context" "fmt" + "testing" + "time" + "github.com/anyproto/any-sync/app/ldiff" - "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" "github.com/anyproto/any-sync/commonspace/object/acl/liststorage/mock_liststorage" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" "github.com/anyproto/any-sync/commonspace/object/tree/treestorage/mock_treestorage" "github.com/anyproto/any-sync/commonspace/spacesyncproto" + "github.com/anyproto/any-sync/consensus/consensusproto" "github.com/anyproto/any-sync/net/peer" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" "storj.io/drpc" - "testing" - "time" ) type pushSpaceRequestMatcher struct { @@ -169,7 +170,7 @@ func TestDiffSyncer(t *testing.T) { settingsStorage := mock_treestorage.NewMockTreeStorage(fx.ctrl) settingsId := "settingsId" aclRootId := "aclRootId" - aclRoot := &aclrecordproto.RawAclRecordWithId{ + aclRoot := &consensusproto.RawRecordWithId{ Id: aclRootId, } settingsRoot := &treechangeproto.RawTreeChangeWithId{ diff --git a/commonspace/object/acl/aclrecordproto/aclrecord.pb.go b/commonspace/object/acl/aclrecordproto/aclrecord.pb.go index 2d264f05..4c2d4333 100644 --- a/commonspace/object/acl/aclrecordproto/aclrecord.pb.go +++ b/commonspace/object/acl/aclrecordproto/aclrecord.pb.go @@ -57,197 +57,6 @@ func (AclUserPermissions) EnumDescriptor() ([]byte, []int) { return fileDescriptor_c8e9f754f34e929b, []int{0} } -// RawAclRecord is a proto message containing the acl payload in bytes, signature of the account who added it and signature of the acceptor -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_c8e9f754f34e929b, []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 -} - -// RawAclRecordWithId is a raw record and the id for convenience -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_c8e9f754f34e929b, []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 "" -} - -// AclRecord is a record containing the acl data -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"` - Timestamp int64 `protobuf:"varint,4,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_c8e9f754f34e929b, []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) GetTimestamp() int64 { - if m != nil { - return m.Timestamp - } - return 0 -} - // AclRoot is a root of access control list type AclRoot struct { Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` @@ -262,7 +71,7 @@ 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_c8e9f754f34e929b, []int{3} + return fileDescriptor_c8e9f754f34e929b, []int{0} } func (m *AclRoot) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -342,7 +151,7 @@ func (m *AclAccountInvite) Reset() { *m = AclAccountInvite{} } func (m *AclAccountInvite) String() string { return proto.CompactTextString(m) } func (*AclAccountInvite) ProtoMessage() {} func (*AclAccountInvite) Descriptor() ([]byte, []int) { - return fileDescriptor_c8e9f754f34e929b, []int{4} + return fileDescriptor_c8e9f754f34e929b, []int{1} } func (m *AclAccountInvite) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -390,7 +199,7 @@ func (m *AclAccountRequestJoin) Reset() { *m = AclAccountRequestJoin{} } func (m *AclAccountRequestJoin) String() string { return proto.CompactTextString(m) } func (*AclAccountRequestJoin) ProtoMessage() {} func (*AclAccountRequestJoin) Descriptor() ([]byte, []int) { - return fileDescriptor_c8e9f754f34e929b, []int{5} + return fileDescriptor_c8e9f754f34e929b, []int{2} } func (m *AclAccountRequestJoin) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -459,7 +268,7 @@ func (m *AclAccountRequestAccept) Reset() { *m = AclAccountRequestAccept func (m *AclAccountRequestAccept) String() string { return proto.CompactTextString(m) } func (*AclAccountRequestAccept) ProtoMessage() {} func (*AclAccountRequestAccept) Descriptor() ([]byte, []int) { - return fileDescriptor_c8e9f754f34e929b, []int{6} + return fileDescriptor_c8e9f754f34e929b, []int{3} } func (m *AclAccountRequestAccept) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -525,7 +334,7 @@ func (m *AclAccountRequestDecline) Reset() { *m = AclAccountRequestDecli func (m *AclAccountRequestDecline) String() string { return proto.CompactTextString(m) } func (*AclAccountRequestDecline) ProtoMessage() {} func (*AclAccountRequestDecline) Descriptor() ([]byte, []int) { - return fileDescriptor_c8e9f754f34e929b, []int{7} + return fileDescriptor_c8e9f754f34e929b, []int{4} } func (m *AclAccountRequestDecline) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -570,7 +379,7 @@ func (m *AclAccountInviteRevoke) Reset() { *m = AclAccountInviteRevoke{} func (m *AclAccountInviteRevoke) String() string { return proto.CompactTextString(m) } func (*AclAccountInviteRevoke) ProtoMessage() {} func (*AclAccountInviteRevoke) Descriptor() ([]byte, []int) { - return fileDescriptor_c8e9f754f34e929b, []int{8} + return fileDescriptor_c8e9f754f34e929b, []int{5} } func (m *AclAccountInviteRevoke) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -616,7 +425,7 @@ func (m *AclReadKeyWithRecord) Reset() { *m = AclReadKeyWithRecord{} } func (m *AclReadKeyWithRecord) String() string { return proto.CompactTextString(m) } func (*AclReadKeyWithRecord) ProtoMessage() {} func (*AclReadKeyWithRecord) Descriptor() ([]byte, []int) { - return fileDescriptor_c8e9f754f34e929b, []int{9} + return fileDescriptor_c8e9f754f34e929b, []int{6} } func (m *AclReadKeyWithRecord) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -669,7 +478,7 @@ func (m *AclEncryptedReadKey) Reset() { *m = AclEncryptedReadKey{} } func (m *AclEncryptedReadKey) String() string { return proto.CompactTextString(m) } func (*AclEncryptedReadKey) ProtoMessage() {} func (*AclEncryptedReadKey) Descriptor() ([]byte, []int) { - return fileDescriptor_c8e9f754f34e929b, []int{10} + return fileDescriptor_c8e9f754f34e929b, []int{7} } func (m *AclEncryptedReadKey) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -722,7 +531,7 @@ func (m *AclAccountPermissionChange) Reset() { *m = AclAccountPermission func (m *AclAccountPermissionChange) String() string { return proto.CompactTextString(m) } func (*AclAccountPermissionChange) ProtoMessage() {} func (*AclAccountPermissionChange) Descriptor() ([]byte, []int) { - return fileDescriptor_c8e9f754f34e929b, []int{11} + return fileDescriptor_c8e9f754f34e929b, []int{8} } func (m *AclAccountPermissionChange) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -774,7 +583,7 @@ func (m *AclReadKeyChange) Reset() { *m = AclReadKeyChange{} } func (m *AclReadKeyChange) String() string { return proto.CompactTextString(m) } func (*AclReadKeyChange) ProtoMessage() {} func (*AclReadKeyChange) Descriptor() ([]byte, []int) { - return fileDescriptor_c8e9f754f34e929b, []int{12} + return fileDescriptor_c8e9f754f34e929b, []int{9} } func (m *AclReadKeyChange) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -820,7 +629,7 @@ func (m *AclAccountRemove) Reset() { *m = AclAccountRemove{} } func (m *AclAccountRemove) String() string { return proto.CompactTextString(m) } func (*AclAccountRemove) ProtoMessage() {} func (*AclAccountRemove) Descriptor() ([]byte, []int) { - return fileDescriptor_c8e9f754f34e929b, []int{13} + return fileDescriptor_c8e9f754f34e929b, []int{10} } func (m *AclAccountRemove) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -871,7 +680,7 @@ func (m *AclAccountRequestRemove) Reset() { *m = AclAccountRequestRemove func (m *AclAccountRequestRemove) String() string { return proto.CompactTextString(m) } func (*AclAccountRequestRemove) ProtoMessage() {} func (*AclAccountRequestRemove) Descriptor() ([]byte, []int) { - return fileDescriptor_c8e9f754f34e929b, []int{14} + return fileDescriptor_c8e9f754f34e929b, []int{11} } func (m *AclAccountRequestRemove) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -920,7 +729,7 @@ 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_c8e9f754f34e929b, []int{15} + return fileDescriptor_c8e9f754f34e929b, []int{12} } func (m *AclContentValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1087,7 +896,7 @@ 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_c8e9f754f34e929b, []int{16} + return fileDescriptor_c8e9f754f34e929b, []int{13} } func (m *AclData) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1123,173 +932,8 @@ func (m *AclData) GetAclContent() []*AclContentValue { return nil } -type AclSyncMessage struct { - Content *AclSyncContentValue `protobuf:"bytes,1,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_c8e9f754f34e929b, []int{17} -} -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_c8e9f754f34e929b, []int{18} -} -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_c8e9f754f34e929b, []int{19} -} -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((*AclAccountInvite)(nil), "aclrecord.AclAccountInvite") proto.RegisterType((*AclAccountRequestJoin)(nil), "aclrecord.AclAccountRequestJoin") @@ -1304,9 +948,6 @@ func init() { proto.RegisterType((*AclAccountRequestRemove)(nil), "aclrecord.AclAccountRequestRemove") proto.RegisterType((*AclContentValue)(nil), "aclrecord.AclContentValue") proto.RegisterType((*AclData)(nil), "aclrecord.AclData") - proto.RegisterType((*AclSyncMessage)(nil), "aclrecord.AclSyncMessage") - proto.RegisterType((*AclSyncContentValue)(nil), "aclrecord.AclSyncContentValue") - proto.RegisterType((*AclAddRecords)(nil), "aclrecord.AclAddRecords") } func init() { @@ -1314,207 +955,60 @@ func init() { } var fileDescriptor_c8e9f754f34e929b = []byte{ - // 1008 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0xdd, 0x6e, 0xdc, 0x44, - 0x14, 0xb6, 0x37, 0xc9, 0x6e, 0x7c, 0x9c, 0x6c, 0xb7, 0x43, 0x69, 0x4d, 0x28, 0x4b, 0x30, 0x2a, - 0x8a, 0x2a, 0xd4, 0xa0, 0x45, 0x88, 0x0a, 0x21, 0xda, 0x6d, 0x52, 0xb1, 0x1b, 0x08, 0xa0, 0x09, - 0x50, 0x54, 0x09, 0xa4, 0xe9, 0x78, 0x94, 0x1a, 0xfc, 0xd7, 0xf1, 0x64, 0xab, 0x7d, 0x0b, 0x1e, - 0x81, 0x87, 0xe0, 0x96, 0x7b, 0x2e, 0x7b, 0x83, 0xc4, 0x25, 0x4a, 0x1e, 0x80, 0x57, 0x40, 0x33, - 0xe3, 0x7f, 0xbb, 0x4b, 0x73, 0x91, 0xac, 0xe7, 0xcc, 0x39, 0xdf, 0xf9, 0xfb, 0xce, 0xb1, 0xe1, - 0x53, 0x1a, 0x87, 0x61, 0x1c, 0xa5, 0x09, 0xa1, 0x6c, 0x3f, 0x7e, 0xf2, 0x33, 0xa3, 0x62, 0x9f, - 0xd0, 0x40, 0xfe, 0x71, 0x46, 0x63, 0xee, 0x25, 0x3c, 0x16, 0xf1, 0xbe, 0xfa, 0x9f, 0x96, 0xd2, - 0x3b, 0x4a, 0x80, 0xac, 0x42, 0xe0, 0xfe, 0x66, 0xc2, 0x16, 0x26, 0xcf, 0xa7, 0x34, 0xc0, 0x4a, - 0x80, 0x1c, 0x18, 0x24, 0x64, 0x19, 0xc4, 0xc4, 0x73, 0xcc, 0x5d, 0x73, 0x6f, 0x0b, 0xe7, 0x47, - 0x74, 0x13, 0xac, 0xd4, 0x3f, 0x8d, 0x88, 0x38, 0xe3, 0xcc, 0xe9, 0xa9, 0xbb, 0x52, 0x80, 0x6e, - 0xc3, 0x88, 0x50, 0xca, 0x12, 0x11, 0xf3, 0xb9, 0xc7, 0x22, 0xe1, 0x8b, 0xa5, 0xb3, 0xa6, 0x94, - 0x5a, 0x72, 0xf4, 0x3e, 0x5c, 0xcd, 0x65, 0x27, 0x05, 0xe2, 0xba, 0x52, 0x6e, 0x5f, 0xb8, 0x9f, - 0x01, 0xaa, 0x46, 0xf8, 0xc8, 0x17, 0x4f, 0xe7, 0xab, 0xe2, 0x1c, 0x42, 0xcf, 0xf7, 0x54, 0x80, - 0x16, 0xee, 0xf9, 0x9e, 0xfb, 0x0c, 0xac, 0x32, 0xbd, 0xeb, 0xd0, 0x4f, 0x38, 0x5b, 0xcc, 0xb5, - 0x95, 0x85, 0xb3, 0x13, 0xda, 0x81, 0x4d, 0x3f, 0x0f, 0x5b, 0xe7, 0x56, 0x9c, 0x11, 0x82, 0x75, - 0x8f, 0x08, 0x92, 0xa5, 0xa3, 0x9e, 0x65, 0x31, 0x84, 0x1f, 0xb2, 0x54, 0x90, 0x30, 0x51, 0xa1, - 0xaf, 0xe1, 0x52, 0xe0, 0xfe, 0x65, 0xc2, 0x40, 0xfa, 0x8c, 0x63, 0x51, 0x43, 0x36, 0x1b, 0xc8, - 0x37, 0xc1, 0x0a, 0x49, 0x2a, 0x18, 0xff, 0x82, 0xe5, 0x6e, 0x4b, 0x81, 0x4c, 0x51, 0x35, 0x78, - 0xee, 0x29, 0xd7, 0x16, 0xce, 0x8f, 0xb2, 0xd8, 0x2c, 0xa2, 0x7c, 0x99, 0x08, 0xe6, 0x61, 0x46, - 0x3c, 0x69, 0xae, 0xeb, 0xd7, 0x92, 0xd7, 0x23, 0xdd, 0x68, 0x44, 0x2a, 0x5b, 0x91, 0x47, 0x53, - 0xb6, 0xa2, 0xaf, 0x5b, 0xd1, 0xba, 0x70, 0x3f, 0x80, 0xd1, 0x94, 0x06, 0x53, 0x4a, 0xe3, 0xb3, - 0x48, 0xcc, 0xa3, 0x85, 0x2f, 0x98, 0xc4, 0xf7, 0xd5, 0x93, 0x0c, 0x42, 0x27, 0x58, 0x0a, 0xdc, - 0x3f, 0x4c, 0x78, 0xbd, 0x34, 0xc1, 0xec, 0xd9, 0x19, 0x4b, 0xc5, 0x51, 0xec, 0x47, 0xe8, 0x3d, - 0x18, 0x6a, 0xb5, 0x79, 0xbd, 0x3a, 0x0d, 0x69, 0xa9, 0xa7, 0x3b, 0x38, 0xcf, 0x5b, 0xdb, 0x90, - 0xa2, 0xbb, 0x70, 0xa3, 0x6e, 0x59, 0xe6, 0xa3, 0x1b, 0xf7, 0xb2, 0x6b, 0xd9, 0xa1, 0x90, 0x09, - 0xa2, 0x7a, 0xac, 0xab, 0x58, 0x9c, 0xdd, 0x7f, 0x4d, 0xb8, 0xd1, 0x8a, 0x7f, 0xaa, 0x38, 0xba, - 0xb2, 0xb3, 0x7b, 0x70, 0x85, 0x6b, 0xe5, 0x46, 0xd8, 0x4d, 0x31, 0x3a, 0x86, 0xab, 0xcd, 0x9e, - 0xa5, 0xce, 0xda, 0xee, 0xda, 0x9e, 0x3d, 0x79, 0xfb, 0x4e, 0x39, 0xb9, 0x8a, 0xc2, 0xea, 0x56, - 0x0e, 0x80, 0xb6, 0xc6, 0x6d, 0x4b, 0x74, 0x0f, 0xec, 0x84, 0xf1, 0xd0, 0x4f, 0x53, 0x3f, 0x8e, - 0x52, 0x95, 0xcf, 0x70, 0xf2, 0x56, 0x1d, 0xe8, 0xbb, 0x94, 0xf1, 0x6f, 0x4a, 0x25, 0x5c, 0xb5, - 0x70, 0x0f, 0xc1, 0x69, 0x25, 0x7c, 0xc8, 0x68, 0xe0, 0x47, 0xac, 0x2b, 0x2b, 0xb3, 0x33, 0x2b, - 0xf7, 0x3e, 0x5c, 0x6f, 0x32, 0x05, 0xb3, 0x45, 0xfc, 0x0b, 0xeb, 0xe8, 0xa7, 0xd9, 0xd5, 0x4f, - 0xf7, 0x27, 0xb8, 0xd6, 0x95, 0xb3, 0xac, 0x3a, 0xaf, 0x5b, 0x16, 0xe7, 0xce, 0xb9, 0xe8, 0x75, - 0xcf, 0x85, 0xfb, 0x23, 0xbc, 0x36, 0xa5, 0xc1, 0xc3, 0xe6, 0xb8, 0xac, 0x6a, 0xea, 0x65, 0xe0, - 0x97, 0xb0, 0x53, 0x16, 0xa0, 0x2c, 0xf6, 0xc1, 0x53, 0x12, 0x9d, 0xb2, 0x95, 0x5e, 0x1a, 0x1d, - 0xec, 0x5d, 0xba, 0x83, 0xdf, 0xaa, 0x29, 0xcd, 0x02, 0xc9, 0x1c, 0xde, 0x07, 0x9b, 0xe8, 0x58, - 0x14, 0xbf, 0x4c, 0xc5, 0xaf, 0x71, 0x1d, 0xb4, 0x59, 0x0b, 0x5c, 0x35, 0x71, 0x45, 0x75, 0xf6, - 0x31, 0x0b, 0xe3, 0x05, 0x43, 0x63, 0x80, 0x2c, 0x6c, 0x9f, 0x69, 0xd0, 0x2d, 0x5c, 0x91, 0x34, - 0xbd, 0xf6, 0x2e, 0xef, 0xf5, 0x8d, 0x8e, 0xf1, 0xd3, 0xce, 0xdd, 0xdf, 0x37, 0xe0, 0xca, 0x94, - 0x06, 0x07, 0x71, 0x24, 0x58, 0x24, 0xbe, 0x27, 0xc1, 0x19, 0x43, 0x1f, 0x41, 0x5f, 0xd3, 0x48, - 0x55, 0xd5, 0x9e, 0xbc, 0x59, 0xf7, 0x55, 0xe3, 0xe3, 0xcc, 0xc0, 0x99, 0x32, 0xfa, 0x1c, 0xb6, - 0xfc, 0x0a, 0x47, 0x55, 0xcd, 0xed, 0xc9, 0x3b, 0x2b, 0x8c, 0xb5, 0xe2, 0xcc, 0xc0, 0x35, 0x43, - 0x74, 0x08, 0x36, 0x2f, 0x77, 0x9c, 0x5a, 0x3c, 0xf6, 0x64, 0xb7, 0x13, 0xa7, 0xb2, 0x0b, 0x67, - 0x06, 0xae, 0x9a, 0xa1, 0x23, 0xd8, 0xe6, 0xd5, 0x4d, 0xa3, 0xa6, 0xd8, 0x9e, 0xb8, 0xab, 0x70, - 0xb4, 0xe6, 0xcc, 0xc0, 0x75, 0x53, 0x74, 0x02, 0xa3, 0xa4, 0xc1, 0x3e, 0xf5, 0x16, 0xb0, 0x27, - 0xb7, 0x3a, 0xe1, 0x9a, 0x54, 0x9d, 0x19, 0xb8, 0x05, 0x80, 0x0e, 0x60, 0x9b, 0x54, 0x89, 0xa0, - 0xde, 0x18, 0x2f, 0xab, 0xb6, 0x56, 0x91, 0x91, 0xd5, 0x6c, 0x24, 0x08, 0xaf, 0x72, 0xd4, 0x19, - 0x74, 0x81, 0xd4, 0x68, 0xac, 0xd3, 0xab, 0xf2, 0xfa, 0x18, 0x86, 0xbc, 0xb6, 0xa3, 0x9c, 0x4d, - 0x85, 0xf2, 0xee, 0xaa, 0x5a, 0x65, 0xaa, 0x33, 0x03, 0x37, 0x8c, 0xd1, 0x0f, 0x70, 0x8d, 0x74, - 0x70, 0xcd, 0xb1, 0xfe, 0xbf, 0x01, 0x45, 0x9a, 0x9d, 0x08, 0x0f, 0x06, 0xb0, 0xb1, 0x90, 0x14, - 0x75, 0x1f, 0xaa, 0x4f, 0x83, 0x43, 0xf9, 0x11, 0xf1, 0x09, 0x00, 0x29, 0x08, 0x9c, 0xcd, 0xe4, - 0x4e, 0xdd, 0x47, 0x95, 0xdd, 0xb8, 0xa2, 0xed, 0x1e, 0xc1, 0x70, 0x4a, 0x83, 0x93, 0x65, 0x44, - 0x8f, 0x59, 0x9a, 0x92, 0x53, 0x86, 0xee, 0xc2, 0x80, 0x16, 0x50, 0x66, 0x7b, 0xd0, 0xa4, 0x6e, - 0x0d, 0x2e, 0x57, 0x77, 0x1f, 0xab, 0x55, 0xd8, 0xbc, 0x57, 0xe1, 0x79, 0x9e, 0x5e, 0xbb, 0x69, - 0x86, 0xe9, 0x34, 0x4a, 0x50, 0xdc, 0xcf, 0x0c, 0x5c, 0xd1, 0x2e, 0xd3, 0x9d, 0xc1, 0x76, 0x4d, - 0x0f, 0x7d, 0x0c, 0x03, 0x5e, 0x40, 0xca, 0x8c, 0xab, 0xab, 0xad, 0xfd, 0xa1, 0x87, 0x73, 0xed, - 0xdb, 0x5f, 0x02, 0x6a, 0x6f, 0x3e, 0xb4, 0x09, 0xeb, 0x5f, 0xc5, 0x11, 0x1b, 0x19, 0xc8, 0x82, - 0x8d, 0xaf, 0x9f, 0x47, 0x8c, 0x8f, 0x4c, 0xf9, 0x38, 0xf5, 0x42, 0x3f, 0x1a, 0xf5, 0x10, 0x40, - 0xff, 0x11, 0xf7, 0x05, 0xe3, 0xa3, 0x35, 0xf9, 0x2c, 0xe9, 0xc4, 0xf8, 0x68, 0xfd, 0xc1, 0xbd, - 0x3f, 0xcf, 0xc7, 0xe6, 0x8b, 0xf3, 0xb1, 0xf9, 0xcf, 0xf9, 0xd8, 0xfc, 0xf5, 0x62, 0x6c, 0xbc, - 0xb8, 0x18, 0x1b, 0x7f, 0x5f, 0x8c, 0x8d, 0xc7, 0xb7, 0x5e, 0xe9, 0xdb, 0xfa, 0x49, 0x5f, 0xfd, - 0x7c, 0xf8, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1d, 0x52, 0x8e, 0xdb, 0x8b, 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] = 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 + // 835 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0x5f, 0x4f, 0xdb, 0x56, + 0x14, 0xb7, 0x13, 0x92, 0x90, 0x63, 0xfe, 0x98, 0x3b, 0x36, 0x3c, 0xb6, 0x79, 0x99, 0x27, 0xa6, + 0x08, 0x4d, 0x30, 0x65, 0x9a, 0x34, 0x4d, 0x93, 0x20, 0x10, 0xb4, 0x84, 0x8d, 0x6d, 0xba, 0x6c, + 0x63, 0xaa, 0xd4, 0x4a, 0x17, 0xfb, 0x08, 0xdc, 0xc6, 0x76, 0x7a, 0x7d, 0x93, 0x2a, 0xdf, 0xa2, + 0x1f, 0xa6, 0xaf, 0x7d, 0xef, 0x23, 0x2f, 0x95, 0xfa, 0x58, 0xc1, 0x07, 0xe8, 0x57, 0xa8, 0x7c, + 0x1d, 0xe2, 0x3f, 0x31, 0x69, 0x79, 0x80, 0xd8, 0xe7, 0x9e, 0xdf, 0xef, 0xfc, 0xfb, 0x9d, 0x9b, + 0xc0, 0xaf, 0x76, 0xe0, 0x79, 0x81, 0x1f, 0x0e, 0x98, 0x8d, 0xbb, 0xc1, 0xf9, 0x63, 0xb4, 0xc5, + 0x2e, 0xb3, 0xfb, 0xd1, 0x1f, 0x47, 0x3b, 0xe0, 0xce, 0x80, 0x07, 0x22, 0xd8, 0x95, 0xff, 0xc3, + 0xc4, 0xba, 0x23, 0x0d, 0xa4, 0x3e, 0x35, 0x58, 0xaf, 0x55, 0xa8, 0xb5, 0xed, 0x3e, 0x0d, 0x02, + 0x41, 0x36, 0x61, 0xd1, 0x75, 0xd0, 0x17, 0xae, 0x18, 0x1b, 0x6a, 0x43, 0x6d, 0x2e, 0xd1, 0xe9, + 0x3b, 0xf9, 0x12, 0xea, 0x1e, 0x0b, 0x05, 0xf2, 0xdf, 0x71, 0x6c, 0x94, 0xe4, 0x61, 0x62, 0x20, + 0x06, 0xd4, 0x64, 0x2a, 0x3d, 0xc7, 0x28, 0x37, 0xd4, 0x66, 0x9d, 0xde, 0xbe, 0x92, 0x6d, 0xd0, + 0xd1, 0xb7, 0xf9, 0x78, 0x20, 0xd0, 0xa1, 0xc8, 0x9c, 0x08, 0xbe, 0x20, 0xe1, 0x33, 0xf6, 0x28, + 0x86, 0x70, 0x3d, 0x0c, 0x05, 0xf3, 0x06, 0x46, 0xa5, 0xa1, 0x36, 0xcb, 0x34, 0x31, 0x90, 0xef, + 0x61, 0xed, 0x36, 0x9b, 0x53, 0xf7, 0xc2, 0x67, 0x62, 0xc8, 0xd1, 0xa8, 0x4a, 0xaa, 0xd9, 0x03, + 0xeb, 0x07, 0xd0, 0xdb, 0x76, 0xbf, 0x6d, 0xdb, 0xc1, 0xd0, 0x17, 0x3d, 0x7f, 0xe4, 0x0a, 0x8c, + 0xf8, 0x5d, 0xf9, 0x14, 0x25, 0x11, 0x17, 0x98, 0x18, 0xac, 0x97, 0x2a, 0x7c, 0x9a, 0x40, 0x28, + 0x3e, 0x1d, 0x62, 0x28, 0x8e, 0x03, 0xd7, 0x27, 0xdf, 0xc1, 0x4a, 0xec, 0xd6, 0xcb, 0x76, 0x27, + 0x67, 0x4d, 0xfc, 0xa8, 0xec, 0x6d, 0xcf, 0x91, 0x8d, 0xaa, 0xd3, 0x9c, 0x95, 0xfc, 0x0c, 0x1b, + 0x59, 0x64, 0x52, 0x4f, 0x59, 0x12, 0xdf, 0x75, 0x1c, 0x4d, 0xc8, 0x43, 0xc1, 0x1c, 0x26, 0xd8, + 0xa4, 0x8b, 0xd3, 0x77, 0xeb, 0x9d, 0x0a, 0x1b, 0x33, 0xf9, 0xb7, 0x6d, 0x1b, 0x07, 0xf3, 0x27, + 0xdb, 0x84, 0x55, 0x1e, 0x3b, 0xe7, 0xd2, 0xce, 0x9b, 0xc9, 0x09, 0xac, 0xe5, 0x67, 0x16, 0x1a, + 0xe5, 0x46, 0xb9, 0xa9, 0xb5, 0xbe, 0xde, 0x49, 0x34, 0x16, 0xc9, 0x29, 0x3e, 0x3d, 0x73, 0xc5, + 0x65, 0x8c, 0xa6, 0xb3, 0x48, 0xb2, 0x07, 0xda, 0x00, 0xb9, 0xe7, 0x86, 0xa1, 0x1b, 0xf8, 0xa1, + 0xac, 0x67, 0xa5, 0xf5, 0x55, 0x96, 0xe8, 0xdf, 0x10, 0xf9, 0xdf, 0x89, 0x13, 0x4d, 0x23, 0xac, + 0x0e, 0x18, 0x33, 0x05, 0x77, 0xd0, 0xee, 0xbb, 0x3e, 0x16, 0x55, 0xa5, 0x16, 0x56, 0x65, 0xed, + 0xc3, 0x67, 0x79, 0xa5, 0x50, 0x1c, 0x05, 0x4f, 0xb0, 0x60, 0x9e, 0x6a, 0xd1, 0x3c, 0xad, 0x47, + 0xb0, 0x5e, 0x54, 0x73, 0xd4, 0x75, 0x9e, 0x45, 0x4e, 0xdf, 0x0b, 0xf7, 0xa2, 0x54, 0xbc, 0x17, + 0xd6, 0x43, 0xf8, 0xa4, 0x6d, 0xf7, 0x8f, 0xf2, 0xeb, 0x32, 0x6f, 0xa8, 0xf7, 0xa1, 0x1f, 0xc3, + 0x66, 0xd2, 0x80, 0xa4, 0xd9, 0x87, 0x97, 0xcc, 0xbf, 0xc0, 0xb9, 0x51, 0x72, 0x13, 0x2c, 0xdd, + 0x7b, 0x82, 0xff, 0xc8, 0x2d, 0x9d, 0x24, 0x32, 0x09, 0xb8, 0x0f, 0x1a, 0x8b, 0x73, 0x91, 0xfa, + 0x52, 0xa5, 0xbe, 0xcc, 0x2c, 0x69, 0xbe, 0x17, 0x34, 0x0d, 0xb1, 0x44, 0x7a, 0xf7, 0x29, 0x7a, + 0xc1, 0x08, 0x89, 0x09, 0x30, 0x49, 0xdb, 0xc5, 0x98, 0x74, 0x89, 0xa6, 0x2c, 0xf9, 0xa8, 0xa5, + 0xfb, 0x47, 0xfd, 0xbc, 0x60, 0xfd, 0xe2, 0xe0, 0xd6, 0x8b, 0x0a, 0xac, 0xb6, 0xed, 0xfe, 0x61, + 0xe0, 0x0b, 0xf4, 0xc5, 0x7f, 0xac, 0x3f, 0x44, 0xf2, 0x13, 0x54, 0x63, 0x19, 0xc9, 0xae, 0x6a, + 0xad, 0x2f, 0xb2, 0xb1, 0x32, 0x7a, 0xec, 0x2a, 0x74, 0xe2, 0x4c, 0x7e, 0x83, 0x25, 0x37, 0xa5, + 0x51, 0xd9, 0x73, 0xad, 0xf5, 0xcd, 0x1c, 0x70, 0xec, 0xd8, 0x55, 0x68, 0x06, 0x48, 0x3a, 0xa0, + 0xf1, 0xe4, 0x8e, 0x93, 0x17, 0x8f, 0xd6, 0x6a, 0x14, 0xf2, 0xa4, 0xee, 0xc2, 0xae, 0x42, 0xd3, + 0x30, 0x72, 0x0c, 0xcb, 0x3c, 0x7d, 0xd3, 0xc8, 0x2d, 0xd6, 0x5a, 0xd6, 0x3c, 0x9e, 0xd8, 0xb3, + 0xab, 0xd0, 0x2c, 0x94, 0x9c, 0x82, 0x3e, 0xc8, 0xa9, 0x4f, 0x7e, 0x0b, 0x68, 0xad, 0xad, 0x42, + 0xba, 0xbc, 0x54, 0xbb, 0x0a, 0x9d, 0x21, 0x20, 0x87, 0xb0, 0xcc, 0xd2, 0x42, 0x90, 0xdf, 0x18, + 0x77, 0x75, 0x3b, 0x76, 0x89, 0x32, 0xcb, 0x60, 0x22, 0x12, 0x9e, 0xd6, 0xa8, 0x51, 0x2b, 0x22, + 0xc9, 0xc8, 0x38, 0x2e, 0x2f, 0xad, 0xeb, 0x13, 0x58, 0xe1, 0x99, 0x3b, 0xca, 0x58, 0x94, 0x2c, + 0xdf, 0xce, 0xeb, 0xd5, 0xc4, 0xb5, 0xab, 0xd0, 0x1c, 0x98, 0xfc, 0x0f, 0xeb, 0xac, 0x40, 0x6b, + 0x46, 0xfd, 0xc3, 0x03, 0x98, 0x96, 0x59, 0xc8, 0x70, 0x50, 0x83, 0xca, 0x28, 0x92, 0xa8, 0x75, + 0x24, 0x7f, 0x1a, 0x74, 0x98, 0x60, 0xe4, 0x17, 0x00, 0x36, 0x15, 0xf0, 0x64, 0x27, 0x37, 0xb3, + 0x31, 0xd2, 0xea, 0xa6, 0x29, 0xef, 0xed, 0x3f, 0x80, 0xcc, 0xde, 0x03, 0x64, 0x11, 0x16, 0xfe, + 0x0c, 0x7c, 0xd4, 0x15, 0x52, 0x87, 0xca, 0x5f, 0xcf, 0x7c, 0xe4, 0xba, 0x1a, 0x3d, 0xb6, 0x1d, + 0xcf, 0xf5, 0xf5, 0x12, 0x01, 0xa8, 0x9e, 0x71, 0x57, 0x20, 0xd7, 0xcb, 0xd1, 0x73, 0xd4, 0x5c, + 0xe4, 0xfa, 0xc2, 0xc1, 0xde, 0xab, 0x6b, 0x53, 0xbd, 0xba, 0x36, 0xd5, 0xb7, 0xd7, 0xa6, 0xfa, + 0xfc, 0xc6, 0x54, 0xae, 0x6e, 0x4c, 0xe5, 0xcd, 0x8d, 0xa9, 0x3c, 0xd8, 0xfa, 0xa8, 0xdf, 0x44, + 0xe7, 0x55, 0xf9, 0xf1, 0xe3, 0xfb, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd0, 0xe7, 0x8e, 0xa9, 0x43, + 0x09, 0x00, 0x00, } func (m *AclRoot) Marshal() (dAtA []byte, err error) { @@ -2250,131 +1744,6 @@ func (m *AclData) MarshalToSizedBuffer(dAtA []byte) (int, error) { 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] = 0xa - } - 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 @@ -2386,72 +1755,6 @@ func encodeVarintAclrecord(dAtA []byte, offset int, v uint64) int { 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.Timestamp != 0 { - n += 1 + sovAclrecord(uint64(m.Timestamp)) - } - return n -} - func (m *AclRoot) Size() (n int) { if m == nil { return 0 @@ -2804,535 +2107,12 @@ func (m *AclData) Size() (n int) { 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 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 @@ -5207,261 +3987,6 @@ func (m *AclData) Unmarshal(dAtA []byte) error { } 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 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 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 diff --git a/commonspace/object/acl/aclrecordproto/protos/aclrecord.proto b/commonspace/object/acl/aclrecordproto/protos/aclrecord.proto index a1f2c49c..4b6f2b5e 100644 --- a/commonspace/object/acl/aclrecordproto/protos/aclrecord.proto +++ b/commonspace/object/acl/aclrecordproto/protos/aclrecord.proto @@ -2,28 +2,6 @@ syntax = "proto3"; package aclrecord; option go_package = "commonspace/object/acl/aclrecordproto"; -// RawAclRecord is a proto message containing the acl payload in bytes, signature of the account who added it and signature of the acceptor -message RawAclRecord { - bytes payload = 1; - bytes signature = 2; - bytes acceptorIdentity = 3; - bytes acceptorSignature = 4; -} - -// RawAclRecordWithId is a raw record and the id for convenience -message RawAclRecordWithId { - bytes payload = 1; - string id = 2; -} - -// AclRecord is a record containing the acl data -message AclRecord { - string prevId = 1; - bytes identity = 2; - bytes data = 3; - int64 timestamp = 4; -} - // AclRoot is a root of access control list message AclRoot { bytes identity = 1; @@ -126,18 +104,3 @@ enum AclUserPermissions { Writer = 3; Reader = 4; } - -message AclSyncMessage { - AclSyncContentValue content = 1; -} - -// 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/commonspace/object/acl/list/aclrecordbuilder.go b/commonspace/object/acl/list/aclrecordbuilder.go index a949bd99..28c3c1f6 100644 --- a/commonspace/object/acl/list/aclrecordbuilder.go +++ b/commonspace/object/acl/list/aclrecordbuilder.go @@ -5,6 +5,7 @@ import ( "github.com/anyproto/any-sync/commonspace/object/accountdata" "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" + "github.com/anyproto/any-sync/consensus/consensusproto" "github.com/anyproto/any-sync/util/cidutil" "github.com/anyproto/any-sync/util/crypto" "github.com/gogo/protobuf/proto" @@ -39,24 +40,24 @@ type AccountRemovePayload struct { } type InviteResult struct { - InviteRec *aclrecordproto.RawAclRecord + InviteRec *consensusproto.RawRecord InviteKey crypto.PrivKey } type AclRecordBuilder interface { - UnmarshallWithId(rawIdRecord *aclrecordproto.RawAclRecordWithId) (rec *AclRecord, err error) - Unmarshall(rawRecord *aclrecordproto.RawAclRecord) (rec *AclRecord, err error) + UnmarshallWithId(rawIdRecord *consensusproto.RawRecordWithId) (rec *AclRecord, err error) + Unmarshall(rawRecord *consensusproto.RawRecord) (rec *AclRecord, err error) - BuildRoot(content RootContent) (rec *aclrecordproto.RawAclRecordWithId, err error) + BuildRoot(content RootContent) (rec *consensusproto.RawRecordWithId, err error) BuildInvite() (res InviteResult, err error) - BuildInviteRevoke(inviteRecordId string) (rawRecord *aclrecordproto.RawAclRecord, err error) - BuildRequestJoin(payload RequestJoinPayload) (rawRecord *aclrecordproto.RawAclRecord, err error) - BuildRequestAccept(payload RequestAcceptPayload) (rawRecord *aclrecordproto.RawAclRecord, err error) - BuildRequestDecline(requestRecordId string) (rawRecord *aclrecordproto.RawAclRecord, err error) - BuildRequestRemove() (rawRecord *aclrecordproto.RawAclRecord, err error) - BuildPermissionChange(payload PermissionChangePayload) (rawRecord *aclrecordproto.RawAclRecord, err error) - BuildReadKeyChange(newKey crypto.SymKey) (rawRecord *aclrecordproto.RawAclRecord, err error) - BuildAccountRemove(payload AccountRemovePayload) (rawRecord *aclrecordproto.RawAclRecord, err error) + BuildInviteRevoke(inviteRecordId string) (rawRecord *consensusproto.RawRecord, err error) + BuildRequestJoin(payload RequestJoinPayload) (rawRecord *consensusproto.RawRecord, err error) + BuildRequestAccept(payload RequestAcceptPayload) (rawRecord *consensusproto.RawRecord, err error) + BuildRequestDecline(requestRecordId string) (rawRecord *consensusproto.RawRecord, err error) + BuildRequestRemove() (rawRecord *consensusproto.RawRecord, err error) + BuildPermissionChange(payload PermissionChangePayload) (rawRecord *consensusproto.RawRecord, err error) + BuildReadKeyChange(newKey crypto.SymKey) (rawRecord *consensusproto.RawRecord, err error) + BuildAccountRemove(payload AccountRemovePayload) (rawRecord *consensusproto.RawRecord, err error) } type aclRecordBuilder struct { @@ -76,7 +77,7 @@ func NewAclRecordBuilder(id string, keyStorage crypto.KeyStorage, keys *accountd } } -func (a *aclRecordBuilder) buildRecord(aclContent *aclrecordproto.AclContentValue) (rawRec *aclrecordproto.RawAclRecord, err error) { +func (a *aclRecordBuilder) buildRecord(aclContent *aclrecordproto.AclContentValue) (rawRec *consensusproto.RawRecord, err error) { aclData := &aclrecordproto.AclData{AclContent: []*aclrecordproto.AclContentValue{ aclContent, }} @@ -88,7 +89,7 @@ func (a *aclRecordBuilder) buildRecord(aclContent *aclrecordproto.AclContentValu if err != nil { return } - rec := &aclrecordproto.AclRecord{ + rec := &consensusproto.Record{ PrevId: a.state.lastRecordId, Identity: protoKey, Data: marshalledData, @@ -102,7 +103,7 @@ func (a *aclRecordBuilder) buildRecord(aclContent *aclrecordproto.AclContentValu if err != nil { return } - rawRec = &aclrecordproto.RawAclRecord{ + rawRec = &consensusproto.RawRecord{ Payload: marshalledRec, Signature: signature, } @@ -133,7 +134,7 @@ func (a *aclRecordBuilder) BuildInvite() (res InviteResult, err error) { return } -func (a *aclRecordBuilder) BuildInviteRevoke(inviteRecordId string) (rawRecord *aclrecordproto.RawAclRecord, err error) { +func (a *aclRecordBuilder) BuildInviteRevoke(inviteRecordId string) (rawRecord *consensusproto.RawRecord, err error) { if !a.state.Permissions(a.state.pubKey).CanManageAccounts() { err = ErrInsufficientPermissions return @@ -148,7 +149,7 @@ func (a *aclRecordBuilder) BuildInviteRevoke(inviteRecordId string) (rawRecord * return a.buildRecord(content) } -func (a *aclRecordBuilder) BuildRequestJoin(payload RequestJoinPayload) (rawRecord *aclrecordproto.RawAclRecord, err error) { +func (a *aclRecordBuilder) BuildRequestJoin(payload RequestJoinPayload) (rawRecord *consensusproto.RawRecord, err error) { key, exists := a.state.inviteKeys[payload.InviteRecordId] if !exists { err = ErrNoSuchInvite @@ -179,7 +180,7 @@ func (a *aclRecordBuilder) BuildRequestJoin(payload RequestJoinPayload) (rawReco return a.buildRecord(content) } -func (a *aclRecordBuilder) BuildRequestAccept(payload RequestAcceptPayload) (rawRecord *aclrecordproto.RawAclRecord, err error) { +func (a *aclRecordBuilder) BuildRequestAccept(payload RequestAcceptPayload) (rawRecord *consensusproto.RawRecord, err error) { if !a.state.Permissions(a.state.pubKey).CanManageAccounts() { err = ErrInsufficientPermissions return @@ -221,7 +222,7 @@ func (a *aclRecordBuilder) BuildRequestAccept(payload RequestAcceptPayload) (raw return a.buildRecord(content) } -func (a *aclRecordBuilder) BuildRequestDecline(requestRecordId string) (rawRecord *aclrecordproto.RawAclRecord, err error) { +func (a *aclRecordBuilder) BuildRequestDecline(requestRecordId string) (rawRecord *consensusproto.RawRecord, err error) { if !a.state.Permissions(a.state.pubKey).CanManageAccounts() { err = ErrInsufficientPermissions return @@ -236,7 +237,7 @@ func (a *aclRecordBuilder) BuildRequestDecline(requestRecordId string) (rawRecor return a.buildRecord(content) } -func (a *aclRecordBuilder) BuildPermissionChange(payload PermissionChangePayload) (rawRecord *aclrecordproto.RawAclRecord, err error) { +func (a *aclRecordBuilder) BuildPermissionChange(payload PermissionChangePayload) (rawRecord *consensusproto.RawRecord, err error) { permissions := a.state.Permissions(a.state.pubKey) if !permissions.CanManageAccounts() || payload.Identity.Equals(a.state.pubKey) { err = ErrInsufficientPermissions @@ -258,7 +259,7 @@ func (a *aclRecordBuilder) BuildPermissionChange(payload PermissionChangePayload return a.buildRecord(content) } -func (a *aclRecordBuilder) BuildReadKeyChange(newKey crypto.SymKey) (rawRecord *aclrecordproto.RawAclRecord, err error) { +func (a *aclRecordBuilder) BuildReadKeyChange(newKey crypto.SymKey) (rawRecord *consensusproto.RawRecord, err error) { if !a.state.Permissions(a.state.pubKey).CanManageAccounts() { err = ErrInsufficientPermissions return @@ -291,7 +292,7 @@ func (a *aclRecordBuilder) BuildReadKeyChange(newKey crypto.SymKey) (rawRecord * return a.buildRecord(content) } -func (a *aclRecordBuilder) BuildAccountRemove(payload AccountRemovePayload) (rawRecord *aclrecordproto.RawAclRecord, err error) { +func (a *aclRecordBuilder) BuildAccountRemove(payload AccountRemovePayload) (rawRecord *consensusproto.RawRecord, err error) { deletedMap := map[string]struct{}{} for _, key := range payload.Identities { permissions := a.state.Permissions(key) @@ -346,7 +347,7 @@ func (a *aclRecordBuilder) BuildAccountRemove(payload AccountRemovePayload) (raw return a.buildRecord(content) } -func (a *aclRecordBuilder) BuildRequestRemove() (rawRecord *aclrecordproto.RawAclRecord, err error) { +func (a *aclRecordBuilder) BuildRequestRemove() (rawRecord *consensusproto.RawRecord, err error) { permissions := a.state.Permissions(a.state.pubKey) if permissions.NoPermissions() { err = ErrNoSuchAccount @@ -361,8 +362,8 @@ func (a *aclRecordBuilder) BuildRequestRemove() (rawRecord *aclrecordproto.RawAc return a.buildRecord(content) } -func (a *aclRecordBuilder) Unmarshall(rawRecord *aclrecordproto.RawAclRecord) (rec *AclRecord, err error) { - aclRecord := &aclrecordproto.AclRecord{} +func (a *aclRecordBuilder) Unmarshall(rawRecord *consensusproto.RawRecord) (rec *AclRecord, err error) { + aclRecord := &consensusproto.Record{} err = proto.Unmarshal(rawRecord.Payload, aclRecord) if err != nil { return @@ -395,9 +396,9 @@ func (a *aclRecordBuilder) Unmarshall(rawRecord *aclrecordproto.RawAclRecord) (r return } -func (a *aclRecordBuilder) UnmarshallWithId(rawIdRecord *aclrecordproto.RawAclRecordWithId) (rec *AclRecord, err error) { +func (a *aclRecordBuilder) UnmarshallWithId(rawIdRecord *consensusproto.RawRecordWithId) (rec *AclRecord, err error) { var ( - rawRec = &aclrecordproto.RawAclRecord{} + rawRec = &consensusproto.RawRecord{} pubKey crypto.PubKey ) err = proto.Unmarshal(rawIdRecord.Payload, rawRec) @@ -426,7 +427,7 @@ func (a *aclRecordBuilder) UnmarshallWithId(rawIdRecord *aclrecordproto.RawAclRe if err != nil { return } - aclRecord := &aclrecordproto.AclRecord{} + aclRecord := &consensusproto.Record{} err = proto.Unmarshal(rawRec.Payload, aclRecord) if err != nil { return @@ -455,7 +456,7 @@ func (a *aclRecordBuilder) UnmarshallWithId(rawIdRecord *aclrecordproto.RawAclRe return } -func (a *aclRecordBuilder) BuildRoot(content RootContent) (rec *aclrecordproto.RawAclRecordWithId, err error) { +func (a *aclRecordBuilder) BuildRoot(content RootContent) (rec *consensusproto.RawRecordWithId, err error) { rawIdentity, err := content.PrivKey.GetPublic().Raw() if err != nil { return @@ -489,8 +490,8 @@ func (a *aclRecordBuilder) BuildRoot(content RootContent) (rec *aclrecordproto.R func verifyRaw( pubKey crypto.PubKey, - rawRec *aclrecordproto.RawAclRecord, - recWithId *aclrecordproto.RawAclRecordWithId) (err error) { + rawRec *consensusproto.RawRecord, + recWithId *consensusproto.RawRecordWithId) (err error) { // verifying signature res, err := pubKey.Verify(rawRec.Payload, rawRec.Signature) if err != nil { @@ -508,7 +509,7 @@ func verifyRaw( return } -func marshalAclRoot(aclRoot *aclrecordproto.AclRoot, key crypto.PrivKey) (rawWithId *aclrecordproto.RawAclRecordWithId, err error) { +func marshalAclRoot(aclRoot *aclrecordproto.AclRoot, key crypto.PrivKey) (rawWithId *consensusproto.RawRecordWithId, err error) { marshalledRoot, err := aclRoot.Marshal() if err != nil { return @@ -517,7 +518,7 @@ func marshalAclRoot(aclRoot *aclrecordproto.AclRoot, key crypto.PrivKey) (rawWit if err != nil { return } - raw := &aclrecordproto.RawAclRecord{ + raw := &consensusproto.RawRecord{ Payload: marshalledRoot, Signature: signature, } @@ -529,7 +530,7 @@ func marshalAclRoot(aclRoot *aclrecordproto.AclRoot, key crypto.PrivKey) (rawWit if err != nil { return } - rawWithId = &aclrecordproto.RawAclRecordWithId{ + rawWithId = &consensusproto.RawRecordWithId{ Payload: marshalledRaw, Id: aclHeadId, } diff --git a/commonspace/object/acl/list/list.go b/commonspace/object/acl/list/list.go index cedf772c..f336f823 100644 --- a/commonspace/object/acl/list/list.go +++ b/commonspace/object/acl/list/list.go @@ -8,8 +8,8 @@ import ( "sync" "github.com/anyproto/any-sync/commonspace/object/accountdata" - "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" "github.com/anyproto/any-sync/commonspace/object/acl/liststorage" + "github.com/anyproto/any-sync/consensus/consensusproto" "github.com/anyproto/any-sync/util/crypto" ) @@ -27,20 +27,20 @@ type RWLocker interface { } type AcceptorVerifier interface { - VerifyAcceptor(rec *aclrecordproto.RawAclRecord) (err error) + VerifyAcceptor(rec *consensusproto.RawRecord) (err error) } type NoOpAcceptorVerifier struct { } -func (n NoOpAcceptorVerifier) VerifyAcceptor(rec *aclrecordproto.RawAclRecord) (err error) { +func (n NoOpAcceptorVerifier) VerifyAcceptor(rec *consensusproto.RawRecord) (err error) { return nil } type AclList interface { RWLocker Id() string - Root() *aclrecordproto.RawAclRecordWithId + Root() *consensusproto.RawRecordWithId Records() []*AclRecord AclState() *AclState IsAfter(first string, second string) (bool, error) @@ -53,14 +53,14 @@ type AclList interface { KeyStorage() crypto.KeyStorage RecordBuilder() AclRecordBuilder - ValidateRawRecord(record *aclrecordproto.RawAclRecord) (err error) - AddRawRecord(rawRec *aclrecordproto.RawAclRecordWithId) (err error) + ValidateRawRecord(record *consensusproto.RawRecord) (err error) + AddRawRecord(rawRec *consensusproto.RawRecordWithId) (err error) Close() (err error) } type aclList struct { - root *aclrecordproto.RawAclRecordWithId + root *consensusproto.RawRecordWithId records []*AclRecord indexes map[string]int id string @@ -187,7 +187,7 @@ func (a *aclList) Records() []*AclRecord { return a.records } -func (a *aclList) ValidateRawRecord(rawRec *aclrecordproto.RawAclRecord) (err error) { +func (a *aclList) ValidateRawRecord(rawRec *consensusproto.RawRecord) (err error) { record, err := a.recordBuilder.Unmarshall(rawRec) if err != nil { return @@ -195,7 +195,7 @@ func (a *aclList) ValidateRawRecord(rawRec *aclrecordproto.RawAclRecord) (err er return a.aclState.Validator().ValidateAclRecordContents(record) } -func (a *aclList) AddRawRecord(rawRec *aclrecordproto.RawAclRecordWithId) (err error) { +func (a *aclList) AddRawRecord(rawRec *consensusproto.RawRecordWithId) (err error) { if _, ok := a.indexes[rawRec.Id]; ok { return ErrRecordAlreadyExists } @@ -221,7 +221,7 @@ func (a *aclList) Id() string { return a.id } -func (a *aclList) Root() *aclrecordproto.RawAclRecordWithId { +func (a *aclList) Root() *consensusproto.RawRecordWithId { return a.root } diff --git a/commonspace/object/acl/list/list_test.go b/commonspace/object/acl/list/list_test.go index 17a4a9ec..b1dda008 100644 --- a/commonspace/object/acl/list/list_test.go +++ b/commonspace/object/acl/list/list_test.go @@ -6,12 +6,13 @@ import ( "github.com/anyproto/any-sync/commonspace/object/accountdata" "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" + "github.com/anyproto/any-sync/consensus/consensusproto" "github.com/anyproto/any-sync/util/cidutil" "github.com/anyproto/any-sync/util/crypto" "github.com/stretchr/testify/require" ) -func wrapRecord(rawRec *aclrecordproto.RawAclRecord) *aclrecordproto.RawAclRecordWithId { +func wrapRecord(rawRec *consensusproto.RawRecord) *consensusproto.RawRecordWithId { payload, err := rawRec.Marshal() if err != nil { panic(err) @@ -20,7 +21,7 @@ func wrapRecord(rawRec *aclrecordproto.RawAclRecord) *aclrecordproto.RawAclRecor if err != nil { panic(err) } - return &aclrecordproto.RawAclRecordWithId{ + return &consensusproto.RawRecordWithId{ Payload: payload, Id: id, } @@ -53,7 +54,7 @@ func newFixture(t *testing.T) *aclFixture { } } -func (fx *aclFixture) addRec(t *testing.T, rec *aclrecordproto.RawAclRecordWithId) { +func (fx *aclFixture) addRec(t *testing.T, rec *consensusproto.RawRecordWithId) { err := fx.ownerAcl.AddRawRecord(rec) require.NoError(t, err) err = fx.accountAcl.AddRawRecord(rec) diff --git a/commonspace/object/acl/list/listutils.go b/commonspace/object/acl/list/listutils.go index d337dcc5..d512f748 100644 --- a/commonspace/object/acl/list/listutils.go +++ b/commonspace/object/acl/list/listutils.go @@ -2,8 +2,8 @@ package list import ( "github.com/anyproto/any-sync/commonspace/object/accountdata" - "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" "github.com/anyproto/any-sync/commonspace/object/acl/liststorage" + "github.com/anyproto/any-sync/consensus/consensusproto" "github.com/anyproto/any-sync/util/crypto" ) @@ -21,7 +21,7 @@ func NewTestDerivedAcl(spaceId string, keys *accountdata.AccountKeys) (AclList, if err != nil { return nil, err } - st, err := liststorage.NewInMemoryAclListStorage(root.Id, []*aclrecordproto.RawAclRecordWithId{ + st, err := liststorage.NewInMemoryAclListStorage(root.Id, []*consensusproto.RawRecordWithId{ root, }) if err != nil { @@ -30,8 +30,8 @@ func NewTestDerivedAcl(spaceId string, keys *accountdata.AccountKeys) (AclList, return BuildAclListWithIdentity(keys, st, NoOpAcceptorVerifier{}) } -func NewTestAclWithRoot(keys *accountdata.AccountKeys, root *aclrecordproto.RawAclRecordWithId) (AclList, error) { - st, err := liststorage.NewInMemoryAclListStorage(root.Id, []*aclrecordproto.RawAclRecordWithId{ +func NewTestAclWithRoot(keys *accountdata.AccountKeys, root *consensusproto.RawRecordWithId) (AclList, error) { + st, err := liststorage.NewInMemoryAclListStorage(root.Id, []*consensusproto.RawRecordWithId{ root, }) if err != nil { diff --git a/commonspace/object/acl/list/mock_list/mock_list.go b/commonspace/object/acl/list/mock_list/mock_list.go index 84ad11c1..012c71c6 100644 --- a/commonspace/object/acl/list/mock_list/mock_list.go +++ b/commonspace/object/acl/list/mock_list/mock_list.go @@ -7,8 +7,8 @@ package mock_list import ( reflect "reflect" - aclrecordproto "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" list "github.com/anyproto/any-sync/commonspace/object/acl/list" + consensusproto "github.com/anyproto/any-sync/consensus/consensusproto" crypto "github.com/anyproto/any-sync/util/crypto" gomock "github.com/golang/mock/gomock" ) @@ -51,7 +51,7 @@ func (mr *MockAclListMockRecorder) AclState() *gomock.Call { } // AddRawRecord mocks base method. -func (m *MockAclList) AddRawRecord(arg0 *aclrecordproto.RawAclRecordWithId) error { +func (m *MockAclList) AddRawRecord(arg0 *consensusproto.RawRecordWithId) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AddRawRecord", arg0) ret0, _ := ret[0].(error) @@ -254,10 +254,10 @@ func (mr *MockAclListMockRecorder) Records() *gomock.Call { } // Root mocks base method. -func (m *MockAclList) Root() *aclrecordproto.RawAclRecordWithId { +func (m *MockAclList) Root() *consensusproto.RawRecordWithId { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Root") - ret0, _ := ret[0].(*aclrecordproto.RawAclRecordWithId) + ret0, _ := ret[0].(*consensusproto.RawRecordWithId) return ret0 } @@ -280,7 +280,7 @@ func (mr *MockAclListMockRecorder) Unlock() *gomock.Call { } // ValidateRawRecord mocks base method. -func (m *MockAclList) ValidateRawRecord(arg0 *aclrecordproto.RawAclRecord) error { +func (m *MockAclList) ValidateRawRecord(arg0 *consensusproto.RawRecord) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ValidateRawRecord", arg0) ret0, _ := ret[0].(error) diff --git a/commonspace/object/acl/liststorage/inmemory.go b/commonspace/object/acl/liststorage/inmemory.go index 615fe948..276d4f78 100644 --- a/commonspace/object/acl/liststorage/inmemory.go +++ b/commonspace/object/acl/liststorage/inmemory.go @@ -3,24 +3,26 @@ package liststorage import ( "context" "fmt" - "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" + + "github.com/anyproto/any-sync/consensus/consensusproto" + "sync" ) type inMemoryAclListStorage struct { id string - root *aclrecordproto.RawAclRecordWithId + root *consensusproto.RawRecordWithId head string - records map[string]*aclrecordproto.RawAclRecordWithId + records map[string]*consensusproto.RawRecordWithId sync.RWMutex } func NewInMemoryAclListStorage( id string, - records []*aclrecordproto.RawAclRecordWithId) (ListStorage, error) { + records []*consensusproto.RawRecordWithId) (ListStorage, error) { - allRecords := make(map[string]*aclrecordproto.RawAclRecordWithId) + allRecords := make(map[string]*consensusproto.RawRecordWithId) for _, ch := range records { allRecords[ch.Id] = ch } @@ -41,7 +43,7 @@ func (t *inMemoryAclListStorage) Id() string { return t.id } -func (t *inMemoryAclListStorage) Root() (*aclrecordproto.RawAclRecordWithId, error) { +func (t *inMemoryAclListStorage) Root() (*consensusproto.RawRecordWithId, error) { t.RLock() defer t.RUnlock() return t.root, nil @@ -60,7 +62,7 @@ func (t *inMemoryAclListStorage) SetHead(head string) error { return nil } -func (t *inMemoryAclListStorage) AddRawRecord(ctx context.Context, record *aclrecordproto.RawAclRecordWithId) error { +func (t *inMemoryAclListStorage) AddRawRecord(ctx context.Context, record *consensusproto.RawRecordWithId) error { t.Lock() defer t.Unlock() // TODO: better to do deep copy @@ -68,7 +70,7 @@ func (t *inMemoryAclListStorage) AddRawRecord(ctx context.Context, record *aclre return nil } -func (t *inMemoryAclListStorage) GetRawRecord(ctx context.Context, recordId string) (*aclrecordproto.RawAclRecordWithId, error) { +func (t *inMemoryAclListStorage) GetRawRecord(ctx context.Context, recordId string) (*consensusproto.RawRecordWithId, error) { t.RLock() defer t.RUnlock() if res, exists := t.records[recordId]; exists { diff --git a/commonspace/object/acl/liststorage/liststorage.go b/commonspace/object/acl/liststorage/liststorage.go index 416fe100..f17e201f 100644 --- a/commonspace/object/acl/liststorage/liststorage.go +++ b/commonspace/object/acl/liststorage/liststorage.go @@ -4,7 +4,8 @@ package liststorage import ( "context" "errors" - "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" + + "github.com/anyproto/any-sync/consensus/consensusproto" ) var ( @@ -14,15 +15,15 @@ var ( ) type Exporter interface { - ListStorage(root *aclrecordproto.RawAclRecordWithId) (ListStorage, error) + ListStorage(root *consensusproto.RawRecordWithId) (ListStorage, error) } type ListStorage interface { Id() string - Root() (*aclrecordproto.RawAclRecordWithId, error) + Root() (*consensusproto.RawRecordWithId, 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 + GetRawRecord(ctx context.Context, id string) (*consensusproto.RawRecordWithId, error) + AddRawRecord(ctx context.Context, rec *consensusproto.RawRecordWithId) error } diff --git a/commonspace/object/acl/liststorage/mock_liststorage/mock_liststorage.go b/commonspace/object/acl/liststorage/mock_liststorage/mock_liststorage.go index ce0a8bbf..ef4781e6 100644 --- a/commonspace/object/acl/liststorage/mock_liststorage/mock_liststorage.go +++ b/commonspace/object/acl/liststorage/mock_liststorage/mock_liststorage.go @@ -8,7 +8,7 @@ import ( context "context" reflect "reflect" - aclrecordproto "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" + consensusproto "github.com/anyproto/any-sync/consensus/consensusproto" gomock "github.com/golang/mock/gomock" ) @@ -36,7 +36,7 @@ func (m *MockListStorage) EXPECT() *MockListStorageMockRecorder { } // AddRawRecord mocks base method. -func (m *MockListStorage) AddRawRecord(arg0 context.Context, arg1 *aclrecordproto.RawAclRecordWithId) error { +func (m *MockListStorage) AddRawRecord(arg0 context.Context, arg1 *consensusproto.RawRecordWithId) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AddRawRecord", arg0, arg1) ret0, _ := ret[0].(error) @@ -50,10 +50,10 @@ func (mr *MockListStorageMockRecorder) AddRawRecord(arg0, arg1 interface{}) *gom } // GetRawRecord mocks base method. -func (m *MockListStorage) GetRawRecord(arg0 context.Context, arg1 string) (*aclrecordproto.RawAclRecordWithId, error) { +func (m *MockListStorage) GetRawRecord(arg0 context.Context, arg1 string) (*consensusproto.RawRecordWithId, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetRawRecord", arg0, arg1) - ret0, _ := ret[0].(*aclrecordproto.RawAclRecordWithId) + ret0, _ := ret[0].(*consensusproto.RawRecordWithId) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -94,10 +94,10 @@ func (mr *MockListStorageMockRecorder) Id() *gomock.Call { } // Root mocks base method. -func (m *MockListStorage) Root() (*aclrecordproto.RawAclRecordWithId, error) { +func (m *MockListStorage) Root() (*consensusproto.RawRecordWithId, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Root") - ret0, _ := ret[0].(*aclrecordproto.RawAclRecordWithId) + ret0, _ := ret[0].(*consensusproto.RawRecordWithId) ret1, _ := ret[1].(error) return ret0, ret1 } diff --git a/commonspace/object/acl/syncacl/syncaclhandler.go b/commonspace/object/acl/syncacl/syncaclhandler.go index 5880f70f..357a4bc2 100644 --- a/commonspace/object/acl/syncacl/syncaclhandler.go +++ b/commonspace/object/acl/syncacl/syncaclhandler.go @@ -2,8 +2,7 @@ package syncacl import ( "context" - "fmt" - "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" + "github.com/anyproto/any-sync/commonspace/object/acl/list" "github.com/anyproto/any-sync/commonspace/spacesyncproto" ) @@ -13,19 +12,5 @@ type syncAclHandler struct { } 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 + return nil } diff --git a/commonspace/payloads.go b/commonspace/payloads.go index b3c9835b..4fb5c59c 100644 --- a/commonspace/payloads.go +++ b/commonspace/payloads.go @@ -14,6 +14,7 @@ import ( "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" "github.com/anyproto/any-sync/commonspace/spacestorage" "github.com/anyproto/any-sync/commonspace/spacesyncproto" + "github.com/anyproto/any-sync/consensus/consensusproto" "github.com/anyproto/any-sync/util/cidutil" "github.com/anyproto/any-sync/util/crypto" "github.com/gogo/protobuf/proto" @@ -255,12 +256,12 @@ func ValidateSpaceHeader(rawHeaderWithId *spacesyncproto.RawSpaceHeaderWithId, i return } -func validateCreateSpaceAclPayload(rawWithId *aclrecordproto.RawAclRecordWithId) (spaceId string, err error) { +func validateCreateSpaceAclPayload(rawWithId *consensusproto.RawRecordWithId) (spaceId string, err error) { if !cidutil.VerifyCid(rawWithId.Payload, rawWithId.Id) { err = objecttree.ErrIncorrectCid return } - var rawAcl aclrecordproto.RawAclRecord + var rawAcl consensusproto.RawRecord err = proto.Unmarshal(rawWithId.Payload, &rawAcl) if err != nil { return diff --git a/commonspace/payloads_test.go b/commonspace/payloads_test.go index f144f623..fbfe0f10 100644 --- a/commonspace/payloads_test.go +++ b/commonspace/payloads_test.go @@ -2,20 +2,22 @@ package commonspace import ( "fmt" + "math/rand" + "strconv" + "testing" + "time" + "github.com/anyproto/any-sync/commonspace/object/accountdata" "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" "github.com/anyproto/any-sync/commonspace/spacestorage" "github.com/anyproto/any-sync/commonspace/spacesyncproto" + "github.com/anyproto/any-sync/consensus/consensusproto" "github.com/anyproto/any-sync/util/cidutil" "github.com/anyproto/any-sync/util/crypto" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "math/rand" - "strconv" - "testing" - "time" ) func TestSuccessHeaderPayloadForSpaceCreate(t *testing.T) { @@ -188,14 +190,14 @@ func TestFailAclPayloadSpace_IncorrectCid(t *testing.T) { marshalled, err := aclRoot.Marshal() require.NoError(t, err) signature, err := accountKeys.SignKey.Sign(marshalled) - rawAclRecord := &aclrecordproto.RawAclRecord{ + rawAclRecord := &consensusproto.RawRecord{ Payload: marshalled, Signature: signature, } marshalledRaw, err := rawAclRecord.Marshal() require.NoError(t, err) aclHeadId := "rand" - rawWithId := &aclrecordproto.RawAclRecordWithId{ + rawWithId := &consensusproto.RawRecordWithId{ Payload: marshalledRaw, Id: aclHeadId, } @@ -230,7 +232,7 @@ func TestFailedAclPayloadSpace_IncorrectSignature(t *testing.T) { } marshalled, err := aclRoot.Marshal() require.NoError(t, err) - rawAclRecord := &aclrecordproto.RawAclRecord{ + rawAclRecord := &consensusproto.RawRecord{ Payload: marshalled, Signature: marshalled, } @@ -238,7 +240,7 @@ func TestFailedAclPayloadSpace_IncorrectSignature(t *testing.T) { require.NoError(t, err) aclHeadId, err := cidutil.NewCidFromBytes(marshalledRaw) require.NoError(t, err) - rawWithId := &aclrecordproto.RawAclRecordWithId{ + rawWithId := &consensusproto.RawRecordWithId{ Payload: marshalledRaw, Id: aclHeadId, } @@ -286,7 +288,7 @@ func TestFailedAclPayloadSpace_IncorrectIdentitySignature(t *testing.T) { return } signature, err := accountKeys.SignKey.Sign(marshalled) - rawAclRecord := &aclrecordproto.RawAclRecord{ + rawAclRecord := &consensusproto.RawRecord{ Payload: marshalled, Signature: signature, } @@ -298,7 +300,7 @@ func TestFailedAclPayloadSpace_IncorrectIdentitySignature(t *testing.T) { if err != nil { return } - rawWithId := &aclrecordproto.RawAclRecordWithId{ + rawWithId := &consensusproto.RawRecordWithId{ Payload: marshalledRaw, Id: aclHeadId, } @@ -540,7 +542,7 @@ func rawSettingsPayload(accountKeys *accountdata.AccountKeys, spaceId, aclHeadId return } -func rawAclWithId(accountKeys *accountdata.AccountKeys, spaceId string) (aclHeadId string, rawWithId *aclrecordproto.RawAclRecordWithId, err error) { +func rawAclWithId(accountKeys *accountdata.AccountKeys, spaceId string) (aclHeadId string, rawWithId *consensusproto.RawRecordWithId, err error) { // TODO: use same storage creation methods as we use in spaces readKeyBytes := make([]byte, 32) _, err = rand.Read(readKeyBytes) @@ -582,7 +584,7 @@ func rawAclWithId(accountKeys *accountdata.AccountKeys, spaceId string) (aclHead return } signature, err := accountKeys.SignKey.Sign(marshalled) - rawAclRecord := &aclrecordproto.RawAclRecord{ + rawAclRecord := &consensusproto.RawRecord{ Payload: marshalled, Signature: signature, } @@ -594,7 +596,7 @@ func rawAclWithId(accountKeys *accountdata.AccountKeys, spaceId string) (aclHead if err != nil { return } - rawWithId = &aclrecordproto.RawAclRecordWithId{ + rawWithId = &consensusproto.RawRecordWithId{ Payload: marshalledRaw, Id: aclHeadId, } diff --git a/commonspace/spaceservice.go b/commonspace/spaceservice.go index 3e441aea..3397e212 100644 --- a/commonspace/spaceservice.go +++ b/commonspace/spaceservice.go @@ -2,6 +2,8 @@ package commonspace import ( "context" + "sync/atomic" + "github.com/anyproto/any-sync/accountservice" "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/app/logger" @@ -9,7 +11,6 @@ import ( "github.com/anyproto/any-sync/commonspace/credentialprovider" "github.com/anyproto/any-sync/commonspace/deletionstate" "github.com/anyproto/any-sync/commonspace/headsync" - "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" "github.com/anyproto/any-sync/commonspace/object/acl/syncacl" "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" @@ -24,13 +25,13 @@ import ( "github.com/anyproto/any-sync/commonspace/spacestorage" "github.com/anyproto/any-sync/commonspace/spacesyncproto" "github.com/anyproto/any-sync/commonspace/syncstatus" + "github.com/anyproto/any-sync/consensus/consensusproto" "github.com/anyproto/any-sync/metric" "github.com/anyproto/any-sync/net/peer" "github.com/anyproto/any-sync/net/pool" "github.com/anyproto/any-sync/net/rpc/rpcerr" "github.com/anyproto/any-sync/nodeconf" "storj.io/drpc" - "sync/atomic" ) const CName = "common.commonspace" @@ -193,7 +194,7 @@ func (s *spaceService) NewSpace(ctx context.Context, id string) (Space, error) { func (s *spaceService) addSpaceStorage(ctx context.Context, spaceDescription SpaceDescription) (st spacestorage.SpaceStorage, err error) { payload := spacestorage.SpaceStorageCreatePayload{ - AclWithId: &aclrecordproto.RawAclRecordWithId{ + AclWithId: &consensusproto.RawRecordWithId{ Payload: spaceDescription.AclPayload, Id: spaceDescription.AclId, }, @@ -240,7 +241,7 @@ func (s *spaceService) getSpaceStorageFromRemote(ctx context.Context, id string) } st, err = s.createSpaceStorage(spacestorage.SpaceStorageCreatePayload{ - AclWithId: &aclrecordproto.RawAclRecordWithId{ + AclWithId: &consensusproto.RawRecordWithId{ Payload: res.Payload.AclPayload, Id: res.Payload.AclPayloadId, }, diff --git a/commonspace/spacestorage/inmemorystorage.go b/commonspace/spacestorage/inmemorystorage.go index 096f5a84..0550ffbc 100644 --- a/commonspace/spacestorage/inmemorystorage.go +++ b/commonspace/spacestorage/inmemorystorage.go @@ -2,12 +2,14 @@ package spacestorage import ( "context" + "github.com/anyproto/any-sync/app" - "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" "github.com/anyproto/any-sync/commonspace/object/acl/liststorage" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" "github.com/anyproto/any-sync/commonspace/object/tree/treestorage" "github.com/anyproto/any-sync/commonspace/spacesyncproto" + "github.com/anyproto/any-sync/consensus/consensusproto" + "sync" ) @@ -40,7 +42,7 @@ func (i *InMemorySpaceStorage) Name() (name string) { } func NewInMemorySpaceStorage(payload SpaceStorageCreatePayload) (SpaceStorage, error) { - aclStorage, err := liststorage.NewInMemoryAclListStorage(payload.AclWithId.Id, []*aclrecordproto.RawAclRecordWithId{payload.AclWithId}) + aclStorage, err := liststorage.NewInMemoryAclListStorage(payload.AclWithId.Id, []*consensusproto.RawRecordWithId{payload.AclWithId}) if err != nil { return nil, err } diff --git a/commonspace/spacestorage/spacestorage.go b/commonspace/spacestorage/spacestorage.go index e2807f5a..a0976f3e 100644 --- a/commonspace/spacestorage/spacestorage.go +++ b/commonspace/spacestorage/spacestorage.go @@ -4,12 +4,13 @@ package spacestorage import ( "context" "errors" + "github.com/anyproto/any-sync/app" - "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" "github.com/anyproto/any-sync/commonspace/object/acl/liststorage" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" "github.com/anyproto/any-sync/commonspace/object/tree/treestorage" "github.com/anyproto/any-sync/commonspace/spacesyncproto" + "github.com/anyproto/any-sync/consensus/consensusproto" ) const CName = "common.commonspace.spacestorage" @@ -47,7 +48,7 @@ type SpaceStorage interface { } type SpaceStorageCreatePayload struct { - AclWithId *aclrecordproto.RawAclRecordWithId + AclWithId *consensusproto.RawRecordWithId SpaceHeaderWithId *spacesyncproto.RawSpaceHeaderWithId SpaceSettingsWithId *treechangeproto.RawTreeChangeWithId } diff --git a/commonspace/spacesyncproto/spacesync_drpc.pb.go b/commonspace/spacesyncproto/spacesync_drpc.pb.go index f9c7abae..11e5d715 100644 --- a/commonspace/spacesyncproto/spacesync_drpc.pb.go +++ b/commonspace/spacesyncproto/spacesync_drpc.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-go-drpc. DO NOT EDIT. -// protoc-gen-go-drpc version: v0.0.32 +// protoc-gen-go-drpc version: v0.0.33 // source: commonspace/spacesyncproto/protos/spacesync.proto package spacesyncproto @@ -103,6 +103,10 @@ type drpcSpaceSync_ObjectSyncStreamClient struct { drpc.Stream } +func (x *drpcSpaceSync_ObjectSyncStreamClient) GetStream() drpc.Stream { + return x.Stream +} + func (x *drpcSpaceSync_ObjectSyncStreamClient) Send(m *ObjectSyncMessage) error { return x.MsgSend(m, drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto{}) } diff --git a/coordinator/coordinatorproto/coordinator_drpc.pb.go b/coordinator/coordinatorproto/coordinator_drpc.pb.go index 75e73a7b..0ed69ea2 100644 --- a/coordinator/coordinatorproto/coordinator_drpc.pb.go +++ b/coordinator/coordinatorproto/coordinator_drpc.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-go-drpc. DO NOT EDIT. -// protoc-gen-go-drpc version: v0.0.32 +// protoc-gen-go-drpc version: v0.0.33 // source: coordinator/coordinatorproto/protos/coordinator.proto package coordinatorproto diff --git a/net/streampool/testservice/testservice_drpc.pb.go b/net/streampool/testservice/testservice_drpc.pb.go index f50fdbe7..cfe5bce9 100644 --- a/net/streampool/testservice/testservice_drpc.pb.go +++ b/net/streampool/testservice/testservice_drpc.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-go-drpc. DO NOT EDIT. -// protoc-gen-go-drpc version: v0.0.32 +// protoc-gen-go-drpc version: v0.0.33 // source: net/streampool/testservice/protos/testservice.proto package testservice @@ -72,6 +72,10 @@ type drpcTest_TestStreamClient struct { drpc.Stream } +func (x *drpcTest_TestStreamClient) GetStream() drpc.Stream { + return x.Stream +} + func (x *drpcTest_TestStreamClient) Send(m *StreamMessage) error { return x.MsgSend(m, drpcEncoding_File_net_streampool_testservice_protos_testservice_proto{}) } From 51ac955f1cd208eeef48d05417a75aa5418f9c96 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Sun, 2 Jul 2023 15:55:58 +0200 Subject: [PATCH 102/123] Add sync protocol interfaces --- commonspace/object/acl/list/list.go | 11 + .../object/acl/syncacl/aclsyncprotocol.go | 44 + .../object/acl/syncacl/requestfactory.go | 30 + commonspace/object/acl/syncacl/syncacl.go | 69 +- .../object/acl/syncacl/syncaclhandler.go | 24 +- commonspace/object/acl/syncacl/syncclient.go | 49 + .../object/tree/synctree/syncclient.go | 2 + consensus/consensusproto/consensus.pb.go | 1408 ++++++++++++++++- .../consensusproto/protos/consensus.proto | 35 +- 9 files changed, 1627 insertions(+), 45 deletions(-) create mode 100644 commonspace/object/acl/syncacl/aclsyncprotocol.go create mode 100644 commonspace/object/acl/syncacl/requestfactory.go create mode 100644 commonspace/object/acl/syncacl/syncclient.go diff --git a/commonspace/object/acl/list/list.go b/commonspace/object/acl/list/list.go index f336f823..93a4a952 100644 --- a/commonspace/object/acl/list/list.go +++ b/commonspace/object/acl/list/list.go @@ -55,6 +55,7 @@ type AclList interface { ValidateRawRecord(record *consensusproto.RawRecord) (err error) AddRawRecord(rawRec *consensusproto.RawRecordWithId) (err error) + AddRawRecords(rawRecords []*consensusproto.RawRecordWithId) (err error) Close() (err error) } @@ -195,6 +196,16 @@ func (a *aclList) ValidateRawRecord(rawRec *consensusproto.RawRecord) (err error return a.aclState.Validator().ValidateAclRecordContents(record) } +func (a *aclList) AddRawRecords(rawRecords []*consensusproto.RawRecordWithId) (err error) { + for _, rec := range rawRecords { + err = a.AddRawRecord(rec) + if err != nil { + return + } + } + return +} + func (a *aclList) AddRawRecord(rawRec *consensusproto.RawRecordWithId) (err error) { if _, ok := a.indexes[rawRec.Id]; ok { return ErrRecordAlreadyExists diff --git a/commonspace/object/acl/syncacl/aclsyncprotocol.go b/commonspace/object/acl/syncacl/aclsyncprotocol.go new file mode 100644 index 00000000..a040ae19 --- /dev/null +++ b/commonspace/object/acl/syncacl/aclsyncprotocol.go @@ -0,0 +1,44 @@ +package syncacl + +import ( + "context" + + "github.com/anyproto/any-sync/app/logger" + "github.com/anyproto/any-sync/commonspace/object/acl/list" + "github.com/anyproto/any-sync/consensus/consensusproto" + "go.uber.org/zap" +) + +type AclSyncProtocol interface { + HeadUpdate(ctx context.Context, senderId string, update *consensusproto.LogHeadUpdate) (request *consensusproto.LogSyncMessage, err error) + FullSyncRequest(ctx context.Context, senderId string, request *consensusproto.LogFullSyncRequest) (response *consensusproto.LogSyncMessage, err error) + FullSyncResponse(ctx context.Context, senderId string, response *consensusproto.LogFullSyncResponse) (err error) +} + +type aclSyncProtocol struct { + log logger.CtxLogger + spaceId string + aclList list.AclList + reqFactory RequestFactory +} + +func (a *aclSyncProtocol) HeadUpdate(ctx context.Context, senderId string, update *consensusproto.LogHeadUpdate) (request *consensusproto.LogSyncMessage, err error) { + return +} + +func (a *aclSyncProtocol) FullSyncRequest(ctx context.Context, senderId string, request *consensusproto.LogFullSyncRequest) (response *consensusproto.LogSyncMessage, err error) { + return +} + +func (a *aclSyncProtocol) FullSyncResponse(ctx context.Context, senderId string, response *consensusproto.LogFullSyncResponse) (err error) { + return +} + +func newAclSyncProtocol(spaceId string, aclList list.AclList, reqFactory RequestFactory) *aclSyncProtocol { + return &aclSyncProtocol{ + log: log.With(zap.String("spaceId", spaceId), zap.String("aclId", aclList.Id())), + spaceId: spaceId, + aclList: aclList, + reqFactory: reqFactory, + } +} diff --git a/commonspace/object/acl/syncacl/requestfactory.go b/commonspace/object/acl/syncacl/requestfactory.go new file mode 100644 index 00000000..957ec402 --- /dev/null +++ b/commonspace/object/acl/syncacl/requestfactory.go @@ -0,0 +1,30 @@ +package syncacl + +import ( + "github.com/anyproto/any-sync/commonspace/object/acl/list" + "github.com/anyproto/any-sync/consensus/consensusproto" +) + +type RequestFactory interface { + CreateHeadUpdate(l list.AclList, added []*consensusproto.RawRecordWithId) (msg *consensusproto.LogSyncMessage) + CreateFullSyncRequest(theirHead string) (req *consensusproto.LogSyncMessage, err error) + CreateFullSyncResponse(l list.AclList, theirHead string) (*consensusproto.LogSyncMessage, error) +} + +func NewRequestFactory() RequestFactory { + return &requestFactory{} +} + +type requestFactory struct{} + +func (r *requestFactory) CreateHeadUpdate(l list.AclList, added []*consensusproto.RawRecordWithId) (msg *consensusproto.LogSyncMessage) { + return +} + +func (r *requestFactory) CreateFullSyncRequest(theirHead string) (req *consensusproto.LogSyncMessage, err error) { + return +} + +func (r *requestFactory) CreateFullSyncResponse(l list.AclList, theirHead string) (*consensusproto.LogSyncMessage, error) { + return nil, nil +} diff --git a/commonspace/object/acl/syncacl/syncacl.go b/commonspace/object/acl/syncacl/syncacl.go index 360e0646..30a958b7 100644 --- a/commonspace/object/acl/syncacl/syncacl.go +++ b/commonspace/object/acl/syncacl/syncacl.go @@ -2,30 +2,46 @@ package syncacl import ( "context" + "errors" "github.com/anyproto/any-sync/accountservice" "github.com/anyproto/any-sync/app" + "github.com/anyproto/any-sync/app/logger" "github.com/anyproto/any-sync/commonspace/object/acl/list" + "github.com/anyproto/any-sync/commonspace/objectsync/synchandler" + "github.com/anyproto/any-sync/commonspace/peermanager" + "github.com/anyproto/any-sync/commonspace/requestmanager" "github.com/anyproto/any-sync/commonspace/spacestorage" "github.com/anyproto/any-sync/commonspace/spacesyncproto" + "github.com/anyproto/any-sync/commonspace/syncstatus" + "github.com/anyproto/any-sync/consensus/consensusproto" ) const CName = "common.acl.syncacl" +var ( + log = logger.NewNamed(CName) + + ErrSyncAclClosed = errors.New("sync acl is closed") +) + func New() *SyncAcl { return &SyncAcl{} } type SyncAcl struct { list.AclList + syncClient SyncClient + syncHandler synchandler.SyncHandler + isClosed bool } func (s *SyncAcl) HandleRequest(ctx context.Context, senderId string, request *spacesyncproto.ObjectSyncMessage) (response *spacesyncproto.ObjectSyncMessage, err error) { - return nil, nil + return s.HandleRequest(ctx, senderId, request) } func (s *SyncAcl) HandleMessage(ctx context.Context, senderId string, request *spacesyncproto.ObjectSyncMessage) (err error) { - return nil + return s.HandleMessage(ctx, senderId, request) } func (s *SyncAcl) Init(a *app.App) (err error) { @@ -36,9 +52,58 @@ func (s *SyncAcl) Init(a *app.App) (err error) { } acc := a.MustComponent(accountservice.CName).(accountservice.Service) s.AclList, err = list.BuildAclListWithIdentity(acc.Account(), aclStorage, list.NoOpAcceptorVerifier{}) + if err != nil { + return + } + spaceId := storage.Id() + requestManager := a.MustComponent(requestmanager.CName).(requestmanager.RequestManager) + peerManager := a.MustComponent(peermanager.CName).(peermanager.PeerManager) + syncStatus := a.MustComponent(syncstatus.CName).(syncstatus.StatusService) + s.syncClient = NewSyncClient(spaceId, requestManager, peerManager) + s.syncHandler = newSyncAclHandler(storage.Id(), s, s.syncClient, syncStatus) return err } +func (s *SyncAcl) AddRawRecord(rawRec *consensusproto.RawRecordWithId) (err error) { + if s.isClosed { + return ErrSyncAclClosed + } + err = s.AclList.AddRawRecord(rawRec) + if err != nil { + return + } + headUpdate := s.syncClient.CreateHeadUpdate(s, []*consensusproto.RawRecordWithId{rawRec}) + s.syncClient.Broadcast(headUpdate) + return +} + +func (s *SyncAcl) AddRawRecords(rawRecords []*consensusproto.RawRecordWithId) (err error) { + if s.isClosed { + return ErrSyncAclClosed + } + err = s.AclList.AddRawRecords(rawRecords) + if err != nil { + return + } + headUpdate := s.syncClient.CreateHeadUpdate(s, rawRecords) + s.syncClient.Broadcast(headUpdate) + return +} + +func (s *SyncAcl) SyncWithPeer(ctx context.Context, peerId string) (err error) { + s.Lock() + defer s.Unlock() + headUpdate := s.syncClient.CreateHeadUpdate(s, nil) + return s.syncClient.SendUpdate(peerId, s.Id(), headUpdate) +} + +func (s *SyncAcl) Close() (err error) { + s.Lock() + defer s.Unlock() + s.isClosed = true + return +} + func (s *SyncAcl) Name() (name string) { return CName } diff --git a/commonspace/object/acl/syncacl/syncaclhandler.go b/commonspace/object/acl/syncacl/syncaclhandler.go index 357a4bc2..f0c4e026 100644 --- a/commonspace/object/acl/syncacl/syncaclhandler.go +++ b/commonspace/object/acl/syncacl/syncaclhandler.go @@ -4,13 +4,33 @@ import ( "context" "github.com/anyproto/any-sync/commonspace/object/acl/list" + "github.com/anyproto/any-sync/commonspace/objectsync/synchandler" "github.com/anyproto/any-sync/commonspace/spacesyncproto" + "github.com/anyproto/any-sync/commonspace/syncstatus" ) type syncAclHandler struct { - acl list.AclList + aclList list.AclList + syncClient SyncClient + syncProtocol AclSyncProtocol + syncStatus syncstatus.StatusUpdater + spaceId string +} + +func newSyncAclHandler(spaceId string, aclList list.AclList, syncClient SyncClient, syncStatus syncstatus.StatusUpdater) synchandler.SyncHandler { + return &syncAclHandler{ + aclList: aclList, + syncClient: syncClient, + syncProtocol: newAclSyncProtocol(spaceId, aclList, syncClient), + syncStatus: syncStatus, + spaceId: spaceId, + } } func (s *syncAclHandler) HandleMessage(ctx context.Context, senderId string, req *spacesyncproto.ObjectSyncMessage) (err error) { - return nil + return +} + +func (s *syncAclHandler) HandleRequest(ctx context.Context, senderId string, request *spacesyncproto.ObjectSyncMessage) (response *spacesyncproto.ObjectSyncMessage, err error) { + return } diff --git a/commonspace/object/acl/syncacl/syncclient.go b/commonspace/object/acl/syncacl/syncclient.go new file mode 100644 index 00000000..c06692c5 --- /dev/null +++ b/commonspace/object/acl/syncacl/syncclient.go @@ -0,0 +1,49 @@ +package syncacl + +import ( + "context" + + "github.com/anyproto/any-sync/commonspace/peermanager" + "github.com/anyproto/any-sync/commonspace/requestmanager" + "github.com/anyproto/any-sync/commonspace/spacesyncproto" + "github.com/anyproto/any-sync/consensus/consensusproto" +) + +type SyncClient interface { + RequestFactory + Broadcast(msg *consensusproto.LogSyncMessage) + SendUpdate(peerId, objectId string, msg *consensusproto.LogSyncMessage) (err error) + QueueRequest(peerId, objectId string, msg *consensusproto.LogSyncMessage) (err error) + SendRequest(ctx context.Context, peerId, objectId string, msg *consensusproto.LogSyncMessage) (reply *spacesyncproto.ObjectSyncMessage, err error) +} + +type syncClient struct { + RequestFactory + spaceId string + requestManager requestmanager.RequestManager + peerManager peermanager.PeerManager +} + +func (s *syncClient) Broadcast(msg *consensusproto.LogSyncMessage) { +} + +func (s *syncClient) SendUpdate(peerId, objectId string, msg *consensusproto.LogSyncMessage) (err error) { + return +} + +func (s *syncClient) QueueRequest(peerId, objectId string, msg *consensusproto.LogSyncMessage) (err error) { + return +} + +func (s *syncClient) SendRequest(ctx context.Context, peerId, objectId string, msg *consensusproto.LogSyncMessage) (reply *spacesyncproto.ObjectSyncMessage, err error) { + return +} + +func NewSyncClient(spaceId string, requestManager requestmanager.RequestManager, peerManager peermanager.PeerManager) SyncClient { + return &syncClient{ + RequestFactory: &requestFactory{}, + spaceId: spaceId, + requestManager: requestManager, + peerManager: peerManager, + } +} diff --git a/commonspace/object/tree/synctree/syncclient.go b/commonspace/object/tree/synctree/syncclient.go index 13909b3b..ecf3f6c0 100644 --- a/commonspace/object/tree/synctree/syncclient.go +++ b/commonspace/object/tree/synctree/syncclient.go @@ -2,6 +2,7 @@ package synctree import ( "context" + "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" "github.com/anyproto/any-sync/commonspace/peermanager" "github.com/anyproto/any-sync/commonspace/requestmanager" @@ -32,6 +33,7 @@ func NewSyncClient(spaceId string, requestManager requestmanager.RequestManager, peerManager: peerManager, } } + func (s *syncClient) Broadcast(msg *treechangeproto.TreeSyncMessage) { objMsg, err := MarshallTreeMessage(msg, s.spaceId, msg.RootChange.Id, "") if err != nil { diff --git a/consensus/consensusproto/consensus.pb.go b/consensus/consensusproto/consensus.pb.go index 4e81e61c..c00d8b25 100644 --- a/consensus/consensusproto/consensus.pb.go +++ b/consensus/consensusproto/consensus.pb.go @@ -595,6 +595,318 @@ func (m *Err) GetError() ErrCodes { return ErrCodes_Unexpected } +// LogSyncContentValue provides different types for log sync +type LogSyncContentValue struct { + // Types that are valid to be assigned to Value: + // + // *LogSyncContentValue_HeadUpdate + // *LogSyncContentValue_FullSyncRequest + // *LogSyncContentValue_FullSyncResponse + Value isLogSyncContentValue_Value `protobuf_oneof:"value"` +} + +func (m *LogSyncContentValue) Reset() { *m = LogSyncContentValue{} } +func (m *LogSyncContentValue) String() string { return proto.CompactTextString(m) } +func (*LogSyncContentValue) ProtoMessage() {} +func (*LogSyncContentValue) Descriptor() ([]byte, []int) { + return fileDescriptor_b8d7f1c16b400059, []int{10} +} +func (m *LogSyncContentValue) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LogSyncContentValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_LogSyncContentValue.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 *LogSyncContentValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_LogSyncContentValue.Merge(m, src) +} +func (m *LogSyncContentValue) XXX_Size() int { + return m.Size() +} +func (m *LogSyncContentValue) XXX_DiscardUnknown() { + xxx_messageInfo_LogSyncContentValue.DiscardUnknown(m) +} + +var xxx_messageInfo_LogSyncContentValue proto.InternalMessageInfo + +type isLogSyncContentValue_Value interface { + isLogSyncContentValue_Value() + MarshalTo([]byte) (int, error) + Size() int +} + +type LogSyncContentValue_HeadUpdate struct { + HeadUpdate *LogHeadUpdate `protobuf:"bytes,1,opt,name=headUpdate,proto3,oneof" json:"headUpdate,omitempty"` +} +type LogSyncContentValue_FullSyncRequest struct { + FullSyncRequest *LogFullSyncRequest `protobuf:"bytes,2,opt,name=fullSyncRequest,proto3,oneof" json:"fullSyncRequest,omitempty"` +} +type LogSyncContentValue_FullSyncResponse struct { + FullSyncResponse *LogFullSyncResponse `protobuf:"bytes,3,opt,name=fullSyncResponse,proto3,oneof" json:"fullSyncResponse,omitempty"` +} + +func (*LogSyncContentValue_HeadUpdate) isLogSyncContentValue_Value() {} +func (*LogSyncContentValue_FullSyncRequest) isLogSyncContentValue_Value() {} +func (*LogSyncContentValue_FullSyncResponse) isLogSyncContentValue_Value() {} + +func (m *LogSyncContentValue) GetValue() isLogSyncContentValue_Value { + if m != nil { + return m.Value + } + return nil +} + +func (m *LogSyncContentValue) GetHeadUpdate() *LogHeadUpdate { + if x, ok := m.GetValue().(*LogSyncContentValue_HeadUpdate); ok { + return x.HeadUpdate + } + return nil +} + +func (m *LogSyncContentValue) GetFullSyncRequest() *LogFullSyncRequest { + if x, ok := m.GetValue().(*LogSyncContentValue_FullSyncRequest); ok { + return x.FullSyncRequest + } + return nil +} + +func (m *LogSyncContentValue) GetFullSyncResponse() *LogFullSyncResponse { + if x, ok := m.GetValue().(*LogSyncContentValue_FullSyncResponse); ok { + return x.FullSyncResponse + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*LogSyncContentValue) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*LogSyncContentValue_HeadUpdate)(nil), + (*LogSyncContentValue_FullSyncRequest)(nil), + (*LogSyncContentValue_FullSyncResponse)(nil), + } +} + +// LogSyncMessage is a message sent when we are syncing logs +type LogSyncMessage struct { + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Payload string `protobuf:"bytes,2,opt,name=payload,proto3" json:"payload,omitempty"` + Content *LogSyncContentValue `protobuf:"bytes,3,opt,name=content,proto3" json:"content,omitempty"` +} + +func (m *LogSyncMessage) Reset() { *m = LogSyncMessage{} } +func (m *LogSyncMessage) String() string { return proto.CompactTextString(m) } +func (*LogSyncMessage) ProtoMessage() {} +func (*LogSyncMessage) Descriptor() ([]byte, []int) { + return fileDescriptor_b8d7f1c16b400059, []int{11} +} +func (m *LogSyncMessage) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LogSyncMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_LogSyncMessage.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 *LogSyncMessage) XXX_Merge(src proto.Message) { + xxx_messageInfo_LogSyncMessage.Merge(m, src) +} +func (m *LogSyncMessage) XXX_Size() int { + return m.Size() +} +func (m *LogSyncMessage) XXX_DiscardUnknown() { + xxx_messageInfo_LogSyncMessage.DiscardUnknown(m) +} + +var xxx_messageInfo_LogSyncMessage proto.InternalMessageInfo + +func (m *LogSyncMessage) GetId() string { + if m != nil { + return m.Id + } + return "" +} + +func (m *LogSyncMessage) GetPayload() string { + if m != nil { + return m.Payload + } + return "" +} + +func (m *LogSyncMessage) GetContent() *LogSyncContentValue { + if m != nil { + return m.Content + } + return nil +} + +// LogHeadUpdate is a message sent on consensus log head update +type LogHeadUpdate struct { + Head string `protobuf:"bytes,1,opt,name=head,proto3" json:"head,omitempty"` + Records []*RawRecordWithId `protobuf:"bytes,2,rep,name=records,proto3" json:"records,omitempty"` +} + +func (m *LogHeadUpdate) Reset() { *m = LogHeadUpdate{} } +func (m *LogHeadUpdate) String() string { return proto.CompactTextString(m) } +func (*LogHeadUpdate) ProtoMessage() {} +func (*LogHeadUpdate) Descriptor() ([]byte, []int) { + return fileDescriptor_b8d7f1c16b400059, []int{12} +} +func (m *LogHeadUpdate) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LogHeadUpdate) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_LogHeadUpdate.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 *LogHeadUpdate) XXX_Merge(src proto.Message) { + xxx_messageInfo_LogHeadUpdate.Merge(m, src) +} +func (m *LogHeadUpdate) XXX_Size() int { + return m.Size() +} +func (m *LogHeadUpdate) XXX_DiscardUnknown() { + xxx_messageInfo_LogHeadUpdate.DiscardUnknown(m) +} + +var xxx_messageInfo_LogHeadUpdate proto.InternalMessageInfo + +func (m *LogHeadUpdate) GetHead() string { + if m != nil { + return m.Head + } + return "" +} + +func (m *LogHeadUpdate) GetRecords() []*RawRecordWithId { + if m != nil { + return m.Records + } + return nil +} + +// LogFullSyncRequest is a message sent when consensus log needs full sync +type LogFullSyncRequest struct { + Head string `protobuf:"bytes,1,opt,name=head,proto3" json:"head,omitempty"` +} + +func (m *LogFullSyncRequest) Reset() { *m = LogFullSyncRequest{} } +func (m *LogFullSyncRequest) String() string { return proto.CompactTextString(m) } +func (*LogFullSyncRequest) ProtoMessage() {} +func (*LogFullSyncRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_b8d7f1c16b400059, []int{13} +} +func (m *LogFullSyncRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LogFullSyncRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_LogFullSyncRequest.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 *LogFullSyncRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_LogFullSyncRequest.Merge(m, src) +} +func (m *LogFullSyncRequest) XXX_Size() int { + return m.Size() +} +func (m *LogFullSyncRequest) XXX_DiscardUnknown() { + xxx_messageInfo_LogFullSyncRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_LogFullSyncRequest proto.InternalMessageInfo + +func (m *LogFullSyncRequest) GetHead() string { + if m != nil { + return m.Head + } + return "" +} + +// LogFullSyncResponse is a message sent as a response for a specific full sync +type LogFullSyncResponse struct { + Head string `protobuf:"bytes,1,opt,name=head,proto3" json:"head,omitempty"` + Records []*RawRecordWithId `protobuf:"bytes,2,rep,name=records,proto3" json:"records,omitempty"` +} + +func (m *LogFullSyncResponse) Reset() { *m = LogFullSyncResponse{} } +func (m *LogFullSyncResponse) String() string { return proto.CompactTextString(m) } +func (*LogFullSyncResponse) ProtoMessage() {} +func (*LogFullSyncResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_b8d7f1c16b400059, []int{14} +} +func (m *LogFullSyncResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LogFullSyncResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_LogFullSyncResponse.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 *LogFullSyncResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_LogFullSyncResponse.Merge(m, src) +} +func (m *LogFullSyncResponse) XXX_Size() int { + return m.Size() +} +func (m *LogFullSyncResponse) XXX_DiscardUnknown() { + xxx_messageInfo_LogFullSyncResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_LogFullSyncResponse proto.InternalMessageInfo + +func (m *LogFullSyncResponse) GetHead() string { + if m != nil { + return m.Head + } + return "" +} + +func (m *LogFullSyncResponse) GetRecords() []*RawRecordWithId { + if m != nil { + return m.Records + } + return nil +} + func init() { proto.RegisterEnum("consensusProto.ErrCodes", ErrCodes_name, ErrCodes_value) proto.RegisterType((*Log)(nil), "consensusProto.Log") @@ -607,6 +919,11 @@ func init() { proto.RegisterType((*LogWatchRequest)(nil), "consensusProto.LogWatchRequest") proto.RegisterType((*LogWatchEvent)(nil), "consensusProto.LogWatchEvent") proto.RegisterType((*Err)(nil), "consensusProto.Err") + proto.RegisterType((*LogSyncContentValue)(nil), "consensusProto.LogSyncContentValue") + proto.RegisterType((*LogSyncMessage)(nil), "consensusProto.LogSyncMessage") + proto.RegisterType((*LogHeadUpdate)(nil), "consensusProto.LogHeadUpdate") + proto.RegisterType((*LogFullSyncRequest)(nil), "consensusProto.LogFullSyncRequest") + proto.RegisterType((*LogFullSyncResponse)(nil), "consensusProto.LogFullSyncResponse") } func init() { @@ -614,46 +931,56 @@ func init() { } var fileDescriptor_b8d7f1c16b400059 = []byte{ - // 618 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xcf, 0x6e, 0xd3, 0x4e, - 0x10, 0xce, 0xda, 0x6d, 0x1a, 0x4f, 0x7e, 0x4d, 0xfd, 0x1b, 0x10, 0x32, 0x11, 0x75, 0x23, 0x4b, - 0x48, 0xa5, 0x42, 0x29, 0x04, 0x81, 0x84, 0x7a, 0x82, 0x2a, 0x48, 0x91, 0x42, 0x8b, 0x8c, 0x50, - 0x25, 0xb8, 0x60, 0xbc, 0x5b, 0xd7, 0x34, 0xf5, 0x86, 0xdd, 0x4d, 0xff, 0x3c, 0x03, 0x17, 0x5e, - 0x80, 0xf7, 0xe1, 0xd8, 0x23, 0x47, 0xd4, 0x5e, 0x78, 0x00, 0x1e, 0x00, 0x79, 0x1d, 0x3b, 0x6e, - 0x9a, 0x80, 0xb8, 0x24, 0x3b, 0xdf, 0xfc, 0xfb, 0x66, 0xe6, 0x93, 0x61, 0x33, 0xe4, 0x89, 0x64, - 0x89, 0x1c, 0xc9, 0xc9, 0x6b, 0x28, 0xb8, 0xe2, 0x9b, 0xfa, 0xb7, 0x84, 0xb6, 0x35, 0x80, 0x8d, - 0x02, 0x78, 0x95, 0xda, 0xde, 0x47, 0x30, 0xfb, 0x3c, 0xc2, 0x06, 0x18, 0x31, 0x75, 0x48, 0x8b, - 0xac, 0xff, 0xe7, 0x1b, 0x31, 0x45, 0x07, 0x96, 0x86, 0xc1, 0xd9, 0x80, 0x07, 0xd4, 0x31, 0x34, - 0x98, 0x9b, 0xf8, 0x14, 0x96, 0x04, 0x0b, 0xb9, 0xa0, 0xd2, 0x31, 0x5b, 0xe6, 0x7a, 0xbd, 0xb3, - 0xd6, 0xbe, 0x5a, 0xb2, 0xed, 0x07, 0x27, 0xbe, 0x8e, 0xd8, 0x8b, 0xd5, 0x41, 0x8f, 0xfa, 0x79, - 0xbc, 0xf7, 0x95, 0x80, 0x55, 0x38, 0xcb, 0x2d, 0xc8, 0xd5, 0x16, 0x77, 0xc0, 0x92, 0x71, 0x94, - 0x04, 0x6a, 0x24, 0xd8, 0xb8, 0xfd, 0x04, 0xc0, 0x0d, 0xb0, 0x83, 0x30, 0x64, 0x43, 0xc5, 0x45, - 0x8f, 0xb2, 0x44, 0xc5, 0xea, 0xcc, 0x31, 0x75, 0xd0, 0x35, 0x1c, 0xef, 0xc3, 0xff, 0x39, 0xf6, - 0xba, 0xa8, 0xb8, 0xa0, 0x83, 0xaf, 0x3b, 0xbc, 0x2d, 0x58, 0x99, 0xe2, 0xfe, 0x07, 0x92, 0xd9, - 0xc6, 0x52, 0x76, 0x56, 0xba, 0x31, 0x2f, 0x81, 0xea, 0x78, 0xb0, 0x5b, 0x50, 0x1d, 0x0a, 0x76, - 0xdc, 0xcb, 0x52, 0x2c, 0x7f, 0x6c, 0x61, 0x13, 0x6a, 0x71, 0x4e, 0x38, 0x9b, 0xaa, 0xb0, 0x11, - 0x61, 0x81, 0x06, 0x2a, 0x18, 0x0f, 0xa2, 0xdf, 0xe9, 0x1a, 0x54, 0x7c, 0xc4, 0xa4, 0x0a, 0x8e, - 0x86, 0x9a, 0xb4, 0xe9, 0x4f, 0x00, 0x6f, 0x01, 0x8c, 0xdd, 0x43, 0xef, 0x09, 0x2c, 0xf7, 0x79, - 0xf4, 0x8c, 0x52, 0x9f, 0x7d, 0x1a, 0x31, 0xa9, 0xf0, 0x2e, 0x98, 0x03, 0x1e, 0xe9, 0xce, 0xf5, - 0xce, 0x8d, 0xe9, 0xd3, 0xf4, 0x79, 0xe4, 0xa7, 0x7e, 0xef, 0x1d, 0xd8, 0x19, 0xdb, 0x52, 0xea, - 0x4d, 0x58, 0x1c, 0xf0, 0xa8, 0x97, 0x4f, 0x9a, 0x19, 0xf8, 0x10, 0xaa, 0xd9, 0xfd, 0x34, 0xe7, - 0x7a, 0xe7, 0xf6, 0xdc, 0x73, 0xfb, 0xe3, 0x40, 0xef, 0x25, 0xac, 0xf4, 0x79, 0xb4, 0x17, 0xa8, - 0xf0, 0x20, 0xaf, 0xdd, 0x84, 0xda, 0x49, 0x6a, 0xf7, 0xa8, 0x74, 0x48, 0xcb, 0x4c, 0x67, 0xcf, - 0x6d, 0x74, 0x01, 0x46, 0x49, 0xe1, 0x35, 0xb4, 0xb7, 0x84, 0x78, 0x9f, 0x89, 0x1e, 0x52, 0xd7, - 0xeb, 0x1e, 0xb3, 0x64, 0x1e, 0xd3, 0x92, 0x32, 0x8d, 0x7f, 0x53, 0x26, 0xde, 0x83, 0x45, 0x26, - 0x04, 0x17, 0x7a, 0xff, 0x33, 0xf6, 0xd6, 0x15, 0xc2, 0xcf, 0x22, 0xbc, 0xc7, 0x60, 0x76, 0x85, - 0xc0, 0x76, 0x9e, 0x91, 0x52, 0x68, 0x74, 0x9c, 0x19, 0x19, 0xdb, 0x9c, 0x32, 0x39, 0x4e, 0xdb, - 0x78, 0x0f, 0xb5, 0x1c, 0xc2, 0x06, 0xc0, 0x9b, 0x84, 0x9d, 0x0e, 0x59, 0xa8, 0x18, 0xb5, 0x2b, - 0xb8, 0x0c, 0x56, 0x9f, 0x47, 0xdd, 0xd3, 0x58, 0x2a, 0x69, 0x13, 0x5c, 0x81, 0x7a, 0x9f, 0x47, - 0x3b, 0x5c, 0xbd, 0xe0, 0xa3, 0x84, 0xda, 0x06, 0x22, 0x34, 0x32, 0xda, 0xdb, 0x3c, 0xd9, 0x1f, - 0xc4, 0xa1, 0xb2, 0x4d, 0xb4, 0xa1, 0xde, 0x4d, 0x0b, 0xef, 0xee, 0xef, 0x4b, 0xa6, 0xec, 0x5f, - 0x66, 0xe7, 0x27, 0x01, 0x6b, 0x3b, 0x27, 0x81, 0x5b, 0x50, 0xcd, 0x84, 0x81, 0xab, 0x33, 0x44, - 0x30, 0xb9, 0x7a, 0x13, 0xa7, 0xdd, 0xbb, 0x87, 0xb8, 0x03, 0x56, 0xa1, 0x0e, 0x6c, 0x5d, 0xdb, - 0xe2, 0x94, 0x70, 0x9a, 0x7f, 0xdb, 0x33, 0xee, 0x40, 0x2d, 0x3f, 0x20, 0xae, 0xcd, 0xa0, 0x53, - 0x96, 0x4a, 0x73, 0x75, 0x5e, 0x80, 0xbe, 0xfd, 0x3a, 0x79, 0x40, 0x9e, 0x77, 0xbe, 0x5d, 0xb8, - 0xe4, 0xfc, 0xc2, 0x25, 0x3f, 0x2e, 0x5c, 0xf2, 0xe5, 0xd2, 0xad, 0x9c, 0x5f, 0xba, 0x95, 0xef, - 0x97, 0x6e, 0xe5, 0xad, 0x33, 0xef, 0x7b, 0xf8, 0xa1, 0xaa, 0xff, 0x1e, 0xfd, 0x0e, 0x00, 0x00, - 0xff, 0xff, 0xbc, 0x83, 0xcb, 0xc1, 0x32, 0x05, 0x00, 0x00, + // 782 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0xcf, 0x6e, 0xd3, 0x4c, + 0x10, 0x8f, 0xed, 0x36, 0x89, 0x27, 0x5f, 0x13, 0x7f, 0x5b, 0x84, 0x4c, 0x44, 0xd3, 0xc8, 0x08, + 0x29, 0x54, 0x28, 0x85, 0x20, 0x90, 0x50, 0x85, 0x10, 0x8d, 0x52, 0x25, 0x52, 0x9a, 0x82, 0xab, + 0x52, 0x09, 0x24, 0x84, 0xf1, 0x6e, 0x5c, 0xd3, 0xd4, 0x6b, 0xec, 0x4d, 0xdb, 0x5c, 0xb9, 0x72, + 0xe1, 0x05, 0x78, 0x1f, 0x8e, 0x3d, 0x72, 0x44, 0xed, 0x85, 0x07, 0xe0, 0x01, 0x90, 0xd7, 0x76, + 0xe2, 0x26, 0x4e, 0x11, 0x82, 0x4b, 0xbb, 0xf3, 0xff, 0x37, 0xbf, 0x19, 0x4f, 0x60, 0xdd, 0xa4, + 0x8e, 0x4f, 0x1c, 0x7f, 0xe8, 0x4f, 0x5e, 0xae, 0x47, 0x19, 0x5d, 0xe7, 0x7f, 0x13, 0xda, 0x3a, + 0x57, 0xa0, 0xe2, 0x58, 0xf1, 0x3c, 0x90, 0xb5, 0xf7, 0x20, 0x75, 0xa9, 0x85, 0x8a, 0x20, 0xda, + 0x58, 0x15, 0xaa, 0x42, 0xed, 0x3f, 0x5d, 0xb4, 0x31, 0x52, 0x21, 0xe7, 0x1a, 0xa3, 0x01, 0x35, + 0xb0, 0x2a, 0x72, 0x65, 0x2c, 0xa2, 0xc7, 0x90, 0xf3, 0x88, 0x49, 0x3d, 0xec, 0xab, 0x52, 0x55, + 0xaa, 0x15, 0x1a, 0xab, 0xf5, 0xcb, 0x29, 0xeb, 0xba, 0x71, 0xa2, 0x73, 0x8f, 0x7d, 0x9b, 0x1d, + 0x74, 0xb0, 0x1e, 0xfb, 0x6b, 0x5f, 0x04, 0x90, 0xc7, 0xc6, 0x64, 0x09, 0xe1, 0x72, 0x89, 0x9b, + 0x20, 0xfb, 0xb6, 0xe5, 0x18, 0x6c, 0xe8, 0x91, 0xa8, 0xfc, 0x44, 0x81, 0xd6, 0x40, 0x31, 0x4c, + 0x93, 0xb8, 0x8c, 0x7a, 0x1d, 0x4c, 0x1c, 0x66, 0xb3, 0x91, 0x2a, 0x71, 0xa7, 0x19, 0x3d, 0xba, + 0x0b, 0xff, 0xc7, 0xba, 0xdd, 0x71, 0xc6, 0x05, 0xee, 0x3c, 0x6b, 0xd0, 0x36, 0xa0, 0x34, 0x85, + 0xfd, 0x0a, 0x90, 0x21, 0x63, 0x01, 0x3a, 0x39, 0x60, 0x4c, 0x73, 0x20, 0x1b, 0x35, 0x76, 0x1d, + 0xb2, 0xae, 0x47, 0x8e, 0x3b, 0x61, 0x88, 0xac, 0x47, 0x12, 0x2a, 0x43, 0xde, 0x8e, 0x01, 0x87, + 0x5d, 0x8d, 0x65, 0x84, 0x60, 0x01, 0x1b, 0xcc, 0x88, 0x1a, 0xe1, 0xef, 0x80, 0x06, 0x66, 0x1f, + 0x11, 0x9f, 0x19, 0x47, 0x2e, 0x07, 0x2d, 0xe9, 0x13, 0x85, 0xb6, 0x00, 0xe2, 0xce, 0xa1, 0xf6, + 0x08, 0x96, 0xba, 0xd4, 0x7a, 0x86, 0xb1, 0x4e, 0x3e, 0x0c, 0x89, 0xcf, 0xd0, 0x6d, 0x90, 0x06, + 0xd4, 0xe2, 0x95, 0x0b, 0x8d, 0xe5, 0xe9, 0xd1, 0x74, 0xa9, 0xa5, 0x07, 0x76, 0xed, 0x35, 0x28, + 0x21, 0xda, 0x44, 0xe8, 0x35, 0x58, 0x1c, 0x50, 0xab, 0x13, 0x77, 0x1a, 0x0a, 0xe8, 0x3e, 0x64, + 0xc3, 0xf9, 0x71, 0xcc, 0x85, 0xc6, 0x8d, 0xb9, 0xe3, 0xd6, 0x23, 0x47, 0x6d, 0x1b, 0x4a, 0x5d, + 0x6a, 0xed, 0x1b, 0xcc, 0x3c, 0x88, 0x73, 0x97, 0x21, 0x7f, 0x12, 0xc8, 0x1d, 0xec, 0xab, 0x42, + 0x55, 0x0a, 0x7a, 0x8f, 0x65, 0x54, 0x01, 0x18, 0x3a, 0x63, 0xab, 0xc8, 0xad, 0x09, 0x8d, 0xf6, + 0x49, 0xe0, 0x4d, 0xf2, 0x7c, 0xad, 0x63, 0xe2, 0xcc, 0x43, 0x9a, 0xd8, 0x4c, 0xf1, 0xcf, 0x36, + 0x13, 0xdd, 0x81, 0x45, 0xe2, 0x79, 0xd4, 0xe3, 0xfc, 0xa7, 0xf0, 0xd6, 0xf2, 0x3c, 0x3d, 0xf4, + 0xd0, 0x1e, 0x82, 0xd4, 0xf2, 0x3c, 0x54, 0x8f, 0x23, 0x02, 0x08, 0xc5, 0x86, 0x9a, 0x12, 0xd1, + 0xa4, 0x98, 0xf8, 0x71, 0xd8, 0x47, 0x11, 0x96, 0xbb, 0xd4, 0xda, 0x1d, 0x39, 0x66, 0x93, 0x3a, + 0x8c, 0x38, 0xec, 0xa5, 0x31, 0x18, 0x12, 0xf4, 0x14, 0xe0, 0x80, 0x18, 0x78, 0xcf, 0xc5, 0x06, + 0x23, 0xd1, 0xd8, 0x56, 0x52, 0xc6, 0xd6, 0x1e, 0x3b, 0xb5, 0x33, 0x7a, 0x22, 0x04, 0xf5, 0xa0, + 0xd4, 0x1f, 0x0e, 0x06, 0x41, 0xe2, 0x88, 0xec, 0x68, 0x50, 0x5a, 0x4a, 0x96, 0xad, 0xcb, 0x9e, + 0xed, 0x8c, 0x3e, 0x1d, 0x8c, 0x5e, 0x80, 0x32, 0x51, 0xf9, 0x6e, 0x90, 0x22, 0x62, 0xe5, 0xd6, + 0x95, 0x09, 0x43, 0xd7, 0x76, 0x46, 0x9f, 0x09, 0xdf, 0xcc, 0xc1, 0xe2, 0x71, 0xd0, 0xac, 0x36, + 0x82, 0x62, 0xc4, 0xc1, 0x36, 0xf1, 0x7d, 0xc3, 0x22, 0x89, 0xbb, 0x23, 0xa7, 0xdd, 0x1d, 0x79, + 0xf2, 0xbd, 0x3d, 0x81, 0x9c, 0x19, 0x12, 0x77, 0x05, 0x9c, 0x69, 0x7a, 0xf5, 0x38, 0x46, 0x7b, + 0xc3, 0x77, 0x68, 0xc2, 0x62, 0xf0, 0xc5, 0x05, 0x2c, 0x46, 0xb5, 0xf9, 0xfb, 0x2f, 0x36, 0x48, + 0xab, 0x01, 0x9a, 0xe5, 0x37, 0xad, 0x88, 0x86, 0xf9, 0x22, 0x4c, 0x13, 0xf7, 0x8f, 0xf1, 0xac, + 0xbd, 0x85, 0x7c, 0xbc, 0x82, 0xa8, 0x08, 0xb0, 0xe7, 0x90, 0x53, 0x97, 0x98, 0x8c, 0x60, 0x25, + 0x83, 0x96, 0x40, 0xee, 0x52, 0xab, 0x75, 0x6a, 0xfb, 0xcc, 0x57, 0x04, 0x54, 0x82, 0x42, 0x97, + 0x5a, 0x3d, 0xca, 0xb6, 0xe8, 0xd0, 0xc1, 0x8a, 0x88, 0x10, 0x14, 0xc3, 0xa4, 0x4d, 0xea, 0xf4, + 0x07, 0xb6, 0xc9, 0x14, 0x09, 0x29, 0x50, 0x68, 0x05, 0x8b, 0xbc, 0xd3, 0xef, 0xfb, 0x84, 0x29, + 0x3f, 0xa5, 0xc6, 0x0f, 0x01, 0xe4, 0x66, 0x8c, 0x06, 0x6d, 0x40, 0x36, 0x3c, 0x44, 0x28, 0x6d, + 0x7b, 0x27, 0x57, 0xa6, 0x8c, 0xa6, 0xcd, 0x3b, 0x87, 0xa8, 0x07, 0xf2, 0xf8, 0x1a, 0xa1, 0xea, + 0x4c, 0x8f, 0x53, 0x87, 0xaa, 0xfc, 0x3b, 0x16, 0x50, 0x0f, 0xf2, 0xf1, 0xc1, 0x40, 0xab, 0x29, + 0x70, 0x92, 0xa7, 0xa9, 0xbc, 0x32, 0xcf, 0x81, 0xdf, 0x9a, 0x9a, 0x70, 0x4f, 0xd8, 0x6c, 0x7c, + 0x3d, 0xaf, 0x08, 0x67, 0xe7, 0x15, 0xe1, 0xfb, 0x79, 0x45, 0xf8, 0x7c, 0x51, 0xc9, 0x9c, 0x5d, + 0x54, 0x32, 0xdf, 0x2e, 0x2a, 0x99, 0x57, 0xea, 0xbc, 0xdf, 0xdf, 0x77, 0x59, 0xfe, 0xef, 0xc1, + 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd6, 0x8a, 0x01, 0xa8, 0xa2, 0x07, 0x00, 0x00, } func (m *Log) Marshal() (dAtA []byte, err error) { @@ -1069,6 +1396,268 @@ func (m *Err) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *LogSyncContentValue) 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 *LogSyncContentValue) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *LogSyncContentValue) 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 *LogSyncContentValue_HeadUpdate) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *LogSyncContentValue_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 = encodeVarintConsensus(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} +func (m *LogSyncContentValue_FullSyncRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *LogSyncContentValue_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 = encodeVarintConsensus(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + return len(dAtA) - i, nil +} +func (m *LogSyncContentValue_FullSyncResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *LogSyncContentValue_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 = encodeVarintConsensus(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + return len(dAtA) - i, nil +} +func (m *LogSyncMessage) 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 *LogSyncMessage) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *LogSyncMessage) 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 = encodeVarintConsensus(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + 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] = 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 *LogHeadUpdate) 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 *LogHeadUpdate) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *LogHeadUpdate) 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.Head) > 0 { + i -= len(m.Head) + copy(dAtA[i:], m.Head) + i = encodeVarintConsensus(dAtA, i, uint64(len(m.Head))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *LogFullSyncRequest) 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 *LogFullSyncRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *LogFullSyncRequest) 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 = encodeVarintConsensus(dAtA, i, uint64(len(m.Head))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *LogFullSyncResponse) 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 *LogFullSyncResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *LogFullSyncResponse) 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.Head) > 0 { + i -= len(m.Head) + copy(dAtA[i:], m.Head) + i = encodeVarintConsensus(dAtA, i, uint64(len(m.Head))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintConsensus(dAtA []byte, offset int, v uint64) int { offset -= sovConsensus(v) base := offset @@ -1264,6 +1853,126 @@ func (m *Err) Size() (n int) { return n } +func (m *LogSyncContentValue) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Value != nil { + n += m.Value.Size() + } + return n +} + +func (m *LogSyncContentValue_HeadUpdate) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.HeadUpdate != nil { + l = m.HeadUpdate.Size() + n += 1 + l + sovConsensus(uint64(l)) + } + return n +} +func (m *LogSyncContentValue_FullSyncRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.FullSyncRequest != nil { + l = m.FullSyncRequest.Size() + n += 1 + l + sovConsensus(uint64(l)) + } + return n +} +func (m *LogSyncContentValue_FullSyncResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.FullSyncResponse != nil { + l = m.FullSyncResponse.Size() + n += 1 + l + sovConsensus(uint64(l)) + } + return n +} +func (m *LogSyncMessage) 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.Payload) + if l > 0 { + n += 1 + l + sovConsensus(uint64(l)) + } + if m.Content != nil { + l = m.Content.Size() + n += 1 + l + sovConsensus(uint64(l)) + } + return n +} + +func (m *LogHeadUpdate) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Head) + 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 *LogFullSyncRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Head) + if l > 0 { + n += 1 + l + sovConsensus(uint64(l)) + } + return n +} + +func (m *LogFullSyncResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Head) + 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 sovConsensus(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -2486,6 +3195,625 @@ func (m *Err) Unmarshal(dAtA []byte) error { } return nil } +func (m *LogSyncContentValue) 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: LogSyncContentValue: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LogSyncContentValue: 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 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 + } + v := &LogHeadUpdate{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Value = &LogSyncContentValue_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 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 + } + v := &LogFullSyncRequest{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Value = &LogSyncContentValue_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 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 + } + v := &LogFullSyncResponse{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Value = &LogSyncContentValue_FullSyncResponse{v} + 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 *LogSyncMessage) 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: LogSyncMessage: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LogSyncMessage: 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 ErrIntOverflowConsensus + } + 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 ErrInvalidLengthConsensus + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthConsensus + } + 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 Payload", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConsensus + } + 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 ErrInvalidLengthConsensus + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthConsensus + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Payload = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + 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 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.Content == nil { + m.Content = &LogSyncContentValue{} + } + if err := m.Content.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 *LogHeadUpdate) 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: LogHeadUpdate: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LogHeadUpdate: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + 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 ErrIntOverflowConsensus + } + 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 ErrInvalidLengthConsensus + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthConsensus + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Head = string(dAtA[iNdEx:postIndex]) + 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, &RawRecordWithId{}) + 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 *LogFullSyncRequest) 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: LogFullSyncRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LogFullSyncRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + 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 ErrIntOverflowConsensus + } + 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 ErrInvalidLengthConsensus + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthConsensus + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Head = string(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 *LogFullSyncResponse) 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: LogFullSyncResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LogFullSyncResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + 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 ErrIntOverflowConsensus + } + 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 ErrInvalidLengthConsensus + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthConsensus + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Head = string(dAtA[iNdEx:postIndex]) + 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, &RawRecordWithId{}) + 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 skipConsensus(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/consensus/consensusproto/protos/consensus.proto b/consensus/consensusproto/protos/consensus.proto index 55918519..10d7d0e9 100644 --- a/consensus/consensusproto/protos/consensus.proto +++ b/consensus/consensusproto/protos/consensus.proto @@ -74,4 +74,37 @@ message LogWatchEvent { message Err { ErrCodes error = 1; -} \ No newline at end of file +} + +// LogSyncContentValue provides different types for log sync +message LogSyncContentValue { + oneof value { + LogHeadUpdate headUpdate = 1; + LogFullSyncRequest fullSyncRequest = 2; + LogFullSyncResponse fullSyncResponse = 3; + } +} + +// LogSyncMessage is a message sent when we are syncing logs +message LogSyncMessage { + string id = 1; + string payload = 2; + LogSyncContentValue content = 3; +} + +// LogHeadUpdate is a message sent on consensus log head update +message LogHeadUpdate { + string head = 1; + repeated RawRecordWithId records = 2; +} + +// LogFullSyncRequest is a message sent when consensus log needs full sync +message LogFullSyncRequest { + string head = 1; +} + +// LogFullSyncResponse is a message sent as a response for a specific full sync +message LogFullSyncResponse { + string head = 1; + repeated RawRecordWithId records = 2; +} From 145332b0f772d15dc95b81cfb4eebd858528939e Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Mon, 3 Jul 2023 13:43:54 +0200 Subject: [PATCH 103/123] Add headsync acl logic --- commonspace/headsync/diffsyncer.go | 18 +++++++++++++++++- commonspace/headsync/headsync.go | 13 +++++++++++-- commonspace/object/acl/list/list.go | 4 ++-- commonspace/object/acl/syncacl/syncacl.go | 17 ++++++++++++++++- 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/commonspace/headsync/diffsyncer.go b/commonspace/headsync/diffsyncer.go index a0539681..cbae98f9 100644 --- a/commonspace/headsync/diffsyncer.go +++ b/commonspace/headsync/diffsyncer.go @@ -3,10 +3,13 @@ package headsync import ( "context" "fmt" + "time" + "github.com/anyproto/any-sync/app/ldiff" "github.com/anyproto/any-sync/app/logger" "github.com/anyproto/any-sync/commonspace/credentialprovider" "github.com/anyproto/any-sync/commonspace/deletionstate" + "github.com/anyproto/any-sync/commonspace/object/acl/syncacl" "github.com/anyproto/any-sync/commonspace/object/treemanager" "github.com/anyproto/any-sync/commonspace/peermanager" "github.com/anyproto/any-sync/commonspace/spacestorage" @@ -14,8 +17,8 @@ import ( "github.com/anyproto/any-sync/commonspace/syncstatus" "github.com/anyproto/any-sync/net/peer" "github.com/anyproto/any-sync/net/rpc/rpcerr" + "github.com/anyproto/any-sync/util/slice" "go.uber.org/zap" - "time" ) type DiffSyncer interface { @@ -38,6 +41,7 @@ func newDiffSyncer(hs *headSync) DiffSyncer { log: log, syncStatus: hs.syncStatus, deletionState: hs.deletionState, + syncAcl: hs.syncAcl, } } @@ -53,6 +57,7 @@ type diffSyncer struct { credentialProvider credentialprovider.CredentialProvider syncStatus syncstatus.StatusUpdater treeSyncer treemanager.TreeSyncer + syncAcl *syncacl.SyncAcl } func (d *diffSyncer) Init() { @@ -116,6 +121,7 @@ func (d *diffSyncer) syncWithPeer(ctx context.Context, p peer.Peer) (err error) cl = d.clientFactory.Client(conn) rdiff = NewRemoteDiff(d.spaceId, cl) stateCounter = d.syncStatus.StateCounter() + syncAclId = d.syncAcl.Id() ) newIds, changedIds, removedIds, err := d.diff.Diff(ctx, rdiff) @@ -137,6 +143,16 @@ func (d *diffSyncer) syncWithPeer(ctx context.Context, p peer.Peer) (err error) totalLen := len(newIds) + len(changedIds) + len(removedIds) // not syncing ids which were removed through settings document missingIds := d.deletionState.Filter(newIds) + prevLen := len(changedIds) + changedIds = slice.DiscardFromSlice(changedIds, func(s string) bool { + return s == syncAclId + }) + // if acl head is different + if len(changedIds) < prevLen { + if syncErr := d.syncAcl.SyncWithPeer(ctx, p.Id()); syncErr != nil { + log.Warn("failed to send acl sync message to peer", zap.String("aclId", syncAclId)) + } + } existingIds := append(d.deletionState.Filter(removedIds), d.deletionState.Filter(changedIds)...) d.syncStatus.RemoveAllExcept(p.Id(), existingIds, stateCounter) diff --git a/commonspace/headsync/headsync.go b/commonspace/headsync/headsync.go index 18ed7357..1cc0c485 100644 --- a/commonspace/headsync/headsync.go +++ b/commonspace/headsync/headsync.go @@ -3,12 +3,16 @@ package headsync import ( "context" + "sync/atomic" + "time" + "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/app/ldiff" "github.com/anyproto/any-sync/app/logger" config2 "github.com/anyproto/any-sync/commonspace/config" "github.com/anyproto/any-sync/commonspace/credentialprovider" "github.com/anyproto/any-sync/commonspace/deletionstate" + "github.com/anyproto/any-sync/commonspace/object/acl/syncacl" "github.com/anyproto/any-sync/commonspace/object/treemanager" "github.com/anyproto/any-sync/commonspace/peermanager" "github.com/anyproto/any-sync/commonspace/spacestate" @@ -21,8 +25,6 @@ import ( "github.com/anyproto/any-sync/util/slice" "go.uber.org/zap" "golang.org/x/exp/slices" - "sync/atomic" - "time" ) var log = logger.NewNamed(CName) @@ -60,6 +62,7 @@ type headSync struct { credentialProvider credentialprovider.CredentialProvider syncStatus syncstatus.StatusService deletionState deletionstate.ObjectDeletionState + syncAcl *syncacl.SyncAcl } func New() HeadSync { @@ -71,6 +74,7 @@ var createDiffSyncer = newDiffSyncer func (h *headSync) Init(a *app.App) (err error) { shared := a.MustComponent(spacestate.CName).(*spacestate.SpaceState) cfg := a.MustComponent("config").(config2.ConfigGetter) + h.syncAcl = a.MustComponent(syncacl.CName).(*syncacl.SyncAcl) h.spaceId = shared.SpaceId h.spaceIsDeleted = shared.SpaceIsDeleted h.syncPeriod = cfg.GetSpace().SyncPeriod @@ -92,6 +96,7 @@ func (h *headSync) Init(a *app.App) (err error) { return h.syncer.Sync(ctx) } h.periodicSync = periodicsync.NewPeriodicSync(h.syncPeriod, time.Minute, sync, h.log) + h.syncAcl.SetHeadUpdater(h) // TODO: move to run? h.syncer.Init() return nil @@ -177,6 +182,10 @@ func (h *headSync) fillDiff(objectIds []string) { Head: concatStrings(heads), }) } + els = append(els, ldiff.Element{ + Id: h.syncAcl.Id(), + Head: h.syncAcl.Head().Id, + }) h.diff.Set(els...) if err := h.storage.WriteSpaceHash(h.diff.Hash()); err != nil { h.log.Error("can't write space hash", zap.Error(err)) diff --git a/commonspace/object/acl/list/list.go b/commonspace/object/acl/list/list.go index 93a4a952..0d8d1d4b 100644 --- a/commonspace/object/acl/list/list.go +++ b/commonspace/object/acl/list/list.go @@ -57,7 +57,7 @@ type AclList interface { AddRawRecord(rawRec *consensusproto.RawRecordWithId) (err error) AddRawRecords(rawRecords []*consensusproto.RawRecordWithId) (err error) - Close() (err error) + Close(ctx context.Context) (err error) } type aclList struct { @@ -293,6 +293,6 @@ func (a *aclList) IterateFrom(startId string, iterFunc IterFunc) { } } -func (a *aclList) Close() (err error) { +func (a *aclList) Close(ctx context.Context) (err error) { return nil } diff --git a/commonspace/object/acl/syncacl/syncacl.go b/commonspace/object/acl/syncacl/syncacl.go index 30a958b7..04917ab5 100644 --- a/commonspace/object/acl/syncacl/syncacl.go +++ b/commonspace/object/acl/syncacl/syncacl.go @@ -29,17 +29,30 @@ func New() *SyncAcl { return &SyncAcl{} } +type HeadUpdater interface { + UpdateHeads(id string, heads []string) +} + type SyncAcl struct { list.AclList syncClient SyncClient syncHandler synchandler.SyncHandler + headUpdater HeadUpdater isClosed bool } +func (s *SyncAcl) Run(ctx context.Context) (err error) { + return +} + func (s *SyncAcl) HandleRequest(ctx context.Context, senderId string, request *spacesyncproto.ObjectSyncMessage) (response *spacesyncproto.ObjectSyncMessage, err error) { return s.HandleRequest(ctx, senderId, request) } +func (s *SyncAcl) SetHeadUpdater(updater HeadUpdater) { + s.headUpdater = updater +} + func (s *SyncAcl) HandleMessage(ctx context.Context, senderId string, request *spacesyncproto.ObjectSyncMessage) (err error) { return s.HandleMessage(ctx, senderId, request) } @@ -73,6 +86,7 @@ func (s *SyncAcl) AddRawRecord(rawRec *consensusproto.RawRecordWithId) (err erro return } headUpdate := s.syncClient.CreateHeadUpdate(s, []*consensusproto.RawRecordWithId{rawRec}) + s.headUpdater.UpdateHeads(s.Id(), []string{rawRec.Id}) s.syncClient.Broadcast(headUpdate) return } @@ -86,6 +100,7 @@ func (s *SyncAcl) AddRawRecords(rawRecords []*consensusproto.RawRecordWithId) (e return } headUpdate := s.syncClient.CreateHeadUpdate(s, rawRecords) + s.headUpdater.UpdateHeads(s.Id(), []string{rawRecords[len(rawRecords)-1].Id}) s.syncClient.Broadcast(headUpdate) return } @@ -97,7 +112,7 @@ func (s *SyncAcl) SyncWithPeer(ctx context.Context, peerId string) (err error) { return s.syncClient.SendUpdate(peerId, s.Id(), headUpdate) } -func (s *SyncAcl) Close() (err error) { +func (s *SyncAcl) Close(ctx context.Context) (err error) { s.Lock() defer s.Unlock() s.isClosed = true From 0d16c5d7e4d575976fb882ef244d4e8196d110b6 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Mon, 3 Jul 2023 15:48:48 +0200 Subject: [PATCH 104/123] WIP sync logic --- commonspace/object/acl/list/list.go | 8 +- .../object/acl/syncacl/aclsyncprotocol.go | 75 +++++++- .../object/acl/syncacl/requestfactory.go | 4 +- commonspace/object/acl/syncacl/syncacl.go | 2 +- .../object/acl/syncacl/syncaclhandler.go | 48 ++++- commonspace/object/acl/syncacl/syncclient.go | 57 ++++-- .../object/tree/synctree/syncclient.go | 22 +-- .../object/tree/synctree/synctreehandler.go | 2 +- .../tree/synctree/synctreehandler_test.go | 14 +- .../object/tree/synctree/treesyncprotocol.go | 12 +- commonspace/spacesyncproto/spacesync.go | 14 ++ consensus/consensusproto/consensus.pb.go | 165 ++++++++++++------ .../consensusproto/protos/consensus.proto | 1 + 13 files changed, 314 insertions(+), 110 deletions(-) diff --git a/commonspace/object/acl/list/list.go b/commonspace/object/acl/list/list.go index 0d8d1d4b..42c9fafc 100644 --- a/commonspace/object/acl/list/list.go +++ b/commonspace/object/acl/list/list.go @@ -44,6 +44,7 @@ type AclList interface { Records() []*AclRecord AclState() *AclState IsAfter(first string, second string) (bool, error) + HasHead(head string) bool Head() *AclRecord Get(id string) (*AclRecord, error) GetIndex(idx int) (*AclRecord, error) @@ -199,7 +200,7 @@ func (a *aclList) ValidateRawRecord(rawRec *consensusproto.RawRecord) (err error func (a *aclList) AddRawRecords(rawRecords []*consensusproto.RawRecordWithId) (err error) { for _, rec := range rawRecords { err = a.AddRawRecord(rec) - if err != nil { + if err != nil && err != ErrRecordAlreadyExists { return } } @@ -257,6 +258,11 @@ func (a *aclList) Head() *AclRecord { return a.records[len(a.records)-1] } +func (a *aclList) HasHead(head string) bool { + _, exists := a.indexes[head] + return exists +} + func (a *aclList) Get(id string) (*AclRecord, error) { recIdx, ok := a.indexes[id] if !ok { diff --git a/commonspace/object/acl/syncacl/aclsyncprotocol.go b/commonspace/object/acl/syncacl/aclsyncprotocol.go index a040ae19..6f0b2542 100644 --- a/commonspace/object/acl/syncacl/aclsyncprotocol.go +++ b/commonspace/object/acl/syncacl/aclsyncprotocol.go @@ -23,15 +23,84 @@ type aclSyncProtocol struct { } func (a *aclSyncProtocol) HeadUpdate(ctx context.Context, senderId string, update *consensusproto.LogHeadUpdate) (request *consensusproto.LogSyncMessage, err error) { - return + isEmptyUpdate := len(update.Records) == 0 + log := a.log.With( + zap.String("senderId", senderId), + zap.String("update head", update.Head), + zap.Int("len(update records)", len(update.Records))) + log.DebugCtx(ctx, "received acl head update message") + + defer func() { + if err != nil { + log.ErrorCtx(ctx, "acl head update finished with error", zap.Error(err)) + } else if request != nil { + cnt := request.Content.GetFullSyncRequest() + log.DebugCtx(ctx, "returning acl full sync request", zap.String("request head", cnt.Head)) + } else { + if !isEmptyUpdate { + log.DebugCtx(ctx, "acl head update finished correctly") + } + } + }() + if isEmptyUpdate { + headEquals := a.aclList.Head().Id == update.Head + log.DebugCtx(ctx, "is empty acl head update", zap.Bool("headEquals", headEquals)) + if headEquals { + return + } + return a.reqFactory.CreateFullSyncRequest(a.aclList, update.Head) + } + if a.aclList.HasHead(update.Head) { + return + } + err = a.aclList.AddRawRecords(update.Records) + if err != nil && err != list.ErrIncorrectRecordSequence { + return + } + return a.reqFactory.CreateFullSyncRequest(a.aclList, update.Head) } func (a *aclSyncProtocol) FullSyncRequest(ctx context.Context, senderId string, request *consensusproto.LogFullSyncRequest) (response *consensusproto.LogSyncMessage, err error) { - return + log := a.log.With( + zap.String("senderId", senderId), + zap.String("request head", request.Head), + zap.Int("len(request records)", len(request.Records))) + log.DebugCtx(ctx, "received acl full sync request message") + + defer func() { + if err != nil { + log.ErrorCtx(ctx, "acl full sync request finished with error", zap.Error(err)) + } else if response != nil { + cnt := response.Content.GetFullSyncResponse() + log.DebugCtx(ctx, "acl full sync response sent", zap.String("response head", cnt.Head), zap.Int("len(response records)", len(cnt.Records))) + } + }() + if len(request.Records) > 0 && !a.aclList.HasHead(request.Head) { + err = a.aclList.AddRawRecords(request.Records) + if err != nil { + return + } + } + return a.reqFactory.CreateFullSyncResponse(a.aclList, request.Head) } func (a *aclSyncProtocol) FullSyncResponse(ctx context.Context, senderId string, response *consensusproto.LogFullSyncResponse) (err error) { - return + log := a.log.With( + zap.String("senderId", senderId), + zap.String("response head", response.Head), + zap.Int("len(response records)", len(response.Records))) + log.DebugCtx(ctx, "received acl full sync response message") + defer func() { + if err != nil { + log.ErrorCtx(ctx, "acl full sync response failed", zap.Error(err)) + } else { + log.DebugCtx(ctx, "acl full sync response succeeded") + } + }() + if a.aclList.HasHead(response.Head) { + return + } + return a.aclList.AddRawRecords(response.Records) } func newAclSyncProtocol(spaceId string, aclList list.AclList, reqFactory RequestFactory) *aclSyncProtocol { diff --git a/commonspace/object/acl/syncacl/requestfactory.go b/commonspace/object/acl/syncacl/requestfactory.go index 957ec402..d4b90e4d 100644 --- a/commonspace/object/acl/syncacl/requestfactory.go +++ b/commonspace/object/acl/syncacl/requestfactory.go @@ -7,7 +7,7 @@ import ( type RequestFactory interface { CreateHeadUpdate(l list.AclList, added []*consensusproto.RawRecordWithId) (msg *consensusproto.LogSyncMessage) - CreateFullSyncRequest(theirHead string) (req *consensusproto.LogSyncMessage, err error) + CreateFullSyncRequest(l list.AclList, theirHead string) (req *consensusproto.LogSyncMessage, err error) CreateFullSyncResponse(l list.AclList, theirHead string) (*consensusproto.LogSyncMessage, error) } @@ -21,7 +21,7 @@ func (r *requestFactory) CreateHeadUpdate(l list.AclList, added []*consensusprot return } -func (r *requestFactory) CreateFullSyncRequest(theirHead string) (req *consensusproto.LogSyncMessage, err error) { +func (r *requestFactory) CreateFullSyncRequest(l list.AclList, theirHead string) (req *consensusproto.LogSyncMessage, err error) { return } diff --git a/commonspace/object/acl/syncacl/syncacl.go b/commonspace/object/acl/syncacl/syncacl.go index 04917ab5..bd63c095 100644 --- a/commonspace/object/acl/syncacl/syncacl.go +++ b/commonspace/object/acl/syncacl/syncacl.go @@ -109,7 +109,7 @@ func (s *SyncAcl) SyncWithPeer(ctx context.Context, peerId string) (err error) { s.Lock() defer s.Unlock() headUpdate := s.syncClient.CreateHeadUpdate(s, nil) - return s.syncClient.SendUpdate(peerId, s.Id(), headUpdate) + return s.syncClient.SendUpdate(peerId, headUpdate) } func (s *SyncAcl) Close(ctx context.Context) (err error) { diff --git a/commonspace/object/acl/syncacl/syncaclhandler.go b/commonspace/object/acl/syncacl/syncaclhandler.go index f0c4e026..75e0044c 100644 --- a/commonspace/object/acl/syncacl/syncaclhandler.go +++ b/commonspace/object/acl/syncacl/syncaclhandler.go @@ -2,11 +2,19 @@ package syncacl import ( "context" + "errors" "github.com/anyproto/any-sync/commonspace/object/acl/list" "github.com/anyproto/any-sync/commonspace/objectsync/synchandler" "github.com/anyproto/any-sync/commonspace/spacesyncproto" "github.com/anyproto/any-sync/commonspace/syncstatus" + "github.com/anyproto/any-sync/consensus/consensusproto" + "github.com/gogo/protobuf/proto" +) + +var ( + ErrMessageIsRequest = errors.New("message is request") + ErrMessageIsNotRequest = errors.New("message is not request") ) type syncAclHandler struct { @@ -27,10 +35,46 @@ func newSyncAclHandler(spaceId string, aclList list.AclList, syncClient SyncClie } } -func (s *syncAclHandler) HandleMessage(ctx context.Context, senderId string, req *spacesyncproto.ObjectSyncMessage) (err error) { +func (s *syncAclHandler) HandleMessage(ctx context.Context, senderId string, message *spacesyncproto.ObjectSyncMessage) (err error) { + unmarshalled := &consensusproto.LogSyncMessage{} + err = proto.Unmarshal(message.Payload, unmarshalled) + if err != nil { + return + } + content := unmarshalled.GetContent() + s.aclList.Lock() + defer s.aclList.Unlock() + switch { + case content.GetHeadUpdate() != nil: + var syncReq *consensusproto.LogSyncMessage + syncReq, err = s.syncProtocol.HeadUpdate(ctx, senderId, content.GetHeadUpdate()) + if err != nil || syncReq == nil { + return + } + return s.syncClient.QueueRequest(senderId, syncReq) + case content.GetFullSyncRequest() != nil: + return ErrMessageIsRequest + case content.GetFullSyncResponse() != nil: + return s.syncProtocol.FullSyncResponse(ctx, senderId, content.GetFullSyncResponse()) + } return } func (s *syncAclHandler) HandleRequest(ctx context.Context, senderId string, request *spacesyncproto.ObjectSyncMessage) (response *spacesyncproto.ObjectSyncMessage, err error) { - return + unmarshalled := &consensusproto.LogSyncMessage{} + err = proto.Unmarshal(request.Payload, unmarshalled) + if err != nil { + return + } + fullSyncRequest := unmarshalled.GetContent().GetFullSyncRequest() + if fullSyncRequest == nil { + return nil, ErrMessageIsNotRequest + } + s.aclList.Lock() + defer s.aclList.Unlock() + aclResp, err := s.syncProtocol.FullSyncRequest(ctx, senderId, fullSyncRequest) + if err != nil { + return + } + return spacesyncproto.MarshallSyncMessage(aclResp, s.spaceId, s.aclList.Id()) } diff --git a/commonspace/object/acl/syncacl/syncclient.go b/commonspace/object/acl/syncacl/syncclient.go index c06692c5..28b077f9 100644 --- a/commonspace/object/acl/syncacl/syncclient.go +++ b/commonspace/object/acl/syncacl/syncclient.go @@ -7,14 +7,15 @@ import ( "github.com/anyproto/any-sync/commonspace/requestmanager" "github.com/anyproto/any-sync/commonspace/spacesyncproto" "github.com/anyproto/any-sync/consensus/consensusproto" + "go.uber.org/zap" ) type SyncClient interface { RequestFactory Broadcast(msg *consensusproto.LogSyncMessage) - SendUpdate(peerId, objectId string, msg *consensusproto.LogSyncMessage) (err error) - QueueRequest(peerId, objectId string, msg *consensusproto.LogSyncMessage) (err error) - SendRequest(ctx context.Context, peerId, objectId string, msg *consensusproto.LogSyncMessage) (reply *spacesyncproto.ObjectSyncMessage, err error) + SendUpdate(peerId string, msg *consensusproto.LogSyncMessage) (err error) + QueueRequest(peerId string, msg *consensusproto.LogSyncMessage) (err error) + SendRequest(ctx context.Context, peerId string, msg *consensusproto.LogSyncMessage) (reply *spacesyncproto.ObjectSyncMessage, err error) } type syncClient struct { @@ -24,21 +25,6 @@ type syncClient struct { peerManager peermanager.PeerManager } -func (s *syncClient) Broadcast(msg *consensusproto.LogSyncMessage) { -} - -func (s *syncClient) SendUpdate(peerId, objectId string, msg *consensusproto.LogSyncMessage) (err error) { - return -} - -func (s *syncClient) QueueRequest(peerId, objectId string, msg *consensusproto.LogSyncMessage) (err error) { - return -} - -func (s *syncClient) SendRequest(ctx context.Context, peerId, objectId string, msg *consensusproto.LogSyncMessage) (reply *spacesyncproto.ObjectSyncMessage, err error) { - return -} - func NewSyncClient(spaceId string, requestManager requestmanager.RequestManager, peerManager peermanager.PeerManager) SyncClient { return &syncClient{ RequestFactory: &requestFactory{}, @@ -47,3 +33,38 @@ func NewSyncClient(spaceId string, requestManager requestmanager.RequestManager, peerManager: peerManager, } } + +func (s *syncClient) Broadcast(msg *consensusproto.LogSyncMessage) { + objMsg, err := spacesyncproto.MarshallSyncMessage(msg, s.spaceId, msg.Id) + if err != nil { + return + } + err = s.peerManager.Broadcast(context.Background(), objMsg) + if err != nil { + log.Debug("broadcast error", zap.Error(err)) + } +} + +func (s *syncClient) SendUpdate(peerId string, msg *consensusproto.LogSyncMessage) (err error) { + objMsg, err := spacesyncproto.MarshallSyncMessage(msg, s.spaceId, msg.Id) + if err != nil { + return + } + return s.peerManager.SendPeer(context.Background(), peerId, objMsg) +} + +func (s *syncClient) SendRequest(ctx context.Context, peerId string, msg *consensusproto.LogSyncMessage) (reply *spacesyncproto.ObjectSyncMessage, err error) { + objMsg, err := spacesyncproto.MarshallSyncMessage(msg, s.spaceId, msg.Id) + if err != nil { + return + } + return s.requestManager.SendRequest(ctx, peerId, objMsg) +} + +func (s *syncClient) QueueRequest(peerId string, msg *consensusproto.LogSyncMessage) (err error) { + objMsg, err := spacesyncproto.MarshallSyncMessage(msg, s.spaceId, msg.Id) + if err != nil { + return + } + return s.requestManager.QueueRequest(peerId, objMsg) +} diff --git a/commonspace/object/tree/synctree/syncclient.go b/commonspace/object/tree/synctree/syncclient.go index ecf3f6c0..912cd5b7 100644 --- a/commonspace/object/tree/synctree/syncclient.go +++ b/commonspace/object/tree/synctree/syncclient.go @@ -35,7 +35,7 @@ func NewSyncClient(spaceId string, requestManager requestmanager.RequestManager, } func (s *syncClient) Broadcast(msg *treechangeproto.TreeSyncMessage) { - objMsg, err := MarshallTreeMessage(msg, s.spaceId, msg.RootChange.Id, "") + objMsg, err := spacesyncproto.MarshallSyncMessage(msg, s.spaceId, msg.RootChange.Id) if err != nil { return } @@ -46,7 +46,7 @@ func (s *syncClient) Broadcast(msg *treechangeproto.TreeSyncMessage) { } func (s *syncClient) SendUpdate(peerId, objectId string, msg *treechangeproto.TreeSyncMessage) (err error) { - objMsg, err := MarshallTreeMessage(msg, s.spaceId, objectId, "") + objMsg, err := spacesyncproto.MarshallSyncMessage(msg, s.spaceId, objectId) if err != nil { return } @@ -54,7 +54,7 @@ func (s *syncClient) SendUpdate(peerId, objectId string, msg *treechangeproto.Tr } func (s *syncClient) SendRequest(ctx context.Context, peerId, objectId string, msg *treechangeproto.TreeSyncMessage) (reply *spacesyncproto.ObjectSyncMessage, err error) { - objMsg, err := MarshallTreeMessage(msg, s.spaceId, objectId, "") + objMsg, err := spacesyncproto.MarshallSyncMessage(msg, s.spaceId, objectId) if err != nil { return } @@ -62,23 +62,9 @@ func (s *syncClient) SendRequest(ctx context.Context, peerId, objectId string, m } func (s *syncClient) QueueRequest(peerId, objectId string, msg *treechangeproto.TreeSyncMessage) (err error) { - objMsg, err := MarshallTreeMessage(msg, s.spaceId, objectId, "") + objMsg, err := spacesyncproto.MarshallSyncMessage(msg, s.spaceId, objectId) if err != nil { return } return s.requestManager.QueueRequest(peerId, objMsg) } - -func MarshallTreeMessage(message *treechangeproto.TreeSyncMessage, spaceId, objectId, replyId string) (objMsg *spacesyncproto.ObjectSyncMessage, err error) { - payload, err := message.Marshal() - if err != nil { - return - } - objMsg = &spacesyncproto.ObjectSyncMessage{ - ReplyId: replyId, - Payload: payload, - ObjectId: objectId, - SpaceId: spaceId, - } - return -} diff --git a/commonspace/object/tree/synctree/synctreehandler.go b/commonspace/object/tree/synctree/synctreehandler.go index 8f133c66..14f30961 100644 --- a/commonspace/object/tree/synctree/synctreehandler.go +++ b/commonspace/object/tree/synctree/synctreehandler.go @@ -81,7 +81,7 @@ func (s *syncTreeHandler) handleRequest(ctx context.Context, senderId string, fu if err != nil { return } - response, err = MarshallTreeMessage(treeResp, s.spaceId, s.objTree.Id(), "") + response, err = spacesyncproto.MarshallSyncMessage(treeResp, s.spaceId, s.objTree.Id()) return } diff --git a/commonspace/object/tree/synctree/synctreehandler_test.go b/commonspace/object/tree/synctree/synctreehandler_test.go index 84f3b237..e847403d 100644 --- a/commonspace/object/tree/synctree/synctreehandler_test.go +++ b/commonspace/object/tree/synctree/synctreehandler_test.go @@ -103,7 +103,7 @@ func TestSyncTreeHandler_HandleMessage(t *testing.T) { Heads: []string{"h3"}, } treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) - objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + objectMsg, _ := spacesyncproto.MarshallSyncMessage(treeMsg, "spaceId", treeId) syncReq := &treechangeproto.TreeSyncMessage{} fx.syncHandler.heads = []string{"h2"} @@ -127,7 +127,7 @@ func TestSyncTreeHandler_HandleMessage(t *testing.T) { Heads: []string{"h1"}, } treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) - objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + objectMsg, _ := spacesyncproto.MarshallSyncMessage(treeMsg, "spaceId", treeId) fx.syncHandler.heads = []string{"h1"} fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId) @@ -145,7 +145,7 @@ func TestSyncTreeHandler_HandleMessage(t *testing.T) { Heads: []string{"h3"}, } treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) - objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + objectMsg, _ := spacesyncproto.MarshallSyncMessage(treeMsg, "spaceId", treeId) fx.syncHandler.heads = []string{"h2"} fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId) @@ -167,7 +167,7 @@ func TestSyncTreeHandler_HandleMessage(t *testing.T) { Heads: []string{"h3"}, } treeMsg := treechangeproto.WrapFullRequest(fullRequest, chWithId) - objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + objectMsg, _ := spacesyncproto.MarshallSyncMessage(treeMsg, "spaceId", treeId) fx.syncHandler.heads = []string{"h2"} fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId) @@ -186,7 +186,7 @@ func TestSyncTreeHandler_HandleMessage(t *testing.T) { Heads: []string{"h3"}, } treeMsg := treechangeproto.WrapFullResponse(fullSyncResponse, chWithId) - objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + objectMsg, _ := spacesyncproto.MarshallSyncMessage(treeMsg, "spaceId", treeId) fx.syncHandler.heads = []string{"h2"} fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId) @@ -209,7 +209,7 @@ func TestSyncTreeHandler_HandleRequest(t *testing.T) { chWithId := &treechangeproto.RawTreeChangeWithId{} fullRequest := &treechangeproto.TreeFullSyncRequest{} treeMsg := treechangeproto.WrapFullRequest(fullRequest, chWithId) - objectMsg, _ := MarshallTreeMessage(treeMsg, "spaceId", treeId, "") + objectMsg, _ := spacesyncproto.MarshallSyncMessage(treeMsg, "spaceId", treeId) syncResp := &treechangeproto.TreeSyncMessage{} fx.objectTreeMock.EXPECT().Id().AnyTimes().Return(fx.treeId) @@ -230,7 +230,7 @@ func TestSyncTreeHandler_HandleRequest(t *testing.T) { headUpdate := &treechangeproto.TreeHeadUpdate{} headUpdateMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) for _, msg := range []*treechangeproto.TreeSyncMessage{responseMsg, headUpdateMsg} { - objectMsg, _ := MarshallTreeMessage(msg, "spaceId", treeId, "") + objectMsg, _ := spacesyncproto.MarshallSyncMessage(msg, "spaceId", treeId) _, err := fx.syncHandler.HandleRequest(ctx, fx.senderId, objectMsg) require.Equal(t, err, ErrMessageIsNotRequest) diff --git a/commonspace/object/tree/synctree/treesyncprotocol.go b/commonspace/object/tree/synctree/treesyncprotocol.go index d27d4e15..2750e745 100644 --- a/commonspace/object/tree/synctree/treesyncprotocol.go +++ b/commonspace/object/tree/synctree/treesyncprotocol.go @@ -60,7 +60,7 @@ func (t *treeSyncProtocol) HeadUpdate(ctx context.Context, senderId string, upda // isEmptyUpdate is sent when the tree is brought up from cache if isEmptyUpdate { headEquals := slice.UnsortedEquals(objTree.Heads(), update.Heads) - log.DebugCtx(ctx, "is empty update", zap.String("treeId", objTree.Id()), zap.Bool("headEquals", headEquals)) + log.DebugCtx(ctx, "is empty update", zap.Bool("headEquals", headEquals)) if headEquals { return } @@ -70,7 +70,7 @@ func (t *treeSyncProtocol) HeadUpdate(ctx context.Context, senderId string, upda return } - if t.alreadyHasHeads(objTree, update.Heads) { + if t.hasHeads(objTree, update.Heads) { return } @@ -82,7 +82,7 @@ func (t *treeSyncProtocol) HeadUpdate(ctx context.Context, senderId string, upda return } - if t.alreadyHasHeads(objTree, update.Heads) { + if t.hasHeads(objTree, update.Heads) { return } @@ -109,7 +109,7 @@ func (t *treeSyncProtocol) FullSyncRequest(ctx context.Context, senderId string, } }() - if len(request.Changes) != 0 && !t.alreadyHasHeads(objTree, request.Heads) { + if len(request.Changes) != 0 && !t.hasHeads(objTree, request.Heads) { _, err = objTree.AddRawChanges(ctx, objecttree.RawChangesPayload{ NewHeads: request.Heads, RawChanges: request.Changes, @@ -137,7 +137,7 @@ func (t *treeSyncProtocol) FullSyncResponse(ctx context.Context, senderId string log.DebugCtx(ctx, "full sync response succeeded") } }() - if t.alreadyHasHeads(objTree, response.Heads) { + if t.hasHeads(objTree, response.Heads) { return } @@ -148,6 +148,6 @@ func (t *treeSyncProtocol) FullSyncResponse(ctx context.Context, senderId string return } -func (t *treeSyncProtocol) alreadyHasHeads(ot objecttree.ObjectTree, heads []string) bool { +func (t *treeSyncProtocol) hasHeads(ot objecttree.ObjectTree, heads []string) bool { return slice.UnsortedEquals(ot.Heads(), heads) || ot.HasChanges(heads...) } diff --git a/commonspace/spacesyncproto/spacesync.go b/commonspace/spacesyncproto/spacesync.go index 39f5a25a..417636b2 100644 --- a/commonspace/spacesyncproto/spacesync.go +++ b/commonspace/spacesyncproto/spacesync.go @@ -2,6 +2,7 @@ package spacesyncproto import ( + "github.com/gogo/protobuf/proto" "storj.io/drpc" ) @@ -16,3 +17,16 @@ func (c ClientFactoryFunc) Client(cc drpc.Conn) DRPCSpaceSyncClient { type ClientFactory interface { Client(cc drpc.Conn) DRPCSpaceSyncClient } + +func MarshallSyncMessage(message proto.Marshaler, spaceId, objectId string) (objMsg *ObjectSyncMessage, err error) { + payload, err := message.Marshal() + if err != nil { + return + } + objMsg = &ObjectSyncMessage{ + Payload: payload, + ObjectId: objectId, + SpaceId: spaceId, + } + return +} diff --git a/consensus/consensusproto/consensus.pb.go b/consensus/consensusproto/consensus.pb.go index c00d8b25..23412c7a 100644 --- a/consensus/consensusproto/consensus.pb.go +++ b/consensus/consensusproto/consensus.pb.go @@ -811,7 +811,8 @@ func (m *LogHeadUpdate) GetRecords() []*RawRecordWithId { // LogFullSyncRequest is a message sent when consensus log needs full sync type LogFullSyncRequest struct { - Head string `protobuf:"bytes,1,opt,name=head,proto3" json:"head,omitempty"` + Head string `protobuf:"bytes,1,opt,name=head,proto3" json:"head,omitempty"` + Records []*RawRecordWithId `protobuf:"bytes,2,rep,name=records,proto3" json:"records,omitempty"` } func (m *LogFullSyncRequest) Reset() { *m = LogFullSyncRequest{} } @@ -854,6 +855,13 @@ func (m *LogFullSyncRequest) GetHead() string { return "" } +func (m *LogFullSyncRequest) GetRecords() []*RawRecordWithId { + if m != nil { + return m.Records + } + return nil +} + // LogFullSyncResponse is a message sent as a response for a specific full sync type LogFullSyncResponse struct { Head string `protobuf:"bytes,1,opt,name=head,proto3" json:"head,omitempty"` @@ -931,56 +939,57 @@ func init() { } var fileDescriptor_b8d7f1c16b400059 = []byte{ - // 782 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0xcf, 0x6e, 0xd3, 0x4c, - 0x10, 0x8f, 0xed, 0x36, 0x89, 0x27, 0x5f, 0x13, 0x7f, 0x5b, 0x84, 0x4c, 0x44, 0xd3, 0xc8, 0x08, - 0x29, 0x54, 0x28, 0x85, 0x20, 0x90, 0x50, 0x85, 0x10, 0x8d, 0x52, 0x25, 0x52, 0x9a, 0x82, 0xab, - 0x52, 0x09, 0x24, 0x84, 0xf1, 0x6e, 0x5c, 0xd3, 0xd4, 0x6b, 0xec, 0x4d, 0xdb, 0x5c, 0xb9, 0x72, - 0xe1, 0x05, 0x78, 0x1f, 0x8e, 0x3d, 0x72, 0x44, 0xed, 0x85, 0x07, 0xe0, 0x01, 0x90, 0xd7, 0x76, - 0xe2, 0x26, 0x4e, 0x11, 0x82, 0x4b, 0xbb, 0xf3, 0xff, 0x37, 0xbf, 0x19, 0x4f, 0x60, 0xdd, 0xa4, - 0x8e, 0x4f, 0x1c, 0x7f, 0xe8, 0x4f, 0x5e, 0xae, 0x47, 0x19, 0x5d, 0xe7, 0x7f, 0x13, 0xda, 0x3a, - 0x57, 0xa0, 0xe2, 0x58, 0xf1, 0x3c, 0x90, 0xb5, 0xf7, 0x20, 0x75, 0xa9, 0x85, 0x8a, 0x20, 0xda, - 0x58, 0x15, 0xaa, 0x42, 0xed, 0x3f, 0x5d, 0xb4, 0x31, 0x52, 0x21, 0xe7, 0x1a, 0xa3, 0x01, 0x35, - 0xb0, 0x2a, 0x72, 0x65, 0x2c, 0xa2, 0xc7, 0x90, 0xf3, 0x88, 0x49, 0x3d, 0xec, 0xab, 0x52, 0x55, - 0xaa, 0x15, 0x1a, 0xab, 0xf5, 0xcb, 0x29, 0xeb, 0xba, 0x71, 0xa2, 0x73, 0x8f, 0x7d, 0x9b, 0x1d, - 0x74, 0xb0, 0x1e, 0xfb, 0x6b, 0x5f, 0x04, 0x90, 0xc7, 0xc6, 0x64, 0x09, 0xe1, 0x72, 0x89, 0x9b, - 0x20, 0xfb, 0xb6, 0xe5, 0x18, 0x6c, 0xe8, 0x91, 0xa8, 0xfc, 0x44, 0x81, 0xd6, 0x40, 0x31, 0x4c, - 0x93, 0xb8, 0x8c, 0x7a, 0x1d, 0x4c, 0x1c, 0x66, 0xb3, 0x91, 0x2a, 0x71, 0xa7, 0x19, 0x3d, 0xba, - 0x0b, 0xff, 0xc7, 0xba, 0xdd, 0x71, 0xc6, 0x05, 0xee, 0x3c, 0x6b, 0xd0, 0x36, 0xa0, 0x34, 0x85, - 0xfd, 0x0a, 0x90, 0x21, 0x63, 0x01, 0x3a, 0x39, 0x60, 0x4c, 0x73, 0x20, 0x1b, 0x35, 0x76, 0x1d, - 0xb2, 0xae, 0x47, 0x8e, 0x3b, 0x61, 0x88, 0xac, 0x47, 0x12, 0x2a, 0x43, 0xde, 0x8e, 0x01, 0x87, - 0x5d, 0x8d, 0x65, 0x84, 0x60, 0x01, 0x1b, 0xcc, 0x88, 0x1a, 0xe1, 0xef, 0x80, 0x06, 0x66, 0x1f, - 0x11, 0x9f, 0x19, 0x47, 0x2e, 0x07, 0x2d, 0xe9, 0x13, 0x85, 0xb6, 0x00, 0xe2, 0xce, 0xa1, 0xf6, - 0x08, 0x96, 0xba, 0xd4, 0x7a, 0x86, 0xb1, 0x4e, 0x3e, 0x0c, 0x89, 0xcf, 0xd0, 0x6d, 0x90, 0x06, - 0xd4, 0xe2, 0x95, 0x0b, 0x8d, 0xe5, 0xe9, 0xd1, 0x74, 0xa9, 0xa5, 0x07, 0x76, 0xed, 0x35, 0x28, - 0x21, 0xda, 0x44, 0xe8, 0x35, 0x58, 0x1c, 0x50, 0xab, 0x13, 0x77, 0x1a, 0x0a, 0xe8, 0x3e, 0x64, - 0xc3, 0xf9, 0x71, 0xcc, 0x85, 0xc6, 0x8d, 0xb9, 0xe3, 0xd6, 0x23, 0x47, 0x6d, 0x1b, 0x4a, 0x5d, - 0x6a, 0xed, 0x1b, 0xcc, 0x3c, 0x88, 0x73, 0x97, 0x21, 0x7f, 0x12, 0xc8, 0x1d, 0xec, 0xab, 0x42, - 0x55, 0x0a, 0x7a, 0x8f, 0x65, 0x54, 0x01, 0x18, 0x3a, 0x63, 0xab, 0xc8, 0xad, 0x09, 0x8d, 0xf6, - 0x49, 0xe0, 0x4d, 0xf2, 0x7c, 0xad, 0x63, 0xe2, 0xcc, 0x43, 0x9a, 0xd8, 0x4c, 0xf1, 0xcf, 0x36, - 0x13, 0xdd, 0x81, 0x45, 0xe2, 0x79, 0xd4, 0xe3, 0xfc, 0xa7, 0xf0, 0xd6, 0xf2, 0x3c, 0x3d, 0xf4, - 0xd0, 0x1e, 0x82, 0xd4, 0xf2, 0x3c, 0x54, 0x8f, 0x23, 0x02, 0x08, 0xc5, 0x86, 0x9a, 0x12, 0xd1, - 0xa4, 0x98, 0xf8, 0x71, 0xd8, 0x47, 0x11, 0x96, 0xbb, 0xd4, 0xda, 0x1d, 0x39, 0x66, 0x93, 0x3a, - 0x8c, 0x38, 0xec, 0xa5, 0x31, 0x18, 0x12, 0xf4, 0x14, 0xe0, 0x80, 0x18, 0x78, 0xcf, 0xc5, 0x06, - 0x23, 0xd1, 0xd8, 0x56, 0x52, 0xc6, 0xd6, 0x1e, 0x3b, 0xb5, 0x33, 0x7a, 0x22, 0x04, 0xf5, 0xa0, - 0xd4, 0x1f, 0x0e, 0x06, 0x41, 0xe2, 0x88, 0xec, 0x68, 0x50, 0x5a, 0x4a, 0x96, 0xad, 0xcb, 0x9e, - 0xed, 0x8c, 0x3e, 0x1d, 0x8c, 0x5e, 0x80, 0x32, 0x51, 0xf9, 0x6e, 0x90, 0x22, 0x62, 0xe5, 0xd6, - 0x95, 0x09, 0x43, 0xd7, 0x76, 0x46, 0x9f, 0x09, 0xdf, 0xcc, 0xc1, 0xe2, 0x71, 0xd0, 0xac, 0x36, - 0x82, 0x62, 0xc4, 0xc1, 0x36, 0xf1, 0x7d, 0xc3, 0x22, 0x89, 0xbb, 0x23, 0xa7, 0xdd, 0x1d, 0x79, - 0xf2, 0xbd, 0x3d, 0x81, 0x9c, 0x19, 0x12, 0x77, 0x05, 0x9c, 0x69, 0x7a, 0xf5, 0x38, 0x46, 0x7b, - 0xc3, 0x77, 0x68, 0xc2, 0x62, 0xf0, 0xc5, 0x05, 0x2c, 0x46, 0xb5, 0xf9, 0xfb, 0x2f, 0x36, 0x48, - 0xab, 0x01, 0x9a, 0xe5, 0x37, 0xad, 0x88, 0x86, 0xf9, 0x22, 0x4c, 0x13, 0xf7, 0x8f, 0xf1, 0xac, - 0xbd, 0x85, 0x7c, 0xbc, 0x82, 0xa8, 0x08, 0xb0, 0xe7, 0x90, 0x53, 0x97, 0x98, 0x8c, 0x60, 0x25, - 0x83, 0x96, 0x40, 0xee, 0x52, 0xab, 0x75, 0x6a, 0xfb, 0xcc, 0x57, 0x04, 0x54, 0x82, 0x42, 0x97, - 0x5a, 0x3d, 0xca, 0xb6, 0xe8, 0xd0, 0xc1, 0x8a, 0x88, 0x10, 0x14, 0xc3, 0xa4, 0x4d, 0xea, 0xf4, - 0x07, 0xb6, 0xc9, 0x14, 0x09, 0x29, 0x50, 0x68, 0x05, 0x8b, 0xbc, 0xd3, 0xef, 0xfb, 0x84, 0x29, - 0x3f, 0xa5, 0xc6, 0x0f, 0x01, 0xe4, 0x66, 0x8c, 0x06, 0x6d, 0x40, 0x36, 0x3c, 0x44, 0x28, 0x6d, - 0x7b, 0x27, 0x57, 0xa6, 0x8c, 0xa6, 0xcd, 0x3b, 0x87, 0xa8, 0x07, 0xf2, 0xf8, 0x1a, 0xa1, 0xea, - 0x4c, 0x8f, 0x53, 0x87, 0xaa, 0xfc, 0x3b, 0x16, 0x50, 0x0f, 0xf2, 0xf1, 0xc1, 0x40, 0xab, 0x29, - 0x70, 0x92, 0xa7, 0xa9, 0xbc, 0x32, 0xcf, 0x81, 0xdf, 0x9a, 0x9a, 0x70, 0x4f, 0xd8, 0x6c, 0x7c, - 0x3d, 0xaf, 0x08, 0x67, 0xe7, 0x15, 0xe1, 0xfb, 0x79, 0x45, 0xf8, 0x7c, 0x51, 0xc9, 0x9c, 0x5d, - 0x54, 0x32, 0xdf, 0x2e, 0x2a, 0x99, 0x57, 0xea, 0xbc, 0xdf, 0xdf, 0x77, 0x59, 0xfe, 0xef, 0xc1, - 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd6, 0x8a, 0x01, 0xa8, 0xa2, 0x07, 0x00, 0x00, + // 785 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0x5f, 0x4f, 0xdb, 0x56, + 0x14, 0x8f, 0x6d, 0x48, 0xe2, 0x93, 0x91, 0x78, 0x87, 0x69, 0xf2, 0xa2, 0x11, 0x22, 0x4f, 0x93, + 0x18, 0x9a, 0xc2, 0x96, 0x69, 0x93, 0x26, 0x34, 0x4d, 0x23, 0x0a, 0x4a, 0xa4, 0x10, 0x36, 0x23, + 0x86, 0xb4, 0x49, 0x55, 0x5d, 0xdf, 0x1b, 0xe3, 0x12, 0x7c, 0x5d, 0xfb, 0x06, 0xc8, 0x6b, 0x5f, + 0xfb, 0xd2, 0x2f, 0xd0, 0xef, 0xd3, 0x47, 0x1e, 0xfb, 0x58, 0xc1, 0x4b, 0x3f, 0x40, 0x3f, 0x40, + 0xe5, 0x6b, 0x3b, 0x31, 0xf9, 0x43, 0x55, 0x95, 0x17, 0xf0, 0xf9, 0xff, 0x3b, 0xbf, 0x73, 0xee, + 0x09, 0xec, 0xd8, 0xcc, 0x0b, 0xa9, 0x17, 0x8e, 0xc2, 0xe9, 0x97, 0x1f, 0x30, 0xce, 0x76, 0xc4, + 0xdf, 0x8c, 0xb6, 0x21, 0x14, 0x58, 0x9e, 0x28, 0xfe, 0x8e, 0x64, 0xe3, 0x29, 0x28, 0x3d, 0xe6, + 0x60, 0x19, 0x64, 0x97, 0xe8, 0x52, 0x5d, 0xda, 0xfa, 0xc2, 0x94, 0x5d, 0x82, 0x3a, 0x14, 0x7c, + 0x6b, 0x3c, 0x64, 0x16, 0xd1, 0x65, 0xa1, 0x4c, 0x45, 0xfc, 0x1d, 0x0a, 0x01, 0xb5, 0x59, 0x40, + 0x42, 0x5d, 0xa9, 0x2b, 0x5b, 0xa5, 0xe6, 0x66, 0xe3, 0x6e, 0xca, 0x86, 0x69, 0x5d, 0x9a, 0xc2, + 0xe3, 0xc4, 0xe5, 0xa7, 0x5d, 0x62, 0xa6, 0xfe, 0xc6, 0x2b, 0x09, 0xd4, 0x89, 0x31, 0x5b, 0x42, + 0xba, 0x5b, 0xe2, 0x5b, 0x50, 0x43, 0xd7, 0xf1, 0x2c, 0x3e, 0x0a, 0x68, 0x52, 0x7e, 0xaa, 0xc0, + 0x6d, 0xd0, 0x2c, 0xdb, 0xa6, 0x3e, 0x67, 0x41, 0x97, 0x50, 0x8f, 0xbb, 0x7c, 0xac, 0x2b, 0xc2, + 0x69, 0x4e, 0x8f, 0x3f, 0xc2, 0x97, 0xa9, 0xee, 0x68, 0x92, 0x71, 0x45, 0x38, 0xcf, 0x1b, 0x8c, + 0x5d, 0xa8, 0xcc, 0x60, 0xbf, 0x07, 0x64, 0xcc, 0x58, 0x84, 0x4e, 0x8d, 0x18, 0x33, 0x3c, 0xc8, + 0x27, 0x8d, 0x7d, 0x0d, 0x79, 0x3f, 0xa0, 0x17, 0xdd, 0x38, 0x44, 0x35, 0x13, 0x09, 0xab, 0x50, + 0x74, 0x53, 0xc0, 0x71, 0x57, 0x13, 0x19, 0x11, 0x56, 0x88, 0xc5, 0xad, 0xa4, 0x11, 0xf1, 0x1d, + 0xd1, 0xc0, 0xdd, 0x73, 0x1a, 0x72, 0xeb, 0xdc, 0x17, 0xa0, 0x15, 0x73, 0xaa, 0x30, 0x56, 0x40, + 0x3e, 0x3c, 0x33, 0x7e, 0x83, 0xb5, 0x1e, 0x73, 0xfe, 0x22, 0xc4, 0xa4, 0xcf, 0x46, 0x34, 0xe4, + 0xf8, 0x3d, 0x28, 0x43, 0xe6, 0x88, 0xca, 0xa5, 0xe6, 0xfa, 0xec, 0x68, 0x7a, 0xcc, 0x31, 0x23, + 0xbb, 0xf1, 0x3f, 0x68, 0x31, 0xda, 0x4c, 0xe8, 0x57, 0xb0, 0x3a, 0x64, 0x4e, 0x37, 0xed, 0x34, + 0x16, 0xf0, 0x67, 0xc8, 0xc7, 0xf3, 0x13, 0x98, 0x4b, 0xcd, 0x6f, 0x96, 0x8e, 0xdb, 0x4c, 0x1c, + 0x8d, 0x03, 0xa8, 0xf4, 0x98, 0x73, 0x62, 0x71, 0xfb, 0x34, 0xcd, 0x5d, 0x85, 0xe2, 0x65, 0x24, + 0x77, 0x49, 0xa8, 0x4b, 0x75, 0x25, 0xea, 0x3d, 0x95, 0xb1, 0x06, 0x30, 0xf2, 0x26, 0x56, 0x59, + 0x58, 0x33, 0x1a, 0xe3, 0x85, 0x24, 0x9a, 0x14, 0xf9, 0xda, 0x17, 0xd4, 0x5b, 0x86, 0x34, 0xb3, + 0x99, 0xf2, 0xa7, 0x6d, 0x26, 0xfe, 0x00, 0xab, 0x34, 0x08, 0x58, 0x20, 0xf8, 0x5f, 0xc0, 0x5b, + 0x3b, 0x08, 0xcc, 0xd8, 0xc3, 0xf8, 0x15, 0x94, 0x76, 0x10, 0x60, 0x23, 0x8d, 0x88, 0x20, 0x94, + 0x9b, 0xfa, 0x82, 0x88, 0x16, 0x23, 0x34, 0x4c, 0xc3, 0x9e, 0xcb, 0xb0, 0xde, 0x63, 0xce, 0xd1, + 0xd8, 0xb3, 0x5b, 0xcc, 0xe3, 0xd4, 0xe3, 0xff, 0x5a, 0xc3, 0x11, 0xc5, 0x3f, 0x01, 0x4e, 0xa9, + 0x45, 0x8e, 0x7d, 0x62, 0x71, 0x9a, 0x8c, 0x6d, 0x63, 0xc1, 0xd8, 0x3a, 0x13, 0xa7, 0x4e, 0xce, + 0xcc, 0x84, 0x60, 0x1f, 0x2a, 0x83, 0xd1, 0x70, 0x18, 0x25, 0x4e, 0xc8, 0x4e, 0x06, 0x65, 0x2c, + 0xc8, 0xb2, 0x7f, 0xd7, 0xb3, 0x93, 0x33, 0x67, 0x83, 0xf1, 0x1f, 0xd0, 0xa6, 0xaa, 0xd0, 0x8f, + 0x52, 0x24, 0xac, 0x7c, 0x77, 0x6f, 0xc2, 0xd8, 0xb5, 0x93, 0x33, 0xe7, 0xc2, 0xf7, 0x0a, 0xb0, + 0x7a, 0x11, 0x35, 0x6b, 0x8c, 0xa1, 0x9c, 0x70, 0x70, 0x40, 0xc3, 0xd0, 0x72, 0x68, 0xe6, 0xee, + 0xa8, 0x8b, 0xee, 0x8e, 0x3a, 0x7d, 0x6f, 0x7f, 0x40, 0xc1, 0x8e, 0x89, 0xbb, 0x07, 0xce, 0x2c, + 0xbd, 0x66, 0x1a, 0x63, 0x3c, 0x12, 0x3b, 0x34, 0x65, 0x31, 0x7a, 0x71, 0x11, 0x8b, 0x49, 0x6d, + 0xf1, 0xfd, 0x19, 0x1b, 0x64, 0xd8, 0x80, 0xf3, 0xfc, 0x3e, 0x74, 0x11, 0x22, 0x76, 0x68, 0x96, + 0xf3, 0x07, 0xae, 0xb2, 0xfd, 0x18, 0x8a, 0xe9, 0xf6, 0x62, 0x19, 0xe0, 0xd8, 0xa3, 0x57, 0x3e, + 0xb5, 0x39, 0x25, 0x5a, 0x0e, 0xd7, 0x40, 0xed, 0x31, 0xa7, 0x7d, 0xe5, 0x86, 0x3c, 0xd4, 0x24, + 0xac, 0x40, 0xa9, 0xc7, 0x9c, 0x3e, 0xe3, 0xfb, 0x6c, 0xe4, 0x11, 0x4d, 0x46, 0x84, 0x72, 0x9c, + 0xb4, 0xc5, 0xbc, 0xc1, 0xd0, 0xb5, 0xb9, 0xa6, 0xa0, 0x06, 0xa5, 0x76, 0xf4, 0x06, 0x0e, 0x07, + 0x83, 0x90, 0x72, 0xed, 0xbd, 0xd2, 0x7c, 0x27, 0x81, 0xda, 0x4a, 0xd1, 0xe0, 0x2e, 0xe4, 0xe3, + 0x1b, 0x86, 0x8b, 0x16, 0x7f, 0x7a, 0xa0, 0xaa, 0x38, 0x6b, 0x3e, 0x3c, 0xc3, 0x3e, 0xa8, 0x93, + 0x43, 0x86, 0xf5, 0xb9, 0x1e, 0x67, 0x6e, 0x5c, 0xf5, 0x63, 0x2c, 0x60, 0x1f, 0x8a, 0xe9, 0xad, + 0xc1, 0xcd, 0x05, 0x70, 0xb2, 0x57, 0xad, 0xba, 0xb1, 0xcc, 0x41, 0x9c, 0xa9, 0x2d, 0xe9, 0x27, + 0x69, 0xaf, 0xf9, 0xfa, 0xa6, 0x26, 0x5d, 0xdf, 0xd4, 0xa4, 0xb7, 0x37, 0x35, 0xe9, 0xe5, 0x6d, + 0x2d, 0x77, 0x7d, 0x5b, 0xcb, 0xbd, 0xb9, 0xad, 0xe5, 0xfe, 0xd3, 0x97, 0xfd, 0x74, 0x3f, 0xc9, + 0x8b, 0x7f, 0xbf, 0x7c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x8b, 0x1f, 0x1a, 0x5a, 0xdd, 0x07, 0x00, + 0x00, } func (m *Log) Marshal() (dAtA []byte, err error) { @@ -1604,6 +1613,20 @@ func (m *LogFullSyncRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = 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.Head) > 0 { i -= len(m.Head) copy(dAtA[i:], m.Head) @@ -1951,6 +1974,12 @@ func (m *LogFullSyncRequest) Size() (n int) { 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 } @@ -3677,6 +3706,40 @@ func (m *LogFullSyncRequest) Unmarshal(dAtA []byte) error { } m.Head = string(dAtA[iNdEx:postIndex]) 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, &RawRecordWithId{}) + 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:]) diff --git a/consensus/consensusproto/protos/consensus.proto b/consensus/consensusproto/protos/consensus.proto index 10d7d0e9..7b745667 100644 --- a/consensus/consensusproto/protos/consensus.proto +++ b/consensus/consensusproto/protos/consensus.proto @@ -101,6 +101,7 @@ message LogHeadUpdate { // LogFullSyncRequest is a message sent when consensus log needs full sync message LogFullSyncRequest { string head = 1; + repeated RawRecordWithId records = 2; } // LogFullSyncResponse is a message sent as a response for a specific full sync From b12a056dd90335aceccd4c39e8e8608a50b71970 Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Mon, 3 Jul 2023 16:19:24 +0200 Subject: [PATCH 105/123] consensus: use strings for ids --- consensus/consensusclient/client.go | 32 ++-- consensus/consensusclient/client_test.go | 22 +-- consensus/consensusclient/stream.go | 4 +- consensus/consensusproto/consensus.pb.go | 180 +++++++++--------- .../consensusproto/protos/consensus.proto | 10 +- 5 files changed, 121 insertions(+), 127 deletions(-) diff --git a/consensus/consensusclient/client.go b/consensus/consensusclient/client.go index ff5882a7..6bf5e8ab 100644 --- a/consensus/consensusclient/client.go +++ b/consensus/consensusclient/client.go @@ -38,11 +38,11 @@ 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.RawRecord) (record *consensusproto.RawRecordWithId, err error) + AddRecord(ctx context.Context, logId string, clog *consensusproto.RawRecord) (record *consensusproto.RawRecordWithId, err error) // Watch starts watching to given logId and calls watcher when any relative event received - Watch(logId []byte, w Watcher) (err error) + Watch(logId string, w Watcher) (err error) // UnWatch stops watching given logId and removes watcher - UnWatch(logId []byte) (err error) + UnWatch(logId string) (err error) app.ComponentRunnable } @@ -97,7 +97,7 @@ func (s *service) AddLog(ctx context.Context, clog *consensusproto.Log) (err err }) } -func (s *service) AddRecord(ctx context.Context, logId []byte, clog *consensusproto.RawRecord) (record *consensusproto.RawRecordWithId, err error) { +func (s *service) AddRecord(ctx context.Context, logId string, clog *consensusproto.RawRecord) (record *consensusproto.RawRecordWithId, err error) { err = s.doClient(ctx, func(cl consensusproto.DRPCConsensusClient) error { if record, err = cl.RecordAdd(ctx, &consensusproto.RecordAddRequest{ LogId: logId, @@ -110,30 +110,30 @@ func (s *service) AddRecord(ctx context.Context, logId []byte, clog *consensuspr return } -func (s *service) Watch(logId []byte, w Watcher) (err error) { +func (s *service) Watch(logId string, w Watcher) (err error) { s.mu.Lock() defer s.mu.Unlock() - if _, ok := s.watchers[string(logId)]; ok { + if _, ok := s.watchers[logId]; ok { return ErrWatcherExists } - s.watchers[string(logId)] = w + s.watchers[logId] = w if s.stream != nil { - if wErr := s.stream.WatchIds([][]byte{logId}); wErr != nil { + if wErr := s.stream.WatchIds([]string{logId}); wErr != nil { log.Warn("WatchIds error", zap.Error(wErr)) } } return } -func (s *service) UnWatch(logId []byte) (err error) { +func (s *service) UnWatch(logId string) (err error) { s.mu.Lock() defer s.mu.Unlock() - if _, ok := s.watchers[string(logId)]; !ok { + if _, ok := s.watchers[logId]; !ok { return ErrWatcherNotExists } - delete(s.watchers, string(logId)) + delete(s.watchers, logId) if s.stream != nil { - if wErr := s.stream.UnwatchIds([][]byte{logId}); wErr != nil { + if wErr := s.stream.UnwatchIds([]string{logId}); wErr != nil { log.Warn("UnWatchIds error", zap.Error(wErr)) } } @@ -182,9 +182,9 @@ func (s *service) streamWatcher() { // collect ids and setup stream s.mu.Lock() - var logIds = make([][]byte, 0, len(s.watchers)) + var logIds = make([]string, 0, len(s.watchers)) for id := range s.watchers { - logIds = append(logIds, []byte(id)) + logIds = append(logIds, id) } s.stream = st s.mu.Unlock() @@ -213,14 +213,14 @@ func (s *service) streamReader() error { return s.stream.Err() } for _, e := range events { - if w, ok := s.watchers[string(e.LogId)]; ok { + if w, ok := s.watchers[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)) + log.Warn("received unexpected log id", zap.String("logId", e.LogId)) } } } diff --git a/consensus/consensusclient/client_test.go b/consensus/consensusclient/client_test.go index fd21695c..f4b8f2cc 100644 --- a/consensus/consensusclient/client_test.go +++ b/consensus/consensusclient/client_test.go @@ -24,13 +24,13 @@ 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'} + var logId = "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) + assert.Equal(t, []string{logId}, req.WatchIds) require.NoError(t, st.Send(&consensusproto.LogWatchEvent{ LogId: logId, Error: &consensusproto.Err{ @@ -44,7 +44,7 @@ func TestService_Watch(t *testing.T) { t.Run("watcherExists error", func(t *testing.T) { fx := newFixture(t).run(t) defer fx.Finish() - var logId = []byte{'1'} + var logId = "1" w := &testWatcher{} require.NoError(t, fx.Watch(logId, w)) require.Error(t, fx.Watch(logId, w)) @@ -55,20 +55,20 @@ func TestService_Watch(t *testing.T) { t.Run("watch", func(t *testing.T) { fx := newFixture(t).run(t) defer fx.Finish() - var logId1 = []byte{'1'} + var logId1 = "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) + assert.Equal(t, []string{logId1}, req.WatchIds) - var logId2 = []byte{'2'} + var logId2 = "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) + assert.Equal(t, []string{logId2}, req.WatchIds) fx.testServer.releaseStream <- nil }) @@ -78,14 +78,14 @@ 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'})) + require.Error(t, fx.UnWatch("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'})) + require.NoError(t, fx.Watch("1", w)) + assert.NoError(t, fx.UnWatch("1")) }) } @@ -119,7 +119,7 @@ func TestService_AddLog(t *testing.T) { func TestService_AddRecord(t *testing.T) { fx := newFixture(t).run(t) defer fx.Finish() - rec, err := fx.AddRecord(ctx, []byte{'1'}, &consensusproto.RawRecord{}) + rec, err := fx.AddRecord(ctx, "1", &consensusproto.RawRecord{}) require.NoError(t, err) assert.NotEmpty(t, rec) } diff --git a/consensus/consensusclient/stream.go b/consensus/consensusclient/stream.go index 679dcd74..13348bf2 100644 --- a/consensus/consensusclient/stream.go +++ b/consensus/consensusclient/stream.go @@ -23,13 +23,13 @@ type stream struct { err error } -func (s *stream) WatchIds(logIds [][]byte) (err error) { +func (s *stream) WatchIds(logIds []string) (err error) { return s.rpcStream.Send(&consensusproto.LogWatchRequest{ WatchIds: logIds, }) } -func (s *stream) UnwatchIds(logIds [][]byte) (err error) { +func (s *stream) UnwatchIds(logIds []string) (err error) { return s.rpcStream.Send(&consensusproto.LogWatchRequest{ UnwatchIds: logIds, }) diff --git a/consensus/consensusproto/consensus.pb.go b/consensus/consensusproto/consensus.pb.go index 4e81e61c..d99079b5 100644 --- a/consensus/consensusproto/consensus.pb.go +++ b/consensus/consensusproto/consensus.pb.go @@ -57,7 +57,7 @@ func (ErrCodes) EnumDescriptor() ([]byte, []int) { } type Log struct { - Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` Payload []byte `protobuf:"bytes,2,opt,name=payload,proto3" json:"payload,omitempty"` Records []*RawRecordWithId `protobuf:"bytes,3,rep,name=records,proto3" json:"records,omitempty"` } @@ -95,11 +95,11 @@ func (m *Log) XXX_DiscardUnknown() { var xxx_messageInfo_Log proto.InternalMessageInfo -func (m *Log) GetId() []byte { +func (m *Log) GetId() string { if m != nil { return m.Id } - return nil + return "" } func (m *Log) GetPayload() []byte { @@ -388,7 +388,7 @@ func (m *LogAddRequest) GetLog() *Log { } type RecordAddRequest struct { - LogId []byte `protobuf:"bytes,1,opt,name=logId,proto3" json:"logId,omitempty"` + LogId string `protobuf:"bytes,1,opt,name=logId,proto3" json:"logId,omitempty"` Record *RawRecord `protobuf:"bytes,2,opt,name=record,proto3" json:"record,omitempty"` } @@ -425,11 +425,11 @@ func (m *RecordAddRequest) XXX_DiscardUnknown() { var xxx_messageInfo_RecordAddRequest proto.InternalMessageInfo -func (m *RecordAddRequest) GetLogId() []byte { +func (m *RecordAddRequest) GetLogId() string { if m != nil { return m.LogId } - return nil + return "" } func (m *RecordAddRequest) GetRecord() *RawRecord { @@ -440,8 +440,8 @@ func (m *RecordAddRequest) GetRecord() *RawRecord { } type LogWatchRequest 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"` + WatchIds []string `protobuf:"bytes,1,rep,name=watchIds,proto3" json:"watchIds,omitempty"` + UnwatchIds []string `protobuf:"bytes,2,rep,name=unwatchIds,proto3" json:"unwatchIds,omitempty"` } func (m *LogWatchRequest) Reset() { *m = LogWatchRequest{} } @@ -477,14 +477,14 @@ func (m *LogWatchRequest) XXX_DiscardUnknown() { var xxx_messageInfo_LogWatchRequest proto.InternalMessageInfo -func (m *LogWatchRequest) GetWatchIds() [][]byte { +func (m *LogWatchRequest) GetWatchIds() []string { if m != nil { return m.WatchIds } return nil } -func (m *LogWatchRequest) GetUnwatchIds() [][]byte { +func (m *LogWatchRequest) GetUnwatchIds() []string { if m != nil { return m.UnwatchIds } @@ -492,7 +492,7 @@ func (m *LogWatchRequest) GetUnwatchIds() [][]byte { } type LogWatchEvent struct { - LogId []byte `protobuf:"bytes,1,opt,name=logId,proto3" json:"logId,omitempty"` + LogId string `protobuf:"bytes,1,opt,name=logId,proto3" json:"logId,omitempty"` Records []*RawRecordWithId `protobuf:"bytes,2,rep,name=records,proto3" json:"records,omitempty"` Error *Err `protobuf:"bytes,3,opt,name=error,proto3" json:"error,omitempty"` } @@ -530,11 +530,11 @@ func (m *LogWatchEvent) XXX_DiscardUnknown() { var xxx_messageInfo_LogWatchEvent proto.InternalMessageInfo -func (m *LogWatchEvent) GetLogId() []byte { +func (m *LogWatchEvent) GetLogId() string { if m != nil { return m.LogId } - return nil + return "" } func (m *LogWatchEvent) GetRecords() []*RawRecordWithId { @@ -614,46 +614,46 @@ func init() { } var fileDescriptor_b8d7f1c16b400059 = []byte{ - // 618 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xcf, 0x6e, 0xd3, 0x4e, - 0x10, 0xce, 0xda, 0x6d, 0x1a, 0x4f, 0x7e, 0x4d, 0xfd, 0x1b, 0x10, 0x32, 0x11, 0x75, 0x23, 0x4b, - 0x48, 0xa5, 0x42, 0x29, 0x04, 0x81, 0x84, 0x7a, 0x82, 0x2a, 0x48, 0x91, 0x42, 0x8b, 0x8c, 0x50, - 0x25, 0xb8, 0x60, 0xbc, 0x5b, 0xd7, 0x34, 0xf5, 0x86, 0xdd, 0x4d, 0xff, 0x3c, 0x03, 0x17, 0x5e, - 0x80, 0xf7, 0xe1, 0xd8, 0x23, 0x47, 0xd4, 0x5e, 0x78, 0x00, 0x1e, 0x00, 0x79, 0x1d, 0x3b, 0x6e, - 0x9a, 0x80, 0xb8, 0x24, 0x3b, 0xdf, 0xfc, 0xfb, 0x66, 0xe6, 0x93, 0x61, 0x33, 0xe4, 0x89, 0x64, - 0x89, 0x1c, 0xc9, 0xc9, 0x6b, 0x28, 0xb8, 0xe2, 0x9b, 0xfa, 0xb7, 0x84, 0xb6, 0x35, 0x80, 0x8d, - 0x02, 0x78, 0x95, 0xda, 0xde, 0x47, 0x30, 0xfb, 0x3c, 0xc2, 0x06, 0x18, 0x31, 0x75, 0x48, 0x8b, - 0xac, 0xff, 0xe7, 0x1b, 0x31, 0x45, 0x07, 0x96, 0x86, 0xc1, 0xd9, 0x80, 0x07, 0xd4, 0x31, 0x34, - 0x98, 0x9b, 0xf8, 0x14, 0x96, 0x04, 0x0b, 0xb9, 0xa0, 0xd2, 0x31, 0x5b, 0xe6, 0x7a, 0xbd, 0xb3, - 0xd6, 0xbe, 0x5a, 0xb2, 0xed, 0x07, 0x27, 0xbe, 0x8e, 0xd8, 0x8b, 0xd5, 0x41, 0x8f, 0xfa, 0x79, - 0xbc, 0xf7, 0x95, 0x80, 0x55, 0x38, 0xcb, 0x2d, 0xc8, 0xd5, 0x16, 0x77, 0xc0, 0x92, 0x71, 0x94, - 0x04, 0x6a, 0x24, 0xd8, 0xb8, 0xfd, 0x04, 0xc0, 0x0d, 0xb0, 0x83, 0x30, 0x64, 0x43, 0xc5, 0x45, - 0x8f, 0xb2, 0x44, 0xc5, 0xea, 0xcc, 0x31, 0x75, 0xd0, 0x35, 0x1c, 0xef, 0xc3, 0xff, 0x39, 0xf6, - 0xba, 0xa8, 0xb8, 0xa0, 0x83, 0xaf, 0x3b, 0xbc, 0x2d, 0x58, 0x99, 0xe2, 0xfe, 0x07, 0x92, 0xd9, - 0xc6, 0x52, 0x76, 0x56, 0xba, 0x31, 0x2f, 0x81, 0xea, 0x78, 0xb0, 0x5b, 0x50, 0x1d, 0x0a, 0x76, - 0xdc, 0xcb, 0x52, 0x2c, 0x7f, 0x6c, 0x61, 0x13, 0x6a, 0x71, 0x4e, 0x38, 0x9b, 0xaa, 0xb0, 0x11, - 0x61, 0x81, 0x06, 0x2a, 0x18, 0x0f, 0xa2, 0xdf, 0xe9, 0x1a, 0x54, 0x7c, 0xc4, 0xa4, 0x0a, 0x8e, - 0x86, 0x9a, 0xb4, 0xe9, 0x4f, 0x00, 0x6f, 0x01, 0x8c, 0xdd, 0x43, 0xef, 0x09, 0x2c, 0xf7, 0x79, - 0xf4, 0x8c, 0x52, 0x9f, 0x7d, 0x1a, 0x31, 0xa9, 0xf0, 0x2e, 0x98, 0x03, 0x1e, 0xe9, 0xce, 0xf5, - 0xce, 0x8d, 0xe9, 0xd3, 0xf4, 0x79, 0xe4, 0xa7, 0x7e, 0xef, 0x1d, 0xd8, 0x19, 0xdb, 0x52, 0xea, - 0x4d, 0x58, 0x1c, 0xf0, 0xa8, 0x97, 0x4f, 0x9a, 0x19, 0xf8, 0x10, 0xaa, 0xd9, 0xfd, 0x34, 0xe7, - 0x7a, 0xe7, 0xf6, 0xdc, 0x73, 0xfb, 0xe3, 0x40, 0xef, 0x25, 0xac, 0xf4, 0x79, 0xb4, 0x17, 0xa8, - 0xf0, 0x20, 0xaf, 0xdd, 0x84, 0xda, 0x49, 0x6a, 0xf7, 0xa8, 0x74, 0x48, 0xcb, 0x4c, 0x67, 0xcf, - 0x6d, 0x74, 0x01, 0x46, 0x49, 0xe1, 0x35, 0xb4, 0xb7, 0x84, 0x78, 0x9f, 0x89, 0x1e, 0x52, 0xd7, - 0xeb, 0x1e, 0xb3, 0x64, 0x1e, 0xd3, 0x92, 0x32, 0x8d, 0x7f, 0x53, 0x26, 0xde, 0x83, 0x45, 0x26, - 0x04, 0x17, 0x7a, 0xff, 0x33, 0xf6, 0xd6, 0x15, 0xc2, 0xcf, 0x22, 0xbc, 0xc7, 0x60, 0x76, 0x85, - 0xc0, 0x76, 0x9e, 0x91, 0x52, 0x68, 0x74, 0x9c, 0x19, 0x19, 0xdb, 0x9c, 0x32, 0x39, 0x4e, 0xdb, - 0x78, 0x0f, 0xb5, 0x1c, 0xc2, 0x06, 0xc0, 0x9b, 0x84, 0x9d, 0x0e, 0x59, 0xa8, 0x18, 0xb5, 0x2b, - 0xb8, 0x0c, 0x56, 0x9f, 0x47, 0xdd, 0xd3, 0x58, 0x2a, 0x69, 0x13, 0x5c, 0x81, 0x7a, 0x9f, 0x47, - 0x3b, 0x5c, 0xbd, 0xe0, 0xa3, 0x84, 0xda, 0x06, 0x22, 0x34, 0x32, 0xda, 0xdb, 0x3c, 0xd9, 0x1f, - 0xc4, 0xa1, 0xb2, 0x4d, 0xb4, 0xa1, 0xde, 0x4d, 0x0b, 0xef, 0xee, 0xef, 0x4b, 0xa6, 0xec, 0x5f, - 0x66, 0xe7, 0x27, 0x01, 0x6b, 0x3b, 0x27, 0x81, 0x5b, 0x50, 0xcd, 0x84, 0x81, 0xab, 0x33, 0x44, - 0x30, 0xb9, 0x7a, 0x13, 0xa7, 0xdd, 0xbb, 0x87, 0xb8, 0x03, 0x56, 0xa1, 0x0e, 0x6c, 0x5d, 0xdb, - 0xe2, 0x94, 0x70, 0x9a, 0x7f, 0xdb, 0x33, 0xee, 0x40, 0x2d, 0x3f, 0x20, 0xae, 0xcd, 0xa0, 0x53, - 0x96, 0x4a, 0x73, 0x75, 0x5e, 0x80, 0xbe, 0xfd, 0x3a, 0x79, 0x40, 0x9e, 0x77, 0xbe, 0x5d, 0xb8, - 0xe4, 0xfc, 0xc2, 0x25, 0x3f, 0x2e, 0x5c, 0xf2, 0xe5, 0xd2, 0xad, 0x9c, 0x5f, 0xba, 0x95, 0xef, - 0x97, 0x6e, 0xe5, 0xad, 0x33, 0xef, 0x7b, 0xf8, 0xa1, 0xaa, 0xff, 0x1e, 0xfd, 0x0e, 0x00, 0x00, - 0xff, 0xff, 0xbc, 0x83, 0xcb, 0xc1, 0x32, 0x05, 0x00, 0x00, + // 617 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xcb, 0x6e, 0xd3, 0x4c, + 0x14, 0xce, 0xd8, 0x6d, 0x1a, 0x9f, 0xfc, 0x4d, 0xfd, 0x1f, 0x10, 0x32, 0x11, 0x75, 0x23, 0x4b, + 0x48, 0xa1, 0x42, 0x29, 0x04, 0x81, 0x84, 0xba, 0x82, 0x2a, 0x48, 0x91, 0x42, 0x8b, 0x8c, 0x50, + 0x25, 0xd8, 0x60, 0x3c, 0x53, 0xd7, 0x34, 0xf5, 0x84, 0x99, 0x49, 0x2f, 0xcf, 0xc0, 0x86, 0x17, + 0xe0, 0x7d, 0x58, 0x76, 0xc9, 0x12, 0xb5, 0x1b, 0x1e, 0x80, 0x07, 0x40, 0x19, 0xc7, 0x8e, 0x9b, + 0x0b, 0x88, 0x4d, 0x32, 0xe7, 0x3b, 0xb7, 0xef, 0x7c, 0xe7, 0xc8, 0xb0, 0x15, 0xf2, 0x44, 0xb2, + 0x44, 0x0e, 0xe5, 0xe4, 0x35, 0x10, 0x5c, 0xf1, 0x2d, 0xfd, 0x5b, 0x40, 0x5b, 0x1a, 0xc0, 0x5a, + 0x0e, 0xbc, 0x1a, 0xd9, 0xde, 0x47, 0x30, 0x7b, 0x3c, 0xc2, 0x1a, 0x18, 0x31, 0x75, 0x48, 0x83, + 0x34, 0x2d, 0xdf, 0x88, 0x29, 0x3a, 0xb0, 0x32, 0x08, 0xce, 0xfb, 0x3c, 0xa0, 0x8e, 0xd1, 0x20, + 0xcd, 0xff, 0xfc, 0xcc, 0xc4, 0xa7, 0xb0, 0x22, 0x58, 0xc8, 0x05, 0x95, 0x8e, 0xd9, 0x30, 0x9b, + 0xd5, 0xf6, 0x46, 0xeb, 0x7a, 0xc9, 0x96, 0x1f, 0x9c, 0xfa, 0x3a, 0x62, 0x3f, 0x56, 0x87, 0x5d, + 0xea, 0x67, 0xf1, 0xde, 0x57, 0x02, 0x56, 0xee, 0x2c, 0xb6, 0x20, 0xd7, 0x5b, 0xdc, 0x01, 0x4b, + 0xc6, 0x51, 0x12, 0xa8, 0xa1, 0x60, 0xe3, 0xf6, 0x13, 0x00, 0x37, 0xc1, 0x0e, 0xc2, 0x90, 0x0d, + 0x14, 0x17, 0x5d, 0xca, 0x12, 0x15, 0xab, 0x73, 0xc7, 0xd4, 0x41, 0x33, 0x38, 0xde, 0x87, 0xff, + 0x33, 0xec, 0x75, 0x5e, 0x71, 0x49, 0x07, 0xcf, 0x3a, 0xbc, 0x6d, 0x58, 0x9b, 0xe2, 0xfe, 0x07, + 0x92, 0xa9, 0x62, 0x46, 0xa6, 0x98, 0x97, 0x40, 0x79, 0x3c, 0xd8, 0x2d, 0x28, 0x0f, 0x04, 0x3b, + 0xe9, 0x66, 0x7a, 0x8e, 0x2d, 0xac, 0x43, 0x25, 0xce, 0x08, 0xa7, 0x53, 0xe5, 0x36, 0x22, 0x2c, + 0xd1, 0x40, 0x05, 0xe3, 0x41, 0xf4, 0x7b, 0x24, 0x83, 0x8a, 0x8f, 0x99, 0x54, 0xc1, 0xf1, 0x40, + 0x93, 0x36, 0xfd, 0x09, 0xe0, 0x2d, 0x81, 0xb1, 0x77, 0xe4, 0x3d, 0x81, 0xd5, 0x1e, 0x8f, 0x9e, + 0x51, 0xea, 0xb3, 0x4f, 0x43, 0x26, 0x15, 0xde, 0x05, 0xb3, 0xcf, 0x23, 0xdd, 0xb9, 0xda, 0xbe, + 0x31, 0xbd, 0x9a, 0x1e, 0x8f, 0xfc, 0x91, 0xdf, 0x7b, 0x07, 0x76, 0xca, 0xb6, 0x90, 0x7a, 0x13, + 0x96, 0xfb, 0x3c, 0xca, 0x69, 0xa7, 0x06, 0x3e, 0x84, 0x72, 0xba, 0x3f, 0xcd, 0xb9, 0xda, 0xbe, + 0xbd, 0x70, 0xdd, 0xfe, 0x38, 0xd0, 0x7b, 0x09, 0x6b, 0x3d, 0x1e, 0xed, 0x07, 0x2a, 0x3c, 0xcc, + 0x6a, 0xd7, 0xa1, 0x72, 0x3a, 0xb2, 0xbb, 0x54, 0x3a, 0xa4, 0x61, 0x36, 0x2d, 0x3f, 0xb7, 0xd1, + 0x05, 0x18, 0x26, 0xb9, 0xd7, 0xd0, 0xde, 0x02, 0xe2, 0x7d, 0x26, 0x7a, 0x48, 0x5d, 0xaf, 0x73, + 0xc2, 0x92, 0x45, 0x4c, 0x0b, 0x97, 0x69, 0xfc, 0xdb, 0x65, 0xe2, 0x3d, 0x58, 0x66, 0x42, 0x70, + 0xa1, 0xf5, 0x9f, 0xa3, 0x5b, 0x47, 0x08, 0x3f, 0x8d, 0xf0, 0x1e, 0x83, 0xd9, 0x11, 0x02, 0x5b, + 0x59, 0xc6, 0x88, 0x42, 0xad, 0xed, 0xcc, 0xc9, 0xd8, 0xe1, 0x94, 0xc9, 0x71, 0xda, 0xe6, 0x7b, + 0xa8, 0x64, 0x10, 0xd6, 0x00, 0xde, 0x24, 0xec, 0x6c, 0xc0, 0x42, 0xc5, 0xa8, 0x5d, 0xc2, 0x55, + 0xb0, 0x7a, 0x3c, 0xea, 0x9c, 0xc5, 0x52, 0x49, 0x9b, 0xe0, 0x1a, 0x54, 0x7b, 0x3c, 0xda, 0xe5, + 0xea, 0x05, 0x1f, 0x26, 0xd4, 0x36, 0x10, 0xa1, 0x96, 0xd2, 0xde, 0xe1, 0xc9, 0x41, 0x3f, 0x0e, + 0x95, 0x6d, 0xa2, 0x0d, 0xd5, 0xce, 0xa8, 0xf0, 0xde, 0xc1, 0x81, 0x64, 0xca, 0xfe, 0x65, 0xb6, + 0x7f, 0x12, 0xb0, 0x76, 0x32, 0x12, 0xb8, 0x0d, 0xe5, 0xf4, 0x30, 0x70, 0x7d, 0xce, 0x11, 0x4c, + 0xb6, 0x5e, 0xc7, 0x69, 0xf7, 0xde, 0x11, 0xee, 0x82, 0x95, 0x5f, 0x07, 0x36, 0x66, 0x54, 0x9c, + 0x3a, 0x9c, 0xfa, 0xdf, 0x74, 0xc6, 0x5d, 0xa8, 0x64, 0x0b, 0xc4, 0x8d, 0x39, 0x74, 0x8a, 0xa7, + 0x52, 0x5f, 0x5f, 0x14, 0xa0, 0x77, 0xdf, 0x24, 0x0f, 0xc8, 0xf3, 0xf6, 0xb7, 0x4b, 0x97, 0x5c, + 0x5c, 0xba, 0xe4, 0xc7, 0xa5, 0x4b, 0xbe, 0x5c, 0xb9, 0xa5, 0x8b, 0x2b, 0xb7, 0xf4, 0xfd, 0xca, + 0x2d, 0xbd, 0x75, 0x16, 0x7d, 0x0f, 0x3f, 0x94, 0xf5, 0xdf, 0xa3, 0xdf, 0x01, 0x00, 0x00, 0xff, + 0xff, 0xa3, 0xfa, 0x07, 0x78, 0x32, 0x05, 0x00, 0x00, } func (m *Log) Marshal() (dAtA []byte, err error) { @@ -1215,14 +1215,14 @@ func (m *LogWatchRequest) Size() (n int) { var l int _ = l if len(m.WatchIds) > 0 { - for _, b := range m.WatchIds { - l = len(b) + for _, s := range m.WatchIds { + l = len(s) n += 1 + l + sovConsensus(uint64(l)) } } if len(m.UnwatchIds) > 0 { - for _, b := range m.UnwatchIds { - l = len(b) + for _, s := range m.UnwatchIds { + l = len(s) n += 1 + l + sovConsensus(uint64(l)) } } @@ -1303,7 +1303,7 @@ func (m *Log) Unmarshal(dAtA []byte) error { if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) } - var byteLen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowConsensus @@ -1313,25 +1313,23 @@ func (m *Log) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthConsensus } - postIndex := iNdEx + byteLen + postIndex := iNdEx + intStringLen 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{} - } + m.Id = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { @@ -2062,7 +2060,7 @@ func (m *RecordAddRequest) Unmarshal(dAtA []byte) error { if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field LogId", wireType) } - var byteLen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowConsensus @@ -2072,25 +2070,23 @@ func (m *RecordAddRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthConsensus } - postIndex := iNdEx + byteLen + postIndex := iNdEx + intStringLen 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{} - } + m.LogId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { @@ -2182,7 +2178,7 @@ func (m *LogWatchRequest) Unmarshal(dAtA []byte) error { if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field WatchIds", wireType) } - var byteLen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowConsensus @@ -2192,29 +2188,29 @@ func (m *LogWatchRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthConsensus } - postIndex := iNdEx + byteLen + postIndex := iNdEx + intStringLen 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]) + m.WatchIds = append(m.WatchIds, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field UnwatchIds", wireType) } - var byteLen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowConsensus @@ -2224,23 +2220,23 @@ func (m *LogWatchRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthConsensus } - postIndex := iNdEx + byteLen + postIndex := iNdEx + intStringLen 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]) + m.UnwatchIds = append(m.UnwatchIds, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -2296,7 +2292,7 @@ func (m *LogWatchEvent) Unmarshal(dAtA []byte) error { if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field LogId", wireType) } - var byteLen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowConsensus @@ -2306,25 +2302,23 @@ func (m *LogWatchEvent) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthConsensus } - postIndex := iNdEx + byteLen + postIndex := iNdEx + intStringLen 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{} - } + m.LogId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { diff --git a/consensus/consensusproto/protos/consensus.proto b/consensus/consensusproto/protos/consensus.proto index 55918519..716ddcba 100644 --- a/consensus/consensusproto/protos/consensus.proto +++ b/consensus/consensusproto/protos/consensus.proto @@ -13,7 +13,7 @@ enum ErrCodes { message Log { - bytes id = 1; + string id = 1; bytes payload = 2; repeated RawRecordWithId records = 3; } @@ -57,17 +57,17 @@ message LogAddRequest { } message RecordAddRequest { - bytes logId = 1; + string logId = 1; RawRecord record = 2; } message LogWatchRequest { - repeated bytes watchIds = 1; - repeated bytes unwatchIds = 2; + repeated string watchIds = 1; + repeated string unwatchIds = 2; } message LogWatchEvent { - bytes logId = 1; + string logId = 1; repeated RawRecordWithId records = 2; Err error = 3; } From 0c1d752acf2aabd3fa51d76dc3f900737cf056ff Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Mon, 3 Jul 2023 17:36:31 +0200 Subject: [PATCH 106/123] consensus: err forbidden --- consensus/consensusproto/consensus.pb.go | 84 ++++++++++--------- .../consensusproto/consensuserr/errors.go | 1 + .../consensusproto/protos/consensus.proto | 1 + 3 files changed, 46 insertions(+), 40 deletions(-) diff --git a/consensus/consensusproto/consensus.pb.go b/consensus/consensusproto/consensus.pb.go index d99079b5..a4f55d18 100644 --- a/consensus/consensusproto/consensus.pb.go +++ b/consensus/consensusproto/consensus.pb.go @@ -29,6 +29,7 @@ const ( ErrCodes_LogExists ErrCodes = 1 ErrCodes_LogNotFound ErrCodes = 2 ErrCodes_RecordConflict ErrCodes = 3 + ErrCodes_Forbidden ErrCodes = 4 ErrCodes_ErrorOffset ErrCodes = 500 ) @@ -37,6 +38,7 @@ var ErrCodes_name = map[int32]string{ 1: "LogExists", 2: "LogNotFound", 3: "RecordConflict", + 4: "Forbidden", 500: "ErrorOffset", } @@ -45,6 +47,7 @@ var ErrCodes_value = map[string]int32{ "LogExists": 1, "LogNotFound": 2, "RecordConflict": 3, + "Forbidden": 4, "ErrorOffset": 500, } @@ -614,46 +617,47 @@ func init() { } var fileDescriptor_b8d7f1c16b400059 = []byte{ - // 617 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xcb, 0x6e, 0xd3, 0x4c, - 0x14, 0xce, 0xd8, 0x6d, 0x1a, 0x9f, 0xfc, 0x4d, 0xfd, 0x1f, 0x10, 0x32, 0x11, 0x75, 0x23, 0x4b, - 0x48, 0xa1, 0x42, 0x29, 0x04, 0x81, 0x84, 0xba, 0x82, 0x2a, 0x48, 0x91, 0x42, 0x8b, 0x8c, 0x50, - 0x25, 0xd8, 0x60, 0x3c, 0x53, 0xd7, 0x34, 0xf5, 0x84, 0x99, 0x49, 0x2f, 0xcf, 0xc0, 0x86, 0x17, - 0xe0, 0x7d, 0x58, 0x76, 0xc9, 0x12, 0xb5, 0x1b, 0x1e, 0x80, 0x07, 0x40, 0x19, 0xc7, 0x8e, 0x9b, - 0x0b, 0x88, 0x4d, 0x32, 0xe7, 0x3b, 0xb7, 0xef, 0x7c, 0xe7, 0xc8, 0xb0, 0x15, 0xf2, 0x44, 0xb2, - 0x44, 0x0e, 0xe5, 0xe4, 0x35, 0x10, 0x5c, 0xf1, 0x2d, 0xfd, 0x5b, 0x40, 0x5b, 0x1a, 0xc0, 0x5a, - 0x0e, 0xbc, 0x1a, 0xd9, 0xde, 0x47, 0x30, 0x7b, 0x3c, 0xc2, 0x1a, 0x18, 0x31, 0x75, 0x48, 0x83, - 0x34, 0x2d, 0xdf, 0x88, 0x29, 0x3a, 0xb0, 0x32, 0x08, 0xce, 0xfb, 0x3c, 0xa0, 0x8e, 0xd1, 0x20, - 0xcd, 0xff, 0xfc, 0xcc, 0xc4, 0xa7, 0xb0, 0x22, 0x58, 0xc8, 0x05, 0x95, 0x8e, 0xd9, 0x30, 0x9b, - 0xd5, 0xf6, 0x46, 0xeb, 0x7a, 0xc9, 0x96, 0x1f, 0x9c, 0xfa, 0x3a, 0x62, 0x3f, 0x56, 0x87, 0x5d, - 0xea, 0x67, 0xf1, 0xde, 0x57, 0x02, 0x56, 0xee, 0x2c, 0xb6, 0x20, 0xd7, 0x5b, 0xdc, 0x01, 0x4b, - 0xc6, 0x51, 0x12, 0xa8, 0xa1, 0x60, 0xe3, 0xf6, 0x13, 0x00, 0x37, 0xc1, 0x0e, 0xc2, 0x90, 0x0d, - 0x14, 0x17, 0x5d, 0xca, 0x12, 0x15, 0xab, 0x73, 0xc7, 0xd4, 0x41, 0x33, 0x38, 0xde, 0x87, 0xff, - 0x33, 0xec, 0x75, 0x5e, 0x71, 0x49, 0x07, 0xcf, 0x3a, 0xbc, 0x6d, 0x58, 0x9b, 0xe2, 0xfe, 0x07, - 0x92, 0xa9, 0x62, 0x46, 0xa6, 0x98, 0x97, 0x40, 0x79, 0x3c, 0xd8, 0x2d, 0x28, 0x0f, 0x04, 0x3b, - 0xe9, 0x66, 0x7a, 0x8e, 0x2d, 0xac, 0x43, 0x25, 0xce, 0x08, 0xa7, 0x53, 0xe5, 0x36, 0x22, 0x2c, - 0xd1, 0x40, 0x05, 0xe3, 0x41, 0xf4, 0x7b, 0x24, 0x83, 0x8a, 0x8f, 0x99, 0x54, 0xc1, 0xf1, 0x40, - 0x93, 0x36, 0xfd, 0x09, 0xe0, 0x2d, 0x81, 0xb1, 0x77, 0xe4, 0x3d, 0x81, 0xd5, 0x1e, 0x8f, 0x9e, - 0x51, 0xea, 0xb3, 0x4f, 0x43, 0x26, 0x15, 0xde, 0x05, 0xb3, 0xcf, 0x23, 0xdd, 0xb9, 0xda, 0xbe, - 0x31, 0xbd, 0x9a, 0x1e, 0x8f, 0xfc, 0x91, 0xdf, 0x7b, 0x07, 0x76, 0xca, 0xb6, 0x90, 0x7a, 0x13, - 0x96, 0xfb, 0x3c, 0xca, 0x69, 0xa7, 0x06, 0x3e, 0x84, 0x72, 0xba, 0x3f, 0xcd, 0xb9, 0xda, 0xbe, - 0xbd, 0x70, 0xdd, 0xfe, 0x38, 0xd0, 0x7b, 0x09, 0x6b, 0x3d, 0x1e, 0xed, 0x07, 0x2a, 0x3c, 0xcc, - 0x6a, 0xd7, 0xa1, 0x72, 0x3a, 0xb2, 0xbb, 0x54, 0x3a, 0xa4, 0x61, 0x36, 0x2d, 0x3f, 0xb7, 0xd1, - 0x05, 0x18, 0x26, 0xb9, 0xd7, 0xd0, 0xde, 0x02, 0xe2, 0x7d, 0x26, 0x7a, 0x48, 0x5d, 0xaf, 0x73, - 0xc2, 0x92, 0x45, 0x4c, 0x0b, 0x97, 0x69, 0xfc, 0xdb, 0x65, 0xe2, 0x3d, 0x58, 0x66, 0x42, 0x70, - 0xa1, 0xf5, 0x9f, 0xa3, 0x5b, 0x47, 0x08, 0x3f, 0x8d, 0xf0, 0x1e, 0x83, 0xd9, 0x11, 0x02, 0x5b, - 0x59, 0xc6, 0x88, 0x42, 0xad, 0xed, 0xcc, 0xc9, 0xd8, 0xe1, 0x94, 0xc9, 0x71, 0xda, 0xe6, 0x7b, - 0xa8, 0x64, 0x10, 0xd6, 0x00, 0xde, 0x24, 0xec, 0x6c, 0xc0, 0x42, 0xc5, 0xa8, 0x5d, 0xc2, 0x55, - 0xb0, 0x7a, 0x3c, 0xea, 0x9c, 0xc5, 0x52, 0x49, 0x9b, 0xe0, 0x1a, 0x54, 0x7b, 0x3c, 0xda, 0xe5, - 0xea, 0x05, 0x1f, 0x26, 0xd4, 0x36, 0x10, 0xa1, 0x96, 0xd2, 0xde, 0xe1, 0xc9, 0x41, 0x3f, 0x0e, - 0x95, 0x6d, 0xa2, 0x0d, 0xd5, 0xce, 0xa8, 0xf0, 0xde, 0xc1, 0x81, 0x64, 0xca, 0xfe, 0x65, 0xb6, - 0x7f, 0x12, 0xb0, 0x76, 0x32, 0x12, 0xb8, 0x0d, 0xe5, 0xf4, 0x30, 0x70, 0x7d, 0xce, 0x11, 0x4c, - 0xb6, 0x5e, 0xc7, 0x69, 0xf7, 0xde, 0x11, 0xee, 0x82, 0x95, 0x5f, 0x07, 0x36, 0x66, 0x54, 0x9c, - 0x3a, 0x9c, 0xfa, 0xdf, 0x74, 0xc6, 0x5d, 0xa8, 0x64, 0x0b, 0xc4, 0x8d, 0x39, 0x74, 0x8a, 0xa7, - 0x52, 0x5f, 0x5f, 0x14, 0xa0, 0x77, 0xdf, 0x24, 0x0f, 0xc8, 0xf3, 0xf6, 0xb7, 0x4b, 0x97, 0x5c, - 0x5c, 0xba, 0xe4, 0xc7, 0xa5, 0x4b, 0xbe, 0x5c, 0xb9, 0xa5, 0x8b, 0x2b, 0xb7, 0xf4, 0xfd, 0xca, - 0x2d, 0xbd, 0x75, 0x16, 0x7d, 0x0f, 0x3f, 0x94, 0xf5, 0xdf, 0xa3, 0xdf, 0x01, 0x00, 0x00, 0xff, - 0xff, 0xa3, 0xfa, 0x07, 0x78, 0x32, 0x05, 0x00, 0x00, + // 626 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xcd, 0x6e, 0xd3, 0x40, + 0x10, 0xce, 0xda, 0x69, 0x1a, 0x4f, 0x68, 0x6a, 0x06, 0x84, 0x4c, 0x44, 0xdd, 0xc8, 0x12, 0x52, + 0xa8, 0x50, 0x0a, 0x41, 0x20, 0xa1, 0x9e, 0xa0, 0x4a, 0xa5, 0x48, 0xa1, 0x45, 0x46, 0xa8, 0x12, + 0x9c, 0x5c, 0xef, 0xd6, 0x35, 0x4d, 0xbd, 0x61, 0xbd, 0xe9, 0xcf, 0x33, 0x70, 0xe1, 0x05, 0x78, + 0x1f, 0x8e, 0x3d, 0x72, 0x44, 0xed, 0x85, 0x07, 0xe0, 0x01, 0x90, 0xd7, 0xb1, 0xe3, 0xe6, 0x07, + 0xc4, 0x25, 0xd9, 0xf9, 0x66, 0x66, 0xe7, 0xdb, 0x6f, 0x3e, 0x19, 0x36, 0x7d, 0x1e, 0xc5, 0x2c, + 0x8a, 0x47, 0xf1, 0xe4, 0x34, 0x14, 0x5c, 0xf2, 0x4d, 0xf5, 0x5b, 0x40, 0xdb, 0x0a, 0xc0, 0x7a, + 0x0e, 0xbc, 0x4d, 0x62, 0xe7, 0x13, 0xe8, 0x7d, 0x1e, 0x60, 0x1d, 0xb4, 0x90, 0x5a, 0xa4, 0x49, + 0x5a, 0x86, 0xab, 0x85, 0x14, 0x2d, 0x58, 0x1e, 0x7a, 0x17, 0x03, 0xee, 0x51, 0x4b, 0x6b, 0x92, + 0xd6, 0x2d, 0x37, 0x0b, 0xf1, 0x25, 0x2c, 0x0b, 0xe6, 0x73, 0x41, 0x63, 0x4b, 0x6f, 0xea, 0xad, + 0x5a, 0x67, 0xbd, 0x7d, 0xf3, 0xca, 0xb6, 0xeb, 0x9d, 0xb9, 0xaa, 0x62, 0x3f, 0x94, 0x47, 0x3d, + 0xea, 0x66, 0xf5, 0xce, 0x37, 0x02, 0x46, 0x9e, 0x2c, 0x8e, 0x20, 0x37, 0x47, 0x3c, 0x00, 0x23, + 0x0e, 0x83, 0xc8, 0x93, 0x23, 0xc1, 0xc6, 0xe3, 0x27, 0x00, 0x6e, 0x80, 0xe9, 0xf9, 0x3e, 0x1b, + 0x4a, 0x2e, 0x7a, 0x94, 0x45, 0x32, 0x94, 0x17, 0x96, 0xae, 0x8a, 0x66, 0x70, 0x7c, 0x0c, 0xb7, + 0x33, 0xec, 0x5d, 0x7e, 0x63, 0x59, 0x15, 0xcf, 0x26, 0x9c, 0x2d, 0x58, 0x9d, 0xe2, 0xfe, 0x17, + 0x92, 0xa9, 0x62, 0x5a, 0xa6, 0x98, 0x13, 0x41, 0x65, 0xfc, 0xb0, 0x7b, 0x50, 0x19, 0x0a, 0x76, + 0xda, 0xcb, 0xf4, 0x1c, 0x47, 0xd8, 0x80, 0x6a, 0x98, 0x11, 0x4e, 0x5f, 0x95, 0xc7, 0x88, 0x50, + 0xa6, 0x9e, 0xf4, 0xc6, 0x0f, 0x51, 0xe7, 0x44, 0x06, 0x19, 0x9e, 0xb0, 0x58, 0x7a, 0x27, 0x43, + 0x45, 0x5a, 0x77, 0x27, 0x80, 0x53, 0x06, 0x6d, 0xef, 0xd8, 0x79, 0x01, 0x2b, 0x7d, 0x1e, 0xbc, + 0xa2, 0xd4, 0x65, 0x9f, 0x47, 0x2c, 0x96, 0xf8, 0x10, 0xf4, 0x01, 0x0f, 0xd4, 0xe4, 0x5a, 0xe7, + 0xce, 0xf4, 0x6a, 0xfa, 0x3c, 0x70, 0x93, 0xbc, 0xf3, 0x11, 0xcc, 0x94, 0x6d, 0xa1, 0xf5, 0x2e, + 0x2c, 0x0d, 0x78, 0x90, 0xd3, 0x4e, 0x03, 0x7c, 0x0a, 0x95, 0x74, 0x7f, 0x8a, 0x73, 0xad, 0x73, + 0x7f, 0xe1, 0xba, 0xdd, 0x71, 0xa1, 0xf3, 0x06, 0x56, 0xfb, 0x3c, 0xd8, 0xf7, 0xa4, 0x7f, 0x94, + 0xdd, 0xdd, 0x80, 0xea, 0x59, 0x12, 0xf7, 0x68, 0x6c, 0x91, 0xa6, 0xde, 0x32, 0xdc, 0x3c, 0x46, + 0x1b, 0x60, 0x14, 0xe5, 0x59, 0x4d, 0x65, 0x0b, 0x88, 0xf3, 0x85, 0xa8, 0x47, 0xaa, 0xfb, 0xba, + 0xa7, 0x2c, 0x5a, 0xc4, 0xb4, 0xe0, 0x4c, 0xed, 0xff, 0x9c, 0x89, 0x8f, 0x60, 0x89, 0x09, 0xc1, + 0x85, 0xd2, 0x7f, 0x8e, 0x6e, 0x5d, 0x21, 0xdc, 0xb4, 0xc2, 0x79, 0x0e, 0x7a, 0x57, 0x08, 0x6c, + 0x67, 0x1d, 0x09, 0x85, 0x7a, 0xc7, 0x9a, 0xd3, 0xb1, 0xcd, 0x29, 0x8b, 0xc7, 0x6d, 0x1b, 0x1c, + 0xaa, 0x19, 0x84, 0x75, 0x80, 0xf7, 0x11, 0x3b, 0x1f, 0x32, 0x5f, 0x32, 0x6a, 0x96, 0x70, 0x05, + 0x8c, 0x3e, 0x0f, 0xba, 0xe7, 0x61, 0x2c, 0x63, 0x93, 0xe0, 0x2a, 0xd4, 0xfa, 0x3c, 0xd8, 0xe5, + 0x72, 0x87, 0x8f, 0x22, 0x6a, 0x6a, 0x88, 0x50, 0x4f, 0x69, 0x6f, 0xf3, 0xe8, 0x70, 0x10, 0xfa, + 0xd2, 0xd4, 0x93, 0x9e, 0x1d, 0x2e, 0x0e, 0x42, 0x4a, 0x59, 0x64, 0x96, 0xd1, 0x84, 0x5a, 0x37, + 0x99, 0xb3, 0x77, 0x78, 0x18, 0x33, 0x69, 0xfe, 0xd6, 0x3b, 0xbf, 0x08, 0x18, 0xdb, 0x19, 0x27, + 0xdc, 0x82, 0x4a, 0xea, 0x13, 0x5c, 0x9b, 0xe3, 0x89, 0x89, 0x09, 0x1a, 0x38, 0x9d, 0xde, 0x3b, + 0xc6, 0x5d, 0x30, 0x72, 0xb3, 0x60, 0x73, 0x46, 0xd4, 0x29, 0x1f, 0x35, 0xfe, 0x25, 0x3b, 0xee, + 0x42, 0x35, 0xdb, 0x27, 0xae, 0xcf, 0xa1, 0x53, 0x74, 0x4e, 0x63, 0x6d, 0x51, 0x81, 0xb2, 0x42, + 0x8b, 0x3c, 0x21, 0xaf, 0x3b, 0xdf, 0xaf, 0x6c, 0x72, 0x79, 0x65, 0x93, 0x9f, 0x57, 0x36, 0xf9, + 0x7a, 0x6d, 0x97, 0x2e, 0xaf, 0xed, 0xd2, 0x8f, 0x6b, 0xbb, 0xf4, 0xc1, 0x5a, 0xf4, 0x79, 0x3c, + 0xa8, 0xa8, 0xbf, 0x67, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x21, 0x21, 0x57, 0x7a, 0x41, 0x05, + 0x00, 0x00, } func (m *Log) Marshal() (dAtA []byte, err error) { diff --git a/consensus/consensusproto/consensuserr/errors.go b/consensus/consensusproto/consensuserr/errors.go index a7ba9f96..e313b889 100644 --- a/consensus/consensusproto/consensuserr/errors.go +++ b/consensus/consensusproto/consensuserr/errors.go @@ -13,4 +13,5 @@ var ( 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)) + ErrForbidden = errGroup.Register(fmt.Errorf("forbidden"), uint64(consensusproto.ErrCodes_Forbidden)) ) diff --git a/consensus/consensusproto/protos/consensus.proto b/consensus/consensusproto/protos/consensus.proto index 716ddcba..7409704f 100644 --- a/consensus/consensusproto/protos/consensus.proto +++ b/consensus/consensusproto/protos/consensus.proto @@ -8,6 +8,7 @@ enum ErrCodes { LogExists = 1; LogNotFound = 2; RecordConflict = 3; + Forbidden = 4; ErrorOffset = 500; } From bef93d46ad76b28ac1d34b28f2115b106acac926 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Mon, 3 Jul 2023 18:19:23 +0200 Subject: [PATCH 107/123] Implement sync protocol --- commonspace/headsync/diffsyncer.go | 20 +-- commonspace/object/acl/list/list.go | 17 +++ .../object/acl/syncacl/requestfactory.go | 36 +++++- .../object/acl/syncacl/syncaclhandler.go | 2 + consensus/consensusproto/consensus.go | 45 +++++++ consensus/consensusproto/consensus.pb.go | 120 +++++++++--------- .../consensusproto/protos/consensus.proto | 2 +- 7 files changed, 167 insertions(+), 75 deletions(-) create mode 100644 consensus/consensusproto/consensus.go diff --git a/commonspace/headsync/diffsyncer.go b/commonspace/headsync/diffsyncer.go index cbae98f9..98dfa74b 100644 --- a/commonspace/headsync/diffsyncer.go +++ b/commonspace/headsync/diffsyncer.go @@ -143,28 +143,30 @@ func (d *diffSyncer) syncWithPeer(ctx context.Context, p peer.Peer) (err error) totalLen := len(newIds) + len(changedIds) + len(removedIds) // not syncing ids which were removed through settings document missingIds := d.deletionState.Filter(newIds) - prevLen := len(changedIds) - changedIds = slice.DiscardFromSlice(changedIds, func(s string) bool { + existingIds := append(d.deletionState.Filter(removedIds), d.deletionState.Filter(changedIds)...) + d.syncStatus.RemoveAllExcept(p.Id(), existingIds, stateCounter) + + prevExistingLen := len(existingIds) + existingIds = slice.DiscardFromSlice(existingIds, func(s string) bool { return s == syncAclId }) - // if acl head is different - if len(changedIds) < prevLen { + // if we removed acl head from the list + if len(existingIds) < prevExistingLen { if syncErr := d.syncAcl.SyncWithPeer(ctx, p.Id()); syncErr != nil { log.Warn("failed to send acl sync message to peer", zap.String("aclId", syncAclId)) } } - existingIds := append(d.deletionState.Filter(removedIds), d.deletionState.Filter(changedIds)...) - - d.syncStatus.RemoveAllExcept(p.Id(), existingIds, stateCounter) + // treeSyncer should not get acl id, that's why we filter existing ids before err = d.treeSyncer.SyncAll(ctx, p.Id(), existingIds, missingIds) if err != nil { return err } - d.log.Info("sync done:", zap.Int("newIds", len(newIds)), + d.log.Info("sync done:", + zap.Int("newIds", len(newIds)), zap.Int("changedIds", len(changedIds)), zap.Int("removedIds", len(removedIds)), - zap.Int("already deleted ids", totalLen-len(existingIds)-len(missingIds)), + zap.Int("already deleted ids", totalLen-prevExistingLen-len(missingIds)), zap.String("peerId", p.Id()), ) return diff --git a/commonspace/object/acl/list/list.go b/commonspace/object/acl/list/list.go index 42c9fafc..12d3bed8 100644 --- a/commonspace/object/acl/list/list.go +++ b/commonspace/object/acl/list/list.go @@ -46,6 +46,8 @@ type AclList interface { IsAfter(first string, second string) (bool, error) HasHead(head string) bool Head() *AclRecord + + RecordsAfter(ctx context.Context, id string) (records []*consensusproto.RawRecordWithId, err error) Get(id string) (*AclRecord, error) GetIndex(idx int) (*AclRecord, error) Iterate(iterFunc IterFunc) @@ -287,6 +289,21 @@ func (a *aclList) Iterate(iterFunc IterFunc) { } } +func (a *aclList) RecordsAfter(ctx context.Context, id string) (records []*consensusproto.RawRecordWithId, err error) { + recIdx, ok := a.indexes[id] + if !ok { + return nil, ErrNoSuchRecord + } + for i := recIdx + 1; i < len(a.records); i++ { + rawRec, err := a.storage.GetRawRecord(ctx, a.records[i].Id) + if err != nil { + return nil, err + } + records = append(records, rawRec) + } + return +} + func (a *aclList) IterateFrom(startId string, iterFunc IterFunc) { recIdx, ok := a.indexes[startId] if !ok { diff --git a/commonspace/object/acl/syncacl/requestfactory.go b/commonspace/object/acl/syncacl/requestfactory.go index d4b90e4d..6adddb4b 100644 --- a/commonspace/object/acl/syncacl/requestfactory.go +++ b/commonspace/object/acl/syncacl/requestfactory.go @@ -1,6 +1,8 @@ package syncacl import ( + "context" + "github.com/anyproto/any-sync/commonspace/object/acl/list" "github.com/anyproto/any-sync/consensus/consensusproto" ) @@ -11,20 +13,42 @@ type RequestFactory interface { CreateFullSyncResponse(l list.AclList, theirHead string) (*consensusproto.LogSyncMessage, error) } +type requestFactory struct{} + func NewRequestFactory() RequestFactory { return &requestFactory{} } -type requestFactory struct{} - func (r *requestFactory) CreateHeadUpdate(l list.AclList, added []*consensusproto.RawRecordWithId) (msg *consensusproto.LogSyncMessage) { - return + return consensusproto.WrapHeadUpdate(&consensusproto.LogHeadUpdate{ + Head: l.Head().Id, + Records: added, + }, l.Root()) } func (r *requestFactory) CreateFullSyncRequest(l list.AclList, theirHead string) (req *consensusproto.LogSyncMessage, err error) { - return + if !l.HasHead(theirHead) { + return consensusproto.WrapFullRequest(&consensusproto.LogFullSyncRequest{ + Head: l.Head().Id, + }, l.Root()), nil + } + records, err := l.RecordsAfter(context.Background(), theirHead) + if err != nil { + return + } + return consensusproto.WrapFullRequest(&consensusproto.LogFullSyncRequest{ + Head: l.Head().Id, + Records: records, + }, l.Root()), nil } -func (r *requestFactory) CreateFullSyncResponse(l list.AclList, theirHead string) (*consensusproto.LogSyncMessage, error) { - return nil, nil +func (r *requestFactory) CreateFullSyncResponse(l list.AclList, theirHead string) (resp *consensusproto.LogSyncMessage, err error) { + records, err := l.RecordsAfter(context.Background(), theirHead) + if err != nil { + return + } + return consensusproto.WrapFullResponse(&consensusproto.LogFullSyncResponse{ + Head: l.Head().Id, + Records: records, + }, l.Root()), nil } diff --git a/commonspace/object/acl/syncacl/syncaclhandler.go b/commonspace/object/acl/syncacl/syncaclhandler.go index 75e0044c..2d76cc46 100644 --- a/commonspace/object/acl/syncacl/syncaclhandler.go +++ b/commonspace/object/acl/syncacl/syncaclhandler.go @@ -42,6 +42,8 @@ func (s *syncAclHandler) HandleMessage(ctx context.Context, senderId string, mes return } content := unmarshalled.GetContent() + head := consensusproto.GetHead(unmarshalled) + s.syncStatus.HeadsReceive(senderId, s.aclList.Id(), []string{head}) s.aclList.Lock() defer s.aclList.Unlock() switch { diff --git a/consensus/consensusproto/consensus.go b/consensus/consensusproto/consensus.go new file mode 100644 index 00000000..deb0157a --- /dev/null +++ b/consensus/consensusproto/consensus.go @@ -0,0 +1,45 @@ +package consensusproto + +func WrapHeadUpdate(update *LogHeadUpdate, rootRecord *RawRecordWithId) *LogSyncMessage { + return &LogSyncMessage{ + Content: &LogSyncContentValue{ + Value: &LogSyncContentValue_HeadUpdate{HeadUpdate: update}, + }, + Id: rootRecord.Id, + Payload: rootRecord.Payload, + } +} + +func WrapFullRequest(request *LogFullSyncRequest, rootRecord *RawRecordWithId) *LogSyncMessage { + return &LogSyncMessage{ + Content: &LogSyncContentValue{ + Value: &LogSyncContentValue_FullSyncRequest{FullSyncRequest: request}, + }, + Id: rootRecord.Id, + Payload: rootRecord.Payload, + } +} + +func WrapFullResponse(response *LogFullSyncResponse, rootRecord *RawRecordWithId) *LogSyncMessage { + return &LogSyncMessage{ + Content: &LogSyncContentValue{ + Value: &LogSyncContentValue_FullSyncResponse{FullSyncResponse: response}, + }, + Id: rootRecord.Id, + Payload: rootRecord.Payload, + } +} + +func GetHead(msg *LogSyncMessage) (head string) { + content := msg.GetContent() + switch { + case content.GetHeadUpdate() != nil: + return content.GetHeadUpdate().Head + case content.GetFullSyncRequest() != nil: + return content.GetFullSyncRequest().Head + case content.GetFullSyncResponse() != nil: + return content.GetFullSyncResponse().Head + default: + return "" + } +} diff --git a/consensus/consensusproto/consensus.pb.go b/consensus/consensusproto/consensus.pb.go index a419fdc7..cafc4723 100644 --- a/consensus/consensusproto/consensus.pb.go +++ b/consensus/consensusproto/consensus.pb.go @@ -698,7 +698,7 @@ func (*LogSyncContentValue) XXX_OneofWrappers() []interface{} { // LogSyncMessage is a message sent when we are syncing logs type LogSyncMessage struct { Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Payload string `protobuf:"bytes,2,opt,name=payload,proto3" json:"payload,omitempty"` + Payload []byte `protobuf:"bytes,2,opt,name=payload,proto3" json:"payload,omitempty"` Content *LogSyncContentValue `protobuf:"bytes,3,opt,name=content,proto3" json:"content,omitempty"` } @@ -742,11 +742,11 @@ func (m *LogSyncMessage) GetId() string { return "" } -func (m *LogSyncMessage) GetPayload() string { +func (m *LogSyncMessage) GetPayload() []byte { if m != nil { return m.Payload } - return "" + return nil } func (m *LogSyncMessage) GetContent() *LogSyncContentValue { @@ -939,56 +939,56 @@ func init() { } var fileDescriptor_b8d7f1c16b400059 = []byte{ - // 780 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0xcd, 0x4e, 0xe3, 0x56, - 0x14, 0x8e, 0x6d, 0x48, 0xe2, 0x93, 0x92, 0xb8, 0x87, 0xaa, 0x72, 0xa3, 0x12, 0x22, 0x57, 0x95, - 0x52, 0x54, 0x85, 0x36, 0x55, 0x2b, 0x55, 0xa8, 0xaa, 0x4a, 0x14, 0x94, 0x48, 0x21, 0xb4, 0x46, - 0x14, 0xa9, 0x95, 0xaa, 0xba, 0xbe, 0x37, 0xc6, 0x25, 0xf8, 0xba, 0xf6, 0x0d, 0x90, 0x6d, 0xb7, - 0xb3, 0x99, 0x17, 0x98, 0xf7, 0x99, 0x25, 0xcb, 0x59, 0x8e, 0x60, 0x33, 0x0f, 0x30, 0x0f, 0x30, - 0xf2, 0xf5, 0x4f, 0x42, 0x7e, 0x40, 0xa3, 0x61, 0x03, 0x3e, 0xff, 0xdf, 0xf9, 0xce, 0xb9, 0x27, - 0xb0, 0x6b, 0x33, 0x2f, 0xa4, 0x5e, 0x38, 0x0e, 0xa7, 0x5f, 0x7e, 0xc0, 0x38, 0xdb, 0x15, 0x7f, - 0x67, 0xb4, 0x4d, 0xa1, 0xc0, 0x72, 0xa6, 0xf8, 0x35, 0x92, 0x8d, 0x7f, 0x41, 0xe9, 0x33, 0x07, - 0xcb, 0x20, 0xbb, 0x44, 0x97, 0xea, 0x52, 0x43, 0x35, 0x65, 0x97, 0xa0, 0x0e, 0x05, 0xdf, 0x9a, - 0x8c, 0x98, 0x45, 0x74, 0xb9, 0x2e, 0x35, 0x3e, 0x32, 0x53, 0x11, 0x7f, 0x84, 0x42, 0x40, 0x6d, - 0x16, 0x90, 0x50, 0x57, 0xea, 0x4a, 0xa3, 0xd4, 0xda, 0x6e, 0xde, 0x4f, 0xd9, 0x34, 0xad, 0x2b, - 0x53, 0x78, 0x9c, 0xba, 0xfc, 0xac, 0x47, 0xcc, 0xd4, 0xdf, 0x78, 0x21, 0x81, 0x9a, 0x19, 0x67, - 0x4b, 0x48, 0xf7, 0x4b, 0x7c, 0x0e, 0x6a, 0xe8, 0x3a, 0x9e, 0xc5, 0xc7, 0x01, 0x4d, 0xca, 0x4f, - 0x15, 0xb8, 0x03, 0x9a, 0x65, 0xdb, 0xd4, 0xe7, 0x2c, 0xe8, 0x11, 0xea, 0x71, 0x97, 0x4f, 0x74, - 0x45, 0x38, 0x2d, 0xe8, 0xf1, 0x6b, 0xf8, 0x38, 0xd5, 0x1d, 0x67, 0x19, 0xd7, 0x84, 0xf3, 0xa2, - 0xc1, 0xd8, 0x83, 0xca, 0x1c, 0xf6, 0x07, 0x40, 0xc6, 0x8c, 0xc9, 0x29, 0x63, 0x86, 0x07, 0xf9, - 0xa4, 0xb1, 0x4f, 0x21, 0xef, 0x07, 0xf4, 0xb2, 0x97, 0xf2, 0x99, 0x48, 0x58, 0x85, 0xa2, 0x9b, - 0x02, 0x8e, 0xbb, 0xca, 0x64, 0x44, 0x58, 0x23, 0x16, 0xb7, 0x92, 0x46, 0xc4, 0x77, 0x44, 0x03, - 0x77, 0x2f, 0x68, 0xc8, 0xad, 0x0b, 0x5f, 0x80, 0x56, 0xcc, 0xa9, 0xc2, 0x58, 0x03, 0xf9, 0xe8, - 0xdc, 0xf8, 0x01, 0x36, 0xfa, 0xcc, 0xf9, 0x85, 0x10, 0x93, 0xfe, 0x37, 0xa6, 0x21, 0xc7, 0x2f, - 0x41, 0x19, 0x31, 0x47, 0x54, 0x2e, 0xb5, 0x36, 0xe7, 0x47, 0xd3, 0x67, 0x8e, 0x19, 0xd9, 0x8d, - 0x3f, 0x41, 0x8b, 0xd1, 0xce, 0x84, 0x7e, 0x02, 0xeb, 0x23, 0xe6, 0x64, 0xb0, 0x63, 0x01, 0xbf, - 0x85, 0x7c, 0x3c, 0x3f, 0x81, 0xb9, 0xd4, 0xfa, 0x6c, 0xe5, 0xb8, 0xcd, 0xc4, 0xd1, 0x38, 0x84, - 0x4a, 0x9f, 0x39, 0xa7, 0x16, 0xb7, 0xcf, 0xd2, 0xdc, 0x55, 0x28, 0x5e, 0x45, 0x72, 0x8f, 0x84, - 0xba, 0x54, 0x57, 0x1a, 0xaa, 0x99, 0xc9, 0x58, 0x03, 0x18, 0x7b, 0x99, 0x55, 0x16, 0xd6, 0x19, - 0x8d, 0xf1, 0x4c, 0x12, 0x4d, 0x8a, 0x7c, 0x9d, 0x4b, 0xea, 0xad, 0x42, 0x3a, 0xb3, 0x99, 0xf2, - 0xfb, 0x6d, 0x26, 0x7e, 0x05, 0xeb, 0x34, 0x08, 0x58, 0x20, 0xf8, 0x5f, 0xc2, 0x5b, 0x27, 0x08, - 0xcc, 0xd8, 0xc3, 0xf8, 0x1e, 0x94, 0x4e, 0x10, 0x60, 0x33, 0x8d, 0x88, 0x20, 0x94, 0x5b, 0xfa, - 0x92, 0x88, 0x36, 0x23, 0x34, 0x4c, 0xc3, 0xfe, 0x97, 0x61, 0xb3, 0xcf, 0x9c, 0xe3, 0x89, 0x67, - 0xb7, 0x99, 0xc7, 0xa9, 0xc7, 0x7f, 0xb7, 0x46, 0x63, 0x8a, 0x3f, 0x03, 0x9c, 0x51, 0x8b, 0x9c, - 0xf8, 0xc4, 0xe2, 0x34, 0x19, 0xdb, 0xd6, 0x92, 0xb1, 0x75, 0x33, 0xa7, 0x6e, 0xce, 0x9c, 0x09, - 0xc1, 0x01, 0x54, 0x86, 0xe3, 0xd1, 0x28, 0x4a, 0x9c, 0x90, 0x9d, 0x0c, 0xca, 0x58, 0x92, 0xe5, - 0xe0, 0xbe, 0x67, 0x37, 0x67, 0xce, 0x07, 0xe3, 0x6f, 0xa0, 0x4d, 0x55, 0xa1, 0x1f, 0xa5, 0x48, - 0x58, 0xf9, 0xe2, 0xc1, 0x84, 0xb1, 0x6b, 0x37, 0x67, 0x2e, 0x84, 0xef, 0x17, 0x60, 0xfd, 0x32, - 0x6a, 0xd6, 0x98, 0x40, 0x39, 0xe1, 0xe0, 0x90, 0x86, 0xa1, 0xe5, 0xd0, 0xc7, 0xee, 0x8e, 0x3a, - 0x7d, 0x6f, 0x3f, 0x41, 0xc1, 0x8e, 0x89, 0x7b, 0x00, 0xce, 0x3c, 0xbd, 0x66, 0x1a, 0x63, 0xfc, - 0x25, 0x76, 0x68, 0xca, 0x62, 0xf4, 0xe2, 0x22, 0x16, 0x93, 0xda, 0xe2, 0xfb, 0x03, 0x36, 0xc8, - 0xb0, 0x01, 0x17, 0xf9, 0x7d, 0xea, 0x22, 0x44, 0xec, 0xd0, 0x3c, 0xe7, 0x4f, 0x5c, 0x65, 0xe7, - 0x6f, 0x28, 0xa6, 0xdb, 0x8b, 0x65, 0x80, 0x13, 0x8f, 0x5e, 0xfb, 0xd4, 0xe6, 0x94, 0x68, 0x39, - 0xdc, 0x00, 0xb5, 0xcf, 0x9c, 0xce, 0xb5, 0x1b, 0xf2, 0x50, 0x93, 0xb0, 0x02, 0xa5, 0x3e, 0x73, - 0x06, 0x8c, 0x1f, 0xb0, 0xb1, 0x47, 0x34, 0x19, 0x11, 0xca, 0x71, 0xd2, 0x36, 0xf3, 0x86, 0x23, - 0xd7, 0xe6, 0x9a, 0x82, 0x1a, 0x94, 0x3a, 0xd1, 0x1b, 0x38, 0x1a, 0x0e, 0x43, 0xca, 0xb5, 0xb7, - 0x4a, 0xeb, 0x8d, 0x04, 0x6a, 0x3b, 0x45, 0x83, 0x7b, 0x90, 0x8f, 0x6f, 0x18, 0x2e, 0x5b, 0xfc, - 0xe9, 0x81, 0xaa, 0xe2, 0xbc, 0xf9, 0xe8, 0x1c, 0x07, 0xa0, 0x66, 0x87, 0x0c, 0xeb, 0x0b, 0x3d, - 0xce, 0xdd, 0xb8, 0xea, 0x63, 0x2c, 0xe0, 0x00, 0x8a, 0xe9, 0xad, 0xc1, 0xed, 0x25, 0x70, 0x66, - 0xaf, 0x5a, 0x75, 0x6b, 0x95, 0x83, 0x38, 0x53, 0x0d, 0xe9, 0x1b, 0x69, 0xbf, 0xf5, 0xf2, 0xb6, - 0x26, 0xdd, 0xdc, 0xd6, 0xa4, 0xd7, 0xb7, 0x35, 0xe9, 0xf9, 0x5d, 0x2d, 0x77, 0x73, 0x57, 0xcb, - 0xbd, 0xba, 0xab, 0xe5, 0xfe, 0xd0, 0x57, 0xfd, 0x74, 0xff, 0x93, 0x17, 0xff, 0xbe, 0x7b, 0x17, - 0x00, 0x00, 0xff, 0xff, 0x5e, 0x57, 0x8e, 0x0b, 0xdd, 0x07, 0x00, 0x00, + // 778 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0x5f, 0x4f, 0xdb, 0x56, + 0x14, 0x8f, 0x6d, 0xc8, 0x9f, 0x93, 0x91, 0x78, 0x87, 0x69, 0xf2, 0xa2, 0x11, 0x22, 0x4f, 0x93, + 0x32, 0x34, 0x85, 0x2d, 0xd3, 0x26, 0x4d, 0x68, 0x9a, 0x46, 0x14, 0x94, 0x48, 0x21, 0x6c, 0x46, + 0x0c, 0xa9, 0x95, 0xaa, 0xba, 0xbe, 0x37, 0xc6, 0x25, 0xf8, 0xba, 0xf6, 0x0d, 0x90, 0xd7, 0xbe, + 0xf6, 0xa5, 0x5f, 0xa0, 0xdf, 0xa7, 0x8f, 0x3c, 0xf6, 0xb1, 0x82, 0x97, 0x7e, 0x80, 0x7e, 0x80, + 0xca, 0xd7, 0x7f, 0x12, 0xf2, 0x87, 0x0a, 0x95, 0x17, 0xb8, 0xe7, 0xff, 0xef, 0xfc, 0xce, 0xf1, + 0x09, 0x6c, 0x5b, 0xcc, 0x0d, 0xa8, 0x1b, 0x8c, 0x82, 0xc9, 0xcb, 0xf3, 0x19, 0x67, 0xdb, 0xe2, + 0xef, 0x94, 0xb6, 0x21, 0x14, 0x58, 0x4a, 0x15, 0xff, 0x86, 0xb2, 0xfe, 0x1c, 0x94, 0x1e, 0xb3, + 0xb1, 0x04, 0xb2, 0x43, 0x34, 0xa9, 0x26, 0xd5, 0x0b, 0x86, 0xec, 0x10, 0xd4, 0x20, 0xe7, 0x99, + 0xe3, 0x21, 0x33, 0x89, 0x26, 0xd7, 0xa4, 0xfa, 0x57, 0x46, 0x22, 0xe2, 0x9f, 0x90, 0xf3, 0xa9, + 0xc5, 0x7c, 0x12, 0x68, 0x4a, 0x4d, 0xa9, 0x17, 0x9b, 0x9b, 0x8d, 0xdb, 0x29, 0x1b, 0x86, 0x79, + 0x61, 0x08, 0x8f, 0x63, 0x87, 0x9f, 0x74, 0x89, 0x91, 0xf8, 0xeb, 0x6f, 0x24, 0x28, 0xa4, 0xc6, + 0xe9, 0x12, 0xd2, 0xed, 0x12, 0xdf, 0x43, 0x21, 0x70, 0x6c, 0xd7, 0xe4, 0x23, 0x9f, 0xc6, 0xe5, + 0x27, 0x0a, 0xdc, 0x02, 0xd5, 0xb4, 0x2c, 0xea, 0x71, 0xe6, 0x77, 0x09, 0x75, 0xb9, 0xc3, 0xc7, + 0x9a, 0x22, 0x9c, 0xe6, 0xf4, 0xf8, 0x33, 0x7c, 0x9d, 0xe8, 0x0e, 0xd3, 0x8c, 0x2b, 0xc2, 0x79, + 0xde, 0xa0, 0xef, 0x40, 0x79, 0x06, 0xfb, 0x1d, 0x20, 0x23, 0xc6, 0xe4, 0x84, 0x31, 0xdd, 0x85, + 0x6c, 0xdc, 0xd8, 0xb7, 0x90, 0xf5, 0x7c, 0x7a, 0xde, 0x4d, 0xf8, 0x8c, 0x25, 0xac, 0x40, 0xde, + 0x49, 0x00, 0x47, 0x5d, 0xa5, 0x32, 0x22, 0xac, 0x10, 0x93, 0x9b, 0x71, 0x23, 0xe2, 0x1d, 0xd2, + 0xc0, 0x9d, 0x33, 0x1a, 0x70, 0xf3, 0xcc, 0x13, 0xa0, 0x15, 0x63, 0xa2, 0xd0, 0x57, 0x40, 0x3e, + 0x38, 0xd5, 0xff, 0x80, 0xb5, 0x1e, 0xb3, 0xff, 0x21, 0xc4, 0xa0, 0x2f, 0x46, 0x34, 0xe0, 0xf8, + 0x23, 0x28, 0x43, 0x66, 0x8b, 0xca, 0xc5, 0xe6, 0xfa, 0xec, 0x68, 0x7a, 0xcc, 0x36, 0x42, 0xbb, + 0xfe, 0x18, 0xd4, 0x08, 0xed, 0x54, 0xe8, 0x37, 0xb0, 0x3a, 0x64, 0x76, 0x0a, 0x3b, 0x12, 0xf0, + 0x57, 0xc8, 0x46, 0xf3, 0x13, 0x98, 0x8b, 0xcd, 0xef, 0x96, 0x8e, 0xdb, 0x88, 0x1d, 0xf5, 0x7d, + 0x28, 0xf7, 0x98, 0x7d, 0x6c, 0x72, 0xeb, 0x24, 0xc9, 0x5d, 0x81, 0xfc, 0x45, 0x28, 0x77, 0x49, + 0xa0, 0x49, 0x35, 0xa5, 0x5e, 0x30, 0x52, 0x19, 0xab, 0x00, 0x23, 0x37, 0xb5, 0xca, 0xc2, 0x3a, + 0xa5, 0xd1, 0x5f, 0x49, 0xa2, 0x49, 0x91, 0xaf, 0x7d, 0x4e, 0xdd, 0x65, 0x48, 0xa7, 0x36, 0x53, + 0xbe, 0xdf, 0x66, 0xe2, 0x4f, 0xb0, 0x4a, 0x7d, 0x9f, 0xf9, 0x82, 0xff, 0x05, 0xbc, 0xb5, 0x7d, + 0xdf, 0x88, 0x3c, 0xf4, 0xdf, 0x41, 0x69, 0xfb, 0x3e, 0x36, 0x92, 0x88, 0x10, 0x42, 0xa9, 0xa9, + 0x2d, 0x88, 0x68, 0x31, 0x42, 0x83, 0x24, 0xec, 0xa5, 0x0c, 0xeb, 0x3d, 0x66, 0x1f, 0x8e, 0x5d, + 0xab, 0xc5, 0x5c, 0x4e, 0x5d, 0xfe, 0xbf, 0x39, 0x1c, 0x51, 0xfc, 0x1b, 0xe0, 0x84, 0x9a, 0xe4, + 0xc8, 0x23, 0x26, 0xa7, 0xf1, 0xd8, 0x36, 0x16, 0x8c, 0xad, 0x93, 0x3a, 0x75, 0x32, 0xc6, 0x54, + 0x08, 0xf6, 0xa1, 0x3c, 0x18, 0x0d, 0x87, 0x61, 0xe2, 0x98, 0xec, 0x78, 0x50, 0xfa, 0x82, 0x2c, + 0x7b, 0xb7, 0x3d, 0x3b, 0x19, 0x63, 0x36, 0x18, 0xff, 0x03, 0x75, 0xa2, 0x0a, 0xbc, 0x30, 0x45, + 0xcc, 0xca, 0x0f, 0x77, 0x26, 0x8c, 0x5c, 0x3b, 0x19, 0x63, 0x2e, 0x7c, 0x37, 0x07, 0xab, 0xe7, + 0x61, 0xb3, 0xfa, 0x18, 0x4a, 0x31, 0x07, 0xfb, 0x34, 0x08, 0x4c, 0x9b, 0xde, 0xe3, 0xee, 0xfc, + 0x05, 0x39, 0x2b, 0x22, 0xee, 0x0e, 0x38, 0xb3, 0xf4, 0x1a, 0x49, 0x8c, 0xfe, 0x44, 0xec, 0xd0, + 0x84, 0xc5, 0xf0, 0x8b, 0x0b, 0x59, 0x8c, 0x6b, 0x8b, 0xf7, 0x17, 0x6c, 0x90, 0x6e, 0x01, 0xce, + 0xf3, 0xfb, 0xd0, 0x45, 0x88, 0xd8, 0xa1, 0x59, 0xce, 0x1f, 0xb8, 0xca, 0xd6, 0x53, 0xc8, 0x27, + 0xdb, 0x8b, 0x25, 0x80, 0x23, 0x97, 0x5e, 0x7a, 0xd4, 0xe2, 0x94, 0xa8, 0x19, 0x5c, 0x83, 0x42, + 0x8f, 0xd9, 0xed, 0x4b, 0x27, 0xe0, 0x81, 0x2a, 0x61, 0x19, 0x8a, 0x3d, 0x66, 0xf7, 0x19, 0xdf, + 0x63, 0x23, 0x97, 0xa8, 0x32, 0x22, 0x94, 0xa2, 0xa4, 0x2d, 0xe6, 0x0e, 0x86, 0x8e, 0xc5, 0x55, + 0x05, 0x55, 0x28, 0xb6, 0xc3, 0x6f, 0xe0, 0x60, 0x30, 0x08, 0x28, 0x57, 0x3f, 0x2a, 0xcd, 0x0f, + 0x12, 0x14, 0x5a, 0x09, 0x1a, 0xdc, 0x81, 0x6c, 0x74, 0xc3, 0x70, 0xd1, 0xe2, 0x4f, 0x0e, 0x54, + 0x05, 0x67, 0xcd, 0x07, 0xa7, 0xd8, 0x87, 0x42, 0x7a, 0xc8, 0xb0, 0x36, 0xd7, 0xe3, 0xcc, 0x8d, + 0xab, 0x7c, 0x8e, 0x05, 0xec, 0x43, 0x3e, 0xb9, 0x35, 0xb8, 0xb9, 0x00, 0xce, 0xf4, 0x55, 0xab, + 0x6c, 0x2c, 0x73, 0x10, 0x67, 0xaa, 0x2e, 0xfd, 0x22, 0xed, 0x36, 0xdf, 0x5e, 0x57, 0xa5, 0xab, + 0xeb, 0xaa, 0xf4, 0xfe, 0xba, 0x2a, 0xbd, 0xbe, 0xa9, 0x66, 0xae, 0x6e, 0xaa, 0x99, 0x77, 0x37, + 0xd5, 0xcc, 0x23, 0x6d, 0xd9, 0x4f, 0xf7, 0xb3, 0xac, 0xf8, 0xf7, 0xdb, 0xa7, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x9e, 0x4a, 0x75, 0x11, 0xdd, 0x07, 0x00, 0x00, } func (m *Log) Marshal() (dAtA []byte, err error) { @@ -3437,7 +3437,7 @@ func (m *LogSyncMessage) Unmarshal(dAtA []byte) error { if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Payload", wireType) } - var stringLen uint64 + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowConsensus @@ -3447,23 +3447,25 @@ func (m *LogSyncMessage) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if byteLen < 0 { return ErrInvalidLengthConsensus } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthConsensus } if postIndex > l { return io.ErrUnexpectedEOF } - m.Payload = string(dAtA[iNdEx:postIndex]) + m.Payload = append(m.Payload[:0], dAtA[iNdEx:postIndex]...) + if m.Payload == nil { + m.Payload = []byte{} + } iNdEx = postIndex case 3: if wireType != 2 { diff --git a/consensus/consensusproto/protos/consensus.proto b/consensus/consensusproto/protos/consensus.proto index ad88f466..e7fa086d 100644 --- a/consensus/consensusproto/protos/consensus.proto +++ b/consensus/consensusproto/protos/consensus.proto @@ -88,7 +88,7 @@ message LogSyncContentValue { // LogSyncMessage is a message sent when we are syncing logs message LogSyncMessage { string id = 1; - string payload = 2; + bytes payload = 2; LogSyncContentValue content = 3; } From ab34ff4bc92871d3c93493cb97ccba494f74d8eb Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Tue, 4 Jul 2023 08:07:55 +0200 Subject: [PATCH 108/123] Fix not sending correct connection and incoming count --- net/peer/peer.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/peer/peer.go b/net/peer/peer.go index 25ffbb20..d0226823 100644 --- a/net/peer/peer.go +++ b/net/peer/peer.go @@ -189,7 +189,7 @@ func (p *peer) openDrpcConn(ctx context.Context) (dconn *subConn, err error) { tconn := connutil.NewLastUsageConn(conn) bufSize := p.ctrl.DrpcConfig().Stream.MaxMsgSizeMb * (1 << 20) return &subConn{ - Conn: drpcconn.NewWithOptions(conn, drpcconn.Options{ + Conn: drpcconn.NewWithOptions(tconn, drpcconn.Options{ Manager: drpcmanager.Options{ Reader: drpcwire.ReaderOptions{MaximumBufferSize: bufSize}, Stream: drpcstream.Options{MaximumBufferSize: bufSize}, @@ -296,7 +296,7 @@ func (p *peer) gc(ttl time.Duration) (aliveCount int) { continue } } - return len(p.active) + len(p.inactive) + return len(p.active) + len(p.inactive) + int(p.incomingCount.Load()) } func (p *peer) Close() (err error) { From fe31afc3376ecd32925f040c66cb02a532a43829 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Tue, 4 Jul 2023 16:51:14 +0200 Subject: [PATCH 109/123] Remove cancel with deadline --- commonspace/objectsync/objectsync.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/commonspace/objectsync/objectsync.go b/commonspace/objectsync/objectsync.go index f8125aa8..c98bf8db 100644 --- a/commonspace/objectsync/objectsync.go +++ b/commonspace/objectsync/objectsync.go @@ -149,9 +149,6 @@ func (s *objectSync) processHandleMessage(msg HandleMessage) { err = context.DeadlineExceeded return } - var cancel context.CancelFunc - ctx, cancel = context.WithDeadline(ctx, msg.Deadline) - defer cancel() } if err = s.handleMessage(ctx, msg.SenderId, msg.Message); err != nil { if msg.Message.ObjectId != "" { From cd3c6c736a8557f40c668b817522dc5c92a62323 Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Wed, 5 Jul 2023 18:50:14 +0200 Subject: [PATCH 110/123] consensus: remove log payload --- consensus/consensusclient/client.go | 12 +- consensus/consensusclient/client_test.go | 2 +- consensus/consensusproto/consensus.pb.go | 157 ++++++------------ .../consensusproto/protos/consensus.proto | 4 +- 4 files changed, 61 insertions(+), 114 deletions(-) diff --git a/consensus/consensusclient/client.go b/consensus/consensusclient/client.go index 6bf5e8ab..a17c7a83 100644 --- a/consensus/consensusclient/client.go +++ b/consensus/consensusclient/client.go @@ -36,9 +36,9 @@ type Watcher interface { type Service interface { // AddLog adds new log to consensus servers - AddLog(ctx context.Context, clog *consensusproto.Log) (err error) + AddLog(ctx context.Context, rec *consensusproto.RawRecordWithId) (err error) // AddRecord adds new record to consensus servers - AddRecord(ctx context.Context, logId string, clog *consensusproto.RawRecord) (record *consensusproto.RawRecordWithId, err error) + AddRecord(ctx context.Context, logId string, rec *consensusproto.RawRecord) (record *consensusproto.RawRecordWithId, err error) // Watch starts watching to given logId and calls watcher when any relative event received Watch(logId string, w Watcher) (err error) // UnWatch stops watching given logId and removes watcher @@ -86,10 +86,10 @@ func (s *service) doClient(ctx context.Context, fn func(cl consensusproto.DRPCCo return fn(consensusproto.NewDRPCConsensusClient(dc)) } -func (s *service) AddLog(ctx context.Context, clog *consensusproto.Log) (err error) { +func (s *service) AddLog(ctx context.Context, rec *consensusproto.RawRecordWithId) (err error) { return s.doClient(ctx, func(cl consensusproto.DRPCConsensusClient) error { if _, err = cl.LogAdd(ctx, &consensusproto.LogAddRequest{ - Log: clog, + Record: rec, }); err != nil { return rpcerr.Unwrap(err) } @@ -97,11 +97,11 @@ func (s *service) AddLog(ctx context.Context, clog *consensusproto.Log) (err err }) } -func (s *service) AddRecord(ctx context.Context, logId string, clog *consensusproto.RawRecord) (record *consensusproto.RawRecordWithId, err error) { +func (s *service) AddRecord(ctx context.Context, logId string, rec *consensusproto.RawRecord) (record *consensusproto.RawRecordWithId, err error) { err = s.doClient(ctx, func(cl consensusproto.DRPCConsensusClient) error { if record, err = cl.RecordAdd(ctx, &consensusproto.RecordAddRequest{ LogId: logId, - Record: clog, + Record: rec, }); err != nil { return rpcerr.Unwrap(err) } diff --git a/consensus/consensusclient/client_test.go b/consensus/consensusclient/client_test.go index f4b8f2cc..563ef110 100644 --- a/consensus/consensusclient/client_test.go +++ b/consensus/consensusclient/client_test.go @@ -113,7 +113,7 @@ func TestService_Init(t *testing.T) { func TestService_AddLog(t *testing.T) { fx := newFixture(t).run(t) defer fx.Finish() - assert.NoError(t, fx.AddLog(ctx, &consensusproto.Log{})) + assert.NoError(t, fx.AddLog(ctx, &consensusproto.RawRecordWithId{})) } func TestService_AddRecord(t *testing.T) { diff --git a/consensus/consensusproto/consensus.pb.go b/consensus/consensusproto/consensus.pb.go index a4f55d18..9296468c 100644 --- a/consensus/consensusproto/consensus.pb.go +++ b/consensus/consensusproto/consensus.pb.go @@ -61,7 +61,6 @@ func (ErrCodes) EnumDescriptor() ([]byte, []int) { type Log struct { Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Payload []byte `protobuf:"bytes,2,opt,name=payload,proto3" json:"payload,omitempty"` Records []*RawRecordWithId `protobuf:"bytes,3,rep,name=records,proto3" json:"records,omitempty"` } @@ -105,13 +104,6 @@ func (m *Log) GetId() string { return "" } -func (m *Log) GetPayload() []byte { - if m != nil { - return m.Payload - } - return nil -} - func (m *Log) GetRecords() []*RawRecordWithId { if m != nil { return m.Records @@ -347,7 +339,8 @@ func (m *Ok) XXX_DiscardUnknown() { var xxx_messageInfo_Ok proto.InternalMessageInfo type LogAddRequest struct { - Log *Log `protobuf:"bytes,1,opt,name=log,proto3" json:"log,omitempty"` + // first record in the log, consensus node not sign it + Record *RawRecordWithId `protobuf:"bytes,1,opt,name=record,proto3" json:"record,omitempty"` } func (m *LogAddRequest) Reset() { *m = LogAddRequest{} } @@ -383,9 +376,9 @@ func (m *LogAddRequest) XXX_DiscardUnknown() { var xxx_messageInfo_LogAddRequest proto.InternalMessageInfo -func (m *LogAddRequest) GetLog() *Log { +func (m *LogAddRequest) GetRecord() *RawRecordWithId { if m != nil { - return m.Log + return m.Record } return nil } @@ -617,47 +610,46 @@ func init() { } var fileDescriptor_b8d7f1c16b400059 = []byte{ - // 626 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xcd, 0x6e, 0xd3, 0x40, - 0x10, 0xce, 0xda, 0x69, 0x1a, 0x4f, 0x68, 0x6a, 0x06, 0x84, 0x4c, 0x44, 0xdd, 0xc8, 0x12, 0x52, - 0xa8, 0x50, 0x0a, 0x41, 0x20, 0xa1, 0x9e, 0xa0, 0x4a, 0xa5, 0x48, 0xa1, 0x45, 0x46, 0xa8, 0x12, - 0x9c, 0x5c, 0xef, 0xd6, 0x35, 0x4d, 0xbd, 0x61, 0xbd, 0xe9, 0xcf, 0x33, 0x70, 0xe1, 0x05, 0x78, - 0x1f, 0x8e, 0x3d, 0x72, 0x44, 0xed, 0x85, 0x07, 0xe0, 0x01, 0x90, 0xd7, 0xb1, 0xe3, 0xe6, 0x07, - 0xc4, 0x25, 0xd9, 0xf9, 0x66, 0x66, 0xe7, 0xdb, 0x6f, 0x3e, 0x19, 0x36, 0x7d, 0x1e, 0xc5, 0x2c, - 0x8a, 0x47, 0xf1, 0xe4, 0x34, 0x14, 0x5c, 0xf2, 0x4d, 0xf5, 0x5b, 0x40, 0xdb, 0x0a, 0xc0, 0x7a, - 0x0e, 0xbc, 0x4d, 0x62, 0xe7, 0x13, 0xe8, 0x7d, 0x1e, 0x60, 0x1d, 0xb4, 0x90, 0x5a, 0xa4, 0x49, - 0x5a, 0x86, 0xab, 0x85, 0x14, 0x2d, 0x58, 0x1e, 0x7a, 0x17, 0x03, 0xee, 0x51, 0x4b, 0x6b, 0x92, - 0xd6, 0x2d, 0x37, 0x0b, 0xf1, 0x25, 0x2c, 0x0b, 0xe6, 0x73, 0x41, 0x63, 0x4b, 0x6f, 0xea, 0xad, - 0x5a, 0x67, 0xbd, 0x7d, 0xf3, 0xca, 0xb6, 0xeb, 0x9d, 0xb9, 0xaa, 0x62, 0x3f, 0x94, 0x47, 0x3d, - 0xea, 0x66, 0xf5, 0xce, 0x37, 0x02, 0x46, 0x9e, 0x2c, 0x8e, 0x20, 0x37, 0x47, 0x3c, 0x00, 0x23, - 0x0e, 0x83, 0xc8, 0x93, 0x23, 0xc1, 0xc6, 0xe3, 0x27, 0x00, 0x6e, 0x80, 0xe9, 0xf9, 0x3e, 0x1b, - 0x4a, 0x2e, 0x7a, 0x94, 0x45, 0x32, 0x94, 0x17, 0x96, 0xae, 0x8a, 0x66, 0x70, 0x7c, 0x0c, 0xb7, - 0x33, 0xec, 0x5d, 0x7e, 0x63, 0x59, 0x15, 0xcf, 0x26, 0x9c, 0x2d, 0x58, 0x9d, 0xe2, 0xfe, 0x17, - 0x92, 0xa9, 0x62, 0x5a, 0xa6, 0x98, 0x13, 0x41, 0x65, 0xfc, 0xb0, 0x7b, 0x50, 0x19, 0x0a, 0x76, - 0xda, 0xcb, 0xf4, 0x1c, 0x47, 0xd8, 0x80, 0x6a, 0x98, 0x11, 0x4e, 0x5f, 0x95, 0xc7, 0x88, 0x50, - 0xa6, 0x9e, 0xf4, 0xc6, 0x0f, 0x51, 0xe7, 0x44, 0x06, 0x19, 0x9e, 0xb0, 0x58, 0x7a, 0x27, 0x43, - 0x45, 0x5a, 0x77, 0x27, 0x80, 0x53, 0x06, 0x6d, 0xef, 0xd8, 0x79, 0x01, 0x2b, 0x7d, 0x1e, 0xbc, - 0xa2, 0xd4, 0x65, 0x9f, 0x47, 0x2c, 0x96, 0xf8, 0x10, 0xf4, 0x01, 0x0f, 0xd4, 0xe4, 0x5a, 0xe7, - 0xce, 0xf4, 0x6a, 0xfa, 0x3c, 0x70, 0x93, 0xbc, 0xf3, 0x11, 0xcc, 0x94, 0x6d, 0xa1, 0xf5, 0x2e, - 0x2c, 0x0d, 0x78, 0x90, 0xd3, 0x4e, 0x03, 0x7c, 0x0a, 0x95, 0x74, 0x7f, 0x8a, 0x73, 0xad, 0x73, - 0x7f, 0xe1, 0xba, 0xdd, 0x71, 0xa1, 0xf3, 0x06, 0x56, 0xfb, 0x3c, 0xd8, 0xf7, 0xa4, 0x7f, 0x94, - 0xdd, 0xdd, 0x80, 0xea, 0x59, 0x12, 0xf7, 0x68, 0x6c, 0x91, 0xa6, 0xde, 0x32, 0xdc, 0x3c, 0x46, - 0x1b, 0x60, 0x14, 0xe5, 0x59, 0x4d, 0x65, 0x0b, 0x88, 0xf3, 0x85, 0xa8, 0x47, 0xaa, 0xfb, 0xba, - 0xa7, 0x2c, 0x5a, 0xc4, 0xb4, 0xe0, 0x4c, 0xed, 0xff, 0x9c, 0x89, 0x8f, 0x60, 0x89, 0x09, 0xc1, - 0x85, 0xd2, 0x7f, 0x8e, 0x6e, 0x5d, 0x21, 0xdc, 0xb4, 0xc2, 0x79, 0x0e, 0x7a, 0x57, 0x08, 0x6c, - 0x67, 0x1d, 0x09, 0x85, 0x7a, 0xc7, 0x9a, 0xd3, 0xb1, 0xcd, 0x29, 0x8b, 0xc7, 0x6d, 0x1b, 0x1c, - 0xaa, 0x19, 0x84, 0x75, 0x80, 0xf7, 0x11, 0x3b, 0x1f, 0x32, 0x5f, 0x32, 0x6a, 0x96, 0x70, 0x05, - 0x8c, 0x3e, 0x0f, 0xba, 0xe7, 0x61, 0x2c, 0x63, 0x93, 0xe0, 0x2a, 0xd4, 0xfa, 0x3c, 0xd8, 0xe5, - 0x72, 0x87, 0x8f, 0x22, 0x6a, 0x6a, 0x88, 0x50, 0x4f, 0x69, 0x6f, 0xf3, 0xe8, 0x70, 0x10, 0xfa, - 0xd2, 0xd4, 0x93, 0x9e, 0x1d, 0x2e, 0x0e, 0x42, 0x4a, 0x59, 0x64, 0x96, 0xd1, 0x84, 0x5a, 0x37, - 0x99, 0xb3, 0x77, 0x78, 0x18, 0x33, 0x69, 0xfe, 0xd6, 0x3b, 0xbf, 0x08, 0x18, 0xdb, 0x19, 0x27, - 0xdc, 0x82, 0x4a, 0xea, 0x13, 0x5c, 0x9b, 0xe3, 0x89, 0x89, 0x09, 0x1a, 0x38, 0x9d, 0xde, 0x3b, - 0xc6, 0x5d, 0x30, 0x72, 0xb3, 0x60, 0x73, 0x46, 0xd4, 0x29, 0x1f, 0x35, 0xfe, 0x25, 0x3b, 0xee, - 0x42, 0x35, 0xdb, 0x27, 0xae, 0xcf, 0xa1, 0x53, 0x74, 0x4e, 0x63, 0x6d, 0x51, 0x81, 0xb2, 0x42, - 0x8b, 0x3c, 0x21, 0xaf, 0x3b, 0xdf, 0xaf, 0x6c, 0x72, 0x79, 0x65, 0x93, 0x9f, 0x57, 0x36, 0xf9, - 0x7a, 0x6d, 0x97, 0x2e, 0xaf, 0xed, 0xd2, 0x8f, 0x6b, 0xbb, 0xf4, 0xc1, 0x5a, 0xf4, 0x79, 0x3c, - 0xa8, 0xa8, 0xbf, 0x67, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x21, 0x21, 0x57, 0x7a, 0x41, 0x05, - 0x00, 0x00, + // 612 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xcb, 0x6e, 0xd3, 0x4c, + 0x14, 0xce, 0xd8, 0x69, 0x1a, 0x9f, 0xfc, 0x4d, 0xfd, 0x1f, 0x10, 0x32, 0x11, 0x75, 0x23, 0xaf, + 0x42, 0x85, 0x52, 0x08, 0x42, 0x08, 0x75, 0x05, 0x55, 0x2a, 0x22, 0x85, 0xb6, 0x32, 0x42, 0x95, + 0x60, 0xe5, 0x7a, 0xa6, 0xae, 0xd5, 0xd6, 0x63, 0x66, 0x26, 0xbd, 0x3c, 0x03, 0x1b, 0x5e, 0x80, + 0xf7, 0x61, 0xd9, 0x25, 0x4b, 0xd4, 0x6e, 0x78, 0x00, 0x1e, 0x00, 0x79, 0x1c, 0xbb, 0x69, 0xda, + 0x70, 0xd9, 0x24, 0x73, 0xbe, 0x73, 0xfb, 0xce, 0x39, 0x9f, 0x0c, 0xab, 0x21, 0x4f, 0x24, 0x4b, + 0xe4, 0x48, 0x5e, 0xbd, 0x52, 0xc1, 0x15, 0x5f, 0xd5, 0xbf, 0x13, 0x68, 0x57, 0x03, 0xd8, 0x2c, + 0x81, 0xed, 0xcc, 0xf6, 0xb6, 0xc1, 0x1c, 0xf2, 0x08, 0x9b, 0x60, 0xc4, 0xd4, 0x21, 0x6d, 0xd2, + 0xb1, 0x7c, 0x23, 0xa6, 0xf8, 0x02, 0xe6, 0x05, 0x0b, 0xb9, 0xa0, 0xd2, 0x31, 0xdb, 0x66, 0xa7, + 0xd1, 0x5b, 0xee, 0x5e, 0x4f, 0xec, 0xfa, 0xc1, 0x89, 0xaf, 0x23, 0x76, 0x62, 0xb5, 0x3f, 0xa0, + 0x7e, 0x11, 0xef, 0x7d, 0x21, 0x60, 0x95, 0x4e, 0x74, 0x60, 0x3e, 0x0d, 0xce, 0x0e, 0x79, 0x90, + 0x57, 0xff, 0xcf, 0x2f, 0x4c, 0x7c, 0x00, 0x96, 0x8c, 0xa3, 0x24, 0x50, 0x23, 0xc1, 0x1c, 0x43, + 0xfb, 0xae, 0x00, 0x5c, 0x01, 0x3b, 0x08, 0x43, 0x96, 0x2a, 0x2e, 0x06, 0x94, 0x25, 0x2a, 0x56, + 0x67, 0x8e, 0xa9, 0x83, 0x6e, 0xe0, 0xf8, 0x08, 0xfe, 0x2f, 0xb0, 0xb7, 0x65, 0xc5, 0xaa, 0x0e, + 0xbe, 0xe9, 0xf0, 0xd6, 0x60, 0x71, 0x8a, 0xfb, 0x6f, 0x48, 0xe6, 0x7b, 0x31, 0x8a, 0xbd, 0x78, + 0x09, 0xd4, 0xc6, 0x83, 0xdd, 0x83, 0x5a, 0x2a, 0xd8, 0xf1, 0xa0, 0xd8, 0xda, 0xd8, 0xc2, 0x16, + 0xd4, 0xe3, 0x82, 0x70, 0x3e, 0x55, 0x69, 0x23, 0x42, 0x95, 0x06, 0x2a, 0x18, 0x0f, 0xa2, 0xdf, + 0xd9, 0x1a, 0x54, 0x7c, 0xc4, 0xa4, 0x0a, 0x8e, 0x52, 0x4d, 0xda, 0xf4, 0xaf, 0x00, 0xaf, 0x0a, + 0xc6, 0xd6, 0x81, 0xf7, 0x1a, 0x16, 0x86, 0x3c, 0x7a, 0x49, 0xa9, 0xcf, 0x3e, 0x8e, 0x98, 0x54, + 0xf8, 0x1c, 0x6a, 0xf9, 0xba, 0x75, 0xf3, 0xbf, 0xb8, 0xce, 0x38, 0xdc, 0xfb, 0x00, 0x76, 0x8e, + 0x4f, 0x14, 0xbb, 0x0b, 0x73, 0x87, 0x3c, 0x2a, 0x07, 0xc9, 0x0d, 0x7c, 0x52, 0xb6, 0x30, 0x74, + 0x8b, 0xfb, 0x33, 0x5b, 0x94, 0xc5, 0xdf, 0xc0, 0xe2, 0x90, 0x47, 0x3b, 0x81, 0x0a, 0xf7, 0x8b, + 0xda, 0x2d, 0xa8, 0x9f, 0x64, 0xf6, 0x80, 0x4a, 0x87, 0xb4, 0xcd, 0x8e, 0xe5, 0x97, 0x36, 0xba, + 0x00, 0xa3, 0xa4, 0xf4, 0x1a, 0xda, 0x3b, 0x81, 0x78, 0x9f, 0x88, 0x1e, 0x5b, 0xd7, 0xeb, 0x1f, + 0xb3, 0x64, 0x16, 0xd3, 0x09, 0xad, 0x1a, 0xff, 0xa6, 0x55, 0x7c, 0x08, 0x73, 0x4c, 0x08, 0x2e, + 0xf4, 0x45, 0x1a, 0xbd, 0x3b, 0xd3, 0x89, 0x7d, 0x21, 0xfc, 0x3c, 0xc2, 0x7b, 0x06, 0x66, 0x5f, + 0x08, 0xec, 0x16, 0x19, 0x19, 0x85, 0x66, 0xcf, 0xb9, 0x25, 0x63, 0x9d, 0x53, 0x26, 0xc7, 0x69, + 0x2b, 0x1c, 0xea, 0x05, 0x84, 0x4d, 0x80, 0x77, 0x09, 0x3b, 0x4d, 0x59, 0xa8, 0x18, 0xb5, 0x2b, + 0xb8, 0x00, 0xd6, 0x90, 0x47, 0xfd, 0xd3, 0x58, 0x2a, 0x69, 0x13, 0x5c, 0x84, 0xc6, 0x90, 0x47, + 0x9b, 0x5c, 0x6d, 0xf0, 0x51, 0x42, 0x6d, 0x03, 0x11, 0x9a, 0x39, 0xed, 0x75, 0x9e, 0xec, 0x1d, + 0xc6, 0xa1, 0xb2, 0xcd, 0x2c, 0x67, 0x83, 0x8b, 0xdd, 0x98, 0x52, 0x96, 0xd8, 0x55, 0xb4, 0xa1, + 0xd1, 0xcf, 0xfa, 0x6c, 0xed, 0xed, 0x49, 0xa6, 0xec, 0x9f, 0x66, 0xef, 0x07, 0x01, 0x6b, 0xbd, + 0xe0, 0x84, 0x6b, 0x50, 0xcb, 0x95, 0x83, 0x4b, 0xd3, 0x4c, 0xaf, 0x29, 0xaa, 0x85, 0xd3, 0xee, + 0xad, 0x03, 0xdc, 0x04, 0xab, 0x14, 0x0b, 0xb6, 0x6f, 0x2c, 0x75, 0x4a, 0x47, 0xad, 0x3f, 0xad, + 0x1d, 0x37, 0xa1, 0x5e, 0xdc, 0x13, 0x97, 0x6f, 0xa1, 0x33, 0xa9, 0x9c, 0xd6, 0xd2, 0xac, 0x00, + 0x2d, 0x85, 0x0e, 0x79, 0x4c, 0x5e, 0xf5, 0xbe, 0x5e, 0xb8, 0xe4, 0xfc, 0xc2, 0x25, 0xdf, 0x2f, + 0x5c, 0xf2, 0xf9, 0xd2, 0xad, 0x9c, 0x5f, 0xba, 0x95, 0x6f, 0x97, 0x6e, 0xe5, 0xbd, 0x33, 0xeb, + 0xb3, 0xb8, 0x5b, 0xd3, 0x7f, 0x4f, 0x7f, 0x05, 0x00, 0x00, 0xff, 0xff, 0x62, 0x07, 0x7c, 0x8d, + 0x39, 0x05, 0x00, 0x00, } func (m *Log) Marshal() (dAtA []byte, err error) { @@ -694,13 +686,6 @@ func (m *Log) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x1a } } - 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] = 0x12 - } if len(m.Id) > 0 { i -= len(m.Id) copy(dAtA[i:], m.Id) @@ -891,9 +876,9 @@ func (m *LogAddRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.Log != nil { + if m.Record != nil { { - size, err := m.Log.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.Record.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -1094,10 +1079,6 @@ func (m *Log) Size() (n int) { if l > 0 { n += 1 + l + sovConsensus(uint64(l)) } - l = len(m.Payload) - if l > 0 { - n += 1 + l + sovConsensus(uint64(l)) - } if len(m.Records) > 0 { for _, e := range m.Records { l = e.Size() @@ -1188,8 +1169,8 @@ func (m *LogAddRequest) Size() (n int) { } var l int _ = l - if m.Log != nil { - l = m.Log.Size() + if m.Record != nil { + l = m.Record.Size() n += 1 + l + sovConsensus(uint64(l)) } return n @@ -1335,40 +1316,6 @@ func (m *Log) Unmarshal(dAtA []byte) error { } m.Id = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: - 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 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Records", wireType) @@ -1976,7 +1923,7 @@ func (m *LogAddRequest) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Log", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Record", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -2003,10 +1950,10 @@ func (m *LogAddRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Log == nil { - m.Log = &Log{} + if m.Record == nil { + m.Record = &RawRecordWithId{} } - if err := m.Log.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Record.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/consensus/consensusproto/protos/consensus.proto b/consensus/consensusproto/protos/consensus.proto index 7409704f..8f97ff02 100644 --- a/consensus/consensusproto/protos/consensus.proto +++ b/consensus/consensusproto/protos/consensus.proto @@ -15,7 +15,6 @@ enum ErrCodes { message Log { string id = 1; - bytes payload = 2; repeated RawRecordWithId records = 3; } @@ -54,7 +53,8 @@ service Consensus { message Ok {} message LogAddRequest { - Log log = 1; + // first record in the log, consensus node not sign it + RawRecordWithId record = 1; } message RecordAddRequest { From 648aa15b55ae96bc73f00ef2eadcbe8dd0803254 Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Fri, 7 Jul 2023 11:22:12 +0200 Subject: [PATCH 111/123] consensus: err invalid payload --- consensus/consensusproto/consensus.pb.go | 84 ++++++++++--------- .../consensusproto/consensuserr/errors.go | 11 +-- .../consensusproto/protos/consensus.proto | 1 + 3 files changed, 51 insertions(+), 45 deletions(-) diff --git a/consensus/consensusproto/consensus.pb.go b/consensus/consensusproto/consensus.pb.go index 9296468c..a2df2739 100644 --- a/consensus/consensusproto/consensus.pb.go +++ b/consensus/consensusproto/consensus.pb.go @@ -30,6 +30,7 @@ const ( ErrCodes_LogNotFound ErrCodes = 2 ErrCodes_RecordConflict ErrCodes = 3 ErrCodes_Forbidden ErrCodes = 4 + ErrCodes_InvalidPayload ErrCodes = 5 ErrCodes_ErrorOffset ErrCodes = 500 ) @@ -39,6 +40,7 @@ var ErrCodes_name = map[int32]string{ 2: "LogNotFound", 3: "RecordConflict", 4: "Forbidden", + 5: "InvalidPayload", 500: "ErrorOffset", } @@ -48,6 +50,7 @@ var ErrCodes_value = map[string]int32{ "LogNotFound": 2, "RecordConflict": 3, "Forbidden": 4, + "InvalidPayload": 5, "ErrorOffset": 500, } @@ -610,46 +613,47 @@ func init() { } var fileDescriptor_b8d7f1c16b400059 = []byte{ - // 612 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xcb, 0x6e, 0xd3, 0x4c, - 0x14, 0xce, 0xd8, 0x69, 0x1a, 0x9f, 0xfc, 0x4d, 0xfd, 0x1f, 0x10, 0x32, 0x11, 0x75, 0x23, 0xaf, - 0x42, 0x85, 0x52, 0x08, 0x42, 0x08, 0x75, 0x05, 0x55, 0x2a, 0x22, 0x85, 0xb6, 0x32, 0x42, 0x95, - 0x60, 0xe5, 0x7a, 0xa6, 0xae, 0xd5, 0xd6, 0x63, 0x66, 0x26, 0xbd, 0x3c, 0x03, 0x1b, 0x5e, 0x80, - 0xf7, 0x61, 0xd9, 0x25, 0x4b, 0xd4, 0x6e, 0x78, 0x00, 0x1e, 0x00, 0x79, 0x1c, 0xbb, 0x69, 0xda, - 0x70, 0xd9, 0x24, 0x73, 0xbe, 0x73, 0xfb, 0xce, 0x39, 0x9f, 0x0c, 0xab, 0x21, 0x4f, 0x24, 0x4b, - 0xe4, 0x48, 0x5e, 0xbd, 0x52, 0xc1, 0x15, 0x5f, 0xd5, 0xbf, 0x13, 0x68, 0x57, 0x03, 0xd8, 0x2c, - 0x81, 0xed, 0xcc, 0xf6, 0xb6, 0xc1, 0x1c, 0xf2, 0x08, 0x9b, 0x60, 0xc4, 0xd4, 0x21, 0x6d, 0xd2, - 0xb1, 0x7c, 0x23, 0xa6, 0xf8, 0x02, 0xe6, 0x05, 0x0b, 0xb9, 0xa0, 0xd2, 0x31, 0xdb, 0x66, 0xa7, - 0xd1, 0x5b, 0xee, 0x5e, 0x4f, 0xec, 0xfa, 0xc1, 0x89, 0xaf, 0x23, 0x76, 0x62, 0xb5, 0x3f, 0xa0, - 0x7e, 0x11, 0xef, 0x7d, 0x21, 0x60, 0x95, 0x4e, 0x74, 0x60, 0x3e, 0x0d, 0xce, 0x0e, 0x79, 0x90, - 0x57, 0xff, 0xcf, 0x2f, 0x4c, 0x7c, 0x00, 0x96, 0x8c, 0xa3, 0x24, 0x50, 0x23, 0xc1, 0x1c, 0x43, - 0xfb, 0xae, 0x00, 0x5c, 0x01, 0x3b, 0x08, 0x43, 0x96, 0x2a, 0x2e, 0x06, 0x94, 0x25, 0x2a, 0x56, - 0x67, 0x8e, 0xa9, 0x83, 0x6e, 0xe0, 0xf8, 0x08, 0xfe, 0x2f, 0xb0, 0xb7, 0x65, 0xc5, 0xaa, 0x0e, - 0xbe, 0xe9, 0xf0, 0xd6, 0x60, 0x71, 0x8a, 0xfb, 0x6f, 0x48, 0xe6, 0x7b, 0x31, 0x8a, 0xbd, 0x78, - 0x09, 0xd4, 0xc6, 0x83, 0xdd, 0x83, 0x5a, 0x2a, 0xd8, 0xf1, 0xa0, 0xd8, 0xda, 0xd8, 0xc2, 0x16, - 0xd4, 0xe3, 0x82, 0x70, 0x3e, 0x55, 0x69, 0x23, 0x42, 0x95, 0x06, 0x2a, 0x18, 0x0f, 0xa2, 0xdf, - 0xd9, 0x1a, 0x54, 0x7c, 0xc4, 0xa4, 0x0a, 0x8e, 0x52, 0x4d, 0xda, 0xf4, 0xaf, 0x00, 0xaf, 0x0a, - 0xc6, 0xd6, 0x81, 0xf7, 0x1a, 0x16, 0x86, 0x3c, 0x7a, 0x49, 0xa9, 0xcf, 0x3e, 0x8e, 0x98, 0x54, - 0xf8, 0x1c, 0x6a, 0xf9, 0xba, 0x75, 0xf3, 0xbf, 0xb8, 0xce, 0x38, 0xdc, 0xfb, 0x00, 0x76, 0x8e, - 0x4f, 0x14, 0xbb, 0x0b, 0x73, 0x87, 0x3c, 0x2a, 0x07, 0xc9, 0x0d, 0x7c, 0x52, 0xb6, 0x30, 0x74, - 0x8b, 0xfb, 0x33, 0x5b, 0x94, 0xc5, 0xdf, 0xc0, 0xe2, 0x90, 0x47, 0x3b, 0x81, 0x0a, 0xf7, 0x8b, - 0xda, 0x2d, 0xa8, 0x9f, 0x64, 0xf6, 0x80, 0x4a, 0x87, 0xb4, 0xcd, 0x8e, 0xe5, 0x97, 0x36, 0xba, - 0x00, 0xa3, 0xa4, 0xf4, 0x1a, 0xda, 0x3b, 0x81, 0x78, 0x9f, 0x88, 0x1e, 0x5b, 0xd7, 0xeb, 0x1f, - 0xb3, 0x64, 0x16, 0xd3, 0x09, 0xad, 0x1a, 0xff, 0xa6, 0x55, 0x7c, 0x08, 0x73, 0x4c, 0x08, 0x2e, - 0xf4, 0x45, 0x1a, 0xbd, 0x3b, 0xd3, 0x89, 0x7d, 0x21, 0xfc, 0x3c, 0xc2, 0x7b, 0x06, 0x66, 0x5f, - 0x08, 0xec, 0x16, 0x19, 0x19, 0x85, 0x66, 0xcf, 0xb9, 0x25, 0x63, 0x9d, 0x53, 0x26, 0xc7, 0x69, - 0x2b, 0x1c, 0xea, 0x05, 0x84, 0x4d, 0x80, 0x77, 0x09, 0x3b, 0x4d, 0x59, 0xa8, 0x18, 0xb5, 0x2b, - 0xb8, 0x00, 0xd6, 0x90, 0x47, 0xfd, 0xd3, 0x58, 0x2a, 0x69, 0x13, 0x5c, 0x84, 0xc6, 0x90, 0x47, - 0x9b, 0x5c, 0x6d, 0xf0, 0x51, 0x42, 0x6d, 0x03, 0x11, 0x9a, 0x39, 0xed, 0x75, 0x9e, 0xec, 0x1d, - 0xc6, 0xa1, 0xb2, 0xcd, 0x2c, 0x67, 0x83, 0x8b, 0xdd, 0x98, 0x52, 0x96, 0xd8, 0x55, 0xb4, 0xa1, - 0xd1, 0xcf, 0xfa, 0x6c, 0xed, 0xed, 0x49, 0xa6, 0xec, 0x9f, 0x66, 0xef, 0x07, 0x01, 0x6b, 0xbd, - 0xe0, 0x84, 0x6b, 0x50, 0xcb, 0x95, 0x83, 0x4b, 0xd3, 0x4c, 0xaf, 0x29, 0xaa, 0x85, 0xd3, 0xee, - 0xad, 0x03, 0xdc, 0x04, 0xab, 0x14, 0x0b, 0xb6, 0x6f, 0x2c, 0x75, 0x4a, 0x47, 0xad, 0x3f, 0xad, - 0x1d, 0x37, 0xa1, 0x5e, 0xdc, 0x13, 0x97, 0x6f, 0xa1, 0x33, 0xa9, 0x9c, 0xd6, 0xd2, 0xac, 0x00, - 0x2d, 0x85, 0x0e, 0x79, 0x4c, 0x5e, 0xf5, 0xbe, 0x5e, 0xb8, 0xe4, 0xfc, 0xc2, 0x25, 0xdf, 0x2f, - 0x5c, 0xf2, 0xf9, 0xd2, 0xad, 0x9c, 0x5f, 0xba, 0x95, 0x6f, 0x97, 0x6e, 0xe5, 0xbd, 0x33, 0xeb, - 0xb3, 0xb8, 0x5b, 0xd3, 0x7f, 0x4f, 0x7f, 0x05, 0x00, 0x00, 0xff, 0xff, 0x62, 0x07, 0x7c, 0x8d, - 0x39, 0x05, 0x00, 0x00, + // 625 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xcd, 0x6e, 0xd3, 0x40, + 0x10, 0xce, 0xda, 0x69, 0x1a, 0x4f, 0x68, 0x6a, 0x06, 0x84, 0x4c, 0x44, 0xdd, 0xc8, 0xa7, 0x50, + 0xa1, 0x14, 0x82, 0x10, 0x42, 0x3d, 0x41, 0x95, 0x8a, 0x48, 0xa1, 0xad, 0x8c, 0x50, 0x25, 0x38, + 0xb9, 0xde, 0xad, 0x6b, 0x35, 0xf5, 0x86, 0xdd, 0x4d, 0x7f, 0xce, 0x1c, 0xb9, 0xf0, 0x02, 0xbc, + 0x0f, 0xc7, 0x1e, 0x39, 0xa2, 0xf6, 0xc2, 0x03, 0xf0, 0x00, 0xc8, 0xeb, 0xd8, 0x4d, 0xd3, 0x86, + 0x9f, 0x4b, 0xb2, 0xf3, 0xcd, 0xdf, 0x37, 0x33, 0x9f, 0x0c, 0xab, 0x21, 0x4f, 0x24, 0x4b, 0xe4, + 0x48, 0x5e, 0xbe, 0x86, 0x82, 0x2b, 0xbe, 0xaa, 0x7f, 0x27, 0xd0, 0xb6, 0x06, 0xb0, 0x5e, 0x00, + 0xdb, 0xa9, 0xed, 0x6d, 0x83, 0xd9, 0xe7, 0x11, 0xd6, 0xc1, 0x88, 0xa9, 0x43, 0x9a, 0xa4, 0x65, + 0xf9, 0x46, 0x4c, 0xf1, 0x05, 0xcc, 0x0b, 0x16, 0x72, 0x41, 0xa5, 0x63, 0x36, 0xcd, 0x56, 0xad, + 0xb3, 0xdc, 0xbe, 0x9a, 0xd8, 0xf6, 0x83, 0x63, 0x5f, 0x47, 0xec, 0xc4, 0x6a, 0xbf, 0x47, 0xfd, + 0x3c, 0xde, 0xfb, 0x4a, 0xc0, 0x2a, 0x9c, 0xe8, 0xc0, 0xfc, 0x30, 0x38, 0x1d, 0xf0, 0x20, 0xab, + 0x7e, 0xcb, 0xcf, 0x4d, 0x7c, 0x00, 0x96, 0x8c, 0xa3, 0x24, 0x50, 0x23, 0xc1, 0x1c, 0x43, 0xfb, + 0x2e, 0x01, 0x5c, 0x01, 0x3b, 0x08, 0x43, 0x36, 0x54, 0x5c, 0xf4, 0x28, 0x4b, 0x54, 0xac, 0x4e, + 0x1d, 0x53, 0x07, 0x5d, 0xc3, 0xf1, 0x11, 0xdc, 0xce, 0xb1, 0xb7, 0x45, 0xc5, 0xb2, 0x0e, 0xbe, + 0xee, 0xf0, 0xd6, 0x60, 0x71, 0x8a, 0xfb, 0x1f, 0x48, 0x66, 0x7b, 0x31, 0xf2, 0xbd, 0x78, 0x09, + 0x54, 0xc6, 0x83, 0xdd, 0x83, 0xca, 0x50, 0xb0, 0xa3, 0x5e, 0xbe, 0xb5, 0xb1, 0x85, 0x0d, 0xa8, + 0xc6, 0x39, 0xe1, 0x6c, 0xaa, 0xc2, 0x46, 0x84, 0x32, 0x0d, 0x54, 0x30, 0x1e, 0x44, 0xbf, 0xd3, + 0x35, 0xa8, 0xf8, 0x90, 0x49, 0x15, 0x1c, 0x0e, 0x35, 0x69, 0xd3, 0xbf, 0x04, 0xbc, 0x32, 0x18, + 0x5b, 0x07, 0xde, 0x6b, 0x58, 0xe8, 0xf3, 0xe8, 0x25, 0xa5, 0x3e, 0xfb, 0x38, 0x62, 0x52, 0xe1, + 0x73, 0xa8, 0x64, 0xeb, 0xd6, 0xcd, 0xff, 0xe1, 0x3a, 0xe3, 0x70, 0xef, 0x03, 0xd8, 0x19, 0x3e, + 0x51, 0xec, 0x2e, 0xcc, 0x0d, 0x78, 0x54, 0x0c, 0x92, 0x19, 0xf8, 0xa4, 0x68, 0x61, 0xe8, 0x16, + 0xf7, 0x67, 0xb6, 0x28, 0x8a, 0xbf, 0x81, 0xc5, 0x3e, 0x8f, 0x76, 0x02, 0x15, 0xee, 0xe7, 0xb5, + 0x1b, 0x50, 0x3d, 0x4e, 0xed, 0x1e, 0x95, 0x0e, 0x69, 0x9a, 0x2d, 0xcb, 0x2f, 0x6c, 0x74, 0x01, + 0x46, 0x49, 0xe1, 0x35, 0xb4, 0x77, 0x02, 0xf1, 0x3e, 0x13, 0x3d, 0xb6, 0xae, 0xd7, 0x3d, 0x62, + 0xc9, 0x2c, 0xa6, 0x13, 0x5a, 0x35, 0xfe, 0x4f, 0xab, 0xf8, 0x10, 0xe6, 0x98, 0x10, 0x5c, 0xe8, + 0x8b, 0xd4, 0x3a, 0x77, 0xa6, 0x13, 0xbb, 0x42, 0xf8, 0x59, 0x84, 0xf7, 0x0c, 0xcc, 0xae, 0x10, + 0xd8, 0xce, 0x33, 0x52, 0x0a, 0xf5, 0x8e, 0x73, 0x43, 0xc6, 0x3a, 0xa7, 0x4c, 0x8e, 0xd3, 0x56, + 0x3e, 0x11, 0xa8, 0xe6, 0x18, 0xd6, 0x01, 0xde, 0x25, 0xec, 0x64, 0xc8, 0x42, 0xc5, 0xa8, 0x5d, + 0xc2, 0x05, 0xb0, 0xfa, 0x3c, 0xea, 0x9e, 0xc4, 0x52, 0x49, 0x9b, 0xe0, 0x22, 0xd4, 0xfa, 0x3c, + 0xda, 0xe4, 0x6a, 0x83, 0x8f, 0x12, 0x6a, 0x1b, 0x88, 0x50, 0xcf, 0x78, 0xaf, 0xf3, 0x64, 0x6f, + 0x10, 0x87, 0xca, 0x36, 0xd3, 0x9c, 0x0d, 0x2e, 0x76, 0x63, 0x4a, 0x59, 0x62, 0x97, 0xd3, 0x90, + 0x5e, 0x72, 0x14, 0x0c, 0x62, 0xba, 0x9d, 0x49, 0xd6, 0x9e, 0x43, 0x1b, 0x6a, 0xdd, 0xb4, 0xf9, + 0xd6, 0xde, 0x9e, 0x64, 0xca, 0xfe, 0x65, 0x76, 0x7e, 0x12, 0xb0, 0xd6, 0x73, 0xa2, 0xb8, 0x06, + 0x95, 0x4c, 0x4e, 0xb8, 0x34, 0x4d, 0xff, 0x8a, 0xcc, 0x1a, 0x38, 0xed, 0xde, 0x3a, 0xc0, 0x4d, + 0xb0, 0x0a, 0x05, 0x61, 0xf3, 0xda, 0xa6, 0xa7, 0xc4, 0xd5, 0xf8, 0xdb, 0x2d, 0x70, 0x13, 0xaa, + 0xf9, 0x91, 0x71, 0xf9, 0x06, 0x3a, 0x93, 0x72, 0x6a, 0x2c, 0xcd, 0x0a, 0xd0, 0xfa, 0x68, 0x91, + 0xc7, 0xe4, 0x55, 0xe7, 0xdb, 0xb9, 0x4b, 0xce, 0xce, 0x5d, 0xf2, 0xe3, 0xdc, 0x25, 0x5f, 0x2e, + 0xdc, 0xd2, 0xd9, 0x85, 0x5b, 0xfa, 0x7e, 0xe1, 0x96, 0xde, 0x3b, 0xb3, 0xbe, 0x95, 0xbb, 0x15, + 0xfd, 0xf7, 0xf4, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x20, 0xdd, 0xae, 0xec, 0x4e, 0x05, 0x00, + 0x00, } func (m *Log) Marshal() (dAtA []byte, err error) { diff --git a/consensus/consensusproto/consensuserr/errors.go b/consensus/consensusproto/consensuserr/errors.go index e313b889..4bc59139 100644 --- a/consensus/consensusproto/consensuserr/errors.go +++ b/consensus/consensusproto/consensuserr/errors.go @@ -9,9 +9,10 @@ import ( 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)) - ErrForbidden = errGroup.Register(fmt.Errorf("forbidden"), uint64(consensusproto.ErrCodes_Forbidden)) + 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)) + ErrForbidden = errGroup.Register(fmt.Errorf("forbidden"), uint64(consensusproto.ErrCodes_Forbidden)) + ErrInvalidPayload = errGroup.Register(fmt.Errorf("invalid payload"), uint64(consensusproto.ErrCodes_InvalidPayload)) ) diff --git a/consensus/consensusproto/protos/consensus.proto b/consensus/consensusproto/protos/consensus.proto index 8f97ff02..a36ae5d8 100644 --- a/consensus/consensusproto/protos/consensus.proto +++ b/consensus/consensusproto/protos/consensus.proto @@ -9,6 +9,7 @@ enum ErrCodes { LogNotFound = 2; RecordConflict = 3; Forbidden = 4; + InvalidPayload = 5; ErrorOffset = 500; } From ef128dd33f9f7cae95775b0d60ce93d813a18a08 Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Mon, 10 Jul 2023 15:40:56 +0200 Subject: [PATCH 112/123] switch to uber/gomock --- accountservice/mock_accountservice/helper.go | 2 +- .../mock_accountservice/mock_accountservice.go | 2 +- app/ldiff/mock_ldiff/mock_ldiff.go | 2 +- .../mock_credentialprovider/mock_credentialprovider.go | 2 +- commonspace/deletionstate/deletionstate_test.go | 2 +- .../mock_deletionstate/mock_deletionstate.go | 2 +- commonspace/headsync/diffsyncer_test.go | 2 +- commonspace/headsync/headsync_test.go | 2 +- commonspace/headsync/mock_headsync/mock_headsync.go | 2 +- commonspace/object/acl/list/mock_list/mock_list.go | 2 +- .../liststorage/mock_liststorage/mock_liststorage.go | 2 +- .../tree/objecttree/mock_objecttree/mock_objecttree.go | 2 +- .../tree/synctree/mock_synctree/mock_synctree.go | 2 +- commonspace/object/tree/synctree/synctree_test.go | 2 +- .../object/tree/synctree/synctreehandler_test.go | 2 +- .../object/tree/synctree/treeremotegetter_test.go | 2 +- .../object/tree/synctree/treesyncprotocol_test.go | 2 +- .../mock_updatelistener/mock_updatelistener.go | 2 +- .../treestorage/mock_treestorage/mock_treestorage.go | 2 +- .../treemanager/mock_treemanager/mock_treemanager.go | 2 +- .../objectsync/mock_objectsync/mock_objectsync.go | 2 +- .../mock_objecttreebuilder/mock_objecttreebuilder.go | 2 +- .../peermanager/mock_peermanager/mock_peermanager.go | 2 +- commonspace/requestmanager/requestmanager_test.go | 2 +- commonspace/settings/deleter_test.go | 2 +- commonspace/settings/deletionmanager_test.go | 2 +- commonspace/settings/mock_settings/mock_settings.go | 2 +- commonspace/settings/settingsobject_test.go | 2 +- .../mock_settingsstate/mock_settingsstate.go | 2 +- .../settings/settingsstate/statebuilder_test.go | 2 +- .../mock_spacestorage/mock_spacestorage.go | 2 +- .../mock_spacesyncproto/mock_spacesyncproto.go | 2 +- consensus/consensusclient/client_test.go | 2 +- .../mock_consensusclient/mock_consensusclient.go | 10 +++++----- .../mock_coordinatorclient/mock_coordinatorclient.go | 2 +- go.mod | 2 +- go.sum | 4 ++-- net/peer/mock_peer/mock_peer.go | 2 +- net/peer/peer_test.go | 2 +- net/pool/mock_pool/mock_pool.go | 2 +- net/secureservice/secureservice_test.go | 2 +- net/transport/mock_transport/mock_transport.go | 2 +- net/transport/yamux/yamux_test.go | 2 +- nodeconf/mock_nodeconf/mock_nodeconf.go | 2 +- .../mock_periodicsync/mock_periodicsync.go | 2 +- util/periodicsync/periodicsync_test.go | 2 +- 46 files changed, 51 insertions(+), 51 deletions(-) diff --git a/accountservice/mock_accountservice/helper.go b/accountservice/mock_accountservice/helper.go index cec6f34b..2dbe031e 100644 --- a/accountservice/mock_accountservice/helper.go +++ b/accountservice/mock_accountservice/helper.go @@ -3,7 +3,7 @@ package mock_accountservice import ( "github.com/anyproto/any-sync/accountservice" "github.com/anyproto/any-sync/commonspace/object/accountdata" - "github.com/golang/mock/gomock" + "go.uber.org/mock/gomock" ) func NewAccountServiceWithAccount(ctrl *gomock.Controller, acc *accountdata.AccountKeys) *MockService { diff --git a/accountservice/mock_accountservice/mock_accountservice.go b/accountservice/mock_accountservice/mock_accountservice.go index a9bbff7f..7da43f91 100644 --- a/accountservice/mock_accountservice/mock_accountservice.go +++ b/accountservice/mock_accountservice/mock_accountservice.go @@ -9,7 +9,7 @@ import ( app "github.com/anyproto/any-sync/app" accountdata "github.com/anyproto/any-sync/commonspace/object/accountdata" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockService is a mock of Service interface. diff --git a/app/ldiff/mock_ldiff/mock_ldiff.go b/app/ldiff/mock_ldiff/mock_ldiff.go index 20a522b7..8e09ade9 100644 --- a/app/ldiff/mock_ldiff/mock_ldiff.go +++ b/app/ldiff/mock_ldiff/mock_ldiff.go @@ -9,7 +9,7 @@ import ( reflect "reflect" ldiff "github.com/anyproto/any-sync/app/ldiff" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockDiff is a mock of Diff interface. diff --git a/commonspace/credentialprovider/mock_credentialprovider/mock_credentialprovider.go b/commonspace/credentialprovider/mock_credentialprovider/mock_credentialprovider.go index 77faf28e..18090381 100644 --- a/commonspace/credentialprovider/mock_credentialprovider/mock_credentialprovider.go +++ b/commonspace/credentialprovider/mock_credentialprovider/mock_credentialprovider.go @@ -10,7 +10,7 @@ import ( app "github.com/anyproto/any-sync/app" spacesyncproto "github.com/anyproto/any-sync/commonspace/spacesyncproto" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockCredentialProvider is a mock of CredentialProvider interface. diff --git a/commonspace/deletionstate/deletionstate_test.go b/commonspace/deletionstate/deletionstate_test.go index e5489bd8..2050fc37 100644 --- a/commonspace/deletionstate/deletionstate_test.go +++ b/commonspace/deletionstate/deletionstate_test.go @@ -3,8 +3,8 @@ package deletionstate import ( "github.com/anyproto/any-sync/commonspace/spacestorage" "github.com/anyproto/any-sync/commonspace/spacestorage/mock_spacestorage" - "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" "sort" "testing" ) diff --git a/commonspace/deletionstate/mock_deletionstate/mock_deletionstate.go b/commonspace/deletionstate/mock_deletionstate/mock_deletionstate.go index c4e9fefb..7706b004 100644 --- a/commonspace/deletionstate/mock_deletionstate/mock_deletionstate.go +++ b/commonspace/deletionstate/mock_deletionstate/mock_deletionstate.go @@ -9,7 +9,7 @@ import ( app "github.com/anyproto/any-sync/app" deletionstate "github.com/anyproto/any-sync/commonspace/deletionstate" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockObjectDeletionState is a mock of ObjectDeletionState interface. diff --git a/commonspace/headsync/diffsyncer_test.go b/commonspace/headsync/diffsyncer_test.go index 7cdb870a..dd21d27c 100644 --- a/commonspace/headsync/diffsyncer_test.go +++ b/commonspace/headsync/diffsyncer_test.go @@ -11,8 +11,8 @@ import ( "github.com/anyproto/any-sync/commonspace/object/tree/treestorage/mock_treestorage" "github.com/anyproto/any-sync/commonspace/spacesyncproto" "github.com/anyproto/any-sync/net/peer" - "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" "storj.io/drpc" "testing" "time" diff --git a/commonspace/headsync/headsync_test.go b/commonspace/headsync/headsync_test.go index 4f14d084..54cdd96a 100644 --- a/commonspace/headsync/headsync_test.go +++ b/commonspace/headsync/headsync_test.go @@ -23,8 +23,8 @@ import ( "github.com/anyproto/any-sync/commonspace/syncstatus" "github.com/anyproto/any-sync/nodeconf" "github.com/anyproto/any-sync/nodeconf/mock_nodeconf" - "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" "sync/atomic" "testing" ) diff --git a/commonspace/headsync/mock_headsync/mock_headsync.go b/commonspace/headsync/mock_headsync/mock_headsync.go index 46b16aab..b569fde4 100644 --- a/commonspace/headsync/mock_headsync/mock_headsync.go +++ b/commonspace/headsync/mock_headsync/mock_headsync.go @@ -8,7 +8,7 @@ import ( context "context" reflect "reflect" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockDiffSyncer is a mock of DiffSyncer interface. diff --git a/commonspace/object/acl/list/mock_list/mock_list.go b/commonspace/object/acl/list/mock_list/mock_list.go index b81f0f80..bf86b80d 100644 --- a/commonspace/object/acl/list/mock_list/mock_list.go +++ b/commonspace/object/acl/list/mock_list/mock_list.go @@ -10,7 +10,7 @@ import ( aclrecordproto "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" list "github.com/anyproto/any-sync/commonspace/object/acl/list" crypto "github.com/anyproto/any-sync/util/crypto" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockAclList is a mock of AclList interface. diff --git a/commonspace/object/acl/liststorage/mock_liststorage/mock_liststorage.go b/commonspace/object/acl/liststorage/mock_liststorage/mock_liststorage.go index ce0a8bbf..da5b1bd3 100644 --- a/commonspace/object/acl/liststorage/mock_liststorage/mock_liststorage.go +++ b/commonspace/object/acl/liststorage/mock_liststorage/mock_liststorage.go @@ -9,7 +9,7 @@ import ( reflect "reflect" aclrecordproto "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockListStorage is a mock of ListStorage interface. diff --git a/commonspace/object/tree/objecttree/mock_objecttree/mock_objecttree.go b/commonspace/object/tree/objecttree/mock_objecttree/mock_objecttree.go index 1f0897a5..3e349e9d 100644 --- a/commonspace/object/tree/objecttree/mock_objecttree/mock_objecttree.go +++ b/commonspace/object/tree/objecttree/mock_objecttree/mock_objecttree.go @@ -13,7 +13,7 @@ import ( objecttree "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" treechangeproto "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" treestorage "github.com/anyproto/any-sync/commonspace/object/tree/treestorage" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockObjectTree is a mock of ObjectTree interface. diff --git a/commonspace/object/tree/synctree/mock_synctree/mock_synctree.go b/commonspace/object/tree/synctree/mock_synctree/mock_synctree.go index 792dbee7..3a5984ac 100644 --- a/commonspace/object/tree/synctree/mock_synctree/mock_synctree.go +++ b/commonspace/object/tree/synctree/mock_synctree/mock_synctree.go @@ -15,7 +15,7 @@ import ( treechangeproto "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" treestorage "github.com/anyproto/any-sync/commonspace/object/tree/treestorage" spacesyncproto "github.com/anyproto/any-sync/commonspace/spacesyncproto" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockSyncTree is a mock of SyncTree interface. diff --git a/commonspace/object/tree/synctree/synctree_test.go b/commonspace/object/tree/synctree/synctree_test.go index 76791c59..3bba33b3 100644 --- a/commonspace/object/tree/synctree/synctree_test.go +++ b/commonspace/object/tree/synctree/synctree_test.go @@ -11,8 +11,8 @@ import ( "github.com/anyproto/any-sync/commonspace/objectsync" "github.com/anyproto/any-sync/commonspace/syncstatus" "github.com/anyproto/any-sync/nodeconf" - "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" "testing" ) diff --git a/commonspace/object/tree/synctree/synctreehandler_test.go b/commonspace/object/tree/synctree/synctreehandler_test.go index 84f3b237..320ff56f 100644 --- a/commonspace/object/tree/synctree/synctreehandler_test.go +++ b/commonspace/object/tree/synctree/synctreehandler_test.go @@ -9,8 +9,8 @@ import ( "github.com/anyproto/any-sync/commonspace/object/tree/synctree/mock_synctree" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" "github.com/anyproto/any-sync/commonspace/syncstatus" - "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" ) type testObjTreeMock struct { diff --git a/commonspace/object/tree/synctree/treeremotegetter_test.go b/commonspace/object/tree/synctree/treeremotegetter_test.go index 60452b1a..a191b678 100644 --- a/commonspace/object/tree/synctree/treeremotegetter_test.go +++ b/commonspace/object/tree/synctree/treeremotegetter_test.go @@ -12,8 +12,8 @@ import ( "github.com/anyproto/any-sync/net/peer" "github.com/anyproto/any-sync/net/peer/mock_peer" "github.com/gogo/protobuf/proto" - "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" ) type treeRemoteGetterFixture struct { diff --git a/commonspace/object/tree/synctree/treesyncprotocol_test.go b/commonspace/object/tree/synctree/treesyncprotocol_test.go index c80dbe35..a88dd168 100644 --- a/commonspace/object/tree/synctree/treesyncprotocol_test.go +++ b/commonspace/object/tree/synctree/treesyncprotocol_test.go @@ -8,8 +8,8 @@ import ( "github.com/anyproto/any-sync/commonspace/object/tree/objecttree/mock_objecttree" "github.com/anyproto/any-sync/commonspace/object/tree/synctree/mock_synctree" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" - "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" "testing" ) diff --git a/commonspace/object/tree/synctree/updatelistener/mock_updatelistener/mock_updatelistener.go b/commonspace/object/tree/synctree/updatelistener/mock_updatelistener/mock_updatelistener.go index 794b9381..050f458e 100644 --- a/commonspace/object/tree/synctree/updatelistener/mock_updatelistener/mock_updatelistener.go +++ b/commonspace/object/tree/synctree/updatelistener/mock_updatelistener/mock_updatelistener.go @@ -8,7 +8,7 @@ import ( reflect "reflect" objecttree "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockUpdateListener is a mock of UpdateListener interface. diff --git a/commonspace/object/tree/treestorage/mock_treestorage/mock_treestorage.go b/commonspace/object/tree/treestorage/mock_treestorage/mock_treestorage.go index 2db9a949..3a20051d 100644 --- a/commonspace/object/tree/treestorage/mock_treestorage/mock_treestorage.go +++ b/commonspace/object/tree/treestorage/mock_treestorage/mock_treestorage.go @@ -9,7 +9,7 @@ import ( reflect "reflect" treechangeproto "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockTreeStorage is a mock of TreeStorage interface. diff --git a/commonspace/object/treemanager/mock_treemanager/mock_treemanager.go b/commonspace/object/treemanager/mock_treemanager/mock_treemanager.go index ee285aac..3ef2892f 100644 --- a/commonspace/object/treemanager/mock_treemanager/mock_treemanager.go +++ b/commonspace/object/treemanager/mock_treemanager/mock_treemanager.go @@ -11,7 +11,7 @@ import ( app "github.com/anyproto/any-sync/app" objecttree "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" treemanager "github.com/anyproto/any-sync/commonspace/object/treemanager" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockTreeManager is a mock of TreeManager interface. diff --git a/commonspace/objectsync/mock_objectsync/mock_objectsync.go b/commonspace/objectsync/mock_objectsync/mock_objectsync.go index 2858c6f9..d1c4666d 100644 --- a/commonspace/objectsync/mock_objectsync/mock_objectsync.go +++ b/commonspace/objectsync/mock_objectsync/mock_objectsync.go @@ -12,7 +12,7 @@ import ( app "github.com/anyproto/any-sync/app" objectsync "github.com/anyproto/any-sync/commonspace/objectsync" spacesyncproto "github.com/anyproto/any-sync/commonspace/spacesyncproto" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockObjectSync is a mock of ObjectSync interface. diff --git a/commonspace/objecttreebuilder/mock_objecttreebuilder/mock_objecttreebuilder.go b/commonspace/objecttreebuilder/mock_objecttreebuilder/mock_objecttreebuilder.go index d7cca965..b44d028f 100644 --- a/commonspace/objecttreebuilder/mock_objecttreebuilder/mock_objecttreebuilder.go +++ b/commonspace/objecttreebuilder/mock_objecttreebuilder/mock_objecttreebuilder.go @@ -12,7 +12,7 @@ import ( updatelistener "github.com/anyproto/any-sync/commonspace/object/tree/synctree/updatelistener" treestorage "github.com/anyproto/any-sync/commonspace/object/tree/treestorage" objecttreebuilder "github.com/anyproto/any-sync/commonspace/objecttreebuilder" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockTreeBuilder is a mock of TreeBuilder interface. diff --git a/commonspace/peermanager/mock_peermanager/mock_peermanager.go b/commonspace/peermanager/mock_peermanager/mock_peermanager.go index 210fb319..d7d99e32 100644 --- a/commonspace/peermanager/mock_peermanager/mock_peermanager.go +++ b/commonspace/peermanager/mock_peermanager/mock_peermanager.go @@ -11,7 +11,7 @@ import ( app "github.com/anyproto/any-sync/app" spacesyncproto "github.com/anyproto/any-sync/commonspace/spacesyncproto" peer "github.com/anyproto/any-sync/net/peer" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockPeerManager is a mock of PeerManager interface. diff --git a/commonspace/requestmanager/requestmanager_test.go b/commonspace/requestmanager/requestmanager_test.go index 35d497fc..2135a41b 100644 --- a/commonspace/requestmanager/requestmanager_test.go +++ b/commonspace/requestmanager/requestmanager_test.go @@ -9,8 +9,8 @@ import ( "github.com/anyproto/any-sync/net/peer" "github.com/anyproto/any-sync/net/peer/mock_peer" "github.com/anyproto/any-sync/net/pool/mock_pool" - "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" "storj.io/drpc" "storj.io/drpc/drpcconn" "sync" diff --git a/commonspace/settings/deleter_test.go b/commonspace/settings/deleter_test.go index e4a32e84..c057207a 100644 --- a/commonspace/settings/deleter_test.go +++ b/commonspace/settings/deleter_test.go @@ -6,7 +6,7 @@ import ( "github.com/anyproto/any-sync/commonspace/object/tree/treestorage" "github.com/anyproto/any-sync/commonspace/object/treemanager/mock_treemanager" "github.com/anyproto/any-sync/commonspace/spacestorage/mock_spacestorage" - "github.com/golang/mock/gomock" + "go.uber.org/mock/gomock" "testing" ) diff --git a/commonspace/settings/deletionmanager_test.go b/commonspace/settings/deletionmanager_test.go index 69e8830d..fb1e7355 100644 --- a/commonspace/settings/deletionmanager_test.go +++ b/commonspace/settings/deletionmanager_test.go @@ -6,8 +6,8 @@ import ( "github.com/anyproto/any-sync/commonspace/object/treemanager/mock_treemanager" "github.com/anyproto/any-sync/commonspace/settings/mock_settings" "github.com/anyproto/any-sync/commonspace/settings/settingsstate" - "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" "testing" ) diff --git a/commonspace/settings/mock_settings/mock_settings.go b/commonspace/settings/mock_settings/mock_settings.go index 69598251..2d5da99f 100644 --- a/commonspace/settings/mock_settings/mock_settings.go +++ b/commonspace/settings/mock_settings/mock_settings.go @@ -9,7 +9,7 @@ import ( reflect "reflect" settingsstate "github.com/anyproto/any-sync/commonspace/settings/settingsstate" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockDeletionManager is a mock of DeletionManager interface. diff --git a/commonspace/settings/settingsobject_test.go b/commonspace/settings/settingsobject_test.go index 9d83d9cd..7d2f4eaa 100644 --- a/commonspace/settings/settingsobject_test.go +++ b/commonspace/settings/settingsobject_test.go @@ -16,8 +16,8 @@ import ( "github.com/anyproto/any-sync/commonspace/settings/settingsstate" "github.com/anyproto/any-sync/commonspace/settings/settingsstate/mock_settingsstate" "github.com/anyproto/any-sync/commonspace/spacestorage/mock_spacestorage" - "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" "sync" "testing" "time" diff --git a/commonspace/settings/settingsstate/mock_settingsstate/mock_settingsstate.go b/commonspace/settings/settingsstate/mock_settingsstate/mock_settingsstate.go index 2bb898cf..091c3ea8 100644 --- a/commonspace/settings/settingsstate/mock_settingsstate/mock_settingsstate.go +++ b/commonspace/settings/settingsstate/mock_settingsstate/mock_settingsstate.go @@ -9,7 +9,7 @@ import ( objecttree "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" settingsstate "github.com/anyproto/any-sync/commonspace/settings/settingsstate" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockStateBuilder is a mock of StateBuilder interface. diff --git a/commonspace/settings/settingsstate/statebuilder_test.go b/commonspace/settings/settingsstate/statebuilder_test.go index a2cf3072..c2d1d4ed 100644 --- a/commonspace/settings/settingsstate/statebuilder_test.go +++ b/commonspace/settings/settingsstate/statebuilder_test.go @@ -4,8 +4,8 @@ import ( "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" "github.com/anyproto/any-sync/commonspace/object/tree/objecttree/mock_objecttree" "github.com/anyproto/any-sync/commonspace/spacesyncproto" - "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" "testing" ) diff --git a/commonspace/spacestorage/mock_spacestorage/mock_spacestorage.go b/commonspace/spacestorage/mock_spacestorage/mock_spacestorage.go index bc7f448c..a81d0a93 100644 --- a/commonspace/spacestorage/mock_spacestorage/mock_spacestorage.go +++ b/commonspace/spacestorage/mock_spacestorage/mock_spacestorage.go @@ -13,7 +13,7 @@ import ( treechangeproto "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" treestorage "github.com/anyproto/any-sync/commonspace/object/tree/treestorage" spacesyncproto "github.com/anyproto/any-sync/commonspace/spacesyncproto" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockSpaceStorage is a mock of SpaceStorage interface. diff --git a/commonspace/spacesyncproto/mock_spacesyncproto/mock_spacesyncproto.go b/commonspace/spacesyncproto/mock_spacesyncproto/mock_spacesyncproto.go index 8d8a1111..a04f5e11 100644 --- a/commonspace/spacesyncproto/mock_spacesyncproto/mock_spacesyncproto.go +++ b/commonspace/spacesyncproto/mock_spacesyncproto/mock_spacesyncproto.go @@ -9,7 +9,7 @@ import ( reflect "reflect" spacesyncproto "github.com/anyproto/any-sync/commonspace/spacesyncproto" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" drpc "storj.io/drpc" ) diff --git a/consensus/consensusclient/client_test.go b/consensus/consensusclient/client_test.go index 563ef110..ea47c50a 100644 --- a/consensus/consensusclient/client_test.go +++ b/consensus/consensusclient/client_test.go @@ -12,9 +12,9 @@ import ( "github.com/anyproto/any-sync/nodeconf/mock_nodeconf" "github.com/anyproto/any-sync/testutil/accounttest" "github.com/anyproto/any-sync/util/cidutil" - "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" "sync" "testing" "time" diff --git a/consensus/consensusclient/mock_consensusclient/mock_consensusclient.go b/consensus/consensusclient/mock_consensusclient/mock_consensusclient.go index 95087515..242bd645 100644 --- a/consensus/consensusclient/mock_consensusclient/mock_consensusclient.go +++ b/consensus/consensusclient/mock_consensusclient/mock_consensusclient.go @@ -11,7 +11,7 @@ import ( app "github.com/anyproto/any-sync/app" consensusclient "github.com/anyproto/any-sync/consensus/consensusclient" consensusproto "github.com/anyproto/any-sync/consensus/consensusproto" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockService is a mock of Service interface. @@ -38,7 +38,7 @@ func (m *MockService) EXPECT() *MockServiceMockRecorder { } // AddLog mocks base method. -func (m *MockService) AddLog(arg0 context.Context, arg1 *consensusproto.Log) error { +func (m *MockService) AddLog(arg0 context.Context, arg1 *consensusproto.RawRecordWithId) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AddLog", arg0, arg1) ret0, _ := ret[0].(error) @@ -52,7 +52,7 @@ func (mr *MockServiceMockRecorder) AddLog(arg0, arg1 interface{}) *gomock.Call { } // AddRecord mocks base method. -func (m *MockService) AddRecord(arg0 context.Context, arg1 []byte, arg2 *consensusproto.RawRecord) (*consensusproto.RawRecordWithId, error) { +func (m *MockService) AddRecord(arg0 context.Context, arg1 string, arg2 *consensusproto.RawRecord) (*consensusproto.RawRecordWithId, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AddRecord", arg0, arg1, arg2) ret0, _ := ret[0].(*consensusproto.RawRecordWithId) @@ -123,7 +123,7 @@ func (mr *MockServiceMockRecorder) Run(arg0 interface{}) *gomock.Call { } // UnWatch mocks base method. -func (m *MockService) UnWatch(arg0 []byte) error { +func (m *MockService) UnWatch(arg0 string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UnWatch", arg0) ret0, _ := ret[0].(error) @@ -137,7 +137,7 @@ func (mr *MockServiceMockRecorder) UnWatch(arg0 interface{}) *gomock.Call { } // Watch mocks base method. -func (m *MockService) Watch(arg0 []byte, arg1 consensusclient.Watcher) error { +func (m *MockService) Watch(arg0 string, arg1 consensusclient.Watcher) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Watch", arg0, arg1) ret0, _ := ret[0].(error) diff --git a/coordinator/coordinatorclient/mock_coordinatorclient/mock_coordinatorclient.go b/coordinator/coordinatorclient/mock_coordinatorclient/mock_coordinatorclient.go index d2d83159..c94189e9 100644 --- a/coordinator/coordinatorclient/mock_coordinatorclient/mock_coordinatorclient.go +++ b/coordinator/coordinatorclient/mock_coordinatorclient/mock_coordinatorclient.go @@ -12,7 +12,7 @@ import ( treechangeproto "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" coordinatorclient "github.com/anyproto/any-sync/coordinator/coordinatorclient" coordinatorproto "github.com/anyproto/any-sync/coordinator/coordinatorproto" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockCoordinatorClient is a mock of CoordinatorClient interface. diff --git a/go.mod b/go.mod index 925e5cd6..2a10036c 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,6 @@ require ( github.com/gobwas/glob v0.2.3 github.com/goccy/go-graphviz v0.1.1 github.com/gogo/protobuf v1.3.2 - github.com/golang/mock v1.6.0 github.com/google/uuid v1.3.0 github.com/hashicorp/yamux v0.1.1 github.com/huandu/skiplist v1.2.0 @@ -34,6 +33,7 @@ require ( github.com/tyler-smith/go-bip39 v1.1.0 github.com/zeebo/blake3 v0.2.3 go.uber.org/atomic v1.11.0 + go.uber.org/mock v0.2.0 go.uber.org/zap v1.24.0 golang.org/x/crypto v0.10.0 golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 diff --git a/go.sum b/go.sum index e36885d7..8afce3ca 100644 --- a/go.sum +++ b/go.sum @@ -54,7 +54,6 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69 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/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.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= @@ -281,6 +280,8 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.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/mock v0.2.0 h1:TaP3xedm7JaAgScZO7tlvlKrqT0p7I6OsdGB5YNSMDU= +go.uber.org/mock v0.2.0/go.mod h1:J0y0rp9L3xiff1+ZBfKxlC1fz2+aO16tw0tsDOixfuM= 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.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -365,7 +366,6 @@ golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtn 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.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= diff --git a/net/peer/mock_peer/mock_peer.go b/net/peer/mock_peer/mock_peer.go index dc0a5b6a..5d6531b4 100644 --- a/net/peer/mock_peer/mock_peer.go +++ b/net/peer/mock_peer/mock_peer.go @@ -9,7 +9,7 @@ import ( reflect "reflect" time "time" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" drpc "storj.io/drpc" ) diff --git a/net/peer/peer_test.go b/net/peer/peer_test.go index 7aa8428c..a5275876 100644 --- a/net/peer/peer_test.go +++ b/net/peer/peer_test.go @@ -6,9 +6,9 @@ import ( "github.com/anyproto/any-sync/net/secureservice/handshake" "github.com/anyproto/any-sync/net/secureservice/handshake/handshakeproto" "github.com/anyproto/any-sync/net/transport/mock_transport" - "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" "io" "net" _ "net/http/pprof" diff --git a/net/pool/mock_pool/mock_pool.go b/net/pool/mock_pool/mock_pool.go index be884903..7a304053 100644 --- a/net/pool/mock_pool/mock_pool.go +++ b/net/pool/mock_pool/mock_pool.go @@ -9,7 +9,7 @@ import ( reflect "reflect" peer "github.com/anyproto/any-sync/net/peer" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockPool is a mock of Pool interface. diff --git a/net/secureservice/secureservice_test.go b/net/secureservice/secureservice_test.go index 86735f66..0a6675dd 100644 --- a/net/secureservice/secureservice_test.go +++ b/net/secureservice/secureservice_test.go @@ -9,9 +9,9 @@ import ( "github.com/anyproto/any-sync/nodeconf" "github.com/anyproto/any-sync/nodeconf/mock_nodeconf" "github.com/anyproto/any-sync/testutil/testnodeconf" - "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" "net" "testing" ) diff --git a/net/transport/mock_transport/mock_transport.go b/net/transport/mock_transport/mock_transport.go index e0428014..ddc13ea4 100644 --- a/net/transport/mock_transport/mock_transport.go +++ b/net/transport/mock_transport/mock_transport.go @@ -10,7 +10,7 @@ import ( reflect "reflect" transport "github.com/anyproto/any-sync/net/transport" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockTransport is a mock of Transport interface. diff --git a/net/transport/yamux/yamux_test.go b/net/transport/yamux/yamux_test.go index 9b209054..1fd6ba3a 100644 --- a/net/transport/yamux/yamux_test.go +++ b/net/transport/yamux/yamux_test.go @@ -10,9 +10,9 @@ import ( "github.com/anyproto/any-sync/nodeconf/mock_nodeconf" "github.com/anyproto/any-sync/testutil/accounttest" "github.com/anyproto/any-sync/testutil/testnodeconf" - "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" "io" "net" "sync" diff --git a/nodeconf/mock_nodeconf/mock_nodeconf.go b/nodeconf/mock_nodeconf/mock_nodeconf.go index 353bf921..9b4c7d58 100644 --- a/nodeconf/mock_nodeconf/mock_nodeconf.go +++ b/nodeconf/mock_nodeconf/mock_nodeconf.go @@ -11,7 +11,7 @@ import ( app "github.com/anyproto/any-sync/app" nodeconf "github.com/anyproto/any-sync/nodeconf" chash "github.com/anyproto/go-chash" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockService is a mock of Service interface. diff --git a/util/periodicsync/mock_periodicsync/mock_periodicsync.go b/util/periodicsync/mock_periodicsync/mock_periodicsync.go index d34d6162..909b32e1 100644 --- a/util/periodicsync/mock_periodicsync/mock_periodicsync.go +++ b/util/periodicsync/mock_periodicsync/mock_periodicsync.go @@ -7,7 +7,7 @@ package mock_periodicsync import ( reflect "reflect" - gomock "github.com/golang/mock/gomock" + gomock "go.uber.org/mock/gomock" ) // MockPeriodicSync is a mock of PeriodicSync interface. diff --git a/util/periodicsync/periodicsync_test.go b/util/periodicsync/periodicsync_test.go index 35dd848c..f45a940b 100644 --- a/util/periodicsync/periodicsync_test.go +++ b/util/periodicsync/periodicsync_test.go @@ -3,8 +3,8 @@ package periodicsync import ( "context" "github.com/anyproto/any-sync/app/logger" - "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" "testing" "time" ) From 9dde29a28087034d06ed2ded168df7a2f12e921f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jul 2023 15:25:50 +0000 Subject: [PATCH 113/123] Bump golang.org/x/crypto from 0.10.0 to 0.11.0 Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.10.0 to 0.11.0. - [Commits](https://github.com/golang/crypto/compare/v0.10.0...v0.11.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 4 ++-- go.sum | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 925e5cd6..6a332551 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ require ( github.com/zeebo/blake3 v0.2.3 go.uber.org/atomic v1.11.0 go.uber.org/zap v1.24.0 - golang.org/x/crypto v0.10.0 + golang.org/x/crypto v0.11.0 golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 golang.org/x/net v0.11.0 gopkg.in/yaml.v3 v3.0.1 @@ -99,7 +99,7 @@ require ( go.uber.org/multierr v1.11.0 // indirect golang.org/x/image v0.6.0 // indirect golang.org/x/sync v0.2.0 // indirect - golang.org/x/sys v0.9.0 // indirect + golang.org/x/sys v0.10.0 // indirect golang.org/x/tools v0.9.3 // indirect google.golang.org/protobuf v1.30.0 // indirect lukechampine.com/blake3 v1.2.1 // indirect diff --git a/go.sum b/go.sum index e36885d7..209eaf0a 100644 --- a/go.sum +++ b/go.sum @@ -298,8 +298,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= -golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/image v0.6.0 h1:bR8b5okrPI3g/gyZakLZHeWxAR8Dn5CyxXv1hLH5g/4= @@ -346,8 +346,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= -golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/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/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -356,7 +356,7 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= 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-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= From fc0c3d54f162266f6f7e1ed3debffcf436f7d984 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jul 2023 15:26:07 +0000 Subject: [PATCH 114/123] Bump golang.org/x/net from 0.11.0 to 0.12.0 Bumps [golang.org/x/net](https://github.com/golang/net) from 0.11.0 to 0.12.0. - [Commits](https://github.com/golang/net/compare/v0.11.0...v0.12.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 6 +++--- go.sum | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index 925e5cd6..6b0292df 100644 --- a/go.mod +++ b/go.mod @@ -35,9 +35,9 @@ require ( github.com/zeebo/blake3 v0.2.3 go.uber.org/atomic v1.11.0 go.uber.org/zap v1.24.0 - golang.org/x/crypto v0.10.0 + golang.org/x/crypto v0.11.0 golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 - golang.org/x/net v0.11.0 + golang.org/x/net v0.12.0 gopkg.in/yaml.v3 v3.0.1 storj.io/drpc v0.0.33 ) @@ -99,7 +99,7 @@ require ( go.uber.org/multierr v1.11.0 // indirect golang.org/x/image v0.6.0 // indirect golang.org/x/sync v0.2.0 // indirect - golang.org/x/sys v0.9.0 // indirect + golang.org/x/sys v0.10.0 // indirect golang.org/x/tools v0.9.3 // indirect google.golang.org/protobuf v1.30.0 // indirect lukechampine.com/blake3 v1.2.1 // indirect diff --git a/go.sum b/go.sum index e36885d7..4553f426 100644 --- a/go.sum +++ b/go.sum @@ -298,8 +298,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= -golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/image v0.6.0 h1:bR8b5okrPI3g/gyZakLZHeWxAR8Dn5CyxXv1hLH5g/4= @@ -321,8 +321,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= -golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= +golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= +golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/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= @@ -346,8 +346,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= -golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/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/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -356,7 +356,7 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= 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-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= From 94aea5bafb4ecfee417f73e6115e789c0b8dab19 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Mon, 10 Jul 2023 23:17:05 +0200 Subject: [PATCH 115/123] Expose Acl in space --- commonspace/object/acl/list/list.go | 16 +++++++++ commonspace/object/acl/list/list_test.go | 42 +++++++---------------- commonspace/object/acl/syncacl/syncacl.go | 4 +-- commonspace/space.go | 5 +++ 4 files changed, 36 insertions(+), 31 deletions(-) diff --git a/commonspace/object/acl/list/list.go b/commonspace/object/acl/list/list.go index 12d3bed8..a2177ea4 100644 --- a/commonspace/object/acl/list/list.go +++ b/commonspace/object/acl/list/list.go @@ -10,6 +10,7 @@ import ( "github.com/anyproto/any-sync/commonspace/object/accountdata" "github.com/anyproto/any-sync/commonspace/object/acl/liststorage" "github.com/anyproto/any-sync/consensus/consensusproto" + "github.com/anyproto/any-sync/util/cidutil" "github.com/anyproto/any-sync/util/crypto" ) @@ -319,3 +320,18 @@ func (a *aclList) IterateFrom(startId string, iterFunc IterFunc) { func (a *aclList) Close(ctx context.Context) (err error) { return nil } + +func WrapAclRecord(rawRec *consensusproto.RawRecord) *consensusproto.RawRecordWithId { + payload, err := rawRec.Marshal() + if err != nil { + panic(err) + } + id, err := cidutil.NewCidFromBytes(payload) + if err != nil { + panic(err) + } + return &consensusproto.RawRecordWithId{ + Payload: payload, + Id: id, + } +} diff --git a/commonspace/object/acl/list/list_test.go b/commonspace/object/acl/list/list_test.go index b1dda008..6ce4ea86 100644 --- a/commonspace/object/acl/list/list_test.go +++ b/commonspace/object/acl/list/list_test.go @@ -7,26 +7,10 @@ import ( "github.com/anyproto/any-sync/commonspace/object/accountdata" "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" "github.com/anyproto/any-sync/consensus/consensusproto" - "github.com/anyproto/any-sync/util/cidutil" "github.com/anyproto/any-sync/util/crypto" "github.com/stretchr/testify/require" ) -func wrapRecord(rawRec *consensusproto.RawRecord) *consensusproto.RawRecordWithId { - payload, err := rawRec.Marshal() - if err != nil { - panic(err) - } - id, err := cidutil.NewCidFromBytes(payload) - if err != nil { - panic(err) - } - return &consensusproto.RawRecordWithId{ - Payload: payload, - Id: id, - } -} - type aclFixture struct { ownerKeys *accountdata.AccountKeys accountKeys *accountdata.AccountKeys @@ -71,7 +55,7 @@ func (fx *aclFixture) inviteAccount(t *testing.T, perms AclPermissions) { // building invite inv, err := ownerAcl.RecordBuilder().BuildInvite() require.NoError(t, err) - inviteRec := wrapRecord(inv.InviteRec) + inviteRec := WrapAclRecord(inv.InviteRec) fx.addRec(t, inviteRec) // building request join @@ -80,7 +64,7 @@ func (fx *aclFixture) inviteAccount(t *testing.T, perms AclPermissions) { InviteKey: inv.InviteKey, }) require.NoError(t, err) - requestJoinRec := wrapRecord(requestJoin) + requestJoinRec := WrapAclRecord(requestJoin) fx.addRec(t, requestJoinRec) // building request accept @@ -92,7 +76,7 @@ func (fx *aclFixture) inviteAccount(t *testing.T, perms AclPermissions) { // validate err = ownerAcl.ValidateRawRecord(requestAccept) require.NoError(t, err) - requestAcceptRec := wrapRecord(requestAccept) + requestAcceptRec := WrapAclRecord(requestAccept) fx.addRec(t, requestAcceptRec) // checking acl state @@ -132,13 +116,13 @@ func TestAclList_InviteRevoke(t *testing.T) { // building invite inv, err := fx.ownerAcl.RecordBuilder().BuildInvite() require.NoError(t, err) - inviteRec := wrapRecord(inv.InviteRec) + inviteRec := WrapAclRecord(inv.InviteRec) fx.addRec(t, inviteRec) // building invite revoke inviteRevoke, err := fx.ownerAcl.RecordBuilder().BuildInviteRevoke(ownerState.lastRecordId) require.NoError(t, err) - inviteRevokeRec := wrapRecord(inviteRevoke) + inviteRevokeRec := WrapAclRecord(inviteRevoke) fx.addRec(t, inviteRevokeRec) // checking acl state @@ -159,7 +143,7 @@ func TestAclList_RequestDecline(t *testing.T) { // building invite inv, err := ownerAcl.RecordBuilder().BuildInvite() require.NoError(t, err) - inviteRec := wrapRecord(inv.InviteRec) + inviteRec := WrapAclRecord(inv.InviteRec) fx.addRec(t, inviteRec) // building request join @@ -168,13 +152,13 @@ func TestAclList_RequestDecline(t *testing.T) { InviteKey: inv.InviteKey, }) require.NoError(t, err) - requestJoinRec := wrapRecord(requestJoin) + requestJoinRec := WrapAclRecord(requestJoin) fx.addRec(t, requestJoinRec) // building request decline requestDecline, err := ownerAcl.RecordBuilder().BuildRequestDecline(ownerState.lastRecordId) require.NoError(t, err) - requestDeclineRec := wrapRecord(requestDecline) + requestDeclineRec := WrapAclRecord(requestDecline) fx.addRec(t, requestDeclineRec) // checking acl state @@ -198,7 +182,7 @@ func TestAclList_Remove(t *testing.T) { ReadKey: newReadKey, }) require.NoError(t, err) - removeRec := wrapRecord(remove) + removeRec := WrapAclRecord(remove) fx.addRec(t, removeRec) // checking acl state @@ -225,7 +209,7 @@ func TestAclList_ReadKeyChange(t *testing.T) { newReadKey := crypto.NewAES() readKeyChange, err := fx.ownerAcl.RecordBuilder().BuildReadKeyChange(newReadKey) require.NoError(t, err) - readKeyRec := wrapRecord(readKeyChange) + readKeyRec := WrapAclRecord(readKeyChange) fx.addRec(t, readKeyRec) // checking acl state @@ -255,7 +239,7 @@ func TestAclList_PermissionChange(t *testing.T) { Permissions: AclPermissions(aclrecordproto.AclUserPermissions_Writer), }) require.NoError(t, err) - permissionChangeRec := wrapRecord(permissionChange) + permissionChangeRec := WrapAclRecord(permissionChange) fx.addRec(t, permissionChangeRec) // checking acl state @@ -279,7 +263,7 @@ func TestAclList_RequestRemove(t *testing.T) { removeRequest, err := fx.accountAcl.RecordBuilder().BuildRequestRemove() require.NoError(t, err) - removeRequestRec := wrapRecord(removeRequest) + removeRequestRec := WrapAclRecord(removeRequest) fx.addRec(t, removeRequestRec) recs := fx.accountAcl.AclState().RemoveRecords() @@ -292,7 +276,7 @@ func TestAclList_RequestRemove(t *testing.T) { ReadKey: newReadKey, }) require.NoError(t, err) - removeRec := wrapRecord(remove) + removeRec := WrapAclRecord(remove) fx.addRec(t, removeRec) // checking acl state diff --git a/commonspace/object/acl/syncacl/syncacl.go b/commonspace/object/acl/syncacl/syncacl.go index bd63c095..98e61127 100644 --- a/commonspace/object/acl/syncacl/syncacl.go +++ b/commonspace/object/acl/syncacl/syncacl.go @@ -46,7 +46,7 @@ func (s *SyncAcl) Run(ctx context.Context) (err error) { } func (s *SyncAcl) HandleRequest(ctx context.Context, senderId string, request *spacesyncproto.ObjectSyncMessage) (response *spacesyncproto.ObjectSyncMessage, err error) { - return s.HandleRequest(ctx, senderId, request) + return s.syncHandler.HandleRequest(ctx, senderId, request) } func (s *SyncAcl) SetHeadUpdater(updater HeadUpdater) { @@ -54,7 +54,7 @@ func (s *SyncAcl) SetHeadUpdater(updater HeadUpdater) { } func (s *SyncAcl) HandleMessage(ctx context.Context, senderId string, request *spacesyncproto.ObjectSyncMessage) (err error) { - return s.HandleMessage(ctx, senderId, request) + return s.syncHandler.HandleMessage(ctx, senderId, request) } func (s *SyncAcl) Init(a *app.App) (err error) { diff --git a/commonspace/space.go b/commonspace/space.go index ef5119de..d2d6d486 100644 --- a/commonspace/space.go +++ b/commonspace/space.go @@ -59,6 +59,7 @@ func NewSpaceId(id string, repKey uint64) string { type Space interface { Id() string Init(ctx context.Context) error + Acl() list.AclList StoredIds() []string DebugAllHeads() []headsync.TreeHeads @@ -153,6 +154,10 @@ func (s *space) TreeBuilder() objecttreebuilder.TreeBuilder { return s.treeBuilder } +func (s *space) Acl() list.AclList { + return s.aclList +} + func (s *space) Id() string { return s.state.SpaceId } From b4cc8d0a6161c9ab63b6b4e3a757f1f754232ba3 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Mon, 10 Jul 2023 23:47:29 +0200 Subject: [PATCH 116/123] Change head sync update behaviour --- commonspace/object/acl/syncacl/aclsyncprotocol.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/commonspace/object/acl/syncacl/aclsyncprotocol.go b/commonspace/object/acl/syncacl/aclsyncprotocol.go index 6f0b2542..68ebeeae 100644 --- a/commonspace/object/acl/syncacl/aclsyncprotocol.go +++ b/commonspace/object/acl/syncacl/aclsyncprotocol.go @@ -54,10 +54,10 @@ func (a *aclSyncProtocol) HeadUpdate(ctx context.Context, senderId string, updat return } err = a.aclList.AddRawRecords(update.Records) - if err != nil && err != list.ErrIncorrectRecordSequence { - return + if err == list.ErrIncorrectRecordSequence { + return a.reqFactory.CreateFullSyncRequest(a.aclList, update.Head) } - return a.reqFactory.CreateFullSyncRequest(a.aclList, update.Head) + return } func (a *aclSyncProtocol) FullSyncRequest(ctx context.Context, senderId string, request *consensusproto.LogFullSyncRequest) (response *consensusproto.LogSyncMessage, err error) { From ebf4034ec770bf70b45bc1e332ee26ad35e1432a Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Tue, 11 Jul 2023 12:02:15 +0200 Subject: [PATCH 117/123] consensus: fix race --- consensus/consensusclient/client.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/consensus/consensusclient/client.go b/consensus/consensusclient/client.go index a17c7a83..d745bef6 100644 --- a/consensus/consensusclient/client.go +++ b/consensus/consensusclient/client.go @@ -212,6 +212,7 @@ func (s *service) streamReader() error { if len(events) == 0 { return s.stream.Err() } + s.mu.Lock() for _, e := range events { if w, ok := s.watchers[e.LogId]; ok { if e.Error == nil { @@ -223,6 +224,7 @@ func (s *service) streamReader() error { log.Warn("received unexpected log id", zap.String("logId", e.LogId)) } } + s.mu.Unlock() } } From 098120da84a952e77c44730473d140d0b64d5f4e Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Tue, 11 Jul 2023 13:58:59 +0200 Subject: [PATCH 118/123] Update headsync tests --- commonspace/headsync/diffsyncer.go | 2 +- commonspace/headsync/diffsyncer_test.go | 2 +- commonspace/headsync/headsync.go | 4 +-- commonspace/headsync/headsync_test.go | 13 ++++++- .../object/acl/syncacl/aclsyncprotocol.go | 1 + commonspace/object/acl/syncacl/syncacl.go | 35 ++++++++++++------- commonspace/objectmanager/objectmanager.go | 2 +- commonspace/objecttreebuilder/treebuilder.go | 2 +- 8 files changed, 41 insertions(+), 20 deletions(-) diff --git a/commonspace/headsync/diffsyncer.go b/commonspace/headsync/diffsyncer.go index 98dfa74b..810ca5db 100644 --- a/commonspace/headsync/diffsyncer.go +++ b/commonspace/headsync/diffsyncer.go @@ -57,7 +57,7 @@ type diffSyncer struct { credentialProvider credentialprovider.CredentialProvider syncStatus syncstatus.StatusUpdater treeSyncer treemanager.TreeSyncer - syncAcl *syncacl.SyncAcl + syncAcl syncacl.SyncAcl } func (d *diffSyncer) Init() { diff --git a/commonspace/headsync/diffsyncer_test.go b/commonspace/headsync/diffsyncer_test.go index 6603dd98..fece9e63 100644 --- a/commonspace/headsync/diffsyncer_test.go +++ b/commonspace/headsync/diffsyncer_test.go @@ -14,8 +14,8 @@ import ( "github.com/anyproto/any-sync/commonspace/spacesyncproto" "github.com/anyproto/any-sync/consensus/consensusproto" "github.com/anyproto/any-sync/net/peer" - "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" "storj.io/drpc" ) diff --git a/commonspace/headsync/headsync.go b/commonspace/headsync/headsync.go index 1cc0c485..d7a1d74f 100644 --- a/commonspace/headsync/headsync.go +++ b/commonspace/headsync/headsync.go @@ -62,7 +62,7 @@ type headSync struct { credentialProvider credentialprovider.CredentialProvider syncStatus syncstatus.StatusService deletionState deletionstate.ObjectDeletionState - syncAcl *syncacl.SyncAcl + syncAcl syncacl.SyncAcl } func New() HeadSync { @@ -74,7 +74,7 @@ var createDiffSyncer = newDiffSyncer func (h *headSync) Init(a *app.App) (err error) { shared := a.MustComponent(spacestate.CName).(*spacestate.SpaceState) cfg := a.MustComponent("config").(config2.ConfigGetter) - h.syncAcl = a.MustComponent(syncacl.CName).(*syncacl.SyncAcl) + h.syncAcl = a.MustComponent(syncacl.CName).(syncacl.SyncAcl) h.spaceId = shared.SpaceId h.spaceIsDeleted = shared.SpaceIsDeleted h.syncPeriod = cfg.GetSpace().SyncPeriod diff --git a/commonspace/headsync/headsync_test.go b/commonspace/headsync/headsync_test.go index 4f14d084..1f37419a 100644 --- a/commonspace/headsync/headsync_test.go +++ b/commonspace/headsync/headsync_test.go @@ -11,6 +11,9 @@ import ( "github.com/anyproto/any-sync/commonspace/deletionstate" "github.com/anyproto/any-sync/commonspace/deletionstate/mock_deletionstate" "github.com/anyproto/any-sync/commonspace/headsync/mock_headsync" + "github.com/anyproto/any-sync/commonspace/object/acl/list" + "github.com/anyproto/any-sync/commonspace/object/acl/syncacl" + "github.com/anyproto/any-sync/commonspace/object/acl/syncacl/mock_syncacl" "github.com/anyproto/any-sync/commonspace/object/tree/treestorage/mock_treestorage" "github.com/anyproto/any-sync/commonspace/object/treemanager" "github.com/anyproto/any-sync/commonspace/object/treemanager/mock_treemanager" @@ -23,8 +26,8 @@ import ( "github.com/anyproto/any-sync/commonspace/syncstatus" "github.com/anyproto/any-sync/nodeconf" "github.com/anyproto/any-sync/nodeconf/mock_nodeconf" - "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" "sync/atomic" "testing" ) @@ -60,6 +63,7 @@ type headSyncFixture struct { treeSyncerMock *mock_treemanager.MockTreeSyncer diffMock *mock_ldiff.MockDiff clientMock *mock_spacesyncproto.MockDRPCSpaceSyncClient + aclMock *mock_syncacl.MockSyncAcl headSync *headSync diffSyncer *diffSyncer } @@ -87,9 +91,13 @@ func newHeadSyncFixture(t *testing.T) *headSyncFixture { treeSyncerMock := mock_treemanager.NewMockTreeSyncer(ctrl) diffMock := mock_ldiff.NewMockDiff(ctrl) clientMock := mock_spacesyncproto.NewMockDRPCSpaceSyncClient(ctrl) + aclMock := mock_syncacl.NewMockSyncAcl(ctrl) + aclMock.EXPECT().Name().AnyTimes().Return(syncacl.CName) + aclMock.EXPECT().SetHeadUpdater(gomock.Any()).AnyTimes() hs := &headSync{} a := &app.App{} a.Register(spaceState). + Register(aclMock). Register(mockConfig{}). Register(configurationMock). Register(storageMock). @@ -115,6 +123,7 @@ func newHeadSyncFixture(t *testing.T) *headSyncFixture { treeSyncerMock: treeSyncerMock, diffMock: diffMock, clientMock: clientMock, + aclMock: aclMock, } } @@ -144,6 +153,8 @@ func TestHeadSync(t *testing.T) { treeMock := mock_treestorage.NewMockTreeStorage(fx.ctrl) fx.storageMock.EXPECT().StoredIds().Return(ids, nil) fx.storageMock.EXPECT().TreeStorage(ids[0]).Return(treeMock, nil) + fx.aclMock.EXPECT().Id().AnyTimes().Return("aclId") + fx.aclMock.EXPECT().Head().AnyTimes().Return(&list.AclRecord{Id: "headId"}) treeMock.EXPECT().Heads().Return([]string{"h1", "h2"}, nil) fx.diffMock.EXPECT().Set(ldiff.Element{ Id: "id1", diff --git a/commonspace/object/acl/syncacl/aclsyncprotocol.go b/commonspace/object/acl/syncacl/aclsyncprotocol.go index 68ebeeae..0b856b49 100644 --- a/commonspace/object/acl/syncacl/aclsyncprotocol.go +++ b/commonspace/object/acl/syncacl/aclsyncprotocol.go @@ -1,3 +1,4 @@ +//go:generate mockgen -destination mock_syncacl/mock_syncacl.go github.com/anyproto/any-sync/commonspace/object/acl/syncacl SyncAcl,SyncClient,RequestFactory,AclSyncProtocol package syncacl import ( diff --git a/commonspace/object/acl/syncacl/syncacl.go b/commonspace/object/acl/syncacl/syncacl.go index 98e61127..a612e5c5 100644 --- a/commonspace/object/acl/syncacl/syncacl.go +++ b/commonspace/object/acl/syncacl/syncacl.go @@ -3,6 +3,7 @@ package syncacl import ( "context" "errors" + "github.com/anyproto/any-sync/commonspace/object/syncobjectgetter" "github.com/anyproto/any-sync/accountservice" "github.com/anyproto/any-sync/app" @@ -25,15 +26,23 @@ var ( ErrSyncAclClosed = errors.New("sync acl is closed") ) -func New() *SyncAcl { - return &SyncAcl{} +type SyncAcl interface { + app.ComponentRunnable + list.AclList + syncobjectgetter.SyncObject + SetHeadUpdater(updater HeadUpdater) + SyncWithPeer(ctx context.Context, peerId string) (err error) +} + +func New() SyncAcl { + return &syncAcl{} } type HeadUpdater interface { UpdateHeads(id string, heads []string) } -type SyncAcl struct { +type syncAcl struct { list.AclList syncClient SyncClient syncHandler synchandler.SyncHandler @@ -41,23 +50,23 @@ type SyncAcl struct { isClosed bool } -func (s *SyncAcl) Run(ctx context.Context) (err error) { +func (s *syncAcl) Run(ctx context.Context) (err error) { return } -func (s *SyncAcl) HandleRequest(ctx context.Context, senderId string, request *spacesyncproto.ObjectSyncMessage) (response *spacesyncproto.ObjectSyncMessage, err error) { +func (s *syncAcl) HandleRequest(ctx context.Context, senderId string, request *spacesyncproto.ObjectSyncMessage) (response *spacesyncproto.ObjectSyncMessage, err error) { return s.syncHandler.HandleRequest(ctx, senderId, request) } -func (s *SyncAcl) SetHeadUpdater(updater HeadUpdater) { +func (s *syncAcl) SetHeadUpdater(updater HeadUpdater) { s.headUpdater = updater } -func (s *SyncAcl) HandleMessage(ctx context.Context, senderId string, request *spacesyncproto.ObjectSyncMessage) (err error) { +func (s *syncAcl) HandleMessage(ctx context.Context, senderId string, request *spacesyncproto.ObjectSyncMessage) (err error) { return s.syncHandler.HandleMessage(ctx, senderId, request) } -func (s *SyncAcl) Init(a *app.App) (err error) { +func (s *syncAcl) Init(a *app.App) (err error) { storage := a.MustComponent(spacestorage.CName).(spacestorage.SpaceStorage) aclStorage, err := storage.AclStorage() if err != nil { @@ -77,7 +86,7 @@ func (s *SyncAcl) Init(a *app.App) (err error) { return err } -func (s *SyncAcl) AddRawRecord(rawRec *consensusproto.RawRecordWithId) (err error) { +func (s *syncAcl) AddRawRecord(rawRec *consensusproto.RawRecordWithId) (err error) { if s.isClosed { return ErrSyncAclClosed } @@ -91,7 +100,7 @@ func (s *SyncAcl) AddRawRecord(rawRec *consensusproto.RawRecordWithId) (err erro return } -func (s *SyncAcl) AddRawRecords(rawRecords []*consensusproto.RawRecordWithId) (err error) { +func (s *syncAcl) AddRawRecords(rawRecords []*consensusproto.RawRecordWithId) (err error) { if s.isClosed { return ErrSyncAclClosed } @@ -105,20 +114,20 @@ func (s *SyncAcl) AddRawRecords(rawRecords []*consensusproto.RawRecordWithId) (e return } -func (s *SyncAcl) SyncWithPeer(ctx context.Context, peerId string) (err error) { +func (s *syncAcl) SyncWithPeer(ctx context.Context, peerId string) (err error) { s.Lock() defer s.Unlock() headUpdate := s.syncClient.CreateHeadUpdate(s, nil) return s.syncClient.SendUpdate(peerId, headUpdate) } -func (s *SyncAcl) Close(ctx context.Context) (err error) { +func (s *syncAcl) Close(ctx context.Context) (err error) { s.Lock() defer s.Unlock() s.isClosed = true return } -func (s *SyncAcl) Name() (name string) { +func (s *syncAcl) Name() (name string) { return CName } diff --git a/commonspace/objectmanager/objectmanager.go b/commonspace/objectmanager/objectmanager.go index 49637818..3ebef3d5 100644 --- a/commonspace/objectmanager/objectmanager.go +++ b/commonspace/objectmanager/objectmanager.go @@ -41,7 +41,7 @@ func (o *objectManager) Init(a *app.App) (err error) { o.spaceId = state.SpaceId o.spaceIsClosed = state.SpaceIsClosed settingsObject := a.MustComponent(settings.CName).(settings.Settings).SettingsObject() - acl := a.MustComponent(syncacl.CName).(*syncacl.SyncAcl) + acl := a.MustComponent(syncacl.CName).(syncacl.SyncAcl) o.AddObject(settingsObject) o.AddObject(acl) return nil diff --git a/commonspace/objecttreebuilder/treebuilder.go b/commonspace/objecttreebuilder/treebuilder.go index 640416a7..8f3d09d8 100644 --- a/commonspace/objecttreebuilder/treebuilder.go +++ b/commonspace/objecttreebuilder/treebuilder.go @@ -82,7 +82,7 @@ func (t *treeBuilder) Init(a *app.App) (err error) { t.isClosed = state.SpaceIsClosed t.treesUsed = state.TreesUsed t.builder = state.TreeBuilderFunc - t.aclList = a.MustComponent(syncacl.CName).(*syncacl.SyncAcl) + t.aclList = a.MustComponent(syncacl.CName).(syncacl.SyncAcl) t.spaceStorage = a.MustComponent(spacestorage.CName).(spacestorage.SpaceStorage) t.configuration = a.MustComponent(nodeconf.CName).(nodeconf.NodeConf) t.headsNotifiable = a.MustComponent(headsync.CName).(headsync.HeadSync) From febfb72cec15813c487c916487a8abb3c3d0f55c Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Wed, 12 Jul 2023 12:09:55 +0200 Subject: [PATCH 119/123] Add diffsyncer tests --- commonspace/headsync/diffsyncer_test.go | 26 +++++++++++++++++++ .../tree/synctree/synctreehandler_test.go | 1 + 2 files changed, 27 insertions(+) diff --git a/commonspace/headsync/diffsyncer_test.go b/commonspace/headsync/diffsyncer_test.go index fece9e63..21ab129b 100644 --- a/commonspace/headsync/diffsyncer_test.go +++ b/commonspace/headsync/diffsyncer_test.go @@ -109,6 +109,7 @@ func TestDiffSyncer(t *testing.T) { fx.initDiffSyncer(t) defer fx.stop() mPeer := mockPeer{} + fx.aclMock.EXPECT().Id().AnyTimes().Return("aclId") fx.peerManagerMock.EXPECT(). GetResponsiblePeers(gomock.Any()). Return([]peer.Peer{mPeer}, nil) @@ -122,6 +123,26 @@ func TestDiffSyncer(t *testing.T) { require.NoError(t, fx.diffSyncer.Sync(ctx)) }) + t.Run("diff syncer sync, acl changed", func(t *testing.T) { + fx := newHeadSyncFixture(t) + fx.initDiffSyncer(t) + defer fx.stop() + mPeer := mockPeer{} + fx.aclMock.EXPECT().Id().AnyTimes().Return("aclId") + fx.peerManagerMock.EXPECT(). + GetResponsiblePeers(gomock.Any()). + Return([]peer.Peer{mPeer}, nil) + fx.diffMock.EXPECT(). + Diff(gomock.Any(), gomock.Eq(NewRemoteDiff(fx.spaceState.SpaceId, fx.clientMock))). + Return([]string{"new"}, []string{"changed"}, nil, nil) + fx.deletionStateMock.EXPECT().Filter([]string{"new"}).Return([]string{"new"}).Times(1) + fx.deletionStateMock.EXPECT().Filter([]string{"changed"}).Return([]string{"changed", "aclId"}).Times(1) + fx.deletionStateMock.EXPECT().Filter(nil).Return(nil).Times(1) + fx.treeSyncerMock.EXPECT().SyncAll(gomock.Any(), mPeer.Id(), []string{"changed"}, []string{"new"}).Return(nil) + fx.aclMock.EXPECT().SyncWithPeer(gomock.Any(), mPeer.Id()).Return(nil) + require.NoError(t, fx.diffSyncer.Sync(ctx)) + }) + t.Run("diff syncer sync conf error", func(t *testing.T) { fx := newHeadSyncFixture(t) fx.initDiffSyncer(t) @@ -139,6 +160,7 @@ func TestDiffSyncer(t *testing.T) { fx.initDiffSyncer(t) defer fx.stop() deletedId := "id" + fx.aclMock.EXPECT().Id().AnyTimes().Return("aclId") fx.deletionStateMock.EXPECT().Exists(deletedId).Return(true) // this should not result in any mock being called @@ -152,6 +174,7 @@ func TestDiffSyncer(t *testing.T) { newId := "newId" newHeads := []string{"h1", "h2"} hash := "hash" + fx.aclMock.EXPECT().Id().AnyTimes().Return("aclId") fx.diffMock.EXPECT().Set(ldiff.Element{ Id: newId, Head: concatStrings(newHeads), @@ -166,6 +189,7 @@ func TestDiffSyncer(t *testing.T) { fx := newHeadSyncFixture(t) fx.initDiffSyncer(t) defer fx.stop() + fx.aclMock.EXPECT().Id().AnyTimes().Return("aclId") aclStorageMock := mock_liststorage.NewMockListStorage(fx.ctrl) settingsStorage := mock_treestorage.NewMockTreeStorage(fx.ctrl) settingsId := "settingsId" @@ -211,6 +235,7 @@ func TestDiffSyncer(t *testing.T) { fx := newHeadSyncFixture(t) fx.initDiffSyncer(t) defer fx.stop() + fx.aclMock.EXPECT().Id().AnyTimes().Return("aclId") fx.peerManagerMock.EXPECT(). GetResponsiblePeers(gomock.Any()). Return([]peer.Peer{mockPeer{}}, nil) @@ -226,6 +251,7 @@ func TestDiffSyncer(t *testing.T) { fx.initDiffSyncer(t) defer fx.stop() mPeer := mockPeer{} + fx.aclMock.EXPECT().Id().AnyTimes().Return("aclId") fx.peerManagerMock.EXPECT(). GetResponsiblePeers(gomock.Any()). Return([]peer.Peer{mPeer}, nil) diff --git a/commonspace/object/tree/synctree/synctreehandler_test.go b/commonspace/object/tree/synctree/synctreehandler_test.go index c4ca45a5..ac8d07d0 100644 --- a/commonspace/object/tree/synctree/synctreehandler_test.go +++ b/commonspace/object/tree/synctree/synctreehandler_test.go @@ -8,6 +8,7 @@ import ( "github.com/anyproto/any-sync/commonspace/object/tree/objecttree/mock_objecttree" "github.com/anyproto/any-sync/commonspace/object/tree/synctree/mock_synctree" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" + "github.com/anyproto/any-sync/commonspace/spacesyncproto" "github.com/anyproto/any-sync/commonspace/syncstatus" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" From 22ec754ca7283d29a18ac35992095f439ed28b9a Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Wed, 12 Jul 2023 14:12:00 +0200 Subject: [PATCH 120/123] Add sync protocol tests --- .../object/acl/list/mock_list/mock_list.go | 54 ++++- .../object/acl/syncacl/aclsyncprotocol.go | 14 +- .../acl/syncacl/aclsyncprotocol_test.go | 213 ++++++++++++++++++ .../acl/syncacl/headupdater/headupdater.go | 5 + .../acl/syncacl/mock_syncacl/mock_syncacl.go | 4 +- commonspace/object/acl/syncacl/syncacl.go | 11 +- 6 files changed, 283 insertions(+), 18 deletions(-) create mode 100644 commonspace/object/acl/syncacl/aclsyncprotocol_test.go create mode 100644 commonspace/object/acl/syncacl/headupdater/headupdater.go diff --git a/commonspace/object/acl/list/mock_list/mock_list.go b/commonspace/object/acl/list/mock_list/mock_list.go index 3e5b50be..6cdccac9 100644 --- a/commonspace/object/acl/list/mock_list/mock_list.go +++ b/commonspace/object/acl/list/mock_list/mock_list.go @@ -5,6 +5,7 @@ package mock_list import ( + context "context" reflect "reflect" list "github.com/anyproto/any-sync/commonspace/object/acl/list" @@ -64,18 +65,32 @@ func (mr *MockAclListMockRecorder) AddRawRecord(arg0 interface{}) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRawRecord", reflect.TypeOf((*MockAclList)(nil).AddRawRecord), arg0) } -// Close mocks base method. -func (m *MockAclList) Close() error { +// AddRawRecords mocks base method. +func (m *MockAclList) AddRawRecords(arg0 []*consensusproto.RawRecordWithId) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Close") + ret := m.ctrl.Call(m, "AddRawRecords", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// AddRawRecords indicates an expected call of AddRawRecords. +func (mr *MockAclListMockRecorder) AddRawRecords(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRawRecords", reflect.TypeOf((*MockAclList)(nil).AddRawRecords), arg0) +} + +// Close mocks base method. +func (m *MockAclList) 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 *MockAclListMockRecorder) Close() *gomock.Call { +func (mr *MockAclListMockRecorder) Close(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockAclList)(nil).Close)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockAclList)(nil).Close), arg0) } // Get mocks base method. @@ -108,6 +123,20 @@ func (mr *MockAclListMockRecorder) GetIndex(arg0 interface{}) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetIndex", reflect.TypeOf((*MockAclList)(nil).GetIndex), arg0) } +// HasHead mocks base method. +func (m *MockAclList) HasHead(arg0 string) bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HasHead", arg0) + ret0, _ := ret[0].(bool) + return ret0 +} + +// HasHead indicates an expected call of HasHead. +func (mr *MockAclListMockRecorder) HasHead(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasHead", reflect.TypeOf((*MockAclList)(nil).HasHead), arg0) +} + // Head mocks base method. func (m *MockAclList) Head() *list.AclRecord { m.ctrl.T.Helper() @@ -253,6 +282,21 @@ func (mr *MockAclListMockRecorder) Records() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Records", reflect.TypeOf((*MockAclList)(nil).Records)) } +// RecordsAfter mocks base method. +func (m *MockAclList) RecordsAfter(arg0 context.Context, arg1 string) ([]*consensusproto.RawRecordWithId, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RecordsAfter", arg0, arg1) + ret0, _ := ret[0].([]*consensusproto.RawRecordWithId) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// RecordsAfter indicates an expected call of RecordsAfter. +func (mr *MockAclListMockRecorder) RecordsAfter(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecordsAfter", reflect.TypeOf((*MockAclList)(nil).RecordsAfter), arg0, arg1) +} + // Root mocks base method. func (m *MockAclList) Root() *consensusproto.RawRecordWithId { m.ctrl.T.Helper() diff --git a/commonspace/object/acl/syncacl/aclsyncprotocol.go b/commonspace/object/acl/syncacl/aclsyncprotocol.go index 0b856b49..22fd3a0c 100644 --- a/commonspace/object/acl/syncacl/aclsyncprotocol.go +++ b/commonspace/object/acl/syncacl/aclsyncprotocol.go @@ -76,10 +76,16 @@ func (a *aclSyncProtocol) FullSyncRequest(ctx context.Context, senderId string, log.DebugCtx(ctx, "acl full sync response sent", zap.String("response head", cnt.Head), zap.Int("len(response records)", len(cnt.Records))) } }() - if len(request.Records) > 0 && !a.aclList.HasHead(request.Head) { - err = a.aclList.AddRawRecords(request.Records) - if err != nil { - return + if !a.aclList.HasHead(request.Head) { + if len(request.Records) > 0 { + // in this case we can try to add some records + err = a.aclList.AddRawRecords(request.Records) + if err != nil { + return + } + } else { + // here it is impossible for us to do anything, we can't return records after head as defined in request, because we don't have it + return nil, list.ErrIncorrectRecordSequence } } return a.reqFactory.CreateFullSyncResponse(a.aclList, request.Head) diff --git a/commonspace/object/acl/syncacl/aclsyncprotocol_test.go b/commonspace/object/acl/syncacl/aclsyncprotocol_test.go new file mode 100644 index 00000000..1f861335 --- /dev/null +++ b/commonspace/object/acl/syncacl/aclsyncprotocol_test.go @@ -0,0 +1,213 @@ +package syncacl + +import ( + "context" + "github.com/anyproto/any-sync/app/logger" + "github.com/anyproto/any-sync/commonspace/object/acl/list" + "github.com/anyproto/any-sync/commonspace/object/acl/list/mock_list" + "github.com/anyproto/any-sync/commonspace/object/acl/syncacl/mock_syncacl" + "github.com/anyproto/any-sync/consensus/consensusproto" + "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" + "testing" +) + +type aclSyncProtocolFixture struct { + log logger.CtxLogger + spaceId string + senderId string + aclId string + aclMock *mock_list.MockAclList + reqFactory *mock_syncacl.MockRequestFactory + ctrl *gomock.Controller + syncProtocol AclSyncProtocol +} + +func newSyncProtocolFixture(t *testing.T) *aclSyncProtocolFixture { + ctrl := gomock.NewController(t) + aclList := mock_list.NewMockAclList(ctrl) + spaceId := "spaceId" + reqFactory := mock_syncacl.NewMockRequestFactory(ctrl) + aclList.EXPECT().Id().Return("aclId") + syncProtocol := newAclSyncProtocol(spaceId, aclList, reqFactory) + return &aclSyncProtocolFixture{ + log: log, + spaceId: spaceId, + senderId: "senderId", + aclId: "aclId", + aclMock: aclList, + reqFactory: reqFactory, + ctrl: ctrl, + syncProtocol: syncProtocol, + } +} + +func (fx *aclSyncProtocolFixture) stop() { + fx.ctrl.Finish() +} + +func TestHeadUpdate(t *testing.T) { + ctx := context.Background() + fullRequest := &consensusproto.LogSyncMessage{ + Content: &consensusproto.LogSyncContentValue{ + Value: &consensusproto.LogSyncContentValue_FullSyncRequest{ + FullSyncRequest: &consensusproto.LogFullSyncRequest{}, + }, + }, + } + t.Run("head update non empty all heads added", func(t *testing.T) { + fx := newSyncProtocolFixture(t) + defer fx.stop() + chWithId := &consensusproto.RawRecordWithId{} + headUpdate := &consensusproto.LogHeadUpdate{ + Head: "h1", + Records: []*consensusproto.RawRecordWithId{chWithId}, + } + fx.aclMock.EXPECT().Id().AnyTimes().Return(fx.aclId) + fx.aclMock.EXPECT().HasHead("h1").Return(false) + fx.aclMock.EXPECT().AddRawRecords(headUpdate.Records).Return(nil) + req, err := fx.syncProtocol.HeadUpdate(ctx, fx.senderId, headUpdate) + require.Nil(t, req) + require.NoError(t, err) + }) + t.Run("head update results in full request", func(t *testing.T) { + fx := newSyncProtocolFixture(t) + defer fx.stop() + chWithId := &consensusproto.RawRecordWithId{} + headUpdate := &consensusproto.LogHeadUpdate{ + Head: "h1", + Records: []*consensusproto.RawRecordWithId{chWithId}, + } + fx.aclMock.EXPECT().Id().AnyTimes().Return(fx.aclId) + fx.aclMock.EXPECT().HasHead("h1").Return(false) + fx.aclMock.EXPECT().AddRawRecords(headUpdate.Records).Return(list.ErrIncorrectRecordSequence) + fx.reqFactory.EXPECT().CreateFullSyncRequest(fx.aclMock, headUpdate.Head).Return(fullRequest, nil) + req, err := fx.syncProtocol.HeadUpdate(ctx, fx.senderId, headUpdate) + require.Equal(t, fullRequest, req) + require.NoError(t, err) + }) + t.Run("head update old heads", func(t *testing.T) { + fx := newSyncProtocolFixture(t) + defer fx.stop() + chWithId := &consensusproto.RawRecordWithId{} + headUpdate := &consensusproto.LogHeadUpdate{ + Head: "h1", + Records: []*consensusproto.RawRecordWithId{chWithId}, + } + fx.aclMock.EXPECT().Id().AnyTimes().Return(fx.aclId) + fx.aclMock.EXPECT().HasHead("h1").Return(true) + req, err := fx.syncProtocol.HeadUpdate(ctx, fx.senderId, headUpdate) + require.Nil(t, req) + require.NoError(t, err) + }) + t.Run("head update empty equals", func(t *testing.T) { + fx := newSyncProtocolFixture(t) + defer fx.stop() + headUpdate := &consensusproto.LogHeadUpdate{ + Head: "h1", + } + fx.aclMock.EXPECT().Id().AnyTimes().Return(fx.aclId) + fx.aclMock.EXPECT().Head().Return(&list.AclRecord{Id: "h1"}) + req, err := fx.syncProtocol.HeadUpdate(ctx, fx.senderId, headUpdate) + require.Nil(t, req) + require.NoError(t, err) + }) + t.Run("head update empty results in full request", func(t *testing.T) { + fx := newSyncProtocolFixture(t) + defer fx.stop() + headUpdate := &consensusproto.LogHeadUpdate{ + Head: "h1", + } + fx.aclMock.EXPECT().Id().AnyTimes().Return(fx.aclId) + fx.aclMock.EXPECT().Head().Return(&list.AclRecord{Id: "h2"}) + fx.reqFactory.EXPECT().CreateFullSyncRequest(fx.aclMock, headUpdate.Head).Return(fullRequest, nil) + req, err := fx.syncProtocol.HeadUpdate(ctx, fx.senderId, headUpdate) + require.Equal(t, fullRequest, req) + require.NoError(t, err) + }) +} + +func TestFullSyncRequest(t *testing.T) { + ctx := context.Background() + fullResponse := &consensusproto.LogSyncMessage{ + Content: &consensusproto.LogSyncContentValue{ + Value: &consensusproto.LogSyncContentValue_FullSyncResponse{ + FullSyncResponse: &consensusproto.LogFullSyncResponse{}, + }, + }, + } + t.Run("full sync request non empty all heads added", func(t *testing.T) { + fx := newSyncProtocolFixture(t) + defer fx.stop() + chWithId := &consensusproto.RawRecordWithId{} + fullRequest := &consensusproto.LogFullSyncRequest{ + Head: "h1", + Records: []*consensusproto.RawRecordWithId{chWithId}, + } + fx.aclMock.EXPECT().Id().AnyTimes().Return(fx.aclId) + fx.aclMock.EXPECT().HasHead("h1").Return(false) + fx.aclMock.EXPECT().AddRawRecords(fullRequest.Records).Return(nil) + fx.reqFactory.EXPECT().CreateFullSyncResponse(fx.aclMock, fullRequest.Head).Return(fullResponse, nil) + resp, err := fx.syncProtocol.FullSyncRequest(ctx, fx.senderId, fullRequest) + require.Equal(t, fullResponse, resp) + require.NoError(t, err) + }) + t.Run("full sync request non empty head exists", func(t *testing.T) { + fx := newSyncProtocolFixture(t) + defer fx.stop() + chWithId := &consensusproto.RawRecordWithId{} + fullRequest := &consensusproto.LogFullSyncRequest{ + Head: "h1", + Records: []*consensusproto.RawRecordWithId{chWithId}, + } + fx.aclMock.EXPECT().Id().AnyTimes().Return(fx.aclId) + fx.aclMock.EXPECT().HasHead("h1").Return(true) + fx.reqFactory.EXPECT().CreateFullSyncResponse(fx.aclMock, fullRequest.Head).Return(fullResponse, nil) + resp, err := fx.syncProtocol.FullSyncRequest(ctx, fx.senderId, fullRequest) + require.Equal(t, fullResponse, resp) + require.NoError(t, err) + }) + t.Run("full sync request empty head not exists", func(t *testing.T) { + fx := newSyncProtocolFixture(t) + defer fx.stop() + fullRequest := &consensusproto.LogFullSyncRequest{ + Head: "h1", + } + fx.aclMock.EXPECT().Id().AnyTimes().Return(fx.aclId) + fx.aclMock.EXPECT().HasHead("h1").Return(false) + resp, err := fx.syncProtocol.FullSyncRequest(ctx, fx.senderId, fullRequest) + require.Nil(t, resp) + require.Error(t, list.ErrIncorrectRecordSequence, err) + }) +} + +func TestFullSyncResponse(t *testing.T) { + ctx := context.Background() + t.Run("full sync response no heads", func(t *testing.T) { + fx := newSyncProtocolFixture(t) + defer fx.stop() + chWithId := &consensusproto.RawRecordWithId{} + fullResponse := &consensusproto.LogFullSyncResponse{ + Head: "h1", + Records: []*consensusproto.RawRecordWithId{chWithId}, + } + fx.aclMock.EXPECT().Id().AnyTimes().Return(fx.aclId) + fx.aclMock.EXPECT().HasHead("h1").Return(false) + fx.aclMock.EXPECT().AddRawRecords(fullResponse.Records).Return(nil) + err := fx.syncProtocol.FullSyncResponse(ctx, fx.senderId, fullResponse) + require.NoError(t, err) + }) + t.Run("full sync response has heads", func(t *testing.T) { + fx := newSyncProtocolFixture(t) + defer fx.stop() + chWithId := &consensusproto.RawRecordWithId{} + fullResponse := &consensusproto.LogFullSyncResponse{ + Head: "h1", + Records: []*consensusproto.RawRecordWithId{chWithId}, + } + fx.aclMock.EXPECT().Id().AnyTimes().Return(fx.aclId) + fx.aclMock.EXPECT().HasHead("h1").Return(true) + err := fx.syncProtocol.FullSyncResponse(ctx, fx.senderId, fullResponse) + require.NoError(t, err) + }) +} diff --git a/commonspace/object/acl/syncacl/headupdater/headupdater.go b/commonspace/object/acl/syncacl/headupdater/headupdater.go new file mode 100644 index 00000000..64c41f41 --- /dev/null +++ b/commonspace/object/acl/syncacl/headupdater/headupdater.go @@ -0,0 +1,5 @@ +package headupdater + +type HeadUpdater interface { + UpdateHeads(id string, heads []string) +} diff --git a/commonspace/object/acl/syncacl/mock_syncacl/mock_syncacl.go b/commonspace/object/acl/syncacl/mock_syncacl/mock_syncacl.go index a7ca877c..66d16b9d 100644 --- a/commonspace/object/acl/syncacl/mock_syncacl/mock_syncacl.go +++ b/commonspace/object/acl/syncacl/mock_syncacl/mock_syncacl.go @@ -10,7 +10,7 @@ import ( app "github.com/anyproto/any-sync/app" list "github.com/anyproto/any-sync/commonspace/object/acl/list" - syncacl "github.com/anyproto/any-sync/commonspace/object/acl/syncacl" + headupdater "github.com/anyproto/any-sync/commonspace/object/acl/syncacl/headupdater" spacesyncproto "github.com/anyproto/any-sync/commonspace/spacesyncproto" consensusproto "github.com/anyproto/any-sync/consensus/consensusproto" crypto "github.com/anyproto/any-sync/util/crypto" @@ -386,7 +386,7 @@ func (mr *MockSyncAclMockRecorder) Run(arg0 interface{}) *gomock.Call { } // SetHeadUpdater mocks base method. -func (m *MockSyncAcl) SetHeadUpdater(arg0 syncacl.HeadUpdater) { +func (m *MockSyncAcl) SetHeadUpdater(arg0 headupdater.HeadUpdater) { m.ctrl.T.Helper() m.ctrl.Call(m, "SetHeadUpdater", arg0) } diff --git a/commonspace/object/acl/syncacl/syncacl.go b/commonspace/object/acl/syncacl/syncacl.go index a612e5c5..23592490 100644 --- a/commonspace/object/acl/syncacl/syncacl.go +++ b/commonspace/object/acl/syncacl/syncacl.go @@ -3,6 +3,7 @@ package syncacl import ( "context" "errors" + "github.com/anyproto/any-sync/commonspace/object/acl/syncacl/headupdater" "github.com/anyproto/any-sync/commonspace/object/syncobjectgetter" "github.com/anyproto/any-sync/accountservice" @@ -30,7 +31,7 @@ type SyncAcl interface { app.ComponentRunnable list.AclList syncobjectgetter.SyncObject - SetHeadUpdater(updater HeadUpdater) + SetHeadUpdater(updater headupdater.HeadUpdater) SyncWithPeer(ctx context.Context, peerId string) (err error) } @@ -38,15 +39,11 @@ func New() SyncAcl { return &syncAcl{} } -type HeadUpdater interface { - UpdateHeads(id string, heads []string) -} - type syncAcl struct { list.AclList syncClient SyncClient syncHandler synchandler.SyncHandler - headUpdater HeadUpdater + headUpdater headupdater.HeadUpdater isClosed bool } @@ -58,7 +55,7 @@ func (s *syncAcl) HandleRequest(ctx context.Context, senderId string, request *s return s.syncHandler.HandleRequest(ctx, senderId, request) } -func (s *syncAcl) SetHeadUpdater(updater HeadUpdater) { +func (s *syncAcl) SetHeadUpdater(updater headupdater.HeadUpdater) { s.headUpdater = updater } From e08b3ba6592afc8c3ad5ece6199e5d8753e82161 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Wed, 12 Jul 2023 15:58:41 +0200 Subject: [PATCH 121/123] Add syncaclhandler tests --- .../object/acl/syncacl/syncaclhandler_test.go | 233 ++++++++++++++++++ .../tree/synctree/synctreehandler_test.go | 2 +- 2 files changed, 234 insertions(+), 1 deletion(-) create mode 100644 commonspace/object/acl/syncacl/syncaclhandler_test.go diff --git a/commonspace/object/acl/syncacl/syncaclhandler_test.go b/commonspace/object/acl/syncacl/syncaclhandler_test.go new file mode 100644 index 00000000..bdff2e83 --- /dev/null +++ b/commonspace/object/acl/syncacl/syncaclhandler_test.go @@ -0,0 +1,233 @@ +package syncacl + +import ( + "context" + "fmt" + "github.com/anyproto/any-sync/commonspace/object/acl/list/mock_list" + "github.com/anyproto/any-sync/commonspace/object/acl/syncacl/mock_syncacl" + "github.com/anyproto/any-sync/commonspace/spacesyncproto" + "github.com/anyproto/any-sync/commonspace/syncstatus" + "github.com/anyproto/any-sync/consensus/consensusproto" + "github.com/gogo/protobuf/proto" + "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" + "sync" + "testing" +) + +type testAclMock struct { + *mock_list.MockAclList + m sync.RWMutex +} + +func newTestAclMock(mockAcl *mock_list.MockAclList) *testAclMock { + return &testAclMock{ + MockAclList: mockAcl, + } +} + +func (t *testAclMock) Lock() { + t.m.Lock() +} + +func (t *testAclMock) RLock() { + t.m.RLock() +} + +func (t *testAclMock) Unlock() { + t.m.Unlock() +} + +func (t *testAclMock) RUnlock() { + t.m.RUnlock() +} + +func (t *testAclMock) TryLock() bool { + return t.m.TryLock() +} + +func (t *testAclMock) TryRLock() bool { + return t.m.TryRLock() +} + +type syncHandlerFixture struct { + ctrl *gomock.Controller + syncClientMock *mock_syncacl.MockSyncClient + aclMock *testAclMock + syncProtocolMock *mock_syncacl.MockAclSyncProtocol + spaceId string + senderId string + aclId string + + syncHandler *syncAclHandler +} + +func newSyncHandlerFixture(t *testing.T) *syncHandlerFixture { + ctrl := gomock.NewController(t) + aclMock := newTestAclMock(mock_list.NewMockAclList(ctrl)) + syncClientMock := mock_syncacl.NewMockSyncClient(ctrl) + syncProtocolMock := mock_syncacl.NewMockAclSyncProtocol(ctrl) + spaceId := "spaceId" + + syncHandler := &syncAclHandler{ + aclList: aclMock, + syncClient: syncClientMock, + syncProtocol: syncProtocolMock, + syncStatus: syncstatus.NewNoOpSyncStatus(), + spaceId: spaceId, + } + return &syncHandlerFixture{ + ctrl: ctrl, + syncClientMock: syncClientMock, + aclMock: aclMock, + syncProtocolMock: syncProtocolMock, + spaceId: spaceId, + senderId: "senderId", + aclId: "aclId", + syncHandler: syncHandler, + } +} + +func (fx *syncHandlerFixture) stop() { + fx.ctrl.Finish() +} + +func TestSyncAclHandler_HandleMessage(t *testing.T) { + ctx := context.Background() + t.Run("handle head update, request returned", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() + chWithId := &consensusproto.RawRecordWithId{} + headUpdate := &consensusproto.LogHeadUpdate{ + Head: "h1", + Records: []*consensusproto.RawRecordWithId{chWithId}, + } + logMessage := consensusproto.WrapHeadUpdate(headUpdate, chWithId) + objectMsg, _ := spacesyncproto.MarshallSyncMessage(logMessage, fx.spaceId, fx.aclId) + + syncReq := &consensusproto.LogSyncMessage{} + fx.aclMock.EXPECT().Id().AnyTimes().Return(fx.aclId) + fx.syncProtocolMock.EXPECT().HeadUpdate(ctx, fx.senderId, gomock.Any()).Return(syncReq, nil) + fx.syncClientMock.EXPECT().QueueRequest(fx.senderId, syncReq).Return(nil) + + err := fx.syncHandler.HandleMessage(ctx, fx.senderId, objectMsg) + require.NoError(t, err) + }) + t.Run("handle head update, no request", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() + chWithId := &consensusproto.RawRecordWithId{} + headUpdate := &consensusproto.LogHeadUpdate{ + Head: "h1", + Records: []*consensusproto.RawRecordWithId{chWithId}, + } + logMessage := consensusproto.WrapHeadUpdate(headUpdate, chWithId) + objectMsg, _ := spacesyncproto.MarshallSyncMessage(logMessage, fx.spaceId, fx.aclId) + + fx.aclMock.EXPECT().Id().AnyTimes().Return(fx.aclId) + fx.syncProtocolMock.EXPECT().HeadUpdate(ctx, fx.senderId, gomock.Any()).Return(nil, nil) + + err := fx.syncHandler.HandleMessage(ctx, fx.senderId, objectMsg) + require.NoError(t, err) + }) + t.Run("handle head update, returned error", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() + chWithId := &consensusproto.RawRecordWithId{} + headUpdate := &consensusproto.LogHeadUpdate{ + Head: "h1", + Records: []*consensusproto.RawRecordWithId{chWithId}, + } + logMessage := consensusproto.WrapHeadUpdate(headUpdate, chWithId) + objectMsg, _ := spacesyncproto.MarshallSyncMessage(logMessage, fx.spaceId, fx.aclId) + + fx.aclMock.EXPECT().Id().AnyTimes().Return(fx.aclId) + expectedErr := fmt.Errorf("some error") + fx.syncProtocolMock.EXPECT().HeadUpdate(ctx, fx.senderId, gomock.Any()).Return(nil, expectedErr) + + err := fx.syncHandler.HandleMessage(ctx, fx.senderId, objectMsg) + require.Error(t, expectedErr, err) + }) + t.Run("handle full sync request is forbidden", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() + chWithId := &consensusproto.RawRecordWithId{} + fullRequest := &consensusproto.LogFullSyncRequest{ + Head: "h1", + Records: []*consensusproto.RawRecordWithId{chWithId}, + } + logMessage := consensusproto.WrapFullRequest(fullRequest, chWithId) + objectMsg, _ := spacesyncproto.MarshallSyncMessage(logMessage, fx.spaceId, fx.aclId) + + fx.aclMock.EXPECT().Id().AnyTimes().Return(fx.aclId) + err := fx.syncHandler.HandleMessage(ctx, fx.senderId, objectMsg) + require.Error(t, ErrMessageIsRequest, err) + }) + t.Run("handle full sync response, no error", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() + chWithId := &consensusproto.RawRecordWithId{} + fullResponse := &consensusproto.LogFullSyncResponse{ + Head: "h1", + Records: []*consensusproto.RawRecordWithId{chWithId}, + } + logMessage := consensusproto.WrapFullResponse(fullResponse, chWithId) + objectMsg, _ := spacesyncproto.MarshallSyncMessage(logMessage, fx.spaceId, fx.aclId) + + fx.aclMock.EXPECT().Id().AnyTimes().Return(fx.aclId) + fx.syncProtocolMock.EXPECT().FullSyncResponse(ctx, fx.senderId, gomock.Any()).Return(nil) + + err := fx.syncHandler.HandleMessage(ctx, fx.senderId, objectMsg) + require.NoError(t, err) + }) +} + +func TestSyncAclHandler_HandleRequest(t *testing.T) { + ctx := context.Background() + t.Run("handle full sync request, no error", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() + chWithId := &consensusproto.RawRecordWithId{} + fullRequest := &consensusproto.LogFullSyncRequest{ + Head: "h1", + Records: []*consensusproto.RawRecordWithId{chWithId}, + } + logMessage := consensusproto.WrapFullRequest(fullRequest, chWithId) + objectMsg, _ := spacesyncproto.MarshallSyncMessage(logMessage, fx.spaceId, fx.aclId) + fullResp := &consensusproto.LogSyncMessage{ + Content: &consensusproto.LogSyncContentValue{ + Value: &consensusproto.LogSyncContentValue_FullSyncResponse{ + FullSyncResponse: &consensusproto.LogFullSyncResponse{ + Head: "returnedHead", + }, + }, + }, + } + + fx.aclMock.EXPECT().Id().AnyTimes().Return(fx.aclId) + fx.syncProtocolMock.EXPECT().FullSyncRequest(ctx, fx.senderId, gomock.Any()).Return(fullResp, nil) + res, err := fx.syncHandler.HandleRequest(ctx, fx.senderId, objectMsg) + require.NoError(t, err) + unmarshalled := &consensusproto.LogSyncMessage{} + err = proto.Unmarshal(res.Payload, unmarshalled) + if err != nil { + return + } + require.Equal(t, "returnedHead", consensusproto.GetHead(unmarshalled)) + }) + t.Run("handle other message returns error", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() + chWithId := &consensusproto.RawRecordWithId{} + headUpdate := &consensusproto.LogHeadUpdate{ + Head: "h1", + Records: []*consensusproto.RawRecordWithId{chWithId}, + } + logMessage := consensusproto.WrapHeadUpdate(headUpdate, chWithId) + objectMsg, _ := spacesyncproto.MarshallSyncMessage(logMessage, fx.spaceId, fx.aclId) + + fx.aclMock.EXPECT().Id().AnyTimes().Return(fx.aclId) + _, err := fx.syncHandler.HandleRequest(ctx, fx.senderId, objectMsg) + require.Error(t, ErrMessageIsNotRequest, err) + }) +} diff --git a/commonspace/object/tree/synctree/synctreehandler_test.go b/commonspace/object/tree/synctree/synctreehandler_test.go index ac8d07d0..4152a698 100644 --- a/commonspace/object/tree/synctree/synctreehandler_test.go +++ b/commonspace/object/tree/synctree/synctreehandler_test.go @@ -137,7 +137,7 @@ func TestSyncTreeHandler_HandleMessage(t *testing.T) { require.NoError(t, err) }) - t.Run("handle head update message, empty sync request returned", func(t *testing.T) { + t.Run("handle head update message, no sync request returned", func(t *testing.T) { fx := newSyncHandlerFixture(t) defer fx.stop() treeId := "treeId" From 63e533efb5dc6a8b0391a0accf943459aa2abf2c Mon Sep 17 00:00:00 2001 From: Sergey Fuksman Date: Mon, 17 Jul 2023 10:09:29 +0300 Subject: [PATCH 122/123] Add README.md --- README.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..62e78090 --- /dev/null +++ b/README.md @@ -0,0 +1,43 @@ +# Any-Sync +Any-Sync is an open-source protocol designed to create high-performance, local-first, peer-to-peer, end-to-end encrypted applications that facilitate seamless collaboration among multiple users and devices. + +By utilizing this protocol, users can rest assured that they retain complete control over their data and digital experience. They are empowered to freely transition between various service providers, or even opt to self-host the applications. + +This ensures utmost flexibility and autonomy for users in managing their personal information and digital interactions. + +## Introduction +Most existing information management tools are implemented on centralized client-server architecture or designed for an offline-first single-user usage. Either way there are trade-offs for users: they can face restricted freedoms and privacy violations or compromise on the functionality of tools to avoid this. + +We believe this goes against fundamental digital freedoms and that a new generation of software is needed that will respect these freedoms, while providing best in-class user experience. + +Our goal with `any-sync` is to develop a protocol that will enable the deployment of this software. + +Features: +- Conflict-free data replication across multiple devices and agents +- Built-in end-to-end encryption +- Cryptographically verifiable history of changes +- Adoption to frequent operations (high performance) +- Reliable and scalable infrastructure +- Simultaneous support of p2p and remote communication + +## Protocol explanation +Plese read the [overview](https://tech.anytype.io/any-sync/overview) of protocol entities and design. + +## Implementation + +You can find the various parts of the protocol implemented in Go in the following repositories: +- [`any-sync-node`](https://github.com/anyproto/any-sync-node) — implementation of a sync node responsible for storing spaces and objects. +- [`any-sync-filenode`](https://github.com/anyproto/any-sync-filenode) — implementation of a file node responsible for storing files. +- [`any-sync-coordinator`](https://github.com/anyproto/any-sync-coordinator) — implementation of a coordinator node responsible for network configuration management. + +## Contribution +Thank you for your desire to develop Anytype together. + +Currently, we're not ready to accept PRs, but we will in the nearest future. + +Follow us on [Github](https://github.com/anyproto) and join the [Contributors Community](https://github.com/orgs/anyproto/discussions). + +--- +Made by Any — a Swiss association 🇨🇭 + +Licensed under [MIT License](./LICENSE). \ No newline at end of file From 735536068da74dc26dbab0065d87b3bd462e92e3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jul 2023 15:55:07 +0000 Subject: [PATCH 123/123] Bump github.com/libp2p/go-libp2p from 0.28.1 to 0.29.0 Bumps [github.com/libp2p/go-libp2p](https://github.com/libp2p/go-libp2p) from 0.28.1 to 0.29.0. - [Release notes](https://github.com/libp2p/go-libp2p/releases) - [Changelog](https://github.com/libp2p/go-libp2p/blob/master/CHANGELOG.md) - [Commits](https://github.com/libp2p/go-libp2p/compare/v0.28.1...v0.29.0) --- updated-dependencies: - dependency-name: github.com/libp2p/go-libp2p dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 10 ++++------ go.sum | 34 ++++++++++++++++------------------ 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/go.mod b/go.mod index c427571f..aa746768 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,7 @@ require ( github.com/ipfs/go-ipld-format v0.5.0 github.com/ipfs/go-merkledag v0.11.0 github.com/ipfs/go-unixfs v0.4.6 - github.com/libp2p/go-libp2p v0.28.1 + github.com/libp2p/go-libp2p v0.29.0 github.com/mr-tron/base58 v1.2.0 github.com/multiformats/go-multibase v0.2.0 github.com/multiformats/go-multihash v0.2.3 @@ -36,7 +36,7 @@ require ( go.uber.org/mock v0.2.0 go.uber.org/zap v1.24.0 golang.org/x/crypto v0.11.0 - golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 + golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 golang.org/x/net v0.12.0 gopkg.in/yaml.v3 v3.0.1 storj.io/drpc v0.0.33 @@ -79,7 +79,7 @@ require ( github.com/minio/sha256-simd v1.0.1 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect - github.com/multiformats/go-multiaddr v0.9.0 // indirect + github.com/multiformats/go-multiaddr v0.10.1 // indirect github.com/multiformats/go-multicodec v0.9.0 // indirect github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect @@ -90,7 +90,6 @@ require ( github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.44.0 // indirect github.com/prometheus/procfs v0.10.1 // indirect - github.com/quic-go/quic-go v0.35.1 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/zeebo/errs v1.3.0 // indirect @@ -98,9 +97,8 @@ require ( go.opentelemetry.io/otel/trace v1.7.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/image v0.6.0 // indirect - golang.org/x/sync v0.2.0 // indirect + golang.org/x/sync v0.3.0 // indirect golang.org/x/sys v0.10.0 // indirect - golang.org/x/tools v0.9.3 // indirect google.golang.org/protobuf v1.30.0 // indirect lukechampine.com/blake3 v1.2.1 // indirect ) diff --git a/go.sum b/go.sum index fcf81140..28c4b775 100644 --- a/go.sum +++ b/go.sum @@ -62,7 +62,7 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= -github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs= +github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 h1:n6vlPhxsA+BW/XsS5+uqi7GyzaLa5MH7qlSLBZtRdiA= 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= @@ -151,7 +151,7 @@ github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZl github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE= 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.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= +github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= @@ -165,21 +165,21 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 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-libp2p v0.28.1 h1:YurK+ZAI6cKfASLJBVFkpVBdl3wGhFi6fusOt725ii8= -github.com/libp2p/go-libp2p v0.28.1/go.mod h1:s3Xabc9LSwOcnv9UD4nORnXKTsWkPMkIMB/JIGXVnzk= +github.com/libp2p/go-libp2p v0.29.0 h1:QduJ2XQr/Crg4EnloueWDL0Jj86N3Ezhyyj7XH+XwHI= +github.com/libp2p/go-libp2p v0.29.0/go.mod h1:iNKL7mEnZ9wAss+03IjAwM9ZAQXfVUAPUUmOACQfQ/g= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= github.com/libp2p/go-nat v0.2.0 h1:Tyz+bUFAYqGyJ/ppPPymMGbIgNRH+WqC5QrT5fKrrGk= github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= -github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ= +github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCypkQ= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI= +github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= 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= @@ -194,8 +194,8 @@ github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aG github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= -github.com/multiformats/go-multiaddr v0.9.0 h1:3h4V1LHIk5w4hJHekMKWALPXErDfz/sggzwC/NcqbDQ= -github.com/multiformats/go-multiaddr v0.9.0/go.mod h1:mI67Lb1EeTOYb8GQfL/7wpIZwc46ElrvzhYnoJOmTT0= +github.com/multiformats/go-multiaddr v0.10.1 h1:HghtFrWyZEPrpTvgAMFJi6gFdgHfs2cb0pyfDsk+lqU= +github.com/multiformats/go-multiaddr v0.10.1/go.mod h1:jLEZsA61rwWNZQTHHnqq2HNa+4os/Hz54eqiRnsRqYQ= 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= @@ -214,7 +214,7 @@ github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/n github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5 h1:BvoENQQU+fZ9uukda/RzCAL/191HHwJA5b13R6diVlY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss= +github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= 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= @@ -235,8 +235,7 @@ github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPH github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc86Z5U= github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E= -github.com/quic-go/quic-go v0.35.1 h1:b0kzj6b/cQAf05cT0CkQubHM31wiA+xH3IBkxP62poo= -github.com/quic-go/quic-go v0.35.1/go.mod h1:+4CVgVppm0FNjpG3UcX8Joi/frKOH7/ciD5yGcwOO1g= +github.com/quic-go/quic-go v0.36.2 h1:ZX/UNQ4gvpCv2RmwdbA6lrRjF6EBm5yZ7TMoT4NQVrA= github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= @@ -301,8 +300,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= -golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= -golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= +golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw= +golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/image v0.6.0 h1:bR8b5okrPI3g/gyZakLZHeWxAR8Dn5CyxXv1hLH5g/4= golang.org/x/image v0.6.0/go.mod h1:MXLdDR43H7cDJq5GEGXEVeeNhPgi+YYEQ2pC1byI1x0= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -312,7 +311,7 @@ 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/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= 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= @@ -331,8 +330,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= -golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= 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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -369,8 +368,7 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM= -golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8= 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=