WIP ACLTree
This commit is contained in:
parent
c07b26d568
commit
d5614eb5ee
@ -2,8 +2,11 @@ package acltree
|
||||
|
||||
import (
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/account"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/aclchanges/pb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/thread"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
)
|
||||
|
||||
type AddResultSummary int
|
||||
@ -37,6 +40,7 @@ type aclTree struct {
|
||||
accountData *account.AccountData
|
||||
|
||||
fullTree *Tree
|
||||
aclTree *Tree // this tree is built from start of the document
|
||||
aclState *ACLState
|
||||
|
||||
treeBuilder *treeBuilder
|
||||
@ -70,9 +74,36 @@ func BuildACLTree(t thread.Thread, acc *account.AccountData) (ACLTree, error) {
|
||||
return aclTree, nil
|
||||
}
|
||||
|
||||
func (a *aclTree) rebuildFromThread(fromStart bool) error {
|
||||
var aclTree *Tree
|
||||
func (a *aclTree) rebuildFromTree(validateSnapshot bool) (err error) {
|
||||
if validateSnapshot {
|
||||
err = a.snapshotValidator.init(a.aclTree)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
valid, err := a.snapshotValidator.validateSnapshot(a.fullTree.root)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !valid {
|
||||
return a.rebuildFromThread(true)
|
||||
}
|
||||
}
|
||||
|
||||
err = a.aclStateBuilder.init(a.fullTree)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
a.aclState, err = a.aclStateBuilder.build()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *aclTree) rebuildFromThread(fromStart bool) error {
|
||||
a.treeBuilder.init()
|
||||
a.aclTreeBuilder.init()
|
||||
|
||||
@ -83,13 +114,13 @@ func (a *aclTree) rebuildFromThread(fromStart bool) error {
|
||||
}
|
||||
|
||||
// TODO: remove this from context as this is used only to validate snapshot
|
||||
aclTree, err = a.aclTreeBuilder.build()
|
||||
a.aclTree, err = a.aclTreeBuilder.build()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !fromStart {
|
||||
err = a.snapshotValidator.init(aclTree)
|
||||
err = a.snapshotValidator.init(a.aclTree)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -115,19 +146,120 @@ func (a *aclTree) rebuildFromThread(fromStart bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO: this should not be the responsibility of ACLTree, move it somewhere else after testing
|
||||
func (a *aclTree) getACLHeads() []string {
|
||||
var aclTreeHeads []string
|
||||
for _, head := range a.fullTree.Heads() {
|
||||
if slice.FindPos(aclTreeHeads, head) != -1 { // do not scan known heads
|
||||
continue
|
||||
}
|
||||
precedingHeads := a.getPrecedingACLHeads(head)
|
||||
|
||||
for _, aclHead := range precedingHeads {
|
||||
if slice.FindPos(aclTreeHeads, aclHead) != -1 {
|
||||
continue
|
||||
}
|
||||
aclTreeHeads = append(aclTreeHeads, aclHead)
|
||||
}
|
||||
}
|
||||
return aclTreeHeads
|
||||
}
|
||||
|
||||
func (a *aclTree) getPrecedingACLHeads(head string) []string {
|
||||
headChange := a.fullTree.attached[head]
|
||||
|
||||
if headChange.Content.GetAclData() != nil {
|
||||
return []string{head}
|
||||
} else {
|
||||
return headChange.Content.AclHeadIds
|
||||
}
|
||||
}
|
||||
|
||||
func (a *aclTree) ACLState() *ACLState {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
return a.aclState
|
||||
}
|
||||
|
||||
func (a *aclTree) AddContent(changeContent *ChangeContent) (*Change, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
// TODO: add snapshot creation logic
|
||||
marshalled, err := changeContent.ChangesData.Marshal()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
encrypted, err := a.aclState.userReadKeys[a.aclState.currentReadKeyHash].
|
||||
Encrypt(marshalled)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
aclChange := &pb.ACLChange{
|
||||
TreeHeadIds: a.fullTree.Heads(),
|
||||
AclHeadIds: a.getACLHeads(),
|
||||
SnapshotBaseId: a.fullTree.RootId(),
|
||||
AclData: changeContent.ACLData,
|
||||
ChangesData: encrypted,
|
||||
CurrentReadKeyHash: a.aclState.currentReadKeyHash,
|
||||
Timestamp: 0,
|
||||
Identity: a.accountData.Identity,
|
||||
}
|
||||
|
||||
// TODO: add CID creation logic based on content
|
||||
ch := NewChange(changeContent.Id, aclChange)
|
||||
ch.DecryptedDocumentChange = marshalled
|
||||
|
||||
fullMarshalledChange, err := proto.Marshal(aclChange)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
signature, err := a.accountData.SignKey.Sign(fullMarshalledChange)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if aclChange.AclData != nil {
|
||||
// we can apply change right away without going through builder, because
|
||||
err = a.aclState.applyChange(changeContent.Id, aclChange)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
a.fullTree.AddFast(ch)
|
||||
|
||||
err = a.thread.AddChange(&thread.RawChange{
|
||||
Payload: marshalled,
|
||||
Signature: signature,
|
||||
Id: changeContent.Id,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
a.thread.SetHeads([]string{ch.Id})
|
||||
return a.fullTree.attached[changeContent.Id], nil
|
||||
}
|
||||
|
||||
func (a *aclTree) AddChanges(changes ...*Change) (AddResult, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
var aclChanges []*Change
|
||||
for _, ch := range changes {
|
||||
if ch.IsACLChange() {
|
||||
aclChanges = append(aclChanges, ch)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 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:
|
||||
res, err := d.Build()
|
||||
return res, UpdateResultRebuild, err
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
func (a *aclTree) Heads() []string {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user