diff --git a/pkg/acl/aclchanges/aclpb/aclchanges.pb.go b/pkg/acl/aclchanges/aclpb/aclchanges.pb.go index 0a4b6746..0f6fec52 100644 --- a/pkg/acl/aclchanges/aclpb/aclchanges.pb.go +++ b/pkg/acl/aclchanges/aclpb/aclchanges.pb.go @@ -50,7 +50,7 @@ func (x ACLChangeUserPermissions) String() string { } func (ACLChangeUserPermissions) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{1, 0} + return fileDescriptor_37a022c841a51877, []int{2, 0} } type RawChange struct { @@ -113,6 +113,66 @@ func (m *RawChange) GetId() string { return "" } +type RawRecord struct { + Payload []byte `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"` + Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` + Id string `protobuf:"bytes,3,opt,name=id,proto3" json:"id,omitempty"` +} + +func (m *RawRecord) Reset() { *m = RawRecord{} } +func (m *RawRecord) String() string { return proto.CompactTextString(m) } +func (*RawRecord) ProtoMessage() {} +func (*RawRecord) Descriptor() ([]byte, []int) { + return fileDescriptor_37a022c841a51877, []int{1} +} +func (m *RawRecord) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RawRecord) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RawRecord.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RawRecord) XXX_Merge(src proto.Message) { + xxx_messageInfo_RawRecord.Merge(m, src) +} +func (m *RawRecord) XXX_Size() int { + return m.Size() +} +func (m *RawRecord) XXX_DiscardUnknown() { + xxx_messageInfo_RawRecord.DiscardUnknown(m) +} + +var xxx_messageInfo_RawRecord proto.InternalMessageInfo + +func (m *RawRecord) GetPayload() []byte { + if m != nil { + return m.Payload + } + return nil +} + +func (m *RawRecord) GetSignature() []byte { + if m != nil { + return m.Signature + } + return nil +} + +func (m *RawRecord) GetId() string { + if m != nil { + return m.Id + } + return "" +} + // the element of change tree used to store and internal apply smartBlock history type ACLChange struct { TreeHeadIds []string `protobuf:"bytes,1,rep,name=treeHeadIds,proto3" json:"treeHeadIds,omitempty"` @@ -130,7 +190,7 @@ func (m *ACLChange) Reset() { *m = ACLChange{} } func (m *ACLChange) String() string { return proto.CompactTextString(m) } func (*ACLChange) ProtoMessage() {} func (*ACLChange) Descriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{1} + return fileDescriptor_37a022c841a51877, []int{2} } func (m *ACLChange) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -230,7 +290,7 @@ func (m *ACLChangeACLContentValue) Reset() { *m = ACLChangeACLContentVal func (m *ACLChangeACLContentValue) String() string { return proto.CompactTextString(m) } func (*ACLChangeACLContentValue) ProtoMessage() {} func (*ACLChangeACLContentValue) Descriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{1, 0} + return fileDescriptor_37a022c841a51877, []int{2, 0} } func (m *ACLChangeACLContentValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -361,7 +421,7 @@ func (m *ACLChangeACLData) Reset() { *m = ACLChangeACLData{} } func (m *ACLChangeACLData) String() string { return proto.CompactTextString(m) } func (*ACLChangeACLData) ProtoMessage() {} func (*ACLChangeACLData) Descriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{1, 1} + return fileDescriptor_37a022c841a51877, []int{2, 1} } func (m *ACLChangeACLData) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -413,7 +473,7 @@ func (m *ACLChangeACLSnapshot) Reset() { *m = ACLChangeACLSnapshot{} } func (m *ACLChangeACLSnapshot) String() string { return proto.CompactTextString(m) } func (*ACLChangeACLSnapshot) ProtoMessage() {} func (*ACLChangeACLSnapshot) Descriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{1, 2} + return fileDescriptor_37a022c841a51877, []int{2, 2} } func (m *ACLChangeACLSnapshot) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -459,7 +519,7 @@ func (m *ACLChangeACLState) Reset() { *m = ACLChangeACLState{} } func (m *ACLChangeACLState) String() string { return proto.CompactTextString(m) } func (*ACLChangeACLState) ProtoMessage() {} func (*ACLChangeACLState) Descriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{1, 3} + return fileDescriptor_37a022c841a51877, []int{2, 3} } func (m *ACLChangeACLState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -521,7 +581,7 @@ func (m *ACLChangeUserState) Reset() { *m = ACLChangeUserState{} } func (m *ACLChangeUserState) String() string { return proto.CompactTextString(m) } func (*ACLChangeUserState) ProtoMessage() {} func (*ACLChangeUserState) Descriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{1, 4} + return fileDescriptor_37a022c841a51877, []int{2, 4} } func (m *ACLChangeUserState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -597,7 +657,7 @@ func (m *ACLChangeUserAdd) Reset() { *m = ACLChangeUserAdd{} } func (m *ACLChangeUserAdd) String() string { return proto.CompactTextString(m) } func (*ACLChangeUserAdd) ProtoMessage() {} func (*ACLChangeUserAdd) Descriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{1, 5} + return fileDescriptor_37a022c841a51877, []int{2, 5} } func (m *ACLChangeUserAdd) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -664,7 +724,7 @@ func (m *ACLChangeUserConfirm) Reset() { *m = ACLChangeUserConfirm{} } func (m *ACLChangeUserConfirm) String() string { return proto.CompactTextString(m) } func (*ACLChangeUserConfirm) ProtoMessage() {} func (*ACLChangeUserConfirm) Descriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{1, 6} + return fileDescriptor_37a022c841a51877, []int{2, 6} } func (m *ACLChangeUserConfirm) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -719,7 +779,7 @@ func (m *ACLChangeUserInvite) Reset() { *m = ACLChangeUserInvite{} } func (m *ACLChangeUserInvite) String() string { return proto.CompactTextString(m) } func (*ACLChangeUserInvite) ProtoMessage() {} func (*ACLChangeUserInvite) Descriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{1, 7} + return fileDescriptor_37a022c841a51877, []int{2, 7} } func (m *ACLChangeUserInvite) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -795,7 +855,7 @@ func (m *ACLChangeUserJoin) Reset() { *m = ACLChangeUserJoin{} } func (m *ACLChangeUserJoin) String() string { return proto.CompactTextString(m) } func (*ACLChangeUserJoin) ProtoMessage() {} func (*ACLChangeUserJoin) Descriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{1, 8} + return fileDescriptor_37a022c841a51877, []int{2, 8} } func (m *ACLChangeUserJoin) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -868,7 +928,7 @@ func (m *ACLChangeUserRemove) Reset() { *m = ACLChangeUserRemove{} } func (m *ACLChangeUserRemove) String() string { return proto.CompactTextString(m) } func (*ACLChangeUserRemove) ProtoMessage() {} func (*ACLChangeUserRemove) Descriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{1, 9} + return fileDescriptor_37a022c841a51877, []int{2, 9} } func (m *ACLChangeUserRemove) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -921,7 +981,7 @@ func (m *ACLChangeReadKeyReplace) Reset() { *m = ACLChangeReadKeyReplace func (m *ACLChangeReadKeyReplace) String() string { return proto.CompactTextString(m) } func (*ACLChangeReadKeyReplace) ProtoMessage() {} func (*ACLChangeReadKeyReplace) Descriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{1, 10} + return fileDescriptor_37a022c841a51877, []int{2, 10} } func (m *ACLChangeReadKeyReplace) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -980,7 +1040,7 @@ func (m *ACLChangeUserPermissionChange) Reset() { *m = ACLChangeUserPerm func (m *ACLChangeUserPermissionChange) String() string { return proto.CompactTextString(m) } func (*ACLChangeUserPermissionChange) ProtoMessage() {} func (*ACLChangeUserPermissionChange) Descriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{1, 11} + return fileDescriptor_37a022c841a51877, []int{2, 11} } func (m *ACLChangeUserPermissionChange) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1025,7 +1085,7 @@ func (m *ACLChangeUserPermissionChange) GetPermissions() ACLChangeUserPermission type Change struct { TreeHeadIds []string `protobuf:"bytes,1,rep,name=treeHeadIds,proto3" json:"treeHeadIds,omitempty"` - AclHeadIds []string `protobuf:"bytes,2,rep,name=aclHeadIds,proto3" json:"aclHeadIds,omitempty"` + AclHeadId string `protobuf:"bytes,2,opt,name=aclHeadId,proto3" json:"aclHeadId,omitempty"` SnapshotBaseId string `protobuf:"bytes,3,opt,name=snapshotBaseId,proto3" json:"snapshotBaseId,omitempty"` ChangesData []byte `protobuf:"bytes,4,opt,name=changesData,proto3" json:"changesData,omitempty"` CurrentReadKeyHash uint64 `protobuf:"varint,5,opt,name=currentReadKeyHash,proto3" json:"currentReadKeyHash,omitempty"` @@ -1038,7 +1098,7 @@ func (m *Change) Reset() { *m = Change{} } func (m *Change) String() string { return proto.CompactTextString(m) } func (*Change) ProtoMessage() {} func (*Change) Descriptor() ([]byte, []int) { - return fileDescriptor_37a022c841a51877, []int{2} + return fileDescriptor_37a022c841a51877, []int{3} } func (m *Change) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1074,11 +1134,11 @@ func (m *Change) GetTreeHeadIds() []string { return nil } -func (m *Change) GetAclHeadIds() []string { +func (m *Change) GetAclHeadId() string { if m != nil { - return m.AclHeadIds + return m.AclHeadId } - return nil + return "" } func (m *Change) GetSnapshotBaseId() string { @@ -1123,9 +1183,86 @@ func (m *Change) GetIsSnapshot() bool { return false } +type Record struct { + PrevId string `protobuf:"bytes,1,opt,name=prevId,proto3" json:"prevId,omitempty"` + Identity string `protobuf:"bytes,2,opt,name=identity,proto3" json:"identity,omitempty"` + Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` + CurrentReadKeyHash uint64 `protobuf:"varint,4,opt,name=currentReadKeyHash,proto3" json:"currentReadKeyHash,omitempty"` + Timestamp int64 `protobuf:"varint,5,opt,name=timestamp,proto3" json:"timestamp,omitempty"` +} + +func (m *Record) Reset() { *m = Record{} } +func (m *Record) String() string { return proto.CompactTextString(m) } +func (*Record) ProtoMessage() {} +func (*Record) Descriptor() ([]byte, []int) { + return fileDescriptor_37a022c841a51877, []int{4} +} +func (m *Record) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Record) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Record.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Record) XXX_Merge(src proto.Message) { + xxx_messageInfo_Record.Merge(m, src) +} +func (m *Record) XXX_Size() int { + return m.Size() +} +func (m *Record) XXX_DiscardUnknown() { + xxx_messageInfo_Record.DiscardUnknown(m) +} + +var xxx_messageInfo_Record proto.InternalMessageInfo + +func (m *Record) GetPrevId() string { + if m != nil { + return m.PrevId + } + return "" +} + +func (m *Record) GetIdentity() string { + if m != nil { + return m.Identity + } + return "" +} + +func (m *Record) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +func (m *Record) GetCurrentReadKeyHash() uint64 { + if m != nil { + return m.CurrentReadKeyHash + } + return 0 +} + +func (m *Record) GetTimestamp() int64 { + if m != nil { + return m.Timestamp + } + return 0 +} + func init() { proto.RegisterEnum("acl.ACLChangeUserPermissions", ACLChangeUserPermissions_name, ACLChangeUserPermissions_value) proto.RegisterType((*RawChange)(nil), "acl.RawChange") + proto.RegisterType((*RawRecord)(nil), "acl.RawRecord") proto.RegisterType((*ACLChange)(nil), "acl.ACLChange") proto.RegisterType((*ACLChangeACLContentValue)(nil), "acl.ACLChange.ACLContentValue") proto.RegisterType((*ACLChangeACLData)(nil), "acl.ACLChange.ACLData") @@ -1141,6 +1278,7 @@ func init() { proto.RegisterType((*ACLChangeReadKeyReplace)(nil), "acl.ACLChange.ReadKeyReplace") proto.RegisterType((*ACLChangeUserPermissionChange)(nil), "acl.ACLChange.UserPermissionChange") proto.RegisterType((*Change)(nil), "acl.Change") + proto.RegisterType((*Record)(nil), "acl.Record") } func init() { @@ -1148,69 +1286,73 @@ func init() { } var fileDescriptor_37a022c841a51877 = []byte{ - // 987 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0x4f, 0x8f, 0xdb, 0x44, - 0x14, 0xcf, 0x24, 0x9b, 0x75, 0xfc, 0x1c, 0x76, 0xc3, 0x50, 0x51, 0x63, 0x95, 0x10, 0x85, 0x0a, - 0x45, 0x08, 0x65, 0xab, 0x54, 0x48, 0x15, 0xa0, 0x15, 0xbb, 0x0b, 0x6a, 0xc2, 0x72, 0xa8, 0x66, - 0x55, 0x10, 0xdc, 0x66, 0xed, 0x61, 0xd7, 0xaa, 0x63, 0x1b, 0xcf, 0x64, 0x51, 0x2e, 0x48, 0x9c, - 0xb8, 0x72, 0xe6, 0xc0, 0x17, 0xe1, 0x0b, 0xf4, 0xd8, 0x23, 0x37, 0xd0, 0xee, 0x9d, 0x0b, 0x5f, - 0x00, 0xcd, 0x1f, 0x3b, 0x8e, 0xe3, 0x46, 0x45, 0xaa, 0x2a, 0x71, 0x88, 0x34, 0xf3, 0x7b, 0xbf, - 0x37, 0x79, 0xef, 0xfd, 0xde, 0x3c, 0x0f, 0xdc, 0x4b, 0x9f, 0x5c, 0x1c, 0x50, 0x3f, 0x92, 0x3f, - 0xff, 0x92, 0xc6, 0x17, 0x8c, 0xcb, 0x65, 0x7a, 0x7e, 0x90, 0x66, 0x89, 0x48, 0x78, 0x09, 0x1f, - 0x2b, 0x04, 0xb7, 0xa8, 0x1f, 0x0d, 0xcf, 0xc0, 0x26, 0xf4, 0x87, 0x13, 0x65, 0xc0, 0x2e, 0x58, - 0x29, 0x5d, 0x46, 0x09, 0x0d, 0x5c, 0x34, 0x40, 0xa3, 0x2e, 0xc9, 0xb7, 0xf8, 0x0e, 0xd8, 0x3c, - 0xbc, 0x88, 0xa9, 0x58, 0x64, 0xcc, 0x6d, 0x2a, 0xdb, 0x0a, 0xc0, 0x7b, 0xd0, 0x0c, 0x03, 0xb7, - 0x35, 0x40, 0x23, 0x9b, 0x34, 0xc3, 0x60, 0xf8, 0xcf, 0x1b, 0x60, 0x1f, 0x9d, 0x7c, 0x69, 0x4e, - 0x1d, 0x80, 0x23, 0x32, 0xc6, 0xa6, 0x8c, 0x06, 0xb3, 0x80, 0xbb, 0x68, 0xd0, 0x1a, 0xd9, 0xa4, - 0x0c, 0xe1, 0x3e, 0x00, 0xf5, 0xa3, 0x9c, 0xd0, 0x54, 0x84, 0x12, 0x82, 0xdf, 0x83, 0x3d, 0x1e, - 0xd3, 0x94, 0x5f, 0x26, 0xe2, 0x98, 0x72, 0x36, 0xcb, 0xff, 0xab, 0x82, 0xe2, 0x7b, 0x60, 0x51, - 0x3f, 0xfa, 0x8c, 0x0a, 0xea, 0xee, 0x0c, 0xd0, 0xc8, 0x99, 0xbc, 0x39, 0xa6, 0x7e, 0x34, 0x2e, - 0x42, 0x91, 0x2b, 0x69, 0x25, 0x39, 0x4d, 0xc6, 0x66, 0x8a, 0xa2, 0xbc, 0xda, 0x2a, 0xb3, 0x32, - 0x84, 0xc7, 0x80, 0xfd, 0x45, 0x96, 0xb1, 0x58, 0x10, 0x46, 0x83, 0x53, 0xb6, 0x9c, 0x52, 0x7e, - 0xe9, 0xee, 0x0e, 0xd0, 0x68, 0x87, 0xd4, 0x58, 0x64, 0xa5, 0x44, 0x38, 0x67, 0x5c, 0xd0, 0x79, - 0xea, 0x5a, 0x03, 0x34, 0x6a, 0x91, 0x15, 0x80, 0x3d, 0xe8, 0x84, 0x01, 0x8b, 0x45, 0x28, 0x96, - 0x6e, 0x47, 0xe5, 0x50, 0xec, 0xbd, 0x5f, 0x5b, 0xb0, 0x2f, 0x43, 0x4d, 0x62, 0xc1, 0x62, 0xf1, - 0x15, 0x8d, 0x16, 0x0c, 0x4f, 0xc0, 0x5a, 0x70, 0x96, 0x1d, 0x05, 0x5a, 0x91, 0xcd, 0x8c, 0x1e, - 0x6b, 0xeb, 0xb4, 0x41, 0x72, 0x22, 0xfe, 0x18, 0x40, 0x2e, 0x09, 0x9b, 0x27, 0x57, 0x5a, 0x2c, - 0x67, 0xf2, 0x56, 0x8d, 0x9b, 0x26, 0x4c, 0x1b, 0xa4, 0x44, 0xc7, 0xdf, 0xc0, 0x2d, 0xb9, 0x7b, - 0xc4, 0xb2, 0x79, 0xc8, 0x79, 0x98, 0xc4, 0xda, 0x41, 0x15, 0xdc, 0x99, 0xbc, 0x5b, 0x73, 0x4c, - 0x95, 0x3a, 0x6d, 0x90, 0xda, 0x23, 0xf2, 0xb8, 0x66, 0xf1, 0x55, 0x28, 0x98, 0x11, 0xa8, 0x2e, - 0x2e, 0x4d, 0xc8, 0xe3, 0xd2, 0x3b, 0xfc, 0x21, 0x74, 0xe4, 0xee, 0x8b, 0x24, 0x8c, 0x95, 0x4a, - 0xce, 0xe4, 0x76, 0x8d, 0xab, 0x34, 0x4f, 0x1b, 0xa4, 0xa0, 0xe2, 0x43, 0x70, 0xe4, 0xfa, 0x24, - 0x89, 0xbf, 0x0b, 0xb3, 0xb9, 0x92, 0xcd, 0x99, 0x78, 0x35, 0x9e, 0x86, 0x31, 0x6d, 0x90, 0xb2, - 0xc3, 0xb1, 0x05, 0xed, 0x2b, 0x29, 0x84, 0xf7, 0x33, 0x02, 0xcb, 0x74, 0x0f, 0xfe, 0x04, 0x1c, - 0xea, 0x47, 0x67, 0xa6, 0xf7, 0x8c, 0x30, 0xde, 0x66, 0xab, 0xe5, 0x0c, 0x52, 0xa6, 0xe3, 0x43, - 0xd5, 0xec, 0x46, 0x65, 0xd5, 0xec, 0xce, 0xa4, 0xbf, 0xe9, 0x5c, 0x6e, 0x03, 0x52, 0xf2, 0xf0, - 0x8e, 0xc1, 0x29, 0x9d, 0x8d, 0xef, 0x43, 0x47, 0x9e, 0x2e, 0xa8, 0x60, 0x26, 0x92, 0xdb, 0x35, - 0x91, 0x48, 0x33, 0x29, 0x88, 0xde, 0x4f, 0x4d, 0xe8, 0xe4, 0x30, 0xbe, 0x0b, 0xaf, 0x65, 0xab, - 0x06, 0x66, 0xfa, 0x86, 0xee, 0x90, 0x75, 0x10, 0x3f, 0xd0, 0xea, 0x29, 0x17, 0x6e, 0xc2, 0x76, - 0x6b, 0x0a, 0xa9, 0xff, 0xaa, 0xc4, 0xc5, 0x87, 0x60, 0x85, 0x4a, 0x44, 0xee, 0xb6, 0x94, 0xdb, - 0xdd, 0xe7, 0x04, 0x38, 0xd6, 0x5a, 0xf3, 0xcf, 0x63, 0x91, 0x2d, 0x49, 0xee, 0xe4, 0x3d, 0x86, - 0x6e, 0xd9, 0x80, 0x7b, 0xd0, 0x7a, 0xc2, 0x96, 0x2a, 0x59, 0x9b, 0xc8, 0x25, 0x3e, 0x30, 0x2a, - 0x6d, 0x69, 0x76, 0x7d, 0x02, 0xd1, 0xbc, 0x8f, 0x9a, 0x0f, 0x90, 0xf7, 0x27, 0x02, 0xbb, 0x08, - 0x78, 0xed, 0x62, 0xa2, 0xf5, 0x8b, 0x29, 0x0b, 0xc4, 0x62, 0x3f, 0x5b, 0xa6, 0x22, 0x4c, 0xe2, - 0x53, 0xb6, 0x34, 0x03, 0x70, 0x1d, 0xc4, 0x1f, 0xc0, 0xeb, 0x06, 0x60, 0x81, 0x19, 0x08, 0x3a, - 0xe1, 0x2e, 0xd9, 0x34, 0xe0, 0x4f, 0xc1, 0x49, 0x8b, 0x0b, 0xc2, 0xd5, 0x6d, 0xd8, 0xdb, 0x68, - 0x83, 0xf5, 0xeb, 0xc5, 0x49, 0xd9, 0x45, 0x8e, 0xae, 0x19, 0x37, 0x7d, 0xca, 0x02, 0x75, 0x29, - 0x3a, 0xa4, 0x0c, 0x79, 0xbf, 0x23, 0xb0, 0xcc, 0x7c, 0xf8, 0xff, 0xe5, 0xe7, 0x3d, 0x04, 0xa7, - 0x74, 0x31, 0xb7, 0x26, 0x70, 0x07, 0x6c, 0x33, 0xfc, 0x66, 0x81, 0x0a, 0xde, 0x26, 0x2b, 0xc0, - 0xfb, 0x1b, 0x01, 0xac, 0x5a, 0x00, 0x8f, 0x60, 0x9f, 0xfa, 0x3e, 0x4b, 0xc5, 0xa3, 0xc5, 0x79, - 0x14, 0xfa, 0xa7, 0xa6, 0x95, 0xba, 0xa4, 0x0a, 0xe3, 0xf7, 0xa1, 0x67, 0x12, 0x5b, 0x51, 0x75, - 0x69, 0x36, 0xf0, 0x57, 0xae, 0xbe, 0x07, 0x1d, 0x9d, 0xcf, 0x4c, 0x4b, 0x6f, 0x93, 0x62, 0xef, - 0x3d, 0x45, 0xd0, 0xc9, 0xa7, 0xe1, 0x4b, 0x10, 0xbe, 0x28, 0xd8, 0x59, 0xf1, 0x02, 0x68, 0x95, - 0x0b, 0x56, 0xc0, 0x78, 0x08, 0xdd, 0xd5, 0xc8, 0x9e, 0x05, 0x2a, 0x2f, 0x9b, 0xac, 0x61, 0xf5, - 0x85, 0x6a, 0x3f, 0xa7, 0x50, 0xde, 0xf7, 0x5a, 0x3a, 0xf3, 0x71, 0xda, 0x96, 0xcb, 0x43, 0xd8, - 0x37, 0x03, 0x8b, 0xb0, 0x34, 0xa2, 0x7e, 0x31, 0x6d, 0xde, 0xae, 0x94, 0x95, 0xac, 0xb1, 0x48, - 0xd5, 0xcb, 0xfb, 0x11, 0xf6, 0xd6, 0x29, 0x2f, 0xa1, 0x84, 0xab, 0x4e, 0x2a, 0x72, 0x33, 0x35, - 0xdc, 0xc0, 0x3d, 0x01, 0xb7, 0xea, 0x3e, 0xab, 0x5b, 0xa3, 0xa8, 0xf4, 0x53, 0xf3, 0x3f, 0xf7, - 0xd3, 0xf0, 0x08, 0xf6, 0x2b, 0x76, 0x6c, 0x43, 0xfb, 0x28, 0x98, 0x87, 0x71, 0xaf, 0x81, 0x01, - 0x76, 0xbf, 0xce, 0x42, 0xc1, 0xb2, 0x1e, 0x92, 0x6b, 0x19, 0x2a, 0xcb, 0x7a, 0x4d, 0xec, 0x80, - 0xa5, 0xa5, 0x09, 0x7a, 0xad, 0xe1, 0x6f, 0x4d, 0xd8, 0x7d, 0xe5, 0x4f, 0xbe, 0xca, 0x03, 0x6e, - 0xe7, 0x45, 0x1f, 0x70, 0xed, 0x17, 0x7b, 0xc0, 0xed, 0x6e, 0x7b, 0xc0, 0x59, 0x15, 0x15, 0xfa, - 0x00, 0x21, 0x2f, 0x9e, 0x05, 0x1d, 0x35, 0x90, 0x4b, 0xc8, 0xf1, 0x3b, 0x4f, 0xaf, 0xfb, 0xe8, - 0xd9, 0x75, 0x1f, 0xfd, 0x75, 0xdd, 0x47, 0xbf, 0xdc, 0xf4, 0x1b, 0xcf, 0x6e, 0xfa, 0x8d, 0x3f, - 0x6e, 0xfa, 0x8d, 0x6f, 0xdb, 0xea, 0xa5, 0x7e, 0xbe, 0xab, 0x1e, 0xe6, 0xf7, 0xff, 0x0d, 0x00, - 0x00, 0xff, 0xff, 0xf9, 0xfe, 0x4f, 0x12, 0xcc, 0x0b, 0x00, 0x00, + // 1048 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x57, 0x4f, 0x6f, 0xe3, 0x54, + 0x10, 0x8f, 0x9d, 0x3f, 0x8e, 0xc7, 0xa1, 0x0d, 0x8f, 0xd5, 0xae, 0xb1, 0x4a, 0x88, 0xc2, 0x0a, + 0x45, 0x08, 0xa5, 0xab, 0xac, 0x90, 0x56, 0x80, 0x2a, 0xda, 0x82, 0x36, 0xa1, 0x1c, 0x56, 0xaf, + 0x5a, 0x10, 0xdc, 0x5e, 0xed, 0x47, 0x6b, 0xad, 0x63, 0x1b, 0xfb, 0xa5, 0x28, 0x17, 0x24, 0x4e, + 0x5c, 0x39, 0x23, 0xc4, 0x17, 0xe1, 0x0b, 0xec, 0xb1, 0x47, 0x6e, 0xa0, 0xf6, 0xce, 0x85, 0x2f, + 0x80, 0xde, 0x1f, 0x3b, 0x8e, 0xe3, 0x46, 0x41, 0xaa, 0x90, 0xf6, 0x10, 0xe9, 0xbd, 0xdf, 0xcc, + 0xbc, 0xcc, 0xcc, 0x6f, 0x66, 0x32, 0x81, 0x47, 0xf1, 0x8b, 0xf3, 0x7d, 0xe2, 0x06, 0xfc, 0xe3, + 0x5e, 0x90, 0xf0, 0x9c, 0xa6, 0xfc, 0x18, 0x9f, 0xed, 0xc7, 0x49, 0xc4, 0xa2, 0xb4, 0x80, 0x8f, + 0x04, 0x82, 0xea, 0xc4, 0x0d, 0x06, 0xa7, 0x60, 0x62, 0xf2, 0xfd, 0xb1, 0x10, 0x20, 0x1b, 0x8c, + 0x98, 0x2c, 0x82, 0x88, 0x78, 0xb6, 0xd6, 0xd7, 0x86, 0x1d, 0x9c, 0x5d, 0xd1, 0x1e, 0x98, 0xa9, + 0x7f, 0x1e, 0x12, 0x36, 0x4f, 0xa8, 0xad, 0x0b, 0xd9, 0x12, 0x40, 0x3b, 0xa0, 0xfb, 0x9e, 0x5d, + 0xef, 0x6b, 0x43, 0x13, 0xeb, 0xbe, 0xa7, 0x1e, 0xc5, 0xd4, 0x8d, 0x12, 0xef, 0xce, 0x1e, 0xfd, + 0xe7, 0x0d, 0x30, 0x0f, 0x8f, 0xbf, 0x50, 0xae, 0xf6, 0xc1, 0x62, 0x09, 0xa5, 0x13, 0x4a, 0xbc, + 0xa9, 0x97, 0xda, 0x5a, 0xbf, 0x3e, 0x34, 0x71, 0x11, 0x42, 0x3d, 0x00, 0xe2, 0x06, 0x99, 0x82, + 0x2e, 0x14, 0x0a, 0x08, 0x7a, 0x17, 0x76, 0xd2, 0x90, 0xc4, 0xe9, 0x45, 0xc4, 0x8e, 0x48, 0x4a, + 0xa7, 0xd9, 0x77, 0x95, 0x50, 0xf4, 0x08, 0x0c, 0xe2, 0x06, 0x9f, 0x12, 0x46, 0xec, 0x46, 0x5f, + 0x1b, 0x5a, 0xe3, 0xfb, 0x23, 0xe2, 0x06, 0xa3, 0xdc, 0x15, 0x7e, 0xe2, 0x52, 0x9c, 0xa9, 0x71, + 0xdf, 0x54, 0xa6, 0x85, 0x55, 0x53, 0x44, 0x56, 0x84, 0xd0, 0x08, 0x90, 0x3b, 0x4f, 0x12, 0x1a, + 0x32, 0x4c, 0x89, 0x77, 0x42, 0x17, 0x13, 0x92, 0x5e, 0xd8, 0xad, 0xbe, 0x36, 0x6c, 0xe0, 0x0a, + 0x09, 0xcf, 0x14, 0xf3, 0x67, 0x34, 0x65, 0x64, 0x16, 0xdb, 0x46, 0x5f, 0x1b, 0xd6, 0xf1, 0x12, + 0x40, 0x0e, 0xb4, 0x7d, 0x8f, 0x86, 0xcc, 0x67, 0x0b, 0xbb, 0x2d, 0x62, 0xc8, 0xef, 0xce, 0x2f, + 0x75, 0xd8, 0xe5, 0xae, 0x46, 0x21, 0xa3, 0x21, 0xfb, 0x92, 0x04, 0x73, 0x8a, 0xc6, 0x60, 0xcc, + 0x53, 0x9a, 0x1c, 0x7a, 0x92, 0x91, 0xf5, 0x88, 0x9e, 0x4b, 0xe9, 0xa4, 0x86, 0x33, 0x45, 0xf4, + 0x11, 0x00, 0x3f, 0x62, 0x3a, 0x8b, 0x2e, 0x25, 0x59, 0xd6, 0xf8, 0xcd, 0x0a, 0x33, 0xa9, 0x30, + 0xa9, 0xe1, 0x82, 0x3a, 0xfa, 0x1a, 0xee, 0xf1, 0xdb, 0x33, 0x9a, 0xcc, 0xfc, 0x34, 0xf5, 0xa3, + 0x50, 0x1a, 0x88, 0x84, 0x5b, 0xe3, 0x77, 0x2a, 0x9e, 0x29, 0xab, 0x4e, 0x6a, 0xb8, 0xf2, 0x89, + 0xcc, 0xaf, 0x69, 0x78, 0xe9, 0x33, 0xaa, 0x08, 0xaa, 0xf2, 0x4b, 0x2a, 0x64, 0x7e, 0xc9, 0x1b, + 0xfa, 0x00, 0xda, 0xfc, 0xf6, 0x79, 0xe4, 0x87, 0x82, 0x25, 0x6b, 0xfc, 0xa0, 0xc2, 0x94, 0x8b, + 0x27, 0x35, 0x9c, 0xab, 0xa2, 0x03, 0xb0, 0xf8, 0xf9, 0x38, 0x0a, 0xbf, 0xf5, 0x93, 0x99, 0xa0, + 0xcd, 0x1a, 0x3b, 0x15, 0x96, 0x4a, 0x63, 0x52, 0xc3, 0x45, 0x83, 0x23, 0x03, 0x9a, 0x97, 0x9c, + 0x08, 0xe7, 0x27, 0x0d, 0x0c, 0x55, 0x3d, 0xe8, 0x63, 0xb0, 0x88, 0x1b, 0x9c, 0xaa, 0xda, 0x53, + 0xc4, 0x38, 0xeb, 0xa5, 0x96, 0x69, 0xe0, 0xa2, 0x3a, 0x3a, 0x10, 0xc5, 0xae, 0x58, 0x16, 0xc5, + 0x6e, 0x8d, 0x7b, 0xeb, 0xc6, 0xc5, 0x32, 0xc0, 0x05, 0x0b, 0xe7, 0x08, 0xac, 0xc2, 0xdb, 0xe8, + 0x31, 0xb4, 0xf9, 0xeb, 0x8c, 0x30, 0xaa, 0x3c, 0x79, 0x50, 0xe1, 0x09, 0x17, 0xe3, 0x5c, 0xd1, + 0xf9, 0x51, 0x87, 0x76, 0x06, 0xa3, 0x87, 0xf0, 0x5a, 0xb2, 0x2c, 0x60, 0x2a, 0x3b, 0xb4, 0x81, + 0x57, 0x41, 0xf4, 0x44, 0xb2, 0x27, 0x4c, 0x52, 0xe5, 0xb6, 0x5d, 0x91, 0x48, 0xf9, 0x55, 0x05, + 0x5d, 0x74, 0x00, 0x86, 0x2f, 0x48, 0x4c, 0xed, 0xba, 0x30, 0x7b, 0x78, 0x8b, 0x83, 0x23, 0xc9, + 0x75, 0xfa, 0x59, 0xc8, 0x92, 0x05, 0xce, 0x8c, 0x9c, 0xe7, 0xd0, 0x29, 0x0a, 0x50, 0x17, 0xea, + 0x2f, 0xe8, 0x42, 0x04, 0x6b, 0x62, 0x7e, 0x44, 0xfb, 0x8a, 0xa5, 0x0d, 0xc5, 0x2e, 0x5f, 0xc0, + 0x52, 0xef, 0x43, 0xfd, 0x89, 0xe6, 0xfc, 0xa9, 0x81, 0x99, 0x3b, 0xbc, 0xd2, 0x98, 0xda, 0x6a, + 0x63, 0xf2, 0x04, 0xd1, 0xd0, 0x4d, 0x16, 0x31, 0xf3, 0xa3, 0xf0, 0x84, 0x2e, 0xd4, 0x00, 0x5c, + 0x05, 0xd1, 0xfb, 0xf0, 0xba, 0x02, 0xa8, 0xa7, 0x06, 0x82, 0x0c, 0xb8, 0x83, 0xd7, 0x05, 0xe8, + 0x13, 0xb0, 0xe2, 0xbc, 0x41, 0x52, 0xd1, 0x0d, 0x3b, 0x6b, 0x65, 0xb0, 0xda, 0x5e, 0x29, 0x2e, + 0x9a, 0xf0, 0xd1, 0x35, 0x4d, 0x55, 0x9d, 0x52, 0x4f, 0x34, 0x45, 0x1b, 0x17, 0x21, 0xe7, 0x77, + 0x0d, 0x0c, 0x35, 0x1f, 0x5e, 0xbd, 0xf8, 0x9c, 0xa7, 0x60, 0x15, 0x1a, 0x73, 0x63, 0x00, 0x7b, + 0x60, 0xaa, 0xe1, 0x37, 0xf5, 0x84, 0xf3, 0x26, 0x5e, 0x02, 0xce, 0xdf, 0x1a, 0xc0, 0xb2, 0x04, + 0xd0, 0x10, 0x76, 0x89, 0xeb, 0xd2, 0x98, 0x3d, 0x9b, 0x9f, 0x05, 0xbe, 0x7b, 0xa2, 0x4a, 0xa9, + 0x83, 0xcb, 0x30, 0x7a, 0x0f, 0xba, 0x2a, 0xb0, 0xa5, 0xaa, 0x4c, 0xcd, 0x1a, 0xfe, 0xbf, 0xb3, + 0xef, 0x40, 0x5b, 0xc6, 0x33, 0x95, 0xd4, 0x9b, 0x38, 0xbf, 0x3b, 0x2f, 0x35, 0x68, 0x67, 0xd3, + 0xf0, 0x0e, 0x88, 0xcf, 0x13, 0x76, 0x9a, 0x6f, 0x00, 0xf5, 0x62, 0xc2, 0x72, 0x18, 0x0d, 0xa0, + 0xb3, 0x1c, 0xd9, 0x53, 0x4f, 0xc4, 0x65, 0xe2, 0x15, 0xac, 0x3a, 0x51, 0xcd, 0x5b, 0x12, 0xe5, + 0x7c, 0x27, 0xa9, 0x53, 0x3f, 0x4e, 0x9b, 0x62, 0x79, 0x0a, 0xbb, 0x6a, 0x60, 0x61, 0x1a, 0x07, + 0xc4, 0xcd, 0xa7, 0xcd, 0x5b, 0xa5, 0xb4, 0xe2, 0x15, 0x2d, 0x5c, 0xb6, 0x72, 0x7e, 0x80, 0x9d, + 0x55, 0x95, 0x3b, 0x48, 0xe1, 0xb2, 0x92, 0xf2, 0xd8, 0x54, 0x0e, 0xd7, 0x70, 0x87, 0xc1, 0xbd, + 0xaa, 0x9f, 0xd5, 0x8d, 0x5e, 0x94, 0xea, 0x49, 0xff, 0xcf, 0xf5, 0x34, 0x38, 0x84, 0xdd, 0x92, + 0x1c, 0x99, 0xd0, 0x3c, 0xf4, 0x66, 0x7e, 0xd8, 0xad, 0x21, 0x80, 0xd6, 0x57, 0x89, 0xcf, 0x68, + 0xd2, 0xd5, 0xf8, 0x99, 0xbb, 0x4a, 0x93, 0xae, 0x8e, 0x2c, 0x30, 0x24, 0x35, 0x5e, 0xb7, 0x3e, + 0xf8, 0x55, 0x87, 0xd6, 0xd6, 0x2b, 0xdf, 0x1e, 0x98, 0xf9, 0x82, 0x97, 0xb5, 0x6c, 0x0e, 0x6c, + 0xbd, 0xf0, 0x95, 0xd6, 0xb7, 0xc6, 0xb6, 0xeb, 0x5b, 0x73, 0xbb, 0xf5, 0xad, 0xb5, 0x69, 0x7d, + 0x33, 0x4a, 0x1c, 0xf4, 0x00, 0xfc, 0x34, 0x5f, 0x0a, 0xda, 0x62, 0x1c, 0x17, 0x90, 0xc1, 0x6f, + 0x1a, 0x4f, 0x9c, 0xd8, 0xb3, 0xef, 0x43, 0x2b, 0x4e, 0xe8, 0xe5, 0xd4, 0x53, 0x44, 0xaa, 0xdb, + 0xca, 0xf3, 0x7a, 0xe9, 0x79, 0x04, 0x0d, 0x8f, 0xc7, 0x28, 0xcb, 0x46, 0x9c, 0x6f, 0x09, 0xae, + 0xb1, 0x5d, 0x70, 0xcd, 0x52, 0x70, 0x47, 0x6f, 0xbf, 0xbc, 0xee, 0x69, 0x57, 0xd7, 0x3d, 0xed, + 0xaf, 0xeb, 0x9e, 0xf6, 0xf3, 0x4d, 0xaf, 0x76, 0x75, 0xd3, 0xab, 0xfd, 0x71, 0xd3, 0xab, 0x7d, + 0xd3, 0x14, 0xff, 0x4e, 0xce, 0x5a, 0xe2, 0xcf, 0xc8, 0xe3, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, + 0xb2, 0xbe, 0xb9, 0x2e, 0xc0, 0x0c, 0x00, 0x00, } func (m *RawChange) Marshal() (dAtA []byte, err error) { @@ -1257,6 +1399,50 @@ func (m *RawChange) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *RawRecord) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RawRecord) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RawRecord) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Id) > 0 { + i -= len(m.Id) + copy(dAtA[i:], m.Id) + i = encodeVarintAclchanges(dAtA, i, uint64(len(m.Id))) + i-- + dAtA[i] = 0x1a + } + if len(m.Signature) > 0 { + i -= len(m.Signature) + copy(dAtA[i:], m.Signature) + i = encodeVarintAclchanges(dAtA, i, uint64(len(m.Signature))) + i-- + dAtA[i] = 0x12 + } + if len(m.Payload) > 0 { + i -= len(m.Payload) + copy(dAtA[i:], m.Payload) + i = encodeVarintAclchanges(dAtA, i, uint64(len(m.Payload))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *ACLChange) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -2115,14 +2301,12 @@ func (m *Change) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x1a } - if len(m.AclHeadIds) > 0 { - for iNdEx := len(m.AclHeadIds) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.AclHeadIds[iNdEx]) - copy(dAtA[i:], m.AclHeadIds[iNdEx]) - i = encodeVarintAclchanges(dAtA, i, uint64(len(m.AclHeadIds[iNdEx]))) - i-- - dAtA[i] = 0x12 - } + if len(m.AclHeadId) > 0 { + i -= len(m.AclHeadId) + copy(dAtA[i:], m.AclHeadId) + i = encodeVarintAclchanges(dAtA, i, uint64(len(m.AclHeadId))) + i-- + dAtA[i] = 0x12 } if len(m.TreeHeadIds) > 0 { for iNdEx := len(m.TreeHeadIds) - 1; iNdEx >= 0; iNdEx-- { @@ -2136,6 +2320,60 @@ func (m *Change) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *Record) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Record) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Record) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Timestamp != 0 { + i = encodeVarintAclchanges(dAtA, i, uint64(m.Timestamp)) + i-- + dAtA[i] = 0x28 + } + if m.CurrentReadKeyHash != 0 { + i = encodeVarintAclchanges(dAtA, i, uint64(m.CurrentReadKeyHash)) + i-- + dAtA[i] = 0x20 + } + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = encodeVarintAclchanges(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0x1a + } + if len(m.Identity) > 0 { + i -= len(m.Identity) + copy(dAtA[i:], m.Identity) + i = encodeVarintAclchanges(dAtA, i, uint64(len(m.Identity))) + i-- + dAtA[i] = 0x12 + } + if len(m.PrevId) > 0 { + i -= len(m.PrevId) + copy(dAtA[i:], m.PrevId) + i = encodeVarintAclchanges(dAtA, i, uint64(len(m.PrevId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintAclchanges(dAtA []byte, offset int, v uint64) int { offset -= sovAclchanges(v) base := offset @@ -2168,6 +2406,27 @@ func (m *RawChange) Size() (n int) { return n } +func (m *RawRecord) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Payload) + if l > 0 { + n += 1 + l + sovAclchanges(uint64(l)) + } + l = len(m.Signature) + if l > 0 { + n += 1 + l + sovAclchanges(uint64(l)) + } + l = len(m.Id) + if l > 0 { + n += 1 + l + sovAclchanges(uint64(l)) + } + return n +} + func (m *ACLChange) Size() (n int) { if m == nil { return 0 @@ -2563,11 +2822,9 @@ func (m *Change) Size() (n int) { n += 1 + l + sovAclchanges(uint64(l)) } } - if len(m.AclHeadIds) > 0 { - for _, s := range m.AclHeadIds { - l = len(s) - n += 1 + l + sovAclchanges(uint64(l)) - } + l = len(m.AclHeadId) + if l > 0 { + n += 1 + l + sovAclchanges(uint64(l)) } l = len(m.SnapshotBaseId) if l > 0 { @@ -2593,6 +2850,33 @@ func (m *Change) Size() (n int) { return n } +func (m *Record) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PrevId) + if l > 0 { + n += 1 + l + sovAclchanges(uint64(l)) + } + l = len(m.Identity) + if l > 0 { + n += 1 + l + sovAclchanges(uint64(l)) + } + l = len(m.Data) + if l > 0 { + n += 1 + l + sovAclchanges(uint64(l)) + } + if m.CurrentReadKeyHash != 0 { + n += 1 + sovAclchanges(uint64(m.CurrentReadKeyHash)) + } + if m.Timestamp != 0 { + n += 1 + sovAclchanges(uint64(m.Timestamp)) + } + return n +} + func sovAclchanges(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -2749,6 +3033,156 @@ func (m *RawChange) Unmarshal(dAtA []byte) error { } return nil } +func (m *RawRecord) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclchanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RawRecord: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RawRecord: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Payload", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclchanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclchanges + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclchanges + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Payload = append(m.Payload[:0], dAtA[iNdEx:postIndex]...) + if m.Payload == nil { + m.Payload = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclchanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclchanges + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclchanges + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signature = append(m.Signature[:0], dAtA[iNdEx:postIndex]...) + if m.Signature == nil { + m.Signature = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclchanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAclchanges + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAclchanges + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Id = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAclchanges(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAclchanges + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *ACLChange) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -5103,7 +5537,7 @@ func (m *Change) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AclHeadIds", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AclHeadId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -5131,7 +5565,7 @@ func (m *Change) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.AclHeadIds = append(m.AclHeadIds, string(dAtA[iNdEx:postIndex])) + m.AclHeadId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { @@ -5310,6 +5744,192 @@ func (m *Change) Unmarshal(dAtA []byte) error { } return nil } +func (m *Record) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclchanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Record: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Record: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PrevId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclchanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAclchanges + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAclchanges + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PrevId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Identity", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclchanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAclchanges + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAclchanges + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Identity = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclchanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAclchanges + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAclchanges + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CurrentReadKeyHash", wireType) + } + m.CurrentReadKeyHash = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclchanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CurrentReadKeyHash |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) + } + m.Timestamp = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAclchanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Timestamp |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipAclchanges(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAclchanges + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipAclchanges(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/pkg/acl/aclchanges/aclpb/protos/aclchanges.proto b/pkg/acl/aclchanges/aclpb/protos/aclchanges.proto index bc464cec..5609ca2f 100644 --- a/pkg/acl/aclchanges/aclpb/protos/aclchanges.proto +++ b/pkg/acl/aclchanges/aclpb/protos/aclchanges.proto @@ -8,6 +8,12 @@ message RawChange { string id = 3; } +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; @@ -112,7 +118,7 @@ message ACLChange { message Change { repeated string treeHeadIds = 1; - repeated string aclHeadIds = 2; + string aclHeadId = 2; string snapshotBaseId = 3; // we will only have one base snapshot for both bytes changesData = 4; uint64 currentReadKeyHash = 5; @@ -120,3 +126,11 @@ message Change { string identity = 7; bool isSnapshot = 8; } + +message Record { + string prevId = 1; + string identity = 2; + bytes data = 3; + uint64 currentReadKeyHash = 4; + int64 timestamp = 5; +} diff --git a/pkg/acl/tree/aclstate.go b/pkg/acl/list/aclstate.go similarity index 88% rename from pkg/acl/tree/aclstate.go rename to pkg/acl/list/aclstate.go index fdd796e0..31c0f464 100644 --- a/pkg/acl/tree/aclstate.go +++ b/pkg/acl/list/aclstate.go @@ -1,17 +1,22 @@ -package tree +package list import ( "bytes" "errors" "fmt" + "github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb" + "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys" "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey" "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey" "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/symmetric" "github.com/gogo/protobuf/proto" + "go.uber.org/zap" "hash/fnv" ) +var log = logger.NewNamed("acllist") + var ErrNoSuchUser = errors.New("no such user") var ErrFailedToDecrypt = errors.New("failed to decrypt key") var ErrUserRemoved = errors.New("user was removed from the document") @@ -23,7 +28,7 @@ type ACLState struct { userReadKeys map[uint64]*symmetric.Key userStates map[string]*aclpb.ACLChangeUserState userInvites map[string]*aclpb.ACLChangeUserInvite - signingPubKeyDecoder signingkey.PubKeyDecoder + signingPubKeyDecoder keys.Decoder encryptionKey encryptionkey.PrivKey identity string } @@ -31,14 +36,14 @@ type ACLState struct { func newACLStateWithIdentity( identity string, encryptionKey encryptionkey.PrivKey, - signingPubKeyDecoder signingkey.PubKeyDecoder) *ACLState { + decoder keys.Decoder) *ACLState { return &ACLState{ identity: identity, encryptionKey: encryptionKey, userReadKeys: make(map[uint64]*symmetric.Key), userStates: make(map[string]*aclpb.ACLChangeUserState), userInvites: make(map[string]*aclpb.ACLChangeUserInvite), - signingPubKeyDecoder: signingPubKeyDecoder, + signingPubKeyDecoder: decoder, } } @@ -50,10 +55,18 @@ func newACLState() *ACLState { } } -func (st *ACLState) applyChange(change *aclpb.Change) (err error) { +func (st *ACLState) CurrentReadKeyHash() uint64 { + return st.currentReadKeyHash +} + +func (st *ACLState) UserReadKeys() map[uint64]*symmetric.Key { + return st.userReadKeys +} + +func (st *ACLState) applyRecord(record *aclpb.Record) (err error) { aclData := &aclpb.ACLChangeACLData{} - err = proto.Unmarshal(change.ChangesData, aclData) + err = proto.Unmarshal(record.Data, aclData) if err != nil { return } @@ -62,27 +75,27 @@ func (st *ACLState) applyChange(change *aclpb.Change) (err error) { if err != nil { return } - st.currentReadKeyHash = change.CurrentReadKeyHash + st.currentReadKeyHash = record.CurrentReadKeyHash }() - return st.applyChangeData(aclData, change.CurrentReadKeyHash, change.Identity) + return st.applyChangeData(aclData, record.CurrentReadKeyHash, record.Identity) } -func (st *ACLState) applyChangeAndUpdate(changeWrapper *Change) (err error) { - change := changeWrapper.Content +func (st *ACLState) applyChangeAndUpdate(recordWrapper *Record) (err error) { + change := recordWrapper.Content aclData := &aclpb.ACLChangeACLData{} - if changeWrapper.ParsedModel != nil { - aclData = changeWrapper.ParsedModel.(*aclpb.ACLChangeACLData) + if recordWrapper.ParsedModel != nil { + aclData = recordWrapper.ParsedModel.(*aclpb.ACLChangeACLData) } else { - err = proto.Unmarshal(change.ChangesData, aclData) + err = proto.Unmarshal(change.Data, aclData) if err != nil { return } - changeWrapper.ParsedModel = aclData + recordWrapper.ParsedModel = aclData } - return st.applyChangeData(aclData, changeWrapper.Content.CurrentReadKeyHash, changeWrapper.Content.Identity) + return st.applyChangeData(aclData, recordWrapper.Content.CurrentReadKeyHash, recordWrapper.Content.Identity) } func (st *ACLState) applyChangeData(changeData *aclpb.ACLChangeACLData, hash uint64, identity string) (err error) { @@ -111,7 +124,7 @@ func (st *ACLState) applyChangeData(changeData *aclpb.ACLChangeACLData, hash uin for _, ch := range changeData.GetAclContent() { if err = st.applyChangeContent(ch); err != nil { - log.Infof("error while applying changes: %v; ignore", err) + log.Info("error while applying changes: %v; ignore", zap.Error(err)) return err } } @@ -174,7 +187,7 @@ func (st *ACLState) applyUserJoin(ch *aclpb.ACLChangeUserJoin) error { return fmt.Errorf("failed to decode signing identity as bytes") } - res, err := verificationKey.Verify(rawSignedId, signature) + res, err := verificationKey.(signingkey.PubKey).Verify(rawSignedId, signature) if err != nil { return fmt.Errorf("verification returned error: %w", err) } diff --git a/pkg/acl/list/aclstatebuilder.go b/pkg/acl/list/aclstatebuilder.go new file mode 100644 index 00000000..51dd9139 --- /dev/null +++ b/pkg/acl/list/aclstatebuilder.go @@ -0,0 +1,51 @@ +package list + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account" + "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys" + "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey" +) + +type aclStateBuilder struct { + log ACLList + identity string + key encryptionkey.PrivKey + decoder keys.Decoder +} + +func newACLStateBuilderWithIdentity(decoder keys.Decoder, accountData *account.AccountData) *aclStateBuilder { + return &aclStateBuilder{ + decoder: decoder, + identity: accountData.Identity, + key: accountData.EncKey, + } +} + +func newACLStateBuilder() *aclStateBuilder { + return &aclStateBuilder{} +} + +func (sb *aclStateBuilder) Init(aclLog ACLList) error { + sb.log = aclLog + return nil +} + +func (sb *aclStateBuilder) Build() (*ACLState, error) { + var ( + err error + state *ACLState + ) + + if sb.decoder != nil { + state = newACLStateWithIdentity(sb.identity, sb.key, sb.decoder) + } else { + state = newACLState() + } + + sb.log.Iterate(func(c *Record) (isContinue bool) { + err = state.applyChangeAndUpdate(c) + return err == nil + }) + + return state, err +} diff --git a/pkg/acl/tree/changebuilder.go b/pkg/acl/list/changebuilder.go similarity index 83% rename from pkg/acl/tree/changebuilder.go rename to pkg/acl/list/changebuilder.go index 98961e4b..c5420b50 100644 --- a/pkg/acl/tree/changebuilder.go +++ b/pkg/acl/list/changebuilder.go @@ -1,4 +1,4 @@ -package tree +package list import ( "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account" @@ -20,7 +20,7 @@ type ACLChangeBuilder interface { type aclChangeBuilder struct { aclState *ACLState - tree *Tree + list ACLList acc *account.AccountData aclData *aclpb.ACLChangeACLData @@ -33,9 +33,9 @@ func newACLChangeBuilder() *aclChangeBuilder { return &aclChangeBuilder{} } -func (c *aclChangeBuilder) Init(state *ACLState, tree *Tree, acc *account.AccountData) { +func (c *aclChangeBuilder) Init(state *ACLState, list ACLList, acc *account.AccountData) { c.aclState = state - c.tree = tree + c.list = list c.acc = acc c.aclData = &aclpb.ACLChangeACLData{} @@ -93,30 +93,25 @@ func (c *aclChangeBuilder) UserAdd(identity string, encryptionKey encryptionkey. return nil } -func (c *aclChangeBuilder) BuildAndApply() (*Change, []byte, error) { - aclChange := &aclpb.Change{ - TreeHeadIds: c.tree.Heads(), - SnapshotBaseId: c.tree.RootId(), +func (c *aclChangeBuilder) BuildAndApply() (*Record, []byte, error) { + aclRecord := &aclpb.Record{ + PrevId: c.list.Last().Id, CurrentReadKeyHash: c.readKeyHash, Timestamp: int64(time.Now().Nanosecond()), Identity: c.acc.Identity, } - if c.aclState.currentReadKeyHash == 0 { - // setting IsSnapshot for initial change - aclChange.IsSnapshot = true - } marshalledData, err := proto.Marshal(c.aclData) if err != nil { return nil, nil, err } - aclChange.ChangesData = marshalledData - err = c.aclState.applyChange(aclChange) + aclRecord.Data = marshalledData + err = c.aclState.applyRecord(aclRecord) if err != nil { return nil, nil, err } - fullMarshalledChange, err := proto.Marshal(aclChange) + fullMarshalledChange, err := proto.Marshal(aclRecord) if err != nil { return nil, nil, err } @@ -128,7 +123,7 @@ func (c *aclChangeBuilder) BuildAndApply() (*Change, []byte, error) { if err != nil { return nil, nil, err } - ch := NewChange(id, aclChange) + ch := NewRecord(id, aclRecord) ch.ParsedModel = c.aclData ch.Sign = signature diff --git a/pkg/acl/list/list.go b/pkg/acl/list/list.go new file mode 100644 index 00000000..420f7e84 --- /dev/null +++ b/pkg/acl/list/list.go @@ -0,0 +1,16 @@ +package list + +import "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/tree" + +type IterFunc = func(record *Record) (IsContinue bool) + +type ACLList interface { + tree.RWLocker + ID() string + ACLState() ACLState + IsAfter(first string, second string) (bool, error) + Last() *Record + Get(id string) (*Record, error) + Iterate(iterFunc IterFunc) + IterateFrom(startId string, iterFunc IterFunc) +} diff --git a/pkg/acl/list/record.go b/pkg/acl/list/record.go new file mode 100644 index 00000000..e20351d2 --- /dev/null +++ b/pkg/acl/list/record.go @@ -0,0 +1,17 @@ +package list + +import "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb" + +type Record struct { + Id string + Content *aclpb.Record + ParsedModel interface{} + Sign []byte +} + +func NewRecord(id string, aclRecord *aclpb.Record) *Record { + return &Record{ + Id: id, + Content: aclRecord, + } +} diff --git a/pkg/acl/tree/aclstatebuilder.go b/pkg/acl/tree/aclstatebuilder.go deleted file mode 100644 index 4fd125e9..00000000 --- a/pkg/acl/tree/aclstatebuilder.go +++ /dev/null @@ -1,102 +0,0 @@ -package tree - -import ( - "fmt" - "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/util/keys/asymmetric/encryptionkey" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey" -) - -type aclStateBuilder struct { - tree *Tree - identity string - key encryptionkey.PrivKey - decoder signingkey.PubKeyDecoder -} - -func newACLStateBuilderWithIdentity(decoder signingkey.PubKeyDecoder, accountData *account.AccountData) *aclStateBuilder { - return &aclStateBuilder{ - decoder: decoder, - identity: accountData.Identity, - key: accountData.EncKey, - } -} - -func newACLStateBuilder() *aclStateBuilder { - return &aclStateBuilder{} -} - -func (sb *aclStateBuilder) Init(tree *Tree) error { - sb.tree = tree - return nil -} - -func (sb *aclStateBuilder) Build() (*ACLState, error) { - state, _, err := sb.BuildBefore("") - return state, err -} - -func (sb *aclStateBuilder) BuildBefore(beforeId string) (*ACLState, bool, error) { - var ( - err error - startChange = sb.tree.root - state *ACLState - foundId = false - ) - - if sb.decoder != nil { - state = newACLStateWithIdentity(sb.identity, sb.key, sb.decoder) - } else { - state = newACLState() - } - - if beforeId == startChange.Id { - return state, true, nil - } - - iterFunc := func(c *Change) (isContinue bool) { - defer func() { - if err == nil { - startChange = c - } else if err != ErrDocumentForbidden { - log.Errorf("marking change %s as invalid: %v", c.Id, err) - sb.tree.RemoveInvalidChange(c.Id) - } - }() - err = state.applyChangeAndUpdate(c) - if err != nil { - return false - } - - // the user can't make changes - if !state.hasPermission(c.Content.Identity, aclpb.ACLChange_Writer) && !state.hasPermission(c.Content.Identity, aclpb.ACLChange_Admin) { - err = fmt.Errorf("user %s cannot make changes", c.Content.Identity) - return false - } - - if c.Id == beforeId { - foundId = true - return false - } - - return true - } - - for { - sb.tree.IterateSkip(sb.tree.root.Id, startChange.Id, iterFunc) - if err == nil { - break - } - - // the user is forbidden to access the document - if err == ErrDocumentForbidden { - return nil, foundId, err - } - - // otherwise we have to continue from the change which we had - err = nil - } - - return state, foundId, err -} diff --git a/pkg/acl/tree/acltree.go b/pkg/acl/tree/acltree.go deleted file mode 100644 index 1fe94285..00000000 --- a/pkg/acl/tree/acltree.go +++ /dev/null @@ -1,525 +0,0 @@ -package tree - -import ( - "context" - "errors" - "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/treestorage" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey" - "go.uber.org/zap" - "sync" -) - -type AddResultSummary int - -var ErrTreeWithoutIdentity = errors.New("acl tree is created without identity") -var ErrHasInvalidChanges = errors.New("the change is invalid") - -const ( - AddResultSummaryNothing AddResultSummary = iota - AddResultSummaryAppend - AddResultSummaryRebuild -) - -type AddResult struct { - OldHeads []string - Heads []string - Added []*aclpb.RawChange - // TODO: add summary for changes - Summary AddResultSummary -} - -type ACLTreeUpdateListener interface { - Update(tree ACLTree) - Rebuild(tree ACLTree) -} - -type NoOpListener struct{} - -func (n NoOpListener) Update(tree ACLTree) {} - -func (n NoOpListener) Rebuild(tree ACLTree) {} - -type RWLocker interface { - sync.Locker - RLock() - RUnlock() -} - -var ErrNoCommonSnapshot = errors.New("trees doesn't have a common snapshot") - -type ACLTree interface { - RWLocker - CommonTree - - ACLState() *ACLState - AddContent(ctx context.Context, f func(builder ACLChangeBuilder) error) (*aclpb.RawChange, error) - AddRawChanges(ctx context.Context, changes ...*aclpb.RawChange) (AddResult, error) -} - -type aclTree struct { - treeStorage treestorage.TreeStorage - accountData *account.AccountData - updateListener ACLTreeUpdateListener - - id string - header *treepb.TreeHeader - tree *Tree - aclState *ACLState - - treeBuilder *treeBuilder - aclStateBuilder *aclStateBuilder - changeBuilder *aclChangeBuilder - - sync.RWMutex -} - -func BuildACLTreeWithIdentity(t treestorage.TreeStorage, acc *account.AccountData, listener ACLTreeUpdateListener) (ACLTree, error) { - treeBuilder := newTreeBuilder(t, acc.Decoder) - aclStateBuilder := newACLStateBuilderWithIdentity(acc.Decoder, acc) - changeBuilder := newACLChangeBuilder() - - aclTree := &aclTree{ - treeStorage: t, - accountData: acc, - tree: nil, - aclState: nil, - treeBuilder: treeBuilder, - aclStateBuilder: aclStateBuilder, - changeBuilder: changeBuilder, - updateListener: listener, - } - err := aclTree.rebuildFromStorage() - if err != nil { - return nil, err - } - err = aclTree.removeOrphans() - if err != nil { - return nil, err - } - err = t.SetHeads(aclTree.Heads()) - if err != nil { - return nil, err - } - aclTree.id, err = t.TreeID() - if err != nil { - return nil, err - } - aclTree.header, err = t.Header() - if err != nil { - return nil, err - } - - if listener != nil { - listener.Rebuild(aclTree) - } - - return aclTree, nil -} - -func BuildACLTree(t treestorage.TreeStorage, decoder signingkey.PubKeyDecoder, listener ACLTreeUpdateListener) (ACLTree, error) { - treeBuilder := newTreeBuilder(t, decoder) - aclStateBuilder := newACLStateBuilder() - changeBuilder := newACLChangeBuilder() - - aclTree := &aclTree{ - treeStorage: t, - tree: nil, - aclState: nil, - treeBuilder: treeBuilder, - aclStateBuilder: aclStateBuilder, - changeBuilder: changeBuilder, - updateListener: listener, - } - err := aclTree.rebuildFromStorage() - if err != nil { - return nil, err - } - err = aclTree.removeOrphans() - if err != nil { - return nil, err - } - err = t.SetHeads(aclTree.Heads()) - if err != nil { - return nil, err - } - aclTree.id, err = t.TreeID() - if err != nil { - return nil, err - } - aclTree.header, err = t.Header() - if err != nil { - return nil, err - } - - if listener != nil { - listener.Rebuild(aclTree) - } - - return aclTree, nil -} - -func (a *aclTree) removeOrphans() error { - // removing attached or invalid orphans - var toRemove []string - - orphans, err := a.treeStorage.Orphans() - if err != nil { - return err - } - for _, orphan := range orphans { - if _, exists := a.tree.attached[orphan]; exists { - toRemove = append(toRemove, orphan) - } - if _, exists := a.tree.invalidChanges[orphan]; exists { - toRemove = append(toRemove, orphan) - } - } - return a.treeStorage.RemoveOrphans(toRemove...) -} - -func (a *aclTree) rebuildFromStorage() (err error) { - a.treeBuilder.Init() - - a.tree, err = a.treeBuilder.Build(true) - if err != nil { - return err - } - - err = a.aclStateBuilder.Init(a.tree) - if err != nil { - return err - } - - a.aclState, err = a.aclStateBuilder.Build() - if err != nil { - return err - } - - return nil -} - -func (a *aclTree) ID() string { - return a.id -} - -func (a *aclTree) Header() *treepb.TreeHeader { - return a.header -} - -func (a *aclTree) ACLState() *ACLState { - return a.aclState -} - -func (a *aclTree) Storage() treestorage.TreeStorage { - return a.treeStorage -} - -func (a *aclTree) AddContent(ctx context.Context, build func(builder ACLChangeBuilder) error) (*aclpb.RawChange, error) { - if a.accountData == nil { - return nil, ErrTreeWithoutIdentity - } - - defer func() { - // TODO: should this be called in a separate goroutine to prevent accidental cycles (tree->updater->tree) - if a.updateListener != nil { - a.updateListener.Update(a) - } - }() - - a.changeBuilder.Init(a.aclState, a.tree, a.accountData) - err := build(a.changeBuilder) - if err != nil { - return nil, err - } - - ch, marshalled, err := a.changeBuilder.BuildAndApply() - if err != nil { - return nil, err - } - a.tree.AddFast(ch) - rawCh := &aclpb.RawChange{ - Payload: marshalled, - Signature: ch.Signature(), - Id: ch.Id, - } - - err = a.treeStorage.AddRawChange(rawCh) - if err != nil { - return nil, err - } - - err = a.treeStorage.SetHeads([]string{ch.Id}) - if err != nil { - return nil, err - } - return rawCh, nil -} - -func (a *aclTree) AddRawChanges(ctx context.Context, rawChanges ...*aclpb.RawChange) (AddResult, error) { - // TODO: make proper error handling, because there are a lot of corner cases where this will break - var err error - var mode Mode - - var changes []*Change // TODO: = addChangesBuf[:0] ... - var notSeenIdx []int - prevHeads := a.tree.Heads() - for idx, ch := range rawChanges { - if a.HasChange(ch.Id) { - continue - } - - change, err := NewFromRawChange(ch) - // TODO: think what if we will have incorrect signatures on rawChanges, how everything will work - if err != nil { - continue - } - changes = append(changes, change) - notSeenIdx = append(notSeenIdx, idx) - } - - if len(notSeenIdx) == 0 { - return AddResult{ - OldHeads: prevHeads, - Heads: prevHeads, - Summary: AddResultSummaryNothing, - }, nil - } - - defer func() { - if err != nil { - return - } - - err = a.removeOrphans() - if err != nil { - return - } - - err = a.treeStorage.SetHeads(a.tree.Heads()) - if err != nil { - return - } - - if a.updateListener == nil { - return - } - - switch mode { - case Append: - a.updateListener.Update(a) - case Rebuild: - a.updateListener.Rebuild(a) - default: - break - } - }() - - getAddedChanges := func() []*aclpb.RawChange { - var added []*aclpb.RawChange - for _, idx := range notSeenIdx { - rawChange := rawChanges[idx] - if _, exists := a.tree.attached[rawChange.Id]; exists { - added = append(added, rawChange) - } - } - return added - } - - for _, ch := range changes { - err = a.treeStorage.AddChange(ch) - if err != nil { - return AddResult{}, err - } - err = a.treeStorage.AddOrphans(ch.Id) - if err != nil { - return AddResult{}, err - } - } - - rebuild := func() (AddResult, error) { - err = a.rebuildFromStorage() - if err != nil { - return AddResult{}, err - } - - return AddResult{ - OldHeads: prevHeads, - Heads: a.tree.Heads(), - Added: getAddedChanges(), - Summary: AddResultSummaryRebuild, - }, nil - } - - mode = a.tree.Add(changes...) - switch mode { - case Nothing: - for _, ch := range changes { - // rebuilding if the snapshot is different from the root - if ch.SnapshotId != a.tree.RootId() && ch.SnapshotId != "" { - return rebuild() - } - } - - return AddResult{ - OldHeads: prevHeads, - Heads: prevHeads, - Summary: AddResultSummaryNothing, - }, nil - - case Rebuild: - return rebuild() - default: - // just rebuilding the state from start without reloading everything from tree storage - // as an optimization we could've started from current heads, but I didn't implement that - a.aclState, err = a.aclStateBuilder.Build() - if err != nil { - return AddResult{}, err - } - - return AddResult{ - OldHeads: prevHeads, - Heads: a.tree.Heads(), - Added: getAddedChanges(), - Summary: AddResultSummaryAppend, - }, nil - } -} - -func (a *aclTree) Iterate(f func(change *Change) bool) { - a.tree.Iterate(a.tree.RootId(), f) -} - -func (a *aclTree) IterateFrom(s string, f func(change *Change) bool) { - a.tree.Iterate(s, f) -} - -func (a *aclTree) HasChange(s string) bool { - _, attachedExists := a.tree.attached[s] - _, unattachedExists := a.tree.unAttached[s] - _, invalidExists := a.tree.invalidChanges[s] - return attachedExists || unattachedExists || invalidExists -} - -func (a *aclTree) Heads() []string { - return a.tree.Heads() -} - -func (a *aclTree) Root() *Change { - return a.tree.Root() -} - -func (a *aclTree) Close() error { - return nil -} - -func (a *aclTree) SnapshotPath() []string { - // TODO: think about caching this - - var path []string - // TODO: think that the user may have not all of the snapshots locally - currentSnapshotId := a.tree.RootId() - for currentSnapshotId != "" { - sn, err := a.treeBuilder.loadChange(currentSnapshotId) - if err != nil { - break - } - path = append(path, currentSnapshotId) - currentSnapshotId = sn.SnapshotId - } - return path -} - -func (a *aclTree) ChangesAfterCommonSnapshot(theirPath []string) ([]*aclpb.RawChange, error) { - // TODO: think about when the clients will have their full acl tree and thus full snapshots - // but no changes after some of the snapshots - - var ( - isNewDocument = len(theirPath) == 0 - ourPath = a.SnapshotPath() - // by default returning everything we have - commonSnapshot = ourPath[len(ourPath)-1] // TODO: root snapshot, probably it is better to have a specific method in treestorage - err error - ) - - // if this is non-empty request - if !isNewDocument { - commonSnapshot, err = commonSnapshotForTwoPaths(ourPath, theirPath) - if err != nil { - return nil, err - } - } - var rawChanges []*aclpb.RawChange - // using custom load function to skip verification step and save raw changes - load := func(id string) (*Change, error) { - raw, err := a.treeStorage.GetChange(context.Background(), id) - if err != nil { - return nil, err - } - - ch, err := NewFromRawChange(raw) - if err != nil { - return nil, err - } - - rawChanges = append(rawChanges, raw) - return ch, nil - } - // we presume that we have everything after the common snapshot, though this may not be the case in case of clients and only ACL tree changes - log.With( - zap.Strings("heads", a.tree.Heads()), - zap.String("breakpoint", commonSnapshot), - zap.String("id", a.id)). - Debug("getting all changes from common snapshot") - _, err = a.treeBuilder.dfs(a.tree.Heads(), commonSnapshot, load) - if err != nil { - return nil, err - } - if isNewDocument { - // adding snapshot to raw changes - _, err = load(commonSnapshot) - if err != nil { - return nil, err - } - } - log.With( - zap.Int("len(changes)", len(rawChanges)), - zap.String("id", a.id)). - Debug("returning all changes after common snapshot") - - return rawChanges, nil -} - -func (a *aclTree) DebugDump() (string, error) { - return a.tree.Graph(ACLDescriptionParser) -} - -func commonSnapshotForTwoPaths(ourPath []string, theirPath []string) (string, error) { - var i int - var j int - log.With(zap.Strings("our path", ourPath), zap.Strings("their path", theirPath)). - Debug("finding common snapshot for two paths") -OuterLoop: - // find starting point from the right - for i = len(ourPath) - 1; i >= 0; i-- { - for j = len(theirPath) - 1; j >= 0; j-- { - // most likely there would be only one comparison, because mostly the snapshot path will start from the root for nodes - if ourPath[i] == theirPath[j] { - break OuterLoop - } - } - } - if i < 0 || j < 0 { - return "", ErrNoCommonSnapshot - } - // find last common element of the sequence moving from right to left - for i >= 0 && j >= 0 { - if ourPath[i] == theirPath[j] { - i-- - j-- - } - } - return ourPath[i+1], nil -} diff --git a/pkg/acl/tree/changevalidator.go b/pkg/acl/tree/changevalidator.go index fc2ec75c..b1161878 100644 --- a/pkg/acl/tree/changevalidator.go +++ b/pkg/acl/tree/changevalidator.go @@ -1,7 +1,9 @@ package tree +import "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/list" + type DocTreeValidator interface { - ValidateTree(tree *Tree, aclTree ACLTree) error + ValidateTree(tree *Tree, aclList list.ACLList) error } type docTreeValidator struct{} @@ -9,7 +11,7 @@ type docTreeValidator struct{} func newTreeValidator() DocTreeValidator { return &docTreeValidator{} } -func (v *docTreeValidator) ValidateTree(tree *Tree, aclTree ACLTree) error { +func (v *docTreeValidator) ValidateTree(tree *Tree, list list.ACLList) error { // TODO: add validation logic where we check that the change refers to correct acl heads // that means that more recent changes should refer to more recent acl heads return nil diff --git a/pkg/acl/tree/descriptionparser.go b/pkg/acl/tree/descriptionparser.go index 367afdec..c7ad3bfe 100644 --- a/pkg/acl/tree/descriptionparser.go +++ b/pkg/acl/tree/descriptionparser.go @@ -1,13 +1,5 @@ package tree -import ( - "fmt" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb" - "github.com/gogo/protobuf/proto" - "strings" - "unicode" -) - type DescriptionParser interface { ParseChange(*Change) ([]string, error) } @@ -19,35 +11,3 @@ type noopDescriptionParser struct{} func (n noopDescriptionParser) ParseChange(change *Change) ([]string, error) { return []string{"DOC"}, nil } - -var ACLDescriptionParser = aclDescriptionParser{} - -type aclDescriptionParser struct{} - -func (a aclDescriptionParser) ParseChange(changeWrapper *Change) (res []string, err error) { - change := changeWrapper.Content - aclData := &aclpb.ACLChangeACLData{} - - if changeWrapper.ParsedModel != nil { - aclData = changeWrapper.ParsedModel.(*aclpb.ACLChangeACLData) - } else { - err = proto.Unmarshal(change.ChangesData, aclData) - if err != nil { - return - } - } - - var chSymbs []string - for _, chc := range aclData.AclContent { - tp := fmt.Sprintf("%T", chc.Value) - tp = strings.Replace(tp, "ACLChangeACLContentValueValueOf", "", 1) - res := "" - for _, ts := range tp { - if unicode.IsUpper(ts) { - res += string(ts) - } - } - chSymbs = append(chSymbs, res) - } - return chSymbs, nil -} diff --git a/pkg/acl/tree/doctree.go b/pkg/acl/tree/doctree.go index e2bc014f..8717cc09 100644 --- a/pkg/acl/tree/doctree.go +++ b/pkg/acl/tree/doctree.go @@ -2,8 +2,10 @@ package tree import ( "context" + "errors" "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/treestorage" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb" "github.com/anytypeio/go-anytype-infrastructure-experiments/util/cid" @@ -20,11 +22,37 @@ type TreeUpdateListener interface { Rebuild(tree DocTree) } +type RWLocker interface { + sync.Locker + RLock() + RUnlock() +} + +var ErrHasInvalidChanges = errors.New("the change is invalid") +var ErrNoCommonSnapshot = errors.New("trees doesn't have a common snapshot") +var ErrTreeWithoutIdentity = errors.New("acl tree is created without identity") + +type AddResultSummary int + +const ( + AddResultSummaryNothing AddResultSummary = iota + AddResultSummaryAppend + AddResultSummaryRebuild +) + +type AddResult struct { + OldHeads []string + Heads []string + Added []*aclpb.RawChange + // TODO: add summary for changes + Summary AddResultSummary +} + type DocTree interface { RWLocker CommonTree - AddContent(ctx context.Context, aclTree ACLTree, content proto.Marshaler, isSnapshot bool) (*aclpb.RawChange, error) - AddRawChanges(ctx context.Context, aclTree ACLTree, changes ...*aclpb.RawChange) (AddResult, error) + AddContent(ctx context.Context, aclList list.ACLList, content proto.Marshaler, isSnapshot bool) (*aclpb.RawChange, error) + AddRawChanges(ctx context.Context, aclList list.ACLList, changes ...*aclpb.RawChange) (AddResult, error) } type docTree struct { @@ -48,7 +76,7 @@ type docTree struct { sync.RWMutex } -func BuildDocTreeWithIdentity(t treestorage.TreeStorage, acc *account.AccountData, listener TreeUpdateListener, aclTree ACLTree) (DocTree, error) { +func BuildDocTreeWithIdentity(t treestorage.TreeStorage, acc *account.AccountData, listener TreeUpdateListener, aclList list.ACLList) (DocTree, error) { treeBuilder := newTreeBuilder(t, acc.Decoder) validator := newTreeValidator() @@ -64,7 +92,7 @@ func BuildDocTreeWithIdentity(t treestorage.TreeStorage, acc *account.AccountDat notSeenIdxBuf: make([]int, 0, 10), identityKeys: make(map[string]signingkey.PubKey), } - err := docTree.rebuildFromStorage(aclTree, nil) + err := docTree.rebuildFromStorage(aclList, nil) if err != nil { return nil, err } @@ -84,7 +112,7 @@ func BuildDocTreeWithIdentity(t treestorage.TreeStorage, acc *account.AccountDat return docTree, nil } -func BuildDocTree(t treestorage.TreeStorage, decoder keys.Decoder, listener TreeUpdateListener, aclTree ACLTree) (DocTree, error) { +func BuildDocTree(t treestorage.TreeStorage, decoder keys.Decoder, listener TreeUpdateListener, aclList list.ACLList) (DocTree, error) { treeBuilder := newTreeBuilder(t, decoder) validator := newTreeValidator() @@ -99,7 +127,7 @@ func BuildDocTree(t treestorage.TreeStorage, decoder keys.Decoder, listener Tree notSeenIdxBuf: make([]int, 0, 10), identityKeys: make(map[string]signingkey.PubKey), } - err := docTree.rebuildFromStorage(aclTree, nil) + err := docTree.rebuildFromStorage(aclList, nil) if err != nil { return nil, err } @@ -119,7 +147,7 @@ func BuildDocTree(t treestorage.TreeStorage, decoder keys.Decoder, listener Tree return docTree, nil } -func (d *docTree) rebuildFromStorage(aclTree ACLTree, newChanges []*Change) (err error) { +func (d *docTree) rebuildFromStorage(aclList list.ACLList, newChanges []*Change) (err error) { d.treeBuilder.Init(d.identityKeys) d.tree, err = d.treeBuilder.Build(false, newChanges) @@ -127,7 +155,7 @@ func (d *docTree) rebuildFromStorage(aclTree ACLTree, newChanges []*Change) (err return err } - return d.validator.ValidateTree(d.tree, aclTree) + return d.validator.ValidateTree(d.tree, aclList) } func (d *docTree) ID() string { @@ -142,7 +170,7 @@ func (d *docTree) Storage() treestorage.TreeStorage { return d.treeStorage } -func (d *docTree) AddContent(ctx context.Context, aclTree ACLTree, content proto.Marshaler, isSnapshot bool) (*aclpb.RawChange, error) { +func (d *docTree) AddContent(ctx context.Context, aclList list.ACLList, content proto.Marshaler, isSnapshot bool) (*aclpb.RawChange, error) { if d.accountData == nil { return nil, ErrTreeWithoutIdentity } @@ -153,12 +181,12 @@ func (d *docTree) AddContent(ctx context.Context, aclTree ACLTree, content proto d.updateListener.Update(d) } }() - state := aclTree.ACLState() + state := aclList.ACLState() change := &aclpb.Change{ TreeHeadIds: d.tree.Heads(), - AclHeadIds: aclTree.Heads(), + AclHeadId: aclList.Last().Id, SnapshotBaseId: d.tree.RootId(), - CurrentReadKeyHash: state.currentReadKeyHash, + CurrentReadKeyHash: state.CurrentReadKeyHash(), Timestamp: int64(time.Now().Nanosecond()), Identity: d.accountData.Identity, IsSnapshot: isSnapshot, @@ -168,7 +196,7 @@ func (d *docTree) AddContent(ctx context.Context, aclTree ACLTree, content proto if err != nil { return nil, err } - encrypted, err := state.userReadKeys[state.currentReadKeyHash].Encrypt(marshalledData) + encrypted, err := state.UserReadKeys()[state.CurrentReadKeyHash()].Encrypt(marshalledData) if err != nil { return nil, err } @@ -213,7 +241,7 @@ func (d *docTree) AddContent(ctx context.Context, aclTree ACLTree, content proto return rawCh, nil } -func (d *docTree) AddRawChanges(ctx context.Context, aclTree ACLTree, rawChanges ...*aclpb.RawChange) (addResult AddResult, err error) { +func (d *docTree) AddRawChanges(ctx context.Context, aclList list.ACLList, rawChanges ...*aclpb.RawChange) (addResult AddResult, err error) { var mode Mode // resetting buffers @@ -300,7 +328,7 @@ func (d *docTree) AddRawChanges(ctx context.Context, aclTree ACLTree, rawChanges // checking if we have some changes with different snapshot and then rebuilding for _, ch := range d.tmpChangesBuf { if ch.SnapshotId != d.tree.RootId() && ch.SnapshotId != "" { - err = d.rebuildFromStorage(aclTree, d.tmpChangesBuf) + err = d.rebuildFromStorage(aclList, d.tmpChangesBuf) if err != nil { return AddResult{}, err } @@ -331,7 +359,7 @@ func (d *docTree) AddRawChanges(ctx context.Context, aclTree ACLTree, rawChanges default: // just rebuilding the state from start without reloading everything from tree storage // as an optimization we could've started from current heads, but I didn't implement that - err = d.validator.ValidateTree(d.tree, aclTree) + err = d.validator.ValidateTree(d.tree, aclList) if err != nil { // rolling back for _, ch := range d.tmpChangesBuf { @@ -366,8 +394,7 @@ func (d *docTree) IterateFrom(s string, f func(change *Change) bool) { func (d *docTree) HasChange(s string) bool { _, attachedExists := d.tree.attached[s] _, unattachedExists := d.tree.unAttached[s] - _, invalidExists := d.tree.invalidChanges[s] - return attachedExists || unattachedExists || invalidExists + return attachedExists || unattachedExists } func (d *docTree) Heads() []string { @@ -462,3 +489,31 @@ func (d *docTree) ChangesAfterCommonSnapshot(theirPath []string) ([]*aclpb.RawCh func (d *docTree) DebugDump() (string, error) { return d.tree.Graph(NoOpDescriptionParser) } + +func commonSnapshotForTwoPaths(ourPath []string, theirPath []string) (string, error) { + var i int + var j int + log.With(zap.Strings("our path", ourPath), zap.Strings("their path", theirPath)). + Debug("finding common snapshot for two paths") +OuterLoop: + // find starting point from the right + for i = len(ourPath) - 1; i >= 0; i-- { + for j = len(theirPath) - 1; j >= 0; j-- { + // most likely there would be only one comparison, because mostly the snapshot path will start from the root for nodes + if ourPath[i] == theirPath[j] { + break OuterLoop + } + } + } + if i < 0 || j < 0 { + return "", ErrNoCommonSnapshot + } + // find last common element of the sequence moving from right to left + for i >= 0 && j >= 0 { + if ourPath[i] == theirPath[j] { + i-- + j-- + } + } + return ourPath[i+1], nil +} diff --git a/pkg/acl/tree/treestorage.go b/pkg/acl/tree/treestorage.go index a407a374..87a3a47d 100644 --- a/pkg/acl/tree/treestorage.go +++ b/pkg/acl/tree/treestorage.go @@ -3,65 +3,66 @@ 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/treestorage" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb" "github.com/anytypeio/go-anytype-infrastructure-experiments/util/cid" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey" "github.com/gogo/protobuf/proto" "time" ) -func CreateNewTreeStorageWithACL( - acc *account.AccountData, - build func(builder ACLChangeBuilder) error, - create treestorage.CreatorFunc) (treestorage.TreeStorage, error) { - bld := newACLChangeBuilder() - bld.Init( - newACLStateWithIdentity(acc.Identity, acc.EncKey, signingkey.NewEd25519PubKeyDecoder()), - &Tree{}, - acc) - err := build(bld) - if err != nil { - return nil, err - } - - change, payload, err := bld.BuildAndApply() - if err != nil { - return nil, err - } - - rawChange := &aclpb.RawChange{ - Payload: payload, - Signature: change.Signature(), - Id: change.CID(), - } - header, id, err := createTreeHeaderAndId(rawChange, treepb.TreeHeader_ACLTree, "") - if err != nil { - return nil, err - } - - thr, err := create(id, header, []*aclpb.RawChange{rawChange}) - if err != nil { - return nil, err - } - - err = thr.SetHeads([]string{change.CID()}) - if err != nil { - return nil, err - } - return thr, nil -} +// +//func CreateNewTreeStorageWithACL( +// acc *account.AccountData, +// build func(builder list.ACLChangeBuilder) error, +// create treestorage.CreatorFunc) (treestorage.TreeStorage, error) { +// bld := list.newACLChangeBuilder() +// bld.Init( +// list.newACLStateWithIdentity(acc.Identity, acc.EncKey, signingkey.NewEd25519PubKeyDecoder()), +// &Tree{}, +// acc) +// err := build(bld) +// if err != nil { +// return nil, err +// } +// +// change, payload, err := bld.BuildAndApply() +// if err != nil { +// return nil, err +// } +// +// rawChange := &aclpb.RawChange{ +// Payload: payload, +// Signature: change.Signature(), +// Id: change.CID(), +// } +// header, id, err := createTreeHeaderAndId(rawChange, treepb.TreeHeader_ACLTree, "") +// if err != nil { +// return nil, err +// } +// +// thr, err := create(id, header, []*aclpb.RawChange{rawChange}) +// if err != nil { +// return nil, err +// } +// +// err = thr.SetHeads([]string{change.CID()}) +// if err != nil { +// return nil, err +// } +// return thr, nil +//} func CreateNewTreeStorage( acc *account.AccountData, - aclTree ACLTree, + aclList list.ACLList, content proto.Marshaler, create treestorage.CreatorFunc) (treestorage.TreeStorage, error) { - state := aclTree.ACLState() + state := aclList.ACLState() change := &aclpb.Change{ - AclHeadIds: aclTree.Heads(), - CurrentReadKeyHash: state.currentReadKeyHash, + AclHeadId: aclList.Last().Id, + CurrentReadKeyHash: state.CurrentReadKeyHash(), Timestamp: int64(time.Now().Nanosecond()), Identity: acc.Identity, IsSnapshot: true, @@ -71,7 +72,7 @@ func CreateNewTreeStorage( if err != nil { return nil, err } - encrypted, err := state.userReadKeys[state.currentReadKeyHash].Encrypt(marshalledData) + encrypted, err := state.UserReadKeys()[state.CurrentReadKeyHash()].Encrypt(marshalledData) if err != nil { return nil, err } @@ -95,7 +96,7 @@ func CreateNewTreeStorage( Signature: signature, Id: changeId, } - header, treeId, err := createTreeHeaderAndId(rawChange, treepb.TreeHeader_DocTree, aclTree.ID()) + header, treeId, err := createTreeHeaderAndId(rawChange, treepb.TreeHeader_DocTree, aclList.ID()) if err != nil { return nil, err } diff --git a/service/document/service.go b/service/document/service.go index 99c0dbcc..ccd4a3aa 100644 --- a/service/document/service.go +++ b/service/document/service.go @@ -6,6 +6,7 @@ import ( "github.com/anytypeio/go-anytype-infrastructure-experiments/app" "github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger" "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/testutils/testchanges/testchangepb" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/tree" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage/treepb" @@ -131,7 +132,7 @@ func (s *service) CreateACLTree(ctx context.Context) (id string, err error) { heads []string ) - t, err := tree.CreateNewTreeStorageWithACL(acc, func(builder tree.ACLChangeBuilder) error { + t, err := tree.CreateNewTreeStorageWithACL(acc, func(builder list.ACLChangeBuilder) error { err := builder.UserAdd(acc.Identity, acc.EncKey.GetPublic(), aclpb.ACLChange_Admin) if err != nil { return err