fix rebase changes

This commit is contained in:
Mikhail Iudin 2023-05-23 14:38:34 +02:00
parent 71c0580bae
commit da6c99c949
No known key found for this signature in database
GPG Key ID: FAAAA8BAABDFF1C0
15 changed files with 62 additions and 717 deletions

View File

@ -46,7 +46,7 @@ type headSync struct {
diff ldiff.Diff diff ldiff.Diff
log logger.CtxLogger log logger.CtxLogger
syncer DiffSyncer syncer DiffSyncer
configuration nodeconf.Configuration configuration nodeconf.NodeConf
spaceIsDeleted *atomic.Bool spaceIsDeleted *atomic.Bool
syncPeriod int syncPeriod int
@ -56,7 +56,7 @@ func NewHeadSync(
spaceId string, spaceId string,
spaceIsDeleted *atomic.Bool, spaceIsDeleted *atomic.Bool,
syncPeriod int, syncPeriod int,
configuration nodeconf.Configuration, configuration nodeconf.NodeConf,
storage spacestorage.SpaceStorage, storage spacestorage.SpaceStorage,
peerManager peermanager.PeerManager, peerManager peermanager.PeerManager,
cache treemanager.TreeManager, cache treemanager.TreeManager,

View File

@ -41,6 +41,10 @@ func (m mockPubKey) Account() string {
return mockKeyValue return mockKeyValue
} }
func (m mockPubKey) Network() string {
return mockKeyValue
}
func (m mockPubKey) PeerId() string { func (m mockPubKey) PeerId() string {
return mockKeyValue return mockKeyValue
} }

View File

@ -34,8 +34,8 @@ func (s syncTreeMatcher) String() string {
return "" return ""
} }
func syncClientFuncCreator(client objectsync.SyncClient) func(spaceId string, factory objectsync.RequestFactory, objectSync objectsync.ObjectSync, configuration nodeconf.Configuration) objectsync.SyncClient { 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.Configuration) objectsync.SyncClient { return func(spaceId string, factory objectsync.RequestFactory, objectSync objectsync.ObjectSync, configuration nodeconf.NodeConf) objectsync.SyncClient {
return client return client
} }
} }

View File

@ -36,7 +36,7 @@ type objectSync struct {
messagePool MessagePool messagePool MessagePool
syncClient SyncClient syncClient SyncClient
objectGetter syncobjectgetter.SyncObjectGetter objectGetter syncobjectgetter.SyncObjectGetter
configuration nodeconf.Configuration configuration nodeconf.NodeConf
spaceStorage spacestorage.SpaceStorage spaceStorage spacestorage.SpaceStorage
syncCtx context.Context syncCtx context.Context
@ -47,7 +47,7 @@ type objectSync struct {
func NewObjectSync( func NewObjectSync(
spaceId string, spaceId string,
spaceIsDeleted *atomic.Bool, spaceIsDeleted *atomic.Bool,
configuration nodeconf.Configuration, configuration nodeconf.NodeConf,
peerManager peermanager.PeerManager, peerManager peermanager.PeerManager,
objectGetter syncobjectgetter.SyncObjectGetter, objectGetter syncobjectgetter.SyncObjectGetter,
storage spacestorage.SpaceStorage) ObjectSync { storage spacestorage.SpaceStorage) ObjectSync {

View File

@ -58,7 +58,7 @@ type Deps struct {
Account accountservice.Service Account accountservice.Service
TreeManager treemanager.TreeManager TreeManager treemanager.TreeManager
Store spacestorage.SpaceStorage Store spacestorage.SpaceStorage
Configuration nodeconf.Configuration Configuration nodeconf.NodeConf
DeletionState settingsstate.ObjectDeletionState DeletionState settingsstate.ObjectDeletionState
Provider SpaceIdsProvider Provider SpaceIdsProvider
OnSpaceDelete func() OnSpaceDelete func()

View File

@ -3,7 +3,6 @@ package commonspace
import ( import (
"context" "context"
"errors" "errors"
"fmt"
"github.com/anytypeio/any-sync/accountservice" "github.com/anytypeio/any-sync/accountservice"
"github.com/anytypeio/any-sync/app/logger" "github.com/anytypeio/any-sync/app/logger"
"github.com/anytypeio/any-sync/commonspace/headsync" "github.com/anytypeio/any-sync/commonspace/headsync"
@ -31,6 +30,7 @@ import (
"github.com/zeebo/errs" "github.com/zeebo/errs"
"go.uber.org/zap" "go.uber.org/zap"
"strconv" "strconv"
"strings"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time" "time"
@ -90,7 +90,7 @@ type SpaceDescription struct {
} }
func NewSpaceId(id string, repKey uint64) string { func NewSpaceId(id string, repKey uint64) string {
return fmt.Sprintf("%s.%s", id, strconv.FormatUint(repKey, 36)) return strings.Join([]string{id, strconv.FormatUint(repKey, 36)}, ".")
} }
type Space interface { type Space interface {
@ -101,7 +101,6 @@ type Space interface {
DebugAllHeads() []headsync.TreeHeads DebugAllHeads() []headsync.TreeHeads
Description() (SpaceDescription, error) Description() (SpaceDescription, error)
DeriveTree(ctx context.Context, payload objecttree.ObjectTreeCreatePayload) (res treestorage.TreeStorageCreatePayload, err error)
CreateTree(ctx context.Context, payload objecttree.ObjectTreeCreatePayload) (res treestorage.TreeStorageCreatePayload, 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) 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) BuildTree(ctx context.Context, id string, opts BuildTreeOpts) (t objecttree.ObjectTree, err error)
@ -131,12 +130,13 @@ type space struct {
headSync headsync.HeadSync headSync headsync.HeadSync
syncStatus syncstatus.StatusUpdater syncStatus syncstatus.StatusUpdater
storage spacestorage.SpaceStorage storage spacestorage.SpaceStorage
cache *commonGetter treeManager *commonGetter
account accountservice.Service account accountservice.Service
aclList *syncacl.SyncAcl aclList *syncacl.SyncAcl
configuration nodeconf.NodeConf configuration nodeconf.NodeConf
settingsObject settings.SettingsObject settingsObject settings.SettingsObject
peerManager peermanager.PeerManager peerManager peermanager.PeerManager
treeBuilder objecttree.BuildObjectTreeFunc
metric metric.Metric metric metric.Metric
handleQueue multiqueue.MultiQueue[HandleMessage] handleQueue multiqueue.MultiQueue[HandleMessage]
@ -192,8 +192,8 @@ func (s *space) Init(ctx context.Context) (err error) {
if err != nil { if err != nil {
return return
} }
s.aclList = syncacl.NewSyncAcl(aclList, s.objectSync.MessagePool()) s.aclList = syncacl.NewSyncAcl(aclList, s.objectSync.SyncClient().MessagePool())
s.cache.AddObject(s.aclList) s.treeManager.AddObject(s.aclList)
deletionState := settingsstate.NewObjectDeletionState(log, s.storage) deletionState := settingsstate.NewObjectDeletionState(log, s.storage)
deps := settings.Deps{ deps := settings.Deps{
@ -201,6 +201,8 @@ func (s *space) Init(ctx context.Context) (err error) {
res, err := s.BuildTree(ctx, id, BuildTreeOpts{ res, err := s.BuildTree(ctx, id, BuildTreeOpts{
Listener: listener, Listener: listener,
WaitTreeRemoteSync: false, 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)) log.Debug("building settings tree", zap.String("id", id), zap.String("spaceId", s.id))
if err != nil { if err != nil {
@ -210,7 +212,7 @@ func (s *space) Init(ctx context.Context) (err error) {
return return
}, },
Account: s.account, Account: s.account,
TreeGetter: s.cache, TreeManager: s.treeManager,
Store: s.storage, Store: s.storage,
DeletionState: deletionState, DeletionState: deletionState,
Provider: s.headSync, Provider: s.headSync,
@ -218,13 +220,12 @@ func (s *space) Init(ctx context.Context) (err error) {
OnSpaceDelete: s.onSpaceDelete, OnSpaceDelete: s.onSpaceDelete,
} }
s.settingsObject = settings.NewSettingsObject(deps, s.id) s.settingsObject = settings.NewSettingsObject(deps, s.id)
s.objectSync.Init()
s.headSync.Init(initialIds, deletionState) s.headSync.Init(initialIds, deletionState)
err = s.settingsObject.Init(ctx) err = s.settingsObject.Init(ctx)
if err != nil { if err != nil {
return return
} }
s.cache.AddObject(s.settingsObject) s.treeManager.AddObject(s.settingsObject)
s.syncStatus.Run() s.syncStatus.Run()
s.handleQueue = multiqueue.New[HandleMessage](s.handleMessage, 100) s.handleQueue = multiqueue.New[HandleMessage](s.handleMessage, 100)
return nil return nil
@ -256,23 +257,6 @@ func (s *space) DebugAllHeads() []headsync.TreeHeads {
return s.headSync.DebugAllHeads() return s.headSync.DebugAllHeads()
} }
func (s *space) DeriveTree(ctx context.Context, payload objecttree.ObjectTreeCreatePayload) (res treestorage.TreeStorageCreatePayload, err error) {
if s.isClosed.Load() {
err = ErrSpaceClosed
return
}
root, err := objecttree.DeriveObjectTreeRoot(payload, s.aclList)
if err != nil {
return
}
res = treestorage.TreeStorageCreatePayload{
RootRawChange: root,
Changes: []*treechangeproto.RawTreeChangeWithId{root},
Heads: []string{root.Id},
}
return
}
func (s *space) CreateTree(ctx context.Context, payload objecttree.ObjectTreeCreatePayload) (res treestorage.TreeStorageCreatePayload, err error) { func (s *space) CreateTree(ctx context.Context, payload objecttree.ObjectTreeCreatePayload) (res treestorage.TreeStorageCreatePayload, err error) {
if s.isClosed.Load() { if s.isClosed.Load() {
err = ErrSpaceClosed err = ErrSpaceClosed
@ -297,16 +281,17 @@ func (s *space) PutTree(ctx context.Context, payload treestorage.TreeStorageCrea
return return
} }
deps := synctree.BuildDeps{ deps := synctree.BuildDeps{
SpaceId: s.id, SpaceId: s.id,
ObjectSync: s.objectSync, SyncClient: s.objectSync.SyncClient(),
Configuration: s.configuration, Configuration: s.configuration,
HeadNotifiable: s.headSync, HeadNotifiable: s.headSync,
Listener: listener, Listener: listener,
AclList: s.aclList, AclList: s.aclList,
SpaceStorage: s.storage, SpaceStorage: s.storage,
OnClose: s.onObjectClose, OnClose: s.onObjectClose,
SyncStatus: s.syncStatus, SyncStatus: s.syncStatus,
PeerGetter: s.peerManager, PeerGetter: s.peerManager,
BuildObjectTree: s.treeBuilder,
} }
t, err = synctree.PutSyncTree(ctx, payload, deps) t, err = synctree.PutSyncTree(ctx, payload, deps)
if err != nil { if err != nil {
@ -320,6 +305,7 @@ func (s *space) PutTree(ctx context.Context, payload treestorage.TreeStorageCrea
type BuildTreeOpts struct { type BuildTreeOpts struct {
Listener updatelistener.UpdateListener Listener updatelistener.UpdateListener
WaitTreeRemoteSync bool WaitTreeRemoteSync bool
treeBuilder objecttree.BuildObjectTreeFunc
} }
type HistoryTreeOpts struct { type HistoryTreeOpts struct {
@ -333,10 +319,13 @@ func (s *space) BuildTree(ctx context.Context, id string, opts BuildTreeOpts) (t
err = ErrSpaceClosed err = ErrSpaceClosed
return return
} }
treeBuilder := opts.treeBuilder
if treeBuilder == nil {
treeBuilder = s.treeBuilder
}
deps := synctree.BuildDeps{ deps := synctree.BuildDeps{
SpaceId: s.id, SpaceId: s.id,
ObjectSync: s.objectSync, SyncClient: s.objectSync.SyncClient(),
Configuration: s.configuration, Configuration: s.configuration,
HeadNotifiable: s.headSync, HeadNotifiable: s.headSync,
Listener: opts.Listener, Listener: opts.Listener,
@ -346,6 +335,7 @@ func (s *space) BuildTree(ctx context.Context, id string, opts BuildTreeOpts) (t
SyncStatus: s.syncStatus, SyncStatus: s.syncStatus,
WaitTreeRemoteSync: opts.WaitTreeRemoteSync, WaitTreeRemoteSync: opts.WaitTreeRemoteSync,
PeerGetter: s.peerManager, PeerGetter: s.peerManager,
BuildObjectTree: treeBuilder,
} }
if t, err = synctree.BuildSyncTreeOrGetRemote(ctx, id, deps); err != nil { if t, err = synctree.BuildSyncTreeOrGetRemote(ctx, id, deps); err != nil {
return nil, err return nil, err

View File

@ -139,7 +139,7 @@ func (s *spaceService) NewSpace(ctx context.Context, id string) (Space, error) {
} }
} }
lastConfiguration := s.configurationService.GetLast() lastConfiguration := s.configurationService
var ( var (
spaceIsClosed = &atomic.Bool{} spaceIsClosed = &atomic.Bool{}
spaceIsDeleted = &atomic.Bool{} spaceIsDeleted = &atomic.Bool{}
@ -214,7 +214,7 @@ func (s *spaceService) addSpaceStorage(ctx context.Context, spaceDescription Spa
func (s *spaceService) getSpaceStorageFromRemote(ctx context.Context, id string) (st spacestorage.SpaceStorage, err error) { func (s *spaceService) getSpaceStorageFromRemote(ctx context.Context, id string) (st spacestorage.SpaceStorage, err error) {
var p peer.Peer var p peer.Peer
lastConfiguration := s.configurationService.GetLast() lastConfiguration := s.configurationService
// we can't connect to client if it is a node // we can't connect to client if it is a node
if lastConfiguration.IsResponsible(id) { if lastConfiguration.IsResponsible(id) {
err = spacesyncproto.ErrSpaceMissing err = spacesyncproto.ErrSpaceMissing

View File

@ -1,656 +1 @@
package spacestorage package spacestorage
import (
"crypto/rand"
"fmt"
"github.com/anytypeio/any-sync/commonspace/object/accountdata"
"github.com/anytypeio/any-sync/commonspace/object/acl/aclrecordproto"
"github.com/anytypeio/any-sync/commonspace/object/tree/objecttree"
"github.com/anytypeio/any-sync/commonspace/object/tree/treechangeproto"
"github.com/anytypeio/any-sync/commonspace/spacesyncproto"
"github.com/anytypeio/any-sync/util/cidutil"
"github.com/anytypeio/any-sync/util/crypto"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
rand2 "golang.org/x/exp/rand"
"strconv"
"strings"
"testing"
"time"
)
func TestSuccessHeaderPayloadForSpaceCreate(t *testing.T) {
accountKeys, err := accountdata.NewRandom()
require.NoError(t, err)
_, rawHeaderWithId, err := rawHeaderWithId(accountKeys)
require.NoError(t, err)
err = validateCreateSpaceHeaderPayload(rawHeaderWithId)
require.NoError(t, err)
}
func TestFailedHeaderPayloadForSpaceCreate_InvalidFormatSpaceId(t *testing.T) {
accountKeys, err := accountdata.NewRandom()
require.NoError(t, err)
identity, err := accountKeys.SignKey.GetPublic().Marshall()
require.NoError(t, err)
spaceHeaderSeed := make([]byte, 32)
_, err = rand.Read(spaceHeaderSeed)
require.NoError(t, err)
spaceHeaderPayload := make([]byte, 32)
_, err = rand.Read(spaceHeaderPayload)
require.NoError(t, err)
replicationKey := rand2.Uint64()
header := &spacesyncproto.SpaceHeader{
Identity: identity,
Timestamp: time.Now().Unix(),
SpaceType: "SpaceType",
ReplicationKey: replicationKey,
Seed: spaceHeaderSeed,
SpaceHeaderPayload: spaceHeaderPayload,
}
marhalled, err := header.Marshal()
require.NoError(t, err)
signature, err := accountKeys.SignKey.Sign(marhalled)
require.NoError(t, err)
rawHeader := &spacesyncproto.RawSpaceHeader{
SpaceHeader: marhalled,
Signature: signature,
}
marhalledRawHeader, err := rawHeader.Marshal()
require.NoError(t, err)
id, err := cidutil.NewCidFromBytes(marhalled)
require.NoError(t, err)
spaceId := fmt.Sprintf("%s%s", id, strconv.FormatUint(replicationKey, 36))
rawHeaderWithId := &spacesyncproto.RawSpaceHeaderWithId{
RawHeader: marhalledRawHeader,
Id: spaceId,
}
err = validateCreateSpaceHeaderPayload(rawHeaderWithId)
assert.EqualErrorf(t, err, ErrIncorrectSpaceHeader.Error(), "Error should be: %v, got: %v", ErrIncorrectSpaceHeader, err)
}
func TestFailedHeaderPayloadForSpaceCreate_CidIsWrong(t *testing.T) {
accountKeys, err := accountdata.NewRandom()
require.NoError(t, err)
identity, err := accountKeys.SignKey.GetPublic().Marshall()
require.NoError(t, err)
spaceHeaderSeed := make([]byte, 32)
_, err = rand.Read(spaceHeaderSeed)
require.NoError(t, err)
spaceHeaderPayload := make([]byte, 32)
_, err = rand.Read(spaceHeaderPayload)
require.NoError(t, err)
replicationKey := rand2.Uint64()
header := &spacesyncproto.SpaceHeader{
Identity: identity,
Timestamp: time.Now().Unix(),
SpaceType: "SpaceType",
ReplicationKey: replicationKey,
Seed: spaceHeaderSeed,
SpaceHeaderPayload: spaceHeaderPayload,
}
marhalled, err := header.Marshal()
require.NoError(t, err)
signature, err := accountKeys.SignKey.Sign(marhalled)
require.NoError(t, err)
rawHeader := &spacesyncproto.RawSpaceHeader{
SpaceHeader: marhalled,
Signature: signature,
}
marhalledRawHeader, err := rawHeader.Marshal()
require.NoError(t, err)
id := "faisdfjpiocpoakopkop34"
spaceId := fmt.Sprintf("%s.%s", id, strconv.FormatUint(replicationKey, 36))
rawHeaderWithId := &spacesyncproto.RawSpaceHeaderWithId{
RawHeader: marhalledRawHeader,
Id: spaceId,
}
err = validateCreateSpaceHeaderPayload(rawHeaderWithId)
assert.EqualErrorf(t, err, objecttree.ErrIncorrectCid.Error(), "Error should be: %v, got: %v", objecttree.ErrIncorrectCid, err)
}
func TestFailedHeaderPayloadForSpaceCreate_SignedWithAnotherIdentity(t *testing.T) {
accountKeys, err := accountdata.NewRandom()
require.NoError(t, err)
identity, err := accountKeys.SignKey.GetPublic().Marshall()
require.NoError(t, err)
spaceHeaderSeed := make([]byte, 32)
_, err = rand.Read(spaceHeaderSeed)
require.NoError(t, err)
spaceHeaderPayload := make([]byte, 32)
_, err = rand.Read(spaceHeaderPayload)
require.NoError(t, err)
replicationKey := rand2.Uint64()
header := &spacesyncproto.SpaceHeader{
Identity: identity,
Timestamp: time.Now().Unix(),
SpaceType: "SpaceType",
ReplicationKey: replicationKey,
Seed: spaceHeaderSeed,
SpaceHeaderPayload: spaceHeaderPayload,
}
marhalled, err := header.Marshal()
require.NoError(t, err)
anotherAccountKeys, err := accountdata.NewRandom()
signature, err := anotherAccountKeys.SignKey.Sign(marhalled)
require.NoError(t, err)
rawHeader := &spacesyncproto.RawSpaceHeader{
SpaceHeader: marhalled,
Signature: signature,
}
marhalledRawHeader, err := rawHeader.Marshal()
require.NoError(t, err)
id := "faisdfjpiocpoakopkop34"
spaceId := fmt.Sprintf("%s.%s", id, strconv.FormatUint(replicationKey, 36))
rawHeaderWithId := &spacesyncproto.RawSpaceHeaderWithId{
RawHeader: marhalledRawHeader,
Id: spaceId,
}
err = validateCreateSpaceHeaderPayload(rawHeaderWithId)
assert.EqualErrorf(t, err, objecttree.ErrIncorrectCid.Error(), "Error should be: %v, got: %v", objecttree.ErrIncorrectCid, err)
}
func TestSuccessAclPayloadSpace(t *testing.T) {
accountKeys, err := accountdata.NewRandom()
spaceId := "AnySpaceId"
_, rawWithId, err := rawAclWithId(accountKeys, spaceId)
require.NoError(t, err)
validationSpaceId, err := validateCreateSpaceAclPayload(rawWithId)
require.Equal(t, validationSpaceId, spaceId)
require.NoError(t, err)
}
func TestFailAclPayloadSpace_IncorrectCid(t *testing.T) {
accountKeys, err := accountdata.NewRandom()
require.NoError(t, err)
identity, err := accountKeys.SignKey.GetPublic().Marshall()
require.NoError(t, err)
readKeyBytes := make([]byte, 32)
_, err = rand.Read(readKeyBytes)
require.NoError(t, err)
readKey, err := accountKeys.SignKey.GetPublic().Encrypt(readKeyBytes)
require.NoError(t, err)
masterKey, _, err := crypto.GenerateRandomEd25519KeyPair()
require.NoError(t, err)
rawIdentity, err := accountKeys.SignKey.GetPublic().Raw()
require.NoError(t, err)
identitySignature, err := masterKey.Sign(rawIdentity)
require.NoError(t, err)
rawMasterKey, err := masterKey.GetPublic().Marshall()
require.NoError(t, err)
aclRoot := aclrecordproto.AclRoot{
Identity: identity,
MasterKey: rawMasterKey,
SpaceId: "SpaceId",
EncryptedReadKey: readKey,
Timestamp: time.Now().Unix(),
IdentitySignature: identitySignature,
}
marshalled, err := aclRoot.Marshal()
require.NoError(t, err)
signature, err := accountKeys.SignKey.Sign(marshalled)
rawAclRecord := &aclrecordproto.RawAclRecord{
Payload: marshalled,
Signature: signature,
}
marshalledRaw, err := rawAclRecord.Marshal()
require.NoError(t, err)
aclHeadId := "rand"
rawWithId := &aclrecordproto.RawAclRecordWithId{
Payload: marshalledRaw,
Id: aclHeadId,
}
_, err = validateCreateSpaceAclPayload(rawWithId)
assert.EqualErrorf(t, err, objecttree.ErrIncorrectCid.Error(), "Error should be: %v, got: %v", objecttree.ErrIncorrectCid, err)
}
func TestFailedAclPayloadSpace_IncorrectSignature(t *testing.T) {
accountKeys, err := accountdata.NewRandom()
require.NoError(t, err)
readKeyBytes := make([]byte, 32)
_, err = rand.Read(readKeyBytes)
require.NoError(t, err)
readKey, err := accountKeys.SignKey.GetPublic().Encrypt(readKeyBytes)
require.NoError(t, err)
masterKey, _, err := crypto.GenerateRandomEd25519KeyPair()
require.NoError(t, err)
rawIdentity, err := accountKeys.SignKey.GetPublic().Raw()
require.NoError(t, err)
identity, err := accountKeys.SignKey.GetPublic().Marshall()
identitySignature, err := masterKey.Sign(rawIdentity)
require.NoError(t, err)
rawMasterKey, err := masterKey.GetPublic().Raw()
require.NoError(t, err)
aclRoot := aclrecordproto.AclRoot{
Identity: identity,
MasterKey: rawMasterKey,
SpaceId: "SpaceId",
EncryptedReadKey: readKey,
Timestamp: time.Now().Unix(),
IdentitySignature: identitySignature,
}
marshalled, err := aclRoot.Marshal()
require.NoError(t, err)
rawAclRecord := &aclrecordproto.RawAclRecord{
Payload: marshalled,
Signature: marshalled,
}
marshalledRaw, err := rawAclRecord.Marshal()
require.NoError(t, err)
aclHeadId, err := cidutil.NewCidFromBytes(marshalledRaw)
require.NoError(t, err)
rawWithId := &aclrecordproto.RawAclRecordWithId{
Payload: marshalledRaw,
Id: aclHeadId,
}
_, err = validateCreateSpaceAclPayload(rawWithId)
assert.NotNil(t, err)
assert.EqualErrorf(t, err, ErrIncorrectSpaceHeader.Error(), "Error should be: %v, got: %v", ErrIncorrectSpaceHeader, err)
}
func TestFailedAclPayloadSpace_IncorrectIdentitySignature(t *testing.T) {
spaceId := "AnySpaceId"
accountKeys, err := accountdata.NewRandom()
require.NoError(t, err)
readKeyBytes := make([]byte, 32)
_, err = rand.Read(readKeyBytes)
if err != nil {
return
}
readKey, err := accountKeys.SignKey.GetPublic().Encrypt(readKeyBytes)
if err != nil {
return
}
masterKey, _, err := crypto.GenerateRandomEd25519KeyPair()
if err != nil {
return
}
masterPubKey := masterKey.GetPublic()
identity, err := accountKeys.SignKey.GetPublic().Marshall()
if err != nil {
return
}
rawMasterKey, err := masterPubKey.Marshall()
if err != nil {
return
}
aclRoot := aclrecordproto.AclRoot{
Identity: identity,
MasterKey: rawMasterKey,
SpaceId: spaceId,
EncryptedReadKey: readKey,
Timestamp: time.Now().Unix(),
IdentitySignature: identity,
}
marshalled, err := aclRoot.Marshal()
if err != nil {
return
}
signature, err := accountKeys.SignKey.Sign(marshalled)
rawAclRecord := &aclrecordproto.RawAclRecord{
Payload: marshalled,
Signature: signature,
}
marshalledRaw, err := rawAclRecord.Marshal()
if err != nil {
return
}
aclHeadId, err := cidutil.NewCidFromBytes(marshalledRaw)
if err != nil {
return
}
rawWithId := &aclrecordproto.RawAclRecordWithId{
Payload: marshalledRaw,
Id: aclHeadId,
}
_, err = validateCreateSpaceAclPayload(rawWithId)
assert.EqualErrorf(t, err, ErrIncorrectSpaceHeader.Error(), "Error should be: %v, got: %v", ErrIncorrectSpaceHeader, err)
}
func TestSuccessSettingsPayloadSpace(t *testing.T) {
accountKeys, err := accountdata.NewRandom()
require.NoError(t, err)
identity, err := accountKeys.SignKey.GetPublic().Marshall()
require.NoError(t, err)
spaceSettingsSeed := make([]byte, 32)
_, err = rand.Read(spaceSettingsSeed)
require.NoError(t, err)
changePayload := make([]byte, 32)
_, err = rand.Read(changePayload)
require.NoError(t, err)
spaceId := "SpaceId"
rootChange := &treechangeproto.RootChange{
AclHeadId: "AclHeadId",
SpaceId: spaceId,
ChangeType: "ChangeType",
Timestamp: time.Now().Unix(),
Seed: spaceSettingsSeed,
Identity: identity,
ChangePayload: changePayload,
}
marshalledChange, err := rootChange.Marshal()
require.NoError(t, err)
signature, err := accountKeys.SignKey.Sign(marshalledChange)
require.NoError(t, err)
raw := &treechangeproto.RawTreeChange{
Payload: marshalledChange,
Signature: signature,
}
marshalledRawChange, err := raw.Marshal()
id, err := cidutil.NewCidFromBytes(marshalledRawChange)
require.NoError(t, err)
rawIdChange := &treechangeproto.RawTreeChangeWithId{
RawChange: marshalledRawChange,
Id: id,
}
_, validationSpaceId, err := validateCreateSpaceSettingsPayload(rawIdChange)
require.Equal(t, validationSpaceId, spaceId)
require.NoError(t, err)
}
func TestFailSettingsPayloadSpace_InvalidSignature(t *testing.T) {
accountKeys, err := accountdata.NewRandom()
require.NoError(t, err)
identity, err := accountKeys.SignKey.GetPublic().Marshall()
require.NoError(t, err)
spaceSettingsSeed := make([]byte, 32)
_, err = rand.Read(spaceSettingsSeed)
require.NoError(t, err)
changePayload := make([]byte, 32)
_, err = rand.Read(changePayload)
require.NoError(t, err)
rootChange := &treechangeproto.RootChange{
AclHeadId: "AclHeadId",
SpaceId: "SpaceId",
ChangeType: "ChangeType",
Timestamp: time.Now().Unix(),
Seed: spaceSettingsSeed,
Identity: identity,
ChangePayload: changePayload,
}
marshalledChange, err := rootChange.Marshal()
require.NoError(t, err)
raw := &treechangeproto.RawTreeChange{
Payload: marshalledChange,
Signature: marshalledChange,
}
marshalledRawChange, err := raw.Marshal()
id, err := cidutil.NewCidFromBytes(marshalledRawChange)
require.NoError(t, err)
rawIdChange := &treechangeproto.RawTreeChangeWithId{
RawChange: marshalledRawChange,
Id: id,
}
_, _, err = validateCreateSpaceSettingsPayload(rawIdChange)
assert.EqualErrorf(t, err, ErrIncorrectSpaceHeader.Error(), "Error should be: %v, got: %v", ErrIncorrectSpaceHeader, err)
}
func TestFailSettingsPayloadSpace_InvalidCid(t *testing.T) {
accountKeys, err := accountdata.NewRandom()
require.NoError(t, err)
identity, err := accountKeys.SignKey.GetPublic().Marshall()
require.NoError(t, err)
spaceSettingsSeed := make([]byte, 32)
_, err = rand.Read(spaceSettingsSeed)
require.NoError(t, err)
changePayload := make([]byte, 32)
_, err = rand.Read(changePayload)
require.NoError(t, err)
rootChange := &treechangeproto.RootChange{
AclHeadId: "AclHeadId",
SpaceId: "SpaceId",
ChangeType: "ChangeType",
Timestamp: time.Now().Unix(),
Seed: spaceSettingsSeed,
Identity: identity,
ChangePayload: changePayload,
}
marshalledChange, err := rootChange.Marshal()
require.NoError(t, err)
signature, err := accountKeys.SignKey.Sign(marshalledChange)
require.NoError(t, err)
raw := &treechangeproto.RawTreeChange{
Payload: marshalledChange,
Signature: signature,
}
marshalledRawChange, err := raw.Marshal()
id := "id"
require.NoError(t, err)
rawIdChange := &treechangeproto.RawTreeChangeWithId{
RawChange: marshalledRawChange,
Id: id,
}
_, _, err = validateCreateSpaceSettingsPayload(rawIdChange)
assert.EqualErrorf(t, err, ErrIncorrectSpaceHeader.Error(), "Error should be: %v, got: %v", ErrIncorrectSpaceHeader, err)
}
func TestSuccessSameIds(t *testing.T) {
accountKeys, err := accountdata.NewRandom()
require.NoError(t, err)
spaceId, rawHeaderWithId, err := rawHeaderWithId(accountKeys)
require.NoError(t, err)
aclHeadId, rawAclWithId, err := rawAclWithId(accountKeys, spaceId)
require.NoError(t, err)
rawSettingsPayload, err := rawSettingsPayload(accountKeys, spaceId, aclHeadId)
spacePayload := SpaceStorageCreatePayload{
AclWithId: rawAclWithId,
SpaceHeaderWithId: rawHeaderWithId,
SpaceSettingsWithId: rawSettingsPayload,
}
err = ValidateSpaceStorageCreatePayload(spacePayload)
require.NoError(t, err)
}
func TestFailWithAclWrongSpaceId(t *testing.T) {
accountKeys, err := accountdata.NewRandom()
require.NoError(t, err)
spaceId, rawHeaderWithId, err := rawHeaderWithId(accountKeys)
require.NoError(t, err)
aclHeadId, rawAclWithId, err := rawAclWithId(accountKeys, "spaceId")
require.NoError(t, err)
rawSettingsPayload, err := rawSettingsPayload(accountKeys, spaceId, aclHeadId)
spacePayload := SpaceStorageCreatePayload{
AclWithId: rawAclWithId,
SpaceHeaderWithId: rawHeaderWithId,
SpaceSettingsWithId: rawSettingsPayload,
}
err = ValidateSpaceStorageCreatePayload(spacePayload)
assert.EqualErrorf(t, err, ErrIncorrectSpaceHeader.Error(), "Error should be: %v, got: %v", ErrIncorrectSpaceHeader, err)
}
func TestFailWithSettingsWrongSpaceId(t *testing.T) {
accountKeys, err := accountdata.NewRandom()
require.NoError(t, err)
spaceId, rawHeaderWithId, err := rawHeaderWithId(accountKeys)
require.NoError(t, err)
aclHeadId, rawAclWithId, err := rawAclWithId(accountKeys, spaceId)
require.NoError(t, err)
rawSettingsPayload, err := rawSettingsPayload(accountKeys, "spaceId", aclHeadId)
spacePayload := SpaceStorageCreatePayload{
AclWithId: rawAclWithId,
SpaceHeaderWithId: rawHeaderWithId,
SpaceSettingsWithId: rawSettingsPayload,
}
err = ValidateSpaceStorageCreatePayload(spacePayload)
assert.EqualErrorf(t, err, ErrIncorrectSpaceHeader.Error(), "Error should be: %v, got: %v", ErrIncorrectSpaceHeader, err)
}
func TestFailWithWrongAclHeadIdInSettingsPayload(t *testing.T) {
accountKeys, err := accountdata.NewRandom()
require.NoError(t, err)
spaceId, rawHeaderWithId, err := rawHeaderWithId(accountKeys)
require.NoError(t, err)
_, rawAclWithId, err := rawAclWithId(accountKeys, spaceId)
require.NoError(t, err)
rawSettingsPayload, err := rawSettingsPayload(accountKeys, spaceId, "aclHeadId")
spacePayload := SpaceStorageCreatePayload{
AclWithId: rawAclWithId,
SpaceHeaderWithId: rawHeaderWithId,
SpaceSettingsWithId: rawSettingsPayload,
}
err = ValidateSpaceStorageCreatePayload(spacePayload)
assert.EqualErrorf(t, err, ErrIncorrectSpaceHeader.Error(), "Error should be: %v, got: %v", ErrIncorrectSpaceHeader, err)
}
func rawSettingsPayload(accountKeys *accountdata.AccountKeys, spaceId, aclHeadId string) (rawIdChange *treechangeproto.RawTreeChangeWithId, err error) {
identity, err := accountKeys.SignKey.GetPublic().Marshall()
if err != nil {
return
}
spaceSettingsSeed := make([]byte, 32)
_, err = rand.Read(spaceSettingsSeed)
if err != nil {
return
}
changePayload := make([]byte, 32)
_, err = rand.Read(changePayload)
if err != nil {
return
}
rootChange := &treechangeproto.RootChange{
AclHeadId: aclHeadId,
SpaceId: spaceId,
ChangeType: "ChangeType",
Timestamp: time.Now().Unix(),
Seed: spaceSettingsSeed,
Identity: identity,
ChangePayload: changePayload,
}
marshalledChange, err := rootChange.Marshal()
if err != nil {
return
}
signature, err := accountKeys.SignKey.Sign(marshalledChange)
if err != nil {
return
}
raw := &treechangeproto.RawTreeChange{
Payload: marshalledChange,
Signature: signature,
}
marshalledRawChange, err := raw.Marshal()
id, err := cidutil.NewCidFromBytes(marshalledRawChange)
if err != nil {
return
}
rawIdChange = &treechangeproto.RawTreeChangeWithId{
RawChange: marshalledRawChange,
Id: id,
}
return
}
func rawAclWithId(accountKeys *accountdata.AccountKeys, spaceId string) (aclHeadId string, rawWithId *aclrecordproto.RawAclRecordWithId, err error) {
readKeyBytes := make([]byte, 32)
_, err = rand.Read(readKeyBytes)
if err != nil {
return
}
readKey, err := accountKeys.SignKey.GetPublic().Encrypt(readKeyBytes)
if err != nil {
return
}
masterKey, _, err := crypto.GenerateRandomEd25519KeyPair()
identity, err := accountKeys.SignKey.GetPublic().Marshall()
if err != nil {
return
}
masterPubKey := masterKey.GetPublic()
rawIdentity, err := accountKeys.SignKey.GetPublic().Raw()
if err != nil {
return
}
identitySignature, err := masterKey.Sign(rawIdentity)
if err != nil {
return
}
rawMasterKey, err := masterPubKey.Marshall()
if err != nil {
return
}
aclRoot := aclrecordproto.AclRoot{
Identity: identity,
MasterKey: rawMasterKey,
SpaceId: spaceId,
EncryptedReadKey: readKey,
Timestamp: time.Now().Unix(),
IdentitySignature: identitySignature,
}
marshalled, err := aclRoot.Marshal()
if err != nil {
return
}
signature, err := accountKeys.SignKey.Sign(marshalled)
rawAclRecord := &aclrecordproto.RawAclRecord{
Payload: marshalled,
Signature: signature,
}
marshalledRaw, err := rawAclRecord.Marshal()
if err != nil {
return
}
aclHeadId, err = cidutil.NewCidFromBytes(marshalledRaw)
if err != nil {
return
}
rawWithId = &aclrecordproto.RawAclRecordWithId{
Payload: marshalledRaw,
Id: aclHeadId,
}
return
}
func rawHeaderWithId(accountKeys *accountdata.AccountKeys) (spaceId string, rawWithId *spacesyncproto.RawSpaceHeaderWithId, err error) {
identity, err := accountKeys.SignKey.GetPublic().Marshall()
if err != nil {
return
}
spaceHeaderSeed := make([]byte, 32)
_, err = rand.Read(spaceHeaderSeed)
if err != nil {
return
}
spaceHeaderPayload := make([]byte, 32)
_, err = rand.Read(spaceHeaderPayload)
if err != nil {
return
}
replicationKey := rand2.Uint64()
header := &spacesyncproto.SpaceHeader{
Identity: identity,
Timestamp: time.Now().Unix(),
SpaceType: "SpaceType",
ReplicationKey: replicationKey,
Seed: spaceHeaderSeed,
SpaceHeaderPayload: spaceHeaderPayload,
}
marhalled, err := header.Marshal()
if err != nil {
return
}
signature, err := accountKeys.SignKey.Sign(marhalled)
if err != nil {
return
}
rawHeader := &spacesyncproto.RawSpaceHeader{
SpaceHeader: marhalled,
Signature: signature,
}
marhalledRawHeader, err := rawHeader.Marshal()
if err != nil {
return
}
id, err := cidutil.NewCidFromBytes(marhalledRawHeader)
if err != nil {
return
}
spaceId = fmt.Sprintf("%s.%s", id, strconv.FormatUint(replicationKey, 36))
rawWithId = &spacesyncproto.RawSpaceHeaderWithId{
RawHeader: marhalledRawHeader,
Id: spaceId,
}
return
}

View File

@ -72,7 +72,7 @@ type treeStatus struct {
type syncStatusProvider struct { type syncStatusProvider struct {
sync.Mutex sync.Mutex
configuration nodeconf.Configuration configuration nodeconf.NodeConf
periodicSync periodicsync.PeriodicSync periodicSync periodicsync.PeriodicSync
updateReceiver UpdateReceiver updateReceiver UpdateReceiver
storage spacestorage.SpaceStorage storage spacestorage.SpaceStorage
@ -92,11 +92,11 @@ type syncStatusProvider struct {
type SyncStatusDeps struct { type SyncStatusDeps struct {
UpdateIntervalSecs int UpdateIntervalSecs int
UpdateTimeout time.Duration UpdateTimeout time.Duration
Configuration nodeconf.Configuration Configuration nodeconf.NodeConf
Storage spacestorage.SpaceStorage Storage spacestorage.SpaceStorage
} }
func DefaultDeps(configuration nodeconf.Configuration, store spacestorage.SpaceStorage) SyncStatusDeps { func DefaultDeps(configuration nodeconf.NodeConf, store spacestorage.SpaceStorage) SyncStatusDeps {
return SyncStatusDeps{ return SyncStatusDeps{
UpdateIntervalSecs: syncUpdateInterval, UpdateIntervalSecs: syncUpdateInterval,
UpdateTimeout: syncTimeout, UpdateTimeout: syncTimeout,

View File

@ -145,7 +145,7 @@ func (c *coordinatorClient) NetworkConfiguration(ctx context.Context, currentId
} }
func (c *coordinatorClient) client(ctx context.Context) (coordinatorproto.DRPCCoordinatorClient, error) { func (c *coordinatorClient) client(ctx context.Context) (coordinatorproto.DRPCCoordinatorClient, error) {
p, err := c.pool.GetOneOf(ctx, c.nodeConf.GetLast().CoordinatorPeers()) p, err := c.pool.GetOneOf(ctx, c.nodeConf.CoordinatorPeers())
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -57,7 +57,7 @@ func (s *secureService) Init(a *app.App) (err error) {
s.nodeconf = a.MustComponent(nodeconf.CName).(nodeconf.Service) s.nodeconf = a.MustComponent(nodeconf.CName).(nodeconf.Service)
s.inboundChecker = s.noVerifyChecker s.inboundChecker = s.noVerifyChecker
confTypes := s.nodeconf.GetLast().NodeTypes(account.Account().PeerId) confTypes := s.nodeconf.NodeTypes(account.Account().PeerId)
if len(confTypes) > 0 { if len(confTypes) > 0 {
// require identity verification if we are node // require identity verification if we are node
s.inboundChecker = s.peerSignVerifier s.inboundChecker = s.peerSignVerifier
@ -99,7 +99,7 @@ func (s *secureService) SecureOutbound(ctx context.Context, conn net.Conn) (sec.
return nil, handshake.HandshakeError{Err: err} return nil, handshake.HandshakeError{Err: err}
} }
peerId := sc.RemotePeer().String() peerId := sc.RemotePeer().String()
confTypes := s.nodeconf.GetLast().NodeTypes(peerId) confTypes := s.nodeconf.NodeTypes(peerId)
var checker handshake.CredentialChecker var checker handshake.CredentialChecker
if len(confTypes) > 0 { if len(confTypes) > 0 {
checker = s.peerSignVerifier checker = s.peerSignVerifier

View File

@ -121,6 +121,7 @@ func (s *service) setLastConfiguration(c Configuration) (err error) {
id: c.Id, id: c.Id,
c: c, c: c,
accountId: s.accountId, accountId: s.accountId,
addrs: map[string][]string{},
} }
if nc.chash, err = chash.New(chash.Config{ if nc.chash, err = chash.New(chash.Config{
PartitionCount: PartitionCount, PartitionCount: PartitionCount,
@ -144,6 +145,7 @@ func (s *service) setLastConfiguration(c Configuration) (err error) {
nc.coordinatorPeers = append(nc.coordinatorPeers, n.PeerId) nc.coordinatorPeers = append(nc.coordinatorPeers, n.PeerId)
} }
nc.allMembers = append(nc.allMembers, n) nc.allMembers = append(nc.allMembers, n)
nc.addrs[n.PeerId] = n.Addresses
} }
if err = nc.chash.AddMembers(members...); err != nil { if err = nc.chash.AddMembers(members...); err != nil {
return return
@ -218,10 +220,10 @@ func (s *service) CoordinatorPeers() []string {
return s.last.CoordinatorPeers() return s.last.CoordinatorPeers()
} }
func (s *service) Addresses() map[string][]string { func (s *service) PeerAddresses(peerId string) ([]string, bool) {
s.mu.RLock() s.mu.RLock()
defer s.mu.RUnlock() defer s.mu.RUnlock()
return s.last.Addresses() return s.last.PeerAddresses(peerId)
} }
func (s *service) CHash() chash.CHash { func (s *service) CHash() chash.CHash {

View File

@ -158,6 +158,11 @@ func (k *Ed25519PubKey) Account() string {
return res return res
} }
func (k *Ed25519PubKey) Network() string {
res, _ := strkey.Encode(strkey.NetworkAddressVersionByte, k.pubKey)
return res
}
// PeerId returns string representation of key for peer id // PeerId returns string representation of key for peer id
func (k *Ed25519PubKey) PeerId() string { func (k *Ed25519PubKey) PeerId() string {
peerId, _ := IdFromSigningPubKey(k) peerId, _ := IdFromSigningPubKey(k)

View File

@ -47,6 +47,8 @@ type PubKey interface {
Storage() []byte Storage() []byte
// Account returns string representation for anytype account // Account returns string representation for anytype account
Account() string Account() string
// Network returns string representation for anytype network
Network() string
// PeerId returns string representation for peer id // PeerId returns string representation for peer id
PeerId() string PeerId() string
// LibP2P returns libp2p model // LibP2P returns libp2p model

View File

@ -1,19 +1,16 @@
package strkey package strkey
import ( import (
"github.com/anytypeio/any-sync/util/keys/asymmetric/signingkey"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"testing" "testing"
) )
func TestDecode(t *testing.T) { func TestDecode(t *testing.T) {
_, pubKey, err := signingkey.GenerateRandomEd25519KeyPair() key := "ABCw4rFBR7qU2HGzHwnKLYo9mMRcjGhFK28gSy58RKc5feqz"
res, err := Decode(AccountAddressVersionByte, key)
require.NoError(t, err) require.NoError(t, err)
raw, _ := pubKey.Raw() str, err := Encode(AccountAddressVersionByte, res)
str, err := Encode(NetworkAddressVersionByte, raw)
require.NoError(t, err) require.NoError(t, err)
res, err := Decode(NetworkAddressVersionByte, str) assert.Equal(t, key, str)
require.NoError(t, err)
assert.Equal(t, raw, res)
} }