1
0
Fork 0
mirror of https://github.com/anyproto/any-sync.git synced 2025-06-08 05:57:03 +09:00

Merge branch 'main' of github.com:anyproto/any-sync into GO-1737-any-id-repository

This commit is contained in:
Sergey Cherepanov 2023-08-03 14:17:43 +02:00
commit 59d41386c4
No known key found for this signature in database
GPG key ID: 87F8EDE8FBDF637C
44 changed files with 2245 additions and 543 deletions

17
.githooks/pre-push Executable file
View file

@ -0,0 +1,17 @@
#!/usr/bin/env bash
INSTALL_PYTHON=python3
ARGS=(hook-impl --config=.pre-commit-config.yaml --hook-type=pre-push)
# end templated
HERE="$(cd "$(dirname "$0")" && pwd)"
ARGS+=(--hook-dir "$HERE" -- "$@")
if [ -x "$INSTALL_PYTHON" ]; then
exec "$INSTALL_PYTHON" -mpre_commit "${ARGS[@]}"
elif command -v pre-commit > /dev/null; then
exec pre-commit "${ARGS[@]}"
else
echo '`pre-commit` not found. Please visit https://wiki.anytype.io/doc/mandatory-git-hooks-5rQt1Qyw7k ' 1>&2
exit 1
fi

17
.github/workflows/cla.yml vendored Normal file
View file

@ -0,0 +1,17 @@
name: "CLA Check"
on:
issue_comment:
types: [created]
pull_request_target:
types: [opened,closed,synchronize]
permissions:
actions: write
contents: write
pull-requests: write
statuses: write
jobs:
cla-check:
uses: anyproto/open/.github/workflows/cla.yml@main
secrets: inherit

View file

@ -3,6 +3,10 @@ on:
branches:
- main
permissions:
contents: write
pull-requests: write
jobs:
test:
runs-on: ubuntu-latest
@ -32,6 +36,21 @@ jobs:
${{ runner.os }}-go-${{ matrix.go-version }}-
# }}
- name: Setup license repository
uses: actions/checkout@master
with:
repository: anyproto/open
ref: refs/heads/main
path: ./open
- name: Check licenses
run: |
cd open
python3 tools/generate.py --platform golang
cd ..
sudo gem install license_finder
license_finder inherited_decisions add open/decisions.yml
license_finder --enabled-package-managers gomodules
- name: deps
run: make deps
@ -55,3 +74,4 @@ jobs:
echo "Failed"
exit 1
fi
- uses: seriousben/go-patch-cover-action@v1

5
.pre-commit-config.yaml Normal file
View file

@ -0,0 +1,5 @@
repos:
- repo: https://github.com/zricethezav/gitleaks
rev: v8.16.0
hooks:
- id: gitleaks

View file

@ -2,6 +2,10 @@
export GOPRIVATE=github.com/anyproto
export PATH:=deps:$(PATH)
all:
@set -e;
@git config core.hooksPath .githooks;
proto:
@echo 'Generating protobuf packages (Go)...'

View file

@ -31,11 +31,15 @@ You can find the various parts of the protocol implemented in Go in the followin
- [`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.
Thank you for your desire to develop Anytype together!
Currently, we're not ready to accept PRs, but we will in the nearest future.
❤️ This project and everyone involved in it is governed by the [Code of Conduct](https://github.com/anyproto/.github/blob/main/docs/CODE_OF_CONDUCT.md).
Follow us on [Github](https://github.com/anyproto) and join the [Contributors Community](https://github.com/orgs/anyproto/discussions).
🧑‍💻 Check out our [contributing guide](https://github.com/anyproto/.github/blob/main/docs/CONTRIBUTING.md) to learn about asking questions, creating issues, or submitting pull requests.
🫢 For security findings, please email [security@anytype.io](mailto:security@anytype.io) and refer to our [security guide](https://github.com/anyproto/.github/blob/main/docs/SECURITY.md) for more information.
🤝 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 🇨🇭

View file

@ -3,11 +3,11 @@ package fileservice
import (
"context"
"github.com/anyproto/any-sync/commonfile/fileblockstore"
"github.com/ipfs/boxo/blockservice"
blockstore "github.com/ipfs/boxo/blockstore"
exchange "github.com/ipfs/boxo/exchange"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-blockservice"
"github.com/ipfs/go-cid"
blockstore "github.com/ipfs/go-ipfs-blockstore"
exchange "github.com/ipfs/go-ipfs-exchange-interface"
)
func newBlockService(store fileblockstore.BlockStore) blockservice.BlockService {

View file

@ -6,13 +6,13 @@ import (
"github.com/anyproto/any-sync/app"
"github.com/anyproto/any-sync/app/logger"
"github.com/anyproto/any-sync/commonfile/fileblockstore"
chunker "github.com/ipfs/boxo/chunker"
"github.com/ipfs/boxo/ipld/merkledag"
"github.com/ipfs/boxo/ipld/unixfs/importer/balanced"
"github.com/ipfs/boxo/ipld/unixfs/importer/helpers"
ufsio "github.com/ipfs/boxo/ipld/unixfs/io"
"github.com/ipfs/go-cid"
chunker "github.com/ipfs/go-ipfs-chunker"
ipld "github.com/ipfs/go-ipld-format"
"github.com/ipfs/go-merkledag"
"github.com/ipfs/go-unixfs/importer/balanced"
"github.com/ipfs/go-unixfs/importer/helpers"
ufsio "github.com/ipfs/go-unixfs/io"
"github.com/multiformats/go-multihash"
"go.uber.org/zap"
"io"

View file

@ -51,6 +51,7 @@ func TestSpaceDeleteIds(t *testing.T) {
fx := newFixture(t)
acc := fx.account.Account()
rk := crypto.NewAES()
privKey, _, _ := crypto.GenerateRandomEd25519KeyPair()
ctx := context.Background()
totalObjs := 1500
@ -58,7 +59,8 @@ func TestSpaceDeleteIds(t *testing.T) {
sp, err := fx.spaceService.CreateSpace(ctx, SpaceCreatePayload{
SigningKey: acc.SignKey,
SpaceType: "type",
ReadKey: rk.Bytes(),
ReadKey: rk,
MetadataKey: privKey,
ReplicationKey: 10,
MasterKey: acc.PeerKey,
})
@ -126,6 +128,7 @@ func TestSpaceDeleteIdsIncorrectSnapshot(t *testing.T) {
fx := newFixture(t)
acc := fx.account.Account()
rk := crypto.NewAES()
privKey, _, _ := crypto.GenerateRandomEd25519KeyPair()
ctx := context.Background()
totalObjs := 1500
partialObjs := 300
@ -134,7 +137,8 @@ func TestSpaceDeleteIdsIncorrectSnapshot(t *testing.T) {
sp, err := fx.spaceService.CreateSpace(ctx, SpaceCreatePayload{
SigningKey: acc.SignKey,
SpaceType: "type",
ReadKey: rk.Bytes(),
ReadKey: rk,
MetadataKey: privKey,
ReplicationKey: 10,
MasterKey: acc.PeerKey,
})
@ -212,6 +216,7 @@ func TestSpaceDeleteIdsMarkDeleted(t *testing.T) {
fx := newFixture(t)
acc := fx.account.Account()
rk := crypto.NewAES()
privKey, _, _ := crypto.GenerateRandomEd25519KeyPair()
ctx := context.Background()
totalObjs := 1500
@ -219,7 +224,8 @@ func TestSpaceDeleteIdsMarkDeleted(t *testing.T) {
sp, err := fx.spaceService.CreateSpace(ctx, SpaceCreatePayload{
SigningKey: acc.SignKey,
SpaceType: "type",
ReadKey: rk.Bytes(),
ReadKey: rk,
MetadataKey: privKey,
ReplicationKey: 10,
MasterKey: acc.PeerKey,
})

View file

@ -29,6 +29,8 @@ type DiffSyncer interface {
Close() error
}
const logPeriodSecs = 200
func newDiffSyncer(hs *headSync) DiffSyncer {
return &diffSyncer{
diff: hs.diff,
@ -38,7 +40,7 @@ func newDiffSyncer(hs *headSync) DiffSyncer {
peerManager: hs.peerManager,
clientFactory: spacesyncproto.ClientFactoryFunc(spacesyncproto.NewDRPCSpaceSyncClient),
credentialProvider: hs.credentialProvider,
log: log,
log: newSyncLogger(hs.log, logPeriodSecs),
syncStatus: hs.syncStatus,
deletionState: hs.deletionState,
syncAcl: hs.syncAcl,
@ -52,7 +54,7 @@ type diffSyncer struct {
treeManager treemanager.TreeManager
storage spacestorage.SpaceStorage
clientFactory spacesyncproto.ClientFactory
log logger.CtxLogger
log syncLogger
deletionState deletionstate.ObjectDeletionState
credentialProvider credentialprovider.CredentialProvider
syncStatus syncstatus.StatusUpdater
@ -105,7 +107,7 @@ func (d *diffSyncer) Sync(ctx context.Context) error {
d.log.ErrorCtx(ctx, "can't sync with peer", zap.String("peer", p.Id()), zap.Error(err))
}
}
d.log.InfoCtx(ctx, "diff done", zap.String("spaceId", d.spaceId), zap.Duration("dur", time.Since(st)))
d.log.DebugCtx(ctx, "diff done", zap.String("spaceId", d.spaceId), zap.Duration("dur", time.Since(st)))
return nil
}
@ -162,13 +164,7 @@ func (d *diffSyncer) syncWithPeer(ctx context.Context, p peer.Peer) (err error)
if err != nil {
return err
}
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-prevExistingLen-len(missingIds)),
zap.String("peerId", p.Id()),
)
d.log.logSyncDone(p.Id(), len(newIds), len(changedIds), len(removedIds), totalLen-len(existingIds)-len(missingIds))
return
}

View file

@ -9,7 +9,7 @@ import (
"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/config"
"github.com/anyproto/any-sync/commonspace/credentialprovider"
"github.com/anyproto/any-sync/commonspace/deletionstate"
"github.com/anyproto/any-sync/commonspace/object/acl/syncacl"
@ -73,7 +73,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)
cfg := a.MustComponent("config").(config.ConfigGetter)
h.syncAcl = a.MustComponent(syncacl.CName).(syncacl.SyncAcl)
h.spaceId = shared.SpaceId
h.spaceIsDeleted = shared.SpaceIsDeleted

View file

@ -0,0 +1,41 @@
package headsync
import (
"time"
"github.com/anyproto/any-sync/app/logger"
"go.uber.org/zap"
)
type syncLogger struct {
lastLogged map[string]time.Time
logInterval time.Duration
logger.CtxLogger
}
func newSyncLogger(log logger.CtxLogger, syncLogPeriodSecs int) syncLogger {
return syncLogger{
lastLogged: map[string]time.Time{},
logInterval: time.Duration(syncLogPeriodSecs) * time.Second,
CtxLogger: log,
}
}
func (s syncLogger) logSyncDone(peerId string, newIds, changedIds, removedIds, deltedIds int) {
now := time.Now()
differentIds := newIds + changedIds + removedIds + deltedIds
// always logging if some ids are different or there are no log interval
if differentIds == 0 && s.logInterval > 0 {
lastLogged := s.lastLogged[peerId]
if now.Before(lastLogged.Add(s.logInterval)) {
return
}
}
s.lastLogged[peerId] = now
s.Info("sync done:", zap.Int("newIds", newIds),
zap.Int("changedIds", changedIds),
zap.Int("removedIds", removedIds),
zap.Int("already deleted ids", deltedIds),
zap.String("peerId", peerId),
)
}

View file

@ -59,12 +59,14 @@ func (AclUserPermissions) EnumDescriptor() ([]byte, []int) {
// 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"`
SpaceId string `protobuf:"bytes,3,opt,name=spaceId,proto3" json:"spaceId,omitempty"`
EncryptedReadKey []byte `protobuf:"bytes,4,opt,name=encryptedReadKey,proto3" json:"encryptedReadKey,omitempty"`
Timestamp int64 `protobuf:"varint,5,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
IdentitySignature []byte `protobuf:"bytes,6,opt,name=identitySignature,proto3" json:"identitySignature,omitempty"`
Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"`
MasterKey []byte `protobuf:"bytes,2,opt,name=masterKey,proto3" json:"masterKey,omitempty"`
SpaceId string `protobuf:"bytes,3,opt,name=spaceId,proto3" json:"spaceId,omitempty"`
EncryptedReadKey []byte `protobuf:"bytes,4,opt,name=encryptedReadKey,proto3" json:"encryptedReadKey,omitempty"`
Timestamp int64 `protobuf:"varint,5,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
IdentitySignature []byte `protobuf:"bytes,6,opt,name=identitySignature,proto3" json:"identitySignature,omitempty"`
MetadataPubKey []byte `protobuf:"bytes,7,opt,name=metadataPubKey,proto3" json:"metadataPubKey,omitempty"`
EncryptedMetadataPrivKey []byte `protobuf:"bytes,8,opt,name=encryptedMetadataPrivKey,proto3" json:"encryptedMetadataPrivKey,omitempty"`
}
func (m *AclRoot) Reset() { *m = AclRoot{} }
@ -142,6 +144,20 @@ func (m *AclRoot) GetIdentitySignature() []byte {
return nil
}
func (m *AclRoot) GetMetadataPubKey() []byte {
if m != nil {
return m.MetadataPubKey
}
return nil
}
func (m *AclRoot) GetEncryptedMetadataPrivKey() []byte {
if m != nil {
return m.EncryptedMetadataPrivKey
}
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"`
@ -192,7 +208,8 @@ 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"`
// Metadata is encrypted with metadata key of the space
Metadata []byte `protobuf:"bytes,4,opt,name=metadata,proto3" json:"metadata,omitempty"`
}
func (m *AclAccountRequestJoin) Reset() { *m = AclAccountRequestJoin{} }
@ -258,10 +275,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 []*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"`
Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"`
RequestRecordId string `protobuf:"bytes,2,opt,name=requestRecordId,proto3" json:"requestRecordId,omitempty"`
EncryptedReadKey []byte `protobuf:"bytes,3,opt,name=encryptedReadKey,proto3" json:"encryptedReadKey,omitempty"`
Permissions AclUserPermissions `protobuf:"varint,4,opt,name=permissions,proto3,enum=aclrecord.AclUserPermissions" json:"permissions,omitempty"`
}
func (m *AclAccountRequestAccept) Reset() { *m = AclAccountRequestAccept{} }
@ -311,9 +328,9 @@ func (m *AclAccountRequestAccept) GetRequestRecordId() string {
return ""
}
func (m *AclAccountRequestAccept) GetEncryptedReadKeys() []*AclReadKeyWithRecord {
func (m *AclAccountRequestAccept) GetEncryptedReadKey() []byte {
if m != nil {
return m.EncryptedReadKeys
return m.EncryptedReadKey
}
return nil
}
@ -576,7 +593,12 @@ func (m *AclAccountPermissionChange) GetPermissions() AclUserPermissions {
// AclReadKeyChange changes the key for a space
type AclReadKeyChange struct {
AccountKeys []*AclEncryptedReadKey `protobuf:"bytes,1,rep,name=accountKeys,proto3" json:"accountKeys,omitempty"`
AccountKeys []*AclEncryptedReadKey `protobuf:"bytes,1,rep,name=accountKeys,proto3" json:"accountKeys,omitempty"`
MetadataPubKey []byte `protobuf:"bytes,2,opt,name=metadataPubKey,proto3" json:"metadataPubKey,omitempty"`
// EncryptedMetadataPrivKey is encrypted with new read key
EncryptedMetadataPrivKey []byte `protobuf:"bytes,3,opt,name=encryptedMetadataPrivKey,proto3" json:"encryptedMetadataPrivKey,omitempty"`
// EncryptedOldReadKey is encrypted with new read key
EncryptedOldReadKey []byte `protobuf:"bytes,4,opt,name=encryptedOldReadKey,proto3" json:"encryptedOldReadKey,omitempty"`
}
func (m *AclReadKeyChange) Reset() { *m = AclReadKeyChange{} }
@ -619,10 +641,31 @@ func (m *AclReadKeyChange) GetAccountKeys() []*AclEncryptedReadKey {
return nil
}
func (m *AclReadKeyChange) GetMetadataPubKey() []byte {
if m != nil {
return m.MetadataPubKey
}
return nil
}
func (m *AclReadKeyChange) GetEncryptedMetadataPrivKey() []byte {
if m != nil {
return m.EncryptedMetadataPrivKey
}
return nil
}
func (m *AclReadKeyChange) GetEncryptedOldReadKey() []byte {
if m != nil {
return m.EncryptedOldReadKey
}
return nil
}
// AclAccountRemove removes an account and changes read key for space
type AclAccountRemove struct {
Identities [][]byte `protobuf:"bytes,1,rep,name=identities,proto3" json:"identities,omitempty"`
AccountKeys []*AclEncryptedReadKey `protobuf:"bytes,2,rep,name=accountKeys,proto3" json:"accountKeys,omitempty"`
Identities [][]byte `protobuf:"bytes,1,rep,name=identities,proto3" json:"identities,omitempty"`
ReadKeyChange *AclReadKeyChange `protobuf:"bytes,2,opt,name=readKeyChange,proto3" json:"readKeyChange,omitempty"`
}
func (m *AclAccountRemove) Reset() { *m = AclAccountRemove{} }
@ -665,9 +708,9 @@ func (m *AclAccountRemove) GetIdentities() [][]byte {
return nil
}
func (m *AclAccountRemove) GetAccountKeys() []*AclEncryptedReadKey {
func (m *AclAccountRemove) GetReadKeyChange() *AclReadKeyChange {
if m != nil {
return m.AccountKeys
return m.ReadKeyChange
}
return nil
}
@ -955,60 +998,63 @@ func init() {
}
var fileDescriptor_c8e9f754f34e929b = []byte{
// 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,
// 887 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0x4f, 0x6f, 0x1b, 0x45,
0x14, 0xdf, 0xb5, 0x93, 0x38, 0x7e, 0x9b, 0xa6, 0x66, 0x5a, 0xe8, 0x12, 0xc0, 0x32, 0x8b, 0x8a,
0xac, 0x0a, 0x35, 0x95, 0x11, 0x12, 0xaa, 0x90, 0xda, 0x6d, 0x52, 0xe1, 0xb4, 0x94, 0x56, 0x53,
0x41, 0x11, 0x12, 0x48, 0x93, 0xd9, 0xa7, 0x76, 0x60, 0xff, 0x98, 0xd9, 0xb1, 0x91, 0xbf, 0x05,
0x1f, 0x86, 0x0b, 0x07, 0xee, 0x1c, 0x38, 0xf4, 0xc8, 0x11, 0x25, 0x37, 0x3e, 0x05, 0x9a, 0xd9,
0xcd, 0xfe, 0xf3, 0xc6, 0x69, 0x0e, 0x89, 0x77, 0xde, 0x7b, 0xbf, 0x37, 0xef, 0xfd, 0xde, 0x9f,
0x5d, 0xf8, 0x82, 0x27, 0x51, 0x94, 0xc4, 0xe9, 0x8c, 0x71, 0xdc, 0x4f, 0x8e, 0x7f, 0x42, 0xae,
0xf6, 0x19, 0x0f, 0xf5, 0x9f, 0x44, 0x9e, 0xc8, 0x60, 0x26, 0x13, 0x95, 0xec, 0x9b, 0xff, 0x69,
0x29, 0xbd, 0x6d, 0x04, 0xa4, 0x5f, 0x08, 0xbc, 0x3f, 0x3a, 0xd0, 0xf3, 0x79, 0x48, 0x93, 0x44,
0x91, 0x3d, 0xd8, 0x16, 0x01, 0xc6, 0x4a, 0xa8, 0xa5, 0x6b, 0x8f, 0xec, 0xf1, 0x0e, 0x2d, 0xce,
0xe4, 0x7d, 0xe8, 0x47, 0x2c, 0x55, 0x28, 0x1f, 0xe3, 0xd2, 0xed, 0x18, 0x65, 0x29, 0x20, 0x2e,
0xf4, 0x4c, 0x28, 0x47, 0x81, 0xdb, 0x1d, 0xd9, 0xe3, 0x3e, 0x3d, 0x3b, 0x92, 0x5b, 0x30, 0xc0,
0x98, 0xcb, 0xe5, 0x4c, 0x61, 0x40, 0x91, 0x05, 0x1a, 0xbe, 0x61, 0xe0, 0x2b, 0x72, 0x7d, 0x87,
0x12, 0x11, 0xa6, 0x8a, 0x45, 0x33, 0x77, 0x73, 0x64, 0x8f, 0xbb, 0xb4, 0x14, 0x90, 0x4f, 0xe0,
0xad, 0xb3, 0x68, 0x9e, 0x8b, 0x97, 0x31, 0x53, 0x73, 0x89, 0xee, 0x96, 0x71, 0xb5, 0xaa, 0x20,
0x1f, 0xc3, 0x6e, 0x84, 0x8a, 0x05, 0x4c, 0xb1, 0x67, 0xf3, 0x63, 0x7d, 0x6b, 0xcf, 0x98, 0x36,
0xa4, 0xe4, 0x2e, 0xb8, 0x45, 0x1c, 0x4f, 0xce, 0x54, 0x52, 0x2c, 0x34, 0x62, 0xdb, 0x20, 0xce,
0xd5, 0x7b, 0x77, 0x60, 0xe0, 0xf3, 0xd0, 0xe7, 0x3c, 0x99, 0xc7, 0xea, 0x28, 0x5e, 0x08, 0x85,
0x3a, 0x07, 0x61, 0x9e, 0xb4, 0x83, 0x8c, 0xc4, 0x52, 0xe0, 0xfd, 0x69, 0xc3, 0xdb, 0x25, 0x84,
0xe2, 0x2f, 0x73, 0x4c, 0xd5, 0xa3, 0x44, 0xc4, 0x3a, 0xde, 0xcc, 0xec, 0xa8, 0x5e, 0x81, 0x86,
0xb4, 0xb4, 0xa3, 0xa6, 0x7e, 0x47, 0x81, 0x29, 0x46, 0x9f, 0x36, 0xa4, 0xe4, 0x73, 0xb8, 0x51,
0x47, 0x96, 0x9c, 0x75, 0x8d, 0xe3, 0xf3, 0xd4, 0xba, 0x0b, 0xce, 0x38, 0xca, 0x2b, 0x55, 0x9c,
0xbd, 0xbf, 0x6d, 0xb8, 0xb1, 0x12, 0xbf, 0xcf, 0x39, 0xce, 0xd6, 0x77, 0xcf, 0x18, 0xae, 0xca,
0xcc, 0xb8, 0x11, 0x76, 0x53, 0xdc, 0xda, 0x2f, 0xdd, 0x73, 0xfa, 0xe5, 0x1e, 0x38, 0x33, 0x94,
0x91, 0x48, 0x53, 0x91, 0xc4, 0xa9, 0x09, 0x76, 0x77, 0xf2, 0xc1, 0xed, 0xb2, 0xdb, 0x7d, 0x1e,
0x7e, 0x93, 0xa2, 0x7c, 0x56, 0x1a, 0xd1, 0x2a, 0xc2, 0x3b, 0x04, 0x77, 0x25, 0x9b, 0x43, 0xe4,
0xa1, 0x88, 0xb1, 0x2d, 0x64, 0xbb, 0x35, 0x64, 0xef, 0x3e, 0xbc, 0xd3, 0x6c, 0x03, 0x8a, 0x8b,
0xe4, 0x67, 0x6c, 0x29, 0x96, 0xdd, 0x56, 0x2c, 0xef, 0x47, 0xb8, 0xae, 0x67, 0x30, 0x4b, 0xeb,
0x85, 0x50, 0xaf, 0x32, 0x8d, 0xa6, 0x54, 0xd6, 0x91, 0xc5, 0xb9, 0x95, 0xa8, 0x4e, 0x3b, 0x51,
0xde, 0x0f, 0x70, 0xcd, 0xe7, 0xe1, 0xc3, 0x26, 0x7f, 0xeb, 0x2a, 0x76, 0x19, 0xf7, 0x4b, 0xd8,
0x2b, 0x09, 0x28, 0xc9, 0x3e, 0x78, 0xc5, 0xe2, 0x97, 0xb8, 0xf6, 0x96, 0x46, 0x05, 0x3b, 0x97,
0xae, 0xe0, 0x7f, 0xb6, 0x99, 0xc1, 0x3c, 0x92, 0xfc, 0xc6, 0xfb, 0xe0, 0xb0, 0x2c, 0x98, 0xc7,
0xb8, 0x4c, 0x5d, 0x7b, 0xd4, 0x1d, 0x3b, 0x93, 0x61, 0xdd, 0x6b, 0x93, 0x0c, 0x5a, 0x85, 0xb4,
0x6c, 0x8f, 0xce, 0xa5, 0xb7, 0x47, 0x77, 0xfd, 0xf6, 0x20, 0x77, 0xe0, 0x5a, 0xa1, 0x7b, 0x1a,
0x36, 0x96, 0x63, 0x9b, 0xca, 0x9b, 0x57, 0xf7, 0x0d, 0xc5, 0x28, 0x59, 0x20, 0x19, 0x02, 0xe4,
0x6c, 0x0a, 0xcc, 0x52, 0xdd, 0xa1, 0x15, 0x09, 0xf1, 0xe1, 0x8a, 0xac, 0x92, 0x63, 0x12, 0x71,
0x26, 0xef, 0xd5, 0xd9, 0xa8, 0xf1, 0x47, 0xeb, 0x08, 0xef, 0xdd, 0x96, 0x99, 0xcf, 0x6e, 0xf7,
0x7e, 0xdf, 0x84, 0xab, 0x3e, 0x0f, 0x0f, 0x92, 0x58, 0x61, 0xac, 0xbe, 0x65, 0xe1, 0x1c, 0xc9,
0x67, 0xb0, 0x95, 0xb5, 0xb7, 0xa9, 0xf6, 0xca, 0x55, 0xb5, 0x39, 0x99, 0x5a, 0x34, 0x37, 0x26,
0x5f, 0xc2, 0x8e, 0xa8, 0xcc, 0x4e, 0x1e, 0xe7, 0x87, 0x6b, 0xc0, 0x99, 0xe1, 0xd4, 0xa2, 0x35,
0x20, 0x39, 0x04, 0x47, 0x96, 0x8b, 0xd5, 0x94, 0xc1, 0x99, 0x8c, 0x5a, 0xfd, 0x54, 0x16, 0xf0,
0xd4, 0xa2, 0x55, 0x18, 0x79, 0xa4, 0x79, 0xab, 0xac, 0x37, 0x53, 0x17, 0x67, 0xe2, 0xad, 0xf3,
0x93, 0x59, 0x4e, 0x2d, 0x5a, 0x87, 0x92, 0xe7, 0x30, 0x98, 0x35, 0xa6, 0xc2, 0xbc, 0xde, 0x9c,
0xc9, 0xcd, 0x56, 0x77, 0xcd, 0x11, 0x9a, 0x5a, 0x74, 0xc5, 0x01, 0x39, 0x80, 0x2b, 0xac, 0xda,
0x09, 0xe6, 0x55, 0x78, 0x1e, 0xdb, 0x99, 0x89, 0x8e, 0xac, 0x86, 0xd1, 0x4e, 0xea, 0xdd, 0xd1,
0xbb, 0xb0, 0x3b, 0xb2, 0xf4, 0xaa, 0xe3, 0xf6, 0x04, 0x76, 0x65, 0x6d, 0x77, 0x9a, 0x17, 0xa7,
0x33, 0xf9, 0x68, 0x1d, 0x57, 0xb9, 0xe9, 0xd4, 0xa2, 0x0d, 0x30, 0xf9, 0x0e, 0xae, 0xb3, 0x96,
0x5e, 0x73, 0xfb, 0x17, 0x17, 0xa0, 0x48, 0xb3, 0xd5, 0xc3, 0x83, 0x1e, 0x6c, 0x2e, 0x74, 0x8b,
0x7a, 0x0f, 0xcd, 0x37, 0xcf, 0x21, 0x53, 0x8c, 0xdc, 0x05, 0x60, 0x45, 0x03, 0xe7, 0xab, 0x62,
0xaf, 0x7e, 0x47, 0xb5, 0xbb, 0x69, 0xc5, 0xfa, 0xd6, 0x57, 0x40, 0x56, 0xf7, 0x13, 0xd9, 0x86,
0x8d, 0xaf, 0x93, 0x18, 0x07, 0x16, 0xe9, 0xc3, 0xe6, 0xd3, 0x5f, 0x63, 0x94, 0x03, 0x5b, 0x3f,
0xfa, 0x41, 0x24, 0xe2, 0x41, 0x87, 0x00, 0x6c, 0xbd, 0x90, 0x42, 0xa1, 0x1c, 0x74, 0xf5, 0xb3,
0x26, 0x17, 0xe5, 0x60, 0xe3, 0xc1, 0xbd, 0xbf, 0x4e, 0x86, 0xf6, 0xeb, 0x93, 0xa1, 0xfd, 0xef,
0xc9, 0xd0, 0xfe, 0xed, 0x74, 0x68, 0xbd, 0x3e, 0x1d, 0x5a, 0xff, 0x9c, 0x0e, 0xad, 0xef, 0x6f,
0xbe, 0xd1, 0xc7, 0xde, 0xf1, 0x96, 0xf9, 0xf9, 0xf4, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55,
0x49, 0xdd, 0x11, 0x1c, 0x0a, 0x00, 0x00,
}
func (m *AclRoot) Marshal() (dAtA []byte, err error) {
@ -1031,6 +1077,20 @@ func (m *AclRoot) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if len(m.EncryptedMetadataPrivKey) > 0 {
i -= len(m.EncryptedMetadataPrivKey)
copy(dAtA[i:], m.EncryptedMetadataPrivKey)
i = encodeVarintAclrecord(dAtA, i, uint64(len(m.EncryptedMetadataPrivKey)))
i--
dAtA[i] = 0x42
}
if len(m.MetadataPubKey) > 0 {
i -= len(m.MetadataPubKey)
copy(dAtA[i:], m.MetadataPubKey)
i = encodeVarintAclrecord(dAtA, i, uint64(len(m.MetadataPubKey)))
i--
dAtA[i] = 0x3a
}
if len(m.IdentitySignature) > 0 {
i -= len(m.IdentitySignature)
copy(dAtA[i:], m.IdentitySignature)
@ -1180,19 +1240,12 @@ func (m *AclAccountRequestAccept) MarshalToSizedBuffer(dAtA []byte) (int, error)
i--
dAtA[i] = 0x20
}
if len(m.EncryptedReadKeys) > 0 {
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.EncryptedReadKey) > 0 {
i -= len(m.EncryptedReadKey)
copy(dAtA[i:], m.EncryptedReadKey)
i = encodeVarintAclrecord(dAtA, i, uint64(len(m.EncryptedReadKey)))
i--
dAtA[i] = 0x1a
}
if len(m.RequestRecordId) > 0 {
i -= len(m.RequestRecordId)
@ -1400,6 +1453,27 @@ func (m *AclReadKeyChange) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if len(m.EncryptedOldReadKey) > 0 {
i -= len(m.EncryptedOldReadKey)
copy(dAtA[i:], m.EncryptedOldReadKey)
i = encodeVarintAclrecord(dAtA, i, uint64(len(m.EncryptedOldReadKey)))
i--
dAtA[i] = 0x22
}
if len(m.EncryptedMetadataPrivKey) > 0 {
i -= len(m.EncryptedMetadataPrivKey)
copy(dAtA[i:], m.EncryptedMetadataPrivKey)
i = encodeVarintAclrecord(dAtA, i, uint64(len(m.EncryptedMetadataPrivKey)))
i--
dAtA[i] = 0x1a
}
if len(m.MetadataPubKey) > 0 {
i -= len(m.MetadataPubKey)
copy(dAtA[i:], m.MetadataPubKey)
i = encodeVarintAclrecord(dAtA, i, uint64(len(m.MetadataPubKey)))
i--
dAtA[i] = 0x12
}
if len(m.AccountKeys) > 0 {
for iNdEx := len(m.AccountKeys) - 1; iNdEx >= 0; iNdEx-- {
{
@ -1437,19 +1511,17 @@ func (m *AclAccountRemove) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = 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))
if m.ReadKeyChange != nil {
{
size, err := m.ReadKeyChange.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i--
dAtA[i] = 0x12
i -= size
i = encodeVarintAclrecord(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x12
}
if len(m.Identities) > 0 {
for iNdEx := len(m.Identities) - 1; iNdEx >= 0; iNdEx-- {
@ -1784,6 +1856,14 @@ func (m *AclRoot) Size() (n int) {
if l > 0 {
n += 1 + l + sovAclrecord(uint64(l))
}
l = len(m.MetadataPubKey)
if l > 0 {
n += 1 + l + sovAclrecord(uint64(l))
}
l = len(m.EncryptedMetadataPrivKey)
if l > 0 {
n += 1 + l + sovAclrecord(uint64(l))
}
return n
}
@ -1839,11 +1919,9 @@ func (m *AclAccountRequestAccept) Size() (n int) {
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))
}
l = len(m.EncryptedReadKey)
if l > 0 {
n += 1 + l + sovAclrecord(uint64(l))
}
if m.Permissions != 0 {
n += 1 + sovAclrecord(uint64(m.Permissions))
@ -1939,6 +2017,18 @@ func (m *AclReadKeyChange) Size() (n int) {
n += 1 + l + sovAclrecord(uint64(l))
}
}
l = len(m.MetadataPubKey)
if l > 0 {
n += 1 + l + sovAclrecord(uint64(l))
}
l = len(m.EncryptedMetadataPrivKey)
if l > 0 {
n += 1 + l + sovAclrecord(uint64(l))
}
l = len(m.EncryptedOldReadKey)
if l > 0 {
n += 1 + l + sovAclrecord(uint64(l))
}
return n
}
@ -1954,11 +2044,9 @@ func (m *AclAccountRemove) Size() (n int) {
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))
}
if m.ReadKeyChange != nil {
l = m.ReadKeyChange.Size()
n += 1 + l + sovAclrecord(uint64(l))
}
return n
}
@ -2329,6 +2417,74 @@ func (m *AclRoot) Unmarshal(dAtA []byte) error {
m.IdentitySignature = []byte{}
}
iNdEx = postIndex
case 7:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field MetadataPubKey", 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.MetadataPubKey = append(m.MetadataPubKey[:0], dAtA[iNdEx:postIndex]...)
if m.MetadataPubKey == nil {
m.MetadataPubKey = []byte{}
}
iNdEx = postIndex
case 8:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field EncryptedMetadataPrivKey", 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.EncryptedMetadataPrivKey = append(m.EncryptedMetadataPrivKey[:0], dAtA[iNdEx:postIndex]...)
if m.EncryptedMetadataPrivKey == nil {
m.EncryptedMetadataPrivKey = []byte{}
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipAclrecord(dAtA[iNdEx:])
@ -2715,9 +2871,9 @@ func (m *AclAccountRequestAccept) Unmarshal(dAtA []byte) error {
iNdEx = postIndex
case 3:
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 msglen int
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowAclrecord
@ -2727,24 +2883,24 @@ func (m *AclAccountRequestAccept) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
if byteLen < 0 {
return ErrInvalidLengthAclrecord
}
postIndex := iNdEx + msglen
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthAclrecord
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.EncryptedReadKeys = append(m.EncryptedReadKeys, &AclReadKeyWithRecord{})
if err := m.EncryptedReadKeys[len(m.EncryptedReadKeys)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
m.EncryptedReadKey = append(m.EncryptedReadKey[:0], dAtA[iNdEx:postIndex]...)
if m.EncryptedReadKey == nil {
m.EncryptedReadKey = []byte{}
}
iNdEx = postIndex
case 4:
@ -3351,6 +3507,108 @@ func (m *AclReadKeyChange) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field MetadataPubKey", 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.MetadataPubKey = append(m.MetadataPubKey[:0], dAtA[iNdEx:postIndex]...)
if m.MetadataPubKey == nil {
m.MetadataPubKey = []byte{}
}
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field EncryptedMetadataPrivKey", 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.EncryptedMetadataPrivKey = append(m.EncryptedMetadataPrivKey[:0], dAtA[iNdEx:postIndex]...)
if m.EncryptedMetadataPrivKey == nil {
m.EncryptedMetadataPrivKey = []byte{}
}
iNdEx = postIndex
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field EncryptedOldReadKey", 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.EncryptedOldReadKey = append(m.EncryptedOldReadKey[:0], dAtA[iNdEx:postIndex]...)
if m.EncryptedOldReadKey == nil {
m.EncryptedOldReadKey = []byte{}
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipAclrecord(dAtA[iNdEx:])
@ -3435,7 +3693,7 @@ func (m *AclAccountRemove) Unmarshal(dAtA []byte) error {
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field AccountKeys", wireType)
return fmt.Errorf("proto: wrong wireType = %d for field ReadKeyChange", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
@ -3462,8 +3720,10 @@ func (m *AclAccountRemove) Unmarshal(dAtA []byte) error {
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.AccountKeys = append(m.AccountKeys, &AclEncryptedReadKey{})
if err := m.AccountKeys[len(m.AccountKeys)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
if m.ReadKeyChange == nil {
m.ReadKeyChange = &AclReadKeyChange{}
}
if err := m.ReadKeyChange.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex

View file

@ -10,6 +10,8 @@ message AclRoot {
bytes encryptedReadKey = 4;
int64 timestamp = 5;
bytes identitySignature = 6;
bytes metadataPubKey = 7;
bytes encryptedMetadataPrivKey = 8;
}
// AclAccountInvite contains the public invite key, the private part of which is sent to the user directly
@ -22,6 +24,7 @@ message AclAccountRequestJoin {
bytes inviteIdentity = 1;
string inviteRecordId = 2;
bytes inviteIdentitySignature = 3;
// Metadata is encrypted with metadata key of the space
bytes metadata = 4;
}
@ -29,7 +32,7 @@ message AclAccountRequestJoin {
message AclAccountRequestAccept {
bytes identity = 1;
string requestRecordId = 2;
repeated AclReadKeyWithRecord encryptedReadKeys = 3;
bytes encryptedReadKey = 3;
AclUserPermissions permissions = 4;
}
@ -43,12 +46,6 @@ message AclAccountInviteRevoke {
string inviteRecordId = 1;
}
// AclReadKeys are a read key with record id
message AclReadKeyWithRecord {
string recordId = 1;
bytes encryptedReadKey = 2;
}
// AclEncryptedReadKeys are new key for specific identity
message AclEncryptedReadKey {
bytes identity = 1;
@ -64,12 +61,17 @@ message AclAccountPermissionChange {
// AclReadKeyChange changes the key for a space
message AclReadKeyChange {
repeated AclEncryptedReadKey accountKeys = 1;
bytes metadataPubKey = 2;
// EncryptedMetadataPrivKey is encrypted with new read key
bytes encryptedMetadataPrivKey = 3;
// EncryptedOldReadKey is encrypted with new read key
bytes encryptedOldReadKey = 4;
}
// AclAccountRemove removes an account and changes read key for space
message AclAccountRemove {
repeated bytes identities = 1;
repeated AclEncryptedReadKey accountKeys = 2;
AclReadKeyChange readKeyChange = 2;
}
// AclAccountRequestRemove adds a request to remove an account

View file

@ -12,10 +12,10 @@ import (
)
type RootContent struct {
PrivKey crypto.PrivKey
MasterKey crypto.PrivKey
SpaceId string
EncryptedReadKey []byte
PrivKey crypto.PrivKey
MasterKey crypto.PrivKey
SpaceId string
Change ReadKeyChangePayload
}
type RequestJoinPayload struct {
@ -24,6 +24,11 @@ type RequestJoinPayload struct {
Metadata []byte
}
type ReadKeyChangePayload struct {
MetadataKey crypto.PrivKey
ReadKey crypto.SymKey
}
type RequestAcceptPayload struct {
RequestRecordId string
Permissions AclPermissions
@ -36,7 +41,7 @@ type PermissionChangePayload struct {
type AccountRemovePayload struct {
Identities []crypto.PubKey
ReadKey crypto.SymKey
Change ReadKeyChangePayload
}
type InviteResult struct {
@ -56,7 +61,7 @@ type AclRecordBuilder interface {
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)
BuildReadKeyChange(payload ReadKeyChangePayload) (rawRecord *consensusproto.RawRecord, err error)
BuildAccountRemove(payload AccountRemovePayload) (rawRecord *consensusproto.RawRecord, err error)
}
@ -158,6 +163,17 @@ func (a *aclRecordBuilder) BuildRequestJoin(payload RequestJoinPayload) (rawReco
if !payload.InviteKey.GetPublic().Equals(key) {
err = ErrIncorrectInviteKey
}
mkKey, err := a.state.CurrentMetadataKey()
if err != nil {
return nil, err
}
encMeta, err := mkKey.Encrypt(payload.Metadata)
if err != nil {
return nil, err
}
if len(encMeta) > MaxMetadataLen {
return nil, ErrMetadataTooLarge
}
rawIdentity, err := a.accountKeys.SignKey.GetPublic().Raw()
if err != nil {
return
@ -174,7 +190,7 @@ func (a *aclRecordBuilder) BuildRequestJoin(payload RequestJoinPayload) (rawReco
InviteIdentity: protoIdentity,
InviteRecordId: payload.InviteRecordId,
InviteIdentitySignature: signature,
Metadata: payload.Metadata,
Metadata: encMeta,
}
content := &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_RequestJoin{RequestJoin: joinRec}}
return a.buildRecord(content)
@ -190,33 +206,27 @@ func (a *aclRecordBuilder) BuildRequestAccept(payload RequestAcceptPayload) (raw
err = ErrNoSuchRequest
return
}
var encryptedReadKeys []*aclrecordproto.AclReadKeyWithRecord
for keyId, key := range a.state.userReadKeys {
rawKey, err := key.Raw()
if err != nil {
return nil, err
}
enc, err := request.RequestIdentity.Encrypt(rawKey)
if err != nil {
return nil, err
}
encryptedReadKeys = append(encryptedReadKeys, &aclrecordproto.AclReadKeyWithRecord{
RecordId: keyId,
EncryptedReadKey: enc,
})
}
readKey, err := a.state.CurrentReadKey()
if err != nil {
return
return nil, ErrNoReadKey
}
protoKey, err := readKey.Marshall()
if err != nil {
return nil, err
}
enc, err := request.RequestIdentity.Encrypt(protoKey)
if err != nil {
return nil, err
}
requestIdentityProto, err := request.RequestIdentity.Marshall()
if err != nil {
return
}
acceptRec := &aclrecordproto.AclAccountRequestAccept{
Identity: requestIdentityProto,
RequestRecordId: payload.RequestRecordId,
EncryptedReadKeys: encryptedReadKeys,
Permissions: aclrecordproto.AclUserPermissions(payload.Permissions),
Identity: requestIdentityProto,
RequestRecordId: payload.RequestRecordId,
EncryptedReadKey: enc,
Permissions: aclrecordproto.AclUserPermissions(payload.Permissions),
}
content := &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_RequestAccept{RequestAccept: acceptRec}}
return a.buildRecord(content)
@ -259,26 +269,37 @@ func (a *aclRecordBuilder) BuildPermissionChange(payload PermissionChangePayload
return a.buildRecord(content)
}
func (a *aclRecordBuilder) BuildReadKeyChange(newKey crypto.SymKey) (rawRecord *consensusproto.RawRecord, err error) {
func (a *aclRecordBuilder) BuildReadKeyChange(payload ReadKeyChangePayload) (rawRecord *consensusproto.RawRecord, err error) {
if !a.state.Permissions(a.state.pubKey).CanManageAccounts() {
err = ErrInsufficientPermissions
return
}
rawKey, err := newKey.Raw()
rkChange, err := a.buildReadKeyChange(payload, nil)
if err != nil {
return
return nil, err
}
if len(rawKey) != crypto.KeyBytes {
err = ErrIncorrectReadKey
return
content := &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_ReadKeyChange{ReadKeyChange: rkChange}}
return a.buildRecord(content)
}
func (a *aclRecordBuilder) buildReadKeyChange(payload ReadKeyChangePayload, removedIdentities map[string]struct{}) (*aclrecordproto.AclReadKeyChange, error) {
// encrypting new read key with all keys of users
protoKey, err := payload.ReadKey.Marshall()
if err != nil {
return nil, err
}
var aclReadKeys []*aclrecordproto.AclEncryptedReadKey
for _, st := range a.state.userStates {
for identity, st := range a.state.accountStates {
if removedIdentities != nil {
if _, exists := removedIdentities[identity]; exists {
continue
}
}
protoIdentity, err := st.PubKey.Marshall()
if err != nil {
return nil, err
}
enc, err := st.PubKey.Encrypt(rawKey)
enc, err := st.PubKey.Encrypt(protoKey)
if err != nil {
return nil, err
}
@ -287,9 +308,39 @@ func (a *aclRecordBuilder) BuildReadKeyChange(newKey crypto.SymKey) (rawRecord *
EncryptedReadKey: enc,
})
}
readRec := &aclrecordproto.AclReadKeyChange{AccountKeys: aclReadKeys}
content := &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_ReadKeyChange{ReadKeyChange: readRec}}
return a.buildRecord(content)
// encrypting metadata key with new read key
mkPubKey, err := payload.MetadataKey.GetPublic().Marshall()
if err != nil {
return nil, err
}
mkPrivKeyProto, err := payload.MetadataKey.Marshall()
if err != nil {
return nil, err
}
encPrivKey, err := payload.ReadKey.Encrypt(mkPrivKeyProto)
if err != nil {
return nil, err
}
// encrypting current read key with new read key
curKey, err := a.state.CurrentReadKey()
if err != nil {
return nil, err
}
curKeyProto, err := curKey.Marshall()
if err != nil {
return nil, err
}
encOldKey, err := payload.ReadKey.Encrypt(curKeyProto)
if err != nil {
return nil, err
}
readRec := &aclrecordproto.AclReadKeyChange{
AccountKeys: aclReadKeys,
MetadataPubKey: mkPubKey,
EncryptedMetadataPrivKey: encPrivKey,
EncryptedOldReadKey: encOldKey,
}
return readRec, nil
}
func (a *aclRecordBuilder) BuildAccountRemove(payload AccountRemovePayload) (rawRecord *consensusproto.RawRecord, err error) {
@ -308,32 +359,6 @@ func (a *aclRecordBuilder) BuildAccountRemove(payload AccountRemovePayload) (raw
err = ErrInsufficientPermissions
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 _, exists := deletedMap[mapKeyFromPubKey(st.PubKey)]; exists {
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,
})
}
var marshalledIdentities [][]byte
for _, key := range payload.Identities {
protoIdentity, err := key.Marshall()
@ -342,7 +367,11 @@ func (a *aclRecordBuilder) BuildAccountRemove(payload AccountRemovePayload) (raw
}
marshalledIdentities = append(marshalledIdentities, protoIdentity)
}
removeRec := &aclrecordproto.AclAccountRemove{AccountKeys: aclReadKeys, Identities: marshalledIdentities}
rkChange, err := a.buildReadKeyChange(payload.Change, deletedMap)
if err != nil {
return nil, err
}
removeRec := &aclrecordproto.AclAccountRemove{ReadKeyChange: rkChange, Identities: marshalledIdentities}
content := &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_AccountRemove{AccountRemove: removeRec}}
return a.buildRecord(content)
}
@ -473,17 +502,34 @@ func (a *aclRecordBuilder) BuildRoot(content RootContent) (rec *consensusproto.R
if err != nil {
return
}
var timestamp int64
if content.EncryptedReadKey != nil {
timestamp = time.Now().Unix()
}
aclRoot := &aclrecordproto.AclRoot{
Identity: identity,
SpaceId: content.SpaceId,
EncryptedReadKey: content.EncryptedReadKey,
MasterKey: masterKey,
IdentitySignature: identitySignature,
Timestamp: timestamp,
}
if content.Change.ReadKey != nil {
aclRoot.Timestamp = time.Now().Unix()
metadataPrivProto, err := content.Change.MetadataKey.Marshall()
if err != nil {
return nil, err
}
aclRoot.EncryptedMetadataPrivKey, err = content.Change.ReadKey.Encrypt(metadataPrivProto)
if err != nil {
return nil, err
}
aclRoot.MetadataPubKey, err = content.Change.MetadataKey.GetPublic().Marshall()
if err != nil {
return nil, err
}
rkProto, err := content.Change.ReadKey.Marshall()
if err != nil {
return nil, err
}
aclRoot.EncryptedReadKey, err = content.PrivKey.GetPublic().Encrypt(rkProto)
if err != nil {
return nil, err
}
}
return marshalAclRoot(aclRoot, content.PrivKey)
}

View file

@ -2,7 +2,6 @@ package list
import (
"errors"
"github.com/anyproto/any-sync/app/logger"
"github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto"
"github.com/anyproto/any-sync/util/crypto"
@ -19,6 +18,7 @@ var (
ErrIncorrectIdentity = errors.New("incorrect identity")
ErrIncorrectInviteKey = errors.New("incorrect invite key")
ErrFailedToDecrypt = errors.New("failed to decrypt key")
ErrNoMetadataKey = errors.New("no metadata key")
ErrNoSuchRecord = errors.New("no such record")
ErrNoSuchRequest = errors.New("no such request")
ErrNoSuchInvite = errors.New("no such invite")
@ -26,54 +26,65 @@ var (
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")
ErrNoReadKey = errors.New("no 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")
ErrMetadataTooLarge = errors.New("metadata size too large")
)
const MaxMetadataLen = 1024
type UserPermissionPair struct {
Identity crypto.PubKey
Permission aclrecordproto.AclUserPermissions
}
type AclKeys struct {
ReadKey crypto.SymKey
MetadataPrivKey crypto.PrivKey
MetadataPubKey crypto.PubKey
}
type AclState struct {
id string
currentReadKeyId string
// 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
// keys represent current keys of the acl
keys map[string]AclKeys
// accountStates is a map pubKey -> state which defines current account state
accountStates map[string]AclAccountState
// statesAtRecord is a map recordId -> state which define account 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
statesAtRecord map[string][]AclAccountState
// 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 -> recordId
pendingRequests map[string]string
key crypto.PrivKey
pubKey crypto.PubKey
keyStore crypto.KeyStorage
totalReadKeys int
// readKeyChanges is a list of records containing read key changes
readKeyChanges []string
key crypto.PrivKey
pubKey crypto.PubKey
keyStore crypto.KeyStorage
lastRecordId string
contentValidator ContentValidator
list AclList
}
func newAclStateWithKeys(
id string,
key crypto.PrivKey) (*AclState, error) {
st := &AclState{
id: id,
rootRecord *AclRecord,
key crypto.PrivKey) (st *AclState, err error) {
st = &AclState{
id: rootRecord.Id,
key: key,
pubKey: key.GetPublic(),
userReadKeys: make(map[string]crypto.SymKey),
userStates: make(map[string]AclUserState),
statesAtRecord: make(map[string][]AclUserState),
keys: make(map[string]AclKeys),
accountStates: make(map[string]AclAccountState),
statesAtRecord: make(map[string][]AclAccountState),
inviteKeys: make(map[string]crypto.PubKey),
requestRecords: make(map[string]RequestRecord),
pendingRequests: make(map[string]string),
@ -83,15 +94,22 @@ func newAclStateWithKeys(
keyStore: st.keyStore,
aclState: st,
}
err = st.applyRoot(rootRecord)
if err != nil {
return
}
st.statesAtRecord[rootRecord.Id] = []AclAccountState{
st.accountStates[mapKeyFromPubKey(rootRecord.Identity)],
}
return st, nil
}
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),
func newAclState(rootRecord *AclRecord) (st *AclState, err error) {
st = &AclState{
id: rootRecord.Id,
keys: make(map[string]AclKeys),
accountStates: make(map[string]AclAccountState),
statesAtRecord: make(map[string][]AclAccountState),
inviteKeys: make(map[string]crypto.PubKey),
requestRecords: make(map[string]RequestRecord),
pendingRequests: make(map[string]string),
@ -101,7 +119,14 @@ func newAclState(id string) *AclState {
keyStore: st.keyStore,
aclState: st,
}
return st
err = st.applyRoot(rootRecord)
if err != nil {
return
}
st.statesAtRecord[rootRecord.Id] = []AclAccountState{
st.accountStates[mapKeyFromPubKey(rootRecord.Identity)],
}
return st, nil
}
func (st *AclState) Validator() ContentValidator {
@ -109,57 +134,53 @@ func (st *AclState) Validator() ContentValidator {
}
func (st *AclState) CurrentReadKeyId() string {
return st.currentReadKeyId
return st.readKeyChanges[len(st.readKeyChanges)-1]
}
func (st *AclState) AccountKey() crypto.PrivKey {
return st.key
}
func (st *AclState) CurrentReadKey() (crypto.SymKey, error) {
key, exists := st.userReadKeys[st.CurrentReadKeyId()]
curKeys, exists := st.keys[st.CurrentReadKeyId()]
if !exists {
return nil, ErrNoReadKey
}
return key, nil
return curKeys.ReadKey, nil
}
func (st *AclState) UserReadKeys() map[string]crypto.SymKey {
return st.userReadKeys
func (st *AclState) CurrentMetadataKey() (crypto.PubKey, error) {
curKeys, exists := st.keys[st.CurrentReadKeyId()]
if !exists {
return nil, ErrNoMetadataKey
}
return curKeys.MetadataPubKey, nil
}
func (st *AclState) StateAtRecord(id string, pubKey crypto.PubKey) (AclUserState, error) {
userState, ok := st.statesAtRecord[id]
func (st *AclState) Keys() map[string]AclKeys {
return st.keys
}
func (st *AclState) StateAtRecord(id string, pubKey crypto.PubKey) (AclAccountState, error) {
accountState, ok := st.statesAtRecord[id]
if !ok {
log.Errorf("missing record at id %s", id)
return AclUserState{}, ErrNoSuchRecord
return AclAccountState{}, ErrNoSuchRecord
}
for _, perm := range userState {
for _, perm := range accountState {
if perm.PubKey.Equals(pubKey) {
return perm, nil
}
}
return AclUserState{}, ErrNoSuchAccount
return AclAccountState{}, ErrNoSuchAccount
}
func (st *AclState) applyRecord(record *AclRecord) (err error) {
defer func() {
if err == nil {
st.lastRecordId = record.Id
}
}()
if st.lastRecordId != record.PrevId {
err = ErrIncorrectRecordSequence
return
}
// if the record is root record
if record.Id == st.id {
err = st.applyRoot(record)
if err != nil {
return
}
st.statesAtRecord[record.Id] = []AclUserState{
st.userStates[mapKeyFromPubKey(record.Identity)],
}
return
}
// if the model is not cached
if record.Model == nil {
aclData := &aclrecordproto.AclData{}
@ -175,51 +196,68 @@ func (st *AclState) applyRecord(record *AclRecord) (err error) {
return
}
// getting all states for users at record and saving them
var states []AclUserState
for _, state := range st.userStates {
var states []AclAccountState
for _, state := range st.accountStates {
states = append(states, state)
}
st.statesAtRecord[record.Id] = states
st.lastRecordId = record.Id
return
}
func (st *AclState) applyRoot(record *AclRecord) (err error) {
if st.key != nil && st.pubKey.Equals(record.Identity) {
err = st.saveReadKeyFromRoot(record)
if err != nil {
return
}
}
// adding user to the list
userState := AclUserState{
PubKey: record.Identity,
Permissions: AclPermissions(aclrecordproto.AclUserPermissions_Owner),
}
st.currentReadKeyId = record.Id
st.userStates[mapKeyFromPubKey(record.Identity)] = userState
st.totalReadKeys++
return
}
func (st *AclState) saveReadKeyFromRoot(record *AclRecord) (err error) {
var readKey crypto.SymKey
root, ok := record.Model.(*aclrecordproto.AclRoot)
if !ok {
return ErrIncorrectRoot
}
if root.EncryptedReadKey == nil {
readKey, err = st.deriveKey()
if root.EncryptedReadKey != nil {
mkPubKey, err := st.keyStore.PubKeyFromProto(root.MetadataPubKey)
if err != nil {
return
return err
}
st.keys[record.Id] = AclKeys{MetadataPubKey: mkPubKey}
} else {
readKey, err = st.decryptReadKey(root.EncryptedReadKey)
// this should be a derived acl
st.keys[record.Id] = AclKeys{}
}
if st.key != nil && st.pubKey.Equals(record.Identity) {
err = st.saveKeysFromRoot(record.Id, root)
if err != nil {
return
}
}
st.userReadKeys[record.Id] = readKey
// adding an account to the list
accountState := AclAccountState{
PubKey: record.Identity,
Permissions: AclPermissions(aclrecordproto.AclUserPermissions_Owner),
}
st.readKeyChanges = []string{record.Id}
st.accountStates[mapKeyFromPubKey(record.Identity)] = accountState
st.lastRecordId = record.Id
return
}
func (st *AclState) saveKeysFromRoot(id string, root *aclrecordproto.AclRoot) (err error) {
aclKeys := st.keys[id]
if root.EncryptedReadKey == nil {
readKey, err := st.deriveKey()
if err != nil {
return err
}
aclKeys.ReadKey = readKey
} else {
readKey, err := st.unmarshallDecryptReadKey(root.EncryptedReadKey, st.key.Decrypt)
if err != nil {
return err
}
metadataKey, err := st.unmarshallDecryptPrivKey(root.EncryptedMetadataPrivKey, readKey.Decrypt)
if err != nil {
return err
}
aclKeys.ReadKey = readKey
aclKeys.MetadataPrivKey = metadataKey
}
st.keys[id] = aclKeys
return
}
@ -251,7 +289,7 @@ func (st *AclState) applyChangeContent(ch *aclrecordproto.AclContentValue, recor
case ch.GetAccountRemove() != nil:
return st.applyAccountRemove(ch.GetAccountRemove(), recordId, authorIdentity)
case ch.GetReadKeyChange() != nil:
return st.applyReadKeyChange(ch.GetReadKeyChange(), recordId, authorIdentity)
return st.applyReadKeyChange(ch.GetReadKeyChange(), recordId, authorIdentity, true)
case ch.GetAccountRequestRemove() != nil:
return st.applyRequestRemove(ch.GetAccountRequestRemove(), recordId, authorIdentity)
default:
@ -269,9 +307,9 @@ func (st *AclState) applyPermissionChange(ch *aclrecordproto.AclAccountPermissio
return err
}
stringKey := mapKeyFromPubKey(chIdentity)
state, _ := st.userStates[stringKey]
state, _ := st.accountStates[stringKey]
state.Permissions = AclPermissions(ch.Permissions)
st.userStates[stringKey] = state
st.accountStates[stringKey] = state
return nil
}
@ -321,25 +359,64 @@ func (st *AclState) applyRequestAccept(ch *aclrecordproto.AclAccountRequestAccep
return err
}
record, _ := st.requestRecords[ch.RequestRecordId]
st.userStates[mapKeyFromPubKey(acceptIdentity)] = AclUserState{
st.accountStates[mapKeyFromPubKey(acceptIdentity)] = AclAccountState{
PubKey: acceptIdentity,
Permissions: AclPermissions(ch.Permissions),
RequestMetadata: record.RequestMetadata,
KeyRecordId: st.CurrentReadKeyId(),
}
delete(st.pendingRequests, mapKeyFromPubKey(st.requestRecords[ch.RequestRecordId].RequestIdentity))
if !st.pubKey.Equals(acceptIdentity) {
return nil
}
for _, key := range ch.EncryptedReadKeys {
decrypted, err := st.key.Decrypt(key.EncryptedReadKey)
iterReadKey, err := st.unmarshallDecryptReadKey(ch.EncryptedReadKey, st.key.Decrypt)
if err != nil {
return err
}
for idx := len(st.readKeyChanges) - 1; idx >= 0; idx-- {
recId := st.readKeyChanges[idx]
rec, err := st.list.Get(recId)
if err != nil {
return err
}
sym, err := crypto.UnmarshallAESKey(decrypted)
// if this is a first key change
if recId == st.id {
ch := rec.Model.(*aclrecordproto.AclRoot)
metadataKey, err := st.unmarshallDecryptPrivKey(ch.EncryptedMetadataPrivKey, iterReadKey.Decrypt)
if err != nil {
return err
}
aclKeys := st.keys[recId]
aclKeys.ReadKey = iterReadKey
aclKeys.MetadataPrivKey = metadataKey
st.keys[recId] = aclKeys
break
}
model := rec.Model.(*aclrecordproto.AclData)
if len(model.GetAclContent()) != 1 {
return ErrIncorrectReadKey
}
ch := model.GetAclContent()[0]
var readKeyChange *aclrecordproto.AclReadKeyChange
switch {
case ch.GetReadKeyChange() != nil:
readKeyChange = ch.GetReadKeyChange()
case ch.GetAccountRemove() != nil:
readKeyChange = ch.GetAccountRemove().GetReadKeyChange()
}
oldReadKey, err := st.unmarshallDecryptReadKey(readKeyChange.EncryptedOldReadKey, iterReadKey.Decrypt)
if err != nil {
return err
}
st.userReadKeys[key.RecordId] = sym
metadataKey, err := st.unmarshallDecryptPrivKey(readKeyChange.EncryptedMetadataPrivKey, iterReadKey.Decrypt)
if err != nil {
return err
}
aclKeys := st.keys[recId]
aclKeys.ReadKey = iterReadKey
aclKeys.MetadataPrivKey = metadataKey
st.keys[recId] = aclKeys
iterReadKey = oldReadKey
}
return nil
}
@ -378,49 +455,89 @@ func (st *AclState) applyAccountRemove(ch *aclrecordproto.AclAccountRemove, reco
return err
}
idKey := mapKeyFromPubKey(identity)
delete(st.userStates, idKey)
delete(st.accountStates, idKey)
delete(st.pendingRequests, idKey)
}
return st.updateReadKey(ch.AccountKeys, recordId)
return st.applyReadKeyChange(ch.ReadKeyChange, recordId, authorIdentity, false)
}
func (st *AclState) applyReadKeyChange(ch *aclrecordproto.AclReadKeyChange, recordId string, authorIdentity crypto.PubKey) error {
err := st.contentValidator.ValidateReadKeyChange(ch, authorIdentity)
func (st *AclState) applyReadKeyChange(ch *aclrecordproto.AclReadKeyChange, recordId string, authorIdentity crypto.PubKey, validate bool) error {
if validate {
err := st.contentValidator.ValidateReadKeyChange(ch, authorIdentity)
if err != nil {
return err
}
}
st.readKeyChanges = append(st.readKeyChanges, recordId)
mkPubKey, err := st.keyStore.PubKeyFromProto(ch.MetadataPubKey)
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 {
aclKeys := AclKeys{
MetadataPubKey: mkPubKey,
}
for _, accKey := range ch.AccountKeys {
identity, _ := st.keyStore.PubKeyFromProto(accKey.Identity)
if st.pubKey.Equals(identity) {
res, err := st.decryptReadKey(accKey.EncryptedReadKey)
res, err := st.unmarshallDecryptReadKey(accKey.EncryptedReadKey, st.key.Decrypt)
if err != nil {
return err
}
st.userReadKeys[recordId] = res
aclKeys.ReadKey = res
}
}
st.currentReadKeyId = recordId
if aclKeys.ReadKey != nil {
metadataKey, err := st.unmarshallDecryptPrivKey(ch.EncryptedMetadataPrivKey, aclKeys.ReadKey.Decrypt)
if err != nil {
return err
}
aclKeys.MetadataPrivKey = metadataKey
}
st.keys[recordId] = aclKeys
return nil
}
func (st *AclState) decryptReadKey(msg []byte) (crypto.SymKey, error) {
decrypted, err := st.key.Decrypt(msg)
func (st *AclState) unmarshallDecryptReadKey(msg []byte, decryptor func(msg []byte) ([]byte, error)) (crypto.SymKey, error) {
decrypted, err := decryptor(msg)
if err != nil {
return nil, ErrFailedToDecrypt
}
key, err := crypto.UnmarshallAESKey(decrypted)
key, err := crypto.UnmarshallAESKeyProto(decrypted)
if err != nil {
return nil, ErrFailedToDecrypt
}
return key, nil
}
func (st *AclState) unmarshallDecryptPrivKey(msg []byte, decryptor func(msg []byte) ([]byte, error)) (crypto.PrivKey, error) {
decrypted, err := decryptor(msg)
if err != nil {
return nil, ErrFailedToDecrypt
}
key, err := crypto.UnmarshalEd25519PrivateKeyProto(decrypted)
if err != nil {
return nil, ErrFailedToDecrypt
}
return key, nil
}
func (st *AclState) GetMetadata(identity crypto.PubKey, decrypt bool) (res []byte, err error) {
state, exists := st.accountStates[mapKeyFromPubKey(identity)]
if !exists {
return nil, ErrNoSuchAccount
}
if !decrypt {
return state.RequestMetadata, nil
}
aclKeys := st.keys[state.KeyRecordId]
if aclKeys.MetadataPrivKey == nil {
return nil, ErrFailedToDecrypt
}
return aclKeys.MetadataPrivKey.Decrypt(state.RequestMetadata)
}
func (st *AclState) Permissions(identity crypto.PubKey) AclPermissions {
state, exists := st.userStates[mapKeyFromPubKey(identity)]
state, exists := st.accountStates[mapKeyFromPubKey(identity)]
if !exists {
return AclPermissions(aclrecordproto.AclUserPermissions_None)
}

View file

@ -25,15 +25,21 @@ func (sb *aclStateBuilder) Init(id string) {
}
func (sb *aclStateBuilder) Build(records []*AclRecord) (state *AclState, err error) {
if len(records) == 0 {
return nil, ErrIncorrectRecordSequence
}
if sb.privKey != nil {
state, err = newAclStateWithKeys(sb.id, sb.privKey)
state, err = newAclStateWithKeys(records[0], sb.privKey)
if err != nil {
return
}
} else {
state = newAclState(sb.id)
state, err = newAclState(records[0])
if err != nil {
return
}
}
for _, rec := range records {
for _, rec := range records[1:] {
err = state.applyRecord(rec)
if err != nil {
return nil, err

View file

@ -49,6 +49,7 @@ type AclList interface {
Head() *AclRecord
RecordsAfter(ctx context.Context, id string) (records []*consensusproto.RawRecordWithId, err error)
RecordsBefore(ctx context.Context, headId string) (records []*consensusproto.RawRecordWithId, err error)
Get(id string) (*AclRecord, error)
GetIndex(idx int) (*AclRecord, error)
Iterate(iterFunc IterFunc)
@ -181,6 +182,7 @@ func build(deps internalDeps) (list AclList, err error) {
storage: storage,
id: id,
}
state.list = list
return
}
@ -200,14 +202,14 @@ func (a *aclList) ValidateRawRecord(rawRec *consensusproto.RawRecord) (err error
return a.aclState.Validator().ValidateAclRecordContents(record)
}
func (a *aclList) AddRawRecords(rawRecords []*consensusproto.RawRecordWithId) (err error) {
func (a *aclList) AddRawRecords(rawRecords []*consensusproto.RawRecordWithId) error {
for _, rec := range rawRecords {
err = a.AddRawRecord(rec)
err := a.AddRawRecord(rec)
if err != nil && err != ErrRecordAlreadyExists {
return
return err
}
}
return
return nil
}
func (a *aclList) AddRawRecord(rawRec *consensusproto.RawRecordWithId) (err error) {
@ -305,6 +307,24 @@ func (a *aclList) RecordsAfter(ctx context.Context, id string) (records []*conse
return
}
func (a *aclList) RecordsBefore(ctx context.Context, headId string) (records []*consensusproto.RawRecordWithId, err error) {
if headId == "" {
headId = a.Head().Id
}
recIdx, ok := a.indexes[headId]
if !ok {
return nil, ErrNoSuchRecord
}
for i := 0; i <= recIdx; 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 {

View file

@ -19,6 +19,8 @@ type aclFixture struct {
spaceId string
}
var mockMetadata = []byte("very important metadata")
func newFixture(t *testing.T) *aclFixture {
ownerKeys, err := accountdata.NewRandom()
require.NoError(t, err)
@ -29,6 +31,9 @@ func newFixture(t *testing.T) *aclFixture {
require.NoError(t, err)
accountAcl, err := NewTestAclWithRoot(accountKeys, ownerAcl.Root())
require.NoError(t, err)
require.Equal(t, ownerAcl.AclState().lastRecordId, ownerAcl.Id())
require.Equal(t, ownerAcl.AclState().lastRecordId, accountAcl.AclState().lastRecordId)
require.NotEmpty(t, ownerAcl.Id())
return &aclFixture{
ownerKeys: ownerKeys,
accountKeys: accountKeys,
@ -62,6 +67,7 @@ func (fx *aclFixture) inviteAccount(t *testing.T, perms AclPermissions) {
requestJoin, err := accountAcl.RecordBuilder().BuildRequestJoin(RequestJoinPayload{
InviteRecordId: inviteRec.Id,
InviteKey: inv.InviteKey,
Metadata: mockMetadata,
})
require.NoError(t, err)
requestJoinRec := WrapAclRecord(requestJoin)
@ -92,6 +98,9 @@ func (fx *aclFixture) inviteAccount(t *testing.T, perms AclPermissions) {
stateAtRec, err := ownerState.StateAtRecord(requestAcceptRec.Id, accountState.pubKey)
require.NoError(t, err)
require.True(t, stateAtRec.Permissions == perms)
require.Equal(t, ownerAcl.AclState().lastRecordId, requestAcceptRec.Id)
require.Equal(t, ownerAcl.AclState().lastRecordId, accountAcl.AclState().lastRecordId)
require.NotEmpty(t, requestAcceptRec.Id)
}
func TestAclList_BuildRoot(t *testing.T) {
@ -177,9 +186,14 @@ func TestAclList_Remove(t *testing.T) {
fx.inviteAccount(t, AclPermissions(aclrecordproto.AclUserPermissions_Writer))
newReadKey := crypto.NewAES()
privKey, pubKey, err := crypto.GenerateRandomEd25519KeyPair()
require.NoError(t, err)
remove, err := fx.ownerAcl.RecordBuilder().BuildAccountRemove(AccountRemovePayload{
Identities: []crypto.PubKey{fx.accountKeys.SignKey.GetPublic()},
ReadKey: newReadKey,
Change: ReadKeyChangePayload{
MetadataKey: privKey,
ReadKey: newReadKey,
},
})
require.NoError(t, err)
removeRec := WrapAclRecord(remove)
@ -188,14 +202,45 @@ func TestAclList_Remove(t *testing.T) {
// 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.True(t, ownerState.keys[removeRec.Id].ReadKey.Equals(newReadKey))
require.True(t, ownerState.keys[removeRec.Id].MetadataPrivKey.Equals(privKey))
require.True(t, ownerState.keys[removeRec.Id].MetadataPubKey.Equals(pubKey))
require.NotEmpty(t, ownerState.keys[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()])
require.NotEmpty(t, accountState.keys[removeRec.Id])
require.Nil(t, accountState.keys[removeRec.Id].MetadataPrivKey)
require.NotNil(t, accountState.keys[removeRec.Id].MetadataPubKey)
require.Nil(t, accountState.keys[removeRec.Id].ReadKey)
require.NotEmpty(t, accountState.keys[fx.ownerAcl.Id()])
}
func TestAclList_KeyChangeInvite(t *testing.T) {
fx := newFixture(t)
newReadKey := crypto.NewAES()
privKey, _, err := crypto.GenerateRandomEd25519KeyPair()
require.NoError(t, err)
readKeyChange, err := fx.ownerAcl.RecordBuilder().BuildReadKeyChange(ReadKeyChangePayload{
MetadataKey: privKey,
ReadKey: newReadKey,
})
require.NoError(t, err)
readKeyRec := WrapAclRecord(readKeyChange)
fx.addRec(t, readKeyRec)
fx.inviteAccount(t, AclPermissions(aclrecordproto.AclUserPermissions_Writer))
}
func TestAclList_MetadataDecrypt(t *testing.T) {
fx := newFixture(t)
fx.inviteAccount(t, AclPermissions(aclrecordproto.AclUserPermissions_Writer))
meta, err := fx.ownerAcl.AclState().GetMetadata(fx.accountKeys.SignKey.GetPublic(), true)
require.NoError(t, err)
require.Equal(t, mockMetadata, meta)
meta, err = fx.ownerAcl.AclState().GetMetadata(fx.accountKeys.SignKey.GetPublic(), false)
require.NoError(t, err)
require.NotEqual(t, mockMetadata, meta)
}
func TestAclList_ReadKeyChange(t *testing.T) {
@ -207,7 +252,12 @@ func TestAclList_ReadKeyChange(t *testing.T) {
fx.inviteAccount(t, AclPermissions(aclrecordproto.AclUserPermissions_Admin))
newReadKey := crypto.NewAES()
readKeyChange, err := fx.ownerAcl.RecordBuilder().BuildReadKeyChange(newReadKey)
privKey, pubKey, err := crypto.GenerateRandomEd25519KeyPair()
require.NoError(t, err)
readKeyChange, err := fx.ownerAcl.RecordBuilder().BuildReadKeyChange(ReadKeyChangePayload{
MetadataKey: privKey,
ReadKey: newReadKey,
})
require.NoError(t, err)
readKeyRec := WrapAclRecord(readKeyChange)
fx.addRec(t, readKeyRec)
@ -215,10 +265,12 @@ func TestAclList_ReadKeyChange(t *testing.T) {
// 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()])
require.True(t, ownerState.keys[readKeyRec.Id].ReadKey.Equals(newReadKey))
require.True(t, ownerState.keys[readKeyRec.Id].MetadataPrivKey.Equals(privKey))
require.True(t, ownerState.keys[readKeyRec.Id].MetadataPubKey.Equals(pubKey))
require.True(t, accountState.keys[readKeyRec.Id].ReadKey.Equals(newReadKey))
require.NotEmpty(t, ownerState.keys[fx.ownerAcl.Id()])
require.NotEmpty(t, accountState.keys[fx.ownerAcl.Id()])
readKey, err := ownerState.CurrentReadKey()
require.NoError(t, err)
require.True(t, newReadKey.Equals(readKey))
@ -247,8 +299,8 @@ func TestAclList_PermissionChange(t *testing.T) {
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.NotEmpty(t, ownerState.keys[fx.ownerAcl.Id()])
require.NotEmpty(t, accountState.keys[fx.ownerAcl.Id()])
require.Equal(t, 0, len(ownerState.pendingRequests))
require.Equal(t, 0, len(accountState.pendingRequests))
}
@ -271,9 +323,14 @@ func TestAclList_RequestRemove(t *testing.T) {
require.True(t, accountState.pubKey.Equals(recs[0].RequestIdentity))
newReadKey := crypto.NewAES()
privKey, _, err := crypto.GenerateRandomEd25519KeyPair()
require.NoError(t, err)
remove, err := fx.ownerAcl.RecordBuilder().BuildAccountRemove(AccountRemovePayload{
Identities: []crypto.PubKey{recs[0].RequestIdentity},
ReadKey: newReadKey,
Change: ReadKeyChangePayload{
MetadataKey: privKey,
ReadKey: newReadKey,
},
})
require.NoError(t, err)
removeRec := WrapAclRecord(remove)
@ -282,12 +339,14 @@ func TestAclList_RequestRemove(t *testing.T) {
// 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.True(t, ownerState.keys[removeRec.Id].ReadKey.Equals(newReadKey))
require.NotEmpty(t, ownerState.keys[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()])
require.Nil(t, accountState.keys[removeRec.Id].MetadataPrivKey)
require.NotNil(t, accountState.keys[removeRec.Id].MetadataPubKey)
require.Nil(t, accountState.keys[removeRec.Id].ReadKey)
require.NotEmpty(t, accountState.keys[fx.ownerAcl.Id()])
}

View file

@ -13,10 +13,19 @@ func NewTestDerivedAcl(spaceId string, keys *accountdata.AccountKeys) (AclList,
if err != nil {
return nil, err
}
newReadKey := crypto.NewAES()
privKey, _, err := crypto.GenerateRandomEd25519KeyPair()
if err != nil {
return nil, err
}
root, err := builder.BuildRoot(RootContent{
PrivKey: keys.SignKey,
SpaceId: spaceId,
MasterKey: masterKey,
Change: ReadKeyChangePayload{
MetadataKey: privKey,
ReadKey: newReadKey,
},
})
if err != nil {
return nil, err

View file

@ -297,6 +297,21 @@ func (mr *MockAclListMockRecorder) RecordsAfter(arg0, arg1 interface{}) *gomock.
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecordsAfter", reflect.TypeOf((*MockAclList)(nil).RecordsAfter), arg0, arg1)
}
// RecordsBefore mocks base method.
func (m *MockAclList) RecordsBefore(arg0 context.Context, arg1 string) ([]*consensusproto.RawRecordWithId, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "RecordsBefore", arg0, arg1)
ret0, _ := ret[0].([]*consensusproto.RawRecordWithId)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// RecordsBefore indicates an expected call of RecordsBefore.
func (mr *MockAclListMockRecorder) RecordsBefore(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecordsBefore", reflect.TypeOf((*MockAclList)(nil).RecordsBefore), arg0, arg1)
}
// Root mocks base method.
func (m *MockAclList) Root() *consensusproto.RawRecordWithId {
m.ctrl.T.Helper()

View file

@ -21,10 +21,11 @@ type RequestRecord struct {
Type RequestType
}
type AclUserState struct {
type AclAccountState struct {
PubKey crypto.PubKey
Permissions AclPermissions
RequestMetadata []byte
KeyRecordId string
}
type RequestType int

View file

@ -70,7 +70,7 @@ func (c *contentValidator) ValidatePermissionChange(ch *aclrecordproto.AclAccoun
if err != nil {
return err
}
_, exists := c.aclState.userStates[mapKeyFromPubKey(chIdentity)]
_, exists := c.aclState.accountStates[mapKeyFromPubKey(chIdentity)]
if !exists {
return ErrNoSuchAccount
}
@ -122,6 +122,9 @@ func (c *contentValidator) ValidateRequestJoin(ch *aclrecordproto.AclAccountRequ
if !ok {
return ErrInvalidSignature
}
if len(ch.Metadata) > MaxMetadataLen {
return ErrMetadataTooLarge
}
return
}
@ -183,7 +186,7 @@ func (c *contentValidator) ValidateAccountRemove(ch *aclrecordproto.AclAccountRe
}
seenIdentities[mapKeyFromPubKey(identity)] = struct{}{}
}
return c.validateAccountReadKeys(ch.AccountKeys, len(c.aclState.userStates)-len(ch.Identities))
return c.validateReadKeyChange(ch.ReadKeyChange, seenIdentities)
}
func (c *contentValidator) ValidateRequestRemove(ch *aclrecordproto.AclAccountRequestRemove, authorIdentity crypto.PubKey) (err error) {
@ -197,22 +200,34 @@ func (c *contentValidator) ValidateRequestRemove(ch *aclrecordproto.AclAccountRe
}
func (c *contentValidator) ValidateReadKeyChange(ch *aclrecordproto.AclReadKeyChange, authorIdentity crypto.PubKey) (err error) {
return c.validateAccountReadKeys(ch.AccountKeys, len(c.aclState.userStates))
return c.validateReadKeyChange(ch, nil)
}
func (c *contentValidator) validateAccountReadKeys(accountKeys []*aclrecordproto.AclEncryptedReadKey, usersNum int) (err error) {
if len(accountKeys) != usersNum {
return ErrIncorrectNumberOfAccounts
func (c *contentValidator) validateReadKeyChange(ch *aclrecordproto.AclReadKeyChange, removedUsers map[string]struct{}) (err error) {
_, err = c.keyStore.PubKeyFromProto(ch.MetadataPubKey)
if err != nil {
return ErrNoMetadataKey
}
for _, encKeys := range accountKeys {
if ch.EncryptedMetadataPrivKey == nil || ch.EncryptedOldReadKey == nil {
return ErrIncorrectReadKey
}
for _, encKeys := range ch.AccountKeys {
identity, err := c.keyStore.PubKeyFromProto(encKeys.Identity)
if err != nil {
return err
}
_, exists := c.aclState.userStates[mapKeyFromPubKey(identity)]
idKey := mapKeyFromPubKey(identity)
_, exists := c.aclState.accountStates[idKey]
if !exists {
return ErrNoSuchAccount
}
if removedUsers == nil {
continue
}
_, exists = removedUsers[idKey]
if exists {
return ErrIncorrectNumberOfAccounts
}
}
return
}

View file

@ -357,6 +357,21 @@ func (mr *MockSyncAclMockRecorder) RecordsAfter(arg0, arg1 interface{}) *gomock.
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecordsAfter", reflect.TypeOf((*MockSyncAcl)(nil).RecordsAfter), arg0, arg1)
}
// RecordsBefore mocks base method.
func (m *MockSyncAcl) RecordsBefore(arg0 context.Context, arg1 string) ([]*consensusproto.RawRecordWithId, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "RecordsBefore", arg0, arg1)
ret0, _ := ret[0].([]*consensusproto.RawRecordWithId)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// RecordsBefore indicates an expected call of RecordsBefore.
func (mr *MockSyncAclMockRecorder) RecordsBefore(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecordsBefore", reflect.TypeOf((*MockSyncAcl)(nil).RecordsBefore), arg0, arg1)
}
// Root mocks base method.
func (m *MockSyncAcl) Root() *consensusproto.RawRecordWithId {
m.ctrl.T.Helper()

View file

@ -48,6 +48,9 @@ type syncAcl struct {
}
func (s *syncAcl) Run(ctx context.Context) (err error) {
s.Lock()
defer s.Unlock()
s.headUpdater.UpdateHeads(s.Id(), []string{s.Head().Id})
return
}
@ -119,6 +122,9 @@ func (s *syncAcl) SyncWithPeer(ctx context.Context, peerId string) (err error) {
}
func (s *syncAcl) Close(ctx context.Context) (err error) {
if s.AclList == nil {
return
}
s.Lock()
defer s.Unlock()
s.isClosed = true

View file

@ -642,11 +642,15 @@ func (ot *objectTree) validateTree(newChanges []*Change) error {
func (ot *objectTree) readKeysFromAclState(state *list.AclState) (err error) {
// just not to take lock many times, updating the key map from aclList
if len(ot.keys) == len(state.UserReadKeys()) {
if len(ot.keys) == len(state.Keys()) {
return nil
}
for key, value := range state.UserReadKeys() {
treeKey, err := deriveTreeKey(value, ot.id)
// if we can't read the keys anyway
if state.AccountKey() == nil || state.Permissions(state.AccountKey().GetPublic()).NoPermissions() {
return nil
}
for key, value := range state.Keys() {
treeKey, err := deriveTreeKey(value.ReadKey, ot.id)
if err != nil {
return err
}

View file

@ -52,7 +52,7 @@ func (v *objectTreeValidator) ValidateNewChanges(tree *Tree, aclList list.AclLis
func (v *objectTreeValidator) validateChange(tree *Tree, aclList list.AclList, c *Change) (err error) {
var (
userState list.AclUserState
userState list.AclAccountState
state = aclList.AclState()
)
// checking if the user could write

View file

@ -157,6 +157,10 @@ func (r *requestPeerManager) GetResponsiblePeers(ctx context.Context) (peers []p
return nil, nil
}
func (r *requestPeerManager) GetNodePeers(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

View file

@ -66,19 +66,18 @@ func storagePayloadForSpaceCreate(payload SpaceCreatePayload) (storagePayload sp
RawHeader: marshalled,
Id: spaceId,
}
readKey, err := payload.SigningKey.GetPublic().Encrypt(payload.ReadKey)
if err != nil {
return
}
// building acl root
keyStorage := crypto.NewKeyStorage()
aclBuilder := list.NewAclRecordBuilder("", keyStorage, nil, list.NoOpAcceptorVerifier{})
aclRoot, err := aclBuilder.BuildRoot(list.RootContent{
PrivKey: payload.SigningKey,
MasterKey: payload.MasterKey,
SpaceId: spaceId,
EncryptedReadKey: readKey,
PrivKey: payload.SigningKey,
MasterKey: payload.MasterKey,
SpaceId: spaceId,
Change: list.ReadKeyChangePayload{
MetadataKey: payload.MetadataKey,
ReadKey: payload.ReadKey,
},
})
if err != nil {
return

View file

@ -51,6 +51,21 @@ func (mr *MockPeerManagerMockRecorder) Broadcast(arg0, arg1 interface{}) *gomock
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Broadcast", reflect.TypeOf((*MockPeerManager)(nil).Broadcast), arg0, arg1)
}
// GetNodePeers mocks base method.
func (m *MockPeerManager) GetNodePeers(arg0 context.Context) ([]peer.Peer, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetNodePeers", arg0)
ret0, _ := ret[0].([]peer.Peer)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetNodePeers indicates an expected call of GetNodePeers.
func (mr *MockPeerManagerMockRecorder) GetNodePeers(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNodePeers", reflect.TypeOf((*MockPeerManager)(nil).GetNodePeers), arg0)
}
// GetResponsiblePeers mocks base method.
func (m *MockPeerManager) GetResponsiblePeers(arg0 context.Context) ([]peer.Peer, error) {
m.ctrl.T.Helper()

View file

@ -18,8 +18,10 @@ type PeerManager interface {
SendPeer(ctx context.Context, peerId string, msg *spacesyncproto.ObjectSyncMessage) (err error)
// Broadcast sends a message to all subscribed peers
Broadcast(ctx context.Context, msg *spacesyncproto.ObjectSyncMessage) (err error)
// GetResponsiblePeers dials or gets from cache responsible peers to unary operations
// GetResponsiblePeers dials or gets from cache responsible peers
GetResponsiblePeers(ctx context.Context) (peers []peer.Peer, err error)
// GetNodePeers dials or gets from cache node peers
GetNodePeers(ctx context.Context) (peers []peer.Peer, err error)
}
type PeerManagerProvider interface {

View file

@ -9,11 +9,13 @@ import (
"github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto"
"github.com/anyproto/any-sync/commonspace/objectsync"
"github.com/anyproto/any-sync/commonspace/objecttreebuilder"
"github.com/anyproto/any-sync/commonspace/peermanager"
"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/syncstatus"
"github.com/anyproto/any-sync/net/peer"
"github.com/anyproto/any-sync/util/crypto"
"go.uber.org/zap"
"strconv"
@ -27,14 +29,16 @@ type SpaceCreatePayload struct {
SigningKey crypto.PrivKey
// SpaceType is an arbitrary string
SpaceType string
// ReadKey is a first symmetric encryption key for a space
ReadKey []byte
// ReplicationKey is a key which is to be used to determine the node where the space should be held
ReplicationKey uint64
// SpacePayload is an arbitrary payload related to space type
SpacePayload []byte
// MasterKey is the master key of the owner
MasterKey crypto.PrivKey
// ReadKey is the first read key of space
ReadKey crypto.SymKey
// MetadataKey is the first metadata key of space
MetadataKey crypto.PrivKey
}
type SpaceDerivePayload struct {
@ -73,6 +77,8 @@ type Space interface {
SpaceDeleteRawChange(ctx context.Context) (raw *treechangeproto.RawTreeChangeWithId, err error)
DeleteSpace(ctx context.Context, deleteChange *treechangeproto.RawTreeChangeWithId) (err error)
GetNodePeers(ctx context.Context) (peer []peer.Peer, err error)
HandleMessage(ctx context.Context, msg objectsync.HandleMessage) (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)
@ -89,6 +95,7 @@ type space struct {
app *app.App
treeBuilder objecttreebuilder.TreeBuilderComponent
peerManager peermanager.PeerManager
headSync headsync.HeadSync
objectSync objectsync.ObjectSync
syncStatus syncstatus.StatusService
@ -154,6 +161,10 @@ func (s *space) TreeBuilder() objecttreebuilder.TreeBuilder {
return s.treeBuilder
}
func (s *space) GetNodePeers(ctx context.Context) (peer []peer.Peer, err error) {
return s.peerManager.GetNodePeers(ctx)
}
func (s *space) Acl() list.AclList {
return s.aclList
}
@ -173,6 +184,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.peerManager = s.app.MustComponent(peermanager.CName).(peermanager.PeerManager)
s.aclList = s.app.MustComponent(syncacl.CName).(list.AclList)
s.header, err = s.storage.SpaceHeader()
return

View file

@ -36,6 +36,36 @@ func (m *MockDRPCSpaceSyncClient) EXPECT() *MockDRPCSpaceSyncClientMockRecorder
return m.recorder
}
// AclAddRecord mocks base method.
func (m *MockDRPCSpaceSyncClient) AclAddRecord(arg0 context.Context, arg1 *spacesyncproto.AclAddRecordRequest) (*spacesyncproto.AclAddRecordResponse, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AclAddRecord", arg0, arg1)
ret0, _ := ret[0].(*spacesyncproto.AclAddRecordResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// AclAddRecord indicates an expected call of AclAddRecord.
func (mr *MockDRPCSpaceSyncClientMockRecorder) AclAddRecord(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AclAddRecord", reflect.TypeOf((*MockDRPCSpaceSyncClient)(nil).AclAddRecord), arg0, arg1)
}
// AclGetRecords mocks base method.
func (m *MockDRPCSpaceSyncClient) AclGetRecords(arg0 context.Context, arg1 *spacesyncproto.AclGetRecordsRequest) (*spacesyncproto.AclGetRecordsResponse, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AclGetRecords", arg0, arg1)
ret0, _ := ret[0].(*spacesyncproto.AclGetRecordsResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// AclGetRecords indicates an expected call of AclGetRecords.
func (mr *MockDRPCSpaceSyncClientMockRecorder) AclGetRecords(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AclGetRecords", reflect.TypeOf((*MockDRPCSpaceSyncClient)(nil).AclGetRecords), arg0, arg1)
}
// DRPCConn mocks base method.
func (m *MockDRPCSpaceSyncClient) DRPCConn() drpc.Conn {
m.ctrl.T.Helper()

View file

@ -11,6 +11,7 @@ enum ErrCodes {
SpaceIsDeleted = 4;
PeerIsNotResponsible = 5;
ReceiptIsInvalid = 6;
InvalidPayload = 7;
ErrorOffset = 100;
}
@ -25,6 +26,10 @@ service SpaceSync {
rpc ObjectSyncStream(stream ObjectSyncMessage) returns (stream ObjectSyncMessage);
// ObjectSync sends object sync message and synchronously gets response message
rpc ObjectSync(ObjectSyncMessage) returns (ObjectSyncMessage);
// AclAddRecord adds a new record to acl log. Works only with any-sync-node
rpc AclAddRecord(AclAddRecordRequest) returns (AclAddRecordResponse);
// AclGetRecords gets acl records
rpc AclGetRecords(AclGetRecordsRequest) returns (AclGetRecordsResponse);
}
// HeadSyncRange presenting a request for one range
@ -157,3 +162,27 @@ message SpaceSubscription {
repeated string spaceIds = 1;
SpaceSubscriptionAction action = 2;
}
// AclAddRecordRequest contains marshaled consensusproto.RawRecord
message AclAddRecordRequest {
string spaceId = 1;
bytes payload = 2;
}
// AclAddRecordResponse contains created record id and marshaled consensusproto.RawRecord
message AclAddRecordResponse {
string recordId = 1;
bytes payload = 2;
}
// AclGetRecordsRequest can optionally contain the last known aclHeal, the server will return only new records or an empty list if there are no new records.
// If aclHead is not provided the whole list will be returned.
message AclGetRecordsRequest {
string spaceId = 1;
string aclHead = 2;
}
// AclGetRecordsResponse contains list of marshaled consensusproto.RawRecordWithId
message AclGetRecordsResponse {
repeated bytes records = 1;
}

File diff suppressed because it is too large Load diff

View file

@ -45,6 +45,8 @@ type DRPCSpaceSyncClient interface {
SpacePull(ctx context.Context, in *SpacePullRequest) (*SpacePullResponse, error)
ObjectSyncStream(ctx context.Context) (DRPCSpaceSync_ObjectSyncStreamClient, error)
ObjectSync(ctx context.Context, in *ObjectSyncMessage) (*ObjectSyncMessage, error)
AclAddRecord(ctx context.Context, in *AclAddRecordRequest) (*AclAddRecordResponse, error)
AclGetRecords(ctx context.Context, in *AclGetRecordsRequest) (*AclGetRecordsResponse, error)
}
type drpcSpaceSyncClient struct {
@ -132,12 +134,32 @@ func (c *drpcSpaceSyncClient) ObjectSync(ctx context.Context, in *ObjectSyncMess
return out, nil
}
func (c *drpcSpaceSyncClient) AclAddRecord(ctx context.Context, in *AclAddRecordRequest) (*AclAddRecordResponse, error) {
out := new(AclAddRecordResponse)
err := c.cc.Invoke(ctx, "/spacesync.SpaceSync/AclAddRecord", drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto{}, in, out)
if err != nil {
return nil, err
}
return out, nil
}
func (c *drpcSpaceSyncClient) AclGetRecords(ctx context.Context, in *AclGetRecordsRequest) (*AclGetRecordsResponse, error) {
out := new(AclGetRecordsResponse)
err := c.cc.Invoke(ctx, "/spacesync.SpaceSync/AclGetRecords", 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)
AclAddRecord(context.Context, *AclAddRecordRequest) (*AclAddRecordResponse, error)
AclGetRecords(context.Context, *AclGetRecordsRequest) (*AclGetRecordsResponse, error)
}
type DRPCSpaceSyncUnimplementedServer struct{}
@ -162,9 +184,17 @@ func (s *DRPCSpaceSyncUnimplementedServer) ObjectSync(context.Context, *ObjectSy
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCSpaceSyncUnimplementedServer) AclAddRecord(context.Context, *AclAddRecordRequest) (*AclAddRecordResponse, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCSpaceSyncUnimplementedServer) AclGetRecords(context.Context, *AclGetRecordsRequest) (*AclGetRecordsResponse, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
type DRPCSpaceSyncDescription struct{}
func (DRPCSpaceSyncDescription) NumMethods() int { return 5 }
func (DRPCSpaceSyncDescription) NumMethods() int { return 7 }
func (DRPCSpaceSyncDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver, interface{}, bool) {
switch n {
@ -212,6 +242,24 @@ func (DRPCSpaceSyncDescription) Method(n int) (string, drpc.Encoding, drpc.Recei
in1.(*ObjectSyncMessage),
)
}, DRPCSpaceSyncServer.ObjectSync, true
case 5:
return "/spacesync.SpaceSync/AclAddRecord", drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCSpaceSyncServer).
AclAddRecord(
ctx,
in1.(*AclAddRecordRequest),
)
}, DRPCSpaceSyncServer.AclAddRecord, true
case 6:
return "/spacesync.SpaceSync/AclGetRecords", drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCSpaceSyncServer).
AclGetRecords(
ctx,
in1.(*AclGetRecordsRequest),
)
}, DRPCSpaceSyncServer.AclGetRecords, true
default:
return "", nil, nil, nil, false
}
@ -310,3 +358,35 @@ func (x *drpcSpaceSync_ObjectSyncStream) SendAndClose(m *ObjectSyncMessage) erro
}
return x.CloseSend()
}
type DRPCSpaceSync_AclAddRecordStream interface {
drpc.Stream
SendAndClose(*AclAddRecordResponse) error
}
type drpcSpaceSync_AclAddRecordStream struct {
drpc.Stream
}
func (x *drpcSpaceSync_AclAddRecordStream) SendAndClose(m *AclAddRecordResponse) error {
if err := x.MsgSend(m, drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto{}); err != nil {
return err
}
return x.CloseSend()
}
type DRPCSpaceSync_AclGetRecordsStream interface {
drpc.Stream
SendAndClose(*AclGetRecordsResponse) error
}
type drpcSpaceSync_AclGetRecordsStream struct {
drpc.Stream
}
func (x *drpcSpaceSync_AclGetRecordsStream) SendAndClose(m *AclGetRecordsResponse) error {
if err := x.MsgSend(m, drpcEncoding_File_commonspace_spacesyncproto_protos_spacesync_proto{}); err != nil {
return err
}
return x.CloseSend()
}

View file

@ -151,6 +151,10 @@ func (p *mockPeerManager) GetResponsiblePeers(ctx context.Context) (peers []peer
return nil, nil
}
func (p *mockPeerManager) GetNodePeers(ctx context.Context) (peers []peer.Peer, err error) {
return nil, nil
}
//
// Mock PeerManagerProvider
//

View file

@ -3,9 +3,11 @@ package coordinatorclient
import (
"context"
"errors"
"github.com/anyproto/any-sync/app"
"github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto"
"github.com/anyproto/any-sync/coordinator/coordinatorproto"
"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"
@ -15,6 +17,11 @@ import (
const CName = "common.coordinator.coordinatorclient"
var (
ErrPubKeyMissing = errors.New("peer pub key missing")
ErrNetworkMismatched = errors.New("network mismatched")
)
func New() CoordinatorClient {
return new(coordinatorClient)
}
@ -145,6 +152,13 @@ func (c *coordinatorClient) doClient(ctx context.Context, f func(cl coordinatorp
if err != nil {
return err
}
pubKey, err := peer.CtxPubKey(p.Context())
if err != nil {
return ErrPubKeyMissing
}
if pubKey.Network() != c.nodeConf.Configuration().NetworkId {
return ErrNetworkMismatched
}
return p.DoDrpc(ctx, func(conn drpc.Conn) error {
return f(coordinatorproto.NewDRPCCoordinatorClient(conn))
})

21
go.mod
View file

@ -15,15 +15,10 @@ require (
github.com/google/uuid v1.3.0
github.com/hashicorp/yamux v0.1.1
github.com/huandu/skiplist v1.2.0
github.com/ipfs/boxo v0.11.0
github.com/ipfs/go-block-format v0.1.2
github.com/ipfs/go-blockservice v0.5.2
github.com/ipfs/go-cid v0.4.1
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.5.0
github.com/ipfs/go-merkledag v0.11.0
github.com/ipfs/go-unixfs v0.4.6
github.com/libp2p/go-libp2p v0.29.0
github.com/mr-tron/base58 v1.2.0
github.com/multiformats/go-multibase v0.2.0
@ -55,19 +50,14 @@ 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/hashicorp/golang-lru v0.5.4 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.2 // 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
github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect
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-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
github.com/ipfs/go-verifcid v0.0.1 // indirect
github.com/ipld/go-codec-dagpb v1.6.0 // indirect
github.com/ipld/go-ipld-prime v0.20.0 // indirect
github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect
@ -83,18 +73,17 @@ require (
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/opentracing/opentracing-go v1.2.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e // indirect
github.com/polydawn/refmt v0.89.0 // indirect
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/spaolacci/murmur3 v1.1.0 // 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.opentelemetry.io/otel v1.14.0 // indirect
go.opentelemetry.io/otel/trace v1.14.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/image v0.6.0 // indirect
golang.org/x/sync v0.3.0 // indirect

107
go.sum
View file

@ -22,6 +22,7 @@ github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
github.com/cheggaaa/mb/v3 v3.0.1 h1:BuEOipGTqybXYi5KXVCpqhR1LWN2lrurq6UrH+VBhXc=
github.com/cheggaaa/mb/v3 v3.0.1/go.mod h1:zCt2QeYukhd/g0bIdNqF+b/kKz1hnLFNDkP49qN5kqI=
github.com/corona10/goimagehash v1.0.2 h1:pUfB0LnsJASMPGEZLj7tGY251vF+qLGqOgEP4rUs6kA=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 h1:HVTnpeuvF6Owjd5mniCL8DEXo7uYXdQEmOP4FJbV5tg=
github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE=
github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0=
@ -39,12 +40,12 @@ github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzP
github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
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=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0=
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=
@ -59,19 +60,15 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS
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.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=
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
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=
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/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU=
github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48=
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4=
github.com/hashicorp/golang-lru/v2 v2.0.2 h1:Dwmkdr5Nc/oBiXgJS3CDHNhJtIHkuZ3DZF5twqnfBdU=
github.com/hashicorp/golang-lru/v2 v2.0.2/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c=
@ -81,63 +78,31 @@ github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXM
github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY=
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/boxo v0.11.0 h1:urMxhZ3xoF4HssJVD3+0ssGT9pptEfHfbL8DYdoWFlg=
github.com/ipfs/boxo v0.11.0/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w=
github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA=
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.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.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog=
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=
github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk=
github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8=
github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk=
github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps=
github.com/ipfs/go-ipfs-blockstore v1.3.1 h1:cEI9ci7V0sRNivqaOr0elDsamxXFxJMMMy7PTTDQNsQ=
github.com/ipfs/go-ipfs-blockstore v1.3.1/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE=
github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ=
github.com/ipfs/go-ipfs-chunker v0.0.6 h1:+EBescK+ekHPMfmX3VYXRyOn/f80RXv7V8tGgLEYvo8=
github.com/ipfs/go-ipfs-chunker v0.0.6/go.mod h1:whszqTIBqWNUvYvjkKvBSoR1akrsSpZbZCYMFbekMjE=
github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw=
github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ=
github.com/ipfs/go-ipfs-ds-help v1.1.0 h1:yLE2w9RAsl31LtfMt91tRZcrx+e61O5mDxFRR994w4Q=
github.com/ipfs/go-ipfs-ds-help v1.1.0/go.mod h1:YR5+6EaebOhfcqVCyqemItCLthrpVNot+rsOU/5IatU=
github.com/ipfs/go-ipfs-exchange-interface v0.2.1 h1:jMzo2VhLKSHbVe+mHNzYgs95n0+t0Q69GQ5WhRDZV/s=
github.com/ipfs/go-ipfs-exchange-interface v0.2.1/go.mod h1:MUsYn6rKbG6CTtsDp+lKJPmVt3ZrCViNyH3rfPGsZ2E=
github.com/ipfs/go-ipfs-exchange-offline v0.3.0 h1:c/Dg8GDPzixGd0MC8Jh6mjOwU57uYokgWRFidfvEkuA=
github.com/ipfs/go-ipfs-files v0.2.0 h1:z6MCYHQSZpDWpUSK59Kf0ajP1fi4gLCf6fIulVsp8A8=
github.com/ipfs/go-ipfs-files v0.2.0/go.mod h1:vT7uaQfIsprKktzbTPLnIsd+NGw9ZbYwSq0g3N74u0M=
github.com/ipfs/go-ipfs-posinfo v0.0.1 h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6OtpRs=
github.com/ipfs/go-ipfs-posinfo v0.0.1/go.mod h1:SwyeVP+jCwiDu0C313l/8jg6ZxM0qqtlt2a0vILTc1A=
github.com/ipfs/go-ipfs-pq v0.0.2 h1:e1vOOW6MuOwG2lqxcLA+wEn93i/9laCY8sXAw76jFOY=
github.com/ipfs/go-ipfs-routing v0.3.0 h1:9W/W3N+g+y4ZDeffSgqhgo7BsBSJwPMcyssET9OWevc=
github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc=
github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE=
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-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms=
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.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=
github.com/ipfs/go-unixfs v0.4.6 h1:4PCH8+ptflEqmD1ifrdjGu0hA/MfM1s4QlrsQb4BvJM=
github.com/ipfs/go-unixfs v0.4.6/go.mod h1:BIznJNvt/gEx/ooRMI4Us9K8+qeGO7vx1ohnbk8gjFg=
github.com/ipfs/go-verifcid v0.0.1 h1:m2HI7zIuR5TFyQ1b79Da5N9dnnCP1vcu2QqawmWlK2E=
github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0=
github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg=
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.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g=
@ -148,7 +113,8 @@ 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 h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/kisielk/errcheck v1.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.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
@ -157,7 +123,6 @@ github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/q
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=
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=
@ -181,15 +146,12 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zk
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
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=
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=
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.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0=
@ -198,12 +160,10 @@ github.com/multiformats/go-multiaddr v0.10.1 h1:HghtFrWyZEPrpTvgAMFJi6gFdgHfs2cb
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=
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.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc=
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=
@ -215,15 +175,13 @@ github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOEL
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.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=
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-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/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4=
github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw=
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=
@ -237,10 +195,13 @@ github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc8
github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E=
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=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs=
github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg=
github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM=
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=
@ -248,13 +209,14 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
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/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/warpfork/go-testmark v0.11.0 h1:J6LnV8KpceDvo7spaNU4+DauH2n1x+6RaO2rJrmpQ9U=
github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a h1:G++j5e0OC488te356JvdhaM8YS6nMsjLAYF7JxCv07w=
github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ=
github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw=
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=
@ -269,11 +231,10 @@ github.com/zeebo/errs v1.3.0 h1:hmiaKqgYZzcVgRL1Vkc1Mn2914BbzB0IBxs+ebeutGs=
github.com/zeebo/errs v1.3.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4=
github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo=
github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
go.opentelemetry.io/otel v1.7.0 h1:Z2lA3Tdch0iDcrhJXDIlC94XE+bxok1F9B+4Lz/lGsM=
go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk=
go.opentelemetry.io/otel/trace v1.7.0 h1:O37Iogk1lEkMRXewVtZ1BBTVn5JEp8GrJvP92bJqC6o=
go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM=
go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU=
go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M=
go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
@ -281,18 +242,13 @@ go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpK
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=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@ -305,7 +261,6 @@ golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N0
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=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
@ -333,7 +288,6 @@ golang.org/x/sync v0.1.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=
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=
@ -359,9 +313,7 @@ golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
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=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
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=
@ -379,9 +331,7 @@ google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cn
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
@ -389,7 +339,6 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI=
lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
storj.io/drpc v0.0.33 h1:yCGZ26r66ZdMP0IcTYsj7WDAUIIjzXk6DJhbhvt9FHI=

View file

@ -106,10 +106,10 @@ 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) + int(p.openingWaitCount.Load()))
p.openingWaitCount.Add(1)
defer p.openingWaitCount.Add(-1)
p.mu.Unlock()
if wait != nil {
p.openingWaitCount.Add(1)
defer p.openingWaitCount.Add(-1)
// throttle new connection opening
select {
case <-ctx.Done():

View file

@ -20,7 +20,8 @@ const CName = "net.peerservice"
var log = logger.NewNamed(CName)
var (
ErrAddrsNotFound = errors.New("addrs for peer not found")
ErrAddrsNotFound = errors.New("addrs for peer not found")
ErrPeerIdMismatched = errors.New("peerId mismatched")
)
func New() PeerService {
@ -67,7 +68,7 @@ func (p *peerService) Dial(ctx context.Context, peerId string) (pr peer.Peer, er
}
var mc transport.MultiConn
log.InfoCtx(ctx, "dial", zap.String("peerId", peerId), zap.Strings("addrs", addrs))
log.DebugCtx(ctx, "dial", zap.String("peerId", peerId), zap.Strings("addrs", addrs))
for _, addr := range addrs {
mc, err = p.yamux.Dial(ctx, addr)
if err != nil {
@ -79,6 +80,13 @@ func (p *peerService) Dial(ctx context.Context, peerId string) (pr peer.Peer, er
if err != nil {
return
}
connPeerId, err := peer.CtxPeerId(mc.Context())
if err != nil {
return nil, err
}
if connPeerId != peerId {
return nil, ErrPeerIdMismatched
}
return peer.NewPeer(mc, p.server)
}

View file

@ -6,6 +6,8 @@ import (
"crypto/rand"
"crypto/subtle"
"fmt"
"github.com/anyproto/any-sync/util/crypto/cryptoproto"
"github.com/gogo/protobuf/proto"
mbase "github.com/multiformats/go-multibase"
)
@ -60,6 +62,19 @@ func UnmarshallAESKey(k []byte) (*AESKey, error) {
return &AESKey{raw: k}, nil
}
// UnmarshallAESKeyProto returns a key by decoding bytes.
func UnmarshallAESKeyProto(k []byte) (*AESKey, error) {
msg := &cryptoproto.Key{}
err := proto.Unmarshal(k, msg)
if err != nil {
return nil, err
}
if msg.Type != cryptoproto.KeyType_AES {
return nil, ErrIncorrectKeyType
}
return UnmarshallAESKey(msg.Data)
}
// UnmarshallAESKeyString returns a key by decoding a base32-encoded string.
func UnmarshallAESKeyString(k string) (*AESKey, error) {
_, b, err := mbase.Decode(k)
@ -119,3 +134,12 @@ func (k *AESKey) Decrypt(ciphertext []byte) ([]byte, error) {
}
return plain, nil
}
// Marshall marshalls the key into proto
func (k *AESKey) Marshall() ([]byte, error) {
msg := &cryptoproto.Key{
Type: cryptoproto.KeyType_AES,
Data: k.raw,
}
return msg.Marshal()
}

View file

@ -62,6 +62,8 @@ type SymKey interface {
Decrypt(message []byte) ([]byte, error)
// Encrypt encrypts the message and returns the result
Encrypt(message []byte) ([]byte, error)
// Marshall wraps key in proto encoding and marshalls it
Marshall() ([]byte, error)
}
func KeyEquals(k1, k2 Key) bool {