merge
This commit is contained in:
commit
fa8ac48c2a
5
.gitignore
vendored
5
.gitignore
vendored
@ -8,8 +8,9 @@
|
||||
# Test binary, built with `go test -c`
|
||||
*.test
|
||||
|
||||
# playground folder for testing different clients
|
||||
playground
|
||||
# playground/tmp folder for testing different clients
|
||||
playground/tmp
|
||||
playground/debug.json
|
||||
|
||||
# .paw folder for macos paw client
|
||||
.paw
|
||||
|
||||
1
Makefile
1
Makefile
@ -15,6 +15,7 @@ export PATH=$(GOPATH)/bin:$(shell echo $$PATH)
|
||||
proto:
|
||||
$(MAKE) -C common proto
|
||||
$(MAKE) -C consensus proto
|
||||
$(MAKE) -C client proto
|
||||
|
||||
build:
|
||||
$(MAKE) -C node build
|
||||
|
||||
6
client/Makefile
Normal file
6
client/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
.PHONY: proto
|
||||
export GOPRIVATE=github.com/anytypeio
|
||||
|
||||
proto:
|
||||
@$(eval GOGO_START := GOGO_NO_UNDERSCORE=1 GOGO_EXPORT_ONEOF_INTERFACE=1)
|
||||
$(GOGO_START) protoc --gogofaster_out=:. --go-drpc_out=protolib=github.com/gogo/protobuf:. api/apiproto/protos/*.proto
|
||||
4012
client/api/apiproto/api.pb.go
Normal file
4012
client/api/apiproto/api.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
473
client/api/apiproto/api_drpc.pb.go
Normal file
473
client/api/apiproto/api_drpc.pb.go
Normal file
@ -0,0 +1,473 @@
|
||||
// Code generated by protoc-gen-go-drpc. DO NOT EDIT.
|
||||
// protoc-gen-go-drpc version: v0.0.32
|
||||
// source: api/apiproto/protos/api.proto
|
||||
|
||||
package apiproto
|
||||
|
||||
import (
|
||||
bytes "bytes"
|
||||
context "context"
|
||||
errors "errors"
|
||||
jsonpb "github.com/gogo/protobuf/jsonpb"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
drpc "storj.io/drpc"
|
||||
drpcerr "storj.io/drpc/drpcerr"
|
||||
)
|
||||
|
||||
type drpcEncoding_File_api_apiproto_protos_api_proto struct{}
|
||||
|
||||
func (drpcEncoding_File_api_apiproto_protos_api_proto) Marshal(msg drpc.Message) ([]byte, error) {
|
||||
return proto.Marshal(msg.(proto.Message))
|
||||
}
|
||||
|
||||
func (drpcEncoding_File_api_apiproto_protos_api_proto) Unmarshal(buf []byte, msg drpc.Message) error {
|
||||
return proto.Unmarshal(buf, msg.(proto.Message))
|
||||
}
|
||||
|
||||
func (drpcEncoding_File_api_apiproto_protos_api_proto) JSONMarshal(msg drpc.Message) ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
err := new(jsonpb.Marshaler).Marshal(&buf, msg.(proto.Message))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
func (drpcEncoding_File_api_apiproto_protos_api_proto) JSONUnmarshal(buf []byte, msg drpc.Message) error {
|
||||
return jsonpb.Unmarshal(bytes.NewReader(buf), msg.(proto.Message))
|
||||
}
|
||||
|
||||
type DRPCClientApiClient interface {
|
||||
DRPCConn() drpc.Conn
|
||||
|
||||
CreateSpace(ctx context.Context, in *CreateSpaceRequest) (*CreateSpaceResponse, error)
|
||||
DeriveSpace(ctx context.Context, in *DeriveSpaceRequest) (*DeriveSpaceResponse, error)
|
||||
CreateDocument(ctx context.Context, in *CreateDocumentRequest) (*CreateDocumentResponse, error)
|
||||
DeleteDocument(ctx context.Context, in *DeleteDocumentRequest) (*DeleteDocumentResponse, error)
|
||||
AddText(ctx context.Context, in *AddTextRequest) (*AddTextResponse, error)
|
||||
DumpTree(ctx context.Context, in *DumpTreeRequest) (*DumpTreeResponse, error)
|
||||
TreeParams(ctx context.Context, in *TreeParamsRequest) (*TreeParamsResponse, error)
|
||||
AllTrees(ctx context.Context, in *AllTreesRequest) (*AllTreesResponse, error)
|
||||
AllSpaces(ctx context.Context, in *AllSpacesRequest) (*AllSpacesResponse, error)
|
||||
LoadSpace(ctx context.Context, in *LoadSpaceRequest) (*LoadSpaceResponse, error)
|
||||
}
|
||||
|
||||
type drpcClientApiClient struct {
|
||||
cc drpc.Conn
|
||||
}
|
||||
|
||||
func NewDRPCClientApiClient(cc drpc.Conn) DRPCClientApiClient {
|
||||
return &drpcClientApiClient{cc}
|
||||
}
|
||||
|
||||
func (c *drpcClientApiClient) DRPCConn() drpc.Conn { return c.cc }
|
||||
|
||||
func (c *drpcClientApiClient) CreateSpace(ctx context.Context, in *CreateSpaceRequest) (*CreateSpaceResponse, error) {
|
||||
out := new(CreateSpaceResponse)
|
||||
err := c.cc.Invoke(ctx, "/clientapi.ClientApi/CreateSpace", drpcEncoding_File_api_apiproto_protos_api_proto{}, in, out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *drpcClientApiClient) DeriveSpace(ctx context.Context, in *DeriveSpaceRequest) (*DeriveSpaceResponse, error) {
|
||||
out := new(DeriveSpaceResponse)
|
||||
err := c.cc.Invoke(ctx, "/clientapi.ClientApi/DeriveSpace", drpcEncoding_File_api_apiproto_protos_api_proto{}, in, out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *drpcClientApiClient) CreateDocument(ctx context.Context, in *CreateDocumentRequest) (*CreateDocumentResponse, error) {
|
||||
out := new(CreateDocumentResponse)
|
||||
err := c.cc.Invoke(ctx, "/clientapi.ClientApi/CreateDocument", drpcEncoding_File_api_apiproto_protos_api_proto{}, in, out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *drpcClientApiClient) DeleteDocument(ctx context.Context, in *DeleteDocumentRequest) (*DeleteDocumentResponse, error) {
|
||||
out := new(DeleteDocumentResponse)
|
||||
err := c.cc.Invoke(ctx, "/clientapi.ClientApi/DeleteDocument", drpcEncoding_File_api_apiproto_protos_api_proto{}, in, out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *drpcClientApiClient) AddText(ctx context.Context, in *AddTextRequest) (*AddTextResponse, error) {
|
||||
out := new(AddTextResponse)
|
||||
err := c.cc.Invoke(ctx, "/clientapi.ClientApi/AddText", drpcEncoding_File_api_apiproto_protos_api_proto{}, in, out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *drpcClientApiClient) DumpTree(ctx context.Context, in *DumpTreeRequest) (*DumpTreeResponse, error) {
|
||||
out := new(DumpTreeResponse)
|
||||
err := c.cc.Invoke(ctx, "/clientapi.ClientApi/DumpTree", drpcEncoding_File_api_apiproto_protos_api_proto{}, in, out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *drpcClientApiClient) TreeParams(ctx context.Context, in *TreeParamsRequest) (*TreeParamsResponse, error) {
|
||||
out := new(TreeParamsResponse)
|
||||
err := c.cc.Invoke(ctx, "/clientapi.ClientApi/TreeParams", drpcEncoding_File_api_apiproto_protos_api_proto{}, in, out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *drpcClientApiClient) AllTrees(ctx context.Context, in *AllTreesRequest) (*AllTreesResponse, error) {
|
||||
out := new(AllTreesResponse)
|
||||
err := c.cc.Invoke(ctx, "/clientapi.ClientApi/AllTrees", drpcEncoding_File_api_apiproto_protos_api_proto{}, in, out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *drpcClientApiClient) AllSpaces(ctx context.Context, in *AllSpacesRequest) (*AllSpacesResponse, error) {
|
||||
out := new(AllSpacesResponse)
|
||||
err := c.cc.Invoke(ctx, "/clientapi.ClientApi/AllSpaces", drpcEncoding_File_api_apiproto_protos_api_proto{}, in, out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *drpcClientApiClient) LoadSpace(ctx context.Context, in *LoadSpaceRequest) (*LoadSpaceResponse, error) {
|
||||
out := new(LoadSpaceResponse)
|
||||
err := c.cc.Invoke(ctx, "/clientapi.ClientApi/LoadSpace", drpcEncoding_File_api_apiproto_protos_api_proto{}, in, out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
type DRPCClientApiServer interface {
|
||||
CreateSpace(context.Context, *CreateSpaceRequest) (*CreateSpaceResponse, error)
|
||||
DeriveSpace(context.Context, *DeriveSpaceRequest) (*DeriveSpaceResponse, error)
|
||||
CreateDocument(context.Context, *CreateDocumentRequest) (*CreateDocumentResponse, error)
|
||||
DeleteDocument(context.Context, *DeleteDocumentRequest) (*DeleteDocumentResponse, error)
|
||||
AddText(context.Context, *AddTextRequest) (*AddTextResponse, error)
|
||||
DumpTree(context.Context, *DumpTreeRequest) (*DumpTreeResponse, error)
|
||||
TreeParams(context.Context, *TreeParamsRequest) (*TreeParamsResponse, error)
|
||||
AllTrees(context.Context, *AllTreesRequest) (*AllTreesResponse, error)
|
||||
AllSpaces(context.Context, *AllSpacesRequest) (*AllSpacesResponse, error)
|
||||
LoadSpace(context.Context, *LoadSpaceRequest) (*LoadSpaceResponse, error)
|
||||
}
|
||||
|
||||
type DRPCClientApiUnimplementedServer struct{}
|
||||
|
||||
func (s *DRPCClientApiUnimplementedServer) CreateSpace(context.Context, *CreateSpaceRequest) (*CreateSpaceResponse, error) {
|
||||
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
|
||||
}
|
||||
|
||||
func (s *DRPCClientApiUnimplementedServer) DeriveSpace(context.Context, *DeriveSpaceRequest) (*DeriveSpaceResponse, error) {
|
||||
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
|
||||
}
|
||||
|
||||
func (s *DRPCClientApiUnimplementedServer) CreateDocument(context.Context, *CreateDocumentRequest) (*CreateDocumentResponse, error) {
|
||||
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
|
||||
}
|
||||
|
||||
func (s *DRPCClientApiUnimplementedServer) DeleteDocument(context.Context, *DeleteDocumentRequest) (*DeleteDocumentResponse, error) {
|
||||
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
|
||||
}
|
||||
|
||||
func (s *DRPCClientApiUnimplementedServer) AddText(context.Context, *AddTextRequest) (*AddTextResponse, error) {
|
||||
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
|
||||
}
|
||||
|
||||
func (s *DRPCClientApiUnimplementedServer) DumpTree(context.Context, *DumpTreeRequest) (*DumpTreeResponse, error) {
|
||||
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
|
||||
}
|
||||
|
||||
func (s *DRPCClientApiUnimplementedServer) TreeParams(context.Context, *TreeParamsRequest) (*TreeParamsResponse, error) {
|
||||
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
|
||||
}
|
||||
|
||||
func (s *DRPCClientApiUnimplementedServer) AllTrees(context.Context, *AllTreesRequest) (*AllTreesResponse, error) {
|
||||
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
|
||||
}
|
||||
|
||||
func (s *DRPCClientApiUnimplementedServer) AllSpaces(context.Context, *AllSpacesRequest) (*AllSpacesResponse, error) {
|
||||
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
|
||||
}
|
||||
|
||||
func (s *DRPCClientApiUnimplementedServer) LoadSpace(context.Context, *LoadSpaceRequest) (*LoadSpaceResponse, error) {
|
||||
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
|
||||
}
|
||||
|
||||
type DRPCClientApiDescription struct{}
|
||||
|
||||
func (DRPCClientApiDescription) NumMethods() int { return 10 }
|
||||
|
||||
func (DRPCClientApiDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver, interface{}, bool) {
|
||||
switch n {
|
||||
case 0:
|
||||
return "/clientapi.ClientApi/CreateSpace", drpcEncoding_File_api_apiproto_protos_api_proto{},
|
||||
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
|
||||
return srv.(DRPCClientApiServer).
|
||||
CreateSpace(
|
||||
ctx,
|
||||
in1.(*CreateSpaceRequest),
|
||||
)
|
||||
}, DRPCClientApiServer.CreateSpace, true
|
||||
case 1:
|
||||
return "/clientapi.ClientApi/DeriveSpace", drpcEncoding_File_api_apiproto_protos_api_proto{},
|
||||
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
|
||||
return srv.(DRPCClientApiServer).
|
||||
DeriveSpace(
|
||||
ctx,
|
||||
in1.(*DeriveSpaceRequest),
|
||||
)
|
||||
}, DRPCClientApiServer.DeriveSpace, true
|
||||
case 2:
|
||||
return "/clientapi.ClientApi/CreateDocument", drpcEncoding_File_api_apiproto_protos_api_proto{},
|
||||
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
|
||||
return srv.(DRPCClientApiServer).
|
||||
CreateDocument(
|
||||
ctx,
|
||||
in1.(*CreateDocumentRequest),
|
||||
)
|
||||
}, DRPCClientApiServer.CreateDocument, true
|
||||
case 3:
|
||||
return "/clientapi.ClientApi/DeleteDocument", drpcEncoding_File_api_apiproto_protos_api_proto{},
|
||||
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
|
||||
return srv.(DRPCClientApiServer).
|
||||
DeleteDocument(
|
||||
ctx,
|
||||
in1.(*DeleteDocumentRequest),
|
||||
)
|
||||
}, DRPCClientApiServer.DeleteDocument, true
|
||||
case 4:
|
||||
return "/clientapi.ClientApi/AddText", drpcEncoding_File_api_apiproto_protos_api_proto{},
|
||||
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
|
||||
return srv.(DRPCClientApiServer).
|
||||
AddText(
|
||||
ctx,
|
||||
in1.(*AddTextRequest),
|
||||
)
|
||||
}, DRPCClientApiServer.AddText, true
|
||||
case 5:
|
||||
return "/clientapi.ClientApi/DumpTree", drpcEncoding_File_api_apiproto_protos_api_proto{},
|
||||
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
|
||||
return srv.(DRPCClientApiServer).
|
||||
DumpTree(
|
||||
ctx,
|
||||
in1.(*DumpTreeRequest),
|
||||
)
|
||||
}, DRPCClientApiServer.DumpTree, true
|
||||
case 6:
|
||||
return "/clientapi.ClientApi/TreeParams", drpcEncoding_File_api_apiproto_protos_api_proto{},
|
||||
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
|
||||
return srv.(DRPCClientApiServer).
|
||||
TreeParams(
|
||||
ctx,
|
||||
in1.(*TreeParamsRequest),
|
||||
)
|
||||
}, DRPCClientApiServer.TreeParams, true
|
||||
case 7:
|
||||
return "/clientapi.ClientApi/AllTrees", drpcEncoding_File_api_apiproto_protos_api_proto{},
|
||||
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
|
||||
return srv.(DRPCClientApiServer).
|
||||
AllTrees(
|
||||
ctx,
|
||||
in1.(*AllTreesRequest),
|
||||
)
|
||||
}, DRPCClientApiServer.AllTrees, true
|
||||
case 8:
|
||||
return "/clientapi.ClientApi/AllSpaces", drpcEncoding_File_api_apiproto_protos_api_proto{},
|
||||
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
|
||||
return srv.(DRPCClientApiServer).
|
||||
AllSpaces(
|
||||
ctx,
|
||||
in1.(*AllSpacesRequest),
|
||||
)
|
||||
}, DRPCClientApiServer.AllSpaces, true
|
||||
case 9:
|
||||
return "/clientapi.ClientApi/LoadSpace", drpcEncoding_File_api_apiproto_protos_api_proto{},
|
||||
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
|
||||
return srv.(DRPCClientApiServer).
|
||||
LoadSpace(
|
||||
ctx,
|
||||
in1.(*LoadSpaceRequest),
|
||||
)
|
||||
}, DRPCClientApiServer.LoadSpace, true
|
||||
default:
|
||||
return "", nil, nil, nil, false
|
||||
}
|
||||
}
|
||||
|
||||
func DRPCRegisterClientApi(mux drpc.Mux, impl DRPCClientApiServer) error {
|
||||
return mux.Register(impl, DRPCClientApiDescription{})
|
||||
}
|
||||
|
||||
type DRPCClientApi_CreateSpaceStream interface {
|
||||
drpc.Stream
|
||||
SendAndClose(*CreateSpaceResponse) error
|
||||
}
|
||||
|
||||
type drpcClientApi_CreateSpaceStream struct {
|
||||
drpc.Stream
|
||||
}
|
||||
|
||||
func (x *drpcClientApi_CreateSpaceStream) SendAndClose(m *CreateSpaceResponse) error {
|
||||
if err := x.MsgSend(m, drpcEncoding_File_api_apiproto_protos_api_proto{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return x.CloseSend()
|
||||
}
|
||||
|
||||
type DRPCClientApi_DeriveSpaceStream interface {
|
||||
drpc.Stream
|
||||
SendAndClose(*DeriveSpaceResponse) error
|
||||
}
|
||||
|
||||
type drpcClientApi_DeriveSpaceStream struct {
|
||||
drpc.Stream
|
||||
}
|
||||
|
||||
func (x *drpcClientApi_DeriveSpaceStream) SendAndClose(m *DeriveSpaceResponse) error {
|
||||
if err := x.MsgSend(m, drpcEncoding_File_api_apiproto_protos_api_proto{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return x.CloseSend()
|
||||
}
|
||||
|
||||
type DRPCClientApi_CreateDocumentStream interface {
|
||||
drpc.Stream
|
||||
SendAndClose(*CreateDocumentResponse) error
|
||||
}
|
||||
|
||||
type drpcClientApi_CreateDocumentStream struct {
|
||||
drpc.Stream
|
||||
}
|
||||
|
||||
func (x *drpcClientApi_CreateDocumentStream) SendAndClose(m *CreateDocumentResponse) error {
|
||||
if err := x.MsgSend(m, drpcEncoding_File_api_apiproto_protos_api_proto{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return x.CloseSend()
|
||||
}
|
||||
|
||||
type DRPCClientApi_DeleteDocumentStream interface {
|
||||
drpc.Stream
|
||||
SendAndClose(*DeleteDocumentResponse) error
|
||||
}
|
||||
|
||||
type drpcClientApi_DeleteDocumentStream struct {
|
||||
drpc.Stream
|
||||
}
|
||||
|
||||
func (x *drpcClientApi_DeleteDocumentStream) SendAndClose(m *DeleteDocumentResponse) error {
|
||||
if err := x.MsgSend(m, drpcEncoding_File_api_apiproto_protos_api_proto{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return x.CloseSend()
|
||||
}
|
||||
|
||||
type DRPCClientApi_AddTextStream interface {
|
||||
drpc.Stream
|
||||
SendAndClose(*AddTextResponse) error
|
||||
}
|
||||
|
||||
type drpcClientApi_AddTextStream struct {
|
||||
drpc.Stream
|
||||
}
|
||||
|
||||
func (x *drpcClientApi_AddTextStream) SendAndClose(m *AddTextResponse) error {
|
||||
if err := x.MsgSend(m, drpcEncoding_File_api_apiproto_protos_api_proto{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return x.CloseSend()
|
||||
}
|
||||
|
||||
type DRPCClientApi_DumpTreeStream interface {
|
||||
drpc.Stream
|
||||
SendAndClose(*DumpTreeResponse) error
|
||||
}
|
||||
|
||||
type drpcClientApi_DumpTreeStream struct {
|
||||
drpc.Stream
|
||||
}
|
||||
|
||||
func (x *drpcClientApi_DumpTreeStream) SendAndClose(m *DumpTreeResponse) error {
|
||||
if err := x.MsgSend(m, drpcEncoding_File_api_apiproto_protos_api_proto{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return x.CloseSend()
|
||||
}
|
||||
|
||||
type DRPCClientApi_TreeParamsStream interface {
|
||||
drpc.Stream
|
||||
SendAndClose(*TreeParamsResponse) error
|
||||
}
|
||||
|
||||
type drpcClientApi_TreeParamsStream struct {
|
||||
drpc.Stream
|
||||
}
|
||||
|
||||
func (x *drpcClientApi_TreeParamsStream) SendAndClose(m *TreeParamsResponse) error {
|
||||
if err := x.MsgSend(m, drpcEncoding_File_api_apiproto_protos_api_proto{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return x.CloseSend()
|
||||
}
|
||||
|
||||
type DRPCClientApi_AllTreesStream interface {
|
||||
drpc.Stream
|
||||
SendAndClose(*AllTreesResponse) error
|
||||
}
|
||||
|
||||
type drpcClientApi_AllTreesStream struct {
|
||||
drpc.Stream
|
||||
}
|
||||
|
||||
func (x *drpcClientApi_AllTreesStream) SendAndClose(m *AllTreesResponse) error {
|
||||
if err := x.MsgSend(m, drpcEncoding_File_api_apiproto_protos_api_proto{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return x.CloseSend()
|
||||
}
|
||||
|
||||
type DRPCClientApi_AllSpacesStream interface {
|
||||
drpc.Stream
|
||||
SendAndClose(*AllSpacesResponse) error
|
||||
}
|
||||
|
||||
type drpcClientApi_AllSpacesStream struct {
|
||||
drpc.Stream
|
||||
}
|
||||
|
||||
func (x *drpcClientApi_AllSpacesStream) SendAndClose(m *AllSpacesResponse) error {
|
||||
if err := x.MsgSend(m, drpcEncoding_File_api_apiproto_protos_api_proto{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return x.CloseSend()
|
||||
}
|
||||
|
||||
type DRPCClientApi_LoadSpaceStream interface {
|
||||
drpc.Stream
|
||||
SendAndClose(*LoadSpaceResponse) error
|
||||
}
|
||||
|
||||
type drpcClientApi_LoadSpaceStream struct {
|
||||
drpc.Stream
|
||||
}
|
||||
|
||||
func (x *drpcClientApi_LoadSpaceStream) SendAndClose(m *LoadSpaceResponse) error {
|
||||
if err := x.MsgSend(m, drpcEncoding_File_api_apiproto_protos_api_proto{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return x.CloseSend()
|
||||
}
|
||||
106
client/api/apiproto/protos/api.proto
Normal file
106
client/api/apiproto/protos/api.proto
Normal file
@ -0,0 +1,106 @@
|
||||
syntax = "proto3";
|
||||
package clientapi;
|
||||
|
||||
option go_package = "api/apiproto";
|
||||
|
||||
service ClientApi {
|
||||
rpc CreateSpace(CreateSpaceRequest) returns(CreateSpaceResponse);
|
||||
rpc DeriveSpace(DeriveSpaceRequest) returns(DeriveSpaceResponse);
|
||||
rpc CreateDocument(CreateDocumentRequest) returns(CreateDocumentResponse);
|
||||
rpc DeleteDocument(DeleteDocumentRequest) returns(DeleteDocumentResponse);
|
||||
rpc AddText(AddTextRequest) returns(AddTextResponse);
|
||||
rpc DumpTree(DumpTreeRequest) returns(DumpTreeResponse);
|
||||
rpc TreeParams(TreeParamsRequest) returns(TreeParamsResponse);
|
||||
rpc AllTrees(AllTreesRequest) returns(AllTreesResponse);
|
||||
rpc AllSpaces(AllSpacesRequest) returns(AllSpacesResponse);
|
||||
rpc LoadSpace(LoadSpaceRequest) returns(LoadSpaceResponse);
|
||||
}
|
||||
|
||||
message CreateSpaceRequest {
|
||||
}
|
||||
|
||||
message CreateSpaceResponse {
|
||||
string id = 1;
|
||||
}
|
||||
|
||||
message DeriveSpaceRequest {
|
||||
}
|
||||
|
||||
message DeriveSpaceResponse {
|
||||
string id = 1;
|
||||
}
|
||||
|
||||
message CreateDocumentRequest {
|
||||
string spaceId = 1;
|
||||
}
|
||||
|
||||
message CreateDocumentResponse {
|
||||
string id = 1;
|
||||
}
|
||||
|
||||
message DeleteDocumentRequest {
|
||||
string spaceId = 1;
|
||||
string documentId = 2;
|
||||
}
|
||||
|
||||
message DeleteDocumentResponse {
|
||||
}
|
||||
|
||||
message AddTextRequest {
|
||||
string spaceId = 1;
|
||||
string documentId = 2;
|
||||
string text = 3;
|
||||
bool isSnapshot = 4;
|
||||
}
|
||||
|
||||
message AddTextResponse {
|
||||
string documentId = 1;
|
||||
string headId = 2;
|
||||
string rootId = 3;
|
||||
}
|
||||
|
||||
message DumpTreeRequest {
|
||||
string spaceId = 1;
|
||||
string documentId = 2;
|
||||
}
|
||||
|
||||
message DumpTreeResponse {
|
||||
string dump = 1;
|
||||
}
|
||||
|
||||
message AllTreesRequest {
|
||||
string spaceId = 1;
|
||||
}
|
||||
|
||||
message Tree {
|
||||
string id = 1;
|
||||
repeated string heads = 2;
|
||||
}
|
||||
|
||||
message AllTreesResponse {
|
||||
repeated Tree trees = 1;
|
||||
}
|
||||
|
||||
message AllSpacesRequest {
|
||||
}
|
||||
|
||||
message AllSpacesResponse {
|
||||
repeated string spaceIds = 1;
|
||||
}
|
||||
|
||||
message LoadSpaceRequest {
|
||||
string spaceId = 1;
|
||||
}
|
||||
|
||||
message LoadSpaceResponse {
|
||||
}
|
||||
|
||||
message TreeParamsRequest {
|
||||
string spaceId = 1;
|
||||
string documentId = 2;
|
||||
}
|
||||
|
||||
message TreeParamsResponse {
|
||||
string rootId = 1;
|
||||
repeated string headIds = 2;
|
||||
}
|
||||
@ -1,125 +0,0 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/client/clientspace"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/client/document"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/client/storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/account"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/symmetric"
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
type Controller interface {
|
||||
// DeriveSpace derives the space from current account
|
||||
DeriveSpace() (id string, err error)
|
||||
// CreateSpace creates new space with random data
|
||||
CreateSpace() (id string, err error)
|
||||
// AllSpaceIds returns ids of all spaces
|
||||
AllSpaceIds() (ids []string, err error)
|
||||
// LoadSpace asks node to load a particular space
|
||||
LoadSpace(id string) (err error)
|
||||
|
||||
// CreateDocument creates new document in space
|
||||
CreateDocument(spaceId string) (id string, err error)
|
||||
// AllDocumentIds gets all ids of documents in space
|
||||
AllDocumentIds(spaceId string) (ids []string, err error)
|
||||
// AddText adds text to space document
|
||||
AddText(spaceId, documentId, text string) (err error)
|
||||
// DumpDocumentTree dumps the tree data into string
|
||||
DumpDocumentTree(spaceId, documentId string) (dump string, err error)
|
||||
|
||||
ValidInvites(spaceId string) (invites []string, err error)
|
||||
GenerateInvite(spaceId string) (invite string, err error)
|
||||
JoinSpace(invite string) (err error)
|
||||
}
|
||||
|
||||
type controller struct {
|
||||
spaceService clientspace.Service
|
||||
storageService storage.ClientStorage
|
||||
docService document.Service
|
||||
account account.Service
|
||||
}
|
||||
|
||||
func newController(spaceService clientspace.Service,
|
||||
storageService storage.ClientStorage,
|
||||
docService document.Service,
|
||||
account account.Service) Controller {
|
||||
return &controller{
|
||||
spaceService: spaceService,
|
||||
storageService: storageService,
|
||||
docService: docService,
|
||||
account: account,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *controller) DeriveSpace() (id string, err error) {
|
||||
sp, err := c.spaceService.DeriveSpace(context.Background(), commonspace.SpaceDerivePayload{
|
||||
SigningKey: c.account.Account().SignKey,
|
||||
EncryptionKey: c.account.Account().EncKey,
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
id = sp.Id()
|
||||
return
|
||||
}
|
||||
|
||||
func (c *controller) CreateSpace() (id string, err error) {
|
||||
key, err := symmetric.NewRandom()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
sp, err := c.spaceService.CreateSpace(context.Background(), commonspace.SpaceCreatePayload{
|
||||
SigningKey: c.account.Account().SignKey,
|
||||
EncryptionKey: c.account.Account().EncKey,
|
||||
ReadKey: key.Bytes(),
|
||||
ReplicationKey: rand.Uint64(),
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
id = sp.Id()
|
||||
return
|
||||
}
|
||||
|
||||
func (c *controller) AllSpaceIds() (ids []string, err error) {
|
||||
return c.storageService.AllSpaceIds()
|
||||
}
|
||||
|
||||
func (c *controller) LoadSpace(id string) (err error) {
|
||||
_, err = c.spaceService.GetSpace(context.Background(), id)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *controller) CreateDocument(spaceId string) (id string, err error) {
|
||||
return c.docService.CreateDocument(spaceId)
|
||||
}
|
||||
|
||||
func (c *controller) AllDocumentIds(spaceId string) (ids []string, err error) {
|
||||
return c.docService.AllDocumentIds(spaceId)
|
||||
}
|
||||
|
||||
func (c *controller) AddText(spaceId, documentId, text string) (err error) {
|
||||
return c.docService.AddText(spaceId, documentId, text)
|
||||
}
|
||||
|
||||
func (c *controller) DumpDocumentTree(spaceId, documentId string) (dump string, err error) {
|
||||
return c.docService.DumpDocumentTree(spaceId, documentId)
|
||||
}
|
||||
|
||||
func (c *controller) ValidInvites(spaceId string) (invites []string, err error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (c *controller) GenerateInvite(spaceId string) (invite string, err error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (c *controller) JoinSpace(invite string) (err error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
}
|
||||
146
client/api/rpchandler.go
Normal file
146
client/api/rpchandler.go
Normal file
@ -0,0 +1,146 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/client/api/apiproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/client/clientspace"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/client/document"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/client/storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/account"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/symmetric"
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
type rpcHandler struct {
|
||||
spaceService clientspace.Service
|
||||
storageService storage.ClientStorage
|
||||
docService document.Service
|
||||
account account.Service
|
||||
}
|
||||
|
||||
func (r *rpcHandler) LoadSpace(ctx context.Context, request *apiproto.LoadSpaceRequest) (resp *apiproto.LoadSpaceResponse, err error) {
|
||||
_, err = r.spaceService.GetSpace(context.Background(), request.SpaceId)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
resp = &apiproto.LoadSpaceResponse{}
|
||||
return
|
||||
}
|
||||
|
||||
func (r *rpcHandler) CreateSpace(ctx context.Context, request *apiproto.CreateSpaceRequest) (resp *apiproto.CreateSpaceResponse, err error) {
|
||||
key, err := symmetric.NewRandom()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
sp, err := r.spaceService.CreateSpace(context.Background(), commonspace.SpaceCreatePayload{
|
||||
SigningKey: r.account.Account().SignKey,
|
||||
EncryptionKey: r.account.Account().EncKey,
|
||||
ReadKey: key.Bytes(),
|
||||
ReplicationKey: rand.Uint64(),
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
id := sp.Id()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
resp = &apiproto.CreateSpaceResponse{Id: id}
|
||||
return
|
||||
}
|
||||
|
||||
func (r *rpcHandler) DeriveSpace(ctx context.Context, request *apiproto.DeriveSpaceRequest) (resp *apiproto.DeriveSpaceResponse, err error) {
|
||||
sp, err := r.spaceService.DeriveSpace(context.Background(), commonspace.SpaceDerivePayload{
|
||||
SigningKey: r.account.Account().SignKey,
|
||||
EncryptionKey: r.account.Account().EncKey,
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
id := sp.Id()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
resp = &apiproto.DeriveSpaceResponse{Id: id}
|
||||
return
|
||||
}
|
||||
|
||||
func (r *rpcHandler) CreateDocument(ctx context.Context, request *apiproto.CreateDocumentRequest) (resp *apiproto.CreateDocumentResponse, err error) {
|
||||
id, err := r.docService.CreateDocument(request.SpaceId)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
resp = &apiproto.CreateDocumentResponse{Id: id}
|
||||
return
|
||||
}
|
||||
|
||||
func (r *rpcHandler) DeleteDocument(ctx context.Context, request *apiproto.DeleteDocumentRequest) (resp *apiproto.DeleteDocumentResponse, err error) {
|
||||
err = r.docService.DeleteDocument(request.SpaceId, request.DocumentId)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
resp = &apiproto.DeleteDocumentResponse{}
|
||||
return
|
||||
}
|
||||
|
||||
func (r *rpcHandler) AddText(ctx context.Context, request *apiproto.AddTextRequest) (resp *apiproto.AddTextResponse, err error) {
|
||||
root, head, err := r.docService.AddText(request.SpaceId, request.DocumentId, request.Text, request.IsSnapshot)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
resp = &apiproto.AddTextResponse{
|
||||
DocumentId: request.DocumentId,
|
||||
HeadId: head,
|
||||
RootId: root,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (r *rpcHandler) DumpTree(ctx context.Context, request *apiproto.DumpTreeRequest) (resp *apiproto.DumpTreeResponse, err error) {
|
||||
dump, err := r.docService.DumpDocumentTree(request.SpaceId, request.DocumentId)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
resp = &apiproto.DumpTreeResponse{
|
||||
Dump: dump,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (r *rpcHandler) AllTrees(ctx context.Context, request *apiproto.AllTreesRequest) (resp *apiproto.AllTreesResponse, err error) {
|
||||
heads, err := r.docService.AllDocumentHeads(request.SpaceId)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var trees []*apiproto.Tree
|
||||
for _, head := range heads {
|
||||
trees = append(trees, &apiproto.Tree{
|
||||
Id: head.Id,
|
||||
Heads: head.Heads,
|
||||
})
|
||||
}
|
||||
resp = &apiproto.AllTreesResponse{Trees: trees}
|
||||
return
|
||||
}
|
||||
|
||||
func (r *rpcHandler) AllSpaces(ctx context.Context, request *apiproto.AllSpacesRequest) (resp *apiproto.AllSpacesResponse, err error) {
|
||||
ids, err := r.storageService.AllSpaceIds()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
resp = &apiproto.AllSpacesResponse{SpaceIds: ids}
|
||||
return
|
||||
}
|
||||
|
||||
func (r *rpcHandler) TreeParams(ctx context.Context, request *apiproto.TreeParamsRequest) (resp *apiproto.TreeParamsResponse, err error) {
|
||||
root, heads, err := r.docService.TreeParams(request.SpaceId, request.DocumentId)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
resp = &apiproto.TreeParamsResponse{
|
||||
RootId: root,
|
||||
HeadIds: heads,
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -2,7 +2,7 @@ package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/client/api/apiproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/client/clientspace"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/client/document"
|
||||
clientstorage "github.com/anytypeio/go-anytype-infrastructure-experiments/client/storage"
|
||||
@ -11,37 +11,41 @@ import (
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/config"
|
||||
"go.uber.org/zap"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/rpc/server"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/secure"
|
||||
"storj.io/drpc"
|
||||
)
|
||||
|
||||
const CName = "api.service"
|
||||
|
||||
var log = logger.NewNamed("api")
|
||||
var log = logger.NewNamed(CName)
|
||||
|
||||
func New() Service {
|
||||
return &service{}
|
||||
return &service{BaseDrpcServer: server.NewBaseDrpcServer()}
|
||||
}
|
||||
|
||||
type Service interface {
|
||||
app.ComponentRunnable
|
||||
drpc.Mux
|
||||
}
|
||||
|
||||
type service struct {
|
||||
controller Controller
|
||||
srv *http.Server
|
||||
cfg *config.Config
|
||||
transport secure.Service
|
||||
cfg *config.Config
|
||||
spaceService clientspace.Service
|
||||
storageService clientstorage.ClientStorage
|
||||
docService document.Service
|
||||
account account.Service
|
||||
*server.BaseDrpcServer
|
||||
}
|
||||
|
||||
func (s *service) Init(a *app.App) (err error) {
|
||||
s.controller = newController(
|
||||
a.MustComponent(clientspace.CName).(clientspace.Service),
|
||||
a.MustComponent(storage.CName).(clientstorage.ClientStorage),
|
||||
a.MustComponent(document.CName).(document.Service),
|
||||
a.MustComponent(account.CName).(account.Service))
|
||||
s.spaceService = a.MustComponent(clientspace.CName).(clientspace.Service)
|
||||
s.storageService = a.MustComponent(storage.CName).(clientstorage.ClientStorage)
|
||||
s.docService = a.MustComponent(document.CName).(document.Service)
|
||||
s.account = a.MustComponent(account.CName).(account.Service)
|
||||
s.cfg = a.MustComponent(config.CName).(*config.Config)
|
||||
s.transport = a.MustComponent(secure.CName).(secure.Service)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -50,132 +54,19 @@ func (s *service) Name() (name string) {
|
||||
}
|
||||
|
||||
func (s *service) Run(ctx context.Context) (err error) {
|
||||
defer func() {
|
||||
if err == nil {
|
||||
log.With(zap.String("port", s.cfg.APIServer.Port)).Info("api server started running")
|
||||
}
|
||||
}()
|
||||
|
||||
s.srv = &http.Server{
|
||||
Addr: fmt.Sprintf(":%s", s.cfg.APIServer.Port),
|
||||
}
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/deriveSpace", s.deriveSpace)
|
||||
mux.HandleFunc("/createSpace", s.createSpace)
|
||||
mux.HandleFunc("/loadSpace", s.loadSpace)
|
||||
mux.HandleFunc("/allSpaceIds", s.allSpaceIds)
|
||||
mux.HandleFunc("/createDocument", s.createDocument)
|
||||
mux.HandleFunc("/allDocumentIds", s.allDocumentIds)
|
||||
mux.HandleFunc("/addText", s.addText)
|
||||
mux.HandleFunc("/dumpDocumentTree", s.dumpDocumentTree)
|
||||
s.srv.Handler = mux
|
||||
|
||||
go s.runServer()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *service) runServer() {
|
||||
err := s.srv.ListenAndServe()
|
||||
err = s.BaseDrpcServer.Run(
|
||||
ctx,
|
||||
s.cfg.APIServer.ListenAddrs,
|
||||
func(handler drpc.Handler) drpc.Handler {
|
||||
return handler
|
||||
},
|
||||
s.transport.BasicListener)
|
||||
if err != nil {
|
||||
log.With(zap.Error(err)).Error("could not run api server")
|
||||
return
|
||||
}
|
||||
return apiproto.DRPCRegisterClientApi(s, &rpcHandler{s.spaceService, s.storageService, s.docService, s.account})
|
||||
}
|
||||
|
||||
func (s *service) Close(ctx context.Context) (err error) {
|
||||
return s.srv.Shutdown(ctx)
|
||||
}
|
||||
|
||||
func (s *service) deriveSpace(w http.ResponseWriter, req *http.Request) {
|
||||
id, err := s.controller.DeriveSpace()
|
||||
if err != nil {
|
||||
sendText(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
sendText(w, http.StatusOK, id)
|
||||
}
|
||||
|
||||
func (s *service) loadSpace(w http.ResponseWriter, req *http.Request) {
|
||||
query := req.URL.Query()
|
||||
spaceId := query.Get("spaceId")
|
||||
err := s.controller.LoadSpace(query.Get("spaceId"))
|
||||
if err != nil {
|
||||
sendText(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
sendText(w, http.StatusOK, spaceId)
|
||||
}
|
||||
|
||||
func (s *service) createSpace(w http.ResponseWriter, req *http.Request) {
|
||||
id, err := s.controller.CreateSpace()
|
||||
if err != nil {
|
||||
sendText(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
sendText(w, http.StatusOK, id)
|
||||
}
|
||||
|
||||
func (s *service) allSpaceIds(w http.ResponseWriter, req *http.Request) {
|
||||
ids, err := s.controller.AllSpaceIds()
|
||||
if err != nil {
|
||||
sendText(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
sendText(w, http.StatusOK, strings.Join(ids, "\n"))
|
||||
}
|
||||
|
||||
func (s *service) createDocument(w http.ResponseWriter, req *http.Request) {
|
||||
query := req.URL.Query()
|
||||
spaceId := query.Get("spaceId")
|
||||
id, err := s.controller.CreateDocument(spaceId)
|
||||
if err != nil {
|
||||
sendText(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
sendText(w, http.StatusOK, id)
|
||||
}
|
||||
|
||||
func (s *service) allDocumentIds(w http.ResponseWriter, req *http.Request) {
|
||||
query := req.URL.Query()
|
||||
spaceId := query.Get("spaceId")
|
||||
ids, err := s.controller.AllDocumentIds(spaceId)
|
||||
if err != nil {
|
||||
sendText(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
sendText(w, http.StatusOK, strings.Join(ids, "\n"))
|
||||
}
|
||||
|
||||
func (s *service) addText(w http.ResponseWriter, req *http.Request) {
|
||||
query := req.URL.Query()
|
||||
spaceId := query.Get("spaceId")
|
||||
documentId := query.Get("documentId")
|
||||
text := query.Get("text")
|
||||
err := s.controller.AddText(spaceId, documentId, text)
|
||||
if err != nil {
|
||||
sendText(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
sendText(w, http.StatusOK, "Text added")
|
||||
}
|
||||
|
||||
func (s *service) dumpDocumentTree(w http.ResponseWriter, req *http.Request) {
|
||||
query := req.URL.Query()
|
||||
spaceId := query.Get("spaceId")
|
||||
documentId := query.Get("documentId")
|
||||
dump, err := s.controller.DumpDocumentTree(spaceId, documentId)
|
||||
if err != nil {
|
||||
sendText(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
sendText(w, http.StatusOK, dump)
|
||||
}
|
||||
|
||||
func sendText(r http.ResponseWriter, code int, body string) {
|
||||
r.Header().Set("Content-Type", "text/plain")
|
||||
r.WriteHeader(code)
|
||||
|
||||
_, err := io.WriteString(r, fmt.Sprintf("%s\n", body))
|
||||
if err != nil {
|
||||
log.Error("writing response failed", zap.Error(err))
|
||||
}
|
||||
return s.BaseDrpcServer.Close(ctx)
|
||||
}
|
||||
|
||||
@ -103,6 +103,20 @@ func (c *treeCache) GetTree(ctx context.Context, spaceId, id string) (tr tree.Ob
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
tr = doc.Tree()
|
||||
// we have to do this trick, otherwise the compiler won't understand that TextDocument conforms to SyncHandler interface
|
||||
tr = doc.InnerTree()
|
||||
return
|
||||
}
|
||||
|
||||
func (c *treeCache) DeleteTree(ctx context.Context, spaceId, treeId string) (err error) {
|
||||
tr, err := c.GetTree(ctx, spaceId, treeId)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = tr.Delete()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
_, err = c.cache.Remove(treeId)
|
||||
return
|
||||
}
|
||||
|
||||
@ -19,22 +19,34 @@ func (r *rpcHandler) PullSpace(ctx context.Context, request *spacesyncproto.Pull
|
||||
return
|
||||
}
|
||||
|
||||
description := sp.Description()
|
||||
spaceDesc, err := sp.Description()
|
||||
if err != nil {
|
||||
err = spacesyncproto.ErrUnexpected
|
||||
return
|
||||
}
|
||||
|
||||
resp = &spacesyncproto.PullSpaceResponse{
|
||||
SpaceHeader: description.SpaceHeader,
|
||||
AclPayload: description.AclPayload,
|
||||
AclPayloadId: description.AclId,
|
||||
Payload: &spacesyncproto.SpacePayload{
|
||||
SpaceHeader: spaceDesc.SpaceHeader,
|
||||
AclPayloadId: spaceDesc.AclId,
|
||||
AclPayload: spaceDesc.AclPayload,
|
||||
SpaceSettingsPayload: spaceDesc.SpaceSettingsPayload,
|
||||
SpaceSettingsPayloadId: spaceDesc.SpaceSettingsId,
|
||||
},
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (r *rpcHandler) PushSpace(ctx context.Context, req *spacesyncproto.PushSpaceRequest) (resp *spacesyncproto.PushSpaceResponse, err error) {
|
||||
description := commonspace.SpaceDescription{
|
||||
SpaceHeader: req.SpaceHeader,
|
||||
AclId: req.AclPayloadId,
|
||||
AclPayload: req.AclPayload,
|
||||
SpaceHeader: req.Payload.SpaceHeader,
|
||||
AclId: req.Payload.AclPayloadId,
|
||||
AclPayload: req.Payload.AclPayload,
|
||||
SpaceSettingsPayload: req.Payload.SpaceSettingsPayload,
|
||||
SpaceSettingsId: req.Payload.SpaceSettingsPayloadId,
|
||||
}
|
||||
err = r.s.AddSpace(ctx, description)
|
||||
ctx = context.WithValue(ctx, commonspace.AddSpaceCtxKey, description)
|
||||
_, err = r.s.GetSpace(ctx, description.SpaceHeader.GetId())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@ -23,7 +23,6 @@ func New() Service {
|
||||
|
||||
type Service interface {
|
||||
GetSpace(ctx context.Context, id string) (commonspace.Space, error)
|
||||
AddSpace(ctx context.Context, description commonspace.SpaceDescription) (err error)
|
||||
CreateSpace(ctx context.Context, payload commonspace.SpaceCreatePayload) (commonspace.Space, error)
|
||||
DeriveSpace(ctx context.Context, payload commonspace.SpaceDerivePayload) (commonspace.Space, error)
|
||||
app.ComponentRunnable
|
||||
@ -91,10 +90,6 @@ func (s *service) GetSpace(ctx context.Context, id string) (container commonspac
|
||||
return v.(commonspace.Space), nil
|
||||
}
|
||||
|
||||
func (s *service) AddSpace(ctx context.Context, description commonspace.SpaceDescription) (err error) {
|
||||
return s.commonSpace.AddSpace(ctx, description)
|
||||
}
|
||||
|
||||
func (s *service) loadSpace(ctx context.Context, id string) (value ocache.Object, err error) {
|
||||
cc, err := s.commonSpace.NewSpace(ctx, id)
|
||||
if err != nil {
|
||||
|
||||
@ -8,15 +8,19 @@ import (
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/account"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/diffservice"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter"
|
||||
)
|
||||
|
||||
type Service interface {
|
||||
app.Component
|
||||
CreateDocument(spaceId string) (id string, err error)
|
||||
DeleteDocument(spaceId, documentId string) (err error)
|
||||
AllDocumentIds(spaceId string) (ids []string, err error)
|
||||
AddText(spaceId, documentId, text string) (err error)
|
||||
AllDocumentHeads(spaceId string) (ids []diffservice.TreeHeads, err error)
|
||||
AddText(spaceId, documentId, text string, isSnapshot bool) (root, head string, err error)
|
||||
DumpDocumentTree(spaceId, documentId string) (dump string, err error)
|
||||
TreeParams(spaceId, documentId string) (root string, head []string, err error)
|
||||
}
|
||||
|
||||
const CName = "client.document"
|
||||
@ -49,12 +53,16 @@ func (s *service) CreateDocument(spaceId string) (id string, err error) {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
doc, err := textdocument.CreateTextDocument(context.Background(), space, s.account, nil)
|
||||
id, err = textdocument.CreateTextDocument(context.Background(), space, s.account)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *service) DeleteDocument(spaceId, documentId string) (err error) {
|
||||
space, err := s.spaceService.GetSpace(context.Background(), spaceId)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
id = doc.Tree().ID()
|
||||
return
|
||||
return space.DeleteTree(context.Background(), documentId)
|
||||
}
|
||||
|
||||
func (s *service) AllDocumentIds(spaceId string) (ids []string, err error) {
|
||||
@ -66,12 +74,21 @@ func (s *service) AllDocumentIds(spaceId string) (ids []string, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (s *service) AddText(spaceId, documentId, text string) (err error) {
|
||||
func (s *service) AllDocumentHeads(spaceId string) (ids []diffservice.TreeHeads, err error) {
|
||||
space, err := s.spaceService.GetSpace(context.Background(), spaceId)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
ids = space.DebugAllHeads()
|
||||
return
|
||||
}
|
||||
|
||||
func (s *service) AddText(spaceId, documentId, text string, isSnapshot bool) (root, head string, err error) {
|
||||
doc, err := s.cache.GetDocument(context.Background(), spaceId, documentId)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return doc.AddText(text)
|
||||
return doc.AddText(text, isSnapshot)
|
||||
}
|
||||
|
||||
func (s *service) DumpDocumentTree(spaceId, documentId string) (dump string, err error) {
|
||||
@ -79,5 +96,13 @@ func (s *service) DumpDocumentTree(spaceId, documentId string) (dump string, err
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return doc.Tree().DebugDump()
|
||||
return doc.DebugDump()
|
||||
}
|
||||
|
||||
func (s *service) TreeParams(spaceId, documentId string) (root string, heads []string, err error) {
|
||||
tr, err := s.cache.GetTree(context.Background(), spaceId, documentId)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return tr.Root().Id, tr.Heads(), nil
|
||||
}
|
||||
|
||||
@ -11,37 +11,29 @@ import (
|
||||
)
|
||||
|
||||
type TextDocument interface {
|
||||
Tree() tree.ObjectTree
|
||||
AddText(text string) error
|
||||
tree.ObjectTree
|
||||
InnerTree() tree.ObjectTree
|
||||
AddText(text string, isSnapshot bool) (string, string, error)
|
||||
Text() (string, error)
|
||||
TreeDump() string
|
||||
Close() error
|
||||
}
|
||||
|
||||
type textDocument struct {
|
||||
objTree tree.ObjectTree
|
||||
tree.ObjectTree
|
||||
account account.Service
|
||||
}
|
||||
|
||||
func CreateTextDocument(
|
||||
ctx context.Context,
|
||||
space commonspace.Space,
|
||||
account account.Service,
|
||||
listener updatelistener.UpdateListener) (doc TextDocument, err error) {
|
||||
account account.Service) (id string, err error) {
|
||||
payload := tree.ObjectTreeCreatePayload{
|
||||
SignKey: account.Account().SignKey,
|
||||
SpaceId: space.Id(),
|
||||
Identity: account.Account().Identity,
|
||||
}
|
||||
t, err := space.CreateTree(ctx, payload, listener)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return &textDocument{
|
||||
objTree: t,
|
||||
account: account,
|
||||
}, nil
|
||||
return space.CreateTree(ctx, payload)
|
||||
}
|
||||
|
||||
func NewTextDocument(ctx context.Context, space commonspace.Space, id string, listener updatelistener.UpdateListener, account account.Service) (doc TextDocument, err error) {
|
||||
@ -50,16 +42,16 @@ func NewTextDocument(ctx context.Context, space commonspace.Space, id string, li
|
||||
return
|
||||
}
|
||||
return &textDocument{
|
||||
objTree: t,
|
||||
account: account,
|
||||
ObjectTree: t,
|
||||
account: account,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (t *textDocument) Tree() tree.ObjectTree {
|
||||
return t.objTree
|
||||
func (t *textDocument) InnerTree() tree.ObjectTree {
|
||||
return t.ObjectTree
|
||||
}
|
||||
|
||||
func (t *textDocument) AddText(text string) (err error) {
|
||||
func (t *textDocument) AddText(text string, isSnapshot bool) (root, head string, err error) {
|
||||
content := &testchanges.TextContent_TextAppend{
|
||||
TextAppend: &testchanges.TextAppend{Text: text},
|
||||
}
|
||||
@ -73,22 +65,27 @@ func (t *textDocument) AddText(text string) (err error) {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
t.objTree.Lock()
|
||||
defer t.objTree.Unlock()
|
||||
_, err = t.objTree.AddContent(context.Background(), tree.SignableChangeContent{
|
||||
t.Lock()
|
||||
defer t.Unlock()
|
||||
addRes, err := t.AddContent(context.Background(), tree.SignableChangeContent{
|
||||
Data: res,
|
||||
Key: t.account.Account().SignKey,
|
||||
Identity: t.account.Account().Identity,
|
||||
IsSnapshot: false,
|
||||
IsSnapshot: isSnapshot,
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
root = t.Root().Id
|
||||
head = addRes.Heads[0]
|
||||
return
|
||||
}
|
||||
|
||||
func (t *textDocument) Text() (text string, err error) {
|
||||
t.objTree.RLock()
|
||||
defer t.objTree.RUnlock()
|
||||
t.RLock()
|
||||
defer t.RUnlock()
|
||||
|
||||
err = t.objTree.Iterate(
|
||||
err = t.Iterate(
|
||||
func(decrypted []byte) (any, error) {
|
||||
textChange := &testchanges.TextData{}
|
||||
err = proto.Unmarshal(decrypted, textChange)
|
||||
@ -110,7 +107,3 @@ func (t *textDocument) Text() (text string, err error) {
|
||||
func (t *textDocument) TreeDump() string {
|
||||
return t.TreeDump()
|
||||
}
|
||||
|
||||
func (t *textDocument) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -31,18 +31,20 @@ func (a aclKeys) RawRecordKey(id string) []byte {
|
||||
}
|
||||
|
||||
type treeKeys struct {
|
||||
id string
|
||||
spaceId string
|
||||
headsKey []byte
|
||||
rootKey []byte
|
||||
id string
|
||||
spaceId string
|
||||
headsKey []byte
|
||||
rootKey []byte
|
||||
rawChangePrefix []byte
|
||||
}
|
||||
|
||||
func newTreeKeys(spaceId, id string) treeKeys {
|
||||
return treeKeys{
|
||||
id: id,
|
||||
spaceId: spaceId,
|
||||
headsKey: storage.JoinStringsToBytes("space", spaceId, "t", id, "heads"),
|
||||
rootKey: storage.JoinStringsToBytes("space", spaceId, "t", "rootId", id),
|
||||
id: id,
|
||||
spaceId: spaceId,
|
||||
headsKey: storage.JoinStringsToBytes("space", spaceId, "t", id, "heads"),
|
||||
rootKey: storage.JoinStringsToBytes("space", spaceId, "t", "rootId", id),
|
||||
rawChangePrefix: storage.JoinStringsToBytes("space", spaceId, "t", id),
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,15 +60,23 @@ func (t treeKeys) RawChangeKey(id string) []byte {
|
||||
return storage.JoinStringsToBytes("space", t.spaceId, "t", t.id, id)
|
||||
}
|
||||
|
||||
func (t treeKeys) RawChangePrefix() []byte {
|
||||
return t.rawChangePrefix
|
||||
}
|
||||
|
||||
type spaceKeys struct {
|
||||
headerKey []byte
|
||||
treePrefixKey []byte
|
||||
spaceId string
|
||||
headerKey []byte
|
||||
treePrefixKey []byte
|
||||
spaceSettingsIdKey []byte
|
||||
}
|
||||
|
||||
func newSpaceKeys(spaceId string) spaceKeys {
|
||||
return spaceKeys{
|
||||
headerKey: storage.JoinStringsToBytes("space", "header", spaceId),
|
||||
treePrefixKey: storage.JoinStringsToBytes("space", spaceId, "t", "rootId"),
|
||||
spaceId: spaceId,
|
||||
headerKey: storage.JoinStringsToBytes("space", "header", spaceId),
|
||||
treePrefixKey: storage.JoinStringsToBytes("space", spaceId, "t", "rootId"),
|
||||
spaceSettingsIdKey: storage.JoinStringsToBytes("space", spaceId, "spaceSettingsId"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,6 +88,14 @@ func (s spaceKeys) TreeRootPrefix() []byte {
|
||||
return s.treePrefixKey
|
||||
}
|
||||
|
||||
func (s spaceKeys) SpaceSettingsId() []byte {
|
||||
return s.spaceSettingsIdKey
|
||||
}
|
||||
|
||||
func (s spaceKeys) TreeDeletedKey(id string) []byte {
|
||||
return storage.JoinStringsToBytes("space", s.spaceId, "deleted", id)
|
||||
}
|
||||
|
||||
type storageServiceKeys struct {
|
||||
spacePrefix []byte
|
||||
}
|
||||
|
||||
@ -4,19 +4,21 @@ import (
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
|
||||
spacestorage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
|
||||
storage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto"
|
||||
"github.com/dgraph-io/badger/v3"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type spaceStorage struct {
|
||||
spaceId string
|
||||
objDb *badger.DB
|
||||
keys spaceKeys
|
||||
aclStorage storage.ListStorage
|
||||
header *spacesyncproto.RawSpaceHeaderWithId
|
||||
mx sync.Mutex
|
||||
spaceId string
|
||||
spaceSettingsId string
|
||||
objDb *badger.DB
|
||||
keys spaceKeys
|
||||
aclStorage storage.ListStorage
|
||||
header *spacesyncproto.RawSpaceHeaderWithId
|
||||
}
|
||||
|
||||
var spaceValidationFunc = spacestorage.ValidateSpaceStorageCreatePayload
|
||||
|
||||
func newSpaceStorage(objDb *badger.DB, spaceId string) (store spacestorage.SpaceStorage, err error) {
|
||||
keys := newSpaceKeys(spaceId)
|
||||
err = objDb.View(func(txn *badger.Txn) error {
|
||||
@ -30,10 +32,15 @@ func newSpaceStorage(objDb *badger.DB, spaceId string) (store spacestorage.Space
|
||||
return err
|
||||
}
|
||||
|
||||
spaceSettingsId, err := getTxn(txn, keys.SpaceSettingsId())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
store = &spaceStorage{
|
||||
spaceId: spaceId,
|
||||
objDb: objDb,
|
||||
keys: keys,
|
||||
spaceId: spaceId,
|
||||
spaceSettingsId: string(spaceSettingsId),
|
||||
objDb: objDb,
|
||||
keys: keys,
|
||||
header: &spacesyncproto.RawSpaceHeaderWithId{
|
||||
RawHeader: header,
|
||||
Id: spaceId,
|
||||
@ -43,7 +50,7 @@ func newSpaceStorage(objDb *badger.DB, spaceId string) (store spacestorage.Space
|
||||
return nil
|
||||
})
|
||||
if err == badger.ErrKeyNotFound {
|
||||
err = spacesyncproto.ErrSpaceMissing
|
||||
err = spacestorage.ErrSpaceStorageMissing
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -51,11 +58,35 @@ func newSpaceStorage(objDb *badger.DB, spaceId string) (store spacestorage.Space
|
||||
func createSpaceStorage(db *badger.DB, payload spacestorage.SpaceStorageCreatePayload) (store spacestorage.SpaceStorage, err error) {
|
||||
keys := newSpaceKeys(payload.SpaceHeaderWithId.Id)
|
||||
if hasDB(db, keys.HeaderKey()) {
|
||||
err = spacesyncproto.ErrSpaceExists
|
||||
err = spacestorage.ErrSpaceStorageExists
|
||||
return
|
||||
}
|
||||
err = spaceValidationFunc(payload)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
spaceStore := &spaceStorage{
|
||||
spaceId: payload.SpaceHeaderWithId.Id,
|
||||
objDb: db,
|
||||
keys: keys,
|
||||
spaceSettingsId: payload.SpaceSettingsWithId.Id,
|
||||
header: payload.SpaceHeaderWithId,
|
||||
}
|
||||
_, err = spaceStore.CreateTreeStorage(storage.TreeStorageCreatePayload{
|
||||
RootRawChange: payload.SpaceSettingsWithId,
|
||||
Changes: []*treechangeproto.RawTreeChangeWithId{payload.SpaceSettingsWithId},
|
||||
Heads: []string{payload.SpaceSettingsWithId.Id},
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = db.Update(func(txn *badger.Txn) error {
|
||||
aclStorage, err := createListStorage(payload.SpaceHeaderWithId.Id, db, txn, payload.RecWithId)
|
||||
err = txn.Set(keys.SpaceSettingsId(), []byte(payload.SpaceSettingsWithId.Id))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
aclStorage, err := createListStorage(payload.SpaceHeaderWithId.Id, db, txn, payload.AclWithId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -65,15 +96,10 @@ func createSpaceStorage(db *badger.DB, payload spacestorage.SpaceStorageCreatePa
|
||||
return err
|
||||
}
|
||||
|
||||
store = &spaceStorage{
|
||||
spaceId: payload.SpaceHeaderWithId.Id,
|
||||
objDb: db,
|
||||
keys: keys,
|
||||
aclStorage: aclStorage,
|
||||
header: payload.SpaceHeaderWithId,
|
||||
}
|
||||
spaceStore.aclStorage = aclStorage
|
||||
return nil
|
||||
})
|
||||
store = spaceStore
|
||||
return
|
||||
}
|
||||
|
||||
@ -81,15 +107,15 @@ func (s *spaceStorage) Id() string {
|
||||
return s.spaceId
|
||||
}
|
||||
|
||||
func (s *spaceStorage) SpaceSettingsId() string {
|
||||
return s.spaceSettingsId
|
||||
}
|
||||
|
||||
func (s *spaceStorage) TreeStorage(id string) (storage.TreeStorage, error) {
|
||||
return newTreeStorage(s.objDb, s.spaceId, id)
|
||||
}
|
||||
|
||||
func (s *spaceStorage) CreateTreeStorage(payload storage.TreeStorageCreatePayload) (ts storage.TreeStorage, err error) {
|
||||
// we have mutex here, so we prevent overwriting the heads of a tree on concurrent creation
|
||||
s.mx.Lock()
|
||||
defer s.mx.Unlock()
|
||||
|
||||
return createTreeStorage(s.objDb, s.spaceId, payload)
|
||||
}
|
||||
|
||||
@ -112,7 +138,8 @@ func (s *spaceStorage) StoredIds() (ids []string, err error) {
|
||||
|
||||
for it.Rewind(); it.Valid(); it.Next() {
|
||||
item := it.Item()
|
||||
id := item.Key()
|
||||
id := make([]byte, 0, len(item.Key()))
|
||||
id = item.KeyCopy(id)
|
||||
if len(id) <= len(s.keys.TreeRootPrefix())+1 {
|
||||
continue
|
||||
}
|
||||
@ -124,6 +151,27 @@ func (s *spaceStorage) StoredIds() (ids []string, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (s *spaceStorage) SetTreeDeletedStatus(id, status string) (err error) {
|
||||
return s.objDb.Update(func(txn *badger.Txn) error {
|
||||
return txn.Set(s.keys.TreeDeletedKey(id), []byte(status))
|
||||
})
|
||||
}
|
||||
|
||||
func (s *spaceStorage) TreeDeletedStatus(id string) (status string, err error) {
|
||||
err = s.objDb.View(func(txn *badger.Txn) error {
|
||||
res, err := getTxn(txn, s.keys.TreeDeletedKey(id))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
status = string(res)
|
||||
return nil
|
||||
})
|
||||
if err == badger.ErrKeyNotFound {
|
||||
err = nil
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *spaceStorage) Close() (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -4,7 +4,9 @@ import (
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
|
||||
spacestorage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto"
|
||||
"github.com/stretchr/testify/require"
|
||||
"sort"
|
||||
"strconv"
|
||||
"testing"
|
||||
)
|
||||
@ -18,9 +20,14 @@ func spaceTestPayload() spacestorage.SpaceStorageCreatePayload {
|
||||
Payload: []byte("aclRoot"),
|
||||
Id: "aclRootId",
|
||||
}
|
||||
settings := &treechangeproto.RawTreeChangeWithId{
|
||||
RawChange: []byte("settings"),
|
||||
Id: "settingsId",
|
||||
}
|
||||
return spacestorage.SpaceStorageCreatePayload{
|
||||
RecWithId: aclRoot,
|
||||
SpaceHeaderWithId: header,
|
||||
AclWithId: aclRoot,
|
||||
SpaceHeaderWithId: header,
|
||||
SpaceSettingsWithId: settings,
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,7 +38,7 @@ func testSpace(t *testing.T, store spacestorage.SpaceStorage, payload spacestora
|
||||
|
||||
aclStorage, err := store.ACLStorage()
|
||||
require.NoError(t, err)
|
||||
testList(t, aclStorage, payload.RecWithId, payload.RecWithId.Id)
|
||||
testList(t, aclStorage, payload.AclWithId, payload.AclWithId.Id)
|
||||
}
|
||||
|
||||
func TestSpaceStorage_Create(t *testing.T) {
|
||||
@ -68,7 +75,7 @@ func TestSpaceStorage_NewAndCreateTree(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
testSpace(t, store, payload)
|
||||
|
||||
t.Run("create tree and get tree", func(t *testing.T) {
|
||||
t.Run("create tree, get tree and mark deleted", func(t *testing.T) {
|
||||
payload := treeTestPayload()
|
||||
treeStore, err := store.CreateTreeStorage(payload)
|
||||
require.NoError(t, err)
|
||||
@ -77,6 +84,14 @@ func TestSpaceStorage_NewAndCreateTree(t *testing.T) {
|
||||
otherStore, err := store.TreeStorage(payload.RootRawChange.Id)
|
||||
require.NoError(t, err)
|
||||
testTreePayload(t, otherStore, payload)
|
||||
|
||||
initialStatus := "deleted"
|
||||
err = store.SetTreeDeletedStatus(otherStore.Id(), initialStatus)
|
||||
require.NoError(t, err)
|
||||
|
||||
status, err := store.TreeDeletedStatus(otherStore.Id())
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, initialStatus, status)
|
||||
})
|
||||
}
|
||||
|
||||
@ -101,8 +116,11 @@ func TestSpaceStorage_StoredIds(t *testing.T) {
|
||||
_, err := store.CreateTreeStorage(treePayload)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
ids = append(ids, payload.SpaceSettingsWithId.Id)
|
||||
sort.Strings(ids)
|
||||
|
||||
storedIds, err := store.StoredIds()
|
||||
require.NoError(t, err)
|
||||
sort.Strings(storedIds)
|
||||
require.Equal(t, ids, storedIds)
|
||||
}
|
||||
|
||||
@ -136,3 +136,46 @@ func (t *treeStorage) GetRawChange(ctx context.Context, id string) (raw *treecha
|
||||
func (t *treeStorage) HasChange(ctx context.Context, id string) (bool, error) {
|
||||
return hasDB(t.db, t.keys.RawChangeKey(id)), nil
|
||||
}
|
||||
|
||||
func (t *treeStorage) Delete() (err error) {
|
||||
storedKeys, err := t.storedKeys()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = t.db.Update(func(txn *badger.Txn) error {
|
||||
for _, k := range storedKeys {
|
||||
err = txn.Delete(k)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func (t *treeStorage) storedKeys() (keys [][]byte, err error) {
|
||||
err = t.db.View(func(txn *badger.Txn) error {
|
||||
opts := badger.DefaultIteratorOptions
|
||||
opts.PrefetchValues = false
|
||||
// this will get all raw changes and also "heads"
|
||||
opts.Prefix = t.keys.RawChangePrefix()
|
||||
|
||||
it := txn.NewIterator(opts)
|
||||
defer it.Close()
|
||||
|
||||
for it.Rewind(); it.Valid(); it.Next() {
|
||||
item := it.Item()
|
||||
key := item.Key()
|
||||
keyCopy := make([]byte, 0, len(key))
|
||||
keyCopy = item.KeyCopy(keyCopy)
|
||||
keys = append(keys, keyCopy)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
keys = append(keys, t.keys.RootIdKey())
|
||||
return
|
||||
}
|
||||
|
||||
@ -61,6 +61,42 @@ func (fx *fixture) stop(t *testing.T) {
|
||||
require.NoError(t, fx.db.Close())
|
||||
}
|
||||
|
||||
func (fx *fixture) testNoKeysExist(t *testing.T, spaceId, treeId string) {
|
||||
treeKeys := newTreeKeys(spaceId, treeId)
|
||||
|
||||
var keys [][]byte
|
||||
err := fx.db.View(func(txn *badger.Txn) error {
|
||||
opts := badger.DefaultIteratorOptions
|
||||
opts.PrefetchValues = false
|
||||
opts.Prefix = treeKeys.RawChangePrefix()
|
||||
|
||||
it := txn.NewIterator(opts)
|
||||
defer it.Close()
|
||||
|
||||
for it.Rewind(); it.Valid(); it.Next() {
|
||||
item := it.Item()
|
||||
key := item.Key()
|
||||
keyCopy := make([]byte, 0, len(key))
|
||||
keyCopy = item.KeyCopy(key)
|
||||
keys = append(keys, keyCopy)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, len(keys))
|
||||
|
||||
err = fx.db.View(func(txn *badger.Txn) error {
|
||||
_, err = getTxn(txn, treeKeys.RootIdKey())
|
||||
require.Equal(t, err, badger.ErrKeyNotFound)
|
||||
|
||||
_, err = getTxn(txn, treeKeys.HeadsKey())
|
||||
require.Equal(t, err, badger.ErrKeyNotFound)
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func TestTreeStorage_Create(t *testing.T) {
|
||||
fx := newFixture(t)
|
||||
fx.open(t)
|
||||
@ -121,3 +157,32 @@ func TestTreeStorage_Methods(t *testing.T) {
|
||||
require.False(t, has)
|
||||
})
|
||||
}
|
||||
|
||||
func TestTreeStorage_Delete(t *testing.T) {
|
||||
fx := newFixture(t)
|
||||
fx.open(t)
|
||||
payload := treeTestPayload()
|
||||
spaceId := "spaceId"
|
||||
_, err := createTreeStorage(fx.db, spaceId, payload)
|
||||
require.NoError(t, err)
|
||||
fx.stop(t)
|
||||
|
||||
fx.open(t)
|
||||
defer fx.stop(t)
|
||||
store, err := newTreeStorage(fx.db, spaceId, payload.RootRawChange.Id)
|
||||
require.NoError(t, err)
|
||||
testTreePayload(t, store, payload)
|
||||
|
||||
t.Run("add raw change, get change and has change", func(t *testing.T) {
|
||||
newChange := &treechangeproto.RawTreeChangeWithId{RawChange: []byte("ab"), Id: "newId"}
|
||||
require.NoError(t, store.AddRawChange(newChange))
|
||||
|
||||
err = store.Delete()
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = newTreeStorage(fx.db, spaceId, payload.RootRawChange.Id)
|
||||
require.Equal(t, err, storage.ErrUnknownTreeId)
|
||||
|
||||
fx.testNoKeysExist(t, spaceId, payload.RootRawChange.Id)
|
||||
})
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ export GOPRIVATE=github.com/anytypeio
|
||||
|
||||
proto:
|
||||
@echo 'Generating protobuf packages (Go)...'
|
||||
# Uncomment if needed
|
||||
|
||||
@$(eval GOGO_START := GOGO_NO_UNDERSCORE=1 GOGO_EXPORT_ONEOF_INTERFACE=1)
|
||||
@$(eval P_ACL_RECORDS_PATH_PB := pkg/acl/aclrecordproto)
|
||||
@$(eval P_TREE_CHANGES_PATH_PB := pkg/acl/treechangeproto)
|
||||
|
||||
78
common/account/mock_account/mock_account.go
Normal file
78
common/account/mock_account/mock_account.go
Normal file
@ -0,0 +1,78 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/anytypeio/go-anytype-infrastructure-experiments/common/account (interfaces: Service)
|
||||
|
||||
// Package mock_account is a generated GoMock package.
|
||||
package mock_account
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
app "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app"
|
||||
account "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/account"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
)
|
||||
|
||||
// MockService is a mock of Service interface.
|
||||
type MockService struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockServiceMockRecorder
|
||||
}
|
||||
|
||||
// MockServiceMockRecorder is the mock recorder for MockService.
|
||||
type MockServiceMockRecorder struct {
|
||||
mock *MockService
|
||||
}
|
||||
|
||||
// NewMockService creates a new mock instance.
|
||||
func NewMockService(ctrl *gomock.Controller) *MockService {
|
||||
mock := &MockService{ctrl: ctrl}
|
||||
mock.recorder = &MockServiceMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockService) EXPECT() *MockServiceMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Account mocks base method.
|
||||
func (m *MockService) Account() *account.AccountData {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Account")
|
||||
ret0, _ := ret[0].(*account.AccountData)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Account indicates an expected call of Account.
|
||||
func (mr *MockServiceMockRecorder) Account() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Account", reflect.TypeOf((*MockService)(nil).Account))
|
||||
}
|
||||
|
||||
// Init mocks base method.
|
||||
func (m *MockService) Init(arg0 *app.App) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Init", arg0)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Init indicates an expected call of Init.
|
||||
func (mr *MockServiceMockRecorder) Init(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockService)(nil).Init), arg0)
|
||||
}
|
||||
|
||||
// Name mocks base method.
|
||||
func (m *MockService) Name() string {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Name")
|
||||
ret0, _ := ret[0].(string)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Name indicates an expected call of Name.
|
||||
func (mr *MockServiceMockRecorder) Name() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockService)(nil).Name))
|
||||
}
|
||||
@ -1,3 +1,4 @@
|
||||
//go:generate mockgen -destination mock_account/mock_account.go github.com/anytypeio/go-anytype-infrastructure-experiments/common/account Service
|
||||
package account
|
||||
|
||||
import (
|
||||
|
||||
@ -3,6 +3,7 @@ package commonspace
|
||||
import (
|
||||
"context"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/objectgetter"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/settingsdocument"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncacl"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter"
|
||||
)
|
||||
@ -11,13 +12,15 @@ type commonSpaceGetter struct {
|
||||
spaceId string
|
||||
aclList *syncacl.SyncACL
|
||||
treeGetter treegetter.TreeGetter
|
||||
settings settingsdocument.SettingsDocument
|
||||
}
|
||||
|
||||
func newCommonSpaceGetter(spaceId string, aclList *syncacl.SyncACL, treeGetter treegetter.TreeGetter) objectgetter.ObjectGetter {
|
||||
func newCommonSpaceGetter(spaceId string, aclList *syncacl.SyncACL, treeGetter treegetter.TreeGetter, settings settingsdocument.SettingsDocument) objectgetter.ObjectGetter {
|
||||
return &commonSpaceGetter{
|
||||
spaceId: spaceId,
|
||||
aclList: aclList,
|
||||
treeGetter: treeGetter,
|
||||
settings: settings,
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,6 +29,10 @@ func (c *commonSpaceGetter) GetObject(ctx context.Context, objectId string) (obj
|
||||
obj = c.aclList
|
||||
return
|
||||
}
|
||||
if c.settings.ID() == objectId {
|
||||
obj = c.settings.(objectgetter.Object)
|
||||
return
|
||||
}
|
||||
t, err := c.treeGetter.GetTree(ctx, c.spaceId, objectId)
|
||||
if err != nil {
|
||||
return
|
||||
|
||||
28
common/commonspace/commonstorage.go
Normal file
28
common/commonspace/commonstorage.go
Normal file
@ -0,0 +1,28 @@
|
||||
package commonspace
|
||||
|
||||
import (
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
|
||||
treestorage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage"
|
||||
)
|
||||
|
||||
type commonStorage struct {
|
||||
storage.SpaceStorage
|
||||
}
|
||||
|
||||
func newCommonStorage(spaceStorage storage.SpaceStorage) storage.SpaceStorage {
|
||||
return &commonStorage{
|
||||
SpaceStorage: spaceStorage,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *commonStorage) CreateTreeStorage(payload treestorage.TreeStorageCreatePayload) (store treestorage.TreeStorage, err error) {
|
||||
status, err := c.TreeDeletedStatus(payload.RootRawChange.Id)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if status == "" {
|
||||
return c.SpaceStorage.CreateTreeStorage(payload)
|
||||
}
|
||||
err = storage.ErrTreeStorageAlreadyDeleted
|
||||
return
|
||||
}
|
||||
@ -1,34 +1,43 @@
|
||||
//go:generate mockgen -destination mock_diffservice/mock_diffservice.go github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/diffservice DiffSyncer,PeriodicSync
|
||||
//go:generate mockgen -destination mock_diffservice/mock_diffservice.go github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/diffservice DiffSyncer
|
||||
package diffservice
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/remotediff"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/settingsdocument/deletionstate"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ldiff"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/periodicsync"
|
||||
"go.uber.org/zap"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type DiffService interface {
|
||||
HeadNotifiable
|
||||
HandleRangeRequest(ctx context.Context, req *spacesyncproto.HeadSyncRequest) (resp *spacesyncproto.HeadSyncResponse, err error)
|
||||
RemoveObject(id string)
|
||||
AllIds() []string
|
||||
type TreeHeads struct {
|
||||
Id string
|
||||
Heads []string
|
||||
}
|
||||
|
||||
Init(objectIds []string)
|
||||
type DiffService interface {
|
||||
UpdateHeads(id string, heads []string)
|
||||
HandleRangeRequest(ctx context.Context, req *spacesyncproto.HeadSyncRequest) (resp *spacesyncproto.HeadSyncResponse, err error)
|
||||
RemoveObjects(ids []string)
|
||||
AllIds() []string
|
||||
DebugAllHeads() (res []TreeHeads)
|
||||
|
||||
Init(objectIds []string, deletionState deletionstate.DeletionState)
|
||||
Close() (err error)
|
||||
}
|
||||
|
||||
type diffService struct {
|
||||
spaceId string
|
||||
periodicSync PeriodicSync
|
||||
periodicSync periodicsync.PeriodicSync
|
||||
storage storage.SpaceStorage
|
||||
diff ldiff.Diff
|
||||
log *zap.Logger
|
||||
syncer DiffSyncer
|
||||
|
||||
syncPeriod int
|
||||
}
|
||||
@ -45,11 +54,12 @@ func NewDiffService(
|
||||
l := log.With(zap.String("spaceId", spaceId))
|
||||
factory := spacesyncproto.ClientFactoryFunc(spacesyncproto.NewDRPCSpaceClient)
|
||||
syncer := newDiffSyncer(spaceId, diff, confConnector, cache, storage, factory, l)
|
||||
periodicSync := newPeriodicSync(syncPeriod, syncer, l)
|
||||
periodicSync := periodicsync.NewPeriodicSync(syncPeriod, syncer.Sync, l)
|
||||
|
||||
return &diffService{
|
||||
spaceId: spaceId,
|
||||
storage: storage,
|
||||
syncer: syncer,
|
||||
periodicSync: periodicSync,
|
||||
diff: diff,
|
||||
log: log,
|
||||
@ -57,8 +67,9 @@ func NewDiffService(
|
||||
}
|
||||
}
|
||||
|
||||
func (d *diffService) Init(objectIds []string) {
|
||||
func (d *diffService) Init(objectIds []string, deletionState deletionstate.DeletionState) {
|
||||
d.fillDiff(objectIds)
|
||||
d.syncer.Init(deletionState)
|
||||
d.periodicSync.Run()
|
||||
}
|
||||
|
||||
@ -67,19 +78,27 @@ func (d *diffService) HandleRangeRequest(ctx context.Context, req *spacesyncprot
|
||||
}
|
||||
|
||||
func (d *diffService) UpdateHeads(id string, heads []string) {
|
||||
d.diff.Set(ldiff.Element{
|
||||
Id: id,
|
||||
Head: concatStrings(heads),
|
||||
})
|
||||
d.syncer.UpdateHeads(id, heads)
|
||||
}
|
||||
|
||||
func (d *diffService) AllIds() []string {
|
||||
return d.diff.Ids()
|
||||
}
|
||||
|
||||
func (d *diffService) RemoveObject(id string) {
|
||||
// TODO: add space document to remove ids
|
||||
d.diff.RemoveId(id)
|
||||
func (d *diffService) DebugAllHeads() (res []TreeHeads) {
|
||||
els := d.diff.Elements()
|
||||
for _, el := range els {
|
||||
idHead := TreeHeads{
|
||||
Id: el.Id,
|
||||
Heads: splitString(el.Head),
|
||||
}
|
||||
res = append(res, idHead)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d *diffService) RemoveObjects(ids []string) {
|
||||
d.syncer.RemoveObjects(ids)
|
||||
}
|
||||
|
||||
func (d *diffService) Close() (err error) {
|
||||
@ -121,3 +140,11 @@ func concatStrings(strs []string) string {
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func splitString(str string) (res []string) {
|
||||
const cidLen = 59
|
||||
for i := 0; i < len(str); i += cidLen {
|
||||
res = append(res, str[i:i+cidLen])
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -3,10 +3,12 @@ package diffservice
|
||||
import (
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/diffservice/mock_diffservice"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/settingsdocument/deletionstate/mock_deletionstate"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage/mock_storage"
|
||||
mock_storage2 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage/mock_storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ldiff"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ldiff/mock_ldiff"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/periodicsync/mock_periodicsync"
|
||||
"github.com/golang/mock/gomock"
|
||||
"testing"
|
||||
)
|
||||
@ -17,10 +19,12 @@ func TestDiffService(t *testing.T) {
|
||||
|
||||
spaceId := "spaceId"
|
||||
l := logger.NewNamed("sync")
|
||||
pSyncMock := mock_diffservice.NewMockPeriodicSync(ctrl)
|
||||
pSyncMock := mock_periodicsync.NewMockPeriodicSync(ctrl)
|
||||
storageMock := mock_storage.NewMockSpaceStorage(ctrl)
|
||||
treeStorageMock := mock_storage2.NewMockTreeStorage(ctrl)
|
||||
diffMock := mock_ldiff.NewMockDiff(ctrl)
|
||||
syncer := mock_diffservice.NewMockDiffSyncer(ctrl)
|
||||
delState := mock_deletionstate.NewMockDeletionState(ctrl)
|
||||
syncPeriod := 1
|
||||
initId := "initId"
|
||||
|
||||
@ -28,6 +32,7 @@ func TestDiffService(t *testing.T) {
|
||||
spaceId: spaceId,
|
||||
storage: storageMock,
|
||||
periodicSync: pSyncMock,
|
||||
syncer: syncer,
|
||||
diff: diffMock,
|
||||
log: l,
|
||||
syncPeriod: syncPeriod,
|
||||
@ -36,22 +41,25 @@ func TestDiffService(t *testing.T) {
|
||||
t.Run("init", func(t *testing.T) {
|
||||
storageMock.EXPECT().TreeStorage(initId).Return(treeStorageMock, nil)
|
||||
treeStorageMock.EXPECT().Heads().Return([]string{"h1", "h2"}, nil)
|
||||
syncer.EXPECT().Init(delState)
|
||||
diffMock.EXPECT().Set(ldiff.Element{
|
||||
Id: initId,
|
||||
Head: "h1h2",
|
||||
})
|
||||
pSyncMock.EXPECT().Run()
|
||||
service.Init([]string{initId})
|
||||
service.Init([]string{initId}, delState)
|
||||
})
|
||||
|
||||
t.Run("update heads", func(t *testing.T) {
|
||||
diffMock.EXPECT().Set(ldiff.Element{
|
||||
Id: initId,
|
||||
Head: "h1h2",
|
||||
})
|
||||
syncer.EXPECT().UpdateHeads(initId, []string{"h1", "h2"})
|
||||
service.UpdateHeads(initId, []string{"h1", "h2"})
|
||||
})
|
||||
|
||||
t.Run("remove objects", func(t *testing.T) {
|
||||
syncer.EXPECT().RemoveObjects([]string{"h1", "h2"})
|
||||
service.RemoveObjects([]string{"h1", "h2"})
|
||||
})
|
||||
|
||||
t.Run("close", func(t *testing.T) {
|
||||
pSyncMock.EXPECT().Close()
|
||||
service.Close()
|
||||
|
||||
@ -3,8 +3,10 @@ package diffservice
|
||||
import (
|
||||
"context"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/remotediff"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/settingsdocument/deletionstate"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/peer"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/rpc/rpcerr"
|
||||
@ -16,6 +18,9 @@ import (
|
||||
|
||||
type DiffSyncer interface {
|
||||
Sync(ctx context.Context) error
|
||||
RemoveObjects(ids []string)
|
||||
UpdateHeads(id string, heads []string)
|
||||
Init(deletionState deletionstate.DeletionState)
|
||||
}
|
||||
|
||||
func newDiffSyncer(
|
||||
@ -45,6 +50,28 @@ type diffSyncer struct {
|
||||
storage storage.SpaceStorage
|
||||
clientFactory spacesyncproto.ClientFactory
|
||||
log *zap.Logger
|
||||
deletionState deletionstate.DeletionState
|
||||
}
|
||||
|
||||
func (d *diffSyncer) Init(deletionState deletionstate.DeletionState) {
|
||||
d.deletionState = deletionState
|
||||
d.deletionState.AddObserver(d.RemoveObjects)
|
||||
}
|
||||
|
||||
func (d *diffSyncer) RemoveObjects(ids []string) {
|
||||
for _, id := range ids {
|
||||
d.diff.RemoveId(id)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *diffSyncer) UpdateHeads(id string, heads []string) {
|
||||
if d.deletionState.Exists(id) {
|
||||
return
|
||||
}
|
||||
d.diff.Set(ldiff.Element{
|
||||
Id: id,
|
||||
Head: concatStrings(heads),
|
||||
})
|
||||
}
|
||||
|
||||
func (d *diffSyncer) Sync(ctx context.Context) error {
|
||||
@ -74,21 +101,35 @@ func (d *diffSyncer) syncWithPeer(ctx context.Context, p peer.Peer) (err error)
|
||||
if err == spacesyncproto.ErrSpaceMissing {
|
||||
return d.sendPushSpaceRequest(ctx, cl)
|
||||
}
|
||||
totalLen := len(newIds) + len(changedIds) + len(removedIds)
|
||||
// not syncing ids which were removed through settings document
|
||||
filteredIds := d.deletionState.FilterJoin(newIds, changedIds, removedIds)
|
||||
|
||||
ctx = peer.CtxWithPeerId(ctx, p.Id())
|
||||
d.pingTreesInCache(ctx, newIds)
|
||||
d.pingTreesInCache(ctx, changedIds)
|
||||
d.pingTreesInCache(ctx, removedIds)
|
||||
d.pingTreesInCache(ctx, filteredIds)
|
||||
|
||||
d.log.Info("sync done:", zap.Int("newIds", len(newIds)),
|
||||
zap.Int("changedIds", len(changedIds)),
|
||||
zap.Int("removedIds", len(removedIds)))
|
||||
zap.Int("removedIds", len(removedIds)),
|
||||
zap.Int("already deleted ids", totalLen-len(filteredIds)))
|
||||
return
|
||||
}
|
||||
|
||||
func (d *diffSyncer) pingTreesInCache(ctx context.Context, trees []string) {
|
||||
for _, tId := range trees {
|
||||
_, _ = d.cache.GetTree(ctx, d.spaceId, tId)
|
||||
tree, err := d.cache.GetTree(ctx, d.spaceId, tId)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
syncTree, ok := tree.(synctree.SyncTree)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
// the idea why we call it directly is that if we try to get it from cache
|
||||
// it may be already there (i.e. loaded)
|
||||
// and build func will not be called, thus we won't sync the tree
|
||||
// therefore we just do it manually
|
||||
syncTree.Ping()
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,10 +149,24 @@ func (d *diffSyncer) sendPushSpaceRequest(ctx context.Context, cl spacesyncproto
|
||||
return
|
||||
}
|
||||
|
||||
settingsStorage, err := d.storage.TreeStorage(d.storage.SpaceSettingsId())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
spaceSettingsRoot, err := settingsStorage.Root()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
spacePayload := &spacesyncproto.SpacePayload{
|
||||
SpaceHeader: header,
|
||||
AclPayload: root.Payload,
|
||||
AclPayloadId: root.Id,
|
||||
SpaceSettingsPayload: spaceSettingsRoot.RawChange,
|
||||
SpaceSettingsPayloadId: spaceSettingsRoot.Id,
|
||||
}
|
||||
_, err = cl.PushSpace(ctx, &spacesyncproto.PushSpaceRequest{
|
||||
SpaceHeader: header,
|
||||
AclPayload: root.Payload,
|
||||
AclPayloadId: root.Id,
|
||||
Payload: spacePayload,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/remotediff"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/settingsdocument/deletionstate/mock_deletionstate"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto/mock_spacesyncproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage/mock_storage"
|
||||
@ -13,6 +14,9 @@ import (
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf/mock_nodeconf"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto"
|
||||
mock_aclstorage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage/mock_storage"
|
||||
mock_treestorage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage/mock_storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ldiff"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ldiff/mock_ldiff"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/libp2p/go-libp2p/core/sec"
|
||||
@ -25,6 +29,7 @@ import (
|
||||
type pushSpaceRequestMatcher struct {
|
||||
spaceId string
|
||||
aclRootId string
|
||||
settingsId string
|
||||
spaceHeader *spacesyncproto.RawSpaceHeaderWithId
|
||||
}
|
||||
|
||||
@ -34,7 +39,7 @@ func (p pushSpaceRequestMatcher) Matches(x interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
return res.AclPayloadId == p.aclRootId && res.SpaceHeader == p.spaceHeader
|
||||
return res.Payload.AclPayloadId == p.aclRootId && res.Payload.SpaceHeader == p.spaceHeader && res.Payload.SpaceSettingsPayloadId == p.settingsId
|
||||
}
|
||||
|
||||
func (p pushSpaceRequestMatcher) String() string {
|
||||
@ -77,10 +82,12 @@ func (m mockPeer) NewStream(ctx context.Context, rpc string, enc drpc.Encoding)
|
||||
func newPushSpaceRequestMatcher(
|
||||
spaceId string,
|
||||
aclRootId string,
|
||||
settingsId string,
|
||||
spaceHeader *spacesyncproto.RawSpaceHeaderWithId) *pushSpaceRequestMatcher {
|
||||
return &pushSpaceRequestMatcher{
|
||||
spaceId: spaceId,
|
||||
aclRootId: aclRootId,
|
||||
settingsId: settingsId,
|
||||
spaceHeader: spaceHeader,
|
||||
}
|
||||
}
|
||||
@ -99,18 +106,22 @@ func TestDiffSyncer_Sync(t *testing.T) {
|
||||
factory := spacesyncproto.ClientFactoryFunc(func(cc drpc.Conn) spacesyncproto.DRPCSpaceClient {
|
||||
return clientMock
|
||||
})
|
||||
delState := mock_deletionstate.NewMockDeletionState(ctrl)
|
||||
spaceId := "spaceId"
|
||||
aclRootId := "aclRootId"
|
||||
l := logger.NewNamed(spaceId)
|
||||
diffSyncer := newDiffSyncer(spaceId, diffMock, connectorMock, cacheMock, stMock, factory, l)
|
||||
delState.EXPECT().AddObserver(gomock.Any())
|
||||
diffSyncer.Init(delState)
|
||||
|
||||
t.Run("diff syncer sync simple", func(t *testing.T) {
|
||||
t.Run("diff syncer sync", func(t *testing.T) {
|
||||
connectorMock.EXPECT().
|
||||
GetResponsiblePeers(gomock.Any(), spaceId).
|
||||
Return([]peer.Peer{mockPeer{}}, nil)
|
||||
diffMock.EXPECT().
|
||||
Diff(gomock.Any(), gomock.Eq(remotediff.NewRemoteDiff(spaceId, clientMock))).
|
||||
Return([]string{"new"}, []string{"changed"}, nil, nil)
|
||||
delState.EXPECT().FilterJoin(gomock.Any()).Return([]string{"new", "changed"})
|
||||
for _, arg := range []string{"new", "changed"} {
|
||||
cacheMock.EXPECT().
|
||||
GetTree(gomock.Any(), spaceId, arg).
|
||||
@ -127,12 +138,37 @@ func TestDiffSyncer_Sync(t *testing.T) {
|
||||
require.Error(t, diffSyncer.Sync(ctx))
|
||||
})
|
||||
|
||||
t.Run("deletion state remove objects", func(t *testing.T) {
|
||||
deletedId := "id"
|
||||
delState.EXPECT().Exists(deletedId).Return(true)
|
||||
|
||||
// this should not result in any mock being called
|
||||
diffSyncer.UpdateHeads(deletedId, []string{"someHead"})
|
||||
})
|
||||
|
||||
t.Run("update heads updates diff", func(t *testing.T) {
|
||||
newId := "newId"
|
||||
newHeads := []string{"h1", "h2"}
|
||||
diffMock.EXPECT().Set(ldiff.Element{
|
||||
Id: newId,
|
||||
Head: concatStrings(newHeads),
|
||||
})
|
||||
delState.EXPECT().Exists(newId).Return(false)
|
||||
diffSyncer.UpdateHeads(newId, newHeads)
|
||||
})
|
||||
|
||||
t.Run("diff syncer sync space missing", func(t *testing.T) {
|
||||
aclStorageMock := mock_aclstorage.NewMockListStorage(ctrl)
|
||||
settingsStorage := mock_treestorage.NewMockTreeStorage(ctrl)
|
||||
settingsId := "settingsId"
|
||||
aclRoot := &aclrecordproto.RawACLRecordWithId{
|
||||
Id: aclRootId,
|
||||
}
|
||||
settingsRoot := &treechangeproto.RawTreeChangeWithId{
|
||||
Id: settingsId,
|
||||
}
|
||||
spaceHeader := &spacesyncproto.RawSpaceHeaderWithId{}
|
||||
spaceSettingsId := "spaceSettingsId"
|
||||
|
||||
connectorMock.EXPECT().
|
||||
GetResponsiblePeers(gomock.Any(), spaceId).
|
||||
@ -140,17 +176,18 @@ func TestDiffSyncer_Sync(t *testing.T) {
|
||||
diffMock.EXPECT().
|
||||
Diff(gomock.Any(), gomock.Eq(remotediff.NewRemoteDiff(spaceId, clientMock))).
|
||||
Return(nil, nil, nil, spacesyncproto.ErrSpaceMissing)
|
||||
stMock.EXPECT().
|
||||
ACLStorage().
|
||||
Return(aclStorageMock, nil)
|
||||
stMock.EXPECT().
|
||||
SpaceHeader().
|
||||
Return(spaceHeader, nil)
|
||||
|
||||
stMock.EXPECT().ACLStorage().Return(aclStorageMock, nil)
|
||||
stMock.EXPECT().SpaceHeader().Return(spaceHeader, nil)
|
||||
stMock.EXPECT().SpaceSettingsId().Return(spaceSettingsId)
|
||||
stMock.EXPECT().TreeStorage(spaceSettingsId).Return(settingsStorage, nil)
|
||||
|
||||
settingsStorage.EXPECT().Root().Return(settingsRoot, nil)
|
||||
aclStorageMock.EXPECT().
|
||||
Root().
|
||||
Return(aclRoot, nil)
|
||||
clientMock.EXPECT().
|
||||
PushSpace(gomock.Any(), newPushSpaceRequestMatcher(spaceId, aclRootId, spaceHeader)).
|
||||
PushSpace(gomock.Any(), newPushSpaceRequestMatcher(spaceId, aclRootId, settingsId, spaceHeader)).
|
||||
Return(nil, nil)
|
||||
|
||||
require.NoError(t, diffSyncer.Sync(ctx))
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
package diffservice
|
||||
|
||||
type HeadNotifiable interface {
|
||||
UpdateHeads(id string, heads []string)
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/diffservice (interfaces: DiffSyncer,PeriodicSync)
|
||||
// Source: github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/diffservice (interfaces: DiffSyncer)
|
||||
|
||||
// Package mock_diffservice is a generated GoMock package.
|
||||
package mock_diffservice
|
||||
@ -8,6 +8,7 @@ import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
deletionstate "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/settingsdocument/deletionstate"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
)
|
||||
|
||||
@ -34,6 +35,30 @@ func (m *MockDiffSyncer) EXPECT() *MockDiffSyncerMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Init mocks base method.
|
||||
func (m *MockDiffSyncer) Init(arg0 deletionstate.DeletionState) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "Init", arg0)
|
||||
}
|
||||
|
||||
// Init indicates an expected call of Init.
|
||||
func (mr *MockDiffSyncerMockRecorder) Init(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockDiffSyncer)(nil).Init), arg0)
|
||||
}
|
||||
|
||||
// RemoveObjects mocks base method.
|
||||
func (m *MockDiffSyncer) RemoveObjects(arg0 []string) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "RemoveObjects", arg0)
|
||||
}
|
||||
|
||||
// RemoveObjects indicates an expected call of RemoveObjects.
|
||||
func (mr *MockDiffSyncerMockRecorder) RemoveObjects(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveObjects", reflect.TypeOf((*MockDiffSyncer)(nil).RemoveObjects), arg0)
|
||||
}
|
||||
|
||||
// Sync mocks base method.
|
||||
func (m *MockDiffSyncer) Sync(arg0 context.Context) error {
|
||||
m.ctrl.T.Helper()
|
||||
@ -48,49 +73,14 @@ func (mr *MockDiffSyncerMockRecorder) Sync(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Sync", reflect.TypeOf((*MockDiffSyncer)(nil).Sync), arg0)
|
||||
}
|
||||
|
||||
// MockPeriodicSync is a mock of PeriodicSync interface.
|
||||
type MockPeriodicSync struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockPeriodicSyncMockRecorder
|
||||
}
|
||||
|
||||
// MockPeriodicSyncMockRecorder is the mock recorder for MockPeriodicSync.
|
||||
type MockPeriodicSyncMockRecorder struct {
|
||||
mock *MockPeriodicSync
|
||||
}
|
||||
|
||||
// NewMockPeriodicSync creates a new mock instance.
|
||||
func NewMockPeriodicSync(ctrl *gomock.Controller) *MockPeriodicSync {
|
||||
mock := &MockPeriodicSync{ctrl: ctrl}
|
||||
mock.recorder = &MockPeriodicSyncMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockPeriodicSync) EXPECT() *MockPeriodicSyncMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Close mocks base method.
|
||||
func (m *MockPeriodicSync) Close() {
|
||||
// UpdateHeads mocks base method.
|
||||
func (m *MockDiffSyncer) UpdateHeads(arg0 string, arg1 []string) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "Close")
|
||||
m.ctrl.Call(m, "UpdateHeads", arg0, arg1)
|
||||
}
|
||||
|
||||
// Close indicates an expected call of Close.
|
||||
func (mr *MockPeriodicSyncMockRecorder) Close() *gomock.Call {
|
||||
// UpdateHeads indicates an expected call of UpdateHeads.
|
||||
func (mr *MockDiffSyncerMockRecorder) UpdateHeads(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockPeriodicSync)(nil).Close))
|
||||
}
|
||||
|
||||
// Run mocks base method.
|
||||
func (m *MockPeriodicSync) Run() {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "Run")
|
||||
}
|
||||
|
||||
// Run indicates an expected call of Run.
|
||||
func (mr *MockPeriodicSyncMockRecorder) Run() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockPeriodicSync)(nil).Run))
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateHeads", reflect.TypeOf((*MockDiffSyncer)(nil).UpdateHeads), arg0, arg1)
|
||||
}
|
||||
|
||||
@ -3,7 +3,9 @@ package commonspace
|
||||
import (
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
|
||||
aclrecordproto2 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto"
|
||||
aclrecordproto "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/common"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/cid"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/signingkey"
|
||||
"hash/fnv"
|
||||
@ -11,6 +13,11 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
SpaceSettingsChangeType = "reserved.spacesettings"
|
||||
SpaceDerivationScheme = "derivation.standard"
|
||||
)
|
||||
|
||||
func storagePayloadForSpaceCreate(payload SpaceCreatePayload) (storagePayload storage.SpaceStorageCreatePayload, err error) {
|
||||
// unmarshalling signing and encryption keys
|
||||
identity, err := payload.SigningKey.GetPublic().Raw()
|
||||
@ -23,8 +30,8 @@ func storagePayloadForSpaceCreate(payload SpaceCreatePayload) (storagePayload st
|
||||
}
|
||||
|
||||
// preparing header and space id
|
||||
bytes := make([]byte, 32)
|
||||
_, err = rand.Read(bytes)
|
||||
spaceHeaderSeed := make([]byte, 32)
|
||||
_, err = rand.Read(spaceHeaderSeed)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@ -33,7 +40,7 @@ func storagePayloadForSpaceCreate(payload SpaceCreatePayload) (storagePayload st
|
||||
Timestamp: time.Now().UnixNano(),
|
||||
SpaceType: payload.SpaceType,
|
||||
ReplicationKey: payload.ReplicationKey,
|
||||
Seed: bytes,
|
||||
Seed: spaceHeaderSeed,
|
||||
}
|
||||
marshalled, err := header.Marshal()
|
||||
if err != nil {
|
||||
@ -68,12 +75,11 @@ func storagePayloadForSpaceCreate(payload SpaceCreatePayload) (storagePayload st
|
||||
}
|
||||
|
||||
// preparing acl
|
||||
aclRoot := &aclrecordproto2.ACLRoot{
|
||||
aclRoot := &aclrecordproto.ACLRoot{
|
||||
Identity: identity,
|
||||
EncryptionKey: encPubKey,
|
||||
SpaceId: spaceId,
|
||||
EncryptedReadKey: encReadKey,
|
||||
DerivationScheme: "",
|
||||
CurrentReadKeyHash: readKeyHash,
|
||||
Timestamp: time.Now().UnixNano(),
|
||||
}
|
||||
@ -82,10 +88,31 @@ func storagePayloadForSpaceCreate(payload SpaceCreatePayload) (storagePayload st
|
||||
return
|
||||
}
|
||||
|
||||
builder := tree.NewChangeBuilder(common.NewKeychain(), nil)
|
||||
spaceSettingsSeed := make([]byte, 32)
|
||||
_, err = rand.Read(spaceSettingsSeed)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
_, settingsRoot, err := builder.BuildInitialContent(tree.InitialContent{
|
||||
AclHeadId: rawWithId.Id,
|
||||
Identity: aclRoot.Identity,
|
||||
SigningKey: payload.SigningKey,
|
||||
SpaceId: spaceId,
|
||||
Seed: spaceSettingsSeed,
|
||||
ChangeType: SpaceSettingsChangeType,
|
||||
Timestamp: time.Now().UnixNano(),
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// creating storage
|
||||
storagePayload = storage.SpaceStorageCreatePayload{
|
||||
RecWithId: rawWithId,
|
||||
SpaceHeaderWithId: rawHeaderWithId,
|
||||
AclWithId: rawWithId,
|
||||
SpaceHeaderWithId: rawHeaderWithId,
|
||||
SpaceSettingsWithId: settingsRoot,
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -144,7 +171,7 @@ func storagePayloadForSpaceDerive(payload SpaceDerivePayload) (storagePayload st
|
||||
}
|
||||
|
||||
// deriving and encrypting read key
|
||||
readKey, err := aclrecordproto2.ACLReadKeyDerive(signPrivKey, encPrivKey)
|
||||
readKey, err := aclrecordproto.ACLReadKeyDerive(signPrivKey, encPrivKey)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@ -160,29 +187,41 @@ func storagePayloadForSpaceDerive(payload SpaceDerivePayload) (storagePayload st
|
||||
}
|
||||
|
||||
// preparing acl
|
||||
aclRoot := &aclrecordproto2.ACLRoot{
|
||||
aclRoot := &aclrecordproto.ACLRoot{
|
||||
Identity: identity,
|
||||
EncryptionKey: encPubKey,
|
||||
SpaceId: spaceId,
|
||||
EncryptedReadKey: encReadKey,
|
||||
DerivationScheme: "",
|
||||
DerivationScheme: SpaceDerivationScheme,
|
||||
CurrentReadKeyHash: readKeyHash,
|
||||
Timestamp: time.Now().UnixNano(),
|
||||
}
|
||||
rawWithId, err := marshalACLRoot(aclRoot, payload.SigningKey)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
builder := tree.NewChangeBuilder(common.NewKeychain(), nil)
|
||||
_, settingsRoot, err := builder.BuildInitialContent(tree.InitialContent{
|
||||
AclHeadId: rawWithId.Id,
|
||||
Identity: aclRoot.Identity,
|
||||
SigningKey: payload.SigningKey,
|
||||
SpaceId: spaceId,
|
||||
ChangeType: SpaceSettingsChangeType,
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// creating storage
|
||||
storagePayload = storage.SpaceStorageCreatePayload{
|
||||
RecWithId: rawWithId,
|
||||
SpaceHeaderWithId: rawHeaderWithId,
|
||||
AclWithId: rawWithId,
|
||||
SpaceHeaderWithId: rawHeaderWithId,
|
||||
SpaceSettingsWithId: settingsRoot,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func marshalACLRoot(aclRoot *aclrecordproto2.ACLRoot, key signingkey.PrivKey) (rawWithId *aclrecordproto2.RawACLRecordWithId, err error) {
|
||||
func marshalACLRoot(aclRoot *aclrecordproto.ACLRoot, key signingkey.PrivKey) (rawWithId *aclrecordproto.RawACLRecordWithId, err error) {
|
||||
marshalledRoot, err := aclRoot.Marshal()
|
||||
if err != nil {
|
||||
return
|
||||
@ -191,7 +230,7 @@ func marshalACLRoot(aclRoot *aclrecordproto2.ACLRoot, key signingkey.PrivKey) (r
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
raw := &aclrecordproto2.RawACLRecord{
|
||||
raw := &aclrecordproto.RawACLRecord{
|
||||
Payload: marshalledRoot,
|
||||
Signature: signature,
|
||||
}
|
||||
@ -203,7 +242,7 @@ func marshalACLRoot(aclRoot *aclrecordproto2.ACLRoot, key signingkey.PrivKey) (r
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
rawWithId = &aclrecordproto2.RawACLRecordWithId{
|
||||
rawWithId = &aclrecordproto.RawACLRecordWithId{
|
||||
Payload: marshalledRaw,
|
||||
Id: aclHeadId,
|
||||
}
|
||||
|
||||
@ -15,6 +15,7 @@ import (
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/pool"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto"
|
||||
)
|
||||
|
||||
const CName = "common.commonspace"
|
||||
@ -25,11 +26,14 @@ func New() Service {
|
||||
return &service{}
|
||||
}
|
||||
|
||||
type ctxKey int
|
||||
|
||||
const AddSpaceCtxKey ctxKey = 0
|
||||
|
||||
type Service interface {
|
||||
DeriveSpace(ctx context.Context, payload SpaceDerivePayload) (string, error)
|
||||
CreateSpace(ctx context.Context, payload SpaceCreatePayload) (string, error)
|
||||
NewSpace(ctx context.Context, id string) (sp Space, err error)
|
||||
AddSpace(ctx context.Context, spaceDescription SpaceDescription) (err error)
|
||||
app.Component
|
||||
}
|
||||
|
||||
@ -82,47 +86,23 @@ func (s *service) DeriveSpace(ctx context.Context, payload SpaceDerivePayload) (
|
||||
return store.Id(), nil
|
||||
}
|
||||
|
||||
func (s *service) AddSpace(ctx context.Context, spaceDescription SpaceDescription) (err error) {
|
||||
_, err = s.storageProvider.SpaceStorage(spaceDescription.SpaceHeader.Id)
|
||||
if err == nil {
|
||||
err = spacesyncproto.ErrSpaceExists
|
||||
return
|
||||
}
|
||||
if err != storage.ErrSpaceStorageMissing {
|
||||
err = spacesyncproto.ErrUnexpected
|
||||
return
|
||||
}
|
||||
|
||||
payload := storage.SpaceStorageCreatePayload{
|
||||
RecWithId: &aclrecordproto.RawACLRecordWithId{
|
||||
Payload: spaceDescription.AclPayload,
|
||||
Id: spaceDescription.AclId,
|
||||
},
|
||||
SpaceHeaderWithId: spaceDescription.SpaceHeader,
|
||||
}
|
||||
st, err := s.storageProvider.CreateSpaceStorage(payload)
|
||||
if err != nil {
|
||||
err = spacesyncproto.ErrUnexpected
|
||||
if err == storage.ErrSpaceStorageExists {
|
||||
err = spacesyncproto.ErrSpaceExists
|
||||
}
|
||||
return
|
||||
}
|
||||
err = st.Close()
|
||||
return
|
||||
}
|
||||
|
||||
func (s *service) NewSpace(ctx context.Context, id string) (Space, error) {
|
||||
st, err := s.storageProvider.SpaceStorage(id)
|
||||
if err != nil {
|
||||
if err != spacesyncproto.ErrSpaceMissing {
|
||||
if err != storage.ErrSpaceStorageMissing {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
st, err = s.getSpaceStorageFromRemote(ctx, id)
|
||||
if err != nil {
|
||||
err = storage.ErrSpaceStorageMissing
|
||||
return nil, err
|
||||
if description, ok := ctx.Value(AddSpaceCtxKey).(SpaceDescription); ok {
|
||||
st, err = s.addSpaceStorage(ctx, description)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
st, err = s.getSpaceStorageFromRemote(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,10 +122,33 @@ func (s *service) NewSpace(ctx context.Context, id string) (Space, error) {
|
||||
return sp, nil
|
||||
}
|
||||
|
||||
func (s *service) addSpaceStorage(ctx context.Context, spaceDescription SpaceDescription) (st storage.SpaceStorage, err error) {
|
||||
payload := storage.SpaceStorageCreatePayload{
|
||||
AclWithId: &aclrecordproto.RawACLRecordWithId{
|
||||
Payload: spaceDescription.AclPayload,
|
||||
Id: spaceDescription.AclId,
|
||||
},
|
||||
SpaceHeaderWithId: spaceDescription.SpaceHeader,
|
||||
SpaceSettingsWithId: &treechangeproto.RawTreeChangeWithId{
|
||||
RawChange: spaceDescription.SpaceSettingsPayload,
|
||||
Id: spaceDescription.SpaceSettingsId,
|
||||
},
|
||||
}
|
||||
st, err = s.storageProvider.CreateSpaceStorage(payload)
|
||||
if err != nil {
|
||||
err = spacesyncproto.ErrUnexpected
|
||||
if err == storage.ErrSpaceStorageExists {
|
||||
err = spacesyncproto.ErrSpaceExists
|
||||
}
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *service) getSpaceStorageFromRemote(ctx context.Context, id string) (st storage.SpaceStorage, err error) {
|
||||
var p peer.Peer
|
||||
lastConfiguration := s.configurationService.GetLast()
|
||||
// for nodes we always get remote space only if we have id in the context
|
||||
// we can't connect to client if it is a node
|
||||
if lastConfiguration.IsResponsible(id) {
|
||||
err = spacesyncproto.ErrSpaceMissing
|
||||
return
|
||||
@ -161,12 +164,17 @@ func (s *service) getSpaceStorageFromRemote(ctx context.Context, id string) (st
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
st, err = s.storageProvider.CreateSpaceStorage(storage.SpaceStorageCreatePayload{
|
||||
RecWithId: &aclrecordproto.RawACLRecordWithId{
|
||||
Payload: res.AclPayload,
|
||||
Id: res.AclPayloadId,
|
||||
AclWithId: &aclrecordproto.RawACLRecordWithId{
|
||||
Payload: res.Payload.AclPayload,
|
||||
Id: res.Payload.AclPayloadId,
|
||||
},
|
||||
SpaceHeaderWithId: res.SpaceHeader,
|
||||
SpaceSettingsWithId: &treechangeproto.RawTreeChangeWithId{
|
||||
RawChange: res.Payload.SpaceSettingsPayload,
|
||||
Id: res.Payload.SpaceSettingsPayloadId,
|
||||
},
|
||||
SpaceHeaderWithId: res.Payload.SpaceHeader,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
53
common/commonspace/settingsdocument/deleteloop.go
Normal file
53
common/commonspace/settingsdocument/deleteloop.go
Normal file
@ -0,0 +1,53 @@
|
||||
package settingsdocument
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
type deleteLoop struct {
|
||||
deleteCtx context.Context
|
||||
deleteCancel context.CancelFunc
|
||||
deleteChan chan struct{}
|
||||
deleteFunc func()
|
||||
loopDone chan struct{}
|
||||
}
|
||||
|
||||
func newDeleteLoop(deleteFunc func()) *deleteLoop {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
return &deleteLoop{
|
||||
deleteCtx: ctx,
|
||||
deleteCancel: cancel,
|
||||
deleteChan: make(chan struct{}, 1),
|
||||
deleteFunc: deleteFunc,
|
||||
loopDone: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
func (dl *deleteLoop) Run() {
|
||||
go dl.loop()
|
||||
}
|
||||
|
||||
func (dl *deleteLoop) loop() {
|
||||
defer close(dl.loopDone)
|
||||
dl.deleteFunc()
|
||||
for {
|
||||
select {
|
||||
case <-dl.deleteCtx.Done():
|
||||
return
|
||||
case <-dl.deleteChan:
|
||||
dl.deleteFunc()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (dl *deleteLoop) notify() {
|
||||
select {
|
||||
case dl.deleteChan <- struct{}{}:
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
func (dl *deleteLoop) Close() {
|
||||
dl.deleteCancel()
|
||||
<-dl.loopDone
|
||||
}
|
||||
39
common/commonspace/settingsdocument/deleter.go
Normal file
39
common/commonspace/settingsdocument/deleter.go
Normal file
@ -0,0 +1,39 @@
|
||||
package settingsdocument
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/settingsdocument/deletionstate"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type Deleter interface {
|
||||
Delete()
|
||||
}
|
||||
|
||||
type deleter struct {
|
||||
st storage.SpaceStorage
|
||||
state deletionstate.DeletionState
|
||||
getter treegetter.TreeGetter
|
||||
}
|
||||
|
||||
func newDeleter(st storage.SpaceStorage, state deletionstate.DeletionState, getter treegetter.TreeGetter) Deleter {
|
||||
return &deleter{st, state, getter}
|
||||
}
|
||||
|
||||
func (d *deleter) Delete() {
|
||||
allQueued := d.state.GetQueued()
|
||||
for _, id := range allQueued {
|
||||
err := d.getter.DeleteTree(context.Background(), d.st.Id(), id)
|
||||
if err != nil && err != storage.ErrTreeStorageAlreadyDeleted {
|
||||
log.With(zap.String("id", id), zap.Error(err)).Error("failed to delete object")
|
||||
continue
|
||||
}
|
||||
err = d.state.Delete(id)
|
||||
if err != nil {
|
||||
log.With(zap.String("id", id), zap.Error(err)).Error("failed to mark object as deleted")
|
||||
}
|
||||
log.With(zap.String("id", id), zap.Error(err)).Debug("object successfully deleted")
|
||||
}
|
||||
}
|
||||
52
common/commonspace/settingsdocument/deleter_test.go
Normal file
52
common/commonspace/settingsdocument/deleter_test.go
Normal file
@ -0,0 +1,52 @@
|
||||
package settingsdocument
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/settingsdocument/deletionstate/mock_deletionstate"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage/mock_storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter/mock_treegetter"
|
||||
"github.com/golang/mock/gomock"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDeleter_Delete(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
treeGetter := mock_treegetter.NewMockTreeGetter(ctrl)
|
||||
st := mock_storage.NewMockSpaceStorage(ctrl)
|
||||
delState := mock_deletionstate.NewMockDeletionState(ctrl)
|
||||
|
||||
deleter := newDeleter(st, delState, treeGetter)
|
||||
|
||||
t.Run("deleter delete queued", func(t *testing.T) {
|
||||
id := "id"
|
||||
spaceId := "spaceId"
|
||||
delState.EXPECT().GetQueued().Return([]string{id})
|
||||
st.EXPECT().Id().Return(spaceId)
|
||||
treeGetter.EXPECT().DeleteTree(gomock.Any(), spaceId, id).Return(nil)
|
||||
delState.EXPECT().Delete(id).Return(nil)
|
||||
|
||||
deleter.Delete()
|
||||
})
|
||||
|
||||
t.Run("deleter delete already deleted", func(t *testing.T) {
|
||||
id := "id"
|
||||
spaceId := "spaceId"
|
||||
delState.EXPECT().GetQueued().Return([]string{id})
|
||||
st.EXPECT().Id().Return(spaceId)
|
||||
treeGetter.EXPECT().DeleteTree(gomock.Any(), spaceId, id).Return(storage.ErrTreeStorageAlreadyDeleted)
|
||||
delState.EXPECT().Delete(id).Return(nil)
|
||||
|
||||
deleter.Delete()
|
||||
})
|
||||
|
||||
t.Run("deleter delete error", func(t *testing.T) {
|
||||
id := "id"
|
||||
spaceId := "spaceId"
|
||||
delState.EXPECT().GetQueued().Return([]string{id})
|
||||
st.EXPECT().Id().Return(spaceId)
|
||||
treeGetter.EXPECT().DeleteTree(gomock.Any(), spaceId, id).Return(fmt.Errorf("some error"))
|
||||
|
||||
deleter.Delete()
|
||||
})
|
||||
}
|
||||
@ -0,0 +1,153 @@
|
||||
//go:generate mockgen -destination mock_deletionstate/mock_deletionstate.go github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/settingsdocument/deletionstate DeletionState
|
||||
package deletionstate
|
||||
|
||||
import (
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type StateUpdateObserver func(ids []string)
|
||||
|
||||
type DeletionState interface {
|
||||
AddObserver(observer StateUpdateObserver)
|
||||
Add(ids []string) (err error)
|
||||
GetQueued() (ids []string)
|
||||
Delete(id string) (err error)
|
||||
Exists(id string) bool
|
||||
FilterJoin(ids ...[]string) (filtered []string)
|
||||
CreateDeleteChange(id string, isSnapshot bool) (res []byte, err error)
|
||||
}
|
||||
|
||||
type deletionState struct {
|
||||
sync.RWMutex
|
||||
queued map[string]struct{}
|
||||
deleted map[string]struct{}
|
||||
stateUpdateObservers []StateUpdateObserver
|
||||
storage storage.SpaceStorage
|
||||
}
|
||||
|
||||
func NewDeletionState(storage storage.SpaceStorage) DeletionState {
|
||||
return &deletionState{
|
||||
queued: map[string]struct{}{},
|
||||
deleted: map[string]struct{}{},
|
||||
storage: storage,
|
||||
}
|
||||
}
|
||||
|
||||
func (st *deletionState) AddObserver(observer StateUpdateObserver) {
|
||||
st.Lock()
|
||||
defer st.Unlock()
|
||||
st.stateUpdateObservers = append(st.stateUpdateObservers, observer)
|
||||
}
|
||||
|
||||
func (st *deletionState) Add(ids []string) (err error) {
|
||||
st.Lock()
|
||||
defer func() {
|
||||
st.Unlock()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, ob := range st.stateUpdateObservers {
|
||||
ob(ids)
|
||||
}
|
||||
}()
|
||||
|
||||
for _, id := range ids {
|
||||
if _, exists := st.deleted[id]; exists {
|
||||
continue
|
||||
}
|
||||
if _, exists := st.queued[id]; exists {
|
||||
continue
|
||||
}
|
||||
|
||||
var status string
|
||||
status, err = st.storage.TreeDeletedStatus(id)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
switch status {
|
||||
case storage.TreeDeletedStatusQueued:
|
||||
st.queued[id] = struct{}{}
|
||||
case storage.TreeDeletedStatusDeleted:
|
||||
st.deleted[id] = struct{}{}
|
||||
default:
|
||||
st.queued[id] = struct{}{}
|
||||
err = st.storage.SetTreeDeletedStatus(id, storage.TreeDeletedStatusQueued)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (st *deletionState) GetQueued() (ids []string) {
|
||||
st.RLock()
|
||||
defer st.RUnlock()
|
||||
ids = make([]string, 0, len(st.queued))
|
||||
for id := range st.queued {
|
||||
ids = append(ids, id)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (st *deletionState) Delete(id string) (err error) {
|
||||
st.Lock()
|
||||
defer st.Unlock()
|
||||
delete(st.queued, id)
|
||||
st.deleted[id] = struct{}{}
|
||||
err = st.storage.SetTreeDeletedStatus(id, storage.TreeDeletedStatusDeleted)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (st *deletionState) Exists(id string) bool {
|
||||
st.RLock()
|
||||
defer st.RUnlock()
|
||||
return st.exists(id)
|
||||
}
|
||||
|
||||
func (st *deletionState) FilterJoin(ids ...[]string) (filtered []string) {
|
||||
st.RLock()
|
||||
defer st.RUnlock()
|
||||
filter := func(ids []string) {
|
||||
for _, id := range ids {
|
||||
if !st.exists(id) {
|
||||
filtered = append(filtered, id)
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, arr := range ids {
|
||||
filter(arr)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (st *deletionState) CreateDeleteChange(id string, isSnapshot bool) (res []byte, err error) {
|
||||
content := &spacesyncproto.SpaceSettingsContent_ObjectDelete{
|
||||
ObjectDelete: &spacesyncproto.ObjectDelete{Id: id},
|
||||
}
|
||||
change := &spacesyncproto.SettingsData{
|
||||
Content: []*spacesyncproto.SpaceSettingsContent{
|
||||
{content},
|
||||
},
|
||||
Snapshot: nil,
|
||||
}
|
||||
// TODO: add snapshot logic
|
||||
res, err = change.Marshal()
|
||||
return
|
||||
}
|
||||
|
||||
func (st *deletionState) exists(id string) bool {
|
||||
if _, exists := st.deleted[id]; exists {
|
||||
return true
|
||||
}
|
||||
if _, exists := st.queued[id]; exists {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
@ -0,0 +1,127 @@
|
||||
package deletionstate
|
||||
|
||||
import (
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage/mock_storage"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/stretchr/testify/require"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type fixture struct {
|
||||
ctrl *gomock.Controller
|
||||
delState *deletionState
|
||||
spaceStorage *mock_storage.MockSpaceStorage
|
||||
}
|
||||
|
||||
func newFixture(t *testing.T) *fixture {
|
||||
ctrl := gomock.NewController(t)
|
||||
spaceStorage := mock_storage.NewMockSpaceStorage(ctrl)
|
||||
delState := NewDeletionState(spaceStorage).(*deletionState)
|
||||
return &fixture{
|
||||
ctrl: ctrl,
|
||||
delState: delState,
|
||||
spaceStorage: spaceStorage,
|
||||
}
|
||||
}
|
||||
|
||||
func (fx *fixture) stop() {
|
||||
fx.ctrl.Finish()
|
||||
}
|
||||
|
||||
func TestDeletionState_Add(t *testing.T) {
|
||||
t.Run("add new", func(t *testing.T) {
|
||||
fx := newFixture(t)
|
||||
defer fx.stop()
|
||||
id := "newId"
|
||||
fx.spaceStorage.EXPECT().TreeDeletedStatus(id).Return("", nil)
|
||||
fx.spaceStorage.EXPECT().SetTreeDeletedStatus(id, storage.TreeDeletedStatusQueued).Return(nil)
|
||||
err := fx.delState.Add([]string{id})
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, fx.delState.queued, id)
|
||||
})
|
||||
|
||||
t.Run("add existing queued", func(t *testing.T) {
|
||||
fx := newFixture(t)
|
||||
defer fx.stop()
|
||||
id := "newId"
|
||||
fx.spaceStorage.EXPECT().TreeDeletedStatus(id).Return(storage.TreeDeletedStatusQueued, nil)
|
||||
err := fx.delState.Add([]string{id})
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, fx.delState.queued, id)
|
||||
})
|
||||
|
||||
t.Run("add existing deleted", func(t *testing.T) {
|
||||
fx := newFixture(t)
|
||||
defer fx.stop()
|
||||
id := "newId"
|
||||
fx.spaceStorage.EXPECT().TreeDeletedStatus(id).Return(storage.TreeDeletedStatusDeleted, nil)
|
||||
err := fx.delState.Add([]string{id})
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, fx.delState.deleted, id)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDeletionState_GetQueued(t *testing.T) {
|
||||
fx := newFixture(t)
|
||||
defer fx.stop()
|
||||
|
||||
fx.delState.queued["id1"] = struct{}{}
|
||||
fx.delState.queued["id2"] = struct{}{}
|
||||
|
||||
queued := fx.delState.GetQueued()
|
||||
require.Equal(t, []string{"id1", "id2"}, queued)
|
||||
}
|
||||
|
||||
func TestDeletionState_FilterJoin(t *testing.T) {
|
||||
fx := newFixture(t)
|
||||
defer fx.stop()
|
||||
|
||||
fx.delState.queued["id1"] = struct{}{}
|
||||
fx.delState.queued["id2"] = struct{}{}
|
||||
|
||||
filtered := fx.delState.FilterJoin([]string{"id1"}, []string{"id3", "id2"}, []string{"id4"})
|
||||
require.Equal(t, []string{"id3", "id4"}, filtered)
|
||||
}
|
||||
|
||||
func TestDeletionState_AddObserver(t *testing.T) {
|
||||
fx := newFixture(t)
|
||||
defer fx.stop()
|
||||
|
||||
var queued []string
|
||||
|
||||
fx.delState.AddObserver(func(ids []string) {
|
||||
queued = ids
|
||||
})
|
||||
id := "newId"
|
||||
fx.spaceStorage.EXPECT().TreeDeletedStatus(id).Return("", nil)
|
||||
fx.spaceStorage.EXPECT().SetTreeDeletedStatus(id, storage.TreeDeletedStatusQueued).Return(nil)
|
||||
err := fx.delState.Add([]string{id})
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, fx.delState.queued, id)
|
||||
require.Equal(t, []string{id}, queued)
|
||||
}
|
||||
|
||||
func TestDeletionState_Delete(t *testing.T) {
|
||||
fx := newFixture(t)
|
||||
defer fx.stop()
|
||||
|
||||
id := "deletedId"
|
||||
fx.delState.queued[id] = struct{}{}
|
||||
fx.spaceStorage.EXPECT().SetTreeDeletedStatus(id, storage.TreeDeletedStatusDeleted).Return(nil)
|
||||
err := fx.delState.Delete(id)
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, fx.delState.deleted, id)
|
||||
require.NotContains(t, fx.delState.queued, id)
|
||||
}
|
||||
|
||||
func TestDeletionState_Exists(t *testing.T) {
|
||||
fx := newFixture(t)
|
||||
defer fx.stop()
|
||||
|
||||
fx.delState.queued["id1"] = struct{}{}
|
||||
fx.delState.deleted["id2"] = struct{}{}
|
||||
require.True(t, fx.delState.Exists("id1"))
|
||||
require.True(t, fx.delState.Exists("id2"))
|
||||
require.False(t, fx.delState.Exists("id3"))
|
||||
}
|
||||
@ -0,0 +1,136 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/settingsdocument/deletionstate (interfaces: DeletionState)
|
||||
|
||||
// Package mock_deletionstate is a generated GoMock package.
|
||||
package mock_deletionstate
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
deletionstate "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/settingsdocument/deletionstate"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
)
|
||||
|
||||
// MockDeletionState is a mock of DeletionState interface.
|
||||
type MockDeletionState struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockDeletionStateMockRecorder
|
||||
}
|
||||
|
||||
// MockDeletionStateMockRecorder is the mock recorder for MockDeletionState.
|
||||
type MockDeletionStateMockRecorder struct {
|
||||
mock *MockDeletionState
|
||||
}
|
||||
|
||||
// NewMockDeletionState creates a new mock instance.
|
||||
func NewMockDeletionState(ctrl *gomock.Controller) *MockDeletionState {
|
||||
mock := &MockDeletionState{ctrl: ctrl}
|
||||
mock.recorder = &MockDeletionStateMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockDeletionState) EXPECT() *MockDeletionStateMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Add mocks base method.
|
||||
func (m *MockDeletionState) Add(arg0 []string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Add", arg0)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Add indicates an expected call of Add.
|
||||
func (mr *MockDeletionStateMockRecorder) Add(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Add", reflect.TypeOf((*MockDeletionState)(nil).Add), arg0)
|
||||
}
|
||||
|
||||
// AddObserver mocks base method.
|
||||
func (m *MockDeletionState) AddObserver(arg0 deletionstate.StateUpdateObserver) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "AddObserver", arg0)
|
||||
}
|
||||
|
||||
// AddObserver indicates an expected call of AddObserver.
|
||||
func (mr *MockDeletionStateMockRecorder) AddObserver(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddObserver", reflect.TypeOf((*MockDeletionState)(nil).AddObserver), arg0)
|
||||
}
|
||||
|
||||
// CreateDeleteChange mocks base method.
|
||||
func (m *MockDeletionState) CreateDeleteChange(arg0 string, arg1 bool) ([]byte, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CreateDeleteChange", arg0, arg1)
|
||||
ret0, _ := ret[0].([]byte)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// CreateDeleteChange indicates an expected call of CreateDeleteChange.
|
||||
func (mr *MockDeletionStateMockRecorder) CreateDeleteChange(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateDeleteChange", reflect.TypeOf((*MockDeletionState)(nil).CreateDeleteChange), arg0, arg1)
|
||||
}
|
||||
|
||||
// Delete mocks base method.
|
||||
func (m *MockDeletionState) Delete(arg0 string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Delete", arg0)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Delete indicates an expected call of Delete.
|
||||
func (mr *MockDeletionStateMockRecorder) Delete(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockDeletionState)(nil).Delete), arg0)
|
||||
}
|
||||
|
||||
// Exists mocks base method.
|
||||
func (m *MockDeletionState) Exists(arg0 string) bool {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Exists", arg0)
|
||||
ret0, _ := ret[0].(bool)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Exists indicates an expected call of Exists.
|
||||
func (mr *MockDeletionStateMockRecorder) Exists(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Exists", reflect.TypeOf((*MockDeletionState)(nil).Exists), arg0)
|
||||
}
|
||||
|
||||
// FilterJoin mocks base method.
|
||||
func (m *MockDeletionState) FilterJoin(arg0 ...[]string) []string {
|
||||
m.ctrl.T.Helper()
|
||||
varargs := []interface{}{}
|
||||
for _, a := range arg0 {
|
||||
varargs = append(varargs, a)
|
||||
}
|
||||
ret := m.ctrl.Call(m, "FilterJoin", varargs...)
|
||||
ret0, _ := ret[0].([]string)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// FilterJoin indicates an expected call of FilterJoin.
|
||||
func (mr *MockDeletionStateMockRecorder) FilterJoin(arg0 ...interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FilterJoin", reflect.TypeOf((*MockDeletionState)(nil).FilterJoin), arg0...)
|
||||
}
|
||||
|
||||
// GetQueued mocks base method.
|
||||
func (m *MockDeletionState) GetQueued() []string {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetQueued")
|
||||
ret0, _ := ret[0].([]string)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetQueued indicates an expected call of GetQueued.
|
||||
func (mr *MockDeletionStateMockRecorder) GetQueued() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetQueued", reflect.TypeOf((*MockDeletionState)(nil).GetQueued))
|
||||
}
|
||||
59
common/commonspace/settingsdocument/idprovider.go
Normal file
59
common/commonspace/settingsdocument/idprovider.go
Normal file
@ -0,0 +1,59 @@
|
||||
package settingsdocument
|
||||
|
||||
import (
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
)
|
||||
|
||||
type DeletedIdsProvider interface {
|
||||
ProvideIds(tr tree.ObjectTree, startId string) (ids []string, lastId string, err error)
|
||||
}
|
||||
|
||||
type provider struct{}
|
||||
|
||||
func (p *provider) processChange(change *tree.Change, rootId, startId string, ids []string) []string {
|
||||
// ignoring root change which has empty model or startId change
|
||||
if change.Model == nil || (change.Id == startId && startId != "") {
|
||||
return ids
|
||||
}
|
||||
|
||||
deleteChange := change.Model.(*spacesyncproto.SettingsData)
|
||||
// getting data from snapshot if we start from it
|
||||
if change.Id == rootId {
|
||||
ids = deleteChange.Snapshot.DeletedIds
|
||||
return ids
|
||||
}
|
||||
|
||||
// otherwise getting data from content
|
||||
for _, cnt := range deleteChange.Content {
|
||||
if cnt.GetObjectDelete() != nil {
|
||||
ids = append(ids, cnt.GetObjectDelete().GetId())
|
||||
}
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
func (p *provider) ProvideIds(tr tree.ObjectTree, startId string) (ids []string, lastId string, err error) {
|
||||
rootId := tr.Root().Id
|
||||
process := func(change *tree.Change) bool {
|
||||
lastId = change.Id
|
||||
ids = p.processChange(change, rootId, startId, ids)
|
||||
return true
|
||||
}
|
||||
convert := func(decrypted []byte) (res any, err error) {
|
||||
deleteChange := &spacesyncproto.SettingsData{}
|
||||
err = proto.Unmarshal(decrypted, deleteChange)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return deleteChange, nil
|
||||
}
|
||||
|
||||
if startId == "" {
|
||||
err = tr.IterateFrom(tr.ID(), convert, process)
|
||||
} else {
|
||||
err = tr.IterateFrom(startId, convert, process)
|
||||
}
|
||||
return
|
||||
}
|
||||
94
common/commonspace/settingsdocument/idprovider_test.go
Normal file
94
common/commonspace/settingsdocument/idprovider_test.go
Normal file
@ -0,0 +1,94 @@
|
||||
package settingsdocument
|
||||
|
||||
import (
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree"
|
||||
mock_tree "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree/mock_objecttree"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/stretchr/testify/require"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestProvider_ProcessChange(t *testing.T) {
|
||||
//ctrl := gomock.NewController(t)
|
||||
//objTree := mock_tree.NewMockObjectTree(ctrl)
|
||||
prov := &provider{}
|
||||
//defer ctrl.Finish()
|
||||
|
||||
t.Run("empty model", func(t *testing.T) {
|
||||
ch := &tree.Change{}
|
||||
startId := "startId"
|
||||
rootId := "rootId"
|
||||
ids := []string{startId}
|
||||
otherIds := prov.processChange(ch, rootId, startId, ids)
|
||||
require.Equal(t, []string{startId}, otherIds)
|
||||
})
|
||||
|
||||
t.Run("changeId is equal to startId", func(t *testing.T) {
|
||||
ch := &tree.Change{}
|
||||
ch.Model = &spacesyncproto.SettingsData{}
|
||||
ch.Id = "startId"
|
||||
|
||||
startId := "startId"
|
||||
rootId := "rootId"
|
||||
ids := []string{startId}
|
||||
otherIds := prov.processChange(ch, rootId, startId, ids)
|
||||
require.Equal(t, []string{startId}, otherIds)
|
||||
})
|
||||
|
||||
t.Run("changeId is equal to rootId, startId is empty", func(t *testing.T) {
|
||||
ch := &tree.Change{}
|
||||
ch.Model = &spacesyncproto.SettingsData{
|
||||
Snapshot: &spacesyncproto.SpaceSettingsSnapshot{
|
||||
DeletedIds: []string{"id1", "id2"},
|
||||
},
|
||||
}
|
||||
ch.Id = "rootId"
|
||||
|
||||
startId := ""
|
||||
rootId := "rootId"
|
||||
otherIds := prov.processChange(ch, rootId, startId, nil)
|
||||
require.Equal(t, []string{"id1", "id2"}, otherIds)
|
||||
})
|
||||
|
||||
t.Run("changeId is equal to rootId, startId is empty", func(t *testing.T) {
|
||||
ch := &tree.Change{}
|
||||
ch.Model = &spacesyncproto.SettingsData{
|
||||
Content: []*spacesyncproto.SpaceSettingsContent{
|
||||
{&spacesyncproto.SpaceSettingsContent_ObjectDelete{
|
||||
ObjectDelete: &spacesyncproto.ObjectDelete{Id: "id1"},
|
||||
}},
|
||||
},
|
||||
}
|
||||
ch.Id = "someId"
|
||||
|
||||
startId := "startId"
|
||||
rootId := "rootId"
|
||||
otherIds := prov.processChange(ch, rootId, startId, nil)
|
||||
require.Equal(t, []string{"id1"}, otherIds)
|
||||
})
|
||||
}
|
||||
|
||||
func TestProvider_ProvideIds(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
objTree := mock_tree.NewMockObjectTree(ctrl)
|
||||
prov := &provider{}
|
||||
defer ctrl.Finish()
|
||||
|
||||
t.Run("startId is empty", func(t *testing.T) {
|
||||
ch := &tree.Change{Id: "rootId"}
|
||||
objTree.EXPECT().Root().Return(ch)
|
||||
objTree.EXPECT().ID().Return("id")
|
||||
objTree.EXPECT().IterateFrom("id", gomock.Any(), gomock.Any()).Return(nil)
|
||||
_, _, err := prov.ProvideIds(objTree, "")
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("startId is not empty", func(t *testing.T) {
|
||||
ch := &tree.Change{Id: "rootId"}
|
||||
objTree.EXPECT().Root().Return(ch)
|
||||
objTree.EXPECT().IterateFrom("startId", gomock.Any(), gomock.Any()).Return(nil)
|
||||
_, _, err := prov.ProvideIds(objTree, "startId")
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
@ -0,0 +1,86 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/settingsdocument (interfaces: DeletedIdsProvider,Deleter)
|
||||
|
||||
// Package mock_settingsdocument is a generated GoMock package.
|
||||
package mock_settingsdocument
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
tree "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
)
|
||||
|
||||
// MockDeletedIdsProvider is a mock of DeletedIdsProvider interface.
|
||||
type MockDeletedIdsProvider struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockDeletedIdsProviderMockRecorder
|
||||
}
|
||||
|
||||
// MockDeletedIdsProviderMockRecorder is the mock recorder for MockDeletedIdsProvider.
|
||||
type MockDeletedIdsProviderMockRecorder struct {
|
||||
mock *MockDeletedIdsProvider
|
||||
}
|
||||
|
||||
// NewMockDeletedIdsProvider creates a new mock instance.
|
||||
func NewMockDeletedIdsProvider(ctrl *gomock.Controller) *MockDeletedIdsProvider {
|
||||
mock := &MockDeletedIdsProvider{ctrl: ctrl}
|
||||
mock.recorder = &MockDeletedIdsProviderMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockDeletedIdsProvider) EXPECT() *MockDeletedIdsProviderMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// ProvideIds mocks base method.
|
||||
func (m *MockDeletedIdsProvider) ProvideIds(arg0 tree.ObjectTree, arg1 string) ([]string, string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ProvideIds", arg0, arg1)
|
||||
ret0, _ := ret[0].([]string)
|
||||
ret1, _ := ret[1].(string)
|
||||
ret2, _ := ret[2].(error)
|
||||
return ret0, ret1, ret2
|
||||
}
|
||||
|
||||
// ProvideIds indicates an expected call of ProvideIds.
|
||||
func (mr *MockDeletedIdsProviderMockRecorder) ProvideIds(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProvideIds", reflect.TypeOf((*MockDeletedIdsProvider)(nil).ProvideIds), arg0, arg1)
|
||||
}
|
||||
|
||||
// MockDeleter is a mock of Deleter interface.
|
||||
type MockDeleter struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockDeleterMockRecorder
|
||||
}
|
||||
|
||||
// MockDeleterMockRecorder is the mock recorder for MockDeleter.
|
||||
type MockDeleterMockRecorder struct {
|
||||
mock *MockDeleter
|
||||
}
|
||||
|
||||
// NewMockDeleter creates a new mock instance.
|
||||
func NewMockDeleter(ctrl *gomock.Controller) *MockDeleter {
|
||||
mock := &MockDeleter{ctrl: ctrl}
|
||||
mock.recorder = &MockDeleterMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockDeleter) EXPECT() *MockDeleterMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Delete mocks base method.
|
||||
func (m *MockDeleter) Delete() {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "Delete")
|
||||
}
|
||||
|
||||
// Delete indicates an expected call of Delete.
|
||||
func (mr *MockDeleterMockRecorder) Delete() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockDeleter)(nil).Delete))
|
||||
}
|
||||
173
common/commonspace/settingsdocument/settingsdocument.go
Normal file
173
common/commonspace/settingsdocument/settingsdocument.go
Normal file
@ -0,0 +1,173 @@
|
||||
//go:generate mockgen -destination mock_settingsdocument/mock_settingsdocument.go github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/settingsdocument DeletedIdsProvider,Deleter
|
||||
package settingsdocument
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/account"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/settingsdocument/deletionstate"
|
||||
spacestorage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree/updatelistener"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var log = logger.NewNamed("commonspace.settingsdocument")
|
||||
|
||||
type SettingsDocument interface {
|
||||
synctree.SyncTree
|
||||
Init(ctx context.Context) (err error)
|
||||
DeleteObject(id string) (err error)
|
||||
}
|
||||
|
||||
var (
|
||||
ErrDeleteSelf = errors.New("cannot delete seld")
|
||||
ErrAlreadyDeleted = errors.New("the document is already deleted")
|
||||
ErrDocDoesNotExist = errors.New("the document does not exist")
|
||||
)
|
||||
|
||||
type BuildTreeFunc func(ctx context.Context, id string, listener updatelistener.UpdateListener) (t synctree.SyncTree, err error)
|
||||
|
||||
type Deps struct {
|
||||
BuildFunc BuildTreeFunc
|
||||
Account account.Service
|
||||
TreeGetter treegetter.TreeGetter
|
||||
Store spacestorage.SpaceStorage
|
||||
DeletionState deletionstate.DeletionState
|
||||
// testing dependencies
|
||||
prov DeletedIdsProvider
|
||||
del Deleter
|
||||
}
|
||||
|
||||
type settingsDocument struct {
|
||||
synctree.SyncTree
|
||||
account account.Service
|
||||
spaceId string
|
||||
treeGetter treegetter.TreeGetter
|
||||
store spacestorage.SpaceStorage
|
||||
prov DeletedIdsProvider
|
||||
buildFunc BuildTreeFunc
|
||||
loop *deleteLoop
|
||||
|
||||
deletionState deletionstate.DeletionState
|
||||
lastChangeId string
|
||||
}
|
||||
|
||||
func NewSettingsDocument(deps Deps, spaceId string) (doc SettingsDocument) {
|
||||
var deleter Deleter
|
||||
if deps.del == nil {
|
||||
deleter = newDeleter(deps.Store, deps.DeletionState, deps.TreeGetter)
|
||||
} else {
|
||||
deleter = deps.del
|
||||
}
|
||||
|
||||
loop := newDeleteLoop(func() {
|
||||
deleter.Delete()
|
||||
})
|
||||
deps.DeletionState.AddObserver(func(ids []string) {
|
||||
loop.notify()
|
||||
})
|
||||
|
||||
s := &settingsDocument{
|
||||
loop: loop,
|
||||
spaceId: spaceId,
|
||||
account: deps.Account,
|
||||
deletionState: deps.DeletionState,
|
||||
treeGetter: deps.TreeGetter,
|
||||
store: deps.Store,
|
||||
buildFunc: deps.BuildFunc,
|
||||
}
|
||||
|
||||
// this is needed mainly for testing
|
||||
if deps.prov == nil {
|
||||
s.prov = &provider{}
|
||||
} else {
|
||||
s.prov = deps.prov
|
||||
}
|
||||
|
||||
doc = s
|
||||
return
|
||||
}
|
||||
|
||||
func (s *settingsDocument) updateIds(tr tree.ObjectTree, lastChangeId string) {
|
||||
s.lastChangeId = lastChangeId
|
||||
ids, lastId, err := s.prov.ProvideIds(tr, s.lastChangeId)
|
||||
if err != nil {
|
||||
log.With(zap.Strings("ids", ids), zap.Error(err)).Error("failed to update state")
|
||||
return
|
||||
}
|
||||
s.lastChangeId = lastId
|
||||
if err = s.deletionState.Add(ids); err != nil {
|
||||
log.With(zap.Strings("ids", ids), zap.Error(err)).Error("failed to queue ids to delete")
|
||||
}
|
||||
}
|
||||
|
||||
// Update is called as part of UpdateListener interface
|
||||
func (s *settingsDocument) Update(tr tree.ObjectTree) {
|
||||
s.updateIds(tr, s.lastChangeId)
|
||||
}
|
||||
|
||||
// Rebuild is called as part of UpdateListener interface (including when the object is built for the first time, e.g. on Init call)
|
||||
func (s *settingsDocument) Rebuild(tr tree.ObjectTree) {
|
||||
// at initial build "s" may not contain the object tree, so it is safer to provide it from the function parameter
|
||||
s.updateIds(tr, "")
|
||||
}
|
||||
|
||||
func (s *settingsDocument) Init(ctx context.Context) (err error) {
|
||||
settingsId := s.store.SpaceSettingsId()
|
||||
log.Debug("space settings id", zap.String("id", settingsId))
|
||||
s.SyncTree, err = s.buildFunc(ctx, settingsId, s)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
s.loop.Run()
|
||||
return
|
||||
}
|
||||
|
||||
func (s *settingsDocument) Close() error {
|
||||
s.loop.Close()
|
||||
return s.SyncTree.Close()
|
||||
}
|
||||
|
||||
func (s *settingsDocument) DeleteObject(id string) (err error) {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
if s.ID() == id {
|
||||
err = ErrDeleteSelf
|
||||
return
|
||||
}
|
||||
if s.deletionState.Exists(id) {
|
||||
err = ErrAlreadyDeleted
|
||||
return nil
|
||||
}
|
||||
_, err = s.store.TreeStorage(id)
|
||||
if err != nil {
|
||||
err = ErrDocDoesNotExist
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: add snapshot logic
|
||||
res, err := s.deletionState.CreateDeleteChange(id, false)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
accountData := s.account.Account()
|
||||
_, err = s.AddContent(context.Background(), tree.SignableChangeContent{
|
||||
Data: res,
|
||||
Key: accountData.SignKey,
|
||||
Identity: accountData.Identity,
|
||||
IsSnapshot: false,
|
||||
IsEncrypted: false,
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
s.Update(s)
|
||||
return
|
||||
}
|
||||
190
common/commonspace/settingsdocument/settingsdocument_test.go
Normal file
190
common/commonspace/settingsdocument/settingsdocument_test.go
Normal file
@ -0,0 +1,190 @@
|
||||
package settingsdocument
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/account/mock_account"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/settingsdocument/deletionstate/mock_deletionstate"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/settingsdocument/mock_settingsdocument"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage/mock_storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree/mock_synctree"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree/updatelistener"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter/mock_treegetter"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/account"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/signingkey"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/stretchr/testify/require"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
type testSyncTreeMock struct {
|
||||
*mock_synctree.MockSyncTree
|
||||
m sync.Mutex
|
||||
}
|
||||
|
||||
func newTestObjMock(mockTree *mock_synctree.MockSyncTree) *testSyncTreeMock {
|
||||
return &testSyncTreeMock{
|
||||
MockSyncTree: mockTree,
|
||||
}
|
||||
}
|
||||
|
||||
func (t *testSyncTreeMock) Lock() {
|
||||
t.m.Lock()
|
||||
}
|
||||
|
||||
func (t *testSyncTreeMock) Unlock() {
|
||||
t.m.Unlock()
|
||||
}
|
||||
|
||||
type settingsFixture struct {
|
||||
spaceId string
|
||||
docId string
|
||||
doc *settingsDocument
|
||||
ctrl *gomock.Controller
|
||||
treeGetter *mock_treegetter.MockTreeGetter
|
||||
spaceStorage *mock_storage.MockSpaceStorage
|
||||
provider *mock_settingsdocument.MockDeletedIdsProvider
|
||||
deleter *mock_settingsdocument.MockDeleter
|
||||
syncTree *mock_synctree.MockSyncTree
|
||||
delState *mock_deletionstate.MockDeletionState
|
||||
account *mock_account.MockService
|
||||
}
|
||||
|
||||
func newSettingsFixture(t *testing.T) *settingsFixture {
|
||||
spaceId := "spaceId"
|
||||
docId := "documentId"
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
acc := mock_account.NewMockService(ctrl)
|
||||
treeGetter := mock_treegetter.NewMockTreeGetter(ctrl)
|
||||
st := mock_storage.NewMockSpaceStorage(ctrl)
|
||||
delState := mock_deletionstate.NewMockDeletionState(ctrl)
|
||||
prov := mock_settingsdocument.NewMockDeletedIdsProvider(ctrl)
|
||||
syncTree := mock_synctree.NewMockSyncTree(ctrl)
|
||||
del := mock_settingsdocument.NewMockDeleter(ctrl)
|
||||
|
||||
delState.EXPECT().AddObserver(gomock.Any())
|
||||
|
||||
buildFunc := BuildTreeFunc(func(ctx context.Context, id string, listener updatelistener.UpdateListener) (synctree.SyncTree, error) {
|
||||
require.Equal(t, docId, id)
|
||||
return newTestObjMock(syncTree), nil
|
||||
})
|
||||
|
||||
deps := Deps{
|
||||
BuildFunc: buildFunc,
|
||||
Account: acc,
|
||||
TreeGetter: treeGetter,
|
||||
Store: st,
|
||||
DeletionState: delState,
|
||||
prov: prov,
|
||||
del: del,
|
||||
}
|
||||
doc := NewSettingsDocument(deps, spaceId).(*settingsDocument)
|
||||
return &settingsFixture{
|
||||
spaceId: spaceId,
|
||||
docId: docId,
|
||||
doc: doc,
|
||||
ctrl: ctrl,
|
||||
treeGetter: treeGetter,
|
||||
spaceStorage: st,
|
||||
provider: prov,
|
||||
deleter: del,
|
||||
syncTree: syncTree,
|
||||
account: acc,
|
||||
delState: delState,
|
||||
}
|
||||
}
|
||||
|
||||
func (fx *settingsFixture) stop() {
|
||||
fx.ctrl.Finish()
|
||||
}
|
||||
|
||||
func TestSettingsDocument_Init(t *testing.T) {
|
||||
fx := newSettingsFixture(t)
|
||||
defer fx.stop()
|
||||
|
||||
fx.spaceStorage.EXPECT().SpaceSettingsId().Return(fx.docId)
|
||||
fx.deleter.EXPECT().Delete()
|
||||
fx.syncTree.EXPECT().Close().Return(nil)
|
||||
|
||||
err := fx.doc.Init(context.Background())
|
||||
require.NoError(t, err)
|
||||
err = fx.doc.Close()
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestSettingsDocument_DeleteObject(t *testing.T) {
|
||||
fx := newSettingsFixture(t)
|
||||
defer fx.stop()
|
||||
|
||||
fx.spaceStorage.EXPECT().SpaceSettingsId().Return(fx.docId)
|
||||
fx.deleter.EXPECT().Delete()
|
||||
|
||||
err := fx.doc.Init(context.Background())
|
||||
require.NoError(t, err)
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
delId := "delId"
|
||||
|
||||
fx.syncTree.EXPECT().ID().Return("syncId")
|
||||
fx.delState.EXPECT().Exists(delId).Return(false)
|
||||
fx.spaceStorage.EXPECT().TreeStorage(delId).Return(nil, nil)
|
||||
res := []byte("settingsData")
|
||||
fx.delState.EXPECT().CreateDeleteChange(delId, false).Return(res, nil)
|
||||
|
||||
accountData := &account.AccountData{
|
||||
Identity: []byte("id"),
|
||||
PeerKey: nil,
|
||||
SignKey: &signingkey.Ed25519PrivateKey{},
|
||||
EncKey: nil,
|
||||
}
|
||||
fx.account.EXPECT().Account().Return(accountData)
|
||||
fx.syncTree.EXPECT().AddContent(gomock.Any(), tree.SignableChangeContent{
|
||||
Data: res,
|
||||
Key: accountData.SignKey,
|
||||
Identity: accountData.Identity,
|
||||
IsSnapshot: false,
|
||||
IsEncrypted: false,
|
||||
}).Return(tree.AddResult{}, nil)
|
||||
|
||||
lastChangeId := "someId"
|
||||
retIds := []string{"id1", "id2"}
|
||||
fx.doc.lastChangeId = lastChangeId
|
||||
fx.provider.EXPECT().ProvideIds(gomock.Not(nil), lastChangeId).Return(retIds, retIds[len(retIds)-1], nil)
|
||||
fx.delState.EXPECT().Add(retIds).Return(nil)
|
||||
err = fx.doc.DeleteObject(delId)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, retIds[len(retIds)-1], fx.doc.lastChangeId)
|
||||
|
||||
fx.syncTree.EXPECT().Close().Return(nil)
|
||||
err = fx.doc.Close()
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestSettingsDocument_Rebuild(t *testing.T) {
|
||||
fx := newSettingsFixture(t)
|
||||
defer fx.stop()
|
||||
|
||||
fx.spaceStorage.EXPECT().SpaceSettingsId().Return(fx.docId)
|
||||
fx.deleter.EXPECT().Delete()
|
||||
|
||||
err := fx.doc.Init(context.Background())
|
||||
require.NoError(t, err)
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
lastChangeId := "someId"
|
||||
retIds := []string{"id1", "id2"}
|
||||
fx.doc.lastChangeId = lastChangeId
|
||||
fx.provider.EXPECT().ProvideIds(gomock.Not(nil), "").Return(retIds, retIds[len(retIds)-1], nil)
|
||||
fx.delState.EXPECT().Add(retIds).Return(nil)
|
||||
|
||||
fx.doc.Rebuild(fx.doc)
|
||||
require.Equal(t, retIds[len(retIds)-1], fx.doc.lastChangeId)
|
||||
|
||||
fx.syncTree.EXPECT().Close().Return(nil)
|
||||
err = fx.doc.Close()
|
||||
require.NoError(t, err)
|
||||
}
|
||||
@ -6,6 +6,8 @@ import (
|
||||
"fmt"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/account"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/diffservice"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/settingsdocument"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/settingsdocument/deletionstate"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncacl"
|
||||
@ -16,6 +18,7 @@ import (
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/list"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ocache"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/encryptionkey"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/signingkey"
|
||||
"github.com/zeebo/errs"
|
||||
@ -48,9 +51,11 @@ type SpaceDerivePayload struct {
|
||||
}
|
||||
|
||||
type SpaceDescription struct {
|
||||
SpaceHeader *spacesyncproto.RawSpaceHeaderWithId
|
||||
AclId string
|
||||
AclPayload []byte
|
||||
SpaceHeader *spacesyncproto.RawSpaceHeaderWithId
|
||||
AclId string
|
||||
AclPayload []byte
|
||||
SpaceSettingsId string
|
||||
SpaceSettingsPayload []byte
|
||||
}
|
||||
|
||||
func NewSpaceId(id string, repKey uint64) string {
|
||||
@ -58,17 +63,22 @@ func NewSpaceId(id string, repKey uint64) string {
|
||||
}
|
||||
|
||||
type Space interface {
|
||||
ocache.ObjectLocker
|
||||
ocache.ObjectLastUsage
|
||||
|
||||
Id() string
|
||||
Init(ctx context.Context) error
|
||||
|
||||
StoredIds() []string
|
||||
Description() SpaceDescription
|
||||
DebugAllHeads() []diffservice.TreeHeads
|
||||
Description() (SpaceDescription, error)
|
||||
|
||||
SpaceSyncRpc() RpcHandler
|
||||
|
||||
DeriveTree(ctx context.Context, payload tree.ObjectTreeCreatePayload, listener updatelistener.UpdateListener) (tree.ObjectTree, error)
|
||||
CreateTree(ctx context.Context, payload tree.ObjectTreeCreatePayload, listener updatelistener.UpdateListener) (tree.ObjectTree, error)
|
||||
DeriveTree(ctx context.Context, payload tree.ObjectTreeCreatePayload) (string, error)
|
||||
CreateTree(ctx context.Context, payload tree.ObjectTreeCreatePayload) (string, error)
|
||||
BuildTree(ctx context.Context, id string, listener updatelistener.UpdateListener) (tree.ObjectTree, error)
|
||||
DeleteTree(ctx context.Context, id string) (err error)
|
||||
|
||||
Close() error
|
||||
}
|
||||
@ -80,35 +90,58 @@ type space struct {
|
||||
|
||||
rpc *rpcHandler
|
||||
|
||||
syncService syncservice.SyncService
|
||||
diffService diffservice.DiffService
|
||||
storage storage.SpaceStorage
|
||||
cache treegetter.TreeGetter
|
||||
account account.Service
|
||||
aclList *syncacl.SyncACL
|
||||
configuration nodeconf.Configuration
|
||||
syncService syncservice.SyncService
|
||||
diffService diffservice.DiffService
|
||||
storage storage.SpaceStorage
|
||||
cache treegetter.TreeGetter
|
||||
account account.Service
|
||||
aclList *syncacl.SyncACL
|
||||
configuration nodeconf.Configuration
|
||||
settingsDocument settingsdocument.SettingsDocument
|
||||
|
||||
isClosed atomic.Bool
|
||||
isClosed atomic.Bool
|
||||
treesUsed atomic.Int32
|
||||
}
|
||||
|
||||
func (s *space) LastUsage() time.Time {
|
||||
return s.syncService.LastUsage()
|
||||
}
|
||||
|
||||
func (s *space) Locked() bool {
|
||||
locked := s.treesUsed.Load() > 1
|
||||
log.With(zap.Int32("trees used", s.treesUsed.Load()), zap.Bool("locked", locked)).Debug("space lock status check")
|
||||
return locked
|
||||
}
|
||||
|
||||
func (s *space) Id() string {
|
||||
return s.id
|
||||
}
|
||||
|
||||
func (s *space) Description() SpaceDescription {
|
||||
func (s *space) Description() (desc SpaceDescription, err error) {
|
||||
root := s.aclList.Root()
|
||||
return SpaceDescription{
|
||||
SpaceHeader: s.header,
|
||||
AclId: root.Id,
|
||||
AclPayload: root.Payload,
|
||||
settingsStorage, err := s.storage.TreeStorage(s.storage.SpaceSettingsId())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
settingsRoot, err := settingsStorage.Root()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
desc = SpaceDescription{
|
||||
SpaceHeader: s.header,
|
||||
AclId: root.Id,
|
||||
AclPayload: root.Payload,
|
||||
SpaceSettingsId: settingsRoot.Id,
|
||||
SpaceSettingsPayload: settingsRoot.RawChange,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *space) Init(ctx context.Context) (err error) {
|
||||
log.With(zap.String("spaceId", s.id)).Debug("initializing space")
|
||||
s.storage = newCommonStorage(s.storage)
|
||||
|
||||
header, err := s.storage.SpaceHeader()
|
||||
if err != nil {
|
||||
return
|
||||
@ -128,9 +161,32 @@ func (s *space) Init(ctx context.Context) (err error) {
|
||||
return
|
||||
}
|
||||
s.aclList = syncacl.NewSyncACL(aclList, s.syncService.StreamPool())
|
||||
objectGetter := newCommonSpaceGetter(s.id, s.aclList, s.cache)
|
||||
|
||||
deletionState := deletionstate.NewDeletionState(s.storage)
|
||||
deps := settingsdocument.Deps{
|
||||
BuildFunc: func(ctx context.Context, id string, listener updatelistener.UpdateListener) (t synctree.SyncTree, err error) {
|
||||
res, err := s.BuildTree(ctx, id, listener)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
t = res.(synctree.SyncTree)
|
||||
return
|
||||
},
|
||||
Account: s.account,
|
||||
TreeGetter: s.cache,
|
||||
Store: s.storage,
|
||||
DeletionState: deletionState,
|
||||
}
|
||||
s.settingsDocument = settingsdocument.NewSettingsDocument(deps, s.id)
|
||||
|
||||
objectGetter := newCommonSpaceGetter(s.id, s.aclList, s.cache, s.settingsDocument)
|
||||
s.syncService.Init(objectGetter)
|
||||
s.diffService.Init(initialIds)
|
||||
s.diffService.Init(initialIds, deletionState)
|
||||
err = s.settingsDocument.Init(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -150,38 +206,38 @@ func (s *space) StoredIds() []string {
|
||||
return s.diffService.AllIds()
|
||||
}
|
||||
|
||||
func (s *space) DeriveTree(ctx context.Context, payload tree.ObjectTreeCreatePayload, listener updatelistener.UpdateListener) (tr tree.ObjectTree, err error) {
|
||||
func (s *space) DebugAllHeads() []diffservice.TreeHeads {
|
||||
return s.diffService.DebugAllHeads()
|
||||
}
|
||||
|
||||
func (s *space) DeriveTree(ctx context.Context, payload tree.ObjectTreeCreatePayload) (id string, err error) {
|
||||
if s.isClosed.Load() {
|
||||
err = ErrSpaceClosed
|
||||
return
|
||||
}
|
||||
deps := synctree.CreateDeps{
|
||||
SpaceId: s.id,
|
||||
Payload: payload,
|
||||
StreamPool: s.syncService.StreamPool(),
|
||||
Configuration: s.configuration,
|
||||
HeadNotifiable: s.diffService,
|
||||
Listener: listener,
|
||||
AclList: s.aclList,
|
||||
CreateStorage: s.storage.CreateTreeStorage,
|
||||
SpaceId: s.id,
|
||||
Payload: payload,
|
||||
StreamPool: s.syncService.StreamPool(),
|
||||
Configuration: s.configuration,
|
||||
AclList: s.aclList,
|
||||
SpaceStorage: s.storage,
|
||||
}
|
||||
return synctree.DeriveSyncTree(ctx, deps)
|
||||
}
|
||||
|
||||
func (s *space) CreateTree(ctx context.Context, payload tree.ObjectTreeCreatePayload, listener updatelistener.UpdateListener) (tr tree.ObjectTree, err error) {
|
||||
func (s *space) CreateTree(ctx context.Context, payload tree.ObjectTreeCreatePayload) (id string, err error) {
|
||||
if s.isClosed.Load() {
|
||||
err = ErrSpaceClosed
|
||||
return
|
||||
}
|
||||
deps := synctree.CreateDeps{
|
||||
SpaceId: s.id,
|
||||
Payload: payload,
|
||||
StreamPool: s.syncService.StreamPool(),
|
||||
Configuration: s.configuration,
|
||||
HeadNotifiable: s.diffService,
|
||||
Listener: listener,
|
||||
AclList: s.aclList,
|
||||
CreateStorage: s.storage.CreateTreeStorage,
|
||||
SpaceId: s.id,
|
||||
Payload: payload,
|
||||
StreamPool: s.syncService.StreamPool(),
|
||||
Configuration: s.configuration,
|
||||
AclList: s.aclList,
|
||||
SpaceStorage: s.storage,
|
||||
}
|
||||
return synctree.CreateSyncTree(ctx, deps)
|
||||
}
|
||||
@ -199,10 +255,15 @@ func (s *space) BuildTree(ctx context.Context, id string, listener updatelistene
|
||||
Listener: listener,
|
||||
AclList: s.aclList,
|
||||
SpaceStorage: s.storage,
|
||||
TreeUsage: &s.treesUsed,
|
||||
}
|
||||
return synctree.BuildSyncTreeOrGetRemote(ctx, id, deps)
|
||||
}
|
||||
|
||||
func (s *space) DeleteTree(ctx context.Context, id string) (err error) {
|
||||
return s.settingsDocument.DeleteObject(id)
|
||||
}
|
||||
|
||||
func (s *space) Close() error {
|
||||
log.With(zap.String("id", s.id)).Debug("space is closing")
|
||||
defer func() {
|
||||
@ -216,6 +277,9 @@ func (s *space) Close() error {
|
||||
if err := s.syncService.Close(); err != nil {
|
||||
mError.Add(err)
|
||||
}
|
||||
if err := s.settingsDocument.Close(); err != nil {
|
||||
mError.Add(err)
|
||||
}
|
||||
if err := s.aclList.Close(); err != nil {
|
||||
mError.Add(err)
|
||||
}
|
||||
|
||||
@ -64,9 +64,7 @@ message ObjectSyncMessage {
|
||||
|
||||
// PushSpaceRequest is a request to add space on a node containing only one acl record
|
||||
message PushSpaceRequest {
|
||||
RawSpaceHeaderWithId spaceHeader = 1;
|
||||
bytes aclPayload = 2;
|
||||
string aclPayloadId = 3;
|
||||
SpacePayload payload = 1;
|
||||
}
|
||||
|
||||
// PushSpaceResponse is an empty response
|
||||
@ -79,9 +77,15 @@ message PullSpaceRequest {
|
||||
|
||||
// PullSpaceResponse is a response with header and acl root
|
||||
message PullSpaceResponse {
|
||||
SpacePayload payload = 1;
|
||||
}
|
||||
|
||||
message SpacePayload {
|
||||
RawSpaceHeaderWithId spaceHeader = 1;
|
||||
bytes aclPayload = 2;
|
||||
string aclPayloadId = 3;
|
||||
bytes spaceSettingsPayload = 4;
|
||||
string spaceSettingsPayloadId = 5;
|
||||
}
|
||||
|
||||
// SpaceHeader is a header for a space
|
||||
@ -102,3 +106,23 @@ message RawSpaceHeaderWithId {
|
||||
bytes rawHeader = 1;
|
||||
string id = 2;
|
||||
}
|
||||
|
||||
message SpaceSettingsContent {
|
||||
oneof value {
|
||||
ObjectDelete objectDelete = 1;
|
||||
}
|
||||
}
|
||||
|
||||
message ObjectDelete {
|
||||
string id = 1;
|
||||
}
|
||||
|
||||
message SpaceSettingsSnapshot {
|
||||
repeated string deletedIds = 1;
|
||||
}
|
||||
|
||||
message SettingsData {
|
||||
repeated SpaceSettingsContent content = 1;
|
||||
SpaceSettingsSnapshot snapshot = 2;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -176,6 +176,20 @@ func (mr *MockSpaceStorageMockRecorder) Id() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Id", reflect.TypeOf((*MockSpaceStorage)(nil).Id))
|
||||
}
|
||||
|
||||
// SetTreeDeletedStatus mocks base method.
|
||||
func (m *MockSpaceStorage) SetTreeDeletedStatus(arg0, arg1 string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SetTreeDeletedStatus", arg0, arg1)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// SetTreeDeletedStatus indicates an expected call of SetTreeDeletedStatus.
|
||||
func (mr *MockSpaceStorageMockRecorder) SetTreeDeletedStatus(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTreeDeletedStatus", reflect.TypeOf((*MockSpaceStorage)(nil).SetTreeDeletedStatus), arg0, arg1)
|
||||
}
|
||||
|
||||
// SpaceHeader mocks base method.
|
||||
func (m *MockSpaceStorage) SpaceHeader() (*spacesyncproto.RawSpaceHeaderWithId, error) {
|
||||
m.ctrl.T.Helper()
|
||||
@ -191,6 +205,20 @@ func (mr *MockSpaceStorageMockRecorder) SpaceHeader() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SpaceHeader", reflect.TypeOf((*MockSpaceStorage)(nil).SpaceHeader))
|
||||
}
|
||||
|
||||
// SpaceSettingsId mocks base method.
|
||||
func (m *MockSpaceStorage) SpaceSettingsId() string {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SpaceSettingsId")
|
||||
ret0, _ := ret[0].(string)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// SpaceSettingsId indicates an expected call of SpaceSettingsId.
|
||||
func (mr *MockSpaceStorageMockRecorder) SpaceSettingsId() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SpaceSettingsId", reflect.TypeOf((*MockSpaceStorage)(nil).SpaceSettingsId))
|
||||
}
|
||||
|
||||
// StoredIds mocks base method.
|
||||
func (m *MockSpaceStorage) StoredIds() ([]string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
@ -206,6 +234,21 @@ func (mr *MockSpaceStorageMockRecorder) StoredIds() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StoredIds", reflect.TypeOf((*MockSpaceStorage)(nil).StoredIds))
|
||||
}
|
||||
|
||||
// TreeDeletedStatus mocks base method.
|
||||
func (m *MockSpaceStorage) TreeDeletedStatus(arg0 string) (string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "TreeDeletedStatus", arg0)
|
||||
ret0, _ := ret[0].(string)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// TreeDeletedStatus indicates an expected call of TreeDeletedStatus.
|
||||
func (mr *MockSpaceStorageMockRecorder) TreeDeletedStatus(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TreeDeletedStatus", reflect.TypeOf((*MockSpaceStorage)(nil).TreeDeletedStatus), arg0)
|
||||
}
|
||||
|
||||
// TreeStorage mocks base method.
|
||||
func (m *MockSpaceStorage) TreeStorage(arg0 string) (storage0.TreeStorage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
|
||||
@ -7,16 +7,29 @@ import (
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto"
|
||||
)
|
||||
|
||||
const CName = "commonspace.storage"
|
||||
|
||||
var ErrSpaceStorageExists = errors.New("space storage exists")
|
||||
var ErrSpaceStorageMissing = errors.New("space storage missing")
|
||||
var (
|
||||
ErrSpaceStorageExists = errors.New("space storage exists")
|
||||
ErrSpaceStorageMissing = errors.New("space storage missing")
|
||||
|
||||
ErrTreeStorageAlreadyDeleted = errors.New("tree storage already deleted")
|
||||
)
|
||||
|
||||
const (
|
||||
TreeDeletedStatusQueued = "queued"
|
||||
TreeDeletedStatusDeleted = "deleted"
|
||||
)
|
||||
|
||||
type SpaceStorage interface {
|
||||
storage.Provider
|
||||
Id() string
|
||||
SetTreeDeletedStatus(id, state string) error
|
||||
TreeDeletedStatus(id string) (string, error)
|
||||
SpaceSettingsId() string
|
||||
ACLStorage() (storage.ListStorage, error)
|
||||
SpaceHeader() (*spacesyncproto.RawSpaceHeaderWithId, error)
|
||||
StoredIds() ([]string, error)
|
||||
@ -24,8 +37,9 @@ type SpaceStorage interface {
|
||||
}
|
||||
|
||||
type SpaceStorageCreatePayload struct {
|
||||
RecWithId *aclrecordproto.RawACLRecordWithId
|
||||
SpaceHeaderWithId *spacesyncproto.RawSpaceHeaderWithId
|
||||
AclWithId *aclrecordproto.RawACLRecordWithId
|
||||
SpaceHeaderWithId *spacesyncproto.RawSpaceHeaderWithId
|
||||
SpaceSettingsWithId *treechangeproto.RawTreeChangeWithId
|
||||
}
|
||||
|
||||
type SpaceStorageProvider interface {
|
||||
@ -33,3 +47,8 @@ type SpaceStorageProvider interface {
|
||||
SpaceStorage(id string) (SpaceStorage, error)
|
||||
CreateSpaceStorage(payload SpaceStorageCreatePayload) (SpaceStorage, error)
|
||||
}
|
||||
|
||||
func ValidateSpaceStorageCreatePayload(payload SpaceStorageCreatePayload) (err error) {
|
||||
// TODO: add proper validation
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ import (
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/rpc/rpcerr"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ocache"
|
||||
"go.uber.org/zap"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -36,6 +37,7 @@ type syncService struct {
|
||||
stopStreamLoop context.CancelFunc
|
||||
connector nodeconf.ConfConnector
|
||||
streamLoopDone chan struct{}
|
||||
log *zap.SugaredLogger // TODO: change to logger
|
||||
}
|
||||
|
||||
func NewSyncService(
|
||||
@ -62,6 +64,7 @@ func newSyncService(
|
||||
connector: connector,
|
||||
clientFactory: clientFactory,
|
||||
spaceId: spaceId,
|
||||
log: log.With(zap.String("id", spaceId)),
|
||||
streamLoopDone: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
@ -83,6 +86,7 @@ func (s *syncService) LastUsage() time.Time {
|
||||
}
|
||||
|
||||
func (s *syncService) HandleMessage(ctx context.Context, senderId string, message *spacesyncproto.ObjectSyncMessage) (err error) {
|
||||
s.log.With(zap.String("peerId", senderId), zap.String("objectId", message.ObjectId)).Debug("handling message")
|
||||
obj, err := s.objectGetter.GetObject(ctx, message.ObjectId)
|
||||
if err != nil {
|
||||
return
|
||||
@ -93,18 +97,28 @@ func (s *syncService) HandleMessage(ctx context.Context, senderId string, messag
|
||||
func (s *syncService) responsibleStreamCheckLoop(ctx context.Context) {
|
||||
defer close(s.streamLoopDone)
|
||||
checkResponsiblePeers := func() {
|
||||
respPeers, err := s.connector.DialResponsiblePeers(ctx, s.spaceId)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, p := range respPeers {
|
||||
if s.streamPool.HasActiveStream(p.Id()) {
|
||||
var (
|
||||
activeNodeIds []string
|
||||
configuration = s.connector.Configuration()
|
||||
)
|
||||
for _, nodeId := range configuration.NodeIds(s.spaceId) {
|
||||
if s.streamPool.HasActiveStream(nodeId) {
|
||||
s.log.Debug("has active stream for", zap.String("id", nodeId))
|
||||
activeNodeIds = append(activeNodeIds, nodeId)
|
||||
continue
|
||||
}
|
||||
}
|
||||
newPeers, err := s.connector.DialInactiveResponsiblePeers(ctx, s.spaceId, activeNodeIds)
|
||||
if err != nil {
|
||||
s.log.Error("failed to dial peers", zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
for _, p := range newPeers {
|
||||
stream, err := s.clientFactory.Client(p).Stream(ctx)
|
||||
if err != nil {
|
||||
err = rpcerr.Unwrap(err)
|
||||
log.With("spaceId", s.spaceId).Errorf("failed to open stream: %v", err)
|
||||
s.log.Errorf("failed to open stream: %v", err)
|
||||
// so here probably the request is failed because there is no such space,
|
||||
// but diffService should handle such cases by sending pushSpace
|
||||
continue
|
||||
@ -113,9 +127,10 @@ func (s *syncService) responsibleStreamCheckLoop(ctx context.Context) {
|
||||
err = stream.Send(&spacesyncproto.ObjectSyncMessage{SpaceId: s.spaceId})
|
||||
if err != nil {
|
||||
err = rpcerr.Unwrap(err)
|
||||
log.With("spaceId", s.spaceId).Errorf("failed to send first message to stream: %v", err)
|
||||
s.log.Errorf("failed to send first message to stream: %v", err)
|
||||
continue
|
||||
}
|
||||
s.log.Debug("reading stream for", zap.String("id", p.Id()))
|
||||
s.streamPool.AddAndReadStreamAsync(stream)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,15 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree (interfaces: SyncClient)
|
||||
// Source: github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree (interfaces: SyncClient,SyncTree)
|
||||
|
||||
// Package mock_synctree is a generated GoMock package.
|
||||
package mock_synctree
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
spacesyncproto "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
|
||||
storage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage"
|
||||
tree "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree"
|
||||
treechangeproto "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
@ -134,3 +137,325 @@ func (mr *MockSyncClientMockRecorder) SendAsync(arg0, arg1, arg2 interface{}) *g
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendAsync", reflect.TypeOf((*MockSyncClient)(nil).SendAsync), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// MockSyncTree is a mock of SyncTree interface.
|
||||
type MockSyncTree struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockSyncTreeMockRecorder
|
||||
}
|
||||
|
||||
// MockSyncTreeMockRecorder is the mock recorder for MockSyncTree.
|
||||
type MockSyncTreeMockRecorder struct {
|
||||
mock *MockSyncTree
|
||||
}
|
||||
|
||||
// NewMockSyncTree creates a new mock instance.
|
||||
func NewMockSyncTree(ctrl *gomock.Controller) *MockSyncTree {
|
||||
mock := &MockSyncTree{ctrl: ctrl}
|
||||
mock.recorder = &MockSyncTreeMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockSyncTree) EXPECT() *MockSyncTreeMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// AddContent mocks base method.
|
||||
func (m *MockSyncTree) AddContent(arg0 context.Context, arg1 tree.SignableChangeContent) (tree.AddResult, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "AddContent", arg0, arg1)
|
||||
ret0, _ := ret[0].(tree.AddResult)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// AddContent indicates an expected call of AddContent.
|
||||
func (mr *MockSyncTreeMockRecorder) AddContent(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddContent", reflect.TypeOf((*MockSyncTree)(nil).AddContent), arg0, arg1)
|
||||
}
|
||||
|
||||
// AddRawChanges mocks base method.
|
||||
func (m *MockSyncTree) AddRawChanges(arg0 context.Context, arg1 ...*treechangeproto.RawTreeChangeWithId) (tree.AddResult, error) {
|
||||
m.ctrl.T.Helper()
|
||||
varargs := []interface{}{arg0}
|
||||
for _, a := range arg1 {
|
||||
varargs = append(varargs, a)
|
||||
}
|
||||
ret := m.ctrl.Call(m, "AddRawChanges", varargs...)
|
||||
ret0, _ := ret[0].(tree.AddResult)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// AddRawChanges indicates an expected call of AddRawChanges.
|
||||
func (mr *MockSyncTreeMockRecorder) AddRawChanges(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
varargs := append([]interface{}{arg0}, arg1...)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRawChanges", reflect.TypeOf((*MockSyncTree)(nil).AddRawChanges), varargs...)
|
||||
}
|
||||
|
||||
// ChangesAfterCommonSnapshot mocks base method.
|
||||
func (m *MockSyncTree) ChangesAfterCommonSnapshot(arg0, arg1 []string) ([]*treechangeproto.RawTreeChangeWithId, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ChangesAfterCommonSnapshot", arg0, arg1)
|
||||
ret0, _ := ret[0].([]*treechangeproto.RawTreeChangeWithId)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ChangesAfterCommonSnapshot indicates an expected call of ChangesAfterCommonSnapshot.
|
||||
func (mr *MockSyncTreeMockRecorder) ChangesAfterCommonSnapshot(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChangesAfterCommonSnapshot", reflect.TypeOf((*MockSyncTree)(nil).ChangesAfterCommonSnapshot), arg0, arg1)
|
||||
}
|
||||
|
||||
// Close mocks base method.
|
||||
func (m *MockSyncTree) Close() error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Close")
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Close indicates an expected call of Close.
|
||||
func (mr *MockSyncTreeMockRecorder) Close() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockSyncTree)(nil).Close))
|
||||
}
|
||||
|
||||
// DebugDump mocks base method.
|
||||
func (m *MockSyncTree) DebugDump() (string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "DebugDump")
|
||||
ret0, _ := ret[0].(string)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// DebugDump indicates an expected call of DebugDump.
|
||||
func (mr *MockSyncTreeMockRecorder) DebugDump() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DebugDump", reflect.TypeOf((*MockSyncTree)(nil).DebugDump))
|
||||
}
|
||||
|
||||
// Delete mocks base method.
|
||||
func (m *MockSyncTree) Delete() error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Delete")
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Delete indicates an expected call of Delete.
|
||||
func (mr *MockSyncTreeMockRecorder) Delete() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockSyncTree)(nil).Delete))
|
||||
}
|
||||
|
||||
// HandleMessage mocks base method.
|
||||
func (m *MockSyncTree) HandleMessage(arg0 context.Context, arg1 string, arg2 *spacesyncproto.ObjectSyncMessage) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "HandleMessage", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// HandleMessage indicates an expected call of HandleMessage.
|
||||
func (mr *MockSyncTreeMockRecorder) HandleMessage(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleMessage", reflect.TypeOf((*MockSyncTree)(nil).HandleMessage), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// HasChanges mocks base method.
|
||||
func (m *MockSyncTree) HasChanges(arg0 ...string) bool {
|
||||
m.ctrl.T.Helper()
|
||||
varargs := []interface{}{}
|
||||
for _, a := range arg0 {
|
||||
varargs = append(varargs, a)
|
||||
}
|
||||
ret := m.ctrl.Call(m, "HasChanges", varargs...)
|
||||
ret0, _ := ret[0].(bool)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// HasChanges indicates an expected call of HasChanges.
|
||||
func (mr *MockSyncTreeMockRecorder) HasChanges(arg0 ...interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasChanges", reflect.TypeOf((*MockSyncTree)(nil).HasChanges), arg0...)
|
||||
}
|
||||
|
||||
// Header mocks base method.
|
||||
func (m *MockSyncTree) Header() *treechangeproto.RawTreeChangeWithId {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Header")
|
||||
ret0, _ := ret[0].(*treechangeproto.RawTreeChangeWithId)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Header indicates an expected call of Header.
|
||||
func (mr *MockSyncTreeMockRecorder) Header() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Header", reflect.TypeOf((*MockSyncTree)(nil).Header))
|
||||
}
|
||||
|
||||
// Heads mocks base method.
|
||||
func (m *MockSyncTree) Heads() []string {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Heads")
|
||||
ret0, _ := ret[0].([]string)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Heads indicates an expected call of Heads.
|
||||
func (mr *MockSyncTreeMockRecorder) Heads() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Heads", reflect.TypeOf((*MockSyncTree)(nil).Heads))
|
||||
}
|
||||
|
||||
// ID mocks base method.
|
||||
func (m *MockSyncTree) ID() string {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ID")
|
||||
ret0, _ := ret[0].(string)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// ID indicates an expected call of ID.
|
||||
func (mr *MockSyncTreeMockRecorder) ID() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ID", reflect.TypeOf((*MockSyncTree)(nil).ID))
|
||||
}
|
||||
|
||||
// Iterate mocks base method.
|
||||
func (m *MockSyncTree) Iterate(arg0 func([]byte) (interface{}, error), arg1 func(*tree.Change) bool) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Iterate", arg0, arg1)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Iterate indicates an expected call of Iterate.
|
||||
func (mr *MockSyncTreeMockRecorder) Iterate(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Iterate", reflect.TypeOf((*MockSyncTree)(nil).Iterate), arg0, arg1)
|
||||
}
|
||||
|
||||
// IterateFrom mocks base method.
|
||||
func (m *MockSyncTree) IterateFrom(arg0 string, arg1 func([]byte) (interface{}, error), arg2 func(*tree.Change) bool) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "IterateFrom", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// IterateFrom indicates an expected call of IterateFrom.
|
||||
func (mr *MockSyncTreeMockRecorder) IterateFrom(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IterateFrom", reflect.TypeOf((*MockSyncTree)(nil).IterateFrom), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// Lock mocks base method.
|
||||
func (m *MockSyncTree) Lock() {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "Lock")
|
||||
}
|
||||
|
||||
// Lock indicates an expected call of Lock.
|
||||
func (mr *MockSyncTreeMockRecorder) Lock() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Lock", reflect.TypeOf((*MockSyncTree)(nil).Lock))
|
||||
}
|
||||
|
||||
// Ping mocks base method.
|
||||
func (m *MockSyncTree) Ping() error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Ping")
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Ping indicates an expected call of Ping.
|
||||
func (mr *MockSyncTreeMockRecorder) Ping() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ping", reflect.TypeOf((*MockSyncTree)(nil).Ping))
|
||||
}
|
||||
|
||||
// RLock mocks base method.
|
||||
func (m *MockSyncTree) RLock() {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "RLock")
|
||||
}
|
||||
|
||||
// RLock indicates an expected call of RLock.
|
||||
func (mr *MockSyncTreeMockRecorder) RLock() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RLock", reflect.TypeOf((*MockSyncTree)(nil).RLock))
|
||||
}
|
||||
|
||||
// RUnlock mocks base method.
|
||||
func (m *MockSyncTree) RUnlock() {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "RUnlock")
|
||||
}
|
||||
|
||||
// RUnlock indicates an expected call of RUnlock.
|
||||
func (mr *MockSyncTreeMockRecorder) RUnlock() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RUnlock", reflect.TypeOf((*MockSyncTree)(nil).RUnlock))
|
||||
}
|
||||
|
||||
// Root mocks base method.
|
||||
func (m *MockSyncTree) Root() *tree.Change {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Root")
|
||||
ret0, _ := ret[0].(*tree.Change)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Root indicates an expected call of Root.
|
||||
func (mr *MockSyncTreeMockRecorder) Root() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Root", reflect.TypeOf((*MockSyncTree)(nil).Root))
|
||||
}
|
||||
|
||||
// SnapshotPath mocks base method.
|
||||
func (m *MockSyncTree) SnapshotPath() []string {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SnapshotPath")
|
||||
ret0, _ := ret[0].([]string)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// SnapshotPath indicates an expected call of SnapshotPath.
|
||||
func (mr *MockSyncTreeMockRecorder) SnapshotPath() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SnapshotPath", reflect.TypeOf((*MockSyncTree)(nil).SnapshotPath))
|
||||
}
|
||||
|
||||
// Storage mocks base method.
|
||||
func (m *MockSyncTree) Storage() storage.TreeStorage {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Storage")
|
||||
ret0, _ := ret[0].(storage.TreeStorage)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Storage indicates an expected call of Storage.
|
||||
func (mr *MockSyncTreeMockRecorder) Storage() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Storage", reflect.TypeOf((*MockSyncTree)(nil).Storage))
|
||||
}
|
||||
|
||||
// Unlock mocks base method.
|
||||
func (m *MockSyncTree) Unlock() {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "Unlock")
|
||||
}
|
||||
|
||||
// Unlock indicates an expected call of Unlock.
|
||||
func (mr *MockSyncTreeMockRecorder) Unlock() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Unlock", reflect.TypeOf((*MockSyncTree)(nil).Unlock))
|
||||
}
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
//go:generate mockgen -destination mock_synctree/mock_synctree.go github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree SyncClient
|
||||
//go:generate mockgen -destination mock_synctree/mock_synctree.go github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree SyncClient,SyncTree
|
||||
package synctree
|
||||
|
||||
import (
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/diffservice"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf"
|
||||
@ -20,27 +19,23 @@ type syncClient struct {
|
||||
syncservice.StreamPool
|
||||
RequestFactory
|
||||
spaceId string
|
||||
notifiable diffservice.HeadNotifiable
|
||||
configuration nodeconf.Configuration
|
||||
}
|
||||
|
||||
func newSyncClient(
|
||||
spaceId string,
|
||||
pool syncservice.StreamPool,
|
||||
notifiable diffservice.HeadNotifiable,
|
||||
factory RequestFactory,
|
||||
configuration nodeconf.Configuration) SyncClient {
|
||||
return &syncClient{
|
||||
StreamPool: pool,
|
||||
RequestFactory: factory,
|
||||
notifiable: notifiable,
|
||||
configuration: configuration,
|
||||
spaceId: spaceId,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *syncClient) BroadcastAsync(message *treechangeproto.TreeSyncMessage) (err error) {
|
||||
s.notifyIfNeeded(message)
|
||||
objMsg, err := marshallTreeMessage(message, message.RootChange.Id, "")
|
||||
if err != nil {
|
||||
return
|
||||
@ -57,7 +52,6 @@ func (s *syncClient) SendAsync(peerId string, message *treechangeproto.TreeSyncM
|
||||
}
|
||||
|
||||
func (s *syncClient) BroadcastAsyncOrSendResponsible(message *treechangeproto.TreeSyncMessage) (err error) {
|
||||
s.notifyIfNeeded(message)
|
||||
objMsg, err := marshallTreeMessage(message, message.RootChange.Id, "")
|
||||
if err != nil {
|
||||
return
|
||||
@ -68,13 +62,6 @@ func (s *syncClient) BroadcastAsyncOrSendResponsible(message *treechangeproto.Tr
|
||||
return s.BroadcastAsync(message)
|
||||
}
|
||||
|
||||
func (s *syncClient) notifyIfNeeded(message *treechangeproto.TreeSyncMessage) {
|
||||
if message.GetContent().GetHeadUpdate() != nil {
|
||||
update := message.GetContent().GetHeadUpdate()
|
||||
s.notifiable.UpdateHeads(message.RootChange.Id, update.Heads)
|
||||
}
|
||||
}
|
||||
|
||||
func marshallTreeMessage(message *treechangeproto.TreeSyncMessage, id, replyId string) (objMsg *spacesyncproto.ObjectSyncMessage, err error) {
|
||||
payload, err := message.Marshal()
|
||||
if err != nil {
|
||||
|
||||
@ -5,7 +5,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/diffservice"
|
||||
spacestorage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice/synchandler"
|
||||
@ -18,17 +17,34 @@ import (
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"go.uber.org/zap"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
var ErrSyncTreeClosed = errors.New("sync tree is closed")
|
||||
var (
|
||||
ErrSyncTreeClosed = errors.New("sync tree is closed")
|
||||
ErrSyncTreeDeleted = errors.New("sync tree is deleted")
|
||||
)
|
||||
|
||||
type HeadNotifiable interface {
|
||||
UpdateHeads(id string, heads []string)
|
||||
}
|
||||
|
||||
type SyncTree interface {
|
||||
tree.ObjectTree
|
||||
synchandler.SyncHandler
|
||||
Ping() (err error)
|
||||
}
|
||||
|
||||
// SyncTree sends head updates to sync service and also sends new changes to update listener
|
||||
type SyncTree struct {
|
||||
type syncTree struct {
|
||||
tree.ObjectTree
|
||||
synchandler.SyncHandler
|
||||
syncClient SyncClient
|
||||
notifiable HeadNotifiable
|
||||
listener updatelistener.UpdateListener
|
||||
treeUsage *atomic.Int32
|
||||
isClosed bool
|
||||
isDeleted bool
|
||||
}
|
||||
|
||||
var log = logger.NewNamed("commonspace.synctree").Sugar()
|
||||
@ -39,78 +55,62 @@ var buildObjectTree = tree.BuildObjectTree
|
||||
var createSyncClient = newSyncClient
|
||||
|
||||
type CreateDeps struct {
|
||||
SpaceId string
|
||||
Payload tree.ObjectTreeCreatePayload
|
||||
Configuration nodeconf.Configuration
|
||||
HeadNotifiable diffservice.HeadNotifiable
|
||||
StreamPool syncservice.StreamPool
|
||||
Listener updatelistener.UpdateListener
|
||||
AclList list.ACLList
|
||||
CreateStorage storage.TreeStorageCreatorFunc
|
||||
SpaceId string
|
||||
Payload tree.ObjectTreeCreatePayload
|
||||
Configuration nodeconf.Configuration
|
||||
StreamPool syncservice.StreamPool
|
||||
AclList list.ACLList
|
||||
SpaceStorage spacestorage.SpaceStorage
|
||||
}
|
||||
|
||||
type BuildDeps struct {
|
||||
SpaceId string
|
||||
StreamPool syncservice.StreamPool
|
||||
Configuration nodeconf.Configuration
|
||||
HeadNotifiable diffservice.HeadNotifiable
|
||||
HeadNotifiable HeadNotifiable
|
||||
Listener updatelistener.UpdateListener
|
||||
AclList list.ACLList
|
||||
SpaceStorage spacestorage.SpaceStorage
|
||||
TreeStorage storage.TreeStorage
|
||||
TreeUsage *atomic.Int32
|
||||
}
|
||||
|
||||
func DeriveSyncTree(ctx context.Context, deps CreateDeps) (t tree.ObjectTree, err error) {
|
||||
t, err = createDerivedObjectTree(deps.Payload, deps.AclList, deps.CreateStorage)
|
||||
func DeriveSyncTree(ctx context.Context, deps CreateDeps) (id string, err error) {
|
||||
objTree, err := createDerivedObjectTree(deps.Payload, deps.AclList, deps.SpaceStorage.CreateTreeStorage)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
syncClient := createSyncClient(
|
||||
deps.SpaceId,
|
||||
deps.StreamPool,
|
||||
deps.HeadNotifiable,
|
||||
sharedFactory,
|
||||
deps.Configuration)
|
||||
syncTree := &SyncTree{
|
||||
ObjectTree: t,
|
||||
syncClient: syncClient,
|
||||
listener: deps.Listener,
|
||||
}
|
||||
syncHandler := newSyncTreeHandler(syncTree, syncClient)
|
||||
syncTree.SyncHandler = syncHandler
|
||||
t = syncTree
|
||||
|
||||
headUpdate := syncClient.CreateHeadUpdate(t, nil)
|
||||
err = syncClient.BroadcastAsync(headUpdate)
|
||||
headUpdate := syncClient.CreateHeadUpdate(objTree, nil)
|
||||
syncClient.BroadcastAsync(headUpdate)
|
||||
id = objTree.ID()
|
||||
return
|
||||
}
|
||||
|
||||
func CreateSyncTree(ctx context.Context, deps CreateDeps) (t tree.ObjectTree, err error) {
|
||||
t, err = createObjectTree(deps.Payload, deps.AclList, deps.CreateStorage)
|
||||
func CreateSyncTree(ctx context.Context, deps CreateDeps) (id string, err error) {
|
||||
objTree, err := createObjectTree(deps.Payload, deps.AclList, deps.SpaceStorage.CreateTreeStorage)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
syncClient := createSyncClient(
|
||||
deps.SpaceId,
|
||||
deps.StreamPool,
|
||||
deps.HeadNotifiable,
|
||||
GetRequestFactory(),
|
||||
deps.Configuration)
|
||||
syncTree := &SyncTree{
|
||||
ObjectTree: t,
|
||||
syncClient: syncClient,
|
||||
listener: deps.Listener,
|
||||
}
|
||||
syncHandler := newSyncTreeHandler(syncTree, syncClient)
|
||||
syncTree.SyncHandler = syncHandler
|
||||
t = syncTree
|
||||
|
||||
headUpdate := syncClient.CreateHeadUpdate(t, nil)
|
||||
err = syncClient.BroadcastAsync(headUpdate)
|
||||
headUpdate := syncClient.CreateHeadUpdate(objTree, nil)
|
||||
syncClient.BroadcastAsync(headUpdate)
|
||||
id = objTree.ID()
|
||||
return
|
||||
}
|
||||
|
||||
func BuildSyncTreeOrGetRemote(ctx context.Context, id string, deps BuildDeps) (t tree.ObjectTree, err error) {
|
||||
func BuildSyncTreeOrGetRemote(ctx context.Context, id string, deps BuildDeps) (t SyncTree, err error) {
|
||||
getTreeRemote := func() (msg *treechangeproto.TreeSyncMessage, err error) {
|
||||
peerId, err := peer.CtxPeerId(ctx)
|
||||
if err != nil {
|
||||
@ -140,6 +140,15 @@ func BuildSyncTreeOrGetRemote(ctx context.Context, id string, deps BuildDeps) (t
|
||||
return
|
||||
}
|
||||
|
||||
status, err := deps.SpaceStorage.TreeDeletedStatus(id)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if status != "" {
|
||||
err = spacestorage.ErrTreeStorageAlreadyDeleted
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := getTreeRemote()
|
||||
if err != nil {
|
||||
return
|
||||
@ -170,56 +179,71 @@ func BuildSyncTreeOrGetRemote(ctx context.Context, id string, deps BuildDeps) (t
|
||||
return buildSyncTree(ctx, true, deps)
|
||||
}
|
||||
|
||||
func buildSyncTree(ctx context.Context, isFirstBuild bool, deps BuildDeps) (t tree.ObjectTree, err error) {
|
||||
|
||||
t, err = buildObjectTree(deps.TreeStorage, deps.AclList)
|
||||
func buildSyncTree(ctx context.Context, isFirstBuild bool, deps BuildDeps) (t SyncTree, err error) {
|
||||
objTree, err := buildObjectTree(deps.TreeStorage, deps.AclList)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
syncClient := createSyncClient(
|
||||
deps.SpaceId,
|
||||
deps.StreamPool,
|
||||
deps.HeadNotifiable,
|
||||
GetRequestFactory(),
|
||||
deps.Configuration)
|
||||
syncTree := &SyncTree{
|
||||
ObjectTree: t,
|
||||
syncTree := &syncTree{
|
||||
ObjectTree: objTree,
|
||||
syncClient: syncClient,
|
||||
notifiable: deps.HeadNotifiable,
|
||||
treeUsage: deps.TreeUsage,
|
||||
listener: deps.Listener,
|
||||
}
|
||||
syncHandler := newSyncTreeHandler(syncTree, syncClient)
|
||||
syncTree.SyncHandler = syncHandler
|
||||
t = syncTree
|
||||
syncTree.Lock()
|
||||
defer syncTree.Unlock()
|
||||
syncTree.afterBuild()
|
||||
|
||||
headUpdate := syncTree.syncClient.CreateHeadUpdate(t, nil)
|
||||
// here we will have different behaviour based on who is sending this update
|
||||
if isFirstBuild {
|
||||
// send to everybody, because everybody should know that the node or client got new tree
|
||||
err = syncTree.syncClient.BroadcastAsync(headUpdate)
|
||||
} else {
|
||||
// send either to everybody if client or to replica set if node
|
||||
err = syncTree.syncClient.BroadcastAsyncOrSendResponsible(headUpdate)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *SyncTree) AddContent(ctx context.Context, content tree.SignableChangeContent) (res tree.AddResult, err error) {
|
||||
if s.isClosed {
|
||||
err = ErrSyncTreeClosed
|
||||
func (s *syncTree) IterateFrom(id string, convert tree.ChangeConvertFunc, iterate tree.ChangeIterateFunc) (err error) {
|
||||
if err = s.checkAlive(); err != nil {
|
||||
return
|
||||
}
|
||||
return s.ObjectTree.IterateFrom(id, convert, iterate)
|
||||
}
|
||||
|
||||
func (s *syncTree) Iterate(convert tree.ChangeConvertFunc, iterate tree.ChangeIterateFunc) (err error) {
|
||||
if err = s.checkAlive(); err != nil {
|
||||
return
|
||||
}
|
||||
return s.ObjectTree.Iterate(convert, iterate)
|
||||
}
|
||||
|
||||
func (s *syncTree) AddContent(ctx context.Context, content tree.SignableChangeContent) (res tree.AddResult, err error) {
|
||||
if err = s.checkAlive(); err != nil {
|
||||
return
|
||||
}
|
||||
res, err = s.ObjectTree.AddContent(ctx, content)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if s.notifiable != nil {
|
||||
s.notifiable.UpdateHeads(s.ID(), res.Heads)
|
||||
}
|
||||
headUpdate := s.syncClient.CreateHeadUpdate(s, res.Added)
|
||||
err = s.syncClient.BroadcastAsync(headUpdate)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *SyncTree) AddRawChanges(ctx context.Context, changes ...*treechangeproto.RawTreeChangeWithId) (res tree.AddResult, err error) {
|
||||
if s.isClosed {
|
||||
err = ErrSyncTreeClosed
|
||||
func (s *syncTree) AddRawChanges(ctx context.Context, changes ...*treechangeproto.RawTreeChangeWithId) (res tree.AddResult, err error) {
|
||||
if err = s.checkAlive(); err != nil {
|
||||
return
|
||||
}
|
||||
res, err = s.ObjectTree.AddRawChanges(ctx, changes...)
|
||||
@ -236,22 +260,64 @@ func (s *SyncTree) AddRawChanges(ctx context.Context, changes ...*treechangeprot
|
||||
s.listener.Rebuild(s)
|
||||
}
|
||||
}
|
||||
//if res.Mode != tree.Nothing {
|
||||
headUpdate := s.syncClient.CreateHeadUpdate(s, res.Added)
|
||||
err = s.syncClient.BroadcastAsync(headUpdate)
|
||||
//}
|
||||
if res.Mode != tree.Nothing {
|
||||
if s.notifiable != nil {
|
||||
s.notifiable.UpdateHeads(s.ID(), res.Heads)
|
||||
}
|
||||
headUpdate := s.syncClient.CreateHeadUpdate(s, res.Added)
|
||||
err = s.syncClient.BroadcastAsync(headUpdate)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *SyncTree) Close() (err error) {
|
||||
func (s *syncTree) Delete() (err error) {
|
||||
log.With("id", s.ID()).Debug("deleting sync tree")
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
if err = s.checkAlive(); err != nil {
|
||||
return
|
||||
}
|
||||
err = s.ObjectTree.Delete()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
s.isDeleted = true
|
||||
return
|
||||
}
|
||||
|
||||
func (s *syncTree) Close() (err error) {
|
||||
log.With("id", s.ID()).Debug("closing sync tree")
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
log.With("id", s.ID()).Debug("taken lock on sync tree")
|
||||
if s.isClosed {
|
||||
err = ErrSyncTreeClosed
|
||||
return
|
||||
return ErrSyncTreeClosed
|
||||
}
|
||||
s.treeUsage.Add(-1)
|
||||
s.isClosed = true
|
||||
return
|
||||
}
|
||||
|
||||
func (s *syncTree) checkAlive() (err error) {
|
||||
if s.isClosed {
|
||||
err = ErrSyncTreeClosed
|
||||
}
|
||||
if s.isDeleted {
|
||||
err = ErrSyncTreeDeleted
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *syncTree) Ping() (err error) {
|
||||
headUpdate := s.syncClient.CreateHeadUpdate(s, nil)
|
||||
return s.syncClient.BroadcastAsyncOrSendResponsible(headUpdate)
|
||||
}
|
||||
|
||||
func (s *syncTree) afterBuild() {
|
||||
if s.listener != nil {
|
||||
s.listener.Rebuild(s)
|
||||
}
|
||||
s.treeUsage.Add(1)
|
||||
if s.notifiable != nil {
|
||||
s.notifiable.UpdateHeads(s.ID(), s.Heads())
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ package synctree
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/diffservice"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage/mock_storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree/mock_synctree"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree/updatelistener"
|
||||
@ -26,7 +26,7 @@ type syncTreeMatcher struct {
|
||||
}
|
||||
|
||||
func (s syncTreeMatcher) Matches(x interface{}) bool {
|
||||
t, ok := x.(*SyncTree)
|
||||
t, ok := x.(*syncTree)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
@ -42,10 +42,10 @@ func Test_DeriveSyncTree(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
updateListenerMock := mock_updatelistener.NewMockUpdateListener(ctrl)
|
||||
syncClientMock := mock_synctree.NewMockSyncClient(ctrl)
|
||||
aclListMock := mock_list.NewMockACLList(ctrl)
|
||||
objTreeMock := mock_tree.NewMockObjectTree(ctrl)
|
||||
objTreeMock := newTestObjMock(mock_tree.NewMockObjectTree(ctrl))
|
||||
spaceStorageMock := mock_storage.NewMockSpaceStorage(ctrl)
|
||||
spaceId := "spaceId"
|
||||
expectedPayload := tree.ObjectTreeCreatePayload{SpaceId: spaceId}
|
||||
createDerivedObjectTree = func(payload tree.ObjectTreeCreatePayload, l list.ACLList, create storage2.TreeStorageCreatorFunc) (objTree tree.ObjectTree, err error) {
|
||||
@ -53,13 +53,18 @@ func Test_DeriveSyncTree(t *testing.T) {
|
||||
require.Equal(t, expectedPayload, payload)
|
||||
return objTreeMock, nil
|
||||
}
|
||||
createSyncClient = func(spaceId string, pool syncservice.StreamPool, notifiable diffservice.HeadNotifiable, factory RequestFactory, configuration nodeconf.Configuration) SyncClient {
|
||||
createSyncClient = func(spaceId string, pool syncservice.StreamPool, factory RequestFactory, configuration nodeconf.Configuration) SyncClient {
|
||||
return syncClientMock
|
||||
}
|
||||
headUpdate := &treechangeproto.TreeSyncMessage{}
|
||||
syncClientMock.EXPECT().CreateHeadUpdate(syncTreeMatcher{objTreeMock, syncClientMock, updateListenerMock}, gomock.Nil()).Return(headUpdate)
|
||||
syncClientMock.EXPECT().CreateHeadUpdate(gomock.Any(), gomock.Nil()).Return(headUpdate)
|
||||
syncClientMock.EXPECT().BroadcastAsync(gomock.Eq(headUpdate)).Return(nil)
|
||||
deps := CreateDeps{AclList: aclListMock, SpaceId: spaceId, Payload: expectedPayload, Listener: updateListenerMock}
|
||||
deps := CreateDeps{
|
||||
AclList: aclListMock,
|
||||
SpaceId: spaceId,
|
||||
Payload: expectedPayload,
|
||||
SpaceStorage: spaceStorageMock,
|
||||
}
|
||||
|
||||
_, err := DeriveSyncTree(ctx, deps)
|
||||
require.NoError(t, err)
|
||||
@ -70,10 +75,10 @@ func Test_CreateSyncTree(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
updateListenerMock := mock_updatelistener.NewMockUpdateListener(ctrl)
|
||||
syncClientMock := mock_synctree.NewMockSyncClient(ctrl)
|
||||
aclListMock := mock_list.NewMockACLList(ctrl)
|
||||
objTreeMock := mock_tree.NewMockObjectTree(ctrl)
|
||||
objTreeMock := newTestObjMock(mock_tree.NewMockObjectTree(ctrl))
|
||||
spaceStorageMock := mock_storage.NewMockSpaceStorage(ctrl)
|
||||
spaceId := "spaceId"
|
||||
expectedPayload := tree.ObjectTreeCreatePayload{SpaceId: spaceId}
|
||||
createObjectTree = func(payload tree.ObjectTreeCreatePayload, l list.ACLList, create storage2.TreeStorageCreatorFunc) (objTree tree.ObjectTree, err error) {
|
||||
@ -81,13 +86,18 @@ func Test_CreateSyncTree(t *testing.T) {
|
||||
require.Equal(t, expectedPayload, payload)
|
||||
return objTreeMock, nil
|
||||
}
|
||||
createSyncClient = func(spaceId string, pool syncservice.StreamPool, notifiable diffservice.HeadNotifiable, factory RequestFactory, configuration nodeconf.Configuration) SyncClient {
|
||||
createSyncClient = func(spaceId string, pool syncservice.StreamPool, factory RequestFactory, configuration nodeconf.Configuration) SyncClient {
|
||||
return syncClientMock
|
||||
}
|
||||
headUpdate := &treechangeproto.TreeSyncMessage{}
|
||||
syncClientMock.EXPECT().CreateHeadUpdate(syncTreeMatcher{objTreeMock, syncClientMock, updateListenerMock}, gomock.Nil()).Return(headUpdate)
|
||||
syncClientMock.EXPECT().CreateHeadUpdate(gomock.Any(), gomock.Nil()).Return(headUpdate)
|
||||
syncClientMock.EXPECT().BroadcastAsync(gomock.Eq(headUpdate)).Return(nil)
|
||||
deps := CreateDeps{AclList: aclListMock, SpaceId: spaceId, Payload: expectedPayload, Listener: updateListenerMock}
|
||||
deps := CreateDeps{
|
||||
AclList: aclListMock,
|
||||
SpaceId: spaceId,
|
||||
Payload: expectedPayload,
|
||||
SpaceStorage: spaceStorageMock,
|
||||
}
|
||||
|
||||
_, err := CreateSyncTree(ctx, deps)
|
||||
require.NoError(t, err)
|
||||
@ -100,8 +110,8 @@ func Test_BuildSyncTree(t *testing.T) {
|
||||
|
||||
updateListenerMock := mock_updatelistener.NewMockUpdateListener(ctrl)
|
||||
syncClientMock := mock_synctree.NewMockSyncClient(ctrl)
|
||||
objTreeMock := mock_tree.NewMockObjectTree(ctrl)
|
||||
tr := &SyncTree{
|
||||
objTreeMock := newTestObjMock(mock_tree.NewMockObjectTree(ctrl))
|
||||
tr := &syncTree{
|
||||
ObjectTree: objTreeMock,
|
||||
SyncHandler: nil,
|
||||
syncClient: syncClientMock,
|
||||
|
||||
@ -50,6 +50,20 @@ func (mr *MockTreeGetterMockRecorder) Close(arg0 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockTreeGetter)(nil).Close), arg0)
|
||||
}
|
||||
|
||||
// DeleteTree mocks base method.
|
||||
func (m *MockTreeGetter) DeleteTree(arg0 context.Context, arg1, arg2 string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "DeleteTree", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// DeleteTree indicates an expected call of DeleteTree.
|
||||
func (mr *MockTreeGetterMockRecorder) DeleteTree(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteTree", reflect.TypeOf((*MockTreeGetter)(nil).DeleteTree), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// GetTree mocks base method.
|
||||
func (m *MockTreeGetter) GetTree(arg0 context.Context, arg1, arg2 string) (tree.ObjectTree, error) {
|
||||
m.ctrl.T.Helper()
|
||||
|
||||
@ -15,4 +15,5 @@ var ErrSpaceNotFound = errors.New("space not found")
|
||||
type TreeGetter interface {
|
||||
app.ComponentRunnable
|
||||
GetTree(ctx context.Context, spaceId, treeId string) (tree.ObjectTree, error)
|
||||
DeleteTree(ctx context.Context, spaceId, treeId string) error
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ type Config struct {
|
||||
Anytype Anytype `yaml:"anytype"`
|
||||
GrpcServer GrpcServer `yaml:"grpcServer"`
|
||||
Account Account `yaml:"account"`
|
||||
APIServer APIServer `yaml:"apiServer"`
|
||||
APIServer GrpcServer `yaml:"apiServer"`
|
||||
Nodes []Node `yaml:"nodes"`
|
||||
Space Space `yaml:"space"`
|
||||
Storage Storage `yaml:"storage"`
|
||||
|
||||
102
common/net/rpc/server/baseserver.go
Normal file
102
common/net/rpc/server/baseserver.go
Normal file
@ -0,0 +1,102 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/secure"
|
||||
"github.com/zeebo/errs"
|
||||
"go.uber.org/zap"
|
||||
"io"
|
||||
"net"
|
||||
"storj.io/drpc"
|
||||
"storj.io/drpc/drpcmux"
|
||||
"storj.io/drpc/drpcserver"
|
||||
"time"
|
||||
)
|
||||
|
||||
type BaseDrpcServer struct {
|
||||
drpcServer *drpcserver.Server
|
||||
transport secure.Service
|
||||
listeners []secure.ContextListener
|
||||
cancel func()
|
||||
*drpcmux.Mux
|
||||
}
|
||||
|
||||
type DRPCHandlerWrapper func(handler drpc.Handler) drpc.Handler
|
||||
type ListenerConverter func(listener net.Listener) secure.ContextListener
|
||||
|
||||
func NewBaseDrpcServer() *BaseDrpcServer {
|
||||
return &BaseDrpcServer{Mux: drpcmux.New()}
|
||||
}
|
||||
|
||||
func (s *BaseDrpcServer) Run(ctx context.Context, listenAddrs []string, wrapper DRPCHandlerWrapper, converter ListenerConverter) (err error) {
|
||||
s.drpcServer = drpcserver.New(wrapper(s.Mux))
|
||||
ctx, s.cancel = context.WithCancel(ctx)
|
||||
for _, addr := range listenAddrs {
|
||||
tcpList, err := net.Listen("tcp", addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tlsList := converter(tcpList)
|
||||
go s.serve(ctx, tlsList)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *BaseDrpcServer) serve(ctx context.Context, lis secure.ContextListener) {
|
||||
l := log.With(zap.String("localAddr", lis.Addr().String()))
|
||||
l.Info("drpc listener started")
|
||||
defer func() {
|
||||
l.Debug("drpc listener stopped")
|
||||
}()
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
default:
|
||||
}
|
||||
ctx, conn, err := lis.Accept(ctx)
|
||||
if err != nil {
|
||||
if isTemporary(err) {
|
||||
l.Debug("listener temporary accept error", zap.Error(err))
|
||||
t := time.NewTimer(500 * time.Millisecond)
|
||||
select {
|
||||
case <-t.C:
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
continue
|
||||
}
|
||||
if _, ok := err.(secure.HandshakeError); ok {
|
||||
l.Warn("listener handshake error", zap.Error(err))
|
||||
continue
|
||||
}
|
||||
l.Error("listener accept error", zap.Error(err))
|
||||
return
|
||||
}
|
||||
go s.serveConn(ctx, conn)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *BaseDrpcServer) serveConn(ctx context.Context, conn net.Conn) {
|
||||
l := log.With(zap.String("remoteAddr", conn.RemoteAddr().String())).With(zap.String("localAddr", conn.LocalAddr().String()))
|
||||
l.Debug("connection opened")
|
||||
if err := s.drpcServer.ServeOne(ctx, conn); err != nil {
|
||||
if errs.Is(err, context.Canceled) || errs.Is(err, io.EOF) {
|
||||
l.Debug("connection closed")
|
||||
} else {
|
||||
l.Warn("serve connection error", zap.Error(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *BaseDrpcServer) Close(ctx context.Context) (err error) {
|
||||
if s.cancel != nil {
|
||||
s.cancel()
|
||||
}
|
||||
for _, l := range s.listeners {
|
||||
if e := l.Close(); e != nil {
|
||||
log.Warn("close listener error", zap.Error(e))
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -8,14 +8,7 @@ import (
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/metric"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/secure"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/zeebo/errs"
|
||||
"go.uber.org/zap"
|
||||
"io"
|
||||
"net"
|
||||
"storj.io/drpc"
|
||||
"storj.io/drpc/drpcmux"
|
||||
"storj.io/drpc/drpcserver"
|
||||
"time"
|
||||
)
|
||||
|
||||
const CName = "common.net.drpcserver"
|
||||
@ -23,7 +16,7 @@ const CName = "common.net.drpcserver"
|
||||
var log = logger.NewNamed(CName)
|
||||
|
||||
func New() DRPCServer {
|
||||
return &drpcServer{Mux: drpcmux.New()}
|
||||
return &drpcServer{BaseDrpcServer: NewBaseDrpcServer()}
|
||||
}
|
||||
|
||||
type DRPCServer interface {
|
||||
@ -36,19 +29,16 @@ type configGetter interface {
|
||||
}
|
||||
|
||||
type drpcServer struct {
|
||||
config config.GrpcServer
|
||||
drpcServer *drpcserver.Server
|
||||
transport secure.Service
|
||||
listeners []secure.ContextListener
|
||||
metric metric.Metric
|
||||
cancel func()
|
||||
*drpcmux.Mux
|
||||
config config.GrpcServer
|
||||
metric metric.Metric
|
||||
transport secure.Service
|
||||
*BaseDrpcServer
|
||||
}
|
||||
|
||||
func (s *drpcServer) Init(a *app.App) (err error) {
|
||||
s.config = a.MustComponent(config.CName).(configGetter).GetGRPCServer()
|
||||
s.transport = a.MustComponent(secure.CName).(secure.Service)
|
||||
s.metric = a.MustComponent(metric.CName).(metric.Metric)
|
||||
s.transport = a.MustComponent(secure.CName).(secure.Service)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -68,80 +58,21 @@ func (s *drpcServer) Run(ctx context.Context) (err error) {
|
||||
0.99: 0.0001,
|
||||
},
|
||||
}, []string{"rpc"})
|
||||
s.drpcServer = drpcserver.New(&metric.PrometheusDRPC{
|
||||
Handler: s.Mux,
|
||||
SummaryVec: histVec,
|
||||
})
|
||||
if err = s.metric.Registry().Register(histVec); err != nil {
|
||||
return
|
||||
}
|
||||
ctx, s.cancel = context.WithCancel(ctx)
|
||||
for _, addr := range s.config.ListenAddrs {
|
||||
tcpList, err := net.Listen("tcp", addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tlsList := s.transport.TLSListener(tcpList)
|
||||
go s.serve(ctx, tlsList)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *drpcServer) serve(ctx context.Context, lis secure.ContextListener) {
|
||||
l := log.With(zap.String("localAddr", lis.Addr().String()))
|
||||
l.Info("drpc listener started")
|
||||
defer func() {
|
||||
l.Debug("drpc listener stopped")
|
||||
}()
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
default:
|
||||
}
|
||||
ctx, conn, err := lis.Accept(ctx)
|
||||
if err != nil {
|
||||
if isTemporary(err) {
|
||||
l.Debug("listener temporary accept error", zap.Error(err))
|
||||
t := time.NewTimer(500 * time.Millisecond)
|
||||
select {
|
||||
case <-t.C:
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
continue
|
||||
return s.BaseDrpcServer.Run(
|
||||
ctx,
|
||||
s.config.ListenAddrs,
|
||||
func(handler drpc.Handler) drpc.Handler {
|
||||
return &metric.PrometheusDRPC{
|
||||
Handler: handler,
|
||||
SummaryVec: histVec,
|
||||
}
|
||||
if _, ok := err.(secure.HandshakeError); ok {
|
||||
l.Warn("listener handshake error", zap.Error(err))
|
||||
continue
|
||||
}
|
||||
l.Error("listener accept error", zap.Error(err))
|
||||
return
|
||||
}
|
||||
go s.serveConn(ctx, conn)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *drpcServer) serveConn(ctx context.Context, conn net.Conn) {
|
||||
l := log.With(zap.String("remoteAddr", conn.RemoteAddr().String())).With(zap.String("localAddr", conn.LocalAddr().String()))
|
||||
l.Debug("connection opened")
|
||||
if err := s.drpcServer.ServeOne(ctx, conn); err != nil {
|
||||
if errs.Is(err, context.Canceled) || errs.Is(err, io.EOF) {
|
||||
l.Debug("connection closed")
|
||||
} else {
|
||||
l.Warn("serve connection error", zap.Error(err))
|
||||
}
|
||||
}
|
||||
},
|
||||
s.transport.TLSListener)
|
||||
}
|
||||
|
||||
func (s *drpcServer) Close(ctx context.Context) (err error) {
|
||||
if s.cancel != nil {
|
||||
s.cancel()
|
||||
}
|
||||
for _, l := range s.listeners {
|
||||
if e := l.Close(); e != nil {
|
||||
log.Warn("close listener error", zap.Error(e))
|
||||
}
|
||||
}
|
||||
return
|
||||
return s.BaseDrpcServer.Close(ctx)
|
||||
}
|
||||
|
||||
19
common/net/secure/basiclistener.go
Normal file
19
common/net/secure/basiclistener.go
Normal file
@ -0,0 +1,19 @@
|
||||
package secure
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
)
|
||||
|
||||
type basicListener struct {
|
||||
net.Listener
|
||||
}
|
||||
|
||||
func newBasicListener(listener net.Listener) ContextListener {
|
||||
return &basicListener{listener}
|
||||
}
|
||||
|
||||
func (b *basicListener) Accept(ctx context.Context) (context.Context, net.Conn, error) {
|
||||
conn, err := b.Listener.Accept()
|
||||
return ctx, conn, err
|
||||
}
|
||||
@ -26,6 +26,7 @@ func New() Service {
|
||||
|
||||
type Service interface {
|
||||
TLSListener(lis net.Listener) ContextListener
|
||||
BasicListener(lis net.Listener) ContextListener
|
||||
TLSConn(ctx context.Context, conn net.Conn) (sec.SecureConn, error)
|
||||
app.Component
|
||||
}
|
||||
@ -57,6 +58,10 @@ func (s *service) TLSListener(lis net.Listener) ContextListener {
|
||||
return newTLSListener(s.key, lis)
|
||||
}
|
||||
|
||||
func (s *service) BasicListener(lis net.Listener) ContextListener {
|
||||
return newBasicListener(lis)
|
||||
}
|
||||
|
||||
func (s *service) TLSConn(ctx context.Context, conn net.Conn) (sec.SecureConn, error) {
|
||||
tr, err := libp2ptls.New(s.key)
|
||||
if err != nil {
|
||||
|
||||
@ -4,11 +4,13 @@ import (
|
||||
"context"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/peer"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/pool"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/slice"
|
||||
)
|
||||
|
||||
type ConfConnector interface {
|
||||
Configuration() Configuration
|
||||
GetResponsiblePeers(ctx context.Context, spaceId string) ([]peer.Peer, error)
|
||||
DialResponsiblePeers(ctx context.Context, spaceId string) ([]peer.Peer, error)
|
||||
DialInactiveResponsiblePeers(ctx context.Context, spaceId string, activeNodeIds []string) ([]peer.Peer, error)
|
||||
}
|
||||
|
||||
type confConnector struct {
|
||||
@ -20,21 +22,36 @@ func NewConfConnector(conf Configuration, pool pool.Pool) ConfConnector {
|
||||
return &confConnector{conf: conf, pool: pool}
|
||||
}
|
||||
|
||||
func (s *confConnector) GetResponsiblePeers(ctx context.Context, spaceId string) ([]peer.Peer, error) {
|
||||
return s.connectOneOrMany(ctx, spaceId, s.pool.Get, s.pool.GetOneOf)
|
||||
func (s *confConnector) Configuration() Configuration {
|
||||
return s.conf
|
||||
}
|
||||
|
||||
func (s *confConnector) DialResponsiblePeers(ctx context.Context, spaceId string) ([]peer.Peer, error) {
|
||||
return s.connectOneOrMany(ctx, spaceId, s.pool.Dial, s.pool.DialOneOf)
|
||||
func (s *confConnector) GetResponsiblePeers(ctx context.Context, spaceId string) ([]peer.Peer, error) {
|
||||
return s.connectOneOrMany(ctx, spaceId, nil, s.pool.Get, s.pool.GetOneOf)
|
||||
}
|
||||
|
||||
func (s *confConnector) DialInactiveResponsiblePeers(ctx context.Context, spaceId string, activeNodeIds []string) ([]peer.Peer, error) {
|
||||
return s.connectOneOrMany(ctx, spaceId, activeNodeIds, s.pool.Dial, s.pool.DialOneOf)
|
||||
}
|
||||
|
||||
func (s *confConnector) connectOneOrMany(
|
||||
ctx context.Context, spaceId string,
|
||||
ctx context.Context,
|
||||
spaceId string,
|
||||
activeNodeIds []string,
|
||||
connectOne func(context.Context, string) (peer.Peer, error),
|
||||
connectOneOf func(context.Context, []string) (peer.Peer, error)) (peers []peer.Peer, err error) {
|
||||
allNodes := s.conf.NodeIds(spaceId)
|
||||
var (
|
||||
inactiveNodeIds []string
|
||||
allNodes = s.conf.NodeIds(spaceId)
|
||||
)
|
||||
for _, id := range allNodes {
|
||||
if slice.FindPos(activeNodeIds, id) == -1 {
|
||||
inactiveNodeIds = append(inactiveNodeIds, id)
|
||||
}
|
||||
}
|
||||
|
||||
if s.conf.IsResponsible(spaceId) {
|
||||
for _, id := range allNodes {
|
||||
for _, id := range inactiveNodeIds {
|
||||
var p peer.Peer
|
||||
p, err = connectOne(ctx, id)
|
||||
if err != nil {
|
||||
@ -42,7 +59,8 @@ func (s *confConnector) connectOneOrMany(
|
||||
}
|
||||
peers = append(peers, p)
|
||||
}
|
||||
} else {
|
||||
} else if len(activeNodeIds) == 0 {
|
||||
// that means that all connected ids
|
||||
var p peer.Peer
|
||||
p, err = connectOneOf(ctx, allNodes)
|
||||
if err != nil {
|
||||
|
||||
@ -209,19 +209,33 @@ func (m *MockConfConnector) EXPECT() *MockConfConnectorMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// DialResponsiblePeers mocks base method.
|
||||
func (m *MockConfConnector) DialResponsiblePeers(arg0 context.Context, arg1 string) ([]peer.Peer, error) {
|
||||
// Configuration mocks base method.
|
||||
func (m *MockConfConnector) Configuration() nodeconf.Configuration {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "DialResponsiblePeers", arg0, arg1)
|
||||
ret := m.ctrl.Call(m, "Configuration")
|
||||
ret0, _ := ret[0].(nodeconf.Configuration)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Configuration indicates an expected call of Configuration.
|
||||
func (mr *MockConfConnectorMockRecorder) Configuration() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Configuration", reflect.TypeOf((*MockConfConnector)(nil).Configuration))
|
||||
}
|
||||
|
||||
// DialInactiveResponsiblePeers mocks base method.
|
||||
func (m *MockConfConnector) DialInactiveResponsiblePeers(arg0 context.Context, arg1 string, arg2 []string) ([]peer.Peer, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "DialInactiveResponsiblePeers", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].([]peer.Peer)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// DialResponsiblePeers indicates an expected call of DialResponsiblePeers.
|
||||
func (mr *MockConfConnectorMockRecorder) DialResponsiblePeers(arg0, arg1 interface{}) *gomock.Call {
|
||||
// DialInactiveResponsiblePeers indicates an expected call of DialInactiveResponsiblePeers.
|
||||
func (mr *MockConfConnectorMockRecorder) DialInactiveResponsiblePeers(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DialResponsiblePeers", reflect.TypeOf((*MockConfConnector)(nil).DialResponsiblePeers), arg0, arg1)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DialInactiveResponsiblePeers", reflect.TypeOf((*MockConfConnector)(nil).DialInactiveResponsiblePeers), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// GetResponsiblePeers mocks base method.
|
||||
|
||||
@ -157,6 +157,10 @@ func (t *inMemoryTreeStorage) GetRawChange(ctx context.Context, changeId string)
|
||||
return nil, fmt.Errorf("could not get change with id: %s", changeId)
|
||||
}
|
||||
|
||||
func (t *inMemoryTreeStorage) Delete() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type inMemoryStorageProvider struct {
|
||||
objects map[string]TreeStorage
|
||||
sync.RWMutex
|
||||
|
||||
@ -160,6 +160,20 @@ func (mr *MockTreeStorageMockRecorder) AddRawChange(arg0 interface{}) *gomock.Ca
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRawChange", reflect.TypeOf((*MockTreeStorage)(nil).AddRawChange), arg0)
|
||||
}
|
||||
|
||||
// Delete mocks base method.
|
||||
func (m *MockTreeStorage) Delete() error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Delete")
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Delete indicates an expected call of Delete.
|
||||
func (mr *MockTreeStorageMockRecorder) Delete() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockTreeStorage)(nil).Delete))
|
||||
}
|
||||
|
||||
// GetRawChange mocks base method.
|
||||
func (m *MockTreeStorage) GetRawChange(arg0 context.Context, arg1 string) (*treechangeproto.RawTreeChangeWithId, error) {
|
||||
m.ctrl.T.Helper()
|
||||
|
||||
@ -5,9 +5,11 @@ import (
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto"
|
||||
)
|
||||
|
||||
var ErrUnknownTreeId = errors.New("tree does not exist")
|
||||
var ErrTreeExists = errors.New("tree already exists")
|
||||
var ErrUnkownChange = errors.New("change doesn't exist")
|
||||
var (
|
||||
ErrUnknownTreeId = errors.New("tree does not exist")
|
||||
ErrTreeExists = errors.New("tree already exists")
|
||||
ErrUnknownChange = errors.New("change doesn't exist")
|
||||
)
|
||||
|
||||
type TreeStorageCreatePayload struct {
|
||||
RootRawChange *treechangeproto.RawTreeChangeWithId
|
||||
|
||||
@ -14,6 +14,7 @@ type TreeStorage interface {
|
||||
AddRawChange(change *treechangeproto.RawTreeChangeWithId) error
|
||||
GetRawChange(ctx context.Context, id string) (*treechangeproto.RawTreeChangeWithId, error)
|
||||
HasChange(ctx context.Context, id string) (bool, error)
|
||||
Delete() error
|
||||
}
|
||||
|
||||
type TreeStorageCreatorFunc = func(payload TreeStorageCreatePayload) (TreeStorage, error)
|
||||
|
||||
@ -48,7 +48,7 @@ type changeBuilder struct {
|
||||
keys *common.Keychain
|
||||
}
|
||||
|
||||
func newChangeBuilder(keys *common.Keychain, rootChange *treechangeproto.RawTreeChangeWithId) ChangeBuilder {
|
||||
func NewChangeBuilder(keys *common.Keychain, rootChange *treechangeproto.RawTreeChangeWithId) ChangeBuilder {
|
||||
return &changeBuilder{keys: keys, rootChange: rootChange}
|
||||
}
|
||||
|
||||
@ -155,12 +155,16 @@ func (c *changeBuilder) BuildContent(payload BuilderContent) (ch *Change, rawIdC
|
||||
Identity: payload.Identity,
|
||||
IsSnapshot: payload.IsSnapshot,
|
||||
}
|
||||
|
||||
encrypted, err := payload.ReadKey.Encrypt(payload.Content)
|
||||
if err != nil {
|
||||
return
|
||||
if payload.ReadKey != nil {
|
||||
var encrypted []byte
|
||||
encrypted, err = payload.ReadKey.Encrypt(payload.Content)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
change.ChangesData = encrypted
|
||||
} else {
|
||||
change.ChangesData = payload.Content
|
||||
}
|
||||
change.ChangesData = encrypted
|
||||
|
||||
marshalledChange, err := proto.Marshal(change)
|
||||
if err != nil {
|
||||
@ -188,7 +192,6 @@ func (c *changeBuilder) BuildContent(payload BuilderContent) (ch *Change, rawIdC
|
||||
}
|
||||
|
||||
ch = NewChange(id, change, signature)
|
||||
ch.Model = payload.Content
|
||||
|
||||
rawIdChange = &treechangeproto.RawTreeChangeWithId{
|
||||
RawChange: marshalledRawChange,
|
||||
|
||||
@ -116,6 +116,20 @@ func (mr *MockObjectTreeMockRecorder) DebugDump() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DebugDump", reflect.TypeOf((*MockObjectTree)(nil).DebugDump))
|
||||
}
|
||||
|
||||
// Delete mocks base method.
|
||||
func (m *MockObjectTree) Delete() error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Delete")
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Delete indicates an expected call of Delete.
|
||||
func (mr *MockObjectTreeMockRecorder) Delete() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockObjectTree)(nil).Delete))
|
||||
}
|
||||
|
||||
// HasChanges mocks base method.
|
||||
func (m *MockObjectTree) HasChanges(arg0 ...string) bool {
|
||||
m.ctrl.T.Helper()
|
||||
|
||||
@ -5,7 +5,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/common"
|
||||
list2 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/list"
|
||||
list "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/list"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/symmetric"
|
||||
@ -57,6 +57,7 @@ type ObjectTree interface {
|
||||
AddContent(ctx context.Context, content SignableChangeContent) (AddResult, error)
|
||||
AddRawChanges(ctx context.Context, changes ...*treechangeproto.RawTreeChangeWithId) (AddResult, error)
|
||||
|
||||
Delete() error
|
||||
Close() error
|
||||
}
|
||||
|
||||
@ -66,7 +67,7 @@ type objectTree struct {
|
||||
validator ObjectTreeValidator
|
||||
rawChangeLoader *rawChangeLoader
|
||||
treeBuilder *treeBuilder
|
||||
aclList list2.ACLList
|
||||
aclList list.ACLList
|
||||
|
||||
id string
|
||||
root *treechangeproto.RawTreeChangeWithId
|
||||
@ -91,16 +92,16 @@ type objectTreeDeps struct {
|
||||
treeStorage storage.TreeStorage
|
||||
validator ObjectTreeValidator
|
||||
rawChangeLoader *rawChangeLoader
|
||||
aclList list2.ACLList
|
||||
aclList list.ACLList
|
||||
}
|
||||
|
||||
func defaultObjectTreeDeps(
|
||||
rootChange *treechangeproto.RawTreeChangeWithId,
|
||||
treeStorage storage.TreeStorage,
|
||||
aclList list2.ACLList) objectTreeDeps {
|
||||
aclList list.ACLList) objectTreeDeps {
|
||||
|
||||
keychain := common.NewKeychain()
|
||||
changeBuilder := newChangeBuilder(keychain, rootChange)
|
||||
changeBuilder := NewChangeBuilder(keychain, rootChange)
|
||||
treeBuilder := newTreeBuilder(treeStorage, changeBuilder)
|
||||
return objectTreeDeps{
|
||||
changeBuilder: changeBuilder,
|
||||
@ -186,16 +187,23 @@ func (ot *objectTree) prepareBuilderContent(content SignableChangeContent) (cnt
|
||||
ot.aclList.RLock()
|
||||
defer ot.aclList.RUnlock()
|
||||
|
||||
state := ot.aclList.ACLState() // special method for own keys
|
||||
readKey, err := state.CurrentReadKey()
|
||||
if err != nil {
|
||||
return
|
||||
var (
|
||||
state = ot.aclList.ACLState() // special method for own keys
|
||||
readKey *symmetric.Key
|
||||
readKeyHash uint64
|
||||
)
|
||||
if content.IsEncrypted {
|
||||
readKeyHash = state.CurrentReadKeyHash()
|
||||
readKey, err = state.CurrentReadKey()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
cnt = BuilderContent{
|
||||
TreeHeadIds: ot.tree.Heads(),
|
||||
AclHeadId: ot.aclList.Head().Id,
|
||||
SnapshotBaseId: ot.tree.RootId(),
|
||||
CurrentReadKeyHash: state.CurrentReadKeyHash(),
|
||||
CurrentReadKeyHash: readKeyHash,
|
||||
Identity: content.Identity,
|
||||
IsSnapshot: content.IsSnapshot,
|
||||
SigningKey: content.Key,
|
||||
@ -439,9 +447,25 @@ func (ot *objectTree) IterateFrom(id string, convert ChangeConvertFunc, iterate
|
||||
ot.tree.Iterate(id, iterate)
|
||||
return
|
||||
}
|
||||
decrypt := func(c *Change) (decrypted []byte, err error) {
|
||||
// the change is not encrypted
|
||||
if c.ReadKeyHash == 0 {
|
||||
decrypted = c.Data
|
||||
return
|
||||
}
|
||||
readKey, exists := ot.keys[c.ReadKeyHash]
|
||||
if !exists {
|
||||
err = list.ErrNoReadKey
|
||||
return
|
||||
}
|
||||
|
||||
ot.tree.Iterate(ot.tree.RootId(), func(c *Change) (isContinue bool) {
|
||||
decrypted, err = readKey.Decrypt(c.Data)
|
||||
return
|
||||
}
|
||||
|
||||
ot.tree.Iterate(id, func(c *Change) (isContinue bool) {
|
||||
var model any
|
||||
// if already saved as a model
|
||||
if c.Model != nil {
|
||||
return iterate(c)
|
||||
}
|
||||
@ -449,14 +473,9 @@ func (ot *objectTree) IterateFrom(id string, convert ChangeConvertFunc, iterate
|
||||
if c.Id == ot.id {
|
||||
return iterate(c)
|
||||
}
|
||||
readKey, exists := ot.keys[c.ReadKeyHash]
|
||||
if !exists {
|
||||
err = list2.ErrNoReadKey
|
||||
return false
|
||||
}
|
||||
|
||||
var decrypted []byte
|
||||
decrypted, err = readKey.Decrypt(c.Data)
|
||||
decrypted, err = decrypt(c)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
@ -508,6 +527,10 @@ func (ot *objectTree) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ot *objectTree) Delete() error {
|
||||
return ot.treeStorage.Delete()
|
||||
}
|
||||
|
||||
func (ot *objectTree) SnapshotPath() []string {
|
||||
// TODO: Add error as return parameter
|
||||
if ot.snapshotPathIsActual() {
|
||||
|
||||
@ -116,7 +116,7 @@ func prepareTreeContext(t *testing.T, aclList list.ACLList) testTreeContext {
|
||||
treeStorage := changeCreator.createNewTreeStorage("0", aclList.Head().Id)
|
||||
root, _ := treeStorage.Root()
|
||||
changeBuilder := &mockChangeBuilder{
|
||||
originalBuilder: newChangeBuilder(nil, root),
|
||||
originalBuilder: NewChangeBuilder(nil, root),
|
||||
}
|
||||
deps := objectTreeDeps{
|
||||
changeBuilder: changeBuilder,
|
||||
|
||||
@ -14,10 +14,11 @@ import (
|
||||
)
|
||||
|
||||
type ObjectTreeCreatePayload struct {
|
||||
SignKey signingkey.PrivKey
|
||||
ChangeType string
|
||||
SpaceId string
|
||||
Identity []byte
|
||||
SignKey signingkey.PrivKey
|
||||
ChangeType string
|
||||
SpaceId string
|
||||
Identity []byte
|
||||
IsEncrypted bool
|
||||
}
|
||||
|
||||
func BuildObjectTree(treeStorage storage.TreeStorage, aclList list.ACLList) (ObjectTree, error) {
|
||||
@ -71,7 +72,7 @@ func createObjectTree(
|
||||
Seed: seed,
|
||||
}
|
||||
|
||||
_, raw, err := newChangeBuilder(common.NewKeychain(), nil).BuildInitialContent(cnt)
|
||||
_, raw, err := NewChangeBuilder(common.NewKeychain(), nil).BuildInitialContent(cnt)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@ -137,23 +137,27 @@ func (r *rawChangeLoader) LoadFromStorage(commonSnapshot string, heads, breakpoi
|
||||
if !shouldVisit(entry.position, exists) {
|
||||
continue
|
||||
}
|
||||
if id == commonSnapshot {
|
||||
commonSnapshotVisited = true
|
||||
continue
|
||||
}
|
||||
if !exists {
|
||||
entry, err = r.loadEntry(id)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// setting the counter when we visit
|
||||
r.cache[id] = visit(entry)
|
||||
entry = visit(entry)
|
||||
r.cache[id] = entry
|
||||
|
||||
for _, prev := range entry.change.PreviousIds {
|
||||
if prev == commonSnapshot {
|
||||
commonSnapshotVisited = true
|
||||
break
|
||||
}
|
||||
entry, exists = r.cache[prev]
|
||||
if !shouldVisit(entry.position, exists) {
|
||||
prevEntry, exists := r.cache[prev]
|
||||
if !shouldVisit(prevEntry.position, exists) {
|
||||
continue
|
||||
}
|
||||
r.idStack = append(r.idStack, prev)
|
||||
|
||||
@ -5,8 +5,9 @@ import (
|
||||
)
|
||||
|
||||
type SignableChangeContent struct {
|
||||
Data []byte
|
||||
Key signingkey.PrivKey
|
||||
Identity []byte
|
||||
IsSnapshot bool
|
||||
Data []byte
|
||||
Key signingkey.PrivKey
|
||||
Identity []byte
|
||||
IsSnapshot bool
|
||||
IsEncrypted bool
|
||||
}
|
||||
|
||||
@ -336,8 +336,9 @@ func (t *Tree) dfsPrev(stack []*Change, breakpoints []string, visit func(ch *Cha
|
||||
t.visitedBuf = append(t.visitedBuf, ch)
|
||||
|
||||
for _, prevId := range ch.PreviousIds {
|
||||
prevCh := t.attached[prevId]
|
||||
if !prevCh.visited {
|
||||
prevCh, exists := t.attached[prevId]
|
||||
// here the only time it wouldn't exist if we are at the tree root
|
||||
if exists && !prevCh.visited {
|
||||
stack = append(stack, prevCh)
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,58 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/periodicsync (interfaces: PeriodicSync)
|
||||
|
||||
// Package mock_periodicsync is a generated GoMock package.
|
||||
package mock_periodicsync
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
)
|
||||
|
||||
// MockPeriodicSync is a mock of PeriodicSync interface.
|
||||
type MockPeriodicSync struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockPeriodicSyncMockRecorder
|
||||
}
|
||||
|
||||
// MockPeriodicSyncMockRecorder is the mock recorder for MockPeriodicSync.
|
||||
type MockPeriodicSyncMockRecorder struct {
|
||||
mock *MockPeriodicSync
|
||||
}
|
||||
|
||||
// NewMockPeriodicSync creates a new mock instance.
|
||||
func NewMockPeriodicSync(ctrl *gomock.Controller) *MockPeriodicSync {
|
||||
mock := &MockPeriodicSync{ctrl: ctrl}
|
||||
mock.recorder = &MockPeriodicSyncMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockPeriodicSync) EXPECT() *MockPeriodicSyncMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Close mocks base method.
|
||||
func (m *MockPeriodicSync) Close() {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "Close")
|
||||
}
|
||||
|
||||
// Close indicates an expected call of Close.
|
||||
func (mr *MockPeriodicSyncMockRecorder) Close() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockPeriodicSync)(nil).Close))
|
||||
}
|
||||
|
||||
// Run mocks base method.
|
||||
func (m *MockPeriodicSync) Run() {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "Run")
|
||||
}
|
||||
|
||||
// Run indicates an expected call of Run.
|
||||
func (mr *MockPeriodicSyncMockRecorder) Run() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockPeriodicSync)(nil).Run))
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
package diffservice
|
||||
//go:generate mockgen -destination mock_periodicsync/mock_periodicsync.go github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/periodicsync PeriodicSync
|
||||
package periodicsync
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -11,7 +12,9 @@ type PeriodicSync interface {
|
||||
Close()
|
||||
}
|
||||
|
||||
func newPeriodicSync(periodSeconds int, syncer DiffSyncer, l *zap.Logger) *periodicSync {
|
||||
type SyncerFunc func(ctx context.Context) error
|
||||
|
||||
func NewPeriodicSync(periodSeconds int, syncer SyncerFunc, l *zap.Logger) PeriodicSync {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
return &periodicSync{
|
||||
syncer: syncer,
|
||||
@ -25,7 +28,7 @@ func newPeriodicSync(periodSeconds int, syncer DiffSyncer, l *zap.Logger) *perio
|
||||
|
||||
type periodicSync struct {
|
||||
log *zap.Logger
|
||||
syncer DiffSyncer
|
||||
syncer SyncerFunc
|
||||
syncCtx context.Context
|
||||
syncCancel context.CancelFunc
|
||||
syncLoopDone chan struct{}
|
||||
@ -42,7 +45,7 @@ func (p *periodicSync) syncLoop(periodSeconds int) {
|
||||
doSync := func() {
|
||||
ctx, cancel := context.WithTimeout(p.syncCtx, time.Minute)
|
||||
defer cancel()
|
||||
if err := p.syncer.Sync(ctx); err != nil {
|
||||
if err := p.syncer(ctx); err != nil {
|
||||
p.log.Warn("periodic sync error", zap.Error(err))
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,10 @@
|
||||
package diffservice
|
||||
package periodicsync
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/diffservice/mock_diffservice"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/stretchr/testify/require"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
@ -14,25 +15,34 @@ func TestPeriodicSync_Run(t *testing.T) {
|
||||
defer ctrl.Finish()
|
||||
|
||||
l := logger.NewNamed("sync")
|
||||
diffSyncer := mock_diffservice.NewMockDiffSyncer(ctrl)
|
||||
|
||||
t.Run("diff syncer 1 time", func(t *testing.T) {
|
||||
secs := 0
|
||||
pSync := newPeriodicSync(secs, diffSyncer, l)
|
||||
|
||||
diffSyncer.EXPECT().Sync(gomock.Any()).Times(1).Return(nil)
|
||||
times := 0
|
||||
diffSyncer := func(ctx context.Context) (err error) {
|
||||
times += 1
|
||||
return nil
|
||||
}
|
||||
pSync := NewPeriodicSync(secs, diffSyncer, l)
|
||||
|
||||
pSync.Run()
|
||||
pSync.Close()
|
||||
require.Equal(t, 1, times)
|
||||
})
|
||||
|
||||
t.Run("diff syncer 2 times", func(t *testing.T) {
|
||||
secs := 1
|
||||
|
||||
pSync := newPeriodicSync(secs, diffSyncer, l)
|
||||
diffSyncer.EXPECT().Sync(gomock.Any()).Times(2).Return(nil)
|
||||
times := 0
|
||||
diffSyncer := func(ctx context.Context) (err error) {
|
||||
times += 1
|
||||
return nil
|
||||
}
|
||||
pSync := NewPeriodicSync(secs, diffSyncer, l)
|
||||
|
||||
pSync.Run()
|
||||
time.Sleep(time.Second * time.Duration(secs))
|
||||
pSync.Close()
|
||||
require.Equal(t, 2, times)
|
||||
})
|
||||
}
|
||||
28
etc/acl.yml
28
etc/acl.yml
@ -1,28 +0,0 @@
|
||||
records:
|
||||
- identity: A
|
||||
aclChanges:
|
||||
- userAdd:
|
||||
identity: A
|
||||
permission: admin
|
||||
encryptionKey: key.Enc.A
|
||||
encryptedReadKeys: [key.Read.1]
|
||||
- userAdd:
|
||||
identity: B
|
||||
permission: admin
|
||||
encryptionKey: key.Enc.B
|
||||
encryptedReadKeys: [key.Read.1]
|
||||
readKey: key.Read.1
|
||||
keys:
|
||||
Enc:
|
||||
- name: A
|
||||
value: JgG4CcCbae1qEpe7mKpBzsHjZhXUmDSNVNX2B1gxFZsJyMX4V6kBQUott9zRWyeXaW1ZmpzuxDXnwSQpAnNurhXyGa9iQaAPqzY9A9VWBPD33Yy1eW7TRuVemzToh8jJQKQKnZNbF8ucTWV9qahusKzyvN8uyhrqoW2tAPfA9S3E3ognCuqbLSW6yjE2rBKayvyS1BVwzjSd6FZK4DDyjfU3pbEVjut3wytGEAn9af6sNMmyCnf2MX5vLovWs9rU8av61wD4z7HTsXyGFx4K75N4Go249Hpe9SKAT6HxhRc3yvj63krPLiQV5yMuH2UeMUXBDekUQyNmBEdn9wrur7mLqB67Bc6tcc2PP8XApBCdWJHvHjN4FktSpaG5vbCqoZbLD1oCbk36q2x9s6XM8pydVqD1J9P3nTbfgMb5pJCTFjNtgKeuKv6wjfJeA9jF1VhcJQisfsahgv9MvZ9M8FJpZTq1zKUhYDCRnZxUkraoMS5yNNVdDzaUckKEDthqik7BMWCWT79vq7uVgMwEvGwGi76gtoMg1159bbPMLZ4bdPVfhH2S9QjPrzQfwZSrzB2YeVPjWpaXDeLDity5H8n1NK2oniAQR6gE71n81neSptsuhV6o6QpQ89AU8y57XmEsou4VEryn8vUxBHhULLxrLNUouxyWamCeFiDjk5cSN6koQsf9BYKSNTPFTrwjTKForDokMhcPdMtFktKwjv7u9UEGcY4MKvNzZZkc77gHiP8bqVtdNNoLpTFUC5SZ9i7bKdHvK12HpSy7yzzPeMXJ9UwhLxkok1g81ngTbN1yxRhvYXyHZFtguCR9kvGojDjka91MTBtk551qDw9eCn2xZT9U8jqzBCjdpvSg3mRWKMPnYAGB7m7u1ye165wyGFvzcHAx3vtXjxAqLUeKYZCjv2m6V9D2Y4qH1TQNddWqH14T1JVMis971UCH9Ddpj6a3387oUnufD1P6HZN2ieJCvptrmbGVvxJYYSvmVf1dkwbtqurDRNWD7TJ7gf6iqSP549C9bxP4GpLt3ygjHmMtcuUzstBuztvunJUnQhfnJxqU6LjRdsFzm53wGWgXNxab7ZvQcPyLwsevn1b98FGPnVpS5iY4LjmqW4ugrC6HgrbsjrXiKzR1yZKhLQkCbLzPoaHb8iB5iBnCr7d4yf5CtfpFRqgoqMFdK5LNZYmDX4HzUKN6A7wC3gGiSRFTLcgGZeSMkB5Pa61CZBU7WCQgFxykycE9HRA7PiQa496GWDCV15teToCpFRsAa6jDmR1MGXPeLRqQgve49VXnQN5FL7c1VuEv5SWjeTuCnMB47DJKBaP7eKJNKgLwETALzSCMF3nRiRgeb15kfoS4BbrJ5yupjrvwmbmvNg1AYFFS5sYNWft7K8v87wQvBakRtGP71Kp8NX77XFtu6xdB7sR6jpfC6qJPyB9akWNXgCrWy9kE4ih42gwAZdUugNZ9YtEsgRM3pwb6qJhkAPyEJtrxrja859PCAgqPSQiPQN33PaMkgQ6HJknu8CrjKRiXAycZ16KLUkHV64TNhEjPTcX1a7rqpD131AYMWX8d7CCdc9Ys7RUb6BwguuNSh8rJK3x4AkMDSUsaE8ynKvpC7RXZpJ9Nxfhd
|
||||
- name: B
|
||||
value: JgG4CcCbae1qEpe7mKXzp7m5hNc56SSyZd9DwUaEStKJrq7RToAC2Vgd3i6hKRwa58zCWeN6Wjc3o6qrdKPEPRvcyEPysamajVo5mdQiUgWAmr97pGEsyjuRjQoC2GY2LvLiEQxEgwFgJxKGMHMiaWMtDfxCDUaDEm4bu5RdMhqRZekAWho6c3WoEeruSr14iX1TrocFNfBkBY7CjEw8kcywXCTNgtvhb2Qiwgj5AxEF4wyw4bzaNA9ctXb1hoHPFVMu6C51pkFY7jUD9zwyH3ukgnAewkGAcPNbKmaTAtMosKRVaAN97mAwXh2VRt1hWmRvVk7r76EjnVKhD4vbsKZc56RVcHTVWRVdhU7FGyPsiE5rSQAz1JQGYzxnZpX7EG77CyrmUGyfueVfRHhwY2oq8A4uQCRaQxSaJHYLowjXSxh8DQ2V6MTqyzti32C27utBYdHzLVCJSGkmdzGwrFcHqsq7nLDxmvJVErPvyReixEe8kFmqopJ3e6LLm8WdYw9K6JYBjXnEfwPzm7Von9sf3dcaGDUHYfttMyeke7fAXJkvPRje69hYVyzdQGAauuojzGkkvQWCSMK1KCMNMznRaPDCNvofrQhYrub24WhmwpKhorufdfW8Cb4T6reBDCtaWVsbuinjtL6F6Sui5aYHJFLJ6e4pPewr1P4EuZYRbMBZwN5KvDLhTGLBuBnaTqUUdF6bj2U22NoRYMogiHiftqKqiexKNDXX1Zg9RQEvxgjuVo6SBW42mVEA8agrLhruRqCmiduJxVrfqLNGeYXHXrcmMEgW7uosJbPXvTcfRvdFWS1ov7oSALvj6vhDQ28Yi9D2ETNdNsfVWAFQuwvPpW7CHQGXTitprVbqH8JYxNZuGygcLmr5efbB22Vzu4ntd1HoraQpG12qeDEUA7tXYUpoYyuSdWwKPjSAMtaQcCSfVrhKQHQuKJargrVrez8vjWuwLfvSucV7ZHe7gjqvYgULdE1ubRCRSd7DuLjEN2Vd6obzV2c3MRet7ZSf4Sp88WM5AuTyW7BjArBc4S3gUQ8rYaiZ8Tu7NCxkEzbFwWRaemZkwfvcsX3XxqjyF37tFSGkEqE5kuBvpZW72675LkDffj7kH1zA8yE6dVujJjWsNYVFJWndUtz5Vy2KCdZAbBgq19q4AtsxWPodU2N3yZXzFAFAzTrxS6V4P7Scpdau1avgRvHLcBQPunA37xaYMy8YMifJwtmRY25mnAQwZAk3eANk7tXwZd58SDnciLNvARJvwKzTQBXcshkwyy52SX8XmXDJsPnRLaHmiYBJ63Yzr5XpZuuAtxb9qrWG2NHCNxfomHokWacV1hjZPPd6ZxT1FuRozB6Qt2NLcyqY7bnTcQJb1jPUaTAGXXCR8WVmmmYo2fDQe8CdBmgyPvbzNTEJUyScBz4RdycB5PZap4SurJCWtHbuMyQbQUB6jJgURDstfXS5Akfe4oruNq9rnYcNtnsDJPtrhXHBqzDizmf1BDxR5FB2RCxzCgeAfg8WQ1Ug9PVAGTzob6ZqCrGXzWXEUniZnf1vjr7QhGKBYXEX9SWDoSMUpP4FreVDTnx15ijRZTV3p8xG5fE9e36TnugRVvTyq7XzmyPBjW2r66f1bior
|
||||
Sign:
|
||||
- name: A
|
||||
value: 3id6ddLcoNoe9rDgGM88ET8T6TnvHm5GFqFdN6kBzn7Q8d6VUGgjeT59CNWFiaofdeRnHBvX2A5ZacMXvfwaYEFuCbug
|
||||
- name: B
|
||||
value: 3iiLPj6wMUQpPwTBNZcUgkbXub1jumg4AEV9LfMyFHZVc84GLyAjVbVvH6EAGhcNrxRxL82aW4BimhDZCpLsRCqx5vwj
|
||||
Read:
|
||||
- name: 1
|
||||
value: bamccoi5jdypwnjkiuuogkawvhkbowha4qg756uhnbkecr5vt3h4q
|
||||
@ -1,37 +1,39 @@
|
||||
anytype:
|
||||
swarmKey: /key/swarm/psk/1.0.0/base16/209992e611c27d5dce8fbd2e7389f6b51da9bee980992ef60739460b536139ec
|
||||
swarmKey: /key/swarm/psk/1.0.0/base16/209992e611c27d5dce8fbd2e7389f6b51da9bee980992ef60739460b536139ec
|
||||
grpcServer:
|
||||
listenAddrs:
|
||||
- 127.0.0.1:4630
|
||||
tls: false
|
||||
listenAddrs:
|
||||
- 127.0.0.1:4630
|
||||
tls: false
|
||||
account:
|
||||
peerId: 12D3KooWFqDLPcSZi74A1vVpDc8baTkGU6bd21AXcNxH8CFPMqp6
|
||||
peerKey: s6PUCRVry6ymxhyytNQcqSQVd2ECGyWNMIJB0FkyMUFZXbbOYSBb2yYPeQXrA9jdFdZDXyUSxtvzasvpSMpa6w==
|
||||
signingKey: +UF/Do2KPeBLA0joKvnJj43jiH975JcHGjkLIkLR0p7FCFHnR1r/w4xLSa4RTjhEAQ3sDefjktShOJpalXnGvg==
|
||||
encryptionKey: MIIEpQIBAAKCAQEA7NiHF065o9BfTTAWtAItg3KLqvFnRN2WVQMkjMZ/BukIj4UAd196ppexh2tnDvvqW53qVxFtXcW8oFqX9GmDJx61nnN/ce2FhXNB3aPMa7g3AchlVVB9RHyS8Z49HTkn3DVRi8I8EnbpWer35BjnpGOQ257O/kFpD1P5FzvxyTQ2gF50SyiwoDzibyT2VxgQqaDErr9BfFQKBZb8SEBeLACOlzjb2u0mCv7NeoZNfzl2KsqBC8tiCyfNahhauGfU9ZB7PtHMC1pJKTtPhXhNhQI8Rp39dd+Fr3kiTJl3Fe1f4bg4GDI7LbqCARVBbtCjsLEMi1BMzMS63bFPrPL9ewIDAQABAoIBAQCA261j+Oj3Pz8ad7diaGzqvz9N2dkdlpFb30HbdYNW9yI5M1t1lvTb/lwQGVcQx+5RujDs/gZKpnJhq+hQibdZaVPWyW/lRB0I5hRHyf5F/QuwZJ79M7VztXMdEcKeS6JsJHYhW6PjR97dlQEZkJM21RTS6CwmGOBX/o/fHDYICNxIqt4x7x1Hu+A9Qcs3LWvWq0qAkO48jSYBDeIFJ56BdXZacfIv9A7aCGWoVvih2vFIFEwdn+3z69FHmcW8JzVDK+WdkegtOlvuPcFGgDjS8cHq4zuKyEckur9EVm2Wer+GRdY2v7i9ypxiy/Ej4qJCqJLIa5rtWHmB9Dz7IyFBAoGBAPlIMpu9vAhAhJUeO48vsuEDdCn2ztyq2h4GwYcuNmfZUAnFdKRHHAfb48P7nR1uVCEEvnJYF9uUFkot8zljkDCoqc3J30sOd54PT2Jqn2vPhSWpjNJGW4Ku3CmZq/vfCH15z+bcr7whtlEswshE31bykbZlzCOSyW1tgfz2I+ydAoGBAPM6iEV6M74X+M4GoVCwUn9JMFRUX/JONOu4nfNT+1jDeABeXzVS3gzLSMJ/Vk/+1a/g6NFm73bt5PYHR8jG/jrT3xcTBPUiFj038w1MAM5Fsj2jSnIFRYFxwH8q0RfejWvKJRyWKUyTt7m43VRY9P01+YDfgt+VoLs94rV0PNr3AoGAahmWoL8S5xg+1hE2HG2a3zbPHIVV6oo1qA4MFPNQaMcPz/jg+oLhpV6sBOB1MO+ikyMnxBdGoEjZa90+5rA/0NYY3+QKTDHuK7IsgaEMFaEP9MXDkEQt8uNmBbbIgr2dKXrNSF+p1JMsvEQm64KU5Lb92fpd9s4lOZQgfYBuLekCgYEAwNvPg6+S6Y7edJZjQLSepVjmHmfMsDd81M/NRkx4Bvju5PPvcDul3+UsazRGvyVkUJH4aVnCVL3rB33cWIIYwZKP2R72llyR37bGXOu/088FtsQMWn59j1cf+HV91/xajHZ7mMAkPRj/3B6OOLxUfZZXoO0ZO6nMCcvXQGPLgR8CgYEA2W644EHrSwb4qsDsUmIEeKnjSejS8Vej4S5/g1YOyVzfWEr/5rtejw09Fv4U92SeYhp7Xp3C0UnRCduZKrpXIZJVPO8KgWLDtPi9KvHqDPzpQNRHMNrsXLpOLLv+bnnymWXjcyG8fRecU4sggaH4r1C/QyLPr+s/fLDyVUt7bC8=
|
||||
peerId: 12D3KooWFgtCbkf47HhFyQW2cEdAkvaofpokCiaa24Phnz7hpepG
|
||||
peerKey: 4nWcqWOZxv1iXWYuW35eJlF9nxownm38bZjQ27pmFgVXO26vobKLx70TnNTQzZQdoW/dZtxyE9PO37R74vfPQQ==
|
||||
signingKey: ULbtmmyFjkJ6Z+54FI1OJWfu0QdIeoCckwcrBZDLGhw2o2cXTFH5KGxQuAruNTbREz9eAVGmhGoBZtKVi6/6ng==
|
||||
encryptionKey: MIIEowIBAAKCAQEAuGAvw/JQuivjoFIhV9RGkoCjO60jNkQpVPWK52eUtEvKHT2EzufhCRwxhAreajoyzk0PsyJ75FWrrvYs2tkSVHFOSiBkZIsldn5gPg1cnvnJOZ9VKDFp8h85d/4cPQ5tX78043nYTgLje2EmbB83inIr4oiZgxDrtLkozJHleAyWuOLIvlWO1l4Uplf6+uooL/5+WeUCuSGUM0wgXfpn+I2IuRhVDVZiChfp51Q6D6brTdOzNcWq1dw6Vld67u8aCLF1EVZ+xM/rnLLBC7MFvIw44LqHvmvGs/lpE9nMNx5L2KfpbpHSBI0IH3FkLQe2Qz8OMZpIa+aga/DzrBpEdwIDAQABAoIBACudXU898AjKPxN6ujZ7maIoWfTQ9SZuI1TcrNomr4+i6hHWrqb/RUWRbMkuhQSd9czFf/RBMQuHlJBT3bJ7bRGaqAly9iyumdMY/A1RvdpBfm9qGIvkfIpxBngzHVz4H7lpkspI1XlGx6c1CRDEpa/TaDwzUhUmGIvszRDvZlfqQvjPjyYSV5Hdc4ywh5zjuSFlxOD/9gsPRE5v4M4FGrGv8cm859P1u95Wxxo3pWincpzjvWw2LpsUGctyU34MhErxh86vNhP9v+nR4VkdojVKkHQTYnPKUlaKj6F+IUSj8syxuTJb8bs0GBuvcXW9AKp/K0xq/GBC8Cu/XN7Ln7kCgYEAwZoqLnU9OuwkcN5AHYW7XsxmVCEnxOsncrUbIzEKPvy4wELdOCVVrX66zmIjb+1+mhaz+mGMGEpkVMBld3wdDfmGgo0CAPlF4efH1ppMzUm2aZ+HYQR8KMH1XOT9qjbGEnLeWcANQT0vZPpe77PQLNwLJ1zv6EtXMMrEH0s4ijUCgYEA88zCNsBtB07ayFr9r+RCfHx/X9wFkT59t2K+axIfZE02f62WWqJCZYMlZu9XAbYEQ94H43/NAL9wfA8dgnF7mKSL8stJKt0g2iPa3MluF4Gq5Y2XYEVf/EDEhP2jh8p1l+xs18rVzsQQ6b3CEU9ytmBJWvkWnwVXf+ZnsCFECXsCgYBM3YyJzXp1/nOpbFRAZGw0AytNk6xafpK29DjGDB5pS6V+kA2M0SXnMD2y2zv+oGh3fTQP4NLigga7r3eZrOlMNxm0k4+MG2wneQLarYB4sR9/aBsz5bf15qwoKbKc9gpGIN0u/RVGJai/irhOqzGn3eV/x2Jo9CC1+otLcW4NUQKBgQCOOHlnZTN1GuwICwSIkhiy9BF+AyUASLsfuquoXEcRxPUw4DugnZ0sCKhN9vsDlYHBcYmajhgyAnuE83BcgwT906eMOEhzh9G9T0NCnwLpFYxzIvkWgQHwbnv1tNyrv1CAEryf2cSGPNw87qSCYp1hhKPmPP6UP5J+mxMLrSw6dwKBgHHFweDS2tw4TNxJQjhfQOp5t9VQbQffFZAqpXGFTc4vf7XePlxIGoIpOg4ShHCKKHSy0PtsLe7QjLrdbMkyYh8oGqgNe5CYTzFFDeK6Im1DoiqNWT+YUWF/gzVRUSpo0QW+4J1hfChG2URp9KbnditXKsJ5Vh+QayHPoZwN7Kgl
|
||||
apiServer:
|
||||
port: "8090"
|
||||
listenAddrs:
|
||||
- 127.0.0.1:8090
|
||||
tls: false
|
||||
nodes:
|
||||
- peerId: 12D3KooWLn13hDrZ6YRGM517fHf2zS6qhPNRu18inLMpRqn1YGKu
|
||||
address: 127.0.0.1:4430
|
||||
signingKey: 3mzfKBWtn7mitFEgq8u4eysWOJ6ySbUs49irfHwcuOmi1YMpobz9anoqd4yaT1owZiRPYXqx5k2Z4sNVRE3kXA==
|
||||
encryptionKey: MIIEpQIBAAKCAQEA3U7b4w9JTKE3TLM1WQ5iqdLbvUuozMp/hDEg7S15Gr6wrtLomMSBkfmVQ3Cu+CHdxAFqUFClItYlSFgtZWIFiSiQxCeaN2dmgczd9T4TlRAw6y6uJXtT9r7FIgizPP4B0/tnzPI6yYgpdwzCV2nRSjw3mMr5Nav3QYs18kYrJ1/Np2Wob5HOoRTUD++pPrToevTb7GNL/irrC8wXSE7oU6S7ix6Nh9vzEHg/V5FONBF/wWD/ri7Gy0j0qgUQ+gjxLWKr8xPDnRAve13zzo+54lGCyVvlm/rwCY9Jx378V1IuRx+S8F/GFuVozHD4XVaoSTtpCWPBQNSKDXgaIIKDowIDAQABAoIBACpMXj6ht1LMJXOldPbWhwkKYjFl+pdZxNGRSkfKvzDbbY2chhRcyp8J4vuG2ApY/rftxVIgd8+Wun1/TP3ppEE43aKAJzubqb35WBr9iGSfOZpZy7MiRUQN5kPBAfEQY20OyiIj0hSez74PVD283eGgbMfpU4Rsn8+JOgBaZPkbPViJLJY8PyHU6vwWw60dye1iJTz9yuBtoEqY0XKxnLaVXTQaWx0Te+VYU8twxDgXFWRaXtHuk7xnxOkCZDLrzIvuOYa5lsLoT8K62LDeXbyHBPhbdW0j4ZYzAOTsaUWpjuJzef9aj3JJdfyADiqb5iu6HHksvKzkZEau34zjilECgYEA/c8ZJm62uJMHNssTJYiLRw89l5hYwIZ/1TXdFRF8+xrTin5opYjpscSTO5bY2IYqLx2xuPiJCY1eGGB9L/RtkaVh51ySzq0d+4zpPIRKFcOOgdxHwlgoCgIhQECyfJZNMFGBUIlPXZ/phvXOXRvWFzDPhqThenVG2QzF+wLP0AUCgYEA3zfviQFJ1FOKJMozYO3tUZFmsIrAcO9hfuE7uuWz0Fw2m1XiwxjuOr1RbsSsh/lKke2h4tiGrlfiFhwCpIp91NkVTFrtFOQxbDxkYLkFiWkZDkOaK9YhKMa2cgEm3p+RGawokjbm51LKf+cbYN9xGaAe3y2WzIE4kNpfWE4SXYcCgYEAoagcrrvpqZoMCDxED63ud+4fHsUsEkQYe6Z5EAg5gH5PqnBlGrofjthTpqqnpxGdILFbFyNFtU3TVtduJPMcLp4Vw5TU9MqSxDu1+pOP1FjgFZpGImSf6+/7Wb9bb7sToujm4nLymAFYblt1exxVuiOeqnWuH58+5tQZ7YyW7DkCgYEAl7WuqZEkmpiEpWh/7vsGdo+6GXbUQG2R9+gg7m+7/HsP6hc/XZYOJAIT3JLzKB84nWHCyyiasNeuI5S5/xbZWtaH8TNDOxW0uXl6R3q41qGFk/pCSFTqiIo16dn6jwgoWCh4EpgZ61KLqs5p/zcd6Wq4ULrtaOTSizC/6IZ3WPUCgYEA6xCJy3+ICCgr8/c7hfd2Ylb3aOsXIffdgALhXjDcrNUCqgB4R+S3WReAwrABemQGl4tySQE/1f3Ru7SzMMciFogGyJ/YSXqSi6Y8oDD7MqlKPiWlN6WY1nSRMlLbkUOqpA5JaDM0kcmXjZpBBQr277GOnh9uKN8zUy5xoptctxI=
|
||||
- peerId: 12D3KooWLtuKtCPBYrFJV1NdejiCr2s614ppe9rmUXnkTHtAUD5U
|
||||
address: 127.0.0.1:4431
|
||||
signingKey: 07JMoW5cQUtGO9nNIGQo9e99b7Wf/4YvTtNEA0lt4gCkmhwB1EB9ay+kitxVJJgmdyGLxbUUlGqwXsAj0zlHWw==
|
||||
encryptionKey: MIIEpAIBAAKCAQEA7cA6J/icl8wseeXkt8oJr5AeYadUAG5EdCOdHj4S/Z7ivff4MOIKAeQITpq+rqhmXxOePYXSpQXE20Y9PW9tuw4gzOuq1ylSG/MWMcLDH1eIxg66rnmUqUbdiW4GGJjVjc9jvN0Up+MfSrUF6fM0jWTFoXVJQIeQQGERCIYjFzjfBl1xYvPghdxNgei/K5ZGYRggT28143XdIH4KTXGtp51hAKoyY9eCqYMtm9wvjxazhPVxO2CsYaqMxBLshY3jfHNqJnx8u6+h4Bl4uUcdbLNUgMcEgk7ehbQp2K0CqNoKXxbCTI6V57UVcJHDIaO5B6FyR6BguzHHNPJ4yd3q9wIDAQABAoIBAQCm2Mf3VRlPzhFIWnVwJXE2q8Umcu8Yfkm712Jj3twk8GPfPS4H4Bl1yjmqMB6xI6zz/CiItGlnNe04lMpVWuV+6CNMq/ZwmKbuxmFE+pFEZYGuvJd16gzR3tGJqJTOnjMAGhK8b8oXJ+TF4NQNooe20ol/DXgiuQAargPuH3RwzjYmF3N8VI4KUc3LaG4TwVXn4LwPOxrQSnfwJlZwLml1HAKOV0qcG0mXX6ZXOpoVhEoRPdQyUHc8ZW+53Agbtind7bYh5TsMVDFUrcgNwnwTOsWjil049la1IJO2uMRluacKlrtyzEp6zqrW8ZJO7mYAO69x4WyGqf2ZgIdA6djBAoGBAPqRHWAIgPa80eXbwCYkRtUG/ONBsQGi7+wm6nyhkXvNXJeokgH2DCgLH2+fW2scfOJuZc9r5WftEjOBvNfr2LDcwdyTSTh21WYcPSZx9HDf2d5/SWTcjNcyU0b5qfWIUKi/Zm9UY7r3X7yMA5dUD/cvu1PBJ5NWFrK1Gm2ph44dAoGBAPLn+LkHweU0fbxQq/76T5yVVpMKUaE9xwrJlUxEDPAQGnLPbFg4JeUt/YPhsOV85W4c4oQE+uFZrF0uf+1fEnS6MOJ+sq668upzC2hBp1B5138wM7615v1rvXVVH6qXfFop67FdBzPHt1NAN43mEIBZHTQ5hSVXFlYSZp9mxuEjAoGBAKCzUVO2IIAeub/iIGpV+dfGk4ptJ0kVZyreCqXEObpdC3V496uqUkGcYJ0GZ2ta6f2PMFzHpmnw8it2mdchu+gyrWL6U4uTK2pB0jZF/7Ak4WaB3GCD0xBxhleO6CJBOvn/R4M/bHcNEKmsYuE7WMIAKvScfPVR0VzsKfcLM5VBAoGAVvWg32zdh1bBZLdku8WU1rPH6KAbFSRuq3f7UPBTyWWaclu7p+GB/4f1aE9V6vJJmKASn7zArAhUYo+REMOmcc9uTMea5F7dM/23qb1HTtIvycLR44ZviW4Wx3iP+5x70jOLw1VQjMME6HLm8I/afHhqshWdiv6ganPv9UTwEg0CgYBSDi2dqg8F7ij5CN+LMDLSn3b8GCw+7efGIt7imm/O2V/FlHD40IA6qGg6DXNQrnoZQt94nMb1cZEvm1dxi6rmQNrhCyoMogAaPqgFhZGq1OjmhVZiXFUWy4WAcjdzFc9wZd3/XtaofRKHLK+ngTFhhVApKypLk3Rg9bCAAjzyVg==
|
||||
- peerId: 12D3KooWDCypXSyN6ppuMZGxVnBd1ZQCMV4y7Bn187S4duYmf8rA
|
||||
address: 127.0.0.1:4432
|
||||
signingKey: SGyNE0dFaQgtgNuzdcO7LB+TEz9VHAOtlQLk6WWkrkQyXiZV3casg8Q2/4PO1Oylc8Fu72RU001Hclj5JCbiLw==
|
||||
encryptionKey: MIIEpAIBAAKCAQEA0k3mw4FyexRkLgLjHzYs4Ppeyv6r9ZrP00imNf15JTuM8ajMx5oJX7JQTm8KOLRJjUdZZAd5Gtp0ezfYAQK1ZjEWwCmfp8j8FBgJIDSLpjxl88SXMLgATXYfhklnQvKlQjs/X3Ka4zdTrav2tMH9IAo6TSNZhlPQNsUory1SGHs+KqHv4p0sG8oWuKYhfBj8rWHQdUVptkIBKgojFDeJJD04Tbf9kUakbK/8KuXB6zF5H4WN3p4rMMwkClyTGeYO4LDg5TzVn8NnUi3/b/vO/3us1G/TMoRe/6umUfpQxrwo+7S2T6A4YwetWRp6xALLhp+HfAWnn0lA/D8/w1WpKwIDAQABAoIBAQC5cdQxRa5rddm48PbSCPWeFWkNW3DLDI6CYyedqDvxZwer+QtKXzww1I4X+7ZptiC9odLjb+uMkGHyXZXtnjPTPyounQWZ8JLILUGu0mbqWYwVXp9raHVr2OOHiKaz1D+BnbkOM4L9JUZ2eJL9ZaoNXLd4WdmRp8qM4WI0xqQDzOANx2HhyL/+dJmQeIUND+pdeH+Z+fYowU3ho32txNvBnMXQhF1T5K9i1VO5W49RAjIRbENsT+paPGKbNubDHRt1j36ktK4eC4HSdgv8tccdsGyrEiIbAt1XsTZfM8ie4D3A8RhSxiTC6Fkgv6vIm+iFTLzBFZKesOBcd8sfKeyBAoGBAOts5PQQJhldPDzlbnqzxMOR98WHbkVZjCqWSkNA34vqyFuPcRuX0rHK/qpg23ilbUP0fGMDTGgFzTt51FZLL16SXyRfjNhzjdmryryeddQwbp92ta2GEgnU6t1FyCuSCtcLDKJd/D9A9dC5UI6z+ES4TOnbR3nakXK9t4cUOFthAoGBAOSu+wL+SEA5erR+m3LpOsELK68CCJQPxn3VpoVfJZawgF+fEoXVMLTERxJput1+ADomIEdNc9ex86TjKx9gJ4piNHscRPFeT/AgESOIGHLOc1gk2DPqNj6wBIarUJQ9t4KcHScboh1dTPJeqqv2NSwIiLQoqFUIhfKZLnrW3zwLAoGBAJh0hC+o5YM3ZXLqAIllMN6VACbidP5j5ukNOjojIKCzAdyJH24G+2I3WoNrBbUzK3b+NC7KTAhw+V6ynlbjiWFs2D/twH/LFOkI3tkWpKcsVfbeIPimAbhsMUvpjJ7qjCqF9UCQLHGp14W6+/ftg7C8yNIINlkquVXclaTb60MBAoGAPqmL8ogG+EJH00mWAujRxq/u6meePiQMedKfbJBj1mTK6GjIRI/kZsQZzXvXTnYGTejAk4kvov0KDDaLTG+mpg6+3rUiVxlGwj+nMptKR7s2dAK0k5UsBAVrWBN9YwF+VXW9r0etJmq4ePljvvcaHtS/0M4LQjGxsoYy7EoQpX0CgYAhnf0McB7F1MxSjB0soMNv/v5utVzVihS3re2yKNdkI/YUEMB+yU3Q4gh+OljjBM6Y5To3BsQBAx4l2CysMKFHjIE/5AtdbvIS+chZZqB3vcZXSayvX8P1Z1uFdw/saiO2cRDJmR+TxaOPa2C9SzDoNTACthwLErHfzvEvVroKmw==
|
||||
- peerId: 12D3KooWPuwdqpDQxWhD2Vh4yskx2T5VMrwdpTZLfACzgsGfQfNy
|
||||
address: 127.0.0.1:4430
|
||||
signingKey: yOEpD2+cPldXc2urGuU+szunm7fddRa8xew2uVjaxifRcVzNKhSERpOefjrXaky7PcKmSmTsH/5ZFtcrh1uzqg==
|
||||
encryptionKey: MIIEpAIBAAKCAQEAxnE9Htwto+2fVmonkG9/DxNre33n7kjfrZU73JcHmpKhPlRFirig5T8rs2MaTq1R72/8nGBJuSxsz1PnexI3die39pY1OFYfZCZ59LbT7uH/xHcvkVrK2n50Q41KbbGT9BEzyW+XPkKPDpTq3/igYP+yUQgoWLfMwxCCLKXDe6qUC0fuIxR80fvj3XvorB5dnAiQ01JkH4PtCV1OWT6ZpLGhzcYxsxTHozd6LdMOC7wgGhW26dOSa/vZ1t5avbewFVIz0qfqBncunb7tjO4xa3xVYaA5jBbixDQUYFjVzW7cksrrN4CFNBDBGJ8PLS80MuMg0OG0O+/Qi1mbGb2mUQIDAQABAoIBACODAD0VidVcILeGJ65hRYudHg7raSXrRJv7qMrA/EtdEh3lVsyMXb6on1lq0rphqdf/YmVZldfda1tu2G3dxK8QTIuENeHvB48Uk56HWUXWi77M1WZdqQ+QsZ2lGzymGqQCsBHMNnSd1Jv3alDKXWj+WRrHKvE1cx81RRZYU7M9cpurnF5YNjO7L+7sMxUA9uAQGbe3kDVzrygraicLYQpxSNHytName0A+k3ug0qer4I6PmZhhJykkz6MD3dz/n625HSS+X+TuTm52T2b87tL27xXmSnUK7eYWjZ1vQlP1fWmqnac6u5LApUZaRi0tTjtefSjRW4jr1q20RqOp1kECgYEA7Onh3zM9ejATsjW6WISGKiBPci0D7DUbIuGuJrdQRadlkZzmeQ/VOYAuxIQD4GnQDRhM1FyxsqiAWkJOyCLFiMmsgIEyW9/eRhF8NlCVU+DA/fxy9EagfBbVsgiSBwOex24hPXIVYlaHkLAloNoD4bpw0pQZSDWXr+xvMFNwoGsCgYEA1m3sWA/e8ZuXForaUOoJzBU9nwC79bXv2UNktsVvBlQ1o9pbjoYDcVoAPwuBVUL1UwqDNMzPdhDBKBjZmCyjS6zlYD5ZKjF2m8iTyc4QcaBCdM0iyQpSXTmrfMx+hK1aWwL1p8ssNcednp5ExSAaTyNNGVdbtddiQ6/KMPmhUzMCgYEAwDjLsUNr4BXeBTweo+9yw/9PNn5brm0wRU8C9BrMIJe/izPYs+UqxerBB2Vtl8mCqv1KaQuEika5TYJ7VVsRFvk641DwQScUu5k4RQGBB3tWWz1XL+eWEticLkVR5isDyyAKDEbiHtXCTJz/CtGZUK7rF5BeKv6AwpZ9aKJqwV0CgYEAqXDlQNURu+PR6TtBtoypvz3NmraO0GO7KvipPhAXYm3qkRa8IIxfbhPLfAYQZhpqFvuIoJFzIn2s1I2GbExhoSv3eSzrcn7xlbpSpjYSImeb/AYZhbmFSiuHCi/hjeAaNS7KhZPz1G9vaubvusFaaMyhYPP6AWA4QvpHEJpB06cCgYBqR6/7d2hQiq4MJUrBEzLwG4ijnPeq+UVLQjE598hVIj+8UhRZRRcNWVEJxfcIL1v6Bpo8XISDNVRb30T9bPGVnXvC1jutTUbXKUB1/8iXuyH3IVieobch+bGd4v7ehH/lI7vzB6hjJpFzHopfFUn4wacSQdcFi3tRAwUB/L0S/w==
|
||||
- peerId: 12D3KooWBgHmDqtXH9SrZfAmwCFsD8LZhTD5dg5wkhdbqFoS8GBN
|
||||
address: 127.0.0.1:4431
|
||||
signingKey: l6LFiKqr4ZHgcPbL+DR7KwMbzImufQPFgpoHOJ/nvfUbpb76DCADHuT1I4gIs+XByglnY1KV8jbMfW64XRW5XQ==
|
||||
encryptionKey: MIIEowIBAAKCAQEA4ltcn1AH048bMXcKOOW7/E0TZYPxL3OtcHXWHSAZjeeTA/rc45G2eaNgyY7Ji+feLtZERbXNWGFBdNp31NHDYZAYwbZmjEqTEgV4yVx7BQP3VBEzglTJaNLTf+XIJnVAEkoHS6ogjC0oXTM6paHu64EitoOCzF9zqL023swjE3HU0dm2xwsUdGnKeO5nPMso/6e3VMavkKnFmvB965ECCBujtediP4lVdIABNVtoMHCoeI5Sn+m7TKqJSyDOIEMhHT3orYUNZWVeAHE1YTM2cI5tSnDZP80CHZ674Z/bKL7Jaznmq87mVt1h9Use2EkxR07/dJuTGvFOos4jHoiR9QIDAQABAoIBAHAr8EluooI/j61CnYk2p6LPG0aaTQJD4/YwHuwOBTviP2OghKgthGzg/szDerNfMyaoveqBvoIGqCZdQTbwwE7v1qTgXA83wYwTtBitQLVqkr1RTOJQXAMbPv5Jg5czUY3+q4DejQSKOE9/XJfKGJkSRH6Hy2C2CJ3dLnzYUqWGO3t70RLT1/sC6p6w3lXdy3dKZGkoR2wva+HXQxVrP8X5HOResXgNZwgMHt9KF1QHVCcySKYiEAefEKTSdKD2fOd4FxLgp3zWpvH3jrX0zd/DqzTlFD5Ns6Ayp2sIfHVp3sn99DZZM6DauMepQKtoSCnXZ+qKhekAwNVJnsVQkSECgYEA4spY9araeFUSl4uXCUQOpCkSshYOPRYN6sBbHsx8tV2eQtCT+5SuNYmzur3c5bkiraGEab8rZfGdDL6fLxQyaqbOmN31Db5kNh/2X+sRnxkak8lsROUWQZRF9doH73FDv6ZlI3V/JicZlOUCfN5BYT+x74R4/c1YXfyuD1J9gr0CgYEA/4K4SDwZUY4bOVCmKQz0OM+RW4PAAH6LHKenTAZNTeDNFFxc2nqnzRGMEKZTDGy0kbT5mBhBHFgShXcAiKxc5/MGkpt8Jcq6Fr5KGU9aZtYKji6mwMTsUndPNQydh3vOt5pOmcuMM6ovanNTvI8k6Qo53OY1IpO5CfOROu0hm5kCgYBnWsYd92YnDsYxUEldzKlLgPhnNov4pNNk15LvP0vaL7cPRhUaw1B9T6scAKjp/GxkasZ4lsnFZM4o37qV7wNm/WwL2KN0Rv9Od1SFtBBMzFkDXvk7kJeK/XLAr0OMiLbSYZeYCFUQ4yLSa2et1nA/TJLf0CR/rhSGiMAedX6DlQKBgAx1137OT33GrFUzNacy1oYeuTv5RNfBVA9lrabrd8GggN/JUU3mRWCexnHZaptkgbnJVZKxPBuhv+V6VDBWF4HIPD3SD0/YfxK03PA3CnWRYppkdAValRvAbcBsiRIeW4pgoAyn/IJYfk92qFK9uFMVCJVZNKYnBhMSKbbx8X2hAoGBAKwvzyAImbNB+493q1R/lSayxzG76bRJ/EseiTqwIec9c4C+Bd/sVXR+Re+xZb0FI/va1bz5CrduTzLSKBmf/+0lzl0MJvWY2+SXfGYdbl4+TTyqgDDfwqW0Tj8pDimye2BneyTmXko1rF+2Sxen7kMXnJLwpqjwZ6TZJuoqeK8q
|
||||
- peerId: 12D3KooWASsipDzkridiMBmE7VSqp8yZvGWPY1VqySgMSZk6tsiL
|
||||
address: 127.0.0.1:4432
|
||||
signingKey: /6+uYFwFf9nU6fvXQVtpHhjd8+v4dXc7esZzqkhjyfMJWlMiZOtQeb913FXofD5f20WksU0l6i22B09sFFYwDQ==
|
||||
encryptionKey: MIIEogIBAAKCAQEAwCy84lzkxtzgn4ixGm0LSUTujOBpOh9m7XDoDPZnMTmExdOe9a5v/LXzdlCOCuBvK5u1T3ALBJMA3Zgvjv/jPRQUdiHprP3sbdfc6IgZPBFdLKFTc9yAA7GMbI4y7LhGMLGOMOqQXs+DOeImfmxEs3ykLXHKNas5ORnZPVnB6E9Qod8KH7UyMmBjQkOZYOOw10X4JZiU6xJp/E+VVWcmeXgNBbj5xOWMSzM+hhoA4wNOzBxACucaKDmqD6qugzebOqyUVSzFnEbquro+MYTWYdUDjZTXdvxgUUo80MGQ164gZhkFUKrmSpUvu3YErFySEGqAdFNwOZ6y/4X3s0BHvQIDAQABAoIBAAZiNhAK5+qXMbr67m8jSimv6YCyf6xXmLKwenTbxofDEl8D7ZbZqYyqeqDmgiFoXSkErhwqa6NGQtQZlxLX+zNvNFLMQ5fkg3MOpZ7vzm7JYN/3p+8EVxhIUJLWkmh8opBBhaioUg1kNUa59W9jp1CTBl0gF4h63JbB/g5kqeVOllUw7J1igAoaX36nOJGOwIynCWdizhDhgyjR4OcYfOLwcPDJueKTc5vM10g3LuMSK/sJmaD3TkJFPtDHw+RMW6wqyjsnkrg2D2oohXEyGWYYIXo2so4HCez0AB1I1JAxtVnRPvSIp7xLMm7+AkDoq12QYDHfxZtDTpfmvJg+Sn0CgYEAxCd+oribtdQW+JUctjsDbSQX5CeRISH5Ith3jveBx2jKIqQVnoVPz6URHOvnlIsqYYLANB8B3JHMWfR2UmkK11x0OcZecB06+oBoCZukvSXF+GqVHzLAQUxaoEBDCCPneskj5w+riMWBiiGDp32rUnkqv0nh7dnH+GfORcJ44L8CgYEA+s5s5EALj1jyU9w4+HVUyVsIrUitFnQg6qw/Td3Kj+8CXImKlS+rlmbQv0m1aOcvtFjQRIjjzZJAf/ausfAME+MayoNODgZsDk5RyDKuSWzMLvZLAa1LD52Uli5Pg8KtpzKVTn4xE1MbjsQcUNhFRAgrNEKNyuzXzdp4uXgGOoMCgYASXwiTQOsEepq0KXMI9jn57Nl3+uSyz7W/t7pq329+N6hG2ktUD3RMJE+X/9gup2IOw+owd377I4SaIDU8vq3PQc944cVShspRT9lunO8u7+y8uW7B/0TWWMpcG+irSIGTlGcSavtL0gOx5jWoaDK1hLemNss8NZtu/nnpOq+LjQKBgDisVozJMBOHPNLYS4NROAR77p0BdCNDwIBmxbM5r+EQWA9DAS6u4+4Lc5YV+MkonG37N6yU5iz4pFyGCHmqzX/c7JvgSc3/g4FED1TWpu1uiUD/ZHmPiAuSRxYchtk2L3k9g+GFwF8mg26iP+fAxv4VfnXDqDi3hhg9CtSWG4ozAoGAOWZXlFKqzGAfcucIe54FVQnweXG9sEuIPAvWvVRs4406ggNmL5eHccXpPHWTgetsr2TYMqPTDVMRmhBzSkyrYgk+b2tme79HPzTWs2Yg/pzjOfTgw7MBX/KlvOW5/J+dvrF3Gx8AHHZ9QQdYqi/MS1NKb2K3IbD0/m5gL5Pwi6A=
|
||||
space:
|
||||
gcTTL: 60
|
||||
syncPeriod: 10
|
||||
gcTTL: 60
|
||||
syncPeriod: 11
|
||||
storage:
|
||||
path: db
|
||||
path: db
|
||||
metric:
|
||||
addr: ""
|
||||
addr: ""
|
||||
log:
|
||||
production: false
|
||||
defaultLevel: ""
|
||||
namedLevels: {}
|
||||
production: false
|
||||
defaultLevel: ""
|
||||
namedLevels: {}
|
||||
|
||||
@ -1,37 +1,39 @@
|
||||
anytype:
|
||||
swarmKey: /key/swarm/psk/1.0.0/base16/209992e611c27d5dce8fbd2e7389f6b51da9bee980992ef60739460b536139ec
|
||||
swarmKey: /key/swarm/psk/1.0.0/base16/209992e611c27d5dce8fbd2e7389f6b51da9bee980992ef60739460b536139ec
|
||||
grpcServer:
|
||||
listenAddrs:
|
||||
- 127.0.0.1:4430
|
||||
tls: false
|
||||
listenAddrs:
|
||||
- 127.0.0.1:4430
|
||||
tls: false
|
||||
account:
|
||||
peerId: 12D3KooWLn13hDrZ6YRGM517fHf2zS6qhPNRu18inLMpRqn1YGKu
|
||||
peerKey: 3mzfKBWtn7mitFEgq8u4eysWOJ6ySbUs49irfHwcuOmi1YMpobz9anoqd4yaT1owZiRPYXqx5k2Z4sNVRE3kXA==
|
||||
signingKey: 3mzfKBWtn7mitFEgq8u4eysWOJ6ySbUs49irfHwcuOmi1YMpobz9anoqd4yaT1owZiRPYXqx5k2Z4sNVRE3kXA==
|
||||
encryptionKey: MIIEpQIBAAKCAQEA3U7b4w9JTKE3TLM1WQ5iqdLbvUuozMp/hDEg7S15Gr6wrtLomMSBkfmVQ3Cu+CHdxAFqUFClItYlSFgtZWIFiSiQxCeaN2dmgczd9T4TlRAw6y6uJXtT9r7FIgizPP4B0/tnzPI6yYgpdwzCV2nRSjw3mMr5Nav3QYs18kYrJ1/Np2Wob5HOoRTUD++pPrToevTb7GNL/irrC8wXSE7oU6S7ix6Nh9vzEHg/V5FONBF/wWD/ri7Gy0j0qgUQ+gjxLWKr8xPDnRAve13zzo+54lGCyVvlm/rwCY9Jx378V1IuRx+S8F/GFuVozHD4XVaoSTtpCWPBQNSKDXgaIIKDowIDAQABAoIBACpMXj6ht1LMJXOldPbWhwkKYjFl+pdZxNGRSkfKvzDbbY2chhRcyp8J4vuG2ApY/rftxVIgd8+Wun1/TP3ppEE43aKAJzubqb35WBr9iGSfOZpZy7MiRUQN5kPBAfEQY20OyiIj0hSez74PVD283eGgbMfpU4Rsn8+JOgBaZPkbPViJLJY8PyHU6vwWw60dye1iJTz9yuBtoEqY0XKxnLaVXTQaWx0Te+VYU8twxDgXFWRaXtHuk7xnxOkCZDLrzIvuOYa5lsLoT8K62LDeXbyHBPhbdW0j4ZYzAOTsaUWpjuJzef9aj3JJdfyADiqb5iu6HHksvKzkZEau34zjilECgYEA/c8ZJm62uJMHNssTJYiLRw89l5hYwIZ/1TXdFRF8+xrTin5opYjpscSTO5bY2IYqLx2xuPiJCY1eGGB9L/RtkaVh51ySzq0d+4zpPIRKFcOOgdxHwlgoCgIhQECyfJZNMFGBUIlPXZ/phvXOXRvWFzDPhqThenVG2QzF+wLP0AUCgYEA3zfviQFJ1FOKJMozYO3tUZFmsIrAcO9hfuE7uuWz0Fw2m1XiwxjuOr1RbsSsh/lKke2h4tiGrlfiFhwCpIp91NkVTFrtFOQxbDxkYLkFiWkZDkOaK9YhKMa2cgEm3p+RGawokjbm51LKf+cbYN9xGaAe3y2WzIE4kNpfWE4SXYcCgYEAoagcrrvpqZoMCDxED63ud+4fHsUsEkQYe6Z5EAg5gH5PqnBlGrofjthTpqqnpxGdILFbFyNFtU3TVtduJPMcLp4Vw5TU9MqSxDu1+pOP1FjgFZpGImSf6+/7Wb9bb7sToujm4nLymAFYblt1exxVuiOeqnWuH58+5tQZ7YyW7DkCgYEAl7WuqZEkmpiEpWh/7vsGdo+6GXbUQG2R9+gg7m+7/HsP6hc/XZYOJAIT3JLzKB84nWHCyyiasNeuI5S5/xbZWtaH8TNDOxW0uXl6R3q41qGFk/pCSFTqiIo16dn6jwgoWCh4EpgZ61KLqs5p/zcd6Wq4ULrtaOTSizC/6IZ3WPUCgYEA6xCJy3+ICCgr8/c7hfd2Ylb3aOsXIffdgALhXjDcrNUCqgB4R+S3WReAwrABemQGl4tySQE/1f3Ru7SzMMciFogGyJ/YSXqSi6Y8oDD7MqlKPiWlN6WY1nSRMlLbkUOqpA5JaDM0kcmXjZpBBQr277GOnh9uKN8zUy5xoptctxI=
|
||||
peerId: 12D3KooWPuwdqpDQxWhD2Vh4yskx2T5VMrwdpTZLfACzgsGfQfNy
|
||||
peerKey: yOEpD2+cPldXc2urGuU+szunm7fddRa8xew2uVjaxifRcVzNKhSERpOefjrXaky7PcKmSmTsH/5ZFtcrh1uzqg==
|
||||
signingKey: yOEpD2+cPldXc2urGuU+szunm7fddRa8xew2uVjaxifRcVzNKhSERpOefjrXaky7PcKmSmTsH/5ZFtcrh1uzqg==
|
||||
encryptionKey: MIIEpAIBAAKCAQEAxnE9Htwto+2fVmonkG9/DxNre33n7kjfrZU73JcHmpKhPlRFirig5T8rs2MaTq1R72/8nGBJuSxsz1PnexI3die39pY1OFYfZCZ59LbT7uH/xHcvkVrK2n50Q41KbbGT9BEzyW+XPkKPDpTq3/igYP+yUQgoWLfMwxCCLKXDe6qUC0fuIxR80fvj3XvorB5dnAiQ01JkH4PtCV1OWT6ZpLGhzcYxsxTHozd6LdMOC7wgGhW26dOSa/vZ1t5avbewFVIz0qfqBncunb7tjO4xa3xVYaA5jBbixDQUYFjVzW7cksrrN4CFNBDBGJ8PLS80MuMg0OG0O+/Qi1mbGb2mUQIDAQABAoIBACODAD0VidVcILeGJ65hRYudHg7raSXrRJv7qMrA/EtdEh3lVsyMXb6on1lq0rphqdf/YmVZldfda1tu2G3dxK8QTIuENeHvB48Uk56HWUXWi77M1WZdqQ+QsZ2lGzymGqQCsBHMNnSd1Jv3alDKXWj+WRrHKvE1cx81RRZYU7M9cpurnF5YNjO7L+7sMxUA9uAQGbe3kDVzrygraicLYQpxSNHytName0A+k3ug0qer4I6PmZhhJykkz6MD3dz/n625HSS+X+TuTm52T2b87tL27xXmSnUK7eYWjZ1vQlP1fWmqnac6u5LApUZaRi0tTjtefSjRW4jr1q20RqOp1kECgYEA7Onh3zM9ejATsjW6WISGKiBPci0D7DUbIuGuJrdQRadlkZzmeQ/VOYAuxIQD4GnQDRhM1FyxsqiAWkJOyCLFiMmsgIEyW9/eRhF8NlCVU+DA/fxy9EagfBbVsgiSBwOex24hPXIVYlaHkLAloNoD4bpw0pQZSDWXr+xvMFNwoGsCgYEA1m3sWA/e8ZuXForaUOoJzBU9nwC79bXv2UNktsVvBlQ1o9pbjoYDcVoAPwuBVUL1UwqDNMzPdhDBKBjZmCyjS6zlYD5ZKjF2m8iTyc4QcaBCdM0iyQpSXTmrfMx+hK1aWwL1p8ssNcednp5ExSAaTyNNGVdbtddiQ6/KMPmhUzMCgYEAwDjLsUNr4BXeBTweo+9yw/9PNn5brm0wRU8C9BrMIJe/izPYs+UqxerBB2Vtl8mCqv1KaQuEika5TYJ7VVsRFvk641DwQScUu5k4RQGBB3tWWz1XL+eWEticLkVR5isDyyAKDEbiHtXCTJz/CtGZUK7rF5BeKv6AwpZ9aKJqwV0CgYEAqXDlQNURu+PR6TtBtoypvz3NmraO0GO7KvipPhAXYm3qkRa8IIxfbhPLfAYQZhpqFvuIoJFzIn2s1I2GbExhoSv3eSzrcn7xlbpSpjYSImeb/AYZhbmFSiuHCi/hjeAaNS7KhZPz1G9vaubvusFaaMyhYPP6AWA4QvpHEJpB06cCgYBqR6/7d2hQiq4MJUrBEzLwG4ijnPeq+UVLQjE598hVIj+8UhRZRRcNWVEJxfcIL1v6Bpo8XISDNVRb30T9bPGVnXvC1jutTUbXKUB1/8iXuyH3IVieobch+bGd4v7ehH/lI7vzB6hjJpFzHopfFUn4wacSQdcFi3tRAwUB/L0S/w==
|
||||
apiServer:
|
||||
port: "8084"
|
||||
listenAddrs:
|
||||
- 127.0.0.1:8080
|
||||
tls: false
|
||||
nodes:
|
||||
- peerId: 12D3KooWLn13hDrZ6YRGM517fHf2zS6qhPNRu18inLMpRqn1YGKu
|
||||
address: 127.0.0.1:4430
|
||||
signingKey: 3mzfKBWtn7mitFEgq8u4eysWOJ6ySbUs49irfHwcuOmi1YMpobz9anoqd4yaT1owZiRPYXqx5k2Z4sNVRE3kXA==
|
||||
encryptionKey: MIIEpQIBAAKCAQEA3U7b4w9JTKE3TLM1WQ5iqdLbvUuozMp/hDEg7S15Gr6wrtLomMSBkfmVQ3Cu+CHdxAFqUFClItYlSFgtZWIFiSiQxCeaN2dmgczd9T4TlRAw6y6uJXtT9r7FIgizPP4B0/tnzPI6yYgpdwzCV2nRSjw3mMr5Nav3QYs18kYrJ1/Np2Wob5HOoRTUD++pPrToevTb7GNL/irrC8wXSE7oU6S7ix6Nh9vzEHg/V5FONBF/wWD/ri7Gy0j0qgUQ+gjxLWKr8xPDnRAve13zzo+54lGCyVvlm/rwCY9Jx378V1IuRx+S8F/GFuVozHD4XVaoSTtpCWPBQNSKDXgaIIKDowIDAQABAoIBACpMXj6ht1LMJXOldPbWhwkKYjFl+pdZxNGRSkfKvzDbbY2chhRcyp8J4vuG2ApY/rftxVIgd8+Wun1/TP3ppEE43aKAJzubqb35WBr9iGSfOZpZy7MiRUQN5kPBAfEQY20OyiIj0hSez74PVD283eGgbMfpU4Rsn8+JOgBaZPkbPViJLJY8PyHU6vwWw60dye1iJTz9yuBtoEqY0XKxnLaVXTQaWx0Te+VYU8twxDgXFWRaXtHuk7xnxOkCZDLrzIvuOYa5lsLoT8K62LDeXbyHBPhbdW0j4ZYzAOTsaUWpjuJzef9aj3JJdfyADiqb5iu6HHksvKzkZEau34zjilECgYEA/c8ZJm62uJMHNssTJYiLRw89l5hYwIZ/1TXdFRF8+xrTin5opYjpscSTO5bY2IYqLx2xuPiJCY1eGGB9L/RtkaVh51ySzq0d+4zpPIRKFcOOgdxHwlgoCgIhQECyfJZNMFGBUIlPXZ/phvXOXRvWFzDPhqThenVG2QzF+wLP0AUCgYEA3zfviQFJ1FOKJMozYO3tUZFmsIrAcO9hfuE7uuWz0Fw2m1XiwxjuOr1RbsSsh/lKke2h4tiGrlfiFhwCpIp91NkVTFrtFOQxbDxkYLkFiWkZDkOaK9YhKMa2cgEm3p+RGawokjbm51LKf+cbYN9xGaAe3y2WzIE4kNpfWE4SXYcCgYEAoagcrrvpqZoMCDxED63ud+4fHsUsEkQYe6Z5EAg5gH5PqnBlGrofjthTpqqnpxGdILFbFyNFtU3TVtduJPMcLp4Vw5TU9MqSxDu1+pOP1FjgFZpGImSf6+/7Wb9bb7sToujm4nLymAFYblt1exxVuiOeqnWuH58+5tQZ7YyW7DkCgYEAl7WuqZEkmpiEpWh/7vsGdo+6GXbUQG2R9+gg7m+7/HsP6hc/XZYOJAIT3JLzKB84nWHCyyiasNeuI5S5/xbZWtaH8TNDOxW0uXl6R3q41qGFk/pCSFTqiIo16dn6jwgoWCh4EpgZ61KLqs5p/zcd6Wq4ULrtaOTSizC/6IZ3WPUCgYEA6xCJy3+ICCgr8/c7hfd2Ylb3aOsXIffdgALhXjDcrNUCqgB4R+S3WReAwrABemQGl4tySQE/1f3Ru7SzMMciFogGyJ/YSXqSi6Y8oDD7MqlKPiWlN6WY1nSRMlLbkUOqpA5JaDM0kcmXjZpBBQr277GOnh9uKN8zUy5xoptctxI=
|
||||
- peerId: 12D3KooWLtuKtCPBYrFJV1NdejiCr2s614ppe9rmUXnkTHtAUD5U
|
||||
address: 127.0.0.1:4431
|
||||
signingKey: 07JMoW5cQUtGO9nNIGQo9e99b7Wf/4YvTtNEA0lt4gCkmhwB1EB9ay+kitxVJJgmdyGLxbUUlGqwXsAj0zlHWw==
|
||||
encryptionKey: MIIEpAIBAAKCAQEA7cA6J/icl8wseeXkt8oJr5AeYadUAG5EdCOdHj4S/Z7ivff4MOIKAeQITpq+rqhmXxOePYXSpQXE20Y9PW9tuw4gzOuq1ylSG/MWMcLDH1eIxg66rnmUqUbdiW4GGJjVjc9jvN0Up+MfSrUF6fM0jWTFoXVJQIeQQGERCIYjFzjfBl1xYvPghdxNgei/K5ZGYRggT28143XdIH4KTXGtp51hAKoyY9eCqYMtm9wvjxazhPVxO2CsYaqMxBLshY3jfHNqJnx8u6+h4Bl4uUcdbLNUgMcEgk7ehbQp2K0CqNoKXxbCTI6V57UVcJHDIaO5B6FyR6BguzHHNPJ4yd3q9wIDAQABAoIBAQCm2Mf3VRlPzhFIWnVwJXE2q8Umcu8Yfkm712Jj3twk8GPfPS4H4Bl1yjmqMB6xI6zz/CiItGlnNe04lMpVWuV+6CNMq/ZwmKbuxmFE+pFEZYGuvJd16gzR3tGJqJTOnjMAGhK8b8oXJ+TF4NQNooe20ol/DXgiuQAargPuH3RwzjYmF3N8VI4KUc3LaG4TwVXn4LwPOxrQSnfwJlZwLml1HAKOV0qcG0mXX6ZXOpoVhEoRPdQyUHc8ZW+53Agbtind7bYh5TsMVDFUrcgNwnwTOsWjil049la1IJO2uMRluacKlrtyzEp6zqrW8ZJO7mYAO69x4WyGqf2ZgIdA6djBAoGBAPqRHWAIgPa80eXbwCYkRtUG/ONBsQGi7+wm6nyhkXvNXJeokgH2DCgLH2+fW2scfOJuZc9r5WftEjOBvNfr2LDcwdyTSTh21WYcPSZx9HDf2d5/SWTcjNcyU0b5qfWIUKi/Zm9UY7r3X7yMA5dUD/cvu1PBJ5NWFrK1Gm2ph44dAoGBAPLn+LkHweU0fbxQq/76T5yVVpMKUaE9xwrJlUxEDPAQGnLPbFg4JeUt/YPhsOV85W4c4oQE+uFZrF0uf+1fEnS6MOJ+sq668upzC2hBp1B5138wM7615v1rvXVVH6qXfFop67FdBzPHt1NAN43mEIBZHTQ5hSVXFlYSZp9mxuEjAoGBAKCzUVO2IIAeub/iIGpV+dfGk4ptJ0kVZyreCqXEObpdC3V496uqUkGcYJ0GZ2ta6f2PMFzHpmnw8it2mdchu+gyrWL6U4uTK2pB0jZF/7Ak4WaB3GCD0xBxhleO6CJBOvn/R4M/bHcNEKmsYuE7WMIAKvScfPVR0VzsKfcLM5VBAoGAVvWg32zdh1bBZLdku8WU1rPH6KAbFSRuq3f7UPBTyWWaclu7p+GB/4f1aE9V6vJJmKASn7zArAhUYo+REMOmcc9uTMea5F7dM/23qb1HTtIvycLR44ZviW4Wx3iP+5x70jOLw1VQjMME6HLm8I/afHhqshWdiv6ganPv9UTwEg0CgYBSDi2dqg8F7ij5CN+LMDLSn3b8GCw+7efGIt7imm/O2V/FlHD40IA6qGg6DXNQrnoZQt94nMb1cZEvm1dxi6rmQNrhCyoMogAaPqgFhZGq1OjmhVZiXFUWy4WAcjdzFc9wZd3/XtaofRKHLK+ngTFhhVApKypLk3Rg9bCAAjzyVg==
|
||||
- peerId: 12D3KooWDCypXSyN6ppuMZGxVnBd1ZQCMV4y7Bn187S4duYmf8rA
|
||||
address: 127.0.0.1:4432
|
||||
signingKey: SGyNE0dFaQgtgNuzdcO7LB+TEz9VHAOtlQLk6WWkrkQyXiZV3casg8Q2/4PO1Oylc8Fu72RU001Hclj5JCbiLw==
|
||||
encryptionKey: MIIEpAIBAAKCAQEA0k3mw4FyexRkLgLjHzYs4Ppeyv6r9ZrP00imNf15JTuM8ajMx5oJX7JQTm8KOLRJjUdZZAd5Gtp0ezfYAQK1ZjEWwCmfp8j8FBgJIDSLpjxl88SXMLgATXYfhklnQvKlQjs/X3Ka4zdTrav2tMH9IAo6TSNZhlPQNsUory1SGHs+KqHv4p0sG8oWuKYhfBj8rWHQdUVptkIBKgojFDeJJD04Tbf9kUakbK/8KuXB6zF5H4WN3p4rMMwkClyTGeYO4LDg5TzVn8NnUi3/b/vO/3us1G/TMoRe/6umUfpQxrwo+7S2T6A4YwetWRp6xALLhp+HfAWnn0lA/D8/w1WpKwIDAQABAoIBAQC5cdQxRa5rddm48PbSCPWeFWkNW3DLDI6CYyedqDvxZwer+QtKXzww1I4X+7ZptiC9odLjb+uMkGHyXZXtnjPTPyounQWZ8JLILUGu0mbqWYwVXp9raHVr2OOHiKaz1D+BnbkOM4L9JUZ2eJL9ZaoNXLd4WdmRp8qM4WI0xqQDzOANx2HhyL/+dJmQeIUND+pdeH+Z+fYowU3ho32txNvBnMXQhF1T5K9i1VO5W49RAjIRbENsT+paPGKbNubDHRt1j36ktK4eC4HSdgv8tccdsGyrEiIbAt1XsTZfM8ie4D3A8RhSxiTC6Fkgv6vIm+iFTLzBFZKesOBcd8sfKeyBAoGBAOts5PQQJhldPDzlbnqzxMOR98WHbkVZjCqWSkNA34vqyFuPcRuX0rHK/qpg23ilbUP0fGMDTGgFzTt51FZLL16SXyRfjNhzjdmryryeddQwbp92ta2GEgnU6t1FyCuSCtcLDKJd/D9A9dC5UI6z+ES4TOnbR3nakXK9t4cUOFthAoGBAOSu+wL+SEA5erR+m3LpOsELK68CCJQPxn3VpoVfJZawgF+fEoXVMLTERxJput1+ADomIEdNc9ex86TjKx9gJ4piNHscRPFeT/AgESOIGHLOc1gk2DPqNj6wBIarUJQ9t4KcHScboh1dTPJeqqv2NSwIiLQoqFUIhfKZLnrW3zwLAoGBAJh0hC+o5YM3ZXLqAIllMN6VACbidP5j5ukNOjojIKCzAdyJH24G+2I3WoNrBbUzK3b+NC7KTAhw+V6ynlbjiWFs2D/twH/LFOkI3tkWpKcsVfbeIPimAbhsMUvpjJ7qjCqF9UCQLHGp14W6+/ftg7C8yNIINlkquVXclaTb60MBAoGAPqmL8ogG+EJH00mWAujRxq/u6meePiQMedKfbJBj1mTK6GjIRI/kZsQZzXvXTnYGTejAk4kvov0KDDaLTG+mpg6+3rUiVxlGwj+nMptKR7s2dAK0k5UsBAVrWBN9YwF+VXW9r0etJmq4ePljvvcaHtS/0M4LQjGxsoYy7EoQpX0CgYAhnf0McB7F1MxSjB0soMNv/v5utVzVihS3re2yKNdkI/YUEMB+yU3Q4gh+OljjBM6Y5To3BsQBAx4l2CysMKFHjIE/5AtdbvIS+chZZqB3vcZXSayvX8P1Z1uFdw/saiO2cRDJmR+TxaOPa2C9SzDoNTACthwLErHfzvEvVroKmw==
|
||||
- peerId: 12D3KooWPuwdqpDQxWhD2Vh4yskx2T5VMrwdpTZLfACzgsGfQfNy
|
||||
address: 127.0.0.1:4430
|
||||
signingKey: yOEpD2+cPldXc2urGuU+szunm7fddRa8xew2uVjaxifRcVzNKhSERpOefjrXaky7PcKmSmTsH/5ZFtcrh1uzqg==
|
||||
encryptionKey: MIIEpAIBAAKCAQEAxnE9Htwto+2fVmonkG9/DxNre33n7kjfrZU73JcHmpKhPlRFirig5T8rs2MaTq1R72/8nGBJuSxsz1PnexI3die39pY1OFYfZCZ59LbT7uH/xHcvkVrK2n50Q41KbbGT9BEzyW+XPkKPDpTq3/igYP+yUQgoWLfMwxCCLKXDe6qUC0fuIxR80fvj3XvorB5dnAiQ01JkH4PtCV1OWT6ZpLGhzcYxsxTHozd6LdMOC7wgGhW26dOSa/vZ1t5avbewFVIz0qfqBncunb7tjO4xa3xVYaA5jBbixDQUYFjVzW7cksrrN4CFNBDBGJ8PLS80MuMg0OG0O+/Qi1mbGb2mUQIDAQABAoIBACODAD0VidVcILeGJ65hRYudHg7raSXrRJv7qMrA/EtdEh3lVsyMXb6on1lq0rphqdf/YmVZldfda1tu2G3dxK8QTIuENeHvB48Uk56HWUXWi77M1WZdqQ+QsZ2lGzymGqQCsBHMNnSd1Jv3alDKXWj+WRrHKvE1cx81RRZYU7M9cpurnF5YNjO7L+7sMxUA9uAQGbe3kDVzrygraicLYQpxSNHytName0A+k3ug0qer4I6PmZhhJykkz6MD3dz/n625HSS+X+TuTm52T2b87tL27xXmSnUK7eYWjZ1vQlP1fWmqnac6u5LApUZaRi0tTjtefSjRW4jr1q20RqOp1kECgYEA7Onh3zM9ejATsjW6WISGKiBPci0D7DUbIuGuJrdQRadlkZzmeQ/VOYAuxIQD4GnQDRhM1FyxsqiAWkJOyCLFiMmsgIEyW9/eRhF8NlCVU+DA/fxy9EagfBbVsgiSBwOex24hPXIVYlaHkLAloNoD4bpw0pQZSDWXr+xvMFNwoGsCgYEA1m3sWA/e8ZuXForaUOoJzBU9nwC79bXv2UNktsVvBlQ1o9pbjoYDcVoAPwuBVUL1UwqDNMzPdhDBKBjZmCyjS6zlYD5ZKjF2m8iTyc4QcaBCdM0iyQpSXTmrfMx+hK1aWwL1p8ssNcednp5ExSAaTyNNGVdbtddiQ6/KMPmhUzMCgYEAwDjLsUNr4BXeBTweo+9yw/9PNn5brm0wRU8C9BrMIJe/izPYs+UqxerBB2Vtl8mCqv1KaQuEika5TYJ7VVsRFvk641DwQScUu5k4RQGBB3tWWz1XL+eWEticLkVR5isDyyAKDEbiHtXCTJz/CtGZUK7rF5BeKv6AwpZ9aKJqwV0CgYEAqXDlQNURu+PR6TtBtoypvz3NmraO0GO7KvipPhAXYm3qkRa8IIxfbhPLfAYQZhpqFvuIoJFzIn2s1I2GbExhoSv3eSzrcn7xlbpSpjYSImeb/AYZhbmFSiuHCi/hjeAaNS7KhZPz1G9vaubvusFaaMyhYPP6AWA4QvpHEJpB06cCgYBqR6/7d2hQiq4MJUrBEzLwG4ijnPeq+UVLQjE598hVIj+8UhRZRRcNWVEJxfcIL1v6Bpo8XISDNVRb30T9bPGVnXvC1jutTUbXKUB1/8iXuyH3IVieobch+bGd4v7ehH/lI7vzB6hjJpFzHopfFUn4wacSQdcFi3tRAwUB/L0S/w==
|
||||
- peerId: 12D3KooWBgHmDqtXH9SrZfAmwCFsD8LZhTD5dg5wkhdbqFoS8GBN
|
||||
address: 127.0.0.1:4431
|
||||
signingKey: l6LFiKqr4ZHgcPbL+DR7KwMbzImufQPFgpoHOJ/nvfUbpb76DCADHuT1I4gIs+XByglnY1KV8jbMfW64XRW5XQ==
|
||||
encryptionKey: MIIEowIBAAKCAQEA4ltcn1AH048bMXcKOOW7/E0TZYPxL3OtcHXWHSAZjeeTA/rc45G2eaNgyY7Ji+feLtZERbXNWGFBdNp31NHDYZAYwbZmjEqTEgV4yVx7BQP3VBEzglTJaNLTf+XIJnVAEkoHS6ogjC0oXTM6paHu64EitoOCzF9zqL023swjE3HU0dm2xwsUdGnKeO5nPMso/6e3VMavkKnFmvB965ECCBujtediP4lVdIABNVtoMHCoeI5Sn+m7TKqJSyDOIEMhHT3orYUNZWVeAHE1YTM2cI5tSnDZP80CHZ674Z/bKL7Jaznmq87mVt1h9Use2EkxR07/dJuTGvFOos4jHoiR9QIDAQABAoIBAHAr8EluooI/j61CnYk2p6LPG0aaTQJD4/YwHuwOBTviP2OghKgthGzg/szDerNfMyaoveqBvoIGqCZdQTbwwE7v1qTgXA83wYwTtBitQLVqkr1RTOJQXAMbPv5Jg5czUY3+q4DejQSKOE9/XJfKGJkSRH6Hy2C2CJ3dLnzYUqWGO3t70RLT1/sC6p6w3lXdy3dKZGkoR2wva+HXQxVrP8X5HOResXgNZwgMHt9KF1QHVCcySKYiEAefEKTSdKD2fOd4FxLgp3zWpvH3jrX0zd/DqzTlFD5Ns6Ayp2sIfHVp3sn99DZZM6DauMepQKtoSCnXZ+qKhekAwNVJnsVQkSECgYEA4spY9araeFUSl4uXCUQOpCkSshYOPRYN6sBbHsx8tV2eQtCT+5SuNYmzur3c5bkiraGEab8rZfGdDL6fLxQyaqbOmN31Db5kNh/2X+sRnxkak8lsROUWQZRF9doH73FDv6ZlI3V/JicZlOUCfN5BYT+x74R4/c1YXfyuD1J9gr0CgYEA/4K4SDwZUY4bOVCmKQz0OM+RW4PAAH6LHKenTAZNTeDNFFxc2nqnzRGMEKZTDGy0kbT5mBhBHFgShXcAiKxc5/MGkpt8Jcq6Fr5KGU9aZtYKji6mwMTsUndPNQydh3vOt5pOmcuMM6ovanNTvI8k6Qo53OY1IpO5CfOROu0hm5kCgYBnWsYd92YnDsYxUEldzKlLgPhnNov4pNNk15LvP0vaL7cPRhUaw1B9T6scAKjp/GxkasZ4lsnFZM4o37qV7wNm/WwL2KN0Rv9Od1SFtBBMzFkDXvk7kJeK/XLAr0OMiLbSYZeYCFUQ4yLSa2et1nA/TJLf0CR/rhSGiMAedX6DlQKBgAx1137OT33GrFUzNacy1oYeuTv5RNfBVA9lrabrd8GggN/JUU3mRWCexnHZaptkgbnJVZKxPBuhv+V6VDBWF4HIPD3SD0/YfxK03PA3CnWRYppkdAValRvAbcBsiRIeW4pgoAyn/IJYfk92qFK9uFMVCJVZNKYnBhMSKbbx8X2hAoGBAKwvzyAImbNB+493q1R/lSayxzG76bRJ/EseiTqwIec9c4C+Bd/sVXR+Re+xZb0FI/va1bz5CrduTzLSKBmf/+0lzl0MJvWY2+SXfGYdbl4+TTyqgDDfwqW0Tj8pDimye2BneyTmXko1rF+2Sxen7kMXnJLwpqjwZ6TZJuoqeK8q
|
||||
- peerId: 12D3KooWASsipDzkridiMBmE7VSqp8yZvGWPY1VqySgMSZk6tsiL
|
||||
address: 127.0.0.1:4432
|
||||
signingKey: /6+uYFwFf9nU6fvXQVtpHhjd8+v4dXc7esZzqkhjyfMJWlMiZOtQeb913FXofD5f20WksU0l6i22B09sFFYwDQ==
|
||||
encryptionKey: MIIEogIBAAKCAQEAwCy84lzkxtzgn4ixGm0LSUTujOBpOh9m7XDoDPZnMTmExdOe9a5v/LXzdlCOCuBvK5u1T3ALBJMA3Zgvjv/jPRQUdiHprP3sbdfc6IgZPBFdLKFTc9yAA7GMbI4y7LhGMLGOMOqQXs+DOeImfmxEs3ykLXHKNas5ORnZPVnB6E9Qod8KH7UyMmBjQkOZYOOw10X4JZiU6xJp/E+VVWcmeXgNBbj5xOWMSzM+hhoA4wNOzBxACucaKDmqD6qugzebOqyUVSzFnEbquro+MYTWYdUDjZTXdvxgUUo80MGQ164gZhkFUKrmSpUvu3YErFySEGqAdFNwOZ6y/4X3s0BHvQIDAQABAoIBAAZiNhAK5+qXMbr67m8jSimv6YCyf6xXmLKwenTbxofDEl8D7ZbZqYyqeqDmgiFoXSkErhwqa6NGQtQZlxLX+zNvNFLMQ5fkg3MOpZ7vzm7JYN/3p+8EVxhIUJLWkmh8opBBhaioUg1kNUa59W9jp1CTBl0gF4h63JbB/g5kqeVOllUw7J1igAoaX36nOJGOwIynCWdizhDhgyjR4OcYfOLwcPDJueKTc5vM10g3LuMSK/sJmaD3TkJFPtDHw+RMW6wqyjsnkrg2D2oohXEyGWYYIXo2so4HCez0AB1I1JAxtVnRPvSIp7xLMm7+AkDoq12QYDHfxZtDTpfmvJg+Sn0CgYEAxCd+oribtdQW+JUctjsDbSQX5CeRISH5Ith3jveBx2jKIqQVnoVPz6URHOvnlIsqYYLANB8B3JHMWfR2UmkK11x0OcZecB06+oBoCZukvSXF+GqVHzLAQUxaoEBDCCPneskj5w+riMWBiiGDp32rUnkqv0nh7dnH+GfORcJ44L8CgYEA+s5s5EALj1jyU9w4+HVUyVsIrUitFnQg6qw/Td3Kj+8CXImKlS+rlmbQv0m1aOcvtFjQRIjjzZJAf/ausfAME+MayoNODgZsDk5RyDKuSWzMLvZLAa1LD52Uli5Pg8KtpzKVTn4xE1MbjsQcUNhFRAgrNEKNyuzXzdp4uXgGOoMCgYASXwiTQOsEepq0KXMI9jn57Nl3+uSyz7W/t7pq329+N6hG2ktUD3RMJE+X/9gup2IOw+owd377I4SaIDU8vq3PQc944cVShspRT9lunO8u7+y8uW7B/0TWWMpcG+irSIGTlGcSavtL0gOx5jWoaDK1hLemNss8NZtu/nnpOq+LjQKBgDisVozJMBOHPNLYS4NROAR77p0BdCNDwIBmxbM5r+EQWA9DAS6u4+4Lc5YV+MkonG37N6yU5iz4pFyGCHmqzX/c7JvgSc3/g4FED1TWpu1uiUD/ZHmPiAuSRxYchtk2L3k9g+GFwF8mg26iP+fAxv4VfnXDqDi3hhg9CtSWG4ozAoGAOWZXlFKqzGAfcucIe54FVQnweXG9sEuIPAvWvVRs4406ggNmL5eHccXpPHWTgetsr2TYMqPTDVMRmhBzSkyrYgk+b2tme79HPzTWs2Yg/pzjOfTgw7MBX/KlvOW5/J+dvrF3Gx8AHHZ9QQdYqi/MS1NKb2K3IbD0/m5gL5Pwi6A=
|
||||
space:
|
||||
gcTTL: 60
|
||||
syncPeriod: 10
|
||||
gcTTL: 60
|
||||
syncPeriod: 11
|
||||
storage:
|
||||
path: db
|
||||
path: db
|
||||
metric:
|
||||
addr: ""
|
||||
addr: ""
|
||||
log:
|
||||
production: false
|
||||
defaultLevel: ""
|
||||
namedLevels: {}
|
||||
production: false
|
||||
defaultLevel: ""
|
||||
namedLevels: {}
|
||||
|
||||
@ -5,31 +5,33 @@ grpcServer:
|
||||
- 127.0.0.1:4630
|
||||
tls: false
|
||||
account:
|
||||
peerId: 12D3KooWFqDLPcSZi74A1vVpDc8baTkGU6bd21AXcNxH8CFPMqp6
|
||||
peerKey: s6PUCRVry6ymxhyytNQcqSQVd2ECGyWNMIJB0FkyMUFZXbbOYSBb2yYPeQXrA9jdFdZDXyUSxtvzasvpSMpa6w==
|
||||
signingKey: +UF/Do2KPeBLA0joKvnJj43jiH975JcHGjkLIkLR0p7FCFHnR1r/w4xLSa4RTjhEAQ3sDefjktShOJpalXnGvg==
|
||||
encryptionKey: MIIEpQIBAAKCAQEA7NiHF065o9BfTTAWtAItg3KLqvFnRN2WVQMkjMZ/BukIj4UAd196ppexh2tnDvvqW53qVxFtXcW8oFqX9GmDJx61nnN/ce2FhXNB3aPMa7g3AchlVVB9RHyS8Z49HTkn3DVRi8I8EnbpWer35BjnpGOQ257O/kFpD1P5FzvxyTQ2gF50SyiwoDzibyT2VxgQqaDErr9BfFQKBZb8SEBeLACOlzjb2u0mCv7NeoZNfzl2KsqBC8tiCyfNahhauGfU9ZB7PtHMC1pJKTtPhXhNhQI8Rp39dd+Fr3kiTJl3Fe1f4bg4GDI7LbqCARVBbtCjsLEMi1BMzMS63bFPrPL9ewIDAQABAoIBAQCA261j+Oj3Pz8ad7diaGzqvz9N2dkdlpFb30HbdYNW9yI5M1t1lvTb/lwQGVcQx+5RujDs/gZKpnJhq+hQibdZaVPWyW/lRB0I5hRHyf5F/QuwZJ79M7VztXMdEcKeS6JsJHYhW6PjR97dlQEZkJM21RTS6CwmGOBX/o/fHDYICNxIqt4x7x1Hu+A9Qcs3LWvWq0qAkO48jSYBDeIFJ56BdXZacfIv9A7aCGWoVvih2vFIFEwdn+3z69FHmcW8JzVDK+WdkegtOlvuPcFGgDjS8cHq4zuKyEckur9EVm2Wer+GRdY2v7i9ypxiy/Ej4qJCqJLIa5rtWHmB9Dz7IyFBAoGBAPlIMpu9vAhAhJUeO48vsuEDdCn2ztyq2h4GwYcuNmfZUAnFdKRHHAfb48P7nR1uVCEEvnJYF9uUFkot8zljkDCoqc3J30sOd54PT2Jqn2vPhSWpjNJGW4Ku3CmZq/vfCH15z+bcr7whtlEswshE31bykbZlzCOSyW1tgfz2I+ydAoGBAPM6iEV6M74X+M4GoVCwUn9JMFRUX/JONOu4nfNT+1jDeABeXzVS3gzLSMJ/Vk/+1a/g6NFm73bt5PYHR8jG/jrT3xcTBPUiFj038w1MAM5Fsj2jSnIFRYFxwH8q0RfejWvKJRyWKUyTt7m43VRY9P01+YDfgt+VoLs94rV0PNr3AoGAahmWoL8S5xg+1hE2HG2a3zbPHIVV6oo1qA4MFPNQaMcPz/jg+oLhpV6sBOB1MO+ikyMnxBdGoEjZa90+5rA/0NYY3+QKTDHuK7IsgaEMFaEP9MXDkEQt8uNmBbbIgr2dKXrNSF+p1JMsvEQm64KU5Lb92fpd9s4lOZQgfYBuLekCgYEAwNvPg6+S6Y7edJZjQLSepVjmHmfMsDd81M/NRkx4Bvju5PPvcDul3+UsazRGvyVkUJH4aVnCVL3rB33cWIIYwZKP2R72llyR37bGXOu/088FtsQMWn59j1cf+HV91/xajHZ7mMAkPRj/3B6OOLxUfZZXoO0ZO6nMCcvXQGPLgR8CgYEA2W644EHrSwb4qsDsUmIEeKnjSejS8Vej4S5/g1YOyVzfWEr/5rtejw09Fv4U92SeYhp7Xp3C0UnRCduZKrpXIZJVPO8KgWLDtPi9KvHqDPzpQNRHMNrsXLpOLLv+bnnymWXjcyG8fRecU4sggaH4r1C/QyLPr+s/fLDyVUt7bC8=
|
||||
peerId: 12D3KooWFgtCbkf47HhFyQW2cEdAkvaofpokCiaa24Phnz7hpepG
|
||||
peerKey: 4nWcqWOZxv1iXWYuW35eJlF9nxownm38bZjQ27pmFgVXO26vobKLx70TnNTQzZQdoW/dZtxyE9PO37R74vfPQQ==
|
||||
signingKey: ULbtmmyFjkJ6Z+54FI1OJWfu0QdIeoCckwcrBZDLGhw2o2cXTFH5KGxQuAruNTbREz9eAVGmhGoBZtKVi6/6ng==
|
||||
encryptionKey: MIIEowIBAAKCAQEAuGAvw/JQuivjoFIhV9RGkoCjO60jNkQpVPWK52eUtEvKHT2EzufhCRwxhAreajoyzk0PsyJ75FWrrvYs2tkSVHFOSiBkZIsldn5gPg1cnvnJOZ9VKDFp8h85d/4cPQ5tX78043nYTgLje2EmbB83inIr4oiZgxDrtLkozJHleAyWuOLIvlWO1l4Uplf6+uooL/5+WeUCuSGUM0wgXfpn+I2IuRhVDVZiChfp51Q6D6brTdOzNcWq1dw6Vld67u8aCLF1EVZ+xM/rnLLBC7MFvIw44LqHvmvGs/lpE9nMNx5L2KfpbpHSBI0IH3FkLQe2Qz8OMZpIa+aga/DzrBpEdwIDAQABAoIBACudXU898AjKPxN6ujZ7maIoWfTQ9SZuI1TcrNomr4+i6hHWrqb/RUWRbMkuhQSd9czFf/RBMQuHlJBT3bJ7bRGaqAly9iyumdMY/A1RvdpBfm9qGIvkfIpxBngzHVz4H7lpkspI1XlGx6c1CRDEpa/TaDwzUhUmGIvszRDvZlfqQvjPjyYSV5Hdc4ywh5zjuSFlxOD/9gsPRE5v4M4FGrGv8cm859P1u95Wxxo3pWincpzjvWw2LpsUGctyU34MhErxh86vNhP9v+nR4VkdojVKkHQTYnPKUlaKj6F+IUSj8syxuTJb8bs0GBuvcXW9AKp/K0xq/GBC8Cu/XN7Ln7kCgYEAwZoqLnU9OuwkcN5AHYW7XsxmVCEnxOsncrUbIzEKPvy4wELdOCVVrX66zmIjb+1+mhaz+mGMGEpkVMBld3wdDfmGgo0CAPlF4efH1ppMzUm2aZ+HYQR8KMH1XOT9qjbGEnLeWcANQT0vZPpe77PQLNwLJ1zv6EtXMMrEH0s4ijUCgYEA88zCNsBtB07ayFr9r+RCfHx/X9wFkT59t2K+axIfZE02f62WWqJCZYMlZu9XAbYEQ94H43/NAL9wfA8dgnF7mKSL8stJKt0g2iPa3MluF4Gq5Y2XYEVf/EDEhP2jh8p1l+xs18rVzsQQ6b3CEU9ytmBJWvkWnwVXf+ZnsCFECXsCgYBM3YyJzXp1/nOpbFRAZGw0AytNk6xafpK29DjGDB5pS6V+kA2M0SXnMD2y2zv+oGh3fTQP4NLigga7r3eZrOlMNxm0k4+MG2wneQLarYB4sR9/aBsz5bf15qwoKbKc9gpGIN0u/RVGJai/irhOqzGn3eV/x2Jo9CC1+otLcW4NUQKBgQCOOHlnZTN1GuwICwSIkhiy9BF+AyUASLsfuquoXEcRxPUw4DugnZ0sCKhN9vsDlYHBcYmajhgyAnuE83BcgwT906eMOEhzh9G9T0NCnwLpFYxzIvkWgQHwbnv1tNyrv1CAEryf2cSGPNw87qSCYp1hhKPmPP6UP5J+mxMLrSw6dwKBgHHFweDS2tw4TNxJQjhfQOp5t9VQbQffFZAqpXGFTc4vf7XePlxIGoIpOg4ShHCKKHSy0PtsLe7QjLrdbMkyYh8oGqgNe5CYTzFFDeK6Im1DoiqNWT+YUWF/gzVRUSpo0QW+4J1hfChG2URp9KbnditXKsJ5Vh+QayHPoZwN7Kgl
|
||||
apiServer:
|
||||
port: "8090"
|
||||
listenAddrs:
|
||||
- 127.0.0.1:8090
|
||||
tls: false
|
||||
nodes:
|
||||
- peerId: 12D3KooWLn13hDrZ6YRGM517fHf2zS6qhPNRu18inLMpRqn1YGKu
|
||||
- peerId: 12D3KooWPuwdqpDQxWhD2Vh4yskx2T5VMrwdpTZLfACzgsGfQfNy
|
||||
address: 127.0.0.1:4430
|
||||
signingKey: 3mzfKBWtn7mitFEgq8u4eysWOJ6ySbUs49irfHwcuOmi1YMpobz9anoqd4yaT1owZiRPYXqx5k2Z4sNVRE3kXA==
|
||||
encryptionKey: MIIEpQIBAAKCAQEA3U7b4w9JTKE3TLM1WQ5iqdLbvUuozMp/hDEg7S15Gr6wrtLomMSBkfmVQ3Cu+CHdxAFqUFClItYlSFgtZWIFiSiQxCeaN2dmgczd9T4TlRAw6y6uJXtT9r7FIgizPP4B0/tnzPI6yYgpdwzCV2nRSjw3mMr5Nav3QYs18kYrJ1/Np2Wob5HOoRTUD++pPrToevTb7GNL/irrC8wXSE7oU6S7ix6Nh9vzEHg/V5FONBF/wWD/ri7Gy0j0qgUQ+gjxLWKr8xPDnRAve13zzo+54lGCyVvlm/rwCY9Jx378V1IuRx+S8F/GFuVozHD4XVaoSTtpCWPBQNSKDXgaIIKDowIDAQABAoIBACpMXj6ht1LMJXOldPbWhwkKYjFl+pdZxNGRSkfKvzDbbY2chhRcyp8J4vuG2ApY/rftxVIgd8+Wun1/TP3ppEE43aKAJzubqb35WBr9iGSfOZpZy7MiRUQN5kPBAfEQY20OyiIj0hSez74PVD283eGgbMfpU4Rsn8+JOgBaZPkbPViJLJY8PyHU6vwWw60dye1iJTz9yuBtoEqY0XKxnLaVXTQaWx0Te+VYU8twxDgXFWRaXtHuk7xnxOkCZDLrzIvuOYa5lsLoT8K62LDeXbyHBPhbdW0j4ZYzAOTsaUWpjuJzef9aj3JJdfyADiqb5iu6HHksvKzkZEau34zjilECgYEA/c8ZJm62uJMHNssTJYiLRw89l5hYwIZ/1TXdFRF8+xrTin5opYjpscSTO5bY2IYqLx2xuPiJCY1eGGB9L/RtkaVh51ySzq0d+4zpPIRKFcOOgdxHwlgoCgIhQECyfJZNMFGBUIlPXZ/phvXOXRvWFzDPhqThenVG2QzF+wLP0AUCgYEA3zfviQFJ1FOKJMozYO3tUZFmsIrAcO9hfuE7uuWz0Fw2m1XiwxjuOr1RbsSsh/lKke2h4tiGrlfiFhwCpIp91NkVTFrtFOQxbDxkYLkFiWkZDkOaK9YhKMa2cgEm3p+RGawokjbm51LKf+cbYN9xGaAe3y2WzIE4kNpfWE4SXYcCgYEAoagcrrvpqZoMCDxED63ud+4fHsUsEkQYe6Z5EAg5gH5PqnBlGrofjthTpqqnpxGdILFbFyNFtU3TVtduJPMcLp4Vw5TU9MqSxDu1+pOP1FjgFZpGImSf6+/7Wb9bb7sToujm4nLymAFYblt1exxVuiOeqnWuH58+5tQZ7YyW7DkCgYEAl7WuqZEkmpiEpWh/7vsGdo+6GXbUQG2R9+gg7m+7/HsP6hc/XZYOJAIT3JLzKB84nWHCyyiasNeuI5S5/xbZWtaH8TNDOxW0uXl6R3q41qGFk/pCSFTqiIo16dn6jwgoWCh4EpgZ61KLqs5p/zcd6Wq4ULrtaOTSizC/6IZ3WPUCgYEA6xCJy3+ICCgr8/c7hfd2Ylb3aOsXIffdgALhXjDcrNUCqgB4R+S3WReAwrABemQGl4tySQE/1f3Ru7SzMMciFogGyJ/YSXqSi6Y8oDD7MqlKPiWlN6WY1nSRMlLbkUOqpA5JaDM0kcmXjZpBBQr277GOnh9uKN8zUy5xoptctxI=
|
||||
signingKey: yOEpD2+cPldXc2urGuU+szunm7fddRa8xew2uVjaxifRcVzNKhSERpOefjrXaky7PcKmSmTsH/5ZFtcrh1uzqg==
|
||||
encryptionKey: MIIEpAIBAAKCAQEAxnE9Htwto+2fVmonkG9/DxNre33n7kjfrZU73JcHmpKhPlRFirig5T8rs2MaTq1R72/8nGBJuSxsz1PnexI3die39pY1OFYfZCZ59LbT7uH/xHcvkVrK2n50Q41KbbGT9BEzyW+XPkKPDpTq3/igYP+yUQgoWLfMwxCCLKXDe6qUC0fuIxR80fvj3XvorB5dnAiQ01JkH4PtCV1OWT6ZpLGhzcYxsxTHozd6LdMOC7wgGhW26dOSa/vZ1t5avbewFVIz0qfqBncunb7tjO4xa3xVYaA5jBbixDQUYFjVzW7cksrrN4CFNBDBGJ8PLS80MuMg0OG0O+/Qi1mbGb2mUQIDAQABAoIBACODAD0VidVcILeGJ65hRYudHg7raSXrRJv7qMrA/EtdEh3lVsyMXb6on1lq0rphqdf/YmVZldfda1tu2G3dxK8QTIuENeHvB48Uk56HWUXWi77M1WZdqQ+QsZ2lGzymGqQCsBHMNnSd1Jv3alDKXWj+WRrHKvE1cx81RRZYU7M9cpurnF5YNjO7L+7sMxUA9uAQGbe3kDVzrygraicLYQpxSNHytName0A+k3ug0qer4I6PmZhhJykkz6MD3dz/n625HSS+X+TuTm52T2b87tL27xXmSnUK7eYWjZ1vQlP1fWmqnac6u5LApUZaRi0tTjtefSjRW4jr1q20RqOp1kECgYEA7Onh3zM9ejATsjW6WISGKiBPci0D7DUbIuGuJrdQRadlkZzmeQ/VOYAuxIQD4GnQDRhM1FyxsqiAWkJOyCLFiMmsgIEyW9/eRhF8NlCVU+DA/fxy9EagfBbVsgiSBwOex24hPXIVYlaHkLAloNoD4bpw0pQZSDWXr+xvMFNwoGsCgYEA1m3sWA/e8ZuXForaUOoJzBU9nwC79bXv2UNktsVvBlQ1o9pbjoYDcVoAPwuBVUL1UwqDNMzPdhDBKBjZmCyjS6zlYD5ZKjF2m8iTyc4QcaBCdM0iyQpSXTmrfMx+hK1aWwL1p8ssNcednp5ExSAaTyNNGVdbtddiQ6/KMPmhUzMCgYEAwDjLsUNr4BXeBTweo+9yw/9PNn5brm0wRU8C9BrMIJe/izPYs+UqxerBB2Vtl8mCqv1KaQuEika5TYJ7VVsRFvk641DwQScUu5k4RQGBB3tWWz1XL+eWEticLkVR5isDyyAKDEbiHtXCTJz/CtGZUK7rF5BeKv6AwpZ9aKJqwV0CgYEAqXDlQNURu+PR6TtBtoypvz3NmraO0GO7KvipPhAXYm3qkRa8IIxfbhPLfAYQZhpqFvuIoJFzIn2s1I2GbExhoSv3eSzrcn7xlbpSpjYSImeb/AYZhbmFSiuHCi/hjeAaNS7KhZPz1G9vaubvusFaaMyhYPP6AWA4QvpHEJpB06cCgYBqR6/7d2hQiq4MJUrBEzLwG4ijnPeq+UVLQjE598hVIj+8UhRZRRcNWVEJxfcIL1v6Bpo8XISDNVRb30T9bPGVnXvC1jutTUbXKUB1/8iXuyH3IVieobch+bGd4v7ehH/lI7vzB6hjJpFzHopfFUn4wacSQdcFi3tRAwUB/L0S/w==
|
||||
types : ["tree", "file"]
|
||||
- peerId: 12D3KooWLtuKtCPBYrFJV1NdejiCr2s614ppe9rmUXnkTHtAUD5U
|
||||
- peerId: 12D3KooWBgHmDqtXH9SrZfAmwCFsD8LZhTD5dg5wkhdbqFoS8GBN
|
||||
address: 127.0.0.1:4431
|
||||
signingKey: 07JMoW5cQUtGO9nNIGQo9e99b7Wf/4YvTtNEA0lt4gCkmhwB1EB9ay+kitxVJJgmdyGLxbUUlGqwXsAj0zlHWw==
|
||||
encryptionKey: MIIEpAIBAAKCAQEA7cA6J/icl8wseeXkt8oJr5AeYadUAG5EdCOdHj4S/Z7ivff4MOIKAeQITpq+rqhmXxOePYXSpQXE20Y9PW9tuw4gzOuq1ylSG/MWMcLDH1eIxg66rnmUqUbdiW4GGJjVjc9jvN0Up+MfSrUF6fM0jWTFoXVJQIeQQGERCIYjFzjfBl1xYvPghdxNgei/K5ZGYRggT28143XdIH4KTXGtp51hAKoyY9eCqYMtm9wvjxazhPVxO2CsYaqMxBLshY3jfHNqJnx8u6+h4Bl4uUcdbLNUgMcEgk7ehbQp2K0CqNoKXxbCTI6V57UVcJHDIaO5B6FyR6BguzHHNPJ4yd3q9wIDAQABAoIBAQCm2Mf3VRlPzhFIWnVwJXE2q8Umcu8Yfkm712Jj3twk8GPfPS4H4Bl1yjmqMB6xI6zz/CiItGlnNe04lMpVWuV+6CNMq/ZwmKbuxmFE+pFEZYGuvJd16gzR3tGJqJTOnjMAGhK8b8oXJ+TF4NQNooe20ol/DXgiuQAargPuH3RwzjYmF3N8VI4KUc3LaG4TwVXn4LwPOxrQSnfwJlZwLml1HAKOV0qcG0mXX6ZXOpoVhEoRPdQyUHc8ZW+53Agbtind7bYh5TsMVDFUrcgNwnwTOsWjil049la1IJO2uMRluacKlrtyzEp6zqrW8ZJO7mYAO69x4WyGqf2ZgIdA6djBAoGBAPqRHWAIgPa80eXbwCYkRtUG/ONBsQGi7+wm6nyhkXvNXJeokgH2DCgLH2+fW2scfOJuZc9r5WftEjOBvNfr2LDcwdyTSTh21WYcPSZx9HDf2d5/SWTcjNcyU0b5qfWIUKi/Zm9UY7r3X7yMA5dUD/cvu1PBJ5NWFrK1Gm2ph44dAoGBAPLn+LkHweU0fbxQq/76T5yVVpMKUaE9xwrJlUxEDPAQGnLPbFg4JeUt/YPhsOV85W4c4oQE+uFZrF0uf+1fEnS6MOJ+sq668upzC2hBp1B5138wM7615v1rvXVVH6qXfFop67FdBzPHt1NAN43mEIBZHTQ5hSVXFlYSZp9mxuEjAoGBAKCzUVO2IIAeub/iIGpV+dfGk4ptJ0kVZyreCqXEObpdC3V496uqUkGcYJ0GZ2ta6f2PMFzHpmnw8it2mdchu+gyrWL6U4uTK2pB0jZF/7Ak4WaB3GCD0xBxhleO6CJBOvn/R4M/bHcNEKmsYuE7WMIAKvScfPVR0VzsKfcLM5VBAoGAVvWg32zdh1bBZLdku8WU1rPH6KAbFSRuq3f7UPBTyWWaclu7p+GB/4f1aE9V6vJJmKASn7zArAhUYo+REMOmcc9uTMea5F7dM/23qb1HTtIvycLR44ZviW4Wx3iP+5x70jOLw1VQjMME6HLm8I/afHhqshWdiv6ganPv9UTwEg0CgYBSDi2dqg8F7ij5CN+LMDLSn3b8GCw+7efGIt7imm/O2V/FlHD40IA6qGg6DXNQrnoZQt94nMb1cZEvm1dxi6rmQNrhCyoMogAaPqgFhZGq1OjmhVZiXFUWy4WAcjdzFc9wZd3/XtaofRKHLK+ngTFhhVApKypLk3Rg9bCAAjzyVg==
|
||||
signingKey: l6LFiKqr4ZHgcPbL+DR7KwMbzImufQPFgpoHOJ/nvfUbpb76DCADHuT1I4gIs+XByglnY1KV8jbMfW64XRW5XQ==
|
||||
encryptionKey: MIIEowIBAAKCAQEA4ltcn1AH048bMXcKOOW7/E0TZYPxL3OtcHXWHSAZjeeTA/rc45G2eaNgyY7Ji+feLtZERbXNWGFBdNp31NHDYZAYwbZmjEqTEgV4yVx7BQP3VBEzglTJaNLTf+XIJnVAEkoHS6ogjC0oXTM6paHu64EitoOCzF9zqL023swjE3HU0dm2xwsUdGnKeO5nPMso/6e3VMavkKnFmvB965ECCBujtediP4lVdIABNVtoMHCoeI5Sn+m7TKqJSyDOIEMhHT3orYUNZWVeAHE1YTM2cI5tSnDZP80CHZ674Z/bKL7Jaznmq87mVt1h9Use2EkxR07/dJuTGvFOos4jHoiR9QIDAQABAoIBAHAr8EluooI/j61CnYk2p6LPG0aaTQJD4/YwHuwOBTviP2OghKgthGzg/szDerNfMyaoveqBvoIGqCZdQTbwwE7v1qTgXA83wYwTtBitQLVqkr1RTOJQXAMbPv5Jg5czUY3+q4DejQSKOE9/XJfKGJkSRH6Hy2C2CJ3dLnzYUqWGO3t70RLT1/sC6p6w3lXdy3dKZGkoR2wva+HXQxVrP8X5HOResXgNZwgMHt9KF1QHVCcySKYiEAefEKTSdKD2fOd4FxLgp3zWpvH3jrX0zd/DqzTlFD5Ns6Ayp2sIfHVp3sn99DZZM6DauMepQKtoSCnXZ+qKhekAwNVJnsVQkSECgYEA4spY9araeFUSl4uXCUQOpCkSshYOPRYN6sBbHsx8tV2eQtCT+5SuNYmzur3c5bkiraGEab8rZfGdDL6fLxQyaqbOmN31Db5kNh/2X+sRnxkak8lsROUWQZRF9doH73FDv6ZlI3V/JicZlOUCfN5BYT+x74R4/c1YXfyuD1J9gr0CgYEA/4K4SDwZUY4bOVCmKQz0OM+RW4PAAH6LHKenTAZNTeDNFFxc2nqnzRGMEKZTDGy0kbT5mBhBHFgShXcAiKxc5/MGkpt8Jcq6Fr5KGU9aZtYKji6mwMTsUndPNQydh3vOt5pOmcuMM6ovanNTvI8k6Qo53OY1IpO5CfOROu0hm5kCgYBnWsYd92YnDsYxUEldzKlLgPhnNov4pNNk15LvP0vaL7cPRhUaw1B9T6scAKjp/GxkasZ4lsnFZM4o37qV7wNm/WwL2KN0Rv9Od1SFtBBMzFkDXvk7kJeK/XLAr0OMiLbSYZeYCFUQ4yLSa2et1nA/TJLf0CR/rhSGiMAedX6DlQKBgAx1137OT33GrFUzNacy1oYeuTv5RNfBVA9lrabrd8GggN/JUU3mRWCexnHZaptkgbnJVZKxPBuhv+V6VDBWF4HIPD3SD0/YfxK03PA3CnWRYppkdAValRvAbcBsiRIeW4pgoAyn/IJYfk92qFK9uFMVCJVZNKYnBhMSKbbx8X2hAoGBAKwvzyAImbNB+493q1R/lSayxzG76bRJ/EseiTqwIec9c4C+Bd/sVXR+Re+xZb0FI/va1bz5CrduTzLSKBmf/+0lzl0MJvWY2+SXfGYdbl4+TTyqgDDfwqW0Tj8pDimye2BneyTmXko1rF+2Sxen7kMXnJLwpqjwZ6TZJuoqeK8q
|
||||
types : ["tree", "file"]
|
||||
- peerId: 12D3KooWDCypXSyN6ppuMZGxVnBd1ZQCMV4y7Bn187S4duYmf8rA
|
||||
- peerId: 12D3KooWASsipDzkridiMBmE7VSqp8yZvGWPY1VqySgMSZk6tsiL
|
||||
address: 127.0.0.1:4432
|
||||
signingKey: SGyNE0dFaQgtgNuzdcO7LB+TEz9VHAOtlQLk6WWkrkQyXiZV3casg8Q2/4PO1Oylc8Fu72RU001Hclj5JCbiLw==
|
||||
encryptionKey: MIIEpAIBAAKCAQEA0k3mw4FyexRkLgLjHzYs4Ppeyv6r9ZrP00imNf15JTuM8ajMx5oJX7JQTm8KOLRJjUdZZAd5Gtp0ezfYAQK1ZjEWwCmfp8j8FBgJIDSLpjxl88SXMLgATXYfhklnQvKlQjs/X3Ka4zdTrav2tMH9IAo6TSNZhlPQNsUory1SGHs+KqHv4p0sG8oWuKYhfBj8rWHQdUVptkIBKgojFDeJJD04Tbf9kUakbK/8KuXB6zF5H4WN3p4rMMwkClyTGeYO4LDg5TzVn8NnUi3/b/vO/3us1G/TMoRe/6umUfpQxrwo+7S2T6A4YwetWRp6xALLhp+HfAWnn0lA/D8/w1WpKwIDAQABAoIBAQC5cdQxRa5rddm48PbSCPWeFWkNW3DLDI6CYyedqDvxZwer+QtKXzww1I4X+7ZptiC9odLjb+uMkGHyXZXtnjPTPyounQWZ8JLILUGu0mbqWYwVXp9raHVr2OOHiKaz1D+BnbkOM4L9JUZ2eJL9ZaoNXLd4WdmRp8qM4WI0xqQDzOANx2HhyL/+dJmQeIUND+pdeH+Z+fYowU3ho32txNvBnMXQhF1T5K9i1VO5W49RAjIRbENsT+paPGKbNubDHRt1j36ktK4eC4HSdgv8tccdsGyrEiIbAt1XsTZfM8ie4D3A8RhSxiTC6Fkgv6vIm+iFTLzBFZKesOBcd8sfKeyBAoGBAOts5PQQJhldPDzlbnqzxMOR98WHbkVZjCqWSkNA34vqyFuPcRuX0rHK/qpg23ilbUP0fGMDTGgFzTt51FZLL16SXyRfjNhzjdmryryeddQwbp92ta2GEgnU6t1FyCuSCtcLDKJd/D9A9dC5UI6z+ES4TOnbR3nakXK9t4cUOFthAoGBAOSu+wL+SEA5erR+m3LpOsELK68CCJQPxn3VpoVfJZawgF+fEoXVMLTERxJput1+ADomIEdNc9ex86TjKx9gJ4piNHscRPFeT/AgESOIGHLOc1gk2DPqNj6wBIarUJQ9t4KcHScboh1dTPJeqqv2NSwIiLQoqFUIhfKZLnrW3zwLAoGBAJh0hC+o5YM3ZXLqAIllMN6VACbidP5j5ukNOjojIKCzAdyJH24G+2I3WoNrBbUzK3b+NC7KTAhw+V6ynlbjiWFs2D/twH/LFOkI3tkWpKcsVfbeIPimAbhsMUvpjJ7qjCqF9UCQLHGp14W6+/ftg7C8yNIINlkquVXclaTb60MBAoGAPqmL8ogG+EJH00mWAujRxq/u6meePiQMedKfbJBj1mTK6GjIRI/kZsQZzXvXTnYGTejAk4kvov0KDDaLTG+mpg6+3rUiVxlGwj+nMptKR7s2dAK0k5UsBAVrWBN9YwF+VXW9r0etJmq4ePljvvcaHtS/0M4LQjGxsoYy7EoQpX0CgYAhnf0McB7F1MxSjB0soMNv/v5utVzVihS3re2yKNdkI/YUEMB+yU3Q4gh+OljjBM6Y5To3BsQBAx4l2CysMKFHjIE/5AtdbvIS+chZZqB3vcZXSayvX8P1Z1uFdw/saiO2cRDJmR+TxaOPa2C9SzDoNTACthwLErHfzvEvVroKmw==
|
||||
types : ["tree", "file"]
|
||||
space:
|
||||
gcTTL: 60
|
||||
syncPeriod: 10
|
||||
syncPeriod: 11
|
||||
storage:
|
||||
path: db
|
||||
metric:
|
||||
|
||||
@ -5,31 +5,33 @@ grpcServer:
|
||||
- 127.0.0.1:4631
|
||||
tls: false
|
||||
account:
|
||||
peerId: 12D3KooWA7AHfBCyNPQaMnffj8S7Z9kZzKG6X1apLgtyP1CgpXiJ
|
||||
peerKey: +KIj+xVyg241tP2So4JmRNGFFIgtzK1PWUo8El0e5x0ETXCrCksPkLsA8s6Xww0DJy92dyISwoBoMQ7XhLbdOw==
|
||||
signingKey: +UF/Do2KPeBLA0joKvnJj43jiH975JcHGjkLIkLR0p7FCFHnR1r/w4xLSa4RTjhEAQ3sDefjktShOJpalXnGvg==
|
||||
encryptionKey: MIIEpQIBAAKCAQEA7NiHF065o9BfTTAWtAItg3KLqvFnRN2WVQMkjMZ/BukIj4UAd196ppexh2tnDvvqW53qVxFtXcW8oFqX9GmDJx61nnN/ce2FhXNB3aPMa7g3AchlVVB9RHyS8Z49HTkn3DVRi8I8EnbpWer35BjnpGOQ257O/kFpD1P5FzvxyTQ2gF50SyiwoDzibyT2VxgQqaDErr9BfFQKBZb8SEBeLACOlzjb2u0mCv7NeoZNfzl2KsqBC8tiCyfNahhauGfU9ZB7PtHMC1pJKTtPhXhNhQI8Rp39dd+Fr3kiTJl3Fe1f4bg4GDI7LbqCARVBbtCjsLEMi1BMzMS63bFPrPL9ewIDAQABAoIBAQCA261j+Oj3Pz8ad7diaGzqvz9N2dkdlpFb30HbdYNW9yI5M1t1lvTb/lwQGVcQx+5RujDs/gZKpnJhq+hQibdZaVPWyW/lRB0I5hRHyf5F/QuwZJ79M7VztXMdEcKeS6JsJHYhW6PjR97dlQEZkJM21RTS6CwmGOBX/o/fHDYICNxIqt4x7x1Hu+A9Qcs3LWvWq0qAkO48jSYBDeIFJ56BdXZacfIv9A7aCGWoVvih2vFIFEwdn+3z69FHmcW8JzVDK+WdkegtOlvuPcFGgDjS8cHq4zuKyEckur9EVm2Wer+GRdY2v7i9ypxiy/Ej4qJCqJLIa5rtWHmB9Dz7IyFBAoGBAPlIMpu9vAhAhJUeO48vsuEDdCn2ztyq2h4GwYcuNmfZUAnFdKRHHAfb48P7nR1uVCEEvnJYF9uUFkot8zljkDCoqc3J30sOd54PT2Jqn2vPhSWpjNJGW4Ku3CmZq/vfCH15z+bcr7whtlEswshE31bykbZlzCOSyW1tgfz2I+ydAoGBAPM6iEV6M74X+M4GoVCwUn9JMFRUX/JONOu4nfNT+1jDeABeXzVS3gzLSMJ/Vk/+1a/g6NFm73bt5PYHR8jG/jrT3xcTBPUiFj038w1MAM5Fsj2jSnIFRYFxwH8q0RfejWvKJRyWKUyTt7m43VRY9P01+YDfgt+VoLs94rV0PNr3AoGAahmWoL8S5xg+1hE2HG2a3zbPHIVV6oo1qA4MFPNQaMcPz/jg+oLhpV6sBOB1MO+ikyMnxBdGoEjZa90+5rA/0NYY3+QKTDHuK7IsgaEMFaEP9MXDkEQt8uNmBbbIgr2dKXrNSF+p1JMsvEQm64KU5Lb92fpd9s4lOZQgfYBuLekCgYEAwNvPg6+S6Y7edJZjQLSepVjmHmfMsDd81M/NRkx4Bvju5PPvcDul3+UsazRGvyVkUJH4aVnCVL3rB33cWIIYwZKP2R72llyR37bGXOu/088FtsQMWn59j1cf+HV91/xajHZ7mMAkPRj/3B6OOLxUfZZXoO0ZO6nMCcvXQGPLgR8CgYEA2W644EHrSwb4qsDsUmIEeKnjSejS8Vej4S5/g1YOyVzfWEr/5rtejw09Fv4U92SeYhp7Xp3C0UnRCduZKrpXIZJVPO8KgWLDtPi9KvHqDPzpQNRHMNrsXLpOLLv+bnnymWXjcyG8fRecU4sggaH4r1C/QyLPr+s/fLDyVUt7bC8=
|
||||
peerId: 12D3KooWQuD9ShSHt4nb7bXefg8ndpDXCDzwrm9pjHsnDY2khbRi
|
||||
peerKey: fp/Q18I7TNM4kgKXbbOBQJbJonlrQqAlZwTF6Rx/sKXgHQGZ1dBcS45oXGbTb15Bi2r7sOX+d6HJaaQE29MisQ==
|
||||
signingKey: ULbtmmyFjkJ6Z+54FI1OJWfu0QdIeoCckwcrBZDLGhw2o2cXTFH5KGxQuAruNTbREz9eAVGmhGoBZtKVi6/6ng==
|
||||
encryptionKey: MIIEowIBAAKCAQEAuGAvw/JQuivjoFIhV9RGkoCjO60jNkQpVPWK52eUtEvKHT2EzufhCRwxhAreajoyzk0PsyJ75FWrrvYs2tkSVHFOSiBkZIsldn5gPg1cnvnJOZ9VKDFp8h85d/4cPQ5tX78043nYTgLje2EmbB83inIr4oiZgxDrtLkozJHleAyWuOLIvlWO1l4Uplf6+uooL/5+WeUCuSGUM0wgXfpn+I2IuRhVDVZiChfp51Q6D6brTdOzNcWq1dw6Vld67u8aCLF1EVZ+xM/rnLLBC7MFvIw44LqHvmvGs/lpE9nMNx5L2KfpbpHSBI0IH3FkLQe2Qz8OMZpIa+aga/DzrBpEdwIDAQABAoIBACudXU898AjKPxN6ujZ7maIoWfTQ9SZuI1TcrNomr4+i6hHWrqb/RUWRbMkuhQSd9czFf/RBMQuHlJBT3bJ7bRGaqAly9iyumdMY/A1RvdpBfm9qGIvkfIpxBngzHVz4H7lpkspI1XlGx6c1CRDEpa/TaDwzUhUmGIvszRDvZlfqQvjPjyYSV5Hdc4ywh5zjuSFlxOD/9gsPRE5v4M4FGrGv8cm859P1u95Wxxo3pWincpzjvWw2LpsUGctyU34MhErxh86vNhP9v+nR4VkdojVKkHQTYnPKUlaKj6F+IUSj8syxuTJb8bs0GBuvcXW9AKp/K0xq/GBC8Cu/XN7Ln7kCgYEAwZoqLnU9OuwkcN5AHYW7XsxmVCEnxOsncrUbIzEKPvy4wELdOCVVrX66zmIjb+1+mhaz+mGMGEpkVMBld3wdDfmGgo0CAPlF4efH1ppMzUm2aZ+HYQR8KMH1XOT9qjbGEnLeWcANQT0vZPpe77PQLNwLJ1zv6EtXMMrEH0s4ijUCgYEA88zCNsBtB07ayFr9r+RCfHx/X9wFkT59t2K+axIfZE02f62WWqJCZYMlZu9XAbYEQ94H43/NAL9wfA8dgnF7mKSL8stJKt0g2iPa3MluF4Gq5Y2XYEVf/EDEhP2jh8p1l+xs18rVzsQQ6b3CEU9ytmBJWvkWnwVXf+ZnsCFECXsCgYBM3YyJzXp1/nOpbFRAZGw0AytNk6xafpK29DjGDB5pS6V+kA2M0SXnMD2y2zv+oGh3fTQP4NLigga7r3eZrOlMNxm0k4+MG2wneQLarYB4sR9/aBsz5bf15qwoKbKc9gpGIN0u/RVGJai/irhOqzGn3eV/x2Jo9CC1+otLcW4NUQKBgQCOOHlnZTN1GuwICwSIkhiy9BF+AyUASLsfuquoXEcRxPUw4DugnZ0sCKhN9vsDlYHBcYmajhgyAnuE83BcgwT906eMOEhzh9G9T0NCnwLpFYxzIvkWgQHwbnv1tNyrv1CAEryf2cSGPNw87qSCYp1hhKPmPP6UP5J+mxMLrSw6dwKBgHHFweDS2tw4TNxJQjhfQOp5t9VQbQffFZAqpXGFTc4vf7XePlxIGoIpOg4ShHCKKHSy0PtsLe7QjLrdbMkyYh8oGqgNe5CYTzFFDeK6Im1DoiqNWT+YUWF/gzVRUSpo0QW+4J1hfChG2URp9KbnditXKsJ5Vh+QayHPoZwN7Kgl
|
||||
apiServer:
|
||||
port: "8091"
|
||||
listenAddrs:
|
||||
- 127.0.0.1:8091
|
||||
tls: false
|
||||
nodes:
|
||||
- peerId: 12D3KooWLn13hDrZ6YRGM517fHf2zS6qhPNRu18inLMpRqn1YGKu
|
||||
- peerId: 12D3KooWPuwdqpDQxWhD2Vh4yskx2T5VMrwdpTZLfACzgsGfQfNy
|
||||
address: 127.0.0.1:4430
|
||||
signingKey: 3mzfKBWtn7mitFEgq8u4eysWOJ6ySbUs49irfHwcuOmi1YMpobz9anoqd4yaT1owZiRPYXqx5k2Z4sNVRE3kXA==
|
||||
encryptionKey: MIIEpQIBAAKCAQEA3U7b4w9JTKE3TLM1WQ5iqdLbvUuozMp/hDEg7S15Gr6wrtLomMSBkfmVQ3Cu+CHdxAFqUFClItYlSFgtZWIFiSiQxCeaN2dmgczd9T4TlRAw6y6uJXtT9r7FIgizPP4B0/tnzPI6yYgpdwzCV2nRSjw3mMr5Nav3QYs18kYrJ1/Np2Wob5HOoRTUD++pPrToevTb7GNL/irrC8wXSE7oU6S7ix6Nh9vzEHg/V5FONBF/wWD/ri7Gy0j0qgUQ+gjxLWKr8xPDnRAve13zzo+54lGCyVvlm/rwCY9Jx378V1IuRx+S8F/GFuVozHD4XVaoSTtpCWPBQNSKDXgaIIKDowIDAQABAoIBACpMXj6ht1LMJXOldPbWhwkKYjFl+pdZxNGRSkfKvzDbbY2chhRcyp8J4vuG2ApY/rftxVIgd8+Wun1/TP3ppEE43aKAJzubqb35WBr9iGSfOZpZy7MiRUQN5kPBAfEQY20OyiIj0hSez74PVD283eGgbMfpU4Rsn8+JOgBaZPkbPViJLJY8PyHU6vwWw60dye1iJTz9yuBtoEqY0XKxnLaVXTQaWx0Te+VYU8twxDgXFWRaXtHuk7xnxOkCZDLrzIvuOYa5lsLoT8K62LDeXbyHBPhbdW0j4ZYzAOTsaUWpjuJzef9aj3JJdfyADiqb5iu6HHksvKzkZEau34zjilECgYEA/c8ZJm62uJMHNssTJYiLRw89l5hYwIZ/1TXdFRF8+xrTin5opYjpscSTO5bY2IYqLx2xuPiJCY1eGGB9L/RtkaVh51ySzq0d+4zpPIRKFcOOgdxHwlgoCgIhQECyfJZNMFGBUIlPXZ/phvXOXRvWFzDPhqThenVG2QzF+wLP0AUCgYEA3zfviQFJ1FOKJMozYO3tUZFmsIrAcO9hfuE7uuWz0Fw2m1XiwxjuOr1RbsSsh/lKke2h4tiGrlfiFhwCpIp91NkVTFrtFOQxbDxkYLkFiWkZDkOaK9YhKMa2cgEm3p+RGawokjbm51LKf+cbYN9xGaAe3y2WzIE4kNpfWE4SXYcCgYEAoagcrrvpqZoMCDxED63ud+4fHsUsEkQYe6Z5EAg5gH5PqnBlGrofjthTpqqnpxGdILFbFyNFtU3TVtduJPMcLp4Vw5TU9MqSxDu1+pOP1FjgFZpGImSf6+/7Wb9bb7sToujm4nLymAFYblt1exxVuiOeqnWuH58+5tQZ7YyW7DkCgYEAl7WuqZEkmpiEpWh/7vsGdo+6GXbUQG2R9+gg7m+7/HsP6hc/XZYOJAIT3JLzKB84nWHCyyiasNeuI5S5/xbZWtaH8TNDOxW0uXl6R3q41qGFk/pCSFTqiIo16dn6jwgoWCh4EpgZ61KLqs5p/zcd6Wq4ULrtaOTSizC/6IZ3WPUCgYEA6xCJy3+ICCgr8/c7hfd2Ylb3aOsXIffdgALhXjDcrNUCqgB4R+S3WReAwrABemQGl4tySQE/1f3Ru7SzMMciFogGyJ/YSXqSi6Y8oDD7MqlKPiWlN6WY1nSRMlLbkUOqpA5JaDM0kcmXjZpBBQr277GOnh9uKN8zUy5xoptctxI=
|
||||
signingKey: yOEpD2+cPldXc2urGuU+szunm7fddRa8xew2uVjaxifRcVzNKhSERpOefjrXaky7PcKmSmTsH/5ZFtcrh1uzqg==
|
||||
encryptionKey: MIIEpAIBAAKCAQEAxnE9Htwto+2fVmonkG9/DxNre33n7kjfrZU73JcHmpKhPlRFirig5T8rs2MaTq1R72/8nGBJuSxsz1PnexI3die39pY1OFYfZCZ59LbT7uH/xHcvkVrK2n50Q41KbbGT9BEzyW+XPkKPDpTq3/igYP+yUQgoWLfMwxCCLKXDe6qUC0fuIxR80fvj3XvorB5dnAiQ01JkH4PtCV1OWT6ZpLGhzcYxsxTHozd6LdMOC7wgGhW26dOSa/vZ1t5avbewFVIz0qfqBncunb7tjO4xa3xVYaA5jBbixDQUYFjVzW7cksrrN4CFNBDBGJ8PLS80MuMg0OG0O+/Qi1mbGb2mUQIDAQABAoIBACODAD0VidVcILeGJ65hRYudHg7raSXrRJv7qMrA/EtdEh3lVsyMXb6on1lq0rphqdf/YmVZldfda1tu2G3dxK8QTIuENeHvB48Uk56HWUXWi77M1WZdqQ+QsZ2lGzymGqQCsBHMNnSd1Jv3alDKXWj+WRrHKvE1cx81RRZYU7M9cpurnF5YNjO7L+7sMxUA9uAQGbe3kDVzrygraicLYQpxSNHytName0A+k3ug0qer4I6PmZhhJykkz6MD3dz/n625HSS+X+TuTm52T2b87tL27xXmSnUK7eYWjZ1vQlP1fWmqnac6u5LApUZaRi0tTjtefSjRW4jr1q20RqOp1kECgYEA7Onh3zM9ejATsjW6WISGKiBPci0D7DUbIuGuJrdQRadlkZzmeQ/VOYAuxIQD4GnQDRhM1FyxsqiAWkJOyCLFiMmsgIEyW9/eRhF8NlCVU+DA/fxy9EagfBbVsgiSBwOex24hPXIVYlaHkLAloNoD4bpw0pQZSDWXr+xvMFNwoGsCgYEA1m3sWA/e8ZuXForaUOoJzBU9nwC79bXv2UNktsVvBlQ1o9pbjoYDcVoAPwuBVUL1UwqDNMzPdhDBKBjZmCyjS6zlYD5ZKjF2m8iTyc4QcaBCdM0iyQpSXTmrfMx+hK1aWwL1p8ssNcednp5ExSAaTyNNGVdbtddiQ6/KMPmhUzMCgYEAwDjLsUNr4BXeBTweo+9yw/9PNn5brm0wRU8C9BrMIJe/izPYs+UqxerBB2Vtl8mCqv1KaQuEika5TYJ7VVsRFvk641DwQScUu5k4RQGBB3tWWz1XL+eWEticLkVR5isDyyAKDEbiHtXCTJz/CtGZUK7rF5BeKv6AwpZ9aKJqwV0CgYEAqXDlQNURu+PR6TtBtoypvz3NmraO0GO7KvipPhAXYm3qkRa8IIxfbhPLfAYQZhpqFvuIoJFzIn2s1I2GbExhoSv3eSzrcn7xlbpSpjYSImeb/AYZhbmFSiuHCi/hjeAaNS7KhZPz1G9vaubvusFaaMyhYPP6AWA4QvpHEJpB06cCgYBqR6/7d2hQiq4MJUrBEzLwG4ijnPeq+UVLQjE598hVIj+8UhRZRRcNWVEJxfcIL1v6Bpo8XISDNVRb30T9bPGVnXvC1jutTUbXKUB1/8iXuyH3IVieobch+bGd4v7ehH/lI7vzB6hjJpFzHopfFUn4wacSQdcFi3tRAwUB/L0S/w==
|
||||
types : ["tree", "file"]
|
||||
- peerId: 12D3KooWLtuKtCPBYrFJV1NdejiCr2s614ppe9rmUXnkTHtAUD5U
|
||||
- peerId: 12D3KooWBgHmDqtXH9SrZfAmwCFsD8LZhTD5dg5wkhdbqFoS8GBN
|
||||
address: 127.0.0.1:4431
|
||||
signingKey: 07JMoW5cQUtGO9nNIGQo9e99b7Wf/4YvTtNEA0lt4gCkmhwB1EB9ay+kitxVJJgmdyGLxbUUlGqwXsAj0zlHWw==
|
||||
encryptionKey: MIIEpAIBAAKCAQEA7cA6J/icl8wseeXkt8oJr5AeYadUAG5EdCOdHj4S/Z7ivff4MOIKAeQITpq+rqhmXxOePYXSpQXE20Y9PW9tuw4gzOuq1ylSG/MWMcLDH1eIxg66rnmUqUbdiW4GGJjVjc9jvN0Up+MfSrUF6fM0jWTFoXVJQIeQQGERCIYjFzjfBl1xYvPghdxNgei/K5ZGYRggT28143XdIH4KTXGtp51hAKoyY9eCqYMtm9wvjxazhPVxO2CsYaqMxBLshY3jfHNqJnx8u6+h4Bl4uUcdbLNUgMcEgk7ehbQp2K0CqNoKXxbCTI6V57UVcJHDIaO5B6FyR6BguzHHNPJ4yd3q9wIDAQABAoIBAQCm2Mf3VRlPzhFIWnVwJXE2q8Umcu8Yfkm712Jj3twk8GPfPS4H4Bl1yjmqMB6xI6zz/CiItGlnNe04lMpVWuV+6CNMq/ZwmKbuxmFE+pFEZYGuvJd16gzR3tGJqJTOnjMAGhK8b8oXJ+TF4NQNooe20ol/DXgiuQAargPuH3RwzjYmF3N8VI4KUc3LaG4TwVXn4LwPOxrQSnfwJlZwLml1HAKOV0qcG0mXX6ZXOpoVhEoRPdQyUHc8ZW+53Agbtind7bYh5TsMVDFUrcgNwnwTOsWjil049la1IJO2uMRluacKlrtyzEp6zqrW8ZJO7mYAO69x4WyGqf2ZgIdA6djBAoGBAPqRHWAIgPa80eXbwCYkRtUG/ONBsQGi7+wm6nyhkXvNXJeokgH2DCgLH2+fW2scfOJuZc9r5WftEjOBvNfr2LDcwdyTSTh21WYcPSZx9HDf2d5/SWTcjNcyU0b5qfWIUKi/Zm9UY7r3X7yMA5dUD/cvu1PBJ5NWFrK1Gm2ph44dAoGBAPLn+LkHweU0fbxQq/76T5yVVpMKUaE9xwrJlUxEDPAQGnLPbFg4JeUt/YPhsOV85W4c4oQE+uFZrF0uf+1fEnS6MOJ+sq668upzC2hBp1B5138wM7615v1rvXVVH6qXfFop67FdBzPHt1NAN43mEIBZHTQ5hSVXFlYSZp9mxuEjAoGBAKCzUVO2IIAeub/iIGpV+dfGk4ptJ0kVZyreCqXEObpdC3V496uqUkGcYJ0GZ2ta6f2PMFzHpmnw8it2mdchu+gyrWL6U4uTK2pB0jZF/7Ak4WaB3GCD0xBxhleO6CJBOvn/R4M/bHcNEKmsYuE7WMIAKvScfPVR0VzsKfcLM5VBAoGAVvWg32zdh1bBZLdku8WU1rPH6KAbFSRuq3f7UPBTyWWaclu7p+GB/4f1aE9V6vJJmKASn7zArAhUYo+REMOmcc9uTMea5F7dM/23qb1HTtIvycLR44ZviW4Wx3iP+5x70jOLw1VQjMME6HLm8I/afHhqshWdiv6ganPv9UTwEg0CgYBSDi2dqg8F7ij5CN+LMDLSn3b8GCw+7efGIt7imm/O2V/FlHD40IA6qGg6DXNQrnoZQt94nMb1cZEvm1dxi6rmQNrhCyoMogAaPqgFhZGq1OjmhVZiXFUWy4WAcjdzFc9wZd3/XtaofRKHLK+ngTFhhVApKypLk3Rg9bCAAjzyVg==
|
||||
signingKey: l6LFiKqr4ZHgcPbL+DR7KwMbzImufQPFgpoHOJ/nvfUbpb76DCADHuT1I4gIs+XByglnY1KV8jbMfW64XRW5XQ==
|
||||
encryptionKey: MIIEowIBAAKCAQEA4ltcn1AH048bMXcKOOW7/E0TZYPxL3OtcHXWHSAZjeeTA/rc45G2eaNgyY7Ji+feLtZERbXNWGFBdNp31NHDYZAYwbZmjEqTEgV4yVx7BQP3VBEzglTJaNLTf+XIJnVAEkoHS6ogjC0oXTM6paHu64EitoOCzF9zqL023swjE3HU0dm2xwsUdGnKeO5nPMso/6e3VMavkKnFmvB965ECCBujtediP4lVdIABNVtoMHCoeI5Sn+m7TKqJSyDOIEMhHT3orYUNZWVeAHE1YTM2cI5tSnDZP80CHZ674Z/bKL7Jaznmq87mVt1h9Use2EkxR07/dJuTGvFOos4jHoiR9QIDAQABAoIBAHAr8EluooI/j61CnYk2p6LPG0aaTQJD4/YwHuwOBTviP2OghKgthGzg/szDerNfMyaoveqBvoIGqCZdQTbwwE7v1qTgXA83wYwTtBitQLVqkr1RTOJQXAMbPv5Jg5czUY3+q4DejQSKOE9/XJfKGJkSRH6Hy2C2CJ3dLnzYUqWGO3t70RLT1/sC6p6w3lXdy3dKZGkoR2wva+HXQxVrP8X5HOResXgNZwgMHt9KF1QHVCcySKYiEAefEKTSdKD2fOd4FxLgp3zWpvH3jrX0zd/DqzTlFD5Ns6Ayp2sIfHVp3sn99DZZM6DauMepQKtoSCnXZ+qKhekAwNVJnsVQkSECgYEA4spY9araeFUSl4uXCUQOpCkSshYOPRYN6sBbHsx8tV2eQtCT+5SuNYmzur3c5bkiraGEab8rZfGdDL6fLxQyaqbOmN31Db5kNh/2X+sRnxkak8lsROUWQZRF9doH73FDv6ZlI3V/JicZlOUCfN5BYT+x74R4/c1YXfyuD1J9gr0CgYEA/4K4SDwZUY4bOVCmKQz0OM+RW4PAAH6LHKenTAZNTeDNFFxc2nqnzRGMEKZTDGy0kbT5mBhBHFgShXcAiKxc5/MGkpt8Jcq6Fr5KGU9aZtYKji6mwMTsUndPNQydh3vOt5pOmcuMM6ovanNTvI8k6Qo53OY1IpO5CfOROu0hm5kCgYBnWsYd92YnDsYxUEldzKlLgPhnNov4pNNk15LvP0vaL7cPRhUaw1B9T6scAKjp/GxkasZ4lsnFZM4o37qV7wNm/WwL2KN0Rv9Od1SFtBBMzFkDXvk7kJeK/XLAr0OMiLbSYZeYCFUQ4yLSa2et1nA/TJLf0CR/rhSGiMAedX6DlQKBgAx1137OT33GrFUzNacy1oYeuTv5RNfBVA9lrabrd8GggN/JUU3mRWCexnHZaptkgbnJVZKxPBuhv+V6VDBWF4HIPD3SD0/YfxK03PA3CnWRYppkdAValRvAbcBsiRIeW4pgoAyn/IJYfk92qFK9uFMVCJVZNKYnBhMSKbbx8X2hAoGBAKwvzyAImbNB+493q1R/lSayxzG76bRJ/EseiTqwIec9c4C+Bd/sVXR+Re+xZb0FI/va1bz5CrduTzLSKBmf/+0lzl0MJvWY2+SXfGYdbl4+TTyqgDDfwqW0Tj8pDimye2BneyTmXko1rF+2Sxen7kMXnJLwpqjwZ6TZJuoqeK8q
|
||||
types : ["tree", "file"]
|
||||
- peerId: 12D3KooWDCypXSyN6ppuMZGxVnBd1ZQCMV4y7Bn187S4duYmf8rA
|
||||
- peerId: 12D3KooWASsipDzkridiMBmE7VSqp8yZvGWPY1VqySgMSZk6tsiL
|
||||
address: 127.0.0.1:4432
|
||||
signingKey: SGyNE0dFaQgtgNuzdcO7LB+TEz9VHAOtlQLk6WWkrkQyXiZV3casg8Q2/4PO1Oylc8Fu72RU001Hclj5JCbiLw==
|
||||
encryptionKey: MIIEpAIBAAKCAQEA0k3mw4FyexRkLgLjHzYs4Ppeyv6r9ZrP00imNf15JTuM8ajMx5oJX7JQTm8KOLRJjUdZZAd5Gtp0ezfYAQK1ZjEWwCmfp8j8FBgJIDSLpjxl88SXMLgATXYfhklnQvKlQjs/X3Ka4zdTrav2tMH9IAo6TSNZhlPQNsUory1SGHs+KqHv4p0sG8oWuKYhfBj8rWHQdUVptkIBKgojFDeJJD04Tbf9kUakbK/8KuXB6zF5H4WN3p4rMMwkClyTGeYO4LDg5TzVn8NnUi3/b/vO/3us1G/TMoRe/6umUfpQxrwo+7S2T6A4YwetWRp6xALLhp+HfAWnn0lA/D8/w1WpKwIDAQABAoIBAQC5cdQxRa5rddm48PbSCPWeFWkNW3DLDI6CYyedqDvxZwer+QtKXzww1I4X+7ZptiC9odLjb+uMkGHyXZXtnjPTPyounQWZ8JLILUGu0mbqWYwVXp9raHVr2OOHiKaz1D+BnbkOM4L9JUZ2eJL9ZaoNXLd4WdmRp8qM4WI0xqQDzOANx2HhyL/+dJmQeIUND+pdeH+Z+fYowU3ho32txNvBnMXQhF1T5K9i1VO5W49RAjIRbENsT+paPGKbNubDHRt1j36ktK4eC4HSdgv8tccdsGyrEiIbAt1XsTZfM8ie4D3A8RhSxiTC6Fkgv6vIm+iFTLzBFZKesOBcd8sfKeyBAoGBAOts5PQQJhldPDzlbnqzxMOR98WHbkVZjCqWSkNA34vqyFuPcRuX0rHK/qpg23ilbUP0fGMDTGgFzTt51FZLL16SXyRfjNhzjdmryryeddQwbp92ta2GEgnU6t1FyCuSCtcLDKJd/D9A9dC5UI6z+ES4TOnbR3nakXK9t4cUOFthAoGBAOSu+wL+SEA5erR+m3LpOsELK68CCJQPxn3VpoVfJZawgF+fEoXVMLTERxJput1+ADomIEdNc9ex86TjKx9gJ4piNHscRPFeT/AgESOIGHLOc1gk2DPqNj6wBIarUJQ9t4KcHScboh1dTPJeqqv2NSwIiLQoqFUIhfKZLnrW3zwLAoGBAJh0hC+o5YM3ZXLqAIllMN6VACbidP5j5ukNOjojIKCzAdyJH24G+2I3WoNrBbUzK3b+NC7KTAhw+V6ynlbjiWFs2D/twH/LFOkI3tkWpKcsVfbeIPimAbhsMUvpjJ7qjCqF9UCQLHGp14W6+/ftg7C8yNIINlkquVXclaTb60MBAoGAPqmL8ogG+EJH00mWAujRxq/u6meePiQMedKfbJBj1mTK6GjIRI/kZsQZzXvXTnYGTejAk4kvov0KDDaLTG+mpg6+3rUiVxlGwj+nMptKR7s2dAK0k5UsBAVrWBN9YwF+VXW9r0etJmq4ePljvvcaHtS/0M4LQjGxsoYy7EoQpX0CgYAhnf0McB7F1MxSjB0soMNv/v5utVzVihS3re2yKNdkI/YUEMB+yU3Q4gh+OljjBM6Y5To3BsQBAx4l2CysMKFHjIE/5AtdbvIS+chZZqB3vcZXSayvX8P1Z1uFdw/saiO2cRDJmR+TxaOPa2C9SzDoNTACthwLErHfzvEvVroKmw==
|
||||
types : ["tree", "file"]
|
||||
space:
|
||||
gcTTL: 60
|
||||
syncPeriod: 10
|
||||
syncPeriod: 11
|
||||
storage:
|
||||
path: db
|
||||
metric:
|
||||
|
||||
@ -3,10 +3,10 @@ grpcServer:
|
||||
- 127.0.0.1:4530
|
||||
tls: false
|
||||
account:
|
||||
peerId: 12D3KooWA1MZaN1U8NHDnkvbN5wsacRGvbn7dd341S4pAzXofSng
|
||||
peerKey: rLHblNZKOvJxnAKrwIlxkWy70J3aXDiCYVr8iV+PyQAC0LQLKUjXGJzqOdS4tMU0UUPGNo0VQx8q4YHqqt3KLQ==
|
||||
signingKey: rLHblNZKOvJxnAKrwIlxkWy70J3aXDiCYVr8iV+PyQAC0LQLKUjXGJzqOdS4tMU0UUPGNo0VQx8q4YHqqt3KLQ==
|
||||
encryptionKey: MIIEowIBAAKCAQEAyzE3C3bWEdKCJ4HbBfP0psg34ZsdmiZcflOu55aLLnl2ctzWv17SO6dU6C8XEoVtJA4V+tvfsnQTro6sIy7DDcDpGMnA7HmLHzK9GFKQyC/9EzEFg6s9F4A6ZkW/hyQNNfE7NQBokJj+uvSXzw7wb1b535hvg+o+ZPdeQQfcKFIqZKQWMXOHHSseVV4JH2kJ7BNgvmRU1EEkZ/l9FmrdvDDSUv+SgLz0ogESQv3yR/bwwa07BVaMCAdwAMZAcD04KUjEGpEmHfsDERYRNGvOJ5bnJSHTI9QEow1P53CtOMVQ9Ak3YhqyycGtvaVmrY/CfnFJzUbb8IDmvgW6jw/rrQIDAQABAoIBAD38mJdFvI6ZUp1szv1k6/jJUcrggEpbc5ISQ2RhF7qo0Uq/NkARVD9gj9V5MCe1TpNWPLxXwUl2gd6Zpcfh5x1WAYZPXiyF87wjxW4bGhIIGcN2DAGcBroZozc6BfDbPbB8FBzaMAwUsHkmTv2ayByfQwFERpjOqBQzJqzeEfq2cxFovcQdyhHk3WmfH1+zrGENs4IVVmfmIG1LzXehaXJ7jHqlryyKyKpUmXOmymEtSB5It60pl+9RNNlaez9OzreWgE4bQaeQU09I8105YdIISmvZWGZ6PsBo3ma+Rj+si7zYGLF5CsbGxT+U9olpiO/DW+UbfrDHy0bAArlDOD0CgYEA5dI1b1GDwAifd4fR6Zv64AMFAFMo5hWW1EHsUtXVo1UD0IgheI0oxg4aqs93SkL7uMVrM5rKjfstFcpWfaSfzy38+8mneRsbsI4d17RR5g0F4D+2/uLRYRRU74m4ThQjfP6wf+eDAM1+rdmT86cyQab5y1VU9hqd159xCderu+8CgYEA4lZ77Ygdy2mHmfdzFyQ6eJJhsC5FoapJWnaw7LISEiJgnAun+qeIl1r3yFbuNK1Wx55qfdvz4v7X0KJV8HwFgpxzT7CoUybT3SncItWPwi80tq/lxklZvq6LUeOiNQrpGvECCUrPQ3Wdl0lcmOiUw1GXliAQEVdzBOT+0hGMZiMCgYEAtZ76O47f39LwszXS3hs2l/HK8gbGO460M+olKRF0VC/LY/ExAmQL5Pkgefya+UUWSV866P1bNflaF+5fi8udv81IMHOctkiGCXFGhEEst/Fyw1WW+LenYGEA/oyH6qxfn1hng60iCnBbvGhGVDe9r8SVg+tbyWIfe1e1rWGThmECgYBltGkBpn2E7wmw5OGBj5T6owRkj5ZYe9V0YgtEgQvfvDTfSdmUp32YTZc0HePyJcXt80B1B8ZCxTMjHB8z7fbn5vdl4sLwgm0HX4z81ixAHMg6IzZD8Kf0KCiQhpJX9Wwj4BKDLGuQK6TB24RRbYmTbvGH0yaFNF+J3oCm0p3dMwKBgA1TTXLpbL5lnBaAaWAHYSV9rtqvBkyVfcnB9/Ez9MNSBOQIbk82w9Pb892qjcNhTAfgRNrYTd6JZl8Sov98T0OJW0uMHFV04NSqo+RLQTaGjMfrWQ2ZWfSM4tFkoWA2mFh+R8VblzTJObdu1zDyuVYscfTv3sFnV/QX+zJWJipB
|
||||
peerId: 12D3KooWPHN8pCMgVaNfjzuXhHjsacrryW7DCyicurH3uKHXCyE5
|
||||
peerKey: yHyVKOM1zEIbaHgwIAcBD/s9TmYQj6dU3dSzs5OHyBTIEpMC+jaTKKmS/5QCzgLzJFBnvayFtXwR/dH9G49M7g==
|
||||
signingKey: yHyVKOM1zEIbaHgwIAcBD/s9TmYQj6dU3dSzs5OHyBTIEpMC+jaTKKmS/5QCzgLzJFBnvayFtXwR/dH9G49M7g==
|
||||
encryptionKey: MIIEowIBAAKCAQEAu7C6g3bFuQb113lDuKJKa2zzeZNQxdjEQTcC5NVZkt5Qbz1cV4o1Rav0+nrMYT0mRFz6HPElUM7D1o+e/FIxrCsVnoCm4hinORhpilrR/DBXpnSTMmRyBIocaBK0T8shY4zNMYztQ0eiwkGZnxJSqi3Jk+oa7B871YIVDxzgD3AkOkTcRnFR+5SE+B+2G9qzhvRVj+LvjdEbkgnqMImZOPGsa9sSCfDrC928aSAokick4u8JqCfDnl9lYLlBYaVxGipiMayIg8TgXvUhiNWKrCoNyONHDtAKsmrTDj9DWEWtdX/h01uHrWBGq1/AVUpJ1w/5zHUYKF7kopTEskTYwQIDAQABAoIBAHhmiW817OahwWkFQF0btrOtA48U4nbYdCUFnhSfjEN724tQiIEbhsr34UIhLiSeroKiRkv0oaRxzw0/upRQQc8ZIFg6XVOizvsAXwvC8PtfI4sDMz3bU4z37/sPLJ4XR4bt1t+XcMh9FrqYjGyPu3mxv6LkRXr9Gkv/k3TLaCxd/88AlxLNquCYw5HKzZIN7XxzvYRHgn6YULSE48BewpqPPhSS5APItFyFoE9esafSBAcr54LSlwJ4X0Vee3QCxy1WZl17PzUE3M+lGvQ/gdsm+WrY5zUP0MTz4z95urknrPIP8WDXrfK+SzEXwrBvP1XVk1Sl/KKBJaAf+NMS7cECgYEAw/LEz+TuazDlsSAe1/fx9UNHQOAy5hrNIHd37uWaBUC3DszZEDqenJ6WZhtJD4DHfXwqtvXuj9Ju76YfGInFxxucg8AS4cD4+J+KfZ3p2JmYz9d+f/wPXtvG01HubV/KAPVdpDrN9QF/U+YC3W3QAw30V40X1nzgoZWMcPwjITkCgYEA9TYTh9U1oV23meaXUE8ux2ubufxy+Y/J4x57Zp77ttEU8xRTCKHAPdgm5PbMwhXTsUJEoFrH06iTkbwy9yIjJom4sl00E+p9//fEdCg8sEvpSJms6TwB6CkPsWgkwqNJDYwU5XLXd8EP16WZ83vyewZvCz5ssn7UXq0nKEtk28kCgYEAwHogSfafHDwT5EGhCpRL4JgNzfRtCwsYo+O2s7xl5vMC3k7qib6LP12obvQueEQPsXvemYpKpIwY3N9ZfEkZNdQxklmCMq/T4KUW7P3JTzLRoJgVcrKuhodsbvf0NQv66aYcLc51sU2fPVKbTdcolVeHxNibqd1Q6mh0ZCfIekECgYAsRxl7u5o1izCuD59fFw1BYUL7cIRqX/Z6lnR98VNOja6UviTIODz4beGIErCik0JojajKs9nFdHlBJZSmX3mtacz6GC5hMkSSRfEpcGKVCwAS5fz9GKLXgyKcTEvnAYkdcyAK1pPlwezUacjE2KrOYDkI9Lq3+ILsnaOmeQa7UQKBgGvHLrUvRsi04mB+TVQYwrlwRA0NNsxQTMek1UvFlpx/KN8oaDn7Aylao9zxutXP1jBH3kYmhn56/9lJpluDWJAKtBVXl9a4dh/ppC3WTAloU3+4u0aC0Mk49Hg9730S5LVozqH+q8VWiFh3qbxkrlE/4yocWvm18X5C6+kejKOh
|
||||
mongo:
|
||||
connect: mongodb://localhost:27017/?w=majority
|
||||
database: consensus
|
||||
|
||||
@ -3,10 +3,10 @@ grpcServer:
|
||||
- 127.0.0.1:4531
|
||||
tls: false
|
||||
account:
|
||||
peerId: 12D3KooWKyYmekF5ongQGMwBgx4ZsPDQiyFjHtd5ZfKGsoXTYY7h
|
||||
peerKey: jRWkSxzPtg8SF3rJ7oqhby6UvS6fnWGOO2GlAePHqkWW7xWHE1XC2R8Wt0E/4sFVhpam5OKqyIm9aDsWiILHmA==
|
||||
signingKey: jRWkSxzPtg8SF3rJ7oqhby6UvS6fnWGOO2GlAePHqkWW7xWHE1XC2R8Wt0E/4sFVhpam5OKqyIm9aDsWiILHmA==
|
||||
encryptionKey: MIIEpAIBAAKCAQEAy3UBKE5OifVxeU60KbYUQ9OFob6uixxauUVn8cn24ZX9C2qPAMLQGTYBcWp0GKILqRMgcDmDV1DXF4dNzSYQE4qFDvQ0C5ltoV9vDBAxhyDEN6nftD4K2vvn+fBVYYAXJp//I/2YcdZpOzu7KFHPst74tnFZB1+7LX0oGToGzevFKgqmvoQ1LUj7OqWnINBz4jA61h2WMp11j6/BO71kEeMdeMJyhmO+w6oFlLhd3b6Vsqd/nIc4SKh0yS3jdn+OchgQEMHvNL0KrvExPwdnzQGtU9E2nrf193loeFoCZayX29x+aDgTah2V8JlcN2do40q9h3dJJ6FCgJkk5gBz8wIDAQABAoIBADy0Ym4GP0TGaN8K7pJrc0xxdjO2UxnKkf8piEQKQJE6UU/wsU5G0hRTmsaePpmC7/u4aztQzbFlu2eXxUzqiG1sLRszHbxAQQefE+EDi+OHkUQSeV6sDE0eUC6w2KjIsR+jKVsxtSRyFt/HiKYVEuWJxaeZ1jhvBcgiya4NNC6IG/wS4JYG5iPs8QZZPDT+geR2y1jVQdttchVGxKbthMxDBPfSlG05QFhb/8frCfS+jqBHla1e3UhBfdlA6elZW+IxOoxoKvLLZtMrI5+3D162ZBsfoIGXuME3YqovMBdISnRQBbQ9gsSZlYQsosWofSd2JPxVOm7YdOmOIo4sEcECgYEA3F2W2vQLdxtJ+RaLPrGICtNTXwkP3Fi5KGT/QFGCguJpGo1Z3sGgL6dvD0iKBBCTcmyDj3eBGYW80B/2J+tRiAt/0ME413Pfa6txl7LgKNDlFgAb4/ycth0TocQQE2oL1OawHBr+BiE2b5IbIOyi8wsaQNdtORYzRLS9clieWKMCgYEA7Ft1H2/HAQMBOLeyyn2LMaPkewe5TM/6K+CoDA9orcoRmZ+B3ht2iBkcJE3Efa0c2YDDbL3GENfUzzntF91auyC/aKI3A8MxBZg/6QEiTytgcvbCSeXkwZUCJeNr+BAFLiWOE26sg8P2cJPT5JfjgPkqA4dLWvqwvMFe9LcInHECgYEArVoGSToAJvNVrthYM7puva1egX1cd8dn6OoCjjNQyuuXKOcXUo/ZFoPNbyVuRSJRC4tntx2Ydl5pmQP7nY2VdsMtCihmMb8ae9XDp0V050blX/g3+JKJKQ4YmoHk75DVu+a5lXJ6cJICA6TZKH5e9Xi/b1DIwEbBkAPqoCAseKcCgYEAxSTj5HzPeMCQ3EYdE1j0KUuS4CvpG3C+MqsIgEa6AXtygrjREfnGPG71UjKrmkgysBj+6EzCUHo2P0MJx8YST9NY1GW5jaHZ2djMNgWEIJUFtd6s4Aapb+5iBEhVXmu+ZmdcwkimDKH/hJdJPnqSgJlTue23pQNFN6vzEBs7S4ECgYBhY2YJL22+btVAYR6g/pOkn+50h8S/TtEH+NUL0SKnv8N96WvoBjUJapgNNrWPzzUgmGzS+uSweSTGM5LFeidNU4tEHZ1yNt7nrlnaJP2anGgVp3JcvNQiy1Ffwvs1efo0c8Tc+fORj9V4fhdctpSAoISETDtoGcZbQjUtB/aqYQ==
|
||||
peerId: 12D3KooWA5veToUAwEVVXV6PoR4dFH91HQZA339NZzqeT3C6mMS7
|
||||
peerKey: gGwpn8J8b1WXK3Lhaq3NnQMix+qQsHNRxAH/DUalvM0D/G9dc/GRiAu+NDtGKRc9z2YAw6HKJ5GJAfzWTMDREA==
|
||||
signingKey: gGwpn8J8b1WXK3Lhaq3NnQMix+qQsHNRxAH/DUalvM0D/G9dc/GRiAu+NDtGKRc9z2YAw6HKJ5GJAfzWTMDREA==
|
||||
encryptionKey: MIIEowIBAAKCAQEAw4BsTVcK6Rnt3kYtvMZ7HU3EmD6uQzjn0bqoCsFKFNOMh0x+GE4aDox6j8rEzbeNWFwkn7RI6kPuByuSxe5RPG9QP3mxoIgWc737IKx6X0K9vBc8rLTgbr/OCctQs5zfsvEYZa4sKG+mfXPh5oxNsLfAO87OiPsTEPXLYTrEGZ4GZ71HLO7EBsI8N4JvNWZVQq3bbv+S7kiXtXpI1kdfE1Nu5XZIVw3dSEWoP3X9Tp9zavLM/obwoN8IXFGqAbEKOZE9zZkqvwIVymFxqEn7bcqtkfhbvvyTpg/VSeRAQhJkhmx92QDgz8mt7d2ADan3hgqFO68qHK+VlH7D0eaMOQIDAQABAoIBAQCOG42d8kV2B2kGhxC8BbJ8LIlY+UcGihjINNvtZW8KEHQ37PxDgpIiPS7h0syXlHLj5aahiBTwZIxjHeNEiOT3/xnf6f+Z5xIa89/VckpJcGQmkuWBzMDPABEuwWFaDg/1LJdFYgOrKO1mh5OPWDEo4YiUcNFkdMz5KRG7DVJ6I0NNm2x4sRJf8KVfLiOBDX9CKEUpmXZCciUlA3PnXAiJwpYxHoTSktqMrVj7YWgUuaYB0ZQdaXTG5jPZAL7zdVP3Ub1h5Oc9i56UgP0qAo6uXhQR+Xr7wKptnQk9g27zddx7ofa8NtnDpgzMOfXvJjWsMBB8ego0rQjydUihsvLhAoGBAMree7cd/NgqXgDc8V2zusb1gZ0Ao1uvCcYmp/w7v/tUF/UOuvjYuFkHosvHEOjy3gHNrnFYcj1US3K8OFIRkp7b8TKkEL/ho01SVI9PMfczEws5K6ufBZQ+33hJ7+drOlirRQxW8lIZspL3im/CLxm9K2zSfj/oMreO0ZY5jM4dAoGBAPaz/DJOLSKzeu9LBzFjfDMhYN5N3dLHIG0dPIDYDJYyquXYIARZrOD5wWh3WahX1YyCC5bBgugRi3SG0/IaKZQg2+/X70RdLXNK5sZHxR2ZildGFFaA9ERLYy9Gq75hAGTA0dt4CA4iM90jy0Prwoya32SF+zywoMcGV3LLX0vNAoGAPQya2k5R6pNFWqkikXomuPzklmS8xDh2joTPhJ5Odcmms/5M0doWD+S2XvB27EM5//zvg/iD2GTnl42AvWHAZ8H0YbLxv2ydggVGoSHJ/YQHNRdtRuZB/Yy2HzLQ2Slxk4Fm9AGuRnqpPIT1yg/7sJk22ja1+3Fa4dY+yCBleRkCgYAU9L8Eiu18mCBmOUpYIKpJMZmn6JdiMzYG7sfX7gJLs+wecBhwJinwRmbud8zu5t8l+1n+qVt0WSEuedGBLEXB5nSoUABsHzogJAmsaCZPWF6PAU3y9ytIrdq0Bl3KYzUEWfi5mt2cTb14GHVIxLsW9ITrZhIsWpidr2U4RBxJNQKBgFl5qZd8wFwm1kv8j1BtiGMN3e9cIJlfuIm97SOuaEFSwo/QWnhLQ5QBNwIijXDx+Rx3jPPedMO/fYd8IjFdG1x+1g4XVlnCV8PMCsGFwsu3/Q4Av9q2uflsZlAc+6vdjB9uEr4jhiKd+j7f5SWpPHKCUWyeem47WSjyq3dsM7HG
|
||||
mongo:
|
||||
connect: mongodb://localhost:27017/?w=majority
|
||||
database: consensus
|
||||
|
||||
@ -3,10 +3,10 @@ grpcServer:
|
||||
- 127.0.0.1:4532
|
||||
tls: false
|
||||
account:
|
||||
peerId: 12D3KooWLgWXJyeG869h3Awf9s7Jt7dw9ZnNg5ZFkMFKSHs6Bify
|
||||
peerKey: 6DyqyTRgR35/TNWpEbqVm8NbbmOULNuQDYEk6C+ltyyhbVs1bhOkA2nigRoE6JFip83k2yVjsa2r4ST85kW0OA==
|
||||
signingKey: 6DyqyTRgR35/TNWpEbqVm8NbbmOULNuQDYEk6C+ltyyhbVs1bhOkA2nigRoE6JFip83k2yVjsa2r4ST85kW0OA==
|
||||
encryptionKey: MIIEogIBAAKCAQEAqCZtyjHrM7jUZNyZNchUAgYIZb27YRRsfC6ca2xgdbtIjq0ts9af1+JQcmHMjGyxUTvLjx4I4IPJzDF5KYRwiGSWM4avhfxKxVToW0j8UlqQH+nbN7/TmmQfW8+L4CsgaXcf34uE+CfnyoUnwPoWLe/6SI1m5n/99PcWa9X8monNoTSMoeSOCm/csyK+BBGW9BTOMgo+2Ceyu44KcERl/pdkBGmba1xz3SogEq1m7cpG2Y0Hmd9dyHVJU2jSFczVJQkWF6RuifRoGcjdtbRrY5E8LsF2CM8HeeAZ/0g/q7yoR6D/nCrWaejszXObi+GNEo51EdJW+7gD8g2U6vUqkQIDAQABAoIBAG010FbjhxRntiLwF94Th2RtEKUrznil8DPTfipTEG9GvUBVf/puqhBn38H6fQSzT5MoF/STGEbhsX4an8v0RbaARgGfN375NoLlu6gWRjMiuLrRg1y5DTEYWDmkGf/1Yq68/QmOr0URff1N8Fzo0ODzHQZkOHH6rTGeDYTqTY78ZfU17yGXoNSmXycAqbTGczBP1RvyDRd4mIuBg11E/+A4GBxe8QaSZzJsyfvtBi7jUqKgdDDDI5Gz4x90NZ90L6jRFNvlhuosGETQ80oyNN1soa6tVSq7UhGI7+wcJDyaXQF32/TnqIXArScH5gRLxHiP+FfTDCHzl5iZG5m/D3UCgYEAzHe6oorAELbpcRaUJQayOkMJIAI7KP5EVI2IbP1fhBaW+5BYtzGlxKZOXWZA057E0pjwO99rmVNs2rW6mU0mCfw9hP3oWv4EgszU2DEx1+iHhNF6cy/zGDh3lgDNXgRPoBRR05IS1Ffs8uEgVfhiVjtiv4FyrVE9fY2cTH+7YXcCgYEA0od8pJLXOhcj1ap/1Y0phaHv//ulSqLBtKEQTy36zDw9DfcIozB8LCIK/Q/3nr4RHmd1YQVRDoTB9pX8eUuoJvM3Do9CJiH5/0PXFgIOZZsDXtl/TmL/1diHw2isttDCQF6I+q5lRYlbA+oqc8Vko2c5LQchXE24oz9670gFFjcCgYApDSjVlZH2SSMZZ3Ua8fs6o1bjrE8Abfx+FWR8rWpN9NMfct28+iTUFKfLLMp7MndF6Rriinrp78v9JVtviAPJIXGgj/HkwvdY45MgTNA7Dx6WVhCFq+zcwgmQfly9MZRjCXFcTwmkxHp4USbS2+mycn3jATRrA9KasKHe4g5XBQKBgH/xPtp1Mr9m2Kw9FbseMqG3rDcRI36cMsQnLdYwxz3fTetyuZkTGiNn/O2WCpI6SAUGMttnc78zBv1oYSsFw4cIP+llPnoWI+vxuoDxdvZgoke+PhPRLlEzai5jKrNfYu3jhbNy0LDVrK5QXMRGrcZwMNsgfjGuOgtbxMYuKok5AoGAImYTQ6e0fliVoHO5CjClQRpj3oKsTmB4hwtMofSZ+tFVPOakVM6P4K8UzMa2jcgz3+KgLAD8awpHv0ISO+qdSwG9MgnfIxhz8jxatgRBXdhICHrnqCqwZqyV0hrVmuUeg0uXPN5AisvfGEiGpkAPsQCo3bhAqMD+4QooKCgpz+Y=
|
||||
peerId: 12D3KooWS9fMHSbogWfa2o2NLm2Y7o3SGXojn5anj5zPz1TeZDz7
|
||||
peerKey: UYx7nyuYqq2+j/t8kTZczAoXCNflp1FNW60tNUfkEtzyrHQg/MAHjYwYGhYxzQ00xsntqLsuA0FAuyR+YtVrsA==
|
||||
signingKey: UYx7nyuYqq2+j/t8kTZczAoXCNflp1FNW60tNUfkEtzyrHQg/MAHjYwYGhYxzQ00xsntqLsuA0FAuyR+YtVrsA==
|
||||
encryptionKey: MIIEpQIBAAKCAQEAvbd32m4jCtCVSPthnycxPmbKNnnLUn8tHNQZr5Sl2cH1MBaRBEo1DBhI9UXIqd0iprFCvTJjo6s6vWVdLAXgkGpKbuWvh1wdVuMOsq5kQ34m+XEWKXVpSkpNboUh8LdBTrk7NqvpMy9vC2aUt6bKY2zPDnRFQKFeRobfapwntWLoIhmAtBJJRbZuvc8OsFHUQRjcN4ZXLBziRcMqG0IBFPstpiXJNp4f7oB/bWGKg9yKM4vkgaIXEq5RXSvtPD+Zx1ovt4YF0vStWxxM9rEIAAK49HlCJ/aQ7+YYpFGjzjMQMVjLlH+8pcP0ZO75/DgJa1YZDiZ6ICPJ7YADTURKQwIDAQABAoIBAQCdAKRzZAoj/RJOX5sedvTNy4s1If4du5m97dmD8OSAHX+n2EUS48aax845DRNPX+45PSEaKgVDgYUPED/XGtYJLa2DsRleT+EH8shLHv9iy5e9ftT0YnJMRMln2U2JRF8Lo0dZq1NGRM8FBFO22JVNStLgB2D4Z5L5ksx6Edjaxh5wIWxs3ETihzNSZFWvh1bVXdUzC0VfxO6VuiiTN7IMAeL7DiM0/QVc8vk4BKG00XtV9KvtnGqnynpHYvWZ4xRU4GYYwDwLZFWDssLgU+3SNJCeucGrrckC1/73B5gjJ3Lq39dbr2maEdKvo6KdE8kOLQyZxTMHWdAVH6MKGmPhAoGBAOZGlR5V6P/cI8d594VHz8txEp72IsK3Y73acbdqkV4kmvQUq36oj3ObO6ZNhaH3/j+M9xw12eizh2KV512aDmywEHGXbs2FY9Flck6fMRAamOrEkGHUUDdACDyyCRtO3EQMMNndy00dPY/Q+nrwHKLfwYcfDcrJXsBVS6Zy+hFdAoGBANLo+sMU4grnp/XurIIB+3Zahzfoeo4xMiLNRDOy0nuwG23mgozZKaRnsiyxrtBQ3un3cjQS3+mggsa+N95mF6h+aNzM98ySqqByw7v7N8c7LQjon/BxonBXLi/bETLS5+cdRRXHD6QbvREtFVtD9oRZJAeLvS++BdtS1s8vOfAfAoGBANh7JHbnVusqXmyKKfsfXqcoPtQ4GsepNlhmQx+mTNEPYqjxwaOJ/Yo2NmaKXIW/KUM/V5QqwBf2puE0gdTKHqNpBZx0O5N0wjk5wLNPDwXPq1CRyBZgTaUTSmsdCFim04YZW9eFnjl5ssVANipbDuDDsCFCPWoV00DHLx5k2th1AoGBAJmwA+rb8MuZex8OyM4Du8XGufnXglbTKoGJqkUx7YcMETDIZCFWra2Lkp5W69gI1icPlTy09E0+FY3VVsjNBDhXxPoAsiF0TrmUZ2U37rFTQcHYIZQIeiH6pUFiFOpAHZSgE5OG9rLTM7asb3+Nyrkua77D6Rw9D+9+MeHPvBxpAoGAPD6fta40UAA/SB8lLmviQ4odWlbbN4AiUO/oIey6PswU2ZJllHEOY67snzhfafdT8y8pHCQQGDnPELfdB/2b/4x7Pi4+xQ6LepxMkIgBnW4zrbsokbvuZ64anCAvK8cfqqvcD4OFEdh/GlTQHGSzlQ/RGbOAuQ7GTAYlsQmb+So=
|
||||
mongo:
|
||||
connect: mongodb://localhost:27017/?w=majority
|
||||
database: consensus
|
||||
|
||||
@ -5,31 +5,33 @@ grpcServer:
|
||||
- 127.0.0.1:4430
|
||||
tls: false
|
||||
account:
|
||||
peerId: 12D3KooWLn13hDrZ6YRGM517fHf2zS6qhPNRu18inLMpRqn1YGKu
|
||||
peerKey: 3mzfKBWtn7mitFEgq8u4eysWOJ6ySbUs49irfHwcuOmi1YMpobz9anoqd4yaT1owZiRPYXqx5k2Z4sNVRE3kXA==
|
||||
signingKey: 3mzfKBWtn7mitFEgq8u4eysWOJ6ySbUs49irfHwcuOmi1YMpobz9anoqd4yaT1owZiRPYXqx5k2Z4sNVRE3kXA==
|
||||
encryptionKey: MIIEpQIBAAKCAQEA3U7b4w9JTKE3TLM1WQ5iqdLbvUuozMp/hDEg7S15Gr6wrtLomMSBkfmVQ3Cu+CHdxAFqUFClItYlSFgtZWIFiSiQxCeaN2dmgczd9T4TlRAw6y6uJXtT9r7FIgizPP4B0/tnzPI6yYgpdwzCV2nRSjw3mMr5Nav3QYs18kYrJ1/Np2Wob5HOoRTUD++pPrToevTb7GNL/irrC8wXSE7oU6S7ix6Nh9vzEHg/V5FONBF/wWD/ri7Gy0j0qgUQ+gjxLWKr8xPDnRAve13zzo+54lGCyVvlm/rwCY9Jx378V1IuRx+S8F/GFuVozHD4XVaoSTtpCWPBQNSKDXgaIIKDowIDAQABAoIBACpMXj6ht1LMJXOldPbWhwkKYjFl+pdZxNGRSkfKvzDbbY2chhRcyp8J4vuG2ApY/rftxVIgd8+Wun1/TP3ppEE43aKAJzubqb35WBr9iGSfOZpZy7MiRUQN5kPBAfEQY20OyiIj0hSez74PVD283eGgbMfpU4Rsn8+JOgBaZPkbPViJLJY8PyHU6vwWw60dye1iJTz9yuBtoEqY0XKxnLaVXTQaWx0Te+VYU8twxDgXFWRaXtHuk7xnxOkCZDLrzIvuOYa5lsLoT8K62LDeXbyHBPhbdW0j4ZYzAOTsaUWpjuJzef9aj3JJdfyADiqb5iu6HHksvKzkZEau34zjilECgYEA/c8ZJm62uJMHNssTJYiLRw89l5hYwIZ/1TXdFRF8+xrTin5opYjpscSTO5bY2IYqLx2xuPiJCY1eGGB9L/RtkaVh51ySzq0d+4zpPIRKFcOOgdxHwlgoCgIhQECyfJZNMFGBUIlPXZ/phvXOXRvWFzDPhqThenVG2QzF+wLP0AUCgYEA3zfviQFJ1FOKJMozYO3tUZFmsIrAcO9hfuE7uuWz0Fw2m1XiwxjuOr1RbsSsh/lKke2h4tiGrlfiFhwCpIp91NkVTFrtFOQxbDxkYLkFiWkZDkOaK9YhKMa2cgEm3p+RGawokjbm51LKf+cbYN9xGaAe3y2WzIE4kNpfWE4SXYcCgYEAoagcrrvpqZoMCDxED63ud+4fHsUsEkQYe6Z5EAg5gH5PqnBlGrofjthTpqqnpxGdILFbFyNFtU3TVtduJPMcLp4Vw5TU9MqSxDu1+pOP1FjgFZpGImSf6+/7Wb9bb7sToujm4nLymAFYblt1exxVuiOeqnWuH58+5tQZ7YyW7DkCgYEAl7WuqZEkmpiEpWh/7vsGdo+6GXbUQG2R9+gg7m+7/HsP6hc/XZYOJAIT3JLzKB84nWHCyyiasNeuI5S5/xbZWtaH8TNDOxW0uXl6R3q41qGFk/pCSFTqiIo16dn6jwgoWCh4EpgZ61KLqs5p/zcd6Wq4ULrtaOTSizC/6IZ3WPUCgYEA6xCJy3+ICCgr8/c7hfd2Ylb3aOsXIffdgALhXjDcrNUCqgB4R+S3WReAwrABemQGl4tySQE/1f3Ru7SzMMciFogGyJ/YSXqSi6Y8oDD7MqlKPiWlN6WY1nSRMlLbkUOqpA5JaDM0kcmXjZpBBQr277GOnh9uKN8zUy5xoptctxI=
|
||||
peerId: 12D3KooWPuwdqpDQxWhD2Vh4yskx2T5VMrwdpTZLfACzgsGfQfNy
|
||||
peerKey: yOEpD2+cPldXc2urGuU+szunm7fddRa8xew2uVjaxifRcVzNKhSERpOefjrXaky7PcKmSmTsH/5ZFtcrh1uzqg==
|
||||
signingKey: yOEpD2+cPldXc2urGuU+szunm7fddRa8xew2uVjaxifRcVzNKhSERpOefjrXaky7PcKmSmTsH/5ZFtcrh1uzqg==
|
||||
encryptionKey: MIIEpAIBAAKCAQEAxnE9Htwto+2fVmonkG9/DxNre33n7kjfrZU73JcHmpKhPlRFirig5T8rs2MaTq1R72/8nGBJuSxsz1PnexI3die39pY1OFYfZCZ59LbT7uH/xHcvkVrK2n50Q41KbbGT9BEzyW+XPkKPDpTq3/igYP+yUQgoWLfMwxCCLKXDe6qUC0fuIxR80fvj3XvorB5dnAiQ01JkH4PtCV1OWT6ZpLGhzcYxsxTHozd6LdMOC7wgGhW26dOSa/vZ1t5avbewFVIz0qfqBncunb7tjO4xa3xVYaA5jBbixDQUYFjVzW7cksrrN4CFNBDBGJ8PLS80MuMg0OG0O+/Qi1mbGb2mUQIDAQABAoIBACODAD0VidVcILeGJ65hRYudHg7raSXrRJv7qMrA/EtdEh3lVsyMXb6on1lq0rphqdf/YmVZldfda1tu2G3dxK8QTIuENeHvB48Uk56HWUXWi77M1WZdqQ+QsZ2lGzymGqQCsBHMNnSd1Jv3alDKXWj+WRrHKvE1cx81RRZYU7M9cpurnF5YNjO7L+7sMxUA9uAQGbe3kDVzrygraicLYQpxSNHytName0A+k3ug0qer4I6PmZhhJykkz6MD3dz/n625HSS+X+TuTm52T2b87tL27xXmSnUK7eYWjZ1vQlP1fWmqnac6u5LApUZaRi0tTjtefSjRW4jr1q20RqOp1kECgYEA7Onh3zM9ejATsjW6WISGKiBPci0D7DUbIuGuJrdQRadlkZzmeQ/VOYAuxIQD4GnQDRhM1FyxsqiAWkJOyCLFiMmsgIEyW9/eRhF8NlCVU+DA/fxy9EagfBbVsgiSBwOex24hPXIVYlaHkLAloNoD4bpw0pQZSDWXr+xvMFNwoGsCgYEA1m3sWA/e8ZuXForaUOoJzBU9nwC79bXv2UNktsVvBlQ1o9pbjoYDcVoAPwuBVUL1UwqDNMzPdhDBKBjZmCyjS6zlYD5ZKjF2m8iTyc4QcaBCdM0iyQpSXTmrfMx+hK1aWwL1p8ssNcednp5ExSAaTyNNGVdbtddiQ6/KMPmhUzMCgYEAwDjLsUNr4BXeBTweo+9yw/9PNn5brm0wRU8C9BrMIJe/izPYs+UqxerBB2Vtl8mCqv1KaQuEika5TYJ7VVsRFvk641DwQScUu5k4RQGBB3tWWz1XL+eWEticLkVR5isDyyAKDEbiHtXCTJz/CtGZUK7rF5BeKv6AwpZ9aKJqwV0CgYEAqXDlQNURu+PR6TtBtoypvz3NmraO0GO7KvipPhAXYm3qkRa8IIxfbhPLfAYQZhpqFvuIoJFzIn2s1I2GbExhoSv3eSzrcn7xlbpSpjYSImeb/AYZhbmFSiuHCi/hjeAaNS7KhZPz1G9vaubvusFaaMyhYPP6AWA4QvpHEJpB06cCgYBqR6/7d2hQiq4MJUrBEzLwG4ijnPeq+UVLQjE598hVIj+8UhRZRRcNWVEJxfcIL1v6Bpo8XISDNVRb30T9bPGVnXvC1jutTUbXKUB1/8iXuyH3IVieobch+bGd4v7ehH/lI7vzB6hjJpFzHopfFUn4wacSQdcFi3tRAwUB/L0S/w==
|
||||
apiServer:
|
||||
port: "8080"
|
||||
listenAddrs:
|
||||
- 127.0.0.1:8080
|
||||
tls: false
|
||||
nodes:
|
||||
- peerId: 12D3KooWLn13hDrZ6YRGM517fHf2zS6qhPNRu18inLMpRqn1YGKu
|
||||
- peerId: 12D3KooWPuwdqpDQxWhD2Vh4yskx2T5VMrwdpTZLfACzgsGfQfNy
|
||||
address: 127.0.0.1:4430
|
||||
signingKey: 3mzfKBWtn7mitFEgq8u4eysWOJ6ySbUs49irfHwcuOmi1YMpobz9anoqd4yaT1owZiRPYXqx5k2Z4sNVRE3kXA==
|
||||
encryptionKey: MIIEpQIBAAKCAQEA3U7b4w9JTKE3TLM1WQ5iqdLbvUuozMp/hDEg7S15Gr6wrtLomMSBkfmVQ3Cu+CHdxAFqUFClItYlSFgtZWIFiSiQxCeaN2dmgczd9T4TlRAw6y6uJXtT9r7FIgizPP4B0/tnzPI6yYgpdwzCV2nRSjw3mMr5Nav3QYs18kYrJ1/Np2Wob5HOoRTUD++pPrToevTb7GNL/irrC8wXSE7oU6S7ix6Nh9vzEHg/V5FONBF/wWD/ri7Gy0j0qgUQ+gjxLWKr8xPDnRAve13zzo+54lGCyVvlm/rwCY9Jx378V1IuRx+S8F/GFuVozHD4XVaoSTtpCWPBQNSKDXgaIIKDowIDAQABAoIBACpMXj6ht1LMJXOldPbWhwkKYjFl+pdZxNGRSkfKvzDbbY2chhRcyp8J4vuG2ApY/rftxVIgd8+Wun1/TP3ppEE43aKAJzubqb35WBr9iGSfOZpZy7MiRUQN5kPBAfEQY20OyiIj0hSez74PVD283eGgbMfpU4Rsn8+JOgBaZPkbPViJLJY8PyHU6vwWw60dye1iJTz9yuBtoEqY0XKxnLaVXTQaWx0Te+VYU8twxDgXFWRaXtHuk7xnxOkCZDLrzIvuOYa5lsLoT8K62LDeXbyHBPhbdW0j4ZYzAOTsaUWpjuJzef9aj3JJdfyADiqb5iu6HHksvKzkZEau34zjilECgYEA/c8ZJm62uJMHNssTJYiLRw89l5hYwIZ/1TXdFRF8+xrTin5opYjpscSTO5bY2IYqLx2xuPiJCY1eGGB9L/RtkaVh51ySzq0d+4zpPIRKFcOOgdxHwlgoCgIhQECyfJZNMFGBUIlPXZ/phvXOXRvWFzDPhqThenVG2QzF+wLP0AUCgYEA3zfviQFJ1FOKJMozYO3tUZFmsIrAcO9hfuE7uuWz0Fw2m1XiwxjuOr1RbsSsh/lKke2h4tiGrlfiFhwCpIp91NkVTFrtFOQxbDxkYLkFiWkZDkOaK9YhKMa2cgEm3p+RGawokjbm51LKf+cbYN9xGaAe3y2WzIE4kNpfWE4SXYcCgYEAoagcrrvpqZoMCDxED63ud+4fHsUsEkQYe6Z5EAg5gH5PqnBlGrofjthTpqqnpxGdILFbFyNFtU3TVtduJPMcLp4Vw5TU9MqSxDu1+pOP1FjgFZpGImSf6+/7Wb9bb7sToujm4nLymAFYblt1exxVuiOeqnWuH58+5tQZ7YyW7DkCgYEAl7WuqZEkmpiEpWh/7vsGdo+6GXbUQG2R9+gg7m+7/HsP6hc/XZYOJAIT3JLzKB84nWHCyyiasNeuI5S5/xbZWtaH8TNDOxW0uXl6R3q41qGFk/pCSFTqiIo16dn6jwgoWCh4EpgZ61KLqs5p/zcd6Wq4ULrtaOTSizC/6IZ3WPUCgYEA6xCJy3+ICCgr8/c7hfd2Ylb3aOsXIffdgALhXjDcrNUCqgB4R+S3WReAwrABemQGl4tySQE/1f3Ru7SzMMciFogGyJ/YSXqSi6Y8oDD7MqlKPiWlN6WY1nSRMlLbkUOqpA5JaDM0kcmXjZpBBQr277GOnh9uKN8zUy5xoptctxI=
|
||||
signingKey: yOEpD2+cPldXc2urGuU+szunm7fddRa8xew2uVjaxifRcVzNKhSERpOefjrXaky7PcKmSmTsH/5ZFtcrh1uzqg==
|
||||
encryptionKey: MIIEpAIBAAKCAQEAxnE9Htwto+2fVmonkG9/DxNre33n7kjfrZU73JcHmpKhPlRFirig5T8rs2MaTq1R72/8nGBJuSxsz1PnexI3die39pY1OFYfZCZ59LbT7uH/xHcvkVrK2n50Q41KbbGT9BEzyW+XPkKPDpTq3/igYP+yUQgoWLfMwxCCLKXDe6qUC0fuIxR80fvj3XvorB5dnAiQ01JkH4PtCV1OWT6ZpLGhzcYxsxTHozd6LdMOC7wgGhW26dOSa/vZ1t5avbewFVIz0qfqBncunb7tjO4xa3xVYaA5jBbixDQUYFjVzW7cksrrN4CFNBDBGJ8PLS80MuMg0OG0O+/Qi1mbGb2mUQIDAQABAoIBACODAD0VidVcILeGJ65hRYudHg7raSXrRJv7qMrA/EtdEh3lVsyMXb6on1lq0rphqdf/YmVZldfda1tu2G3dxK8QTIuENeHvB48Uk56HWUXWi77M1WZdqQ+QsZ2lGzymGqQCsBHMNnSd1Jv3alDKXWj+WRrHKvE1cx81RRZYU7M9cpurnF5YNjO7L+7sMxUA9uAQGbe3kDVzrygraicLYQpxSNHytName0A+k3ug0qer4I6PmZhhJykkz6MD3dz/n625HSS+X+TuTm52T2b87tL27xXmSnUK7eYWjZ1vQlP1fWmqnac6u5LApUZaRi0tTjtefSjRW4jr1q20RqOp1kECgYEA7Onh3zM9ejATsjW6WISGKiBPci0D7DUbIuGuJrdQRadlkZzmeQ/VOYAuxIQD4GnQDRhM1FyxsqiAWkJOyCLFiMmsgIEyW9/eRhF8NlCVU+DA/fxy9EagfBbVsgiSBwOex24hPXIVYlaHkLAloNoD4bpw0pQZSDWXr+xvMFNwoGsCgYEA1m3sWA/e8ZuXForaUOoJzBU9nwC79bXv2UNktsVvBlQ1o9pbjoYDcVoAPwuBVUL1UwqDNMzPdhDBKBjZmCyjS6zlYD5ZKjF2m8iTyc4QcaBCdM0iyQpSXTmrfMx+hK1aWwL1p8ssNcednp5ExSAaTyNNGVdbtddiQ6/KMPmhUzMCgYEAwDjLsUNr4BXeBTweo+9yw/9PNn5brm0wRU8C9BrMIJe/izPYs+UqxerBB2Vtl8mCqv1KaQuEika5TYJ7VVsRFvk641DwQScUu5k4RQGBB3tWWz1XL+eWEticLkVR5isDyyAKDEbiHtXCTJz/CtGZUK7rF5BeKv6AwpZ9aKJqwV0CgYEAqXDlQNURu+PR6TtBtoypvz3NmraO0GO7KvipPhAXYm3qkRa8IIxfbhPLfAYQZhpqFvuIoJFzIn2s1I2GbExhoSv3eSzrcn7xlbpSpjYSImeb/AYZhbmFSiuHCi/hjeAaNS7KhZPz1G9vaubvusFaaMyhYPP6AWA4QvpHEJpB06cCgYBqR6/7d2hQiq4MJUrBEzLwG4ijnPeq+UVLQjE598hVIj+8UhRZRRcNWVEJxfcIL1v6Bpo8XISDNVRb30T9bPGVnXvC1jutTUbXKUB1/8iXuyH3IVieobch+bGd4v7ehH/lI7vzB6hjJpFzHopfFUn4wacSQdcFi3tRAwUB/L0S/w==
|
||||
types : ["tree", "file"]
|
||||
- peerId: 12D3KooWLtuKtCPBYrFJV1NdejiCr2s614ppe9rmUXnkTHtAUD5U
|
||||
- peerId: 12D3KooWBgHmDqtXH9SrZfAmwCFsD8LZhTD5dg5wkhdbqFoS8GBN
|
||||
address: 127.0.0.1:4431
|
||||
signingKey: 07JMoW5cQUtGO9nNIGQo9e99b7Wf/4YvTtNEA0lt4gCkmhwB1EB9ay+kitxVJJgmdyGLxbUUlGqwXsAj0zlHWw==
|
||||
encryptionKey: MIIEpAIBAAKCAQEA7cA6J/icl8wseeXkt8oJr5AeYadUAG5EdCOdHj4S/Z7ivff4MOIKAeQITpq+rqhmXxOePYXSpQXE20Y9PW9tuw4gzOuq1ylSG/MWMcLDH1eIxg66rnmUqUbdiW4GGJjVjc9jvN0Up+MfSrUF6fM0jWTFoXVJQIeQQGERCIYjFzjfBl1xYvPghdxNgei/K5ZGYRggT28143XdIH4KTXGtp51hAKoyY9eCqYMtm9wvjxazhPVxO2CsYaqMxBLshY3jfHNqJnx8u6+h4Bl4uUcdbLNUgMcEgk7ehbQp2K0CqNoKXxbCTI6V57UVcJHDIaO5B6FyR6BguzHHNPJ4yd3q9wIDAQABAoIBAQCm2Mf3VRlPzhFIWnVwJXE2q8Umcu8Yfkm712Jj3twk8GPfPS4H4Bl1yjmqMB6xI6zz/CiItGlnNe04lMpVWuV+6CNMq/ZwmKbuxmFE+pFEZYGuvJd16gzR3tGJqJTOnjMAGhK8b8oXJ+TF4NQNooe20ol/DXgiuQAargPuH3RwzjYmF3N8VI4KUc3LaG4TwVXn4LwPOxrQSnfwJlZwLml1HAKOV0qcG0mXX6ZXOpoVhEoRPdQyUHc8ZW+53Agbtind7bYh5TsMVDFUrcgNwnwTOsWjil049la1IJO2uMRluacKlrtyzEp6zqrW8ZJO7mYAO69x4WyGqf2ZgIdA6djBAoGBAPqRHWAIgPa80eXbwCYkRtUG/ONBsQGi7+wm6nyhkXvNXJeokgH2DCgLH2+fW2scfOJuZc9r5WftEjOBvNfr2LDcwdyTSTh21WYcPSZx9HDf2d5/SWTcjNcyU0b5qfWIUKi/Zm9UY7r3X7yMA5dUD/cvu1PBJ5NWFrK1Gm2ph44dAoGBAPLn+LkHweU0fbxQq/76T5yVVpMKUaE9xwrJlUxEDPAQGnLPbFg4JeUt/YPhsOV85W4c4oQE+uFZrF0uf+1fEnS6MOJ+sq668upzC2hBp1B5138wM7615v1rvXVVH6qXfFop67FdBzPHt1NAN43mEIBZHTQ5hSVXFlYSZp9mxuEjAoGBAKCzUVO2IIAeub/iIGpV+dfGk4ptJ0kVZyreCqXEObpdC3V496uqUkGcYJ0GZ2ta6f2PMFzHpmnw8it2mdchu+gyrWL6U4uTK2pB0jZF/7Ak4WaB3GCD0xBxhleO6CJBOvn/R4M/bHcNEKmsYuE7WMIAKvScfPVR0VzsKfcLM5VBAoGAVvWg32zdh1bBZLdku8WU1rPH6KAbFSRuq3f7UPBTyWWaclu7p+GB/4f1aE9V6vJJmKASn7zArAhUYo+REMOmcc9uTMea5F7dM/23qb1HTtIvycLR44ZviW4Wx3iP+5x70jOLw1VQjMME6HLm8I/afHhqshWdiv6ganPv9UTwEg0CgYBSDi2dqg8F7ij5CN+LMDLSn3b8GCw+7efGIt7imm/O2V/FlHD40IA6qGg6DXNQrnoZQt94nMb1cZEvm1dxi6rmQNrhCyoMogAaPqgFhZGq1OjmhVZiXFUWy4WAcjdzFc9wZd3/XtaofRKHLK+ngTFhhVApKypLk3Rg9bCAAjzyVg==
|
||||
signingKey: l6LFiKqr4ZHgcPbL+DR7KwMbzImufQPFgpoHOJ/nvfUbpb76DCADHuT1I4gIs+XByglnY1KV8jbMfW64XRW5XQ==
|
||||
encryptionKey: MIIEowIBAAKCAQEA4ltcn1AH048bMXcKOOW7/E0TZYPxL3OtcHXWHSAZjeeTA/rc45G2eaNgyY7Ji+feLtZERbXNWGFBdNp31NHDYZAYwbZmjEqTEgV4yVx7BQP3VBEzglTJaNLTf+XIJnVAEkoHS6ogjC0oXTM6paHu64EitoOCzF9zqL023swjE3HU0dm2xwsUdGnKeO5nPMso/6e3VMavkKnFmvB965ECCBujtediP4lVdIABNVtoMHCoeI5Sn+m7TKqJSyDOIEMhHT3orYUNZWVeAHE1YTM2cI5tSnDZP80CHZ674Z/bKL7Jaznmq87mVt1h9Use2EkxR07/dJuTGvFOos4jHoiR9QIDAQABAoIBAHAr8EluooI/j61CnYk2p6LPG0aaTQJD4/YwHuwOBTviP2OghKgthGzg/szDerNfMyaoveqBvoIGqCZdQTbwwE7v1qTgXA83wYwTtBitQLVqkr1RTOJQXAMbPv5Jg5czUY3+q4DejQSKOE9/XJfKGJkSRH6Hy2C2CJ3dLnzYUqWGO3t70RLT1/sC6p6w3lXdy3dKZGkoR2wva+HXQxVrP8X5HOResXgNZwgMHt9KF1QHVCcySKYiEAefEKTSdKD2fOd4FxLgp3zWpvH3jrX0zd/DqzTlFD5Ns6Ayp2sIfHVp3sn99DZZM6DauMepQKtoSCnXZ+qKhekAwNVJnsVQkSECgYEA4spY9araeFUSl4uXCUQOpCkSshYOPRYN6sBbHsx8tV2eQtCT+5SuNYmzur3c5bkiraGEab8rZfGdDL6fLxQyaqbOmN31Db5kNh/2X+sRnxkak8lsROUWQZRF9doH73FDv6ZlI3V/JicZlOUCfN5BYT+x74R4/c1YXfyuD1J9gr0CgYEA/4K4SDwZUY4bOVCmKQz0OM+RW4PAAH6LHKenTAZNTeDNFFxc2nqnzRGMEKZTDGy0kbT5mBhBHFgShXcAiKxc5/MGkpt8Jcq6Fr5KGU9aZtYKji6mwMTsUndPNQydh3vOt5pOmcuMM6ovanNTvI8k6Qo53OY1IpO5CfOROu0hm5kCgYBnWsYd92YnDsYxUEldzKlLgPhnNov4pNNk15LvP0vaL7cPRhUaw1B9T6scAKjp/GxkasZ4lsnFZM4o37qV7wNm/WwL2KN0Rv9Od1SFtBBMzFkDXvk7kJeK/XLAr0OMiLbSYZeYCFUQ4yLSa2et1nA/TJLf0CR/rhSGiMAedX6DlQKBgAx1137OT33GrFUzNacy1oYeuTv5RNfBVA9lrabrd8GggN/JUU3mRWCexnHZaptkgbnJVZKxPBuhv+V6VDBWF4HIPD3SD0/YfxK03PA3CnWRYppkdAValRvAbcBsiRIeW4pgoAyn/IJYfk92qFK9uFMVCJVZNKYnBhMSKbbx8X2hAoGBAKwvzyAImbNB+493q1R/lSayxzG76bRJ/EseiTqwIec9c4C+Bd/sVXR+Re+xZb0FI/va1bz5CrduTzLSKBmf/+0lzl0MJvWY2+SXfGYdbl4+TTyqgDDfwqW0Tj8pDimye2BneyTmXko1rF+2Sxen7kMXnJLwpqjwZ6TZJuoqeK8q
|
||||
types : ["tree", "file"]
|
||||
- peerId: 12D3KooWDCypXSyN6ppuMZGxVnBd1ZQCMV4y7Bn187S4duYmf8rA
|
||||
- peerId: 12D3KooWASsipDzkridiMBmE7VSqp8yZvGWPY1VqySgMSZk6tsiL
|
||||
address: 127.0.0.1:4432
|
||||
signingKey: SGyNE0dFaQgtgNuzdcO7LB+TEz9VHAOtlQLk6WWkrkQyXiZV3casg8Q2/4PO1Oylc8Fu72RU001Hclj5JCbiLw==
|
||||
encryptionKey: MIIEpAIBAAKCAQEA0k3mw4FyexRkLgLjHzYs4Ppeyv6r9ZrP00imNf15JTuM8ajMx5oJX7JQTm8KOLRJjUdZZAd5Gtp0ezfYAQK1ZjEWwCmfp8j8FBgJIDSLpjxl88SXMLgATXYfhklnQvKlQjs/X3Ka4zdTrav2tMH9IAo6TSNZhlPQNsUory1SGHs+KqHv4p0sG8oWuKYhfBj8rWHQdUVptkIBKgojFDeJJD04Tbf9kUakbK/8KuXB6zF5H4WN3p4rMMwkClyTGeYO4LDg5TzVn8NnUi3/b/vO/3us1G/TMoRe/6umUfpQxrwo+7S2T6A4YwetWRp6xALLhp+HfAWnn0lA/D8/w1WpKwIDAQABAoIBAQC5cdQxRa5rddm48PbSCPWeFWkNW3DLDI6CYyedqDvxZwer+QtKXzww1I4X+7ZptiC9odLjb+uMkGHyXZXtnjPTPyounQWZ8JLILUGu0mbqWYwVXp9raHVr2OOHiKaz1D+BnbkOM4L9JUZ2eJL9ZaoNXLd4WdmRp8qM4WI0xqQDzOANx2HhyL/+dJmQeIUND+pdeH+Z+fYowU3ho32txNvBnMXQhF1T5K9i1VO5W49RAjIRbENsT+paPGKbNubDHRt1j36ktK4eC4HSdgv8tccdsGyrEiIbAt1XsTZfM8ie4D3A8RhSxiTC6Fkgv6vIm+iFTLzBFZKesOBcd8sfKeyBAoGBAOts5PQQJhldPDzlbnqzxMOR98WHbkVZjCqWSkNA34vqyFuPcRuX0rHK/qpg23ilbUP0fGMDTGgFzTt51FZLL16SXyRfjNhzjdmryryeddQwbp92ta2GEgnU6t1FyCuSCtcLDKJd/D9A9dC5UI6z+ES4TOnbR3nakXK9t4cUOFthAoGBAOSu+wL+SEA5erR+m3LpOsELK68CCJQPxn3VpoVfJZawgF+fEoXVMLTERxJput1+ADomIEdNc9ex86TjKx9gJ4piNHscRPFeT/AgESOIGHLOc1gk2DPqNj6wBIarUJQ9t4KcHScboh1dTPJeqqv2NSwIiLQoqFUIhfKZLnrW3zwLAoGBAJh0hC+o5YM3ZXLqAIllMN6VACbidP5j5ukNOjojIKCzAdyJH24G+2I3WoNrBbUzK3b+NC7KTAhw+V6ynlbjiWFs2D/twH/LFOkI3tkWpKcsVfbeIPimAbhsMUvpjJ7qjCqF9UCQLHGp14W6+/ftg7C8yNIINlkquVXclaTb60MBAoGAPqmL8ogG+EJH00mWAujRxq/u6meePiQMedKfbJBj1mTK6GjIRI/kZsQZzXvXTnYGTejAk4kvov0KDDaLTG+mpg6+3rUiVxlGwj+nMptKR7s2dAK0k5UsBAVrWBN9YwF+VXW9r0etJmq4ePljvvcaHtS/0M4LQjGxsoYy7EoQpX0CgYAhnf0McB7F1MxSjB0soMNv/v5utVzVihS3re2yKNdkI/YUEMB+yU3Q4gh+OljjBM6Y5To3BsQBAx4l2CysMKFHjIE/5AtdbvIS+chZZqB3vcZXSayvX8P1Z1uFdw/saiO2cRDJmR+TxaOPa2C9SzDoNTACthwLErHfzvEvVroKmw==
|
||||
types : ["tree", "file"]
|
||||
space:
|
||||
gcTTL: 60
|
||||
syncPeriod: 10
|
||||
syncPeriod: 11
|
||||
storage:
|
||||
path: db
|
||||
metric:
|
||||
|
||||
@ -5,31 +5,33 @@ grpcServer:
|
||||
- 127.0.0.1:4431
|
||||
tls: false
|
||||
account:
|
||||
peerId: 12D3KooWLtuKtCPBYrFJV1NdejiCr2s614ppe9rmUXnkTHtAUD5U
|
||||
peerKey: 07JMoW5cQUtGO9nNIGQo9e99b7Wf/4YvTtNEA0lt4gCkmhwB1EB9ay+kitxVJJgmdyGLxbUUlGqwXsAj0zlHWw==
|
||||
signingKey: 07JMoW5cQUtGO9nNIGQo9e99b7Wf/4YvTtNEA0lt4gCkmhwB1EB9ay+kitxVJJgmdyGLxbUUlGqwXsAj0zlHWw==
|
||||
encryptionKey: MIIEpAIBAAKCAQEA7cA6J/icl8wseeXkt8oJr5AeYadUAG5EdCOdHj4S/Z7ivff4MOIKAeQITpq+rqhmXxOePYXSpQXE20Y9PW9tuw4gzOuq1ylSG/MWMcLDH1eIxg66rnmUqUbdiW4GGJjVjc9jvN0Up+MfSrUF6fM0jWTFoXVJQIeQQGERCIYjFzjfBl1xYvPghdxNgei/K5ZGYRggT28143XdIH4KTXGtp51hAKoyY9eCqYMtm9wvjxazhPVxO2CsYaqMxBLshY3jfHNqJnx8u6+h4Bl4uUcdbLNUgMcEgk7ehbQp2K0CqNoKXxbCTI6V57UVcJHDIaO5B6FyR6BguzHHNPJ4yd3q9wIDAQABAoIBAQCm2Mf3VRlPzhFIWnVwJXE2q8Umcu8Yfkm712Jj3twk8GPfPS4H4Bl1yjmqMB6xI6zz/CiItGlnNe04lMpVWuV+6CNMq/ZwmKbuxmFE+pFEZYGuvJd16gzR3tGJqJTOnjMAGhK8b8oXJ+TF4NQNooe20ol/DXgiuQAargPuH3RwzjYmF3N8VI4KUc3LaG4TwVXn4LwPOxrQSnfwJlZwLml1HAKOV0qcG0mXX6ZXOpoVhEoRPdQyUHc8ZW+53Agbtind7bYh5TsMVDFUrcgNwnwTOsWjil049la1IJO2uMRluacKlrtyzEp6zqrW8ZJO7mYAO69x4WyGqf2ZgIdA6djBAoGBAPqRHWAIgPa80eXbwCYkRtUG/ONBsQGi7+wm6nyhkXvNXJeokgH2DCgLH2+fW2scfOJuZc9r5WftEjOBvNfr2LDcwdyTSTh21WYcPSZx9HDf2d5/SWTcjNcyU0b5qfWIUKi/Zm9UY7r3X7yMA5dUD/cvu1PBJ5NWFrK1Gm2ph44dAoGBAPLn+LkHweU0fbxQq/76T5yVVpMKUaE9xwrJlUxEDPAQGnLPbFg4JeUt/YPhsOV85W4c4oQE+uFZrF0uf+1fEnS6MOJ+sq668upzC2hBp1B5138wM7615v1rvXVVH6qXfFop67FdBzPHt1NAN43mEIBZHTQ5hSVXFlYSZp9mxuEjAoGBAKCzUVO2IIAeub/iIGpV+dfGk4ptJ0kVZyreCqXEObpdC3V496uqUkGcYJ0GZ2ta6f2PMFzHpmnw8it2mdchu+gyrWL6U4uTK2pB0jZF/7Ak4WaB3GCD0xBxhleO6CJBOvn/R4M/bHcNEKmsYuE7WMIAKvScfPVR0VzsKfcLM5VBAoGAVvWg32zdh1bBZLdku8WU1rPH6KAbFSRuq3f7UPBTyWWaclu7p+GB/4f1aE9V6vJJmKASn7zArAhUYo+REMOmcc9uTMea5F7dM/23qb1HTtIvycLR44ZviW4Wx3iP+5x70jOLw1VQjMME6HLm8I/afHhqshWdiv6ganPv9UTwEg0CgYBSDi2dqg8F7ij5CN+LMDLSn3b8GCw+7efGIt7imm/O2V/FlHD40IA6qGg6DXNQrnoZQt94nMb1cZEvm1dxi6rmQNrhCyoMogAaPqgFhZGq1OjmhVZiXFUWy4WAcjdzFc9wZd3/XtaofRKHLK+ngTFhhVApKypLk3Rg9bCAAjzyVg==
|
||||
peerId: 12D3KooWBgHmDqtXH9SrZfAmwCFsD8LZhTD5dg5wkhdbqFoS8GBN
|
||||
peerKey: l6LFiKqr4ZHgcPbL+DR7KwMbzImufQPFgpoHOJ/nvfUbpb76DCADHuT1I4gIs+XByglnY1KV8jbMfW64XRW5XQ==
|
||||
signingKey: l6LFiKqr4ZHgcPbL+DR7KwMbzImufQPFgpoHOJ/nvfUbpb76DCADHuT1I4gIs+XByglnY1KV8jbMfW64XRW5XQ==
|
||||
encryptionKey: MIIEowIBAAKCAQEA4ltcn1AH048bMXcKOOW7/E0TZYPxL3OtcHXWHSAZjeeTA/rc45G2eaNgyY7Ji+feLtZERbXNWGFBdNp31NHDYZAYwbZmjEqTEgV4yVx7BQP3VBEzglTJaNLTf+XIJnVAEkoHS6ogjC0oXTM6paHu64EitoOCzF9zqL023swjE3HU0dm2xwsUdGnKeO5nPMso/6e3VMavkKnFmvB965ECCBujtediP4lVdIABNVtoMHCoeI5Sn+m7TKqJSyDOIEMhHT3orYUNZWVeAHE1YTM2cI5tSnDZP80CHZ674Z/bKL7Jaznmq87mVt1h9Use2EkxR07/dJuTGvFOos4jHoiR9QIDAQABAoIBAHAr8EluooI/j61CnYk2p6LPG0aaTQJD4/YwHuwOBTviP2OghKgthGzg/szDerNfMyaoveqBvoIGqCZdQTbwwE7v1qTgXA83wYwTtBitQLVqkr1RTOJQXAMbPv5Jg5czUY3+q4DejQSKOE9/XJfKGJkSRH6Hy2C2CJ3dLnzYUqWGO3t70RLT1/sC6p6w3lXdy3dKZGkoR2wva+HXQxVrP8X5HOResXgNZwgMHt9KF1QHVCcySKYiEAefEKTSdKD2fOd4FxLgp3zWpvH3jrX0zd/DqzTlFD5Ns6Ayp2sIfHVp3sn99DZZM6DauMepQKtoSCnXZ+qKhekAwNVJnsVQkSECgYEA4spY9araeFUSl4uXCUQOpCkSshYOPRYN6sBbHsx8tV2eQtCT+5SuNYmzur3c5bkiraGEab8rZfGdDL6fLxQyaqbOmN31Db5kNh/2X+sRnxkak8lsROUWQZRF9doH73FDv6ZlI3V/JicZlOUCfN5BYT+x74R4/c1YXfyuD1J9gr0CgYEA/4K4SDwZUY4bOVCmKQz0OM+RW4PAAH6LHKenTAZNTeDNFFxc2nqnzRGMEKZTDGy0kbT5mBhBHFgShXcAiKxc5/MGkpt8Jcq6Fr5KGU9aZtYKji6mwMTsUndPNQydh3vOt5pOmcuMM6ovanNTvI8k6Qo53OY1IpO5CfOROu0hm5kCgYBnWsYd92YnDsYxUEldzKlLgPhnNov4pNNk15LvP0vaL7cPRhUaw1B9T6scAKjp/GxkasZ4lsnFZM4o37qV7wNm/WwL2KN0Rv9Od1SFtBBMzFkDXvk7kJeK/XLAr0OMiLbSYZeYCFUQ4yLSa2et1nA/TJLf0CR/rhSGiMAedX6DlQKBgAx1137OT33GrFUzNacy1oYeuTv5RNfBVA9lrabrd8GggN/JUU3mRWCexnHZaptkgbnJVZKxPBuhv+V6VDBWF4HIPD3SD0/YfxK03PA3CnWRYppkdAValRvAbcBsiRIeW4pgoAyn/IJYfk92qFK9uFMVCJVZNKYnBhMSKbbx8X2hAoGBAKwvzyAImbNB+493q1R/lSayxzG76bRJ/EseiTqwIec9c4C+Bd/sVXR+Re+xZb0FI/va1bz5CrduTzLSKBmf/+0lzl0MJvWY2+SXfGYdbl4+TTyqgDDfwqW0Tj8pDimye2BneyTmXko1rF+2Sxen7kMXnJLwpqjwZ6TZJuoqeK8q
|
||||
apiServer:
|
||||
port: "8081"
|
||||
listenAddrs:
|
||||
- 127.0.0.1:8081
|
||||
tls: false
|
||||
nodes:
|
||||
- peerId: 12D3KooWLn13hDrZ6YRGM517fHf2zS6qhPNRu18inLMpRqn1YGKu
|
||||
- peerId: 12D3KooWPuwdqpDQxWhD2Vh4yskx2T5VMrwdpTZLfACzgsGfQfNy
|
||||
address: 127.0.0.1:4430
|
||||
signingKey: 3mzfKBWtn7mitFEgq8u4eysWOJ6ySbUs49irfHwcuOmi1YMpobz9anoqd4yaT1owZiRPYXqx5k2Z4sNVRE3kXA==
|
||||
encryptionKey: MIIEpQIBAAKCAQEA3U7b4w9JTKE3TLM1WQ5iqdLbvUuozMp/hDEg7S15Gr6wrtLomMSBkfmVQ3Cu+CHdxAFqUFClItYlSFgtZWIFiSiQxCeaN2dmgczd9T4TlRAw6y6uJXtT9r7FIgizPP4B0/tnzPI6yYgpdwzCV2nRSjw3mMr5Nav3QYs18kYrJ1/Np2Wob5HOoRTUD++pPrToevTb7GNL/irrC8wXSE7oU6S7ix6Nh9vzEHg/V5FONBF/wWD/ri7Gy0j0qgUQ+gjxLWKr8xPDnRAve13zzo+54lGCyVvlm/rwCY9Jx378V1IuRx+S8F/GFuVozHD4XVaoSTtpCWPBQNSKDXgaIIKDowIDAQABAoIBACpMXj6ht1LMJXOldPbWhwkKYjFl+pdZxNGRSkfKvzDbbY2chhRcyp8J4vuG2ApY/rftxVIgd8+Wun1/TP3ppEE43aKAJzubqb35WBr9iGSfOZpZy7MiRUQN5kPBAfEQY20OyiIj0hSez74PVD283eGgbMfpU4Rsn8+JOgBaZPkbPViJLJY8PyHU6vwWw60dye1iJTz9yuBtoEqY0XKxnLaVXTQaWx0Te+VYU8twxDgXFWRaXtHuk7xnxOkCZDLrzIvuOYa5lsLoT8K62LDeXbyHBPhbdW0j4ZYzAOTsaUWpjuJzef9aj3JJdfyADiqb5iu6HHksvKzkZEau34zjilECgYEA/c8ZJm62uJMHNssTJYiLRw89l5hYwIZ/1TXdFRF8+xrTin5opYjpscSTO5bY2IYqLx2xuPiJCY1eGGB9L/RtkaVh51ySzq0d+4zpPIRKFcOOgdxHwlgoCgIhQECyfJZNMFGBUIlPXZ/phvXOXRvWFzDPhqThenVG2QzF+wLP0AUCgYEA3zfviQFJ1FOKJMozYO3tUZFmsIrAcO9hfuE7uuWz0Fw2m1XiwxjuOr1RbsSsh/lKke2h4tiGrlfiFhwCpIp91NkVTFrtFOQxbDxkYLkFiWkZDkOaK9YhKMa2cgEm3p+RGawokjbm51LKf+cbYN9xGaAe3y2WzIE4kNpfWE4SXYcCgYEAoagcrrvpqZoMCDxED63ud+4fHsUsEkQYe6Z5EAg5gH5PqnBlGrofjthTpqqnpxGdILFbFyNFtU3TVtduJPMcLp4Vw5TU9MqSxDu1+pOP1FjgFZpGImSf6+/7Wb9bb7sToujm4nLymAFYblt1exxVuiOeqnWuH58+5tQZ7YyW7DkCgYEAl7WuqZEkmpiEpWh/7vsGdo+6GXbUQG2R9+gg7m+7/HsP6hc/XZYOJAIT3JLzKB84nWHCyyiasNeuI5S5/xbZWtaH8TNDOxW0uXl6R3q41qGFk/pCSFTqiIo16dn6jwgoWCh4EpgZ61KLqs5p/zcd6Wq4ULrtaOTSizC/6IZ3WPUCgYEA6xCJy3+ICCgr8/c7hfd2Ylb3aOsXIffdgALhXjDcrNUCqgB4R+S3WReAwrABemQGl4tySQE/1f3Ru7SzMMciFogGyJ/YSXqSi6Y8oDD7MqlKPiWlN6WY1nSRMlLbkUOqpA5JaDM0kcmXjZpBBQr277GOnh9uKN8zUy5xoptctxI=
|
||||
signingKey: yOEpD2+cPldXc2urGuU+szunm7fddRa8xew2uVjaxifRcVzNKhSERpOefjrXaky7PcKmSmTsH/5ZFtcrh1uzqg==
|
||||
encryptionKey: MIIEpAIBAAKCAQEAxnE9Htwto+2fVmonkG9/DxNre33n7kjfrZU73JcHmpKhPlRFirig5T8rs2MaTq1R72/8nGBJuSxsz1PnexI3die39pY1OFYfZCZ59LbT7uH/xHcvkVrK2n50Q41KbbGT9BEzyW+XPkKPDpTq3/igYP+yUQgoWLfMwxCCLKXDe6qUC0fuIxR80fvj3XvorB5dnAiQ01JkH4PtCV1OWT6ZpLGhzcYxsxTHozd6LdMOC7wgGhW26dOSa/vZ1t5avbewFVIz0qfqBncunb7tjO4xa3xVYaA5jBbixDQUYFjVzW7cksrrN4CFNBDBGJ8PLS80MuMg0OG0O+/Qi1mbGb2mUQIDAQABAoIBACODAD0VidVcILeGJ65hRYudHg7raSXrRJv7qMrA/EtdEh3lVsyMXb6on1lq0rphqdf/YmVZldfda1tu2G3dxK8QTIuENeHvB48Uk56HWUXWi77M1WZdqQ+QsZ2lGzymGqQCsBHMNnSd1Jv3alDKXWj+WRrHKvE1cx81RRZYU7M9cpurnF5YNjO7L+7sMxUA9uAQGbe3kDVzrygraicLYQpxSNHytName0A+k3ug0qer4I6PmZhhJykkz6MD3dz/n625HSS+X+TuTm52T2b87tL27xXmSnUK7eYWjZ1vQlP1fWmqnac6u5LApUZaRi0tTjtefSjRW4jr1q20RqOp1kECgYEA7Onh3zM9ejATsjW6WISGKiBPci0D7DUbIuGuJrdQRadlkZzmeQ/VOYAuxIQD4GnQDRhM1FyxsqiAWkJOyCLFiMmsgIEyW9/eRhF8NlCVU+DA/fxy9EagfBbVsgiSBwOex24hPXIVYlaHkLAloNoD4bpw0pQZSDWXr+xvMFNwoGsCgYEA1m3sWA/e8ZuXForaUOoJzBU9nwC79bXv2UNktsVvBlQ1o9pbjoYDcVoAPwuBVUL1UwqDNMzPdhDBKBjZmCyjS6zlYD5ZKjF2m8iTyc4QcaBCdM0iyQpSXTmrfMx+hK1aWwL1p8ssNcednp5ExSAaTyNNGVdbtddiQ6/KMPmhUzMCgYEAwDjLsUNr4BXeBTweo+9yw/9PNn5brm0wRU8C9BrMIJe/izPYs+UqxerBB2Vtl8mCqv1KaQuEika5TYJ7VVsRFvk641DwQScUu5k4RQGBB3tWWz1XL+eWEticLkVR5isDyyAKDEbiHtXCTJz/CtGZUK7rF5BeKv6AwpZ9aKJqwV0CgYEAqXDlQNURu+PR6TtBtoypvz3NmraO0GO7KvipPhAXYm3qkRa8IIxfbhPLfAYQZhpqFvuIoJFzIn2s1I2GbExhoSv3eSzrcn7xlbpSpjYSImeb/AYZhbmFSiuHCi/hjeAaNS7KhZPz1G9vaubvusFaaMyhYPP6AWA4QvpHEJpB06cCgYBqR6/7d2hQiq4MJUrBEzLwG4ijnPeq+UVLQjE598hVIj+8UhRZRRcNWVEJxfcIL1v6Bpo8XISDNVRb30T9bPGVnXvC1jutTUbXKUB1/8iXuyH3IVieobch+bGd4v7ehH/lI7vzB6hjJpFzHopfFUn4wacSQdcFi3tRAwUB/L0S/w==
|
||||
types : ["tree", "file"]
|
||||
- peerId: 12D3KooWLtuKtCPBYrFJV1NdejiCr2s614ppe9rmUXnkTHtAUD5U
|
||||
- peerId: 12D3KooWBgHmDqtXH9SrZfAmwCFsD8LZhTD5dg5wkhdbqFoS8GBN
|
||||
address: 127.0.0.1:4431
|
||||
signingKey: 07JMoW5cQUtGO9nNIGQo9e99b7Wf/4YvTtNEA0lt4gCkmhwB1EB9ay+kitxVJJgmdyGLxbUUlGqwXsAj0zlHWw==
|
||||
encryptionKey: MIIEpAIBAAKCAQEA7cA6J/icl8wseeXkt8oJr5AeYadUAG5EdCOdHj4S/Z7ivff4MOIKAeQITpq+rqhmXxOePYXSpQXE20Y9PW9tuw4gzOuq1ylSG/MWMcLDH1eIxg66rnmUqUbdiW4GGJjVjc9jvN0Up+MfSrUF6fM0jWTFoXVJQIeQQGERCIYjFzjfBl1xYvPghdxNgei/K5ZGYRggT28143XdIH4KTXGtp51hAKoyY9eCqYMtm9wvjxazhPVxO2CsYaqMxBLshY3jfHNqJnx8u6+h4Bl4uUcdbLNUgMcEgk7ehbQp2K0CqNoKXxbCTI6V57UVcJHDIaO5B6FyR6BguzHHNPJ4yd3q9wIDAQABAoIBAQCm2Mf3VRlPzhFIWnVwJXE2q8Umcu8Yfkm712Jj3twk8GPfPS4H4Bl1yjmqMB6xI6zz/CiItGlnNe04lMpVWuV+6CNMq/ZwmKbuxmFE+pFEZYGuvJd16gzR3tGJqJTOnjMAGhK8b8oXJ+TF4NQNooe20ol/DXgiuQAargPuH3RwzjYmF3N8VI4KUc3LaG4TwVXn4LwPOxrQSnfwJlZwLml1HAKOV0qcG0mXX6ZXOpoVhEoRPdQyUHc8ZW+53Agbtind7bYh5TsMVDFUrcgNwnwTOsWjil049la1IJO2uMRluacKlrtyzEp6zqrW8ZJO7mYAO69x4WyGqf2ZgIdA6djBAoGBAPqRHWAIgPa80eXbwCYkRtUG/ONBsQGi7+wm6nyhkXvNXJeokgH2DCgLH2+fW2scfOJuZc9r5WftEjOBvNfr2LDcwdyTSTh21WYcPSZx9HDf2d5/SWTcjNcyU0b5qfWIUKi/Zm9UY7r3X7yMA5dUD/cvu1PBJ5NWFrK1Gm2ph44dAoGBAPLn+LkHweU0fbxQq/76T5yVVpMKUaE9xwrJlUxEDPAQGnLPbFg4JeUt/YPhsOV85W4c4oQE+uFZrF0uf+1fEnS6MOJ+sq668upzC2hBp1B5138wM7615v1rvXVVH6qXfFop67FdBzPHt1NAN43mEIBZHTQ5hSVXFlYSZp9mxuEjAoGBAKCzUVO2IIAeub/iIGpV+dfGk4ptJ0kVZyreCqXEObpdC3V496uqUkGcYJ0GZ2ta6f2PMFzHpmnw8it2mdchu+gyrWL6U4uTK2pB0jZF/7Ak4WaB3GCD0xBxhleO6CJBOvn/R4M/bHcNEKmsYuE7WMIAKvScfPVR0VzsKfcLM5VBAoGAVvWg32zdh1bBZLdku8WU1rPH6KAbFSRuq3f7UPBTyWWaclu7p+GB/4f1aE9V6vJJmKASn7zArAhUYo+REMOmcc9uTMea5F7dM/23qb1HTtIvycLR44ZviW4Wx3iP+5x70jOLw1VQjMME6HLm8I/afHhqshWdiv6ganPv9UTwEg0CgYBSDi2dqg8F7ij5CN+LMDLSn3b8GCw+7efGIt7imm/O2V/FlHD40IA6qGg6DXNQrnoZQt94nMb1cZEvm1dxi6rmQNrhCyoMogAaPqgFhZGq1OjmhVZiXFUWy4WAcjdzFc9wZd3/XtaofRKHLK+ngTFhhVApKypLk3Rg9bCAAjzyVg==
|
||||
signingKey: l6LFiKqr4ZHgcPbL+DR7KwMbzImufQPFgpoHOJ/nvfUbpb76DCADHuT1I4gIs+XByglnY1KV8jbMfW64XRW5XQ==
|
||||
encryptionKey: MIIEowIBAAKCAQEA4ltcn1AH048bMXcKOOW7/E0TZYPxL3OtcHXWHSAZjeeTA/rc45G2eaNgyY7Ji+feLtZERbXNWGFBdNp31NHDYZAYwbZmjEqTEgV4yVx7BQP3VBEzglTJaNLTf+XIJnVAEkoHS6ogjC0oXTM6paHu64EitoOCzF9zqL023swjE3HU0dm2xwsUdGnKeO5nPMso/6e3VMavkKnFmvB965ECCBujtediP4lVdIABNVtoMHCoeI5Sn+m7TKqJSyDOIEMhHT3orYUNZWVeAHE1YTM2cI5tSnDZP80CHZ674Z/bKL7Jaznmq87mVt1h9Use2EkxR07/dJuTGvFOos4jHoiR9QIDAQABAoIBAHAr8EluooI/j61CnYk2p6LPG0aaTQJD4/YwHuwOBTviP2OghKgthGzg/szDerNfMyaoveqBvoIGqCZdQTbwwE7v1qTgXA83wYwTtBitQLVqkr1RTOJQXAMbPv5Jg5czUY3+q4DejQSKOE9/XJfKGJkSRH6Hy2C2CJ3dLnzYUqWGO3t70RLT1/sC6p6w3lXdy3dKZGkoR2wva+HXQxVrP8X5HOResXgNZwgMHt9KF1QHVCcySKYiEAefEKTSdKD2fOd4FxLgp3zWpvH3jrX0zd/DqzTlFD5Ns6Ayp2sIfHVp3sn99DZZM6DauMepQKtoSCnXZ+qKhekAwNVJnsVQkSECgYEA4spY9araeFUSl4uXCUQOpCkSshYOPRYN6sBbHsx8tV2eQtCT+5SuNYmzur3c5bkiraGEab8rZfGdDL6fLxQyaqbOmN31Db5kNh/2X+sRnxkak8lsROUWQZRF9doH73FDv6ZlI3V/JicZlOUCfN5BYT+x74R4/c1YXfyuD1J9gr0CgYEA/4K4SDwZUY4bOVCmKQz0OM+RW4PAAH6LHKenTAZNTeDNFFxc2nqnzRGMEKZTDGy0kbT5mBhBHFgShXcAiKxc5/MGkpt8Jcq6Fr5KGU9aZtYKji6mwMTsUndPNQydh3vOt5pOmcuMM6ovanNTvI8k6Qo53OY1IpO5CfOROu0hm5kCgYBnWsYd92YnDsYxUEldzKlLgPhnNov4pNNk15LvP0vaL7cPRhUaw1B9T6scAKjp/GxkasZ4lsnFZM4o37qV7wNm/WwL2KN0Rv9Od1SFtBBMzFkDXvk7kJeK/XLAr0OMiLbSYZeYCFUQ4yLSa2et1nA/TJLf0CR/rhSGiMAedX6DlQKBgAx1137OT33GrFUzNacy1oYeuTv5RNfBVA9lrabrd8GggN/JUU3mRWCexnHZaptkgbnJVZKxPBuhv+V6VDBWF4HIPD3SD0/YfxK03PA3CnWRYppkdAValRvAbcBsiRIeW4pgoAyn/IJYfk92qFK9uFMVCJVZNKYnBhMSKbbx8X2hAoGBAKwvzyAImbNB+493q1R/lSayxzG76bRJ/EseiTqwIec9c4C+Bd/sVXR+Re+xZb0FI/va1bz5CrduTzLSKBmf/+0lzl0MJvWY2+SXfGYdbl4+TTyqgDDfwqW0Tj8pDimye2BneyTmXko1rF+2Sxen7kMXnJLwpqjwZ6TZJuoqeK8q
|
||||
types : ["tree", "file"]
|
||||
- peerId: 12D3KooWDCypXSyN6ppuMZGxVnBd1ZQCMV4y7Bn187S4duYmf8rA
|
||||
- peerId: 12D3KooWASsipDzkridiMBmE7VSqp8yZvGWPY1VqySgMSZk6tsiL
|
||||
address: 127.0.0.1:4432
|
||||
signingKey: SGyNE0dFaQgtgNuzdcO7LB+TEz9VHAOtlQLk6WWkrkQyXiZV3casg8Q2/4PO1Oylc8Fu72RU001Hclj5JCbiLw==
|
||||
encryptionKey: MIIEpAIBAAKCAQEA0k3mw4FyexRkLgLjHzYs4Ppeyv6r9ZrP00imNf15JTuM8ajMx5oJX7JQTm8KOLRJjUdZZAd5Gtp0ezfYAQK1ZjEWwCmfp8j8FBgJIDSLpjxl88SXMLgATXYfhklnQvKlQjs/X3Ka4zdTrav2tMH9IAo6TSNZhlPQNsUory1SGHs+KqHv4p0sG8oWuKYhfBj8rWHQdUVptkIBKgojFDeJJD04Tbf9kUakbK/8KuXB6zF5H4WN3p4rMMwkClyTGeYO4LDg5TzVn8NnUi3/b/vO/3us1G/TMoRe/6umUfpQxrwo+7S2T6A4YwetWRp6xALLhp+HfAWnn0lA/D8/w1WpKwIDAQABAoIBAQC5cdQxRa5rddm48PbSCPWeFWkNW3DLDI6CYyedqDvxZwer+QtKXzww1I4X+7ZptiC9odLjb+uMkGHyXZXtnjPTPyounQWZ8JLILUGu0mbqWYwVXp9raHVr2OOHiKaz1D+BnbkOM4L9JUZ2eJL9ZaoNXLd4WdmRp8qM4WI0xqQDzOANx2HhyL/+dJmQeIUND+pdeH+Z+fYowU3ho32txNvBnMXQhF1T5K9i1VO5W49RAjIRbENsT+paPGKbNubDHRt1j36ktK4eC4HSdgv8tccdsGyrEiIbAt1XsTZfM8ie4D3A8RhSxiTC6Fkgv6vIm+iFTLzBFZKesOBcd8sfKeyBAoGBAOts5PQQJhldPDzlbnqzxMOR98WHbkVZjCqWSkNA34vqyFuPcRuX0rHK/qpg23ilbUP0fGMDTGgFzTt51FZLL16SXyRfjNhzjdmryryeddQwbp92ta2GEgnU6t1FyCuSCtcLDKJd/D9A9dC5UI6z+ES4TOnbR3nakXK9t4cUOFthAoGBAOSu+wL+SEA5erR+m3LpOsELK68CCJQPxn3VpoVfJZawgF+fEoXVMLTERxJput1+ADomIEdNc9ex86TjKx9gJ4piNHscRPFeT/AgESOIGHLOc1gk2DPqNj6wBIarUJQ9t4KcHScboh1dTPJeqqv2NSwIiLQoqFUIhfKZLnrW3zwLAoGBAJh0hC+o5YM3ZXLqAIllMN6VACbidP5j5ukNOjojIKCzAdyJH24G+2I3WoNrBbUzK3b+NC7KTAhw+V6ynlbjiWFs2D/twH/LFOkI3tkWpKcsVfbeIPimAbhsMUvpjJ7qjCqF9UCQLHGp14W6+/ftg7C8yNIINlkquVXclaTb60MBAoGAPqmL8ogG+EJH00mWAujRxq/u6meePiQMedKfbJBj1mTK6GjIRI/kZsQZzXvXTnYGTejAk4kvov0KDDaLTG+mpg6+3rUiVxlGwj+nMptKR7s2dAK0k5UsBAVrWBN9YwF+VXW9r0etJmq4ePljvvcaHtS/0M4LQjGxsoYy7EoQpX0CgYAhnf0McB7F1MxSjB0soMNv/v5utVzVihS3re2yKNdkI/YUEMB+yU3Q4gh+OljjBM6Y5To3BsQBAx4l2CysMKFHjIE/5AtdbvIS+chZZqB3vcZXSayvX8P1Z1uFdw/saiO2cRDJmR+TxaOPa2C9SzDoNTACthwLErHfzvEvVroKmw==
|
||||
types : ["tree", "file"]
|
||||
space:
|
||||
gcTTL: 60
|
||||
syncPeriod: 10
|
||||
syncPeriod: 11
|
||||
storage:
|
||||
path: db
|
||||
metric:
|
||||
|
||||
@ -5,31 +5,33 @@ grpcServer:
|
||||
- 127.0.0.1:4432
|
||||
tls: false
|
||||
account:
|
||||
peerId: 12D3KooWDCypXSyN6ppuMZGxVnBd1ZQCMV4y7Bn187S4duYmf8rA
|
||||
peerKey: SGyNE0dFaQgtgNuzdcO7LB+TEz9VHAOtlQLk6WWkrkQyXiZV3casg8Q2/4PO1Oylc8Fu72RU001Hclj5JCbiLw==
|
||||
signingKey: SGyNE0dFaQgtgNuzdcO7LB+TEz9VHAOtlQLk6WWkrkQyXiZV3casg8Q2/4PO1Oylc8Fu72RU001Hclj5JCbiLw==
|
||||
encryptionKey: MIIEpAIBAAKCAQEA0k3mw4FyexRkLgLjHzYs4Ppeyv6r9ZrP00imNf15JTuM8ajMx5oJX7JQTm8KOLRJjUdZZAd5Gtp0ezfYAQK1ZjEWwCmfp8j8FBgJIDSLpjxl88SXMLgATXYfhklnQvKlQjs/X3Ka4zdTrav2tMH9IAo6TSNZhlPQNsUory1SGHs+KqHv4p0sG8oWuKYhfBj8rWHQdUVptkIBKgojFDeJJD04Tbf9kUakbK/8KuXB6zF5H4WN3p4rMMwkClyTGeYO4LDg5TzVn8NnUi3/b/vO/3us1G/TMoRe/6umUfpQxrwo+7S2T6A4YwetWRp6xALLhp+HfAWnn0lA/D8/w1WpKwIDAQABAoIBAQC5cdQxRa5rddm48PbSCPWeFWkNW3DLDI6CYyedqDvxZwer+QtKXzww1I4X+7ZptiC9odLjb+uMkGHyXZXtnjPTPyounQWZ8JLILUGu0mbqWYwVXp9raHVr2OOHiKaz1D+BnbkOM4L9JUZ2eJL9ZaoNXLd4WdmRp8qM4WI0xqQDzOANx2HhyL/+dJmQeIUND+pdeH+Z+fYowU3ho32txNvBnMXQhF1T5K9i1VO5W49RAjIRbENsT+paPGKbNubDHRt1j36ktK4eC4HSdgv8tccdsGyrEiIbAt1XsTZfM8ie4D3A8RhSxiTC6Fkgv6vIm+iFTLzBFZKesOBcd8sfKeyBAoGBAOts5PQQJhldPDzlbnqzxMOR98WHbkVZjCqWSkNA34vqyFuPcRuX0rHK/qpg23ilbUP0fGMDTGgFzTt51FZLL16SXyRfjNhzjdmryryeddQwbp92ta2GEgnU6t1FyCuSCtcLDKJd/D9A9dC5UI6z+ES4TOnbR3nakXK9t4cUOFthAoGBAOSu+wL+SEA5erR+m3LpOsELK68CCJQPxn3VpoVfJZawgF+fEoXVMLTERxJput1+ADomIEdNc9ex86TjKx9gJ4piNHscRPFeT/AgESOIGHLOc1gk2DPqNj6wBIarUJQ9t4KcHScboh1dTPJeqqv2NSwIiLQoqFUIhfKZLnrW3zwLAoGBAJh0hC+o5YM3ZXLqAIllMN6VACbidP5j5ukNOjojIKCzAdyJH24G+2I3WoNrBbUzK3b+NC7KTAhw+V6ynlbjiWFs2D/twH/LFOkI3tkWpKcsVfbeIPimAbhsMUvpjJ7qjCqF9UCQLHGp14W6+/ftg7C8yNIINlkquVXclaTb60MBAoGAPqmL8ogG+EJH00mWAujRxq/u6meePiQMedKfbJBj1mTK6GjIRI/kZsQZzXvXTnYGTejAk4kvov0KDDaLTG+mpg6+3rUiVxlGwj+nMptKR7s2dAK0k5UsBAVrWBN9YwF+VXW9r0etJmq4ePljvvcaHtS/0M4LQjGxsoYy7EoQpX0CgYAhnf0McB7F1MxSjB0soMNv/v5utVzVihS3re2yKNdkI/YUEMB+yU3Q4gh+OljjBM6Y5To3BsQBAx4l2CysMKFHjIE/5AtdbvIS+chZZqB3vcZXSayvX8P1Z1uFdw/saiO2cRDJmR+TxaOPa2C9SzDoNTACthwLErHfzvEvVroKmw==
|
||||
peerId: 12D3KooWASsipDzkridiMBmE7VSqp8yZvGWPY1VqySgMSZk6tsiL
|
||||
peerKey: /6+uYFwFf9nU6fvXQVtpHhjd8+v4dXc7esZzqkhjyfMJWlMiZOtQeb913FXofD5f20WksU0l6i22B09sFFYwDQ==
|
||||
signingKey: /6+uYFwFf9nU6fvXQVtpHhjd8+v4dXc7esZzqkhjyfMJWlMiZOtQeb913FXofD5f20WksU0l6i22B09sFFYwDQ==
|
||||
encryptionKey: MIIEogIBAAKCAQEAwCy84lzkxtzgn4ixGm0LSUTujOBpOh9m7XDoDPZnMTmExdOe9a5v/LXzdlCOCuBvK5u1T3ALBJMA3Zgvjv/jPRQUdiHprP3sbdfc6IgZPBFdLKFTc9yAA7GMbI4y7LhGMLGOMOqQXs+DOeImfmxEs3ykLXHKNas5ORnZPVnB6E9Qod8KH7UyMmBjQkOZYOOw10X4JZiU6xJp/E+VVWcmeXgNBbj5xOWMSzM+hhoA4wNOzBxACucaKDmqD6qugzebOqyUVSzFnEbquro+MYTWYdUDjZTXdvxgUUo80MGQ164gZhkFUKrmSpUvu3YErFySEGqAdFNwOZ6y/4X3s0BHvQIDAQABAoIBAAZiNhAK5+qXMbr67m8jSimv6YCyf6xXmLKwenTbxofDEl8D7ZbZqYyqeqDmgiFoXSkErhwqa6NGQtQZlxLX+zNvNFLMQ5fkg3MOpZ7vzm7JYN/3p+8EVxhIUJLWkmh8opBBhaioUg1kNUa59W9jp1CTBl0gF4h63JbB/g5kqeVOllUw7J1igAoaX36nOJGOwIynCWdizhDhgyjR4OcYfOLwcPDJueKTc5vM10g3LuMSK/sJmaD3TkJFPtDHw+RMW6wqyjsnkrg2D2oohXEyGWYYIXo2so4HCez0AB1I1JAxtVnRPvSIp7xLMm7+AkDoq12QYDHfxZtDTpfmvJg+Sn0CgYEAxCd+oribtdQW+JUctjsDbSQX5CeRISH5Ith3jveBx2jKIqQVnoVPz6URHOvnlIsqYYLANB8B3JHMWfR2UmkK11x0OcZecB06+oBoCZukvSXF+GqVHzLAQUxaoEBDCCPneskj5w+riMWBiiGDp32rUnkqv0nh7dnH+GfORcJ44L8CgYEA+s5s5EALj1jyU9w4+HVUyVsIrUitFnQg6qw/Td3Kj+8CXImKlS+rlmbQv0m1aOcvtFjQRIjjzZJAf/ausfAME+MayoNODgZsDk5RyDKuSWzMLvZLAa1LD52Uli5Pg8KtpzKVTn4xE1MbjsQcUNhFRAgrNEKNyuzXzdp4uXgGOoMCgYASXwiTQOsEepq0KXMI9jn57Nl3+uSyz7W/t7pq329+N6hG2ktUD3RMJE+X/9gup2IOw+owd377I4SaIDU8vq3PQc944cVShspRT9lunO8u7+y8uW7B/0TWWMpcG+irSIGTlGcSavtL0gOx5jWoaDK1hLemNss8NZtu/nnpOq+LjQKBgDisVozJMBOHPNLYS4NROAR77p0BdCNDwIBmxbM5r+EQWA9DAS6u4+4Lc5YV+MkonG37N6yU5iz4pFyGCHmqzX/c7JvgSc3/g4FED1TWpu1uiUD/ZHmPiAuSRxYchtk2L3k9g+GFwF8mg26iP+fAxv4VfnXDqDi3hhg9CtSWG4ozAoGAOWZXlFKqzGAfcucIe54FVQnweXG9sEuIPAvWvVRs4406ggNmL5eHccXpPHWTgetsr2TYMqPTDVMRmhBzSkyrYgk+b2tme79HPzTWs2Yg/pzjOfTgw7MBX/KlvOW5/J+dvrF3Gx8AHHZ9QQdYqi/MS1NKb2K3IbD0/m5gL5Pwi6A=
|
||||
apiServer:
|
||||
port: "8082"
|
||||
listenAddrs:
|
||||
- 127.0.0.1:8082
|
||||
tls: false
|
||||
nodes:
|
||||
- peerId: 12D3KooWLn13hDrZ6YRGM517fHf2zS6qhPNRu18inLMpRqn1YGKu
|
||||
- peerId: 12D3KooWPuwdqpDQxWhD2Vh4yskx2T5VMrwdpTZLfACzgsGfQfNy
|
||||
address: 127.0.0.1:4430
|
||||
signingKey: 3mzfKBWtn7mitFEgq8u4eysWOJ6ySbUs49irfHwcuOmi1YMpobz9anoqd4yaT1owZiRPYXqx5k2Z4sNVRE3kXA==
|
||||
encryptionKey: MIIEpQIBAAKCAQEA3U7b4w9JTKE3TLM1WQ5iqdLbvUuozMp/hDEg7S15Gr6wrtLomMSBkfmVQ3Cu+CHdxAFqUFClItYlSFgtZWIFiSiQxCeaN2dmgczd9T4TlRAw6y6uJXtT9r7FIgizPP4B0/tnzPI6yYgpdwzCV2nRSjw3mMr5Nav3QYs18kYrJ1/Np2Wob5HOoRTUD++pPrToevTb7GNL/irrC8wXSE7oU6S7ix6Nh9vzEHg/V5FONBF/wWD/ri7Gy0j0qgUQ+gjxLWKr8xPDnRAve13zzo+54lGCyVvlm/rwCY9Jx378V1IuRx+S8F/GFuVozHD4XVaoSTtpCWPBQNSKDXgaIIKDowIDAQABAoIBACpMXj6ht1LMJXOldPbWhwkKYjFl+pdZxNGRSkfKvzDbbY2chhRcyp8J4vuG2ApY/rftxVIgd8+Wun1/TP3ppEE43aKAJzubqb35WBr9iGSfOZpZy7MiRUQN5kPBAfEQY20OyiIj0hSez74PVD283eGgbMfpU4Rsn8+JOgBaZPkbPViJLJY8PyHU6vwWw60dye1iJTz9yuBtoEqY0XKxnLaVXTQaWx0Te+VYU8twxDgXFWRaXtHuk7xnxOkCZDLrzIvuOYa5lsLoT8K62LDeXbyHBPhbdW0j4ZYzAOTsaUWpjuJzef9aj3JJdfyADiqb5iu6HHksvKzkZEau34zjilECgYEA/c8ZJm62uJMHNssTJYiLRw89l5hYwIZ/1TXdFRF8+xrTin5opYjpscSTO5bY2IYqLx2xuPiJCY1eGGB9L/RtkaVh51ySzq0d+4zpPIRKFcOOgdxHwlgoCgIhQECyfJZNMFGBUIlPXZ/phvXOXRvWFzDPhqThenVG2QzF+wLP0AUCgYEA3zfviQFJ1FOKJMozYO3tUZFmsIrAcO9hfuE7uuWz0Fw2m1XiwxjuOr1RbsSsh/lKke2h4tiGrlfiFhwCpIp91NkVTFrtFOQxbDxkYLkFiWkZDkOaK9YhKMa2cgEm3p+RGawokjbm51LKf+cbYN9xGaAe3y2WzIE4kNpfWE4SXYcCgYEAoagcrrvpqZoMCDxED63ud+4fHsUsEkQYe6Z5EAg5gH5PqnBlGrofjthTpqqnpxGdILFbFyNFtU3TVtduJPMcLp4Vw5TU9MqSxDu1+pOP1FjgFZpGImSf6+/7Wb9bb7sToujm4nLymAFYblt1exxVuiOeqnWuH58+5tQZ7YyW7DkCgYEAl7WuqZEkmpiEpWh/7vsGdo+6GXbUQG2R9+gg7m+7/HsP6hc/XZYOJAIT3JLzKB84nWHCyyiasNeuI5S5/xbZWtaH8TNDOxW0uXl6R3q41qGFk/pCSFTqiIo16dn6jwgoWCh4EpgZ61KLqs5p/zcd6Wq4ULrtaOTSizC/6IZ3WPUCgYEA6xCJy3+ICCgr8/c7hfd2Ylb3aOsXIffdgALhXjDcrNUCqgB4R+S3WReAwrABemQGl4tySQE/1f3Ru7SzMMciFogGyJ/YSXqSi6Y8oDD7MqlKPiWlN6WY1nSRMlLbkUOqpA5JaDM0kcmXjZpBBQr277GOnh9uKN8zUy5xoptctxI=
|
||||
signingKey: yOEpD2+cPldXc2urGuU+szunm7fddRa8xew2uVjaxifRcVzNKhSERpOefjrXaky7PcKmSmTsH/5ZFtcrh1uzqg==
|
||||
encryptionKey: MIIEpAIBAAKCAQEAxnE9Htwto+2fVmonkG9/DxNre33n7kjfrZU73JcHmpKhPlRFirig5T8rs2MaTq1R72/8nGBJuSxsz1PnexI3die39pY1OFYfZCZ59LbT7uH/xHcvkVrK2n50Q41KbbGT9BEzyW+XPkKPDpTq3/igYP+yUQgoWLfMwxCCLKXDe6qUC0fuIxR80fvj3XvorB5dnAiQ01JkH4PtCV1OWT6ZpLGhzcYxsxTHozd6LdMOC7wgGhW26dOSa/vZ1t5avbewFVIz0qfqBncunb7tjO4xa3xVYaA5jBbixDQUYFjVzW7cksrrN4CFNBDBGJ8PLS80MuMg0OG0O+/Qi1mbGb2mUQIDAQABAoIBACODAD0VidVcILeGJ65hRYudHg7raSXrRJv7qMrA/EtdEh3lVsyMXb6on1lq0rphqdf/YmVZldfda1tu2G3dxK8QTIuENeHvB48Uk56HWUXWi77M1WZdqQ+QsZ2lGzymGqQCsBHMNnSd1Jv3alDKXWj+WRrHKvE1cx81RRZYU7M9cpurnF5YNjO7L+7sMxUA9uAQGbe3kDVzrygraicLYQpxSNHytName0A+k3ug0qer4I6PmZhhJykkz6MD3dz/n625HSS+X+TuTm52T2b87tL27xXmSnUK7eYWjZ1vQlP1fWmqnac6u5LApUZaRi0tTjtefSjRW4jr1q20RqOp1kECgYEA7Onh3zM9ejATsjW6WISGKiBPci0D7DUbIuGuJrdQRadlkZzmeQ/VOYAuxIQD4GnQDRhM1FyxsqiAWkJOyCLFiMmsgIEyW9/eRhF8NlCVU+DA/fxy9EagfBbVsgiSBwOex24hPXIVYlaHkLAloNoD4bpw0pQZSDWXr+xvMFNwoGsCgYEA1m3sWA/e8ZuXForaUOoJzBU9nwC79bXv2UNktsVvBlQ1o9pbjoYDcVoAPwuBVUL1UwqDNMzPdhDBKBjZmCyjS6zlYD5ZKjF2m8iTyc4QcaBCdM0iyQpSXTmrfMx+hK1aWwL1p8ssNcednp5ExSAaTyNNGVdbtddiQ6/KMPmhUzMCgYEAwDjLsUNr4BXeBTweo+9yw/9PNn5brm0wRU8C9BrMIJe/izPYs+UqxerBB2Vtl8mCqv1KaQuEika5TYJ7VVsRFvk641DwQScUu5k4RQGBB3tWWz1XL+eWEticLkVR5isDyyAKDEbiHtXCTJz/CtGZUK7rF5BeKv6AwpZ9aKJqwV0CgYEAqXDlQNURu+PR6TtBtoypvz3NmraO0GO7KvipPhAXYm3qkRa8IIxfbhPLfAYQZhpqFvuIoJFzIn2s1I2GbExhoSv3eSzrcn7xlbpSpjYSImeb/AYZhbmFSiuHCi/hjeAaNS7KhZPz1G9vaubvusFaaMyhYPP6AWA4QvpHEJpB06cCgYBqR6/7d2hQiq4MJUrBEzLwG4ijnPeq+UVLQjE598hVIj+8UhRZRRcNWVEJxfcIL1v6Bpo8XISDNVRb30T9bPGVnXvC1jutTUbXKUB1/8iXuyH3IVieobch+bGd4v7ehH/lI7vzB6hjJpFzHopfFUn4wacSQdcFi3tRAwUB/L0S/w==
|
||||
types : ["tree", "file"]
|
||||
- peerId: 12D3KooWLtuKtCPBYrFJV1NdejiCr2s614ppe9rmUXnkTHtAUD5U
|
||||
- peerId: 12D3KooWBgHmDqtXH9SrZfAmwCFsD8LZhTD5dg5wkhdbqFoS8GBN
|
||||
address: 127.0.0.1:4431
|
||||
signingKey: 07JMoW5cQUtGO9nNIGQo9e99b7Wf/4YvTtNEA0lt4gCkmhwB1EB9ay+kitxVJJgmdyGLxbUUlGqwXsAj0zlHWw==
|
||||
encryptionKey: MIIEpAIBAAKCAQEA7cA6J/icl8wseeXkt8oJr5AeYadUAG5EdCOdHj4S/Z7ivff4MOIKAeQITpq+rqhmXxOePYXSpQXE20Y9PW9tuw4gzOuq1ylSG/MWMcLDH1eIxg66rnmUqUbdiW4GGJjVjc9jvN0Up+MfSrUF6fM0jWTFoXVJQIeQQGERCIYjFzjfBl1xYvPghdxNgei/K5ZGYRggT28143XdIH4KTXGtp51hAKoyY9eCqYMtm9wvjxazhPVxO2CsYaqMxBLshY3jfHNqJnx8u6+h4Bl4uUcdbLNUgMcEgk7ehbQp2K0CqNoKXxbCTI6V57UVcJHDIaO5B6FyR6BguzHHNPJ4yd3q9wIDAQABAoIBAQCm2Mf3VRlPzhFIWnVwJXE2q8Umcu8Yfkm712Jj3twk8GPfPS4H4Bl1yjmqMB6xI6zz/CiItGlnNe04lMpVWuV+6CNMq/ZwmKbuxmFE+pFEZYGuvJd16gzR3tGJqJTOnjMAGhK8b8oXJ+TF4NQNooe20ol/DXgiuQAargPuH3RwzjYmF3N8VI4KUc3LaG4TwVXn4LwPOxrQSnfwJlZwLml1HAKOV0qcG0mXX6ZXOpoVhEoRPdQyUHc8ZW+53Agbtind7bYh5TsMVDFUrcgNwnwTOsWjil049la1IJO2uMRluacKlrtyzEp6zqrW8ZJO7mYAO69x4WyGqf2ZgIdA6djBAoGBAPqRHWAIgPa80eXbwCYkRtUG/ONBsQGi7+wm6nyhkXvNXJeokgH2DCgLH2+fW2scfOJuZc9r5WftEjOBvNfr2LDcwdyTSTh21WYcPSZx9HDf2d5/SWTcjNcyU0b5qfWIUKi/Zm9UY7r3X7yMA5dUD/cvu1PBJ5NWFrK1Gm2ph44dAoGBAPLn+LkHweU0fbxQq/76T5yVVpMKUaE9xwrJlUxEDPAQGnLPbFg4JeUt/YPhsOV85W4c4oQE+uFZrF0uf+1fEnS6MOJ+sq668upzC2hBp1B5138wM7615v1rvXVVH6qXfFop67FdBzPHt1NAN43mEIBZHTQ5hSVXFlYSZp9mxuEjAoGBAKCzUVO2IIAeub/iIGpV+dfGk4ptJ0kVZyreCqXEObpdC3V496uqUkGcYJ0GZ2ta6f2PMFzHpmnw8it2mdchu+gyrWL6U4uTK2pB0jZF/7Ak4WaB3GCD0xBxhleO6CJBOvn/R4M/bHcNEKmsYuE7WMIAKvScfPVR0VzsKfcLM5VBAoGAVvWg32zdh1bBZLdku8WU1rPH6KAbFSRuq3f7UPBTyWWaclu7p+GB/4f1aE9V6vJJmKASn7zArAhUYo+REMOmcc9uTMea5F7dM/23qb1HTtIvycLR44ZviW4Wx3iP+5x70jOLw1VQjMME6HLm8I/afHhqshWdiv6ganPv9UTwEg0CgYBSDi2dqg8F7ij5CN+LMDLSn3b8GCw+7efGIt7imm/O2V/FlHD40IA6qGg6DXNQrnoZQt94nMb1cZEvm1dxi6rmQNrhCyoMogAaPqgFhZGq1OjmhVZiXFUWy4WAcjdzFc9wZd3/XtaofRKHLK+ngTFhhVApKypLk3Rg9bCAAjzyVg==
|
||||
signingKey: l6LFiKqr4ZHgcPbL+DR7KwMbzImufQPFgpoHOJ/nvfUbpb76DCADHuT1I4gIs+XByglnY1KV8jbMfW64XRW5XQ==
|
||||
encryptionKey: MIIEowIBAAKCAQEA4ltcn1AH048bMXcKOOW7/E0TZYPxL3OtcHXWHSAZjeeTA/rc45G2eaNgyY7Ji+feLtZERbXNWGFBdNp31NHDYZAYwbZmjEqTEgV4yVx7BQP3VBEzglTJaNLTf+XIJnVAEkoHS6ogjC0oXTM6paHu64EitoOCzF9zqL023swjE3HU0dm2xwsUdGnKeO5nPMso/6e3VMavkKnFmvB965ECCBujtediP4lVdIABNVtoMHCoeI5Sn+m7TKqJSyDOIEMhHT3orYUNZWVeAHE1YTM2cI5tSnDZP80CHZ674Z/bKL7Jaznmq87mVt1h9Use2EkxR07/dJuTGvFOos4jHoiR9QIDAQABAoIBAHAr8EluooI/j61CnYk2p6LPG0aaTQJD4/YwHuwOBTviP2OghKgthGzg/szDerNfMyaoveqBvoIGqCZdQTbwwE7v1qTgXA83wYwTtBitQLVqkr1RTOJQXAMbPv5Jg5czUY3+q4DejQSKOE9/XJfKGJkSRH6Hy2C2CJ3dLnzYUqWGO3t70RLT1/sC6p6w3lXdy3dKZGkoR2wva+HXQxVrP8X5HOResXgNZwgMHt9KF1QHVCcySKYiEAefEKTSdKD2fOd4FxLgp3zWpvH3jrX0zd/DqzTlFD5Ns6Ayp2sIfHVp3sn99DZZM6DauMepQKtoSCnXZ+qKhekAwNVJnsVQkSECgYEA4spY9araeFUSl4uXCUQOpCkSshYOPRYN6sBbHsx8tV2eQtCT+5SuNYmzur3c5bkiraGEab8rZfGdDL6fLxQyaqbOmN31Db5kNh/2X+sRnxkak8lsROUWQZRF9doH73FDv6ZlI3V/JicZlOUCfN5BYT+x74R4/c1YXfyuD1J9gr0CgYEA/4K4SDwZUY4bOVCmKQz0OM+RW4PAAH6LHKenTAZNTeDNFFxc2nqnzRGMEKZTDGy0kbT5mBhBHFgShXcAiKxc5/MGkpt8Jcq6Fr5KGU9aZtYKji6mwMTsUndPNQydh3vOt5pOmcuMM6ovanNTvI8k6Qo53OY1IpO5CfOROu0hm5kCgYBnWsYd92YnDsYxUEldzKlLgPhnNov4pNNk15LvP0vaL7cPRhUaw1B9T6scAKjp/GxkasZ4lsnFZM4o37qV7wNm/WwL2KN0Rv9Od1SFtBBMzFkDXvk7kJeK/XLAr0OMiLbSYZeYCFUQ4yLSa2et1nA/TJLf0CR/rhSGiMAedX6DlQKBgAx1137OT33GrFUzNacy1oYeuTv5RNfBVA9lrabrd8GggN/JUU3mRWCexnHZaptkgbnJVZKxPBuhv+V6VDBWF4HIPD3SD0/YfxK03PA3CnWRYppkdAValRvAbcBsiRIeW4pgoAyn/IJYfk92qFK9uFMVCJVZNKYnBhMSKbbx8X2hAoGBAKwvzyAImbNB+493q1R/lSayxzG76bRJ/EseiTqwIec9c4C+Bd/sVXR+Re+xZb0FI/va1bz5CrduTzLSKBmf/+0lzl0MJvWY2+SXfGYdbl4+TTyqgDDfwqW0Tj8pDimye2BneyTmXko1rF+2Sxen7kMXnJLwpqjwZ6TZJuoqeK8q
|
||||
types : ["tree", "file"]
|
||||
- peerId: 12D3KooWDCypXSyN6ppuMZGxVnBd1ZQCMV4y7Bn187S4duYmf8rA
|
||||
- peerId: 12D3KooWASsipDzkridiMBmE7VSqp8yZvGWPY1VqySgMSZk6tsiL
|
||||
address: 127.0.0.1:4432
|
||||
signingKey: SGyNE0dFaQgtgNuzdcO7LB+TEz9VHAOtlQLk6WWkrkQyXiZV3casg8Q2/4PO1Oylc8Fu72RU001Hclj5JCbiLw==
|
||||
encryptionKey: MIIEpAIBAAKCAQEA0k3mw4FyexRkLgLjHzYs4Ppeyv6r9ZrP00imNf15JTuM8ajMx5oJX7JQTm8KOLRJjUdZZAd5Gtp0ezfYAQK1ZjEWwCmfp8j8FBgJIDSLpjxl88SXMLgATXYfhklnQvKlQjs/X3Ka4zdTrav2tMH9IAo6TSNZhlPQNsUory1SGHs+KqHv4p0sG8oWuKYhfBj8rWHQdUVptkIBKgojFDeJJD04Tbf9kUakbK/8KuXB6zF5H4WN3p4rMMwkClyTGeYO4LDg5TzVn8NnUi3/b/vO/3us1G/TMoRe/6umUfpQxrwo+7S2T6A4YwetWRp6xALLhp+HfAWnn0lA/D8/w1WpKwIDAQABAoIBAQC5cdQxRa5rddm48PbSCPWeFWkNW3DLDI6CYyedqDvxZwer+QtKXzww1I4X+7ZptiC9odLjb+uMkGHyXZXtnjPTPyounQWZ8JLILUGu0mbqWYwVXp9raHVr2OOHiKaz1D+BnbkOM4L9JUZ2eJL9ZaoNXLd4WdmRp8qM4WI0xqQDzOANx2HhyL/+dJmQeIUND+pdeH+Z+fYowU3ho32txNvBnMXQhF1T5K9i1VO5W49RAjIRbENsT+paPGKbNubDHRt1j36ktK4eC4HSdgv8tccdsGyrEiIbAt1XsTZfM8ie4D3A8RhSxiTC6Fkgv6vIm+iFTLzBFZKesOBcd8sfKeyBAoGBAOts5PQQJhldPDzlbnqzxMOR98WHbkVZjCqWSkNA34vqyFuPcRuX0rHK/qpg23ilbUP0fGMDTGgFzTt51FZLL16SXyRfjNhzjdmryryeddQwbp92ta2GEgnU6t1FyCuSCtcLDKJd/D9A9dC5UI6z+ES4TOnbR3nakXK9t4cUOFthAoGBAOSu+wL+SEA5erR+m3LpOsELK68CCJQPxn3VpoVfJZawgF+fEoXVMLTERxJput1+ADomIEdNc9ex86TjKx9gJ4piNHscRPFeT/AgESOIGHLOc1gk2DPqNj6wBIarUJQ9t4KcHScboh1dTPJeqqv2NSwIiLQoqFUIhfKZLnrW3zwLAoGBAJh0hC+o5YM3ZXLqAIllMN6VACbidP5j5ukNOjojIKCzAdyJH24G+2I3WoNrBbUzK3b+NC7KTAhw+V6ynlbjiWFs2D/twH/LFOkI3tkWpKcsVfbeIPimAbhsMUvpjJ7qjCqF9UCQLHGp14W6+/ftg7C8yNIINlkquVXclaTb60MBAoGAPqmL8ogG+EJH00mWAujRxq/u6meePiQMedKfbJBj1mTK6GjIRI/kZsQZzXvXTnYGTejAk4kvov0KDDaLTG+mpg6+3rUiVxlGwj+nMptKR7s2dAK0k5UsBAVrWBN9YwF+VXW9r0etJmq4ePljvvcaHtS/0M4LQjGxsoYy7EoQpX0CgYAhnf0McB7F1MxSjB0soMNv/v5utVzVihS3re2yKNdkI/YUEMB+yU3Q4gh+OljjBM6Y5To3BsQBAx4l2CysMKFHjIE/5AtdbvIS+chZZqB3vcZXSayvX8P1Z1uFdw/saiO2cRDJmR+TxaOPa2C9SzDoNTACthwLErHfzvEvVroKmw==
|
||||
types : ["tree", "file"]
|
||||
space:
|
||||
gcTTL: 60
|
||||
syncPeriod: 10
|
||||
syncPeriod: 11
|
||||
storage:
|
||||
path: db
|
||||
metric:
|
||||
|
||||
@ -6,4 +6,8 @@ build:
|
||||
go build -v -o ../bin/anytype-node -ldflags "$(FLAGS)" github.com/anytypeio/go-anytype-infrastructure-experiments/node/cmd
|
||||
|
||||
test:
|
||||
go test ./... --cover
|
||||
go test ./... --cover
|
||||
|
||||
proto:
|
||||
@$(eval GOGO_START := GOGO_NO_UNDERSCORE=1 GOGO_EXPORT_ONEOF_INTERFACE=1)
|
||||
$(GOGO_START) protoc --gogofaster_out=:. --go-drpc_out=protolib=github.com/gogo/protobuf:. api/apiproto/protos/*.proto
|
||||
1865
node/api/apiproto/api.pb.go
Normal file
1865
node/api/apiproto/api.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
233
node/api/apiproto/api_drpc.pb.go
Normal file
233
node/api/apiproto/api_drpc.pb.go
Normal file
@ -0,0 +1,233 @@
|
||||
// Code generated by protoc-gen-go-drpc. DO NOT EDIT.
|
||||
// protoc-gen-go-drpc version: v0.0.32
|
||||
// source: api/apiproto/protos/api.proto
|
||||
|
||||
package apiproto
|
||||
|
||||
import (
|
||||
bytes "bytes"
|
||||
context "context"
|
||||
errors "errors"
|
||||
jsonpb "github.com/gogo/protobuf/jsonpb"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
drpc "storj.io/drpc"
|
||||
drpcerr "storj.io/drpc/drpcerr"
|
||||
)
|
||||
|
||||
type drpcEncoding_File_api_apiproto_protos_api_proto struct{}
|
||||
|
||||
func (drpcEncoding_File_api_apiproto_protos_api_proto) Marshal(msg drpc.Message) ([]byte, error) {
|
||||
return proto.Marshal(msg.(proto.Message))
|
||||
}
|
||||
|
||||
func (drpcEncoding_File_api_apiproto_protos_api_proto) Unmarshal(buf []byte, msg drpc.Message) error {
|
||||
return proto.Unmarshal(buf, msg.(proto.Message))
|
||||
}
|
||||
|
||||
func (drpcEncoding_File_api_apiproto_protos_api_proto) JSONMarshal(msg drpc.Message) ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
err := new(jsonpb.Marshaler).Marshal(&buf, msg.(proto.Message))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
func (drpcEncoding_File_api_apiproto_protos_api_proto) JSONUnmarshal(buf []byte, msg drpc.Message) error {
|
||||
return jsonpb.Unmarshal(bytes.NewReader(buf), msg.(proto.Message))
|
||||
}
|
||||
|
||||
type DRPCNodeApiClient interface {
|
||||
DRPCConn() drpc.Conn
|
||||
|
||||
DumpTree(ctx context.Context, in *DumpTreeRequest) (*DumpTreeResponse, error)
|
||||
TreeParams(ctx context.Context, in *TreeParamsRequest) (*TreeParamsResponse, error)
|
||||
AllTrees(ctx context.Context, in *AllTreesRequest) (*AllTreesResponse, error)
|
||||
AllSpaces(ctx context.Context, in *AllSpacesRequest) (*AllSpacesResponse, error)
|
||||
}
|
||||
|
||||
type drpcNodeApiClient struct {
|
||||
cc drpc.Conn
|
||||
}
|
||||
|
||||
func NewDRPCNodeApiClient(cc drpc.Conn) DRPCNodeApiClient {
|
||||
return &drpcNodeApiClient{cc}
|
||||
}
|
||||
|
||||
func (c *drpcNodeApiClient) DRPCConn() drpc.Conn { return c.cc }
|
||||
|
||||
func (c *drpcNodeApiClient) DumpTree(ctx context.Context, in *DumpTreeRequest) (*DumpTreeResponse, error) {
|
||||
out := new(DumpTreeResponse)
|
||||
err := c.cc.Invoke(ctx, "/nodeapi.NodeApi/DumpTree", drpcEncoding_File_api_apiproto_protos_api_proto{}, in, out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *drpcNodeApiClient) TreeParams(ctx context.Context, in *TreeParamsRequest) (*TreeParamsResponse, error) {
|
||||
out := new(TreeParamsResponse)
|
||||
err := c.cc.Invoke(ctx, "/nodeapi.NodeApi/TreeParams", drpcEncoding_File_api_apiproto_protos_api_proto{}, in, out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *drpcNodeApiClient) AllTrees(ctx context.Context, in *AllTreesRequest) (*AllTreesResponse, error) {
|
||||
out := new(AllTreesResponse)
|
||||
err := c.cc.Invoke(ctx, "/nodeapi.NodeApi/AllTrees", drpcEncoding_File_api_apiproto_protos_api_proto{}, in, out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *drpcNodeApiClient) AllSpaces(ctx context.Context, in *AllSpacesRequest) (*AllSpacesResponse, error) {
|
||||
out := new(AllSpacesResponse)
|
||||
err := c.cc.Invoke(ctx, "/nodeapi.NodeApi/AllSpaces", drpcEncoding_File_api_apiproto_protos_api_proto{}, in, out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
type DRPCNodeApiServer interface {
|
||||
DumpTree(context.Context, *DumpTreeRequest) (*DumpTreeResponse, error)
|
||||
TreeParams(context.Context, *TreeParamsRequest) (*TreeParamsResponse, error)
|
||||
AllTrees(context.Context, *AllTreesRequest) (*AllTreesResponse, error)
|
||||
AllSpaces(context.Context, *AllSpacesRequest) (*AllSpacesResponse, error)
|
||||
}
|
||||
|
||||
type DRPCNodeApiUnimplementedServer struct{}
|
||||
|
||||
func (s *DRPCNodeApiUnimplementedServer) DumpTree(context.Context, *DumpTreeRequest) (*DumpTreeResponse, error) {
|
||||
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
|
||||
}
|
||||
|
||||
func (s *DRPCNodeApiUnimplementedServer) TreeParams(context.Context, *TreeParamsRequest) (*TreeParamsResponse, error) {
|
||||
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
|
||||
}
|
||||
|
||||
func (s *DRPCNodeApiUnimplementedServer) AllTrees(context.Context, *AllTreesRequest) (*AllTreesResponse, error) {
|
||||
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
|
||||
}
|
||||
|
||||
func (s *DRPCNodeApiUnimplementedServer) AllSpaces(context.Context, *AllSpacesRequest) (*AllSpacesResponse, error) {
|
||||
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
|
||||
}
|
||||
|
||||
type DRPCNodeApiDescription struct{}
|
||||
|
||||
func (DRPCNodeApiDescription) NumMethods() int { return 4 }
|
||||
|
||||
func (DRPCNodeApiDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver, interface{}, bool) {
|
||||
switch n {
|
||||
case 0:
|
||||
return "/nodeapi.NodeApi/DumpTree", drpcEncoding_File_api_apiproto_protos_api_proto{},
|
||||
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
|
||||
return srv.(DRPCNodeApiServer).
|
||||
DumpTree(
|
||||
ctx,
|
||||
in1.(*DumpTreeRequest),
|
||||
)
|
||||
}, DRPCNodeApiServer.DumpTree, true
|
||||
case 1:
|
||||
return "/nodeapi.NodeApi/TreeParams", drpcEncoding_File_api_apiproto_protos_api_proto{},
|
||||
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
|
||||
return srv.(DRPCNodeApiServer).
|
||||
TreeParams(
|
||||
ctx,
|
||||
in1.(*TreeParamsRequest),
|
||||
)
|
||||
}, DRPCNodeApiServer.TreeParams, true
|
||||
case 2:
|
||||
return "/nodeapi.NodeApi/AllTrees", drpcEncoding_File_api_apiproto_protos_api_proto{},
|
||||
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
|
||||
return srv.(DRPCNodeApiServer).
|
||||
AllTrees(
|
||||
ctx,
|
||||
in1.(*AllTreesRequest),
|
||||
)
|
||||
}, DRPCNodeApiServer.AllTrees, true
|
||||
case 3:
|
||||
return "/nodeapi.NodeApi/AllSpaces", drpcEncoding_File_api_apiproto_protos_api_proto{},
|
||||
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
|
||||
return srv.(DRPCNodeApiServer).
|
||||
AllSpaces(
|
||||
ctx,
|
||||
in1.(*AllSpacesRequest),
|
||||
)
|
||||
}, DRPCNodeApiServer.AllSpaces, true
|
||||
default:
|
||||
return "", nil, nil, nil, false
|
||||
}
|
||||
}
|
||||
|
||||
func DRPCRegisterNodeApi(mux drpc.Mux, impl DRPCNodeApiServer) error {
|
||||
return mux.Register(impl, DRPCNodeApiDescription{})
|
||||
}
|
||||
|
||||
type DRPCNodeApi_DumpTreeStream interface {
|
||||
drpc.Stream
|
||||
SendAndClose(*DumpTreeResponse) error
|
||||
}
|
||||
|
||||
type drpcNodeApi_DumpTreeStream struct {
|
||||
drpc.Stream
|
||||
}
|
||||
|
||||
func (x *drpcNodeApi_DumpTreeStream) SendAndClose(m *DumpTreeResponse) error {
|
||||
if err := x.MsgSend(m, drpcEncoding_File_api_apiproto_protos_api_proto{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return x.CloseSend()
|
||||
}
|
||||
|
||||
type DRPCNodeApi_TreeParamsStream interface {
|
||||
drpc.Stream
|
||||
SendAndClose(*TreeParamsResponse) error
|
||||
}
|
||||
|
||||
type drpcNodeApi_TreeParamsStream struct {
|
||||
drpc.Stream
|
||||
}
|
||||
|
||||
func (x *drpcNodeApi_TreeParamsStream) SendAndClose(m *TreeParamsResponse) error {
|
||||
if err := x.MsgSend(m, drpcEncoding_File_api_apiproto_protos_api_proto{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return x.CloseSend()
|
||||
}
|
||||
|
||||
type DRPCNodeApi_AllTreesStream interface {
|
||||
drpc.Stream
|
||||
SendAndClose(*AllTreesResponse) error
|
||||
}
|
||||
|
||||
type drpcNodeApi_AllTreesStream struct {
|
||||
drpc.Stream
|
||||
}
|
||||
|
||||
func (x *drpcNodeApi_AllTreesStream) SendAndClose(m *AllTreesResponse) error {
|
||||
if err := x.MsgSend(m, drpcEncoding_File_api_apiproto_protos_api_proto{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return x.CloseSend()
|
||||
}
|
||||
|
||||
type DRPCNodeApi_AllSpacesStream interface {
|
||||
drpc.Stream
|
||||
SendAndClose(*AllSpacesResponse) error
|
||||
}
|
||||
|
||||
type drpcNodeApi_AllSpacesStream struct {
|
||||
drpc.Stream
|
||||
}
|
||||
|
||||
func (x *drpcNodeApi_AllSpacesStream) SendAndClose(m *AllSpacesResponse) error {
|
||||
if err := x.MsgSend(m, drpcEncoding_File_api_apiproto_protos_api_proto{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return x.CloseSend()
|
||||
}
|
||||
50
node/api/apiproto/protos/api.proto
Normal file
50
node/api/apiproto/protos/api.proto
Normal file
@ -0,0 +1,50 @@
|
||||
syntax = "proto3";
|
||||
package nodeapi;
|
||||
|
||||
option go_package = "api/apiproto";
|
||||
|
||||
service NodeApi {
|
||||
rpc DumpTree(DumpTreeRequest) returns(DumpTreeResponse);
|
||||
rpc TreeParams(TreeParamsRequest) returns(TreeParamsResponse);
|
||||
rpc AllTrees(AllTreesRequest) returns(AllTreesResponse);
|
||||
rpc AllSpaces(AllSpacesRequest) returns(AllSpacesResponse);
|
||||
}
|
||||
|
||||
message DumpTreeRequest {
|
||||
string spaceId = 1;
|
||||
string documentId = 2;
|
||||
}
|
||||
|
||||
message DumpTreeResponse {
|
||||
string dump = 1;
|
||||
}
|
||||
|
||||
message AllTreesRequest {
|
||||
string spaceId = 1;
|
||||
}
|
||||
|
||||
message Tree {
|
||||
string id = 1;
|
||||
repeated string heads = 2;
|
||||
}
|
||||
|
||||
message AllTreesResponse {
|
||||
repeated Tree trees = 1;
|
||||
}
|
||||
|
||||
message AllSpacesRequest {
|
||||
}
|
||||
|
||||
message AllSpacesResponse {
|
||||
repeated string spaceIds = 1;
|
||||
}
|
||||
|
||||
message TreeParamsRequest {
|
||||
string spaceId = 1;
|
||||
string documentId = 2;
|
||||
}
|
||||
|
||||
message TreeParamsResponse {
|
||||
string rootId = 1;
|
||||
repeated string headIds = 2;
|
||||
}
|
||||
68
node/api/rpchandler.go
Normal file
68
node/api/rpchandler.go
Normal file
@ -0,0 +1,68 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/node/api/apiproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/node/nodespace"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/node/storage"
|
||||
)
|
||||
|
||||
type rpcHandler struct {
|
||||
treeCache treegetter.TreeGetter
|
||||
spaceService nodespace.Service
|
||||
storageService storage.NodeStorage
|
||||
}
|
||||
|
||||
func (r *rpcHandler) DumpTree(ctx context.Context, request *apiproto.DumpTreeRequest) (resp *apiproto.DumpTreeResponse, err error) {
|
||||
tree, err := r.treeCache.GetTree(context.Background(), request.SpaceId, request.DocumentId)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
dump, err := tree.DebugDump()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
resp = &apiproto.DumpTreeResponse{
|
||||
Dump: dump,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (r *rpcHandler) AllTrees(ctx context.Context, request *apiproto.AllTreesRequest) (resp *apiproto.AllTreesResponse, err error) {
|
||||
space, err := r.spaceService.GetSpace(ctx, request.SpaceId)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
heads := space.DebugAllHeads()
|
||||
var trees []*apiproto.Tree
|
||||
for _, head := range heads {
|
||||
trees = append(trees, &apiproto.Tree{
|
||||
Id: head.Id,
|
||||
Heads: head.Heads,
|
||||
})
|
||||
}
|
||||
resp = &apiproto.AllTreesResponse{Trees: trees}
|
||||
return
|
||||
}
|
||||
|
||||
func (r *rpcHandler) AllSpaces(ctx context.Context, request *apiproto.AllSpacesRequest) (resp *apiproto.AllSpacesResponse, err error) {
|
||||
ids, err := r.storageService.AllSpaceIds()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
resp = &apiproto.AllSpacesResponse{SpaceIds: ids}
|
||||
return
|
||||
}
|
||||
|
||||
func (r *rpcHandler) TreeParams(ctx context.Context, request *apiproto.TreeParamsRequest) (resp *apiproto.TreeParamsResponse, err error) {
|
||||
tree, err := r.treeCache.GetTree(context.Background(), request.SpaceId, request.DocumentId)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
resp = &apiproto.TreeParamsResponse{
|
||||
RootId: tree.Root().Id,
|
||||
HeadIds: tree.Heads(),
|
||||
}
|
||||
return
|
||||
}
|
||||
69
node/api/service.go
Normal file
69
node/api/service.go
Normal file
@ -0,0 +1,69 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/config"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/rpc/server"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/secure"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/node/api/apiproto"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/node/nodespace"
|
||||
nodestorage "github.com/anytypeio/go-anytype-infrastructure-experiments/node/storage"
|
||||
"storj.io/drpc"
|
||||
)
|
||||
|
||||
const CName = "api.service"
|
||||
|
||||
var log = logger.NewNamed(CName)
|
||||
|
||||
func New() Service {
|
||||
return &service{BaseDrpcServer: server.NewBaseDrpcServer()}
|
||||
}
|
||||
|
||||
type Service interface {
|
||||
app.ComponentRunnable
|
||||
drpc.Mux
|
||||
}
|
||||
|
||||
type service struct {
|
||||
transport secure.Service
|
||||
cfg *config.Config
|
||||
treeCache treegetter.TreeGetter
|
||||
spaceService nodespace.Service
|
||||
storageService nodestorage.NodeStorage
|
||||
*server.BaseDrpcServer
|
||||
}
|
||||
|
||||
func (s *service) Init(a *app.App) (err error) {
|
||||
s.treeCache = a.MustComponent(treegetter.CName).(treegetter.TreeGetter)
|
||||
s.spaceService = a.MustComponent(nodespace.CName).(nodespace.Service)
|
||||
s.storageService = a.MustComponent(storage.CName).(nodestorage.NodeStorage)
|
||||
s.cfg = a.MustComponent(config.CName).(*config.Config)
|
||||
s.transport = a.MustComponent(secure.CName).(secure.Service)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *service) Name() (name string) {
|
||||
return CName
|
||||
}
|
||||
|
||||
func (s *service) Run(ctx context.Context) (err error) {
|
||||
err = s.BaseDrpcServer.Run(
|
||||
ctx,
|
||||
s.cfg.APIServer.ListenAddrs,
|
||||
func(handler drpc.Handler) drpc.Handler {
|
||||
return handler
|
||||
},
|
||||
s.transport.BasicListener)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return apiproto.DRPCRegisterNodeApi(s, &rpcHandler{s.treeCache, s.spaceService, s.storageService})
|
||||
}
|
||||
|
||||
func (s *service) Close(ctx context.Context) (err error) {
|
||||
return s.BaseDrpcServer.Close(ctx)
|
||||
}
|
||||
@ -15,6 +15,7 @@ import (
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/secure"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/node/account"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/node/api"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/node/nodespace"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/node/nodespace/nodecache"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/node/storage"
|
||||
@ -101,5 +102,6 @@ func Bootstrap(a *app.App) {
|
||||
Register(pool.New()).
|
||||
Register(nodespace.New()).
|
||||
Register(commonspace.New()).
|
||||
Register(server.New())
|
||||
Register(server.New()).
|
||||
Register(api.New())
|
||||
}
|
||||
|
||||
@ -10,6 +10,9 @@ require (
|
||||
github.com/akrylysov/pogreb v0.10.1
|
||||
github.com/anytypeio/go-anytype-infrastructure-experiments/common v0.0.0-00010101000000-000000000000
|
||||
github.com/anytypeio/go-anytype-infrastructure-experiments/consensus v0.0.0-00010101000000-000000000000
|
||||
github.com/golang/mock v1.6.0
|
||||
github.com/ipfs/go-cid v0.3.2
|
||||
github.com/stretchr/testify v1.8.0
|
||||
go.uber.org/zap v1.23.0
|
||||
)
|
||||
|
||||
@ -19,6 +22,7 @@ require (
|
||||
github.com/cespare/xxhash v1.1.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/cheggaaa/mb/v2 v2.0.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect
|
||||
github.com/fogleman/gg v1.3.0 // indirect
|
||||
github.com/goccy/go-graphviz v0.0.9 // indirect
|
||||
@ -26,12 +30,10 @@ require (
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/huandu/skiplist v1.2.0 // indirect
|
||||
github.com/ipfs/go-cid v0.3.2 // indirect
|
||||
github.com/ipfs/go-log/v2 v2.5.1 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.1.1 // indirect
|
||||
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
|
||||
github.com/libp2p/go-libp2p v0.23.2 // indirect
|
||||
github.com/libp2p/go-libp2p-core v0.20.1 // indirect
|
||||
github.com/libp2p/go-openssl v0.1.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.16 // indirect
|
||||
github.com/mattn/go-pointer v0.0.1 // indirect
|
||||
@ -46,6 +48,7 @@ require (
|
||||
github.com/multiformats/go-multihash v0.2.1 // indirect
|
||||
github.com/multiformats/go-varint v0.0.6 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_golang v1.13.0 // indirect
|
||||
github.com/prometheus/client_model v0.2.0 // indirect
|
||||
github.com/prometheus/common v0.37.0 // indirect
|
||||
|
||||
@ -109,6 +109,7 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
@ -191,8 +192,6 @@ github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6
|
||||
github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg=
|
||||
github.com/libp2p/go-libp2p v0.23.2 h1:yqyTeKQJyofWXxEv/eEVUvOrGdt/9x+0PIQ4N1kaxmE=
|
||||
github.com/libp2p/go-libp2p v0.23.2/go.mod h1:s9DEa5NLR4g+LZS+md5uGU4emjMWFiqkZr6hBTY8UxI=
|
||||
github.com/libp2p/go-libp2p-core v0.20.1 h1:fQz4BJyIFmSZAiTbKV8qoYhEH5Dtv/cVhZbG3Ib/+Cw=
|
||||
github.com/libp2p/go-libp2p-core v0.20.1/go.mod h1:6zR8H7CvQWgYLsbG4on6oLNSGcyKaYFSEYyDt51+bIY=
|
||||
github.com/libp2p/go-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+Ooo=
|
||||
github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
@ -271,11 +270,14 @@ github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0b
|
||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
@ -497,6 +499,7 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
@ -70,3 +70,16 @@ func (c *treeCache) GetTree(ctx context.Context, spaceId, id string) (tr tree.Ob
|
||||
tr = value.(tree.ObjectTree)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *treeCache) DeleteTree(ctx context.Context, spaceId, treeId string) (err error) {
|
||||
tr, err := c.GetTree(ctx, spaceId, treeId)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = tr.Delete()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
_, err = c.cache.Remove(treeId)
|
||||
return
|
||||
}
|
||||
|
||||
@ -19,22 +19,34 @@ func (r *rpcHandler) PullSpace(ctx context.Context, request *spacesyncproto.Pull
|
||||
return
|
||||
}
|
||||
|
||||
description := sp.Description()
|
||||
spaceDesc, err := sp.Description()
|
||||
if err != nil {
|
||||
err = spacesyncproto.ErrUnexpected
|
||||
return
|
||||
}
|
||||
|
||||
resp = &spacesyncproto.PullSpaceResponse{
|
||||
SpaceHeader: description.SpaceHeader,
|
||||
AclPayload: description.AclPayload,
|
||||
AclPayloadId: description.AclId,
|
||||
Payload: &spacesyncproto.SpacePayload{
|
||||
SpaceHeader: spaceDesc.SpaceHeader,
|
||||
AclPayloadId: spaceDesc.AclId,
|
||||
AclPayload: spaceDesc.AclPayload,
|
||||
SpaceSettingsPayload: spaceDesc.SpaceSettingsPayload,
|
||||
SpaceSettingsPayloadId: spaceDesc.SpaceSettingsId,
|
||||
},
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (r *rpcHandler) PushSpace(ctx context.Context, req *spacesyncproto.PushSpaceRequest) (resp *spacesyncproto.PushSpaceResponse, err error) {
|
||||
description := commonspace.SpaceDescription{
|
||||
SpaceHeader: req.SpaceHeader,
|
||||
AclId: req.AclPayloadId,
|
||||
AclPayload: req.AclPayload,
|
||||
SpaceHeader: req.Payload.SpaceHeader,
|
||||
AclId: req.Payload.AclPayloadId,
|
||||
AclPayload: req.Payload.AclPayload,
|
||||
SpaceSettingsPayload: req.Payload.SpaceSettingsPayload,
|
||||
SpaceSettingsId: req.Payload.SpaceSettingsPayloadId,
|
||||
}
|
||||
err = r.s.AddSpace(ctx, description)
|
||||
ctx = context.WithValue(ctx, commonspace.AddSpaceCtxKey, description)
|
||||
_, err = r.s.GetSpace(ctx, description.SpaceHeader.GetId())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user