WIP proto refactoring

This commit is contained in:
mcrakhman 2022-09-12 21:06:20 +02:00
parent 018406d25c
commit 9976a84d42
No known key found for this signature in database
GPG Key ID: DED12CFEF5B8396B
33 changed files with 4328 additions and 4937 deletions

View File

@ -30,7 +30,7 @@ proto:
$(GOGO_START) protoc --gogofaster_out=:. $(P_TEST_CHANGES_PATH_PB)/proto/*.proto
$(eval PKGMAP := $$(P_ACL_CHANGES))
$(GOGO_START) protoc --gogofaster_out=$(PKGMAP):. $(P_SYNC_CHANGES_PATH_PB)/proto/*.proto
$(GOGO_START) protoc --gogofaster_out=$(PKGMAP):. service/space/spacesync/protos/*.proto
$(GOGO_START) protoc --gogofaster_out=$(PKGMAP):. common/commonspace/spacesyncproto/protos/*.proto
build:
@$(eval FLAGS := $$(shell govvv -flags -pkg github.com/anytypeio/go-anytype-infrastructure-experiments/app))

View File

@ -1,16 +1,17 @@
syntax = "proto3";
package anySpace;
option go_package = "common/commonspace/spacesyncproto";
import "pkg/acl/aclchanges/aclpb/protos/aclchanges.proto";
enum ErrCodes {
Unexpected = 0;
}
service Space {
// HeadSync compares all objects and their hashes in a space
rpc HeadSync(HeadSyncRequest) returns (HeadSyncResponse);
rpc Stream( stream Msg) returns (stream Msg);
rpc Stream(stream ObjectSyncMessage) returns (stream ObjectSyncMessage);
}
// TODO: temporary mock message
@ -18,8 +19,6 @@ message Msg {
string spaceId = 1;
}
// HeadSyncRange presenting a request for one range
message HeadSyncRange {
uint64 from = 1;
@ -50,3 +49,40 @@ message HeadSyncRequest {
message HeadSyncResponse {
repeated HeadSyncResult results = 1;
}
// ObjectSyncMessage is a message sent on object sync
message ObjectSyncMessage {
string spaceId = 1;
ObjectSyncContentValue content = 2;
acl.TreeHeader treeHeader = 3;
string treeId = 4;
}
// ObjectSyncContentValue provides different types for object sync
message ObjectSyncContentValue {
oneof value {
ObjectHeadUpdate headUpdate = 1;
ObjectFullSyncRequest fullSyncRequest = 2;
ObjectFullSyncResponse fullSyncResponse = 3;
}
}
// ObjectHeadUpdate is a message sent on document head update
message ObjectHeadUpdate {
repeated string heads = 1;
repeated acl.RawTreeChangeWithId changes = 2;
repeated string snapshotPath = 3;
}
// ObjectHeadUpdate is a message sent when document needs full sync
message ObjectFullSyncRequest {
repeated string heads = 1;
repeated string snapshotPath = 2;
}
// ObjectFullSyncResponse is a message sent as a response for a specific full sync
message ObjectFullSyncResponse {
repeated string heads = 1;
repeated acl.RawTreeChangeWithId changes = 2;
repeated string snapshotPath = 3;
}

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ import (
)
type AccountData struct { // TODO: create a convenient constructor for this
Identity string // TODO: this is essentially the same as sign key
Identity []byte // TODO: this is essentially the same as sign key
SignKey signingkey.PrivKey
EncKey encryptionkey.PrivKey
Decoder keys.Decoder

File diff suppressed because it is too large Load Diff

View File

@ -2,147 +2,142 @@ syntax = "proto3";
package acl;
option go_package = "aclpb";
message RawChange {
// ACL protos
message RawACLRecord {
bytes payload = 1;
bytes signature = 2;
string id = 3;
string id = 3; // this field is only used on user side for convenience, it should be empty when saving to db
}
message RawRecord {
bytes payload = 1;
bytes signature = 2;
string id = 3;
}
// the element of change tree used to store and internal apply smartBlock history
message ACLChange {
repeated string treeHeadIds = 1;
repeated string aclHeadIds = 2;
string snapshotBaseId = 3; // we will only have one base snapshot for both
ACLData aclData = 4;
// the data is encoded with read key and should be read in ChangesData format
bytes changesData = 5;
uint64 currentReadKeyHash = 6;
int64 timestamp = 7;
string identity = 8;
message ACLContentValue {
oneof value {
UserAdd userAdd = 1;
UserRemove userRemove = 2;
UserPermissionChange userPermissionChange = 3;
UserInvite userInvite = 4;
UserJoin userJoin = 5;
UserConfirm userConfirm = 6;
}
}
message ACLData {
ACLSnapshot aclSnapshot = 1;
repeated ACLContentValue aclContent = 2;
}
message ACLSnapshot {
// We don't need ACLState as a separate message now, because we simplified the snapshot model
ACLState aclState = 1;
}
message ACLState {
repeated uint64 readKeyHashes = 1;
repeated UserState userStates = 2;
map<string, UserInvite> invites = 3; // TODO: later
// repeated string unconfirmedUsers = 4; // TODO: later
}
message UserState {
string identity = 1;
bytes encryptionKey = 2;
repeated bytes encryptedReadKeys = 3; // all read keys that we know
UserPermissions permissions = 4;
bool IsConfirmed = 5;
}
// we already know identity and encryptionKey
message UserAdd {
string identity = 1; // public signing key
bytes encryptionKey = 2; // public encryption key
repeated bytes encryptedReadKeys = 3; // all read keys that we know for the user
UserPermissions permissions = 4;
}
// TODO: this is not used as of now
message UserConfirm { // not needed for read permissions
string identity = 1; // not needed
string userAddId = 2;
}
message UserInvite {
bytes acceptPublicKey = 1;
bytes encryptPublicKey = 2;
repeated bytes encryptedReadKeys = 3; // all read keys that we know for the user
UserPermissions permissions = 4;
string InviteId = 5;
}
message UserJoin {
string identity = 1;
bytes encryptionKey = 2;
bytes acceptSignature = 3; // sign acceptPublicKey
string userInviteId = 4;
repeated bytes encryptedReadKeys = 5; // the idea is that user should itself reencrypt the keys with the pub key
}
message UserRemove {
string identity = 1;
repeated ReadKeyReplace readKeyReplaces = 3; // new read key encrypted for all users
}
message ReadKeyReplace {
string identity = 1;
bytes encryptionKey = 2;
bytes encryptedReadKey = 3;
}
message UserPermissionChange {
string identity = 1;
UserPermissions permissions = 2;
}
enum UserPermissions {
Admin = 0;
Writer = 1;
Reader = 2;
Removed = 3;
message ACLContentValue {
oneof value {
ACLUserAdd userAdd = 1;
ACLUserRemove userRemove = 2;
ACLUserPermissionChange userPermissionChange = 3;
ACLUserInvite userInvite = 4;
ACLUserJoin userJoin = 5;
ACLUserConfirm userConfirm = 6;
}
}
message Change {
repeated string treeHeadIds = 1;
string aclHeadId = 2;
string snapshotBaseId = 3; // we will only have one base snapshot for both
bytes changesData = 4;
uint64 currentReadKeyHash = 5;
int64 timestamp = 6;
string identity = 7;
bool isSnapshot = 8;
message ACLData {
repeated ACLContentValue aclContent = 1;
}
message Record {
message ACLState {
repeated uint64 readKeyHashes = 1;
repeated ACLUserState userStates = 2;
map<string, ACLUserInvite> invites = 3; // TODO: later
// repeated string unconfirmedUsers = 4; // TODO: later
}
message ACLUserState {
bytes identity = 1;
bytes encryptionKey = 2;
repeated bytes encryptedReadKeys = 3; // all read keys that we know
ACLUserPermissions permissions = 4;
bool isConfirmed = 5;
}
// we already know identity and encryptionKey
message ACLUserAdd {
bytes identity = 1; // public signing key
bytes encryptionKey = 2; // public encryption key
repeated bytes encryptedReadKeys = 3; // all read keys that we know for the user
ACLUserPermissions permissions = 4;
}
// TODO: this is not used as of now
message ACLUserConfirm { // not needed for read permissions
bytes identity = 1; // not needed
string userAddId = 2;
}
message ACLUserInvite {
bytes acceptPublicKey = 1;
bytes encryptPublicKey = 2;
repeated bytes encryptedReadKeys = 3; // all read keys that we know for the user
ACLUserPermissions permissions = 4;
string inviteId = 5;
}
message ACLUserJoin {
bytes identity = 1;
bytes encryptionKey = 2;
bytes acceptSignature = 3; // sign acceptPublicKey
string userInviteId = 4;
repeated bytes encryptedReadKeys = 5; // the idea is that user should itself reencrypt the keys with the pub key
}
message ACLUserRemove {
bytes identity = 1;
repeated ACLReadKeyReplace readKeyReplaces = 3; // new read key encrypted for all users
}
message ACLReadKeyReplace {
bytes identity = 1;
bytes encryptionKey = 2;
bytes encryptedReadKey = 3;
}
message ACLUserPermissionChange {
bytes identity = 1;
ACLUserPermissions permissions = 2;
}
enum ACLUserPermissions {
Admin = 0;
Writer = 1;
Reader = 2;
Removed = 3;
}
message ACLRecord {
string prevId = 1;
string identity = 2;
bytes identity = 2;
bytes data = 3;
uint64 currentReadKeyHash = 4;
int64 timestamp = 5;
}
message Header {
message ACLHeader {
string firstId = 1;
string aclListId = 2;
string workspaceId = 3;
DocType docType = 4;
enum DocType {
ACL = 0;
DocTree = 1;
}
bytes identity = 2; // the identity of the creator
}
// Tree protos
message RawTreeChange {
bytes payload = 1;
bytes signature = 2;
}
message RawTreeChangeWithId {
bytes rawChange = 1;
string id = 2;
}
message TreeChange {
repeated string treeHeadIds = 1;
string aclHeadId = 2;
string snapshotBaseId = 3;
bytes changesData = 4;
uint64 currentReadKeyHash = 5;
int64 timestamp = 6;
bytes identity = 7;
bool isSnapshot = 8;
}
enum TreeHeaderType {
Object = 0;
Space = 1;
}
message TreeHeader {
string firstId = 1;
string aclId = 2;
TreeHeaderType treeHeaderType = 3;
bytes identity = 4;
bytes data = 5; // this should be reserved for the client to add the data it needs
}

View File

@ -1,6 +1,7 @@
package list
import (
"bytes"
"errors"
"fmt"
"github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger"
@ -29,14 +30,14 @@ var ErrInvalidSignature = errors.New("signature is invalid")
type UserPermissionPair struct {
Identity string
Permission aclpb.ACLChangeUserPermissions
Permission aclpb.ACLUserPermissions
}
type ACLState struct {
currentReadKeyHash uint64
userReadKeys map[uint64]*symmetric.Key
userStates map[string]*aclpb.ACLChangeUserState
userInvites map[string]*aclpb.ACLChangeUserInvite
userStates map[string]*aclpb.ACLUserState
userInvites map[string]*aclpb.ACLUserInvite
signingPubKeyDecoder keys.Decoder
encryptionKey encryptionkey.PrivKey
@ -55,8 +56,8 @@ func newACLStateWithIdentity(
identity: identity,
encryptionKey: encryptionKey,
userReadKeys: make(map[uint64]*symmetric.Key),
userStates: make(map[string]*aclpb.ACLChangeUserState),
userInvites: make(map[string]*aclpb.ACLChangeUserInvite),
userStates: make(map[string]*aclpb.ACLUserState),
userInvites: make(map[string]*aclpb.ACLUserInvite),
signingPubKeyDecoder: decoder,
permissionsAtRecord: make(map[string][]UserPermissionPair),
keychain: common.NewKeychain(),
@ -67,8 +68,8 @@ func newACLState(decoder keys.Decoder) *ACLState {
return &ACLState{
signingPubKeyDecoder: decoder,
userReadKeys: make(map[uint64]*symmetric.Key),
userStates: make(map[string]*aclpb.ACLChangeUserState),
userInvites: make(map[string]*aclpb.ACLChangeUserInvite),
userStates: make(map[string]*aclpb.ACLUserState),
userInvites: make(map[string]*aclpb.ACLUserInvite),
permissionsAtRecord: make(map[string][]UserPermissionPair),
keychain: common.NewKeychain(),
}
@ -105,8 +106,8 @@ func (st *ACLState) PermissionsAtRecord(id string, identity string) (UserPermiss
return UserPermissionPair{}, ErrNoSuchUser
}
func (st *ACLState) applyRecord(record *aclpb.Record) (err error) {
aclData := &aclpb.ACLChangeACLData{}
func (st *ACLState) applyRecord(record *aclpb.ACLRecord) (err error) {
aclData := &aclpb.ACLData{}
err = proto.Unmarshal(record.Data, aclData)
if err != nil {
@ -122,14 +123,14 @@ func (st *ACLState) applyRecord(record *aclpb.Record) (err error) {
return
}
func (st *ACLState) applyChangeAndUpdate(recordWrapper *Record) (err error) {
func (st *ACLState) applyChangeAndUpdate(recordWrapper *ACLRecord) (err error) {
var (
change = recordWrapper.Content
aclData = &aclpb.ACLChangeACLData{}
aclData = &aclpb.ACLData{}
)
if recordWrapper.Model != nil {
aclData = recordWrapper.Model.(*aclpb.ACLChangeACLData)
aclData = recordWrapper.Model.(*aclpb.ACLData)
} else {
err = proto.Unmarshal(change.Data, aclData)
if err != nil {
@ -147,7 +148,7 @@ func (st *ACLState) applyChangeAndUpdate(recordWrapper *Record) (err error) {
var permissions []UserPermissionPair
for _, state := range st.userStates {
permission := UserPermissionPair{
Identity: state.Identity,
Identity: string(state.Identity),
Permission: state.Permissions,
}
permissions = append(permissions, permission)
@ -157,7 +158,7 @@ func (st *ACLState) applyChangeAndUpdate(recordWrapper *Record) (err error) {
return nil
}
func (st *ACLState) applyChangeData(changeData *aclpb.ACLChangeACLData, hash uint64, identity string) (err error) {
func (st *ACLState) applyChangeData(changeData *aclpb.ACLData, hash uint64, identity []byte) (err error) {
defer func() {
if err != nil {
return
@ -170,12 +171,12 @@ func (st *ACLState) applyChangeData(changeData *aclpb.ACLChangeACLData, hash uin
skipIdentityCheck := st.isUserJoin(changeData) || (st.currentReadKeyHash == 0 && st.isUserAdd(changeData, identity))
if !skipIdentityCheck {
// we check signature when we add this to the Tree, so no need to do it here
if _, exists := st.userStates[identity]; !exists {
if _, exists := st.userStates[string(identity)]; !exists {
err = ErrNoSuchUser
return
}
if !st.hasPermission(identity, aclpb.ACLChange_Admin) {
if !st.hasPermission(identity, aclpb.ACLUserPermissions_Admin) {
err = fmt.Errorf("user %s must have admin permissions", identity)
return
}
@ -191,7 +192,7 @@ func (st *ACLState) applyChangeData(changeData *aclpb.ACLChangeACLData, hash uin
return nil
}
func (st *ACLState) applyChangeContent(ch *aclpb.ACLChangeACLContentValue) error {
func (st *ACLState) applyChangeContent(ch *aclpb.ACLContentValue) error {
switch {
case ch.GetUserPermissionChange() != nil:
return st.applyUserPermissionChange(ch.GetUserPermissionChange())
@ -210,27 +211,29 @@ func (st *ACLState) applyChangeContent(ch *aclpb.ACLChangeACLContentValue) error
}
}
func (st *ACLState) applyUserPermissionChange(ch *aclpb.ACLChangeUserPermissionChange) error {
if _, exists := st.userStates[ch.Identity]; !exists {
func (st *ACLState) applyUserPermissionChange(ch *aclpb.ACLUserPermissionChange) error {
chIdentity := string(ch.Identity)
if _, exists := st.userStates[chIdentity]; !exists {
return ErrNoSuchUser
}
st.userStates[ch.Identity].Permissions = ch.Permissions
st.userStates[chIdentity].Permissions = ch.Permissions
return nil
}
func (st *ACLState) applyUserInvite(ch *aclpb.ACLChangeUserInvite) error {
func (st *ACLState) applyUserInvite(ch *aclpb.ACLUserInvite) error {
st.userInvites[ch.InviteId] = ch
return nil
}
func (st *ACLState) applyUserJoin(ch *aclpb.ACLChangeUserJoin) error {
func (st *ACLState) applyUserJoin(ch *aclpb.ACLUserJoin) error {
invite, exists := st.userInvites[ch.UserInviteId]
if !exists {
return fmt.Errorf("no such invite with id %s", ch.UserInviteId)
}
chIdentity := string(ch.Identity)
if _, exists = st.userStates[ch.Identity]; exists {
if _, exists = st.userStates[chIdentity]; exists {
return ErrUserAlreadyExists
}
@ -241,12 +244,7 @@ func (st *ACLState) applyUserJoin(ch *aclpb.ACLChangeUserJoin) error {
return fmt.Errorf("public key verifying invite accepts is given in incorrect format: %v", err)
}
rawSignedId, err := st.signingPubKeyDecoder.DecodeFromStringIntoBytes(ch.Identity)
if err != nil {
return fmt.Errorf("failed to decode signing identity as bytes")
}
res, err := verificationKey.(signingkey.PubKey).Verify(rawSignedId, signature)
res, err := verificationKey.(signingkey.PubKey).Verify(ch.Identity, signature)
if err != nil {
return fmt.Errorf("verification returned error: %w", err)
}
@ -255,7 +253,7 @@ func (st *ACLState) applyUserJoin(ch *aclpb.ACLChangeUserJoin) error {
}
// if ourselves -> we need to decrypt the read keys
if st.identity == ch.Identity {
if st.identity == chIdentity {
for _, key := range ch.EncryptedReadKeys {
key, hash, err := st.decryptReadKeyAndHash(key)
if err != nil {
@ -267,30 +265,31 @@ func (st *ACLState) applyUserJoin(ch *aclpb.ACLChangeUserJoin) error {
}
// adding user to the list
userState := &aclpb.ACLChangeUserState{
userState := &aclpb.ACLUserState{
Identity: ch.Identity,
EncryptionKey: ch.EncryptionKey,
EncryptedReadKeys: ch.EncryptedReadKeys,
Permissions: invite.Permissions,
IsConfirmed: true,
}
st.userStates[ch.Identity] = userState
st.userStates[chIdentity] = userState
return nil
}
func (st *ACLState) applyUserAdd(ch *aclpb.ACLChangeUserAdd) error {
if _, exists := st.userStates[ch.Identity]; exists {
func (st *ACLState) applyUserAdd(ch *aclpb.ACLUserAdd) error {
chIdentity := string(ch.Identity)
if _, exists := st.userStates[chIdentity]; exists {
return ErrUserAlreadyExists
}
st.userStates[ch.Identity] = &aclpb.ACLChangeUserState{
st.userStates[chIdentity] = &aclpb.ACLUserState{
Identity: ch.Identity,
EncryptionKey: ch.EncryptionKey,
Permissions: ch.Permissions,
EncryptedReadKeys: ch.EncryptedReadKeys,
}
if ch.Identity == st.identity {
if chIdentity == st.identity {
for _, key := range ch.EncryptedReadKeys {
key, hash, err := st.decryptReadKeyAndHash(key)
if err != nil {
@ -304,26 +303,28 @@ func (st *ACLState) applyUserAdd(ch *aclpb.ACLChangeUserAdd) error {
return nil
}
func (st *ACLState) applyUserRemove(ch *aclpb.ACLChangeUserRemove) error {
if ch.Identity == st.identity {
func (st *ACLState) applyUserRemove(ch *aclpb.ACLUserRemove) error {
chIdentity := string(ch.Identity)
if chIdentity == st.identity {
return ErrDocumentForbidden
}
if _, exists := st.userStates[ch.Identity]; !exists {
if _, exists := st.userStates[chIdentity]; !exists {
return ErrNoSuchUser
}
delete(st.userStates, ch.Identity)
delete(st.userStates, chIdentity)
for _, replace := range ch.ReadKeyReplaces {
userState, exists := st.userStates[replace.Identity]
repIdentity := string(replace.Identity)
userState, exists := st.userStates[repIdentity]
if !exists {
continue
}
userState.EncryptedReadKeys = append(userState.EncryptedReadKeys, replace.EncryptedReadKey)
// if this is our identity then we have to decrypt the key
if replace.Identity == st.identity {
if repIdentity == st.identity {
key, hash, err := st.decryptReadKeyAndHash(replace.EncryptedReadKey)
if err != nil {
return ErrFailedToDecrypt
@ -336,12 +337,13 @@ func (st *ACLState) applyUserRemove(ch *aclpb.ACLChangeUserRemove) error {
return nil
}
func (st *ACLState) applyUserConfirm(ch *aclpb.ACLChangeUserConfirm) error {
if _, exists := st.userStates[ch.Identity]; !exists {
func (st *ACLState) applyUserConfirm(ch *aclpb.ACLUserConfirm) error {
chIdentity := string(ch.Identity)
if _, exists := st.userStates[chIdentity]; !exists {
return ErrNoSuchUser
}
userState := st.userStates[ch.Identity]
userState := st.userStates[chIdentity]
userState.IsConfirmed = true
return nil
}
@ -362,8 +364,8 @@ func (st *ACLState) decryptReadKeyAndHash(msg []byte) (*symmetric.Key, uint64, e
return key, hasher.Sum64(), nil
}
func (st *ACLState) hasPermission(identity string, permission aclpb.ACLChangeUserPermissions) bool {
state, exists := st.userStates[identity]
func (st *ACLState) hasPermission(identity []byte, permission aclpb.ACLUserPermissions) bool {
state, exists := st.userStates[string(identity)]
if !exists {
return false
}
@ -371,17 +373,17 @@ func (st *ACLState) hasPermission(identity string, permission aclpb.ACLChangeUse
return state.Permissions == permission
}
func (st *ACLState) isUserJoin(data *aclpb.ACLChangeACLData) bool {
func (st *ACLState) isUserJoin(data *aclpb.ACLData) bool {
// if we have a UserJoin, then it should always be the first one applied
return data.GetAclContent() != nil && data.GetAclContent()[0].GetUserJoin() != nil
}
func (st *ACLState) isUserAdd(data *aclpb.ACLChangeACLData, identity string) bool {
func (st *ACLState) isUserAdd(data *aclpb.ACLData, identity []byte) bool {
// if we have a UserAdd, then it should always be the first one applied
userAdd := data.GetAclContent()[0].GetUserAdd()
return data.GetAclContent() != nil && userAdd != nil && userAdd.GetIdentity() == identity
return data.GetAclContent() != nil && userAdd != nil && bytes.Compare(userAdd.GetIdentity(), identity) == 0
}
func (st *ACLState) GetUserStates() map[string]*aclpb.ACLChangeUserState {
func (st *ACLState) GetUserStates() map[string]*aclpb.ACLUserState {
return st.userStates
}

View File

@ -15,7 +15,7 @@ type aclStateBuilder struct {
func newACLStateBuilderWithIdentity(decoder keys.Decoder, accountData *account.AccountData) *aclStateBuilder {
return &aclStateBuilder{
decoder: decoder,
identity: accountData.Identity,
identity: string(accountData.Identity),
key: accountData.EncKey,
}
}
@ -26,7 +26,7 @@ func newACLStateBuilder(decoder keys.Decoder) *aclStateBuilder {
}
}
func (sb *aclStateBuilder) Build(records []*Record) (*ACLState, error) {
func (sb *aclStateBuilder) Build(records []*ACLRecord) (*ACLState, error) {
var (
err error
state *ACLState

View File

@ -14,7 +14,7 @@ import (
type MarshalledChange = []byte
type ACLChangeBuilder interface {
UserAdd(identity string, encryptionKey encryptionkey.PubKey, permissions aclpb.ACLChangeUserPermissions) error
UserAdd(identity string, encryptionKey encryptionkey.PubKey, permissions aclpb.ACLUserPermissions) error
AddId(id string) // TODO: this is only for testing
}
@ -23,7 +23,7 @@ type aclChangeBuilder struct {
list ACLList
acc *account.AccountData
aclData *aclpb.ACLChangeACLData
aclData *aclpb.ACLData
id string
readKey *symmetric.Key
readKeyHash uint64
@ -38,7 +38,7 @@ func (c *aclChangeBuilder) Init(state *ACLState, list ACLList, acc *account.Acco
c.list = list
c.acc = acc
c.aclData = &aclpb.ACLChangeACLData{}
c.aclData = &aclpb.ACLData{}
// setting read key for further encryption etc
if state.currentReadKeyHash == 0 {
c.readKey, _ = symmetric.NewRandom()
@ -56,7 +56,7 @@ func (c *aclChangeBuilder) AddId(id string) {
c.id = id
}
func (c *aclChangeBuilder) UserAdd(identity string, encryptionKey encryptionkey.PubKey, permissions aclpb.ACLChangeUserPermissions) error {
func (c *aclChangeBuilder) UserAdd(identity string, encryptionKey encryptionkey.PubKey, permissions aclpb.ACLUserPermissions) error {
var allKeys []*symmetric.Key
if c.aclState.currentReadKeyHash != 0 {
for _, key := range c.aclState.userReadKeys {
@ -79,10 +79,10 @@ func (c *aclChangeBuilder) UserAdd(identity string, encryptionKey encryptionkey.
if err != nil {
return err
}
ch := &aclpb.ACLChangeACLContentValue{
Value: &aclpb.ACLChangeACLContentValueValueOfUserAdd{
UserAdd: &aclpb.ACLChangeUserAdd{
Identity: identity,
ch := &aclpb.ACLContentValue{
Value: &aclpb.ACLContentValue_UserAdd{
UserAdd: &aclpb.ACLUserAdd{
Identity: []byte(identity),
EncryptionKey: rawKey,
EncryptedReadKeys: encryptedKeys,
Permissions: permissions,
@ -93,8 +93,8 @@ func (c *aclChangeBuilder) UserAdd(identity string, encryptionKey encryptionkey.
return nil
}
func (c *aclChangeBuilder) BuildAndApply() (*Record, []byte, error) {
aclRecord := &aclpb.Record{
func (c *aclChangeBuilder) BuildAndApply() (*ACLRecord, []byte, error) {
aclRecord := &aclpb.ACLRecord{
PrevId: c.list.Head().Id,
CurrentReadKeyHash: c.readKeyHash,
Timestamp: int64(time.Now().Nanosecond()),

View File

@ -13,7 +13,7 @@ import (
"sync"
)
type IterFunc = func(record *Record) (IsContinue bool)
type IterFunc = func(record *ACLRecord) (IsContinue bool)
var ErrIncorrectCID = errors.New("incorrect CID")
@ -26,20 +26,20 @@ type RWLocker interface {
type ACLList interface {
RWLocker
ID() string
Header() *aclpb.Header
Records() []*Record
Header() *aclpb.ACLHeader
Records() []*ACLRecord
ACLState() *ACLState
IsAfter(first string, second string) (bool, error)
Head() *Record
Get(id string) (*Record, error)
Head() *ACLRecord
Get(id string) (*ACLRecord, error)
Iterate(iterFunc IterFunc)
IterateFrom(startId string, iterFunc IterFunc)
Close() (err error)
}
type aclList struct {
header *aclpb.Header
records []*Record
header *aclpb.ACLHeader
records []*ACLRecord
indexes map[string]int
id string
@ -84,7 +84,7 @@ func buildWithACLStateBuilder(builder *aclStateBuilder, storage storage.ListStor
if err != nil {
return
}
records := []*Record{record}
records := []*ACLRecord{record}
for record.Content.PrevId != "" {
rawRecord, err = storage.GetRawRecord(context.Background(), record.Content.PrevId)
@ -131,7 +131,7 @@ func buildWithACLStateBuilder(builder *aclStateBuilder, storage storage.ListStor
return
}
func (a *aclList) Records() []*Record {
func (a *aclList) Records() []*ACLRecord {
return a.records
}
@ -139,7 +139,7 @@ func (a *aclList) ID() string {
return a.id
}
func (a *aclList) Header() *aclpb.Header {
func (a *aclList) Header() *aclpb.ACLHeader {
return a.header
}
@ -156,11 +156,11 @@ func (a *aclList) IsAfter(first string, second string) (bool, error) {
return firstRec >= secondRec, nil
}
func (a *aclList) Head() *Record {
func (a *aclList) Head() *ACLRecord {
return a.records[len(a.records)-1]
}
func (a *aclList) Get(id string) (*Record, error) {
func (a *aclList) Get(id string) (*ACLRecord, error) {
recIdx, ok := a.indexes[id]
if !ok {
return nil, fmt.Errorf("no such record")
@ -192,8 +192,8 @@ func (a *aclList) Close() (err error) {
return nil
}
func verifyRecord(keychain *common.Keychain, rawRecord *aclpb.RawRecord, record *Record) (err error) {
identityKey, err := keychain.GetOrAdd(record.Content.Identity)
func verifyRecord(keychain *common.Keychain, rawRecord *aclpb.RawACLRecord, record *ACLRecord) (err error) {
identityKey, err := keychain.GetOrAdd(record.Identity)
if err != nil {
return
}

View File

@ -28,8 +28,8 @@ func TestAclList_ACLState_UserInviteAndJoin(t *testing.T) {
assert.Equal(t, aclpb.ACLChange_Reader, aclList.ACLState().GetUserStates()[idC].Permissions)
assert.Equal(t, aclList.Head().Content.CurrentReadKeyHash, aclList.ACLState().CurrentReadKeyHash())
var records []*Record
aclList.Iterate(func(record *Record) (IsContinue bool) {
var records []*ACLRecord
aclList.Iterate(func(record *ACLRecord) (IsContinue bool) {
records = append(records, record)
return true
})
@ -69,8 +69,8 @@ func TestAclList_ACLState_UserJoinAndRemove(t *testing.T) {
_, exists := aclList.ACLState().GetUserStates()[idB]
assert.Equal(t, false, exists)
var records []*Record
aclList.Iterate(func(record *Record) (IsContinue bool) {
var records []*ACLRecord
aclList.Iterate(func(record *ACLRecord) (IsContinue bool) {
records = append(records, record)
return true
})

View File

@ -5,30 +5,33 @@ import (
"github.com/gogo/protobuf/proto"
)
type Record struct {
Id string
Content *aclpb.Record
Model interface{}
Sign []byte
type ACLRecord struct {
Id string
Content *aclpb.ACLRecord
Identity string
Model interface{}
Sign []byte
}
func NewRecord(id string, aclRecord *aclpb.Record) *Record {
return &Record{
Id: id,
Content: aclRecord,
func NewRecord(id string, aclRecord *aclpb.ACLRecord) *ACLRecord {
return &ACLRecord{
Id: id,
Content: aclRecord,
Identity: string(aclRecord.Identity),
}
}
func NewFromRawRecord(rawRec *aclpb.RawRecord) (*Record, error) {
aclRec := &aclpb.Record{}
func NewFromRawRecord(rawRec *aclpb.RawACLRecord) (*ACLRecord, error) {
aclRec := &aclpb.ACLRecord{}
err := proto.Unmarshal(rawRec.Payload, aclRec)
if err != nil {
return nil, err
}
return &Record{
Id: rawRec.Id,
Content: aclRec,
Sign: rawRec.Signature,
return &ACLRecord{
Id: rawRec.Id,
Content: aclRec,
Sign: rawRec.Signature,
Identity: string(aclRec.Identity),
}, nil
}

View File

@ -8,8 +8,8 @@ import (
)
type inMemoryACLListStorage struct {
header *aclpb.Header
records []*aclpb.RawRecord
header *aclpb.ACLHeader
records []*aclpb.RawACLRecord
id string
@ -18,8 +18,8 @@ type inMemoryACLListStorage struct {
func NewInMemoryACLListStorage(
id string,
header *aclpb.Header,
records []*aclpb.RawRecord) (ListStorage, error) {
header *aclpb.ACLHeader,
records []*aclpb.RawACLRecord) (ListStorage, error) {
return &inMemoryACLListStorage{
id: id,
header: header,
@ -28,19 +28,19 @@ func NewInMemoryACLListStorage(
}, nil
}
func (i *inMemoryACLListStorage) Header() (*aclpb.Header, error) {
func (i *inMemoryACLListStorage) Header() (*aclpb.ACLHeader, error) {
i.RLock()
defer i.RUnlock()
return i.header, nil
}
func (i *inMemoryACLListStorage) Head() (*aclpb.RawRecord, error) {
func (i *inMemoryACLListStorage) Head() (*aclpb.RawACLRecord, error) {
i.RLock()
defer i.RUnlock()
return i.records[len(i.records)-1], nil
}
func (i *inMemoryACLListStorage) GetRawRecord(ctx context.Context, id string) (*aclpb.RawRecord, error) {
func (i *inMemoryACLListStorage) GetRawRecord(ctx context.Context, id string) (*aclpb.RawACLRecord, error) {
i.RLock()
defer i.RUnlock()
for _, rec := range i.records {
@ -51,7 +51,7 @@ func (i *inMemoryACLListStorage) GetRawRecord(ctx context.Context, id string) (*
return nil, fmt.Errorf("no such record")
}
func (i *inMemoryACLListStorage) AddRawRecord(ctx context.Context, rec *aclpb.RawRecord) error {
func (i *inMemoryACLListStorage) AddRawRecord(ctx context.Context, rec *aclpb.RawACLRecord) error {
panic("implement me")
}
@ -63,19 +63,19 @@ func (i *inMemoryACLListStorage) ID() (string, error) {
type inMemoryTreeStorage struct {
id string
header *aclpb.Header
header *aclpb.TreeHeader
heads []string
changes map[string]*aclpb.RawChange
changes map[string]*aclpb.RawTreeChangeWithId
sync.RWMutex
}
func NewInMemoryTreeStorage(
treeId string,
header *aclpb.Header,
header *aclpb.TreeHeader,
heads []string,
changes []*aclpb.RawChange) (TreeStorage, error) {
allChanges := make(map[string]*aclpb.RawChange)
changes []*aclpb.RawTreeChangeWithId) (TreeStorage, error) {
allChanges := make(map[string]*aclpb.RawTreeChangeWithId)
for _, ch := range changes {
allChanges[ch.Id] = ch
}
@ -95,7 +95,7 @@ func (t *inMemoryTreeStorage) ID() (string, error) {
return t.id, nil
}
func (t *inMemoryTreeStorage) Header() (*aclpb.Header, error) {
func (t *inMemoryTreeStorage) Header() (*aclpb.TreeHeader, error) {
t.RLock()
defer t.RUnlock()
return t.header, nil
@ -118,7 +118,7 @@ func (t *inMemoryTreeStorage) SetHeads(heads []string) error {
return nil
}
func (t *inMemoryTreeStorage) AddRawChange(change *aclpb.RawChange) error {
func (t *inMemoryTreeStorage) AddRawChange(change *aclpb.RawTreeChangeWithId) error {
t.Lock()
defer t.Unlock()
// TODO: better to do deep copy
@ -126,7 +126,7 @@ func (t *inMemoryTreeStorage) AddRawChange(change *aclpb.RawChange) error {
return nil
}
func (t *inMemoryTreeStorage) GetRawChange(ctx context.Context, changeId string) (*aclpb.RawChange, error) {
func (t *inMemoryTreeStorage) GetRawChange(ctx context.Context, changeId string) (*aclpb.RawTreeChangeWithId, error) {
t.RLock()
defer t.RUnlock()
if res, exists := t.changes[changeId]; exists {

View File

@ -7,8 +7,8 @@ import (
type ListStorage interface {
Storage
Head() (*aclpb.RawRecord, error)
Head() (*aclpb.RawACLRecord, error)
GetRawRecord(ctx context.Context, id string) (*aclpb.RawRecord, error)
AddRawRecord(ctx context.Context, rec *aclpb.RawRecord) error
GetRawRecord(ctx context.Context, id string) (*aclpb.RawACLRecord, error)
AddRawRecord(ctx context.Context, rec *aclpb.RawACLRecord) error
}

View File

@ -9,15 +9,15 @@ var ErrUnknownTreeId = errors.New("tree does not exist")
type TreeStorageCreatePayload struct {
TreeId string
Header *aclpb.Header
Changes []*aclpb.RawChange
Header *aclpb.TreeHeader
Changes []*aclpb.RawTreeChangeWithId
Heads []string
}
type ACLListStorageCreatePayload struct {
ListId string
Header *aclpb.Header
Records []*aclpb.RawRecord
Header *aclpb.ACLHeader
Records []*aclpb.RawACLRecord
}
type Provider interface {

View File

@ -10,8 +10,8 @@ type TreeStorage interface {
Heads() ([]string, error)
SetHeads(heads []string) error
AddRawChange(change *aclpb.RawChange) error
GetRawChange(ctx context.Context, recordID string) (*aclpb.RawChange, error)
AddRawChange(change *aclpb.RawTreeChangeWithId) error
GetRawChange(ctx context.Context, recordID string) (*aclpb.RawTreeChangeWithId, error)
}
type TreeStorageCreatorFunc = func(payload TreeStorageCreatePayload) (TreeStorage, error)

View File

@ -19,8 +19,8 @@ import (
type ACLListStorageBuilder struct {
aclList string
records []*aclpb.Record
rawRecords []*aclpb.RawRecord
records []*aclpb.ACLRecord
rawRecords []*aclpb.RawACLRecord
indexes map[string]int
keychain *Keychain
header *aclpb.Header
@ -29,7 +29,7 @@ type ACLListStorageBuilder struct {
func NewACLListStorageBuilder(keychain *Keychain) *ACLListStorageBuilder {
return &ACLListStorageBuilder{
records: make([]*aclpb.Record, 0),
records: make([]*aclpb.ACLRecord, 0),
indexes: make(map[string]int),
keychain: keychain,
}
@ -58,7 +58,7 @@ func NewACLListStorageBuilderFromFile(file string) (*ACLListStorageBuilder, erro
return tb, nil
}
func (t *ACLListStorageBuilder) createRaw(rec *aclpb.Record) *aclpb.RawRecord {
func (t *ACLListStorageBuilder) createRaw(rec *aclpb.ACLRecord) *aclpb.RawACLRecord {
aclMarshaled, err := proto.Marshal(rec)
if err != nil {
panic("should be able to marshal final acl message!")
@ -71,18 +71,18 @@ func (t *ACLListStorageBuilder) createRaw(rec *aclpb.Record) *aclpb.RawRecord {
id, _ := cid.NewCIDFromBytes(aclMarshaled)
return &aclpb.RawRecord{
return &aclpb.RawACLRecord{
Payload: aclMarshaled,
Signature: signature,
Id: id,
}
}
func (t *ACLListStorageBuilder) getRecord(idx int) *aclpb.RawRecord {
func (t *ACLListStorageBuilder) getRecord(idx int) *aclpb.RawACLRecord {
return t.rawRecords[idx]
}
func (t *ACLListStorageBuilder) Head() (*aclpb.RawRecord, error) {
func (t *ACLListStorageBuilder) Head() (*aclpb.RawACLRecord, error) {
return t.getRecord(len(t.records) - 1), nil
}
@ -90,7 +90,7 @@ func (t *ACLListStorageBuilder) Header() (*aclpb.Header, error) {
return t.header, nil
}
func (t *ACLListStorageBuilder) GetRawRecord(ctx context.Context, id string) (*aclpb.RawRecord, error) {
func (t *ACLListStorageBuilder) GetRawRecord(ctx context.Context, id string) (*aclpb.RawACLRecord, error) {
recIdx, ok := t.indexes[id]
if !ok {
return nil, fmt.Errorf("no such record")
@ -98,7 +98,7 @@ func (t *ACLListStorageBuilder) GetRawRecord(ctx context.Context, id string) (*a
return t.getRecord(recIdx), nil
}
func (t *ACLListStorageBuilder) AddRawRecord(ctx context.Context, rec *aclpb.RawRecord) error {
func (t *ACLListStorageBuilder) AddRawRecord(ctx context.Context, rec *aclpb.RawACLRecord) error {
panic("implement me")
}
@ -106,7 +106,7 @@ func (t *ACLListStorageBuilder) ID() (string, error) {
return t.id, nil
}
func (t *ACLListStorageBuilder) GetRawRecords() []*aclpb.RawRecord {
func (t *ACLListStorageBuilder) GetRawRecords() []*aclpb.RawACLRecord {
return t.rawRecords
}
@ -132,7 +132,7 @@ func (t *ACLListStorageBuilder) Parse(tree *YMLList) {
t.createHeaderAndId()
}
func (t *ACLListStorageBuilder) parseRecord(rec *Record, prevId string) *aclpb.Record {
func (t *ACLListStorageBuilder) parseRecord(rec *Record, prevId string) *aclpb.ACLRecord {
k := t.keychain.GetKey(rec.ReadKey).(*SymKey)
var aclChangeContents []*aclpb.ACLChangeACLContentValue
for _, ch := range rec.AclChanges {
@ -144,7 +144,7 @@ func (t *ACLListStorageBuilder) parseRecord(rec *Record, prevId string) *aclpb.R
}
bytes, _ := data.Marshal()
return &aclpb.Record{
return &aclpb.ACLRecord{
PrevId: prevId,
Identity: t.keychain.GetIdentity(rec.Identity),
Data: bytes,
@ -163,7 +163,7 @@ func (t *ACLListStorageBuilder) parseACLChange(ch *ACLChange) (convCh *aclpb.ACL
convCh = &aclpb.ACLChangeACLContentValue{
Value: &aclpb.ACLChangeACLContentValueValueOfUserAdd{
UserAdd: &aclpb.ACLChangeUserAdd{
UserAdd: &aclpb.ACLUserPermissionsAdd{
Identity: t.keychain.GetIdentity(add.Identity),
EncryptionKey: rawKey,
EncryptedReadKeys: t.encryptReadKeys(add.EncryptedReadKeys, encKey),
@ -187,7 +187,7 @@ func (t *ACLListStorageBuilder) parseACLChange(ch *ACLChange) (convCh *aclpb.ACL
convCh = &aclpb.ACLChangeACLContentValue{
Value: &aclpb.ACLChangeACLContentValueValueOfUserJoin{
UserJoin: &aclpb.ACLChangeUserJoin{
UserJoin: &aclpb.ACLUserPermissionsJoin{
Identity: t.keychain.GetIdentity(join.Identity),
EncryptionKey: rawKey,
AcceptSignature: signature,
@ -205,7 +205,7 @@ func (t *ACLListStorageBuilder) parseACLChange(ch *ACLChange) (convCh *aclpb.ACL
convCh = &aclpb.ACLChangeACLContentValue{
Value: &aclpb.ACLChangeACLContentValueValueOfUserInvite{
UserInvite: &aclpb.ACLChangeUserInvite{
UserInvite: &aclpb.ACLUserPermissionsInvite{
AcceptPublicKey: rawAcceptKey,
EncryptPublicKey: rawEncKey,
EncryptedReadKeys: t.encryptReadKeys(invite.EncryptedReadKeys, encKey),
@ -219,7 +219,7 @@ func (t *ACLListStorageBuilder) parseACLChange(ch *ACLChange) (convCh *aclpb.ACL
convCh = &aclpb.ACLChangeACLContentValue{
Value: &aclpb.ACLChangeACLContentValueValueOfUserConfirm{
UserConfirm: &aclpb.ACLChangeUserConfirm{
UserConfirm: &aclpb.ACLUserPermissionsConfirm{
Identity: t.keychain.GetIdentity(confirm.Identity),
UserAddId: confirm.UserAddId,
},
@ -230,7 +230,7 @@ func (t *ACLListStorageBuilder) parseACLChange(ch *ACLChange) (convCh *aclpb.ACL
convCh = &aclpb.ACLChangeACLContentValue{
Value: &aclpb.ACLChangeACLContentValueValueOfUserPermissionChange{
UserPermissionChange: &aclpb.ACLChangeUserPermissionChange{
UserPermissionChange: &aclpb.ACLUserPermissionsPermissionChange{
Identity: t.keychain.GetIdentity(permissionChange.Identity),
Permissions: t.convertPermission(permissionChange.Permission),
},
@ -259,7 +259,7 @@ func (t *ACLListStorageBuilder) parseACLChange(ch *ACLChange) (convCh *aclpb.ACL
convCh = &aclpb.ACLChangeACLContentValue{
Value: &aclpb.ACLChangeACLContentValueValueOfUserRemove{
UserRemove: &aclpb.ACLChangeUserRemove{
UserRemove: &aclpb.ACLUserPermissionsRemove{
Identity: t.keychain.GetIdentity(remove.RemovedIdentity),
ReadKeyReplaces: replaces,
},
@ -286,7 +286,7 @@ func (t *ACLListStorageBuilder) encryptReadKeys(keys []string, encKey encryption
return
}
func (t *ACLListStorageBuilder) convertPermission(perm string) aclpb.ACLChangeUserPermissions {
func (t *ACLListStorageBuilder) convertPermission(perm string) aclpb.ACLUserPermissions {
switch perm {
case "admin":
return aclpb.ACLChange_Admin
@ -299,7 +299,7 @@ func (t *ACLListStorageBuilder) convertPermission(perm string) aclpb.ACLChangeUs
}
}
func (t *ACLListStorageBuilder) traverseFromHead(f func(rec *aclpb.Record, id string) error) (err error) {
func (t *ACLListStorageBuilder) traverseFromHead(f func(rec *aclpb.ACLRecord, id string) error) (err error) {
for i := len(t.records) - 1; i >= 0; i-- {
err = f(t.records[i], t.rawRecords[i].Id)
if err != nil {

View File

@ -33,7 +33,7 @@ func (t *ACLListStorageBuilder) Graph() (string, error) {
graph.SetDir(true)
var nodes = make(map[string]struct{})
var addNodes = func(r *aclpb.Record, id string) error {
var addNodes = func(r *aclpb.ACLRecord, id string) error {
style := "solid"
var chSymbs []string
@ -92,7 +92,7 @@ func (t *ACLListStorageBuilder) Graph() (string, error) {
return nil
}
var addLinks = func(r *aclpb.Record, id string) error {
var addLinks = func(r *aclpb.ACLRecord, id string) error {
if r.PrevId == "" {
return nil
}

View File

@ -58,24 +58,24 @@ func (m *PlainTextChange) XXX_DiscardUnknown() {
var xxx_messageInfo_PlainTextChange proto.InternalMessageInfo
type PlainTextChangeContent struct {
type PlainTextChange_Content struct {
// Types that are valid to be assigned to Value:
// *PlainTextChangeContentValueOfTextAppend
Value IsPlainTextChangeContentValue `protobuf_oneof:"value"`
// *PlainTextChange_Content_TextAppend
Value isPlainTextChange_Content_Value `protobuf_oneof:"value"`
}
func (m *PlainTextChangeContent) Reset() { *m = PlainTextChangeContent{} }
func (m *PlainTextChangeContent) String() string { return proto.CompactTextString(m) }
func (*PlainTextChangeContent) ProtoMessage() {}
func (*PlainTextChangeContent) Descriptor() ([]byte, []int) {
func (m *PlainTextChange_Content) Reset() { *m = PlainTextChange_Content{} }
func (m *PlainTextChange_Content) String() string { return proto.CompactTextString(m) }
func (*PlainTextChange_Content) ProtoMessage() {}
func (*PlainTextChange_Content) Descriptor() ([]byte, []int) {
return fileDescriptor_37f33c266ada4318, []int{0, 0}
}
func (m *PlainTextChangeContent) XXX_Unmarshal(b []byte) error {
func (m *PlainTextChange_Content) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *PlainTextChangeContent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
func (m *PlainTextChange_Content) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_PlainTextChangeContent.Marshal(b, m, deterministic)
return xxx_messageInfo_PlainTextChange_Content.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
@ -85,67 +85,67 @@ func (m *PlainTextChangeContent) XXX_Marshal(b []byte, deterministic bool) ([]by
return b[:n], nil
}
}
func (m *PlainTextChangeContent) XXX_Merge(src proto.Message) {
xxx_messageInfo_PlainTextChangeContent.Merge(m, src)
func (m *PlainTextChange_Content) XXX_Merge(src proto.Message) {
xxx_messageInfo_PlainTextChange_Content.Merge(m, src)
}
func (m *PlainTextChangeContent) XXX_Size() int {
func (m *PlainTextChange_Content) XXX_Size() int {
return m.Size()
}
func (m *PlainTextChangeContent) XXX_DiscardUnknown() {
xxx_messageInfo_PlainTextChangeContent.DiscardUnknown(m)
func (m *PlainTextChange_Content) XXX_DiscardUnknown() {
xxx_messageInfo_PlainTextChange_Content.DiscardUnknown(m)
}
var xxx_messageInfo_PlainTextChangeContent proto.InternalMessageInfo
var xxx_messageInfo_PlainTextChange_Content proto.InternalMessageInfo
type IsPlainTextChangeContentValue interface {
IsPlainTextChangeContentValue()
type isPlainTextChange_Content_Value interface {
isPlainTextChange_Content_Value()
MarshalTo([]byte) (int, error)
Size() int
}
type PlainTextChangeContentValueOfTextAppend struct {
TextAppend *PlainTextChangeTextAppend `protobuf:"bytes,1,opt,name=textAppend,proto3,oneof" json:"textAppend,omitempty"`
type PlainTextChange_Content_TextAppend struct {
TextAppend *PlainTextChange_TextAppend `protobuf:"bytes,1,opt,name=textAppend,proto3,oneof" json:"textAppend,omitempty"`
}
func (*PlainTextChangeContentValueOfTextAppend) IsPlainTextChangeContentValue() {}
func (*PlainTextChange_Content_TextAppend) isPlainTextChange_Content_Value() {}
func (m *PlainTextChangeContent) GetValue() IsPlainTextChangeContentValue {
func (m *PlainTextChange_Content) GetValue() isPlainTextChange_Content_Value {
if m != nil {
return m.Value
}
return nil
}
func (m *PlainTextChangeContent) GetTextAppend() *PlainTextChangeTextAppend {
if x, ok := m.GetValue().(*PlainTextChangeContentValueOfTextAppend); ok {
func (m *PlainTextChange_Content) GetTextAppend() *PlainTextChange_TextAppend {
if x, ok := m.GetValue().(*PlainTextChange_Content_TextAppend); ok {
return x.TextAppend
}
return nil
}
// XXX_OneofWrappers is for the internal use of the proto package.
func (*PlainTextChangeContent) XXX_OneofWrappers() []interface{} {
func (*PlainTextChange_Content) XXX_OneofWrappers() []interface{} {
return []interface{}{
(*PlainTextChangeContentValueOfTextAppend)(nil),
(*PlainTextChange_Content_TextAppend)(nil),
}
}
type PlainTextChangeTextAppend struct {
type PlainTextChange_TextAppend struct {
Text string `protobuf:"bytes,1,opt,name=text,proto3" json:"text,omitempty"`
}
func (m *PlainTextChangeTextAppend) Reset() { *m = PlainTextChangeTextAppend{} }
func (m *PlainTextChangeTextAppend) String() string { return proto.CompactTextString(m) }
func (*PlainTextChangeTextAppend) ProtoMessage() {}
func (*PlainTextChangeTextAppend) Descriptor() ([]byte, []int) {
func (m *PlainTextChange_TextAppend) Reset() { *m = PlainTextChange_TextAppend{} }
func (m *PlainTextChange_TextAppend) String() string { return proto.CompactTextString(m) }
func (*PlainTextChange_TextAppend) ProtoMessage() {}
func (*PlainTextChange_TextAppend) Descriptor() ([]byte, []int) {
return fileDescriptor_37f33c266ada4318, []int{0, 1}
}
func (m *PlainTextChangeTextAppend) XXX_Unmarshal(b []byte) error {
func (m *PlainTextChange_TextAppend) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *PlainTextChangeTextAppend) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
func (m *PlainTextChange_TextAppend) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_PlainTextChangeTextAppend.Marshal(b, m, deterministic)
return xxx_messageInfo_PlainTextChange_TextAppend.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
@ -155,41 +155,41 @@ func (m *PlainTextChangeTextAppend) XXX_Marshal(b []byte, deterministic bool) ([
return b[:n], nil
}
}
func (m *PlainTextChangeTextAppend) XXX_Merge(src proto.Message) {
xxx_messageInfo_PlainTextChangeTextAppend.Merge(m, src)
func (m *PlainTextChange_TextAppend) XXX_Merge(src proto.Message) {
xxx_messageInfo_PlainTextChange_TextAppend.Merge(m, src)
}
func (m *PlainTextChangeTextAppend) XXX_Size() int {
func (m *PlainTextChange_TextAppend) XXX_Size() int {
return m.Size()
}
func (m *PlainTextChangeTextAppend) XXX_DiscardUnknown() {
xxx_messageInfo_PlainTextChangeTextAppend.DiscardUnknown(m)
func (m *PlainTextChange_TextAppend) XXX_DiscardUnknown() {
xxx_messageInfo_PlainTextChange_TextAppend.DiscardUnknown(m)
}
var xxx_messageInfo_PlainTextChangeTextAppend proto.InternalMessageInfo
var xxx_messageInfo_PlainTextChange_TextAppend proto.InternalMessageInfo
func (m *PlainTextChangeTextAppend) GetText() string {
func (m *PlainTextChange_TextAppend) GetText() string {
if m != nil {
return m.Text
}
return ""
}
type PlainTextChangeSnapshot struct {
type PlainTextChange_Snapshot struct {
Text string `protobuf:"bytes,1,opt,name=text,proto3" json:"text,omitempty"`
}
func (m *PlainTextChangeSnapshot) Reset() { *m = PlainTextChangeSnapshot{} }
func (m *PlainTextChangeSnapshot) String() string { return proto.CompactTextString(m) }
func (*PlainTextChangeSnapshot) ProtoMessage() {}
func (*PlainTextChangeSnapshot) Descriptor() ([]byte, []int) {
func (m *PlainTextChange_Snapshot) Reset() { *m = PlainTextChange_Snapshot{} }
func (m *PlainTextChange_Snapshot) String() string { return proto.CompactTextString(m) }
func (*PlainTextChange_Snapshot) ProtoMessage() {}
func (*PlainTextChange_Snapshot) Descriptor() ([]byte, []int) {
return fileDescriptor_37f33c266ada4318, []int{0, 2}
}
func (m *PlainTextChangeSnapshot) XXX_Unmarshal(b []byte) error {
func (m *PlainTextChange_Snapshot) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *PlainTextChangeSnapshot) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
func (m *PlainTextChange_Snapshot) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_PlainTextChangeSnapshot.Marshal(b, m, deterministic)
return xxx_messageInfo_PlainTextChange_Snapshot.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
@ -199,42 +199,42 @@ func (m *PlainTextChangeSnapshot) XXX_Marshal(b []byte, deterministic bool) ([]b
return b[:n], nil
}
}
func (m *PlainTextChangeSnapshot) XXX_Merge(src proto.Message) {
xxx_messageInfo_PlainTextChangeSnapshot.Merge(m, src)
func (m *PlainTextChange_Snapshot) XXX_Merge(src proto.Message) {
xxx_messageInfo_PlainTextChange_Snapshot.Merge(m, src)
}
func (m *PlainTextChangeSnapshot) XXX_Size() int {
func (m *PlainTextChange_Snapshot) XXX_Size() int {
return m.Size()
}
func (m *PlainTextChangeSnapshot) XXX_DiscardUnknown() {
xxx_messageInfo_PlainTextChangeSnapshot.DiscardUnknown(m)
func (m *PlainTextChange_Snapshot) XXX_DiscardUnknown() {
xxx_messageInfo_PlainTextChange_Snapshot.DiscardUnknown(m)
}
var xxx_messageInfo_PlainTextChangeSnapshot proto.InternalMessageInfo
var xxx_messageInfo_PlainTextChange_Snapshot proto.InternalMessageInfo
func (m *PlainTextChangeSnapshot) GetText() string {
func (m *PlainTextChange_Snapshot) GetText() string {
if m != nil {
return m.Text
}
return ""
}
type PlainTextChangeData struct {
Content []*PlainTextChangeContent `protobuf:"bytes,1,rep,name=content,proto3" json:"content,omitempty"`
Snapshot *PlainTextChangeSnapshot `protobuf:"bytes,2,opt,name=snapshot,proto3" json:"snapshot,omitempty"`
type PlainTextChange_Data struct {
Content []*PlainTextChange_Content `protobuf:"bytes,1,rep,name=content,proto3" json:"content,omitempty"`
Snapshot *PlainTextChange_Snapshot `protobuf:"bytes,2,opt,name=snapshot,proto3" json:"snapshot,omitempty"`
}
func (m *PlainTextChangeData) Reset() { *m = PlainTextChangeData{} }
func (m *PlainTextChangeData) String() string { return proto.CompactTextString(m) }
func (*PlainTextChangeData) ProtoMessage() {}
func (*PlainTextChangeData) Descriptor() ([]byte, []int) {
func (m *PlainTextChange_Data) Reset() { *m = PlainTextChange_Data{} }
func (m *PlainTextChange_Data) String() string { return proto.CompactTextString(m) }
func (*PlainTextChange_Data) ProtoMessage() {}
func (*PlainTextChange_Data) Descriptor() ([]byte, []int) {
return fileDescriptor_37f33c266ada4318, []int{0, 3}
}
func (m *PlainTextChangeData) XXX_Unmarshal(b []byte) error {
func (m *PlainTextChange_Data) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *PlainTextChangeData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
func (m *PlainTextChange_Data) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_PlainTextChangeData.Marshal(b, m, deterministic)
return xxx_messageInfo_PlainTextChange_Data.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
@ -244,26 +244,26 @@ func (m *PlainTextChangeData) XXX_Marshal(b []byte, deterministic bool) ([]byte,
return b[:n], nil
}
}
func (m *PlainTextChangeData) XXX_Merge(src proto.Message) {
xxx_messageInfo_PlainTextChangeData.Merge(m, src)
func (m *PlainTextChange_Data) XXX_Merge(src proto.Message) {
xxx_messageInfo_PlainTextChange_Data.Merge(m, src)
}
func (m *PlainTextChangeData) XXX_Size() int {
func (m *PlainTextChange_Data) XXX_Size() int {
return m.Size()
}
func (m *PlainTextChangeData) XXX_DiscardUnknown() {
xxx_messageInfo_PlainTextChangeData.DiscardUnknown(m)
func (m *PlainTextChange_Data) XXX_DiscardUnknown() {
xxx_messageInfo_PlainTextChange_Data.DiscardUnknown(m)
}
var xxx_messageInfo_PlainTextChangeData proto.InternalMessageInfo
var xxx_messageInfo_PlainTextChange_Data proto.InternalMessageInfo
func (m *PlainTextChangeData) GetContent() []*PlainTextChangeContent {
func (m *PlainTextChange_Data) GetContent() []*PlainTextChange_Content {
if m != nil {
return m.Content
}
return nil
}
func (m *PlainTextChangeData) GetSnapshot() *PlainTextChangeSnapshot {
func (m *PlainTextChange_Data) GetSnapshot() *PlainTextChange_Snapshot {
if m != nil {
return m.Snapshot
}
@ -272,10 +272,10 @@ func (m *PlainTextChangeData) GetSnapshot() *PlainTextChangeSnapshot {
func init() {
proto.RegisterType((*PlainTextChange)(nil), "anytype.PlainTextChange")
proto.RegisterType((*PlainTextChangeContent)(nil), "anytype.PlainTextChange.Content")
proto.RegisterType((*PlainTextChangeTextAppend)(nil), "anytype.PlainTextChange.TextAppend")
proto.RegisterType((*PlainTextChangeSnapshot)(nil), "anytype.PlainTextChange.Snapshot")
proto.RegisterType((*PlainTextChangeData)(nil), "anytype.PlainTextChange.Data")
proto.RegisterType((*PlainTextChange_Content)(nil), "anytype.PlainTextChange.Content")
proto.RegisterType((*PlainTextChange_TextAppend)(nil), "anytype.PlainTextChange.TextAppend")
proto.RegisterType((*PlainTextChange_Snapshot)(nil), "anytype.PlainTextChange.Snapshot")
proto.RegisterType((*PlainTextChange_Data)(nil), "anytype.PlainTextChange.Data")
}
func init() {
@ -326,7 +326,7 @@ func (m *PlainTextChange) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
func (m *PlainTextChangeContent) Marshal() (dAtA []byte, err error) {
func (m *PlainTextChange_Content) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
@ -336,12 +336,12 @@ func (m *PlainTextChangeContent) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil
}
func (m *PlainTextChangeContent) MarshalTo(dAtA []byte) (int, error) {
func (m *PlainTextChange_Content) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *PlainTextChangeContent) MarshalToSizedBuffer(dAtA []byte) (int, error) {
func (m *PlainTextChange_Content) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
@ -358,12 +358,12 @@ func (m *PlainTextChangeContent) MarshalToSizedBuffer(dAtA []byte) (int, error)
return len(dAtA) - i, nil
}
func (m *PlainTextChangeContentValueOfTextAppend) MarshalTo(dAtA []byte) (int, error) {
func (m *PlainTextChange_Content_TextAppend) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *PlainTextChangeContentValueOfTextAppend) MarshalToSizedBuffer(dAtA []byte) (int, error) {
func (m *PlainTextChange_Content_TextAppend) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
if m.TextAppend != nil {
{
@ -379,7 +379,7 @@ func (m *PlainTextChangeContentValueOfTextAppend) MarshalToSizedBuffer(dAtA []by
}
return len(dAtA) - i, nil
}
func (m *PlainTextChangeTextAppend) Marshal() (dAtA []byte, err error) {
func (m *PlainTextChange_TextAppend) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
@ -389,12 +389,12 @@ func (m *PlainTextChangeTextAppend) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil
}
func (m *PlainTextChangeTextAppend) MarshalTo(dAtA []byte) (int, error) {
func (m *PlainTextChange_TextAppend) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *PlainTextChangeTextAppend) MarshalToSizedBuffer(dAtA []byte) (int, error) {
func (m *PlainTextChange_TextAppend) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
@ -409,7 +409,7 @@ func (m *PlainTextChangeTextAppend) MarshalToSizedBuffer(dAtA []byte) (int, erro
return len(dAtA) - i, nil
}
func (m *PlainTextChangeSnapshot) Marshal() (dAtA []byte, err error) {
func (m *PlainTextChange_Snapshot) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
@ -419,12 +419,12 @@ func (m *PlainTextChangeSnapshot) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil
}
func (m *PlainTextChangeSnapshot) MarshalTo(dAtA []byte) (int, error) {
func (m *PlainTextChange_Snapshot) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *PlainTextChangeSnapshot) MarshalToSizedBuffer(dAtA []byte) (int, error) {
func (m *PlainTextChange_Snapshot) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
@ -439,7 +439,7 @@ func (m *PlainTextChangeSnapshot) MarshalToSizedBuffer(dAtA []byte) (int, error)
return len(dAtA) - i, nil
}
func (m *PlainTextChangeData) Marshal() (dAtA []byte, err error) {
func (m *PlainTextChange_Data) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
@ -449,12 +449,12 @@ func (m *PlainTextChangeData) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil
}
func (m *PlainTextChangeData) MarshalTo(dAtA []byte) (int, error) {
func (m *PlainTextChange_Data) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *PlainTextChangeData) MarshalToSizedBuffer(dAtA []byte) (int, error) {
func (m *PlainTextChange_Data) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
@ -508,7 +508,7 @@ func (m *PlainTextChange) Size() (n int) {
return n
}
func (m *PlainTextChangeContent) Size() (n int) {
func (m *PlainTextChange_Content) Size() (n int) {
if m == nil {
return 0
}
@ -520,7 +520,7 @@ func (m *PlainTextChangeContent) Size() (n int) {
return n
}
func (m *PlainTextChangeContentValueOfTextAppend) Size() (n int) {
func (m *PlainTextChange_Content_TextAppend) Size() (n int) {
if m == nil {
return 0
}
@ -532,7 +532,7 @@ func (m *PlainTextChangeContentValueOfTextAppend) Size() (n int) {
}
return n
}
func (m *PlainTextChangeTextAppend) Size() (n int) {
func (m *PlainTextChange_TextAppend) Size() (n int) {
if m == nil {
return 0
}
@ -545,7 +545,7 @@ func (m *PlainTextChangeTextAppend) Size() (n int) {
return n
}
func (m *PlainTextChangeSnapshot) Size() (n int) {
func (m *PlainTextChange_Snapshot) Size() (n int) {
if m == nil {
return 0
}
@ -558,7 +558,7 @@ func (m *PlainTextChangeSnapshot) Size() (n int) {
return n
}
func (m *PlainTextChangeData) Size() (n int) {
func (m *PlainTextChange_Data) Size() (n int) {
if m == nil {
return 0
}
@ -633,7 +633,7 @@ func (m *PlainTextChange) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *PlainTextChangeContent) Unmarshal(dAtA []byte) error {
func (m *PlainTextChange_Content) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
@ -691,11 +691,11 @@ func (m *PlainTextChangeContent) Unmarshal(dAtA []byte) error {
if postIndex > l {
return io.ErrUnexpectedEOF
}
v := &PlainTextChangeTextAppend{}
v := &PlainTextChange_TextAppend{}
if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
m.Value = &PlainTextChangeContentValueOfTextAppend{v}
m.Value = &PlainTextChange_Content_TextAppend{v}
iNdEx = postIndex
default:
iNdEx = preIndex
@ -718,7 +718,7 @@ func (m *PlainTextChangeContent) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *PlainTextChangeTextAppend) Unmarshal(dAtA []byte) error {
func (m *PlainTextChange_TextAppend) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
@ -800,7 +800,7 @@ func (m *PlainTextChangeTextAppend) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *PlainTextChangeSnapshot) Unmarshal(dAtA []byte) error {
func (m *PlainTextChange_Snapshot) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
@ -882,7 +882,7 @@ func (m *PlainTextChangeSnapshot) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *PlainTextChangeData) Unmarshal(dAtA []byte) error {
func (m *PlainTextChange_Data) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
@ -940,7 +940,7 @@ func (m *PlainTextChangeData) Unmarshal(dAtA []byte) error {
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Content = append(m.Content, &PlainTextChangeContent{})
m.Content = append(m.Content, &PlainTextChange_Content{})
if err := m.Content[len(m.Content)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
@ -975,7 +975,7 @@ func (m *PlainTextChangeData) Unmarshal(dAtA []byte) error {
return io.ErrUnexpectedEOF
}
if m.Snapshot == nil {
m.Snapshot = &PlainTextChangeSnapshot{}
m.Snapshot = &PlainTextChange_Snapshot{}
}
if err := m.Snapshot.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err

View File

@ -16,7 +16,7 @@ var (
type ChangeContent struct {
ChangesData proto.Marshaler
ACLData *aclpb.ACLChangeACLData
ACLData *aclpb.ACLData
Id string // TODO: this is just for testing, because id should be created automatically from content
}
@ -34,8 +34,9 @@ type Change struct {
visited bool
branchesFinished bool
Content *aclpb.Change
Sign []byte
Content *aclpb.TreeChange
Identity string
Sign []byte
}
func (ch *Change) ProtoChange() proto.Marshaler {
@ -56,7 +57,7 @@ func (ch *Change) DecryptContents(key *symmetric.Key) error {
return nil
}
func NewChange(id string, ch *aclpb.Change, signature []byte) *Change {
func NewChange(id string, ch *aclpb.TreeChange, signature []byte) *Change {
return &Change{
Next: nil,
PreviousIds: ch.TreeHeadIds,
@ -64,6 +65,7 @@ func NewChange(id string, ch *aclpb.Change, signature []byte) *Change {
Content: ch,
SnapshotId: ch.SnapshotBaseId,
IsSnapshot: ch.IsSnapshot,
Identity: string(ch.Identity),
Sign: signature,
}
}

View File

@ -1,6 +1,7 @@
package tree
import (
"errors"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/common"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/cid"
@ -10,25 +11,24 @@ import (
"time"
)
const componentBuilder = "tree.changebuilder"
var ErrEmptyChange = errors.New("change payload should not be empty")
type BuilderContent struct {
treeHeadIds []string
aclHeadId string
snapshotBaseId string
currentReadKeyHash uint64
identity string
identity []byte
isSnapshot bool
signingKey signingkey.PrivKey
readKey *symmetric.Key
content proto.Marshaler
content []byte
}
type ChangeBuilder interface {
ConvertFromRaw(rawChange *aclpb.RawChange) (ch *Change, err error)
ConvertFromRawAndVerify(rawChange *aclpb.RawChange) (ch *Change, err error)
BuildContent(payload BuilderContent) (ch *Change, raw *aclpb.RawChange, err error)
BuildRaw(ch *Change) (*aclpb.RawChange, error)
ConvertFromRaw(rawIdChange *aclpb.RawTreeChangeWithId, verify bool) (ch *Change, err error)
BuildContent(payload BuilderContent) (ch *Change, raw *aclpb.RawTreeChangeWithId, err error)
BuildRaw(ch *Change) (*aclpb.RawTreeChangeWithId, error)
}
type changeBuilder struct {
@ -39,49 +39,55 @@ func newChangeBuilder(keys *common.Keychain) ChangeBuilder {
return &changeBuilder{keys: keys}
}
func (c *changeBuilder) ConvertFromRaw(rawChange *aclpb.RawChange) (ch *Change, err error) {
unmarshalled := &aclpb.Change{}
err = proto.Unmarshal(rawChange.Payload, unmarshalled)
if err != nil {
return nil, err
func (c *changeBuilder) ConvertFromRaw(rawIdChange *aclpb.RawTreeChangeWithId, verify bool) (ch *Change, err error) {
if rawIdChange.GetRawChange() == nil {
err = ErrEmptyChange
return
}
ch = NewChange(rawChange.Id, unmarshalled, rawChange.Signature)
if verify {
// verifying ID
if !cid.VerifyCID(rawIdChange.RawChange, rawIdChange.Id) {
err = ErrIncorrectCID
return
}
}
raw := &aclpb.RawTreeChange{}
err = proto.Unmarshal(rawIdChange.GetRawChange(), raw)
if err != nil {
return
}
if verify {
identityKey, err := c.keys.GetOrAdd(ch.Identity)
if err != nil {
return
}
// verifying signature
res, err := identityKey.Verify(raw.Payload, raw.Signature)
if err != nil {
return
}
if !res {
err = ErrIncorrectSignature
return
}
}
unmarshalled := &aclpb.TreeChange{}
err = proto.Unmarshal(raw.Payload, unmarshalled)
if err != nil {
return
}
ch = NewChange(rawIdChange.Id, unmarshalled, raw.Signature)
return
}
func (c *changeBuilder) ConvertFromRawAndVerify(rawChange *aclpb.RawChange) (ch *Change, err error) {
unmarshalled := &aclpb.Change{}
ch, err = c.ConvertFromRaw(rawChange)
if err != nil {
return nil, err
}
identityKey, err := c.keys.GetOrAdd(unmarshalled.Identity)
if err != nil {
return
}
// verifying signature
res, err := identityKey.Verify(rawChange.Payload, rawChange.Signature)
if err != nil {
return
}
if !res {
err = ErrIncorrectSignature
return
}
// verifying ID
if !cid.VerifyCID(rawChange.Payload, rawChange.Id) {
err = ErrIncorrectCID
}
return
}
func (c *changeBuilder) BuildContent(payload BuilderContent) (ch *Change, raw *aclpb.RawChange, err error) {
aclChange := &aclpb.Change{
func (c *changeBuilder) BuildContent(payload BuilderContent) (ch *Change, rawIdChange *aclpb.RawTreeChangeWithId, err error) {
change := &aclpb.TreeChange{
TreeHeadIds: payload.treeHeadIds,
AclHeadId: payload.aclHeadId,
SnapshotBaseId: payload.snapshotBaseId,
@ -90,53 +96,65 @@ func (c *changeBuilder) BuildContent(payload BuilderContent) (ch *Change, raw *a
Identity: payload.identity,
IsSnapshot: payload.isSnapshot,
}
marshalledData, err := payload.content.Marshal()
encrypted, err := payload.readKey.Encrypt(payload.content)
if err != nil {
return
}
change.ChangesData = encrypted
marshalledChange, err := proto.Marshal(change)
if err != nil {
return
}
encrypted, err := payload.readKey.Encrypt(marshalledData)
if err != nil {
return
}
aclChange.ChangesData = encrypted
fullMarshalledChange, err := proto.Marshal(aclChange)
signature, err := payload.signingKey.Sign(marshalledChange)
if err != nil {
return
}
signature, err := payload.signingKey.Sign(fullMarshalledChange)
raw := &aclpb.RawTreeChange{
Payload: marshalledChange,
Signature: signature,
}
marshalledRawChange, err := proto.Marshal(raw)
if err != nil {
return
}
id, err := cid.NewCIDFromBytes(fullMarshalledChange)
id, err := cid.NewCIDFromBytes(marshalledRawChange)
if err != nil {
return
}
ch = NewChange(id, aclChange, signature)
ch = NewChange(id, change, signature)
ch.ParsedModel = payload.content
raw = &aclpb.RawChange{
Payload: fullMarshalledChange,
Signature: signature,
rawIdChange = &aclpb.RawTreeChangeWithId{
RawChange: marshalledRawChange,
Id: id,
}
return
}
func (c *changeBuilder) BuildRaw(ch *Change) (raw *aclpb.RawChange, err error) {
func (c *changeBuilder) BuildRaw(ch *Change) (raw *aclpb.RawTreeChangeWithId, err error) {
var marshalled []byte
marshalled, err = ch.Content.Marshal()
if err != nil {
return
}
raw = &aclpb.RawChange{
marshalledRawChange, err := proto.Marshal(&aclpb.RawTreeChange{
Payload: marshalled,
Signature: ch.Signature(),
Signature: ch.Sign,
})
if err != nil {
return
}
raw = &aclpb.RawTreeChangeWithId{
RawChange: marshalledRawChange,
Id: ch.Id,
}
return

View File

@ -48,7 +48,7 @@ func (v *objectTreeValidator) validateChange(tree *Tree, aclList list.ACLList, c
return
}
if perm.Permission != aclpb.ACLChange_Writer && perm.Permission != aclpb.ACLChange_Admin {
if perm.Permission != aclpb.ACLUserPermissions_Writer && perm.Permission != aclpb.ACLUserPermissions_Admin {
err = list.ErrInsufficientPermissions
return
}

View File

@ -8,8 +8,6 @@ import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/list"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/storage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/symmetric"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice"
"go.uber.org/zap"
"sync"
)
@ -34,7 +32,7 @@ type AddResultSummary int
type AddResult struct {
OldHeads []string
Heads []string
Added []*aclpb.RawChange
Added []*aclpb.RawTreeChangeWithId
Mode Mode
}
@ -46,7 +44,7 @@ type ObjectTree interface {
RWLocker
ID() string
Header() *aclpb.Header
Header() *aclpb.TreeHeader
Heads() []string
Root() *Change
HasChange(string) bool
@ -55,13 +53,13 @@ type ObjectTree interface {
IterateFrom(id string, convert ChangeConvertFunc, iterate ChangeIterateFunc) error
SnapshotPath() []string
ChangesAfterCommonSnapshot(snapshotPath, heads []string) ([]*aclpb.RawChange, error)
ChangesAfterCommonSnapshot(snapshotPath, heads []string) ([]*aclpb.RawTreeChangeWithId, error)
Storage() storage.TreeStorage
DebugDump() (string, error)
AddContent(ctx context.Context, content SignableChangeContent) (*aclpb.RawChange, error)
AddRawChanges(ctx context.Context, changes ...*aclpb.RawChange) (AddResult, error)
AddContent(ctx context.Context, content SignableChangeContent) (*aclpb.RawTreeChangeWithId, error)
AddRawChanges(ctx context.Context, changes ...*aclpb.RawTreeChangeWithId) (AddResult, error)
Close() error
}
@ -76,13 +74,13 @@ type objectTree struct {
aclList list.ACLList
id string
header *aclpb.Header
header *aclpb.TreeHeader
tree *Tree
keys map[uint64]*symmetric.Key
// buffers
difSnapshotBuf []*aclpb.RawChange
difSnapshotBuf []*aclpb.RawTreeChangeWithId
tmpChangesBuf []*Change
newSnapshotsBuf []*Change
notSeenIdxBuf []int
@ -121,65 +119,6 @@ func defaultObjectTreeDeps(
}
}
func buildObjectTree(deps objectTreeDeps) (ObjectTree, error) {
objTree := &objectTree{
treeStorage: deps.treeStorage,
updateListener: deps.updateListener,
treeBuilder: deps.treeBuilder,
validator: deps.validator,
aclList: deps.aclList,
changeBuilder: deps.changeBuilder,
rawChangeLoader: deps.rawChangeLoader,
tree: nil,
keys: make(map[uint64]*symmetric.Key),
tmpChangesBuf: make([]*Change, 0, 10),
difSnapshotBuf: make([]*aclpb.RawChange, 0, 10),
notSeenIdxBuf: make([]int, 0, 10),
newSnapshotsBuf: make([]*Change, 0, 10),
}
err := objTree.rebuildFromStorage(nil)
if err != nil {
return nil, err
}
storageHeads, err := objTree.treeStorage.Heads()
if err != nil {
return nil, err
}
// comparing rebuilt heads with heads in storage
// in theory it can happen that we didn't set heads because the process has crashed
// therefore we want to set them later
if !slice.UnsortedEquals(storageHeads, objTree.tree.Heads()) {
log.With(zap.Strings("storage", storageHeads), zap.Strings("rebuilt", objTree.tree.Heads())).
Errorf("the heads in storage and objTree are different")
err = objTree.treeStorage.SetHeads(objTree.tree.Heads())
if err != nil {
return nil, err
}
}
objTree.id, err = objTree.treeStorage.ID()
if err != nil {
return nil, err
}
objTree.header, err = objTree.treeStorage.Header()
if err != nil {
return nil, err
}
if objTree.updateListener != nil {
objTree.updateListener.Rebuild(objTree)
}
return objTree, nil
}
func BuildObjectTree(treeStorage storage.TreeStorage, listener ObjectTreeUpdateListener, aclList list.ACLList) (ObjectTree, error) {
deps := defaultObjectTreeDeps(treeStorage, listener, aclList)
return buildObjectTree(deps)
}
func (ot *objectTree) rebuildFromStorage(newChanges []*Change) (err error) {
ot.treeBuilder.Reset()
@ -201,7 +140,7 @@ func (ot *objectTree) ID() string {
return ot.id
}
func (ot *objectTree) Header() *aclpb.Header {
func (ot *objectTree) Header() *aclpb.TreeHeader {
return ot.header
}
@ -209,7 +148,7 @@ func (ot *objectTree) Storage() storage.TreeStorage {
return ot.treeStorage
}
func (ot *objectTree) AddContent(ctx context.Context, content SignableChangeContent) (rawChange *aclpb.RawChange, err error) {
func (ot *objectTree) AddContent(ctx context.Context, content SignableChangeContent) (rawChange *aclpb.RawTreeChangeWithId, err error) {
defer func() {
if err == nil && ot.updateListener != nil {
ot.updateListener.Update(ot)
@ -258,12 +197,12 @@ func (ot *objectTree) prepareBuilderContent(content SignableChangeContent) (cnt
isSnapshot: content.IsSnapshot,
signingKey: content.Key,
readKey: readKey,
content: content.Proto,
content: content.Data,
}
return
}
func (ot *objectTree) AddRawChanges(ctx context.Context, rawChanges ...*aclpb.RawChange) (addResult AddResult, err error) {
func (ot *objectTree) AddRawChanges(ctx context.Context, rawChanges ...*aclpb.RawTreeChangeWithId) (addResult AddResult, err error) {
var mode Mode
mode, addResult, err = ot.addRawChanges(ctx, rawChanges...)
if err != nil {
@ -302,7 +241,7 @@ func (ot *objectTree) AddRawChanges(ctx context.Context, rawChanges ...*aclpb.Ra
return
}
func (ot *objectTree) addRawChanges(ctx context.Context, rawChanges ...*aclpb.RawChange) (mode Mode, addResult AddResult, err error) {
func (ot *objectTree) addRawChanges(ctx context.Context, rawChanges ...*aclpb.RawTreeChangeWithId) (mode Mode, addResult AddResult, err error) {
// resetting buffers
ot.tmpChangesBuf = ot.tmpChangesBuf[:0]
ot.notSeenIdxBuf = ot.notSeenIdxBuf[:0]
@ -329,7 +268,7 @@ func (ot *objectTree) addRawChanges(ctx context.Context, rawChanges ...*aclpb.Ra
}
var change *Change
change, err = ot.changeBuilder.ConvertFromRawAndVerify(ch)
change, err = ot.changeBuilder.ConvertFromRaw(ch, true)
if err != nil {
return
}
@ -354,7 +293,7 @@ func (ot *objectTree) addRawChanges(ctx context.Context, rawChanges ...*aclpb.Ra
// returns changes that we added to the tree as attached this round
// they can include not only the changes that were added now,
// but also the changes that were previously in the tree
getAddedChanges := func(toConvert []*Change) (added []*aclpb.RawChange, err error) {
getAddedChanges := func(toConvert []*Change) (added []*aclpb.RawTreeChangeWithId, err error) {
alreadyConverted := make(map[*Change]struct{})
// first we see if we have already unmarshalled those changes
@ -379,7 +318,7 @@ func (ot *objectTree) addRawChanges(ctx context.Context, rawChanges ...*aclpb.Ra
for _, ch := range toConvert {
// if we got some changes that we need to convert to raw
if _, exists := alreadyConverted[ch]; !exists {
var raw *aclpb.RawChange
var raw *aclpb.RawTreeChangeWithId
raw, err = ot.changeBuilder.BuildRaw(ch)
if err != nil {
return
@ -421,7 +360,7 @@ func (ot *objectTree) addRawChanges(ctx context.Context, rawChanges ...*aclpb.Ra
ot.rebuildFromStorage(nil)
return
}
var added []*aclpb.RawChange
var added []*aclpb.RawTreeChangeWithId
added, err = getAddedChanges(nil)
// we shouldn't get any error in this case
if err != nil {
@ -457,7 +396,7 @@ func (ot *objectTree) addRawChanges(ctx context.Context, rawChanges ...*aclpb.Ra
err = ErrHasInvalidChanges
return
}
var added []*aclpb.RawChange
var added []*aclpb.RawTreeChangeWithId
added, err = getAddedChanges(treeChangesAdded)
if err != nil {
// that means that some unattached changes were somehow corrupted in memory
@ -553,7 +492,7 @@ func (ot *objectTree) SnapshotPath() []string {
return path
}
func (ot *objectTree) ChangesAfterCommonSnapshot(theirPath, theirHeads []string) ([]*aclpb.RawChange, error) {
func (ot *objectTree) ChangesAfterCommonSnapshot(theirPath, theirHeads []string) ([]*aclpb.RawTreeChangeWithId, error) {
var (
needFullDocument = len(theirPath) == 0
ourPath = ot.SnapshotPath()
@ -577,11 +516,11 @@ func (ot *objectTree) ChangesAfterCommonSnapshot(theirPath, theirHeads []string)
}
}
func (ot *objectTree) getChangesFromTree(theirHeads []string) (rawChanges []*aclpb.RawChange, err error) {
func (ot *objectTree) getChangesFromTree(theirHeads []string) (rawChanges []*aclpb.RawTreeChangeWithId, err error) {
return ot.rawChangeLoader.LoadFromTree(ot.tree, theirHeads)
}
func (ot *objectTree) getChangesFromDB(commonSnapshot string, theirHeads []string) (rawChanges []*aclpb.RawChange, err error) {
func (ot *objectTree) getChangesFromDB(commonSnapshot string, theirHeads []string) (rawChanges []*aclpb.RawTreeChangeWithId, err error) {
return ot.rawChangeLoader.LoadFromStorage(commonSnapshot, ot.tree.headIds, theirHeads)
}

View File

@ -15,7 +15,7 @@ import (
type mockChangeCreator struct{}
func (c *mockChangeCreator) createRaw(id, aclId, snapshotId string, isSnapshot bool, prevIds ...string) *aclpb.RawChange {
aclChange := &aclpb.Change{
aclChange := &aclpb.TreeChange{
TreeHeadIds: prevIds,
AclHeadId: aclId,
SnapshotBaseId: snapshotId,
@ -23,22 +23,27 @@ func (c *mockChangeCreator) createRaw(id, aclId, snapshotId string, isSnapshot b
IsSnapshot: isSnapshot,
}
res, _ := aclChange.Marshal()
return &aclpb.RawChange{
raw := &aclpb.RawTreeChange{
Payload: res,
Signature: nil,
}
rawMarshalled, _ := raw.Marshal()
return &aclpb.RawTreeChangeWithId{
RawChange: rawMarshalled,
Id: id,
}
}
func (c *mockChangeCreator) createNewTreeStorage(treeId, aclListId, aclHeadId, firstChangeId string) storage.TreeStorage {
firstChange := c.createRaw(firstChangeId, aclHeadId, "", true)
header := &aclpb.Header{
FirstId: firstChangeId,
AclListId: aclListId,
WorkspaceId: "",
DocType: aclpb.Header_DocTree,
header := &aclpb.TreeHeader{
FirstId: firstChangeId,
AclId: aclListId,
TreeHeaderType: aclpb.TreeHeaderType_Object,
}
treeStorage, _ := storage.NewInMemoryTreeStorage(treeId, header, []string{firstChangeId}, []*aclpb.RawChange{firstChange})
treeStorage, _ := storage.NewInMemoryTreeStorage(treeId, header, []string{firstChangeId}, []*aclpb.RawTreeChangeWithId{firstChange})
return treeStorage
}

View File

@ -0,0 +1,161 @@
package tree
import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/list"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/storage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/cid"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/symmetric"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice"
"github.com/gogo/protobuf/proto"
"go.uber.org/zap"
)
type ObjectTreeCreatePayload struct {
AccountData *account.AccountData
HeaderData []byte
ChangeData []byte
TreeType aclpb.TreeHeaderType
}
func BuildObjectTree(treeStorage storage.TreeStorage, listener ObjectTreeUpdateListener, aclList list.ACLList) (ObjectTree, error) {
deps := defaultObjectTreeDeps(treeStorage, listener, aclList)
return buildObjectTree(deps)
}
func CreateObjectTree(
payload ObjectTreeCreatePayload,
listener ObjectTreeUpdateListener,
aclList list.ACLList,
createStorage storage.TreeStorageCreatorFunc) (objTree ObjectTree, err error) {
aclList.RLock()
var (
deps = defaultObjectTreeDeps(nil, listener, aclList)
state = aclList.ACLState()
aclId = aclList.ID()
aclHeadId = aclList.Head().Id
readKeyHash = state.CurrentReadKeyHash()
)
readKey, err := state.CurrentReadKey()
aclList.RUnlock()
if err != nil {
return
}
// create first change
cnt := BuilderContent{
treeHeadIds: nil,
aclHeadId: aclHeadId,
snapshotBaseId: "",
currentReadKeyHash: readKeyHash,
isSnapshot: true,
readKey: readKey,
identity: payload.AccountData.Identity,
signingKey: payload.AccountData.SignKey,
content: payload.ChangeData,
}
_, raw, err := deps.changeBuilder.BuildContent(cnt)
if err != nil {
return
}
// create header
header, id, err := createTreeHeaderAndId(
raw,
payload.TreeType,
aclId,
payload.AccountData.Identity,
payload.HeaderData)
if err != nil {
return
}
// create storage
st, err := createStorage(storage.TreeStorageCreatePayload{
TreeId: id,
Header: header,
Changes: []*aclpb.RawTreeChangeWithId{raw},
Heads: []string{raw.Id},
})
if err != nil {
return
}
deps.treeStorage = st
return buildObjectTree(deps)
}
func buildObjectTree(deps objectTreeDeps) (ObjectTree, error) {
objTree := &objectTree{
treeStorage: deps.treeStorage,
updateListener: deps.updateListener,
treeBuilder: deps.treeBuilder,
validator: deps.validator,
aclList: deps.aclList,
changeBuilder: deps.changeBuilder,
rawChangeLoader: deps.rawChangeLoader,
tree: nil,
keys: make(map[uint64]*symmetric.Key),
tmpChangesBuf: make([]*Change, 0, 10),
difSnapshotBuf: make([]*aclpb.RawTreeChangeWithId, 0, 10),
notSeenIdxBuf: make([]int, 0, 10),
newSnapshotsBuf: make([]*Change, 0, 10),
}
err := objTree.rebuildFromStorage(nil)
if err != nil {
return nil, err
}
storageHeads, err := objTree.treeStorage.Heads()
if err != nil {
return nil, err
}
// comparing rebuilt heads with heads in storage
// in theory it can happen that we didn't set heads because the process has crashed
// therefore we want to set them later
if !slice.UnsortedEquals(storageHeads, objTree.tree.Heads()) {
log.With(zap.Strings("storage", storageHeads), zap.Strings("rebuilt", objTree.tree.Heads())).
Errorf("the heads in storage and objTree are different")
err = objTree.treeStorage.SetHeads(objTree.tree.Heads())
if err != nil {
return nil, err
}
}
objTree.id, err = objTree.treeStorage.ID()
if err != nil {
return nil, err
}
objTree.header, err = objTree.treeStorage.Header()
if err != nil {
return nil, err
}
return objTree, nil
}
func createTreeHeaderAndId(
raw *aclpb.RawTreeChangeWithId,
treeType aclpb.TreeHeaderType,
aclId string,
identity []byte,
headerData []byte) (header *aclpb.TreeHeader, treeId string, err error) {
header = &aclpb.TreeHeader{
FirstId: raw.Id,
TreeHeaderType: treeType,
AclId: aclId,
Identity: identity,
Data: headerData,
}
marshalledHeader, err := proto.Marshal(header)
if err != nil {
return
}
treeId, err = cid.NewCIDFromBytes(marshalledHeader)
return
}

View File

@ -18,7 +18,7 @@ type rawChangeLoader struct {
type rawCacheEntry struct {
change *Change
rawChange *aclpb.RawChange
rawChange *aclpb.RawTreeChangeWithId
position int
}
@ -29,15 +29,15 @@ func newRawChangeLoader(treeStorage storage.TreeStorage, changeBuilder ChangeBui
}
}
func (r *rawChangeLoader) LoadFromTree(t *Tree, breakpoints []string) ([]*aclpb.RawChange, error) {
func (r *rawChangeLoader) LoadFromTree(t *Tree, breakpoints []string) ([]*aclpb.RawTreeChangeWithId, error) {
var stack []*Change
for _, h := range t.headIds {
stack = append(stack, t.attached[h])
}
convert := func(chs []*Change) (rawChanges []*aclpb.RawChange, err error) {
convert := func(chs []*Change) (rawChanges []*aclpb.RawTreeChangeWithId, err error) {
for _, ch := range chs {
var raw *aclpb.RawChange
var raw *aclpb.RawTreeChangeWithId
raw, err = r.changeBuilder.BuildRaw(ch)
if err != nil {
return
@ -95,7 +95,7 @@ func (r *rawChangeLoader) LoadFromTree(t *Tree, breakpoints []string) ([]*aclpb.
return convert(results)
}
func (r *rawChangeLoader) LoadFromStorage(commonSnapshot string, heads, breakpoints []string) ([]*aclpb.RawChange, error) {
func (r *rawChangeLoader) LoadFromStorage(commonSnapshot string, heads, breakpoints []string) ([]*aclpb.RawTreeChangeWithId, error) {
// resetting cache
r.cache = make(map[string]rawCacheEntry)
defer func() {
@ -162,7 +162,7 @@ func (r *rawChangeLoader) LoadFromStorage(commonSnapshot string, heads, breakpoi
// preparing first pass
r.idStack = append(r.idStack, heads...)
var buffer []*aclpb.RawChange
var buffer []*aclpb.RawTreeChangeWithId
rootVisited := dfs(commonSnapshot, heads, 0,
func(counter int, mapExists bool) bool {
@ -203,7 +203,7 @@ func (r *rawChangeLoader) LoadFromStorage(commonSnapshot string, heads, breakpoi
})
// discarding visited
buffer = discardFromSlice(buffer, func(change *aclpb.RawChange) bool {
buffer = discardFromSlice(buffer, func(change *aclpb.RawTreeChangeWithId) bool {
return change == nil
})
@ -219,7 +219,7 @@ func (r *rawChangeLoader) loadEntry(id string) (entry rawCacheEntry, err error)
return
}
change, err := r.changeBuilder.ConvertFromRaw(rawChange)
change, err := r.changeBuilder.ConvertFromRaw(rawChange, false)
if err != nil {
return
}

View File

@ -2,12 +2,11 @@ package tree
import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
"github.com/gogo/protobuf/proto"
)
type SignableChangeContent struct {
Proto proto.Marshaler
Data []byte
Key signingkey.PrivKey
Identity string
Identity []byte
IsSnapshot bool
}

View File

@ -0,0 +1,91 @@
package tests
import (
"bytes"
"math/rand"
"testing"
"time"
)
func BenchmarkHashes(b *testing.B) {
genRandomBytes := func() [][]byte {
var res [][]byte
s := rand.NewSource(time.Now().Unix())
r := rand.New(s)
for i := 0; i < 10000; i++ {
var newBytes []byte
for j := 0; j < 64; j++ {
newBytes = append(newBytes, byte(r.Intn(256)))
}
res = append(res, newBytes)
}
return res
}
makeStrings := func(input [][]byte) []string {
var res []string
for _, bytes := range input {
res = append(res, string(bytes))
}
return res
}
res := genRandomBytes()
stringRes := makeStrings(res)
stringMap := map[string]struct{}{}
b.Run("string bytes hash map write", func(b *testing.B) {
stringMap = map[string]struct{}{}
for i := 0; i < b.N; i++ {
for _, bytes := range res {
stringMap[string(bytes)] = struct{}{}
}
}
b.Run("hash map read", func(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, bytes := range res {
_, _ = stringMap[string(bytes)]
}
}
})
})
b.Run("compare byte slices as strings", func(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, bytes := range res {
if string(bytes) == string(bytes) {
}
}
}
})
b.Run("compare byte slices", func(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, bt := range res {
if bytes.Compare(bt, bt) == 0 {
}
}
}
})
b.Run("compare strings", func(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, st := range stringRes {
if st == st {
}
}
}
})
b.Run("string hash map write", func(b *testing.B) {
stringMap = map[string]struct{}{}
for i := 0; i < b.N; i++ {
for _, str := range stringRes {
stringMap[str] = struct{}{}
}
}
b.Run("hash map read", func(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, str := range stringRes {
_, _ = stringMap[str]
}
}
})
})
}

View File

@ -129,7 +129,7 @@ func (tb *treeBuilder) loadChange(id string) (ch *Change, err error) {
return nil, err
}
ch, err = tb.builder.ConvertFromRawAndVerify(change)
ch, err = tb.builder.ConvertFromRaw(change, true)
if err != nil {
return nil, err
}

View File

@ -1,91 +0,0 @@
package tree
import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/list"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/storage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/cid"
"github.com/gogo/protobuf/proto"
"time"
)
func CreateNewTreeStorage(
acc *account.AccountData,
aclList list.ACLList,
content proto.Marshaler,
create storage.TreeStorageCreatorFunc) (thr storage.TreeStorage, err error) {
state := aclList.ACLState()
change := &aclpb.Change{
AclHeadId: aclList.Head().Id,
CurrentReadKeyHash: state.CurrentReadKeyHash(),
Timestamp: int64(time.Now().Nanosecond()),
Identity: acc.Identity,
IsSnapshot: true,
}
marshalledData, err := content.Marshal()
if err != nil {
return
}
readKey, err := state.CurrentReadKey()
if err != nil {
return
}
encrypted, err := readKey.Encrypt(marshalledData)
if err != nil {
return
}
change.ChangesData = encrypted
fullMarshalledChange, err := proto.Marshal(change)
if err != nil {
return
}
signature, err := acc.SignKey.Sign(fullMarshalledChange)
if err != nil {
return
}
changeId, err := cid.NewCIDFromBytes(fullMarshalledChange)
if err != nil {
return
}
rawChange := &aclpb.RawChange{
Payload: fullMarshalledChange,
Signature: signature,
Id: changeId,
}
header, treeId, err := createTreeHeaderAndId(rawChange, aclpb.Header_DocTree, aclList.ID())
if err != nil {
return
}
return create(storage.TreeStorageCreatePayload{
TreeId: treeId,
Header: header,
Changes: []*aclpb.RawChange{rawChange},
Heads: []string{rawChange.Id},
})
}
func createTreeHeaderAndId(change *aclpb.RawChange, treeType aclpb.HeaderDocType, aclListId string) (header *aclpb.Header, treeId string, err error) {
header = &aclpb.Header{
FirstId: change.Id,
DocType: treeType,
AclListId: aclListId,
}
marshalledHeader, err := proto.Marshal(header)
if err != nil {
return
}
treeId, err = cid.NewCIDFromBytes(marshalledHeader)
return
}

View File

@ -15,7 +15,7 @@ var log = logger.NewNamed("storage").Sugar()
type ImportedACLSyncData struct {
Id string
Header *aclpb.Header
Records []*aclpb.RawRecord
Records []*aclpb.RawACLRecord
}
type Service interface {

View File

@ -47,44 +47,3 @@ message System {
}
}
}
message Sync {
string spaceId = 1;
ContentValue message = 2;
acl.Header treeHeader = 3;
string treeId = 4;
message ContentValue {
oneof value {
HeadUpdate headUpdate = 1;
Full.Request fullSyncRequest = 2;
Full.Response fullSyncResponse = 3;
ACLList aclList = 4;
}
}
message ACLList {
repeated acl.RawRecord records = 1;
}
message HeadUpdate {
repeated string heads = 1;
repeated acl.RawChange changes = 2;
repeated string snapshotPath = 3;
}
message Full {
// here with send the request with all changes we have (we already know sender's snapshot path)
message Request {
repeated string heads = 1;
repeated acl.RawChange changes = 2;
repeated string snapshotPath = 3;
}
message Response {
repeated string heads = 1;
repeated acl.RawChange changes = 2;
repeated string snapshotPath = 3;
}
}
}

File diff suppressed because it is too large Load Diff