From d3acc71d957534881904c8b89d854239b7b3845b Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Mon, 10 Oct 2022 20:10:47 +0200 Subject: [PATCH 01/20] Add some raw prototypes for storage --- common/commonspace/storage/storage.go | 1 + go.mod | 4 +- go.sum | 4 +- node/storage/keys.go | 37 +++++ node/storage/spacestorage.go | 136 +++++++++++++++ node/storage/storageservice.go | 27 +++ node/storage/treestorage.go | 157 ++++++++++++++++++ .../tree/mock_objecttree/mock_objecttree.go | 4 +- 8 files changed, 363 insertions(+), 7 deletions(-) create mode 100644 node/storage/keys.go create mode 100644 node/storage/spacestorage.go create mode 100644 node/storage/storageservice.go create mode 100644 node/storage/treestorage.go diff --git a/common/commonspace/storage/storage.go b/common/commonspace/storage/storage.go index fc1cfa8d..3a98da37 100644 --- a/common/commonspace/storage/storage.go +++ b/common/commonspace/storage/storage.go @@ -12,6 +12,7 @@ import ( const CName = "commonspace.storage" var ErrSpaceStorageExists = errors.New("space storage exists") +var ErrSpaceStorageMissing = errors.New("space storage missing") type SpaceStorage interface { storage.Provider diff --git a/go.mod b/go.mod index c25e1b35..8023dfa2 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/anytypeio/go-anytype-infrastructure-experiments go 1.18 require ( + github.com/akrylysov/pogreb v0.10.1 github.com/anytypeio/go-chash v0.0.0-20220629194632-4ad1154fe232 github.com/awalterschulze/gographviz v0.0.0-20190522210029-fa59802746ab github.com/cespare/xxhash v1.1.0 @@ -61,12 +62,9 @@ require ( go.uber.org/multierr v1.8.0 // indirect golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect golang.org/x/image v0.0.0-20200119044424-58c23975cae1 // indirect - golang.org/x/mod v0.4.2 // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 // indirect golang.org/x/text v0.3.7 // indirect - golang.org/x/tools v0.1.5 // indirect - golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect lukechampine.com/blake3 v1.1.6 // indirect diff --git a/go.sum b/go.sum index 6805b56c..08295176 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,8 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= +github.com/akrylysov/pogreb v0.10.1 h1:FqlR8VR7uCbJdfUob916tPM+idpKgeESDXOA1K0DK4w= +github.com/akrylysov/pogreb v0.10.1/go.mod h1:pNs6QmpQ1UlTJKDezuRWmaqkgUE2TuU0YTWyqJZ7+lI= github.com/anytypeio/go-chash v0.0.0-20220629194632-4ad1154fe232 h1:kMPPZYmJgbs4AJfodbg2OCXg5cp+9LPAJcLZJqmcghk= github.com/anytypeio/go-chash v0.0.0-20220629194632-4ad1154fe232/go.mod h1:+PeHBAWp7gUh/yw6uAauKc5ku0w4cFNg6DUddGxoGq0= github.com/awalterschulze/gographviz v0.0.0-20190522210029-fa59802746ab h1:+cdNqtOJWjvepyhxy23G7z7vmpYCoC65AP0nqi1f53s= @@ -167,7 +169,6 @@ golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+o golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -208,7 +209,6 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 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 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= 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= diff --git a/node/storage/keys.go b/node/storage/keys.go new file mode 100644 index 00000000..dbfdf385 --- /dev/null +++ b/node/storage/keys.go @@ -0,0 +1,37 @@ +package storage + +import ( + "fmt" + "strings" +) + +type treeKeys struct { + id string +} + +func (t treeKeys) HeadsKey() string { + return fmt.Sprintf("%s/heads", t.id) +} + +func (t treeKeys) RootKey() string { + return fmt.Sprintf("t/%s", t.id) +} + +func (t treeKeys) RawChangeKey(id string) string { + return fmt.Sprintf("%s/%s", t.id, id) +} + +type spaceKeys struct { +} + +func (s spaceKeys) HeaderKey() string { + return "header" +} + +func (s spaceKeys) ACLKey() string { + return "acl" +} + +func isTreeKey(path string) bool { + return strings.HasPrefix(path, "t/") +} diff --git a/node/storage/spacestorage.go b/node/storage/spacestorage.go new file mode 100644 index 00000000..66279f72 --- /dev/null +++ b/node/storage/spacestorage.go @@ -0,0 +1,136 @@ +package storage + +import ( + "github.com/akrylysov/pogreb" + "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/pkg/acl/storage" + "github.com/gogo/protobuf/proto" + "path" + "sync" +) + +type spaceStorage struct { + objDb *pogreb.DB + keys spaceKeys + mx sync.Mutex +} + +func newSpaceStorage(rootPath string, spaceId string) (store spacestorage.SpaceStorage, err error) { + dbPath := path.Join(rootPath, spaceId) + objDb, err := pogreb.Open(dbPath, nil) + if err != nil { + return + } + keys := spaceKeys{} + has, err := objDb.Has([]byte(keys.HeaderKey())) + if err != nil { + return + } + if !has { + err = spacestorage.ErrSpaceStorageMissing + return + } + + has, err = objDb.Has([]byte(keys.ACLKey())) + if err != nil { + return + } + if !has { + err = spacestorage.ErrSpaceStorageMissing + return + } + + store = &spaceStorage{ + objDb: objDb, + keys: keys, + } + return +} + +func createSpaceStorage(rootPath string, payload spacestorage.SpaceStorageCreatePayload) (store spacestorage.SpaceStorage, err error) { + dbPath := path.Join(rootPath, payload.Id) + db, err := pogreb.Open(dbPath, nil) + if err != nil { + return + } + + keys := spaceKeys{} + has, err := db.Has([]byte(keys.HeaderKey())) + if err != nil { + return + } + if has { + err = spacestorage.ErrSpaceStorageExists + return + } + + err = db.Put([]byte(payload.RecWithId.Id), payload.RecWithId.Payload) + if err != nil { + return + } + + marshalled, err := payload.SpaceHeader.Marshal() + if err != nil { + return + } + err = db.Put([]byte(payload.Id), marshalled) + if err != nil { + return + } + store = &spaceStorage{ + objDb: db, + keys: keys, + } + return +} + +func (s *spaceStorage) TreeStorage(id string) (storage.TreeStorage, error) { + return newTreeStorage(s.objDb, id) +} + +func (s *spaceStorage) CreateTreeStorage(payload storage.TreeStorageCreatePayload) (ts storage.TreeStorage, err error) { + s.mx.Lock() + defer s.mx.Unlock() + has, err := s.objDb.Has([]byte(payload.TreeId)) + if err != nil { + return + } + if has { + err = spacestorage.ErrSpaceStorageExists + return + } + return createTreeStorage(s.objDb, payload) +} + +func (s *spaceStorage) ACLStorage() (storage.ListStorage, error) { + return nil, nil +} + +func (s *spaceStorage) SpaceHeader() (header *spacesyncproto.SpaceHeader, err error) { + res, err := s.objDb.Get([]byte(s.keys.HeaderKey())) + if err != nil { + return + } + + header = &spacesyncproto.SpaceHeader{} + err = proto.Unmarshal(res, header) + return +} + +func (s *spaceStorage) StoredIds() (ids []string, err error) { + index := s.objDb.Items() + _, value, err := index.Next() + for err == nil { + strVal := string(value) + if isTreeKey(strVal) { + ids = append(ids, string(value)) + } + _, value, err = index.Next() + } + if err != pogreb.ErrIterationDone { + return + } + err = nil + return +} diff --git a/node/storage/storageservice.go b/node/storage/storageservice.go new file mode 100644 index 00000000..802a4f47 --- /dev/null +++ b/node/storage/storageservice.go @@ -0,0 +1,27 @@ +package storage + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage" +) + +type storageService struct { + rootPath string +} + +func (s *storageService) Init(a *app.App) (err error) { + //TODO implement me + panic("implement me") +} + +func (s *storageService) Name() (name string) { + return storage.CName +} + +func (s *storageService) SpaceStorage(id string) (storage.SpaceStorage, error) { + return newSpaceStorage(s.rootPath, id) +} + +func (s *storageService) CreateSpaceStorage(payload storage.SpaceStorageCreatePayload) (storage.SpaceStorage, error) { + return createSpaceStorage(s.rootPath, payload) +} diff --git a/node/storage/treestorage.go b/node/storage/treestorage.go new file mode 100644 index 00000000..2512f565 --- /dev/null +++ b/node/storage/treestorage.go @@ -0,0 +1,157 @@ +package storage + +import ( + "bytes" + "context" + "github.com/akrylysov/pogreb" + "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treechangeproto" + "github.com/gogo/protobuf/proto" + "strings" + "sync" +) + +type treeStorage struct { + db *pogreb.DB + path treeKeys + id string + rootPath []byte + headsPath []byte + heads []string + root *treechangeproto.RawTreeChangeWithId + headsMx sync.Mutex +} + +func newTreeStorage(db *pogreb.DB, treeId string) (ts storage.TreeStorage, err error) { + path := treeKeys{treeId} + heads, err := db.Get([]byte(path.HeadsKey())) + if err != nil { + return + } + + res, err := db.Get([]byte(path.RootKey())) + if err != nil { + return + } + + root := &treechangeproto.RawTreeChangeWithId{} + err = proto.Unmarshal(res, root) + if err != nil { + return + } + + ts = &treeStorage{ + db: db, + path: path, + rootPath: []byte(path.RootKey()), + headsPath: []byte(path.HeadsKey()), + id: treeId, + heads: parseHeads(heads), + root: root, + } + return +} + +func createTreeStorage(db *pogreb.DB, payload storage.TreeStorageCreatePayload) (ts storage.TreeStorage, err error) { + path := treeKeys{payload.TreeId} + heads := createHeadsPayload(payload.Heads) + + for _, ch := range payload.Changes { + err = db.Put([]byte(path.RawChangeKey(ch.Id)), ch.GetRawChange()) + if err != nil { + return + } + } + + err = db.Put([]byte(path.HeadsKey()), heads) + if err != nil { + return + } + + err = db.Put([]byte(path.RootKey()), payload.RootRawChange.GetRawChange()) + if err != nil { + return + } + + ts = &treeStorage{ + db: db, + path: path, + rootPath: []byte(path.RootKey()), + headsPath: []byte(path.HeadsKey()), + id: payload.TreeId, + heads: payload.Heads, + root: payload.RootRawChange, + } + return +} + +func (t *treeStorage) ID() (string, error) { + return t.id, nil +} + +func (t *treeStorage) Root() (raw *treechangeproto.RawTreeChangeWithId, err error) { + return t.root, nil +} + +func (t *treeStorage) Heads() ([]string, error) { + t.headsMx.Lock() + defer t.headsMx.Unlock() + return t.heads, nil +} + +func (t *treeStorage) SetHeads(heads []string) (err error) { + defer func() { + if err == nil { + t.headsMx.Lock() + t.heads = heads + t.headsMx.Unlock() + } + }() + payload := createHeadsPayload(heads) + return t.db.Put(t.headsPath, payload) +} + +func (t *treeStorage) AddRawChange(change *treechangeproto.RawTreeChangeWithId) (err error) { + return t.db.Put([]byte(change.Id), change.RawChange) +} + +func (t *treeStorage) GetRawChange(ctx context.Context, id string) (raw *treechangeproto.RawTreeChangeWithId, err error) { + res, err := t.db.Get([]byte(t.path.RawChangeKey(id))) + if err != nil { + return + } + + raw = &treechangeproto.RawTreeChangeWithId{ + RawChange: res, + Id: id, + } + return +} + +func (t *treeStorage) HasChange(ctx context.Context, id string) (bool, error) { + return t.db.Has([]byte(id)) +} + +func parseHeads(headsPayload []byte) []string { + return strings.Split(string(headsPayload), "/") +} + +func createHeadsPayload(heads []string) []byte { + var ( + b bytes.Buffer + totalLen int + ) + for _, s := range heads { + totalLen += len(s) + } + // adding separators + totalLen += len(heads) - 1 + b.Grow(totalLen) + for idx, s := range heads { + if idx > 0 { + b.WriteString("/") + } + b.WriteString(s) + } + return b.Bytes() +} diff --git a/pkg/acl/tree/mock_objecttree/mock_objecttree.go b/pkg/acl/tree/mock_objecttree/mock_objecttree.go index 70afa9d4..b739900c 100644 --- a/pkg/acl/tree/mock_objecttree/mock_objecttree.go +++ b/pkg/acl/tree/mock_objecttree/mock_objecttree.go @@ -137,7 +137,7 @@ func (mr *MockObjectTreeMockRecorder) HasChanges(arg0 ...interface{}) *gomock.Ca // Header mocks base method. func (m *MockObjectTree) Header() *treechangeproto.RawTreeChangeWithId { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Header") + ret := m.ctrl.Call(m, "HeaderKey") ret0, _ := ret[0].(*treechangeproto.RawTreeChangeWithId) return ret0 } @@ -145,7 +145,7 @@ func (m *MockObjectTree) Header() *treechangeproto.RawTreeChangeWithId { // Header indicates an expected call of Header. func (mr *MockObjectTreeMockRecorder) Header() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Header", reflect.TypeOf((*MockObjectTree)(nil).Header)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HeaderKey", reflect.TypeOf((*MockObjectTree)(nil).Header)) } // Heads mocks base method. From 526ddf12d5f8f1bda7b95c996785c60efb3df684 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Mon, 10 Oct 2022 23:08:44 +0200 Subject: [PATCH 02/20] WIP storage --- common/commonspace/diffservice/diffsyncer.go | 1 - .../diffservice/diffsyncer_test.go | 8 +- common/commonspace/payloads.go | 34 +- common/commonspace/service.go | 4 +- .../spacesyncproto/protos/spacesync.proto | 13 +- .../spacesyncproto/spacesync.pb.go | 626 ++++++++++++++---- .../storage/mock_storage/mock_storage.go | 4 +- common/commonspace/storage/storage.go | 7 +- node/nodespace/rpchandler.go | 7 +- node/storage/keys.go | 6 +- node/storage/spacestorage.go | 21 +- node/storage/treestorage.go | 37 +- pkg/acl/aclrecordproto/aclrecord.pb.go | 1 - .../testutils/testchanges/proto/test.pb.go | 1 - .../tree/mock_objecttree/mock_objecttree.go | 4 +- 15 files changed, 614 insertions(+), 160 deletions(-) diff --git a/common/commonspace/diffservice/diffsyncer.go b/common/commonspace/diffservice/diffsyncer.go index fe1d5d93..d5022323 100644 --- a/common/commonspace/diffservice/diffsyncer.go +++ b/common/commonspace/diffservice/diffsyncer.go @@ -107,7 +107,6 @@ func (d *diffSyncer) sendPushSpaceRequest(ctx context.Context, cl spacesyncproto } _, err = cl.PushSpace(ctx, &spacesyncproto.PushSpaceRequest{ - SpaceId: d.spaceId, SpaceHeader: header, AclRoot: root, }) diff --git a/common/commonspace/diffservice/diffsyncer_test.go b/common/commonspace/diffservice/diffsyncer_test.go index 444b73fa..47fa3c2d 100644 --- a/common/commonspace/diffservice/diffsyncer_test.go +++ b/common/commonspace/diffservice/diffsyncer_test.go @@ -25,7 +25,7 @@ import ( type pushSpaceRequestMatcher struct { spaceId string aclRoot *aclrecordproto.RawACLRecordWithId - spaceHeader *spacesyncproto.SpaceHeader + spaceHeader *spacesyncproto.RawSpaceHeaderWithId } func (p pushSpaceRequestMatcher) Matches(x interface{}) bool { @@ -34,7 +34,7 @@ func (p pushSpaceRequestMatcher) Matches(x interface{}) bool { return false } - return res.SpaceId == p.spaceId && res.AclRoot == p.aclRoot && res.SpaceHeader == p.spaceHeader + return res.AclRoot == p.aclRoot && res.SpaceHeader == p.spaceHeader } func (p pushSpaceRequestMatcher) String() string { @@ -73,7 +73,7 @@ func (m mockPeer) NewStream(ctx context.Context, rpc string, enc drpc.Encoding) func newPushSpaceRequestMatcher( spaceId string, aclRoot *aclrecordproto.RawACLRecordWithId, - spaceHeader *spacesyncproto.SpaceHeader) *pushSpaceRequestMatcher { + spaceHeader *spacesyncproto.RawSpaceHeaderWithId) *pushSpaceRequestMatcher { return &pushSpaceRequestMatcher{ spaceId: spaceId, aclRoot: aclRoot, @@ -125,7 +125,7 @@ func TestDiffSyncer_Sync(t *testing.T) { t.Run("diff syncer sync space missing", func(t *testing.T) { aclStorageMock := mock_aclstorage.NewMockListStorage(ctrl) aclRoot := &aclrecordproto.RawACLRecordWithId{} - spaceHeader := &spacesyncproto.SpaceHeader{} + spaceHeader := &spacesyncproto.RawSpaceHeaderWithId{} connectorMock.EXPECT(). GetResponsiblePeers(gomock.Any(), spaceId). diff --git a/common/commonspace/payloads.go b/common/commonspace/payloads.go index fae285ab..7c25884d 100644 --- a/common/commonspace/payloads.go +++ b/common/commonspace/payloads.go @@ -39,11 +39,21 @@ func storagePayloadForSpaceCreate(payload SpaceCreatePayload) (storagePayload st if err != nil { return } - id, err := cid.NewCIDFromBytes(marshalled) + signature, err := payload.SigningKey.Sign(marshalled) if err != nil { return } + rawHeader := &spacesyncproto.RawSpaceHeader{SpaceHeader: marshalled, Signature: signature} + marshalled, err = rawHeader.Marshal() + if err != nil { + return + } + id, err := cid.NewCIDFromBytes(marshalled) spaceId := NewSpaceId(id, payload.ReplicationKey) + rawHeaderWithId := &spacesyncproto.RawSpaceHeaderWithId{ + RawHeader: marshalled, + Id: spaceId, + } // encrypting read key hasher := fnv.New64() @@ -74,9 +84,8 @@ func storagePayloadForSpaceCreate(payload SpaceCreatePayload) (storagePayload st // creating storage storagePayload = storage.SpaceStorageCreatePayload{ - RecWithId: rawWithId, - SpaceHeader: header, - Id: id, + RecWithId: rawWithId, + SpaceHeaderWithId: rawHeaderWithId, } return } @@ -118,11 +127,21 @@ func storagePayloadForSpaceDerive(payload SpaceDerivePayload) (storagePayload st if err != nil { return } - id, err := cid.NewCIDFromBytes(marshalled) + signature, err := payload.SigningKey.Sign(marshalled) if err != nil { return } + rawHeader := &spacesyncproto.RawSpaceHeader{SpaceHeader: marshalled, Signature: signature} + marshalled, err = rawHeader.Marshal() + if err != nil { + return + } + id, err := cid.NewCIDFromBytes(marshalled) spaceId := NewSpaceId(id, repKey) + rawHeaderWithId := &spacesyncproto.RawSpaceHeaderWithId{ + RawHeader: marshalled, + Id: spaceId, + } // deriving and encrypting read key readKey, err := aclrecordproto.ACLReadKeyDerive(signPrivKey, encPrivKey) @@ -157,9 +176,8 @@ func storagePayloadForSpaceDerive(payload SpaceDerivePayload) (storagePayload st // creating storage storagePayload = storage.SpaceStorageCreatePayload{ - RecWithId: rawWithId, - SpaceHeader: header, - Id: id, + RecWithId: rawWithId, + SpaceHeaderWithId: rawHeaderWithId, } return } diff --git a/common/commonspace/service.go b/common/commonspace/service.go index adefcf7f..dd0347a1 100644 --- a/common/commonspace/service.go +++ b/common/commonspace/service.go @@ -62,7 +62,7 @@ func (s *service) CreateSpace( return } - return s.GetSpace(ctx, storageCreate.Id) + return s.GetSpace(ctx, storageCreate.SpaceHeaderWithId.GetId()) } func (s *service) DeriveSpace( @@ -78,7 +78,7 @@ func (s *service) DeriveSpace( return } - return s.GetSpace(ctx, storageCreate.Id) + return s.GetSpace(ctx, storageCreate.SpaceHeaderWithId.GetId()) } func (s *service) GetSpace(ctx context.Context, id string) (Space, error) { diff --git a/common/commonspace/spacesyncproto/protos/spacesync.proto b/common/commonspace/spacesyncproto/protos/spacesync.proto index 2b45d366..20bb12fa 100644 --- a/common/commonspace/spacesyncproto/protos/spacesync.proto +++ b/common/commonspace/spacesyncproto/protos/spacesync.proto @@ -102,8 +102,7 @@ message ObjectErrorResponse { // PushSpaceRequest is a request to add space on a node containing only one acl record message PushSpaceRequest { - string spaceId = 1; - SpaceHeader spaceHeader = 2; + RawSpaceHeaderWithId spaceHeader = 2; aclrecord.RawACLRecordWithId aclRoot = 3; } @@ -118,3 +117,13 @@ message SpaceHeader { uint64 replicationKey = 4; bytes seed = 5; } + +message RawSpaceHeader { + bytes spaceHeader = 1; + bytes signature = 2; +} + +message RawSpaceHeaderWithId { + bytes rawHeader = 1; + string id = 2; +} diff --git a/common/commonspace/spacesyncproto/spacesync.pb.go b/common/commonspace/spacesyncproto/spacesync.pb.go index 0c89fb20..2fe5cbc4 100644 --- a/common/commonspace/spacesyncproto/spacesync.pb.go +++ b/common/commonspace/spacesyncproto/spacesync.pb.go @@ -747,8 +747,7 @@ func (m *ObjectErrorResponse) GetError() string { // PushSpaceRequest is a request to add space on a node containing only one acl record type PushSpaceRequest struct { - SpaceId string `protobuf:"bytes,1,opt,name=spaceId,proto3" json:"spaceId,omitempty"` - SpaceHeader *SpaceHeader `protobuf:"bytes,2,opt,name=spaceHeader,proto3" json:"spaceHeader,omitempty"` + SpaceHeader *RawSpaceHeaderWithId `protobuf:"bytes,2,opt,name=spaceHeader,proto3" json:"spaceHeader,omitempty"` AclRoot *aclrecordproto.RawACLRecordWithId `protobuf:"bytes,3,opt,name=aclRoot,proto3" json:"aclRoot,omitempty"` } @@ -785,14 +784,7 @@ func (m *PushSpaceRequest) XXX_DiscardUnknown() { var xxx_messageInfo_PushSpaceRequest proto.InternalMessageInfo -func (m *PushSpaceRequest) GetSpaceId() string { - if m != nil { - return m.SpaceId - } - return "" -} - -func (m *PushSpaceRequest) GetSpaceHeader() *SpaceHeader { +func (m *PushSpaceRequest) GetSpaceHeader() *RawSpaceHeaderWithId { if m != nil { return m.SpaceHeader } @@ -920,6 +912,110 @@ func (m *SpaceHeader) GetSeed() []byte { return nil } +type RawSpaceHeader struct { + SpaceHeader []byte `protobuf:"bytes,1,opt,name=spaceHeader,proto3" json:"spaceHeader,omitempty"` + Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (m *RawSpaceHeader) Reset() { *m = RawSpaceHeader{} } +func (m *RawSpaceHeader) String() string { return proto.CompactTextString(m) } +func (*RawSpaceHeader) ProtoMessage() {} +func (*RawSpaceHeader) Descriptor() ([]byte, []int) { + return fileDescriptor_5855f4ef9cf24cdb, []int{14} +} +func (m *RawSpaceHeader) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RawSpaceHeader) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RawSpaceHeader.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RawSpaceHeader) XXX_Merge(src proto.Message) { + xxx_messageInfo_RawSpaceHeader.Merge(m, src) +} +func (m *RawSpaceHeader) XXX_Size() int { + return m.Size() +} +func (m *RawSpaceHeader) XXX_DiscardUnknown() { + xxx_messageInfo_RawSpaceHeader.DiscardUnknown(m) +} + +var xxx_messageInfo_RawSpaceHeader proto.InternalMessageInfo + +func (m *RawSpaceHeader) GetSpaceHeader() []byte { + if m != nil { + return m.SpaceHeader + } + return nil +} + +func (m *RawSpaceHeader) GetSignature() []byte { + if m != nil { + return m.Signature + } + return nil +} + +type RawSpaceHeaderWithId struct { + RawHeader []byte `protobuf:"bytes,1,opt,name=rawHeader,proto3" json:"rawHeader,omitempty"` + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` +} + +func (m *RawSpaceHeaderWithId) Reset() { *m = RawSpaceHeaderWithId{} } +func (m *RawSpaceHeaderWithId) String() string { return proto.CompactTextString(m) } +func (*RawSpaceHeaderWithId) ProtoMessage() {} +func (*RawSpaceHeaderWithId) Descriptor() ([]byte, []int) { + return fileDescriptor_5855f4ef9cf24cdb, []int{15} +} +func (m *RawSpaceHeaderWithId) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RawSpaceHeaderWithId) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RawSpaceHeaderWithId.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RawSpaceHeaderWithId) XXX_Merge(src proto.Message) { + xxx_messageInfo_RawSpaceHeaderWithId.Merge(m, src) +} +func (m *RawSpaceHeaderWithId) XXX_Size() int { + return m.Size() +} +func (m *RawSpaceHeaderWithId) XXX_DiscardUnknown() { + xxx_messageInfo_RawSpaceHeaderWithId.DiscardUnknown(m) +} + +var xxx_messageInfo_RawSpaceHeaderWithId proto.InternalMessageInfo + +func (m *RawSpaceHeaderWithId) GetRawHeader() []byte { + if m != nil { + return m.RawHeader + } + return nil +} + +func (m *RawSpaceHeaderWithId) GetId() string { + if m != nil { + return m.Id + } + return "" +} + func init() { proto.RegisterEnum("anySpace.ErrCodes", ErrCodes_name, ErrCodes_value) proto.RegisterType((*HeadSyncRange)(nil), "anySpace.HeadSyncRange") @@ -936,6 +1032,8 @@ func init() { proto.RegisterType((*PushSpaceRequest)(nil), "anySpace.PushSpaceRequest") proto.RegisterType((*PushSpaceResponse)(nil), "anySpace.PushSpaceResponse") proto.RegisterType((*SpaceHeader)(nil), "anySpace.SpaceHeader") + proto.RegisterType((*RawSpaceHeader)(nil), "anySpace.RawSpaceHeader") + proto.RegisterType((*RawSpaceHeaderWithId)(nil), "anySpace.RawSpaceHeaderWithId") } func init() { @@ -943,65 +1041,68 @@ func init() { } var fileDescriptor_5855f4ef9cf24cdb = []byte{ - // 919 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x56, 0xcd, 0x8e, 0x1b, 0x45, - 0x10, 0xf6, 0x78, 0xbd, 0x6b, 0xbb, 0xbc, 0x3f, 0x4e, 0x87, 0x0d, 0x83, 0x43, 0x1c, 0x33, 0x07, - 0xb4, 0x02, 0xb1, 0x46, 0xe6, 0x10, 0x60, 0x91, 0x50, 0xb2, 0x78, 0x65, 0x2b, 0xe4, 0x47, 0xbd, - 0x09, 0x48, 0x88, 0x4b, 0x67, 0xa6, 0xd6, 0x1e, 0x32, 0x9e, 0x1e, 0xa6, 0xdb, 0x6c, 0xfc, 0x04, - 0x5c, 0x40, 0xe2, 0x09, 0x90, 0x78, 0x16, 0x2e, 0x1c, 0x73, 0xcc, 0x11, 0xed, 0xbe, 0x08, 0xea, - 0x9a, 0x19, 0xcf, 0xd8, 0x4c, 0xb2, 0xc7, 0x5c, 0x3c, 0x5d, 0x55, 0x5f, 0x55, 0x7f, 0xf5, 0xd3, - 0xdd, 0x86, 0xcf, 0x5d, 0x39, 0x9b, 0xc9, 0xb0, 0x9f, 0x7c, 0x54, 0x24, 0x5c, 0xec, 0xd3, 0xaf, - 0x5a, 0x84, 0x6e, 0x14, 0x4b, 0x2d, 0xfb, 0xf4, 0xab, 0x72, 0xed, 0x21, 0x29, 0x58, 0x43, 0x84, - 0x8b, 0x53, 0xa3, 0xeb, 0xf4, 0xa3, 0xe7, 0x93, 0xbe, 0x70, 0x83, 0xbe, 0x8e, 0x11, 0xdd, 0xa9, - 0x08, 0x27, 0xb8, 0xe2, 0x99, 0xab, 0x13, 0xd7, 0xce, 0x27, 0x99, 0x83, 0x70, 0x83, 0x18, 0x5d, - 0x19, 0x7b, 0x2b, 0xf8, 0xa5, 0x36, 0x81, 0x3b, 0x63, 0xd8, 0x19, 0xa1, 0xf0, 0x4e, 0x17, 0xa1, - 0xcb, 0x4d, 0x14, 0xc6, 0xa0, 0x76, 0x16, 0xcb, 0x99, 0x6d, 0xf5, 0xac, 0x83, 0x1a, 0xa7, 0x35, - 0xdb, 0x85, 0xaa, 0x96, 0x76, 0x95, 0x34, 0x55, 0x2d, 0xd9, 0x3b, 0xb0, 0x19, 0xf8, 0x33, 0x5f, - 0xdb, 0x1b, 0x3d, 0xeb, 0x60, 0x87, 0x27, 0x82, 0x73, 0x0e, 0xbb, 0xcb, 0x50, 0xa8, 0xe6, 0x81, - 0x36, 0xb1, 0xa6, 0x42, 0x4d, 0x29, 0xd6, 0x36, 0xa7, 0x35, 0x3b, 0x82, 0x06, 0x06, 0x38, 0xc3, - 0x50, 0x2b, 0xbb, 0xda, 0xdb, 0x38, 0x68, 0x0d, 0x6e, 0x1f, 0x66, 0xd9, 0x1e, 0xae, 0xfa, 0x0f, - 0x13, 0x1c, 0x5f, 0x3a, 0x98, 0x8d, 0x5d, 0x39, 0x0f, 0x97, 0x1b, 0x93, 0xe0, 0x1c, 0xc1, 0x7e, - 0xa9, 0xa3, 0xe1, 0xed, 0x7b, 0xb4, 0x7b, 0x93, 0x57, 0x7d, 0x8f, 0xf8, 0xa0, 0xf0, 0x28, 0x93, - 0x26, 0xa7, 0xb5, 0xf3, 0x23, 0xec, 0xe5, 0xce, 0x3f, 0xcf, 0x51, 0x69, 0x66, 0x43, 0x9d, 0x1a, - 0x32, 0xce, 0x7c, 0x33, 0x91, 0xf5, 0x61, 0x2b, 0x36, 0x55, 0xca, 0xa8, 0xbf, 0x5b, 0x42, 0xdd, - 0xd8, 0x79, 0x0a, 0x73, 0x4e, 0xa0, 0x5d, 0xa0, 0x16, 0xc9, 0x50, 0x21, 0x1b, 0x40, 0x3d, 0x26, - 0x9a, 0xca, 0xb6, 0x28, 0x8a, 0xfd, 0xba, 0x02, 0xf0, 0x0c, 0xe8, 0x5c, 0x58, 0x70, 0xed, 0xd1, - 0xb3, 0x9f, 0xd0, 0xd5, 0xc6, 0xfa, 0x00, 0x95, 0x12, 0x13, 0x7c, 0x03, 0xd1, 0x2f, 0xa1, 0xee, - 0xca, 0x50, 0x63, 0xa8, 0x29, 0xd9, 0xd6, 0xa0, 0x97, 0xef, 0x91, 0xc7, 0x39, 0x4e, 0x20, 0xdf, - 0x89, 0x60, 0x8e, 0x3c, 0x73, 0x60, 0x5f, 0x03, 0xc4, 0x52, 0xea, 0x63, 0x9a, 0x2a, 0xaa, 0xb4, - 0xe9, 0x51, 0x61, 0xd0, 0xb8, 0x38, 0x7f, 0x12, 0x23, 0x26, 0x80, 0xef, 0x7d, 0x3d, 0x1d, 0x7b, - 0xbc, 0xe0, 0xc2, 0x6e, 0xc0, 0x96, 0x41, 0x8f, 0x3d, 0xbb, 0x46, 0xac, 0x52, 0x89, 0x75, 0x01, - 0x74, 0x2c, 0xdc, 0xe7, 0x7e, 0x38, 0x19, 0x7b, 0xf6, 0x26, 0xd9, 0x0a, 0x1a, 0xe7, 0xef, 0x2a, - 0xdc, 0x28, 0x27, 0xc7, 0xbe, 0x02, 0x30, 0xdd, 0x7a, 0x1a, 0x79, 0x42, 0x23, 0x25, 0xdb, 0x1a, - 0x74, 0xd6, 0x53, 0x1a, 0x2d, 0x11, 0xa3, 0x0a, 0x2f, 0xe0, 0xd9, 0x7d, 0xd8, 0x3b, 0x9b, 0x07, - 0x41, 0xa1, 0xc7, 0x69, 0x55, 0x6e, 0xaf, 0x87, 0x38, 0x59, 0x85, 0x8d, 0x2a, 0x7c, 0xdd, 0x93, - 0x3d, 0x84, 0x76, 0xae, 0x4a, 0x5a, 0x9a, 0x16, 0xa9, 0xf7, 0xfa, 0x68, 0x09, 0x6e, 0x54, 0xe1, - 0xff, 0xf3, 0x65, 0x43, 0xd8, 0xc1, 0x38, 0x96, 0xf1, 0x32, 0x58, 0x8d, 0x82, 0xdd, 0x5a, 0x0f, - 0x36, 0x2c, 0x82, 0x46, 0x15, 0xbe, 0xea, 0x75, 0xaf, 0x0e, 0x9b, 0xbf, 0x98, 0x52, 0x39, 0xbf, - 0x5a, 0xd0, 0x5e, 0xaf, 0x87, 0x39, 0x38, 0xa6, 0x1e, 0xc9, 0xc4, 0x35, 0x79, 0x22, 0xb0, 0x2f, - 0xa0, 0x9e, 0xb4, 0x34, 0x3f, 0x8a, 0x57, 0xb4, 0x39, 0xc3, 0x33, 0x07, 0xb6, 0x55, 0x28, 0x22, - 0x35, 0x95, 0xfa, 0xb1, 0xd0, 0x53, 0x7b, 0x83, 0xe2, 0xae, 0xe8, 0x9c, 0xdf, 0x2c, 0xd8, 0x2f, - 0x2d, 0xeb, 0xdb, 0xa1, 0xf3, 0xbb, 0x95, 0x8d, 0xd7, 0x7a, 0x5f, 0xde, 0x0e, 0x9f, 0x8f, 0xe1, - 0x7a, 0x49, 0x67, 0x0d, 0x17, 0xea, 0x6c, 0x7a, 0xa4, 0x13, 0xc1, 0xf9, 0xd3, 0x82, 0xf6, 0xe3, - 0xb9, 0x9a, 0xd2, 0x44, 0x5c, 0x7d, 0x51, 0xdd, 0x81, 0x16, 0x2d, 0xcd, 0x08, 0x60, 0x9c, 0x4e, - 0xfb, 0x7e, 0x3e, 0x52, 0xa7, 0xb9, 0x91, 0x17, 0x91, 0xec, 0x0e, 0xd4, 0x85, 0x1b, 0x70, 0x29, - 0x75, 0x3a, 0xd4, 0xb7, 0x0e, 0xf3, 0x27, 0x83, 0x8b, 0xf3, 0xbb, 0xc7, 0xdf, 0x72, 0x12, 0xb2, - 0x8c, 0x53, 0xb4, 0x73, 0x1d, 0xae, 0x15, 0xf8, 0x25, 0xb9, 0x38, 0x7f, 0x59, 0xd0, 0x2a, 0x6c, - 0xc5, 0x3a, 0xd0, 0xf0, 0x3d, 0x0c, 0xb5, 0xaf, 0x17, 0xe9, 0xa3, 0xb0, 0x94, 0xd9, 0xfb, 0xd0, - 0xd4, 0xfe, 0x0c, 0x95, 0x16, 0xb3, 0x88, 0x08, 0x6f, 0xf0, 0x5c, 0x61, 0xac, 0x44, 0xf3, 0xc9, - 0x22, 0x4a, 0x8e, 0x5b, 0x93, 0xe7, 0x0a, 0xf6, 0x21, 0xec, 0xc6, 0x18, 0x05, 0xbe, 0x2b, 0xb4, - 0x2f, 0xc3, 0xfb, 0xb8, 0xa0, 0x43, 0x54, 0xe3, 0x6b, 0x5a, 0xf3, 0x00, 0x28, 0xc4, 0xe4, 0xee, - 0xd9, 0xe6, 0xb4, 0xfe, 0xe8, 0x21, 0x34, 0x86, 0x71, 0x7c, 0x2c, 0x3d, 0x54, 0x6c, 0x17, 0xe0, - 0x69, 0x88, 0x2f, 0x22, 0x74, 0x35, 0x7a, 0xed, 0x0a, 0x6b, 0xc3, 0x36, 0xd1, 0x7f, 0xe0, 0x2b, - 0xe5, 0x87, 0x93, 0xb6, 0xc5, 0xf6, 0xd2, 0x84, 0x86, 0x2f, 0x7c, 0xa5, 0x55, 0xbb, 0x6a, 0x14, - 0xd4, 0xbf, 0x47, 0x67, 0x67, 0x0a, 0x75, 0xdb, 0x1b, 0xbc, 0xb2, 0x60, 0x93, 0x20, 0xec, 0x2e, - 0x34, 0xb2, 0xfb, 0x9c, 0xbd, 0x57, 0x76, 0xc7, 0x53, 0x17, 0x3b, 0x9d, 0xd2, 0xeb, 0x3f, 0x19, - 0x86, 0x6f, 0xa0, 0xb9, 0xac, 0x2a, 0x2b, 0x00, 0xd7, 0x47, 0xa1, 0x73, 0xb3, 0xd4, 0x96, 0x46, - 0x39, 0x81, 0xad, 0x53, 0x1d, 0xa3, 0x98, 0xb1, 0x9b, 0x65, 0xcf, 0x40, 0xfa, 0x9c, 0x74, 0xde, - 0x64, 0x3c, 0xb0, 0x3e, 0xb5, 0xee, 0x1d, 0xfd, 0x73, 0xd1, 0xb5, 0x5e, 0x5e, 0x74, 0xad, 0x7f, - 0x2f, 0xba, 0xd6, 0x1f, 0x97, 0xdd, 0xca, 0xcb, 0xcb, 0x6e, 0xe5, 0xd5, 0x65, 0xb7, 0xf2, 0xc3, - 0x07, 0x57, 0xfe, 0xd5, 0x79, 0xb6, 0x45, 0x9f, 0xcf, 0xfe, 0x0b, 0x00, 0x00, 0xff, 0xff, 0xce, - 0x99, 0xdc, 0xc5, 0x16, 0x09, 0x00, 0x00, + // 965 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x56, 0xcd, 0x92, 0xdb, 0x44, + 0x10, 0xb6, 0xbc, 0x3f, 0xb6, 0xdb, 0x5e, 0xaf, 0x33, 0xf9, 0x41, 0x38, 0xc4, 0x31, 0x3a, 0x50, + 0x5b, 0x50, 0xac, 0x29, 0x73, 0xe0, 0x67, 0xa9, 0x82, 0x64, 0xe3, 0x2d, 0xbb, 0x42, 0x92, 0xad, + 0xd9, 0x04, 0xaa, 0x28, 0x2e, 0x13, 0x69, 0xd6, 0x16, 0x91, 0x35, 0x62, 0x66, 0x8c, 0xe3, 0x27, + 0xe0, 0x02, 0x55, 0xbc, 0x02, 0xcf, 0xc2, 0x85, 0x63, 0x8e, 0x39, 0x52, 0xbb, 0x2f, 0x42, 0x4d, + 0x4b, 0xb2, 0x24, 0x47, 0x49, 0x8e, 0xb9, 0xd8, 0xd3, 0x3d, 0x5f, 0xf7, 0x7c, 0xf3, 0x75, 0x8f, + 0xdb, 0xf0, 0xa5, 0x2b, 0xe6, 0x73, 0x11, 0x0e, 0xe2, 0x2f, 0x15, 0x31, 0x97, 0x0f, 0xf0, 0x53, + 0xad, 0x42, 0x37, 0x92, 0x42, 0x8b, 0x01, 0x7e, 0xaa, 0xcc, 0x7b, 0x88, 0x0e, 0x52, 0x67, 0xe1, + 0xea, 0xcc, 0xf8, 0xba, 0x83, 0xe8, 0xd9, 0x74, 0xc0, 0xdc, 0x60, 0xa0, 0x25, 0xe7, 0xee, 0x8c, + 0x85, 0x53, 0x5e, 0x88, 0xcc, 0xdc, 0x71, 0x68, 0xf7, 0xd3, 0x34, 0x80, 0xb9, 0x81, 0xe4, 0xae, + 0x90, 0x5e, 0x01, 0xbf, 0xf6, 0xc6, 0x70, 0x67, 0x02, 0x7b, 0x63, 0xce, 0xbc, 0xb3, 0x55, 0xe8, + 0x52, 0x93, 0x85, 0x10, 0xd8, 0x3e, 0x97, 0x62, 0x6e, 0x5b, 0x7d, 0xeb, 0x60, 0x9b, 0xe2, 0x9a, + 0xb4, 0xa1, 0xaa, 0x85, 0x5d, 0x45, 0x4f, 0x55, 0x0b, 0x72, 0x0d, 0x76, 0x02, 0x7f, 0xee, 0x6b, + 0x7b, 0xab, 0x6f, 0x1d, 0xec, 0xd1, 0xd8, 0x70, 0x96, 0xd0, 0x5e, 0xa7, 0xe2, 0x6a, 0x11, 0x68, + 0x93, 0x6b, 0xc6, 0xd4, 0x0c, 0x73, 0xb5, 0x28, 0xae, 0xc9, 0x11, 0xd4, 0x79, 0xc0, 0xe7, 0x3c, + 0xd4, 0xca, 0xae, 0xf6, 0xb7, 0x0e, 0x9a, 0xc3, 0xdb, 0x87, 0xe9, 0x6d, 0x0f, 0x8b, 0xf1, 0xa3, + 0x18, 0x47, 0xd7, 0x01, 0xe6, 0x60, 0x57, 0x2c, 0xc2, 0xf5, 0xc1, 0x68, 0x38, 0x47, 0x70, 0xbd, + 0x34, 0xd0, 0xf0, 0xf6, 0x3d, 0x3c, 0xbd, 0x41, 0xab, 0xbe, 0x87, 0x7c, 0x38, 0xf3, 0xf0, 0x26, + 0x0d, 0x8a, 0x6b, 0xe7, 0x67, 0xd8, 0xcf, 0x82, 0x7f, 0x5d, 0x70, 0xa5, 0x89, 0x0d, 0x35, 0x2c, + 0xc8, 0x24, 0x8d, 0x4d, 0x4d, 0x32, 0x80, 0x5d, 0x69, 0x54, 0x4a, 0xa9, 0xbf, 0x57, 0x42, 0xdd, + 0xec, 0xd3, 0x04, 0xe6, 0x9c, 0x40, 0x27, 0x47, 0x2d, 0x12, 0xa1, 0xe2, 0x64, 0x08, 0x35, 0x89, + 0x34, 0x95, 0x6d, 0x61, 0x16, 0xfb, 0x75, 0x02, 0xd0, 0x14, 0xe8, 0x5c, 0x58, 0x70, 0xe5, 0xd1, + 0xd3, 0x5f, 0xb8, 0xab, 0xcd, 0xee, 0x03, 0xae, 0x14, 0x9b, 0xf2, 0x37, 0x10, 0xfd, 0x1a, 0x6a, + 0xae, 0x08, 0x35, 0x0f, 0x35, 0x5e, 0xb6, 0x39, 0xec, 0x67, 0x67, 0x64, 0x79, 0x8e, 0x63, 0xc8, + 0x0f, 0x2c, 0x58, 0x70, 0x9a, 0x06, 0x90, 0x6f, 0x01, 0xa4, 0x10, 0xfa, 0x18, 0xbb, 0x0a, 0x95, + 0x36, 0x35, 0xca, 0x35, 0x1a, 0x65, 0xcb, 0xc7, 0x92, 0xf3, 0x18, 0xf0, 0xa3, 0xaf, 0x67, 0x13, + 0x8f, 0xe6, 0x42, 0xc8, 0x0d, 0xd8, 0x35, 0xe8, 0x89, 0x67, 0x6f, 0x23, 0xab, 0xc4, 0x22, 0x3d, + 0x00, 0x2d, 0x99, 0xfb, 0xcc, 0x0f, 0xa7, 0x13, 0xcf, 0xde, 0xc1, 0xbd, 0x9c, 0xc7, 0xf9, 0xa7, + 0x0a, 0x37, 0xca, 0xc9, 0x91, 0x6f, 0x00, 0x4c, 0xb5, 0x9e, 0x44, 0x1e, 0xd3, 0x1c, 0x2f, 0xdb, + 0x1c, 0x76, 0x37, 0xaf, 0x34, 0x5e, 0x23, 0xc6, 0x15, 0x9a, 0xc3, 0x93, 0xfb, 0xb0, 0x7f, 0xbe, + 0x08, 0x82, 0x5c, 0x8d, 0x13, 0x55, 0x6e, 0x6f, 0xa6, 0x38, 0x29, 0xc2, 0xc6, 0x15, 0xba, 0x19, + 0x49, 0x1e, 0x42, 0x27, 0x73, 0xc5, 0x25, 0x4d, 0x44, 0xea, 0xbf, 0x3e, 0x5b, 0x8c, 0x1b, 0x57, + 0xe8, 0x2b, 0xb1, 0x64, 0x04, 0x7b, 0x5c, 0x4a, 0x21, 0xd7, 0xc9, 0xb6, 0x31, 0xd9, 0xad, 0xcd, + 0x64, 0xa3, 0x3c, 0x68, 0x5c, 0xa1, 0xc5, 0xa8, 0xbb, 0x35, 0xd8, 0xf9, 0xcd, 0x48, 0xe5, 0xfc, + 0x6e, 0x41, 0x67, 0x53, 0x0f, 0xf3, 0x70, 0x8c, 0x1e, 0x71, 0xc7, 0x35, 0x68, 0x6c, 0x90, 0xaf, + 0xa0, 0x16, 0x97, 0x34, 0x7b, 0x8a, 0x6f, 0x29, 0x73, 0x8a, 0x27, 0x0e, 0xb4, 0x54, 0xc8, 0x22, + 0x35, 0x13, 0xfa, 0x94, 0xe9, 0x99, 0xbd, 0x85, 0x79, 0x0b, 0x3e, 0xe7, 0x0f, 0x0b, 0xae, 0x97, + 0xca, 0xfa, 0x6e, 0xe8, 0xfc, 0x69, 0xa5, 0xed, 0xb5, 0x59, 0x97, 0x77, 0xc3, 0xe7, 0x13, 0xb8, + 0x5a, 0x52, 0x59, 0xc3, 0x05, 0x2b, 0x9b, 0x3c, 0xe9, 0xd8, 0x30, 0xe4, 0x3b, 0xa7, 0x0b, 0x35, + 0xc3, 0x8e, 0x48, 0x65, 0xfc, 0x0e, 0x9a, 0xf8, 0xe0, 0x4d, 0xa1, 0xb9, 0x4c, 0x7a, 0xba, 0x97, + 0x35, 0x0e, 0x65, 0xcb, 0xb3, 0x6c, 0x3f, 0xe1, 0x98, 0x0f, 0x21, 0x5f, 0x40, 0x8d, 0xb9, 0x01, + 0x15, 0x42, 0x27, 0x3d, 0x7c, 0xeb, 0x30, 0x9b, 0x10, 0x94, 0x2d, 0xef, 0x1c, 0x7f, 0x4f, 0xd1, + 0x48, 0x2f, 0x98, 0xa0, 0x9d, 0xab, 0x70, 0x25, 0x47, 0x27, 0xa6, 0xee, 0xfc, 0x6d, 0x41, 0x33, + 0x77, 0x20, 0xe9, 0x42, 0xdd, 0xf7, 0x78, 0xa8, 0x7d, 0xbd, 0x4a, 0x66, 0xc0, 0xda, 0x26, 0x1f, + 0x40, 0x43, 0xfb, 0x73, 0xae, 0x34, 0x9b, 0x47, 0xc8, 0x7c, 0x8b, 0x66, 0x0e, 0xb3, 0x8b, 0x34, + 0x1f, 0xaf, 0xa2, 0xf8, 0x75, 0x35, 0x68, 0xe6, 0x20, 0x1f, 0x41, 0x5b, 0xf2, 0x28, 0xf0, 0x5d, + 0xa6, 0x7d, 0x11, 0xde, 0xe7, 0x2b, 0x7c, 0x33, 0xdb, 0x74, 0xc3, 0x6b, 0x7e, 0xef, 0x15, 0xe7, + 0xf1, 0x4f, 0x4d, 0x8b, 0xe2, 0xda, 0x39, 0x85, 0x76, 0x51, 0x16, 0xd2, 0x2f, 0xaa, 0x18, 0x13, + 0x2d, 0xa8, 0x64, 0xd8, 0xf8, 0xd3, 0x90, 0xe9, 0x85, 0xe4, 0xc8, 0xb5, 0x45, 0x33, 0x87, 0x73, + 0x0f, 0xae, 0x95, 0x09, 0x6d, 0xa2, 0x24, 0x5b, 0x16, 0xb2, 0x66, 0x8e, 0x64, 0x36, 0x55, 0xd3, + 0xd9, 0xf4, 0xf1, 0x43, 0xa8, 0x8f, 0xa4, 0x3c, 0x16, 0x1e, 0x57, 0xa4, 0x0d, 0xf0, 0x24, 0xe4, + 0xcf, 0x23, 0xee, 0x6a, 0xee, 0x75, 0x2a, 0xa4, 0x03, 0x2d, 0x4c, 0xff, 0xc0, 0x57, 0xca, 0x0f, + 0xa7, 0x1d, 0x8b, 0xec, 0x27, 0x42, 0x8f, 0x9e, 0xfb, 0x4a, 0xab, 0x4e, 0xd5, 0x38, 0xb0, 0x8d, + 0x1e, 0x9d, 0x9f, 0x2b, 0xae, 0x3b, 0xde, 0xf0, 0xa5, 0x05, 0x3b, 0x08, 0x21, 0x77, 0xa0, 0x9e, + 0x8e, 0x15, 0xf2, 0x7e, 0xd9, 0xa8, 0xc1, 0x66, 0xea, 0x76, 0x4b, 0xa7, 0x50, 0xdc, 0x93, 0xf7, + 0xa0, 0xb1, 0xae, 0x36, 0xc9, 0x01, 0x37, 0x3b, 0xb2, 0x7b, 0xb3, 0x74, 0x2f, 0xc9, 0x72, 0x02, + 0xbb, 0x67, 0x5a, 0x72, 0x36, 0x27, 0x37, 0xcb, 0xa6, 0x51, 0x32, 0xd5, 0xba, 0x6f, 0xda, 0x3c, + 0xb0, 0x3e, 0xb3, 0xee, 0x1e, 0xfd, 0x7b, 0xd1, 0xb3, 0x5e, 0x5c, 0xf4, 0xac, 0xff, 0x2e, 0x7a, + 0xd6, 0x5f, 0x97, 0xbd, 0xca, 0x8b, 0xcb, 0x5e, 0xe5, 0xe5, 0x65, 0xaf, 0xf2, 0xd3, 0x87, 0x6f, + 0xfd, 0xc7, 0xf5, 0x74, 0x17, 0xbf, 0x3e, 0xff, 0x3f, 0x00, 0x00, 0xff, 0xff, 0x2e, 0x4f, 0xd9, + 0xa3, 0x9d, 0x09, 0x00, 0x00, } func (m *HeadSyncRange) Marshal() (dAtA []byte, err error) { @@ -1632,13 +1733,6 @@ func (m *PushSpaceRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x12 } - if len(m.SpaceId) > 0 { - i -= len(m.SpaceId) - copy(dAtA[i:], m.SpaceId) - i = encodeVarintSpacesync(dAtA, i, uint64(len(m.SpaceId))) - i-- - dAtA[i] = 0xa - } return len(dAtA) - i, nil } @@ -1719,6 +1813,80 @@ func (m *SpaceHeader) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *RawSpaceHeader) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RawSpaceHeader) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RawSpaceHeader) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signature) > 0 { + i -= len(m.Signature) + copy(dAtA[i:], m.Signature) + i = encodeVarintSpacesync(dAtA, i, uint64(len(m.Signature))) + i-- + dAtA[i] = 0x12 + } + if len(m.SpaceHeader) > 0 { + i -= len(m.SpaceHeader) + copy(dAtA[i:], m.SpaceHeader) + i = encodeVarintSpacesync(dAtA, i, uint64(len(m.SpaceHeader))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *RawSpaceHeaderWithId) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RawSpaceHeaderWithId) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RawSpaceHeaderWithId) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Id) > 0 { + i -= len(m.Id) + copy(dAtA[i:], m.Id) + i = encodeVarintSpacesync(dAtA, i, uint64(len(m.Id))) + i-- + dAtA[i] = 0x12 + } + if len(m.RawHeader) > 0 { + i -= len(m.RawHeader) + copy(dAtA[i:], m.RawHeader) + i = encodeVarintSpacesync(dAtA, i, uint64(len(m.RawHeader))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintSpacesync(dAtA []byte, offset int, v uint64) int { offset -= sovSpacesync(v) base := offset @@ -2010,10 +2178,6 @@ func (m *PushSpaceRequest) Size() (n int) { } var l int _ = l - l = len(m.SpaceId) - if l > 0 { - n += 1 + l + sovSpacesync(uint64(l)) - } if m.SpaceHeader != nil { l = m.SpaceHeader.Size() n += 1 + l + sovSpacesync(uint64(l)) @@ -2061,6 +2225,40 @@ func (m *SpaceHeader) Size() (n int) { return n } +func (m *RawSpaceHeader) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.SpaceHeader) + if l > 0 { + n += 1 + l + sovSpacesync(uint64(l)) + } + l = len(m.Signature) + if l > 0 { + n += 1 + l + sovSpacesync(uint64(l)) + } + return n +} + +func (m *RawSpaceHeaderWithId) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.RawHeader) + if l > 0 { + n += 1 + l + sovSpacesync(uint64(l)) + } + l = len(m.Id) + if l > 0 { + n += 1 + l + sovSpacesync(uint64(l)) + } + return n +} + func sovSpacesync(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -3588,38 +3786,6 @@ func (m *PushSpaceRequest) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: PushSpaceRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SpaceId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSpacesync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSpacesync - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSpacesync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.SpaceId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field SpaceHeader", wireType) @@ -3650,7 +3816,7 @@ func (m *PushSpaceRequest) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.SpaceHeader == nil { - m.SpaceHeader = &SpaceHeader{} + m.SpaceHeader = &RawSpaceHeaderWithId{} } if err := m.SpaceHeader.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -3951,6 +4117,240 @@ func (m *SpaceHeader) Unmarshal(dAtA []byte) error { } return nil } +func (m *RawSpaceHeader) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RawSpaceHeader: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RawSpaceHeader: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SpaceHeader", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSpacesync + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSpacesync + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SpaceHeader = append(m.SpaceHeader[:0], dAtA[iNdEx:postIndex]...) + if m.SpaceHeader == nil { + m.SpaceHeader = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSpacesync + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSpacesync + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signature = append(m.Signature[:0], dAtA[iNdEx:postIndex]...) + if m.Signature == nil { + m.Signature = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSpacesync(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSpacesync + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RawSpaceHeaderWithId) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RawSpaceHeaderWithId: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RawSpaceHeaderWithId: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RawHeader", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSpacesync + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSpacesync + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RawHeader = append(m.RawHeader[:0], dAtA[iNdEx:postIndex]...) + if m.RawHeader == nil { + m.RawHeader = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpacesync + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSpacesync + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSpacesync + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Id = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSpacesync(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSpacesync + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipSpacesync(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/common/commonspace/storage/mock_storage/mock_storage.go b/common/commonspace/storage/mock_storage/mock_storage.go index 14b6003f..197e13bd 100644 --- a/common/commonspace/storage/mock_storage/mock_storage.go +++ b/common/commonspace/storage/mock_storage/mock_storage.go @@ -149,10 +149,10 @@ func (mr *MockSpaceStorageMockRecorder) CreateTreeStorage(arg0 interface{}) *gom } // SpaceHeader mocks base method. -func (m *MockSpaceStorage) SpaceHeader() (*spacesyncproto.SpaceHeader, error) { +func (m *MockSpaceStorage) SpaceHeader() (*spacesyncproto.RawSpaceHeaderWithId, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SpaceHeader") - ret0, _ := ret[0].(*spacesyncproto.SpaceHeader) + ret0, _ := ret[0].(*spacesyncproto.RawSpaceHeaderWithId) ret1, _ := ret[1].(error) return ret0, ret1 } diff --git a/common/commonspace/storage/storage.go b/common/commonspace/storage/storage.go index 3a98da37..0dc9df99 100644 --- a/common/commonspace/storage/storage.go +++ b/common/commonspace/storage/storage.go @@ -17,14 +17,13 @@ var ErrSpaceStorageMissing = errors.New("space storage missing") type SpaceStorage interface { storage.Provider ACLStorage() (storage.ListStorage, error) - SpaceHeader() (*spacesyncproto.SpaceHeader, error) + SpaceHeader() (*spacesyncproto.RawSpaceHeaderWithId, error) StoredIds() ([]string, error) } type SpaceStorageCreatePayload struct { - RecWithId *aclrecordproto.RawACLRecordWithId - SpaceHeader *spacesyncproto.SpaceHeader - Id string + RecWithId *aclrecordproto.RawACLRecordWithId + SpaceHeaderWithId *spacesyncproto.RawSpaceHeaderWithId } type SpaceStorageProvider interface { diff --git a/node/nodespace/rpchandler.go b/node/nodespace/rpchandler.go index dd050fde..019c48af 100644 --- a/node/nodespace/rpchandler.go +++ b/node/nodespace/rpchandler.go @@ -12,7 +12,7 @@ type rpcHandler struct { } func (r *rpcHandler) PushSpace(ctx context.Context, req *spacesyncproto.PushSpaceRequest) (resp *spacesyncproto.PushSpaceResponse, err error) { - _, err = r.s.GetSpace(ctx, req.SpaceId) + _, err = r.s.GetSpace(ctx, req.SpaceHeader.Id) if err == nil { err = spacesyncproto.ErrSpaceExists return @@ -23,9 +23,8 @@ func (r *rpcHandler) PushSpace(ctx context.Context, req *spacesyncproto.PushSpac } payload := storage.SpaceStorageCreatePayload{ - RecWithId: req.AclRoot, - SpaceHeader: req.SpaceHeader, - Id: req.SpaceId, + RecWithId: req.AclRoot, + SpaceHeaderWithId: req.SpaceHeader, } _, err = r.s.spaceStorageProvider.CreateSpaceStorage(payload) if err != nil { diff --git a/node/storage/keys.go b/node/storage/keys.go index dbfdf385..de99e6e7 100644 --- a/node/storage/keys.go +++ b/node/storage/keys.go @@ -10,7 +10,7 @@ type treeKeys struct { } func (t treeKeys) HeadsKey() string { - return fmt.Sprintf("%s/heads", t.id) + return fmt.Sprintf("t/%s/heads", t.id) } func (t treeKeys) RootKey() string { @@ -18,7 +18,7 @@ func (t treeKeys) RootKey() string { } func (t treeKeys) RawChangeKey(id string) string { - return fmt.Sprintf("%s/%s", t.id, id) + return fmt.Sprintf("t/%s/%s", t.id, id) } type spaceKeys struct { @@ -33,5 +33,5 @@ func (s spaceKeys) ACLKey() string { } func isTreeKey(path string) bool { - return strings.HasPrefix(path, "t/") + return strings.HasPrefix(path, "t/") && len(strings.Split(path, "/")) > 2 } diff --git a/node/storage/spacestorage.go b/node/storage/spacestorage.go index 66279f72..8f775314 100644 --- a/node/storage/spacestorage.go +++ b/node/storage/spacestorage.go @@ -49,7 +49,8 @@ func newSpaceStorage(rootPath string, spaceId string) (store spacestorage.SpaceS } func createSpaceStorage(rootPath string, payload spacestorage.SpaceStorageCreatePayload) (store spacestorage.SpaceStorage, err error) { - dbPath := path.Join(rootPath, payload.Id) + // TODO: add payload verification + dbPath := path.Join(rootPath, payload.SpaceHeaderWithId.Id) db, err := pogreb.Open(dbPath, nil) if err != nil { return @@ -65,19 +66,24 @@ func createSpaceStorage(rootPath string, payload spacestorage.SpaceStorageCreate return } - err = db.Put([]byte(payload.RecWithId.Id), payload.RecWithId.Payload) + marshalledRec, err := payload.RecWithId.Marshal() + if err != nil { + return + } + err = db.Put([]byte(keys.ACLKey()), marshalledRec) if err != nil { return } - marshalled, err := payload.SpaceHeader.Marshal() + marshalledHeader, err := payload.SpaceHeaderWithId.Marshal() if err != nil { return } - err = db.Put([]byte(payload.Id), marshalled) + err = db.Put([]byte(keys.HeaderKey()), marshalledHeader) if err != nil { return } + store = &spaceStorage{ objDb: db, keys: keys, @@ -100,6 +106,7 @@ func (s *spaceStorage) CreateTreeStorage(payload storage.TreeStorageCreatePayloa err = spacestorage.ErrSpaceStorageExists return } + return createTreeStorage(s.objDb, payload) } @@ -107,19 +114,20 @@ func (s *spaceStorage) ACLStorage() (storage.ListStorage, error) { return nil, nil } -func (s *spaceStorage) SpaceHeader() (header *spacesyncproto.SpaceHeader, err error) { +func (s *spaceStorage) SpaceHeader() (header *spacesyncproto.RawSpaceHeaderWithId, err error) { res, err := s.objDb.Get([]byte(s.keys.HeaderKey())) if err != nil { return } - header = &spacesyncproto.SpaceHeader{} + header = &spacesyncproto.RawSpaceHeaderWithId{} err = proto.Unmarshal(res, header) return } func (s *spaceStorage) StoredIds() (ids []string, err error) { index := s.objDb.Items() + _, value, err := index.Next() for err == nil { strVal := string(value) @@ -128,6 +136,7 @@ func (s *spaceStorage) StoredIds() (ids []string, err error) { } _, value, err = index.Next() } + if err != pogreb.ErrIterationDone { return } diff --git a/node/storage/treestorage.go b/node/storage/treestorage.go index 2512f565..1fdeef2d 100644 --- a/node/storage/treestorage.go +++ b/node/storage/treestorage.go @@ -28,11 +28,19 @@ func newTreeStorage(db *pogreb.DB, treeId string) (ts storage.TreeStorage, err e if err != nil { return } + if heads == nil { + err = storage.ErrUnknownTreeId + return + } res, err := db.Get([]byte(path.RootKey())) if err != nil { return } + if res == nil { + err = storage.ErrUnknownTreeId + return + } root := &treechangeproto.RawTreeChangeWithId{} err = proto.Unmarshal(res, root) @@ -53,31 +61,46 @@ func newTreeStorage(db *pogreb.DB, treeId string) (ts storage.TreeStorage, err e } func createTreeStorage(db *pogreb.DB, payload storage.TreeStorageCreatePayload) (ts storage.TreeStorage, err error) { - path := treeKeys{payload.TreeId} + keys := treeKeys{id: payload.TreeId} + has, err := db.Has([]byte(keys.RootKey())) + if err != nil { + return + } + if !has { + err = storage.ErrUnknownTreeId + return + } + heads := createHeadsPayload(payload.Heads) for _, ch := range payload.Changes { - err = db.Put([]byte(path.RawChangeKey(ch.Id)), ch.GetRawChange()) + err = db.Put([]byte(keys.RawChangeKey(ch.Id)), ch.GetRawChange()) if err != nil { return } } - err = db.Put([]byte(path.HeadsKey()), heads) + err = db.Put([]byte(keys.HeadsKey()), heads) if err != nil { return } - err = db.Put([]byte(path.RootKey()), payload.RootRawChange.GetRawChange()) + // duplicating same change in raw changes + err = db.Put([]byte(keys.RawChangeKey(payload.TreeId)), payload.RootRawChange.GetRawChange()) + if err != nil { + return + } + + err = db.Put([]byte(keys.RootKey()), payload.RootRawChange.GetRawChange()) if err != nil { return } ts = &treeStorage{ db: db, - path: path, - rootPath: []byte(path.RootKey()), - headsPath: []byte(path.HeadsKey()), + path: keys, + rootPath: []byte(keys.RootKey()), + headsPath: []byte(keys.HeadsKey()), id: payload.TreeId, heads: payload.Heads, root: payload.RootRawChange, diff --git a/pkg/acl/aclrecordproto/aclrecord.pb.go b/pkg/acl/aclrecordproto/aclrecord.pb.go index e11f5209..158b70f5 100644 --- a/pkg/acl/aclrecordproto/aclrecord.pb.go +++ b/pkg/acl/aclrecordproto/aclrecord.pb.go @@ -324,7 +324,6 @@ func (m *ACLRoot) GetTimestamp() int64 { type ACLContentValue struct { // Types that are valid to be assigned to Value: - // // *ACLContentValue_UserAdd // *ACLContentValue_UserRemove // *ACLContentValue_UserPermissionChange diff --git a/pkg/acl/testutils/testchanges/proto/test.pb.go b/pkg/acl/testutils/testchanges/proto/test.pb.go index d99ba0b5..e8e43c54 100644 --- a/pkg/acl/testutils/testchanges/proto/test.pb.go +++ b/pkg/acl/testutils/testchanges/proto/test.pb.go @@ -60,7 +60,6 @@ var xxx_messageInfo_PlainTextChange proto.InternalMessageInfo type PlainTextChange_Content struct { // Types that are valid to be assigned to Value: - // // *PlainTextChange_Content_TextAppend Value isPlainTextChange_Content_Value `protobuf_oneof:"value"` } diff --git a/pkg/acl/tree/mock_objecttree/mock_objecttree.go b/pkg/acl/tree/mock_objecttree/mock_objecttree.go index b739900c..70afa9d4 100644 --- a/pkg/acl/tree/mock_objecttree/mock_objecttree.go +++ b/pkg/acl/tree/mock_objecttree/mock_objecttree.go @@ -137,7 +137,7 @@ func (mr *MockObjectTreeMockRecorder) HasChanges(arg0 ...interface{}) *gomock.Ca // Header mocks base method. func (m *MockObjectTree) Header() *treechangeproto.RawTreeChangeWithId { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "HeaderKey") + ret := m.ctrl.Call(m, "Header") ret0, _ := ret[0].(*treechangeproto.RawTreeChangeWithId) return ret0 } @@ -145,7 +145,7 @@ func (m *MockObjectTree) Header() *treechangeproto.RawTreeChangeWithId { // Header indicates an expected call of Header. func (mr *MockObjectTreeMockRecorder) Header() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HeaderKey", reflect.TypeOf((*MockObjectTree)(nil).Header)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Header", reflect.TypeOf((*MockObjectTree)(nil).Header)) } // Heads mocks base method. From 79f5fc6908bcd0e7d52792cbb830e14655f3266a Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Tue, 11 Oct 2022 09:56:51 +0200 Subject: [PATCH 03/20] Fix incorrect storage key --- node/storage/spacestorage.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/node/storage/spacestorage.go b/node/storage/spacestorage.go index 8f775314..b1d797c2 100644 --- a/node/storage/spacestorage.go +++ b/node/storage/spacestorage.go @@ -98,7 +98,9 @@ func (s *spaceStorage) TreeStorage(id string) (storage.TreeStorage, error) { func (s *spaceStorage) CreateTreeStorage(payload storage.TreeStorageCreatePayload) (ts storage.TreeStorage, err error) { s.mx.Lock() defer s.mx.Unlock() - has, err := s.objDb.Has([]byte(payload.TreeId)) + + treeKeys := treeKeys{payload.TreeId} + has, err := s.objDb.Has([]byte(treeKeys.RootKey())) if err != nil { return } From 03eb8834c1a1c2d8173eba5cef1c45b7191a8cc3 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Tue, 11 Oct 2022 10:25:29 +0200 Subject: [PATCH 04/20] Wire up node --- cmd/node/node.go | 5 +- cmd/nodesgen/gen.go | 1 + config/config.go | 1 + config/storage.go | 5 ++ etc/config.yml | 39 ++++++++++++---- etc/configs/cons1.yml | 6 +-- etc/configs/cons2.yml | 6 +-- etc/configs/cons3.yml | 6 +-- etc/configs/node1.yml | 44 +++++++++--------- etc/configs/node2.yml | 44 +++++++++--------- etc/configs/node3.yml | 44 +++++++++--------- node/nodespace/nodecache/treecache.go | 12 ++--- node/storage/keys.go | 27 ++++++----- node/storage/spacestorage.go | 16 +++---- node/storage/storageservice.go | 10 +++- node/storage/treestorage.go | 66 +++++++++++++-------------- 16 files changed, 189 insertions(+), 143 deletions(-) create mode 100644 config/storage.go diff --git a/cmd/node/node.go b/cmd/node/node.go index 47d0c3e5..bc277ebf 100644 --- a/cmd/node/node.go +++ b/cmd/node/node.go @@ -15,6 +15,8 @@ import ( "github.com/anytypeio/go-anytype-infrastructure-experiments/config" "github.com/anytypeio/go-anytype-infrastructure-experiments/node/account" "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" "go.uber.org/zap" "net/http" _ "net/http/pprof" @@ -89,7 +91,8 @@ func main() { func Bootstrap(a *app.App) { a.Register(account.New()). - // TODO: add space storage provider from node side + Register(storage.New()). + Register(nodecache.New(200)). Register(nodeconf.New()). Register(secure.New()). Register(dialer.New()). diff --git a/cmd/nodesgen/gen.go b/cmd/nodesgen/gen.go index 51db1459..2a122295 100644 --- a/cmd/nodesgen/gen.go +++ b/cmd/nodesgen/gen.go @@ -156,6 +156,7 @@ func genNodeConfig(addresses []string, apiPort string) (config.Config, error) { ListenAddrs: addresses, TLS: false, }, + Storage: config.Storage{Path: "db"}, Account: config.Account{ PeerId: peerID.String(), SigningKey: encSignKey, diff --git a/config/config.go b/config/config.go index 012a7da5..8a17e89a 100644 --- a/config/config.go +++ b/config/config.go @@ -29,6 +29,7 @@ type Config struct { APIServer APIServer `yaml:"apiServer"` Nodes []Node `yaml:"nodes"` Space Space `yaml:"space"` + Storage Storage `yaml:"storage"` } func (c *Config) Init(a *app.App) (err error) { diff --git a/config/storage.go b/config/storage.go new file mode 100644 index 00000000..ebafe622 --- /dev/null +++ b/config/storage.go @@ -0,0 +1,5 @@ +package config + +type Storage struct { + Path string `yaml:"path"` +} diff --git a/etc/config.yml b/etc/config.yml index 8c829b5f..a95316f6 100644 --- a/etc/config.yml +++ b/etc/config.yml @@ -5,20 +5,41 @@ grpcServer: - 127.0.0.1:4430 tls: false account: - peerId: 12D3KooWSUx2LXPvoZGp72Dt7b7r1kPSmQ6zAUwKkHFyX64uiXRu - signingKey: 4QTrtkFLQe9wQcWT/cgFEwfMHB5pt4axInNmCIMCZaz3nVdyygRoO8/YH0V15X6Mnw1NQWsS1YIWiLS22hwepA== - encryptionKey: MIIEpAIBAAKCAQEAmqAAOPfR86po3m+zwSzbAlZGgMMF188v35Ulqf9Gb4KO8DZ9ifxrqpjlLZRxPKeXj3wSSQEXsJf3A82rZlDxddZSM0i7Mx5G2G0zRHWx9dC58PpX6o/fDuvSwcyXqOgIK55N/hyEuIbWQgp5Rk9uy2Zbrhv5ZL5CvceM0b9wSKt/hRvntxSbG+HRgXWaQvAReGuJrySVvkh6fhC3G0IwqyFbGNq2zqAJej6NBzZA3thHgTn5PoWD8O4cyukBxunKGu3HLE3vJtqEMFrkNFw5SMpdEtxyTLN6T1HIeYCY9RL+BFYfxIWg6pGtIoIJKUB0XapJr9ltzvXfT9KeSCU0VwIDAQABAoIBAAp/xsQXf7gN4CUKbKg3RX+5H/xqQaFPvi5uUCpk3QGBWfdRm+CctSrWSul3ZOD7eD0T7aHrYxJonysw8ex2no6jyN0WmS91ZNYZRBvn6feI/rcwKHwS3NCEjsD+BWZAqx1bGGyivxhQf4fociemCR3ii2MdHygKCzobrKIpX5RvhanI4j01dyLlxwqTsteuc/o5RR4jfg1eN0kldFjk3UcSNyzzEv5o5UhRsHCLJBTNTvYZBN4FpyaqcLT9gKS9aVBvQH63R+E5dyxo1+24tZZricW59h2bN3CFriqkwBo1y0gTnR6VQ22MBvIUxYUm82cxXs/Vr0YQTSAaEGThxFECgYEAxKQMRnM39WMzrNx1WDwpBERRj1T0TbLf1uq6viPiLdik2Tm2aCBZyr5j82Ey7fZ7OafKGfsM0I2AuYeoBdYDuYN6A7tE9kpnECubnWuIvUeYcL+1VzzMedVtdKwQXrYbhqKtyvnSJ9gQ6CusHtsDE1bQvTMxBX4KNBeBYllCUasCgYEAyU0RPUaj56CyLHKty8jNg6wl+06IZ0pUPIWZ//b1zeZrlHGYDp/InxS8huGFapzOg1sbQBS6j3j3YE3Ts6v6FNuIa4pcPQ91YuHiWWQdgVjrCZdleanFWGTjIx12+RGj9vx4voRhNQcHW1YeTvvyj4BN/ECR6GNaoS/ZjBKo1AUCgYEAj6AyxxJJARagG9Y6b2QhoVg1Kjem6UmJbPStyUt0XIAsh+07afqXGxrM7mtEQ8MQZiBD4Y4Y4gs4xkprUzfqKIn7iNYznKDjflAbrXNpwLaWhWPBFCL4RtS4ycsTedoRaNlRjzvBYBDU6H9djHvzVyDF/itx1s0krr+sZSVE51kCgYBxGRinecna+KFCccgNp6s34H+Se2QNzGgZfOKyOjmOTniA9XV+Oe3I2yi1C34fESzCBm0ACuVqeIdcFz3rQ6OFFnbGHP2H3OiR/uFiYepl4uRjBimgOm9DI6Ot9f8DHxMlUGIygEPxPBq5CWCL9egpEeg+4rRXgYLI7w5mMZGjVQKBgQDC4qyH7FK3lLv5JomoK6nNjpyPNBmr0Rt215oM/AWQaxDhFZH5un68ueZ7MfybwXxHHFQ4ZeSwYs006f1XGPNW6qrH6pi/3SCLFuGVfNnLVwCBkm3QaQrxFm3v9LmVCidTNta0l0DrUldZdK8/P31GBxKo/MmYF/f9LO/Mfm/uDg== + peerId: 12D3KooWNGRznbh4RCYY1hDnG1RLCtWviWwVnZGjKHtsXVgPckNk + signingKey: buHKTg4VF6lskoFWDdjtjWNj2c/fz0zAxKrOW05pRRu4+aw/tClrubW5wpeCOJxPSMHJBTj/8bJ8icwKfe7yMQ== + encryptionKey: MIIEpAIBAAKCAQEAtoc/5YBUSzPUISHv/COa2wTeWpsuxuLGOd+IYLXe8xXIry0GHCqCN7orZq5iz7BFs2i6o0ttK2PpRa5xz/GnKtTkQowmfDNwh/f+jIlMo+CcL54Qq4sURexChBCg6z3XbSQK1C9yGA4QaNFRDgSzAs1IC8BCRFf7XDbK06zxWw/As7D3Bo1V3TO0LWi/URkV1PBZdQxX6unt5VplhTQ92o22xczb15zfBQW59qEZYyPa2apwUfmhZgjoAbSOIQm96U7P+HrLa8va1h9q9o+eYefco2N7wv40MYsDXll09Tfc/VhDEfmuKfwmSe5AEnpsg1gD94fX/4KVt7Usb7u6gwIDAQABAoIBAC7POqS5p2Rt0z33/RqVavY2JmvoFjPtHlbjK49ZtOZ0NLYv/rwkbqap+M1pdW+7zfQ3rH2KL2IMSluTZB6m428Jj8w9MvVxH6/O+pnB8ESqqoNPrwi/LyDLeTdzKEGL535W2uwVitX+bVjkLTxCGkJisNJKqPPr+EtqxdNJK9BlJ9VdOLFLi67mOsu3F6AtDtBC3VFXZJa8Wbocu0A7hm8QWa23AL7+EZdV9kJ8Dw2qEYXyYRwmhExuZWNsPsnMvNhlCj8By9IPuICDzW87SfcsIQd7vjSg3y60mmGvl9WGxJbpEkSa+MxCA175k3E30KP1tYMOBQyhlCr7qRYWpdkCgYEA4a7CJGqtdMB8KByzrfGazm8koI0Y+qcriYaOWeoZayoxshwmemqJQTEP29D5SumxOcobKnKRHhKBhhlJenc5xNwppgMIgexZtLLAB2pZzLZ/bIy39T+lAEVOQWIEWDUQ0MwqaGNvaZ2bXyM1Xq6Bovurs8gSwmRIQspskeD/fy8CgYEAzwxpLa/W+BcRPH7VpLSkwSPgsAXW+TCoxWuCMj/W7MmCplyohW8a8wc42RFwKCH4ULpyNbv0VWdCM910/U1sf+0s7B3+IeW/0oMlLIPOd/Z39Legm+h0o1l3rD7deWdL7AMnaJIJsMBOUp0DRBSE5Bj6iUr1MnIEMX/3zFqdxO0CgYEAo4FSZMHpA3JFQWZyAy7M4o0Bc1RmaYrd7xhOX/RMECkUsh7U/dHbuSCLhc1kH5Mp9F1pyxoP60KrFnWRl6lzcB22CvGdo0uSPmlW2MiDYN5DeWiGCqfeqlCL/rC9xw5DLZMNkm2gFVu7anT+wKcbgvJlFq54cN/ovoMbn6DsWr8CgYEAgUVIbgP5fdA5LMIr9bfrncMeyAf9XnwpA4nKMkF1mUV/UwtLFHR4KQB7V9vxYL1E4nJmWHJPbPsZdHRyVKyAb6bPg2R+hP+DMpY7IX3x7ShvYNU9a9pI6Kw1cc+WS/RYjLSzaDC16CtJO39YyKrfBeMqmYm5aZOSVq2FM4voMUkCgYBudtWqqwKvA/Ig32hPBa/pqh+R11LeN8F/NsjrCA3geo8MlDqD0To+r9FTv14AksR7BsAfhoGglbvpddTL+CqHgtA4igNWp2/UCaomfnCgnFl/rvo+OGiVR5DgaC4ALw9onsdfeNgrQ5PkqCCi2crb3txdRWGA2QyGvsBmb1u8+A== apiServer: port: "8080" nodes: - - peerId: 12D3KooWSUx2LXPvoZGp72Dt7b7r1kPSmQ6zAUwKkHFyX64uiXRu + - peerId: 12D3KooWNGRznbh4RCYY1hDnG1RLCtWviWwVnZGjKHtsXVgPckNk address: 127.0.0.1:4430 - signingKey: 4QTrtkFLQe9wQcWT/cgFEwfMHB5pt4axInNmCIMCZaz3nVdyygRoO8/YH0V15X6Mnw1NQWsS1YIWiLS22hwepA== - encryptionKey: MIIEpAIBAAKCAQEAmqAAOPfR86po3m+zwSzbAlZGgMMF188v35Ulqf9Gb4KO8DZ9ifxrqpjlLZRxPKeXj3wSSQEXsJf3A82rZlDxddZSM0i7Mx5G2G0zRHWx9dC58PpX6o/fDuvSwcyXqOgIK55N/hyEuIbWQgp5Rk9uy2Zbrhv5ZL5CvceM0b9wSKt/hRvntxSbG+HRgXWaQvAReGuJrySVvkh6fhC3G0IwqyFbGNq2zqAJej6NBzZA3thHgTn5PoWD8O4cyukBxunKGu3HLE3vJtqEMFrkNFw5SMpdEtxyTLN6T1HIeYCY9RL+BFYfxIWg6pGtIoIJKUB0XapJr9ltzvXfT9KeSCU0VwIDAQABAoIBAAp/xsQXf7gN4CUKbKg3RX+5H/xqQaFPvi5uUCpk3QGBWfdRm+CctSrWSul3ZOD7eD0T7aHrYxJonysw8ex2no6jyN0WmS91ZNYZRBvn6feI/rcwKHwS3NCEjsD+BWZAqx1bGGyivxhQf4fociemCR3ii2MdHygKCzobrKIpX5RvhanI4j01dyLlxwqTsteuc/o5RR4jfg1eN0kldFjk3UcSNyzzEv5o5UhRsHCLJBTNTvYZBN4FpyaqcLT9gKS9aVBvQH63R+E5dyxo1+24tZZricW59h2bN3CFriqkwBo1y0gTnR6VQ22MBvIUxYUm82cxXs/Vr0YQTSAaEGThxFECgYEAxKQMRnM39WMzrNx1WDwpBERRj1T0TbLf1uq6viPiLdik2Tm2aCBZyr5j82Ey7fZ7OafKGfsM0I2AuYeoBdYDuYN6A7tE9kpnECubnWuIvUeYcL+1VzzMedVtdKwQXrYbhqKtyvnSJ9gQ6CusHtsDE1bQvTMxBX4KNBeBYllCUasCgYEAyU0RPUaj56CyLHKty8jNg6wl+06IZ0pUPIWZ//b1zeZrlHGYDp/InxS8huGFapzOg1sbQBS6j3j3YE3Ts6v6FNuIa4pcPQ91YuHiWWQdgVjrCZdleanFWGTjIx12+RGj9vx4voRhNQcHW1YeTvvyj4BN/ECR6GNaoS/ZjBKo1AUCgYEAj6AyxxJJARagG9Y6b2QhoVg1Kjem6UmJbPStyUt0XIAsh+07afqXGxrM7mtEQ8MQZiBD4Y4Y4gs4xkprUzfqKIn7iNYznKDjflAbrXNpwLaWhWPBFCL4RtS4ycsTedoRaNlRjzvBYBDU6H9djHvzVyDF/itx1s0krr+sZSVE51kCgYBxGRinecna+KFCccgNp6s34H+Se2QNzGgZfOKyOjmOTniA9XV+Oe3I2yi1C34fESzCBm0ACuVqeIdcFz3rQ6OFFnbGHP2H3OiR/uFiYepl4uRjBimgOm9DI6Ot9f8DHxMlUGIygEPxPBq5CWCL9egpEeg+4rRXgYLI7w5mMZGjVQKBgQDC4qyH7FK3lLv5JomoK6nNjpyPNBmr0Rt215oM/AWQaxDhFZH5un68ueZ7MfybwXxHHFQ4ZeSwYs006f1XGPNW6qrH6pi/3SCLFuGVfNnLVwCBkm3QaQrxFm3v9LmVCidTNta0l0DrUldZdK8/P31GBxKo/MmYF/f9LO/Mfm/uDg== - - peerId: 12D3KooWFnz9fYCxHAnf2rvPQ7iPZcCprEqyN8kCtVQfN2K1TfqK + signingKey: buHKTg4VF6lskoFWDdjtjWNj2c/fz0zAxKrOW05pRRu4+aw/tClrubW5wpeCOJxPSMHJBTj/8bJ8icwKfe7yMQ== + encryptionKey: MIIEpAIBAAKCAQEAtoc/5YBUSzPUISHv/COa2wTeWpsuxuLGOd+IYLXe8xXIry0GHCqCN7orZq5iz7BFs2i6o0ttK2PpRa5xz/GnKtTkQowmfDNwh/f+jIlMo+CcL54Qq4sURexChBCg6z3XbSQK1C9yGA4QaNFRDgSzAs1IC8BCRFf7XDbK06zxWw/As7D3Bo1V3TO0LWi/URkV1PBZdQxX6unt5VplhTQ92o22xczb15zfBQW59qEZYyPa2apwUfmhZgjoAbSOIQm96U7P+HrLa8va1h9q9o+eYefco2N7wv40MYsDXll09Tfc/VhDEfmuKfwmSe5AEnpsg1gD94fX/4KVt7Usb7u6gwIDAQABAoIBAC7POqS5p2Rt0z33/RqVavY2JmvoFjPtHlbjK49ZtOZ0NLYv/rwkbqap+M1pdW+7zfQ3rH2KL2IMSluTZB6m428Jj8w9MvVxH6/O+pnB8ESqqoNPrwi/LyDLeTdzKEGL535W2uwVitX+bVjkLTxCGkJisNJKqPPr+EtqxdNJK9BlJ9VdOLFLi67mOsu3F6AtDtBC3VFXZJa8Wbocu0A7hm8QWa23AL7+EZdV9kJ8Dw2qEYXyYRwmhExuZWNsPsnMvNhlCj8By9IPuICDzW87SfcsIQd7vjSg3y60mmGvl9WGxJbpEkSa+MxCA175k3E30KP1tYMOBQyhlCr7qRYWpdkCgYEA4a7CJGqtdMB8KByzrfGazm8koI0Y+qcriYaOWeoZayoxshwmemqJQTEP29D5SumxOcobKnKRHhKBhhlJenc5xNwppgMIgexZtLLAB2pZzLZ/bIy39T+lAEVOQWIEWDUQ0MwqaGNvaZ2bXyM1Xq6Bovurs8gSwmRIQspskeD/fy8CgYEAzwxpLa/W+BcRPH7VpLSkwSPgsAXW+TCoxWuCMj/W7MmCplyohW8a8wc42RFwKCH4ULpyNbv0VWdCM910/U1sf+0s7B3+IeW/0oMlLIPOd/Z39Legm+h0o1l3rD7deWdL7AMnaJIJsMBOUp0DRBSE5Bj6iUr1MnIEMX/3zFqdxO0CgYEAo4FSZMHpA3JFQWZyAy7M4o0Bc1RmaYrd7xhOX/RMECkUsh7U/dHbuSCLhc1kH5Mp9F1pyxoP60KrFnWRl6lzcB22CvGdo0uSPmlW2MiDYN5DeWiGCqfeqlCL/rC9xw5DLZMNkm2gFVu7anT+wKcbgvJlFq54cN/ovoMbn6DsWr8CgYEAgUVIbgP5fdA5LMIr9bfrncMeyAf9XnwpA4nKMkF1mUV/UwtLFHR4KQB7V9vxYL1E4nJmWHJPbPsZdHRyVKyAb6bPg2R+hP+DMpY7IX3x7ShvYNU9a9pI6Kw1cc+WS/RYjLSzaDC16CtJO39YyKrfBeMqmYm5aZOSVq2FM4voMUkCgYBudtWqqwKvA/Ig32hPBa/pqh+R11LeN8F/NsjrCA3geo8MlDqD0To+r9FTv14AksR7BsAfhoGglbvpddTL+CqHgtA4igNWp2/UCaomfnCgnFl/rvo+OGiVR5DgaC4ALw9onsdfeNgrQ5PkqCCi2crb3txdRWGA2QyGvsBmb1u8+A== + - peerId: 12D3KooWKtsepiMYrDtok7AU4itPcmHQaLuwzzfYYyjEW1KoLeXp address: 127.0.0.1:4431 - signingKey: IM0BTVQf4LKMUVRTAHxbBXmdz656+G2ssw4WdLc30pRYy6TsVVdh+n03pKXSCdg665tM/9AjQRCbzgvDf9riWg== - encryptionKey: MIIEpAIBAAKCAQEAm0HILjO7GRYYb0AvESmxdaj6ruIcSHEQIyqhPbfXZSmJNo9wIq89SaYYL4ZTwrF+ykPDJcBA8SjNHGXBPhZY+ejwCDzDyyv42FMs5lKw+/x94Yg++W72sxawtCLVi0RVY1g4UxOlCgAxl3YC9mVYoqQveXN3EsDd0YNK9fWiWP/Xl3KaJ4ErsfW3LZS9rD36dgDsKr9GqeVQf7lGkCkDmivCwHn3uaN/uzHaWvaZ7e7QWE/36vTmMsllTvi0Q9Y+v+HB5isIX9Jve1QmCS//DbDl9IMGdmyg/jlBs63Nk86Qwlw8ft3ttTWNldTpvD4Ycbgj3l59jT4rIvFJ88+5UwIDAQABAoIBAFfUn/1bMIYhlNMi+T15W7YXUTGsIpnstFdgn3T90rGdDM272ZEVl9NZTidck3f516NvMC/kEhkbnuVovyhzlgRS/a97SLxgdNdUPntR3mO/VCtJW27akl9//5j4d9vgXXnlB4AgBeahc2yey1A+xyTDQ0QuyPbn+tSytK5uNlioCeAqH4ruWxcg4t8MnwNQEOsnchrYHfXqJG+XxGn7m60U4oclbObGfxWxYZ85I0B6M5PW71VLkj/eKTvRJcW5ShDKLG5meiUM3KtwUdFRzv9Xi4aB9eTwEQ8ZV18KVmIF7baBy5anWDfGO4O9MvFSMmbMCe3EkrGaEaCp/gXenhkCgYEAw57dj7ewVHIAQxcNZ9SPRUNAY8g9yEYQ//30yTcpUjsGlqGNzua2OvALGL2ntFY304X9Iego+7Tzxs3T0x2FQ1N33NhoxwRcMqBdksMqmCb8Bm8UvnFIuvmsfPGkkzwa/8xNH81GZiz0p9zfi4lSKdZRfTQ4lBqvogExdnalSd0CgYEAyy2Mw4eeJQ0Y6QX3nad2/06oxWiS3++CITI6dAqiepAB6V7lnP90NKfLgzJcCJwzKlMhoVv7Lu4bDCXbvQ03ba+Dl+To8Jf5/9di8j8OfllqDWPnbqyueTHu5CUk+A2Gz3RhjmMXHpVgbFkUJTkJ1RDWPImNq0KzTYQ+ZwU8lO8CgYEAo1/0zuisnXowedew3HyLw17tUeiUoMTTwdiJLduh6Qle8UKvupK4svRzcBBFFbnEGiaXSFAqmj2AMxMHzBOljpsRSiJ7L2uWzLleLQpOcpBsf7sZ6guWoIGQ6zCtMEJMkkJAT0UTfJYjJmazVEg1lLdni1enwRmggX7ZnoRsewkCgYB2SpLF1FOSpsl2Ae9kbnettRI1vOimUD+nLCM0JGzshqNWR9XPTjtN3NN0EwHaUXbIkZXm6DKZ5C8DJ5eDvgojZihrau7kBNecyL3m5CeAEHbaTOwVV5xNG3FGiwm3EckHR271A2QWfkmhS0ubUFYVIrRYko1UxIS4AOKEAFyBKQKBgQCfIsGy4wOqRsKLzbun6fIVSz8X+sS3HclD7UZ6WKanOYyWZ420qnhLnfdDcNQjF/ApbzHdfwwTKVJSaZiK23kmReUVB9Cq2YAHMJYlp0ErgPzZstrRiRidtzJHm93owWc7GZinzd1M8EOYUSJ3+t8EZXZlbsD/oCTbX/BGqolo2w== + signingKey: bqnCY+BB93A2nTM59zyP1CGZg5seSIeoGM/ATCOMy4+VvIfB1kwEK2VM5QVx3ub8zV/kqND8xuuQCC2NIrAFxw== + encryptionKey: MIIEowIBAAKCAQEAxaNDIGlEwkYRtcw6eoM1wRReJJUgHbEPTGSazEHTIp9Vza0Ob5GqT0yTFbWQWec1+vfCCVj49Z0usKiIa78iViiZxN/EZtdbimM2b2LTOPPkHTBNM3KawuBtVd34CYOLyFFhc+m4dtquGTsOGC0q2YQlS/XF+vGNWO/j8LnriF47Vv3Vr2YDfYeLo3aMexjzLKDiL1TC8fxtcSHqwrJnhgkFEHV/BIadPBlCpVukTPPMusEaoMshHVViS2emStf7j7Iq6KDdbIMGRCTAKhLNMOnHDwmDlBo/RSS/iYtEXFEADDfiYPOeIKIExPnAfdbku5I1y3/IaxeSpk+jQDFfMQIDAQABAoIBACLEgsWL3z2x5+GsaMkuleE+fQVAeqLeiAtvU1AFcGgR0Z1aCUUVQfmrReC2zQsTwopA1ZChZ0KGATWwoDccK6UuhUZ9+uYAkqj4pRXZM8E8HnAIFDytt436vyEw6DZ8PrXhoxwqDHpUI/ZqTiNwpq4XMhx3wvlPTwdLRDUP7+BQK7EmmZLZPiU+oq7f8Fo3ag2gkRKakatPIjwKRDSXcLNW+Rz2YrxUOAdEir2KiK0CKYAkqmcZy/O1xBjQ0YgQpYgxgBXRHTgd5iIFjGG/bCIHsLyV+FkpMpgO7oFw0aJa6zISFeoZ3Zekpf0qqSQNrI+Tpc3uStSE8/95nIo+fxUCgYEAxuvt8VRl1W16ddYpGAFO7ytTdzFSg4e07rKPLvZbvQ4M21CASluNPPKn/S9KFaLZDagBM2jl2cjGYdHVfVlVu/fmM8nlTCIhxkjU9iHkyspJWXNxzUcnh12GEjcNb1i7Oc1QTof7HFjEG4TrsRmGdAee4ZjXYyIEPAHCgxAdc7sCgYEA/lkGdggdLfw6HkXceLaiuq8FA7asJ0JK7L5XCptAXZ9ci10oQuwC+58S8eFVkOUmnVwFovc7CF5EtWjUkSdI+AIL3WCnj2Xjm/S/ASNL1Urw7Q7A7QKu0kGawadUQ00/oSRApEC3f3XK0rdkRlryp8mj2WRfUyBEjh+NgLzgzAMCgYBHQK1Le3K6n2t1GBBCM/3FN9y+3iDzUkHiGn2lUcOMlaLPUCeT+vU9dqHr0+uSknFzLdG4S4PBneRJl7MEImLOYL7JoDENM1CryNzXiU59wTXC39JMuIcVOs/SaHvcfYka7EsuxhCRl84vGU6fckgx+aTUpD3KmZ2wrOSys6wJDwKBgC+VrjzE1di1mJXzUgUPfjBY8CI6uch6gZP7JEOqugcJ+oFkQ1UJ3KEAqMWx95UtGeVUwwUzJcsx/77ExwgFBoTHtTqMi6yrTkLuLhHjbZuQ8rQXD4cH+ncBqRdT29Lfj+jw5FsWdH4XJoP3pX34I++6LLpOKfteTRUd2BZev9vLAoGBAL24XaIkqAECCqdGLiID3PEIRLGacnjEoAqS7fT5A8CV0Cle1KKZzkJlJvxU/pzSgp5AjI1TwIiH4jYE/Xtc2+61Kx1C7jqK5tNK4lJ3BkHUY9d1Etr+HdnDZYKZ32XdGfh4nUU7dx+OI965oQJISsLVVmu2GBllsbg6sA+w3LnK + - peerId: 12D3KooWJ2259GQZxf1PBkLBR8J37QN4PMiLedBU9h5PNbUwfaXE + address: 127.0.0.1:4432 + signingKey: RHl/cHYoPtAGXgJl7F3upI2OAnD4hd9aJztiqo08w/V52b3qKvFr2TWnpbNvBlXSxeyXpo4WB1jH+pMslW0irQ== + encryptionKey: MIIEpAIBAAKCAQEA2vHQaQ5U/PzvNFTk3G9t/IMELaxM5OBFV0/HcjDnF3jtc/ADtqG4zsr/VCs7/tiXiEIxn5aMFrvS7APh2/EHLlAnyrjYLyyxvgwqUtV06Gf5K2V7HmFTLch7VFc5HckU4Zg1B61EYAtnWu5JTmsZAmP1v3afsnfpdwTA3LEH65oOyEAXqCeNUtrrwZXYnt77gk1zC0NSdtE4Hf25OJ5to0kckmQf+TMxj5seA5+u55Bg/Hd9sorFl0X0JrAkIxnVcWYt9lCNZk4frPHl1deX9BwOJ5KKrz1Af/617rl8b8H5F+KzkHXpgpJfxtMLWUnUuaX7qm+R3qe1HeMCIAmOLQIDAQABAoIBAGPVHT25/kC5KG1JRG3LFXCtYOtehFVceeG9C+liqQzH5CYYS+krxrPsVg5QBHRI2JeV70CgidIX5K4few4p0ido/yvtqw2fqJBKxcWtdTg/qJsEE+afZCkdIDct6mpNdQsEtzF/7QyKRp9sxdpO9UFkyPp7oYfkK31MmpBG3KCtb57dyIKqfBoIrp9E54X+MtHHQsqpVo7wgdSufUAWA5OtrebqrUGhWrZCRVT5l+BbPp5WliTN12jVU3jdA6rkUzrdyt5jyZQZ1eIm89mBi3wQod3arUx+DnXeICroyWW7eumXqvPdYO9Y2eaGpXY9sjXioGARi97vD/qCB9qB/sECgYEA8L169WaUBfPU6qlD+qZN1Be6PprjBqoTYu3clQikYhF1HGcXT4ri1/8CT8gf9QsUt2NHzNf0vkhyqJ3bD+mxG/c62C7ff4mhLRR2MRiDnqFaYKJL4snFG6eachD7IqgXEJ8Uw8s+LUqljhMa3NlXgDyCdrazVto/J3iDx6/B2/ECgYEA6NKniFEFrJBEVr7neEsMzKSuu8S7VT8bZGNY5yLIHM7+E1YeyJko1BtaQ2f+x9nnRzRPpjO5H+oVLeRWj496retGmvQ24K6VPCq8b7I9QUdYOvhzgo+go6sCM4dzfespIi932EAHGFA0frZ29o9W9a8rgFZUoigde9KAYxVLQf0CgYEAlfUBfZFLDTYoX4/WV3B2NHIfQlYKqqEQeGRALdl3Q9sp/uo8fADActlXIElBlsszOVSvaervegP44A2MYiood4oV7omsEG6zpjgDs2tYuVw6xszxxi/3BtXs/7aSKLFZxLHDJn8YmO/RlmFSL1V3CtsmTTpbFfPWuQh51c4mTJECgYBQEhqR9CN6bIdEOhWLNmxpeP2rEAbJU5HNHam2nCysU7fn2Idvv9Td1aZeZkamXtd+kowOAd3aDvxHsy7d4p9zbuXyZqj07rXeYmg6FdehOrMqXMYFEfZSM37nT981YAneeurBkYufHf5f0crqEvP6PMs+MPKcbiVtr0B+UxV11QKBgQCmNz/q1pPxEltFBOZmsyfmplKgeDyexB8nb0z1NNc00tpKtWL+hvLqGQwYnECJ7kcJDNetKM1J6rDCoLg6hObf/Ze6/BFXTZF8bM6Xqz1elQPYgHl5P+vlJ7yVI5FClVG8RgI73vxr67CZk+4zsZbvTLscaZ1ZPkPR9m+YMJWUrA== + - peerId: 12D3KooWNJdqtKLZAxT3szMrWoSLS1F1JkyKgJ4YQ1rAKfeVPMm6 + address: 127.0.0.1:4530 + signingKey: BwEWqy5XqOeEUy4BmMzv1WltI5TvLPfP2l2mtioxb+a5ijq4aSATKZSFfcm2hpbGDObWOzeyi06BarLOfQsTnQ== + encryptionKey: MIIEpQIBAAKCAQEA2sTIJSgwRRwPVINYyC5lHtZGsBth87wV+mwMVHkt1/Er8WVstudDFj7dvpO4wHE9vzOQi8+VobNT+xZSB1hlLbOuyBMDzdg+0vs1rMmYruKWb12VZ4+ir1xhnqpm5sKhPuPylZFp+m2GuyEeMHjUNnbQDgPSxkh9jNnTnlwG86h8r5BlhbiISZUs0Jh+IiAbgf55xTdYp0UmVREJYpmk8SBOQS4HfkWM7ih85zMrA0lzi6bfghN7CSABpAMYSgLJc9XeP3le8iMSKQsT+RRvXgUAniPT7ftbWg0tZMNjJ9CXF12Mp0ElC95UIwOnJJydgrLMLvQ0Lggie/WdN0PpCwIDAQABAoIBAQCvg37bqLGJUKjP8gzxlZ9VLS5LLbzZUgYEAlmmEA6CmB/cLLYay9Fb8JXwxw1Lf869Ln6CXMm8kGYJJPAsqnOKRgUsyWyc4igNFrQKazbO4EU3Fcq+6lLoA+Lh6+5gpre9AB5oduCipOqaCUjyNI51H79t7w1UPWZU8ZHBFC4TnpanTYTqyYwUThqDR/PExyV7mhYN5gEi3cg4W0cA7qlDaGgwaKBrMphRt2xwNlAlYAhdkwdgRmbnB/zrWb0FHqJAsz6biqqNh0N0EgIsF0ZMO0ZFGRt+Ou36500Z1cRpGurbO1zrpNV2R2Gg0Ssun2tfjoYJN22HqwwLY71s/xXRAoGBAOx5KeiD07zkRCUzfVa9oHd9CxFSpStz0mCauFDpW0nhzgonjSaOmEotGvVRLDF1eqbtji2QOx3WSPXdnNlncyYAsWFJMyupygqsxBxnVBX3yFFicOE6PCaZocwDVmdKNNfg/52U13qS4pxFFclUPHlVvEcovR1VAPP08MvyV4x5AoGBAOzVW7FmVgzAUc9E8ro6pXD4dFyNkE6Hasq5ApQzFbqcaHSUjbS2lF5dKhvur4OABy6XO/wgD78b/bC+vMryxC+yHm4FP+ANpQ+/DSrn+g2X80J0wqC2tIIVqYMOzn3L+gSfRnhW+28vEx5SSofa7aZl/NOoXtXD47amJELwYzijAoGAVH9vJDCG5oZCe3CMpwQXZNr/q272qjI2yGJA3likUCApuaMsYsytSkQXz/Tzb7Dk5OUZ2tog5aZ+Z6yKsXyvvrKcr4CykjWXhnz5jpS1jSv/HmWopDJk7/4RvI6svzfa7hDuBeb7oEcARorBIDHDci/amSrLeMG5F3M84AN2mTECgYEAvx+PV6JWXwP1AWeK2m7phDl87hPwGO9/ZwnW4vI23tnKEgqwMN4G7gARM2lzipOPODIj3luhWYClQjUq9jzjxfngRLlHyvA3/HUZkz6RtNajIUZIqpnHIhOJMJKKYUpzAbfnjsXjMt6ydw3Bx9ENZ/N2DPkbTzc+VO/O45ZK/DECgYEAvhovek7Jk4ZmC1OsxedqudrgQugNGTMnc6gFZR/CUXrtBs1vq4zKe003Nx5WPGaYooySVraSgBplamtsL+dUsVRqWjCyuUrSkuv7XtP6rdSuRJEHTs7vumnGsF2pp+I08W1Bg0zUFToGy0PqFX9pVeR1f63COI4Ca1Vy6+BIw1Q= + isConsensus: true + - peerId: 12D3KooWP2cwtzkokAGAr8UzdW1pmU4NS2D4dvHJtK2q75TBEeKq + address: 127.0.0.1:4531 + signingKey: RyKkgbAlAmo+suhJf1mYau3uneQD93XO9Dks/a8lpXDES5wfPb3dO/8oefEFllI+c/m3bTVkAYBdTHtCZq7lYA== + encryptionKey: MIIEowIBAAKCAQEA6Dhjs/8s/uiTFIopCjoYLTq8JGIM3otbUktYXSnqpBVVUU4TwSJonpyeRCgcYy9FlDWrUPfCNEv/kG6ruNUZQs2UuPbaOMZ1Z5TZRokwZF26rlkmaTlwJLKmKy0wwT9koZT/e5G4NkRO4rOLK/O4NyDlZ/HvWaZPxQtcC4en0CDaaIcDSSKaL5OMz0fcXayQlWKiOsuuP7cSUYlBDybbJPLSPMVYUjGjzIBqZkV6nBgjKGIIBGlknqZpRwX1mgq4vG0UYTfGCOFF1iHQ4TiLM2EiiZw203PVA4ifSyvkZOkMngItBfYcnD5MRYtLXlps2LWW6auN6olAkyUwFQeHLwIDAQABAoIBAGq7kEfo3xuCdieYoOhMb1RKjLMERfn7f0vByal4XJpyG7a09itszz0nqy6UaQfFcGuAh289kQtMavhNhav8dhHYP6UMAJzbypaDOaJL5+wZkHYWD6uJdNvJKMrriF8p7ey+ePaosUxv9PoJn8vhxye/fPFbp7FC2aMtZ279OMpVjyhbBekWlHfAnRbmDaFjMH+7wHfaAArpYsmRaOJ+/ckqhHSWSCXHO7dOyTcRNx4J0NoZ+192J6VsD1bbGxfHEgtVac/3+fj0Uia3mjkA+e9+oe7kfiGAheLs7G+kC0rEht1VLkviwjM0oCPd3zcu50HjqSrQ1q+i4vKJLrPWQFECgYEA8Uz+PlwghCWcJ7c+TYL1Y4UpYMXavRYi+XCHyn5x2PtxLDgK9j38CbLtIJFDY739RxEDLsOAkC3ba5p71EAx2ZF8i4ylmw0ekTe8BhEo/PHhCmLL+12zUrDbmUqsb1/NJBRDVZ9975nqWiT1KWqm3XKrwfBRTvgiP3+dC3XrtiMCgYEA9l3KBUK0oc6RWftNQTbehrwMuG0M4wv05peTHHqlMsYV0b5nKCr1FWU+gA4zhEDNPcs7PkZRl+HHMalkKH/aLpxeafN5a4PkMsQD6ZK5Mz88IENzXbFswBjCI8s5NyAAK+aI4JqXiRoia6fRnWVp+VrC4A1o2dvD6GaZAta3bYUCgYALFhF8RflMePnirT2UjBbAGsca5hw1ocW7lhr3B7YtVOgPMwf15kUlIO5aF7Jz66+uSy7NQDgw55p0KCXWS5i+uTtyoeSd6g1keJ4P3Uv3yxkexAlBJD3v56Y/NboUZ99h7/hj/67mijjFKXuGCpteAz227Faf/TB9oFxTwXgx5wKBgEMOeCRCacP445soSXjMpHjrylKQbAeIg5oX+5Su1TQismGqf41xU9AFBKP6OY9vy+1b2b4ziZXbgEpGHtrfIdW5/gC8onnfJkejDqWOqBYIyibF9Sq1VjJbCsyPTf1xGlrYnrzzlvdcQ64luWor5lJWn+A4Bif2JzakZlVdeAO5AoGBAMynKpkB8vqTLU31yt5SzBroQj8TgZKGbzB2apO1a+2XE8WfmtFOxnS1/iQ67sMkv6Rh/N5SUxMnBLXjsYJFpuNkKjvE+RqO9f4PzklTIJuT49pexheAMKBA9zWv5YPEmMV8xGbqXooSuEP0ixlM07DiqaC7aBzSyIfGdTOvI5w/ + isConsensus: true + - peerId: 12D3KooWMg5c9wHkuXQ48qyHVa72UKerKWAVZRC2dc1ibSadYxTQ + address: 127.0.0.1:4532 + signingKey: gSyxSnCL8NsewJmdFwgVpjQ2hDwDvrbZrLnA1007ymCwLN67/Xd/42q4vsvZAovsXBrv4PuWuoQUqmXhX7OJrw== + encryptionKey: MIIEowIBAAKCAQEAptyiobOzgLUuVfUQetYQD638+kOUAjf+V7uny+9Qhtt0LZM5v4lsJ8DK+NIbJU6fo9sMNJ8Mc2A7QNEZ6iyppI4zszUIMfF9Ixhew8g5zBlaDzieAf1XSGuEd89vj1ikM3Nhp8AXzxxoFOTsgUCMlnAzsHalcVyqXRzN/glAA1Ob6R0pIEIz4LchvMpnjhSLi5XEmBMy3b3XHu+T5nYyLzLxxMpO2fHH41/GpWmOEVrjoT1qP1JSv+ehuXiuMW0rM1833os6jMHCZijfDGh8blWI2nthjOLbr/KQKQhkIqOXKwdkVLY5x4/c78L8dV3eZ647SqurWC/N8kr5r4LvfwIDAQABAoIBABTPHSUHURJzBeVIW5bGDVi3PP5E4Tdpnjl4uJNRM/ytb46jdqcxTyCiBW4EXchIRtZbYelKEHZvANSzfwTaLwnLhh0KNwxrbkyrJF5MIREX9EhDqkjbPEBW0D1UzDfXORsFf5848H8urrg0WF5CG4ZDVd7i3P0HLmPQTMwqgSYo2pLexcj0LtiZZqJ6ta9kxAiJniZyoNshRJnAZMMnFYRhy/eDF+L6sJPHieYgwiQFU5e0CK9UgsLmmOQWCKWtPgvxOhqlbcTz1pJAqkyzOC0wK/ydJpVAh9RUqf46rEDFzL/l90ZOir3AMlYJIHf4PX0TWchXjFW7bbHn5Zvk1xECgYEAzpuGDfaerUl8QziD6F/OoIz1/EZwSumErCH2NXYMBcCyzKu4fBqVqj5tcLsNx42v6kAGaERAQqaC5ZZ9ZNhXiWasHAermQqv8DtlYVCUih4e87dX1/xTF5TzR8RhLwHPADd1rRafCKJMD9X6Qquer5LmSST8ej3mJ4mrflw837cCgYEAzsCoqFenGlCvAZoQrekxS1VmGJDCKBQ7LlbOwQaUkD4I23rjbAHG8J51jmaQQ4epm6lU0JLSma/LKp8dl9oDEP09vcgKj6xuHMZV+EmsA5c181zMrGoH+tSZiWQZjSmJVhd5T147vnbUunTbGKlOQByD0tWM913Dm2dqB3goXnkCgYBZax4dtPr/7KoHPdJ5I939xoQ/5wx6n454IUq54JlbdAbuZfO2Ypsbz2D2RT61ezEDpSogvklBj2dfjj4/AxL/uJwMlZVC60kyI8LA12syS88Bk/xE0kP0FNcl3GxjN9krMtWPUBcMWZGp2OYzLKvFOULJrWRIU7nkqsS6L5l5CQKBgBa/tg8HzfgkRo1LkWhBT041sE0lqGdWioh3vroYakJQwRK9O8bHj0cseEzZ1ifIBo59HDry3L9SS21+Inhx4YJ+CswV9auHUnpSDGWMXaPrgGEtpcuWwxgDSn2GiRUyK81QOeXUvYggdRmq/+x/vH9rY8nP+3nAVGSGBXGa8/4pAoGBAMB7EOk/RnsgQ+SotHbvgv18S0lbJuWsLYGnNp8EcuPxDIxz29fOFH94qzVOwAkk5cbHvAl3/5sl3SelmKM9LXhcOT+1zxoavyAYyVeAGZsrbBmbzj9yeZON0gHtpF3dMWxiguyWuiiHM/pL92gKzlyIXryC3andL/y8/6VpWbtt + isConsensus: true space: gcTTL: 60 syncPeriod: 10 +storage: + path: db diff --git a/etc/configs/cons1.yml b/etc/configs/cons1.yml index f77921a0..eb3a294c 100755 --- a/etc/configs/cons1.yml +++ b/etc/configs/cons1.yml @@ -3,9 +3,9 @@ grpcServer: - 127.0.0.1:4530 tls: false account: - peerId: 12D3KooWB2Xvsa8RrmdhcBTJMoogqPu43tWZ3XUwXMowcCuMjHjo - signingKey: zsY2jhPHbfMKIKfXGh+PsNBhCLD//dmJtBNMhG3m1OIR+bF4a7B5Wid8eBRm6vtCbOJzoxhJZjRYk1vEHuhmgg== - encryptionKey: MIIEpQIBAAKCAQEA4mbDvFUlpfiRkfnW22C0XvpAfB0m1G7vGcDWfNfgMmf8xD1rknWAGNZi2Ek3rjt9uVuL3DnlLEjGf0HrhsNm/VUI3nId72zgqTZd8fHbA+6h2ba9wP1t+IUf456k41bgljD09HxpvEKtHO1OWQGnVFMc5gqMeM7uovZS+NbXvG5RJoVgG/Ugw6BgEmj0e0LDmvvn2FRvmzst77EPQKlp43J4Vl0n7OtvBypLd/KA0dtB3Nl5rjcewFpSbUadhzJMnw38mtj/jwJsvvwUnzKuv6O6ZK1uqW8bFXKN5OmP8gw+EkZo/GX5IuyHdQwjYWKTAuWn/bYXbwsXAqYEtEW+XQIDAQABAoIBADCbC27FgP2u7eG/F6eljVPOukVrJMj6wA5xXhsTZaistpGS9iNNYqDydeolXfTkBMvkoZQ4QcFOJn9vsZcPIG9G8E6BhXe/kkQBzg2BdRnVA55wIzDpt9BhFEWT66Z7ImBcRlqu0yx9zBinwehN+JSb+1pP7XSKSKVn6MxPo6VqSlP4xRN8rQrq8sVvIt1eVH01rxhGBRM/gpoPtIXlf9cYRoa/49c1/Hk3YmE+oYG+oWzoBIsIDS8qEKfEzIrHTB8d0DmLW38xInTqwNgcp6GpoK9mDBhPcb6vZpd0uWx8pwqJ4cYQTJ/ksOrq67T6yyMaJn8WRJflg1taFD9ONoECgYEA9B7LsEXHRMzEAM1YKqxoiOm8UVfv+qdsLUBoeJb81fdgb8YjXq0KhD7+hGhfCogIWuCygXOYCd8srzZxlkSCK3S2F6R5xlsZY7TwSd2LvH4821T8dX/h+mYoe7dbrE2PjWuZL9PwSOLGfEYS7BS7vwl3Qd58sF5/hVX2Rg9V4tECgYEA7Ws7CEt3ic3i7YuzAdaw22WOHGETwb9cV5cwKRnvbhpIcU9fQa291+kIhgV6TaJuAmUJbnB3jwRYG3wEurRodlh8g6HYyCFzB9ZjKuG4av1wlLw8pTSMngH7Vlsy+OiItQhUSB14AUAD9+d4mq5P2uPm0aqw8qbU8Z4tZ6Xyjc0CgYEA4ULRfdTFrcytSHgzVR1GUKAt73mPreFzxsXaIPxiTiY4zKsu1Bwkyic+wHt2x8cCvqj8zssVjnZrSzqX0ath2iuWI3bYD5rccM7zs5VFbiemjFV9qAbbRS2jSZXGd9YSEtMoxaNx5C+uK9qVd1cib4OSkit1L2HjleveloNsIyECgYEA25APR9yC8C43bveC1HB3nm6MvjII02TlQRvQrjIN+wTTefatYVAMAWDBQTBPqvxMQGqwDjJ0Xw7lbIWE2iV9dfTfMdy7XlmQx+68Ryv4IPnA48wxSZcPdBDhHzu4J/jkdIb/arHWCVHqWZj3MBWERCn/jGcOvVkMFWbzFqehaQECgYEAl9saSHtsYYbhEX/PMLbecJtJU2WEOkML0QpyZyzF3Y0FnWpjlY4HV5RUsEOksAjbaAxbF7Xk8NZCjmqdR6+WdHt+3CQl+964vkvBIGWYXyo5/zso5HxzTpZTN8I03Xk09nMfn72lPKq6dWRD1EVBPX0TfOzg1xL7ftng7BR+bx0= + peerId: 12D3KooWNJdqtKLZAxT3szMrWoSLS1F1JkyKgJ4YQ1rAKfeVPMm6 + signingKey: BwEWqy5XqOeEUy4BmMzv1WltI5TvLPfP2l2mtioxb+a5ijq4aSATKZSFfcm2hpbGDObWOzeyi06BarLOfQsTnQ== + encryptionKey: MIIEpQIBAAKCAQEA2sTIJSgwRRwPVINYyC5lHtZGsBth87wV+mwMVHkt1/Er8WVstudDFj7dvpO4wHE9vzOQi8+VobNT+xZSB1hlLbOuyBMDzdg+0vs1rMmYruKWb12VZ4+ir1xhnqpm5sKhPuPylZFp+m2GuyEeMHjUNnbQDgPSxkh9jNnTnlwG86h8r5BlhbiISZUs0Jh+IiAbgf55xTdYp0UmVREJYpmk8SBOQS4HfkWM7ih85zMrA0lzi6bfghN7CSABpAMYSgLJc9XeP3le8iMSKQsT+RRvXgUAniPT7ftbWg0tZMNjJ9CXF12Mp0ElC95UIwOnJJydgrLMLvQ0Lggie/WdN0PpCwIDAQABAoIBAQCvg37bqLGJUKjP8gzxlZ9VLS5LLbzZUgYEAlmmEA6CmB/cLLYay9Fb8JXwxw1Lf869Ln6CXMm8kGYJJPAsqnOKRgUsyWyc4igNFrQKazbO4EU3Fcq+6lLoA+Lh6+5gpre9AB5oduCipOqaCUjyNI51H79t7w1UPWZU8ZHBFC4TnpanTYTqyYwUThqDR/PExyV7mhYN5gEi3cg4W0cA7qlDaGgwaKBrMphRt2xwNlAlYAhdkwdgRmbnB/zrWb0FHqJAsz6biqqNh0N0EgIsF0ZMO0ZFGRt+Ou36500Z1cRpGurbO1zrpNV2R2Gg0Ssun2tfjoYJN22HqwwLY71s/xXRAoGBAOx5KeiD07zkRCUzfVa9oHd9CxFSpStz0mCauFDpW0nhzgonjSaOmEotGvVRLDF1eqbtji2QOx3WSPXdnNlncyYAsWFJMyupygqsxBxnVBX3yFFicOE6PCaZocwDVmdKNNfg/52U13qS4pxFFclUPHlVvEcovR1VAPP08MvyV4x5AoGBAOzVW7FmVgzAUc9E8ro6pXD4dFyNkE6Hasq5ApQzFbqcaHSUjbS2lF5dKhvur4OABy6XO/wgD78b/bC+vMryxC+yHm4FP+ANpQ+/DSrn+g2X80J0wqC2tIIVqYMOzn3L+gSfRnhW+28vEx5SSofa7aZl/NOoXtXD47amJELwYzijAoGAVH9vJDCG5oZCe3CMpwQXZNr/q272qjI2yGJA3likUCApuaMsYsytSkQXz/Tzb7Dk5OUZ2tog5aZ+Z6yKsXyvvrKcr4CykjWXhnz5jpS1jSv/HmWopDJk7/4RvI6svzfa7hDuBeb7oEcARorBIDHDci/amSrLeMG5F3M84AN2mTECgYEAvx+PV6JWXwP1AWeK2m7phDl87hPwGO9/ZwnW4vI23tnKEgqwMN4G7gARM2lzipOPODIj3luhWYClQjUq9jzjxfngRLlHyvA3/HUZkz6RtNajIUZIqpnHIhOJMJKKYUpzAbfnjsXjMt6ydw3Bx9ENZ/N2DPkbTzc+VO/O45ZK/DECgYEAvhovek7Jk4ZmC1OsxedqudrgQugNGTMnc6gFZR/CUXrtBs1vq4zKe003Nx5WPGaYooySVraSgBplamtsL+dUsVRqWjCyuUrSkuv7XtP6rdSuRJEHTs7vumnGsF2pp+I08W1Bg0zUFToGy0PqFX9pVeR1f63COI4Ca1Vy6+BIw1Q= mongo: connect: mongodb://localhost:27017/?w=majority database: consensus diff --git a/etc/configs/cons2.yml b/etc/configs/cons2.yml index e1aad499..fabf14ac 100755 --- a/etc/configs/cons2.yml +++ b/etc/configs/cons2.yml @@ -3,9 +3,9 @@ grpcServer: - 127.0.0.1:4531 tls: false account: - peerId: 12D3KooWHSSHxDymTrGQjTHSATFxWnnz4incxYazKukgBia3xPAm - signingKey: uN55hCvFWVBlFcptEca/PlCJBVvMPmCvB9WnWHHGMftxP2GGPEVntjpeS2aRrcHvfvf0WfjAP47CQdr+V8yD5g== - encryptionKey: MIIEowIBAAKCAQEAuQvwreiIbcoASka0Be0nvdQfU/ZGzIjONzfHCaGWqIfxjqsIG2I55X+3j8kIZZBl+oMIGzk3amZq1KWNGKsRhuDdsHKSaSAnFqPIYYfiAkp5evsBCFzWkMaB2xelDkNzYGAyTemvsnjyp3wlJjrdoJrwW5kNojz84B0NQZjn81O8BH1HOibzXIoO65oBduWGwj5zaqboEe33VFowxRJxXG+RHnOCY4XRoZ40wx32t4LefsDcMbfaNaYEt7av5uzkh/+X9AWNw6VmYKimVv2KAyYwJ5Q+ZkCyASPO9ShBdMfaiR1hETQExVPtBQB3876e0IzW/+j5o1WGu1KPk1t2kwIDAQABAoIBAHvnHM61hrRMr4kMcnoNY7DdmeR0YM+PQtUCSgmO4vwRmpK2voTnbnDW5agnKbInz8C/f+wKkapyzVF5UFKWKPQxGP+Ol65AUyv7mq6Dd7ek+lZ4PybEUv85i7WRzXkRfO2pO8WjlXthNMkkfRNuEvv5AruybciWIZRGn5uusJDh+rMI382z6b00/U7r0igj4g5o1KqT1wYxba2VT4CaSeqNEMbdOcGWDjHx7zIanHvMrRtRG4DgYIY11ohnARU8UUI/wL5WG9iVaeuepq8T1G3vLt+096UwE/GYIhwQ0UUf+HS4HviACcMWJeXbKas64twtUA0Pf0JFCxPnM/QTBtECgYEA0Zpurv8M2P/atqODGG2teKseJqz4nB9vYLbAQfpziv0OyvRQ26r72pjtBwIDxv67fVSL3/HlViBGElMGycrA/XZ1cTiXY2LAcfpnu2P/Q7vUE/n5NBg4C1Cqjgb7D4dFXOTOM182HFL5SSQiUv5jMRvqxZTX5NcxBj3wbuHt0v0CgYEA4gH1755EWtS6q8+UUdLNAM+TL1SKaMcfiGAMdMWL5uSJBQ28fFPZIZv14gTzaU+Zji3AsGXiBpgtwor4rEugmX+nL7FATIaS0rh15hjXEvczg0SyZBkiXygo9WSQFQ/1AuHmQ8dNgNHXuSv9VbQeu52xhr74saii2tCzTOfyDM8CgYBQHA4hpCls5pzZITWBqKmcbQphDcsXIIyZEj/495ghjwaQW0BsNLV9nuU4wHRhIgrWo/Gx7eoRONSPPFxj07JfLV9FnrN9sMiMx3/OBzIQ2UD9QZUVbAw/ht0o21IpZTIFhw2oZMNxn+TXJ5BW2BNhOaJJUdISDI0YLaQvPPqAoQKBgQCBXY/xtYz41PV47NvALkKL6UUdfW2wZfIltJzMplrbMgtAKkmufKw3sbb/xceyiw6hNI0sK1VCYw8mYTfQH4Xw9wGyqendI9ac6VsK90L8pyUESWk3JK/o+erf880JUVX0bWvJdiZlyzeI1aYvzWceCziXoW5m+tklGPrY1ZdWPwKBgEYm3cThyIi1MScjR7lBKPKUKfkmN88ZoNnzfcn1Mgzwpo9alTycyT9otC/wBGIf4WhRmDoCYE7htIA0C0j8YlmYhd8+gEuRnWFn8Gx8ecpSmUIIpZINeV/t9YFSbod6OnYJosxwLJGzHpb6FN4ojpO5lq7iPWN4v/dtd/p/Bfoi + peerId: 12D3KooWP2cwtzkokAGAr8UzdW1pmU4NS2D4dvHJtK2q75TBEeKq + signingKey: RyKkgbAlAmo+suhJf1mYau3uneQD93XO9Dks/a8lpXDES5wfPb3dO/8oefEFllI+c/m3bTVkAYBdTHtCZq7lYA== + encryptionKey: MIIEowIBAAKCAQEA6Dhjs/8s/uiTFIopCjoYLTq8JGIM3otbUktYXSnqpBVVUU4TwSJonpyeRCgcYy9FlDWrUPfCNEv/kG6ruNUZQs2UuPbaOMZ1Z5TZRokwZF26rlkmaTlwJLKmKy0wwT9koZT/e5G4NkRO4rOLK/O4NyDlZ/HvWaZPxQtcC4en0CDaaIcDSSKaL5OMz0fcXayQlWKiOsuuP7cSUYlBDybbJPLSPMVYUjGjzIBqZkV6nBgjKGIIBGlknqZpRwX1mgq4vG0UYTfGCOFF1iHQ4TiLM2EiiZw203PVA4ifSyvkZOkMngItBfYcnD5MRYtLXlps2LWW6auN6olAkyUwFQeHLwIDAQABAoIBAGq7kEfo3xuCdieYoOhMb1RKjLMERfn7f0vByal4XJpyG7a09itszz0nqy6UaQfFcGuAh289kQtMavhNhav8dhHYP6UMAJzbypaDOaJL5+wZkHYWD6uJdNvJKMrriF8p7ey+ePaosUxv9PoJn8vhxye/fPFbp7FC2aMtZ279OMpVjyhbBekWlHfAnRbmDaFjMH+7wHfaAArpYsmRaOJ+/ckqhHSWSCXHO7dOyTcRNx4J0NoZ+192J6VsD1bbGxfHEgtVac/3+fj0Uia3mjkA+e9+oe7kfiGAheLs7G+kC0rEht1VLkviwjM0oCPd3zcu50HjqSrQ1q+i4vKJLrPWQFECgYEA8Uz+PlwghCWcJ7c+TYL1Y4UpYMXavRYi+XCHyn5x2PtxLDgK9j38CbLtIJFDY739RxEDLsOAkC3ba5p71EAx2ZF8i4ylmw0ekTe8BhEo/PHhCmLL+12zUrDbmUqsb1/NJBRDVZ9975nqWiT1KWqm3XKrwfBRTvgiP3+dC3XrtiMCgYEA9l3KBUK0oc6RWftNQTbehrwMuG0M4wv05peTHHqlMsYV0b5nKCr1FWU+gA4zhEDNPcs7PkZRl+HHMalkKH/aLpxeafN5a4PkMsQD6ZK5Mz88IENzXbFswBjCI8s5NyAAK+aI4JqXiRoia6fRnWVp+VrC4A1o2dvD6GaZAta3bYUCgYALFhF8RflMePnirT2UjBbAGsca5hw1ocW7lhr3B7YtVOgPMwf15kUlIO5aF7Jz66+uSy7NQDgw55p0KCXWS5i+uTtyoeSd6g1keJ4P3Uv3yxkexAlBJD3v56Y/NboUZ99h7/hj/67mijjFKXuGCpteAz227Faf/TB9oFxTwXgx5wKBgEMOeCRCacP445soSXjMpHjrylKQbAeIg5oX+5Su1TQismGqf41xU9AFBKP6OY9vy+1b2b4ziZXbgEpGHtrfIdW5/gC8onnfJkejDqWOqBYIyibF9Sq1VjJbCsyPTf1xGlrYnrzzlvdcQ64luWor5lJWn+A4Bif2JzakZlVdeAO5AoGBAMynKpkB8vqTLU31yt5SzBroQj8TgZKGbzB2apO1a+2XE8WfmtFOxnS1/iQ67sMkv6Rh/N5SUxMnBLXjsYJFpuNkKjvE+RqO9f4PzklTIJuT49pexheAMKBA9zWv5YPEmMV8xGbqXooSuEP0ixlM07DiqaC7aBzSyIfGdTOvI5w/ mongo: connect: mongodb://localhost:27017/?w=majority database: consensus diff --git a/etc/configs/cons3.yml b/etc/configs/cons3.yml index e750b653..efae0bfc 100755 --- a/etc/configs/cons3.yml +++ b/etc/configs/cons3.yml @@ -3,9 +3,9 @@ grpcServer: - 127.0.0.1:4532 tls: false account: - peerId: 12D3KooWCm6fXRReUtpD4bQyy3EnzEe7htRGCAvzHw5yewb1SbRS - signingKey: 31nl1dejInkuEbwBf7NyEp7t6adkMOyCMMzq9ub+XQgrvMnFxeIOso/c38RWo08lSMpZLltC2yS88/EkNIWveQ== - encryptionKey: MIIEowIBAAKCAQEA3dSgJsWNz3zusneGYIjufkXe4byl+RGZNE2dUWEwPqlsjyFXLFmBQwU6UMAOvgEGLuNY2HWVLKzWsqccLqkMjEo3ZQSTft1kf3x3TFlFpPFtGI0lL59b37K3zJ6sdY65PPskhXqy4ru/oTjJh4F13qE40x9bVSrmVnllrEzlyG2kR7KOiHWmufChtvTHA6Nv4x8sevsKzwIXOMMdbKb67aw6jWic94gI8lf+KN7UHYAMKA5MvwwvvH4hadUubMH810jtpiD720dkKRYkgLviLuxhOhRn+s2UY+Dl9vDplBO5tfn0ZnU77q0OrF1qAhwPiuy0yq08ykhL4NrKiLjGdwIDAQABAoIBAHQjxlWGSODBABfgDDKufm8OFcsKAbuNQzDnEd5xi9jCy1uEkSdfFRYJvqZYZ1+DGcGitfleVmO1ehK++zpSt4cbtDTnWHGrZ9p3R95pPtVEsWGRRE7SmD9eSmyPBqvltYX/1vcrbkzXD1VRbfHMDfIpZp7iY+cLNt0/YcP73rI3+4U+4DXsPmaf4jtCBpUH0ru59aCJTJWvYFiVsapWdJY+BcAerpV7QH74dVQ3XNIWRCxsG4+S9cfi5uuenHqM3MmCz8jOpTQeepg64aSNmFsTVEeoNXfQ+78ELUIXEWBpDoWWNVTQxoy3edPThuDgEbw0KHP+z6C63ztP552kB0ECgYEA9pKCvigZyrbn/gmFha0FVEfGWkv8SGHkm3LctnOHj3fyfezKmp1bq44bBFhw+p12qN6NmpZIpMh91X/vDcmNJTAQz9ty14pB0Dlq/egV/AffjtUjYb4UzxiV3EmH97BB9rK9B4VkSdPY1FbOtAEyt6cWoYTUwwrHKzTbhOhAn2sCgYEA5k/wU0uN57BwXrcDNP10zkjxbpsoNEINBj+eGpKjZaKXU7XkgoezgzeGa04Ym6crLxmhlXtSojXFkqeLdhn5hJSKPJ+JsAZD9gM0iZ9Hb8l9/opzlSEJzMFLyCdCeu+9Hipq3OuGkJgRemn9h9UMih1zUTo2RwRdfpLvUEUANCUCgYB90AQmQw/l/64gUXtv2fj+KCFtsZfo1wpuxw0Xi5t/+RQibNB0VBaSUtA2R2pedjo1sFlQp54pdqO+bKjtwAnlD8GETdUrZcBvHt0Y8XNGRj4sA1UqanLzuPe+j0Zxe94soscRL18czJu2vRR7hKD8VKWXhM+LNdSqly3rgxZ2QQKBgFJ6okhSMHmeuD9TLzTU5/XQLZY8voMofF2WftppVVbaiXMTGsicLG97fQoEp89maJKvjSxpQ8iPlTfWBJ3A45jVUUQwpjCBrej2cOQwRHcGI7b6gjYP5OCNAMSnOqmoHYQmEKsZNdGmg+vg9UilxZ3YuimGvVVlfM4NdOK8Mzx5AoGBAKKtLvw/rpL+ZLSlO5CTycjBlY8Uy0/SkTI9T/gvwPm7zMdZW0AN7HShsus6SKATba7ZXIySY+tBWfuq9oEACzvC20Qw9tQUTS90g8mwHwTcj4H58cnvmbtOFg75RYMUYvcOjpbPLvcGKsYrobjzqv9MrrL41fgMXw8DVIomqQbP + peerId: 12D3KooWMg5c9wHkuXQ48qyHVa72UKerKWAVZRC2dc1ibSadYxTQ + signingKey: gSyxSnCL8NsewJmdFwgVpjQ2hDwDvrbZrLnA1007ymCwLN67/Xd/42q4vsvZAovsXBrv4PuWuoQUqmXhX7OJrw== + encryptionKey: MIIEowIBAAKCAQEAptyiobOzgLUuVfUQetYQD638+kOUAjf+V7uny+9Qhtt0LZM5v4lsJ8DK+NIbJU6fo9sMNJ8Mc2A7QNEZ6iyppI4zszUIMfF9Ixhew8g5zBlaDzieAf1XSGuEd89vj1ikM3Nhp8AXzxxoFOTsgUCMlnAzsHalcVyqXRzN/glAA1Ob6R0pIEIz4LchvMpnjhSLi5XEmBMy3b3XHu+T5nYyLzLxxMpO2fHH41/GpWmOEVrjoT1qP1JSv+ehuXiuMW0rM1833os6jMHCZijfDGh8blWI2nthjOLbr/KQKQhkIqOXKwdkVLY5x4/c78L8dV3eZ647SqurWC/N8kr5r4LvfwIDAQABAoIBABTPHSUHURJzBeVIW5bGDVi3PP5E4Tdpnjl4uJNRM/ytb46jdqcxTyCiBW4EXchIRtZbYelKEHZvANSzfwTaLwnLhh0KNwxrbkyrJF5MIREX9EhDqkjbPEBW0D1UzDfXORsFf5848H8urrg0WF5CG4ZDVd7i3P0HLmPQTMwqgSYo2pLexcj0LtiZZqJ6ta9kxAiJniZyoNshRJnAZMMnFYRhy/eDF+L6sJPHieYgwiQFU5e0CK9UgsLmmOQWCKWtPgvxOhqlbcTz1pJAqkyzOC0wK/ydJpVAh9RUqf46rEDFzL/l90ZOir3AMlYJIHf4PX0TWchXjFW7bbHn5Zvk1xECgYEAzpuGDfaerUl8QziD6F/OoIz1/EZwSumErCH2NXYMBcCyzKu4fBqVqj5tcLsNx42v6kAGaERAQqaC5ZZ9ZNhXiWasHAermQqv8DtlYVCUih4e87dX1/xTF5TzR8RhLwHPADd1rRafCKJMD9X6Qquer5LmSST8ej3mJ4mrflw837cCgYEAzsCoqFenGlCvAZoQrekxS1VmGJDCKBQ7LlbOwQaUkD4I23rjbAHG8J51jmaQQ4epm6lU0JLSma/LKp8dl9oDEP09vcgKj6xuHMZV+EmsA5c181zMrGoH+tSZiWQZjSmJVhd5T147vnbUunTbGKlOQByD0tWM913Dm2dqB3goXnkCgYBZax4dtPr/7KoHPdJ5I939xoQ/5wx6n454IUq54JlbdAbuZfO2Ypsbz2D2RT61ezEDpSogvklBj2dfjj4/AxL/uJwMlZVC60kyI8LA12syS88Bk/xE0kP0FNcl3GxjN9krMtWPUBcMWZGp2OYzLKvFOULJrWRIU7nkqsS6L5l5CQKBgBa/tg8HzfgkRo1LkWhBT041sE0lqGdWioh3vroYakJQwRK9O8bHj0cseEzZ1ifIBo59HDry3L9SS21+Inhx4YJ+CswV9auHUnpSDGWMXaPrgGEtpcuWwxgDSn2GiRUyK81QOeXUvYggdRmq/+x/vH9rY8nP+3nAVGSGBXGa8/4pAoGBAMB7EOk/RnsgQ+SotHbvgv18S0lbJuWsLYGnNp8EcuPxDIxz29fOFH94qzVOwAkk5cbHvAl3/5sl3SelmKM9LXhcOT+1zxoavyAYyVeAGZsrbBmbzj9yeZON0gHtpF3dMWxiguyWuiiHM/pL92gKzlyIXryC3andL/y8/6VpWbtt mongo: connect: mongodb://localhost:27017/?w=majority database: consensus diff --git a/etc/configs/node1.yml b/etc/configs/node1.yml index 2d15529c..8dc5dd4b 100755 --- a/etc/configs/node1.yml +++ b/etc/configs/node1.yml @@ -5,39 +5,41 @@ grpcServer: - 127.0.0.1:4430 tls: false account: - peerId: 12D3KooWBZFSp1MrqdQgL2uWSZpybgskz7mjrJnmhkDjudSpTUAN - signingKey: JR142BFc9/KJIy0f0BCnfMeO4Yv9InErltCuGyhvs+4Z2A9c9cGi20ECMzthOvtr90N6bq4iyfLbmhNkVMxgiw== - encryptionKey: MIIEpAIBAAKCAQEAt9WEjnITHiG0IhGdn5sGBR32Bo8qwAEZSsPhutQZnvBfTegqQwvb5LxxpfYP4C2+Wy1335fzMGtjtWyv4r2bJHX++fTh0h8xWbuMuqDlbZI79IkAhu4HFfAl6a0Ay/po4DkaBBwqHFu1oPbzKceJpb1fXXXDNO4SIMBo1CYrrI9ipJrVb0NOIbmuDUUvS6c7W8xiIudLH+lrcClpsE4f6+rVaEK188cWESmFvTFwWd0LV+1B+qP28pVRGZDcqMEeV2CoICY0daKdI9P1efPD1XbQGmafU0LlJZyww1pXT5q0yKBSdKMjspZoRbScnUmTJuhZY29cBPfqPjRiEvznjQIDAQABAoIBAQCQlI4PVepxPUKltMMKHutKJPk0yW5u2a5hndMvk9aeqR/bbuemGXKU4Bxl0TNFNdTLcuQfZystfphJvLRMGKEmuOKTBaSBFGVE1Htm4Fnwph0fQoy2kgfimh/HO3gv9L588ovihaAc84fSk8ZEqpk4T8rr/01KmJ6LQahwiaC5sig3uZgQuCGIz11xjNgavHdpytzL3qGhUPLiQAJtCEKaiFuUAEmw+dg/KH0ZHw3+/yCJ/GESwR/8yP6rfuyuLyaR1n4vr/+eH56x4922ua2XtJuz6gdqzcbPjbf2y01Q2XnwEkf6cHO6rYs+ba8BWzM8NZUeTmvLH+qY4CAMWIvBAoGBAPHuResocGdoZEDNvjUpuZlWCCRKO7goTAjFH00z6DEG0Kv37pi53/4AHshaScHLd7kQUBSH8o6Fdtf+fyZaVKdQzfSKqNVt6NglPtVTd7JhI2ddJuU6iOMBKowRk+PYnjfxjETmXMNb6FpF9ZgMc/QC6YiWZwEjooFKrhgfZWvxAoGBAMKGVY1LAoLUFwdL7DsBSf+VndN0l/ApxVjCLhT4l73HrfOEqbts0GAGRTtOA6JO2xhAvtJkcUYbStQiKyz4iPC+zG9CwMm9XNaGRAflFfcxgy1VqMQ/2TnlrwXdCLi1y+oEGcJs69O8IQACBC1m6MfEMrOOsAa3YExkxG7VBMFdAoGAIAgBH9pxz28l3uKerWFB3ohieZOOhppnPr4Cn/Ega+VQGYSxBW2Ot42ChdpWa58p0cnUIHPDbJVFH+HlKcnJ7YEoU5lMMz3jF0MPJ6VucqKj0lql/LGcUBnmbTcikocqo5OKk9DANWlkwRcEJkZ3z7XW/6uSJbd3G5EsraryfbECgYEAnaa1i09xd4pgJ3+2spN233bodEmYIgIYeLjXFBPtFtfP+P5ZeRbVQh2S2l99vnteQaenf2f8Da9s08Plbgr3IPXhRYK6MEYSCaLDXAqj5LTx9TnpDzQX3z5wvLXIrbpYyw4LunEAJ5fevtzjedBfdBdkZ/WKX8caeo9oS9LEidkCgYA9Lf6XK52LDO3uidnX7CZB9piWIV5bzrdJB6ppbJ2ywAD60NF8yecRp7fnyFRg7VCQxGkbIbv5sR9Ua/PAsBo9UFlZQGanUXpAUJi8qnDIDG2Ly6uNTwjF7s3IHC6OIn1aOSvUcgY658sXF1KfDguXv0CUs75JZ5+1djdMQAtRiQ== + peerId: 12D3KooWNGRznbh4RCYY1hDnG1RLCtWviWwVnZGjKHtsXVgPckNk + signingKey: buHKTg4VF6lskoFWDdjtjWNj2c/fz0zAxKrOW05pRRu4+aw/tClrubW5wpeCOJxPSMHJBTj/8bJ8icwKfe7yMQ== + encryptionKey: MIIEpAIBAAKCAQEAtoc/5YBUSzPUISHv/COa2wTeWpsuxuLGOd+IYLXe8xXIry0GHCqCN7orZq5iz7BFs2i6o0ttK2PpRa5xz/GnKtTkQowmfDNwh/f+jIlMo+CcL54Qq4sURexChBCg6z3XbSQK1C9yGA4QaNFRDgSzAs1IC8BCRFf7XDbK06zxWw/As7D3Bo1V3TO0LWi/URkV1PBZdQxX6unt5VplhTQ92o22xczb15zfBQW59qEZYyPa2apwUfmhZgjoAbSOIQm96U7P+HrLa8va1h9q9o+eYefco2N7wv40MYsDXll09Tfc/VhDEfmuKfwmSe5AEnpsg1gD94fX/4KVt7Usb7u6gwIDAQABAoIBAC7POqS5p2Rt0z33/RqVavY2JmvoFjPtHlbjK49ZtOZ0NLYv/rwkbqap+M1pdW+7zfQ3rH2KL2IMSluTZB6m428Jj8w9MvVxH6/O+pnB8ESqqoNPrwi/LyDLeTdzKEGL535W2uwVitX+bVjkLTxCGkJisNJKqPPr+EtqxdNJK9BlJ9VdOLFLi67mOsu3F6AtDtBC3VFXZJa8Wbocu0A7hm8QWa23AL7+EZdV9kJ8Dw2qEYXyYRwmhExuZWNsPsnMvNhlCj8By9IPuICDzW87SfcsIQd7vjSg3y60mmGvl9WGxJbpEkSa+MxCA175k3E30KP1tYMOBQyhlCr7qRYWpdkCgYEA4a7CJGqtdMB8KByzrfGazm8koI0Y+qcriYaOWeoZayoxshwmemqJQTEP29D5SumxOcobKnKRHhKBhhlJenc5xNwppgMIgexZtLLAB2pZzLZ/bIy39T+lAEVOQWIEWDUQ0MwqaGNvaZ2bXyM1Xq6Bovurs8gSwmRIQspskeD/fy8CgYEAzwxpLa/W+BcRPH7VpLSkwSPgsAXW+TCoxWuCMj/W7MmCplyohW8a8wc42RFwKCH4ULpyNbv0VWdCM910/U1sf+0s7B3+IeW/0oMlLIPOd/Z39Legm+h0o1l3rD7deWdL7AMnaJIJsMBOUp0DRBSE5Bj6iUr1MnIEMX/3zFqdxO0CgYEAo4FSZMHpA3JFQWZyAy7M4o0Bc1RmaYrd7xhOX/RMECkUsh7U/dHbuSCLhc1kH5Mp9F1pyxoP60KrFnWRl6lzcB22CvGdo0uSPmlW2MiDYN5DeWiGCqfeqlCL/rC9xw5DLZMNkm2gFVu7anT+wKcbgvJlFq54cN/ovoMbn6DsWr8CgYEAgUVIbgP5fdA5LMIr9bfrncMeyAf9XnwpA4nKMkF1mUV/UwtLFHR4KQB7V9vxYL1E4nJmWHJPbPsZdHRyVKyAb6bPg2R+hP+DMpY7IX3x7ShvYNU9a9pI6Kw1cc+WS/RYjLSzaDC16CtJO39YyKrfBeMqmYm5aZOSVq2FM4voMUkCgYBudtWqqwKvA/Ig32hPBa/pqh+R11LeN8F/NsjrCA3geo8MlDqD0To+r9FTv14AksR7BsAfhoGglbvpddTL+CqHgtA4igNWp2/UCaomfnCgnFl/rvo+OGiVR5DgaC4ALw9onsdfeNgrQ5PkqCCi2crb3txdRWGA2QyGvsBmb1u8+A== apiServer: port: "8080" nodes: - - peerId: 12D3KooWBZFSp1MrqdQgL2uWSZpybgskz7mjrJnmhkDjudSpTUAN + - peerId: 12D3KooWNGRznbh4RCYY1hDnG1RLCtWviWwVnZGjKHtsXVgPckNk address: 127.0.0.1:4430 - signingKey: JR142BFc9/KJIy0f0BCnfMeO4Yv9InErltCuGyhvs+4Z2A9c9cGi20ECMzthOvtr90N6bq4iyfLbmhNkVMxgiw== - encryptionKey: MIIEpAIBAAKCAQEAt9WEjnITHiG0IhGdn5sGBR32Bo8qwAEZSsPhutQZnvBfTegqQwvb5LxxpfYP4C2+Wy1335fzMGtjtWyv4r2bJHX++fTh0h8xWbuMuqDlbZI79IkAhu4HFfAl6a0Ay/po4DkaBBwqHFu1oPbzKceJpb1fXXXDNO4SIMBo1CYrrI9ipJrVb0NOIbmuDUUvS6c7W8xiIudLH+lrcClpsE4f6+rVaEK188cWESmFvTFwWd0LV+1B+qP28pVRGZDcqMEeV2CoICY0daKdI9P1efPD1XbQGmafU0LlJZyww1pXT5q0yKBSdKMjspZoRbScnUmTJuhZY29cBPfqPjRiEvznjQIDAQABAoIBAQCQlI4PVepxPUKltMMKHutKJPk0yW5u2a5hndMvk9aeqR/bbuemGXKU4Bxl0TNFNdTLcuQfZystfphJvLRMGKEmuOKTBaSBFGVE1Htm4Fnwph0fQoy2kgfimh/HO3gv9L588ovihaAc84fSk8ZEqpk4T8rr/01KmJ6LQahwiaC5sig3uZgQuCGIz11xjNgavHdpytzL3qGhUPLiQAJtCEKaiFuUAEmw+dg/KH0ZHw3+/yCJ/GESwR/8yP6rfuyuLyaR1n4vr/+eH56x4922ua2XtJuz6gdqzcbPjbf2y01Q2XnwEkf6cHO6rYs+ba8BWzM8NZUeTmvLH+qY4CAMWIvBAoGBAPHuResocGdoZEDNvjUpuZlWCCRKO7goTAjFH00z6DEG0Kv37pi53/4AHshaScHLd7kQUBSH8o6Fdtf+fyZaVKdQzfSKqNVt6NglPtVTd7JhI2ddJuU6iOMBKowRk+PYnjfxjETmXMNb6FpF9ZgMc/QC6YiWZwEjooFKrhgfZWvxAoGBAMKGVY1LAoLUFwdL7DsBSf+VndN0l/ApxVjCLhT4l73HrfOEqbts0GAGRTtOA6JO2xhAvtJkcUYbStQiKyz4iPC+zG9CwMm9XNaGRAflFfcxgy1VqMQ/2TnlrwXdCLi1y+oEGcJs69O8IQACBC1m6MfEMrOOsAa3YExkxG7VBMFdAoGAIAgBH9pxz28l3uKerWFB3ohieZOOhppnPr4Cn/Ega+VQGYSxBW2Ot42ChdpWa58p0cnUIHPDbJVFH+HlKcnJ7YEoU5lMMz3jF0MPJ6VucqKj0lql/LGcUBnmbTcikocqo5OKk9DANWlkwRcEJkZ3z7XW/6uSJbd3G5EsraryfbECgYEAnaa1i09xd4pgJ3+2spN233bodEmYIgIYeLjXFBPtFtfP+P5ZeRbVQh2S2l99vnteQaenf2f8Da9s08Plbgr3IPXhRYK6MEYSCaLDXAqj5LTx9TnpDzQX3z5wvLXIrbpYyw4LunEAJ5fevtzjedBfdBdkZ/WKX8caeo9oS9LEidkCgYA9Lf6XK52LDO3uidnX7CZB9piWIV5bzrdJB6ppbJ2ywAD60NF8yecRp7fnyFRg7VCQxGkbIbv5sR9Ua/PAsBo9UFlZQGanUXpAUJi8qnDIDG2Ly6uNTwjF7s3IHC6OIn1aOSvUcgY658sXF1KfDguXv0CUs75JZ5+1djdMQAtRiQ== - - peerId: 12D3KooWHTnHZgeyDdZJwrXweFHMrSF7YBXSuuAH9GsxhbzTvfcT + signingKey: buHKTg4VF6lskoFWDdjtjWNj2c/fz0zAxKrOW05pRRu4+aw/tClrubW5wpeCOJxPSMHJBTj/8bJ8icwKfe7yMQ== + encryptionKey: MIIEpAIBAAKCAQEAtoc/5YBUSzPUISHv/COa2wTeWpsuxuLGOd+IYLXe8xXIry0GHCqCN7orZq5iz7BFs2i6o0ttK2PpRa5xz/GnKtTkQowmfDNwh/f+jIlMo+CcL54Qq4sURexChBCg6z3XbSQK1C9yGA4QaNFRDgSzAs1IC8BCRFf7XDbK06zxWw/As7D3Bo1V3TO0LWi/URkV1PBZdQxX6unt5VplhTQ92o22xczb15zfBQW59qEZYyPa2apwUfmhZgjoAbSOIQm96U7P+HrLa8va1h9q9o+eYefco2N7wv40MYsDXll09Tfc/VhDEfmuKfwmSe5AEnpsg1gD94fX/4KVt7Usb7u6gwIDAQABAoIBAC7POqS5p2Rt0z33/RqVavY2JmvoFjPtHlbjK49ZtOZ0NLYv/rwkbqap+M1pdW+7zfQ3rH2KL2IMSluTZB6m428Jj8w9MvVxH6/O+pnB8ESqqoNPrwi/LyDLeTdzKEGL535W2uwVitX+bVjkLTxCGkJisNJKqPPr+EtqxdNJK9BlJ9VdOLFLi67mOsu3F6AtDtBC3VFXZJa8Wbocu0A7hm8QWa23AL7+EZdV9kJ8Dw2qEYXyYRwmhExuZWNsPsnMvNhlCj8By9IPuICDzW87SfcsIQd7vjSg3y60mmGvl9WGxJbpEkSa+MxCA175k3E30KP1tYMOBQyhlCr7qRYWpdkCgYEA4a7CJGqtdMB8KByzrfGazm8koI0Y+qcriYaOWeoZayoxshwmemqJQTEP29D5SumxOcobKnKRHhKBhhlJenc5xNwppgMIgexZtLLAB2pZzLZ/bIy39T+lAEVOQWIEWDUQ0MwqaGNvaZ2bXyM1Xq6Bovurs8gSwmRIQspskeD/fy8CgYEAzwxpLa/W+BcRPH7VpLSkwSPgsAXW+TCoxWuCMj/W7MmCplyohW8a8wc42RFwKCH4ULpyNbv0VWdCM910/U1sf+0s7B3+IeW/0oMlLIPOd/Z39Legm+h0o1l3rD7deWdL7AMnaJIJsMBOUp0DRBSE5Bj6iUr1MnIEMX/3zFqdxO0CgYEAo4FSZMHpA3JFQWZyAy7M4o0Bc1RmaYrd7xhOX/RMECkUsh7U/dHbuSCLhc1kH5Mp9F1pyxoP60KrFnWRl6lzcB22CvGdo0uSPmlW2MiDYN5DeWiGCqfeqlCL/rC9xw5DLZMNkm2gFVu7anT+wKcbgvJlFq54cN/ovoMbn6DsWr8CgYEAgUVIbgP5fdA5LMIr9bfrncMeyAf9XnwpA4nKMkF1mUV/UwtLFHR4KQB7V9vxYL1E4nJmWHJPbPsZdHRyVKyAb6bPg2R+hP+DMpY7IX3x7ShvYNU9a9pI6Kw1cc+WS/RYjLSzaDC16CtJO39YyKrfBeMqmYm5aZOSVq2FM4voMUkCgYBudtWqqwKvA/Ig32hPBa/pqh+R11LeN8F/NsjrCA3geo8MlDqD0To+r9FTv14AksR7BsAfhoGglbvpddTL+CqHgtA4igNWp2/UCaomfnCgnFl/rvo+OGiVR5DgaC4ALw9onsdfeNgrQ5PkqCCi2crb3txdRWGA2QyGvsBmb1u8+A== + - peerId: 12D3KooWKtsepiMYrDtok7AU4itPcmHQaLuwzzfYYyjEW1KoLeXp address: 127.0.0.1:4431 - signingKey: EVlWc7+UbqSKAvjSdBq5iZt2dpcCYhDJiWkSn2+9IrJxl5F5dTHw+eIKNV3MV/tL8ext3YPRkIue/8TvUUfpaA== - encryptionKey: MIIEpAIBAAKCAQEAwLhwWK4vZQooUjulblf4I2+f5/K9yES7/HW+1bz93ZOeeiMuKb5wmw1tVt+vrY2j5cFC/krhSWUdfRwqDvv6Z0q19v9mD7zIfad54KgVSyMcVGxWLt7haGVCr78VckO5JD+aktlEM8/12crzHOWRh+j3jgELmwSwA/LiXo2ZNH9x1Vftw5MHKksWTpvaAprFTkYUrPHvrjpiuSGzT5abGUYOgWUIzTtqZYra+zOMPzVqDAlMykmUYjVO/d/l01L3xgLZQogZ9B3NRgXpTpTJ5iF7UtUejjZSJ6fYGVNwM/TEMrIhKHD54I6FYkLmp+7Rsw2MmxVXHkQPQJ7khYY8ywIDAQABAoIBAQCv97idQG6GE4A9lbi3yBsKQCIB5+LhueDr45ccEjS63M8XNogwFXM8IEZ1zEjcbzf30T8accTC/1Ctq8m7ZNh+9/iuTwUh2X43PXRLbS4ELUrwyvrmURv/9nWtgwxSCQRD1M+OxlM/++K/uk/BUtxO/KkNQGcYZG9TK7MGIsSA6Ua0fNEo+hcTzqBsED3nGYXwmn7nX4zMjPqr6TtQfpxWdwtKYbBsDcvIoigwNPajnsdSbx2M4pZh3cwBuROKs9/HpUNOtSZvPc8BbRenJQOqXG2R+O6SMBGnYf5ycHpk7Wya+1TtGObOAcrgC7RV6y3KGzq0Thu7imWC1B7GvRQBAoGBAM9yA4EBjHSQ0sP5DTT4yD3H7ytQtR3oVZYcKiWg4lPETaFhwucFzbbhmh5gB6Xng71KiIuYuvJZi2XQeL2LcBBaZwoj9cpclJ53KuQ8LL5TPZ1zOn+xU/Iy2mumzVpaSyWcDq7ArlhuGq7JWubAEcrehBia7i26Ss9ro1HqbR+ZAoGBAO3UHnZz8gmkQrUyk6rTPJHivnow2O8nh2dWuK+o+wAN+WCF10VQVaRcUS2bC/khHeomTRNZh+kzs0woLdfEtLlxECA2+MHiIJmXkLat7/Bm8gByd9iWHRZ6d9ZRvb+DPwmbZV0mZoy+8SF5DJno0uFdq6g6tTGQKmQwu1xHeI4DAoGAOQubVxB79VoV+3ozXYvEVOj0Ji8tfynyzzKzjGFvm6Vxy508oZcA+PeVECFMOR0vJxCl9+1qC1cAdGEdstHzYSvbBfjZkGphHCqdCuJZU4VEflW/knnLIeFGGzBlbCFEZPVDPF8UEpFEmSgZ7TaILgd+v91q/fwqslthMBeNJpECgYEAzzNTyu1e/IlwWL8UqepZRdxfCMPP7CPrMtv6EYhODZEfJ7nTgB7qTkTjsLD5MHZqwpnV4rrIzyJs3jfPIMHOlhVr8DUUao5gyo+i05UciryVsFAKG9dExlWyXDVg9B4baHpLSGlxRMQB/qCgmuKd/xyFtg5X2DN6y0ktosrdvBMCgYABqwzMnDF2SPx1mZjXIOCsj/03Oya75E8ZTWGorkROhyarE1wWvES472IGsZSM7qchABmVVGxr09mL0nyNA5KIIEoIWtl59yplXKrunYYoodoXtaS0whTDraf62am98IQ1LAUdf4p1dGfkrAsf8stKuxbzYtEeXQH3EHzzLOzmNg== - - peerId: 12D3KooWE5VmEXLSksS31fWjwydNgoH9c1hMWdMdohKk1mHVVgwC + signingKey: bqnCY+BB93A2nTM59zyP1CGZg5seSIeoGM/ATCOMy4+VvIfB1kwEK2VM5QVx3ub8zV/kqND8xuuQCC2NIrAFxw== + encryptionKey: MIIEowIBAAKCAQEAxaNDIGlEwkYRtcw6eoM1wRReJJUgHbEPTGSazEHTIp9Vza0Ob5GqT0yTFbWQWec1+vfCCVj49Z0usKiIa78iViiZxN/EZtdbimM2b2LTOPPkHTBNM3KawuBtVd34CYOLyFFhc+m4dtquGTsOGC0q2YQlS/XF+vGNWO/j8LnriF47Vv3Vr2YDfYeLo3aMexjzLKDiL1TC8fxtcSHqwrJnhgkFEHV/BIadPBlCpVukTPPMusEaoMshHVViS2emStf7j7Iq6KDdbIMGRCTAKhLNMOnHDwmDlBo/RSS/iYtEXFEADDfiYPOeIKIExPnAfdbku5I1y3/IaxeSpk+jQDFfMQIDAQABAoIBACLEgsWL3z2x5+GsaMkuleE+fQVAeqLeiAtvU1AFcGgR0Z1aCUUVQfmrReC2zQsTwopA1ZChZ0KGATWwoDccK6UuhUZ9+uYAkqj4pRXZM8E8HnAIFDytt436vyEw6DZ8PrXhoxwqDHpUI/ZqTiNwpq4XMhx3wvlPTwdLRDUP7+BQK7EmmZLZPiU+oq7f8Fo3ag2gkRKakatPIjwKRDSXcLNW+Rz2YrxUOAdEir2KiK0CKYAkqmcZy/O1xBjQ0YgQpYgxgBXRHTgd5iIFjGG/bCIHsLyV+FkpMpgO7oFw0aJa6zISFeoZ3Zekpf0qqSQNrI+Tpc3uStSE8/95nIo+fxUCgYEAxuvt8VRl1W16ddYpGAFO7ytTdzFSg4e07rKPLvZbvQ4M21CASluNPPKn/S9KFaLZDagBM2jl2cjGYdHVfVlVu/fmM8nlTCIhxkjU9iHkyspJWXNxzUcnh12GEjcNb1i7Oc1QTof7HFjEG4TrsRmGdAee4ZjXYyIEPAHCgxAdc7sCgYEA/lkGdggdLfw6HkXceLaiuq8FA7asJ0JK7L5XCptAXZ9ci10oQuwC+58S8eFVkOUmnVwFovc7CF5EtWjUkSdI+AIL3WCnj2Xjm/S/ASNL1Urw7Q7A7QKu0kGawadUQ00/oSRApEC3f3XK0rdkRlryp8mj2WRfUyBEjh+NgLzgzAMCgYBHQK1Le3K6n2t1GBBCM/3FN9y+3iDzUkHiGn2lUcOMlaLPUCeT+vU9dqHr0+uSknFzLdG4S4PBneRJl7MEImLOYL7JoDENM1CryNzXiU59wTXC39JMuIcVOs/SaHvcfYka7EsuxhCRl84vGU6fckgx+aTUpD3KmZ2wrOSys6wJDwKBgC+VrjzE1di1mJXzUgUPfjBY8CI6uch6gZP7JEOqugcJ+oFkQ1UJ3KEAqMWx95UtGeVUwwUzJcsx/77ExwgFBoTHtTqMi6yrTkLuLhHjbZuQ8rQXD4cH+ncBqRdT29Lfj+jw5FsWdH4XJoP3pX34I++6LLpOKfteTRUd2BZev9vLAoGBAL24XaIkqAECCqdGLiID3PEIRLGacnjEoAqS7fT5A8CV0Cle1KKZzkJlJvxU/pzSgp5AjI1TwIiH4jYE/Xtc2+61Kx1C7jqK5tNK4lJ3BkHUY9d1Etr+HdnDZYKZ32XdGfh4nUU7dx+OI965oQJISsLVVmu2GBllsbg6sA+w3LnK + - peerId: 12D3KooWJ2259GQZxf1PBkLBR8J37QN4PMiLedBU9h5PNbUwfaXE address: 127.0.0.1:4432 - signingKey: BI+SqqwurrTaNCHtc9+DeItlNPh6/6gH9CrJwNXS6Ug/TwwRHloM7siXqOWvJVRUiJ8UCraYjuAnB4huLdby4w== - encryptionKey: MIIEowIBAAKCAQEAtyliO0Y/M1RHRNCRl5D+x337CVbv/Yhn5bF0+Ib5h72JDtewRLKWcqCxmNa0RhmSbUHIlO7itf9a9k8FBlQOg6SlVgRk5xET1FpGioS+yHsaiwx+KbCgP6QeDSMNLVKW/+WPXItvvZxoQV9m9TywGJzzMBF9QY3rWhMGV1s58S0PvIjficyORbMTZL2aKlcPjf8Mh/Yzo0eiPTR8+sKvguxonhUdEGfpts1Wn0rIr+BQhk9hto8okOeQkEy1LO8cHyVpk0Zm2jIq643CRd0qcfpOYGm+xz9nzEjCWZJdc/Bq5Vok03mi5050fv6nA/HcopBUnk5Jk5jLQEa/0rEXuwIDAQABAoIBADZuYfbjhVynqxZUNTApss1uLvAzmdZqdxXXir9gvT8NoHF8v7FqsTMXdi/JfoFmkBFP/1/jLhSP8mRIT2H2EOomP8w0OhhBBveQbG41zMyfaN/xsnyJNNY024lj5UKWzLD3c4c5GNfsZz8mLt6qTlrCKbMbP3H/zvVRugyz26BEFzXnXVsRo57MXwGPHzhMS2bdYsixuNz6Hwlu3brJkIgzQA740ABVzVG75DRwvdJ1w+kIskrlCa7tFnHl/mVaBQ0plFaY4Urjk3fOI6JzHA8I92FBWYinKPlBXBBeXp/vjsfsp60d5zi1/bdNqvMFL7HbwQO7yJd37UR0bV+1lIECgYEA1XhV18EICpxHQwm0svmvnE8MVUHEzzSlpXYZujQis6x0tXOdXEVqfh8EzSmBlJLj64ndIG13gVVeBIJszXTBLCgoUxrH1JXtECu47jIB2X9QPEaicfpnUlXcbNFS7RQIbyS1yvbKKmK9lJOA6TMtjMVmQ8zpAtivqhsc4LDI6RECgYEA26c4t/CHiqYb31CYsUDNQeL6yor1K6pfyshJ7xO2fvFj3+7H5Q5sVk4bN0btS2pird/WDlfgH7AroCbyxtCEcsnXr3gOywA5I27Jy2UAFmajC9CUvIBINdhKuEAG4Pckn0aDBamBuU/DG145NA2mXBMQQ9MsObNioGC2LVA91AsCgYAIjbPS21c5JZ3tX7wv17Vjq/8wg1wheViR0rOhNGmXjXd3tdQ+WEG2IAQPPHSGwYQEche8Lua09fi4cYluihkbbdh/y/jp2cAP/9B/Kt3MGz/ZynLD4ma1c99LNO//s+fKnEv0gAMFw8MY6vglX/mZRGeem91SUeBoDoIPtsW2IQKBgQCPAk/GSn8lAUNSYNoZRbSduhdIubIoTNPzZfXlB3OhMK6zBHb3Ji3Y/x9vHOmwWUKILBzk18ffOccdjV4xnV8ukUWxQ7x15N5OuHn/x/GHpClxrsq389mP3RPA5EbWP3KDlNgHXrZMHadM8UrTHjP67JqBXkMECkwjWPQjioPGwwKBgGBWi7axhF2Sk+SPSWKVQTTOwbpRhyDj/qzLDB836u9fCo5xYmlbXp/YtiHlk37FbRNfw90qN35tqD10dOKDmGbvm+tJxoRZpmH0w1ExGVr1KBXIp4D2jTyjHPaHEdvJEsWG5wNJcOd8gFuki/m4bafFh7iJMizvYkM8bVNV2Ctm - - peerId: 12D3KooWB2Xvsa8RrmdhcBTJMoogqPu43tWZ3XUwXMowcCuMjHjo + signingKey: RHl/cHYoPtAGXgJl7F3upI2OAnD4hd9aJztiqo08w/V52b3qKvFr2TWnpbNvBlXSxeyXpo4WB1jH+pMslW0irQ== + encryptionKey: MIIEpAIBAAKCAQEA2vHQaQ5U/PzvNFTk3G9t/IMELaxM5OBFV0/HcjDnF3jtc/ADtqG4zsr/VCs7/tiXiEIxn5aMFrvS7APh2/EHLlAnyrjYLyyxvgwqUtV06Gf5K2V7HmFTLch7VFc5HckU4Zg1B61EYAtnWu5JTmsZAmP1v3afsnfpdwTA3LEH65oOyEAXqCeNUtrrwZXYnt77gk1zC0NSdtE4Hf25OJ5to0kckmQf+TMxj5seA5+u55Bg/Hd9sorFl0X0JrAkIxnVcWYt9lCNZk4frPHl1deX9BwOJ5KKrz1Af/617rl8b8H5F+KzkHXpgpJfxtMLWUnUuaX7qm+R3qe1HeMCIAmOLQIDAQABAoIBAGPVHT25/kC5KG1JRG3LFXCtYOtehFVceeG9C+liqQzH5CYYS+krxrPsVg5QBHRI2JeV70CgidIX5K4few4p0ido/yvtqw2fqJBKxcWtdTg/qJsEE+afZCkdIDct6mpNdQsEtzF/7QyKRp9sxdpO9UFkyPp7oYfkK31MmpBG3KCtb57dyIKqfBoIrp9E54X+MtHHQsqpVo7wgdSufUAWA5OtrebqrUGhWrZCRVT5l+BbPp5WliTN12jVU3jdA6rkUzrdyt5jyZQZ1eIm89mBi3wQod3arUx+DnXeICroyWW7eumXqvPdYO9Y2eaGpXY9sjXioGARi97vD/qCB9qB/sECgYEA8L169WaUBfPU6qlD+qZN1Be6PprjBqoTYu3clQikYhF1HGcXT4ri1/8CT8gf9QsUt2NHzNf0vkhyqJ3bD+mxG/c62C7ff4mhLRR2MRiDnqFaYKJL4snFG6eachD7IqgXEJ8Uw8s+LUqljhMa3NlXgDyCdrazVto/J3iDx6/B2/ECgYEA6NKniFEFrJBEVr7neEsMzKSuu8S7VT8bZGNY5yLIHM7+E1YeyJko1BtaQ2f+x9nnRzRPpjO5H+oVLeRWj496retGmvQ24K6VPCq8b7I9QUdYOvhzgo+go6sCM4dzfespIi932EAHGFA0frZ29o9W9a8rgFZUoigde9KAYxVLQf0CgYEAlfUBfZFLDTYoX4/WV3B2NHIfQlYKqqEQeGRALdl3Q9sp/uo8fADActlXIElBlsszOVSvaervegP44A2MYiood4oV7omsEG6zpjgDs2tYuVw6xszxxi/3BtXs/7aSKLFZxLHDJn8YmO/RlmFSL1V3CtsmTTpbFfPWuQh51c4mTJECgYBQEhqR9CN6bIdEOhWLNmxpeP2rEAbJU5HNHam2nCysU7fn2Idvv9Td1aZeZkamXtd+kowOAd3aDvxHsy7d4p9zbuXyZqj07rXeYmg6FdehOrMqXMYFEfZSM37nT981YAneeurBkYufHf5f0crqEvP6PMs+MPKcbiVtr0B+UxV11QKBgQCmNz/q1pPxEltFBOZmsyfmplKgeDyexB8nb0z1NNc00tpKtWL+hvLqGQwYnECJ7kcJDNetKM1J6rDCoLg6hObf/Ze6/BFXTZF8bM6Xqz1elQPYgHl5P+vlJ7yVI5FClVG8RgI73vxr67CZk+4zsZbvTLscaZ1ZPkPR9m+YMJWUrA== + - peerId: 12D3KooWNJdqtKLZAxT3szMrWoSLS1F1JkyKgJ4YQ1rAKfeVPMm6 address: 127.0.0.1:4530 - signingKey: zsY2jhPHbfMKIKfXGh+PsNBhCLD//dmJtBNMhG3m1OIR+bF4a7B5Wid8eBRm6vtCbOJzoxhJZjRYk1vEHuhmgg== - encryptionKey: MIIEpQIBAAKCAQEA4mbDvFUlpfiRkfnW22C0XvpAfB0m1G7vGcDWfNfgMmf8xD1rknWAGNZi2Ek3rjt9uVuL3DnlLEjGf0HrhsNm/VUI3nId72zgqTZd8fHbA+6h2ba9wP1t+IUf456k41bgljD09HxpvEKtHO1OWQGnVFMc5gqMeM7uovZS+NbXvG5RJoVgG/Ugw6BgEmj0e0LDmvvn2FRvmzst77EPQKlp43J4Vl0n7OtvBypLd/KA0dtB3Nl5rjcewFpSbUadhzJMnw38mtj/jwJsvvwUnzKuv6O6ZK1uqW8bFXKN5OmP8gw+EkZo/GX5IuyHdQwjYWKTAuWn/bYXbwsXAqYEtEW+XQIDAQABAoIBADCbC27FgP2u7eG/F6eljVPOukVrJMj6wA5xXhsTZaistpGS9iNNYqDydeolXfTkBMvkoZQ4QcFOJn9vsZcPIG9G8E6BhXe/kkQBzg2BdRnVA55wIzDpt9BhFEWT66Z7ImBcRlqu0yx9zBinwehN+JSb+1pP7XSKSKVn6MxPo6VqSlP4xRN8rQrq8sVvIt1eVH01rxhGBRM/gpoPtIXlf9cYRoa/49c1/Hk3YmE+oYG+oWzoBIsIDS8qEKfEzIrHTB8d0DmLW38xInTqwNgcp6GpoK9mDBhPcb6vZpd0uWx8pwqJ4cYQTJ/ksOrq67T6yyMaJn8WRJflg1taFD9ONoECgYEA9B7LsEXHRMzEAM1YKqxoiOm8UVfv+qdsLUBoeJb81fdgb8YjXq0KhD7+hGhfCogIWuCygXOYCd8srzZxlkSCK3S2F6R5xlsZY7TwSd2LvH4821T8dX/h+mYoe7dbrE2PjWuZL9PwSOLGfEYS7BS7vwl3Qd58sF5/hVX2Rg9V4tECgYEA7Ws7CEt3ic3i7YuzAdaw22WOHGETwb9cV5cwKRnvbhpIcU9fQa291+kIhgV6TaJuAmUJbnB3jwRYG3wEurRodlh8g6HYyCFzB9ZjKuG4av1wlLw8pTSMngH7Vlsy+OiItQhUSB14AUAD9+d4mq5P2uPm0aqw8qbU8Z4tZ6Xyjc0CgYEA4ULRfdTFrcytSHgzVR1GUKAt73mPreFzxsXaIPxiTiY4zKsu1Bwkyic+wHt2x8cCvqj8zssVjnZrSzqX0ath2iuWI3bYD5rccM7zs5VFbiemjFV9qAbbRS2jSZXGd9YSEtMoxaNx5C+uK9qVd1cib4OSkit1L2HjleveloNsIyECgYEA25APR9yC8C43bveC1HB3nm6MvjII02TlQRvQrjIN+wTTefatYVAMAWDBQTBPqvxMQGqwDjJ0Xw7lbIWE2iV9dfTfMdy7XlmQx+68Ryv4IPnA48wxSZcPdBDhHzu4J/jkdIb/arHWCVHqWZj3MBWERCn/jGcOvVkMFWbzFqehaQECgYEAl9saSHtsYYbhEX/PMLbecJtJU2WEOkML0QpyZyzF3Y0FnWpjlY4HV5RUsEOksAjbaAxbF7Xk8NZCjmqdR6+WdHt+3CQl+964vkvBIGWYXyo5/zso5HxzTpZTN8I03Xk09nMfn72lPKq6dWRD1EVBPX0TfOzg1xL7ftng7BR+bx0= + signingKey: BwEWqy5XqOeEUy4BmMzv1WltI5TvLPfP2l2mtioxb+a5ijq4aSATKZSFfcm2hpbGDObWOzeyi06BarLOfQsTnQ== + encryptionKey: MIIEpQIBAAKCAQEA2sTIJSgwRRwPVINYyC5lHtZGsBth87wV+mwMVHkt1/Er8WVstudDFj7dvpO4wHE9vzOQi8+VobNT+xZSB1hlLbOuyBMDzdg+0vs1rMmYruKWb12VZ4+ir1xhnqpm5sKhPuPylZFp+m2GuyEeMHjUNnbQDgPSxkh9jNnTnlwG86h8r5BlhbiISZUs0Jh+IiAbgf55xTdYp0UmVREJYpmk8SBOQS4HfkWM7ih85zMrA0lzi6bfghN7CSABpAMYSgLJc9XeP3le8iMSKQsT+RRvXgUAniPT7ftbWg0tZMNjJ9CXF12Mp0ElC95UIwOnJJydgrLMLvQ0Lggie/WdN0PpCwIDAQABAoIBAQCvg37bqLGJUKjP8gzxlZ9VLS5LLbzZUgYEAlmmEA6CmB/cLLYay9Fb8JXwxw1Lf869Ln6CXMm8kGYJJPAsqnOKRgUsyWyc4igNFrQKazbO4EU3Fcq+6lLoA+Lh6+5gpre9AB5oduCipOqaCUjyNI51H79t7w1UPWZU8ZHBFC4TnpanTYTqyYwUThqDR/PExyV7mhYN5gEi3cg4W0cA7qlDaGgwaKBrMphRt2xwNlAlYAhdkwdgRmbnB/zrWb0FHqJAsz6biqqNh0N0EgIsF0ZMO0ZFGRt+Ou36500Z1cRpGurbO1zrpNV2R2Gg0Ssun2tfjoYJN22HqwwLY71s/xXRAoGBAOx5KeiD07zkRCUzfVa9oHd9CxFSpStz0mCauFDpW0nhzgonjSaOmEotGvVRLDF1eqbtji2QOx3WSPXdnNlncyYAsWFJMyupygqsxBxnVBX3yFFicOE6PCaZocwDVmdKNNfg/52U13qS4pxFFclUPHlVvEcovR1VAPP08MvyV4x5AoGBAOzVW7FmVgzAUc9E8ro6pXD4dFyNkE6Hasq5ApQzFbqcaHSUjbS2lF5dKhvur4OABy6XO/wgD78b/bC+vMryxC+yHm4FP+ANpQ+/DSrn+g2X80J0wqC2tIIVqYMOzn3L+gSfRnhW+28vEx5SSofa7aZl/NOoXtXD47amJELwYzijAoGAVH9vJDCG5oZCe3CMpwQXZNr/q272qjI2yGJA3likUCApuaMsYsytSkQXz/Tzb7Dk5OUZ2tog5aZ+Z6yKsXyvvrKcr4CykjWXhnz5jpS1jSv/HmWopDJk7/4RvI6svzfa7hDuBeb7oEcARorBIDHDci/amSrLeMG5F3M84AN2mTECgYEAvx+PV6JWXwP1AWeK2m7phDl87hPwGO9/ZwnW4vI23tnKEgqwMN4G7gARM2lzipOPODIj3luhWYClQjUq9jzjxfngRLlHyvA3/HUZkz6RtNajIUZIqpnHIhOJMJKKYUpzAbfnjsXjMt6ydw3Bx9ENZ/N2DPkbTzc+VO/O45ZK/DECgYEAvhovek7Jk4ZmC1OsxedqudrgQugNGTMnc6gFZR/CUXrtBs1vq4zKe003Nx5WPGaYooySVraSgBplamtsL+dUsVRqWjCyuUrSkuv7XtP6rdSuRJEHTs7vumnGsF2pp+I08W1Bg0zUFToGy0PqFX9pVeR1f63COI4Ca1Vy6+BIw1Q= isConsensus: true - - peerId: 12D3KooWHSSHxDymTrGQjTHSATFxWnnz4incxYazKukgBia3xPAm + - peerId: 12D3KooWP2cwtzkokAGAr8UzdW1pmU4NS2D4dvHJtK2q75TBEeKq address: 127.0.0.1:4531 - signingKey: uN55hCvFWVBlFcptEca/PlCJBVvMPmCvB9WnWHHGMftxP2GGPEVntjpeS2aRrcHvfvf0WfjAP47CQdr+V8yD5g== - encryptionKey: MIIEowIBAAKCAQEAuQvwreiIbcoASka0Be0nvdQfU/ZGzIjONzfHCaGWqIfxjqsIG2I55X+3j8kIZZBl+oMIGzk3amZq1KWNGKsRhuDdsHKSaSAnFqPIYYfiAkp5evsBCFzWkMaB2xelDkNzYGAyTemvsnjyp3wlJjrdoJrwW5kNojz84B0NQZjn81O8BH1HOibzXIoO65oBduWGwj5zaqboEe33VFowxRJxXG+RHnOCY4XRoZ40wx32t4LefsDcMbfaNaYEt7av5uzkh/+X9AWNw6VmYKimVv2KAyYwJ5Q+ZkCyASPO9ShBdMfaiR1hETQExVPtBQB3876e0IzW/+j5o1WGu1KPk1t2kwIDAQABAoIBAHvnHM61hrRMr4kMcnoNY7DdmeR0YM+PQtUCSgmO4vwRmpK2voTnbnDW5agnKbInz8C/f+wKkapyzVF5UFKWKPQxGP+Ol65AUyv7mq6Dd7ek+lZ4PybEUv85i7WRzXkRfO2pO8WjlXthNMkkfRNuEvv5AruybciWIZRGn5uusJDh+rMI382z6b00/U7r0igj4g5o1KqT1wYxba2VT4CaSeqNEMbdOcGWDjHx7zIanHvMrRtRG4DgYIY11ohnARU8UUI/wL5WG9iVaeuepq8T1G3vLt+096UwE/GYIhwQ0UUf+HS4HviACcMWJeXbKas64twtUA0Pf0JFCxPnM/QTBtECgYEA0Zpurv8M2P/atqODGG2teKseJqz4nB9vYLbAQfpziv0OyvRQ26r72pjtBwIDxv67fVSL3/HlViBGElMGycrA/XZ1cTiXY2LAcfpnu2P/Q7vUE/n5NBg4C1Cqjgb7D4dFXOTOM182HFL5SSQiUv5jMRvqxZTX5NcxBj3wbuHt0v0CgYEA4gH1755EWtS6q8+UUdLNAM+TL1SKaMcfiGAMdMWL5uSJBQ28fFPZIZv14gTzaU+Zji3AsGXiBpgtwor4rEugmX+nL7FATIaS0rh15hjXEvczg0SyZBkiXygo9WSQFQ/1AuHmQ8dNgNHXuSv9VbQeu52xhr74saii2tCzTOfyDM8CgYBQHA4hpCls5pzZITWBqKmcbQphDcsXIIyZEj/495ghjwaQW0BsNLV9nuU4wHRhIgrWo/Gx7eoRONSPPFxj07JfLV9FnrN9sMiMx3/OBzIQ2UD9QZUVbAw/ht0o21IpZTIFhw2oZMNxn+TXJ5BW2BNhOaJJUdISDI0YLaQvPPqAoQKBgQCBXY/xtYz41PV47NvALkKL6UUdfW2wZfIltJzMplrbMgtAKkmufKw3sbb/xceyiw6hNI0sK1VCYw8mYTfQH4Xw9wGyqendI9ac6VsK90L8pyUESWk3JK/o+erf880JUVX0bWvJdiZlyzeI1aYvzWceCziXoW5m+tklGPrY1ZdWPwKBgEYm3cThyIi1MScjR7lBKPKUKfkmN88ZoNnzfcn1Mgzwpo9alTycyT9otC/wBGIf4WhRmDoCYE7htIA0C0j8YlmYhd8+gEuRnWFn8Gx8ecpSmUIIpZINeV/t9YFSbod6OnYJosxwLJGzHpb6FN4ojpO5lq7iPWN4v/dtd/p/Bfoi + signingKey: RyKkgbAlAmo+suhJf1mYau3uneQD93XO9Dks/a8lpXDES5wfPb3dO/8oefEFllI+c/m3bTVkAYBdTHtCZq7lYA== + encryptionKey: MIIEowIBAAKCAQEA6Dhjs/8s/uiTFIopCjoYLTq8JGIM3otbUktYXSnqpBVVUU4TwSJonpyeRCgcYy9FlDWrUPfCNEv/kG6ruNUZQs2UuPbaOMZ1Z5TZRokwZF26rlkmaTlwJLKmKy0wwT9koZT/e5G4NkRO4rOLK/O4NyDlZ/HvWaZPxQtcC4en0CDaaIcDSSKaL5OMz0fcXayQlWKiOsuuP7cSUYlBDybbJPLSPMVYUjGjzIBqZkV6nBgjKGIIBGlknqZpRwX1mgq4vG0UYTfGCOFF1iHQ4TiLM2EiiZw203PVA4ifSyvkZOkMngItBfYcnD5MRYtLXlps2LWW6auN6olAkyUwFQeHLwIDAQABAoIBAGq7kEfo3xuCdieYoOhMb1RKjLMERfn7f0vByal4XJpyG7a09itszz0nqy6UaQfFcGuAh289kQtMavhNhav8dhHYP6UMAJzbypaDOaJL5+wZkHYWD6uJdNvJKMrriF8p7ey+ePaosUxv9PoJn8vhxye/fPFbp7FC2aMtZ279OMpVjyhbBekWlHfAnRbmDaFjMH+7wHfaAArpYsmRaOJ+/ckqhHSWSCXHO7dOyTcRNx4J0NoZ+192J6VsD1bbGxfHEgtVac/3+fj0Uia3mjkA+e9+oe7kfiGAheLs7G+kC0rEht1VLkviwjM0oCPd3zcu50HjqSrQ1q+i4vKJLrPWQFECgYEA8Uz+PlwghCWcJ7c+TYL1Y4UpYMXavRYi+XCHyn5x2PtxLDgK9j38CbLtIJFDY739RxEDLsOAkC3ba5p71EAx2ZF8i4ylmw0ekTe8BhEo/PHhCmLL+12zUrDbmUqsb1/NJBRDVZ9975nqWiT1KWqm3XKrwfBRTvgiP3+dC3XrtiMCgYEA9l3KBUK0oc6RWftNQTbehrwMuG0M4wv05peTHHqlMsYV0b5nKCr1FWU+gA4zhEDNPcs7PkZRl+HHMalkKH/aLpxeafN5a4PkMsQD6ZK5Mz88IENzXbFswBjCI8s5NyAAK+aI4JqXiRoia6fRnWVp+VrC4A1o2dvD6GaZAta3bYUCgYALFhF8RflMePnirT2UjBbAGsca5hw1ocW7lhr3B7YtVOgPMwf15kUlIO5aF7Jz66+uSy7NQDgw55p0KCXWS5i+uTtyoeSd6g1keJ4P3Uv3yxkexAlBJD3v56Y/NboUZ99h7/hj/67mijjFKXuGCpteAz227Faf/TB9oFxTwXgx5wKBgEMOeCRCacP445soSXjMpHjrylKQbAeIg5oX+5Su1TQismGqf41xU9AFBKP6OY9vy+1b2b4ziZXbgEpGHtrfIdW5/gC8onnfJkejDqWOqBYIyibF9Sq1VjJbCsyPTf1xGlrYnrzzlvdcQ64luWor5lJWn+A4Bif2JzakZlVdeAO5AoGBAMynKpkB8vqTLU31yt5SzBroQj8TgZKGbzB2apO1a+2XE8WfmtFOxnS1/iQ67sMkv6Rh/N5SUxMnBLXjsYJFpuNkKjvE+RqO9f4PzklTIJuT49pexheAMKBA9zWv5YPEmMV8xGbqXooSuEP0ixlM07DiqaC7aBzSyIfGdTOvI5w/ isConsensus: true - - peerId: 12D3KooWCm6fXRReUtpD4bQyy3EnzEe7htRGCAvzHw5yewb1SbRS + - peerId: 12D3KooWMg5c9wHkuXQ48qyHVa72UKerKWAVZRC2dc1ibSadYxTQ address: 127.0.0.1:4532 - signingKey: 31nl1dejInkuEbwBf7NyEp7t6adkMOyCMMzq9ub+XQgrvMnFxeIOso/c38RWo08lSMpZLltC2yS88/EkNIWveQ== - encryptionKey: MIIEowIBAAKCAQEA3dSgJsWNz3zusneGYIjufkXe4byl+RGZNE2dUWEwPqlsjyFXLFmBQwU6UMAOvgEGLuNY2HWVLKzWsqccLqkMjEo3ZQSTft1kf3x3TFlFpPFtGI0lL59b37K3zJ6sdY65PPskhXqy4ru/oTjJh4F13qE40x9bVSrmVnllrEzlyG2kR7KOiHWmufChtvTHA6Nv4x8sevsKzwIXOMMdbKb67aw6jWic94gI8lf+KN7UHYAMKA5MvwwvvH4hadUubMH810jtpiD720dkKRYkgLviLuxhOhRn+s2UY+Dl9vDplBO5tfn0ZnU77q0OrF1qAhwPiuy0yq08ykhL4NrKiLjGdwIDAQABAoIBAHQjxlWGSODBABfgDDKufm8OFcsKAbuNQzDnEd5xi9jCy1uEkSdfFRYJvqZYZ1+DGcGitfleVmO1ehK++zpSt4cbtDTnWHGrZ9p3R95pPtVEsWGRRE7SmD9eSmyPBqvltYX/1vcrbkzXD1VRbfHMDfIpZp7iY+cLNt0/YcP73rI3+4U+4DXsPmaf4jtCBpUH0ru59aCJTJWvYFiVsapWdJY+BcAerpV7QH74dVQ3XNIWRCxsG4+S9cfi5uuenHqM3MmCz8jOpTQeepg64aSNmFsTVEeoNXfQ+78ELUIXEWBpDoWWNVTQxoy3edPThuDgEbw0KHP+z6C63ztP552kB0ECgYEA9pKCvigZyrbn/gmFha0FVEfGWkv8SGHkm3LctnOHj3fyfezKmp1bq44bBFhw+p12qN6NmpZIpMh91X/vDcmNJTAQz9ty14pB0Dlq/egV/AffjtUjYb4UzxiV3EmH97BB9rK9B4VkSdPY1FbOtAEyt6cWoYTUwwrHKzTbhOhAn2sCgYEA5k/wU0uN57BwXrcDNP10zkjxbpsoNEINBj+eGpKjZaKXU7XkgoezgzeGa04Ym6crLxmhlXtSojXFkqeLdhn5hJSKPJ+JsAZD9gM0iZ9Hb8l9/opzlSEJzMFLyCdCeu+9Hipq3OuGkJgRemn9h9UMih1zUTo2RwRdfpLvUEUANCUCgYB90AQmQw/l/64gUXtv2fj+KCFtsZfo1wpuxw0Xi5t/+RQibNB0VBaSUtA2R2pedjo1sFlQp54pdqO+bKjtwAnlD8GETdUrZcBvHt0Y8XNGRj4sA1UqanLzuPe+j0Zxe94soscRL18czJu2vRR7hKD8VKWXhM+LNdSqly3rgxZ2QQKBgFJ6okhSMHmeuD9TLzTU5/XQLZY8voMofF2WftppVVbaiXMTGsicLG97fQoEp89maJKvjSxpQ8iPlTfWBJ3A45jVUUQwpjCBrej2cOQwRHcGI7b6gjYP5OCNAMSnOqmoHYQmEKsZNdGmg+vg9UilxZ3YuimGvVVlfM4NdOK8Mzx5AoGBAKKtLvw/rpL+ZLSlO5CTycjBlY8Uy0/SkTI9T/gvwPm7zMdZW0AN7HShsus6SKATba7ZXIySY+tBWfuq9oEACzvC20Qw9tQUTS90g8mwHwTcj4H58cnvmbtOFg75RYMUYvcOjpbPLvcGKsYrobjzqv9MrrL41fgMXw8DVIomqQbP + signingKey: gSyxSnCL8NsewJmdFwgVpjQ2hDwDvrbZrLnA1007ymCwLN67/Xd/42q4vsvZAovsXBrv4PuWuoQUqmXhX7OJrw== + encryptionKey: MIIEowIBAAKCAQEAptyiobOzgLUuVfUQetYQD638+kOUAjf+V7uny+9Qhtt0LZM5v4lsJ8DK+NIbJU6fo9sMNJ8Mc2A7QNEZ6iyppI4zszUIMfF9Ixhew8g5zBlaDzieAf1XSGuEd89vj1ikM3Nhp8AXzxxoFOTsgUCMlnAzsHalcVyqXRzN/glAA1Ob6R0pIEIz4LchvMpnjhSLi5XEmBMy3b3XHu+T5nYyLzLxxMpO2fHH41/GpWmOEVrjoT1qP1JSv+ehuXiuMW0rM1833os6jMHCZijfDGh8blWI2nthjOLbr/KQKQhkIqOXKwdkVLY5x4/c78L8dV3eZ647SqurWC/N8kr5r4LvfwIDAQABAoIBABTPHSUHURJzBeVIW5bGDVi3PP5E4Tdpnjl4uJNRM/ytb46jdqcxTyCiBW4EXchIRtZbYelKEHZvANSzfwTaLwnLhh0KNwxrbkyrJF5MIREX9EhDqkjbPEBW0D1UzDfXORsFf5848H8urrg0WF5CG4ZDVd7i3P0HLmPQTMwqgSYo2pLexcj0LtiZZqJ6ta9kxAiJniZyoNshRJnAZMMnFYRhy/eDF+L6sJPHieYgwiQFU5e0CK9UgsLmmOQWCKWtPgvxOhqlbcTz1pJAqkyzOC0wK/ydJpVAh9RUqf46rEDFzL/l90ZOir3AMlYJIHf4PX0TWchXjFW7bbHn5Zvk1xECgYEAzpuGDfaerUl8QziD6F/OoIz1/EZwSumErCH2NXYMBcCyzKu4fBqVqj5tcLsNx42v6kAGaERAQqaC5ZZ9ZNhXiWasHAermQqv8DtlYVCUih4e87dX1/xTF5TzR8RhLwHPADd1rRafCKJMD9X6Qquer5LmSST8ej3mJ4mrflw837cCgYEAzsCoqFenGlCvAZoQrekxS1VmGJDCKBQ7LlbOwQaUkD4I23rjbAHG8J51jmaQQ4epm6lU0JLSma/LKp8dl9oDEP09vcgKj6xuHMZV+EmsA5c181zMrGoH+tSZiWQZjSmJVhd5T147vnbUunTbGKlOQByD0tWM913Dm2dqB3goXnkCgYBZax4dtPr/7KoHPdJ5I939xoQ/5wx6n454IUq54JlbdAbuZfO2Ypsbz2D2RT61ezEDpSogvklBj2dfjj4/AxL/uJwMlZVC60kyI8LA12syS88Bk/xE0kP0FNcl3GxjN9krMtWPUBcMWZGp2OYzLKvFOULJrWRIU7nkqsS6L5l5CQKBgBa/tg8HzfgkRo1LkWhBT041sE0lqGdWioh3vroYakJQwRK9O8bHj0cseEzZ1ifIBo59HDry3L9SS21+Inhx4YJ+CswV9auHUnpSDGWMXaPrgGEtpcuWwxgDSn2GiRUyK81QOeXUvYggdRmq/+x/vH9rY8nP+3nAVGSGBXGa8/4pAoGBAMB7EOk/RnsgQ+SotHbvgv18S0lbJuWsLYGnNp8EcuPxDIxz29fOFH94qzVOwAkk5cbHvAl3/5sl3SelmKM9LXhcOT+1zxoavyAYyVeAGZsrbBmbzj9yeZON0gHtpF3dMWxiguyWuiiHM/pL92gKzlyIXryC3andL/y8/6VpWbtt isConsensus: true space: gcTTL: 60 syncPeriod: 10 +storage: + path: db diff --git a/etc/configs/node2.yml b/etc/configs/node2.yml index 57318da5..5bb42612 100755 --- a/etc/configs/node2.yml +++ b/etc/configs/node2.yml @@ -5,39 +5,41 @@ grpcServer: - 127.0.0.1:4431 tls: false account: - peerId: 12D3KooWHTnHZgeyDdZJwrXweFHMrSF7YBXSuuAH9GsxhbzTvfcT - signingKey: EVlWc7+UbqSKAvjSdBq5iZt2dpcCYhDJiWkSn2+9IrJxl5F5dTHw+eIKNV3MV/tL8ext3YPRkIue/8TvUUfpaA== - encryptionKey: MIIEpAIBAAKCAQEAwLhwWK4vZQooUjulblf4I2+f5/K9yES7/HW+1bz93ZOeeiMuKb5wmw1tVt+vrY2j5cFC/krhSWUdfRwqDvv6Z0q19v9mD7zIfad54KgVSyMcVGxWLt7haGVCr78VckO5JD+aktlEM8/12crzHOWRh+j3jgELmwSwA/LiXo2ZNH9x1Vftw5MHKksWTpvaAprFTkYUrPHvrjpiuSGzT5abGUYOgWUIzTtqZYra+zOMPzVqDAlMykmUYjVO/d/l01L3xgLZQogZ9B3NRgXpTpTJ5iF7UtUejjZSJ6fYGVNwM/TEMrIhKHD54I6FYkLmp+7Rsw2MmxVXHkQPQJ7khYY8ywIDAQABAoIBAQCv97idQG6GE4A9lbi3yBsKQCIB5+LhueDr45ccEjS63M8XNogwFXM8IEZ1zEjcbzf30T8accTC/1Ctq8m7ZNh+9/iuTwUh2X43PXRLbS4ELUrwyvrmURv/9nWtgwxSCQRD1M+OxlM/++K/uk/BUtxO/KkNQGcYZG9TK7MGIsSA6Ua0fNEo+hcTzqBsED3nGYXwmn7nX4zMjPqr6TtQfpxWdwtKYbBsDcvIoigwNPajnsdSbx2M4pZh3cwBuROKs9/HpUNOtSZvPc8BbRenJQOqXG2R+O6SMBGnYf5ycHpk7Wya+1TtGObOAcrgC7RV6y3KGzq0Thu7imWC1B7GvRQBAoGBAM9yA4EBjHSQ0sP5DTT4yD3H7ytQtR3oVZYcKiWg4lPETaFhwucFzbbhmh5gB6Xng71KiIuYuvJZi2XQeL2LcBBaZwoj9cpclJ53KuQ8LL5TPZ1zOn+xU/Iy2mumzVpaSyWcDq7ArlhuGq7JWubAEcrehBia7i26Ss9ro1HqbR+ZAoGBAO3UHnZz8gmkQrUyk6rTPJHivnow2O8nh2dWuK+o+wAN+WCF10VQVaRcUS2bC/khHeomTRNZh+kzs0woLdfEtLlxECA2+MHiIJmXkLat7/Bm8gByd9iWHRZ6d9ZRvb+DPwmbZV0mZoy+8SF5DJno0uFdq6g6tTGQKmQwu1xHeI4DAoGAOQubVxB79VoV+3ozXYvEVOj0Ji8tfynyzzKzjGFvm6Vxy508oZcA+PeVECFMOR0vJxCl9+1qC1cAdGEdstHzYSvbBfjZkGphHCqdCuJZU4VEflW/knnLIeFGGzBlbCFEZPVDPF8UEpFEmSgZ7TaILgd+v91q/fwqslthMBeNJpECgYEAzzNTyu1e/IlwWL8UqepZRdxfCMPP7CPrMtv6EYhODZEfJ7nTgB7qTkTjsLD5MHZqwpnV4rrIzyJs3jfPIMHOlhVr8DUUao5gyo+i05UciryVsFAKG9dExlWyXDVg9B4baHpLSGlxRMQB/qCgmuKd/xyFtg5X2DN6y0ktosrdvBMCgYABqwzMnDF2SPx1mZjXIOCsj/03Oya75E8ZTWGorkROhyarE1wWvES472IGsZSM7qchABmVVGxr09mL0nyNA5KIIEoIWtl59yplXKrunYYoodoXtaS0whTDraf62am98IQ1LAUdf4p1dGfkrAsf8stKuxbzYtEeXQH3EHzzLOzmNg== + peerId: 12D3KooWKtsepiMYrDtok7AU4itPcmHQaLuwzzfYYyjEW1KoLeXp + signingKey: bqnCY+BB93A2nTM59zyP1CGZg5seSIeoGM/ATCOMy4+VvIfB1kwEK2VM5QVx3ub8zV/kqND8xuuQCC2NIrAFxw== + encryptionKey: MIIEowIBAAKCAQEAxaNDIGlEwkYRtcw6eoM1wRReJJUgHbEPTGSazEHTIp9Vza0Ob5GqT0yTFbWQWec1+vfCCVj49Z0usKiIa78iViiZxN/EZtdbimM2b2LTOPPkHTBNM3KawuBtVd34CYOLyFFhc+m4dtquGTsOGC0q2YQlS/XF+vGNWO/j8LnriF47Vv3Vr2YDfYeLo3aMexjzLKDiL1TC8fxtcSHqwrJnhgkFEHV/BIadPBlCpVukTPPMusEaoMshHVViS2emStf7j7Iq6KDdbIMGRCTAKhLNMOnHDwmDlBo/RSS/iYtEXFEADDfiYPOeIKIExPnAfdbku5I1y3/IaxeSpk+jQDFfMQIDAQABAoIBACLEgsWL3z2x5+GsaMkuleE+fQVAeqLeiAtvU1AFcGgR0Z1aCUUVQfmrReC2zQsTwopA1ZChZ0KGATWwoDccK6UuhUZ9+uYAkqj4pRXZM8E8HnAIFDytt436vyEw6DZ8PrXhoxwqDHpUI/ZqTiNwpq4XMhx3wvlPTwdLRDUP7+BQK7EmmZLZPiU+oq7f8Fo3ag2gkRKakatPIjwKRDSXcLNW+Rz2YrxUOAdEir2KiK0CKYAkqmcZy/O1xBjQ0YgQpYgxgBXRHTgd5iIFjGG/bCIHsLyV+FkpMpgO7oFw0aJa6zISFeoZ3Zekpf0qqSQNrI+Tpc3uStSE8/95nIo+fxUCgYEAxuvt8VRl1W16ddYpGAFO7ytTdzFSg4e07rKPLvZbvQ4M21CASluNPPKn/S9KFaLZDagBM2jl2cjGYdHVfVlVu/fmM8nlTCIhxkjU9iHkyspJWXNxzUcnh12GEjcNb1i7Oc1QTof7HFjEG4TrsRmGdAee4ZjXYyIEPAHCgxAdc7sCgYEA/lkGdggdLfw6HkXceLaiuq8FA7asJ0JK7L5XCptAXZ9ci10oQuwC+58S8eFVkOUmnVwFovc7CF5EtWjUkSdI+AIL3WCnj2Xjm/S/ASNL1Urw7Q7A7QKu0kGawadUQ00/oSRApEC3f3XK0rdkRlryp8mj2WRfUyBEjh+NgLzgzAMCgYBHQK1Le3K6n2t1GBBCM/3FN9y+3iDzUkHiGn2lUcOMlaLPUCeT+vU9dqHr0+uSknFzLdG4S4PBneRJl7MEImLOYL7JoDENM1CryNzXiU59wTXC39JMuIcVOs/SaHvcfYka7EsuxhCRl84vGU6fckgx+aTUpD3KmZ2wrOSys6wJDwKBgC+VrjzE1di1mJXzUgUPfjBY8CI6uch6gZP7JEOqugcJ+oFkQ1UJ3KEAqMWx95UtGeVUwwUzJcsx/77ExwgFBoTHtTqMi6yrTkLuLhHjbZuQ8rQXD4cH+ncBqRdT29Lfj+jw5FsWdH4XJoP3pX34I++6LLpOKfteTRUd2BZev9vLAoGBAL24XaIkqAECCqdGLiID3PEIRLGacnjEoAqS7fT5A8CV0Cle1KKZzkJlJvxU/pzSgp5AjI1TwIiH4jYE/Xtc2+61Kx1C7jqK5tNK4lJ3BkHUY9d1Etr+HdnDZYKZ32XdGfh4nUU7dx+OI965oQJISsLVVmu2GBllsbg6sA+w3LnK apiServer: port: "8081" nodes: - - peerId: 12D3KooWBZFSp1MrqdQgL2uWSZpybgskz7mjrJnmhkDjudSpTUAN + - peerId: 12D3KooWNGRznbh4RCYY1hDnG1RLCtWviWwVnZGjKHtsXVgPckNk address: 127.0.0.1:4430 - signingKey: JR142BFc9/KJIy0f0BCnfMeO4Yv9InErltCuGyhvs+4Z2A9c9cGi20ECMzthOvtr90N6bq4iyfLbmhNkVMxgiw== - encryptionKey: MIIEpAIBAAKCAQEAt9WEjnITHiG0IhGdn5sGBR32Bo8qwAEZSsPhutQZnvBfTegqQwvb5LxxpfYP4C2+Wy1335fzMGtjtWyv4r2bJHX++fTh0h8xWbuMuqDlbZI79IkAhu4HFfAl6a0Ay/po4DkaBBwqHFu1oPbzKceJpb1fXXXDNO4SIMBo1CYrrI9ipJrVb0NOIbmuDUUvS6c7W8xiIudLH+lrcClpsE4f6+rVaEK188cWESmFvTFwWd0LV+1B+qP28pVRGZDcqMEeV2CoICY0daKdI9P1efPD1XbQGmafU0LlJZyww1pXT5q0yKBSdKMjspZoRbScnUmTJuhZY29cBPfqPjRiEvznjQIDAQABAoIBAQCQlI4PVepxPUKltMMKHutKJPk0yW5u2a5hndMvk9aeqR/bbuemGXKU4Bxl0TNFNdTLcuQfZystfphJvLRMGKEmuOKTBaSBFGVE1Htm4Fnwph0fQoy2kgfimh/HO3gv9L588ovihaAc84fSk8ZEqpk4T8rr/01KmJ6LQahwiaC5sig3uZgQuCGIz11xjNgavHdpytzL3qGhUPLiQAJtCEKaiFuUAEmw+dg/KH0ZHw3+/yCJ/GESwR/8yP6rfuyuLyaR1n4vr/+eH56x4922ua2XtJuz6gdqzcbPjbf2y01Q2XnwEkf6cHO6rYs+ba8BWzM8NZUeTmvLH+qY4CAMWIvBAoGBAPHuResocGdoZEDNvjUpuZlWCCRKO7goTAjFH00z6DEG0Kv37pi53/4AHshaScHLd7kQUBSH8o6Fdtf+fyZaVKdQzfSKqNVt6NglPtVTd7JhI2ddJuU6iOMBKowRk+PYnjfxjETmXMNb6FpF9ZgMc/QC6YiWZwEjooFKrhgfZWvxAoGBAMKGVY1LAoLUFwdL7DsBSf+VndN0l/ApxVjCLhT4l73HrfOEqbts0GAGRTtOA6JO2xhAvtJkcUYbStQiKyz4iPC+zG9CwMm9XNaGRAflFfcxgy1VqMQ/2TnlrwXdCLi1y+oEGcJs69O8IQACBC1m6MfEMrOOsAa3YExkxG7VBMFdAoGAIAgBH9pxz28l3uKerWFB3ohieZOOhppnPr4Cn/Ega+VQGYSxBW2Ot42ChdpWa58p0cnUIHPDbJVFH+HlKcnJ7YEoU5lMMz3jF0MPJ6VucqKj0lql/LGcUBnmbTcikocqo5OKk9DANWlkwRcEJkZ3z7XW/6uSJbd3G5EsraryfbECgYEAnaa1i09xd4pgJ3+2spN233bodEmYIgIYeLjXFBPtFtfP+P5ZeRbVQh2S2l99vnteQaenf2f8Da9s08Plbgr3IPXhRYK6MEYSCaLDXAqj5LTx9TnpDzQX3z5wvLXIrbpYyw4LunEAJ5fevtzjedBfdBdkZ/WKX8caeo9oS9LEidkCgYA9Lf6XK52LDO3uidnX7CZB9piWIV5bzrdJB6ppbJ2ywAD60NF8yecRp7fnyFRg7VCQxGkbIbv5sR9Ua/PAsBo9UFlZQGanUXpAUJi8qnDIDG2Ly6uNTwjF7s3IHC6OIn1aOSvUcgY658sXF1KfDguXv0CUs75JZ5+1djdMQAtRiQ== - - peerId: 12D3KooWHTnHZgeyDdZJwrXweFHMrSF7YBXSuuAH9GsxhbzTvfcT + signingKey: buHKTg4VF6lskoFWDdjtjWNj2c/fz0zAxKrOW05pRRu4+aw/tClrubW5wpeCOJxPSMHJBTj/8bJ8icwKfe7yMQ== + encryptionKey: MIIEpAIBAAKCAQEAtoc/5YBUSzPUISHv/COa2wTeWpsuxuLGOd+IYLXe8xXIry0GHCqCN7orZq5iz7BFs2i6o0ttK2PpRa5xz/GnKtTkQowmfDNwh/f+jIlMo+CcL54Qq4sURexChBCg6z3XbSQK1C9yGA4QaNFRDgSzAs1IC8BCRFf7XDbK06zxWw/As7D3Bo1V3TO0LWi/URkV1PBZdQxX6unt5VplhTQ92o22xczb15zfBQW59qEZYyPa2apwUfmhZgjoAbSOIQm96U7P+HrLa8va1h9q9o+eYefco2N7wv40MYsDXll09Tfc/VhDEfmuKfwmSe5AEnpsg1gD94fX/4KVt7Usb7u6gwIDAQABAoIBAC7POqS5p2Rt0z33/RqVavY2JmvoFjPtHlbjK49ZtOZ0NLYv/rwkbqap+M1pdW+7zfQ3rH2KL2IMSluTZB6m428Jj8w9MvVxH6/O+pnB8ESqqoNPrwi/LyDLeTdzKEGL535W2uwVitX+bVjkLTxCGkJisNJKqPPr+EtqxdNJK9BlJ9VdOLFLi67mOsu3F6AtDtBC3VFXZJa8Wbocu0A7hm8QWa23AL7+EZdV9kJ8Dw2qEYXyYRwmhExuZWNsPsnMvNhlCj8By9IPuICDzW87SfcsIQd7vjSg3y60mmGvl9WGxJbpEkSa+MxCA175k3E30KP1tYMOBQyhlCr7qRYWpdkCgYEA4a7CJGqtdMB8KByzrfGazm8koI0Y+qcriYaOWeoZayoxshwmemqJQTEP29D5SumxOcobKnKRHhKBhhlJenc5xNwppgMIgexZtLLAB2pZzLZ/bIy39T+lAEVOQWIEWDUQ0MwqaGNvaZ2bXyM1Xq6Bovurs8gSwmRIQspskeD/fy8CgYEAzwxpLa/W+BcRPH7VpLSkwSPgsAXW+TCoxWuCMj/W7MmCplyohW8a8wc42RFwKCH4ULpyNbv0VWdCM910/U1sf+0s7B3+IeW/0oMlLIPOd/Z39Legm+h0o1l3rD7deWdL7AMnaJIJsMBOUp0DRBSE5Bj6iUr1MnIEMX/3zFqdxO0CgYEAo4FSZMHpA3JFQWZyAy7M4o0Bc1RmaYrd7xhOX/RMECkUsh7U/dHbuSCLhc1kH5Mp9F1pyxoP60KrFnWRl6lzcB22CvGdo0uSPmlW2MiDYN5DeWiGCqfeqlCL/rC9xw5DLZMNkm2gFVu7anT+wKcbgvJlFq54cN/ovoMbn6DsWr8CgYEAgUVIbgP5fdA5LMIr9bfrncMeyAf9XnwpA4nKMkF1mUV/UwtLFHR4KQB7V9vxYL1E4nJmWHJPbPsZdHRyVKyAb6bPg2R+hP+DMpY7IX3x7ShvYNU9a9pI6Kw1cc+WS/RYjLSzaDC16CtJO39YyKrfBeMqmYm5aZOSVq2FM4voMUkCgYBudtWqqwKvA/Ig32hPBa/pqh+R11LeN8F/NsjrCA3geo8MlDqD0To+r9FTv14AksR7BsAfhoGglbvpddTL+CqHgtA4igNWp2/UCaomfnCgnFl/rvo+OGiVR5DgaC4ALw9onsdfeNgrQ5PkqCCi2crb3txdRWGA2QyGvsBmb1u8+A== + - peerId: 12D3KooWKtsepiMYrDtok7AU4itPcmHQaLuwzzfYYyjEW1KoLeXp address: 127.0.0.1:4431 - signingKey: EVlWc7+UbqSKAvjSdBq5iZt2dpcCYhDJiWkSn2+9IrJxl5F5dTHw+eIKNV3MV/tL8ext3YPRkIue/8TvUUfpaA== - encryptionKey: MIIEpAIBAAKCAQEAwLhwWK4vZQooUjulblf4I2+f5/K9yES7/HW+1bz93ZOeeiMuKb5wmw1tVt+vrY2j5cFC/krhSWUdfRwqDvv6Z0q19v9mD7zIfad54KgVSyMcVGxWLt7haGVCr78VckO5JD+aktlEM8/12crzHOWRh+j3jgELmwSwA/LiXo2ZNH9x1Vftw5MHKksWTpvaAprFTkYUrPHvrjpiuSGzT5abGUYOgWUIzTtqZYra+zOMPzVqDAlMykmUYjVO/d/l01L3xgLZQogZ9B3NRgXpTpTJ5iF7UtUejjZSJ6fYGVNwM/TEMrIhKHD54I6FYkLmp+7Rsw2MmxVXHkQPQJ7khYY8ywIDAQABAoIBAQCv97idQG6GE4A9lbi3yBsKQCIB5+LhueDr45ccEjS63M8XNogwFXM8IEZ1zEjcbzf30T8accTC/1Ctq8m7ZNh+9/iuTwUh2X43PXRLbS4ELUrwyvrmURv/9nWtgwxSCQRD1M+OxlM/++K/uk/BUtxO/KkNQGcYZG9TK7MGIsSA6Ua0fNEo+hcTzqBsED3nGYXwmn7nX4zMjPqr6TtQfpxWdwtKYbBsDcvIoigwNPajnsdSbx2M4pZh3cwBuROKs9/HpUNOtSZvPc8BbRenJQOqXG2R+O6SMBGnYf5ycHpk7Wya+1TtGObOAcrgC7RV6y3KGzq0Thu7imWC1B7GvRQBAoGBAM9yA4EBjHSQ0sP5DTT4yD3H7ytQtR3oVZYcKiWg4lPETaFhwucFzbbhmh5gB6Xng71KiIuYuvJZi2XQeL2LcBBaZwoj9cpclJ53KuQ8LL5TPZ1zOn+xU/Iy2mumzVpaSyWcDq7ArlhuGq7JWubAEcrehBia7i26Ss9ro1HqbR+ZAoGBAO3UHnZz8gmkQrUyk6rTPJHivnow2O8nh2dWuK+o+wAN+WCF10VQVaRcUS2bC/khHeomTRNZh+kzs0woLdfEtLlxECA2+MHiIJmXkLat7/Bm8gByd9iWHRZ6d9ZRvb+DPwmbZV0mZoy+8SF5DJno0uFdq6g6tTGQKmQwu1xHeI4DAoGAOQubVxB79VoV+3ozXYvEVOj0Ji8tfynyzzKzjGFvm6Vxy508oZcA+PeVECFMOR0vJxCl9+1qC1cAdGEdstHzYSvbBfjZkGphHCqdCuJZU4VEflW/knnLIeFGGzBlbCFEZPVDPF8UEpFEmSgZ7TaILgd+v91q/fwqslthMBeNJpECgYEAzzNTyu1e/IlwWL8UqepZRdxfCMPP7CPrMtv6EYhODZEfJ7nTgB7qTkTjsLD5MHZqwpnV4rrIzyJs3jfPIMHOlhVr8DUUao5gyo+i05UciryVsFAKG9dExlWyXDVg9B4baHpLSGlxRMQB/qCgmuKd/xyFtg5X2DN6y0ktosrdvBMCgYABqwzMnDF2SPx1mZjXIOCsj/03Oya75E8ZTWGorkROhyarE1wWvES472IGsZSM7qchABmVVGxr09mL0nyNA5KIIEoIWtl59yplXKrunYYoodoXtaS0whTDraf62am98IQ1LAUdf4p1dGfkrAsf8stKuxbzYtEeXQH3EHzzLOzmNg== - - peerId: 12D3KooWE5VmEXLSksS31fWjwydNgoH9c1hMWdMdohKk1mHVVgwC + signingKey: bqnCY+BB93A2nTM59zyP1CGZg5seSIeoGM/ATCOMy4+VvIfB1kwEK2VM5QVx3ub8zV/kqND8xuuQCC2NIrAFxw== + encryptionKey: MIIEowIBAAKCAQEAxaNDIGlEwkYRtcw6eoM1wRReJJUgHbEPTGSazEHTIp9Vza0Ob5GqT0yTFbWQWec1+vfCCVj49Z0usKiIa78iViiZxN/EZtdbimM2b2LTOPPkHTBNM3KawuBtVd34CYOLyFFhc+m4dtquGTsOGC0q2YQlS/XF+vGNWO/j8LnriF47Vv3Vr2YDfYeLo3aMexjzLKDiL1TC8fxtcSHqwrJnhgkFEHV/BIadPBlCpVukTPPMusEaoMshHVViS2emStf7j7Iq6KDdbIMGRCTAKhLNMOnHDwmDlBo/RSS/iYtEXFEADDfiYPOeIKIExPnAfdbku5I1y3/IaxeSpk+jQDFfMQIDAQABAoIBACLEgsWL3z2x5+GsaMkuleE+fQVAeqLeiAtvU1AFcGgR0Z1aCUUVQfmrReC2zQsTwopA1ZChZ0KGATWwoDccK6UuhUZ9+uYAkqj4pRXZM8E8HnAIFDytt436vyEw6DZ8PrXhoxwqDHpUI/ZqTiNwpq4XMhx3wvlPTwdLRDUP7+BQK7EmmZLZPiU+oq7f8Fo3ag2gkRKakatPIjwKRDSXcLNW+Rz2YrxUOAdEir2KiK0CKYAkqmcZy/O1xBjQ0YgQpYgxgBXRHTgd5iIFjGG/bCIHsLyV+FkpMpgO7oFw0aJa6zISFeoZ3Zekpf0qqSQNrI+Tpc3uStSE8/95nIo+fxUCgYEAxuvt8VRl1W16ddYpGAFO7ytTdzFSg4e07rKPLvZbvQ4M21CASluNPPKn/S9KFaLZDagBM2jl2cjGYdHVfVlVu/fmM8nlTCIhxkjU9iHkyspJWXNxzUcnh12GEjcNb1i7Oc1QTof7HFjEG4TrsRmGdAee4ZjXYyIEPAHCgxAdc7sCgYEA/lkGdggdLfw6HkXceLaiuq8FA7asJ0JK7L5XCptAXZ9ci10oQuwC+58S8eFVkOUmnVwFovc7CF5EtWjUkSdI+AIL3WCnj2Xjm/S/ASNL1Urw7Q7A7QKu0kGawadUQ00/oSRApEC3f3XK0rdkRlryp8mj2WRfUyBEjh+NgLzgzAMCgYBHQK1Le3K6n2t1GBBCM/3FN9y+3iDzUkHiGn2lUcOMlaLPUCeT+vU9dqHr0+uSknFzLdG4S4PBneRJl7MEImLOYL7JoDENM1CryNzXiU59wTXC39JMuIcVOs/SaHvcfYka7EsuxhCRl84vGU6fckgx+aTUpD3KmZ2wrOSys6wJDwKBgC+VrjzE1di1mJXzUgUPfjBY8CI6uch6gZP7JEOqugcJ+oFkQ1UJ3KEAqMWx95UtGeVUwwUzJcsx/77ExwgFBoTHtTqMi6yrTkLuLhHjbZuQ8rQXD4cH+ncBqRdT29Lfj+jw5FsWdH4XJoP3pX34I++6LLpOKfteTRUd2BZev9vLAoGBAL24XaIkqAECCqdGLiID3PEIRLGacnjEoAqS7fT5A8CV0Cle1KKZzkJlJvxU/pzSgp5AjI1TwIiH4jYE/Xtc2+61Kx1C7jqK5tNK4lJ3BkHUY9d1Etr+HdnDZYKZ32XdGfh4nUU7dx+OI965oQJISsLVVmu2GBllsbg6sA+w3LnK + - peerId: 12D3KooWJ2259GQZxf1PBkLBR8J37QN4PMiLedBU9h5PNbUwfaXE address: 127.0.0.1:4432 - signingKey: BI+SqqwurrTaNCHtc9+DeItlNPh6/6gH9CrJwNXS6Ug/TwwRHloM7siXqOWvJVRUiJ8UCraYjuAnB4huLdby4w== - encryptionKey: MIIEowIBAAKCAQEAtyliO0Y/M1RHRNCRl5D+x337CVbv/Yhn5bF0+Ib5h72JDtewRLKWcqCxmNa0RhmSbUHIlO7itf9a9k8FBlQOg6SlVgRk5xET1FpGioS+yHsaiwx+KbCgP6QeDSMNLVKW/+WPXItvvZxoQV9m9TywGJzzMBF9QY3rWhMGV1s58S0PvIjficyORbMTZL2aKlcPjf8Mh/Yzo0eiPTR8+sKvguxonhUdEGfpts1Wn0rIr+BQhk9hto8okOeQkEy1LO8cHyVpk0Zm2jIq643CRd0qcfpOYGm+xz9nzEjCWZJdc/Bq5Vok03mi5050fv6nA/HcopBUnk5Jk5jLQEa/0rEXuwIDAQABAoIBADZuYfbjhVynqxZUNTApss1uLvAzmdZqdxXXir9gvT8NoHF8v7FqsTMXdi/JfoFmkBFP/1/jLhSP8mRIT2H2EOomP8w0OhhBBveQbG41zMyfaN/xsnyJNNY024lj5UKWzLD3c4c5GNfsZz8mLt6qTlrCKbMbP3H/zvVRugyz26BEFzXnXVsRo57MXwGPHzhMS2bdYsixuNz6Hwlu3brJkIgzQA740ABVzVG75DRwvdJ1w+kIskrlCa7tFnHl/mVaBQ0plFaY4Urjk3fOI6JzHA8I92FBWYinKPlBXBBeXp/vjsfsp60d5zi1/bdNqvMFL7HbwQO7yJd37UR0bV+1lIECgYEA1XhV18EICpxHQwm0svmvnE8MVUHEzzSlpXYZujQis6x0tXOdXEVqfh8EzSmBlJLj64ndIG13gVVeBIJszXTBLCgoUxrH1JXtECu47jIB2X9QPEaicfpnUlXcbNFS7RQIbyS1yvbKKmK9lJOA6TMtjMVmQ8zpAtivqhsc4LDI6RECgYEA26c4t/CHiqYb31CYsUDNQeL6yor1K6pfyshJ7xO2fvFj3+7H5Q5sVk4bN0btS2pird/WDlfgH7AroCbyxtCEcsnXr3gOywA5I27Jy2UAFmajC9CUvIBINdhKuEAG4Pckn0aDBamBuU/DG145NA2mXBMQQ9MsObNioGC2LVA91AsCgYAIjbPS21c5JZ3tX7wv17Vjq/8wg1wheViR0rOhNGmXjXd3tdQ+WEG2IAQPPHSGwYQEche8Lua09fi4cYluihkbbdh/y/jp2cAP/9B/Kt3MGz/ZynLD4ma1c99LNO//s+fKnEv0gAMFw8MY6vglX/mZRGeem91SUeBoDoIPtsW2IQKBgQCPAk/GSn8lAUNSYNoZRbSduhdIubIoTNPzZfXlB3OhMK6zBHb3Ji3Y/x9vHOmwWUKILBzk18ffOccdjV4xnV8ukUWxQ7x15N5OuHn/x/GHpClxrsq389mP3RPA5EbWP3KDlNgHXrZMHadM8UrTHjP67JqBXkMECkwjWPQjioPGwwKBgGBWi7axhF2Sk+SPSWKVQTTOwbpRhyDj/qzLDB836u9fCo5xYmlbXp/YtiHlk37FbRNfw90qN35tqD10dOKDmGbvm+tJxoRZpmH0w1ExGVr1KBXIp4D2jTyjHPaHEdvJEsWG5wNJcOd8gFuki/m4bafFh7iJMizvYkM8bVNV2Ctm - - peerId: 12D3KooWB2Xvsa8RrmdhcBTJMoogqPu43tWZ3XUwXMowcCuMjHjo + signingKey: RHl/cHYoPtAGXgJl7F3upI2OAnD4hd9aJztiqo08w/V52b3qKvFr2TWnpbNvBlXSxeyXpo4WB1jH+pMslW0irQ== + encryptionKey: MIIEpAIBAAKCAQEA2vHQaQ5U/PzvNFTk3G9t/IMELaxM5OBFV0/HcjDnF3jtc/ADtqG4zsr/VCs7/tiXiEIxn5aMFrvS7APh2/EHLlAnyrjYLyyxvgwqUtV06Gf5K2V7HmFTLch7VFc5HckU4Zg1B61EYAtnWu5JTmsZAmP1v3afsnfpdwTA3LEH65oOyEAXqCeNUtrrwZXYnt77gk1zC0NSdtE4Hf25OJ5to0kckmQf+TMxj5seA5+u55Bg/Hd9sorFl0X0JrAkIxnVcWYt9lCNZk4frPHl1deX9BwOJ5KKrz1Af/617rl8b8H5F+KzkHXpgpJfxtMLWUnUuaX7qm+R3qe1HeMCIAmOLQIDAQABAoIBAGPVHT25/kC5KG1JRG3LFXCtYOtehFVceeG9C+liqQzH5CYYS+krxrPsVg5QBHRI2JeV70CgidIX5K4few4p0ido/yvtqw2fqJBKxcWtdTg/qJsEE+afZCkdIDct6mpNdQsEtzF/7QyKRp9sxdpO9UFkyPp7oYfkK31MmpBG3KCtb57dyIKqfBoIrp9E54X+MtHHQsqpVo7wgdSufUAWA5OtrebqrUGhWrZCRVT5l+BbPp5WliTN12jVU3jdA6rkUzrdyt5jyZQZ1eIm89mBi3wQod3arUx+DnXeICroyWW7eumXqvPdYO9Y2eaGpXY9sjXioGARi97vD/qCB9qB/sECgYEA8L169WaUBfPU6qlD+qZN1Be6PprjBqoTYu3clQikYhF1HGcXT4ri1/8CT8gf9QsUt2NHzNf0vkhyqJ3bD+mxG/c62C7ff4mhLRR2MRiDnqFaYKJL4snFG6eachD7IqgXEJ8Uw8s+LUqljhMa3NlXgDyCdrazVto/J3iDx6/B2/ECgYEA6NKniFEFrJBEVr7neEsMzKSuu8S7VT8bZGNY5yLIHM7+E1YeyJko1BtaQ2f+x9nnRzRPpjO5H+oVLeRWj496retGmvQ24K6VPCq8b7I9QUdYOvhzgo+go6sCM4dzfespIi932EAHGFA0frZ29o9W9a8rgFZUoigde9KAYxVLQf0CgYEAlfUBfZFLDTYoX4/WV3B2NHIfQlYKqqEQeGRALdl3Q9sp/uo8fADActlXIElBlsszOVSvaervegP44A2MYiood4oV7omsEG6zpjgDs2tYuVw6xszxxi/3BtXs/7aSKLFZxLHDJn8YmO/RlmFSL1V3CtsmTTpbFfPWuQh51c4mTJECgYBQEhqR9CN6bIdEOhWLNmxpeP2rEAbJU5HNHam2nCysU7fn2Idvv9Td1aZeZkamXtd+kowOAd3aDvxHsy7d4p9zbuXyZqj07rXeYmg6FdehOrMqXMYFEfZSM37nT981YAneeurBkYufHf5f0crqEvP6PMs+MPKcbiVtr0B+UxV11QKBgQCmNz/q1pPxEltFBOZmsyfmplKgeDyexB8nb0z1NNc00tpKtWL+hvLqGQwYnECJ7kcJDNetKM1J6rDCoLg6hObf/Ze6/BFXTZF8bM6Xqz1elQPYgHl5P+vlJ7yVI5FClVG8RgI73vxr67CZk+4zsZbvTLscaZ1ZPkPR9m+YMJWUrA== + - peerId: 12D3KooWNJdqtKLZAxT3szMrWoSLS1F1JkyKgJ4YQ1rAKfeVPMm6 address: 127.0.0.1:4530 - signingKey: zsY2jhPHbfMKIKfXGh+PsNBhCLD//dmJtBNMhG3m1OIR+bF4a7B5Wid8eBRm6vtCbOJzoxhJZjRYk1vEHuhmgg== - encryptionKey: MIIEpQIBAAKCAQEA4mbDvFUlpfiRkfnW22C0XvpAfB0m1G7vGcDWfNfgMmf8xD1rknWAGNZi2Ek3rjt9uVuL3DnlLEjGf0HrhsNm/VUI3nId72zgqTZd8fHbA+6h2ba9wP1t+IUf456k41bgljD09HxpvEKtHO1OWQGnVFMc5gqMeM7uovZS+NbXvG5RJoVgG/Ugw6BgEmj0e0LDmvvn2FRvmzst77EPQKlp43J4Vl0n7OtvBypLd/KA0dtB3Nl5rjcewFpSbUadhzJMnw38mtj/jwJsvvwUnzKuv6O6ZK1uqW8bFXKN5OmP8gw+EkZo/GX5IuyHdQwjYWKTAuWn/bYXbwsXAqYEtEW+XQIDAQABAoIBADCbC27FgP2u7eG/F6eljVPOukVrJMj6wA5xXhsTZaistpGS9iNNYqDydeolXfTkBMvkoZQ4QcFOJn9vsZcPIG9G8E6BhXe/kkQBzg2BdRnVA55wIzDpt9BhFEWT66Z7ImBcRlqu0yx9zBinwehN+JSb+1pP7XSKSKVn6MxPo6VqSlP4xRN8rQrq8sVvIt1eVH01rxhGBRM/gpoPtIXlf9cYRoa/49c1/Hk3YmE+oYG+oWzoBIsIDS8qEKfEzIrHTB8d0DmLW38xInTqwNgcp6GpoK9mDBhPcb6vZpd0uWx8pwqJ4cYQTJ/ksOrq67T6yyMaJn8WRJflg1taFD9ONoECgYEA9B7LsEXHRMzEAM1YKqxoiOm8UVfv+qdsLUBoeJb81fdgb8YjXq0KhD7+hGhfCogIWuCygXOYCd8srzZxlkSCK3S2F6R5xlsZY7TwSd2LvH4821T8dX/h+mYoe7dbrE2PjWuZL9PwSOLGfEYS7BS7vwl3Qd58sF5/hVX2Rg9V4tECgYEA7Ws7CEt3ic3i7YuzAdaw22WOHGETwb9cV5cwKRnvbhpIcU9fQa291+kIhgV6TaJuAmUJbnB3jwRYG3wEurRodlh8g6HYyCFzB9ZjKuG4av1wlLw8pTSMngH7Vlsy+OiItQhUSB14AUAD9+d4mq5P2uPm0aqw8qbU8Z4tZ6Xyjc0CgYEA4ULRfdTFrcytSHgzVR1GUKAt73mPreFzxsXaIPxiTiY4zKsu1Bwkyic+wHt2x8cCvqj8zssVjnZrSzqX0ath2iuWI3bYD5rccM7zs5VFbiemjFV9qAbbRS2jSZXGd9YSEtMoxaNx5C+uK9qVd1cib4OSkit1L2HjleveloNsIyECgYEA25APR9yC8C43bveC1HB3nm6MvjII02TlQRvQrjIN+wTTefatYVAMAWDBQTBPqvxMQGqwDjJ0Xw7lbIWE2iV9dfTfMdy7XlmQx+68Ryv4IPnA48wxSZcPdBDhHzu4J/jkdIb/arHWCVHqWZj3MBWERCn/jGcOvVkMFWbzFqehaQECgYEAl9saSHtsYYbhEX/PMLbecJtJU2WEOkML0QpyZyzF3Y0FnWpjlY4HV5RUsEOksAjbaAxbF7Xk8NZCjmqdR6+WdHt+3CQl+964vkvBIGWYXyo5/zso5HxzTpZTN8I03Xk09nMfn72lPKq6dWRD1EVBPX0TfOzg1xL7ftng7BR+bx0= + signingKey: BwEWqy5XqOeEUy4BmMzv1WltI5TvLPfP2l2mtioxb+a5ijq4aSATKZSFfcm2hpbGDObWOzeyi06BarLOfQsTnQ== + encryptionKey: MIIEpQIBAAKCAQEA2sTIJSgwRRwPVINYyC5lHtZGsBth87wV+mwMVHkt1/Er8WVstudDFj7dvpO4wHE9vzOQi8+VobNT+xZSB1hlLbOuyBMDzdg+0vs1rMmYruKWb12VZ4+ir1xhnqpm5sKhPuPylZFp+m2GuyEeMHjUNnbQDgPSxkh9jNnTnlwG86h8r5BlhbiISZUs0Jh+IiAbgf55xTdYp0UmVREJYpmk8SBOQS4HfkWM7ih85zMrA0lzi6bfghN7CSABpAMYSgLJc9XeP3le8iMSKQsT+RRvXgUAniPT7ftbWg0tZMNjJ9CXF12Mp0ElC95UIwOnJJydgrLMLvQ0Lggie/WdN0PpCwIDAQABAoIBAQCvg37bqLGJUKjP8gzxlZ9VLS5LLbzZUgYEAlmmEA6CmB/cLLYay9Fb8JXwxw1Lf869Ln6CXMm8kGYJJPAsqnOKRgUsyWyc4igNFrQKazbO4EU3Fcq+6lLoA+Lh6+5gpre9AB5oduCipOqaCUjyNI51H79t7w1UPWZU8ZHBFC4TnpanTYTqyYwUThqDR/PExyV7mhYN5gEi3cg4W0cA7qlDaGgwaKBrMphRt2xwNlAlYAhdkwdgRmbnB/zrWb0FHqJAsz6biqqNh0N0EgIsF0ZMO0ZFGRt+Ou36500Z1cRpGurbO1zrpNV2R2Gg0Ssun2tfjoYJN22HqwwLY71s/xXRAoGBAOx5KeiD07zkRCUzfVa9oHd9CxFSpStz0mCauFDpW0nhzgonjSaOmEotGvVRLDF1eqbtji2QOx3WSPXdnNlncyYAsWFJMyupygqsxBxnVBX3yFFicOE6PCaZocwDVmdKNNfg/52U13qS4pxFFclUPHlVvEcovR1VAPP08MvyV4x5AoGBAOzVW7FmVgzAUc9E8ro6pXD4dFyNkE6Hasq5ApQzFbqcaHSUjbS2lF5dKhvur4OABy6XO/wgD78b/bC+vMryxC+yHm4FP+ANpQ+/DSrn+g2X80J0wqC2tIIVqYMOzn3L+gSfRnhW+28vEx5SSofa7aZl/NOoXtXD47amJELwYzijAoGAVH9vJDCG5oZCe3CMpwQXZNr/q272qjI2yGJA3likUCApuaMsYsytSkQXz/Tzb7Dk5OUZ2tog5aZ+Z6yKsXyvvrKcr4CykjWXhnz5jpS1jSv/HmWopDJk7/4RvI6svzfa7hDuBeb7oEcARorBIDHDci/amSrLeMG5F3M84AN2mTECgYEAvx+PV6JWXwP1AWeK2m7phDl87hPwGO9/ZwnW4vI23tnKEgqwMN4G7gARM2lzipOPODIj3luhWYClQjUq9jzjxfngRLlHyvA3/HUZkz6RtNajIUZIqpnHIhOJMJKKYUpzAbfnjsXjMt6ydw3Bx9ENZ/N2DPkbTzc+VO/O45ZK/DECgYEAvhovek7Jk4ZmC1OsxedqudrgQugNGTMnc6gFZR/CUXrtBs1vq4zKe003Nx5WPGaYooySVraSgBplamtsL+dUsVRqWjCyuUrSkuv7XtP6rdSuRJEHTs7vumnGsF2pp+I08W1Bg0zUFToGy0PqFX9pVeR1f63COI4Ca1Vy6+BIw1Q= isConsensus: true - - peerId: 12D3KooWHSSHxDymTrGQjTHSATFxWnnz4incxYazKukgBia3xPAm + - peerId: 12D3KooWP2cwtzkokAGAr8UzdW1pmU4NS2D4dvHJtK2q75TBEeKq address: 127.0.0.1:4531 - signingKey: uN55hCvFWVBlFcptEca/PlCJBVvMPmCvB9WnWHHGMftxP2GGPEVntjpeS2aRrcHvfvf0WfjAP47CQdr+V8yD5g== - encryptionKey: MIIEowIBAAKCAQEAuQvwreiIbcoASka0Be0nvdQfU/ZGzIjONzfHCaGWqIfxjqsIG2I55X+3j8kIZZBl+oMIGzk3amZq1KWNGKsRhuDdsHKSaSAnFqPIYYfiAkp5evsBCFzWkMaB2xelDkNzYGAyTemvsnjyp3wlJjrdoJrwW5kNojz84B0NQZjn81O8BH1HOibzXIoO65oBduWGwj5zaqboEe33VFowxRJxXG+RHnOCY4XRoZ40wx32t4LefsDcMbfaNaYEt7av5uzkh/+X9AWNw6VmYKimVv2KAyYwJ5Q+ZkCyASPO9ShBdMfaiR1hETQExVPtBQB3876e0IzW/+j5o1WGu1KPk1t2kwIDAQABAoIBAHvnHM61hrRMr4kMcnoNY7DdmeR0YM+PQtUCSgmO4vwRmpK2voTnbnDW5agnKbInz8C/f+wKkapyzVF5UFKWKPQxGP+Ol65AUyv7mq6Dd7ek+lZ4PybEUv85i7WRzXkRfO2pO8WjlXthNMkkfRNuEvv5AruybciWIZRGn5uusJDh+rMI382z6b00/U7r0igj4g5o1KqT1wYxba2VT4CaSeqNEMbdOcGWDjHx7zIanHvMrRtRG4DgYIY11ohnARU8UUI/wL5WG9iVaeuepq8T1G3vLt+096UwE/GYIhwQ0UUf+HS4HviACcMWJeXbKas64twtUA0Pf0JFCxPnM/QTBtECgYEA0Zpurv8M2P/atqODGG2teKseJqz4nB9vYLbAQfpziv0OyvRQ26r72pjtBwIDxv67fVSL3/HlViBGElMGycrA/XZ1cTiXY2LAcfpnu2P/Q7vUE/n5NBg4C1Cqjgb7D4dFXOTOM182HFL5SSQiUv5jMRvqxZTX5NcxBj3wbuHt0v0CgYEA4gH1755EWtS6q8+UUdLNAM+TL1SKaMcfiGAMdMWL5uSJBQ28fFPZIZv14gTzaU+Zji3AsGXiBpgtwor4rEugmX+nL7FATIaS0rh15hjXEvczg0SyZBkiXygo9WSQFQ/1AuHmQ8dNgNHXuSv9VbQeu52xhr74saii2tCzTOfyDM8CgYBQHA4hpCls5pzZITWBqKmcbQphDcsXIIyZEj/495ghjwaQW0BsNLV9nuU4wHRhIgrWo/Gx7eoRONSPPFxj07JfLV9FnrN9sMiMx3/OBzIQ2UD9QZUVbAw/ht0o21IpZTIFhw2oZMNxn+TXJ5BW2BNhOaJJUdISDI0YLaQvPPqAoQKBgQCBXY/xtYz41PV47NvALkKL6UUdfW2wZfIltJzMplrbMgtAKkmufKw3sbb/xceyiw6hNI0sK1VCYw8mYTfQH4Xw9wGyqendI9ac6VsK90L8pyUESWk3JK/o+erf880JUVX0bWvJdiZlyzeI1aYvzWceCziXoW5m+tklGPrY1ZdWPwKBgEYm3cThyIi1MScjR7lBKPKUKfkmN88ZoNnzfcn1Mgzwpo9alTycyT9otC/wBGIf4WhRmDoCYE7htIA0C0j8YlmYhd8+gEuRnWFn8Gx8ecpSmUIIpZINeV/t9YFSbod6OnYJosxwLJGzHpb6FN4ojpO5lq7iPWN4v/dtd/p/Bfoi + signingKey: RyKkgbAlAmo+suhJf1mYau3uneQD93XO9Dks/a8lpXDES5wfPb3dO/8oefEFllI+c/m3bTVkAYBdTHtCZq7lYA== + encryptionKey: MIIEowIBAAKCAQEA6Dhjs/8s/uiTFIopCjoYLTq8JGIM3otbUktYXSnqpBVVUU4TwSJonpyeRCgcYy9FlDWrUPfCNEv/kG6ruNUZQs2UuPbaOMZ1Z5TZRokwZF26rlkmaTlwJLKmKy0wwT9koZT/e5G4NkRO4rOLK/O4NyDlZ/HvWaZPxQtcC4en0CDaaIcDSSKaL5OMz0fcXayQlWKiOsuuP7cSUYlBDybbJPLSPMVYUjGjzIBqZkV6nBgjKGIIBGlknqZpRwX1mgq4vG0UYTfGCOFF1iHQ4TiLM2EiiZw203PVA4ifSyvkZOkMngItBfYcnD5MRYtLXlps2LWW6auN6olAkyUwFQeHLwIDAQABAoIBAGq7kEfo3xuCdieYoOhMb1RKjLMERfn7f0vByal4XJpyG7a09itszz0nqy6UaQfFcGuAh289kQtMavhNhav8dhHYP6UMAJzbypaDOaJL5+wZkHYWD6uJdNvJKMrriF8p7ey+ePaosUxv9PoJn8vhxye/fPFbp7FC2aMtZ279OMpVjyhbBekWlHfAnRbmDaFjMH+7wHfaAArpYsmRaOJ+/ckqhHSWSCXHO7dOyTcRNx4J0NoZ+192J6VsD1bbGxfHEgtVac/3+fj0Uia3mjkA+e9+oe7kfiGAheLs7G+kC0rEht1VLkviwjM0oCPd3zcu50HjqSrQ1q+i4vKJLrPWQFECgYEA8Uz+PlwghCWcJ7c+TYL1Y4UpYMXavRYi+XCHyn5x2PtxLDgK9j38CbLtIJFDY739RxEDLsOAkC3ba5p71EAx2ZF8i4ylmw0ekTe8BhEo/PHhCmLL+12zUrDbmUqsb1/NJBRDVZ9975nqWiT1KWqm3XKrwfBRTvgiP3+dC3XrtiMCgYEA9l3KBUK0oc6RWftNQTbehrwMuG0M4wv05peTHHqlMsYV0b5nKCr1FWU+gA4zhEDNPcs7PkZRl+HHMalkKH/aLpxeafN5a4PkMsQD6ZK5Mz88IENzXbFswBjCI8s5NyAAK+aI4JqXiRoia6fRnWVp+VrC4A1o2dvD6GaZAta3bYUCgYALFhF8RflMePnirT2UjBbAGsca5hw1ocW7lhr3B7YtVOgPMwf15kUlIO5aF7Jz66+uSy7NQDgw55p0KCXWS5i+uTtyoeSd6g1keJ4P3Uv3yxkexAlBJD3v56Y/NboUZ99h7/hj/67mijjFKXuGCpteAz227Faf/TB9oFxTwXgx5wKBgEMOeCRCacP445soSXjMpHjrylKQbAeIg5oX+5Su1TQismGqf41xU9AFBKP6OY9vy+1b2b4ziZXbgEpGHtrfIdW5/gC8onnfJkejDqWOqBYIyibF9Sq1VjJbCsyPTf1xGlrYnrzzlvdcQ64luWor5lJWn+A4Bif2JzakZlVdeAO5AoGBAMynKpkB8vqTLU31yt5SzBroQj8TgZKGbzB2apO1a+2XE8WfmtFOxnS1/iQ67sMkv6Rh/N5SUxMnBLXjsYJFpuNkKjvE+RqO9f4PzklTIJuT49pexheAMKBA9zWv5YPEmMV8xGbqXooSuEP0ixlM07DiqaC7aBzSyIfGdTOvI5w/ isConsensus: true - - peerId: 12D3KooWCm6fXRReUtpD4bQyy3EnzEe7htRGCAvzHw5yewb1SbRS + - peerId: 12D3KooWMg5c9wHkuXQ48qyHVa72UKerKWAVZRC2dc1ibSadYxTQ address: 127.0.0.1:4532 - signingKey: 31nl1dejInkuEbwBf7NyEp7t6adkMOyCMMzq9ub+XQgrvMnFxeIOso/c38RWo08lSMpZLltC2yS88/EkNIWveQ== - encryptionKey: MIIEowIBAAKCAQEA3dSgJsWNz3zusneGYIjufkXe4byl+RGZNE2dUWEwPqlsjyFXLFmBQwU6UMAOvgEGLuNY2HWVLKzWsqccLqkMjEo3ZQSTft1kf3x3TFlFpPFtGI0lL59b37K3zJ6sdY65PPskhXqy4ru/oTjJh4F13qE40x9bVSrmVnllrEzlyG2kR7KOiHWmufChtvTHA6Nv4x8sevsKzwIXOMMdbKb67aw6jWic94gI8lf+KN7UHYAMKA5MvwwvvH4hadUubMH810jtpiD720dkKRYkgLviLuxhOhRn+s2UY+Dl9vDplBO5tfn0ZnU77q0OrF1qAhwPiuy0yq08ykhL4NrKiLjGdwIDAQABAoIBAHQjxlWGSODBABfgDDKufm8OFcsKAbuNQzDnEd5xi9jCy1uEkSdfFRYJvqZYZ1+DGcGitfleVmO1ehK++zpSt4cbtDTnWHGrZ9p3R95pPtVEsWGRRE7SmD9eSmyPBqvltYX/1vcrbkzXD1VRbfHMDfIpZp7iY+cLNt0/YcP73rI3+4U+4DXsPmaf4jtCBpUH0ru59aCJTJWvYFiVsapWdJY+BcAerpV7QH74dVQ3XNIWRCxsG4+S9cfi5uuenHqM3MmCz8jOpTQeepg64aSNmFsTVEeoNXfQ+78ELUIXEWBpDoWWNVTQxoy3edPThuDgEbw0KHP+z6C63ztP552kB0ECgYEA9pKCvigZyrbn/gmFha0FVEfGWkv8SGHkm3LctnOHj3fyfezKmp1bq44bBFhw+p12qN6NmpZIpMh91X/vDcmNJTAQz9ty14pB0Dlq/egV/AffjtUjYb4UzxiV3EmH97BB9rK9B4VkSdPY1FbOtAEyt6cWoYTUwwrHKzTbhOhAn2sCgYEA5k/wU0uN57BwXrcDNP10zkjxbpsoNEINBj+eGpKjZaKXU7XkgoezgzeGa04Ym6crLxmhlXtSojXFkqeLdhn5hJSKPJ+JsAZD9gM0iZ9Hb8l9/opzlSEJzMFLyCdCeu+9Hipq3OuGkJgRemn9h9UMih1zUTo2RwRdfpLvUEUANCUCgYB90AQmQw/l/64gUXtv2fj+KCFtsZfo1wpuxw0Xi5t/+RQibNB0VBaSUtA2R2pedjo1sFlQp54pdqO+bKjtwAnlD8GETdUrZcBvHt0Y8XNGRj4sA1UqanLzuPe+j0Zxe94soscRL18czJu2vRR7hKD8VKWXhM+LNdSqly3rgxZ2QQKBgFJ6okhSMHmeuD9TLzTU5/XQLZY8voMofF2WftppVVbaiXMTGsicLG97fQoEp89maJKvjSxpQ8iPlTfWBJ3A45jVUUQwpjCBrej2cOQwRHcGI7b6gjYP5OCNAMSnOqmoHYQmEKsZNdGmg+vg9UilxZ3YuimGvVVlfM4NdOK8Mzx5AoGBAKKtLvw/rpL+ZLSlO5CTycjBlY8Uy0/SkTI9T/gvwPm7zMdZW0AN7HShsus6SKATba7ZXIySY+tBWfuq9oEACzvC20Qw9tQUTS90g8mwHwTcj4H58cnvmbtOFg75RYMUYvcOjpbPLvcGKsYrobjzqv9MrrL41fgMXw8DVIomqQbP + signingKey: gSyxSnCL8NsewJmdFwgVpjQ2hDwDvrbZrLnA1007ymCwLN67/Xd/42q4vsvZAovsXBrv4PuWuoQUqmXhX7OJrw== + encryptionKey: MIIEowIBAAKCAQEAptyiobOzgLUuVfUQetYQD638+kOUAjf+V7uny+9Qhtt0LZM5v4lsJ8DK+NIbJU6fo9sMNJ8Mc2A7QNEZ6iyppI4zszUIMfF9Ixhew8g5zBlaDzieAf1XSGuEd89vj1ikM3Nhp8AXzxxoFOTsgUCMlnAzsHalcVyqXRzN/glAA1Ob6R0pIEIz4LchvMpnjhSLi5XEmBMy3b3XHu+T5nYyLzLxxMpO2fHH41/GpWmOEVrjoT1qP1JSv+ehuXiuMW0rM1833os6jMHCZijfDGh8blWI2nthjOLbr/KQKQhkIqOXKwdkVLY5x4/c78L8dV3eZ647SqurWC/N8kr5r4LvfwIDAQABAoIBABTPHSUHURJzBeVIW5bGDVi3PP5E4Tdpnjl4uJNRM/ytb46jdqcxTyCiBW4EXchIRtZbYelKEHZvANSzfwTaLwnLhh0KNwxrbkyrJF5MIREX9EhDqkjbPEBW0D1UzDfXORsFf5848H8urrg0WF5CG4ZDVd7i3P0HLmPQTMwqgSYo2pLexcj0LtiZZqJ6ta9kxAiJniZyoNshRJnAZMMnFYRhy/eDF+L6sJPHieYgwiQFU5e0CK9UgsLmmOQWCKWtPgvxOhqlbcTz1pJAqkyzOC0wK/ydJpVAh9RUqf46rEDFzL/l90ZOir3AMlYJIHf4PX0TWchXjFW7bbHn5Zvk1xECgYEAzpuGDfaerUl8QziD6F/OoIz1/EZwSumErCH2NXYMBcCyzKu4fBqVqj5tcLsNx42v6kAGaERAQqaC5ZZ9ZNhXiWasHAermQqv8DtlYVCUih4e87dX1/xTF5TzR8RhLwHPADd1rRafCKJMD9X6Qquer5LmSST8ej3mJ4mrflw837cCgYEAzsCoqFenGlCvAZoQrekxS1VmGJDCKBQ7LlbOwQaUkD4I23rjbAHG8J51jmaQQ4epm6lU0JLSma/LKp8dl9oDEP09vcgKj6xuHMZV+EmsA5c181zMrGoH+tSZiWQZjSmJVhd5T147vnbUunTbGKlOQByD0tWM913Dm2dqB3goXnkCgYBZax4dtPr/7KoHPdJ5I939xoQ/5wx6n454IUq54JlbdAbuZfO2Ypsbz2D2RT61ezEDpSogvklBj2dfjj4/AxL/uJwMlZVC60kyI8LA12syS88Bk/xE0kP0FNcl3GxjN9krMtWPUBcMWZGp2OYzLKvFOULJrWRIU7nkqsS6L5l5CQKBgBa/tg8HzfgkRo1LkWhBT041sE0lqGdWioh3vroYakJQwRK9O8bHj0cseEzZ1ifIBo59HDry3L9SS21+Inhx4YJ+CswV9auHUnpSDGWMXaPrgGEtpcuWwxgDSn2GiRUyK81QOeXUvYggdRmq/+x/vH9rY8nP+3nAVGSGBXGa8/4pAoGBAMB7EOk/RnsgQ+SotHbvgv18S0lbJuWsLYGnNp8EcuPxDIxz29fOFH94qzVOwAkk5cbHvAl3/5sl3SelmKM9LXhcOT+1zxoavyAYyVeAGZsrbBmbzj9yeZON0gHtpF3dMWxiguyWuiiHM/pL92gKzlyIXryC3andL/y8/6VpWbtt isConsensus: true space: gcTTL: 60 syncPeriod: 10 +storage: + path: db diff --git a/etc/configs/node3.yml b/etc/configs/node3.yml index 3b77fd1d..9b19e294 100755 --- a/etc/configs/node3.yml +++ b/etc/configs/node3.yml @@ -5,39 +5,41 @@ grpcServer: - 127.0.0.1:4432 tls: false account: - peerId: 12D3KooWE5VmEXLSksS31fWjwydNgoH9c1hMWdMdohKk1mHVVgwC - signingKey: BI+SqqwurrTaNCHtc9+DeItlNPh6/6gH9CrJwNXS6Ug/TwwRHloM7siXqOWvJVRUiJ8UCraYjuAnB4huLdby4w== - encryptionKey: MIIEowIBAAKCAQEAtyliO0Y/M1RHRNCRl5D+x337CVbv/Yhn5bF0+Ib5h72JDtewRLKWcqCxmNa0RhmSbUHIlO7itf9a9k8FBlQOg6SlVgRk5xET1FpGioS+yHsaiwx+KbCgP6QeDSMNLVKW/+WPXItvvZxoQV9m9TywGJzzMBF9QY3rWhMGV1s58S0PvIjficyORbMTZL2aKlcPjf8Mh/Yzo0eiPTR8+sKvguxonhUdEGfpts1Wn0rIr+BQhk9hto8okOeQkEy1LO8cHyVpk0Zm2jIq643CRd0qcfpOYGm+xz9nzEjCWZJdc/Bq5Vok03mi5050fv6nA/HcopBUnk5Jk5jLQEa/0rEXuwIDAQABAoIBADZuYfbjhVynqxZUNTApss1uLvAzmdZqdxXXir9gvT8NoHF8v7FqsTMXdi/JfoFmkBFP/1/jLhSP8mRIT2H2EOomP8w0OhhBBveQbG41zMyfaN/xsnyJNNY024lj5UKWzLD3c4c5GNfsZz8mLt6qTlrCKbMbP3H/zvVRugyz26BEFzXnXVsRo57MXwGPHzhMS2bdYsixuNz6Hwlu3brJkIgzQA740ABVzVG75DRwvdJ1w+kIskrlCa7tFnHl/mVaBQ0plFaY4Urjk3fOI6JzHA8I92FBWYinKPlBXBBeXp/vjsfsp60d5zi1/bdNqvMFL7HbwQO7yJd37UR0bV+1lIECgYEA1XhV18EICpxHQwm0svmvnE8MVUHEzzSlpXYZujQis6x0tXOdXEVqfh8EzSmBlJLj64ndIG13gVVeBIJszXTBLCgoUxrH1JXtECu47jIB2X9QPEaicfpnUlXcbNFS7RQIbyS1yvbKKmK9lJOA6TMtjMVmQ8zpAtivqhsc4LDI6RECgYEA26c4t/CHiqYb31CYsUDNQeL6yor1K6pfyshJ7xO2fvFj3+7H5Q5sVk4bN0btS2pird/WDlfgH7AroCbyxtCEcsnXr3gOywA5I27Jy2UAFmajC9CUvIBINdhKuEAG4Pckn0aDBamBuU/DG145NA2mXBMQQ9MsObNioGC2LVA91AsCgYAIjbPS21c5JZ3tX7wv17Vjq/8wg1wheViR0rOhNGmXjXd3tdQ+WEG2IAQPPHSGwYQEche8Lua09fi4cYluihkbbdh/y/jp2cAP/9B/Kt3MGz/ZynLD4ma1c99LNO//s+fKnEv0gAMFw8MY6vglX/mZRGeem91SUeBoDoIPtsW2IQKBgQCPAk/GSn8lAUNSYNoZRbSduhdIubIoTNPzZfXlB3OhMK6zBHb3Ji3Y/x9vHOmwWUKILBzk18ffOccdjV4xnV8ukUWxQ7x15N5OuHn/x/GHpClxrsq389mP3RPA5EbWP3KDlNgHXrZMHadM8UrTHjP67JqBXkMECkwjWPQjioPGwwKBgGBWi7axhF2Sk+SPSWKVQTTOwbpRhyDj/qzLDB836u9fCo5xYmlbXp/YtiHlk37FbRNfw90qN35tqD10dOKDmGbvm+tJxoRZpmH0w1ExGVr1KBXIp4D2jTyjHPaHEdvJEsWG5wNJcOd8gFuki/m4bafFh7iJMizvYkM8bVNV2Ctm + peerId: 12D3KooWJ2259GQZxf1PBkLBR8J37QN4PMiLedBU9h5PNbUwfaXE + signingKey: RHl/cHYoPtAGXgJl7F3upI2OAnD4hd9aJztiqo08w/V52b3qKvFr2TWnpbNvBlXSxeyXpo4WB1jH+pMslW0irQ== + encryptionKey: MIIEpAIBAAKCAQEA2vHQaQ5U/PzvNFTk3G9t/IMELaxM5OBFV0/HcjDnF3jtc/ADtqG4zsr/VCs7/tiXiEIxn5aMFrvS7APh2/EHLlAnyrjYLyyxvgwqUtV06Gf5K2V7HmFTLch7VFc5HckU4Zg1B61EYAtnWu5JTmsZAmP1v3afsnfpdwTA3LEH65oOyEAXqCeNUtrrwZXYnt77gk1zC0NSdtE4Hf25OJ5to0kckmQf+TMxj5seA5+u55Bg/Hd9sorFl0X0JrAkIxnVcWYt9lCNZk4frPHl1deX9BwOJ5KKrz1Af/617rl8b8H5F+KzkHXpgpJfxtMLWUnUuaX7qm+R3qe1HeMCIAmOLQIDAQABAoIBAGPVHT25/kC5KG1JRG3LFXCtYOtehFVceeG9C+liqQzH5CYYS+krxrPsVg5QBHRI2JeV70CgidIX5K4few4p0ido/yvtqw2fqJBKxcWtdTg/qJsEE+afZCkdIDct6mpNdQsEtzF/7QyKRp9sxdpO9UFkyPp7oYfkK31MmpBG3KCtb57dyIKqfBoIrp9E54X+MtHHQsqpVo7wgdSufUAWA5OtrebqrUGhWrZCRVT5l+BbPp5WliTN12jVU3jdA6rkUzrdyt5jyZQZ1eIm89mBi3wQod3arUx+DnXeICroyWW7eumXqvPdYO9Y2eaGpXY9sjXioGARi97vD/qCB9qB/sECgYEA8L169WaUBfPU6qlD+qZN1Be6PprjBqoTYu3clQikYhF1HGcXT4ri1/8CT8gf9QsUt2NHzNf0vkhyqJ3bD+mxG/c62C7ff4mhLRR2MRiDnqFaYKJL4snFG6eachD7IqgXEJ8Uw8s+LUqljhMa3NlXgDyCdrazVto/J3iDx6/B2/ECgYEA6NKniFEFrJBEVr7neEsMzKSuu8S7VT8bZGNY5yLIHM7+E1YeyJko1BtaQ2f+x9nnRzRPpjO5H+oVLeRWj496retGmvQ24K6VPCq8b7I9QUdYOvhzgo+go6sCM4dzfespIi932EAHGFA0frZ29o9W9a8rgFZUoigde9KAYxVLQf0CgYEAlfUBfZFLDTYoX4/WV3B2NHIfQlYKqqEQeGRALdl3Q9sp/uo8fADActlXIElBlsszOVSvaervegP44A2MYiood4oV7omsEG6zpjgDs2tYuVw6xszxxi/3BtXs/7aSKLFZxLHDJn8YmO/RlmFSL1V3CtsmTTpbFfPWuQh51c4mTJECgYBQEhqR9CN6bIdEOhWLNmxpeP2rEAbJU5HNHam2nCysU7fn2Idvv9Td1aZeZkamXtd+kowOAd3aDvxHsy7d4p9zbuXyZqj07rXeYmg6FdehOrMqXMYFEfZSM37nT981YAneeurBkYufHf5f0crqEvP6PMs+MPKcbiVtr0B+UxV11QKBgQCmNz/q1pPxEltFBOZmsyfmplKgeDyexB8nb0z1NNc00tpKtWL+hvLqGQwYnECJ7kcJDNetKM1J6rDCoLg6hObf/Ze6/BFXTZF8bM6Xqz1elQPYgHl5P+vlJ7yVI5FClVG8RgI73vxr67CZk+4zsZbvTLscaZ1ZPkPR9m+YMJWUrA== apiServer: port: "8082" nodes: - - peerId: 12D3KooWBZFSp1MrqdQgL2uWSZpybgskz7mjrJnmhkDjudSpTUAN + - peerId: 12D3KooWNGRznbh4RCYY1hDnG1RLCtWviWwVnZGjKHtsXVgPckNk address: 127.0.0.1:4430 - signingKey: JR142BFc9/KJIy0f0BCnfMeO4Yv9InErltCuGyhvs+4Z2A9c9cGi20ECMzthOvtr90N6bq4iyfLbmhNkVMxgiw== - encryptionKey: MIIEpAIBAAKCAQEAt9WEjnITHiG0IhGdn5sGBR32Bo8qwAEZSsPhutQZnvBfTegqQwvb5LxxpfYP4C2+Wy1335fzMGtjtWyv4r2bJHX++fTh0h8xWbuMuqDlbZI79IkAhu4HFfAl6a0Ay/po4DkaBBwqHFu1oPbzKceJpb1fXXXDNO4SIMBo1CYrrI9ipJrVb0NOIbmuDUUvS6c7W8xiIudLH+lrcClpsE4f6+rVaEK188cWESmFvTFwWd0LV+1B+qP28pVRGZDcqMEeV2CoICY0daKdI9P1efPD1XbQGmafU0LlJZyww1pXT5q0yKBSdKMjspZoRbScnUmTJuhZY29cBPfqPjRiEvznjQIDAQABAoIBAQCQlI4PVepxPUKltMMKHutKJPk0yW5u2a5hndMvk9aeqR/bbuemGXKU4Bxl0TNFNdTLcuQfZystfphJvLRMGKEmuOKTBaSBFGVE1Htm4Fnwph0fQoy2kgfimh/HO3gv9L588ovihaAc84fSk8ZEqpk4T8rr/01KmJ6LQahwiaC5sig3uZgQuCGIz11xjNgavHdpytzL3qGhUPLiQAJtCEKaiFuUAEmw+dg/KH0ZHw3+/yCJ/GESwR/8yP6rfuyuLyaR1n4vr/+eH56x4922ua2XtJuz6gdqzcbPjbf2y01Q2XnwEkf6cHO6rYs+ba8BWzM8NZUeTmvLH+qY4CAMWIvBAoGBAPHuResocGdoZEDNvjUpuZlWCCRKO7goTAjFH00z6DEG0Kv37pi53/4AHshaScHLd7kQUBSH8o6Fdtf+fyZaVKdQzfSKqNVt6NglPtVTd7JhI2ddJuU6iOMBKowRk+PYnjfxjETmXMNb6FpF9ZgMc/QC6YiWZwEjooFKrhgfZWvxAoGBAMKGVY1LAoLUFwdL7DsBSf+VndN0l/ApxVjCLhT4l73HrfOEqbts0GAGRTtOA6JO2xhAvtJkcUYbStQiKyz4iPC+zG9CwMm9XNaGRAflFfcxgy1VqMQ/2TnlrwXdCLi1y+oEGcJs69O8IQACBC1m6MfEMrOOsAa3YExkxG7VBMFdAoGAIAgBH9pxz28l3uKerWFB3ohieZOOhppnPr4Cn/Ega+VQGYSxBW2Ot42ChdpWa58p0cnUIHPDbJVFH+HlKcnJ7YEoU5lMMz3jF0MPJ6VucqKj0lql/LGcUBnmbTcikocqo5OKk9DANWlkwRcEJkZ3z7XW/6uSJbd3G5EsraryfbECgYEAnaa1i09xd4pgJ3+2spN233bodEmYIgIYeLjXFBPtFtfP+P5ZeRbVQh2S2l99vnteQaenf2f8Da9s08Plbgr3IPXhRYK6MEYSCaLDXAqj5LTx9TnpDzQX3z5wvLXIrbpYyw4LunEAJ5fevtzjedBfdBdkZ/WKX8caeo9oS9LEidkCgYA9Lf6XK52LDO3uidnX7CZB9piWIV5bzrdJB6ppbJ2ywAD60NF8yecRp7fnyFRg7VCQxGkbIbv5sR9Ua/PAsBo9UFlZQGanUXpAUJi8qnDIDG2Ly6uNTwjF7s3IHC6OIn1aOSvUcgY658sXF1KfDguXv0CUs75JZ5+1djdMQAtRiQ== - - peerId: 12D3KooWHTnHZgeyDdZJwrXweFHMrSF7YBXSuuAH9GsxhbzTvfcT + signingKey: buHKTg4VF6lskoFWDdjtjWNj2c/fz0zAxKrOW05pRRu4+aw/tClrubW5wpeCOJxPSMHJBTj/8bJ8icwKfe7yMQ== + encryptionKey: MIIEpAIBAAKCAQEAtoc/5YBUSzPUISHv/COa2wTeWpsuxuLGOd+IYLXe8xXIry0GHCqCN7orZq5iz7BFs2i6o0ttK2PpRa5xz/GnKtTkQowmfDNwh/f+jIlMo+CcL54Qq4sURexChBCg6z3XbSQK1C9yGA4QaNFRDgSzAs1IC8BCRFf7XDbK06zxWw/As7D3Bo1V3TO0LWi/URkV1PBZdQxX6unt5VplhTQ92o22xczb15zfBQW59qEZYyPa2apwUfmhZgjoAbSOIQm96U7P+HrLa8va1h9q9o+eYefco2N7wv40MYsDXll09Tfc/VhDEfmuKfwmSe5AEnpsg1gD94fX/4KVt7Usb7u6gwIDAQABAoIBAC7POqS5p2Rt0z33/RqVavY2JmvoFjPtHlbjK49ZtOZ0NLYv/rwkbqap+M1pdW+7zfQ3rH2KL2IMSluTZB6m428Jj8w9MvVxH6/O+pnB8ESqqoNPrwi/LyDLeTdzKEGL535W2uwVitX+bVjkLTxCGkJisNJKqPPr+EtqxdNJK9BlJ9VdOLFLi67mOsu3F6AtDtBC3VFXZJa8Wbocu0A7hm8QWa23AL7+EZdV9kJ8Dw2qEYXyYRwmhExuZWNsPsnMvNhlCj8By9IPuICDzW87SfcsIQd7vjSg3y60mmGvl9WGxJbpEkSa+MxCA175k3E30KP1tYMOBQyhlCr7qRYWpdkCgYEA4a7CJGqtdMB8KByzrfGazm8koI0Y+qcriYaOWeoZayoxshwmemqJQTEP29D5SumxOcobKnKRHhKBhhlJenc5xNwppgMIgexZtLLAB2pZzLZ/bIy39T+lAEVOQWIEWDUQ0MwqaGNvaZ2bXyM1Xq6Bovurs8gSwmRIQspskeD/fy8CgYEAzwxpLa/W+BcRPH7VpLSkwSPgsAXW+TCoxWuCMj/W7MmCplyohW8a8wc42RFwKCH4ULpyNbv0VWdCM910/U1sf+0s7B3+IeW/0oMlLIPOd/Z39Legm+h0o1l3rD7deWdL7AMnaJIJsMBOUp0DRBSE5Bj6iUr1MnIEMX/3zFqdxO0CgYEAo4FSZMHpA3JFQWZyAy7M4o0Bc1RmaYrd7xhOX/RMECkUsh7U/dHbuSCLhc1kH5Mp9F1pyxoP60KrFnWRl6lzcB22CvGdo0uSPmlW2MiDYN5DeWiGCqfeqlCL/rC9xw5DLZMNkm2gFVu7anT+wKcbgvJlFq54cN/ovoMbn6DsWr8CgYEAgUVIbgP5fdA5LMIr9bfrncMeyAf9XnwpA4nKMkF1mUV/UwtLFHR4KQB7V9vxYL1E4nJmWHJPbPsZdHRyVKyAb6bPg2R+hP+DMpY7IX3x7ShvYNU9a9pI6Kw1cc+WS/RYjLSzaDC16CtJO39YyKrfBeMqmYm5aZOSVq2FM4voMUkCgYBudtWqqwKvA/Ig32hPBa/pqh+R11LeN8F/NsjrCA3geo8MlDqD0To+r9FTv14AksR7BsAfhoGglbvpddTL+CqHgtA4igNWp2/UCaomfnCgnFl/rvo+OGiVR5DgaC4ALw9onsdfeNgrQ5PkqCCi2crb3txdRWGA2QyGvsBmb1u8+A== + - peerId: 12D3KooWKtsepiMYrDtok7AU4itPcmHQaLuwzzfYYyjEW1KoLeXp address: 127.0.0.1:4431 - signingKey: EVlWc7+UbqSKAvjSdBq5iZt2dpcCYhDJiWkSn2+9IrJxl5F5dTHw+eIKNV3MV/tL8ext3YPRkIue/8TvUUfpaA== - encryptionKey: MIIEpAIBAAKCAQEAwLhwWK4vZQooUjulblf4I2+f5/K9yES7/HW+1bz93ZOeeiMuKb5wmw1tVt+vrY2j5cFC/krhSWUdfRwqDvv6Z0q19v9mD7zIfad54KgVSyMcVGxWLt7haGVCr78VckO5JD+aktlEM8/12crzHOWRh+j3jgELmwSwA/LiXo2ZNH9x1Vftw5MHKksWTpvaAprFTkYUrPHvrjpiuSGzT5abGUYOgWUIzTtqZYra+zOMPzVqDAlMykmUYjVO/d/l01L3xgLZQogZ9B3NRgXpTpTJ5iF7UtUejjZSJ6fYGVNwM/TEMrIhKHD54I6FYkLmp+7Rsw2MmxVXHkQPQJ7khYY8ywIDAQABAoIBAQCv97idQG6GE4A9lbi3yBsKQCIB5+LhueDr45ccEjS63M8XNogwFXM8IEZ1zEjcbzf30T8accTC/1Ctq8m7ZNh+9/iuTwUh2X43PXRLbS4ELUrwyvrmURv/9nWtgwxSCQRD1M+OxlM/++K/uk/BUtxO/KkNQGcYZG9TK7MGIsSA6Ua0fNEo+hcTzqBsED3nGYXwmn7nX4zMjPqr6TtQfpxWdwtKYbBsDcvIoigwNPajnsdSbx2M4pZh3cwBuROKs9/HpUNOtSZvPc8BbRenJQOqXG2R+O6SMBGnYf5ycHpk7Wya+1TtGObOAcrgC7RV6y3KGzq0Thu7imWC1B7GvRQBAoGBAM9yA4EBjHSQ0sP5DTT4yD3H7ytQtR3oVZYcKiWg4lPETaFhwucFzbbhmh5gB6Xng71KiIuYuvJZi2XQeL2LcBBaZwoj9cpclJ53KuQ8LL5TPZ1zOn+xU/Iy2mumzVpaSyWcDq7ArlhuGq7JWubAEcrehBia7i26Ss9ro1HqbR+ZAoGBAO3UHnZz8gmkQrUyk6rTPJHivnow2O8nh2dWuK+o+wAN+WCF10VQVaRcUS2bC/khHeomTRNZh+kzs0woLdfEtLlxECA2+MHiIJmXkLat7/Bm8gByd9iWHRZ6d9ZRvb+DPwmbZV0mZoy+8SF5DJno0uFdq6g6tTGQKmQwu1xHeI4DAoGAOQubVxB79VoV+3ozXYvEVOj0Ji8tfynyzzKzjGFvm6Vxy508oZcA+PeVECFMOR0vJxCl9+1qC1cAdGEdstHzYSvbBfjZkGphHCqdCuJZU4VEflW/knnLIeFGGzBlbCFEZPVDPF8UEpFEmSgZ7TaILgd+v91q/fwqslthMBeNJpECgYEAzzNTyu1e/IlwWL8UqepZRdxfCMPP7CPrMtv6EYhODZEfJ7nTgB7qTkTjsLD5MHZqwpnV4rrIzyJs3jfPIMHOlhVr8DUUao5gyo+i05UciryVsFAKG9dExlWyXDVg9B4baHpLSGlxRMQB/qCgmuKd/xyFtg5X2DN6y0ktosrdvBMCgYABqwzMnDF2SPx1mZjXIOCsj/03Oya75E8ZTWGorkROhyarE1wWvES472IGsZSM7qchABmVVGxr09mL0nyNA5KIIEoIWtl59yplXKrunYYoodoXtaS0whTDraf62am98IQ1LAUdf4p1dGfkrAsf8stKuxbzYtEeXQH3EHzzLOzmNg== - - peerId: 12D3KooWE5VmEXLSksS31fWjwydNgoH9c1hMWdMdohKk1mHVVgwC + signingKey: bqnCY+BB93A2nTM59zyP1CGZg5seSIeoGM/ATCOMy4+VvIfB1kwEK2VM5QVx3ub8zV/kqND8xuuQCC2NIrAFxw== + encryptionKey: MIIEowIBAAKCAQEAxaNDIGlEwkYRtcw6eoM1wRReJJUgHbEPTGSazEHTIp9Vza0Ob5GqT0yTFbWQWec1+vfCCVj49Z0usKiIa78iViiZxN/EZtdbimM2b2LTOPPkHTBNM3KawuBtVd34CYOLyFFhc+m4dtquGTsOGC0q2YQlS/XF+vGNWO/j8LnriF47Vv3Vr2YDfYeLo3aMexjzLKDiL1TC8fxtcSHqwrJnhgkFEHV/BIadPBlCpVukTPPMusEaoMshHVViS2emStf7j7Iq6KDdbIMGRCTAKhLNMOnHDwmDlBo/RSS/iYtEXFEADDfiYPOeIKIExPnAfdbku5I1y3/IaxeSpk+jQDFfMQIDAQABAoIBACLEgsWL3z2x5+GsaMkuleE+fQVAeqLeiAtvU1AFcGgR0Z1aCUUVQfmrReC2zQsTwopA1ZChZ0KGATWwoDccK6UuhUZ9+uYAkqj4pRXZM8E8HnAIFDytt436vyEw6DZ8PrXhoxwqDHpUI/ZqTiNwpq4XMhx3wvlPTwdLRDUP7+BQK7EmmZLZPiU+oq7f8Fo3ag2gkRKakatPIjwKRDSXcLNW+Rz2YrxUOAdEir2KiK0CKYAkqmcZy/O1xBjQ0YgQpYgxgBXRHTgd5iIFjGG/bCIHsLyV+FkpMpgO7oFw0aJa6zISFeoZ3Zekpf0qqSQNrI+Tpc3uStSE8/95nIo+fxUCgYEAxuvt8VRl1W16ddYpGAFO7ytTdzFSg4e07rKPLvZbvQ4M21CASluNPPKn/S9KFaLZDagBM2jl2cjGYdHVfVlVu/fmM8nlTCIhxkjU9iHkyspJWXNxzUcnh12GEjcNb1i7Oc1QTof7HFjEG4TrsRmGdAee4ZjXYyIEPAHCgxAdc7sCgYEA/lkGdggdLfw6HkXceLaiuq8FA7asJ0JK7L5XCptAXZ9ci10oQuwC+58S8eFVkOUmnVwFovc7CF5EtWjUkSdI+AIL3WCnj2Xjm/S/ASNL1Urw7Q7A7QKu0kGawadUQ00/oSRApEC3f3XK0rdkRlryp8mj2WRfUyBEjh+NgLzgzAMCgYBHQK1Le3K6n2t1GBBCM/3FN9y+3iDzUkHiGn2lUcOMlaLPUCeT+vU9dqHr0+uSknFzLdG4S4PBneRJl7MEImLOYL7JoDENM1CryNzXiU59wTXC39JMuIcVOs/SaHvcfYka7EsuxhCRl84vGU6fckgx+aTUpD3KmZ2wrOSys6wJDwKBgC+VrjzE1di1mJXzUgUPfjBY8CI6uch6gZP7JEOqugcJ+oFkQ1UJ3KEAqMWx95UtGeVUwwUzJcsx/77ExwgFBoTHtTqMi6yrTkLuLhHjbZuQ8rQXD4cH+ncBqRdT29Lfj+jw5FsWdH4XJoP3pX34I++6LLpOKfteTRUd2BZev9vLAoGBAL24XaIkqAECCqdGLiID3PEIRLGacnjEoAqS7fT5A8CV0Cle1KKZzkJlJvxU/pzSgp5AjI1TwIiH4jYE/Xtc2+61Kx1C7jqK5tNK4lJ3BkHUY9d1Etr+HdnDZYKZ32XdGfh4nUU7dx+OI965oQJISsLVVmu2GBllsbg6sA+w3LnK + - peerId: 12D3KooWJ2259GQZxf1PBkLBR8J37QN4PMiLedBU9h5PNbUwfaXE address: 127.0.0.1:4432 - signingKey: BI+SqqwurrTaNCHtc9+DeItlNPh6/6gH9CrJwNXS6Ug/TwwRHloM7siXqOWvJVRUiJ8UCraYjuAnB4huLdby4w== - encryptionKey: MIIEowIBAAKCAQEAtyliO0Y/M1RHRNCRl5D+x337CVbv/Yhn5bF0+Ib5h72JDtewRLKWcqCxmNa0RhmSbUHIlO7itf9a9k8FBlQOg6SlVgRk5xET1FpGioS+yHsaiwx+KbCgP6QeDSMNLVKW/+WPXItvvZxoQV9m9TywGJzzMBF9QY3rWhMGV1s58S0PvIjficyORbMTZL2aKlcPjf8Mh/Yzo0eiPTR8+sKvguxonhUdEGfpts1Wn0rIr+BQhk9hto8okOeQkEy1LO8cHyVpk0Zm2jIq643CRd0qcfpOYGm+xz9nzEjCWZJdc/Bq5Vok03mi5050fv6nA/HcopBUnk5Jk5jLQEa/0rEXuwIDAQABAoIBADZuYfbjhVynqxZUNTApss1uLvAzmdZqdxXXir9gvT8NoHF8v7FqsTMXdi/JfoFmkBFP/1/jLhSP8mRIT2H2EOomP8w0OhhBBveQbG41zMyfaN/xsnyJNNY024lj5UKWzLD3c4c5GNfsZz8mLt6qTlrCKbMbP3H/zvVRugyz26BEFzXnXVsRo57MXwGPHzhMS2bdYsixuNz6Hwlu3brJkIgzQA740ABVzVG75DRwvdJ1w+kIskrlCa7tFnHl/mVaBQ0plFaY4Urjk3fOI6JzHA8I92FBWYinKPlBXBBeXp/vjsfsp60d5zi1/bdNqvMFL7HbwQO7yJd37UR0bV+1lIECgYEA1XhV18EICpxHQwm0svmvnE8MVUHEzzSlpXYZujQis6x0tXOdXEVqfh8EzSmBlJLj64ndIG13gVVeBIJszXTBLCgoUxrH1JXtECu47jIB2X9QPEaicfpnUlXcbNFS7RQIbyS1yvbKKmK9lJOA6TMtjMVmQ8zpAtivqhsc4LDI6RECgYEA26c4t/CHiqYb31CYsUDNQeL6yor1K6pfyshJ7xO2fvFj3+7H5Q5sVk4bN0btS2pird/WDlfgH7AroCbyxtCEcsnXr3gOywA5I27Jy2UAFmajC9CUvIBINdhKuEAG4Pckn0aDBamBuU/DG145NA2mXBMQQ9MsObNioGC2LVA91AsCgYAIjbPS21c5JZ3tX7wv17Vjq/8wg1wheViR0rOhNGmXjXd3tdQ+WEG2IAQPPHSGwYQEche8Lua09fi4cYluihkbbdh/y/jp2cAP/9B/Kt3MGz/ZynLD4ma1c99LNO//s+fKnEv0gAMFw8MY6vglX/mZRGeem91SUeBoDoIPtsW2IQKBgQCPAk/GSn8lAUNSYNoZRbSduhdIubIoTNPzZfXlB3OhMK6zBHb3Ji3Y/x9vHOmwWUKILBzk18ffOccdjV4xnV8ukUWxQ7x15N5OuHn/x/GHpClxrsq389mP3RPA5EbWP3KDlNgHXrZMHadM8UrTHjP67JqBXkMECkwjWPQjioPGwwKBgGBWi7axhF2Sk+SPSWKVQTTOwbpRhyDj/qzLDB836u9fCo5xYmlbXp/YtiHlk37FbRNfw90qN35tqD10dOKDmGbvm+tJxoRZpmH0w1ExGVr1KBXIp4D2jTyjHPaHEdvJEsWG5wNJcOd8gFuki/m4bafFh7iJMizvYkM8bVNV2Ctm - - peerId: 12D3KooWB2Xvsa8RrmdhcBTJMoogqPu43tWZ3XUwXMowcCuMjHjo + signingKey: RHl/cHYoPtAGXgJl7F3upI2OAnD4hd9aJztiqo08w/V52b3qKvFr2TWnpbNvBlXSxeyXpo4WB1jH+pMslW0irQ== + encryptionKey: MIIEpAIBAAKCAQEA2vHQaQ5U/PzvNFTk3G9t/IMELaxM5OBFV0/HcjDnF3jtc/ADtqG4zsr/VCs7/tiXiEIxn5aMFrvS7APh2/EHLlAnyrjYLyyxvgwqUtV06Gf5K2V7HmFTLch7VFc5HckU4Zg1B61EYAtnWu5JTmsZAmP1v3afsnfpdwTA3LEH65oOyEAXqCeNUtrrwZXYnt77gk1zC0NSdtE4Hf25OJ5to0kckmQf+TMxj5seA5+u55Bg/Hd9sorFl0X0JrAkIxnVcWYt9lCNZk4frPHl1deX9BwOJ5KKrz1Af/617rl8b8H5F+KzkHXpgpJfxtMLWUnUuaX7qm+R3qe1HeMCIAmOLQIDAQABAoIBAGPVHT25/kC5KG1JRG3LFXCtYOtehFVceeG9C+liqQzH5CYYS+krxrPsVg5QBHRI2JeV70CgidIX5K4few4p0ido/yvtqw2fqJBKxcWtdTg/qJsEE+afZCkdIDct6mpNdQsEtzF/7QyKRp9sxdpO9UFkyPp7oYfkK31MmpBG3KCtb57dyIKqfBoIrp9E54X+MtHHQsqpVo7wgdSufUAWA5OtrebqrUGhWrZCRVT5l+BbPp5WliTN12jVU3jdA6rkUzrdyt5jyZQZ1eIm89mBi3wQod3arUx+DnXeICroyWW7eumXqvPdYO9Y2eaGpXY9sjXioGARi97vD/qCB9qB/sECgYEA8L169WaUBfPU6qlD+qZN1Be6PprjBqoTYu3clQikYhF1HGcXT4ri1/8CT8gf9QsUt2NHzNf0vkhyqJ3bD+mxG/c62C7ff4mhLRR2MRiDnqFaYKJL4snFG6eachD7IqgXEJ8Uw8s+LUqljhMa3NlXgDyCdrazVto/J3iDx6/B2/ECgYEA6NKniFEFrJBEVr7neEsMzKSuu8S7VT8bZGNY5yLIHM7+E1YeyJko1BtaQ2f+x9nnRzRPpjO5H+oVLeRWj496retGmvQ24K6VPCq8b7I9QUdYOvhzgo+go6sCM4dzfespIi932EAHGFA0frZ29o9W9a8rgFZUoigde9KAYxVLQf0CgYEAlfUBfZFLDTYoX4/WV3B2NHIfQlYKqqEQeGRALdl3Q9sp/uo8fADActlXIElBlsszOVSvaervegP44A2MYiood4oV7omsEG6zpjgDs2tYuVw6xszxxi/3BtXs/7aSKLFZxLHDJn8YmO/RlmFSL1V3CtsmTTpbFfPWuQh51c4mTJECgYBQEhqR9CN6bIdEOhWLNmxpeP2rEAbJU5HNHam2nCysU7fn2Idvv9Td1aZeZkamXtd+kowOAd3aDvxHsy7d4p9zbuXyZqj07rXeYmg6FdehOrMqXMYFEfZSM37nT981YAneeurBkYufHf5f0crqEvP6PMs+MPKcbiVtr0B+UxV11QKBgQCmNz/q1pPxEltFBOZmsyfmplKgeDyexB8nb0z1NNc00tpKtWL+hvLqGQwYnECJ7kcJDNetKM1J6rDCoLg6hObf/Ze6/BFXTZF8bM6Xqz1elQPYgHl5P+vlJ7yVI5FClVG8RgI73vxr67CZk+4zsZbvTLscaZ1ZPkPR9m+YMJWUrA== + - peerId: 12D3KooWNJdqtKLZAxT3szMrWoSLS1F1JkyKgJ4YQ1rAKfeVPMm6 address: 127.0.0.1:4530 - signingKey: zsY2jhPHbfMKIKfXGh+PsNBhCLD//dmJtBNMhG3m1OIR+bF4a7B5Wid8eBRm6vtCbOJzoxhJZjRYk1vEHuhmgg== - encryptionKey: MIIEpQIBAAKCAQEA4mbDvFUlpfiRkfnW22C0XvpAfB0m1G7vGcDWfNfgMmf8xD1rknWAGNZi2Ek3rjt9uVuL3DnlLEjGf0HrhsNm/VUI3nId72zgqTZd8fHbA+6h2ba9wP1t+IUf456k41bgljD09HxpvEKtHO1OWQGnVFMc5gqMeM7uovZS+NbXvG5RJoVgG/Ugw6BgEmj0e0LDmvvn2FRvmzst77EPQKlp43J4Vl0n7OtvBypLd/KA0dtB3Nl5rjcewFpSbUadhzJMnw38mtj/jwJsvvwUnzKuv6O6ZK1uqW8bFXKN5OmP8gw+EkZo/GX5IuyHdQwjYWKTAuWn/bYXbwsXAqYEtEW+XQIDAQABAoIBADCbC27FgP2u7eG/F6eljVPOukVrJMj6wA5xXhsTZaistpGS9iNNYqDydeolXfTkBMvkoZQ4QcFOJn9vsZcPIG9G8E6BhXe/kkQBzg2BdRnVA55wIzDpt9BhFEWT66Z7ImBcRlqu0yx9zBinwehN+JSb+1pP7XSKSKVn6MxPo6VqSlP4xRN8rQrq8sVvIt1eVH01rxhGBRM/gpoPtIXlf9cYRoa/49c1/Hk3YmE+oYG+oWzoBIsIDS8qEKfEzIrHTB8d0DmLW38xInTqwNgcp6GpoK9mDBhPcb6vZpd0uWx8pwqJ4cYQTJ/ksOrq67T6yyMaJn8WRJflg1taFD9ONoECgYEA9B7LsEXHRMzEAM1YKqxoiOm8UVfv+qdsLUBoeJb81fdgb8YjXq0KhD7+hGhfCogIWuCygXOYCd8srzZxlkSCK3S2F6R5xlsZY7TwSd2LvH4821T8dX/h+mYoe7dbrE2PjWuZL9PwSOLGfEYS7BS7vwl3Qd58sF5/hVX2Rg9V4tECgYEA7Ws7CEt3ic3i7YuzAdaw22WOHGETwb9cV5cwKRnvbhpIcU9fQa291+kIhgV6TaJuAmUJbnB3jwRYG3wEurRodlh8g6HYyCFzB9ZjKuG4av1wlLw8pTSMngH7Vlsy+OiItQhUSB14AUAD9+d4mq5P2uPm0aqw8qbU8Z4tZ6Xyjc0CgYEA4ULRfdTFrcytSHgzVR1GUKAt73mPreFzxsXaIPxiTiY4zKsu1Bwkyic+wHt2x8cCvqj8zssVjnZrSzqX0ath2iuWI3bYD5rccM7zs5VFbiemjFV9qAbbRS2jSZXGd9YSEtMoxaNx5C+uK9qVd1cib4OSkit1L2HjleveloNsIyECgYEA25APR9yC8C43bveC1HB3nm6MvjII02TlQRvQrjIN+wTTefatYVAMAWDBQTBPqvxMQGqwDjJ0Xw7lbIWE2iV9dfTfMdy7XlmQx+68Ryv4IPnA48wxSZcPdBDhHzu4J/jkdIb/arHWCVHqWZj3MBWERCn/jGcOvVkMFWbzFqehaQECgYEAl9saSHtsYYbhEX/PMLbecJtJU2WEOkML0QpyZyzF3Y0FnWpjlY4HV5RUsEOksAjbaAxbF7Xk8NZCjmqdR6+WdHt+3CQl+964vkvBIGWYXyo5/zso5HxzTpZTN8I03Xk09nMfn72lPKq6dWRD1EVBPX0TfOzg1xL7ftng7BR+bx0= + signingKey: BwEWqy5XqOeEUy4BmMzv1WltI5TvLPfP2l2mtioxb+a5ijq4aSATKZSFfcm2hpbGDObWOzeyi06BarLOfQsTnQ== + encryptionKey: MIIEpQIBAAKCAQEA2sTIJSgwRRwPVINYyC5lHtZGsBth87wV+mwMVHkt1/Er8WVstudDFj7dvpO4wHE9vzOQi8+VobNT+xZSB1hlLbOuyBMDzdg+0vs1rMmYruKWb12VZ4+ir1xhnqpm5sKhPuPylZFp+m2GuyEeMHjUNnbQDgPSxkh9jNnTnlwG86h8r5BlhbiISZUs0Jh+IiAbgf55xTdYp0UmVREJYpmk8SBOQS4HfkWM7ih85zMrA0lzi6bfghN7CSABpAMYSgLJc9XeP3le8iMSKQsT+RRvXgUAniPT7ftbWg0tZMNjJ9CXF12Mp0ElC95UIwOnJJydgrLMLvQ0Lggie/WdN0PpCwIDAQABAoIBAQCvg37bqLGJUKjP8gzxlZ9VLS5LLbzZUgYEAlmmEA6CmB/cLLYay9Fb8JXwxw1Lf869Ln6CXMm8kGYJJPAsqnOKRgUsyWyc4igNFrQKazbO4EU3Fcq+6lLoA+Lh6+5gpre9AB5oduCipOqaCUjyNI51H79t7w1UPWZU8ZHBFC4TnpanTYTqyYwUThqDR/PExyV7mhYN5gEi3cg4W0cA7qlDaGgwaKBrMphRt2xwNlAlYAhdkwdgRmbnB/zrWb0FHqJAsz6biqqNh0N0EgIsF0ZMO0ZFGRt+Ou36500Z1cRpGurbO1zrpNV2R2Gg0Ssun2tfjoYJN22HqwwLY71s/xXRAoGBAOx5KeiD07zkRCUzfVa9oHd9CxFSpStz0mCauFDpW0nhzgonjSaOmEotGvVRLDF1eqbtji2QOx3WSPXdnNlncyYAsWFJMyupygqsxBxnVBX3yFFicOE6PCaZocwDVmdKNNfg/52U13qS4pxFFclUPHlVvEcovR1VAPP08MvyV4x5AoGBAOzVW7FmVgzAUc9E8ro6pXD4dFyNkE6Hasq5ApQzFbqcaHSUjbS2lF5dKhvur4OABy6XO/wgD78b/bC+vMryxC+yHm4FP+ANpQ+/DSrn+g2X80J0wqC2tIIVqYMOzn3L+gSfRnhW+28vEx5SSofa7aZl/NOoXtXD47amJELwYzijAoGAVH9vJDCG5oZCe3CMpwQXZNr/q272qjI2yGJA3likUCApuaMsYsytSkQXz/Tzb7Dk5OUZ2tog5aZ+Z6yKsXyvvrKcr4CykjWXhnz5jpS1jSv/HmWopDJk7/4RvI6svzfa7hDuBeb7oEcARorBIDHDci/amSrLeMG5F3M84AN2mTECgYEAvx+PV6JWXwP1AWeK2m7phDl87hPwGO9/ZwnW4vI23tnKEgqwMN4G7gARM2lzipOPODIj3luhWYClQjUq9jzjxfngRLlHyvA3/HUZkz6RtNajIUZIqpnHIhOJMJKKYUpzAbfnjsXjMt6ydw3Bx9ENZ/N2DPkbTzc+VO/O45ZK/DECgYEAvhovek7Jk4ZmC1OsxedqudrgQugNGTMnc6gFZR/CUXrtBs1vq4zKe003Nx5WPGaYooySVraSgBplamtsL+dUsVRqWjCyuUrSkuv7XtP6rdSuRJEHTs7vumnGsF2pp+I08W1Bg0zUFToGy0PqFX9pVeR1f63COI4Ca1Vy6+BIw1Q= isConsensus: true - - peerId: 12D3KooWHSSHxDymTrGQjTHSATFxWnnz4incxYazKukgBia3xPAm + - peerId: 12D3KooWP2cwtzkokAGAr8UzdW1pmU4NS2D4dvHJtK2q75TBEeKq address: 127.0.0.1:4531 - signingKey: uN55hCvFWVBlFcptEca/PlCJBVvMPmCvB9WnWHHGMftxP2GGPEVntjpeS2aRrcHvfvf0WfjAP47CQdr+V8yD5g== - encryptionKey: MIIEowIBAAKCAQEAuQvwreiIbcoASka0Be0nvdQfU/ZGzIjONzfHCaGWqIfxjqsIG2I55X+3j8kIZZBl+oMIGzk3amZq1KWNGKsRhuDdsHKSaSAnFqPIYYfiAkp5evsBCFzWkMaB2xelDkNzYGAyTemvsnjyp3wlJjrdoJrwW5kNojz84B0NQZjn81O8BH1HOibzXIoO65oBduWGwj5zaqboEe33VFowxRJxXG+RHnOCY4XRoZ40wx32t4LefsDcMbfaNaYEt7av5uzkh/+X9AWNw6VmYKimVv2KAyYwJ5Q+ZkCyASPO9ShBdMfaiR1hETQExVPtBQB3876e0IzW/+j5o1WGu1KPk1t2kwIDAQABAoIBAHvnHM61hrRMr4kMcnoNY7DdmeR0YM+PQtUCSgmO4vwRmpK2voTnbnDW5agnKbInz8C/f+wKkapyzVF5UFKWKPQxGP+Ol65AUyv7mq6Dd7ek+lZ4PybEUv85i7WRzXkRfO2pO8WjlXthNMkkfRNuEvv5AruybciWIZRGn5uusJDh+rMI382z6b00/U7r0igj4g5o1KqT1wYxba2VT4CaSeqNEMbdOcGWDjHx7zIanHvMrRtRG4DgYIY11ohnARU8UUI/wL5WG9iVaeuepq8T1G3vLt+096UwE/GYIhwQ0UUf+HS4HviACcMWJeXbKas64twtUA0Pf0JFCxPnM/QTBtECgYEA0Zpurv8M2P/atqODGG2teKseJqz4nB9vYLbAQfpziv0OyvRQ26r72pjtBwIDxv67fVSL3/HlViBGElMGycrA/XZ1cTiXY2LAcfpnu2P/Q7vUE/n5NBg4C1Cqjgb7D4dFXOTOM182HFL5SSQiUv5jMRvqxZTX5NcxBj3wbuHt0v0CgYEA4gH1755EWtS6q8+UUdLNAM+TL1SKaMcfiGAMdMWL5uSJBQ28fFPZIZv14gTzaU+Zji3AsGXiBpgtwor4rEugmX+nL7FATIaS0rh15hjXEvczg0SyZBkiXygo9WSQFQ/1AuHmQ8dNgNHXuSv9VbQeu52xhr74saii2tCzTOfyDM8CgYBQHA4hpCls5pzZITWBqKmcbQphDcsXIIyZEj/495ghjwaQW0BsNLV9nuU4wHRhIgrWo/Gx7eoRONSPPFxj07JfLV9FnrN9sMiMx3/OBzIQ2UD9QZUVbAw/ht0o21IpZTIFhw2oZMNxn+TXJ5BW2BNhOaJJUdISDI0YLaQvPPqAoQKBgQCBXY/xtYz41PV47NvALkKL6UUdfW2wZfIltJzMplrbMgtAKkmufKw3sbb/xceyiw6hNI0sK1VCYw8mYTfQH4Xw9wGyqendI9ac6VsK90L8pyUESWk3JK/o+erf880JUVX0bWvJdiZlyzeI1aYvzWceCziXoW5m+tklGPrY1ZdWPwKBgEYm3cThyIi1MScjR7lBKPKUKfkmN88ZoNnzfcn1Mgzwpo9alTycyT9otC/wBGIf4WhRmDoCYE7htIA0C0j8YlmYhd8+gEuRnWFn8Gx8ecpSmUIIpZINeV/t9YFSbod6OnYJosxwLJGzHpb6FN4ojpO5lq7iPWN4v/dtd/p/Bfoi + signingKey: RyKkgbAlAmo+suhJf1mYau3uneQD93XO9Dks/a8lpXDES5wfPb3dO/8oefEFllI+c/m3bTVkAYBdTHtCZq7lYA== + encryptionKey: MIIEowIBAAKCAQEA6Dhjs/8s/uiTFIopCjoYLTq8JGIM3otbUktYXSnqpBVVUU4TwSJonpyeRCgcYy9FlDWrUPfCNEv/kG6ruNUZQs2UuPbaOMZ1Z5TZRokwZF26rlkmaTlwJLKmKy0wwT9koZT/e5G4NkRO4rOLK/O4NyDlZ/HvWaZPxQtcC4en0CDaaIcDSSKaL5OMz0fcXayQlWKiOsuuP7cSUYlBDybbJPLSPMVYUjGjzIBqZkV6nBgjKGIIBGlknqZpRwX1mgq4vG0UYTfGCOFF1iHQ4TiLM2EiiZw203PVA4ifSyvkZOkMngItBfYcnD5MRYtLXlps2LWW6auN6olAkyUwFQeHLwIDAQABAoIBAGq7kEfo3xuCdieYoOhMb1RKjLMERfn7f0vByal4XJpyG7a09itszz0nqy6UaQfFcGuAh289kQtMavhNhav8dhHYP6UMAJzbypaDOaJL5+wZkHYWD6uJdNvJKMrriF8p7ey+ePaosUxv9PoJn8vhxye/fPFbp7FC2aMtZ279OMpVjyhbBekWlHfAnRbmDaFjMH+7wHfaAArpYsmRaOJ+/ckqhHSWSCXHO7dOyTcRNx4J0NoZ+192J6VsD1bbGxfHEgtVac/3+fj0Uia3mjkA+e9+oe7kfiGAheLs7G+kC0rEht1VLkviwjM0oCPd3zcu50HjqSrQ1q+i4vKJLrPWQFECgYEA8Uz+PlwghCWcJ7c+TYL1Y4UpYMXavRYi+XCHyn5x2PtxLDgK9j38CbLtIJFDY739RxEDLsOAkC3ba5p71EAx2ZF8i4ylmw0ekTe8BhEo/PHhCmLL+12zUrDbmUqsb1/NJBRDVZ9975nqWiT1KWqm3XKrwfBRTvgiP3+dC3XrtiMCgYEA9l3KBUK0oc6RWftNQTbehrwMuG0M4wv05peTHHqlMsYV0b5nKCr1FWU+gA4zhEDNPcs7PkZRl+HHMalkKH/aLpxeafN5a4PkMsQD6ZK5Mz88IENzXbFswBjCI8s5NyAAK+aI4JqXiRoia6fRnWVp+VrC4A1o2dvD6GaZAta3bYUCgYALFhF8RflMePnirT2UjBbAGsca5hw1ocW7lhr3B7YtVOgPMwf15kUlIO5aF7Jz66+uSy7NQDgw55p0KCXWS5i+uTtyoeSd6g1keJ4P3Uv3yxkexAlBJD3v56Y/NboUZ99h7/hj/67mijjFKXuGCpteAz227Faf/TB9oFxTwXgx5wKBgEMOeCRCacP445soSXjMpHjrylKQbAeIg5oX+5Su1TQismGqf41xU9AFBKP6OY9vy+1b2b4ziZXbgEpGHtrfIdW5/gC8onnfJkejDqWOqBYIyibF9Sq1VjJbCsyPTf1xGlrYnrzzlvdcQ64luWor5lJWn+A4Bif2JzakZlVdeAO5AoGBAMynKpkB8vqTLU31yt5SzBroQj8TgZKGbzB2apO1a+2XE8WfmtFOxnS1/iQ67sMkv6Rh/N5SUxMnBLXjsYJFpuNkKjvE+RqO9f4PzklTIJuT49pexheAMKBA9zWv5YPEmMV8xGbqXooSuEP0ixlM07DiqaC7aBzSyIfGdTOvI5w/ isConsensus: true - - peerId: 12D3KooWCm6fXRReUtpD4bQyy3EnzEe7htRGCAvzHw5yewb1SbRS + - peerId: 12D3KooWMg5c9wHkuXQ48qyHVa72UKerKWAVZRC2dc1ibSadYxTQ address: 127.0.0.1:4532 - signingKey: 31nl1dejInkuEbwBf7NyEp7t6adkMOyCMMzq9ub+XQgrvMnFxeIOso/c38RWo08lSMpZLltC2yS88/EkNIWveQ== - encryptionKey: MIIEowIBAAKCAQEA3dSgJsWNz3zusneGYIjufkXe4byl+RGZNE2dUWEwPqlsjyFXLFmBQwU6UMAOvgEGLuNY2HWVLKzWsqccLqkMjEo3ZQSTft1kf3x3TFlFpPFtGI0lL59b37K3zJ6sdY65PPskhXqy4ru/oTjJh4F13qE40x9bVSrmVnllrEzlyG2kR7KOiHWmufChtvTHA6Nv4x8sevsKzwIXOMMdbKb67aw6jWic94gI8lf+KN7UHYAMKA5MvwwvvH4hadUubMH810jtpiD720dkKRYkgLviLuxhOhRn+s2UY+Dl9vDplBO5tfn0ZnU77q0OrF1qAhwPiuy0yq08ykhL4NrKiLjGdwIDAQABAoIBAHQjxlWGSODBABfgDDKufm8OFcsKAbuNQzDnEd5xi9jCy1uEkSdfFRYJvqZYZ1+DGcGitfleVmO1ehK++zpSt4cbtDTnWHGrZ9p3R95pPtVEsWGRRE7SmD9eSmyPBqvltYX/1vcrbkzXD1VRbfHMDfIpZp7iY+cLNt0/YcP73rI3+4U+4DXsPmaf4jtCBpUH0ru59aCJTJWvYFiVsapWdJY+BcAerpV7QH74dVQ3XNIWRCxsG4+S9cfi5uuenHqM3MmCz8jOpTQeepg64aSNmFsTVEeoNXfQ+78ELUIXEWBpDoWWNVTQxoy3edPThuDgEbw0KHP+z6C63ztP552kB0ECgYEA9pKCvigZyrbn/gmFha0FVEfGWkv8SGHkm3LctnOHj3fyfezKmp1bq44bBFhw+p12qN6NmpZIpMh91X/vDcmNJTAQz9ty14pB0Dlq/egV/AffjtUjYb4UzxiV3EmH97BB9rK9B4VkSdPY1FbOtAEyt6cWoYTUwwrHKzTbhOhAn2sCgYEA5k/wU0uN57BwXrcDNP10zkjxbpsoNEINBj+eGpKjZaKXU7XkgoezgzeGa04Ym6crLxmhlXtSojXFkqeLdhn5hJSKPJ+JsAZD9gM0iZ9Hb8l9/opzlSEJzMFLyCdCeu+9Hipq3OuGkJgRemn9h9UMih1zUTo2RwRdfpLvUEUANCUCgYB90AQmQw/l/64gUXtv2fj+KCFtsZfo1wpuxw0Xi5t/+RQibNB0VBaSUtA2R2pedjo1sFlQp54pdqO+bKjtwAnlD8GETdUrZcBvHt0Y8XNGRj4sA1UqanLzuPe+j0Zxe94soscRL18czJu2vRR7hKD8VKWXhM+LNdSqly3rgxZ2QQKBgFJ6okhSMHmeuD9TLzTU5/XQLZY8voMofF2WftppVVbaiXMTGsicLG97fQoEp89maJKvjSxpQ8iPlTfWBJ3A45jVUUQwpjCBrej2cOQwRHcGI7b6gjYP5OCNAMSnOqmoHYQmEKsZNdGmg+vg9UilxZ3YuimGvVVlfM4NdOK8Mzx5AoGBAKKtLvw/rpL+ZLSlO5CTycjBlY8Uy0/SkTI9T/gvwPm7zMdZW0AN7HShsus6SKATba7ZXIySY+tBWfuq9oEACzvC20Qw9tQUTS90g8mwHwTcj4H58cnvmbtOFg75RYMUYvcOjpbPLvcGKsYrobjzqv9MrrL41fgMXw8DVIomqQbP + signingKey: gSyxSnCL8NsewJmdFwgVpjQ2hDwDvrbZrLnA1007ymCwLN67/Xd/42q4vsvZAovsXBrv4PuWuoQUqmXhX7OJrw== + encryptionKey: MIIEowIBAAKCAQEAptyiobOzgLUuVfUQetYQD638+kOUAjf+V7uny+9Qhtt0LZM5v4lsJ8DK+NIbJU6fo9sMNJ8Mc2A7QNEZ6iyppI4zszUIMfF9Ixhew8g5zBlaDzieAf1XSGuEd89vj1ikM3Nhp8AXzxxoFOTsgUCMlnAzsHalcVyqXRzN/glAA1Ob6R0pIEIz4LchvMpnjhSLi5XEmBMy3b3XHu+T5nYyLzLxxMpO2fHH41/GpWmOEVrjoT1qP1JSv+ehuXiuMW0rM1833os6jMHCZijfDGh8blWI2nthjOLbr/KQKQhkIqOXKwdkVLY5x4/c78L8dV3eZ647SqurWC/N8kr5r4LvfwIDAQABAoIBABTPHSUHURJzBeVIW5bGDVi3PP5E4Tdpnjl4uJNRM/ytb46jdqcxTyCiBW4EXchIRtZbYelKEHZvANSzfwTaLwnLhh0KNwxrbkyrJF5MIREX9EhDqkjbPEBW0D1UzDfXORsFf5848H8urrg0WF5CG4ZDVd7i3P0HLmPQTMwqgSYo2pLexcj0LtiZZqJ6ta9kxAiJniZyoNshRJnAZMMnFYRhy/eDF+L6sJPHieYgwiQFU5e0CK9UgsLmmOQWCKWtPgvxOhqlbcTz1pJAqkyzOC0wK/ydJpVAh9RUqf46rEDFzL/l90ZOir3AMlYJIHf4PX0TWchXjFW7bbHn5Zvk1xECgYEAzpuGDfaerUl8QziD6F/OoIz1/EZwSumErCH2NXYMBcCyzKu4fBqVqj5tcLsNx42v6kAGaERAQqaC5ZZ9ZNhXiWasHAermQqv8DtlYVCUih4e87dX1/xTF5TzR8RhLwHPADd1rRafCKJMD9X6Qquer5LmSST8ej3mJ4mrflw837cCgYEAzsCoqFenGlCvAZoQrekxS1VmGJDCKBQ7LlbOwQaUkD4I23rjbAHG8J51jmaQQ4epm6lU0JLSma/LKp8dl9oDEP09vcgKj6xuHMZV+EmsA5c181zMrGoH+tSZiWQZjSmJVhd5T147vnbUunTbGKlOQByD0tWM913Dm2dqB3goXnkCgYBZax4dtPr/7KoHPdJ5I939xoQ/5wx6n454IUq54JlbdAbuZfO2Ypsbz2D2RT61ezEDpSogvklBj2dfjj4/AxL/uJwMlZVC60kyI8LA12syS88Bk/xE0kP0FNcl3GxjN9krMtWPUBcMWZGp2OYzLKvFOULJrWRIU7nkqsS6L5l5CQKBgBa/tg8HzfgkRo1LkWhBT041sE0lqGdWioh3vroYakJQwRK9O8bHj0cseEzZ1ifIBo59HDry3L9SS21+Inhx4YJ+CswV9auHUnpSDGWMXaPrgGEtpcuWwxgDSn2GiRUyK81QOeXUvYggdRmq/+x/vH9rY8nP+3nAVGSGBXGa8/4pAoGBAMB7EOk/RnsgQ+SotHbvgv18S0lbJuWsLYGnNp8EcuPxDIxz29fOFH94qzVOwAkk5cbHvAl3/5sl3SelmKM9LXhcOT+1zxoavyAYyVeAGZsrbBmbzj9yeZON0gHtpF3dMWxiguyWuiiHM/pL92gKzlyIXryC3andL/y8/6VpWbtt isConsensus: true space: gcTTL: 60 syncPeriod: 10 +storage: + path: db diff --git a/node/nodespace/nodecache/treecache.go b/node/nodespace/nodecache/treecache.go index e0238528..0b9446a3 100644 --- a/node/nodespace/nodecache/treecache.go +++ b/node/nodespace/nodecache/treecache.go @@ -24,6 +24,12 @@ type treeCache struct { nodeService nodespace.Service } +func New(ttl int) cache.TreeCache { + return &treeCache{ + gcttl: ttl, + } +} + func (c *treeCache) Run(ctx context.Context) (err error) { return nil } @@ -55,12 +61,6 @@ func (c *treeCache) Name() (name string) { return cache.CName } -func NewNodeCache(ttl int) cache.TreeCache { - return &treeCache{ - gcttl: ttl, - } -} - func (c *treeCache) GetTree(ctx context.Context, spaceId, id string) (res cache.TreeResult, err error) { var cacheRes ocache.Object ctx = context.WithValue(ctx, spaceKey, spaceId) diff --git a/node/storage/keys.go b/node/storage/keys.go index de99e6e7..b3782d8b 100644 --- a/node/storage/keys.go +++ b/node/storage/keys.go @@ -9,29 +9,32 @@ type treeKeys struct { id string } -func (t treeKeys) HeadsKey() string { - return fmt.Sprintf("t/%s/heads", t.id) +func (t treeKeys) HeadsKey() []byte { + return []byte(fmt.Sprintf("t/%s/heads", t.id)) } -func (t treeKeys) RootKey() string { - return fmt.Sprintf("t/%s", t.id) +func (t treeKeys) RootKey() []byte { + return []byte(fmt.Sprintf("t/%s", t.id)) } -func (t treeKeys) RawChangeKey(id string) string { - return fmt.Sprintf("t/%s/%s", t.id, id) +func (t treeKeys) RawChangeKey(id string) []byte { + return []byte(fmt.Sprintf("t/%s/%s", t.id, id)) } type spaceKeys struct { } -func (s spaceKeys) HeaderKey() string { - return "header" +var headerKey = []byte("header") +var aclKey = []byte("acl") + +func (s spaceKeys) HeaderKey() []byte { + return headerKey } -func (s spaceKeys) ACLKey() string { - return "acl" +func (s spaceKeys) ACLKey() []byte { + return aclKey } -func isTreeKey(path string) bool { - return strings.HasPrefix(path, "t/") && len(strings.Split(path, "/")) > 2 +func isRootKey(key string) bool { + return strings.HasPrefix(key, "t/") && len(strings.Split(key, "/")) == 2 } diff --git a/node/storage/spacestorage.go b/node/storage/spacestorage.go index b1d797c2..52a4b52f 100644 --- a/node/storage/spacestorage.go +++ b/node/storage/spacestorage.go @@ -23,7 +23,7 @@ func newSpaceStorage(rootPath string, spaceId string) (store spacestorage.SpaceS return } keys := spaceKeys{} - has, err := objDb.Has([]byte(keys.HeaderKey())) + has, err := objDb.Has(keys.HeaderKey()) if err != nil { return } @@ -32,7 +32,7 @@ func newSpaceStorage(rootPath string, spaceId string) (store spacestorage.SpaceS return } - has, err = objDb.Has([]byte(keys.ACLKey())) + has, err = objDb.Has(keys.ACLKey()) if err != nil { return } @@ -57,7 +57,7 @@ func createSpaceStorage(rootPath string, payload spacestorage.SpaceStorageCreate } keys := spaceKeys{} - has, err := db.Has([]byte(keys.HeaderKey())) + has, err := db.Has(keys.HeaderKey()) if err != nil { return } @@ -70,7 +70,7 @@ func createSpaceStorage(rootPath string, payload spacestorage.SpaceStorageCreate if err != nil { return } - err = db.Put([]byte(keys.ACLKey()), marshalledRec) + err = db.Put(keys.ACLKey(), marshalledRec) if err != nil { return } @@ -79,7 +79,7 @@ func createSpaceStorage(rootPath string, payload spacestorage.SpaceStorageCreate if err != nil { return } - err = db.Put([]byte(keys.HeaderKey()), marshalledHeader) + err = db.Put(keys.HeaderKey(), marshalledHeader) if err != nil { return } @@ -100,7 +100,7 @@ func (s *spaceStorage) CreateTreeStorage(payload storage.TreeStorageCreatePayloa defer s.mx.Unlock() treeKeys := treeKeys{payload.TreeId} - has, err := s.objDb.Has([]byte(treeKeys.RootKey())) + has, err := s.objDb.Has(treeKeys.RootKey()) if err != nil { return } @@ -117,7 +117,7 @@ func (s *spaceStorage) ACLStorage() (storage.ListStorage, error) { } func (s *spaceStorage) SpaceHeader() (header *spacesyncproto.RawSpaceHeaderWithId, err error) { - res, err := s.objDb.Get([]byte(s.keys.HeaderKey())) + res, err := s.objDb.Get(s.keys.HeaderKey()) if err != nil { return } @@ -133,7 +133,7 @@ func (s *spaceStorage) StoredIds() (ids []string, err error) { _, value, err := index.Next() for err == nil { strVal := string(value) - if isTreeKey(strVal) { + if isRootKey(strVal) { ids = append(ids, string(value)) } _, value, err = index.Next() diff --git a/node/storage/storageservice.go b/node/storage/storageservice.go index 802a4f47..92927595 100644 --- a/node/storage/storageservice.go +++ b/node/storage/storageservice.go @@ -3,15 +3,21 @@ package storage import ( "github.com/anytypeio/go-anytype-infrastructure-experiments/app" "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/config" ) type storageService struct { rootPath string } +func New() storage.SpaceStorageProvider { + return &storageService{} +} + func (s *storageService) Init(a *app.App) (err error) { - //TODO implement me - panic("implement me") + cfg := a.MustComponent(config.CName).(*config.Config) + s.rootPath = cfg.Storage.Path + return nil } func (s *storageService) Name() (name string) { diff --git a/node/storage/treestorage.go b/node/storage/treestorage.go index 1fdeef2d..68e88bfd 100644 --- a/node/storage/treestorage.go +++ b/node/storage/treestorage.go @@ -12,19 +12,19 @@ import ( ) type treeStorage struct { - db *pogreb.DB - path treeKeys - id string - rootPath []byte - headsPath []byte - heads []string - root *treechangeproto.RawTreeChangeWithId - headsMx sync.Mutex + db *pogreb.DB + keys treeKeys + id string + rootKey []byte + headsKey []byte + heads []string + root *treechangeproto.RawTreeChangeWithId + headsMx sync.Mutex } func newTreeStorage(db *pogreb.DB, treeId string) (ts storage.TreeStorage, err error) { - path := treeKeys{treeId} - heads, err := db.Get([]byte(path.HeadsKey())) + keys := treeKeys{treeId} + heads, err := db.Get(keys.HeadsKey()) if err != nil { return } @@ -33,7 +33,7 @@ func newTreeStorage(db *pogreb.DB, treeId string) (ts storage.TreeStorage, err e return } - res, err := db.Get([]byte(path.RootKey())) + res, err := db.Get(keys.RootKey()) if err != nil { return } @@ -49,20 +49,20 @@ func newTreeStorage(db *pogreb.DB, treeId string) (ts storage.TreeStorage, err e } ts = &treeStorage{ - db: db, - path: path, - rootPath: []byte(path.RootKey()), - headsPath: []byte(path.HeadsKey()), - id: treeId, - heads: parseHeads(heads), - root: root, + db: db, + keys: keys, + rootKey: keys.RootKey(), + headsKey: keys.HeadsKey(), + id: treeId, + heads: parseHeads(heads), + root: root, } return } func createTreeStorage(db *pogreb.DB, payload storage.TreeStorageCreatePayload) (ts storage.TreeStorage, err error) { keys := treeKeys{id: payload.TreeId} - has, err := db.Has([]byte(keys.RootKey())) + has, err := db.Has(keys.RootKey()) if err != nil { return } @@ -74,36 +74,36 @@ func createTreeStorage(db *pogreb.DB, payload storage.TreeStorageCreatePayload) heads := createHeadsPayload(payload.Heads) for _, ch := range payload.Changes { - err = db.Put([]byte(keys.RawChangeKey(ch.Id)), ch.GetRawChange()) + err = db.Put(keys.RawChangeKey(ch.Id), ch.GetRawChange()) if err != nil { return } } - err = db.Put([]byte(keys.HeadsKey()), heads) + err = db.Put(keys.HeadsKey(), heads) if err != nil { return } // duplicating same change in raw changes - err = db.Put([]byte(keys.RawChangeKey(payload.TreeId)), payload.RootRawChange.GetRawChange()) + err = db.Put(keys.RawChangeKey(payload.TreeId), payload.RootRawChange.GetRawChange()) if err != nil { return } - err = db.Put([]byte(keys.RootKey()), payload.RootRawChange.GetRawChange()) + err = db.Put(keys.RootKey(), payload.RootRawChange.GetRawChange()) if err != nil { return } ts = &treeStorage{ - db: db, - path: keys, - rootPath: []byte(keys.RootKey()), - headsPath: []byte(keys.HeadsKey()), - id: payload.TreeId, - heads: payload.Heads, - root: payload.RootRawChange, + db: db, + keys: keys, + rootKey: keys.RootKey(), + headsKey: keys.HeadsKey(), + id: payload.TreeId, + heads: payload.Heads, + root: payload.RootRawChange, } return } @@ -131,7 +131,7 @@ func (t *treeStorage) SetHeads(heads []string) (err error) { } }() payload := createHeadsPayload(heads) - return t.db.Put(t.headsPath, payload) + return t.db.Put(t.headsKey, payload) } func (t *treeStorage) AddRawChange(change *treechangeproto.RawTreeChangeWithId) (err error) { @@ -139,7 +139,7 @@ func (t *treeStorage) AddRawChange(change *treechangeproto.RawTreeChangeWithId) } func (t *treeStorage) GetRawChange(ctx context.Context, id string) (raw *treechangeproto.RawTreeChangeWithId, err error) { - res, err := t.db.Get([]byte(t.path.RawChangeKey(id))) + res, err := t.db.Get(t.keys.RawChangeKey(id)) if err != nil { return } @@ -152,7 +152,7 @@ func (t *treeStorage) GetRawChange(ctx context.Context, id string) (raw *treecha } func (t *treeStorage) HasChange(ctx context.Context, id string) (bool, error) { - return t.db.Has([]byte(id)) + return t.db.Has(t.keys.RawChangeKey(id)) } func parseHeads(headsPayload []byte) []string { From 46f562e91d86e5aaf7c637926f4772acc982e57a Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Tue, 11 Oct 2022 11:15:46 +0200 Subject: [PATCH 05/20] Change mutex logic --- node/storage/treestorage.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/node/storage/treestorage.go b/node/storage/treestorage.go index 68e88bfd..224cf292 100644 --- a/node/storage/treestorage.go +++ b/node/storage/treestorage.go @@ -123,11 +123,11 @@ func (t *treeStorage) Heads() ([]string, error) { } func (t *treeStorage) SetHeads(heads []string) (err error) { + t.headsMx.Lock() + defer t.headsMx.Unlock() defer func() { if err == nil { - t.headsMx.Lock() t.heads = heads - t.headsMx.Unlock() } }() payload := createHeadsPayload(heads) From d2b64fb272bc785f5f43e9d509fe7023b8b6220b Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Tue, 11 Oct 2022 21:30:06 +0200 Subject: [PATCH 06/20] Add wip benchmarks --- cmd/benchmarks/db/badger.go | 116 ++++++++++++++++++++++++++++++++ cmd/benchmarks/db/common.go | 22 +++++++ cmd/benchmarks/db/pogreb.go | 79 ++++++++++++++++++++++ cmd/benchmarks/dbbench.go | 127 ++++++++++++++++++++++++++++++++++++ go.mod | 13 +++- go.sum | 85 ++++++++++++++++++++++++ 6 files changed, 441 insertions(+), 1 deletion(-) create mode 100644 cmd/benchmarks/db/badger.go create mode 100644 cmd/benchmarks/db/common.go create mode 100644 cmd/benchmarks/db/pogreb.go create mode 100644 cmd/benchmarks/dbbench.go diff --git a/cmd/benchmarks/db/badger.go b/cmd/benchmarks/db/badger.go new file mode 100644 index 00000000..7ddfa6ce --- /dev/null +++ b/cmd/benchmarks/db/badger.go @@ -0,0 +1,116 @@ +package db + +import ( + "fmt" + "github.com/dgraph-io/badger/v3" +) + +type badgerTree struct { + id string + spaceId string + db *badger.DB +} + +func (b *badgerTree) Id() string { + return b.id +} + +func (b *badgerTree) UpdateHead(head string) (err error) { + key := fmt.Sprintf("space/%s/tree/%s/heads", b.spaceId, b.id) + return b.db.Update(func(txn *badger.Txn) error { + return txn.Set([]byte(key), []byte(head)) + }) +} + +func (b *badgerTree) AddChange(key string, value []byte) (err error) { + badgerKey := fmt.Sprintf("space/%s/tree/%s/change/%s", b.spaceId, b.id, key) + return b.db.Update(func(txn *badger.Txn) error { + return txn.Set([]byte(badgerKey), value) + }) +} + +type badgerSpace struct { + id string + db *badger.DB +} + +func (b *badgerSpace) Id() string { + return b.id +} + +func (b *badgerSpace) CreateTree(id string) (Tree, error) { + key := fmt.Sprintf("space/%s/tree/%s", b.id, id) + err := b.db.Update(func(txn *badger.Txn) error { + return txn.Set([]byte(key), []byte("exists")) + }) + if err != nil { + return nil, err + } + return &badgerTree{ + id: id, + spaceId: b.id, + db: b.db, + }, nil +} + +func (b *badgerSpace) GetTree(id string) (Tree, error) { + //TODO implement me + panic("implement me") +} + +func (b *badgerSpace) Close() error { + return nil +} + +type badgerSpaceCreator struct { + rootPath string + db *badger.DB +} + +func (b *badgerSpaceCreator) CreateSpace(id string) (Space, error) { + key := fmt.Sprintf("space/%s", id) + err := b.db.Update(func(txn *badger.Txn) error { + return txn.Set([]byte(key), []byte("exists")) + }) + if err != nil { + return nil, err + } + return &badgerSpace{ + id: id, + db: b.db, + }, nil +} + +func (b *badgerSpaceCreator) GetSpace(id string) (Space, error) { + key := fmt.Sprintf("space/%s", id) + err := b.db.Update(func(txn *badger.Txn) error { + _, err := txn.Get([]byte(key)) + if err != nil { + return err + } + return nil + }) + if err != nil { + return nil, err + } + return &badgerSpace{ + id: id, + db: b.db, + }, nil +} + +func (b *badgerSpaceCreator) Close() error { + return b.db.Close() +} + +func NewBadgerSpaceCreator() SpaceCreator { + rootPath := "badger.db.test" + db, err := badger.Open(badger.DefaultOptions(rootPath)) + if err != nil { + panic(err) + } + return &badgerSpaceCreator{ + rootPath: rootPath, + db: db, + } +} diff --git a/cmd/benchmarks/db/common.go b/cmd/benchmarks/db/common.go new file mode 100644 index 00000000..12f611aa --- /dev/null +++ b/cmd/benchmarks/db/common.go @@ -0,0 +1,22 @@ +package db + +type Tree interface { + Id() string + UpdateHead(head string) (err error) + AddChange(key string, value []byte) (err error) +} + +type Space interface { + Id() string + CreateTree(id string) (Tree, error) + GetTree(id string) (Tree, error) + Close() error +} + +type SpaceCreator interface { + CreateSpace(id string) (Space, error) + GetSpace(id string) (Space, error) + Close() error +} + +type SpaceCreatorFactory func() SpaceCreator diff --git a/cmd/benchmarks/db/pogreb.go b/cmd/benchmarks/db/pogreb.go new file mode 100644 index 00000000..7bdf3f0b --- /dev/null +++ b/cmd/benchmarks/db/pogreb.go @@ -0,0 +1,79 @@ +package db + +import ( + "fmt" + "github.com/akrylysov/pogreb" + "path" +) + +type pogrebTree struct { + id string + db *pogreb.DB +} + +func (p *pogrebTree) Id() string { + return p.id +} + +func (p *pogrebTree) UpdateHead(head string) (err error) { + return p.db.Put([]byte(fmt.Sprintf("t/%s/heads", p.id)), []byte(head)) +} + +func (p *pogrebTree) AddChange(key string, value []byte) (err error) { + return p.db.Put([]byte(fmt.Sprintf("t/%s/%s", p.id, key)), value) +} + +type pogrebSpace struct { + id string + db *pogreb.DB +} + +func (p *pogrebSpace) Id() string { + return p.id +} + +func (p *pogrebSpace) CreateTree(id string) (Tree, error) { + return &pogrebTree{ + id: id, + db: p.db, + }, nil +} + +func (p *pogrebSpace) GetTree(id string) (Tree, error) { + return p.CreateTree(id) +} + +func (p *pogrebSpace) Close() error { + return p.db.Close() +} + +type pogrebSpaceCreator struct { + rootPath string +} + +func (p *pogrebSpaceCreator) CreateSpace(id string) (Space, error) { + dbPath := path.Join(p.rootPath, id) + db, err := pogreb.Open(dbPath, &pogreb.Options{ + BackgroundSyncInterval: 0, + BackgroundCompactionInterval: 20000, + }) + if err != nil { + return nil, err + } + return &pogrebSpace{ + id: id, + db: db, + }, nil +} + +func (p *pogrebSpaceCreator) GetSpace(id string) (Space, error) { + return p.CreateSpace(id) +} + +func (p *pogrebSpaceCreator) Close() error { + return nil +} + +func NewPogrebSpaceCreator() SpaceCreator { + return &pogrebSpaceCreator{rootPath: "db.test"} +} diff --git a/cmd/benchmarks/dbbench.go b/cmd/benchmarks/dbbench.go new file mode 100644 index 00000000..66314d31 --- /dev/null +++ b/cmd/benchmarks/dbbench.go @@ -0,0 +1,127 @@ +package main + +import ( + "fmt" + "github.com/anytypeio/go-anytype-infrastructure-experiments/cmd/benchmarks/db" + "os" + "os/signal" + "syscall" + "time" +) + +func main() { + //bench(db.NewPogrebSpaceCreator, options{ + // numSpaces: 100, + // numEntriesInSpace: 100, + // numChangesInTree: 10, + // numHeadUpdates: 100, + // defValueSize: 1000, + // lenHeadUpdate: 10, + //}) + bench(db.NewPogrebSpaceCreator, options{ + numSpaces: 1000, + numEntriesInSpace: 100, + numChangesInTree: 10, + numHeadUpdates: 100, + defValueSize: 1000, + lenHeadUpdate: 10, + }) +} + +type options struct { + numSpaces int + numEntriesInSpace int + numChangesInTree int + numHeadUpdates int + defValueSize int + lenHeadUpdate int +} + +func bench(factory db.SpaceCreatorFactory, opts options) { + spaceIdGetter := func(n int) string { + return fmt.Sprintf("space%d", n) + } + treeIdGetter := func(n int) string { + return fmt.Sprintf("tree%d", n) + } + changeIdGetter := func(n int) string { + return fmt.Sprintf("change%d", n) + } + + var byteSlice []byte + for i := 0; i < opts.defValueSize; i++ { + byteSlice = append(byteSlice, byte('a')) + } + + var headUpdate string + for i := 0; i < opts.lenHeadUpdate; i++ { + headUpdate += "a" + } + + creator := factory() + // creating spaces + now := time.Now() + var spaces []db.Space + for i := 0; i < opts.numSpaces; i++ { + sp, err := creator.CreateSpace(spaceIdGetter(i)) + if err != nil { + panic(err) + } + err = sp.Close() + if err != nil { + panic(err) + } + } + fmt.Println(opts.numSpaces, "spaces creation, spent ms", time.Now().Sub(now).Milliseconds()) + now = time.Now() + // creating trees + var trees []db.Tree + for i := 0; i < opts.numSpaces; i++ { + space, err := creator.GetSpace(spaceIdGetter(i)) + if err != nil { + panic(err) + } + spaces = append(spaces, space) + for j := 0; j < opts.numEntriesInSpace; j++ { + tr, err := space.CreateTree(treeIdGetter(j)) + if err != nil { + panic(err) + } + trees = append(trees, tr) + } + } + fmt.Println(opts.numSpaces*opts.numEntriesInSpace, "trees creation, spent ms", time.Now().Sub(now).Milliseconds()) + now = time.Now() + + // filling entries and updating heads + for _, t := range trees { + for i := 0; i < opts.numChangesInTree; i++ { + err := t.AddChange(changeIdGetter(i), byteSlice) + if err != nil { + panic(err) + } + } + for i := 0; i < opts.numHeadUpdates; i++ { + err := t.UpdateHead(headUpdate) + if err != nil { + panic(err) + } + } + } + fmt.Println(opts.numSpaces*opts.numEntriesInSpace*opts.numChangesInTree, "changes creation, spent ms", time.Now().Sub(now).Milliseconds()) + + exit := make(chan os.Signal, 1) + signal.Notify(exit, os.Interrupt, syscall.SIGKILL, syscall.SIGTERM, syscall.SIGQUIT) + sig := <-exit + for _, sp := range spaces { + err := sp.Close() + if err != nil { + panic(err) + } + } + err := creator.Close() + if err != nil { + panic(err) + } + fmt.Println(sig) +} diff --git a/go.mod b/go.mod index 8023dfa2..49dbf9e1 100644 --- a/go.mod +++ b/go.mod @@ -34,11 +34,19 @@ require ( github.com/btcsuite/btcd v0.22.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.1.3 // indirect github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect + github.com/dgraph-io/badger/v3 v3.2103.2 // indirect + github.com/dgraph-io/ristretto v0.1.0 // indirect + github.com/dustin/go-humanize v1.0.0 // indirect github.com/fogleman/gg v1.3.0 // indirect github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect - github.com/golang/snappy v0.0.1 // indirect + github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect + github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/snappy v0.0.3 // indirect + github.com/google/flatbuffers v1.12.1 // indirect github.com/klauspost/compress v1.15.1 // indirect github.com/klauspost/cpuid/v2 v2.0.12 // indirect github.com/libp2p/go-buffer-pool v0.0.2 // indirect @@ -58,13 +66,16 @@ require ( github.com/xdg-go/scram v1.1.1 // indirect github.com/xdg-go/stringprep v1.0.3 // indirect github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect + go.opencensus.io v0.22.5 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.8.0 // indirect golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect golang.org/x/image v0.0.0-20200119044424-58c23975cae1 // indirect + golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 // indirect golang.org/x/text v0.3.7 // indirect + google.golang.org/protobuf v1.27.1 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect lukechampine.com/blake3 v1.1.6 // indirect diff --git a/go.sum b/go.sum index 08295176..03ccc1fe 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= @@ -5,6 +7,7 @@ github.com/akrylysov/pogreb v0.10.1 h1:FqlR8VR7uCbJdfUob916tPM+idpKgeESDXOA1K0DK github.com/akrylysov/pogreb v0.10.1/go.mod h1:pNs6QmpQ1UlTJKDezuRWmaqkgUE2TuU0YTWyqJZ7+lI= github.com/anytypeio/go-chash v0.0.0-20220629194632-4ad1154fe232 h1:kMPPZYmJgbs4AJfodbg2OCXg5cp+9LPAJcLZJqmcghk= github.com/anytypeio/go-chash v0.0.0-20220629194632-4ad1154fe232/go.mod h1:+PeHBAWp7gUh/yw6uAauKc5ku0w4cFNg6DUddGxoGq0= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/awalterschulze/gographviz v0.0.0-20190522210029-fa59802746ab h1:+cdNqtOJWjvepyhxy23G7z7vmpYCoC65AP0nqi1f53s= github.com/awalterschulze/gographviz v0.0.0-20190522210029-fa59802746ab/go.mod h1:GEV5wmg4YquNw7v1kkyoX9etIk8yVmXj+AkDHuuETHs= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -17,10 +20,18 @@ github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOF github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cheggaaa/mb/v2 v2.0.1 h1:gn0khbEbKlw3i5VOYi0VnHEHayjZKfUDOyGSpHAybBs= github.com/cheggaaa/mb/v2 v2.0.1/go.mod h1:XGeZw20Iqgjky26KL0mvCwk3+4NyZCUbshSo6ALne+c= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/corona10/goimagehash v1.0.2 h1:pUfB0LnsJASMPGEZLj7tGY251vF+qLGqOgEP4rUs6kA= github.com/corona10/goimagehash v1.0.2/go.mod h1:/l9umBhvcHQXVtQO1V6Gp1yD20STawkhRnnX0D1bvVI= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -28,30 +39,58 @@ github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/dgraph-io/badger/v3 v3.2103.2 h1:dpyM5eCJAtQCBcMCZcT4UBZchuTJgCywerHHgmxfxM8= +github.com/dgraph-io/badger/v3 v3.2103.2/go.mod h1:RHo4/GmYcKKh5Lxu63wLEMHJ70Pac2JqZRYGhlyAo2M= +github.com/dgraph-io/ristretto v0.1.0 h1:Jv3CGQHp9OjuMBSne1485aDpUkTKEcUqF+jm/LuerPI= +github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8= github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/goccy/go-graphviz v0.0.9 h1:s/FMMJ1Joj6La3S5ApO3Jk2cwM4LpXECC2muFx3IPQQ= github.com/goccy/go-graphviz v0.0.9/go.mod h1:wXVsXxmyMQU6TN3zGRttjNn3h+iCAS7xQFC6TlNvLhk= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 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.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= +github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c= github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw= github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-cid v0.1.0 h1:YN33LQulcRHjfom/i25yoOZR4Telp1Hr/2RU3d0PnC0= github.com/ipfs/go-cid v0.1.0/go.mod h1:rH5/Xv83Rfy8Rw6xG+id3DYAMUVmem1MowoKwdXmN2o= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.1 h1:y9FcTHGyrebwfP0ZZqFiaxTaiDnUrGkJkI+f583BL1A= github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= @@ -72,11 +111,14 @@ github.com/libp2p/go-libp2p-core v0.16.1 h1:bWoiEBqVkpJ13hbv/f69tHODp86t6mvc4fBN github.com/libp2p/go-libp2p-core v0.16.1/go.mod h1:O3i/7y+LqUb0N+qhzXjBjjpchgptWAVMG1Voegk7b4c= github.com/libp2p/go-openssl v0.0.7 h1:eCAzdLejcNVBzP/iZM9vqHnQm+XyCEbSSIheIPRGNsw= github.com/libp2p/go-openssl v0.0.7/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= @@ -103,18 +145,27 @@ github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2 github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5 h1:BvoENQQU+fZ9uukda/RzCAL/191HHwJA5b13R6diVlY= github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/stretchr/objx v0.1.0/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.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -124,12 +175,14 @@ github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PK github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E= github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= github.com/xdg-go/stringprep v1.0.3 h1:kdwGpVNwPFtjs98xCGkHjQtGKh86rDcRZN17QEMCOIs= github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -145,6 +198,8 @@ github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= go.mongodb.org/mongo-driver v1.10.2 h1:4Wk3cnqOrQCn0P92L3/mmurMxzdvWWs5J9jinAVKD+k= go.mongodb.org/mongo-driver v1.10.2/go.mod h1:z4XpeoU6w+9Vht+jAFyLgVrD+jGSQQe0+CBWFHNiHt8= +go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= @@ -155,6 +210,7 @@ go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -164,12 +220,19 @@ golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/image v0.0.0-20200119044424-58c23975cae1 h1:5h3ngYt7+vXCDZCup/HkCQgW5XwmSvR/nA2JmJ0RErg= golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -177,18 +240,27 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -204,6 +276,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -215,6 +289,16 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= @@ -229,6 +313,7 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= lukechampine.com/blake3 v1.1.6 h1:H3cROdztr7RCfoaTpGZFQsrqvweFLrqS73j7L7cmR5c= lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= storj.io/drpc v0.0.32 h1:5p5ZwsK/VOgapaCu+oxaPVwO6UwIs+iwdMiD50+R4PI= From 85d83ed9ba8af6d41141f617dd80f927052d785c Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Tue, 11 Oct 2022 23:01:41 +0200 Subject: [PATCH 07/20] Add checks for bench --- cmd/benchmarks/db/badger.go | 29 ++++++++++++++++++++++++++++ cmd/benchmarks/db/common.go | 2 ++ cmd/benchmarks/db/pogreb.go | 16 +++++++++++++--- cmd/benchmarks/dbbench.go | 38 ++++++++++++++++++++++++++++++++++++- 4 files changed, 81 insertions(+), 4 deletions(-) diff --git a/cmd/benchmarks/db/badger.go b/cmd/benchmarks/db/badger.go index 7ddfa6ce..1487aafc 100644 --- a/cmd/benchmarks/db/badger.go +++ b/cmd/benchmarks/db/badger.go @@ -29,6 +29,35 @@ func (b *badgerTree) AddChange(key string, value []byte) (err error) { }) } +func (b *badgerTree) GetChange(key string) (val []byte, err error) { + badgerKey := fmt.Sprintf("space/%s/tree/%s/change/%s", b.spaceId, b.id, key) + err = b.db.View(func(txn *badger.Txn) error { + item, err := txn.Get([]byte(badgerKey)) + if err != nil { + return err + } + val, err = item.ValueCopy(val) + if err != nil { + return err + } + return nil + }) + return +} + +func (b *badgerTree) HasChange(key string) (has bool, err error) { + badgerKey := fmt.Sprintf("space/%s/tree/%s/change/%s", b.spaceId, b.id, key) + err = b.db.View(func(txn *badger.Txn) error { + _, err := txn.Get([]byte(badgerKey)) + return err + }) + if err != nil { + return + } + has = true + return +} + type badgerSpace struct { id string db *badger.DB diff --git a/cmd/benchmarks/db/common.go b/cmd/benchmarks/db/common.go index 12f611aa..d690473c 100644 --- a/cmd/benchmarks/db/common.go +++ b/cmd/benchmarks/db/common.go @@ -4,6 +4,8 @@ type Tree interface { Id() string UpdateHead(head string) (err error) AddChange(key string, value []byte) (err error) + GetChange(key string) ([]byte, error) + HasChange(key string) (has bool, err error) } type Space interface { diff --git a/cmd/benchmarks/db/pogreb.go b/cmd/benchmarks/db/pogreb.go index 7bdf3f0b..6cdde374 100644 --- a/cmd/benchmarks/db/pogreb.go +++ b/cmd/benchmarks/db/pogreb.go @@ -20,7 +20,18 @@ func (p *pogrebTree) UpdateHead(head string) (err error) { } func (p *pogrebTree) AddChange(key string, value []byte) (err error) { - return p.db.Put([]byte(fmt.Sprintf("t/%s/%s", p.id, key)), value) + changeKey := fmt.Sprintf("t/%s/%s", p.id, key) + return p.db.Put([]byte(changeKey), value) +} + +func (p *pogrebTree) GetChange(key string) (val []byte, err error) { + changeKey := fmt.Sprintf("t/%s/%s", p.id, key) + return p.db.Get([]byte(changeKey)) +} + +func (p *pogrebTree) HasChange(key string) (has bool, err error) { + changeKey := fmt.Sprintf("t/%s/%s", p.id, key) + return p.db.Has([]byte(changeKey)) } type pogrebSpace struct { @@ -54,8 +65,7 @@ type pogrebSpaceCreator struct { func (p *pogrebSpaceCreator) CreateSpace(id string) (Space, error) { dbPath := path.Join(p.rootPath, id) db, err := pogreb.Open(dbPath, &pogreb.Options{ - BackgroundSyncInterval: 0, - BackgroundCompactionInterval: 20000, + BackgroundCompactionInterval: 200000, }) if err != nil { return nil, err diff --git a/cmd/benchmarks/dbbench.go b/cmd/benchmarks/dbbench.go index 66314d31..f377c664 100644 --- a/cmd/benchmarks/dbbench.go +++ b/cmd/benchmarks/dbbench.go @@ -3,6 +3,8 @@ package main import ( "fmt" "github.com/anytypeio/go-anytype-infrastructure-experiments/cmd/benchmarks/db" + "net/http" + _ "net/http/pprof" "os" "os/signal" "syscall" @@ -18,6 +20,9 @@ func main() { // defValueSize: 1000, // lenHeadUpdate: 10, //}) + go func() { + fmt.Println(http.ListenAndServe("localhost:6060", nil)) + }() bench(db.NewPogrebSpaceCreator, options{ numSpaces: 1000, numEntriesInSpace: 100, @@ -108,7 +113,38 @@ func bench(factory db.SpaceCreatorFactory, opts options) { } } } - fmt.Println(opts.numSpaces*opts.numEntriesInSpace*opts.numChangesInTree, "changes creation, spent ms", time.Now().Sub(now).Milliseconds()) + total := opts.numSpaces * opts.numEntriesInSpace * opts.numChangesInTree + fmt.Println(total, "changes creation, spent ms", time.Now().Sub(now).Milliseconds()) + now = time.Now() + + // getting some values from tree + for _, t := range trees { + for i := 0; i < opts.numChangesInTree; i++ { + res, err := t.GetChange(changeIdGetter(i)) + if err != nil { + panic(err) + } + if res == nil { + panic("shouldn't be empty") + } + } + } + fmt.Println(total, "changes getting, spent ms", time.Now().Sub(now).Milliseconds()) + now = time.Now() + + // getting some values from tree + for _, t := range trees { + for i := 0; i < opts.numChangesInTree; i++ { + b, err := t.HasChange(changeIdGetter(i)) + if err != nil { + panic(err) + } + if !b { + panic("should be able to check with has") + } + } + } + fmt.Println(total, "changes checking, spent ms", time.Now().Sub(now).Milliseconds()) exit := make(chan os.Signal, 1) signal.Notify(exit, os.Interrupt, syscall.SIGKILL, syscall.SIGTERM, syscall.SIGQUIT) From 296d9a86d043869fd6c5580e09c9ee3d63b33ba4 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Tue, 11 Oct 2022 23:11:17 +0200 Subject: [PATCH 08/20] Naming fixes --- cmd/benchmarks/dbbench.go | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/cmd/benchmarks/dbbench.go b/cmd/benchmarks/dbbench.go index f377c664..0c37302d 100644 --- a/cmd/benchmarks/dbbench.go +++ b/cmd/benchmarks/dbbench.go @@ -12,17 +12,10 @@ import ( ) func main() { - //bench(db.NewPogrebSpaceCreator, options{ - // numSpaces: 100, - // numEntriesInSpace: 100, - // numChangesInTree: 10, - // numHeadUpdates: 100, - // defValueSize: 1000, - // lenHeadUpdate: 10, - //}) go func() { fmt.Println(http.ListenAndServe("localhost:6060", nil)) }() + //bench(db.NewBadgerSpaceCreator, options{ bench(db.NewPogrebSpaceCreator, options{ numSpaces: 1000, numEntriesInSpace: 100, @@ -43,13 +36,13 @@ type options struct { } func bench(factory db.SpaceCreatorFactory, opts options) { - spaceIdGetter := func(n int) string { + spaceIdKey := func(n int) string { return fmt.Sprintf("space%d", n) } - treeIdGetter := func(n int) string { + treeIdKey := func(n int) string { return fmt.Sprintf("tree%d", n) } - changeIdGetter := func(n int) string { + changeIdKey := func(n int) string { return fmt.Sprintf("change%d", n) } @@ -68,7 +61,7 @@ func bench(factory db.SpaceCreatorFactory, opts options) { now := time.Now() var spaces []db.Space for i := 0; i < opts.numSpaces; i++ { - sp, err := creator.CreateSpace(spaceIdGetter(i)) + sp, err := creator.CreateSpace(spaceIdKey(i)) if err != nil { panic(err) } @@ -82,13 +75,13 @@ func bench(factory db.SpaceCreatorFactory, opts options) { // creating trees var trees []db.Tree for i := 0; i < opts.numSpaces; i++ { - space, err := creator.GetSpace(spaceIdGetter(i)) + space, err := creator.GetSpace(spaceIdKey(i)) if err != nil { panic(err) } spaces = append(spaces, space) for j := 0; j < opts.numEntriesInSpace; j++ { - tr, err := space.CreateTree(treeIdGetter(j)) + tr, err := space.CreateTree(treeIdKey(j)) if err != nil { panic(err) } @@ -101,7 +94,7 @@ func bench(factory db.SpaceCreatorFactory, opts options) { // filling entries and updating heads for _, t := range trees { for i := 0; i < opts.numChangesInTree; i++ { - err := t.AddChange(changeIdGetter(i), byteSlice) + err := t.AddChange(changeIdKey(i), byteSlice) if err != nil { panic(err) } @@ -120,7 +113,7 @@ func bench(factory db.SpaceCreatorFactory, opts options) { // getting some values from tree for _, t := range trees { for i := 0; i < opts.numChangesInTree; i++ { - res, err := t.GetChange(changeIdGetter(i)) + res, err := t.GetChange(changeIdKey(i)) if err != nil { panic(err) } @@ -135,7 +128,7 @@ func bench(factory db.SpaceCreatorFactory, opts options) { // getting some values from tree for _, t := range trees { for i := 0; i < opts.numChangesInTree; i++ { - b, err := t.HasChange(changeIdGetter(i)) + b, err := t.HasChange(changeIdKey(i)) if err != nil { panic(err) } From 5e2a6778f0d84fd3a2092e5de28b11d834327c27 Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Wed, 12 Oct 2022 15:14:19 +0300 Subject: [PATCH 09/20] change copaction interval --- cmd/benchmarks/db/pogreb.go | 4 +++- cmd/benchmarks/dbbench.go | 30 ++++++++++++++++++------------ 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/cmd/benchmarks/db/pogreb.go b/cmd/benchmarks/db/pogreb.go index 6cdde374..7cc9759a 100644 --- a/cmd/benchmarks/db/pogreb.go +++ b/cmd/benchmarks/db/pogreb.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/akrylysov/pogreb" "path" + "time" ) type pogrebTree struct { @@ -65,7 +66,8 @@ type pogrebSpaceCreator struct { func (p *pogrebSpaceCreator) CreateSpace(id string) (Space, error) { dbPath := path.Join(p.rootPath, id) db, err := pogreb.Open(dbPath, &pogreb.Options{ - BackgroundCompactionInterval: 200000, + BackgroundSyncInterval: time.Second * 30, + BackgroundCompactionInterval: time.Minute * 2, }) if err != nil { return nil, err diff --git a/cmd/benchmarks/dbbench.go b/cmd/benchmarks/dbbench.go index 0c37302d..c3db3601 100644 --- a/cmd/benchmarks/dbbench.go +++ b/cmd/benchmarks/dbbench.go @@ -3,6 +3,7 @@ package main import ( "fmt" "github.com/anytypeio/go-anytype-infrastructure-experiments/cmd/benchmarks/db" + "math/rand" "net/http" _ "net/http/pprof" "os" @@ -15,15 +16,18 @@ func main() { go func() { fmt.Println(http.ListenAndServe("localhost:6060", nil)) }() - //bench(db.NewBadgerSpaceCreator, options{ - bench(db.NewPogrebSpaceCreator, options{ + opts := options{ numSpaces: 1000, numEntriesInSpace: 100, numChangesInTree: 10, numHeadUpdates: 100, defValueSize: 1000, - lenHeadUpdate: 10, - }) + lenHeadUpdate: 1000, + } + fmt.Println("badger") + bench(db.NewBadgerSpaceCreator, opts) + fmt.Println("pogreb") + bench(db.NewPogrebSpaceCreator, opts) } type options struct { @@ -46,14 +50,16 @@ func bench(factory db.SpaceCreatorFactory, opts options) { return fmt.Sprintf("change%d", n) } - var byteSlice []byte - for i := 0; i < opts.defValueSize; i++ { - byteSlice = append(byteSlice, byte('a')) + var byteSlice = func() []byte { + var buf = make([]byte, opts.defValueSize) + rand.Read(buf) + return buf } - var headUpdate string - for i := 0; i < opts.lenHeadUpdate; i++ { - headUpdate += "a" + var headUpdate = func() []byte { + var buf = make([]byte, opts.lenHeadUpdate) + rand.Read(buf) + return buf } creator := factory() @@ -94,13 +100,13 @@ func bench(factory db.SpaceCreatorFactory, opts options) { // filling entries and updating heads for _, t := range trees { for i := 0; i < opts.numChangesInTree; i++ { - err := t.AddChange(changeIdKey(i), byteSlice) + err := t.AddChange(changeIdKey(i), byteSlice()) if err != nil { panic(err) } } for i := 0; i < opts.numHeadUpdates; i++ { - err := t.UpdateHead(headUpdate) + err := t.UpdateHead(string(headUpdate())) if err != nil { panic(err) } From ad021e5758a6519eb22c51175799409fd791ea24 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Wed, 12 Oct 2022 21:36:16 +0200 Subject: [PATCH 10/20] Add close waiter and close logic for db --- common/commonspace/space.go | 3 +- common/commonspace/storage/storage.go | 1 + node/nodespace/service.go | 8 +++- node/storage/spacestorage.go | 19 ++++++++- pkg/ocache/closewaiter.go | 60 +++++++++++++++++++++++++++ 5 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 pkg/ocache/closewaiter.go diff --git a/common/commonspace/space.go b/common/commonspace/space.go index 8111895a..aa255f51 100644 --- a/common/commonspace/space.go +++ b/common/commonspace/space.go @@ -146,5 +146,6 @@ func (s *space) BuildTree(ctx context.Context, id string, listener updatelistene func (s *space) Close() error { s.diffService.Close() - return s.syncService.Close() + s.syncService.Close() + return s.storage.Close() } diff --git a/common/commonspace/storage/storage.go b/common/commonspace/storage/storage.go index 0dc9df99..eada36f7 100644 --- a/common/commonspace/storage/storage.go +++ b/common/commonspace/storage/storage.go @@ -19,6 +19,7 @@ type SpaceStorage interface { ACLStorage() (storage.ListStorage, error) SpaceHeader() (*spacesyncproto.RawSpaceHeaderWithId, error) StoredIds() ([]string, error) + Close() error } type SpaceStorageCreatePayload struct { diff --git a/node/nodespace/service.go b/node/nodespace/service.go index 0920ef42..2bb60781 100644 --- a/node/nodespace/service.go +++ b/node/nodespace/service.go @@ -29,17 +29,21 @@ type Service interface { type service struct { conf config.Space spaceCache ocache.OCache + closeWaiter *ocache.CloseWaiter commonSpace commonspace.Service spaceStorageProvider storage.SpaceStorageProvider } func (s *service) Init(a *app.App) (err error) { + s.closeWaiter = ocache.NewCloseWaiter(func(ctx context.Context, id string) (value ocache.Object, err error) { + return s.commonSpace.GetSpace(ctx, id) + }) s.conf = a.MustComponent(config.CName).(*config.Config).Space s.commonSpace = a.MustComponent(commonspace.CName).(commonspace.Service) s.spaceStorageProvider = a.MustComponent(storage.CName).(storage.SpaceStorageProvider) s.spaceCache = ocache.New( func(ctx context.Context, id string) (value ocache.Object, err error) { - return s.commonSpace.GetSpace(ctx, id) + return s.closeWaiter.Load(ctx, id) }, ocache.WithLogger(log.Sugar()), ocache.WithGCPeriod(time.Minute), @@ -66,7 +70,7 @@ func (s *service) GetSpace(ctx context.Context, id string) (commonspace.Space, e if err != nil { return nil, err } - return v.(commonspace.Space), nil + return v.(*ocache.CloseWrapper).Value.(commonspace.Space), nil } func (s *service) Close(ctx context.Context) (err error) { diff --git a/node/storage/spacestorage.go b/node/storage/spacestorage.go index 52a4b52f..4f0d0a49 100644 --- a/node/storage/spacestorage.go +++ b/node/storage/spacestorage.go @@ -8,8 +8,13 @@ import ( "github.com/gogo/protobuf/proto" "path" "sync" + "time" ) +var defPogrebOptions = &pogreb.Options{ + BackgroundCompactionInterval: time.Minute * 5, +} + type spaceStorage struct { objDb *pogreb.DB keys spaceKeys @@ -18,7 +23,7 @@ type spaceStorage struct { func newSpaceStorage(rootPath string, spaceId string) (store spacestorage.SpaceStorage, err error) { dbPath := path.Join(rootPath, spaceId) - objDb, err := pogreb.Open(dbPath, nil) + objDb, err := pogreb.Open(dbPath, defPogrebOptions) if err != nil { return } @@ -51,11 +56,17 @@ func newSpaceStorage(rootPath string, spaceId string) (store spacestorage.SpaceS func createSpaceStorage(rootPath string, payload spacestorage.SpaceStorageCreatePayload) (store spacestorage.SpaceStorage, err error) { // TODO: add payload verification dbPath := path.Join(rootPath, payload.SpaceHeaderWithId.Id) - db, err := pogreb.Open(dbPath, nil) + db, err := pogreb.Open(dbPath, defPogrebOptions) if err != nil { return } + defer func() { + if err != nil { + db.Close() + } + }() + keys := spaceKeys{} has, err := db.Has(keys.HeaderKey()) if err != nil { @@ -145,3 +156,7 @@ func (s *spaceStorage) StoredIds() (ids []string, err error) { err = nil return } + +func (s *spaceStorage) Close() (err error) { + return s.objDb.Close() +} diff --git a/pkg/ocache/closewaiter.go b/pkg/ocache/closewaiter.go new file mode 100644 index 00000000..52043c70 --- /dev/null +++ b/pkg/ocache/closewaiter.go @@ -0,0 +1,60 @@ +package ocache + +import ( + "context" + "sync" +) + +type CloseWrapper struct { + Value Object + ch chan struct{} +} + +func (c *CloseWrapper) Close() (err error) { + err = c.Value.Close() + close(c.ch) + return err +} + +type CloseWaiter struct { + load func(ctx context.Context, id string) (value Object, err error) + + mx sync.Mutex + closeMap map[string]chan struct{} +} + +func NewCloseWaiter(load func(ctx context.Context, id string) (value Object, err error)) *CloseWaiter { + return &CloseWaiter{ + load: load, + closeMap: make(map[string]chan struct{}), + } +} + +func (l *CloseWaiter) Load(ctx context.Context, id string) (value Object, err error) { + // this uses assumption of ocache, that for each id load function cannot be called simultaneously + var ch chan struct{} + l.mx.Lock() + if c, exists := l.closeMap[id]; exists { + ch = c + } + l.mx.Unlock() + if ch != nil { + <-ch + } + + value, err = l.load(ctx, id) + if err != nil { + return + } + + ch = make(chan struct{}) + l.mx.Lock() + l.closeMap[id] = ch + l.mx.Unlock() + + value = &CloseWrapper{ + Value: value, + ch: ch, + } + return +} From 980357509d4f55894c7d5640b032cbc1b7b137d5 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Thu, 13 Oct 2022 13:27:18 +0200 Subject: [PATCH 11/20] Change ocache to include wait for closing --- pkg/ocache/ocache.go | 72 +++++++++++++++++++++++++++++++++----------- 1 file changed, 54 insertions(+), 18 deletions(-) diff --git a/pkg/ocache/ocache.go b/pkg/ocache/ocache.go index 44dc9d42..998faf6d 100644 --- a/pkg/ocache/ocache.go +++ b/pkg/ocache/ocache.go @@ -89,6 +89,8 @@ type entry struct { load chan struct{} loadErr error value Object + isClosing bool + close chan struct{} } func (e *entry) locked() bool { @@ -148,6 +150,7 @@ func (c *oCache) Get(ctx context.Context, id string) (value Object, err error) { ok bool load bool ) +Load: c.mu.Lock() if c.closed { c.mu.Unlock() @@ -161,11 +164,18 @@ func (c *oCache) Get(ctx context.Context, id string) (value Object, err error) { } c.data[id] = e } - e.lastUsage = c.timeNow() - if !c.noRefCounter { - e.refCount++ + closing := e.isClosing + if !e.isClosing { + e.lastUsage = c.timeNow() + if !c.noRefCounter { + e.refCount++ + } } c.mu.Unlock() + if closing { + <-e.close + goto Load + } if load { go c.load(ctx, id, e) @@ -181,17 +191,18 @@ func (c *oCache) Get(ctx context.Context, id string) (value Object, err error) { func (c *oCache) Pick(ctx context.Context, id string) (value Object, err error) { c.mu.Lock() val, ok := c.data[id] - c.mu.Unlock() - if !ok { + if !ok || val.isClosing { + c.mu.Unlock() return nil, ErrNotExists } + c.mu.Unlock() + select { case <-ctx.Done(): return nil, ctx.Err() case <-val.load: + return val.value, val.loadErr } - <-val.load - return val.value, val.loadErr } func (c *oCache) load(ctx context.Context, id string, e *entry) { @@ -238,17 +249,30 @@ func (c *oCache) Reset(id string) bool { func (c *oCache) Remove(id string) (ok bool, err error) { c.mu.Lock() - e, ok := c.data[id] - if ok { - delete(c.data, id) + if c.closed { + c.mu.Unlock() + err = ErrClosed + return } + var e *entry + e, ok = c.data[id] + if !ok || e.isClosing { + c.mu.Unlock() + return + } + e.isClosing = true + e.close = make(chan struct{}) c.mu.Unlock() - if ok { - <-e.load - if e.value != nil { - err = e.value.Close() - } + + <-e.load + if e.value != nil { + err = e.value.Close() } + c.mu.Lock() + close(e.close) + delete(c.data, e.id) + c.mu.Unlock() + return } @@ -288,7 +312,7 @@ func (c *oCache) ForEach(f func(obj Object) (isContinue bool)) { for _, v := range c.data { select { case <-v.load: - if v.value != nil { + if v.value != nil && !v.isClosing { objects = append(objects, v.value) } default: @@ -323,18 +347,23 @@ func (c *oCache) GC() { } deadline := c.timeNow().Add(-c.ttl) var toClose []*entry - for k, e := range c.data { + for _, e := range c.data { + if e.isClosing { + continue + } lu := e.lastUsage if lug, ok := e.value.(ObjectLastUsage); ok { lu = lug.LastUsage() } if !e.locked() && e.refCount <= 0 && lu.Before(deadline) { - delete(c.data, k) + e.isClosing = true + e.close = make(chan struct{}) toClose = append(toClose, e) } } size := len(c.data) c.mu.Unlock() + c.log.Infof("GC: removed %d; cache size: %d", len(toClose), size) for _, e := range toClose { <-e.load @@ -344,6 +373,13 @@ func (c *oCache) GC() { } } } + + c.mu.Lock() + for _, e := range toClose { + close(e.close) + delete(c.data, e.id) + } + c.mu.Unlock() } func (c *oCache) Len() int { From 401402021afeb073818682eeb4dc373576b426bf Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Fri, 14 Oct 2022 12:37:45 +0200 Subject: [PATCH 12/20] Add tests for ocache --- pkg/ocache/ocache.go | 2 +- pkg/ocache/ocache_test.go | 106 +++++++++++++++++++++++++++++++++----- 2 files changed, 93 insertions(+), 15 deletions(-) diff --git a/pkg/ocache/ocache.go b/pkg/ocache/ocache.go index 998faf6d..c19c398c 100644 --- a/pkg/ocache/ocache.go +++ b/pkg/ocache/ocache.go @@ -86,10 +86,10 @@ type entry struct { id string lastUsage time.Time refCount uint32 + isClosing bool load chan struct{} loadErr error value Object - isClosing bool close chan struct{} } diff --git a/pkg/ocache/ocache_test.go b/pkg/ocache/ocache_test.go index 55bf2e95..cebed09a 100644 --- a/pkg/ocache/ocache_test.go +++ b/pkg/ocache/ocache_test.go @@ -14,16 +14,23 @@ import ( type testObject struct { name string closeErr error + closeCh chan struct{} +} + +func NewTestObject(name string, closeCh chan struct{}) *testObject { + return &testObject{ + name: name, + closeCh: closeCh, + } } func (t *testObject) Close() (err error) { + if t.closeCh != nil { + <-t.closeCh + } return t.closeErr } -func (t *testObject) ShouldClose() bool { - return true -} - func TestOCache_Get(t *testing.T) { t.Run("successful", func(t *testing.T) { c := New(func(ctx context.Context, id string) (value Object, err error) { @@ -109,20 +116,91 @@ func TestOCache_Get(t *testing.T) { } func TestOCache_GC(t *testing.T) { + t.Run("test without close wait", func(t *testing.T) { + c := New(func(ctx context.Context, id string) (value Object, err error) { + return &testObject{name: id}, nil + }, WithTTL(time.Millisecond*10)) + val, err := c.Get(context.TODO(), "id") + require.NoError(t, err) + require.NotNil(t, val) + assert.Equal(t, 1, c.Len()) + c.GC() + assert.Equal(t, 1, c.Len()) + time.Sleep(time.Millisecond * 30) + c.GC() + assert.Equal(t, 1, c.Len()) + assert.True(t, c.Release("id")) + c.GC() + assert.Equal(t, 0, c.Len()) + assert.False(t, c.Release("id")) + }) + t.Run("test with close wait", func(t *testing.T) { + closeCh := make(chan struct{}) + getCh := make(chan struct{}) + + c := New(func(ctx context.Context, id string) (value Object, err error) { + return NewTestObject(id, closeCh), nil + }, WithTTL(time.Millisecond*10)) + val, err := c.Get(context.TODO(), "id") + require.NoError(t, err) + require.NotNil(t, val) + assert.Equal(t, 1, c.Len()) + assert.True(t, c.Release("id")) + // making ttl pass + time.Sleep(time.Millisecond * 40) + // first gc will be run after 20 secs, so calling it manually + go c.GC() + // waiting until all objects are marked as closing + time.Sleep(time.Millisecond * 40) + var events []string + go func() { + _, err := c.Get(context.TODO(), "id") + require.NoError(t, err) + require.NotNil(t, val) + events = append(events, "get") + close(getCh) + }() + events = append(events, "close") + // sleeping to make sure that Get is called + time.Sleep(time.Millisecond * 40) + close(closeCh) + + <-getCh + require.Equal(t, []string{"close", "get"}, events) + }) +} + +func Test_OCache_Remove(t *testing.T) { + closeCh := make(chan struct{}) + getCh := make(chan struct{}) + c := New(func(ctx context.Context, id string) (value Object, err error) { - return &testObject{name: id}, nil + return NewTestObject(id, closeCh), nil }, WithTTL(time.Millisecond*10)) val, err := c.Get(context.TODO(), "id") require.NoError(t, err) require.NotNil(t, val) assert.Equal(t, 1, c.Len()) - c.GC() - assert.Equal(t, 1, c.Len()) - time.Sleep(time.Millisecond * 30) - c.GC() - assert.Equal(t, 1, c.Len()) - assert.True(t, c.Release("id")) - c.GC() - assert.Equal(t, 0, c.Len()) - assert.False(t, c.Release("id")) + // removing the object, so we will wait on closing + go func() { + _, err := c.Remove("id") + require.NoError(t, err) + }() + time.Sleep(time.Millisecond * 40) + + var events []string + go func() { + _, err := c.Get(context.TODO(), "id") + require.NoError(t, err) + require.NotNil(t, val) + events = append(events, "get") + close(getCh) + }() + events = append(events, "close") + // sleeping to make sure that Get is called + time.Sleep(time.Millisecond * 40) + close(closeCh) + + <-getCh + require.Equal(t, []string{"close", "get"}, events) } From a1aacbffed0eef8f056755a957892a80a343440a Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Fri, 14 Oct 2022 13:32:40 +0200 Subject: [PATCH 13/20] Fix keys and remove close waiter --- node/nodespace/service.go | 8 ++--- node/storage/keys.go | 30 +++++++++++++++--- node/storage/spacestorage.go | 1 - pkg/ocache/closewaiter.go | 60 ------------------------------------ 4 files changed, 27 insertions(+), 72 deletions(-) delete mode 100644 pkg/ocache/closewaiter.go diff --git a/node/nodespace/service.go b/node/nodespace/service.go index 2bb60781..0920ef42 100644 --- a/node/nodespace/service.go +++ b/node/nodespace/service.go @@ -29,21 +29,17 @@ type Service interface { type service struct { conf config.Space spaceCache ocache.OCache - closeWaiter *ocache.CloseWaiter commonSpace commonspace.Service spaceStorageProvider storage.SpaceStorageProvider } func (s *service) Init(a *app.App) (err error) { - s.closeWaiter = ocache.NewCloseWaiter(func(ctx context.Context, id string) (value ocache.Object, err error) { - return s.commonSpace.GetSpace(ctx, id) - }) s.conf = a.MustComponent(config.CName).(*config.Config).Space s.commonSpace = a.MustComponent(commonspace.CName).(commonspace.Service) s.spaceStorageProvider = a.MustComponent(storage.CName).(storage.SpaceStorageProvider) s.spaceCache = ocache.New( func(ctx context.Context, id string) (value ocache.Object, err error) { - return s.closeWaiter.Load(ctx, id) + return s.commonSpace.GetSpace(ctx, id) }, ocache.WithLogger(log.Sugar()), ocache.WithGCPeriod(time.Minute), @@ -70,7 +66,7 @@ func (s *service) GetSpace(ctx context.Context, id string) (commonspace.Space, e if err != nil { return nil, err } - return v.(*ocache.CloseWrapper).Value.(commonspace.Space), nil + return v.(commonspace.Space), nil } func (s *service) Close(ctx context.Context) (err error) { diff --git a/node/storage/keys.go b/node/storage/keys.go index b3782d8b..0d4b8de5 100644 --- a/node/storage/keys.go +++ b/node/storage/keys.go @@ -1,7 +1,7 @@ package storage import ( - "fmt" + "bytes" "strings" ) @@ -10,15 +10,15 @@ type treeKeys struct { } func (t treeKeys) HeadsKey() []byte { - return []byte(fmt.Sprintf("t/%s/heads", t.id)) + return joinStringsToBytes("t", t.id, "heads") } func (t treeKeys) RootKey() []byte { - return []byte(fmt.Sprintf("t/%s", t.id)) + return joinStringsToBytes("t", t.id) } func (t treeKeys) RawChangeKey(id string) []byte { - return []byte(fmt.Sprintf("t/%s/%s", t.id, id)) + return joinStringsToBytes("t", t.id, id) } type spaceKeys struct { @@ -36,5 +36,25 @@ func (s spaceKeys) ACLKey() []byte { } func isRootKey(key string) bool { - return strings.HasPrefix(key, "t/") && len(strings.Split(key, "/")) == 2 + return strings.HasPrefix(key, "t/") && strings.Count(key, "/") == 2 +} + +func joinStringsToBytes(strs ...string) []byte { + var ( + b bytes.Buffer + totalLen int + ) + for _, s := range strs { + totalLen += len(s) + } + // adding separators + totalLen += len(strs) - 1 + b.Grow(totalLen) + for idx, s := range strs { + if idx > 0 { + b.WriteString("/") + } + b.WriteString(s) + } + return b.Bytes() } diff --git a/node/storage/spacestorage.go b/node/storage/spacestorage.go index 4f0d0a49..c2faab6c 100644 --- a/node/storage/spacestorage.go +++ b/node/storage/spacestorage.go @@ -54,7 +54,6 @@ func newSpaceStorage(rootPath string, spaceId string) (store spacestorage.SpaceS } func createSpaceStorage(rootPath string, payload spacestorage.SpaceStorageCreatePayload) (store spacestorage.SpaceStorage, err error) { - // TODO: add payload verification dbPath := path.Join(rootPath, payload.SpaceHeaderWithId.Id) db, err := pogreb.Open(dbPath, defPogrebOptions) if err != nil { diff --git a/pkg/ocache/closewaiter.go b/pkg/ocache/closewaiter.go deleted file mode 100644 index 52043c70..00000000 --- a/pkg/ocache/closewaiter.go +++ /dev/null @@ -1,60 +0,0 @@ -package ocache - -import ( - "context" - "sync" -) - -type CloseWrapper struct { - Value Object - ch chan struct{} -} - -func (c *CloseWrapper) Close() (err error) { - err = c.Value.Close() - close(c.ch) - return err -} - -type CloseWaiter struct { - load func(ctx context.Context, id string) (value Object, err error) - - mx sync.Mutex - closeMap map[string]chan struct{} -} - -func NewCloseWaiter(load func(ctx context.Context, id string) (value Object, err error)) *CloseWaiter { - return &CloseWaiter{ - load: load, - closeMap: make(map[string]chan struct{}), - } -} - -func (l *CloseWaiter) Load(ctx context.Context, id string) (value Object, err error) { - // this uses assumption of ocache, that for each id load function cannot be called simultaneously - var ch chan struct{} - l.mx.Lock() - if c, exists := l.closeMap[id]; exists { - ch = c - } - l.mx.Unlock() - if ch != nil { - <-ch - } - - value, err = l.load(ctx, id) - if err != nil { - return - } - - ch = make(chan struct{}) - l.mx.Lock() - l.closeMap[id] = ch - l.mx.Unlock() - - value = &CloseWrapper{ - Value: value, - ch: ch, - } - return -} From 3facea9a06500f856fdefa939b7508a651fd5475 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Sat, 15 Oct 2022 16:26:03 +0200 Subject: [PATCH 14/20] Change pogreb implementation --- .../storage/mock_storage/mock_storage.go | 14 ++ node/storage/keys.go | 44 ++++-- node/storage/liststorage.go | 135 ++++++++++++++++++ node/storage/spacestorage.go | 89 ++++++------ node/storage/treestorage.go | 76 +++++----- pkg/acl/list/list.go | 8 +- pkg/acl/storage/inmemory.go | 4 +- pkg/acl/storage/liststorage.go | 7 +- pkg/acl/storage/mock_storage/mock_storage.go | 4 +- pkg/acl/storage/provider.go | 2 + .../acllistbuilder/liststoragebuilder.go | 6 +- 11 files changed, 289 insertions(+), 100 deletions(-) create mode 100644 node/storage/liststorage.go diff --git a/common/commonspace/storage/mock_storage/mock_storage.go b/common/commonspace/storage/mock_storage/mock_storage.go index 197e13bd..4cca0580 100644 --- a/common/commonspace/storage/mock_storage/mock_storage.go +++ b/common/commonspace/storage/mock_storage/mock_storage.go @@ -133,6 +133,20 @@ func (mr *MockSpaceStorageMockRecorder) ACLStorage() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ACLStorage", reflect.TypeOf((*MockSpaceStorage)(nil).ACLStorage)) } +// Close mocks base method. +func (m *MockSpaceStorage) 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 *MockSpaceStorageMockRecorder) Close() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockSpaceStorage)(nil).Close)) +} + // CreateTreeStorage mocks base method. func (m *MockSpaceStorage) CreateTreeStorage(arg0 storage0.TreeStorageCreatePayload) (storage0.TreeStorage, error) { m.ctrl.T.Helper() diff --git a/node/storage/keys.go b/node/storage/keys.go index 0d4b8de5..9f5597ab 100644 --- a/node/storage/keys.go +++ b/node/storage/keys.go @@ -5,6 +5,24 @@ import ( "strings" ) +type aclKeys struct { +} + +var aclHeadIdKey = []byte("a/headId") +var aclRootIdKey = []byte("a/rootId") + +func (a aclKeys) HeadIdKey() []byte { + return aclHeadIdKey +} + +func (a aclKeys) RootIdKey() []byte { + return aclRootIdKey +} + +func (a aclKeys) RawRecordKey(id string) []byte { + return joinStringsToBytes("a", id) +} + type treeKeys struct { id string } @@ -13,8 +31,8 @@ func (t treeKeys) HeadsKey() []byte { return joinStringsToBytes("t", t.id, "heads") } -func (t treeKeys) RootKey() []byte { - return joinStringsToBytes("t", t.id) +func (t treeKeys) RootIdKey() []byte { + return joinStringsToBytes("t", t.id, "rootId") } func (t treeKeys) RawChangeKey(id string) []byte { @@ -22,21 +40,25 @@ func (t treeKeys) RawChangeKey(id string) []byte { } type spaceKeys struct { + headerKey []byte } -var headerKey = []byte("header") -var aclKey = []byte("acl") +func newSpaceKeys(spaceId string) spaceKeys { + return spaceKeys{headerKey: joinStringsToBytes("s", spaceId)} +} + +var spaceIdKey = []byte("spaceId") + +func (s spaceKeys) SpaceIdKey() []byte { + return spaceIdKey +} func (s spaceKeys) HeaderKey() []byte { - return headerKey + return s.headerKey } -func (s spaceKeys) ACLKey() []byte { - return aclKey -} - -func isRootKey(key string) bool { - return strings.HasPrefix(key, "t/") && strings.Count(key, "/") == 2 +func isRootIdKey(key string) bool { + return strings.HasPrefix(key, "t/") && strings.HasSuffix(key, "rootId") } func joinStringsToBytes(strs ...string) []byte { diff --git a/node/storage/liststorage.go b/node/storage/liststorage.go new file mode 100644 index 00000000..989791b6 --- /dev/null +++ b/node/storage/liststorage.go @@ -0,0 +1,135 @@ +package storage + +import ( + "context" + "github.com/akrylysov/pogreb" + "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclrecordproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/storage" +) + +type listStorage struct { + db *pogreb.DB + keys aclKeys + id string + root *aclrecordproto.RawACLRecordWithId +} + +func newListStorage(db *pogreb.DB) (ls storage.ListStorage, err error) { + keys := aclKeys{} + head, err := db.Get(keys.HeadIdKey()) + if err != nil { + return + } + if head == nil { + err = storage.ErrUnknownACLId + return + } + + rootId, err := db.Get(keys.RootIdKey()) + if err != nil { + return + } + if rootId == nil { + err = storage.ErrUnknownACLId + return + } + + root, err := db.Get(keys.RawRecordKey(string(rootId))) + if err != nil { + return + } + if root == nil { + err = storage.ErrUnknownACLId + return + } + + rootWithId := &aclrecordproto.RawACLRecordWithId{ + Payload: root, + Id: string(rootId), + } + + ls = &listStorage{ + db: db, + keys: aclKeys{}, + id: string(rootId), + root: rootWithId, + } + return +} + +func createListStorage(db *pogreb.DB, root *aclrecordproto.RawACLRecordWithId) (ls storage.ListStorage, err error) { + keys := aclKeys{} + has, err := db.Has(keys.RootIdKey()) + if err != nil { + return + } + if has { + err = storage.ErrACLExists + return + } + + err = db.Put(keys.HeadIdKey(), []byte(root.Id)) + if err != nil { + return + } + + err = db.Put(keys.RawRecordKey(root.Id), root.Payload) + if err != nil { + return + } + + err = db.Put(keys.RootIdKey(), []byte(root.Id)) + if err != nil { + return + } + + ls = &listStorage{ + db: db, + keys: aclKeys{}, + id: root.Id, + root: root, + } + return +} + +func (l *listStorage) ID() (string, error) { + return l.id, nil +} + +func (l *listStorage) Root() (*aclrecordproto.RawACLRecordWithId, error) { + return l.root, nil +} + +func (l *listStorage) Head() (head string, err error) { + bytes, err := l.db.Get(l.keys.HeadIdKey()) + if err != nil { + return + } + if bytes == nil { + err = storage.ErrUnknownACLId + return + } + head = string(bytes) + return +} + +func (l *listStorage) GetRawRecord(ctx context.Context, id string) (raw *aclrecordproto.RawACLRecordWithId, err error) { + res, err := l.db.Get(l.keys.RawRecordKey(id)) + if err != nil { + return + } + if res == nil { + err = storage.ErrUnknownRecord + return + } + + raw = &aclrecordproto.RawACLRecordWithId{ + Payload: res, + Id: id, + } + return +} + +func (l *listStorage) AddRawRecord(ctx context.Context, rec *aclrecordproto.RawACLRecordWithId) error { + return l.db.Put([]byte(rec.Id), rec.Payload) +} diff --git a/node/storage/spacestorage.go b/node/storage/spacestorage.go index c2faab6c..12b15534 100644 --- a/node/storage/spacestorage.go +++ b/node/storage/spacestorage.go @@ -5,7 +5,6 @@ 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/pkg/acl/storage" - "github.com/gogo/protobuf/proto" "path" "sync" "time" @@ -16,9 +15,11 @@ var defPogrebOptions = &pogreb.Options{ } type spaceStorage struct { - objDb *pogreb.DB - keys spaceKeys - mx sync.Mutex + objDb *pogreb.DB + keys spaceKeys + aclStorage storage.ListStorage + header *spacesyncproto.RawSpaceHeaderWithId + mx sync.Mutex } func newSpaceStorage(rootPath string, spaceId string) (store spacestorage.SpaceStorage, err error) { @@ -27,8 +28,15 @@ func newSpaceStorage(rootPath string, spaceId string) (store spacestorage.SpaceS if err != nil { return } - keys := spaceKeys{} - has, err := objDb.Has(keys.HeaderKey()) + + defer func() { + if err != nil { + objDb.Close() + } + }() + + keys := newSpaceKeys(spaceId) + has, err := objDb.Has(keys.SpaceIdKey()) if err != nil { return } @@ -37,18 +45,28 @@ func newSpaceStorage(rootPath string, spaceId string) (store spacestorage.SpaceS return } - has, err = objDb.Has(keys.ACLKey()) + header, err := objDb.Get(keys.HeaderKey()) if err != nil { return } - if !has { + if header == nil { err = spacestorage.ErrSpaceStorageMissing return } + aclStorage, err := newListStorage(objDb) + if err != nil { + return + } + store = &spaceStorage{ objDb: objDb, keys: keys, + header: &spacesyncproto.RawSpaceHeaderWithId{ + RawHeader: header, + Id: spaceId, + }, + aclStorage: aclStorage, } return } @@ -66,37 +84,36 @@ func createSpaceStorage(rootPath string, payload spacestorage.SpaceStorageCreate } }() - keys := spaceKeys{} - has, err := db.Has(keys.HeaderKey()) + keys := newSpaceKeys(payload.SpaceHeaderWithId.Id) + has, err := db.Has(keys.SpaceIdKey()) if err != nil { return } if has { - err = spacestorage.ErrSpaceStorageExists + err = spacesyncproto.ErrSpaceExists return } - marshalledRec, err := payload.RecWithId.Marshal() - if err != nil { - return - } - err = db.Put(keys.ACLKey(), marshalledRec) + aclStorage, err := createListStorage(db, payload.RecWithId) if err != nil { return } - marshalledHeader, err := payload.SpaceHeaderWithId.Marshal() + err = db.Put(keys.HeaderKey(), payload.SpaceHeaderWithId.RawHeader) if err != nil { return } - err = db.Put(keys.HeaderKey(), marshalledHeader) + + err = db.Put(keys.SpaceIdKey(), []byte(payload.SpaceHeaderWithId.Id)) if err != nil { return } store = &spaceStorage{ - objDb: db, - keys: keys, + objDb: db, + keys: keys, + aclStorage: aclStorage, + header: payload.SpaceHeaderWithId, } return } @@ -106,47 +123,31 @@ func (s *spaceStorage) TreeStorage(id string) (storage.TreeStorage, error) { } 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() - treeKeys := treeKeys{payload.TreeId} - has, err := s.objDb.Has(treeKeys.RootKey()) - if err != nil { - return - } - if has { - err = spacestorage.ErrSpaceStorageExists - return - } - return createTreeStorage(s.objDb, payload) } func (s *spaceStorage) ACLStorage() (storage.ListStorage, error) { - return nil, nil + return s.aclStorage, nil } func (s *spaceStorage) SpaceHeader() (header *spacesyncproto.RawSpaceHeaderWithId, err error) { - res, err := s.objDb.Get(s.keys.HeaderKey()) - if err != nil { - return - } - - header = &spacesyncproto.RawSpaceHeaderWithId{} - err = proto.Unmarshal(res, header) - return + return s.header, nil } func (s *spaceStorage) StoredIds() (ids []string, err error) { index := s.objDb.Items() - _, value, err := index.Next() + key, val, err := index.Next() for err == nil { - strVal := string(value) - if isRootKey(strVal) { - ids = append(ids, string(value)) + strKey := string(key) + if isRootIdKey(strKey) { + ids = append(ids, string(val)) } - _, value, err = index.Next() + key, val, err = index.Next() } if err != pogreb.ErrIterationDone { diff --git a/node/storage/treestorage.go b/node/storage/treestorage.go index 224cf292..4bc24c62 100644 --- a/node/storage/treestorage.go +++ b/node/storage/treestorage.go @@ -6,24 +6,28 @@ import ( "github.com/akrylysov/pogreb" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/storage" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treechangeproto" - "github.com/gogo/protobuf/proto" "strings" - "sync" ) type treeStorage struct { db *pogreb.DB keys treeKeys id string - rootKey []byte headsKey []byte - heads []string root *treechangeproto.RawTreeChangeWithId - headsMx sync.Mutex } func newTreeStorage(db *pogreb.DB, treeId string) (ts storage.TreeStorage, err error) { keys := treeKeys{treeId} + has, err := db.Has(keys.RootIdKey()) + if err != nil { + return + } + if !has { + err = storage.ErrUnknownTreeId + return + } + heads, err := db.Get(keys.HeadsKey()) if err != nil { return @@ -33,17 +37,19 @@ func newTreeStorage(db *pogreb.DB, treeId string) (ts storage.TreeStorage, err e return } - res, err := db.Get(keys.RootKey()) + root, err := db.Get(keys.RawChangeKey(treeId)) if err != nil { return } - if res == nil { + if root == nil { err = storage.ErrUnknownTreeId return } - root := &treechangeproto.RawTreeChangeWithId{} - err = proto.Unmarshal(res, root) + rootWithId := &treechangeproto.RawTreeChangeWithId{ + RawChange: root, + Id: treeId, + } if err != nil { return } @@ -51,23 +57,21 @@ func newTreeStorage(db *pogreb.DB, treeId string) (ts storage.TreeStorage, err e ts = &treeStorage{ db: db, keys: keys, - rootKey: keys.RootKey(), headsKey: keys.HeadsKey(), id: treeId, - heads: parseHeads(heads), - root: root, + root: rootWithId, } return } func createTreeStorage(db *pogreb.DB, payload storage.TreeStorageCreatePayload) (ts storage.TreeStorage, err error) { keys := treeKeys{id: payload.TreeId} - has, err := db.Has(keys.RootKey()) + has, err := db.Has(keys.RootIdKey()) if err != nil { return } - if !has { - err = storage.ErrUnknownTreeId + if has { + err = storage.ErrTreeExists return } @@ -80,18 +84,17 @@ func createTreeStorage(db *pogreb.DB, payload storage.TreeStorageCreatePayload) } } + err = db.Put(keys.RawChangeKey(payload.RootRawChange.Id), payload.RootRawChange.GetRawChange()) + if err != nil { + return + } + err = db.Put(keys.HeadsKey(), heads) if err != nil { return } - // duplicating same change in raw changes - err = db.Put(keys.RawChangeKey(payload.TreeId), payload.RootRawChange.GetRawChange()) - if err != nil { - return - } - - err = db.Put(keys.RootKey(), payload.RootRawChange.GetRawChange()) + err = db.Put(keys.RootIdKey(), []byte(payload.RootRawChange.Id)) if err != nil { return } @@ -99,10 +102,8 @@ func createTreeStorage(db *pogreb.DB, payload storage.TreeStorageCreatePayload) ts = &treeStorage{ db: db, keys: keys, - rootKey: keys.RootKey(), headsKey: keys.HeadsKey(), - id: payload.TreeId, - heads: payload.Heads, + id: payload.RootRawChange.Id, root: payload.RootRawChange, } return @@ -116,20 +117,20 @@ func (t *treeStorage) Root() (raw *treechangeproto.RawTreeChangeWithId, err erro return t.root, nil } -func (t *treeStorage) Heads() ([]string, error) { - t.headsMx.Lock() - defer t.headsMx.Unlock() - return t.heads, nil +func (t *treeStorage) Heads() (heads []string, err error) { + headsBytes, err := t.db.Get(t.keys.HeadsKey()) + if err != nil { + return + } + if heads == nil { + err = storage.ErrUnknownTreeId + return + } + heads = parseHeads(headsBytes) + return } func (t *treeStorage) SetHeads(heads []string) (err error) { - t.headsMx.Lock() - defer t.headsMx.Unlock() - defer func() { - if err == nil { - t.heads = heads - } - }() payload := createHeadsPayload(heads) return t.db.Put(t.headsKey, payload) } @@ -143,6 +144,9 @@ func (t *treeStorage) GetRawChange(ctx context.Context, id string) (raw *treecha if err != nil { return } + if res == nil { + err = storage.ErrUnkownChange + } raw = &treechangeproto.RawTreeChangeWithId{ RawChange: res, diff --git a/pkg/acl/list/list.go b/pkg/acl/list/list.go index dae887e6..382ecf4e 100644 --- a/pkg/acl/list/list.go +++ b/pkg/acl/list/list.go @@ -67,6 +67,7 @@ func BuildACLList(storage storage.ListStorage) (ACLList, error) { } func build(id string, stateBuilder *aclStateBuilder, recBuilder ACLRecordBuilder, storage storage.ListStorage) (list ACLList, err error) { + // TODO: need to add context here rootWithId, err := storage.Root() if err != nil { return @@ -76,7 +77,12 @@ func build(id string, stateBuilder *aclStateBuilder, recBuilder ACLRecordBuilder return } - rawRecordWithId, err := storage.Head() + head, err := storage.Head() + if err != nil { + return + } + + rawRecordWithId, err := storage.GetRawRecord(context.Background(), head) if err != nil { return } diff --git a/pkg/acl/storage/inmemory.go b/pkg/acl/storage/inmemory.go index 487caa04..b9948c3e 100644 --- a/pkg/acl/storage/inmemory.go +++ b/pkg/acl/storage/inmemory.go @@ -31,10 +31,10 @@ func (i *inMemoryACLListStorage) Root() (*aclrecordproto.RawACLRecordWithId, err return i.records[0], nil } -func (i *inMemoryACLListStorage) Head() (*aclrecordproto.RawACLRecordWithId, error) { +func (i *inMemoryACLListStorage) Head() (string, error) { i.RLock() defer i.RUnlock() - return i.records[len(i.records)-1], nil + return i.records[len(i.records)-1].Id, nil } func (i *inMemoryACLListStorage) GetRawRecord(ctx context.Context, id string) (*aclrecordproto.RawACLRecordWithId, error) { diff --git a/pkg/acl/storage/liststorage.go b/pkg/acl/storage/liststorage.go index 222fd8d8..ad61a7fa 100644 --- a/pkg/acl/storage/liststorage.go +++ b/pkg/acl/storage/liststorage.go @@ -3,13 +3,18 @@ package storage import ( "context" + "errors" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclrecordproto" ) +var ErrUnknownACLId = errors.New("acl does not exist") +var ErrACLExists = errors.New("acl already exists") +var ErrUnknownRecord = errors.New("record doesn't exist") + type ListStorage interface { Storage Root() (*aclrecordproto.RawACLRecordWithId, error) - Head() (*aclrecordproto.RawACLRecordWithId, error) + Head() (string, error) GetRawRecord(ctx context.Context, id string) (*aclrecordproto.RawACLRecordWithId, error) AddRawRecord(ctx context.Context, rec *aclrecordproto.RawACLRecordWithId) error diff --git a/pkg/acl/storage/mock_storage/mock_storage.go b/pkg/acl/storage/mock_storage/mock_storage.go index f20bf468..c4cf8800 100644 --- a/pkg/acl/storage/mock_storage/mock_storage.go +++ b/pkg/acl/storage/mock_storage/mock_storage.go @@ -66,10 +66,10 @@ func (mr *MockListStorageMockRecorder) GetRawRecord(arg0, arg1 interface{}) *gom } // Head mocks base method. -func (m *MockListStorage) Head() (*aclrecordproto.RawACLRecordWithId, error) { +func (m *MockListStorage) Head() (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Head") - ret0, _ := ret[0].(*aclrecordproto.RawACLRecordWithId) + ret0, _ := ret[0].(string) ret1, _ := ret[1].(error) return ret0, ret1 } diff --git a/pkg/acl/storage/provider.go b/pkg/acl/storage/provider.go index 4e738b28..1d40cb30 100644 --- a/pkg/acl/storage/provider.go +++ b/pkg/acl/storage/provider.go @@ -6,6 +6,8 @@ import ( ) var ErrUnknownTreeId = errors.New("tree does not exist") +var ErrTreeExists = errors.New("tree already exists") +var ErrUnkownChange = errors.New("change doesn't exist") type TreeStorageCreatePayload struct { TreeId string diff --git a/pkg/acl/testutils/acllistbuilder/liststoragebuilder.go b/pkg/acl/testutils/acllistbuilder/liststoragebuilder.go index d855ac99..206550a5 100644 --- a/pkg/acl/testutils/acllistbuilder/liststoragebuilder.go +++ b/pkg/acl/testutils/acllistbuilder/liststoragebuilder.go @@ -89,12 +89,12 @@ func (t *ACLListStorageBuilder) createRaw(rec proto.Marshaler, identity []byte) } } -func (t *ACLListStorageBuilder) Head() (*aclrecordproto.RawACLRecordWithId, error) { +func (t *ACLListStorageBuilder) Head() (string, error) { l := len(t.records) if l > 0 { - return t.rawRecords[l-1], nil + return t.rawRecords[l-1].Id, nil } - return t.rawRoot, nil + return t.rawRoot.Id, nil } func (t *ACLListStorageBuilder) Root() (*aclrecordproto.RawACLRecordWithId, error) { From e6d6cae35c308da37f1b060d1ce46ad0703888fa Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Sat, 15 Oct 2022 17:09:25 +0200 Subject: [PATCH 15/20] Change tree keys logic --- node/storage/keys.go | 16 +++++++++++++--- node/storage/treestorage.go | 33 +++++++++++++++------------------ 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/node/storage/keys.go b/node/storage/keys.go index 9f5597ab..853cfdd8 100644 --- a/node/storage/keys.go +++ b/node/storage/keys.go @@ -24,15 +24,25 @@ func (a aclKeys) RawRecordKey(id string) []byte { } type treeKeys struct { - id string + id string + headsKey []byte + rootKey []byte +} + +func newTreeKeys(id string) treeKeys { + return treeKeys{ + id: id, + headsKey: joinStringsToBytes("t", id, "heads"), + rootKey: joinStringsToBytes("t", id, "rootId"), + } } func (t treeKeys) HeadsKey() []byte { - return joinStringsToBytes("t", t.id, "heads") + return t.headsKey } func (t treeKeys) RootIdKey() []byte { - return joinStringsToBytes("t", t.id, "rootId") + return t.rootKey } func (t treeKeys) RawChangeKey(id string) []byte { diff --git a/node/storage/treestorage.go b/node/storage/treestorage.go index 4bc24c62..6c6c0d57 100644 --- a/node/storage/treestorage.go +++ b/node/storage/treestorage.go @@ -10,15 +10,14 @@ import ( ) type treeStorage struct { - db *pogreb.DB - keys treeKeys - id string - headsKey []byte - root *treechangeproto.RawTreeChangeWithId + db *pogreb.DB + keys treeKeys + id string + root *treechangeproto.RawTreeChangeWithId } func newTreeStorage(db *pogreb.DB, treeId string) (ts storage.TreeStorage, err error) { - keys := treeKeys{treeId} + keys := newTreeKeys(treeId) has, err := db.Has(keys.RootIdKey()) if err != nil { return @@ -55,17 +54,16 @@ func newTreeStorage(db *pogreb.DB, treeId string) (ts storage.TreeStorage, err e } ts = &treeStorage{ - db: db, - keys: keys, - headsKey: keys.HeadsKey(), - id: treeId, - root: rootWithId, + db: db, + keys: keys, + id: treeId, + root: rootWithId, } return } func createTreeStorage(db *pogreb.DB, payload storage.TreeStorageCreatePayload) (ts storage.TreeStorage, err error) { - keys := treeKeys{id: payload.TreeId} + keys := newTreeKeys(payload.TreeId) has, err := db.Has(keys.RootIdKey()) if err != nil { return @@ -100,11 +98,10 @@ func createTreeStorage(db *pogreb.DB, payload storage.TreeStorageCreatePayload) } ts = &treeStorage{ - db: db, - keys: keys, - headsKey: keys.HeadsKey(), - id: payload.RootRawChange.Id, - root: payload.RootRawChange, + db: db, + keys: keys, + id: payload.RootRawChange.Id, + root: payload.RootRawChange, } return } @@ -132,7 +129,7 @@ func (t *treeStorage) Heads() (heads []string, err error) { func (t *treeStorage) SetHeads(heads []string) (err error) { payload := createHeadsPayload(heads) - return t.db.Put(t.headsKey, payload) + return t.db.Put(t.keys.HeadsKey(), payload) } func (t *treeStorage) AddRawChange(change *treechangeproto.RawTreeChangeWithId) (err error) { From baa275b05bcf39c46a16fe43bbf77930f8abec31 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Sat, 15 Oct 2022 21:43:01 +0200 Subject: [PATCH 16/20] Client badger WIP --- client/account/service.go | 62 ++++++ client/badgerprovider/helpers.go | 76 ++++++++ client/badgerprovider/service.go | 41 ++++ client/clientspace/clientcache/treecache.go | 86 +++++++++ client/clientspace/rpchandler.go | 58 ++++++ client/clientspace/service.go | 74 +++++++ client/storage/keys.go | 91 +++++++++ client/storage/liststorage.go | 131 +++++++++++++ client/storage/spacestorage.go | 159 +++++++++++++++ client/storage/storageservice.go | 34 ++++ client/storage/treestorage.go | 181 ++++++++++++++++++ go.mod | 3 + go.sum | 2 + node/storage/keys.go | 6 - node/storage/liststorage.go | 9 - node/storage/treestorage.go | 16 +- pkg/acl/aclrecordproto/protos/aclrecord.proto | 9 + 17 files changed, 1008 insertions(+), 30 deletions(-) create mode 100644 client/account/service.go create mode 100644 client/badgerprovider/helpers.go create mode 100644 client/badgerprovider/service.go create mode 100644 client/clientspace/clientcache/treecache.go create mode 100644 client/clientspace/rpchandler.go create mode 100644 client/clientspace/service.go create mode 100644 client/storage/keys.go create mode 100644 client/storage/liststorage.go create mode 100644 client/storage/spacestorage.go create mode 100644 client/storage/storageservice.go create mode 100644 client/storage/treestorage.go diff --git a/client/account/service.go b/client/account/service.go new file mode 100644 index 00000000..3181f9bd --- /dev/null +++ b/client/account/service.go @@ -0,0 +1,62 @@ +package account + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/app" + commonaccount "github.com/anytypeio/go-anytype-infrastructure-experiments/common/account" + "github.com/anytypeio/go-anytype-infrastructure-experiments/config" + "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account" + "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys" + "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey" + "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey" +) + +type service struct { + accountData *account.AccountData + peerId string +} + +func (s *service) Account() *account.AccountData { + return s.accountData +} + +func New() app.Component { + return &service{} +} + +func (s *service) Init(a *app.App) (err error) { + acc := a.MustComponent(config.CName).(commonaccount.ConfigGetter).GetAccount() + + decodedEncryptionKey, err := keys.DecodeKeyFromString( + acc.EncryptionKey, + encryptionkey.NewEncryptionRsaPrivKeyFromBytes, + nil) + if err != nil { + return err + } + + decodedSigningKey, err := keys.DecodeKeyFromString( + acc.SigningKey, + signingkey.NewSigningEd25519PrivKeyFromBytes, + nil) + if err != nil { + return err + } + + identity, err := decodedSigningKey.GetPublic().Raw() + if err != nil { + return err + } + + s.accountData = &account.AccountData{ + Identity: identity, + SignKey: decodedSigningKey, + EncKey: decodedEncryptionKey, + } + s.peerId = acc.PeerId + + return nil +} + +func (s *service) Name() (name string) { + return commonaccount.CName +} diff --git a/client/badgerprovider/helpers.go b/client/badgerprovider/helpers.go new file mode 100644 index 00000000..96ed8acf --- /dev/null +++ b/client/badgerprovider/helpers.go @@ -0,0 +1,76 @@ +package badgerprovider + +import ( + "errors" + "github.com/dgraph-io/badger/v3" +) + +var ErrIncorrectKey = errors.New("the key is incorrect") + +func Has(db *badger.DB, key []byte) (has bool, err error) { + err = db.View(func(txn *badger.Txn) error { + _, err := txn.Get(key) + return err + }) + if err != nil { + return + } + has = true + return +} + +func Put(db *badger.DB, key, value []byte) (err error) { + return db.Update(func(txn *badger.Txn) error { + return txn.Set(key, value) + }) +} + +func Get(db *badger.DB, key []byte) (value []byte, err error) { + err = db.View(func(txn *badger.Txn) error { + item, err := txn.Get(key) + if err != nil { + return err + } + value, err = item.ValueCopy(value) + if err != nil { + return err + } + return err + }) + return +} + +func GetKeySuffix(txn *badger.Txn, keyPrefix []byte) (suffix []byte, err error) { + iter := txn.NewIterator(badger.IteratorOptions{Prefix: keyPrefix}) + iter.Next() + if !iter.Valid() { + err = badger.ErrKeyNotFound + return + } + + suffix = iter.Item().Key() + if len(suffix) <= len(keyPrefix)+1 { + err = ErrIncorrectKey + return + } + suffix = suffix[len(keyPrefix)+1:] + return +} + +func GetKeySuffixAndValue(txn *badger.Txn, keyPrefix []byte) (suffix []byte, value []byte, err error) { + iter := txn.NewIterator(badger.IteratorOptions{Prefix: keyPrefix}) + iter.Next() + if !iter.Valid() { + err = badger.ErrKeyNotFound + return + } + + suffix = iter.Item().Key() + if len(suffix) <= len(keyPrefix)+1 { + err = ErrIncorrectKey + return + } + suffix = suffix[len(keyPrefix)+1:] + value, err = iter.Item().ValueCopy(value) + return +} diff --git a/client/badgerprovider/service.go b/client/badgerprovider/service.go new file mode 100644 index 00000000..2fb8a9c0 --- /dev/null +++ b/client/badgerprovider/service.go @@ -0,0 +1,41 @@ +package badgerprovider + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/config" + "github.com/dgraph-io/badger/v3" +) + +type BadgerProvider interface { + app.ComponentRunnable + Badger() *badger.DB +} + +var CName = "client.badgerprovider" + +type service struct { + db *badger.DB +} + +func (s *service) Init(a *app.App) (err error) { + cfg := a.MustComponent(config.CName).(*config.Config) + s.db, err = badger.Open(badger.DefaultOptions(cfg.Storage.Path)) + return +} + +func (s *service) Name() (name string) { + return CName +} + +func (s *service) Badger() *badger.DB { + return s.db +} + +func (s *service) Run(ctx context.Context) (err error) { + return +} + +func (s *service) Close(ctx context.Context) (err error) { + return s.db.Close() +} diff --git a/client/clientspace/clientcache/treecache.go b/client/clientspace/clientcache/treecache.go new file mode 100644 index 00000000..eee57452 --- /dev/null +++ b/client/clientspace/clientcache/treecache.go @@ -0,0 +1,86 @@ +package clientcache + +import ( + "context" + "errors" + "github.com/anytypeio/go-anytype-infrastructure-experiments/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/client/clientspace" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/cache" + "github.com/anytypeio/go-anytype-infrastructure-experiments/node/nodespace" + "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/ocache" + "time" +) + +var log = logger.NewNamed("treecache") +var ErrCacheObjectWithoutTree = errors.New("cache object contains no tree") + +type ctxKey int + +const spaceKey ctxKey = 0 + +type treeCache struct { + gcttl int + cache ocache.OCache + clientService clientspace.Service +} + +func New(ttl int) cache.TreeCache { + return &treeCache{ + gcttl: ttl, + } +} + +func (c *treeCache) Run(ctx context.Context) (err error) { + return nil +} + +func (c *treeCache) Close(ctx context.Context) (err error) { + return c.cache.Close() +} + +func (c *treeCache) Init(a *app.App) (err error) { + c.clientService = a.MustComponent(nodespace.CName).(nodespace.Service) + c.cache = ocache.New( + func(ctx context.Context, id string) (value ocache.Object, err error) { + spaceId := ctx.Value(spaceKey).(string) + space, err := c.clientService.GetSpace(ctx, spaceId) + if err != nil { + return + } + return space.BuildTree(ctx, id, nil) + }, + ocache.WithLogger(log.Sugar()), + ocache.WithGCPeriod(time.Minute), + ocache.WithTTL(time.Duration(c.gcttl)*time.Second), + ocache.WithRefCounter(false), + ) + return nil +} + +func (c *treeCache) Name() (name string) { + return cache.CName +} + +func (c *treeCache) GetTree(ctx context.Context, spaceId, id string) (res cache.TreeResult, err error) { + var cacheRes ocache.Object + ctx = context.WithValue(ctx, spaceKey, spaceId) + cacheRes, err = c.cache.Get(ctx, id) + if err != nil { + return cache.TreeResult{}, err + } + + treeContainer, ok := cacheRes.(cache.TreeContainer) + if !ok { + err = ErrCacheObjectWithoutTree + return + } + + res = cache.TreeResult{ + Release: func() { + c.cache.Release(id) + }, + TreeContainer: treeContainer, + } + return +} diff --git a/client/clientspace/rpchandler.go b/client/clientspace/rpchandler.go new file mode 100644 index 00000000..3a76454c --- /dev/null +++ b/client/clientspace/rpchandler.go @@ -0,0 +1,58 @@ +package clientspace + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/cache" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage" +) + +type rpcHandler struct { + s *service +} + +func (r *rpcHandler) PushSpace(ctx context.Context, req *spacesyncproto.PushSpaceRequest) (resp *spacesyncproto.PushSpaceResponse, err error) { + _, err = r.s.GetSpace(ctx, req.SpaceHeader.Id) + if err == nil { + err = spacesyncproto.ErrSpaceExists + return + } + if err != cache.ErrSpaceNotFound { + err = spacesyncproto.ErrUnexpected + return + } + + payload := storage.SpaceStorageCreatePayload{ + RecWithId: req.AclRoot, + SpaceHeaderWithId: req.SpaceHeader, + } + _, err = r.s.spaceStorageProvider.CreateSpaceStorage(payload) + if err != nil { + err = spacesyncproto.ErrUnexpected + if err == storage.ErrSpaceStorageExists { + err = spacesyncproto.ErrSpaceExists + } + return + } + return +} + +func (r *rpcHandler) HeadSync(ctx context.Context, req *spacesyncproto.HeadSyncRequest) (*spacesyncproto.HeadSyncResponse, error) { + sp, err := r.s.GetSpace(ctx, req.SpaceId) + if err != nil { + return nil, spacesyncproto.ErrSpaceMissing + } + return sp.SpaceSyncRpc().HeadSync(ctx, req) +} + +func (r *rpcHandler) Stream(stream spacesyncproto.DRPCSpace_StreamStream) error { + msg, err := stream.Recv() + if err != nil { + return err + } + sp, err := r.s.GetSpace(stream.Context(), msg.SpaceId) + if err != nil { + return spacesyncproto.ErrSpaceMissing + } + return sp.SpaceSyncRpc().Stream(stream) +} diff --git a/client/clientspace/service.go b/client/clientspace/service.go new file mode 100644 index 00000000..3fcebc1b --- /dev/null +++ b/client/clientspace/service.go @@ -0,0 +1,74 @@ +package clientspace + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace" + "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/net/rpc/server" + "github.com/anytypeio/go-anytype-infrastructure-experiments/config" + "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/ocache" + "time" +) + +const CName = "client.clientspace" + +var log = logger.NewNamed(CName) + +func New() Service { + return &service{} +} + +type Service interface { + GetSpace(ctx context.Context, id string) (commonspace.Space, error) + app.ComponentRunnable +} + +type service struct { + conf config.Space + spaceCache ocache.OCache + commonSpace commonspace.Service + spaceStorageProvider storage.SpaceStorageProvider +} + +func (s *service) Init(a *app.App) (err error) { + s.conf = a.MustComponent(config.CName).(*config.Config).Space + s.commonSpace = a.MustComponent(commonspace.CName).(commonspace.Service) + s.spaceStorageProvider = a.MustComponent(storage.CName).(storage.SpaceStorageProvider) + s.spaceCache = ocache.New( + func(ctx context.Context, id string) (value ocache.Object, err error) { + return s.commonSpace.GetSpace(ctx, id) + }, + ocache.WithLogger(log.Sugar()), + ocache.WithGCPeriod(time.Minute), + ocache.WithTTL(time.Duration(s.conf.GCTTL)*time.Second), + ocache.WithRefCounter(false), + ) + return spacesyncproto.DRPCRegisterSpace(a.MustComponent(server.CName).(server.DRPCServer), &rpcHandler{s}) +} + +func (s *service) Name() (name string) { + return CName +} + +func (s *service) Run(ctx context.Context) (err error) { + go func() { + time.Sleep(time.Second * 5) + _, _ = s.GetSpace(ctx, "testDSpace") + }() + return +} + +func (s *service) GetSpace(ctx context.Context, id string) (commonspace.Space, error) { + v, err := s.spaceCache.Get(ctx, id) + if err != nil { + return nil, err + } + return v.(commonspace.Space), nil +} + +func (s *service) Close(ctx context.Context) (err error) { + return s.spaceCache.Close() +} diff --git a/client/storage/keys.go b/client/storage/keys.go new file mode 100644 index 00000000..5ee5958f --- /dev/null +++ b/client/storage/keys.go @@ -0,0 +1,91 @@ +package storage + +import ( + "bytes" +) + +type aclKeys struct { + spaceId string + rootKey []byte + headKey []byte +} + +func newACLKeys(spaceId string) aclKeys { + return aclKeys{ + spaceId: spaceId, + rootKey: joinStringsToBytes("space", spaceId, "a", "rootId"), + headKey: joinStringsToBytes("space", spaceId, "a", "headId"), + } +} + +func (a aclKeys) HeadIdKey() []byte { + return a.headKey +} + +func (a aclKeys) RootIdKey() []byte { + return a.rootKey +} + +func (a aclKeys) RawRecordKey(id string) []byte { + return joinStringsToBytes("space", a.spaceId, "a", id) +} + +type treeKeys struct { + id string + spaceId string + headsKey []byte + rootKey []byte +} + +func newTreeKeys(spaceId, id string) treeKeys { + return treeKeys{ + id: id, + spaceId: spaceId, + headsKey: joinStringsToBytes("space", spaceId, "t", id, "heads"), + rootKey: joinStringsToBytes("space", spaceId, "t", id), + } +} + +func (t treeKeys) HeadsKey() []byte { + return t.headsKey +} + +func (t treeKeys) RootIdKey() []byte { + return t.rootKey +} + +func (t treeKeys) RawChangeKey(id string) []byte { + return joinStringsToBytes("space", t.spaceId, "t", t.id, id) +} + +type spaceKeys struct { + headerKey []byte +} + +func newSpaceKeys(spaceId string) spaceKeys { + return spaceKeys{headerKey: joinStringsToBytes("space", spaceId)} +} + +func (s spaceKeys) HeaderKey() []byte { + return s.headerKey +} + +func joinStringsToBytes(strs ...string) []byte { + var ( + b bytes.Buffer + totalLen int + ) + for _, s := range strs { + totalLen += len(s) + } + // adding separators + totalLen += len(strs) - 1 + b.Grow(totalLen) + for idx, s := range strs { + if idx > 0 { + b.WriteString("/") + } + b.WriteString(s) + } + return b.Bytes() +} diff --git a/client/storage/liststorage.go b/client/storage/liststorage.go new file mode 100644 index 00000000..30910d65 --- /dev/null +++ b/client/storage/liststorage.go @@ -0,0 +1,131 @@ +package storage + +import ( + "context" + "errors" + provider "github.com/anytypeio/go-anytype-infrastructure-experiments/client/badgerprovider" + "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclrecordproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/storage" + "github.com/dgraph-io/badger/v3" +) + +var ErrIncorrectKey = errors.New("key format is incorrect") + +type listStorage struct { + db *badger.DB + keys aclKeys + id string + root *aclrecordproto.RawACLRecordWithId +} + +func newListStorage(spaceId string, db *badger.DB, txn *badger.Txn) (ls storage.ListStorage, err error) { + keys := newACLKeys(spaceId) + rootId, err := provider.GetKeySuffix(txn, keys.RootIdKey()) + if err != nil { + if err == badger.ErrKeyNotFound { + err = storage.ErrUnknownACLId + } + return + } + stringId := string(rootId) + rootItem, err := txn.Get(keys.RawRecordKey(stringId)) + if err != nil { + if err == badger.ErrKeyNotFound { + err = storage.ErrUnknownACLId + } + return + } + var value []byte + value, err = rootItem.ValueCopy(value) + if err != nil { + return + } + + rootWithId := &aclrecordproto.RawACLRecordWithId{ + Payload: value, + Id: stringId, + } + + ls = &listStorage{ + db: db, + keys: aclKeys{}, + id: stringId, + root: rootWithId, + } + return +} + +func createListStorage(spaceId string, db *badger.DB, txn *badger.Txn, root *aclrecordproto.RawACLRecordWithId) (ls storage.ListStorage, err error) { + keys := newACLKeys(spaceId) + _, err = provider.GetKeySuffix(txn, keys.RootIdKey()) + if err != nil && err != badger.ErrKeyNotFound { + return + } + if err == nil { + err = storage.ErrACLExists + return + } + aclRootKey := append(keys.RootIdKey(), '/') + aclRootKey = append(aclRootKey, []byte(root.Id)...) + + err = txn.Set(aclRootKey, nil) + if err != nil { + return + } + + err = txn.Set(keys.HeadIdKey(), []byte(root.Id)) + if err != nil { + return + } + + err = txn.Set(keys.RawRecordKey(root.Id), root.Payload) + if err != nil { + return + } + + ls = &listStorage{ + db: db, + keys: aclKeys{}, + id: root.Id, + root: root, + } + return +} + +func (l *listStorage) ID() (string, error) { + return l.id, nil +} + +func (l *listStorage) Root() (*aclrecordproto.RawACLRecordWithId, error) { + return l.root, nil +} + +func (l *listStorage) Head() (head string, err error) { + bytes, err := provider.Get(l.db, l.keys.HeadIdKey()) + if err != nil { + return + } + head = string(bytes) + return +} + +func (l *listStorage) GetRawRecord(ctx context.Context, id string) (raw *aclrecordproto.RawACLRecordWithId, err error) { + res, err := l.db.Get(l.keys.RawRecordKey(id)) + if err != nil { + return + } + if res == nil { + err = storage.ErrUnknownRecord + return + } + + raw = &aclrecordproto.RawACLRecordWithId{ + Payload: res, + Id: id, + } + return +} + +func (l *listStorage) AddRawRecord(ctx context.Context, rec *aclrecordproto.RawACLRecordWithId) error { + return l.db.Put([]byte(rec.Id), rec.Payload) +} diff --git a/client/storage/spacestorage.go b/client/storage/spacestorage.go new file mode 100644 index 00000000..1affdc14 --- /dev/null +++ b/client/storage/spacestorage.go @@ -0,0 +1,159 @@ +package storage + +import ( + "github.com/akrylysov/pogreb" + provider "github.com/anytypeio/go-anytype-infrastructure-experiments/client/badgerprovider" + "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/pkg/acl/storage" + "github.com/dgraph-io/badger/v3" + "path" + "sync" + "time" +) + +var defPogrebOptions = &pogreb.Options{ + BackgroundCompactionInterval: time.Minute * 5, +} + +type spaceStorage struct { + objDb *pogreb.DB + keys spaceKeys + aclStorage storage.ListStorage + header *spacesyncproto.RawSpaceHeaderWithId + mx sync.Mutex +} + +func newSpaceStorage(objDb *badger.DB, spaceId string) (store spacestorage.SpaceStorage, err error) { + keys := newSpaceKeys(spaceId) + err = objDb.Update(func(txn *badger.Txn) error { + header, err := txn.Get(keys.HeaderKey()) + if err != nil { + return err + } + + }) + has, err := provider.Has(obj) + if err != nil { + return + } + if !has { + err = spacestorage.ErrSpaceStorageMissing + return + } + + header, err := objDb.Get(keys.HeaderKey()) + if err != nil { + return + } + if header == nil { + err = spacestorage.ErrSpaceStorageMissing + return + } + + aclStorage, err := newListStorage(objDb) + if err != nil { + return + } + + store = &spaceStorage{ + objDb: objDb, + keys: keys, + header: &spacesyncproto.RawSpaceHeaderWithId{ + RawHeader: header, + Id: spaceId, + }, + aclStorage: aclStorage, + } + return +} + +func createSpaceStorage(rootPath string, payload spacestorage.SpaceStorageCreatePayload) (store spacestorage.SpaceStorage, err error) { + dbPath := path.Join(rootPath, payload.SpaceHeaderWithId.Id) + db, err := pogreb.Open(dbPath, defPogrebOptions) + if err != nil { + return + } + + defer func() { + if err != nil { + db.Close() + } + }() + + keys := newSpaceKeys(payload.SpaceHeaderWithId.Id) + has, err := db.Has(keys.SpaceIdKey()) + if err != nil { + return + } + if has { + err = spacesyncproto.ErrSpaceExists + return + } + + aclStorage, err := createListStorage(db, payload.RecWithId) + if err != nil { + return + } + + err = db.Put(keys.HeaderKey(), payload.SpaceHeaderWithId.RawHeader) + if err != nil { + return + } + + err = db.Put(keys.SpaceIdKey(), []byte(payload.SpaceHeaderWithId.Id)) + if err != nil { + return + } + + store = &spaceStorage{ + objDb: db, + keys: keys, + aclStorage: aclStorage, + header: payload.SpaceHeaderWithId, + } + return +} + +func (s *spaceStorage) TreeStorage(id string) (storage.TreeStorage, error) { + return newTreeStorage(s.objDb, 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, payload) +} + +func (s *spaceStorage) ACLStorage() (storage.ListStorage, error) { + return s.aclStorage, nil +} + +func (s *spaceStorage) SpaceHeader() (header *spacesyncproto.RawSpaceHeaderWithId, err error) { + return s.header, nil +} + +func (s *spaceStorage) StoredIds() (ids []string, err error) { + index := s.objDb.Items() + + key, val, err := index.Next() + for err == nil { + strKey := string(key) + if isRootIdKey(strKey) { + ids = append(ids, string(val)) + } + key, val, err = index.Next() + } + + if err != pogreb.ErrIterationDone { + return + } + err = nil + return +} + +func (s *spaceStorage) Close() (err error) { + return s.objDb.Close() +} diff --git a/client/storage/storageservice.go b/client/storage/storageservice.go new file mode 100644 index 00000000..ba9de309 --- /dev/null +++ b/client/storage/storageservice.go @@ -0,0 +1,34 @@ +package storage + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/app" + "github.com/anytypeio/go-anytype-infrastructure-experiments/client/badgerprovider" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage" + "github.com/dgraph-io/badger/v3" +) + +type storageService struct { + db *badger.DB +} + +func New() storage.SpaceStorageProvider { + return &storageService{} +} + +func (s *storageService) Init(a *app.App) (err error) { + provider := a.MustComponent(badgerprovider.CName).(badgerprovider.BadgerProvider) + s.db = provider.Badger() + return +} + +func (s *storageService) Name() (name string) { + return storage.CName +} + +func (s *storageService) SpaceStorage(id string) (storage.SpaceStorage, error) { + return newSpaceStorage(s.rootPath, id) +} + +func (s *storageService) CreateSpaceStorage(payload storage.SpaceStorageCreatePayload) (storage.SpaceStorage, error) { + return createSpaceStorage(s.rootPath, payload) +} diff --git a/client/storage/treestorage.go b/client/storage/treestorage.go new file mode 100644 index 00000000..6c6c0d57 --- /dev/null +++ b/client/storage/treestorage.go @@ -0,0 +1,181 @@ +package storage + +import ( + "bytes" + "context" + "github.com/akrylysov/pogreb" + "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/storage" + "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treechangeproto" + "strings" +) + +type treeStorage struct { + db *pogreb.DB + keys treeKeys + id string + root *treechangeproto.RawTreeChangeWithId +} + +func newTreeStorage(db *pogreb.DB, treeId string) (ts storage.TreeStorage, err error) { + keys := newTreeKeys(treeId) + has, err := db.Has(keys.RootIdKey()) + if err != nil { + return + } + if !has { + err = storage.ErrUnknownTreeId + return + } + + heads, err := db.Get(keys.HeadsKey()) + if err != nil { + return + } + if heads == nil { + err = storage.ErrUnknownTreeId + return + } + + root, err := db.Get(keys.RawChangeKey(treeId)) + if err != nil { + return + } + if root == nil { + err = storage.ErrUnknownTreeId + return + } + + rootWithId := &treechangeproto.RawTreeChangeWithId{ + RawChange: root, + Id: treeId, + } + if err != nil { + return + } + + ts = &treeStorage{ + db: db, + keys: keys, + id: treeId, + root: rootWithId, + } + return +} + +func createTreeStorage(db *pogreb.DB, payload storage.TreeStorageCreatePayload) (ts storage.TreeStorage, err error) { + keys := newTreeKeys(payload.TreeId) + has, err := db.Has(keys.RootIdKey()) + if err != nil { + return + } + if has { + err = storage.ErrTreeExists + return + } + + heads := createHeadsPayload(payload.Heads) + + for _, ch := range payload.Changes { + err = db.Put(keys.RawChangeKey(ch.Id), ch.GetRawChange()) + if err != nil { + return + } + } + + err = db.Put(keys.RawChangeKey(payload.RootRawChange.Id), payload.RootRawChange.GetRawChange()) + if err != nil { + return + } + + err = db.Put(keys.HeadsKey(), heads) + if err != nil { + return + } + + err = db.Put(keys.RootIdKey(), []byte(payload.RootRawChange.Id)) + if err != nil { + return + } + + ts = &treeStorage{ + db: db, + keys: keys, + id: payload.RootRawChange.Id, + root: payload.RootRawChange, + } + return +} + +func (t *treeStorage) ID() (string, error) { + return t.id, nil +} + +func (t *treeStorage) Root() (raw *treechangeproto.RawTreeChangeWithId, err error) { + return t.root, nil +} + +func (t *treeStorage) Heads() (heads []string, err error) { + headsBytes, err := t.db.Get(t.keys.HeadsKey()) + if err != nil { + return + } + if heads == nil { + err = storage.ErrUnknownTreeId + return + } + heads = parseHeads(headsBytes) + return +} + +func (t *treeStorage) SetHeads(heads []string) (err error) { + payload := createHeadsPayload(heads) + return t.db.Put(t.keys.HeadsKey(), payload) +} + +func (t *treeStorage) AddRawChange(change *treechangeproto.RawTreeChangeWithId) (err error) { + return t.db.Put([]byte(change.Id), change.RawChange) +} + +func (t *treeStorage) GetRawChange(ctx context.Context, id string) (raw *treechangeproto.RawTreeChangeWithId, err error) { + res, err := t.db.Get(t.keys.RawChangeKey(id)) + if err != nil { + return + } + if res == nil { + err = storage.ErrUnkownChange + } + + raw = &treechangeproto.RawTreeChangeWithId{ + RawChange: res, + Id: id, + } + return +} + +func (t *treeStorage) HasChange(ctx context.Context, id string) (bool, error) { + return t.db.Has(t.keys.RawChangeKey(id)) +} + +func parseHeads(headsPayload []byte) []string { + return strings.Split(string(headsPayload), "/") +} + +func createHeadsPayload(heads []string) []byte { + var ( + b bytes.Buffer + totalLen int + ) + for _, s := range heads { + totalLen += len(s) + } + // adding separators + totalLen += len(heads) - 1 + b.Grow(totalLen) + for idx, s := range heads { + if idx > 0 { + b.WriteString("/") + } + b.WriteString(s) + } + return b.Bytes() +} diff --git a/go.mod b/go.mod index 49dbf9e1..b234e89d 100644 --- a/go.mod +++ b/go.mod @@ -71,10 +71,13 @@ require ( go.uber.org/multierr v1.8.0 // indirect golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect golang.org/x/image v0.0.0-20200119044424-58c23975cae1 // indirect + golang.org/x/mod v0.4.2 // indirect golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 // indirect golang.org/x/text v0.3.7 // indirect + golang.org/x/tools v0.1.5 // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/protobuf v1.27.1 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 03ccc1fe..8af8e42b 100644 --- a/go.sum +++ b/go.sum @@ -229,6 +229,7 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -283,6 +284,7 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 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 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= 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= diff --git a/node/storage/keys.go b/node/storage/keys.go index 853cfdd8..7840334e 100644 --- a/node/storage/keys.go +++ b/node/storage/keys.go @@ -26,14 +26,12 @@ func (a aclKeys) RawRecordKey(id string) []byte { type treeKeys struct { id string headsKey []byte - rootKey []byte } func newTreeKeys(id string) treeKeys { return treeKeys{ id: id, headsKey: joinStringsToBytes("t", id, "heads"), - rootKey: joinStringsToBytes("t", id, "rootId"), } } @@ -41,10 +39,6 @@ func (t treeKeys) HeadsKey() []byte { return t.headsKey } -func (t treeKeys) RootIdKey() []byte { - return t.rootKey -} - func (t treeKeys) RawChangeKey(id string) []byte { return joinStringsToBytes("t", t.id, id) } diff --git a/node/storage/liststorage.go b/node/storage/liststorage.go index 989791b6..e4d99add 100644 --- a/node/storage/liststorage.go +++ b/node/storage/liststorage.go @@ -16,15 +16,6 @@ type listStorage struct { func newListStorage(db *pogreb.DB) (ls storage.ListStorage, err error) { keys := aclKeys{} - head, err := db.Get(keys.HeadIdKey()) - if err != nil { - return - } - if head == nil { - err = storage.ErrUnknownACLId - return - } - rootId, err := db.Get(keys.RootIdKey()) if err != nil { return diff --git a/node/storage/treestorage.go b/node/storage/treestorage.go index 6c6c0d57..a1253492 100644 --- a/node/storage/treestorage.go +++ b/node/storage/treestorage.go @@ -18,15 +18,6 @@ type treeStorage struct { func newTreeStorage(db *pogreb.DB, treeId string) (ts storage.TreeStorage, err error) { keys := newTreeKeys(treeId) - has, err := db.Has(keys.RootIdKey()) - if err != nil { - return - } - if !has { - err = storage.ErrUnknownTreeId - return - } - heads, err := db.Get(keys.HeadsKey()) if err != nil { return @@ -64,7 +55,7 @@ func newTreeStorage(db *pogreb.DB, treeId string) (ts storage.TreeStorage, err e func createTreeStorage(db *pogreb.DB, payload storage.TreeStorageCreatePayload) (ts storage.TreeStorage, err error) { keys := newTreeKeys(payload.TreeId) - has, err := db.Has(keys.RootIdKey()) + has, err := db.Has(keys.HeadsKey()) if err != nil { return } @@ -92,11 +83,6 @@ func createTreeStorage(db *pogreb.DB, payload storage.TreeStorageCreatePayload) return } - err = db.Put(keys.RootIdKey(), []byte(payload.RootRawChange.Id)) - if err != nil { - return - } - ts = &treeStorage{ db: db, keys: keys, diff --git a/pkg/acl/aclrecordproto/protos/aclrecord.proto b/pkg/acl/aclrecordproto/protos/aclrecord.proto index 4d2a969a..0da3b260 100644 --- a/pkg/acl/aclrecordproto/protos/aclrecord.proto +++ b/pkg/acl/aclrecordproto/protos/aclrecord.proto @@ -63,6 +63,15 @@ message ACLUserAdd { ACLUserPermissions permissions = 4; } +// signing accept key +// rsa encryption key -> read keys + +// accept key, encrypt key, invite id +// GetSpace(id) -> ... (space header + acl root) -> diff +// Join(ACLJoinRecord) -> Ok + +// + message ACLUserInvite { bytes acceptPublicKey = 1; bytes encryptPublicKey = 2; From 700e04cc14235f51210708e11c567796984b55ed Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Sun, 16 Oct 2022 10:13:17 +0200 Subject: [PATCH 17/20] Add transaction benchmarks for badger --- cmd/benchmarks/db/badger.go | 27 +++++++++++++++++++++++++++ cmd/benchmarks/db/common.go | 6 ++++++ cmd/benchmarks/db/pogreb.go | 4 ++++ cmd/benchmarks/dbbench.go | 32 ++++++++++++++++++++++++++++++-- 4 files changed, 67 insertions(+), 2 deletions(-) diff --git a/cmd/benchmarks/db/badger.go b/cmd/benchmarks/db/badger.go index 1487aafc..87bc01a2 100644 --- a/cmd/benchmarks/db/badger.go +++ b/cmd/benchmarks/db/badger.go @@ -11,6 +11,33 @@ type badgerTree struct { db *badger.DB } +type badgerTransaction struct { + spaceId string + id string + txn *badger.Txn +} + +func (b *badgerTransaction) AddChange(key string, value []byte) (err error) { + badgerKey := fmt.Sprintf("space/%s/tree/%s/change/%s", b.spaceId, b.id, key) + return b.txn.Set([]byte(badgerKey), value) +} + +func (b *badgerTransaction) GetChange(key string) (val []byte, err error) { + badgerKey := fmt.Sprintf("space/%s/tree/%s/change/%s", b.spaceId, b.id, key) + it, err := b.txn.Get([]byte(badgerKey)) + if err != nil { + return + } + return it.ValueCopy(val) +} + +func (b *badgerTree) Perform(f func(txn Transaction) error) error { + return b.db.Update(func(txn *badger.Txn) error { + bTxn := &badgerTransaction{b.spaceId, b.id, txn} + return f(bTxn) + }) +} + func (b *badgerTree) Id() string { return b.id } diff --git a/cmd/benchmarks/db/common.go b/cmd/benchmarks/db/common.go index d690473c..0443e3f6 100644 --- a/cmd/benchmarks/db/common.go +++ b/cmd/benchmarks/db/common.go @@ -1,11 +1,17 @@ package db +type Transaction interface { + AddChange(key string, value []byte) (err error) + GetChange(key string) ([]byte, error) +} + type Tree interface { Id() string UpdateHead(head string) (err error) AddChange(key string, value []byte) (err error) GetChange(key string) ([]byte, error) HasChange(key string) (has bool, err error) + Perform(func(txn Transaction) error) error } type Space interface { diff --git a/cmd/benchmarks/db/pogreb.go b/cmd/benchmarks/db/pogreb.go index 7cc9759a..2edca852 100644 --- a/cmd/benchmarks/db/pogreb.go +++ b/cmd/benchmarks/db/pogreb.go @@ -12,6 +12,10 @@ type pogrebTree struct { db *pogreb.DB } +func (p *pogrebTree) Perform(f func(txn Transaction) error) error { + return f(p) +} + func (p *pogrebTree) Id() string { return p.id } diff --git a/cmd/benchmarks/dbbench.go b/cmd/benchmarks/dbbench.go index c3db3601..faa06943 100644 --- a/cmd/benchmarks/dbbench.go +++ b/cmd/benchmarks/dbbench.go @@ -17,9 +17,9 @@ func main() { fmt.Println(http.ListenAndServe("localhost:6060", nil)) }() opts := options{ - numSpaces: 1000, + numSpaces: 10, numEntriesInSpace: 100, - numChangesInTree: 10, + numChangesInTree: 1000, numHeadUpdates: 100, defValueSize: 1000, lenHeadUpdate: 1000, @@ -105,6 +105,15 @@ func bench(factory db.SpaceCreatorFactory, opts options) { panic(err) } } + //t.Perform(func(txn db.Transaction) error { + // for i := 0; i < opts.numChangesInTree; i++ { + // err := t.AddChange(changeIdKey(i), byteSlice()) + // if err != nil { + // panic(err) + // } + // } + // return nil + //}) for i := 0; i < opts.numHeadUpdates; i++ { err := t.UpdateHead(string(headUpdate())) if err != nil { @@ -116,6 +125,25 @@ func bench(factory db.SpaceCreatorFactory, opts options) { fmt.Println(total, "changes creation, spent ms", time.Now().Sub(now).Milliseconds()) now = time.Now() + // getting some values from tree + for _, t := range trees { + err := t.Perform(func(txn db.Transaction) error { + for i := 0; i < opts.numChangesInTree; i++ { + _, err := t.GetChange(changeIdKey(i)) + if err != nil { + return err + } + } + return nil + }) + if err != nil { + panic(err) + } + } + + fmt.Println(total, "changes getting perform, spent ms", time.Now().Sub(now).Milliseconds()) + now = time.Now() + // getting some values from tree for _, t := range trees { for i := 0; i < opts.numChangesInTree; i++ { From a2d2c61f1e560281db15167d4da2912a35dd0fba Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Sun, 16 Oct 2022 16:41:01 +0200 Subject: [PATCH 18/20] Further wip badger --- client/badgerprovider/helpers.go | 46 ++------ client/storage/keys.go | 42 +++---- client/storage/liststorage.go | 49 +++------ client/storage/spacestorage.go | 155 +++++++++++--------------- client/storage/storageservice.go | 4 +- client/storage/treestorage.go | 183 ++++++++++++------------------- node/storage/keys.go | 30 +---- node/storage/liststorage.go | 3 +- node/storage/treestorage.go | 38 +------ pkg/acl/storage/helpers.go | 34 ++++++ 10 files changed, 215 insertions(+), 369 deletions(-) create mode 100644 pkg/acl/storage/helpers.go diff --git a/client/badgerprovider/helpers.go b/client/badgerprovider/helpers.go index 96ed8acf..afaf5da4 100644 --- a/client/badgerprovider/helpers.go +++ b/client/badgerprovider/helpers.go @@ -7,16 +7,11 @@ import ( var ErrIncorrectKey = errors.New("the key is incorrect") -func Has(db *badger.DB, key []byte) (has bool, err error) { - err = db.View(func(txn *badger.Txn) error { +func Has(db *badger.DB, key []byte) bool { + return db.View(func(txn *badger.Txn) error { _, err := txn.Get(key) return err - }) - if err != nil { - return - } - has = true - return + }) == nil } func Put(db *badger.DB, key, value []byte) (err error) { @@ -40,37 +35,10 @@ func Get(db *badger.DB, key []byte) (value []byte, err error) { return } -func GetKeySuffix(txn *badger.Txn, keyPrefix []byte) (suffix []byte, err error) { - iter := txn.NewIterator(badger.IteratorOptions{Prefix: keyPrefix}) - iter.Next() - if !iter.Valid() { - err = badger.ErrKeyNotFound +func GetAndCopy(txn *badger.Txn, key []byte) (value []byte, err error) { + item, err := txn.Get(key) + if err != nil { return } - - suffix = iter.Item().Key() - if len(suffix) <= len(keyPrefix)+1 { - err = ErrIncorrectKey - return - } - suffix = suffix[len(keyPrefix)+1:] - return -} - -func GetKeySuffixAndValue(txn *badger.Txn, keyPrefix []byte) (suffix []byte, value []byte, err error) { - iter := txn.NewIterator(badger.IteratorOptions{Prefix: keyPrefix}) - iter.Next() - if !iter.Valid() { - err = badger.ErrKeyNotFound - return - } - - suffix = iter.Item().Key() - if len(suffix) <= len(keyPrefix)+1 { - err = ErrIncorrectKey - return - } - suffix = suffix[len(keyPrefix)+1:] - value, err = iter.Item().ValueCopy(value) - return + return item.ValueCopy(value) } diff --git a/client/storage/keys.go b/client/storage/keys.go index 5ee5958f..08749a89 100644 --- a/client/storage/keys.go +++ b/client/storage/keys.go @@ -1,7 +1,7 @@ package storage import ( - "bytes" + "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/storage" ) type aclKeys struct { @@ -13,8 +13,8 @@ type aclKeys struct { func newACLKeys(spaceId string) aclKeys { return aclKeys{ spaceId: spaceId, - rootKey: joinStringsToBytes("space", spaceId, "a", "rootId"), - headKey: joinStringsToBytes("space", spaceId, "a", "headId"), + rootKey: storage.JoinStringsToBytes("space", spaceId, "a", "rootId"), + headKey: storage.JoinStringsToBytes("space", spaceId, "a", "headId"), } } @@ -27,7 +27,7 @@ func (a aclKeys) RootIdKey() []byte { } func (a aclKeys) RawRecordKey(id string) []byte { - return joinStringsToBytes("space", a.spaceId, "a", id) + return storage.JoinStringsToBytes("space", a.spaceId, "a", id) } type treeKeys struct { @@ -41,8 +41,8 @@ func newTreeKeys(spaceId, id string) treeKeys { return treeKeys{ id: id, spaceId: spaceId, - headsKey: joinStringsToBytes("space", spaceId, "t", id, "heads"), - rootKey: joinStringsToBytes("space", spaceId, "t", id), + headsKey: storage.JoinStringsToBytes("space", spaceId, "t", id, "heads"), + rootKey: storage.JoinStringsToBytes("space", spaceId, "t", "rootId", id), } } @@ -55,37 +55,25 @@ func (t treeKeys) RootIdKey() []byte { } func (t treeKeys) RawChangeKey(id string) []byte { - return joinStringsToBytes("space", t.spaceId, "t", t.id, id) + return storage.JoinStringsToBytes("space", t.spaceId, "t", t.id, id) } type spaceKeys struct { - headerKey []byte + headerKey []byte + treePrefixKey []byte } func newSpaceKeys(spaceId string) spaceKeys { - return spaceKeys{headerKey: joinStringsToBytes("space", spaceId)} + return spaceKeys{ + headerKey: storage.JoinStringsToBytes("space", spaceId), + treePrefixKey: storage.JoinStringsToBytes("space", spaceId, "t", "rootId"), + } } func (s spaceKeys) HeaderKey() []byte { return s.headerKey } -func joinStringsToBytes(strs ...string) []byte { - var ( - b bytes.Buffer - totalLen int - ) - for _, s := range strs { - totalLen += len(s) - } - // adding separators - totalLen += len(strs) - 1 - b.Grow(totalLen) - for idx, s := range strs { - if idx > 0 { - b.WriteString("/") - } - b.WriteString(s) - } - return b.Bytes() +func (s spaceKeys) TreeRootPrefix() []byte { + return s.treePrefixKey } diff --git a/client/storage/liststorage.go b/client/storage/liststorage.go index 30910d65..edb9a17d 100644 --- a/client/storage/liststorage.go +++ b/client/storage/liststorage.go @@ -20,23 +20,13 @@ type listStorage struct { func newListStorage(spaceId string, db *badger.DB, txn *badger.Txn) (ls storage.ListStorage, err error) { keys := newACLKeys(spaceId) - rootId, err := provider.GetKeySuffix(txn, keys.RootIdKey()) + rootId, err := provider.GetAndCopy(txn, keys.RootIdKey()) if err != nil { - if err == badger.ErrKeyNotFound { - err = storage.ErrUnknownACLId - } return } + stringId := string(rootId) - rootItem, err := txn.Get(keys.RawRecordKey(stringId)) - if err != nil { - if err == badger.ErrKeyNotFound { - err = storage.ErrUnknownACLId - } - return - } - var value []byte - value, err = rootItem.ValueCopy(value) + value, err := provider.GetAndCopy(txn, keys.RawRecordKey(stringId)) if err != nil { return } @@ -57,19 +47,11 @@ func newListStorage(spaceId string, db *badger.DB, txn *badger.Txn) (ls storage. func createListStorage(spaceId string, db *badger.DB, txn *badger.Txn, root *aclrecordproto.RawACLRecordWithId) (ls storage.ListStorage, err error) { keys := newACLKeys(spaceId) - _, err = provider.GetKeySuffix(txn, keys.RootIdKey()) - if err != nil && err != badger.ErrKeyNotFound { - return - } - if err == nil { - err = storage.ErrACLExists - return - } - aclRootKey := append(keys.RootIdKey(), '/') - aclRootKey = append(aclRootKey, []byte(root.Id)...) - - err = txn.Set(aclRootKey, nil) - if err != nil { + _, err = provider.GetAndCopy(txn, keys.RootIdKey()) + if err != badger.ErrKeyNotFound { + if err == nil { + return newListStorage(spaceId, db, txn) + } return } @@ -82,6 +64,10 @@ func createListStorage(spaceId string, db *badger.DB, txn *badger.Txn, root *acl if err != nil { return } + err = txn.Set(keys.RootIdKey(), []byte(root.Id)) + if err != nil { + return + } ls = &listStorage{ db: db, @@ -110,12 +96,11 @@ func (l *listStorage) Head() (head string, err error) { } func (l *listStorage) GetRawRecord(ctx context.Context, id string) (raw *aclrecordproto.RawACLRecordWithId, err error) { - res, err := l.db.Get(l.keys.RawRecordKey(id)) + res, err := provider.Get(l.db, l.keys.RawRecordKey(id)) if err != nil { - return - } - if res == nil { - err = storage.ErrUnknownRecord + if err == badger.ErrKeyNotFound { + err = storage.ErrUnknownRecord + } return } @@ -127,5 +112,5 @@ func (l *listStorage) GetRawRecord(ctx context.Context, id string) (raw *aclreco } func (l *listStorage) AddRawRecord(ctx context.Context, rec *aclrecordproto.RawACLRecordWithId) error { - return l.db.Put([]byte(rec.Id), rec.Payload) + return provider.Put(l.db, []byte(rec.Id), rec.Payload) } diff --git a/client/storage/spacestorage.go b/client/storage/spacestorage.go index 1affdc14..5fb03f72 100644 --- a/client/storage/spacestorage.go +++ b/client/storage/spacestorage.go @@ -1,23 +1,17 @@ package storage import ( - "github.com/akrylysov/pogreb" provider "github.com/anytypeio/go-anytype-infrastructure-experiments/client/badgerprovider" "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/pkg/acl/storage" "github.com/dgraph-io/badger/v3" - "path" "sync" - "time" ) -var defPogrebOptions = &pogreb.Options{ - BackgroundCompactionInterval: time.Minute * 5, -} - type spaceStorage struct { - objDb *pogreb.DB + spaceId string + objDb *badger.DB keys spaceKeys aclStorage storage.ListStorage header *spacesyncproto.RawSpaceHeaderWithId @@ -26,97 +20,66 @@ type spaceStorage struct { func newSpaceStorage(objDb *badger.DB, spaceId string) (store spacestorage.SpaceStorage, err error) { keys := newSpaceKeys(spaceId) - err = objDb.Update(func(txn *badger.Txn) error { - header, err := txn.Get(keys.HeaderKey()) + err = objDb.View(func(txn *badger.Txn) error { + header, err := provider.GetAndCopy(txn, keys.HeaderKey()) if err != nil { return err } + aclStorage, err := newListStorage(spaceId, objDb, txn) + if err != nil { + return err + } + + store = &spaceStorage{ + spaceId: spaceId, + objDb: objDb, + keys: keys, + header: &spacesyncproto.RawSpaceHeaderWithId{ + RawHeader: header, + Id: spaceId, + }, + aclStorage: aclStorage, + } + return nil }) - has, err := provider.Has(obj) - if err != nil { - return - } - if !has { - err = spacestorage.ErrSpaceStorageMissing - return - } - - header, err := objDb.Get(keys.HeaderKey()) - if err != nil { - return - } - if header == nil { - err = spacestorage.ErrSpaceStorageMissing - return - } - - aclStorage, err := newListStorage(objDb) - if err != nil { - return - } - - store = &spaceStorage{ - objDb: objDb, - keys: keys, - header: &spacesyncproto.RawSpaceHeaderWithId{ - RawHeader: header, - Id: spaceId, - }, - aclStorage: aclStorage, + if err == badger.ErrKeyNotFound { + err = spacesyncproto.ErrSpaceMissing } return } -func createSpaceStorage(rootPath string, payload spacestorage.SpaceStorageCreatePayload) (store spacestorage.SpaceStorage, err error) { - dbPath := path.Join(rootPath, payload.SpaceHeaderWithId.Id) - db, err := pogreb.Open(dbPath, defPogrebOptions) - if err != nil { - return - } - - defer func() { - if err != nil { - db.Close() - } - }() - +func createSpaceStorage(db *badger.DB, payload spacestorage.SpaceStorageCreatePayload) (store spacestorage.SpaceStorage, err error) { keys := newSpaceKeys(payload.SpaceHeaderWithId.Id) - has, err := db.Has(keys.SpaceIdKey()) - if err != nil { - return - } - if has { + if provider.Has(db, keys.HeaderKey()) { err = spacesyncproto.ErrSpaceExists return } + err = db.Update(func(txn *badger.Txn) error { + aclStorage, err := createListStorage(payload.SpaceHeaderWithId.Id, db, txn, payload.RecWithId) + if err != nil { + return err + } - aclStorage, err := createListStorage(db, payload.RecWithId) - if err != nil { - return - } + err = txn.Set(keys.HeaderKey(), payload.SpaceHeaderWithId.RawHeader) + if err != nil { + return err + } - err = db.Put(keys.HeaderKey(), payload.SpaceHeaderWithId.RawHeader) - if err != nil { - return - } - - err = db.Put(keys.SpaceIdKey(), []byte(payload.SpaceHeaderWithId.Id)) - if err != nil { - return - } - - store = &spaceStorage{ - objDb: db, - keys: keys, - aclStorage: aclStorage, - header: payload.SpaceHeaderWithId, - } + store = &spaceStorage{ + spaceId: payload.SpaceHeaderWithId.Id, + objDb: db, + keys: keys, + aclStorage: aclStorage, + header: payload.SpaceHeaderWithId, + } + return nil + }) return } func (s *spaceStorage) TreeStorage(id string) (storage.TreeStorage, error) { - return newTreeStorage(s.objDb, id) + return newTreeStorage(s.objDb, s.spaceId, id) } func (s *spaceStorage) CreateTreeStorage(payload storage.TreeStorageCreatePayload) (ts storage.TreeStorage, err error) { @@ -124,7 +87,7 @@ func (s *spaceStorage) CreateTreeStorage(payload storage.TreeStorageCreatePayloa s.mx.Lock() defer s.mx.Unlock() - return createTreeStorage(s.objDb, payload) + return createTreeStorage(s.objDb, s.spaceId, payload) } func (s *spaceStorage) ACLStorage() (storage.ListStorage, error) { @@ -136,21 +99,25 @@ func (s *spaceStorage) SpaceHeader() (header *spacesyncproto.RawSpaceHeaderWithI } func (s *spaceStorage) StoredIds() (ids []string, err error) { - index := s.objDb.Items() + err = s.objDb.View(func(txn *badger.Txn) error { + opts := badger.DefaultIteratorOptions + opts.PrefetchValues = false + opts.Prefix = s.keys.TreeRootPrefix() - key, val, err := index.Next() - for err == nil { - strKey := string(key) - if isRootIdKey(strKey) { - ids = append(ids, string(val)) + it := txn.NewIterator(opts) + defer it.Close() + + for it.Rewind(); it.Valid(); it.Next() { + item := it.Item() + id := item.Key() + if len(id) <= len(s.keys.TreeRootPrefix())+1 { + continue + } + id = id[len(s.keys.TreeRootPrefix())+1:] + ids = append(ids, string(id)) } - key, val, err = index.Next() - } - - if err != pogreb.ErrIterationDone { - return - } - err = nil + return nil + }) return } diff --git a/client/storage/storageservice.go b/client/storage/storageservice.go index ba9de309..0cc9250e 100644 --- a/client/storage/storageservice.go +++ b/client/storage/storageservice.go @@ -26,9 +26,9 @@ func (s *storageService) Name() (name string) { } func (s *storageService) SpaceStorage(id string) (storage.SpaceStorage, error) { - return newSpaceStorage(s.rootPath, id) + return newSpaceStorage(s.db, id) } func (s *storageService) CreateSpaceStorage(payload storage.SpaceStorageCreatePayload) (storage.SpaceStorage, error) { - return createSpaceStorage(s.rootPath, payload) + return createSpaceStorage(s.db, payload) } diff --git a/client/storage/treestorage.go b/client/storage/treestorage.go index 6c6c0d57..aea492ac 100644 --- a/client/storage/treestorage.go +++ b/client/storage/treestorage.go @@ -1,108 +1,88 @@ package storage import ( - "bytes" "context" - "github.com/akrylysov/pogreb" + provider "github.com/anytypeio/go-anytype-infrastructure-experiments/client/badgerprovider" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/storage" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treechangeproto" - "strings" + "github.com/dgraph-io/badger/v3" ) type treeStorage struct { - db *pogreb.DB + db *badger.DB keys treeKeys id string root *treechangeproto.RawTreeChangeWithId } -func newTreeStorage(db *pogreb.DB, treeId string) (ts storage.TreeStorage, err error) { - keys := newTreeKeys(treeId) - has, err := db.Has(keys.RootIdKey()) - if err != nil { - return - } - if !has { - err = storage.ErrUnknownTreeId - return - } +func newTreeStorage(db *badger.DB, spaceId, treeId string) (ts storage.TreeStorage, err error) { + keys := newTreeKeys(spaceId, treeId) + err = db.View(func(txn *badger.Txn) error { + _, err := txn.Get(keys.RootIdKey()) + if err != nil { + return err + } - heads, err := db.Get(keys.HeadsKey()) - if err != nil { - return - } - if heads == nil { - err = storage.ErrUnknownTreeId - return - } + root, err := provider.GetAndCopy(txn, keys.RawChangeKey(treeId)) + if err != nil { + return err + } - root, err := db.Get(keys.RawChangeKey(treeId)) - if err != nil { - return - } - if root == nil { - err = storage.ErrUnknownTreeId - return - } + rootWithId := &treechangeproto.RawTreeChangeWithId{ + RawChange: root, + Id: treeId, + } - rootWithId := &treechangeproto.RawTreeChangeWithId{ - RawChange: root, - Id: treeId, - } - if err != nil { - return - } - - ts = &treeStorage{ - db: db, - keys: keys, - id: treeId, - root: rootWithId, - } + ts = &treeStorage{ + db: db, + keys: keys, + id: treeId, + root: rootWithId, + } + return nil + }) return } -func createTreeStorage(db *pogreb.DB, payload storage.TreeStorageCreatePayload) (ts storage.TreeStorage, err error) { - keys := newTreeKeys(payload.TreeId) - has, err := db.Has(keys.RootIdKey()) - if err != nil { - return - } - if has { +func createTreeStorage(db *badger.DB, spaceId string, payload storage.TreeStorageCreatePayload) (ts storage.TreeStorage, err error) { + keys := newTreeKeys(spaceId, payload.TreeId) + if provider.Has(db, keys.RootIdKey()) { err = storage.ErrTreeExists return } + err = db.Update(func(txn *badger.Txn) error { + heads := storage.CreateHeadsPayload(payload.Heads) - heads := createHeadsPayload(payload.Heads) - - for _, ch := range payload.Changes { - err = db.Put(keys.RawChangeKey(ch.Id), ch.GetRawChange()) - if err != nil { - return + for _, ch := range payload.Changes { + err = txn.Set(keys.RawChangeKey(ch.Id), ch.GetRawChange()) + if err != nil { + return err + } } - } - err = db.Put(keys.RawChangeKey(payload.RootRawChange.Id), payload.RootRawChange.GetRawChange()) - if err != nil { - return - } + err = txn.Set(keys.RawChangeKey(payload.RootRawChange.Id), payload.RootRawChange.GetRawChange()) + if err != nil { + return err + } - err = db.Put(keys.HeadsKey(), heads) - if err != nil { - return - } + err = txn.Set(keys.HeadsKey(), heads) + if err != nil { + return err + } - err = db.Put(keys.RootIdKey(), []byte(payload.RootRawChange.Id)) - if err != nil { - return - } + err = txn.Set(keys.RootIdKey(), nil) + if err != nil { + return err + } - ts = &treeStorage{ - db: db, - keys: keys, - id: payload.RootRawChange.Id, - root: payload.RootRawChange, - } + ts = &treeStorage{ + db: db, + keys: keys, + id: payload.RootRawChange.Id, + root: payload.RootRawChange, + } + return nil + }) return } @@ -115,35 +95,34 @@ func (t *treeStorage) Root() (raw *treechangeproto.RawTreeChangeWithId, err erro } func (t *treeStorage) Heads() (heads []string, err error) { - headsBytes, err := t.db.Get(t.keys.HeadsKey()) + headsBytes, err := provider.Get(t.db, t.keys.HeadsKey()) if err != nil { + if err == badger.ErrKeyNotFound { + err = storage.ErrUnknownTreeId + } return } - if heads == nil { - err = storage.ErrUnknownTreeId - return - } - heads = parseHeads(headsBytes) + heads = storage.ParseHeads(headsBytes) return } func (t *treeStorage) SetHeads(heads []string) (err error) { - payload := createHeadsPayload(heads) - return t.db.Put(t.keys.HeadsKey(), payload) + payload := storage.CreateHeadsPayload(heads) + return provider.Put(t.db, t.keys.HeadsKey(), payload) } func (t *treeStorage) AddRawChange(change *treechangeproto.RawTreeChangeWithId) (err error) { - return t.db.Put([]byte(change.Id), change.RawChange) + return provider.Put(t.db, t.keys.RawChangeKey(change.Id), change.RawChange) } func (t *treeStorage) GetRawChange(ctx context.Context, id string) (raw *treechangeproto.RawTreeChangeWithId, err error) { - res, err := t.db.Get(t.keys.RawChangeKey(id)) + res, err := provider.Get(t.db, t.keys.RawChangeKey(id)) if err != nil { + if err == badger.ErrKeyNotFound { + err = storage.ErrUnknownTreeId + } return } - if res == nil { - err = storage.ErrUnkownChange - } raw = &treechangeproto.RawTreeChangeWithId{ RawChange: res, @@ -153,29 +132,5 @@ func (t *treeStorage) GetRawChange(ctx context.Context, id string) (raw *treecha } func (t *treeStorage) HasChange(ctx context.Context, id string) (bool, error) { - return t.db.Has(t.keys.RawChangeKey(id)) -} - -func parseHeads(headsPayload []byte) []string { - return strings.Split(string(headsPayload), "/") -} - -func createHeadsPayload(heads []string) []byte { - var ( - b bytes.Buffer - totalLen int - ) - for _, s := range heads { - totalLen += len(s) - } - // adding separators - totalLen += len(heads) - 1 - b.Grow(totalLen) - for idx, s := range heads { - if idx > 0 { - b.WriteString("/") - } - b.WriteString(s) - } - return b.Bytes() + return provider.Has(t.db, t.keys.RawChangeKey(id)), nil } diff --git a/node/storage/keys.go b/node/storage/keys.go index 7840334e..fe12046a 100644 --- a/node/storage/keys.go +++ b/node/storage/keys.go @@ -1,7 +1,7 @@ package storage import ( - "bytes" + "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/storage" "strings" ) @@ -20,7 +20,7 @@ func (a aclKeys) RootIdKey() []byte { } func (a aclKeys) RawRecordKey(id string) []byte { - return joinStringsToBytes("a", id) + return storage.JoinStringsToBytes("a", id) } type treeKeys struct { @@ -31,7 +31,7 @@ type treeKeys struct { func newTreeKeys(id string) treeKeys { return treeKeys{ id: id, - headsKey: joinStringsToBytes("t", id, "heads"), + headsKey: storage.JoinStringsToBytes("t", id, "heads"), } } @@ -40,7 +40,7 @@ func (t treeKeys) HeadsKey() []byte { } func (t treeKeys) RawChangeKey(id string) []byte { - return joinStringsToBytes("t", t.id, id) + return storage.JoinStringsToBytes("t", t.id, id) } type spaceKeys struct { @@ -48,7 +48,7 @@ type spaceKeys struct { } func newSpaceKeys(spaceId string) spaceKeys { - return spaceKeys{headerKey: joinStringsToBytes("s", spaceId)} + return spaceKeys{headerKey: storage.JoinStringsToBytes("s", spaceId)} } var spaceIdKey = []byte("spaceId") @@ -64,23 +64,3 @@ func (s spaceKeys) HeaderKey() []byte { func isRootIdKey(key string) bool { return strings.HasPrefix(key, "t/") && strings.HasSuffix(key, "rootId") } - -func joinStringsToBytes(strs ...string) []byte { - var ( - b bytes.Buffer - totalLen int - ) - for _, s := range strs { - totalLen += len(s) - } - // adding separators - totalLen += len(strs) - 1 - b.Grow(totalLen) - for idx, s := range strs { - if idx > 0 { - b.WriteString("/") - } - b.WriteString(s) - } - return b.Bytes() -} diff --git a/node/storage/liststorage.go b/node/storage/liststorage.go index e4d99add..966f3fe0 100644 --- a/node/storage/liststorage.go +++ b/node/storage/liststorage.go @@ -55,8 +55,7 @@ func createListStorage(db *pogreb.DB, root *aclrecordproto.RawACLRecordWithId) ( return } if has { - err = storage.ErrACLExists - return + return newListStorage(db) } err = db.Put(keys.HeadIdKey(), []byte(root.Id)) diff --git a/node/storage/treestorage.go b/node/storage/treestorage.go index a1253492..f600b6a2 100644 --- a/node/storage/treestorage.go +++ b/node/storage/treestorage.go @@ -1,12 +1,10 @@ package storage import ( - "bytes" "context" "github.com/akrylysov/pogreb" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/storage" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treechangeproto" - "strings" ) type treeStorage struct { @@ -40,10 +38,6 @@ func newTreeStorage(db *pogreb.DB, treeId string) (ts storage.TreeStorage, err e RawChange: root, Id: treeId, } - if err != nil { - return - } - ts = &treeStorage{ db: db, keys: keys, @@ -64,7 +58,7 @@ func createTreeStorage(db *pogreb.DB, payload storage.TreeStorageCreatePayload) return } - heads := createHeadsPayload(payload.Heads) + heads := storage.CreateHeadsPayload(payload.Heads) for _, ch := range payload.Changes { err = db.Put(keys.RawChangeKey(ch.Id), ch.GetRawChange()) @@ -109,17 +103,17 @@ func (t *treeStorage) Heads() (heads []string, err error) { err = storage.ErrUnknownTreeId return } - heads = parseHeads(headsBytes) + heads = storage.ParseHeads(headsBytes) return } func (t *treeStorage) SetHeads(heads []string) (err error) { - payload := createHeadsPayload(heads) + payload := storage.CreateHeadsPayload(heads) return t.db.Put(t.keys.HeadsKey(), payload) } func (t *treeStorage) AddRawChange(change *treechangeproto.RawTreeChangeWithId) (err error) { - return t.db.Put([]byte(change.Id), change.RawChange) + return t.db.Put(t.keys.RawChangeKey(change.Id), change.RawChange) } func (t *treeStorage) GetRawChange(ctx context.Context, id string) (raw *treechangeproto.RawTreeChangeWithId, err error) { @@ -141,27 +135,3 @@ func (t *treeStorage) GetRawChange(ctx context.Context, id string) (raw *treecha func (t *treeStorage) HasChange(ctx context.Context, id string) (bool, error) { return t.db.Has(t.keys.RawChangeKey(id)) } - -func parseHeads(headsPayload []byte) []string { - return strings.Split(string(headsPayload), "/") -} - -func createHeadsPayload(heads []string) []byte { - var ( - b bytes.Buffer - totalLen int - ) - for _, s := range heads { - totalLen += len(s) - } - // adding separators - totalLen += len(heads) - 1 - b.Grow(totalLen) - for idx, s := range heads { - if idx > 0 { - b.WriteString("/") - } - b.WriteString(s) - } - return b.Bytes() -} diff --git a/pkg/acl/storage/helpers.go b/pkg/acl/storage/helpers.go new file mode 100644 index 00000000..7796a15f --- /dev/null +++ b/pkg/acl/storage/helpers.go @@ -0,0 +1,34 @@ +package storage + +import ( + "bytes" + "strings" +) + +func ParseHeads(headsPayload []byte) []string { + return strings.Split(string(headsPayload), "/") +} + +func CreateHeadsPayload(heads []string) []byte { + return JoinStringsToBytes(heads...) +} + +func JoinStringsToBytes(strs ...string) []byte { + var ( + b bytes.Buffer + totalLen int + ) + for _, s := range strs { + totalLen += len(s) + } + // adding separators + totalLen += len(strs) - 1 + b.Grow(totalLen) + for idx, s := range strs { + if idx > 0 { + b.WriteString("/") + } + b.WriteString(s) + } + return b.Bytes() +} From 0013f64c6190b34abe11dce67d8635bf0621fe5b Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Sun, 16 Oct 2022 17:59:16 +0200 Subject: [PATCH 19/20] Add preliminary API and fix space service methods --- client/api/controller.go | 18 ++++++++++++++++++ common/commonspace/service.go | 6 ++---- 2 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 client/api/controller.go diff --git a/client/api/controller.go b/client/api/controller.go new file mode 100644 index 00000000..e39e3fc4 --- /dev/null +++ b/client/api/controller.go @@ -0,0 +1,18 @@ +package api + +type Controller interface { + CreateDerivedSpace() (id string, err error) + CreateSpace() (id string, err error) + GetAllSpacesIds() (ids []string, err error) + // LoadSpace asks node to load a particular space + LoadSpace(id string) (err error) + + CreateDocument(spaceId string) (id string, err error) + GetAllDocumentIds(spaceId string) (ids []string, err error) + AddText(documentId, text string) (err error) + DumpDocumentTree(documentId string) (err error) + + GetValidInvites(spaceId string) (invites []string, err error) + GenerateInvite(spaceId string) (invite string, err error) + JoinSpace(invite string) (err error) +} diff --git a/common/commonspace/service.go b/common/commonspace/service.go index dd0347a1..c7c27081 100644 --- a/common/commonspace/service.go +++ b/common/commonspace/service.go @@ -22,8 +22,8 @@ func New() Service { } type Service interface { - CreateSpace(ctx context.Context, cache cache.TreeCache, payload SpaceCreatePayload) (Space, error) - DeriveSpace(ctx context.Context, cache cache.TreeCache, payload SpaceDerivePayload) (Space, error) + DeriveSpace(ctx context.Context, payload SpaceDerivePayload) (Space, error) + CreateSpace(ctx context.Context, payload SpaceCreatePayload) (Space, error) GetSpace(ctx context.Context, id string) (sp Space, err error) app.Component } @@ -51,7 +51,6 @@ func (s *service) Name() (name string) { func (s *service) CreateSpace( ctx context.Context, - cache cache.TreeCache, payload SpaceCreatePayload) (sp Space, err error) { storageCreate, err := storagePayloadForSpaceCreate(payload) if err != nil { @@ -67,7 +66,6 @@ func (s *service) CreateSpace( func (s *service) DeriveSpace( ctx context.Context, - cache cache.TreeCache, payload SpaceDerivePayload) (sp Space, err error) { storageCreate, err := storagePayloadForSpaceDerive(payload) if err != nil { From d80986e6d0c0df665433611285983a9fa26bdf24 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Mon, 17 Oct 2022 12:40:55 +0200 Subject: [PATCH 20/20] Change space service methods and change list storage --- client/api/controller.go | 4 ++- client/clientspace/clientcache/treecache.go | 3 +- client/clientspace/service.go | 28 +++++++++++++++++++ client/document/service.go | 13 +++++++++ client/{badgerprovider => storage}/helpers.go | 13 ++++----- client/storage/liststorage.go | 19 +++++++------ client/storage/spacestorage.go | 9 ++++-- client/storage/treestorage.go | 15 +++++----- common/commonspace/service.go | 16 +++++------ common/commonspace/space.go | 13 ++++++--- .../storage/mock_storage/mock_storage.go | 15 ++++++++++ common/commonspace/storage/storage.go | 1 + node/storage/liststorage.go | 8 ++++-- node/storage/spacestorage.go | 11 ++++++-- pkg/acl/storage/inmemory.go | 4 +++ pkg/acl/storage/liststorage.go | 1 + pkg/acl/storage/mock_storage/mock_storage.go | 14 ++++++++++ .../acllistbuilder/liststoragebuilder.go | 4 +++ 18 files changed, 145 insertions(+), 46 deletions(-) create mode 100644 client/document/service.go rename client/{badgerprovider => storage}/helpers.go (61%) diff --git a/client/api/controller.go b/client/api/controller.go index e39e3fc4..51629007 100644 --- a/client/api/controller.go +++ b/client/api/controller.go @@ -1,7 +1,9 @@ package api type Controller interface { - CreateDerivedSpace() (id string, err error) + // DeriveSpace derives the space from current account + DeriveSpace() (id string, err error) + // CreateSpace creates new space with random data CreateSpace() (id string, err error) GetAllSpacesIds() (ids []string, err error) // LoadSpace asks node to load a particular space diff --git a/client/clientspace/clientcache/treecache.go b/client/clientspace/clientcache/treecache.go index eee57452..01e230b2 100644 --- a/client/clientspace/clientcache/treecache.go +++ b/client/clientspace/clientcache/treecache.go @@ -7,7 +7,6 @@ import ( "github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger" "github.com/anytypeio/go-anytype-infrastructure-experiments/client/clientspace" "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/cache" - "github.com/anytypeio/go-anytype-infrastructure-experiments/node/nodespace" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/ocache" "time" ) @@ -40,7 +39,7 @@ func (c *treeCache) Close(ctx context.Context) (err error) { } func (c *treeCache) Init(a *app.App) (err error) { - c.clientService = a.MustComponent(nodespace.CName).(nodespace.Service) + c.clientService = a.MustComponent(clientspace.CName).(clientspace.Service) c.cache = ocache.New( func(ctx context.Context, id string) (value ocache.Object, err error) { spaceId := ctx.Value(spaceKey).(string) diff --git a/client/clientspace/service.go b/client/clientspace/service.go index 3fcebc1b..4da8b2e8 100644 --- a/client/clientspace/service.go +++ b/client/clientspace/service.go @@ -23,6 +23,8 @@ func New() Service { type Service interface { GetSpace(ctx context.Context, id string) (commonspace.Space, error) + CreateSpace(ctx context.Context, payload commonspace.SpaceCreatePayload) (commonspace.Space, error) + DeriveSpace(ctx context.Context, payload commonspace.SpaceDerivePayload) (commonspace.Space, error) app.ComponentRunnable } @@ -61,6 +63,32 @@ func (s *service) Run(ctx context.Context) (err error) { return } +func (s *service) CreateSpace(ctx context.Context, payload commonspace.SpaceCreatePayload) (space commonspace.Space, err error) { + id, err := s.commonSpace.CreateSpace(ctx, payload) + if err != nil { + return + } + + obj, err := s.commonSpace.GetSpace(ctx, id) + if err != nil { + return + } + return obj.(commonspace.Space), nil +} + +func (s *service) DeriveSpace(ctx context.Context, payload commonspace.SpaceDerivePayload) (space commonspace.Space, err error) { + id, err := s.commonSpace.DeriveSpace(ctx, payload) + if err != nil { + return + } + + obj, err := s.commonSpace.GetSpace(ctx, id) + if err != nil { + return + } + return obj.(commonspace.Space), nil +} + func (s *service) GetSpace(ctx context.Context, id string) (commonspace.Space, error) { v, err := s.spaceCache.Get(ctx, id) if err != nil { diff --git a/client/document/service.go b/client/document/service.go new file mode 100644 index 00000000..afd16366 --- /dev/null +++ b/client/document/service.go @@ -0,0 +1,13 @@ +package document + +import "github.com/anytypeio/go-anytype-infrastructure-experiments/app" + +type Service interface { + app.Component + CreateDocument(spaceId string) (id string, err error) + GetAllDocumentIds(spaceId string) (ids []string, err error) + AddText(documentId, text string) (err error) + DumpDocumentTree(documentId string) (err error) +} + +const CName = "client.document" diff --git a/client/badgerprovider/helpers.go b/client/storage/helpers.go similarity index 61% rename from client/badgerprovider/helpers.go rename to client/storage/helpers.go index afaf5da4..d1d5915a 100644 --- a/client/badgerprovider/helpers.go +++ b/client/storage/helpers.go @@ -1,26 +1,23 @@ -package badgerprovider +package storage import ( - "errors" "github.com/dgraph-io/badger/v3" ) -var ErrIncorrectKey = errors.New("the key is incorrect") - -func Has(db *badger.DB, key []byte) bool { +func hasDB(db *badger.DB, key []byte) bool { return db.View(func(txn *badger.Txn) error { _, err := txn.Get(key) return err }) == nil } -func Put(db *badger.DB, key, value []byte) (err error) { +func putDB(db *badger.DB, key, value []byte) (err error) { return db.Update(func(txn *badger.Txn) error { return txn.Set(key, value) }) } -func Get(db *badger.DB, key []byte) (value []byte, err error) { +func getDB(db *badger.DB, key []byte) (value []byte, err error) { err = db.View(func(txn *badger.Txn) error { item, err := txn.Get(key) if err != nil { @@ -35,7 +32,7 @@ func Get(db *badger.DB, key []byte) (value []byte, err error) { return } -func GetAndCopy(txn *badger.Txn, key []byte) (value []byte, err error) { +func getTxn(txn *badger.Txn, key []byte) (value []byte, err error) { item, err := txn.Get(key) if err != nil { return diff --git a/client/storage/liststorage.go b/client/storage/liststorage.go index edb9a17d..bf68b602 100644 --- a/client/storage/liststorage.go +++ b/client/storage/liststorage.go @@ -3,7 +3,6 @@ package storage import ( "context" "errors" - provider "github.com/anytypeio/go-anytype-infrastructure-experiments/client/badgerprovider" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclrecordproto" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/storage" "github.com/dgraph-io/badger/v3" @@ -20,13 +19,13 @@ type listStorage struct { func newListStorage(spaceId string, db *badger.DB, txn *badger.Txn) (ls storage.ListStorage, err error) { keys := newACLKeys(spaceId) - rootId, err := provider.GetAndCopy(txn, keys.RootIdKey()) + rootId, err := getTxn(txn, keys.RootIdKey()) if err != nil { return } stringId := string(rootId) - value, err := provider.GetAndCopy(txn, keys.RawRecordKey(stringId)) + value, err := getTxn(txn, keys.RawRecordKey(stringId)) if err != nil { return } @@ -47,7 +46,7 @@ func newListStorage(spaceId string, db *badger.DB, txn *badger.Txn) (ls storage. func createListStorage(spaceId string, db *badger.DB, txn *badger.Txn, root *aclrecordproto.RawACLRecordWithId) (ls storage.ListStorage, err error) { keys := newACLKeys(spaceId) - _, err = provider.GetAndCopy(txn, keys.RootIdKey()) + _, err = getTxn(txn, keys.RootIdKey()) if err != badger.ErrKeyNotFound { if err == nil { return newListStorage(spaceId, db, txn) @@ -87,7 +86,7 @@ func (l *listStorage) Root() (*aclrecordproto.RawACLRecordWithId, error) { } func (l *listStorage) Head() (head string, err error) { - bytes, err := provider.Get(l.db, l.keys.HeadIdKey()) + bytes, err := getDB(l.db, l.keys.HeadIdKey()) if err != nil { return } @@ -96,7 +95,7 @@ func (l *listStorage) Head() (head string, err error) { } func (l *listStorage) GetRawRecord(ctx context.Context, id string) (raw *aclrecordproto.RawACLRecordWithId, err error) { - res, err := provider.Get(l.db, l.keys.RawRecordKey(id)) + res, err := getDB(l.db, l.keys.RawRecordKey(id)) if err != nil { if err == badger.ErrKeyNotFound { err = storage.ErrUnknownRecord @@ -111,6 +110,10 @@ func (l *listStorage) GetRawRecord(ctx context.Context, id string) (raw *aclreco return } -func (l *listStorage) AddRawRecord(ctx context.Context, rec *aclrecordproto.RawACLRecordWithId) error { - return provider.Put(l.db, []byte(rec.Id), rec.Payload) +func (l *listStorage) SetHead(headId string) (err error) { + return putDB(l.db, l.keys.HeadIdKey(), []byte(headId)) +} + +func (l *listStorage) AddRawRecord(ctx context.Context, rec *aclrecordproto.RawACLRecordWithId) error { + return putDB(l.db, l.keys.RawRecordKey(rec.Id), rec.Payload) } diff --git a/client/storage/spacestorage.go b/client/storage/spacestorage.go index 5fb03f72..e05efa99 100644 --- a/client/storage/spacestorage.go +++ b/client/storage/spacestorage.go @@ -1,7 +1,6 @@ package storage import ( - provider "github.com/anytypeio/go-anytype-infrastructure-experiments/client/badgerprovider" "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/pkg/acl/storage" @@ -21,7 +20,7 @@ type spaceStorage struct { func newSpaceStorage(objDb *badger.DB, spaceId string) (store spacestorage.SpaceStorage, err error) { keys := newSpaceKeys(spaceId) err = objDb.View(func(txn *badger.Txn) error { - header, err := provider.GetAndCopy(txn, keys.HeaderKey()) + header, err := getTxn(txn, keys.HeaderKey()) if err != nil { return err } @@ -51,7 +50,7 @@ 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 provider.Has(db, keys.HeaderKey()) { + if hasDB(db, keys.HeaderKey()) { err = spacesyncproto.ErrSpaceExists return } @@ -78,6 +77,10 @@ func createSpaceStorage(db *badger.DB, payload spacestorage.SpaceStorageCreatePa return } +func (s *spaceStorage) ID() (string, error) { + return s.spaceId, nil +} + func (s *spaceStorage) TreeStorage(id string) (storage.TreeStorage, error) { return newTreeStorage(s.objDb, s.spaceId, id) } diff --git a/client/storage/treestorage.go b/client/storage/treestorage.go index aea492ac..39fbe8e2 100644 --- a/client/storage/treestorage.go +++ b/client/storage/treestorage.go @@ -2,7 +2,6 @@ package storage import ( "context" - provider "github.com/anytypeio/go-anytype-infrastructure-experiments/client/badgerprovider" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/storage" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treechangeproto" "github.com/dgraph-io/badger/v3" @@ -23,7 +22,7 @@ func newTreeStorage(db *badger.DB, spaceId, treeId string) (ts storage.TreeStora return err } - root, err := provider.GetAndCopy(txn, keys.RawChangeKey(treeId)) + root, err := getTxn(txn, keys.RawChangeKey(treeId)) if err != nil { return err } @@ -46,7 +45,7 @@ func newTreeStorage(db *badger.DB, spaceId, treeId string) (ts storage.TreeStora func createTreeStorage(db *badger.DB, spaceId string, payload storage.TreeStorageCreatePayload) (ts storage.TreeStorage, err error) { keys := newTreeKeys(spaceId, payload.TreeId) - if provider.Has(db, keys.RootIdKey()) { + if hasDB(db, keys.RootIdKey()) { err = storage.ErrTreeExists return } @@ -95,7 +94,7 @@ func (t *treeStorage) Root() (raw *treechangeproto.RawTreeChangeWithId, err erro } func (t *treeStorage) Heads() (heads []string, err error) { - headsBytes, err := provider.Get(t.db, t.keys.HeadsKey()) + headsBytes, err := getDB(t.db, t.keys.HeadsKey()) if err != nil { if err == badger.ErrKeyNotFound { err = storage.ErrUnknownTreeId @@ -108,15 +107,15 @@ func (t *treeStorage) Heads() (heads []string, err error) { func (t *treeStorage) SetHeads(heads []string) (err error) { payload := storage.CreateHeadsPayload(heads) - return provider.Put(t.db, t.keys.HeadsKey(), payload) + return putDB(t.db, t.keys.HeadsKey(), payload) } func (t *treeStorage) AddRawChange(change *treechangeproto.RawTreeChangeWithId) (err error) { - return provider.Put(t.db, t.keys.RawChangeKey(change.Id), change.RawChange) + return putDB(t.db, t.keys.RawChangeKey(change.Id), change.RawChange) } func (t *treeStorage) GetRawChange(ctx context.Context, id string) (raw *treechangeproto.RawTreeChangeWithId, err error) { - res, err := provider.Get(t.db, t.keys.RawChangeKey(id)) + res, err := getDB(t.db, t.keys.RawChangeKey(id)) if err != nil { if err == badger.ErrKeyNotFound { err = storage.ErrUnknownTreeId @@ -132,5 +131,5 @@ func (t *treeStorage) GetRawChange(ctx context.Context, id string) (raw *treecha } func (t *treeStorage) HasChange(ctx context.Context, id string) (bool, error) { - return provider.Has(t.db, t.keys.RawChangeKey(id)), nil + return hasDB(t.db, t.keys.RawChangeKey(id)), nil } diff --git a/common/commonspace/service.go b/common/commonspace/service.go index c7c27081..2b5f2404 100644 --- a/common/commonspace/service.go +++ b/common/commonspace/service.go @@ -22,8 +22,8 @@ func New() Service { } type Service interface { - DeriveSpace(ctx context.Context, payload SpaceDerivePayload) (Space, error) - CreateSpace(ctx context.Context, payload SpaceCreatePayload) (Space, error) + DeriveSpace(ctx context.Context, payload SpaceDerivePayload) (string, error) + CreateSpace(ctx context.Context, payload SpaceCreatePayload) (string, error) GetSpace(ctx context.Context, id string) (sp Space, err error) app.Component } @@ -51,32 +51,32 @@ func (s *service) Name() (name string) { func (s *service) CreateSpace( ctx context.Context, - payload SpaceCreatePayload) (sp Space, err error) { + payload SpaceCreatePayload) (id string, err error) { storageCreate, err := storagePayloadForSpaceCreate(payload) if err != nil { return } - _, err = s.storageProvider.CreateSpaceStorage(storageCreate) + store, err := s.storageProvider.CreateSpaceStorage(storageCreate) if err != nil { return } - return s.GetSpace(ctx, storageCreate.SpaceHeaderWithId.GetId()) + return store.ID() } func (s *service) DeriveSpace( ctx context.Context, - payload SpaceDerivePayload) (sp Space, err error) { + payload SpaceDerivePayload) (id string, err error) { storageCreate, err := storagePayloadForSpaceDerive(payload) if err != nil { return } - _, err = s.storageProvider.CreateSpaceStorage(storageCreate) + store, err := s.storageProvider.CreateSpaceStorage(storageCreate) if err != nil { return } - return s.GetSpace(ctx, storageCreate.SpaceHeaderWithId.GetId()) + return store.ID() } func (s *service) GetSpace(ctx context.Context, id string) (Space, error) { diff --git a/common/commonspace/space.go b/common/commonspace/space.go index aa255f51..fca752ab 100644 --- a/common/commonspace/space.go +++ b/common/commonspace/space.go @@ -19,10 +19,15 @@ import ( ) type SpaceCreatePayload struct { - SigningKey signingkey.PrivKey - EncryptionKey encryptionkey.PrivKey - SpaceType string - ReadKey []byte + // SigningKey is the signing key of the owner + SigningKey signingkey.PrivKey + // EncryptionKey is the encryption key of the owner + EncryptionKey encryptionkey.PrivKey + // SpaceType is an arbitrary string + SpaceType string + // ReadKey is a first symmetric encryption key for a space + ReadKey []byte + // ReplicationKey is a key which is to be used to determine the node where the space should be held ReplicationKey uint64 } diff --git a/common/commonspace/storage/mock_storage/mock_storage.go b/common/commonspace/storage/mock_storage/mock_storage.go index 4cca0580..d1fd5934 100644 --- a/common/commonspace/storage/mock_storage/mock_storage.go +++ b/common/commonspace/storage/mock_storage/mock_storage.go @@ -162,6 +162,21 @@ func (mr *MockSpaceStorageMockRecorder) CreateTreeStorage(arg0 interface{}) *gom return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateTreeStorage", reflect.TypeOf((*MockSpaceStorage)(nil).CreateTreeStorage), arg0) } +// ID mocks base method. +func (m *MockSpaceStorage) ID() (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ID") + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ID indicates an expected call of ID. +func (mr *MockSpaceStorageMockRecorder) ID() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ID", reflect.TypeOf((*MockSpaceStorage)(nil).ID)) +} + // SpaceHeader mocks base method. func (m *MockSpaceStorage) SpaceHeader() (*spacesyncproto.RawSpaceHeaderWithId, error) { m.ctrl.T.Helper() diff --git a/common/commonspace/storage/storage.go b/common/commonspace/storage/storage.go index eada36f7..1189ede2 100644 --- a/common/commonspace/storage/storage.go +++ b/common/commonspace/storage/storage.go @@ -15,6 +15,7 @@ var ErrSpaceStorageExists = errors.New("space storage exists") var ErrSpaceStorageMissing = errors.New("space storage missing") type SpaceStorage interface { + storage.Storage storage.Provider ACLStorage() (storage.ListStorage, error) SpaceHeader() (*spacesyncproto.RawSpaceHeaderWithId, error) diff --git a/node/storage/liststorage.go b/node/storage/liststorage.go index 966f3fe0..142e175b 100644 --- a/node/storage/liststorage.go +++ b/node/storage/liststorage.go @@ -120,6 +120,10 @@ func (l *listStorage) GetRawRecord(ctx context.Context, id string) (raw *aclreco return } -func (l *listStorage) AddRawRecord(ctx context.Context, rec *aclrecordproto.RawACLRecordWithId) error { - return l.db.Put([]byte(rec.Id), rec.Payload) +func (l *listStorage) SetHead(headId string) (err error) { + return l.db.Put(l.keys.HeadIdKey(), []byte(headId)) +} + +func (l *listStorage) AddRawRecord(ctx context.Context, rec *aclrecordproto.RawACLRecordWithId) error { + return l.db.Put(l.keys.RawRecordKey(rec.Id), rec.Payload) } diff --git a/node/storage/spacestorage.go b/node/storage/spacestorage.go index 12b15534..3bf41085 100644 --- a/node/storage/spacestorage.go +++ b/node/storage/spacestorage.go @@ -15,6 +15,7 @@ var defPogrebOptions = &pogreb.Options{ } type spaceStorage struct { + spaceId string objDb *pogreb.DB keys spaceKeys aclStorage storage.ListStorage @@ -60,8 +61,9 @@ func newSpaceStorage(rootPath string, spaceId string) (store spacestorage.SpaceS } store = &spaceStorage{ - objDb: objDb, - keys: keys, + spaceId: spaceId, + objDb: objDb, + keys: keys, header: &spacesyncproto.RawSpaceHeaderWithId{ RawHeader: header, Id: spaceId, @@ -110,6 +112,7 @@ func createSpaceStorage(rootPath string, payload spacestorage.SpaceStorageCreate } store = &spaceStorage{ + spaceId: payload.SpaceHeaderWithId.Id, objDb: db, keys: keys, aclStorage: aclStorage, @@ -118,6 +121,10 @@ func createSpaceStorage(rootPath string, payload spacestorage.SpaceStorageCreate return } +func (s *spaceStorage) ID() (string, error) { + return s.spaceId, nil +} + func (s *spaceStorage) TreeStorage(id string) (storage.TreeStorage, error) { return newTreeStorage(s.objDb, id) } diff --git a/pkg/acl/storage/inmemory.go b/pkg/acl/storage/inmemory.go index b9948c3e..a992e84a 100644 --- a/pkg/acl/storage/inmemory.go +++ b/pkg/acl/storage/inmemory.go @@ -31,6 +31,10 @@ func (i *inMemoryACLListStorage) Root() (*aclrecordproto.RawACLRecordWithId, err return i.records[0], nil } +func (i *inMemoryACLListStorage) SetHead(headId string) error { + panic("implement me") +} + func (i *inMemoryACLListStorage) Head() (string, error) { i.RLock() defer i.RUnlock() diff --git a/pkg/acl/storage/liststorage.go b/pkg/acl/storage/liststorage.go index ad61a7fa..4ce5f814 100644 --- a/pkg/acl/storage/liststorage.go +++ b/pkg/acl/storage/liststorage.go @@ -15,6 +15,7 @@ type ListStorage interface { Storage Root() (*aclrecordproto.RawACLRecordWithId, error) Head() (string, error) + SetHead(headId string) error GetRawRecord(ctx context.Context, id string) (*aclrecordproto.RawACLRecordWithId, error) AddRawRecord(ctx context.Context, rec *aclrecordproto.RawACLRecordWithId) error diff --git a/pkg/acl/storage/mock_storage/mock_storage.go b/pkg/acl/storage/mock_storage/mock_storage.go index c4cf8800..0bfa22e8 100644 --- a/pkg/acl/storage/mock_storage/mock_storage.go +++ b/pkg/acl/storage/mock_storage/mock_storage.go @@ -110,6 +110,20 @@ func (mr *MockListStorageMockRecorder) Root() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Root", reflect.TypeOf((*MockListStorage)(nil).Root)) } +// SetHead mocks base method. +func (m *MockListStorage) SetHead(arg0 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetHead", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetHead indicates an expected call of SetHead. +func (mr *MockListStorageMockRecorder) SetHead(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetHead", reflect.TypeOf((*MockListStorage)(nil).SetHead), arg0) +} + // MockTreeStorage is a mock of TreeStorage interface. type MockTreeStorage struct { ctrl *gomock.Controller diff --git a/pkg/acl/testutils/acllistbuilder/liststoragebuilder.go b/pkg/acl/testutils/acllistbuilder/liststoragebuilder.go index 206550a5..7c0f4565 100644 --- a/pkg/acl/testutils/acllistbuilder/liststoragebuilder.go +++ b/pkg/acl/testutils/acllistbuilder/liststoragebuilder.go @@ -97,6 +97,10 @@ func (t *ACLListStorageBuilder) Head() (string, error) { return t.rawRoot.Id, nil } +func (t *ACLListStorageBuilder) SetHead(headId string) error { + panic("SetHead is not implemented") +} + func (t *ACLListStorageBuilder) Root() (*aclrecordproto.RawACLRecordWithId, error) { return t.rawRoot, nil }