1
0
Fork 0
mirror of https://github.com/anyproto/any-sync.git synced 2025-06-08 05:57:03 +09:00
This commit is contained in:
Sergey Cherepanov 2024-02-15 19:12:28 +01:00
commit e86ba80a67
No known key found for this signature in database
GPG key ID: 87F8EDE8FBDF637C
21 changed files with 485 additions and 164 deletions

View file

@ -23,6 +23,7 @@ type AclJoiningClient interface {
app.Component
AclGetRecords(ctx context.Context, spaceId, aclHead string) ([]*consensusproto.RawRecordWithId, error)
RequestJoin(ctx context.Context, spaceId string, payload list.RequestJoinPayload) error
SendRecord(ctx context.Context, spaceId string, rec *consensusproto.RawRecord) (res *spacesyncproto.AclAddRecordResponse, err error)
}
type aclJoiningClient struct {
@ -113,6 +114,24 @@ func (c *aclJoiningClient) RequestJoin(ctx context.Context, spaceId string, payl
})
}
func (c *aclJoiningClient) SendRecord(ctx context.Context, spaceId string, rec *consensusproto.RawRecord) (res *spacesyncproto.AclAddRecordResponse, err error) {
marshalled, err := rec.Marshal()
if err != nil {
return
}
err = c.doClient(ctx, spaceId, func(cl spacesyncproto.DRPCSpaceSyncClient) error {
res, err = cl.AclAddRecord(ctx, &spacesyncproto.AclAddRecordRequest{
SpaceId: spaceId,
Payload: marshalled,
})
if err != nil {
return err
}
return nil
})
return
}
func (c *aclJoiningClient) doClient(ctx context.Context, spaceId string, f func(cl spacesyncproto.DRPCSpaceSyncClient) error) error {
p, err := c.pool.GetOneOf(ctx, c.nodeConf.NodeIds(spaceId))
if err != nil {

View file

@ -113,6 +113,9 @@ func (d *diffSyncer) Sync(ctx context.Context) error {
}
func (d *diffSyncer) syncWithPeer(ctx context.Context, p peer.Peer) (err error) {
if !d.treeSyncer.ShouldSync(p.Id()) {
return
}
ctx = logger.CtxWithFields(ctx, zap.String("peerId", p.Id()))
conn, err := p.AcquireDrpcConn(ctx)
if err != nil {

View file

@ -119,6 +119,7 @@ func TestDiffSyncer(t *testing.T) {
mPeer := mockPeer{}
remDiff := NewRemoteDiff(fx.spaceState.SpaceId, fx.clientMock)
fx.aclMock.EXPECT().Id().AnyTimes().Return("aclId")
fx.treeSyncerMock.EXPECT().ShouldSync(gomock.Any()).Return(true)
fx.peerManagerMock.EXPECT().
GetResponsiblePeers(gomock.Any()).
Return([]peer.Peer{mPeer}, nil)
@ -140,6 +141,7 @@ func TestDiffSyncer(t *testing.T) {
defer fx.stop()
mPeer := mockPeer{}
remDiff := NewRemoteDiff(fx.spaceState.SpaceId, fx.clientMock)
fx.treeSyncerMock.EXPECT().ShouldSync(gomock.Any()).Return(true)
fx.aclMock.EXPECT().Id().AnyTimes().Return("aclId")
fx.peerManagerMock.EXPECT().
GetResponsiblePeers(gomock.Any()).
@ -205,6 +207,7 @@ func TestDiffSyncer(t *testing.T) {
fx.initDiffSyncer(t)
defer fx.stop()
fx.aclMock.EXPECT().Id().AnyTimes().Return("aclId")
fx.treeSyncerMock.EXPECT().ShouldSync(gomock.Any()).Return(true)
aclStorageMock := mock_liststorage.NewMockListStorage(fx.ctrl)
settingsStorage := mock_treestorage.NewMockTreeStorage(fx.ctrl)
settingsId := "settingsId"
@ -255,6 +258,7 @@ func TestDiffSyncer(t *testing.T) {
defer fx.stop()
remDiff := NewRemoteDiff(fx.spaceState.SpaceId, fx.clientMock)
fx.aclMock.EXPECT().Id().AnyTimes().Return("aclId")
fx.treeSyncerMock.EXPECT().ShouldSync(gomock.Any()).Return(true)
fx.peerManagerMock.EXPECT().
GetResponsiblePeers(gomock.Any()).
Return([]peer.Peer{mockPeer{}}, nil)
@ -273,6 +277,7 @@ func TestDiffSyncer(t *testing.T) {
defer fx.stop()
mPeer := mockPeer{}
remDiff := NewRemoteDiff(fx.spaceState.SpaceId, fx.clientMock)
fx.treeSyncerMock.EXPECT().ShouldSync(gomock.Any()).Return(true)
fx.aclMock.EXPECT().Id().AnyTimes().Return("aclId")
fx.peerManagerMock.EXPECT().
GetResponsiblePeers(gomock.Any()).

View file

@ -1,6 +1,7 @@
package list
import (
"errors"
"time"
"github.com/gogo/protobuf/proto"
@ -509,6 +510,10 @@ func (a *aclRecordBuilder) BuildRequestRemove() (rawRecord *consensusproto.RawRe
err = ErrIsOwner
return
}
_, err = a.state.Record(a.state.pubKey)
if !errors.Is(err, ErrNoSuchRecord) {
return nil, ErrPendingRequest
}
removeRec := &aclrecordproto.AclAccountRequestRemove{}
content := &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_AccountRequestRemove{AccountRequestRemove: removeRec}}
return a.buildRecord(content)

View file

@ -163,7 +163,7 @@ func (st *AclState) PermissionsAtRecord(id string, pubKey crypto.PubKey) (AclPer
return perms, nil
}
func (st *AclState) CurrentStates() []AccountState {
func (st *AclState) CurrentAccounts() []AccountState {
var res []AccountState
for _, state := range st.accountStates {
res = append(res, state)
@ -171,6 +171,19 @@ func (st *AclState) CurrentStates() []AccountState {
return res
}
func (st *AclState) HadReadPermissions(identity crypto.PubKey) (had bool) {
state, exists := st.accountStates[mapKeyFromPubKey(identity)]
if !exists {
return false
}
for _, perm := range state.PermissionChanges {
if !perm.Permission.NoPermissions() {
return true
}
}
return false
}
func (st *AclState) Invites() []crypto.PubKey {
var invites []crypto.PubKey
for _, inv := range st.inviteKeys {

View file

@ -101,6 +101,7 @@ func TestAclExecutor(t *testing.T) {
// g can cancel request to remove
{"g.cancel:g", nil},
{"g.request_remove:g", nil},
{"g.request_remove:g", ErrPendingRequest},
{"a.remove:g", nil},
// g cannot cancel not existing request to remove
{"g.cancel:g", ErrNoSuchRecord},

View file

@ -247,6 +247,9 @@ func (c *contentValidator) ValidateRequestRemove(ch *aclrecordproto.AclAccountRe
if c.aclState.Permissions(authorIdentity).NoPermissions() {
return ErrInsufficientPermissions
}
if c.aclState.Permissions(authorIdentity).IsOwner() {
return ErrIsOwner
}
if _, exists := c.aclState.pendingRequests[mapKeyFromPubKey(authorIdentity)]; exists {
return ErrPendingRequest
}

View file

@ -1,12 +1,17 @@
package objecttree
import (
"github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto"
"github.com/gogo/protobuf/proto"
"github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto"
)
func IsEmptyDerivedTree(tree ObjectTree) bool {
return tree.IsDerived() && tree.Len() == 1 && tree.Root().Id == tree.Header().Id
return tree.IsDerived() && IsEmptyTree(tree)
}
func IsEmptyTree(tree ObjectTree) bool {
return tree.Len() == 1 && tree.Root().Id == tree.Header().Id
}
func IsDerivedRoot(root *treechangeproto.RawTreeChangeWithId) (derived bool, err error) {

View file

@ -366,6 +366,16 @@ func (ot *objectTree) addRawChanges(ctx context.Context, changesPayload RawChang
return
}
var (
filteredHeads = false
headsToUse = changesPayload.NewHeads
)
// if our validator provides filtering mechanism then we use it
filteredHeads, ot.newChangesBuf, ot.newSnapshotsBuf, ot.notSeenIdxBuf = ot.validator.FilterChanges(ot.aclList, changesPayload.NewHeads, ot.newChangesBuf, ot.newSnapshotsBuf, ot.notSeenIdxBuf)
if filteredHeads {
// if we filtered some of the heads, then we don't know which heads to use
headsToUse = []string{}
}
rollback := func(changes []*Change) {
for _, ch := range changes {
if _, exists := ot.tree.attached[ch.Id]; exists {
@ -400,7 +410,7 @@ func (ot *objectTree) addRawChanges(ctx context.Context, changesPayload RawChang
}
if shouldRebuildFromStorage {
err = ot.rebuildFromStorage(changesPayload.NewHeads, ot.newChangesBuf)
err = ot.rebuildFromStorage(headsToUse, ot.newChangesBuf)
if err != nil {
// rebuilding without new changes
ot.rebuildFromStorage(nil, nil)
@ -662,12 +672,15 @@ func (ot *objectTree) readKeysFromAclState(state *list.AclState) (err error) {
return nil
}
// if we can't read the keys anyway
if state.AccountKey() == nil || state.Permissions(state.AccountKey().GetPublic()).NoPermissions() {
if state.AccountKey() == nil || !state.HadReadPermissions(state.AccountKey().GetPublic()) {
return nil
}
for key, value := range state.Keys() {
if _, exists := ot.keys[key]; exists {
continue
}
if value.ReadKey == nil {
return list.ErrNoReadKey
continue
}
treeKey, err := deriveTreeKey(value.ReadKey, ot.id)
if err != nil {
@ -679,6 +692,9 @@ func (ot *objectTree) readKeysFromAclState(state *list.AclState) (err error) {
if err != nil {
return err
}
if curKey == nil {
return nil
}
ot.currentReadKey, err = deriveTreeKey(curKey, ot.id)
return err
}

View file

@ -25,6 +25,25 @@ type testTreeContext struct {
objTree ObjectTree
}
func genBuildFilterableTestableTree(filterFunc func(ch *Change) bool) func(treeStorage treestorage.TreeStorage, aclList list.AclList) (ObjectTree, error) {
return func(treeStorage treestorage.TreeStorage, aclList list.AclList) (ObjectTree, error) {
root, _ := treeStorage.Root()
changeBuilder := &nonVerifiableChangeBuilder{
ChangeBuilder: NewChangeBuilder(newMockKeyStorage(), root),
}
deps := objectTreeDeps{
changeBuilder: changeBuilder,
treeBuilder: newTreeBuilder(true, treeStorage, changeBuilder),
treeStorage: treeStorage,
rawChangeLoader: newRawChangeLoader(treeStorage, changeBuilder),
validator: &noOpTreeValidator{filterFunc: filterFunc},
aclList: aclList,
}
return buildObjectTree(deps)
}
}
func prepareAclList(t *testing.T) (list.AclList, *accountdata.AccountKeys) {
randKeys, err := accountdata.NewRandom()
require.NoError(t, err)
@ -129,7 +148,7 @@ func TestObjectTree(t *testing.T) {
}, aAccount.Acl)
require.NoError(t, err)
aStore, _ := treestorage.NewInMemoryTreeStorage(root, []string{root.Id}, []*treechangeproto.RawTreeChangeWithId{root})
aTree, err := BuildKeyVerifiableObjectTree(aStore, aAccount.Acl)
aTree, err := BuildKeyFilterableObjectTree(aStore, aAccount.Acl)
require.NoError(t, err)
_, err = aTree.AddContent(ctx, SignableChangeContent{
Data: []byte("some"),
@ -140,7 +159,7 @@ func TestObjectTree(t *testing.T) {
})
require.NoError(t, err)
bStore := aTree.Storage().(*treestorage.InMemoryTreeStorage).Copy()
bTree, err := BuildKeyVerifiableObjectTree(bStore, bAccount.Acl)
bTree, err := BuildKeyFilterableObjectTree(bStore, bAccount.Acl)
require.NoError(t, err)
err = exec.Execute("a.remove:b")
require.NoError(t, err)
@ -157,17 +176,17 @@ func TestObjectTree(t *testing.T) {
NewHeads: aTree.Heads(),
RawChanges: res.Added,
})
require.Equal(t, ErrHasInvalidChanges, err)
require.Equal(t, oldHeads, bTree.Heads())
bStore = aTree.Storage().(*treestorage.InMemoryTreeStorage).Copy()
root, _ = bStore.Root()
heads, _ := bStore.Heads()
err = ValidateRawTreeBuildFunc(treestorage.TreeStorageCreatePayload{
filteredPayload, err := ValidateFilterRawTree(treestorage.TreeStorageCreatePayload{
RootRawChange: root,
Changes: bStore.AllChanges(),
Heads: heads,
}, BuildKeyVerifiableObjectTree, bAccount.Acl)
require.Equal(t, ErrHasInvalidChanges, err)
}, bAccount.Acl)
require.NoError(t, err)
require.Equal(t, 2, len(filteredPayload.Changes))
err = aTree.IterateRoot(func(change *Change, decrypted []byte) (any, error) {
return nil, nil
}, func(change *Change) bool {
@ -667,6 +686,35 @@ func TestObjectTree(t *testing.T) {
})
})
t.Run("test tree filter", func(t *testing.T) {
filterFunc := func(change *Change) bool {
return slices.Contains([]string{"0", "1", "2", "3", "4", "7", "8"}, change.Id)
}
ctx := prepareContext(t, aclList, genBuildFilterableTestableTree(filterFunc), false, nil)
rawChanges := []*treechangeproto.RawTreeChangeWithId{
ctx.changeCreator.CreateRawWithData("1", aclList.Head().Id, "0", false, []byte("1"), "0"),
ctx.changeCreator.CreateRawWithData("2", aclList.Head().Id, "0", false, []byte("2"), "1"),
ctx.changeCreator.CreateRawWithData("3", aclList.Head().Id, "0", false, []byte("3"), "2"),
ctx.changeCreator.CreateRawWithData("4", aclList.Head().Id, "0", false, []byte("4"), "2"),
ctx.changeCreator.CreateRawWithData("5", aclList.Head().Id, "0", false, []byte("5"), "1"),
ctx.changeCreator.CreateRawWithData("6", aclList.Head().Id, "0", true, []byte("6"), "3", "4", "5"),
ctx.changeCreator.CreateRawWithData("7", aclList.Head().Id, "6", false, []byte("7"), "6"),
ctx.changeCreator.CreateRawWithData("8", aclList.Head().Id, "6", false, []byte("8"), "6"),
}
_, err := ctx.objTree.AddRawChanges(context.Background(), RawChangesPayload{
NewHeads: []string{"7", "8"},
RawChanges: rawChanges,
})
require.NoError(t, err)
var ids []string
ctx.objTree.IterateRoot(nil, func(change *Change) bool {
ids = append(ids, change.Id)
return true
})
slices.Sort(ids)
require.Equal(t, []string{"0", "1", "2", "3", "4"}, ids)
})
t.Run("rollback when add to storage returns error", func(t *testing.T) {
ctx := prepareTreeContext(t, aclList)
changeCreator := ctx.changeCreator

View file

@ -55,7 +55,7 @@ func verifiableTreeDeps(
changeBuilder: changeBuilder,
treeBuilder: treeBuilder,
treeStorage: treeStorage,
validator: newTreeValidator(false),
validator: newTreeValidator(false, false),
rawChangeLoader: newRawChangeLoader(treeStorage, changeBuilder),
aclList: aclList,
}
@ -71,7 +71,7 @@ func emptyDataTreeDeps(
changeBuilder: changeBuilder,
treeBuilder: treeBuilder,
treeStorage: treeStorage,
validator: newTreeValidator(false),
validator: newTreeValidator(false, false),
rawChangeLoader: newStorageLoader(treeStorage, changeBuilder),
aclList: aclList,
}
@ -136,13 +136,13 @@ func BuildEmptyDataTestableTree(treeStorage treestorage.TreeStorage, aclList lis
return buildObjectTree(deps)
}
func BuildKeyVerifiableObjectTree(treeStorage treestorage.TreeStorage, aclList list.AclList) (ObjectTree, error) {
func BuildKeyFilterableObjectTree(treeStorage treestorage.TreeStorage, aclList list.AclList) (ObjectTree, error) {
rootChange, err := treeStorage.Root()
if err != nil {
return nil, err
}
deps := defaultObjectTreeDeps(rootChange, treeStorage, aclList)
deps.validator = newTreeValidator(true)
deps.validator = newTreeValidator(true, true)
return buildObjectTree(deps)
}

View file

@ -9,14 +9,19 @@ import (
"github.com/anyproto/any-sync/util/slice"
)
type ValidatorFunc func(payload treestorage.TreeStorageCreatePayload, buildFunc BuildObjectTreeFunc, aclList list.AclList) (retPayload treestorage.TreeStorageCreatePayload, err error)
type ObjectTreeValidator interface {
// ValidateFullTree should always be entered while holding a read lock on AclList
ValidateFullTree(tree *Tree, aclList list.AclList) error
// ValidateNewChanges should always be entered while holding a read lock on AclList
ValidateNewChanges(tree *Tree, aclList list.AclList, newChanges []*Change) error
FilterChanges(aclList list.AclList, heads []string, changes []*Change, snapshots []*Change, indexes []int) (filteredHeads bool, filtered, filteredSnapshots []*Change, newIndexes []int)
}
type noOpTreeValidator struct{}
type noOpTreeValidator struct {
filterFunc func(ch *Change) bool
}
func (n *noOpTreeValidator) ValidateFullTree(tree *Tree, aclList list.AclList) error {
return nil
@ -26,13 +31,34 @@ func (n *noOpTreeValidator) ValidateNewChanges(tree *Tree, aclList list.AclList,
return nil
}
type objectTreeValidator struct {
validateKeys bool
func (n *noOpTreeValidator) FilterChanges(aclList list.AclList, heads []string, changes []*Change, snapshots []*Change, indexes []int) (filteredHeads bool, filtered, filteredSnapshots []*Change, newIndexes []int) {
if n.filterFunc == nil {
return false, changes, snapshots, indexes
}
for idx, c := range changes {
// only taking changes which we can read
if n.filterFunc(c) {
newIndexes = append(newIndexes, indexes[idx])
filtered = append(filtered, c)
if c.IsSnapshot {
filteredSnapshots = append(filteredSnapshots, c)
}
} else {
filteredHeads = true
}
}
return
}
func newTreeValidator(validateKeys bool) ObjectTreeValidator {
type objectTreeValidator struct {
validateKeys bool
shouldFilter bool
}
func newTreeValidator(validateKeys bool, filterChanges bool) ObjectTreeValidator {
return &objectTreeValidator{
validateKeys: validateKeys,
shouldFilter: filterChanges,
}
}
@ -54,6 +80,30 @@ func (v *objectTreeValidator) ValidateNewChanges(tree *Tree, aclList list.AclLis
return
}
func (v *objectTreeValidator) FilterChanges(aclList list.AclList, heads []string, changes []*Change, snapshots []*Change, indexes []int) (filteredHeads bool, filtered, filteredSnapshots []*Change, newIndexes []int) {
if !v.shouldFilter {
return false, changes, snapshots, indexes
}
aclList.RLock()
defer aclList.RUnlock()
state := aclList.AclState()
for idx, c := range changes {
// only taking changes which we can read
if keys, exists := state.Keys()[c.ReadKeyId]; exists && keys.ReadKey != nil {
newIndexes = append(newIndexes, indexes[idx])
filtered = append(filtered, c)
if c.IsSnapshot {
filteredSnapshots = append(filteredSnapshots, c)
}
} else {
// if we filtered at least one change this can be the change between heads and other changes
// thus we cannot use heads
filteredHeads = true
}
}
return
}
func (v *objectTreeValidator) validateChange(tree *Tree, aclList list.AclList, c *Change) (err error) {
var (
perms list.AclPermissions
@ -103,7 +153,7 @@ func (v *objectTreeValidator) validateChange(tree *Tree, aclList list.AclList, c
return
}
func ValidateRawTreeBuildFunc(payload treestorage.TreeStorageCreatePayload, buildFunc BuildObjectTreeFunc, aclList list.AclList) (err error) {
func ValidateRawTreeBuildFunc(payload treestorage.TreeStorageCreatePayload, buildFunc BuildObjectTreeFunc, aclList list.AclList) (newPayload treestorage.TreeStorageCreatePayload, err error) {
treeStorage, err := treestorage.NewInMemoryTreeStorage(payload.RootRawChange, []string{payload.RootRawChange.Id}, nil)
if err != nil {
return
@ -120,15 +170,48 @@ func ValidateRawTreeBuildFunc(payload treestorage.TreeStorageCreatePayload, buil
return
}
if !slice.UnsortedEquals(res.Heads, payload.Heads) {
return ErrHasInvalidChanges
return payload, ErrHasInvalidChanges
}
// if tree has only one change we still should check if the snapshot id is same as root
if IsEmptyDerivedTree(tree) {
return ErrDerived
return payload, ErrDerived
}
return payload, nil
}
func ValidateFilterRawTree(payload treestorage.TreeStorageCreatePayload, aclList list.AclList) (retPayload treestorage.TreeStorageCreatePayload, err error) {
aclList.RLock()
if !aclList.AclState().HadReadPermissions(aclList.AclState().Identity()) {
aclList.RUnlock()
return payload, list.ErrNoReadKey
}
aclList.RUnlock()
treeStorage, err := treestorage.NewInMemoryTreeStorage(payload.RootRawChange, []string{payload.RootRawChange.Id}, nil)
if err != nil {
return
}
tree, err := BuildKeyFilterableObjectTree(treeStorage, aclList)
if err != nil {
return
}
res, err := tree.AddRawChanges(context.Background(), RawChangesPayload{
NewHeads: payload.Heads,
RawChanges: payload.Changes,
})
if err != nil {
return
}
if IsEmptyTree(tree) {
return payload, ErrNoChangeInTree
}
return treestorage.TreeStorageCreatePayload{
RootRawChange: payload.RootRawChange,
Heads: res.Heads,
Changes: treeStorage.(*treestorage.InMemoryTreeStorage).AllChanges(),
}, nil
}
func ValidateRawTree(payload treestorage.TreeStorageCreatePayload, aclList list.AclList) (err error) {
return ValidateRawTreeBuildFunc(payload, BuildObjectTree, aclList)
_, err = ValidateRawTreeBuildFunc(payload, BuildObjectTree, aclList)
return
}

View file

@ -6,6 +6,8 @@ import (
"errors"
"time"
"go.uber.org/zap"
"github.com/anyproto/any-sync/app/logger"
"github.com/anyproto/any-sync/commonspace/object/acl/list"
"github.com/anyproto/any-sync/commonspace/object/tree/objecttree"
@ -16,7 +18,6 @@ import (
"github.com/anyproto/any-sync/commonspace/syncstatus"
"github.com/anyproto/any-sync/net/peer"
"github.com/anyproto/any-sync/nodeconf"
"go.uber.org/zap"
)
var (
@ -71,6 +72,7 @@ type BuildDeps struct {
SyncStatus syncstatus.StatusUpdater
PeerGetter ResponsiblePeersGetter
BuildObjectTree objecttree.BuildObjectTreeFunc
ValidateObjectTree objecttree.ValidatorFunc
}
func BuildSyncTreeOrGetRemote(ctx context.Context, id string, deps BuildDeps) (t SyncTree, err error) {

View file

@ -104,13 +104,17 @@ func (t treeRemoteGetter) getTree(ctx context.Context) (treeStorage treestorage.
Heads: fullSyncResp.Heads,
}
validatorFunc := t.deps.ValidateObjectTree
if validatorFunc == nil {
validatorFunc = objecttree.ValidateRawTreeBuildFunc
}
// basically building tree with in-memory storage and validating that it was without errors
log.With(zap.String("id", t.treeId)).DebugCtx(ctx, "validating tree")
err = objecttree.ValidateRawTreeBuildFunc(payload, t.deps.BuildObjectTree, t.deps.AclList)
newPayload, err := validatorFunc(payload, t.deps.BuildObjectTree, t.deps.AclList)
if err != nil {
return
}
// now we are sure that we can save it to the storage
treeStorage, err = t.deps.SpaceStorage.CreateTreeStorage(payload)
treeStorage, err = t.deps.SpaceStorage.CreateTreeStorage(newPayload)
return
}

View file

@ -5,7 +5,6 @@
//
// mockgen -destination mock_treesyncer/mock_treesyncer.go github.com/anyproto/any-sync/commonspace/object/treesyncer TreeSyncer
//
// Package mock_treesyncer is a generated GoMock package.
package mock_treesyncer
@ -96,6 +95,20 @@ func (mr *MockTreeSyncerMockRecorder) Run(arg0 any) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockTreeSyncer)(nil).Run), arg0)
}
// ShouldSync mocks base method.
func (m *MockTreeSyncer) ShouldSync(arg0 string) bool {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ShouldSync", arg0)
ret0, _ := ret[0].(bool)
return ret0
}
// ShouldSync indicates an expected call of ShouldSync.
func (mr *MockTreeSyncerMockRecorder) ShouldSync(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ShouldSync", reflect.TypeOf((*MockTreeSyncer)(nil).ShouldSync), arg0)
}
// StartSync mocks base method.
func (m *MockTreeSyncer) StartSync() {
m.ctrl.T.Helper()
@ -108,6 +121,18 @@ func (mr *MockTreeSyncerMockRecorder) StartSync() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartSync", reflect.TypeOf((*MockTreeSyncer)(nil).StartSync))
}
// StopSync mocks base method.
func (m *MockTreeSyncer) StopSync() {
m.ctrl.T.Helper()
m.ctrl.Call(m, "StopSync")
}
// StopSync indicates an expected call of StopSync.
func (mr *MockTreeSyncerMockRecorder) StopSync() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StopSync", reflect.TypeOf((*MockTreeSyncer)(nil).StopSync))
}
// SyncAll mocks base method.
func (m *MockTreeSyncer) SyncAll(arg0 context.Context, arg1 string, arg2, arg3 []string) error {
m.ctrl.T.Helper()

View file

@ -12,5 +12,7 @@ const CName = "common.object.treesyncer"
type TreeSyncer interface {
app.ComponentRunnable
StartSync()
StopSync()
ShouldSync(peerId string) bool
SyncAll(ctx context.Context, peerId string, existing, missing []string) error
}

View file

@ -6,6 +6,8 @@ import (
"errors"
"sync/atomic"
"go.uber.org/zap"
"github.com/anyproto/any-sync/app"
"github.com/anyproto/any-sync/app/logger"
"github.com/anyproto/any-sync/commonspace/headsync"
@ -23,12 +25,12 @@ import (
"github.com/anyproto/any-sync/commonspace/spacestorage"
"github.com/anyproto/any-sync/commonspace/syncstatus"
"github.com/anyproto/any-sync/nodeconf"
"go.uber.org/zap"
)
type BuildTreeOpts struct {
Listener updatelistener.UpdateListener
TreeBuilder objecttree.BuildObjectTreeFunc
TreeValidator objecttree.ValidatorFunc
}
const CName = "common.commonspace.objecttreebuilder"
@ -122,6 +124,7 @@ func (t *treeBuilder) BuildTree(ctx context.Context, id string, opts BuildTreeOp
SyncStatus: t.syncStatus,
PeerGetter: t.peerManager,
BuildObjectTree: treeBuilder,
ValidateObjectTree: opts.TreeValidator,
}
t.treesUsed.Add(1)
t.log.Debug("incrementing counter", zap.String("id", id), zap.Int32("trees", t.treesUsed.Load()))

View file

@ -4,9 +4,13 @@ import (
"context"
"errors"
"fmt"
"github.com/anyproto/any-sync/commonspace/deletionmanager"
"github.com/anyproto/any-sync/util/crypto"
"github.com/gogo/protobuf/proto"
"go.uber.org/zap"
"github.com/anyproto/any-sync/accountservice"
"github.com/anyproto/any-sync/app/logger"
"github.com/anyproto/any-sync/commonspace/object/tree/objecttree"
@ -18,8 +22,6 @@ import (
"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"
)
var log = logger.NewNamed("common.commonspace.settings")
@ -166,7 +168,10 @@ func (s *settingsObject) checkHistoryState(ctx context.Context) (err error) {
}
func (s *settingsObject) Close() error {
if s.SyncTree != nil {
return s.SyncTree.Close()
}
return nil
}
var isDerivedRoot = objecttree.IsDerivedRoot

View file

@ -6,6 +6,9 @@ import (
"testing"
"time"
"github.com/anyproto/go-chash"
"github.com/stretchr/testify/require"
accountService "github.com/anyproto/any-sync/accountservice"
"github.com/anyproto/any-sync/app"
"github.com/anyproto/any-sync/app/ocache"
@ -23,8 +26,6 @@ import (
"github.com/anyproto/any-sync/net/pool"
"github.com/anyproto/any-sync/nodeconf"
"github.com/anyproto/any-sync/testutil/accounttest"
"github.com/anyproto/go-chash"
"github.com/stretchr/testify/require"
)
//
@ -282,6 +283,10 @@ func (n noOpSyncer) Close() error {
type mockTreeSyncer struct {
}
func (m mockTreeSyncer) ShouldSync(peerId string) bool {
return false
}
func (m mockTreeSyncer) Init(a *app.App) (err error) {
return nil
}
@ -301,6 +306,9 @@ func (m mockTreeSyncer) Close(ctx context.Context) (err error) {
func (m mockTreeSyncer) StartSync() {
}
func (m mockTreeSyncer) StopSync() {
}
func (m mockTreeSyncer) SyncAll(ctx context.Context, peerId string, existing, missing []string) error {
return nil
}

View file

@ -99,6 +99,31 @@ func (SpaceStatus) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_d94f6f99586adae2, []int{1}
}
type SpacePermissions int32
const (
SpacePermissions_SpacePermissionsUnknown SpacePermissions = 0
SpacePermissions_SpacePermissionsOwner SpacePermissions = 1
)
var SpacePermissions_name = map[int32]string{
0: "SpacePermissionsUnknown",
1: "SpacePermissionsOwner",
}
var SpacePermissions_value = map[string]int32{
"SpacePermissionsUnknown": 0,
"SpacePermissionsOwner": 1,
}
func (x SpacePermissions) String() string {
return proto.EnumName(SpacePermissions_name, int32(x))
}
func (SpacePermissions) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_d94f6f99586adae2, []int{2}
}
// NodeType determines the type of API that a node supports
type NodeType int32
@ -142,7 +167,7 @@ func (x NodeType) String() string {
}
func (NodeType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_d94f6f99586adae2, []int{2}
return fileDescriptor_d94f6f99586adae2, []int{3}
}
// DeletionChangeType determines the type of deletion payload
@ -171,7 +196,7 @@ func (x DeletionPayloadType) String() string {
}
func (DeletionPayloadType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_d94f6f99586adae2, []int{3}
return fileDescriptor_d94f6f99586adae2, []int{4}
}
type DeletionLogRecordStatus int32
@ -202,7 +227,7 @@ func (x DeletionLogRecordStatus) String() string {
}
func (DeletionLogRecordStatus) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_d94f6f99586adae2, []int{4}
return fileDescriptor_d94f6f99586adae2, []int{5}
}
type SpaceSignRequest struct {
@ -289,6 +314,7 @@ func (m *SpaceSignRequest) GetForceRequest() bool {
type SpaceStatusPayload struct {
Status SpaceStatus `protobuf:"varint,1,opt,name=status,proto3,enum=coordinator.SpaceStatus" json:"status,omitempty"`
DeletionTimestamp int64 `protobuf:"varint,2,opt,name=deletionTimestamp,proto3" json:"deletionTimestamp,omitempty"`
Permissions SpacePermissions `protobuf:"varint,3,opt,name=permissions,proto3,enum=coordinator.SpacePermissions" json:"permissions,omitempty"`
}
func (m *SpaceStatusPayload) Reset() { *m = SpaceStatusPayload{} }
@ -338,6 +364,13 @@ func (m *SpaceStatusPayload) GetDeletionTimestamp() int64 {
return 0
}
func (m *SpaceStatusPayload) GetPermissions() SpacePermissions {
if m != nil {
return m.Permissions
}
return SpacePermissions_SpacePermissionsUnknown
}
type SpaceSignResponse struct {
Receipt *SpaceReceiptWithSignature `protobuf:"bytes,1,opt,name=receipt,proto3" json:"receipt,omitempty"`
}
@ -1995,6 +2028,7 @@ func (m *AclGetRecordsResponse) GetRecords() [][]byte {
func init() {
proto.RegisterEnum("coordinator.ErrorCodes", ErrorCodes_name, ErrorCodes_value)
proto.RegisterEnum("coordinator.SpaceStatus", SpaceStatus_name, SpaceStatus_value)
proto.RegisterEnum("coordinator.SpacePermissions", SpacePermissions_name, SpacePermissions_value)
proto.RegisterEnum("coordinator.NodeType", NodeType_name, NodeType_value)
proto.RegisterEnum("coordinator.DeletionPayloadType", DeletionPayloadType_name, DeletionPayloadType_value)
proto.RegisterEnum("coordinator.DeletionLogRecordStatus", DeletionLogRecordStatus_name, DeletionLogRecordStatus_value)
@ -2037,105 +2071,109 @@ func init() {
}
var fileDescriptor_d94f6f99586adae2 = []byte{
// 1567 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x58, 0xcf, 0x73, 0xd3, 0xc6,
0x17, 0xb7, 0x64, 0x3b, 0xb1, 0x9f, 0x83, 0x51, 0x36, 0x3f, 0xf0, 0xd7, 0x18, 0x63, 0x16, 0xbe,
0xd4, 0xb8, 0x1d, 0xa0, 0x66, 0xda, 0x29, 0x43, 0x0f, 0x84, 0x40, 0x69, 0xf8, 0x11, 0x32, 0x0a,
0xa1, 0xd3, 0x72, 0xe8, 0x08, 0x69, 0xe3, 0x68, 0x62, 0x4b, 0xae, 0xb4, 0x06, 0xfc, 0x5f, 0xf4,
0xd6, 0x53, 0xef, 0x9d, 0x69, 0x0f, 0x9d, 0x5e, 0x7a, 0xe8, 0x4c, 0xcf, 0x3d, 0x72, 0xec, 0x91,
0x81, 0x6b, 0xff, 0x88, 0xce, 0xae, 0x56, 0xd2, 0xea, 0x87, 0x9d, 0x74, 0x38, 0x70, 0x49, 0xbc,
0x9f, 0x7d, 0xef, 0xed, 0xfb, 0xb5, 0xef, 0xbd, 0x15, 0x7c, 0x62, 0xba, 0xae, 0x67, 0xd9, 0x8e,
0x41, 0x5d, 0xef, 0x8a, 0xf4, 0x7b, 0xec, 0xb9, 0xd4, 0xbd, 0xc2, 0xff, 0xfa, 0x32, 0x7e, 0x99,
0x43, 0xa8, 0x26, 0x41, 0xf8, 0x4f, 0x05, 0xb4, 0xdd, 0xb1, 0x61, 0x92, 0x5d, 0x7b, 0xe0, 0xe8,
0xe4, 0xbb, 0x09, 0xf1, 0x29, 0x6a, 0xc0, 0xa2, 0xcf, 0xb0, 0x2d, 0xab, 0xa1, 0x74, 0x94, 0x6e,
0x55, 0x0f, 0x97, 0x68, 0x1d, 0x16, 0x0e, 0x88, 0x61, 0x11, 0xaf, 0xa1, 0x76, 0x94, 0xee, 0x92,
0x2e, 0x56, 0xa8, 0x03, 0x35, 0x77, 0x68, 0x6d, 0x59, 0xc4, 0xa1, 0x36, 0x9d, 0x36, 0x8a, 0x7c,
0x53, 0x86, 0x50, 0x1f, 0x56, 0x1d, 0xf2, 0x22, 0x5c, 0xb2, 0xd3, 0x0c, 0x3a, 0xf1, 0x48, 0xa3,
0xc4, 0x49, 0x73, 0xf7, 0x10, 0x86, 0xa5, 0x7d, 0xd7, 0x33, 0x89, 0xd0, 0xab, 0x51, 0xee, 0x28,
0xdd, 0x8a, 0x9e, 0xc0, 0x30, 0x05, 0x14, 0xe8, 0x4f, 0x0d, 0x3a, 0xf1, 0x77, 0x8c, 0xe9, 0xd0,
0x35, 0x2c, 0x74, 0x15, 0x16, 0x7c, 0x0e, 0x70, 0x03, 0xea, 0xfd, 0xc6, 0x65, 0xd9, 0x0f, 0x12,
0x83, 0x2e, 0xe8, 0xd0, 0x47, 0xb0, 0x6c, 0x91, 0x21, 0xa1, 0xb6, 0xeb, 0x3c, 0xb6, 0x47, 0xc4,
0xa7, 0xc6, 0x68, 0xcc, 0x8d, 0x2c, 0xea, 0xd9, 0x0d, 0xbc, 0x07, 0xcb, 0x92, 0xd7, 0xfc, 0xb1,
0xeb, 0xf8, 0x04, 0xdd, 0x84, 0x45, 0x8f, 0x98, 0xc4, 0x1e, 0x53, 0x7e, 0x6a, 0xad, 0x7f, 0x31,
0x7b, 0xaa, 0x1e, 0x10, 0x7c, 0x65, 0xd3, 0x83, 0xc8, 0x4e, 0x3d, 0x64, 0xc3, 0x87, 0xf0, 0xbf,
0x99, 0x54, 0xe8, 0x2a, 0xac, 0xf8, 0xd2, 0xa6, 0x30, 0x95, 0x1f, 0xb5, 0xa4, 0xe7, 0x6d, 0xa1,
0x16, 0x54, 0xfd, 0xc8, 0xd1, 0x41, 0xc0, 0x62, 0x00, 0xff, 0xa4, 0xc0, 0x92, 0x7c, 0xda, 0xfc,
0xb0, 0x8f, 0x09, 0xf1, 0xb6, 0x2c, 0x2e, 0xa5, 0xaa, 0x8b, 0x15, 0xea, 0xc2, 0x49, 0xc3, 0x34,
0xdd, 0x89, 0x43, 0x53, 0xa1, 0x4f, 0xc3, 0x4c, 0x15, 0x87, 0xd0, 0x17, 0xae, 0x77, 0xb8, 0x65,
0xf1, 0x98, 0x57, 0xf5, 0x18, 0x40, 0x6d, 0x80, 0xe7, 0xc6, 0xd0, 0xb6, 0xf6, 0x1c, 0x6a, 0x0f,
0x79, 0x98, 0x4b, 0xba, 0x84, 0xe0, 0xa7, 0xb0, 0xf6, 0x85, 0x3d, 0x24, 0x0f, 0xec, 0x91, 0x4d,
0x37, 0x0f, 0x88, 0x79, 0x18, 0x66, 0x6a, 0x8e, 0x02, 0x4a, 0xbe, 0x02, 0x92, 0x71, 0x6a, 0xc2,
0x38, 0xbc, 0x0d, 0xeb, 0x69, 0xe1, 0x22, 0xa0, 0xab, 0x50, 0x1e, 0x32, 0x94, 0xcb, 0x2c, 0xe9,
0xc1, 0x82, 0x29, 0xeb, 0x53, 0xd7, 0x33, 0x06, 0xe4, 0x3e, 0x99, 0x0a, 0x61, 0x12, 0x82, 0xaf,
0xc1, 0x29, 0x29, 0xc1, 0x12, 0xea, 0xce, 0xf4, 0x30, 0xde, 0x83, 0x46, 0x96, 0x49, 0xa8, 0x71,
0x1d, 0x16, 0xc7, 0x52, 0xb0, 0x6b, 0xfd, 0xb3, 0xb3, 0xb2, 0x59, 0x04, 0x5e, 0x0f, 0xe9, 0xf1,
0x75, 0x38, 0x9d, 0x16, 0xfb, 0xd0, 0x70, 0xa6, 0xa1, 0x3e, 0x4d, 0xa8, 0x08, 0x05, 0xd8, 0x45,
0x29, 0x76, 0xab, 0x7a, 0xb4, 0xc6, 0x4f, 0xa1, 0x95, 0xcf, 0x2a, 0xb4, 0xba, 0x01, 0x15, 0x71,
0x4a, 0xc0, 0x7b, 0x0c, 0xb5, 0x22, 0x06, 0xfc, 0x5a, 0x49, 0xd9, 0x6b, 0x38, 0x03, 0x72, 0x74,
0xf9, 0x91, 0x2e, 0xa9, 0x90, 0x19, 0x85, 0x33, 0xbb, 0xc1, 0x92, 0x23, 0x05, 0x86, 0xd9, 0x99,
0x82, 0x91, 0x0e, 0x2b, 0x29, 0xe8, 0xf1, 0x74, 0x1c, 0xd4, 0xa6, 0x7a, 0xbf, 0x93, 0x30, 0xeb,
0x76, 0x96, 0x4e, 0xcf, 0x63, 0xc6, 0x4f, 0xc4, 0x5d, 0x4e, 0x5a, 0xf8, 0xee, 0x21, 0xbd, 0x01,
0xa7, 0xb7, 0x83, 0x8b, 0xb3, 0xe9, 0x3a, 0xfb, 0xf6, 0x60, 0xe2, 0x19, 0xec, 0xe8, 0xd0, 0x79,
0x2d, 0xa8, 0x9a, 0x13, 0xcf, 0x23, 0x2c, 0xf5, 0x85, 0xfb, 0x62, 0x00, 0xff, 0xa1, 0x40, 0x2b,
0x9f, 0x5b, 0x28, 0xd6, 0x85, 0x93, 0xa6, 0xbc, 0x11, 0x09, 0x49, 0xc3, 0xc9, 0x1b, 0xad, 0xa6,
0x6f, 0xf4, 0x07, 0x50, 0x76, 0x5c, 0x8b, 0xf8, 0x8d, 0x22, 0x4f, 0x8d, 0xe5, 0x84, 0x79, 0xdb,
0xae, 0x45, 0xf4, 0x60, 0x1f, 0xf5, 0x40, 0x33, 0x3d, 0x62, 0x84, 0xe5, 0x75, 0xcf, 0xb1, 0x5f,
0x72, 0xbf, 0x97, 0xf4, 0x0c, 0x8e, 0x6d, 0x28, 0x31, 0x56, 0xa9, 0x1c, 0x29, 0x89, 0x72, 0xd4,
0x82, 0xaa, 0x61, 0x59, 0x1e, 0xf1, 0x7d, 0xe2, 0x37, 0x54, 0x9e, 0xcf, 0x31, 0x80, 0x3e, 0x84,
0x32, 0x9d, 0x8e, 0x85, 0x4a, 0xf5, 0xfe, 0x5a, 0x46, 0x25, 0x1e, 0xcb, 0x80, 0x06, 0x8f, 0xe0,
0x7c, 0x18, 0x69, 0xee, 0x28, 0x6f, 0x24, 0x02, 0x91, 0xac, 0xc9, 0x39, 0x29, 0xa6, 0xe4, 0xa7,
0xd8, 0xfc, 0x5a, 0xfc, 0xab, 0x02, 0xeb, 0xf9, 0xe7, 0xbd, 0xc7, 0xaa, 0xdc, 0x82, 0x2a, 0x8d,
0x5a, 0x61, 0x99, 0xb7, 0xc2, 0x18, 0xc0, 0xb7, 0x01, 0x85, 0x1a, 0x3f, 0x70, 0x07, 0xd2, 0xdd,
0x35, 0xf6, 0xa9, 0x14, 0x9b, 0x70, 0x19, 0x17, 0x53, 0xa6, 0xec, 0x09, 0x51, 0x4c, 0xb1, 0x0d,
0x2b, 0x09, 0x29, 0x22, 0x0d, 0x3f, 0xe3, 0xad, 0xd4, 0xf5, 0xa2, 0xda, 0xd2, 0xce, 0xbd, 0x84,
0x9c, 0x85, 0x91, 0xe9, 0x21, 0x39, 0x53, 0xe0, 0xc0, 0xf0, 0x1f, 0xba, 0xc2, 0xcb, 0x15, 0x3d,
0x5c, 0xe2, 0xdf, 0x15, 0x58, 0xce, 0x30, 0xa2, 0x3a, 0xa8, 0x76, 0xa8, 0xab, 0x6a, 0x5b, 0xb3,
0xfb, 0x04, 0xfa, 0x3c, 0x9a, 0x29, 0x8a, 0xbc, 0x2e, 0x5c, 0x98, 0xaf, 0x52, 0x6a, 0xbe, 0x48,
0x38, 0xb3, 0x94, 0x72, 0x26, 0xdb, 0xdd, 0xb7, 0x87, 0xe4, 0xae, 0xe7, 0x4e, 0x02, 0x57, 0x57,
0xf5, 0x18, 0xc0, 0xbf, 0x29, 0x62, 0xc8, 0xe1, 0x87, 0xbc, 0xc7, 0x3a, 0xd9, 0x03, 0x2d, 0x84,
0x6e, 0x8b, 0x4a, 0x20, 0x6c, 0xc9, 0xe0, 0x78, 0x0b, 0x56, 0x12, 0x3a, 0x8b, 0xc8, 0xf6, 0x61,
0x95, 0xba, 0xb7, 0x04, 0x6a, 0xc5, 0xa3, 0x96, 0xc2, 0xc5, 0xe4, 0xee, 0x61, 0x07, 0x56, 0x37,
0x82, 0xcc, 0x4d, 0x3a, 0x20, 0xd7, 0x4c, 0xe5, 0x3f, 0x98, 0xa9, 0xe6, 0x9a, 0x89, 0x7f, 0x54,
0xe0, 0x8c, 0x7c, 0x60, 0xf6, 0x52, 0xce, 0xaa, 0x40, 0x39, 0x57, 0x4f, 0x3d, 0xc6, 0xd5, 0x2b,
0xce, 0xbd, 0x7a, 0xe9, 0x6c, 0xc1, 0xf7, 0x61, 0x2d, 0xe5, 0x8f, 0x77, 0x70, 0x6e, 0x1b, 0x5a,
0x42, 0x98, 0x4e, 0x9e, 0x13, 0x2f, 0xb2, 0x38, 0x1c, 0xb0, 0xcf, 0x46, 0xbe, 0x48, 0xef, 0x07,
0x87, 0xb2, 0x40, 0x6f, 0x98, 0xc3, 0x0d, 0xcb, 0x12, 0x57, 0xf1, 0xc8, 0xec, 0x6c, 0xc4, 0xcd,
0x2f, 0x70, 0x4e, 0xd4, 0xdb, 0x1e, 0xb0, 0x40, 0xcb, 0xa2, 0x84, 0x5d, 0x4d, 0xa8, 0x04, 0xf7,
0x3b, 0x12, 0x16, 0xad, 0xe7, 0x48, 0xbb, 0xc7, 0xa5, 0xdd, 0x25, 0x34, 0x90, 0xe6, 0x1f, 0x4b,
0x33, 0xc3, 0x1c, 0x7e, 0x49, 0x8c, 0xe8, 0xf2, 0x8b, 0x25, 0xfe, 0x98, 0xb9, 0x3c, 0x21, 0x4b,
0xa8, 0xd6, 0x48, 0x56, 0xaa, 0xa5, 0xa8, 0x12, 0xf5, 0x7e, 0x56, 0x00, 0xee, 0x78, 0x9e, 0xeb,
0x6d, 0xf2, 0x46, 0x57, 0x07, 0xd8, 0x73, 0xc8, 0xcb, 0x31, 0x31, 0x29, 0xb1, 0xb4, 0x02, 0xd2,
0xc4, 0xf4, 0x2d, 0x02, 0xa2, 0x29, 0xa8, 0x01, 0xab, 0x31, 0xc2, 0xd2, 0x91, 0x38, 0x96, 0xed,
0x0c, 0x34, 0x35, 0xa2, 0xdd, 0x64, 0x1d, 0x91, 0x58, 0x5a, 0x11, 0x21, 0xa8, 0x73, 0x64, 0xdb,
0xa5, 0x77, 0x5e, 0xda, 0x3e, 0xf5, 0xb5, 0x12, 0x5a, 0x13, 0x8f, 0x12, 0x3e, 0xc9, 0xea, 0xc4,
0x30, 0x0f, 0x88, 0xa5, 0x95, 0x19, 0x69, 0x22, 0x5b, 0x2c, 0x6d, 0x01, 0x69, 0x50, 0xe3, 0xaa,
0x3d, 0xda, 0xdf, 0xf7, 0x09, 0xd5, 0x7e, 0x51, 0x7b, 0x3f, 0x28, 0x50, 0x93, 0xc6, 0x0e, 0xb4,
0x9e, 0x78, 0x57, 0x85, 0x07, 0x17, 0x50, 0x1b, 0x9a, 0xf2, 0x74, 0x12, 0xa8, 0x18, 0x6a, 0xac,
0x29, 0xa9, 0xfd, 0x70, 0x63, 0x97, 0x1a, 0x1e, 0xe3, 0x57, 0x53, 0x72, 0x43, 0x8d, 0x8a, 0x91,
0xf1, 0x01, 0x2e, 0x99, 0xd5, 0x7b, 0x01, 0x95, 0xb0, 0x3b, 0xa3, 0x1a, 0x2c, 0x3e, 0xf6, 0x08,
0xd9, 0xd8, 0xd9, 0xd2, 0x0a, 0x6c, 0xc1, 0x06, 0x77, 0xb6, 0x50, 0x98, 0x95, 0x9b, 0x71, 0x39,
0x66, 0x18, 0x77, 0xdb, 0x26, 0x0b, 0x92, 0xe3, 0x4f, 0x7c, 0x86, 0x14, 0xd1, 0x32, 0x9c, 0xd8,
0x36, 0x46, 0xb6, 0x33, 0x60, 0x12, 0x19, 0x54, 0x62, 0x07, 0xef, 0x18, 0xd3, 0x11, 0x71, 0xe8,
0x8e, 0xe7, 0x9a, 0xc4, 0xf7, 0x6d, 0x67, 0xc0, 0x76, 0xca, 0xbd, 0xeb, 0x71, 0x6f, 0x92, 0x06,
0x3b, 0x54, 0x81, 0x12, 0xd3, 0x21, 0x50, 0x40, 0xd4, 0x05, 0x4d, 0x61, 0x0b, 0xe1, 0x66, 0x4d,
0xed, 0xdd, 0x84, 0x53, 0x33, 0x1a, 0x02, 0x5a, 0x00, 0xf5, 0xd1, 0xa1, 0x56, 0x60, 0xaa, 0xe8,
0x64, 0xe4, 0x3e, 0x27, 0x3b, 0x1e, 0x19, 0x1b, 0x1e, 0xd1, 0x14, 0x04, 0xb0, 0x10, 0x40, 0x9a,
0xda, 0xff, 0xa7, 0x02, 0x35, 0xc9, 0x20, 0x74, 0x0f, 0xaa, 0xd1, 0x8b, 0x13, 0x9d, 0xc9, 0x99,
0x16, 0xe3, 0xf7, 0x7b, 0xb3, 0x3d, 0x6b, 0x5b, 0xe4, 0xec, 0xd7, 0x50, 0x4f, 0xbe, 0x78, 0x10,
0x4e, 0x70, 0xe4, 0xbe, 0xb5, 0x9a, 0xe7, 0xe7, 0xd2, 0x08, 0xd1, 0xdf, 0x86, 0x9f, 0x13, 0xe2,
0x57, 0x03, 0xba, 0x30, 0x6b, 0xb6, 0x4d, 0x88, 0xff, 0xff, 0x11, 0x54, 0xe2, 0x80, 0xc3, 0x44,
0x9e, 0x44, 0xcf, 0x12, 0xd4, 0x9d, 0xcb, 0x2e, 0x3d, 0x7a, 0x9a, 0x97, 0x8e, 0x41, 0x29, 0x0e,
0x7b, 0x16, 0x3e, 0xf3, 0xa5, 0x19, 0x1e, 0xcd, 0x51, 0x54, 0x7a, 0xc5, 0x34, 0x2f, 0x1e, 0x45,
0x16, 0x1b, 0x94, 0x37, 0x91, 0xa7, 0x0c, 0x9a, 0x33, 0xf2, 0xa7, 0x0c, 0x9a, 0x3b, 0xde, 0xef,
0x40, 0x4d, 0xca, 0x4b, 0x74, 0x76, 0xf6, 0x08, 0x13, 0x88, 0xee, 0xcc, 0x26, 0x88, 0x25, 0x4a,
0x65, 0x0c, 0xe5, 0xbc, 0x63, 0x12, 0x3d, 0x3b, 0x25, 0x31, 0x6f, 0x42, 0x78, 0x02, 0x27, 0x12,
0xf5, 0x0a, 0x9d, 0x4b, 0xb0, 0xe4, 0x4d, 0x02, 0x4d, 0x3c, 0x8f, 0x44, 0xc8, 0x75, 0xa2, 0xae,
0x99, 0x6c, 0x64, 0xe8, 0x52, 0x1e, 0x73, 0x6e, 0x33, 0x6c, 0xf6, 0x8e, 0x43, 0x2a, 0xce, 0xdb,
0x85, 0x25, 0xb9, 0x99, 0xa1, 0x4e, 0x8a, 0x37, 0xd3, 0x32, 0x9b, 0xe7, 0xe6, 0x50, 0xc8, 0xce,
0x91, 0xfa, 0x50, 0xc6, 0x39, 0xd9, 0x7e, 0x97, 0x71, 0x4e, 0x4e, 0x1b, 0xbb, 0xf5, 0xe9, 0x5f,
0x6f, 0xda, 0xca, 0xab, 0x37, 0x6d, 0xe5, 0xf5, 0x9b, 0xb6, 0xf2, 0xfd, 0xdb, 0x76, 0xe1, 0xd5,
0xdb, 0x76, 0xe1, 0xef, 0xb7, 0xed, 0xc2, 0x37, 0xad, 0x79, 0x5f, 0x19, 0x9f, 0x2d, 0xf0, 0x7f,
0xd7, 0xfe, 0x0d, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xe6, 0x06, 0x8a, 0x8c, 0x14, 0x00, 0x00,
// 1626 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x58, 0xcf, 0x6f, 0x13, 0xc7,
0x17, 0xf7, 0x6e, 0x9c, 0xc4, 0x7e, 0x0e, 0x66, 0x33, 0xf9, 0x81, 0x31, 0xc6, 0x84, 0x85, 0x2f,
0xdf, 0xe0, 0xef, 0x57, 0x40, 0x8d, 0x5a, 0x15, 0x51, 0xa9, 0x84, 0x40, 0x69, 0xf8, 0x11, 0xa2,
0x0d, 0xa1, 0x6a, 0x39, 0x54, 0xcb, 0xee, 0xc4, 0x59, 0xc5, 0x9e, 0x75, 0x67, 0xc7, 0x84, 0xfc,
0x17, 0xbd, 0xf5, 0xd4, 0x7b, 0xa5, 0xf6, 0x50, 0x55, 0xaa, 0x7a, 0xa8, 0xd4, 0x73, 0x8f, 0x1c,
0x7b, 0x44, 0x70, 0xed, 0x1f, 0x51, 0xcd, 0xec, 0xec, 0xee, 0xec, 0x0f, 0x3b, 0xa9, 0x38, 0x70,
0x49, 0x3c, 0x9f, 0x79, 0xef, 0xcd, 0xfb, 0x35, 0xef, 0xcd, 0x5b, 0xf8, 0xd0, 0xf1, 0x7d, 0xea,
0x7a, 0xc4, 0x66, 0x3e, 0xbd, 0xaa, 0xfc, 0x1e, 0x52, 0x9f, 0xf9, 0x57, 0xc5, 0xdf, 0x40, 0xc5,
0xaf, 0x08, 0x08, 0xd5, 0x14, 0xc8, 0xfc, 0x43, 0x03, 0x63, 0x7b, 0x68, 0x3b, 0x78, 0xdb, 0xeb,
0x11, 0x0b, 0x7f, 0x33, 0xc2, 0x01, 0x43, 0x0d, 0x98, 0x0d, 0x38, 0xb6, 0xe1, 0x36, 0xb4, 0x15,
0x6d, 0xb5, 0x6a, 0x45, 0x4b, 0xb4, 0x0c, 0x33, 0x7b, 0xd8, 0x76, 0x31, 0x6d, 0xe8, 0x2b, 0xda,
0xea, 0x9c, 0x25, 0x57, 0x68, 0x05, 0x6a, 0x7e, 0xdf, 0xdd, 0x70, 0x31, 0x61, 0x1e, 0x3b, 0x6c,
0x4c, 0x89, 0x4d, 0x15, 0x42, 0x5d, 0x58, 0x24, 0xf8, 0x20, 0x5a, 0xf2, 0xd3, 0x6c, 0x36, 0xa2,
0xb8, 0x51, 0x16, 0xa4, 0x85, 0x7b, 0xc8, 0x84, 0xb9, 0x5d, 0x9f, 0x3a, 0x58, 0xea, 0xd5, 0x98,
0x5e, 0xd1, 0x56, 0x2b, 0x56, 0x0a, 0x33, 0x7f, 0xd5, 0x00, 0x85, 0x06, 0x30, 0x9b, 0x8d, 0x82,
0x2d, 0xfb, 0xb0, 0xef, 0xdb, 0x2e, 0xba, 0x06, 0x33, 0x81, 0x00, 0x84, 0x05, 0xf5, 0x6e, 0xe3,
0x8a, 0xea, 0x08, 0x85, 0xc1, 0x92, 0x74, 0xe8, 0xff, 0x30, 0xef, 0xe2, 0x3e, 0x66, 0x9e, 0x4f,
0x9e, 0x78, 0x03, 0x1c, 0x30, 0x7b, 0x30, 0x14, 0x56, 0x4e, 0x59, 0xf9, 0x0d, 0xf4, 0x29, 0xd4,
0x86, 0x98, 0x0e, 0xbc, 0x20, 0xf0, 0x7c, 0x12, 0x08, 0x83, 0xeb, 0xdd, 0xb3, 0xf9, 0x43, 0xb6,
0x12, 0x22, 0x4b, 0xe5, 0x30, 0x77, 0x60, 0x5e, 0xf1, 0x7b, 0x30, 0xf4, 0x49, 0x80, 0xd1, 0x2d,
0x98, 0xa5, 0xd8, 0xc1, 0xde, 0x90, 0x09, 0xb5, 0x6b, 0xdd, 0x4b, 0x79, 0x89, 0x56, 0x48, 0xf0,
0x85, 0xc7, 0xf6, 0x62, 0x4f, 0x59, 0x11, 0x9b, 0xb9, 0x0f, 0xa7, 0xc7, 0x52, 0xa1, 0x6b, 0xb0,
0x10, 0x28, 0x9b, 0xd2, 0x57, 0xe2, 0xa8, 0x39, 0xab, 0x68, 0x0b, 0xb5, 0xa0, 0x1a, 0xc4, 0xa1,
0x0a, 0x43, 0x9e, 0x00, 0xe6, 0x0f, 0x1a, 0xcc, 0xa9, 0xa7, 0x4d, 0x4e, 0x9c, 0x21, 0xc6, 0x74,
0xc3, 0x15, 0x52, 0xaa, 0x96, 0x5c, 0xa1, 0x55, 0x38, 0x69, 0x3b, 0x8e, 0x3f, 0x22, 0x2c, 0x93,
0x3c, 0x59, 0x98, 0xab, 0x42, 0x30, 0x3b, 0xf0, 0xe9, 0xfe, 0x86, 0x2b, 0xb2, 0xa6, 0x6a, 0x25,
0x00, 0x6a, 0x03, 0xbc, 0xb0, 0xfb, 0x9e, 0xbb, 0x43, 0x98, 0xd7, 0x17, 0x89, 0x52, 0xb6, 0x14,
0xc4, 0x7c, 0x06, 0x4b, 0x9f, 0x79, 0x7d, 0xfc, 0xd0, 0x1b, 0x78, 0x6c, 0x7d, 0x0f, 0x3b, 0xfb,
0x51, 0xae, 0x17, 0x28, 0xa0, 0x15, 0x2b, 0xa0, 0x18, 0xa7, 0xa7, 0x8c, 0x33, 0x37, 0x61, 0x39,
0x2b, 0x5c, 0x06, 0x74, 0x11, 0xa6, 0xfb, 0x1c, 0x15, 0x32, 0xcb, 0x56, 0xb8, 0xe0, 0xca, 0x06,
0xcc, 0xa7, 0x76, 0x0f, 0x3f, 0xc0, 0x87, 0x52, 0x98, 0x82, 0x98, 0xd7, 0xe1, 0x94, 0x92, 0xa1,
0x29, 0x75, 0xc7, 0x7a, 0xd8, 0xdc, 0x81, 0x46, 0x9e, 0x49, 0xaa, 0x71, 0x03, 0x66, 0x87, 0x4a,
0xb0, 0x6b, 0xdd, 0x73, 0xe3, 0xae, 0x83, 0x0c, 0xbc, 0x15, 0xd1, 0x9b, 0x37, 0xe0, 0x4c, 0x56,
0xec, 0x23, 0x9b, 0x1c, 0x46, 0xfa, 0x34, 0xa1, 0x22, 0x15, 0xe0, 0x37, 0x6d, 0x6a, 0xb5, 0x6a,
0xc5, 0x6b, 0xf3, 0x19, 0xb4, 0x8a, 0x59, 0xa5, 0x56, 0x37, 0xa1, 0x22, 0x4f, 0x09, 0x79, 0x8f,
0xa1, 0x56, 0xcc, 0x60, 0xbe, 0xd6, 0x32, 0xf6, 0xda, 0xa4, 0x87, 0x8f, 0x2e, 0x60, 0xca, 0x2d,
0x97, 0x32, 0xe3, 0x70, 0xe6, 0x37, 0x78, 0x72, 0x64, 0xc0, 0x28, 0x3b, 0x33, 0x30, 0xb2, 0x60,
0x21, 0x03, 0x3d, 0x39, 0x1c, 0x86, 0xd5, 0xad, 0xde, 0x5d, 0x49, 0x99, 0x75, 0x27, 0x4f, 0x67,
0x15, 0x31, 0x9b, 0x4f, 0xe5, 0x5d, 0x4e, 0x5b, 0xf8, 0xee, 0x21, 0xbd, 0x09, 0x67, 0x36, 0xc3,
0x8b, 0xb3, 0xee, 0x93, 0x5d, 0xaf, 0x37, 0xa2, 0x36, 0x3f, 0x3a, 0x72, 0x5e, 0x0b, 0xaa, 0xce,
0x88, 0x52, 0xcc, 0x53, 0x5f, 0xba, 0x2f, 0x01, 0xcc, 0xdf, 0x35, 0x68, 0x15, 0x73, 0x4b, 0xc5,
0x56, 0xe1, 0xa4, 0xa3, 0x6e, 0xc4, 0x42, 0xb2, 0x70, 0xfa, 0x46, 0xeb, 0xd9, 0x1b, 0xfd, 0x5f,
0x98, 0x26, 0xbe, 0x8b, 0x79, 0x6d, 0xe5, 0xa9, 0x31, 0x9f, 0x32, 0x6f, 0xd3, 0x77, 0xb1, 0x15,
0xee, 0xa3, 0x0e, 0x18, 0x0e, 0xc5, 0x76, 0x54, 0x9f, 0x77, 0x88, 0xf7, 0x52, 0xf8, 0xbd, 0x6c,
0xe5, 0x70, 0xd3, 0x83, 0x32, 0x67, 0x55, 0xca, 0x91, 0x96, 0x2a, 0x47, 0x2d, 0xa8, 0xda, 0xae,
0x4b, 0x71, 0x10, 0xe0, 0xa0, 0xa1, 0x8b, 0x7c, 0x4e, 0x00, 0xf4, 0x3f, 0x98, 0x66, 0x87, 0x43,
0xa9, 0x52, 0xbd, 0xbb, 0x94, 0x53, 0x49, 0xc4, 0x32, 0xa4, 0x31, 0x07, 0x70, 0x21, 0x8a, 0xb4,
0x70, 0x14, 0x1d, 0xc8, 0x40, 0xa4, 0x6b, 0x72, 0x41, 0x8a, 0x69, 0xc5, 0x29, 0x36, 0xb9, 0x16,
0xff, 0xac, 0xc1, 0x72, 0xf1, 0x79, 0xef, 0xb1, 0x2a, 0xb7, 0xa0, 0xca, 0xe2, 0x5e, 0x3a, 0x2d,
0x7a, 0x69, 0x02, 0x98, 0x77, 0x00, 0x45, 0x1a, 0x3f, 0xf4, 0x7b, 0xca, 0xdd, 0xb5, 0x77, 0x99,
0x12, 0x9b, 0x68, 0x99, 0x14, 0x53, 0xae, 0xec, 0x09, 0x59, 0x4c, 0x4d, 0x0f, 0x16, 0x52, 0x52,
0x64, 0x1a, 0x7e, 0x2c, 0x5a, 0xa9, 0x4f, 0xe3, 0xda, 0xd2, 0x2e, 0xbc, 0x84, 0x82, 0x85, 0x93,
0x59, 0x11, 0x39, 0x57, 0x60, 0xcf, 0x0e, 0x1e, 0xf9, 0xd2, 0xcb, 0x15, 0x2b, 0x5a, 0x9a, 0xbf,
0x69, 0x30, 0x9f, 0x63, 0x44, 0x75, 0xd0, 0xbd, 0x48, 0x57, 0xdd, 0x73, 0xc7, 0xf7, 0x09, 0xf4,
0x49, 0xfc, 0x28, 0x09, 0xdf, 0x0b, 0x17, 0x27, 0xab, 0x94, 0x79, 0xa0, 0xa4, 0x9c, 0x59, 0xce,
0x38, 0x93, 0xef, 0xee, 0x7a, 0x7d, 0x7c, 0x8f, 0xfa, 0xa3, 0xd0, 0xd5, 0x55, 0x2b, 0x01, 0xcc,
0x5f, 0xa2, 0x57, 0x92, 0x38, 0xe4, 0x3d, 0xd6, 0xc9, 0x0e, 0x18, 0x11, 0x74, 0x47, 0x56, 0x02,
0x69, 0x4b, 0x0e, 0x37, 0x37, 0x60, 0x21, 0xa5, 0xb3, 0x8c, 0x6c, 0x17, 0x16, 0x99, 0x7f, 0x5b,
0xa2, 0x6e, 0xf2, 0x56, 0xd3, 0x84, 0x98, 0xc2, 0x3d, 0x93, 0xc0, 0xe2, 0x5a, 0x98, 0xb9, 0x69,
0x07, 0x14, 0x9a, 0xa9, 0xfd, 0x0b, 0x33, 0xf5, 0x42, 0x33, 0xcd, 0xef, 0x35, 0x38, 0xab, 0x1e,
0x98, 0xbf, 0x94, 0xe3, 0x2a, 0x50, 0xc1, 0xd5, 0xd3, 0x8f, 0x71, 0xf5, 0xa6, 0x26, 0x5e, 0xbd,
0x6c, 0xb6, 0x98, 0x0f, 0x60, 0x29, 0xe3, 0x8f, 0x77, 0x70, 0x6e, 0x1b, 0x5a, 0x52, 0x98, 0x85,
0x5f, 0x60, 0x1a, 0x5b, 0x1c, 0x3d, 0xd1, 0xcf, 0xc5, 0xbe, 0xc8, 0xee, 0x87, 0x87, 0xf2, 0x40,
0xaf, 0x39, 0xfd, 0x35, 0xd7, 0x95, 0x57, 0xf1, 0xc8, 0xec, 0x6c, 0x24, 0xcd, 0x2f, 0x74, 0x4e,
0xdc, 0xdb, 0x1e, 0xf2, 0x40, 0xab, 0xa2, 0xa4, 0x5d, 0x4d, 0xa8, 0x84, 0xf7, 0x3b, 0x16, 0x16,
0xaf, 0x27, 0x48, 0xbb, 0x2f, 0xa4, 0xdd, 0xc3, 0x2c, 0x94, 0x16, 0x1c, 0x4b, 0x33, 0xdb, 0xe9,
0x7f, 0x8e, 0xed, 0xf8, 0xf2, 0xcb, 0xa5, 0xf9, 0x01, 0x77, 0x79, 0x4a, 0x96, 0x54, 0xad, 0x91,
0xae, 0x54, 0x73, 0x71, 0x25, 0xea, 0xfc, 0xa8, 0x01, 0xdc, 0xa5, 0xd4, 0xa7, 0xeb, 0xa2, 0xd1,
0xd5, 0x01, 0x76, 0x08, 0x7e, 0x39, 0xc4, 0x0e, 0xc3, 0xae, 0x51, 0x42, 0x86, 0x7c, 0x7d, 0xcb,
0x80, 0x18, 0x1a, 0x6a, 0xc0, 0x62, 0x82, 0xf0, 0x74, 0xc4, 0xc4, 0xf5, 0x48, 0xcf, 0xd0, 0x63,
0xda, 0x75, 0xde, 0x11, 0xb1, 0x6b, 0x4c, 0x21, 0x04, 0x75, 0x81, 0x6c, 0xfa, 0xec, 0xee, 0x4b,
0x2f, 0x60, 0x81, 0x51, 0x46, 0x4b, 0x72, 0x28, 0x11, 0x2f, 0x59, 0x0b, 0xdb, 0xce, 0x1e, 0x76,
0x8d, 0x69, 0x4e, 0x9a, 0xca, 0x16, 0xd7, 0x98, 0x41, 0x06, 0xd4, 0x84, 0x6a, 0x8f, 0x77, 0x77,
0x03, 0xcc, 0x8c, 0x9f, 0xf4, 0xce, 0x77, 0x1a, 0xd4, 0x94, 0x67, 0x07, 0x5a, 0x4e, 0x0d, 0x66,
0xd1, 0xc1, 0x25, 0xd4, 0x86, 0xa6, 0xfa, 0x3a, 0x09, 0x55, 0x8c, 0x34, 0x36, 0xb4, 0xcc, 0x7e,
0xb4, 0xb1, 0xcd, 0x6c, 0xca, 0xf9, 0xf5, 0x8c, 0xdc, 0x48, 0xa3, 0xa9, 0xd8, 0xf8, 0x10, 0x57,
0xcc, 0xea, 0xdc, 0x97, 0x33, 0xae, 0x32, 0x8c, 0xa1, 0x33, 0xf2, 0x8d, 0xad, 0x60, 0x3b, 0x64,
0x9f, 0xf8, 0x07, 0xc4, 0x28, 0xa1, 0xd3, 0xb0, 0x94, 0xdd, 0x7c, 0x7c, 0x40, 0x30, 0x35, 0xb4,
0xce, 0x01, 0x54, 0xa2, 0x4e, 0x8f, 0x6a, 0x30, 0xfb, 0x84, 0x62, 0xbc, 0xb6, 0xb5, 0x61, 0x94,
0xf8, 0x82, 0x0f, 0x01, 0x7c, 0xa1, 0x71, 0x8f, 0xad, 0x27, 0xa5, 0x9d, 0x63, 0x22, 0x04, 0xeb,
0x3c, 0xe0, 0x24, 0x18, 0x05, 0x1c, 0x99, 0x42, 0xf3, 0x70, 0x62, 0xd3, 0x1e, 0x78, 0xa4, 0xc7,
0x25, 0x72, 0xa8, 0xcc, 0x8d, 0xd8, 0xb2, 0x0f, 0x07, 0x98, 0xb0, 0x2d, 0xea, 0x3b, 0x38, 0x08,
0x3c, 0xd2, 0xe3, 0x3b, 0xd3, 0x9d, 0x1b, 0x49, 0x9f, 0x53, 0x1e, 0x89, 0xa8, 0x02, 0x65, 0xae,
0x43, 0xa8, 0x80, 0xac, 0x31, 0x86, 0xc6, 0x17, 0x32, 0x64, 0x86, 0xde, 0xb9, 0x05, 0xa7, 0xc6,
0x34, 0x17, 0x34, 0x03, 0xfa, 0xe3, 0x7d, 0xa3, 0xc4, 0x55, 0xb1, 0xf0, 0xc0, 0x7f, 0x81, 0xb7,
0x28, 0x1e, 0xda, 0x14, 0x1b, 0x1a, 0x02, 0x98, 0x09, 0x21, 0x43, 0xef, 0xfe, 0x5d, 0x81, 0x9a,
0x62, 0x10, 0xba, 0x0f, 0xd5, 0x78, 0x7a, 0x45, 0x05, 0x63, 0xaf, 0xf2, 0x35, 0xa1, 0xd9, 0x1e,
0xb7, 0x2d, 0xf3, 0xff, 0x4b, 0xa8, 0xa7, 0xa7, 0x27, 0x64, 0xa6, 0x38, 0x0a, 0xe7, 0xb6, 0xe6,
0x85, 0x89, 0x34, 0x52, 0xf4, 0xd7, 0xd1, 0xc7, 0x8d, 0x64, 0x02, 0x41, 0x17, 0xc7, 0xbd, 0x93,
0x53, 0xe2, 0xff, 0x73, 0x04, 0x95, 0x3c, 0x60, 0x3f, 0x95, 0x73, 0xf1, 0x88, 0x83, 0x56, 0x27,
0xb2, 0x2b, 0x03, 0x54, 0xf3, 0xf2, 0x31, 0x28, 0xe5, 0x61, 0xcf, 0xa3, 0x4f, 0x06, 0xca, 0x3c,
0x80, 0x26, 0x28, 0xaa, 0x4c, 0x44, 0xcd, 0x4b, 0x47, 0x91, 0x25, 0x06, 0x15, 0xbd, 0xee, 0x33,
0x06, 0x4d, 0x18, 0x1f, 0x32, 0x06, 0x4d, 0x1c, 0x15, 0xb6, 0xa0, 0xa6, 0xe4, 0x25, 0x3a, 0x37,
0xfe, 0x39, 0x14, 0x8a, 0x5e, 0x19, 0x4f, 0x90, 0x48, 0x54, 0x4a, 0x22, 0x2a, 0x98, 0x89, 0x52,
0xfd, 0x3f, 0x23, 0xb1, 0xe8, 0xb5, 0xf1, 0x14, 0x4e, 0xa4, 0x6a, 0x1f, 0x3a, 0x9f, 0x62, 0x29,
0x7a, 0x55, 0x34, 0xcd, 0x49, 0x24, 0x52, 0x2e, 0x89, 0x3b, 0x70, 0xba, 0x29, 0xa2, 0xcb, 0x45,
0xcc, 0x85, 0x8d, 0xb5, 0xd9, 0x39, 0x0e, 0xa9, 0x3c, 0x6f, 0x1b, 0xe6, 0xd4, 0xc6, 0x88, 0x56,
0x32, 0xbc, 0xb9, 0xf6, 0xdb, 0x3c, 0x3f, 0x81, 0x42, 0x75, 0x8e, 0xd2, 0xd3, 0x72, 0xce, 0xc9,
0xf7, 0xce, 0x9c, 0x73, 0x0a, 0x5a, 0xe2, 0xed, 0x8f, 0xfe, 0x7c, 0xd3, 0xd6, 0x5e, 0xbd, 0x69,
0x6b, 0xaf, 0xdf, 0xb4, 0xb5, 0x6f, 0xdf, 0xb6, 0x4b, 0xaf, 0xde, 0xb6, 0x4b, 0x7f, 0xbd, 0x6d,
0x97, 0xbe, 0x6a, 0x4d, 0xfa, 0xe6, 0xf9, 0x7c, 0x46, 0xfc, 0xbb, 0xfe, 0x4f, 0x00, 0x00, 0x00,
0xff, 0xff, 0x83, 0x2d, 0x56, 0x38, 0x1a, 0x15, 0x00, 0x00,
}
func (m *SpaceSignRequest) Marshal() (dAtA []byte, err error) {
@ -2219,6 +2257,11 @@ func (m *SpaceStatusPayload) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if m.Permissions != 0 {
i = encodeVarintCoordinator(dAtA, i, uint64(m.Permissions))
i--
dAtA[i] = 0x18
}
if m.DeletionTimestamp != 0 {
i = encodeVarintCoordinator(dAtA, i, uint64(m.DeletionTimestamp))
i--
@ -3453,6 +3496,9 @@ func (m *SpaceStatusPayload) Size() (n int) {
if m.DeletionTimestamp != 0 {
n += 1 + sovCoordinator(uint64(m.DeletionTimestamp))
}
if m.Permissions != 0 {
n += 1 + sovCoordinator(uint64(m.Permissions))
}
return n
}
@ -4261,6 +4307,25 @@ func (m *SpaceStatusPayload) Unmarshal(dAtA []byte) error {
break
}
}
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 ErrIntOverflowCoordinator
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Permissions |= SpacePermissions(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipCoordinator(dAtA[iNdEx:])

View file

@ -75,9 +75,15 @@ enum SpaceStatus {
SpaceStatusNotExists = 4;
}
enum SpacePermissions {
SpacePermissionsUnknown = 0;
SpacePermissionsOwner = 1;
}
message SpaceStatusPayload {
SpaceStatus status = 1;
int64 deletionTimestamp = 2;
SpacePermissions permissions = 3;
}
message SpaceSignResponse {