WIP Change interface rework

This commit is contained in:
mcrakhman 2022-07-10 11:44:02 +02:00 committed by Mikhail Iudin
parent 8570c4e318
commit e6534e134b
No known key found for this signature in database
GPG Key ID: FAAAA8BAABDFF1C0
9 changed files with 89 additions and 25 deletions

10
aclchanges/change.go Normal file
View File

@ -0,0 +1,10 @@
package aclchanges
import "github.com/anytypeio/go-anytype-infrastructure-experiments/aclchanges/pb"
type Change interface {
ProtoChange() *pb.ACLChange
DecryptedChangeContent() []byte
Signature() []byte
CID() string
}

View File

@ -32,7 +32,7 @@ type ACLTree interface {
Heads() []string
Iterate(func(change *Change) bool)
IterateFrom(string, func(change *Change) bool)
HasChange(change *Change) bool
HasChange(string) bool
}
type aclTree struct {
@ -225,7 +225,7 @@ func (a *aclTree) AddContent(changeContent *ChangeContent) (*Change, error) {
}
a.fullTree.AddFast(ch)
err = a.thread.AddChange(&thread.RawChange{
err = a.thread.AddRawChange(&thread.RawChange{
Payload: marshalled,
Signature: signature,
Id: changeContent.Id,
@ -245,28 +245,23 @@ func (a *aclTree) AddChanges(changes ...*Change) (AddResult, error) {
aclChanges = append(aclChanges, ch)
break
}
a.thread.A
}
// TODO: understand the common snapshot problem
prevHeads := a.fullTree.Heads()
prevRoot := a.
mode := a.fullTree.Add(changes...)
switch mode {
case acltree.Nothing:
return d.docContext.docState, UpdateResultNoAction, nil
case acltree.Rebuild:
case Nothing:
return AddResult{Summary: AddResultSummaryNothing}, nil
case Rebuild:
res, err := d.Build()
return res, UpdateResultRebuild, err
return AddResult{Summary: Rebuild}, err
default:
break
}
}
func (a *aclTree) Heads() []string {
//TODO implement me
panic("implement me")
}
func (a *aclTree) Iterate(f func(change *Change) bool) {
//TODO implement me
panic("implement me")
@ -277,7 +272,7 @@ func (a *aclTree) IterateFrom(s string, f func(change *Change) bool) {
panic("implement me")
}
func (a *aclTree) HasChange(change *Change) bool {
func (a *aclTree) HasChange(s string) bool {
//TODO implement me
panic("implement me")
}

View File

@ -38,7 +38,7 @@ func (tb *aclTreeBuilder) init() {
}
func (tb *aclTreeBuilder) build() (*Tree, error) {
heads := tb.thread.MaybeHeads()
heads := tb.thread.PossibleHeads()
aclHeads, err := tb.getACLHeads(heads)
if err != nil {
return nil, err

View File

@ -25,6 +25,7 @@ type Change struct {
DecryptedDocumentChange []byte
Content *pb.ACLChange
Sign []byte
}
func (ch *Change) DecryptContents(key *symmetric.Key) error {
@ -66,3 +67,19 @@ func NewACLChange(id string, ch *pb.ACLChange) *Change {
IsSnapshot: ch.GetAclData().GetAclSnapshot() != nil,
}
}
func (ch *Change) ProtoChange() *pb.ACLChange {
return ch.Content
}
func (ch *Change) DecryptedChangeContent() []byte {
return ch.DecryptedDocumentChange
}
func (ch *Change) Signature() []byte {
return ch.Sign
}
func (ch *Change) CID() string {
return ch.Id
}

View File

@ -33,6 +33,10 @@ type Tree struct {
duplicateEvents int
}
func (t *Tree) GetUnattachedChanges(changes ...*Change) []*Change {
return nil
}
func (t *Tree) RootId() string {
if t.root != nil {
return t.root.Id

View File

@ -46,7 +46,7 @@ func (tb *treeBuilder) init() {
}
func (tb *treeBuilder) build(fromStart bool) (*Tree, error) {
heads := tb.thread.MaybeHeads()
heads := tb.thread.PossibleHeads()
if fromStart {
if err := tb.buildTreeFromStart(heads); err != nil {

View File

@ -4,6 +4,7 @@ import (
"fmt"
"github.com/anytypeio/go-anytype-infrastructure-experiments/acltree"
"github.com/anytypeio/go-anytype-infrastructure-experiments/data/pb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/thread"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice"
"github.com/gogo/protobuf/proto"
)
@ -144,7 +145,7 @@ func (d *Document) Update(changes ...*thread.RawChange) (DocumentState, UpdateRe
treeChange := d.treeBuilder.changeCreator(ch.Id, aclChange)
treeChanges = append(treeChanges, treeChange)
// this already sets MaybeHeads to include new changes
// this already sets PossibleHeads to include new changes
// TODO: change this behaviour as non-obvious, because it is not evident from the interface
err = d.thread.AddChange(ch)
if err != nil {

View File

@ -3,6 +3,7 @@ package threadbuilder
import (
"context"
"fmt"
"github.com/anytypeio/go-anytype-infrastructure-experiments/aclchanges"
"io/ioutil"
"github.com/gogo/protobuf/proto"
@ -77,11 +78,10 @@ func (t *ThreadBuilder) Heads() []string {
return t.heads
}
func (t *ThreadBuilder) AddChange(change *thread.RawChange) error {
func (t *ThreadBuilder) AddRawChange(change *thread.RawChange) error {
aclChange := new(pb.ACLChange)
var err error
// TODO: think what should we do with such cases, because this can be used by attacker to break our tree
if err = proto.Unmarshal(change.Payload, aclChange); err != nil {
return fmt.Errorf("could not unmarshall changes")
}
@ -98,7 +98,6 @@ func (t *ThreadBuilder) AddChange(change *thread.RawChange) error {
// get correct signing key
signKey := t.keychain.SigningKeysByIdentity[aclChange.Identity]
t.maybeHeads = append(t.maybeHeads, change.Id)
t.allChanges[change.Id] = &threadChange{
ACLChange: aclChange,
@ -110,11 +109,42 @@ func (t *ThreadBuilder) AddChange(change *thread.RawChange) error {
return nil
}
func (t *ThreadBuilder) MaybeHeads() []string {
func (t *ThreadBuilder) AddPossibleHead(head string) {
t.maybeHeads = append(t.maybeHeads, head)
}
func (t *ThreadBuilder) AddChange(change aclchanges.Change) error {
aclChange := change.ProtoChange()
var err error
var changesData []byte
// get correct readkey
readKey := t.keychain.ReadKeysByHash[aclChange.CurrentReadKeyHash]
if aclChange.ChangesData != nil {
changesData, err = readKey.Key.Decrypt(aclChange.ChangesData)
if err != nil {
return fmt.Errorf("failed to decrypt changes data: %w", err)
}
}
// get correct signing key
signKey := t.keychain.SigningKeysByIdentity[aclChange.Identity]
t.allChanges[change.CID()] = &threadChange{
ACLChange: aclChange,
id: change.CID(),
readKey: readKey,
signKey: signKey,
changesDataDecrypted: changesData,
}
return nil
}
func (t *ThreadBuilder) PossibleHeads() []string {
return t.maybeHeads
}
func (t *ThreadBuilder) SetMaybeHeads(heads []string) {
func (t *ThreadBuilder) SetPossibleHeads(heads []string) {
// we should copy here instead of just setting the value
t.maybeHeads = heads
}

View File

@ -2,16 +2,23 @@ package thread
import (
"context"
"github.com/anytypeio/go-anytype-infrastructure-experiments/aclchanges"
)
// TODO: change methods to have errors as a return parameter, because we will be dealing with a real database
type Thread interface {
ID() string
Heads() []string
MaybeHeads() []string
GetChange(ctx context.Context, recordID string) (*RawChange, error)
PossibleHeads() []string
SetHeads(heads []string)
SetMaybeHeads(heads []string)
AddChange(change *RawChange) error
SetPossibleHeads(heads []string)
AddPossibleHead(head string)
AddRawChange(change *RawChange) error
AddChange(change aclchanges.Change) error
GetChange(ctx context.Context, recordID string) (*RawChange, error)
}
type RawChange struct {