WIP Change interface rework
This commit is contained in:
parent
d5614eb5ee
commit
126d080c63
10
aclchanges/change.go
Normal file
10
aclchanges/change.go
Normal 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
|
||||||
|
}
|
||||||
@ -32,7 +32,7 @@ type ACLTree interface {
|
|||||||
Heads() []string
|
Heads() []string
|
||||||
Iterate(func(change *Change) bool)
|
Iterate(func(change *Change) bool)
|
||||||
IterateFrom(string, func(change *Change) bool)
|
IterateFrom(string, func(change *Change) bool)
|
||||||
HasChange(change *Change) bool
|
HasChange(string) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type aclTree struct {
|
type aclTree struct {
|
||||||
@ -225,7 +225,7 @@ func (a *aclTree) AddContent(changeContent *ChangeContent) (*Change, error) {
|
|||||||
}
|
}
|
||||||
a.fullTree.AddFast(ch)
|
a.fullTree.AddFast(ch)
|
||||||
|
|
||||||
err = a.thread.AddChange(&thread.RawChange{
|
err = a.thread.AddRawChange(&thread.RawChange{
|
||||||
Payload: marshalled,
|
Payload: marshalled,
|
||||||
Signature: signature,
|
Signature: signature,
|
||||||
Id: changeContent.Id,
|
Id: changeContent.Id,
|
||||||
@ -245,28 +245,23 @@ func (a *aclTree) AddChanges(changes ...*Change) (AddResult, error) {
|
|||||||
aclChanges = append(aclChanges, ch)
|
aclChanges = append(aclChanges, ch)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
a.thread.A
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: understand the common snapshot problem
|
// TODO: understand the common snapshot problem
|
||||||
prevHeads := a.fullTree.Heads()
|
prevHeads := a.fullTree.Heads()
|
||||||
prevRoot := a.
|
|
||||||
mode := a.fullTree.Add(changes...)
|
mode := a.fullTree.Add(changes...)
|
||||||
switch mode {
|
switch mode {
|
||||||
case acltree.Nothing:
|
case Nothing:
|
||||||
return d.docContext.docState, UpdateResultNoAction, nil
|
return AddResult{Summary: AddResultSummaryNothing}, nil
|
||||||
case acltree.Rebuild:
|
case Rebuild:
|
||||||
res, err := d.Build()
|
res, err := d.Build()
|
||||||
return res, UpdateResultRebuild, err
|
return AddResult{Summary: Rebuild}, err
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *aclTree) Heads() []string {
|
|
||||||
//TODO implement me
|
|
||||||
panic("implement me")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *aclTree) Iterate(f func(change *Change) bool) {
|
func (a *aclTree) Iterate(f func(change *Change) bool) {
|
||||||
//TODO implement me
|
//TODO implement me
|
||||||
panic("implement me")
|
panic("implement me")
|
||||||
@ -277,7 +272,7 @@ func (a *aclTree) IterateFrom(s string, f func(change *Change) bool) {
|
|||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *aclTree) HasChange(change *Change) bool {
|
func (a *aclTree) HasChange(s string) bool {
|
||||||
//TODO implement me
|
//TODO implement me
|
||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,7 +38,7 @@ func (tb *aclTreeBuilder) init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (tb *aclTreeBuilder) build() (*Tree, error) {
|
func (tb *aclTreeBuilder) build() (*Tree, error) {
|
||||||
heads := tb.thread.MaybeHeads()
|
heads := tb.thread.PossibleHeads()
|
||||||
aclHeads, err := tb.getACLHeads(heads)
|
aclHeads, err := tb.getACLHeads(heads)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@ -25,6 +25,7 @@ type Change struct {
|
|||||||
DecryptedDocumentChange []byte
|
DecryptedDocumentChange []byte
|
||||||
|
|
||||||
Content *pb.ACLChange
|
Content *pb.ACLChange
|
||||||
|
Sign []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ch *Change) DecryptContents(key *symmetric.Key) error {
|
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,
|
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
|
||||||
|
}
|
||||||
|
|||||||
@ -33,6 +33,10 @@ type Tree struct {
|
|||||||
duplicateEvents int
|
duplicateEvents int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Tree) GetUnattachedChanges(changes ...*Change) []*Change {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (t *Tree) RootId() string {
|
func (t *Tree) RootId() string {
|
||||||
if t.root != nil {
|
if t.root != nil {
|
||||||
return t.root.Id
|
return t.root.Id
|
||||||
|
|||||||
@ -46,7 +46,7 @@ func (tb *treeBuilder) init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (tb *treeBuilder) build(fromStart bool) (*Tree, error) {
|
func (tb *treeBuilder) build(fromStart bool) (*Tree, error) {
|
||||||
heads := tb.thread.MaybeHeads()
|
heads := tb.thread.PossibleHeads()
|
||||||
|
|
||||||
if fromStart {
|
if fromStart {
|
||||||
if err := tb.buildTreeFromStart(heads); err != nil {
|
if err := tb.buildTreeFromStart(heads); err != nil {
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/acltree"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/acltree"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/data/pb"
|
"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/anytypeio/go-anytype-infrastructure-experiments/util/slice"
|
||||||
"github.com/gogo/protobuf/proto"
|
"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)
|
treeChange := d.treeBuilder.changeCreator(ch.Id, aclChange)
|
||||||
treeChanges = append(treeChanges, treeChange)
|
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
|
// TODO: change this behaviour as non-obvious, because it is not evident from the interface
|
||||||
err = d.thread.AddChange(ch)
|
err = d.thread.AddChange(ch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package threadbuilder
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/aclchanges"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
|
||||||
"github.com/gogo/protobuf/proto"
|
"github.com/gogo/protobuf/proto"
|
||||||
@ -77,11 +78,10 @@ func (t *ThreadBuilder) Heads() []string {
|
|||||||
return t.heads
|
return t.heads
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *ThreadBuilder) AddChange(change *thread.RawChange) error {
|
func (t *ThreadBuilder) AddRawChange(change *thread.RawChange) error {
|
||||||
aclChange := new(pb.ACLChange)
|
aclChange := new(pb.ACLChange)
|
||||||
var err error
|
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 {
|
if err = proto.Unmarshal(change.Payload, aclChange); err != nil {
|
||||||
return fmt.Errorf("could not unmarshall changes")
|
return fmt.Errorf("could not unmarshall changes")
|
||||||
}
|
}
|
||||||
@ -98,7 +98,6 @@ func (t *ThreadBuilder) AddChange(change *thread.RawChange) error {
|
|||||||
|
|
||||||
// get correct signing key
|
// get correct signing key
|
||||||
signKey := t.keychain.SigningKeysByIdentity[aclChange.Identity]
|
signKey := t.keychain.SigningKeysByIdentity[aclChange.Identity]
|
||||||
t.maybeHeads = append(t.maybeHeads, change.Id)
|
|
||||||
|
|
||||||
t.allChanges[change.Id] = &threadChange{
|
t.allChanges[change.Id] = &threadChange{
|
||||||
ACLChange: aclChange,
|
ACLChange: aclChange,
|
||||||
@ -110,11 +109,42 @@ func (t *ThreadBuilder) AddChange(change *thread.RawChange) error {
|
|||||||
return nil
|
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
|
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
|
// we should copy here instead of just setting the value
|
||||||
t.maybeHeads = heads
|
t.maybeHeads = heads
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,16 +2,23 @@ package thread
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"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 {
|
type Thread interface {
|
||||||
ID() string
|
ID() string
|
||||||
|
|
||||||
Heads() []string
|
Heads() []string
|
||||||
MaybeHeads() []string
|
PossibleHeads() []string
|
||||||
GetChange(ctx context.Context, recordID string) (*RawChange, error)
|
|
||||||
SetHeads(heads []string)
|
SetHeads(heads []string)
|
||||||
SetMaybeHeads(heads []string)
|
SetPossibleHeads(heads []string)
|
||||||
AddChange(change *RawChange) error
|
AddPossibleHead(head string)
|
||||||
|
|
||||||
|
AddRawChange(change *RawChange) error
|
||||||
|
AddChange(change aclchanges.Change) error
|
||||||
|
GetChange(ctx context.Context, recordID string) (*RawChange, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type RawChange struct {
|
type RawChange struct {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user