diff --git a/client/api/service.go b/client/api/service.go index 0c09a39f..bd606651 100644 --- a/client/api/service.go +++ b/client/api/service.go @@ -54,13 +54,16 @@ func (s *service) Name() (name string) { } func (s *service) Run(ctx context.Context) (err error) { - err = s.BaseDrpcServer.Run( - ctx, - s.cfg.APIServer.ListenAddrs, - func(handler drpc.Handler) drpc.Handler { + params := server.Params{ + BufferSizeMb: s.cfg.Stream.MaxMsgSizeMb, + TimeoutMillis: s.cfg.Stream.TimeoutMilliseconds, + ListenAddrs: s.cfg.APIServer.ListenAddrs, + Wrapper: func(handler drpc.Handler) drpc.Handler { return handler }, - s.transport.BasicListener) + Converter: s.transport.BasicListener, + } + err = s.BaseDrpcServer.Run(ctx, params) if err != nil { return } diff --git a/common/commonspace/diffservice/diffservice.go b/common/commonspace/diffservice/diffservice.go index 31a678a9..8bae2f08 100644 --- a/common/commonspace/diffservice/diffservice.go +++ b/common/commonspace/diffservice/diffservice.go @@ -13,6 +13,7 @@ import ( "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/periodicsync" "go.uber.org/zap" "strings" + "time" ) type TreeHeads struct { @@ -54,7 +55,7 @@ func NewDiffService( l := log.With(zap.String("spaceId", spaceId)) factory := spacesyncproto.ClientFactoryFunc(spacesyncproto.NewDRPCSpaceClient) syncer := newDiffSyncer(spaceId, diff, confConnector, cache, storage, factory, l) - periodicSync := periodicsync.NewPeriodicSync(syncPeriod, syncer.Sync, l) + periodicSync := periodicsync.NewPeriodicSync(syncPeriod, time.Minute, syncer.Sync, l) return &diffService{ spaceId: spaceId, diff --git a/common/commonspace/rpchandler.go b/common/commonspace/rpchandler.go index dbc5b7aa..c8b1dbd4 100644 --- a/common/commonspace/rpchandler.go +++ b/common/commonspace/rpchandler.go @@ -19,5 +19,6 @@ func (r *rpcHandler) HeadSync(ctx context.Context, req *spacesyncproto.HeadSyncR } func (r *rpcHandler) Stream(stream spacesyncproto.DRPCSpace_StreamStream) (err error) { + // TODO: if needed we can launch full sync here return r.s.SyncService().StreamPool().AddAndReadStreamSync(stream) } diff --git a/common/commonspace/service.go b/common/commonspace/service.go index ba3dabd2..6b279140 100644 --- a/common/commonspace/service.go +++ b/common/commonspace/service.go @@ -109,7 +109,7 @@ func (s *service) NewSpace(ctx context.Context, id string) (Space, error) { lastConfiguration := s.configurationService.GetLast() confConnector := nodeconf.NewConfConnector(lastConfiguration, s.pool) diffService := diffservice.NewDiffService(id, s.config.SyncPeriod, st, confConnector, s.treeGetter, log) - syncService := syncservice.NewSyncService(id, confConnector) + syncService := syncservice.NewSyncService(id, confConnector, s.config.SyncPeriod) sp := &space{ id: id, syncService: syncService, diff --git a/common/commonspace/space.go b/common/commonspace/space.go index e23796a7..9a656ee7 100644 --- a/common/commonspace/space.go +++ b/common/commonspace/space.go @@ -218,7 +218,7 @@ func (s *space) DeriveTree(ctx context.Context, payload tree.ObjectTreeCreatePay deps := synctree.CreateDeps{ SpaceId: s.id, Payload: payload, - StreamPool: s.syncService.StreamPool(), + SyncService: s.syncService, Configuration: s.configuration, AclList: s.aclList, SpaceStorage: s.storage, @@ -234,7 +234,7 @@ func (s *space) CreateTree(ctx context.Context, payload tree.ObjectTreeCreatePay deps := synctree.CreateDeps{ SpaceId: s.id, Payload: payload, - StreamPool: s.syncService.StreamPool(), + SyncService: s.syncService, Configuration: s.configuration, AclList: s.aclList, SpaceStorage: s.storage, @@ -249,7 +249,7 @@ func (s *space) BuildTree(ctx context.Context, id string, listener updatelistene } deps := synctree.BuildDeps{ SpaceId: s.id, - StreamPool: s.syncService.StreamPool(), + SyncService: s.syncService, Configuration: s.configuration, HeadNotifiable: s.diffService, Listener: listener, diff --git a/common/commonspace/syncservice/actionqueue.go b/common/commonspace/syncservice/actionqueue.go new file mode 100644 index 00000000..17a5400a --- /dev/null +++ b/common/commonspace/syncservice/actionqueue.go @@ -0,0 +1,87 @@ +package syncservice + +import ( + "context" + "github.com/cheggaaa/mb/v3" + "go.uber.org/zap" +) + +type ActionFunc func() error + +type ActionQueue interface { + Send(action ActionFunc) (err error) + Run() + Close() +} + +type actionQueue struct { + batcher *mb.MB[ActionFunc] + ctx context.Context + cancel context.CancelFunc + queueDone chan struct{} +} + +func NewActionQueue() ActionQueue { + return &actionQueue{ + batcher: mb.New[ActionFunc](0), + ctx: nil, + cancel: nil, + queueDone: make(chan struct{}), + } +} + +func (q *actionQueue) Send(action ActionFunc) (err error) { + log.Debug("adding action to batcher") + return q.batcher.Add(q.ctx, action) +} + +func (q *actionQueue) Run() { + log.Debug("running the queue") + q.ctx, q.cancel = context.WithCancel(context.Background()) + go q.read() +} + +func (q *actionQueue) read() { + limiter := make(chan struct{}, maxSimultaneousOperationsPerStream) + for i := 0; i < maxSimultaneousOperationsPerStream; i++ { + limiter <- struct{}{} + } + defer func() { + // wait until all operations are done + for i := 0; i < maxSimultaneousOperationsPerStream; i++ { + <-limiter + } + close(q.queueDone) + }() + doSendActions := func() { + actions, err := q.batcher.Wait(q.ctx) + log.Debug("reading from batcher") + if err != nil { + log.With(zap.Error(err)).Error("queue finished") + return + } + for _, msg := range actions { + <-limiter + go func(action ActionFunc) { + err = action() + if err != nil { + log.With(zap.Error(err)).Debug("action errored out") + } + limiter <- struct{}{} + }(msg) + } + } + for { + select { + case <-q.ctx.Done(): + return + default: + doSendActions() + } + } +} + +func (q *actionQueue) Close() { + q.cancel() + <-q.queueDone +} diff --git a/common/commonspace/syncservice/mock_syncservice/mock_syncservice.go b/common/commonspace/syncservice/mock_syncservice/mock_syncservice.go new file mode 100644 index 00000000..4617bf7f --- /dev/null +++ b/common/commonspace/syncservice/mock_syncservice/mock_syncservice.go @@ -0,0 +1,73 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice (interfaces: ActionQueue) + +// Package mock_syncservice is a generated GoMock package. +package mock_syncservice + +import ( + reflect "reflect" + + syncservice "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice" + gomock "github.com/golang/mock/gomock" +) + +// MockActionQueue is a mock of ActionQueue interface. +type MockActionQueue struct { + ctrl *gomock.Controller + recorder *MockActionQueueMockRecorder +} + +// MockActionQueueMockRecorder is the mock recorder for MockActionQueue. +type MockActionQueueMockRecorder struct { + mock *MockActionQueue +} + +// NewMockActionQueue creates a new mock instance. +func NewMockActionQueue(ctrl *gomock.Controller) *MockActionQueue { + mock := &MockActionQueue{ctrl: ctrl} + mock.recorder = &MockActionQueueMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockActionQueue) EXPECT() *MockActionQueueMockRecorder { + return m.recorder +} + +// Close mocks base method. +func (m *MockActionQueue) Close() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Close") +} + +// Close indicates an expected call of Close. +func (mr *MockActionQueueMockRecorder) Close() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockActionQueue)(nil).Close)) +} + +// Run mocks base method. +func (m *MockActionQueue) Run() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Run") +} + +// Run indicates an expected call of Run. +func (mr *MockActionQueueMockRecorder) Run() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockActionQueue)(nil).Run)) +} + +// Send mocks base method. +func (m *MockActionQueue) Send(arg0 syncservice.ActionFunc) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Send", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Send indicates an expected call of Send. +func (mr *MockActionQueueMockRecorder) Send(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockActionQueue)(nil).Send), arg0) +} diff --git a/common/commonspace/syncservice/streamchecker.go b/common/commonspace/syncservice/streamchecker.go new file mode 100644 index 00000000..85bd928d --- /dev/null +++ b/common/commonspace/syncservice/streamchecker.go @@ -0,0 +1,98 @@ +package syncservice + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/rpc/rpcerr" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf" + "go.uber.org/atomic" + "go.uber.org/zap" + "time" +) + +type StreamChecker interface { + CheckResponsiblePeers() +} + +type streamChecker struct { + spaceId string + connector nodeconf.ConfConnector + streamPool StreamPool + clientFactory spacesyncproto.ClientFactory + log *zap.Logger + syncCtx context.Context + lastCheck *atomic.Time +} + +const streamCheckerInterval = time.Second * 10 + +func NewStreamChecker( + spaceId string, + connector nodeconf.ConfConnector, + streamPool StreamPool, + clientFactory spacesyncproto.ClientFactory, + syncCtx context.Context, + log *zap.Logger) StreamChecker { + return &streamChecker{ + spaceId: spaceId, + connector: connector, + streamPool: streamPool, + clientFactory: clientFactory, + log: log, + syncCtx: syncCtx, + lastCheck: atomic.NewTime(time.Time{}), + } +} + +func (s *streamChecker) CheckResponsiblePeers() { + lastCheck := s.lastCheck.Load() + now := time.Now() + if lastCheck.Add(streamCheckerInterval).After(now) { + return + } + s.lastCheck.Store(now) + + var ( + activeNodeIds []string + configuration = s.connector.Configuration() + ) + nodeIds := configuration.NodeIds(s.spaceId) + for _, nodeId := range nodeIds { + if s.streamPool.HasActiveStream(nodeId) { + s.log.Debug("has active stream for", zap.String("id", nodeId)) + activeNodeIds = append(activeNodeIds, nodeId) + continue + } + } + s.log.Debug("total streams", zap.Int("total", len(activeNodeIds))) + newPeers, err := s.connector.DialInactiveResponsiblePeers(s.syncCtx, s.spaceId, activeNodeIds) + if err != nil { + s.log.Error("failed to dial peers", zap.Error(err)) + return + } + + for _, p := range newPeers { + stream, err := s.clientFactory.Client(p).Stream(s.syncCtx) + if err != nil { + err = rpcerr.Unwrap(err) + s.log.Error("failed to open stream", zap.Error(err)) + // so here probably the request is failed because there is no such space, + // but diffService should handle such cases by sending pushSpace + continue + } + // sending empty message for the server to understand from which space is it coming + err = stream.Send(&spacesyncproto.ObjectSyncMessage{SpaceId: s.spaceId}) + if err != nil { + err = rpcerr.Unwrap(err) + s.log.Error("failed to send first message to stream", zap.Error(err)) + continue + } + err = s.streamPool.AddAndReadStreamAsync(stream) + if err != nil { + s.log.Error("failed to read from stream async", zap.Error(err)) + continue + } + s.log.Debug("reading stream for", zap.String("id", p.Id())) + } + return +} diff --git a/common/commonspace/syncservice/streampool.go b/common/commonspace/syncservice/streampool.go index a2bbe4ce..4191aab0 100644 --- a/common/commonspace/syncservice/streampool.go +++ b/common/commonspace/syncservice/streampool.go @@ -7,6 +7,7 @@ import ( "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/peer" "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ocache" + "go.uber.org/zap" "sync" "sync/atomic" "time" @@ -24,7 +25,7 @@ var ErrSyncTimeout = errors.New("too long wait on sync receive") type StreamPool interface { ocache.ObjectLastUsage AddAndReadStreamSync(stream spacesyncproto.SpaceStream) (err error) - AddAndReadStreamAsync(stream spacesyncproto.SpaceStream) + AddAndReadStreamAsync(stream spacesyncproto.SpaceStream) (err error) SendSync(peerId string, message *spacesyncproto.ObjectSyncMessage) (reply *spacesyncproto.ObjectSyncMessage, err error) SendAsync(peers []string, message *spacesyncproto.ObjectSyncMessage) (err error) @@ -97,7 +98,7 @@ func (s *streamPool) SendSync( delete(s.waiters, msg.ReplyId) s.waitersMx.Unlock() - log.With("replyId", msg.ReplyId).Error("time elapsed when waiting") + log.With(zap.String("replyId", msg.ReplyId)).Error("time elapsed when waiting") err = ErrSyncTimeout case reply = <-waiter.ch: if !delay.Stop() { @@ -124,10 +125,13 @@ func (s *streamPool) SendAsync(peers []string, message *spacesyncproto.ObjectSyn streams := getStreams() s.Unlock() - log.With("objectId", message.ObjectId). - Debugf("sending message to %d peers", len(streams)) - for _, s := range streams { - err = s.Send(message) + log.With(zap.String("objectId", message.ObjectId), zap.Int("peers", len(streams))). + Debug("sending message to peers") + for _, stream := range streams { + err = stream.Send(message) + if err != nil { + log.Debug("error sending message to stream", zap.Error(err)) + } } if len(peers) != 1 { err = nil @@ -164,6 +168,7 @@ Loop: default: break } + log.With(zap.String("id", id)).Debug("getting peer stream") streams = append(streams, stream) } @@ -172,40 +177,68 @@ Loop: func (s *streamPool) BroadcastAsync(message *spacesyncproto.ObjectSyncMessage) (err error) { streams := s.getAllStreams() - log.With("objectId", message.ObjectId). - Debugf("broadcasting message to %d peers", len(streams)) + log.With(zap.String("objectId", message.ObjectId), zap.Int("peers", len(streams))). + Debug("broadcasting message to peers") for _, stream := range streams { if err = stream.Send(message); err != nil { - // TODO: add logging + log.Debug("error sending message to stream", zap.Error(err)) } } return nil } -func (s *streamPool) AddAndReadStreamAsync(stream spacesyncproto.SpaceStream) { - go s.AddAndReadStreamSync(stream) +func (s *streamPool) AddAndReadStreamAsync(stream spacesyncproto.SpaceStream) (err error) { + peerId, err := s.addStream(stream) + if err != nil { + return + } + go s.readPeerLoop(peerId, stream) + return } func (s *streamPool) AddAndReadStreamSync(stream spacesyncproto.SpaceStream) (err error) { + peerId, err := s.addStream(stream) + if err != nil { + return + } + return s.readPeerLoop(peerId, stream) +} + +func (s *streamPool) addStream(stream spacesyncproto.SpaceStream) (peerId string, err error) { s.Lock() - peerId, err := peer.CtxPeerId(stream.Context()) + peerId, err = peer.CtxPeerId(stream.Context()) if err != nil { s.Unlock() return } + log.With(zap.String("peer id", peerId)).Debug("adding stream") + + if oldStream, ok := s.peerStreams[peerId]; ok { + s.Unlock() + oldStream.Close() + s.Lock() + log.With(zap.String("peer id", peerId)).Debug("closed old stream before adding") + } s.peerStreams[peerId] = stream s.wg.Add(1) s.Unlock() - log.With("peerId", peerId).Debug("reading stream from peer") - return s.readPeerLoop(peerId, stream) + return } func (s *streamPool) Close() (err error) { s.Lock() wg := s.wg s.Unlock() + streams := s.getAllStreams() + + log.Debug("closing streams on lock") + for _, stream := range streams { + stream.Close() + } + log.Debug("closed streams") + if wg != nil { wg.Wait() } @@ -213,6 +246,7 @@ func (s *streamPool) Close() (err error) { } func (s *streamPool) readPeerLoop(peerId string, stream spacesyncproto.SpaceStream) (err error) { + log.With(zap.String("replyId", peerId)).Debug("reading stream from peer") defer s.wg.Done() limiter := make(chan struct{}, maxSimultaneousOperationsPerStream) for i := 0; i < maxSimultaneousOperationsPerStream; i++ { @@ -221,21 +255,22 @@ func (s *streamPool) readPeerLoop(peerId string, stream spacesyncproto.SpaceStre process := func(msg *spacesyncproto.ObjectSyncMessage) { s.lastUsage.Store(time.Now().Unix()) + log.With(zap.String("replyId", msg.ReplyId), zap.String("object id", msg.ObjectId)). + Debug("getting message with reply id") if msg.ReplyId == "" { s.messageHandler(stream.Context(), peerId, msg) return } - log.With("replyId", msg.ReplyId).Debug("getting message with reply id") s.waitersMx.Lock() waiter, exists := s.waiters[msg.ReplyId] if !exists { - log.With("replyId", msg.ReplyId).Debug("reply id not exists") + log.With(zap.String("replyId", msg.ReplyId)).Debug("reply id not exists") s.waitersMx.Unlock() s.messageHandler(stream.Context(), peerId, msg) return } - log.With("replyId", msg.ReplyId).Debug("reply id exists") + log.With(zap.String("replyId", msg.ReplyId)).Debug("reply id exists") delete(s.waiters, msg.ReplyId) s.waitersMx.Unlock() @@ -253,6 +288,7 @@ Loop: select { case <-limiter: case <-stream.Context().Done(): + log.Debug("stream context done") break Loop } go func() { @@ -260,19 +296,23 @@ Loop: limiter <- struct{}{} }() } - log.With("peerId", peerId).Debug("stopped reading stream from peer") - s.removePeer(peerId) + log.With(zap.String("peerId", peerId)).Debug("stopped reading stream from peer") + s.removePeer(peerId, stream) return } -func (s *streamPool) removePeer(peerId string) (err error) { +func (s *streamPool) removePeer(peerId string, stream spacesyncproto.SpaceStream) (err error) { s.Lock() defer s.Unlock() - _, ok := s.peerStreams[peerId] + mapStream, ok := s.peerStreams[peerId] if !ok { return ErrEmptyPeer } - delete(s.peerStreams, peerId) + + // it can be the case that the stream was already replaced + if mapStream == stream { + delete(s.peerStreams, peerId) + } return } diff --git a/common/commonspace/syncservice/streampool_test.go b/common/commonspace/syncservice/streampool_test.go index 2d2ff512..3fd7f746 100644 --- a/common/commonspace/syncservice/streampool_test.go +++ b/common/commonspace/syncservice/streampool_test.go @@ -122,39 +122,16 @@ func TestStreamPool_AddAndReadStreamAsync(t *testing.T) { func TestStreamPool_Close(t *testing.T) { remId := "remoteId" - t.Run("client close", func(t *testing.T) { + t.Run("close", func(t *testing.T) { fx := newFixture(t, "", remId, nil) fx.run(t) - var events []string - recvChan := make(chan struct{}) - go func() { - fx.pool.Close() - events = append(events, "pool_close") - recvChan <- struct{}{} - }() - time.Sleep(50 * time.Millisecond) //err = <-waitCh - events = append(events, "stream_close") - err := fx.clientStream.Close() - require.NoError(t, err) - <-recvChan - require.Equal(t, []string{"stream_close", "pool_close"}, events) - }) - t.Run("server close", func(t *testing.T) { - fx := newFixture(t, "", remId, nil) - fx.run(t) - var events []string - recvChan := make(chan struct{}) - go func() { - fx.pool.Close() - events = append(events, "pool_close") - recvChan <- struct{}{} - }() - time.Sleep(50 * time.Millisecond) //err = <-waitCh - events = append(events, "stream_close") - err := fx.clientStream.Close() - require.NoError(t, err) - <-recvChan - require.Equal(t, []string{"stream_close", "pool_close"}, events) + fx.pool.Close() + select { + case <-fx.clientStream.Context().Done(): + break + case <-time.After(time.Millisecond * 100): + t.Fatal("context should be closed") + } }) } diff --git a/common/commonspace/syncservice/syncservice.go b/common/commonspace/syncservice/syncservice.go index 06cf98a4..574d5f6f 100644 --- a/common/commonspace/syncservice/syncservice.go +++ b/common/commonspace/syncservice/syncservice.go @@ -1,3 +1,4 @@ +//go:generate mockgen -destination mock_syncservice/mock_syncservice.go github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice ActionQueue package syncservice import ( @@ -6,78 +7,99 @@ import ( "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/objectgetter" "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice/synchandler" - "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/rpc/rpcerr" "github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf" "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ocache" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/periodicsync" "go.uber.org/zap" "time" ) -var log = logger.NewNamed("syncservice").Sugar() +var log = logger.NewNamed("commonspace.syncservice") type SyncService interface { ocache.ObjectLastUsage synchandler.SyncHandler StreamPool() StreamPool + StreamChecker() StreamChecker + ActionQueue() ActionQueue Init(getter objectgetter.ObjectGetter) Close() (err error) } -const respPeersStreamCheckInterval = time.Second * 10 - type syncService struct { spaceId string - streamPool StreamPool - clientFactory spacesyncproto.ClientFactory - objectGetter objectgetter.ObjectGetter + streamPool StreamPool + checker StreamChecker + periodicSync periodicsync.PeriodicSync + objectGetter objectgetter.ObjectGetter + actionQueue ActionQueue - streamLoopCtx context.Context - stopStreamLoop context.CancelFunc - connector nodeconf.ConfConnector - streamLoopDone chan struct{} - log *zap.SugaredLogger // TODO: change to logger + syncCtx context.Context + cancelSync context.CancelFunc } func NewSyncService( spaceId string, - confConnector nodeconf.ConfConnector) (syncService SyncService) { + confConnector nodeconf.ConfConnector, + periodicSeconds int) (syncService SyncService) { streamPool := newStreamPool(func(ctx context.Context, senderId string, message *spacesyncproto.ObjectSyncMessage) (err error) { return syncService.HandleMessage(ctx, senderId, message) }) + clientFactory := spacesyncproto.ClientFactoryFunc(spacesyncproto.NewDRPCSpaceClient) + syncLog := log.With(zap.String("id", spaceId)) + syncCtx, cancel := context.WithCancel(context.Background()) + checker := NewStreamChecker( + spaceId, + confConnector, + streamPool, + clientFactory, + syncCtx, + syncLog) + periodicSync := periodicsync.NewPeriodicSync(periodicSeconds, 0, func(ctx context.Context) error { + checker.CheckResponsiblePeers() + return nil + }, syncLog) syncService = newSyncService( spaceId, streamPool, - spacesyncproto.ClientFactoryFunc(spacesyncproto.NewDRPCSpaceClient), - confConnector) + periodicSync, + checker, + syncCtx, + cancel) return } func newSyncService( spaceId string, streamPool StreamPool, - clientFactory spacesyncproto.ClientFactory, - connector nodeconf.ConfConnector) *syncService { + periodicSync periodicsync.PeriodicSync, + checker StreamChecker, + syncCtx context.Context, + cancel context.CancelFunc, +) *syncService { return &syncService{ - streamPool: streamPool, - connector: connector, - clientFactory: clientFactory, - spaceId: spaceId, - log: log.With(zap.String("id", spaceId)), - streamLoopDone: make(chan struct{}), + periodicSync: periodicSync, + streamPool: streamPool, + spaceId: spaceId, + checker: checker, + syncCtx: syncCtx, + cancelSync: cancel, + actionQueue: NewActionQueue(), } } func (s *syncService) Init(objectGetter objectgetter.ObjectGetter) { s.objectGetter = objectGetter - s.streamLoopCtx, s.stopStreamLoop = context.WithCancel(context.Background()) - go s.responsibleStreamCheckLoop(s.streamLoopCtx) + s.actionQueue.Run() + s.periodicSync.Run() } func (s *syncService) Close() (err error) { - s.stopStreamLoop() - <-s.streamLoopDone + s.actionQueue.Close() + s.periodicSync.Close() + s.cancelSync() return s.streamPool.Close() } @@ -86,7 +108,7 @@ func (s *syncService) LastUsage() time.Time { } func (s *syncService) HandleMessage(ctx context.Context, senderId string, message *spacesyncproto.ObjectSyncMessage) (err error) { - s.log.With(zap.String("peerId", senderId), zap.String("objectId", message.ObjectId)).Debug("handling message") + log.With(zap.String("peerId", senderId), zap.String("objectId", message.ObjectId)).Debug("handling message") obj, err := s.objectGetter.GetObject(ctx, message.ObjectId) if err != nil { return @@ -94,60 +116,14 @@ func (s *syncService) HandleMessage(ctx context.Context, senderId string, messag return obj.HandleMessage(ctx, senderId, message) } -func (s *syncService) responsibleStreamCheckLoop(ctx context.Context) { - defer close(s.streamLoopDone) - checkResponsiblePeers := func() { - var ( - activeNodeIds []string - configuration = s.connector.Configuration() - ) - for _, nodeId := range configuration.NodeIds(s.spaceId) { - if s.streamPool.HasActiveStream(nodeId) { - s.log.Debug("has active stream for", zap.String("id", nodeId)) - activeNodeIds = append(activeNodeIds, nodeId) - continue - } - } - newPeers, err := s.connector.DialInactiveResponsiblePeers(ctx, s.spaceId, activeNodeIds) - if err != nil { - s.log.Error("failed to dial peers", zap.Error(err)) - return - } - - for _, p := range newPeers { - stream, err := s.clientFactory.Client(p).Stream(ctx) - if err != nil { - err = rpcerr.Unwrap(err) - s.log.Errorf("failed to open stream: %v", err) - // so here probably the request is failed because there is no such space, - // but diffService should handle such cases by sending pushSpace - continue - } - // sending empty message for the server to understand from which space is it coming - err = stream.Send(&spacesyncproto.ObjectSyncMessage{SpaceId: s.spaceId}) - if err != nil { - err = rpcerr.Unwrap(err) - s.log.Errorf("failed to send first message to stream: %v", err) - continue - } - s.log.Debug("reading stream for", zap.String("id", p.Id())) - s.streamPool.AddAndReadStreamAsync(stream) - } - } - - checkResponsiblePeers() - ticker := time.NewTicker(respPeersStreamCheckInterval) - defer ticker.Stop() - for { - select { - case <-s.streamLoopCtx.Done(): - return - case <-ticker.C: - checkResponsiblePeers() - } - } -} - func (s *syncService) StreamPool() StreamPool { return s.streamPool } + +func (s *syncService) StreamChecker() StreamChecker { + return s.checker +} + +func (s *syncService) ActionQueue() ActionQueue { + return s.actionQueue +} diff --git a/common/commonspace/synctree/mock_synctree/mock_synctree.go b/common/commonspace/synctree/mock_synctree/mock_synctree.go index c8f84390..cbb6e976 100644 --- a/common/commonspace/synctree/mock_synctree/mock_synctree.go +++ b/common/commonspace/synctree/mock_synctree/mock_synctree.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree (interfaces: SyncClient,SyncTree) +// Source: github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree (interfaces: SyncClient,SyncTree,ReceiveQueue) // Package mock_synctree is a generated GoMock package. package mock_synctree @@ -177,23 +177,18 @@ func (mr *MockSyncTreeMockRecorder) AddContent(arg0, arg1 interface{}) *gomock.C } // AddRawChanges mocks base method. -func (m *MockSyncTree) AddRawChanges(arg0 context.Context, arg1 ...*treechangeproto.RawTreeChangeWithId) (tree.AddResult, error) { +func (m *MockSyncTree) AddRawChanges(arg0 context.Context, arg1 tree.RawChangesPayload) (tree.AddResult, error) { m.ctrl.T.Helper() - varargs := []interface{}{arg0} - for _, a := range arg1 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "AddRawChanges", varargs...) + ret := m.ctrl.Call(m, "AddRawChanges", arg0, arg1) ret0, _ := ret[0].(tree.AddResult) ret1, _ := ret[1].(error) return ret0, ret1 } // AddRawChanges indicates an expected call of AddRawChanges. -func (mr *MockSyncTreeMockRecorder) AddRawChanges(arg0 interface{}, arg1 ...interface{}) *gomock.Call { +func (mr *MockSyncTreeMockRecorder) AddRawChanges(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0}, arg1...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRawChanges", reflect.TypeOf((*MockSyncTree)(nil).AddRawChanges), varargs...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRawChanges", reflect.TypeOf((*MockSyncTree)(nil).AddRawChanges), arg0, arg1) } // ChangesAfterCommonSnapshot mocks base method. @@ -459,3 +454,68 @@ func (mr *MockSyncTreeMockRecorder) Unlock() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Unlock", reflect.TypeOf((*MockSyncTree)(nil).Unlock)) } + +// MockReceiveQueue is a mock of ReceiveQueue interface. +type MockReceiveQueue struct { + ctrl *gomock.Controller + recorder *MockReceiveQueueMockRecorder +} + +// MockReceiveQueueMockRecorder is the mock recorder for MockReceiveQueue. +type MockReceiveQueueMockRecorder struct { + mock *MockReceiveQueue +} + +// NewMockReceiveQueue creates a new mock instance. +func NewMockReceiveQueue(ctrl *gomock.Controller) *MockReceiveQueue { + mock := &MockReceiveQueue{ctrl: ctrl} + mock.recorder = &MockReceiveQueueMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockReceiveQueue) EXPECT() *MockReceiveQueueMockRecorder { + return m.recorder +} + +// AddMessage mocks base method. +func (m *MockReceiveQueue) AddMessage(arg0 string, arg1 *treechangeproto.TreeSyncMessage, arg2 string) bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AddMessage", arg0, arg1, arg2) + ret0, _ := ret[0].(bool) + return ret0 +} + +// AddMessage indicates an expected call of AddMessage. +func (mr *MockReceiveQueueMockRecorder) AddMessage(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddMessage", reflect.TypeOf((*MockReceiveQueue)(nil).AddMessage), arg0, arg1, arg2) +} + +// ClearQueue mocks base method. +func (m *MockReceiveQueue) ClearQueue(arg0 string) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "ClearQueue", arg0) +} + +// ClearQueue indicates an expected call of ClearQueue. +func (mr *MockReceiveQueueMockRecorder) ClearQueue(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClearQueue", reflect.TypeOf((*MockReceiveQueue)(nil).ClearQueue), arg0) +} + +// GetMessage mocks base method. +func (m *MockReceiveQueue) GetMessage(arg0 string) (*treechangeproto.TreeSyncMessage, string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetMessage", arg0) + ret0, _ := ret[0].(*treechangeproto.TreeSyncMessage) + ret1, _ := ret[1].(string) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// GetMessage indicates an expected call of GetMessage. +func (mr *MockReceiveQueueMockRecorder) GetMessage(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMessage", reflect.TypeOf((*MockReceiveQueue)(nil).GetMessage), arg0) +} diff --git a/common/commonspace/synctree/queuedclient.go b/common/commonspace/synctree/queuedclient.go new file mode 100644 index 00000000..a0fceff9 --- /dev/null +++ b/common/commonspace/synctree/queuedclient.go @@ -0,0 +1,36 @@ +package synctree + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto" +) + +type queuedClient struct { + SyncClient + queue syncservice.ActionQueue +} + +func newQueuedClient(client SyncClient, queue syncservice.ActionQueue) SyncClient { + return &queuedClient{ + SyncClient: client, + queue: queue, + } +} + +func (q *queuedClient) BroadcastAsync(message *treechangeproto.TreeSyncMessage) (err error) { + return q.queue.Send(func() error { + return q.SyncClient.BroadcastAsync(message) + }) +} + +func (q *queuedClient) SendAsync(peerId string, message *treechangeproto.TreeSyncMessage, replyId string) (err error) { + return q.queue.Send(func() error { + return q.SyncClient.SendAsync(peerId, message, replyId) + }) +} + +func (q *queuedClient) BroadcastAsyncOrSendResponsible(message *treechangeproto.TreeSyncMessage) (err error) { + return q.queue.Send(func() error { + return q.SyncClient.BroadcastAsyncOrSendResponsible(message) + }) +} diff --git a/common/commonspace/synctree/receivequeue.go b/common/commonspace/synctree/receivequeue.go new file mode 100644 index 00000000..d9913684 --- /dev/null +++ b/common/commonspace/synctree/receivequeue.go @@ -0,0 +1,74 @@ +package synctree + +import ( + "errors" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto" + "sync" +) + +type ReceiveQueue interface { + AddMessage(senderId string, msg *treechangeproto.TreeSyncMessage, replyId string) (queueFull bool) + GetMessage(senderId string) (msg *treechangeproto.TreeSyncMessage, replyId string, err error) + ClearQueue(senderId string) +} + +type queueMsg struct { + replyId string + syncMessage *treechangeproto.TreeSyncMessage +} + +type receiveQueue struct { + sync.Mutex + handlerMap map[string][]queueMsg + maxSize int +} + +func newReceiveQueue(maxSize int) ReceiveQueue { + return &receiveQueue{ + Mutex: sync.Mutex{}, + handlerMap: map[string][]queueMsg{}, + maxSize: maxSize, + } +} + +var errEmptyQueue = errors.New("the queue is empty") + +func (q *receiveQueue) AddMessage(senderId string, msg *treechangeproto.TreeSyncMessage, replyId string) (queueFull bool) { + q.Lock() + defer q.Unlock() + + queue := q.handlerMap[senderId] + queueFull = len(queue) >= maxQueueSize + queue = append(queue, queueMsg{replyId, msg}) + q.handlerMap[senderId] = queue + + return +} + +func (q *receiveQueue) GetMessage(senderId string) (msg *treechangeproto.TreeSyncMessage, replyId string, err error) { + q.Lock() + defer q.Unlock() + + if len(q.handlerMap) == 0 { + err = errEmptyQueue + return + } + + qMsg := q.handlerMap[senderId][0] + msg = qMsg.syncMessage + replyId = qMsg.replyId + return +} + +func (q *receiveQueue) ClearQueue(senderId string) { + q.Lock() + defer q.Unlock() + + queue := q.handlerMap[senderId] + excessLen := len(queue) - q.maxSize + 1 + if excessLen <= 0 { + excessLen = 1 + } + queue = queue[excessLen:] + q.handlerMap[senderId] = queue +} diff --git a/common/commonspace/synctree/syncclient.go b/common/commonspace/synctree/syncclient.go index a049f2b1..a4eeaed0 100644 --- a/common/commonspace/synctree/syncclient.go +++ b/common/commonspace/synctree/syncclient.go @@ -1,4 +1,4 @@ -//go:generate mockgen -destination mock_synctree/mock_synctree.go github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree SyncClient,SyncTree +//go:generate mockgen -destination mock_synctree/mock_synctree.go github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree SyncClient,SyncTree,ReceiveQueue package synctree import ( @@ -19,18 +19,23 @@ type syncClient struct { syncservice.StreamPool RequestFactory spaceId string + connector nodeconf.ConfConnector configuration nodeconf.Configuration + + checker syncservice.StreamChecker } func newSyncClient( spaceId string, pool syncservice.StreamPool, factory RequestFactory, - configuration nodeconf.Configuration) SyncClient { + configuration nodeconf.Configuration, + checker syncservice.StreamChecker) SyncClient { return &syncClient{ StreamPool: pool, RequestFactory: factory, configuration: configuration, + checker: checker, spaceId: spaceId, } } @@ -40,6 +45,7 @@ func (s *syncClient) BroadcastAsync(message *treechangeproto.TreeSyncMessage) (e if err != nil { return } + s.checker.CheckResponsiblePeers() return s.StreamPool.BroadcastAsync(objMsg) } @@ -57,6 +63,7 @@ func (s *syncClient) BroadcastAsyncOrSendResponsible(message *treechangeproto.Tr return } if s.configuration.IsResponsible(s.spaceId) { + s.checker.CheckResponsiblePeers() return s.StreamPool.SendAsync(s.configuration.NodeIds(s.spaceId), objMsg) } return s.BroadcastAsync(message) diff --git a/common/commonspace/synctree/synctree.go b/common/commonspace/synctree/synctree.go index 830d8104..221e71e3 100644 --- a/common/commonspace/synctree/synctree.go +++ b/common/commonspace/synctree/synctree.go @@ -52,20 +52,20 @@ var log = logger.NewNamed("commonspace.synctree").Sugar() var createDerivedObjectTree = tree.CreateDerivedObjectTree var createObjectTree = tree.CreateObjectTree var buildObjectTree = tree.BuildObjectTree -var createSyncClient = newSyncClient +var createSyncClient = newWrappedSyncClient type CreateDeps struct { SpaceId string Payload tree.ObjectTreeCreatePayload Configuration nodeconf.Configuration - StreamPool syncservice.StreamPool + SyncService syncservice.SyncService AclList list.ACLList SpaceStorage spacestorage.SpaceStorage } type BuildDeps struct { SpaceId string - StreamPool syncservice.StreamPool + SyncService syncservice.SyncService Configuration nodeconf.Configuration HeadNotifiable HeadNotifiable Listener updatelistener.UpdateListener @@ -75,6 +75,11 @@ type BuildDeps struct { TreeUsage *atomic.Int32 } +func newWrappedSyncClient(spaceId string, factory RequestFactory, syncService syncservice.SyncService, configuration nodeconf.Configuration) SyncClient { + syncClient := newSyncClient(spaceId, syncService.StreamPool(), factory, configuration, syncService.StreamChecker()) + return newQueuedClient(syncClient, syncService.ActionQueue()) +} + func DeriveSyncTree(ctx context.Context, deps CreateDeps) (id string, err error) { objTree, err := createDerivedObjectTree(deps.Payload, deps.AclList, deps.SpaceStorage.CreateTreeStorage) if err != nil { @@ -83,8 +88,8 @@ func DeriveSyncTree(ctx context.Context, deps CreateDeps) (id string, err error) syncClient := createSyncClient( deps.SpaceId, - deps.StreamPool, sharedFactory, + deps.SyncService, deps.Configuration) headUpdate := syncClient.CreateHeadUpdate(objTree, nil) @@ -100,8 +105,8 @@ func CreateSyncTree(ctx context.Context, deps CreateDeps) (id string, err error) } syncClient := createSyncClient( deps.SpaceId, - deps.StreamPool, - GetRequestFactory(), + sharedFactory, + deps.SyncService, deps.Configuration) headUpdate := syncClient.CreateHeadUpdate(objTree, nil) @@ -122,7 +127,7 @@ func BuildSyncTreeOrGetRemote(ctx context.Context, id string, deps BuildDeps) (t return } - resp, err := deps.StreamPool.SendSync(peerId, objMsg) + resp, err := deps.SyncService.StreamPool().SendSync(peerId, objMsg) if err != nil { return } @@ -186,8 +191,8 @@ func buildSyncTree(ctx context.Context, isFirstBuild bool, deps BuildDeps) (t Sy } syncClient := createSyncClient( deps.SpaceId, - deps.StreamPool, - GetRequestFactory(), + sharedFactory, + deps.SyncService, deps.Configuration) syncTree := &syncTree{ ObjectTree: objTree, @@ -200,12 +205,11 @@ func buildSyncTree(ctx context.Context, isFirstBuild bool, deps BuildDeps) (t Sy syncTree.SyncHandler = syncHandler t = syncTree syncTree.Lock() - defer syncTree.Unlock() syncTree.afterBuild() + syncTree.Unlock() - headUpdate := syncTree.syncClient.CreateHeadUpdate(t, nil) - // here we will have different behaviour based on who is sending this update if isFirstBuild { + headUpdate := syncTree.syncClient.CreateHeadUpdate(t, nil) // send to everybody, because everybody should know that the node or client got new tree err = syncTree.syncClient.BroadcastAsync(headUpdate) } @@ -242,11 +246,11 @@ func (s *syncTree) AddContent(ctx context.Context, content tree.SignableChangeCo return } -func (s *syncTree) AddRawChanges(ctx context.Context, changes ...*treechangeproto.RawTreeChangeWithId) (res tree.AddResult, err error) { +func (s *syncTree) AddRawChanges(ctx context.Context, changesPayload tree.RawChangesPayload) (res tree.AddResult, err error) { if err = s.checkAlive(); err != nil { return } - res, err = s.ObjectTree.AddRawChanges(ctx, changes...) + res, err = s.ObjectTree.AddRawChanges(ctx, changesPayload) if err != nil { return } @@ -308,6 +312,8 @@ func (s *syncTree) checkAlive() (err error) { } func (s *syncTree) Ping() (err error) { + s.Lock() + defer s.Unlock() headUpdate := s.syncClient.CreateHeadUpdate(s, nil) return s.syncClient.BroadcastAsyncOrSendResponsible(headUpdate) } diff --git a/common/commonspace/synctree/synctree_test.go b/common/commonspace/synctree/synctree_test.go index bdf2c451..5c8acc6c 100644 --- a/common/commonspace/synctree/synctree_test.go +++ b/common/commonspace/synctree/synctree_test.go @@ -37,6 +37,12 @@ func (s syncTreeMatcher) String() string { return "" } +func syncClientFuncCreator(client SyncClient) func(spaceId string, factory RequestFactory, syncService syncservice.SyncService, configuration nodeconf.Configuration) SyncClient { + return func(spaceId string, factory RequestFactory, syncService syncservice.SyncService, configuration nodeconf.Configuration) SyncClient { + return client + } +} + func Test_DeriveSyncTree(t *testing.T) { ctx := context.Background() ctrl := gomock.NewController(t) @@ -53,9 +59,7 @@ func Test_DeriveSyncTree(t *testing.T) { require.Equal(t, expectedPayload, payload) return objTreeMock, nil } - createSyncClient = func(spaceId string, pool syncservice.StreamPool, factory RequestFactory, configuration nodeconf.Configuration) SyncClient { - return syncClientMock - } + createSyncClient = syncClientFuncCreator(syncClientMock) headUpdate := &treechangeproto.TreeSyncMessage{} syncClientMock.EXPECT().CreateHeadUpdate(gomock.Any(), gomock.Nil()).Return(headUpdate) syncClientMock.EXPECT().BroadcastAsync(gomock.Eq(headUpdate)).Return(nil) @@ -65,6 +69,7 @@ func Test_DeriveSyncTree(t *testing.T) { Payload: expectedPayload, SpaceStorage: spaceStorageMock, } + objTreeMock.EXPECT().ID().Return("id") _, err := DeriveSyncTree(ctx, deps) require.NoError(t, err) @@ -86,12 +91,12 @@ func Test_CreateSyncTree(t *testing.T) { require.Equal(t, expectedPayload, payload) return objTreeMock, nil } - createSyncClient = func(spaceId string, pool syncservice.StreamPool, factory RequestFactory, configuration nodeconf.Configuration) SyncClient { - return syncClientMock - } + + createSyncClient = syncClientFuncCreator(syncClientMock) headUpdate := &treechangeproto.TreeSyncMessage{} syncClientMock.EXPECT().CreateHeadUpdate(gomock.Any(), gomock.Nil()).Return(headUpdate) syncClientMock.EXPECT().BroadcastAsync(gomock.Eq(headUpdate)).Return(nil) + objTreeMock.EXPECT().ID().Return("id") deps := CreateDeps{ AclList: aclListMock, SpaceId: spaceId, @@ -122,48 +127,61 @@ func Test_BuildSyncTree(t *testing.T) { headUpdate := &treechangeproto.TreeSyncMessage{} t.Run("AddRawChanges update", func(t *testing.T) { changes := []*treechangeproto.RawTreeChangeWithId{{Id: "some"}} + payload := tree.RawChangesPayload{ + NewHeads: nil, + RawChanges: changes, + } expectedRes := tree.AddResult{ Added: changes, Mode: tree.Append, } - objTreeMock.EXPECT().AddRawChanges(gomock.Any(), gomock.Eq(changes)). + objTreeMock.EXPECT().AddRawChanges(gomock.Any(), gomock.Eq(payload)). Return(expectedRes, nil) updateListenerMock.EXPECT().Update(tr) syncClientMock.EXPECT().CreateHeadUpdate(gomock.Eq(tr), gomock.Eq(changes)).Return(headUpdate) syncClientMock.EXPECT().BroadcastAsync(gomock.Eq(headUpdate)).Return(nil) - res, err := tr.AddRawChanges(ctx, changes...) + res, err := tr.AddRawChanges(ctx, payload) require.NoError(t, err) require.Equal(t, expectedRes, res) }) t.Run("AddRawChanges rebuild", func(t *testing.T) { changes := []*treechangeproto.RawTreeChangeWithId{{Id: "some"}} + payload := tree.RawChangesPayload{ + NewHeads: nil, + RawChanges: changes, + } + expectedRes := tree.AddResult{ Added: changes, Mode: tree.Rebuild, } - objTreeMock.EXPECT().AddRawChanges(gomock.Any(), gomock.Eq(changes)). + objTreeMock.EXPECT().AddRawChanges(gomock.Any(), gomock.Eq(payload)). Return(expectedRes, nil) updateListenerMock.EXPECT().Rebuild(tr) syncClientMock.EXPECT().CreateHeadUpdate(gomock.Eq(tr), gomock.Eq(changes)).Return(headUpdate) syncClientMock.EXPECT().BroadcastAsync(gomock.Eq(headUpdate)).Return(nil) - res, err := tr.AddRawChanges(ctx, changes...) + res, err := tr.AddRawChanges(ctx, payload) require.NoError(t, err) require.Equal(t, expectedRes, res) }) t.Run("AddRawChanges nothing", func(t *testing.T) { changes := []*treechangeproto.RawTreeChangeWithId{{Id: "some"}} + payload := tree.RawChangesPayload{ + NewHeads: nil, + RawChanges: changes, + } expectedRes := tree.AddResult{ Added: changes, Mode: tree.Nothing, } - objTreeMock.EXPECT().AddRawChanges(gomock.Any(), gomock.Eq(changes)). + objTreeMock.EXPECT().AddRawChanges(gomock.Any(), gomock.Eq(payload)). Return(expectedRes, nil) - res, err := tr.AddRawChanges(ctx, changes...) + res, err := tr.AddRawChanges(ctx, payload) require.NoError(t, err) require.Equal(t, expectedRes, res) }) diff --git a/common/commonspace/synctree/synctreehandler.go b/common/commonspace/synctree/synctreehandler.go index 8c119e2a..923965c4 100644 --- a/common/commonspace/synctree/synctreehandler.go +++ b/common/commonspace/synctree/synctreehandler.go @@ -8,37 +8,63 @@ import ( "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto" "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/slice" "github.com/gogo/protobuf/proto" + "go.uber.org/zap" + "sync" ) type syncTreeHandler struct { - objTree tree.ObjectTree - syncClient SyncClient + objTree tree.ObjectTree + syncClient SyncClient + handlerLock sync.Mutex + queue ReceiveQueue } +const maxQueueSize = 5 + func newSyncTreeHandler(objTree tree.ObjectTree, syncClient SyncClient) synchandler.SyncHandler { return &syncTreeHandler{ objTree: objTree, syncClient: syncClient, + queue: newReceiveQueue(maxQueueSize), } } func (s *syncTreeHandler) HandleMessage(ctx context.Context, senderId string, msg *spacesyncproto.ObjectSyncMessage) (err error) { + // TODO: when implementing sync status check msg heads before sending into queue unmarshalled := &treechangeproto.TreeSyncMessage{} err = proto.Unmarshal(msg.Payload, unmarshalled) if err != nil { return } - content := unmarshalled.GetContent() + queueFull := s.queue.AddMessage(senderId, unmarshalled, msg.ReplyId) + if queueFull { + return + } + + return s.handleMessage(ctx, senderId) +} + +func (s *syncTreeHandler) handleMessage(ctx context.Context, senderId string) (err error) { + s.objTree.Lock() + defer s.objTree.Unlock() + msg, replyId, err := s.queue.GetMessage(senderId) + if err != nil { + return + } + + defer s.queue.ClearQueue(senderId) + + content := msg.GetContent() switch { case content.GetHeadUpdate() != nil: - return s.handleHeadUpdate(ctx, senderId, content.GetHeadUpdate(), msg.ReplyId) + return s.handleHeadUpdate(ctx, senderId, content.GetHeadUpdate(), replyId) case content.GetFullSyncRequest() != nil: - return s.handleFullSyncRequest(ctx, senderId, content.GetFullSyncRequest(), msg.ReplyId) + return s.handleFullSyncRequest(ctx, senderId, content.GetFullSyncRequest(), replyId) case content.GetFullSyncResponse() != nil: return s.handleFullSyncResponse(ctx, senderId, content.GetFullSyncResponse()) } - return nil + return } func (s *syncTreeHandler) handleHeadUpdate( @@ -46,60 +72,66 @@ func (s *syncTreeHandler) handleHeadUpdate( senderId string, update *treechangeproto.TreeHeadUpdate, replyId string) (err error) { - log.With("senderId", senderId). - With("heads", update.Heads). - With("treeId", s.objTree.ID()). - Debug("received head update message") var ( fullRequest *treechangeproto.TreeSyncMessage isEmptyUpdate = len(update.Changes) == 0 objTree = s.objTree ) - err = func() error { - objTree.Lock() - defer objTree.Unlock() + log := log.With("senderId", senderId). + With("heads", objTree.Heads()). + With("treeId", objTree.ID()) + log.Debug("received head update message") - // isEmptyUpdate is sent when the tree is brought up from cache - if isEmptyUpdate { - log.With("treeId", objTree.ID()).Debug("is empty update") - if slice.UnsortedEquals(objTree.Heads(), update.Heads) { - return nil - } - // we need to sync in any case - fullRequest, err = s.syncClient.CreateFullSyncRequest(objTree, update.Heads, update.SnapshotPath) - return err - } - - if s.alreadyHasHeads(objTree, update.Heads) { - return nil - } - - _, err = objTree.AddRawChanges(ctx, update.Changes...) + defer func() { if err != nil { - return err + log.With(zap.Error(err)).Debug("head update finished with error") + } else if fullRequest != nil { + log.Debug("sending full sync request") + } else { + if !isEmptyUpdate { + log.Debug("head update finished correctly") + } } - - if s.alreadyHasHeads(objTree, update.Heads) { - return nil - } - - fullRequest, err = s.syncClient.CreateFullSyncRequest(objTree, update.Heads, update.SnapshotPath) - return err }() - if fullRequest != nil { - log.With("senderId", senderId). - With("heads", objTree.Heads()). - With("treeId", objTree.ID()). - Debug("sending full sync request") + // isEmptyUpdate is sent when the tree is brought up from cache + if isEmptyUpdate { + log.With("treeId", objTree.ID()).Debug("is empty update") + if slice.UnsortedEquals(objTree.Heads(), update.Heads) { + return + } + // we need to sync in any case + fullRequest, err = s.syncClient.CreateFullSyncRequest(objTree, update.Heads, update.SnapshotPath) + if err != nil { + return + } + return s.syncClient.SendAsync(senderId, fullRequest, replyId) } - log.With("senderId", senderId). - With("heads", update.Heads). - With("treeId", objTree.ID()). - Debug("head update finished correctly") - return + + if s.alreadyHasHeads(objTree, update.Heads) { + return + } + + _, err = objTree.AddRawChanges(ctx, tree.RawChangesPayload{ + NewHeads: update.Heads, + RawChanges: update.Changes, + }) + if err != nil { + return + } + + if s.alreadyHasHeads(objTree, update.Heads) { + return + } + + fullRequest, err = s.syncClient.CreateFullSyncRequest(objTree, update.Heads, update.SnapshotPath) + if err != nil { + return + } + + return s.syncClient.SendAsync(senderId, fullRequest, replyId) } func (s *syncTreeHandler) handleFullSyncRequest( @@ -107,40 +139,43 @@ func (s *syncTreeHandler) handleFullSyncRequest( senderId string, request *treechangeproto.TreeFullSyncRequest, replyId string) (err error) { - log.With("senderId", senderId). - With("heads", request.Heads). - With("treeId", s.objTree.ID()). - With("trackingId", replyId). - Debug("received full sync request message") var ( fullResponse *treechangeproto.TreeSyncMessage header = s.objTree.Header() objTree = s.objTree ) + + log := log.With("senderId", senderId). + With("heads", request.Heads). + With("treeId", s.objTree.ID()). + With("replyId", replyId) + log.Debug("received full sync request message") + defer func() { if err != nil { + log.With(zap.Error(err)).Debug("full sync request finished with error") + s.syncClient.SendAsync(senderId, treechangeproto.WrapError(err, header), replyId) + return + } else if fullResponse != nil { + log.Debug("full sync response sent") } }() - err = func() error { - objTree.Lock() - defer objTree.Unlock() - - if len(request.Changes) != 0 && !s.alreadyHasHeads(objTree, request.Heads) { - _, err = objTree.AddRawChanges(ctx, request.Changes...) - if err != nil { - return err - } + if len(request.Changes) != 0 && !s.alreadyHasHeads(objTree, request.Heads) { + _, err = objTree.AddRawChanges(ctx, tree.RawChangesPayload{ + NewHeads: request.Heads, + RawChanges: request.Changes, + }) + if err != nil { + return } - - fullResponse, err = s.syncClient.CreateFullSyncResponse(objTree, request.Heads, request.SnapshotPath) - return err - }() - + } + fullResponse, err = s.syncClient.CreateFullSyncResponse(objTree, request.Heads, request.SnapshotPath) if err != nil { return } + return s.syncClient.SendAsync(senderId, fullResponse, replyId) } @@ -148,34 +183,30 @@ func (s *syncTreeHandler) handleFullSyncResponse( ctx context.Context, senderId string, response *treechangeproto.TreeFullSyncResponse) (err error) { - log.With("senderId", senderId). + var ( + objTree = s.objTree + ) + log := log.With("senderId", senderId). With("heads", response.Heads). - With("treeId", s.objTree.ID()). - Debug("received full sync response message") - objTree := s.objTree - if err != nil { - log.With("senderId", senderId). - With("heads", response.Heads). - With("treeId", s.objTree.ID()). - Debug("failed to find the tree in full sync response") + With("treeId", s.objTree.ID()) + log.Debug("received full sync response message") + + defer func() { + if err != nil { + log.With(zap.Error(err)).Debug("full sync response failed") + } else { + log.Debug("full sync response succeeded") + } + }() + + if s.alreadyHasHeads(objTree, response.Heads) { return } - err = func() error { - objTree.Lock() - defer objTree.Unlock() - - if s.alreadyHasHeads(objTree, response.Heads) { - return nil - } - - _, err = objTree.AddRawChanges(ctx, response.Changes...) - return err - }() - log.With("error", err != nil). - With("heads", response.Heads). - With("treeId", s.objTree.ID()). - Debug("finished full sync response") + _, err = objTree.AddRawChanges(ctx, tree.RawChangesPayload{ + NewHeads: response.Heads, + RawChanges: response.Changes, + }) return } diff --git a/common/commonspace/synctree/synctreehandler_test.go b/common/commonspace/synctree/synctreehandler_test.go index 72cda749..40cfa65f 100644 --- a/common/commonspace/synctree/synctreehandler_test.go +++ b/common/commonspace/synctree/synctreehandler_test.go @@ -33,18 +33,46 @@ func (t *testObjTreeMock) Unlock() { t.m.Unlock() } -func TestSyncHandler_HandleHeadUpdate(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() +type syncHandlerFixture struct { + ctrl *gomock.Controller + syncClientMock *mock_synctree.MockSyncClient + objectTreeMock *testObjTreeMock + receiveQueueMock *mock_synctree.MockReceiveQueue - ctx := context.Background() + syncHandler *syncTreeHandler +} + +func newSyncHandlerFixture(t *testing.T) *syncHandlerFixture { + ctrl := gomock.NewController(t) syncClientMock := mock_synctree.NewMockSyncClient(ctrl) objectTreeMock := newTestObjMock(mock_tree.NewMockObjectTree(ctrl)) + receiveQueueMock := mock_synctree.NewMockReceiveQueue(ctrl) - syncHandler := newSyncTreeHandler(objectTreeMock, syncClientMock) + syncHandler := &syncTreeHandler{ + objTree: objectTreeMock, + syncClient: syncClientMock, + queue: receiveQueueMock, + } + return &syncHandlerFixture{ + ctrl: ctrl, + syncClientMock: syncClientMock, + objectTreeMock: objectTreeMock, + receiveQueueMock: receiveQueueMock, + syncHandler: syncHandler, + } +} + +func (fx *syncHandlerFixture) stop() { + fx.ctrl.Finish() +} + +func TestSyncHandler_HandleHeadUpdate(t *testing.T) { + ctx := context.Background() log = zap.NewNop().Sugar() t.Run("head update non empty all heads added", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() treeId := "treeId" senderId := "senderId" chWithId := &treechangeproto.RawTreeChangeWithId{} @@ -56,29 +84,29 @@ func TestSyncHandler_HandleHeadUpdate(t *testing.T) { treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) objectMsg, _ := marshallTreeMessage(treeMsg, treeId, "") - objectTreeMock.EXPECT(). - ID().AnyTimes().Return(treeId) - objectTreeMock.EXPECT(). - Heads(). - Return([]string{"h2"}) - objectTreeMock.EXPECT(). - HasChanges(gomock.Eq([]string{"h1"})). - Return(false) - objectTreeMock.EXPECT(). - AddRawChanges(gomock.Any(), gomock.Eq([]*treechangeproto.RawTreeChangeWithId{chWithId})). - Return(tree.AddResult{}, nil) - objectTreeMock.EXPECT(). - Heads(). - Return([]string{"h2", "h1"}) - objectTreeMock.EXPECT(). - HasChanges(gomock.Eq([]string{"h1"})). - Return(true) + fx.receiveQueueMock.EXPECT().AddMessage(senderId, gomock.Eq(treeMsg), "").Return(false) + fx.receiveQueueMock.EXPECT().GetMessage(senderId).Return(treeMsg, "", nil) - err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + fx.objectTreeMock.EXPECT().ID().AnyTimes().Return(treeId) + fx.objectTreeMock.EXPECT().Heads().Return([]string{"h2"}).Times(2) + fx.objectTreeMock.EXPECT().HasChanges(gomock.Eq([]string{"h1"})).Return(false) + fx.objectTreeMock.EXPECT(). + AddRawChanges(gomock.Any(), gomock.Eq(tree.RawChangesPayload{ + NewHeads: []string{"h1"}, + RawChanges: []*treechangeproto.RawTreeChangeWithId{chWithId}, + })). + Return(tree.AddResult{}, nil) + fx.objectTreeMock.EXPECT().Heads().Return([]string{"h2", "h1"}) + fx.objectTreeMock.EXPECT().HasChanges(gomock.Eq([]string{"h1"})).Return(true) + + fx.receiveQueueMock.EXPECT().ClearQueue(senderId) + err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) require.NoError(t, err) }) t.Run("head update non empty heads not added", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() treeId := "treeId" senderId := "senderId" chWithId := &treechangeproto.RawTreeChangeWithId{} @@ -90,38 +118,32 @@ func TestSyncHandler_HandleHeadUpdate(t *testing.T) { treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) objectMsg, _ := marshallTreeMessage(treeMsg, treeId, "") fullRequest := &treechangeproto.TreeSyncMessage{} + fx.receiveQueueMock.EXPECT().AddMessage(senderId, gomock.Eq(treeMsg), "").Return(false) + fx.receiveQueueMock.EXPECT().GetMessage(senderId).Return(treeMsg, "", nil) - objectTreeMock.EXPECT(). - ID().AnyTimes().Return(treeId) - objectTreeMock.EXPECT(). - Heads(). - Return([]string{"h2"}) - objectTreeMock.EXPECT(). - HasChanges(gomock.Eq([]string{"h1"})). - Return(false) - objectTreeMock.EXPECT(). - AddRawChanges(gomock.Any(), gomock.Eq([]*treechangeproto.RawTreeChangeWithId{chWithId})). + fx.objectTreeMock.EXPECT().ID().AnyTimes().Return(treeId) + fx.objectTreeMock.EXPECT().Heads().Return([]string{"h2"}).AnyTimes() + fx.objectTreeMock.EXPECT().HasChanges(gomock.Eq([]string{"h1"})).Return(false) + fx.objectTreeMock.EXPECT(). + AddRawChanges(gomock.Any(), gomock.Eq(tree.RawChangesPayload{ + NewHeads: []string{"h1"}, + RawChanges: []*treechangeproto.RawTreeChangeWithId{chWithId}, + })). Return(tree.AddResult{}, nil) - objectTreeMock.EXPECT(). - Heads(). - Return([]string{"h2"}) - objectTreeMock.EXPECT(). - HasChanges(gomock.Eq([]string{"h1"})). - Return(false) - syncClientMock.EXPECT(). - CreateFullSyncRequest(gomock.Eq(objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). + fx.objectTreeMock.EXPECT().HasChanges(gomock.Eq([]string{"h1"})).Return(false) + fx.syncClientMock.EXPECT(). + CreateFullSyncRequest(gomock.Eq(fx.objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). Return(fullRequest, nil) - objectTreeMock.EXPECT(). - Heads(). - Return([]string{"h2"}) + fx.syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Eq(fullRequest), gomock.Eq("")) - syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Eq(fullRequest), gomock.Eq("")) - - err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + fx.receiveQueueMock.EXPECT().ClearQueue(senderId) + err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) require.NoError(t, err) }) t.Run("head update non empty equal heads", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() treeId := "treeId" senderId := "senderId" chWithId := &treechangeproto.RawTreeChangeWithId{} @@ -132,18 +154,20 @@ func TestSyncHandler_HandleHeadUpdate(t *testing.T) { } treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) objectMsg, _ := marshallTreeMessage(treeMsg, treeId, "") + fx.receiveQueueMock.EXPECT().AddMessage(senderId, gomock.Eq(treeMsg), "").Return(false) + fx.receiveQueueMock.EXPECT().GetMessage(senderId).Return(treeMsg, "", nil) - objectTreeMock.EXPECT(). - ID().AnyTimes().Return(treeId) - objectTreeMock.EXPECT(). - Heads(). - Return([]string{"h1"}) + fx.objectTreeMock.EXPECT().ID().AnyTimes().Return(treeId) + fx.objectTreeMock.EXPECT().Heads().Return([]string{"h1"}).AnyTimes() - err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + fx.receiveQueueMock.EXPECT().ClearQueue(senderId) + err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) require.NoError(t, err) }) t.Run("head update empty", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() treeId := "treeId" senderId := "senderId" chWithId := &treechangeproto.RawTreeChangeWithId{} @@ -155,26 +179,24 @@ func TestSyncHandler_HandleHeadUpdate(t *testing.T) { treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) objectMsg, _ := marshallTreeMessage(treeMsg, treeId, "") fullRequest := &treechangeproto.TreeSyncMessage{} + fx.receiveQueueMock.EXPECT().AddMessage(senderId, gomock.Eq(treeMsg), "").Return(false) + fx.receiveQueueMock.EXPECT().GetMessage(senderId).Return(treeMsg, "", nil) - objectTreeMock.EXPECT(). - ID().AnyTimes().Return(treeId) - objectTreeMock.EXPECT(). - Heads(). - Return([]string{"h2"}) - syncClientMock.EXPECT(). - CreateFullSyncRequest(gomock.Eq(objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). + fx.objectTreeMock.EXPECT().ID().AnyTimes().Return(treeId) + fx.objectTreeMock.EXPECT().Heads().Return([]string{"h2"}).AnyTimes() + fx.syncClientMock.EXPECT(). + CreateFullSyncRequest(gomock.Eq(fx.objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). Return(fullRequest, nil) - objectTreeMock.EXPECT(). - Heads(). - Return([]string{"h2"}) + fx.syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Eq(fullRequest), gomock.Eq("")) - syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Eq(fullRequest), gomock.Eq("")) - - err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + fx.receiveQueueMock.EXPECT().ClearQueue(senderId) + err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) require.NoError(t, err) }) t.Run("head update empty equal heads", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() treeId := "treeId" senderId := "senderId" chWithId := &treechangeproto.RawTreeChangeWithId{} @@ -185,29 +207,25 @@ func TestSyncHandler_HandleHeadUpdate(t *testing.T) { } treeMsg := treechangeproto.WrapHeadUpdate(headUpdate, chWithId) objectMsg, _ := marshallTreeMessage(treeMsg, treeId, "") + fx.receiveQueueMock.EXPECT().AddMessage(senderId, gomock.Eq(treeMsg), "").Return(false) + fx.receiveQueueMock.EXPECT().GetMessage(senderId).Return(treeMsg, "", nil) - objectTreeMock.EXPECT(). - ID().AnyTimes().Return(treeId) - objectTreeMock.EXPECT(). - Heads(). - Return([]string{"h1"}) + fx.objectTreeMock.EXPECT().ID().AnyTimes().Return(treeId) + fx.objectTreeMock.EXPECT().Heads().Return([]string{"h1"}).AnyTimes() - err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + fx.receiveQueueMock.EXPECT().ClearQueue(senderId) + err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) require.NoError(t, err) }) } func TestSyncHandler_HandleFullSyncRequest(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - ctx := context.Background() - syncClientMock := mock_synctree.NewMockSyncClient(ctrl) - objectTreeMock := newTestObjMock(mock_tree.NewMockObjectTree(ctrl)) - - syncHandler := newSyncTreeHandler(objectTreeMock, syncClientMock) log = zap.NewNop().Sugar() + t.Run("full sync request with change", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() treeId := "treeId" senderId := "senderId" chWithId := &treechangeproto.RawTreeChangeWithId{} @@ -219,27 +237,32 @@ func TestSyncHandler_HandleFullSyncRequest(t *testing.T) { treeMsg := treechangeproto.WrapFullRequest(fullSyncRequest, chWithId) objectMsg, _ := marshallTreeMessage(treeMsg, treeId, "") fullResponse := &treechangeproto.TreeSyncMessage{} - objectTreeMock.EXPECT(). - ID().AnyTimes().Return(treeId) - objectTreeMock.EXPECT().Header().Return(nil) - objectTreeMock.EXPECT(). - Heads(). - Return([]string{"h2"}) - objectTreeMock.EXPECT(). - HasChanges(gomock.Eq([]string{"h1"})). - Return(false) - objectTreeMock.EXPECT(). - AddRawChanges(gomock.Any(), gomock.Eq([]*treechangeproto.RawTreeChangeWithId{chWithId})). + fx.receiveQueueMock.EXPECT().AddMessage(senderId, gomock.Eq(treeMsg), "").Return(false) + fx.receiveQueueMock.EXPECT().GetMessage(senderId).Return(treeMsg, "", nil) + + fx.objectTreeMock.EXPECT().ID().AnyTimes().Return(treeId) + fx.objectTreeMock.EXPECT().Header().Return(nil) + fx.objectTreeMock.EXPECT().Heads().Return([]string{"h2"}).AnyTimes() + fx.objectTreeMock.EXPECT().HasChanges(gomock.Eq([]string{"h1"})).Return(false) + fx.objectTreeMock.EXPECT(). + AddRawChanges(gomock.Any(), gomock.Eq(tree.RawChangesPayload{ + NewHeads: []string{"h1"}, + RawChanges: []*treechangeproto.RawTreeChangeWithId{chWithId}, + })). Return(tree.AddResult{}, nil) - syncClientMock.EXPECT(). - CreateFullSyncResponse(gomock.Eq(objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). + fx.syncClientMock.EXPECT(). + CreateFullSyncResponse(gomock.Eq(fx.objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). Return(fullResponse, nil) - syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Eq(fullResponse), gomock.Eq("")) - err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + fx.syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Eq(fullResponse), gomock.Eq("")) + + fx.receiveQueueMock.EXPECT().ClearQueue(senderId) + err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) require.NoError(t, err) }) t.Run("full sync request with change same heads", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() treeId := "treeId" senderId := "senderId" chWithId := &treechangeproto.RawTreeChangeWithId{} @@ -251,21 +274,28 @@ func TestSyncHandler_HandleFullSyncRequest(t *testing.T) { treeMsg := treechangeproto.WrapFullRequest(fullSyncRequest, chWithId) objectMsg, _ := marshallTreeMessage(treeMsg, treeId, "") fullResponse := &treechangeproto.TreeSyncMessage{} - objectTreeMock.EXPECT(). + fx.receiveQueueMock.EXPECT().AddMessage(senderId, gomock.Eq(treeMsg), "").Return(false) + fx.receiveQueueMock.EXPECT().GetMessage(senderId).Return(treeMsg, "", nil) + + fx.objectTreeMock.EXPECT(). ID().AnyTimes().Return(treeId) - objectTreeMock.EXPECT().Header().Return(nil) - objectTreeMock.EXPECT(). + fx.objectTreeMock.EXPECT().Header().Return(nil) + fx.objectTreeMock.EXPECT(). Heads(). - Return([]string{"h1"}) - syncClientMock.EXPECT(). - CreateFullSyncResponse(gomock.Eq(objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). + Return([]string{"h1"}).AnyTimes() + fx.syncClientMock.EXPECT(). + CreateFullSyncResponse(gomock.Eq(fx.objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). Return(fullResponse, nil) - syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Eq(fullResponse), gomock.Eq("")) - err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + fx.syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Eq(fullResponse), gomock.Eq("")) + + fx.receiveQueueMock.EXPECT().ClearQueue(senderId) + err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) require.NoError(t, err) }) t.Run("full sync request without change but with reply id", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() treeId := "treeId" senderId := "senderId" replyId := "replyId" @@ -277,18 +307,25 @@ func TestSyncHandler_HandleFullSyncRequest(t *testing.T) { treeMsg := treechangeproto.WrapFullRequest(fullSyncRequest, chWithId) objectMsg, _ := marshallTreeMessage(treeMsg, treeId, replyId) fullResponse := &treechangeproto.TreeSyncMessage{} - objectTreeMock.EXPECT(). + fx.receiveQueueMock.EXPECT().AddMessage(senderId, gomock.Eq(treeMsg), replyId).Return(false) + fx.receiveQueueMock.EXPECT().GetMessage(senderId).Return(treeMsg, replyId, nil) + + fx.objectTreeMock.EXPECT(). ID().AnyTimes().Return(treeId) - objectTreeMock.EXPECT().Header().Return(nil) - syncClientMock.EXPECT(). - CreateFullSyncResponse(gomock.Eq(objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). + fx.objectTreeMock.EXPECT().Header().Return(nil) + fx.syncClientMock.EXPECT(). + CreateFullSyncResponse(gomock.Eq(fx.objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"})). Return(fullResponse, nil) - syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Eq(fullResponse), gomock.Eq(replyId)) - err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + fx.syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Eq(fullResponse), gomock.Eq(replyId)) + + fx.receiveQueueMock.EXPECT().ClearQueue(senderId) + err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) require.NoError(t, err) }) t.Run("full sync request with add raw changes error", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() treeId := "treeId" senderId := "senderId" chWithId := &treechangeproto.RawTreeChangeWithId{} @@ -299,36 +336,39 @@ func TestSyncHandler_HandleFullSyncRequest(t *testing.T) { } treeMsg := treechangeproto.WrapFullRequest(fullSyncRequest, chWithId) objectMsg, _ := marshallTreeMessage(treeMsg, treeId, "") - objectTreeMock.EXPECT(). + fx.receiveQueueMock.EXPECT().AddMessage(senderId, gomock.Eq(treeMsg), "").Return(false) + fx.receiveQueueMock.EXPECT().GetMessage(senderId).Return(treeMsg, "", nil) + + fx.objectTreeMock.EXPECT(). ID().AnyTimes().Return(treeId) - objectTreeMock.EXPECT().Header().Return(nil) - objectTreeMock.EXPECT(). + fx.objectTreeMock.EXPECT().Header().Return(nil) + fx.objectTreeMock.EXPECT(). Heads(). Return([]string{"h2"}) - objectTreeMock.EXPECT(). + fx.objectTreeMock.EXPECT(). HasChanges(gomock.Eq([]string{"h1"})). Return(false) - objectTreeMock.EXPECT(). - AddRawChanges(gomock.Any(), gomock.Eq([]*treechangeproto.RawTreeChangeWithId{chWithId})). + fx.objectTreeMock.EXPECT(). + AddRawChanges(gomock.Any(), gomock.Eq(tree.RawChangesPayload{ + NewHeads: []string{"h1"}, + RawChanges: []*treechangeproto.RawTreeChangeWithId{chWithId}, + })). Return(tree.AddResult{}, fmt.Errorf("")) - syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Any(), gomock.Eq("")) - err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + fx.syncClientMock.EXPECT().SendAsync(gomock.Eq(senderId), gomock.Any(), gomock.Eq("")) + + fx.receiveQueueMock.EXPECT().ClearQueue(senderId) + err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) require.Error(t, err) }) } func TestSyncHandler_HandleFullSyncResponse(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - ctx := context.Background() - syncClientMock := mock_synctree.NewMockSyncClient(ctrl) - objectTreeMock := newTestObjMock(mock_tree.NewMockObjectTree(ctrl)) - - syncHandler := newSyncTreeHandler(objectTreeMock, syncClientMock) log = zap.NewNop().Sugar() t.Run("full sync response with change", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() treeId := "treeId" senderId := "senderId" replyId := "replyId" @@ -340,22 +380,31 @@ func TestSyncHandler_HandleFullSyncResponse(t *testing.T) { } treeMsg := treechangeproto.WrapFullResponse(fullSyncResponse, chWithId) objectMsg, _ := marshallTreeMessage(treeMsg, treeId, replyId) - objectTreeMock.EXPECT().ID().AnyTimes().Return(treeId) - objectTreeMock.EXPECT(). + fx.receiveQueueMock.EXPECT().AddMessage(senderId, gomock.Eq(treeMsg), replyId).Return(false) + fx.receiveQueueMock.EXPECT().GetMessage(senderId).Return(treeMsg, replyId, nil) + + fx.objectTreeMock.EXPECT().ID().AnyTimes().Return(treeId) + fx.objectTreeMock.EXPECT(). Heads(). - Return([]string{"h2"}) - objectTreeMock.EXPECT(). + Return([]string{"h2"}).AnyTimes() + fx.objectTreeMock.EXPECT(). HasChanges(gomock.Eq([]string{"h1"})). Return(false) - objectTreeMock.EXPECT(). - AddRawChanges(gomock.Any(), gomock.Eq([]*treechangeproto.RawTreeChangeWithId{chWithId})). + fx.objectTreeMock.EXPECT(). + AddRawChanges(gomock.Any(), gomock.Eq(tree.RawChangesPayload{ + NewHeads: []string{"h1"}, + RawChanges: []*treechangeproto.RawTreeChangeWithId{chWithId}, + })). Return(tree.AddResult{}, nil) - err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + fx.receiveQueueMock.EXPECT().ClearQueue(senderId) + err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) require.NoError(t, err) }) t.Run("full sync response with same heads", func(t *testing.T) { + fx := newSyncHandlerFixture(t) + defer fx.stop() treeId := "treeId" senderId := "senderId" replyId := "replyId" @@ -367,12 +416,16 @@ func TestSyncHandler_HandleFullSyncResponse(t *testing.T) { } treeMsg := treechangeproto.WrapFullResponse(fullSyncResponse, chWithId) objectMsg, _ := marshallTreeMessage(treeMsg, treeId, replyId) - objectTreeMock.EXPECT().ID().AnyTimes().Return(treeId) - objectTreeMock.EXPECT(). - Heads(). - Return([]string{"h1"}) + fx.receiveQueueMock.EXPECT().AddMessage(senderId, gomock.Eq(treeMsg), replyId).Return(false) + fx.receiveQueueMock.EXPECT().GetMessage(senderId).Return(treeMsg, replyId, nil) - err := syncHandler.HandleMessage(ctx, senderId, objectMsg) + fx.objectTreeMock.EXPECT().ID().AnyTimes().Return(treeId) + fx.objectTreeMock.EXPECT(). + Heads(). + Return([]string{"h1"}).AnyTimes() + + fx.receiveQueueMock.EXPECT().ClearQueue(senderId) + err := fx.syncHandler.HandleMessage(ctx, senderId, objectMsg) require.NoError(t, err) }) } diff --git a/common/config/config.go b/common/config/config.go index 59afb523..eb8a8c61 100644 --- a/common/config/config.go +++ b/common/config/config.go @@ -32,6 +32,7 @@ type Config struct { Storage Storage `yaml:"storage"` Metric Metric `yaml:"metric"` Log Log `yaml:"log"` + Stream Stream `yaml:"stream"` } func (c *Config) Init(a *app.App) (err error) { @@ -51,6 +52,10 @@ func (c Config) GetGRPCServer() GrpcServer { return c.GrpcServer } +func (c Config) GetStream() Stream { + return c.Stream +} + func (c Config) GetAccount() Account { return c.Account } diff --git a/common/config/stream.go b/common/config/stream.go new file mode 100644 index 00000000..e120c2f9 --- /dev/null +++ b/common/config/stream.go @@ -0,0 +1,6 @@ +package config + +type Stream struct { + TimeoutMilliseconds int `yaml:"timeoutMilliseconds"` + MaxMsgSizeMb int `yaml:"maxMsgSizeMb"` +} diff --git a/common/go.mod b/common/go.mod index 8dfec05d..f8522376 100644 --- a/common/go.mod +++ b/common/go.mod @@ -28,6 +28,7 @@ require ( require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/cheggaaa/mb/v3 v3.0.0-20221122160120-e9034545510c // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect github.com/fogleman/gg v1.3.0 // indirect @@ -55,7 +56,7 @@ require ( github.com/spaolacci/murmur3 v1.1.0 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.8.0 // indirect - golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect + golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect golang.org/x/image v0.0.0-20200119044424-58c23975cae1 // indirect golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect google.golang.org/protobuf v1.28.1 // indirect diff --git a/common/go.sum b/common/go.sum index 03e87801..3359eaee 100644 --- a/common/go.sum +++ b/common/go.sum @@ -56,6 +56,8 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf 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/v3 v3.0.0-20221122160120-e9034545510c h1:+bD75daSbsxyTzkKpNplC4xls+7/tGwty+zruzOnOmk= +github.com/cheggaaa/mb/v3 v3.0.0-20221122160120-e9034545510c/go.mod h1:zCt2QeYukhd/g0bIdNqF+b/kKz1hnLFNDkP49qN5kqI= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -313,6 +315,7 @@ golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +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/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= diff --git a/common/net/dialer/dialer.go b/common/net/dialer/dialer.go index ebef079b..44b23b54 100644 --- a/common/net/dialer/dialer.go +++ b/common/net/dialer/dialer.go @@ -8,12 +8,16 @@ import ( "github.com/anytypeio/go-anytype-infrastructure-experiments/common/config" "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/peer" "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/secure" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/timeoutconn" "github.com/libp2p/go-libp2p/core/sec" "go.uber.org/zap" "net" "storj.io/drpc" "storj.io/drpc/drpcconn" + "storj.io/drpc/drpcmanager" + "storj.io/drpc/drpcwire" "sync" + "time" ) const CName = "common.net.dialer" @@ -34,6 +38,7 @@ type Dialer interface { type dialer struct { transport secure.Service + config *config.Config peerAddrs map[string][]string mu sync.RWMutex @@ -41,9 +46,9 @@ type dialer struct { func (d *dialer) Init(a *app.App) (err error) { d.transport = a.MustComponent(secure.CName).(secure.Service) - nodes := a.MustComponent(config.CName).(*config.Config).Nodes + d.config = a.MustComponent(config.CName).(*config.Config) d.peerAddrs = map[string][]string{} - for _, n := range nodes { + for _, n := range d.config.Nodes { d.peerAddrs[n.PeerId] = []string{n.Address} } return @@ -90,11 +95,15 @@ func (d *dialer) handshake(ctx context.Context, addr string) (conn drpc.Conn, sc if err != nil { return } - sc, err = d.transport.TLSConn(ctx, tcpConn) + + timeoutConn := timeoutconn.NewConn(tcpConn, time.Millisecond*time.Duration(d.config.Stream.TimeoutMilliseconds)) + sc, err = d.transport.TLSConn(ctx, timeoutConn) if err != nil { return } log.Info("connected with remote host", zap.String("serverPeer", sc.RemotePeer().String()), zap.String("per", sc.LocalPeer().String())) - conn = drpcconn.New(sc) + conn = drpcconn.NewWithOptions(sc, drpcconn.Options{Manager: drpcmanager.Options{ + Reader: drpcwire.ReaderOptions{MaximumBufferSize: d.config.Stream.MaxMsgSizeMb * (1 << 20)}, + }}) return conn, sc, err } diff --git a/common/net/rpc/server/baseserver.go b/common/net/rpc/server/baseserver.go index 49347a9a..02e12fd8 100644 --- a/common/net/rpc/server/baseserver.go +++ b/common/net/rpc/server/baseserver.go @@ -8,8 +8,10 @@ import ( "io" "net" "storj.io/drpc" + "storj.io/drpc/drpcmanager" "storj.io/drpc/drpcmux" "storj.io/drpc/drpcserver" + "storj.io/drpc/drpcwire" "time" ) @@ -22,21 +24,31 @@ type BaseDrpcServer struct { } type DRPCHandlerWrapper func(handler drpc.Handler) drpc.Handler -type ListenerConverter func(listener net.Listener) secure.ContextListener +type ListenerConverter func(listener net.Listener, timeoutMillis int) secure.ContextListener + +type Params struct { + BufferSizeMb int + ListenAddrs []string + Wrapper DRPCHandlerWrapper + Converter ListenerConverter + TimeoutMillis int +} func NewBaseDrpcServer() *BaseDrpcServer { return &BaseDrpcServer{Mux: drpcmux.New()} } -func (s *BaseDrpcServer) Run(ctx context.Context, listenAddrs []string, wrapper DRPCHandlerWrapper, converter ListenerConverter) (err error) { - s.drpcServer = drpcserver.New(wrapper(s.Mux)) +func (s *BaseDrpcServer) Run(ctx context.Context, params Params) (err error) { + s.drpcServer = drpcserver.NewWithOptions(params.Wrapper(s.Mux), drpcserver.Options{Manager: drpcmanager.Options{ + Reader: drpcwire.ReaderOptions{MaximumBufferSize: params.BufferSizeMb * (1 << 20)}, + }}) ctx, s.cancel = context.WithCancel(ctx) - for _, addr := range listenAddrs { + for _, addr := range params.ListenAddrs { tcpList, err := net.Listen("tcp", addr) if err != nil { return err } - tlsList := converter(tcpList) + tlsList := params.Converter(tcpList, params.TimeoutMillis) go s.serve(ctx, tlsList) } return diff --git a/common/net/rpc/server/drpcserver.go b/common/net/rpc/server/drpcserver.go index 73559cfe..aaa3f759 100644 --- a/common/net/rpc/server/drpcserver.go +++ b/common/net/rpc/server/drpcserver.go @@ -26,17 +26,18 @@ type DRPCServer interface { type configGetter interface { GetGRPCServer() config.GrpcServer + GetStream() config.Stream } type drpcServer struct { - config config.GrpcServer + config configGetter metric metric.Metric transport secure.Service *BaseDrpcServer } func (s *drpcServer) Init(a *app.App) (err error) { - s.config = a.MustComponent(config.CName).(configGetter).GetGRPCServer() + s.config = a.MustComponent(config.CName).(configGetter) s.metric = a.MustComponent(metric.CName).(metric.Metric) s.transport = a.MustComponent(secure.CName).(secure.Service) return nil @@ -61,16 +62,19 @@ func (s *drpcServer) Run(ctx context.Context) (err error) { if err = s.metric.Registry().Register(histVec); err != nil { return } - return s.BaseDrpcServer.Run( - ctx, - s.config.ListenAddrs, - func(handler drpc.Handler) drpc.Handler { + params := Params{ + BufferSizeMb: s.config.GetStream().MaxMsgSizeMb, + TimeoutMillis: s.config.GetStream().TimeoutMilliseconds, + ListenAddrs: s.config.GetGRPCServer().ListenAddrs, + Wrapper: func(handler drpc.Handler) drpc.Handler { return &metric.PrometheusDRPC{ Handler: handler, SummaryVec: histVec, } }, - s.transport.TLSListener) + Converter: s.transport.TLSListener, + } + return s.BaseDrpcServer.Run(ctx, params) } func (s *drpcServer) Close(ctx context.Context) (err error) { diff --git a/common/net/secure/basiclistener.go b/common/net/secure/basiclistener.go index 7244edf0..927965af 100644 --- a/common/net/secure/basiclistener.go +++ b/common/net/secure/basiclistener.go @@ -2,18 +2,25 @@ package secure import ( "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/timeoutconn" "net" + "time" ) type basicListener struct { net.Listener + timeoutMillis int } -func newBasicListener(listener net.Listener) ContextListener { - return &basicListener{listener} +func newBasicListener(listener net.Listener, timeoutMillis int) ContextListener { + return &basicListener{listener, timeoutMillis} } func (b *basicListener) Accept(ctx context.Context) (context.Context, net.Conn, error) { conn, err := b.Listener.Accept() - return ctx, conn, err + if err != nil { + return nil, nil, err + } + timeoutConn := timeoutconn.NewConn(conn, time.Duration(b.timeoutMillis)*time.Millisecond) + return ctx, timeoutConn, err } diff --git a/common/net/secure/service.go b/common/net/secure/service.go index ea92faf2..9e919582 100644 --- a/common/net/secure/service.go +++ b/common/net/secure/service.go @@ -25,8 +25,8 @@ func New() Service { } type Service interface { - TLSListener(lis net.Listener) ContextListener - BasicListener(lis net.Listener) ContextListener + TLSListener(lis net.Listener, timeoutMillis int) ContextListener + BasicListener(lis net.Listener, timeoutMillis int) ContextListener TLSConn(ctx context.Context, conn net.Conn) (sec.SecureConn, error) app.Component } @@ -54,12 +54,12 @@ func (s *service) Name() (name string) { return CName } -func (s *service) TLSListener(lis net.Listener) ContextListener { - return newTLSListener(s.key, lis) +func (s *service) TLSListener(lis net.Listener, timeoutMillis int) ContextListener { + return newTLSListener(s.key, lis, timeoutMillis) } -func (s *service) BasicListener(lis net.Listener) ContextListener { - return newBasicListener(lis) +func (s *service) BasicListener(lis net.Listener, timeoutMillis int) ContextListener { + return newBasicListener(lis, timeoutMillis) } func (s *service) TLSConn(ctx context.Context, conn net.Conn) (sec.SecureConn, error) { diff --git a/common/net/secure/tlslistener.go b/common/net/secure/tlslistener.go index db16470f..120c6f01 100644 --- a/common/net/secure/tlslistener.go +++ b/common/net/secure/tlslistener.go @@ -3,9 +3,11 @@ package secure import ( "context" "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/peer" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/timeoutconn" "github.com/libp2p/go-libp2p/core/crypto" libp2ptls "github.com/libp2p/go-libp2p/p2p/security/tls" "net" + "time" ) type ContextListener interface { @@ -20,17 +22,19 @@ type ContextListener interface { Addr() net.Addr } -func newTLSListener(key crypto.PrivKey, lis net.Listener) ContextListener { +func newTLSListener(key crypto.PrivKey, lis net.Listener, timeoutMillis int) ContextListener { tr, _ := libp2ptls.New(key) return &tlsListener{ - tr: tr, - Listener: lis, + tr: tr, + Listener: lis, + timeoutMillis: timeoutMillis, } } type tlsListener struct { net.Listener - tr *libp2ptls.Transport + tr *libp2ptls.Transport + timeoutMillis int } func (p *tlsListener) Accept(ctx context.Context) (context.Context, net.Conn, error) { @@ -38,7 +42,8 @@ func (p *tlsListener) Accept(ctx context.Context) (context.Context, net.Conn, er if err != nil { return nil, nil, err } - return p.upgradeConn(ctx, conn) + timeoutConn := timeoutconn.NewConn(conn, time.Duration(p.timeoutMillis)*time.Millisecond) + return p.upgradeConn(ctx, timeoutConn) } func (p *tlsListener) upgradeConn(ctx context.Context, conn net.Conn) (context.Context, net.Conn, error) { diff --git a/common/net/timeoutconn/conn.go b/common/net/timeoutconn/conn.go new file mode 100644 index 00000000..77f53069 --- /dev/null +++ b/common/net/timeoutconn/conn.go @@ -0,0 +1,39 @@ +package timeoutconn + +import ( + "errors" + "net" + "os" + "time" +) + +type Conn struct { + net.Conn + timeout time.Duration +} + +func NewConn(conn net.Conn, timeout time.Duration) *Conn { + return &Conn{conn, timeout} +} + +func (c *Conn) Write(p []byte) (n int, err error) { + for { + if c.timeout != 0 { + c.Conn.SetWriteDeadline(time.Now().Add(c.timeout)) + } + nn, err := c.Conn.Write(p[n:]) + n += nn + if n < len(p) && nn > 0 && errors.Is(err, os.ErrDeadlineExceeded) { + // Keep extending the deadline so long as we're making progress. + continue + } + if c.timeout != 0 { + c.Conn.SetWriteDeadline(time.Time{}) + } + if err != nil { + // if the connection is timed out and we should close it + c.Conn.Close() + } + return n, err + } +} diff --git a/common/pkg/acl/list/aclstate.go b/common/pkg/acl/list/aclstate.go index 94754aba..90a33c5c 100644 --- a/common/pkg/acl/list/aclstate.go +++ b/common/pkg/acl/list/aclstate.go @@ -246,7 +246,7 @@ func (st *ACLState) applyChangeData(changeData *aclrecordproto.ACLData, hash uin return } - if !st.hasPermission(identity, aclrecordproto.ACLUserPermissions_Admin) { + if !st.HasPermission(identity, aclrecordproto.ACLUserPermissions_Admin) { err = fmt.Errorf("user %s must have admin permissions", identity) return } @@ -413,7 +413,7 @@ func (st *ACLState) decryptReadKeyAndHash(msg []byte) (*symmetric.Key, uint64, e return key, hasher.Sum64(), nil } -func (st *ACLState) hasPermission(identity []byte, permission aclrecordproto.ACLUserPermissions) bool { +func (st *ACLState) HasPermission(identity []byte, permission aclrecordproto.ACLUserPermissions) bool { state, exists := st.userStates[string(identity)] if !exists { return false diff --git a/common/pkg/acl/tree/mock_objecttree/mock_objecttree.go b/common/pkg/acl/tree/mock_objecttree/mock_objecttree.go index 4cfca949..ca2151cb 100644 --- a/common/pkg/acl/tree/mock_objecttree/mock_objecttree.go +++ b/common/pkg/acl/tree/mock_objecttree/mock_objecttree.go @@ -53,23 +53,18 @@ func (mr *MockObjectTreeMockRecorder) AddContent(arg0, arg1 interface{}) *gomock } // AddRawChanges mocks base method. -func (m *MockObjectTree) AddRawChanges(arg0 context.Context, arg1 ...*treechangeproto.RawTreeChangeWithId) (tree.AddResult, error) { +func (m *MockObjectTree) AddRawChanges(arg0 context.Context, arg1 tree.RawChangesPayload) (tree.AddResult, error) { m.ctrl.T.Helper() - varargs := []interface{}{arg0} - for _, a := range arg1 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "AddRawChanges", varargs...) + ret := m.ctrl.Call(m, "AddRawChanges", arg0, arg1) ret0, _ := ret[0].(tree.AddResult) ret1, _ := ret[1].(error) return ret0, ret1 } // AddRawChanges indicates an expected call of AddRawChanges. -func (mr *MockObjectTreeMockRecorder) AddRawChanges(arg0 interface{}, arg1 ...interface{}) *gomock.Call { +func (mr *MockObjectTreeMockRecorder) AddRawChanges(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0}, arg1...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRawChanges", reflect.TypeOf((*MockObjectTree)(nil).AddRawChanges), varargs...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRawChanges", reflect.TypeOf((*MockObjectTree)(nil).AddRawChanges), arg0, arg1) } // ChangesAfterCommonSnapshot mocks base method. diff --git a/common/pkg/acl/tree/objecttree.go b/common/pkg/acl/tree/objecttree.go index bb8dfc6a..772a7f1e 100644 --- a/common/pkg/acl/tree/objecttree.go +++ b/common/pkg/acl/tree/objecttree.go @@ -4,6 +4,7 @@ package tree import ( "context" "errors" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/common" list "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/list" "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage" @@ -33,6 +34,11 @@ type AddResult struct { Mode Mode } +type RawChangesPayload struct { + NewHeads []string + RawChanges []*treechangeproto.RawTreeChangeWithId +} + type ChangeIterateFunc = func(change *Change) bool type ChangeConvertFunc = func(decrypted []byte) (any, error) @@ -55,7 +61,7 @@ type ObjectTree interface { Storage() storage.TreeStorage AddContent(ctx context.Context, content SignableChangeContent) (AddResult, error) - AddRawChanges(ctx context.Context, changes ...*treechangeproto.RawTreeChangeWithId) (AddResult, error) + AddRawChanges(ctx context.Context, changes RawChangesPayload) (AddResult, error) Delete() error Close() error @@ -113,10 +119,10 @@ func defaultObjectTreeDeps( } } -func (ot *objectTree) rebuildFromStorage(newChanges []*Change) (err error) { +func (ot *objectTree) rebuildFromStorage(theirHeads []string, newChanges []*Change) (err error) { ot.treeBuilder.Reset() - ot.tree, err = ot.treeBuilder.Build(newChanges) + ot.tree, err = ot.treeBuilder.Build(theirHeads, newChanges) if err != nil { return } @@ -192,6 +198,13 @@ func (ot *objectTree) prepareBuilderContent(content SignableChangeContent) (cnt readKey *symmetric.Key readKeyHash uint64 ) + canWrite := state.HasPermission(content.Identity, aclrecordproto.ACLUserPermissions_Writer) || + state.HasPermission(content.Identity, aclrecordproto.ACLUserPermissions_Admin) + if !canWrite { + err = list.ErrInsufficientPermissions + return + } + if content.IsEncrypted { readKeyHash = state.CurrentReadKeyHash() readKey, err = state.CurrentReadKey() @@ -213,8 +226,8 @@ func (ot *objectTree) prepareBuilderContent(content SignableChangeContent) (cnt return } -func (ot *objectTree) AddRawChanges(ctx context.Context, rawChanges ...*treechangeproto.RawTreeChangeWithId) (addResult AddResult, err error) { - addResult, err = ot.addRawChanges(ctx, rawChanges...) +func (ot *objectTree) AddRawChanges(ctx context.Context, changesPayload RawChangesPayload) (addResult AddResult, err error) { + addResult, err = ot.addRawChanges(ctx, changesPayload) if err != nil { return } @@ -235,7 +248,7 @@ func (ot *objectTree) AddRawChanges(ctx context.Context, rawChanges ...*treechan return } -func (ot *objectTree) addRawChanges(ctx context.Context, rawChanges ...*treechangeproto.RawTreeChangeWithId) (addResult AddResult, err error) { +func (ot *objectTree) addRawChanges(ctx context.Context, changesPayload RawChangesPayload) (addResult AddResult, err error) { // resetting buffers ot.newChangesBuf = ot.newChangesBuf[:0] ot.notSeenIdxBuf = ot.notSeenIdxBuf[:0] @@ -252,7 +265,7 @@ func (ot *objectTree) addRawChanges(ctx context.Context, rawChanges ...*treechan prevHeadsCopy := headsCopy() // filtering changes, verifying and unmarshalling them - for idx, ch := range rawChanges { + for idx, ch := range changesPayload.RawChanges { // not unmarshalling the changes if they were already added either as unattached or attached if _, exists := ot.tree.attached[ch.Id]; exists { continue @@ -331,17 +344,17 @@ func (ot *objectTree) addRawChanges(ctx context.Context, rawChanges ...*treechan ot.newChangesBuf = discardFromSlice(ot.newChangesBuf, func(ch *Change) bool { return ch == nil }) if shouldRebuildFromStorage { - err = ot.rebuildFromStorage(ot.newChangesBuf) + err = ot.rebuildFromStorage(changesPayload.NewHeads, ot.newChangesBuf) if err != nil { // rebuilding without new changes - ot.rebuildFromStorage(nil) + ot.rebuildFromStorage(nil, nil) return } - addResult, err = ot.createAddResult(prevHeadsCopy, Rebuild, nil, rawChanges) + addResult, err = ot.createAddResult(prevHeadsCopy, Rebuild, nil, changesPayload.RawChanges) if err != nil { // that means that some unattached changes were somehow corrupted in memory // this shouldn't happen but if that happens, then rebuilding from storage - ot.rebuildFromStorage(nil) + ot.rebuildFromStorage(nil, nil) return } return @@ -366,11 +379,11 @@ func (ot *objectTree) addRawChanges(ctx context.Context, rawChanges ...*treechan err = ErrHasInvalidChanges return } - addResult, err = ot.createAddResult(prevHeadsCopy, mode, treeChangesAdded, rawChanges) + addResult, err = ot.createAddResult(prevHeadsCopy, mode, treeChangesAdded, changesPayload.RawChanges) if err != nil { // that means that some unattached changes were somehow corrupted in memory // this shouldn't happen but if that happens, then rebuilding from storage - ot.rebuildFromStorage(nil) + ot.rebuildFromStorage(nil, nil) return } return diff --git a/common/pkg/acl/tree/objecttree_test.go b/common/pkg/acl/tree/objecttree_test.go index 337f7903..84c39547 100644 --- a/common/pkg/acl/tree/objecttree_test.go +++ b/common/pkg/acl/tree/objecttree_test.go @@ -161,7 +161,11 @@ func TestObjectTree(t *testing.T) { changeCreator.createRaw("1", aclList.Head().Id, "0", false, "0"), changeCreator.createRaw("2", aclList.Head().Id, "0", false, "1"), } - res, err := objTree.AddRawChanges(context.Background(), rawChanges...) + payload := RawChangesPayload{ + NewHeads: []string{rawChanges[len(rawChanges)-1].Id}, + RawChanges: rawChanges, + } + res, err := objTree.AddRawChanges(context.Background(), payload) require.NoError(t, err, "adding changes should be without error") // check result @@ -201,7 +205,11 @@ func TestObjectTree(t *testing.T) { rawChanges := []*treechangeproto.RawTreeChangeWithId{ changeCreator.createRaw("0", aclList.Head().Id, "", true, ""), } - res, err := objTree.AddRawChanges(context.Background(), rawChanges...) + payload := RawChangesPayload{ + NewHeads: []string{rawChanges[len(rawChanges)-1].Id}, + RawChanges: rawChanges, + } + res, err := objTree.AddRawChanges(context.Background(), payload) require.NoError(t, err, "adding changes should be without error") // check result @@ -221,7 +229,11 @@ func TestObjectTree(t *testing.T) { rawChanges := []*treechangeproto.RawTreeChangeWithId{ changeCreator.createRaw("2", aclList.Head().Id, "0", false, "1"), } - res, err := objTree.AddRawChanges(context.Background(), rawChanges...) + payload := RawChangesPayload{ + NewHeads: []string{rawChanges[len(rawChanges)-1].Id}, + RawChanges: rawChanges, + } + res, err := objTree.AddRawChanges(context.Background(), payload) require.NoError(t, err, "adding changes should be without error") // check result @@ -246,7 +258,12 @@ func TestObjectTree(t *testing.T) { changeCreator.createRaw("3", aclList.Head().Id, "0", true, "2"), changeCreator.createRaw("4", aclList.Head().Id, "3", false, "3"), } - res, err := objTree.AddRawChanges(context.Background(), rawChanges...) + payload := RawChangesPayload{ + NewHeads: []string{rawChanges[len(rawChanges)-1].Id}, + RawChanges: rawChanges, + } + + res, err := objTree.AddRawChanges(context.Background(), payload) require.NoError(t, err, "adding changes should be without error") // check result @@ -289,7 +306,12 @@ func TestObjectTree(t *testing.T) { changeCreator.createRaw("2", aclList.Head().Id, "0", false, "1"), changeCreator.createRaw("3", aclList.Head().Id, "0", true, "2"), } - _, err := objTree.AddRawChanges(context.Background(), rawChanges...) + payload := RawChangesPayload{ + NewHeads: []string{rawChanges[len(rawChanges)-1].Id}, + RawChanges: rawChanges, + } + + _, err := objTree.AddRawChanges(context.Background(), payload) require.NoError(t, err, "adding changes should be without error") snapshotPath := objTree.SnapshotPath() @@ -312,7 +334,12 @@ func TestObjectTree(t *testing.T) { changeCreator.createRaw("6", aclList.Head().Id, "0", false, "3", "4", "5"), } - _, err := objTree.AddRawChanges(context.Background(), rawChanges...) + payload := RawChangesPayload{ + NewHeads: []string{rawChanges[len(rawChanges)-1].Id}, + RawChanges: rawChanges, + } + + _, err := objTree.AddRawChanges(context.Background(), payload) require.NoError(t, err, "adding changes should be without error") require.Equal(t, "0", objTree.Root().Id) @@ -387,7 +414,12 @@ func TestObjectTree(t *testing.T) { changeCreator.createRaw("6", aclList.Head().Id, "0", true, "3", "4", "5"), } - _, err := objTree.AddRawChanges(context.Background(), rawChanges...) + payload := RawChangesPayload{ + NewHeads: []string{rawChanges[len(rawChanges)-1].Id}, + RawChanges: rawChanges, + } + + _, err := objTree.AddRawChanges(context.Background(), payload) require.NoError(t, err, "adding changes should be without error") require.Equal(t, "6", objTree.Root().Id) @@ -458,7 +490,12 @@ func TestObjectTree(t *testing.T) { changeCreator.createRaw("2", aclList.Head().Id, "0", false, "1"), changeCreator.createRaw("3", aclList.Head().Id, "0", true, "2"), } - res, err := objTree.AddRawChanges(context.Background(), rawChanges...) + payload := RawChangesPayload{ + NewHeads: []string{rawChanges[len(rawChanges)-1].Id}, + RawChanges: rawChanges, + } + + res, err := objTree.AddRawChanges(context.Background(), payload) require.NoError(t, err, "adding changes should be without error") require.Equal(t, "3", objTree.Root().Id) @@ -467,7 +504,12 @@ func TestObjectTree(t *testing.T) { changeCreator.createRaw("5", aclList.Head().Id, "0", false, "1"), changeCreator.createRaw("6", aclList.Head().Id, "0", false, "3", "4", "5"), } - res, err = objTree.AddRawChanges(context.Background(), rawChanges...) + payload = RawChangesPayload{ + NewHeads: []string{rawChanges[len(rawChanges)-1].Id}, + RawChanges: rawChanges, + } + + res, err = objTree.AddRawChanges(context.Background(), payload) require.NoError(t, err, "adding changes should be without error") // check result diff --git a/common/pkg/acl/tree/objecttreefactory.go b/common/pkg/acl/tree/objecttreefactory.go index ac655814..73706bca 100644 --- a/common/pkg/acl/tree/objecttreefactory.go +++ b/common/pkg/acl/tree/objecttreefactory.go @@ -106,7 +106,7 @@ func buildObjectTree(deps objectTreeDeps) (ObjectTree, error) { newSnapshotsBuf: make([]*Change, 0, 10), } - err := objTree.rebuildFromStorage(nil) + err := objTree.rebuildFromStorage(nil, nil) if err != nil { return nil, err } diff --git a/common/pkg/acl/tree/rawloader.go b/common/pkg/acl/tree/rawloader.go index 58d77427..bbb6509b 100644 --- a/common/pkg/acl/tree/rawloader.go +++ b/common/pkg/acl/tree/rawloader.go @@ -143,6 +143,7 @@ func (r *rawChangeLoader) LoadFromStorage(commonSnapshot string, heads, breakpoi } if !exists { entry, err = r.loadEntry(id) + entry.position = -1 if err != nil { continue } @@ -204,7 +205,6 @@ func (r *rawChangeLoader) LoadFromStorage(commonSnapshot string, heads, breakpoi if entry.position != -1 { buffer[entry.position] = nil } - entry.position = len(buffer) + 1 return entry }) diff --git a/common/pkg/acl/tree/treebuilder.go b/common/pkg/acl/tree/treebuilder.go index 1250bfdc..d9e7f531 100644 --- a/common/pkg/acl/tree/treebuilder.go +++ b/common/pkg/acl/tree/treebuilder.go @@ -40,27 +40,49 @@ func (tb *treeBuilder) Reset() { tb.tree = &Tree{} } -func (tb *treeBuilder) Build(newChanges []*Change) (*Tree, error) { - var headsAndNewChanges []string +func (tb *treeBuilder) Build(theirHeads []string, newChanges []*Change) (*Tree, error) { + var proposedHeads []string + tb.cache = make(map[string]*Change) heads, err := tb.treeStorage.Heads() if err != nil { return nil, err } - headsAndNewChanges = append(headsAndNewChanges, heads...) - tb.cache = make(map[string]*Change) - for _, ch := range newChanges { - headsAndNewChanges = append(headsAndNewChanges, ch.Id) - tb.cache[ch.Id] = ch - } - - log.With(zap.Strings("heads", heads)).Debug("building tree") - breakpoint, err := tb.findBreakpoint(headsAndNewChanges) + // TODO: we can actually get this from tree (though not sure, that there would always be + // an invariant where the tree has the closest common snapshot of heads) + // so if optimization is critical we can change this to inject from tree directly + // but then we have to be sure that invariant stays true + oldBreakpoint, err := tb.findBreakpoint(heads, true) if err != nil { + // this should never error out, because otherwise we have broken data return nil, fmt.Errorf("findBreakpoint error: %v", err) } - if err = tb.buildTree(headsAndNewChanges, breakpoint); err != nil { + if len(theirHeads) > 0 { + proposedHeads = append(proposedHeads, theirHeads...) + } + for _, ch := range newChanges { + if len(theirHeads) == 0 { + // in this case we don't know what new heads are, so every change can be head + proposedHeads = append(proposedHeads, ch.Id) + } + tb.cache[ch.Id] = ch + } + + // getting common snapshot for new heads + breakpoint, err := tb.findBreakpoint(proposedHeads, false) + if err != nil { + breakpoint = oldBreakpoint + } else { + breakpoint, err = tb.findCommonForTwoSnapshots(oldBreakpoint, breakpoint) + if err != nil { + breakpoint = oldBreakpoint + } + } + proposedHeads = append(proposedHeads, heads...) + + log.With(zap.Strings("heads", proposedHeads)).Debug("building tree") + if err = tb.buildTree(proposedHeads, breakpoint); err != nil { return nil, fmt.Errorf("buildTree error: %v", err) } @@ -73,13 +95,12 @@ func (tb *treeBuilder) buildTree(heads []string, breakpoint string) (err error) return } tb.tree.AddFast(ch) - changes, err := tb.dfs(heads, breakpoint) - + changes := tb.dfs(heads, breakpoint) tb.tree.AddFast(changes...) return } -func (tb *treeBuilder) dfs(heads []string, breakpoint string) (buf []*Change, err error) { +func (tb *treeBuilder) dfs(heads []string, breakpoint string) []*Change { // initializing buffers tb.idStack = tb.idStack[:0] tb.loadBuffer = tb.loadBuffer[:0] @@ -113,7 +134,7 @@ func (tb *treeBuilder) dfs(heads []string, breakpoint string) (buf []*Change, er tb.idStack = append(tb.idStack, prev) } } - return tb.loadBuffer, nil + return tb.loadBuffer } func (tb *treeBuilder) loadChange(id string) (ch *Change, err error) { @@ -138,18 +159,34 @@ func (tb *treeBuilder) loadChange(id string) (ch *Change, err error) { return ch, nil } -func (tb *treeBuilder) findBreakpoint(heads []string) (breakpoint string, err error) { +func (tb *treeBuilder) findBreakpoint(heads []string, noError bool) (breakpoint string, err error) { var ( ch *Change snapshotIds []string ) for _, head := range heads { if ch, err = tb.loadChange(head); err != nil { - return + if noError { + return + } + + log.With(zap.String("head", head), zap.Error(err)).Debug("couldn't find head") + continue } + shId := ch.SnapshotId if ch.IsSnapshot { shId = ch.Id + } else { + _, err = tb.loadChange(shId) + if err != nil { + if noError { + return + } + + log.With(zap.String("snapshot id", shId), zap.Error(err)).Debug("couldn't find head's snapshot") + continue + } } if slice.FindPos(snapshotIds, shId) == -1 { snapshotIds = append(snapshotIds, shId) @@ -165,6 +202,7 @@ func (tb *treeBuilder) findCommonSnapshot(snapshotIds []string) (snapshotId stri return "", fmt.Errorf("snapshots not found") } + // TODO: use divide and conquer to find the snapshot, then we will have only logN findCommonForTwoSnapshots calls for len(snapshotIds) > 1 { l := len(snapshotIds) shId, e := tb.findCommonForTwoSnapshots(snapshotIds[l-2], snapshotIds[l-1]) diff --git a/common/util/periodicsync/periodicsync.go b/common/util/periodicsync/periodicsync.go index 52db0935..d3d5e3e5 100644 --- a/common/util/periodicsync/periodicsync.go +++ b/common/util/periodicsync/periodicsync.go @@ -14,7 +14,7 @@ type PeriodicSync interface { type SyncerFunc func(ctx context.Context) error -func NewPeriodicSync(periodSeconds int, syncer SyncerFunc, l *zap.Logger) PeriodicSync { +func NewPeriodicSync(periodSeconds int, timeout time.Duration, syncer SyncerFunc, l *zap.Logger) PeriodicSync { ctx, cancel := context.WithCancel(context.Background()) return &periodicSync{ syncer: syncer, @@ -23,6 +23,7 @@ func NewPeriodicSync(periodSeconds int, syncer SyncerFunc, l *zap.Logger) Period syncCancel: cancel, syncLoopDone: make(chan struct{}), periodSeconds: periodSeconds, + timeout: timeout, } } @@ -33,6 +34,7 @@ type periodicSync struct { syncCancel context.CancelFunc syncLoopDone chan struct{} periodSeconds int + timeout time.Duration } func (p *periodicSync) Run() { @@ -43,8 +45,12 @@ func (p *periodicSync) syncLoop(periodSeconds int) { period := time.Duration(periodSeconds) * time.Second defer close(p.syncLoopDone) doSync := func() { - ctx, cancel := context.WithTimeout(p.syncCtx, time.Minute) - defer cancel() + ctx := p.syncCtx + if p.timeout != 0 { + var cancel context.CancelFunc + ctx, cancel = context.WithTimeout(p.syncCtx, p.timeout) + defer cancel() + } if err := p.syncer(ctx); err != nil { p.log.Warn("periodic sync error", zap.Error(err)) } diff --git a/common/util/periodicsync/periodicsync_test.go b/common/util/periodicsync/periodicsync_test.go index c4463e41..c7802323 100644 --- a/common/util/periodicsync/periodicsync_test.go +++ b/common/util/periodicsync/periodicsync_test.go @@ -23,7 +23,7 @@ func TestPeriodicSync_Run(t *testing.T) { times += 1 return nil } - pSync := NewPeriodicSync(secs, diffSyncer, l) + pSync := NewPeriodicSync(secs, 0, diffSyncer, l) pSync.Run() pSync.Close() @@ -38,7 +38,7 @@ func TestPeriodicSync_Run(t *testing.T) { times += 1 return nil } - pSync := NewPeriodicSync(secs, diffSyncer, l) + pSync := NewPeriodicSync(secs, 0, diffSyncer, l) pSync.Run() time.Sleep(time.Second * time.Duration(secs)) diff --git a/consensus/config/config.go b/consensus/config/config.go index e50d92d5..74804930 100644 --- a/consensus/config/config.go +++ b/consensus/config/config.go @@ -27,6 +27,7 @@ type Config struct { Mongo Mongo `yaml:"mongo"` Metric config2.Metric `yaml:"metric"` Log config2.Log `yaml:"log"` + Stream config2.Stream `yaml:"stream"` } func (c *Config) Init(a *app.App) (err error) { @@ -45,6 +46,10 @@ func (c Config) GetGRPCServer() config2.GrpcServer { return c.GrpcServer } +func (c Config) GetStream() config2.Stream { + return c.Stream +} + func (c Config) GetAccount() config2.Account { return c.Account } diff --git a/etc/client.yml b/etc/client.yml index 9be9ee38..236f0ef5 100644 --- a/etc/client.yml +++ b/etc/client.yml @@ -5,30 +5,30 @@ grpcServer: - 127.0.0.1:4630 tls: false account: - peerId: 12D3KooWFgtCbkf47HhFyQW2cEdAkvaofpokCiaa24Phnz7hpepG - peerKey: 4nWcqWOZxv1iXWYuW35eJlF9nxownm38bZjQ27pmFgVXO26vobKLx70TnNTQzZQdoW/dZtxyE9PO37R74vfPQQ== - signingKey: ULbtmmyFjkJ6Z+54FI1OJWfu0QdIeoCckwcrBZDLGhw2o2cXTFH5KGxQuAruNTbREz9eAVGmhGoBZtKVi6/6ng== - encryptionKey: MIIEowIBAAKCAQEAuGAvw/JQuivjoFIhV9RGkoCjO60jNkQpVPWK52eUtEvKHT2EzufhCRwxhAreajoyzk0PsyJ75FWrrvYs2tkSVHFOSiBkZIsldn5gPg1cnvnJOZ9VKDFp8h85d/4cPQ5tX78043nYTgLje2EmbB83inIr4oiZgxDrtLkozJHleAyWuOLIvlWO1l4Uplf6+uooL/5+WeUCuSGUM0wgXfpn+I2IuRhVDVZiChfp51Q6D6brTdOzNcWq1dw6Vld67u8aCLF1EVZ+xM/rnLLBC7MFvIw44LqHvmvGs/lpE9nMNx5L2KfpbpHSBI0IH3FkLQe2Qz8OMZpIa+aga/DzrBpEdwIDAQABAoIBACudXU898AjKPxN6ujZ7maIoWfTQ9SZuI1TcrNomr4+i6hHWrqb/RUWRbMkuhQSd9czFf/RBMQuHlJBT3bJ7bRGaqAly9iyumdMY/A1RvdpBfm9qGIvkfIpxBngzHVz4H7lpkspI1XlGx6c1CRDEpa/TaDwzUhUmGIvszRDvZlfqQvjPjyYSV5Hdc4ywh5zjuSFlxOD/9gsPRE5v4M4FGrGv8cm859P1u95Wxxo3pWincpzjvWw2LpsUGctyU34MhErxh86vNhP9v+nR4VkdojVKkHQTYnPKUlaKj6F+IUSj8syxuTJb8bs0GBuvcXW9AKp/K0xq/GBC8Cu/XN7Ln7kCgYEAwZoqLnU9OuwkcN5AHYW7XsxmVCEnxOsncrUbIzEKPvy4wELdOCVVrX66zmIjb+1+mhaz+mGMGEpkVMBld3wdDfmGgo0CAPlF4efH1ppMzUm2aZ+HYQR8KMH1XOT9qjbGEnLeWcANQT0vZPpe77PQLNwLJ1zv6EtXMMrEH0s4ijUCgYEA88zCNsBtB07ayFr9r+RCfHx/X9wFkT59t2K+axIfZE02f62WWqJCZYMlZu9XAbYEQ94H43/NAL9wfA8dgnF7mKSL8stJKt0g2iPa3MluF4Gq5Y2XYEVf/EDEhP2jh8p1l+xs18rVzsQQ6b3CEU9ytmBJWvkWnwVXf+ZnsCFECXsCgYBM3YyJzXp1/nOpbFRAZGw0AytNk6xafpK29DjGDB5pS6V+kA2M0SXnMD2y2zv+oGh3fTQP4NLigga7r3eZrOlMNxm0k4+MG2wneQLarYB4sR9/aBsz5bf15qwoKbKc9gpGIN0u/RVGJai/irhOqzGn3eV/x2Jo9CC1+otLcW4NUQKBgQCOOHlnZTN1GuwICwSIkhiy9BF+AyUASLsfuquoXEcRxPUw4DugnZ0sCKhN9vsDlYHBcYmajhgyAnuE83BcgwT906eMOEhzh9G9T0NCnwLpFYxzIvkWgQHwbnv1tNyrv1CAEryf2cSGPNw87qSCYp1hhKPmPP6UP5J+mxMLrSw6dwKBgHHFweDS2tw4TNxJQjhfQOp5t9VQbQffFZAqpXGFTc4vf7XePlxIGoIpOg4ShHCKKHSy0PtsLe7QjLrdbMkyYh8oGqgNe5CYTzFFDeK6Im1DoiqNWT+YUWF/gzVRUSpo0QW+4J1hfChG2URp9KbnditXKsJ5Vh+QayHPoZwN7Kgl + peerId: 12D3KooWQajuCbCYJdh6fhfTQpwJpJ61mV1ZV4F4XuJnFHeVfeSF + peerKey: Gz1ARVeHzdusDtBL0DawuQKoKdKhL827WiCPekOndSnbYb65zdtgoxGP8Y+enTfKksPftODaiqzZr16Dfq+JvA== + signingKey: wKPnynjYCBVqDEiREnMRHz6id1NFNIfjV4XKmB27ave9BSyS8saW71BEb/0XT0IZDJep6oSKr9ua5kAxcr7tQA== + encryptionKey: MIIEpAIBAAKCAQEA1DJ/TtBpSEVZVfPWJdp7tPaGY9d+4zrD91LM/4N4DKKhhSFfcWlHgZeQiEtP6bKCdIp2nPMURiS8hd1JzYmNJNk/hUYlzCUJOZWyduVeaow9rlTT6I9a8BVUBQHtVD+PUu5pkfjLFgAojcSzg/mIPzJ0T76AlsFXBdXRfS2wnVKfF0/V+jHiLB1V2JBLjyuRf2V5HFglEmWfrCoG02Q9OENZJHy02NXGCs7FnZdYhHct9u00dXk6Xp0w+oBD74+h4gsyFAHnRodRnhC0WMSv2LIPIQUh7x5LfvKx85n6LMFk/aYgTNFKQfu15VTzjfbVbeAm8jsHgV/FifRvETHm6QIDAQABAoIBAF6RLqlaOkFqHpkutRZjm1QXtebTCAqOiv0zGocY+SxwYhlpuRZa+/ImMNR8891Ln9X+S0RBFJz6DEaASz7deVidtTBZBclIDCdsrn9MU1qaq3aA+XugP7/VUX91z2YHeYFVHRlfzmo8odYkfnhnga/gdXOAi+Ajw/umwdjOvvItKqzm4FHHrwmqKDGlMfPgVcbkE/1iDRSwGvuEPOtMuNrTGcPyz0w10BO5zfpxgxJ2Esgmg66VG+H/KPSoLCtStZilErC8gRx9AbbJGUJcLkjd3T6A02cS9IS/hyTEK7qjxNjVaW0DfCrjXfIFiVHeXTB1LSS2JR95kArG437WTw0CgYEA/JsW6qDjl1jF7tYr+E6PjnCk/dgm3nlsC8sTbZd5edPN3dp+D6qlwv4KYKDETpxohMMhOdSl5SYp4dirsnyPDF1BcGdrkq73aE6n4Tx7oQBMeuZLvK9hxWprJqRa9WP49CDiLOc/GLOe3N90s8ViSqU08/tqOtQLU4BmjHMCDzcCgYEA1wxpL7XUUeDa+bGXrtii3oXlZpyoUXft3JjhTazC1lQuwp5M5+0HA/BuTpl8b43+0gcgrUjqB7yeKWZ8Us0gE9ZMBPTGNNGjXjGOtOk1Lpm+PHrCxmADzfJ8V+rrQXvW2KcImJ0bZk87eNUKtDSsWy6+NIQ6W66GUFvv8iblit8CgYEAvBVKCedDrqQFtKC5Wog8MYXEA9IWlt33ygwp6ha39zLyfPa7mDSqebanyWzK3fFtjTSxH5sq7qTs2GF47kv6Qu2I1QXcPfqS8pJmQ7nCH43WZEfnKpW3icOEBuCnbUFD05pMbby86UqMxc6H2Xblicja1bNkVGsgB8t6D6duaB8CgYEAq337OA/x1KXTGoJ0avvZzkjK6uyNEgLozh2gtpfJ/K+/ZnZk8CNGj+6hmM6vvCpphsYmWeomr6rMGknfZQytwwQHNYCZu69eb5RnsH+1aIc0fPiM8TPKdOcmH9p4Z41BhR6XLVVEb29KBw8l7RWASWraRfkYrNpdxCG9FMfOD9MCgYBJ6Z7YNZsJq263s9oJ01npT2NlfXORd3KDHi/A6qC8Jx1dK3+Jew2VV53/PeXJKuPuePSV7nEOwA0wpg3+TuEsWHHOZVO4c+ZVJmonO0x0IzjMHzBB/8VZc+5n+yi/UOSupt/WRcoPOTjJ7tQdhc2m9C7YA248laYikbzkW5DHoA== apiServer: listenAddrs: - 127.0.0.1:8090 tls: false nodes: - - peerId: 12D3KooWPuwdqpDQxWhD2Vh4yskx2T5VMrwdpTZLfACzgsGfQfNy + - peerId: 12D3KooWHtnADt84naf6NeejZ1MxYGZPLk5SPEu2DL4ZV948uWPS address: 127.0.0.1:4430 - signingKey: yOEpD2+cPldXc2urGuU+szunm7fddRa8xew2uVjaxifRcVzNKhSERpOefjrXaky7PcKmSmTsH/5ZFtcrh1uzqg== - encryptionKey: MIIEpAIBAAKCAQEAxnE9Htwto+2fVmonkG9/DxNre33n7kjfrZU73JcHmpKhPlRFirig5T8rs2MaTq1R72/8nGBJuSxsz1PnexI3die39pY1OFYfZCZ59LbT7uH/xHcvkVrK2n50Q41KbbGT9BEzyW+XPkKPDpTq3/igYP+yUQgoWLfMwxCCLKXDe6qUC0fuIxR80fvj3XvorB5dnAiQ01JkH4PtCV1OWT6ZpLGhzcYxsxTHozd6LdMOC7wgGhW26dOSa/vZ1t5avbewFVIz0qfqBncunb7tjO4xa3xVYaA5jBbixDQUYFjVzW7cksrrN4CFNBDBGJ8PLS80MuMg0OG0O+/Qi1mbGb2mUQIDAQABAoIBACODAD0VidVcILeGJ65hRYudHg7raSXrRJv7qMrA/EtdEh3lVsyMXb6on1lq0rphqdf/YmVZldfda1tu2G3dxK8QTIuENeHvB48Uk56HWUXWi77M1WZdqQ+QsZ2lGzymGqQCsBHMNnSd1Jv3alDKXWj+WRrHKvE1cx81RRZYU7M9cpurnF5YNjO7L+7sMxUA9uAQGbe3kDVzrygraicLYQpxSNHytName0A+k3ug0qer4I6PmZhhJykkz6MD3dz/n625HSS+X+TuTm52T2b87tL27xXmSnUK7eYWjZ1vQlP1fWmqnac6u5LApUZaRi0tTjtefSjRW4jr1q20RqOp1kECgYEA7Onh3zM9ejATsjW6WISGKiBPci0D7DUbIuGuJrdQRadlkZzmeQ/VOYAuxIQD4GnQDRhM1FyxsqiAWkJOyCLFiMmsgIEyW9/eRhF8NlCVU+DA/fxy9EagfBbVsgiSBwOex24hPXIVYlaHkLAloNoD4bpw0pQZSDWXr+xvMFNwoGsCgYEA1m3sWA/e8ZuXForaUOoJzBU9nwC79bXv2UNktsVvBlQ1o9pbjoYDcVoAPwuBVUL1UwqDNMzPdhDBKBjZmCyjS6zlYD5ZKjF2m8iTyc4QcaBCdM0iyQpSXTmrfMx+hK1aWwL1p8ssNcednp5ExSAaTyNNGVdbtddiQ6/KMPmhUzMCgYEAwDjLsUNr4BXeBTweo+9yw/9PNn5brm0wRU8C9BrMIJe/izPYs+UqxerBB2Vtl8mCqv1KaQuEika5TYJ7VVsRFvk641DwQScUu5k4RQGBB3tWWz1XL+eWEticLkVR5isDyyAKDEbiHtXCTJz/CtGZUK7rF5BeKv6AwpZ9aKJqwV0CgYEAqXDlQNURu+PR6TtBtoypvz3NmraO0GO7KvipPhAXYm3qkRa8IIxfbhPLfAYQZhpqFvuIoJFzIn2s1I2GbExhoSv3eSzrcn7xlbpSpjYSImeb/AYZhbmFSiuHCi/hjeAaNS7KhZPz1G9vaubvusFaaMyhYPP6AWA4QvpHEJpB06cCgYBqR6/7d2hQiq4MJUrBEzLwG4ijnPeq+UVLQjE598hVIj+8UhRZRRcNWVEJxfcIL1v6Bpo8XISDNVRb30T9bPGVnXvC1jutTUbXKUB1/8iXuyH3IVieobch+bGd4v7ehH/lI7vzB6hjJpFzHopfFUn4wacSQdcFi3tRAwUB/L0S/w== - - peerId: 12D3KooWBgHmDqtXH9SrZfAmwCFsD8LZhTD5dg5wkhdbqFoS8GBN + signingKey: Fu/H792JFWVYQpOZeLBIr1Y5UuHdZzJxkGO7eakZDaZ3/vIDhjGgNab1+1NMdTJ0IUP6Tv3KQutcRwtX26/wmQ== + encryptionKey: MIIEowIBAAKCAQEAs+N32tT2Q4Nv9MlyH0B34TJZYLh1+Y/4hc0vupiS/Ct0Mt+Rh62KkPy6Hz2JRDd7ryYpz/Un+qAFQBhfugKy6a5R0U/OnaK8/WwJjstTPd59c7iGnCeW9mWumexT2wiQVbWcSdcAE5SPYmBkIPnwzgxZgtNzvEnbdUDWIOsR3ifDAt3iUqqlo+cZWIZaXiTjyrMlaWY/BR/SGrklYzxcUzNj+K6DdY4yFN5/5ywKIe81llooULTyM5U+fWEW5uri4ERgT/YcRAoii2UJ5kHzpIZmGKcrJ4kUdyFLE7VxYIQMHHXRkDlpTEYlAAJGl5frcHvFufTWIJaohBXAxg5tyQIDAQABAoIBAD3TI9I19x1lAwliYrKS+aCQKV+whftrm8KArrK21W2NkbYaWG4FGuaRtXYfNBoZ54xe1Wf/nenpLWTF+8B2RP9DRiNmBmDvGX0PsIk/IDDXUs5+0OTCRoQQll2Yd4mD+/c5H6nRFtmj6VOqRT+AJ17pp6nq+o/v4lj+G5ncsJtlAtq1xb20yHQYEl6sbK2UqYuiFtXpKMCK/8V3hDj+ROM8UMkxMj+qj9NFd2sCk4FEZ+S2QmHIjY55s4Rpe1RzZZZEYOuJ99Fism+HYXtf3JlFORaNIdhdWY1UkVAFuKY/ULoHOhf/RdJ8ZArak3CplpEdPTYC4IRBI1eZDDF2GgECgYEAw0jvV7E1kqfGD5Q1WTFsss4xHQntPtWRfyAI1viy16sqMX6wQ4ZixWXsOeMB1o5azqqjYo0BBiGw6ie1GKl0iZ09FxHmMDqFLf8a0JZXAlTvC/wEHgAXCzg7tpHRJD1B6gAiU6u6ALW14DtWe6tikFehrY0mwGb9koedQNgoGnkCgYEA69EcUTejGm5Hm6ANC5u5Vn1aaB4BrTJ36FGTaxjnSUPePBj0Eo2Bt+c25DiD3uGj2Jws5QrRhpu+NYhOTC+/P1/rm82w9Tpc8z/wA7nUk0gGEncgtJ8RFokom4B+Ui83JJiH0V7puZUhCc/TOmfa5N0SH5gM4q4rBoVDZtnTGdECgYEAlnssW9GlK6Z2++hEF7/7N+mldPACTkn6PRCtXyHzhjdSYyNxpgb3M49vsceY0gGOPfTFxBpNsLDjh/wjE6b4s1ZkDdPwIjfmCmSrABLpZ1WVgxGnBoshNrcVZIEGvTsrAKsryHfq88MSLIDtCo0tfXbZkkfTla2HNpOj/KTUelkCgYBl0pMRlp58qSWOUxuO6ZyrddD1qA89Q892ptKqqcQkZIOvG284G5XpXJLdFHIMaQ2gWD8iXvt9zf3hi4uTZgKEUNyhF73TBXJhLjhqw3DAb5b/niSnGQ/91ReNnXvt7Kk4ygvLIdp14ai0XeJtE672p2ZN8g+OSXoWhLBH1sJKIQKBgA7NH/Y4RbVHIMWY7jH/1d4ODZ4Hr1RK2Q99HJCAurfD5tjhpcMApoQQJKJDpv7J5Ipx6ynQJD7CFfx27+vqBEG4ffAUm66lKM5xrKcOevcyWemppurCLuza64GgWDP6jBRnHeqrUyZUqoI/I0FNwjxIJbu08NpRSt8khq59+iyF + - peerId: 12D3KooWG1r2SVzTMGDhkiw9McbZq98H9C1Ggzp7FSfWDGbVSCbZ address: 127.0.0.1:4431 - signingKey: l6LFiKqr4ZHgcPbL+DR7KwMbzImufQPFgpoHOJ/nvfUbpb76DCADHuT1I4gIs+XByglnY1KV8jbMfW64XRW5XQ== - encryptionKey: MIIEowIBAAKCAQEA4ltcn1AH048bMXcKOOW7/E0TZYPxL3OtcHXWHSAZjeeTA/rc45G2eaNgyY7Ji+feLtZERbXNWGFBdNp31NHDYZAYwbZmjEqTEgV4yVx7BQP3VBEzglTJaNLTf+XIJnVAEkoHS6ogjC0oXTM6paHu64EitoOCzF9zqL023swjE3HU0dm2xwsUdGnKeO5nPMso/6e3VMavkKnFmvB965ECCBujtediP4lVdIABNVtoMHCoeI5Sn+m7TKqJSyDOIEMhHT3orYUNZWVeAHE1YTM2cI5tSnDZP80CHZ674Z/bKL7Jaznmq87mVt1h9Use2EkxR07/dJuTGvFOos4jHoiR9QIDAQABAoIBAHAr8EluooI/j61CnYk2p6LPG0aaTQJD4/YwHuwOBTviP2OghKgthGzg/szDerNfMyaoveqBvoIGqCZdQTbwwE7v1qTgXA83wYwTtBitQLVqkr1RTOJQXAMbPv5Jg5czUY3+q4DejQSKOE9/XJfKGJkSRH6Hy2C2CJ3dLnzYUqWGO3t70RLT1/sC6p6w3lXdy3dKZGkoR2wva+HXQxVrP8X5HOResXgNZwgMHt9KF1QHVCcySKYiEAefEKTSdKD2fOd4FxLgp3zWpvH3jrX0zd/DqzTlFD5Ns6Ayp2sIfHVp3sn99DZZM6DauMepQKtoSCnXZ+qKhekAwNVJnsVQkSECgYEA4spY9araeFUSl4uXCUQOpCkSshYOPRYN6sBbHsx8tV2eQtCT+5SuNYmzur3c5bkiraGEab8rZfGdDL6fLxQyaqbOmN31Db5kNh/2X+sRnxkak8lsROUWQZRF9doH73FDv6ZlI3V/JicZlOUCfN5BYT+x74R4/c1YXfyuD1J9gr0CgYEA/4K4SDwZUY4bOVCmKQz0OM+RW4PAAH6LHKenTAZNTeDNFFxc2nqnzRGMEKZTDGy0kbT5mBhBHFgShXcAiKxc5/MGkpt8Jcq6Fr5KGU9aZtYKji6mwMTsUndPNQydh3vOt5pOmcuMM6ovanNTvI8k6Qo53OY1IpO5CfOROu0hm5kCgYBnWsYd92YnDsYxUEldzKlLgPhnNov4pNNk15LvP0vaL7cPRhUaw1B9T6scAKjp/GxkasZ4lsnFZM4o37qV7wNm/WwL2KN0Rv9Od1SFtBBMzFkDXvk7kJeK/XLAr0OMiLbSYZeYCFUQ4yLSa2et1nA/TJLf0CR/rhSGiMAedX6DlQKBgAx1137OT33GrFUzNacy1oYeuTv5RNfBVA9lrabrd8GggN/JUU3mRWCexnHZaptkgbnJVZKxPBuhv+V6VDBWF4HIPD3SD0/YfxK03PA3CnWRYppkdAValRvAbcBsiRIeW4pgoAyn/IJYfk92qFK9uFMVCJVZNKYnBhMSKbbx8X2hAoGBAKwvzyAImbNB+493q1R/lSayxzG76bRJ/EseiTqwIec9c4C+Bd/sVXR+Re+xZb0FI/va1bz5CrduTzLSKBmf/+0lzl0MJvWY2+SXfGYdbl4+TTyqgDDfwqW0Tj8pDimye2BneyTmXko1rF+2Sxen7kMXnJLwpqjwZ6TZJuoqeK8q - - peerId: 12D3KooWASsipDzkridiMBmE7VSqp8yZvGWPY1VqySgMSZk6tsiL + signingKey: CZTN+NFi4g9MA4BKl3OiCKuzXh63ukIvYWo9D5t9qfZcFwIeOW8eP9W8mtnXaY3JAFyb6GliBW0uCaw4wjRcCA== + encryptionKey: MIIEpAIBAAKCAQEAo9Nuypzg9kZ+LP+8jQgSTaoRUu8VFdJdCOEjuroPQK+2NwBD/Z9BqKiN0Z+jmhkI9yA0/Fwdh21ibAKX3Je9uffAKOhXI2sxIAlccDORu1kGDnhcc7N3L644DK+uFZvKnMQWiCwmtTnNHkoCzWcIE44G56wMa2c4W7mrOuRWqG6a5Z9JUuLqafOIlf6Dw2fiVM6xXiTIMQ0OyXByxFNjsS5O/PYcwoIKMV8MY+gUnAmyPLE0bslvz/8W+3E7d/LDO4lhqW+N1kDmboe6sc7DBf5JD4DLnP2VWV8Ae/rfJvxwu9ZqVT8RdYKMsZqvs9sV+6jQC9UcX+K8Q4Wdo0eMHwIDAQABAoIBAACR57zEtvOkYyP878b91DJ4+P503nno9XHmdp1bsFnlQpkGYzYqq6vOik/EYmlS1PknH4gROfkSpFkD2UtnK73N4tlBlawF33HhFnU9eLBSKvc56/hrE2sTDBbfNZfVpurMs9ddb/UJcnE8iK32QczvnY6IxrJI9aU8DCB0UujbGDnya/HbFU9pLLxu2EUoHNxjSHG/jCx+AR7JRknRA65KPZG7mu5jeAaaklYTY/aLGlctgecDKfNKDsZo6rgAMUW6ZXI8ogNGqfKHUFazCVe0l1tp4hxvgmyjcw79iKvFr4mlpHtgjYTFCeoMJKvOXUImZUJL0vCA6WKvUdIfzAECgYEA0lCTXYwOHqOwYMb1qi8lIIApcI//B/Nzn++MDQ4ZO4SzVJTTv4rSdXAuoihsO6E7LYZK+wdVNjiCbeMukfTqEfaxWXIsIDaHSR3440NsYSwdBz04UhRgpxFE2FwPK7J5dQ57FBaCAgksnO3XjcByBMYgMWVbA+ezIWfVdN96YoECgYEAx2mm/W4ZGdDyJgDonzEGGxfaNqo6DIv+67fDwI6WyqOWFWJTBaVFkm1uPJfcXYuTI9YCNFRKuRU7dyqSPLErMVusC/8Iww8++kqmkc1m04tbkqh4KpREYuMw8/tTYSWDwgpY8ksM5YRpYRJLTuuC0cEmefGco1RsXG8bYYeZXp8CgYBq5fexYcG/gxXgauBtSx9E4L+vbhGD2hNYJKr768GZhf6crDTgs8/7TzT0yTUSLgZlQlAUPgrqz1hEQGfoWiMrVEeanjSdfvnOiUR7R0bsMT7j8hMRbTgfUuC6VDiFzmZ7wAuBD1uvazhY329jpoCNuqKcWNclKfzbqupNSFXtgQKBgQCTlR7Qm0YadChydeOzxX2GWa3XHT7fAFFHNPa8MQtqp40xAFb/a6TEzRZz49RkqyLXt9Bj2CqBNjSPakNWhay41+bJ7hMXAdaTOOJ0L/c1AwNf1C0zHg5KvWgCefPohvIvjqbrkx3VU50GCZsQqn5kLLYENAvAWX/lHRm/obKhcwKBgQC/iAOC8ZdZC5w4F0Mf7roZWa9P/42JWlCMzm/I/5mEIn4mYY6+1C5V+fXoET6845oAh+P8CkH4waJtqqN6BKQhj7SKqoCHgGBCQy+HrSCBtzk7NuXdpz6sk14zfcVpjR3y3l9TuXc4cVQMSLAqg8yUQf+qnEQTit4jyfikV/5XEw== + - peerId: 12D3KooWDXDcBYxtZ8KNRoJebNgNAv9nFbQatQMoWm1BLwmQh6u7 address: 127.0.0.1:4432 - signingKey: /6+uYFwFf9nU6fvXQVtpHhjd8+v4dXc7esZzqkhjyfMJWlMiZOtQeb913FXofD5f20WksU0l6i22B09sFFYwDQ== - encryptionKey: MIIEogIBAAKCAQEAwCy84lzkxtzgn4ixGm0LSUTujOBpOh9m7XDoDPZnMTmExdOe9a5v/LXzdlCOCuBvK5u1T3ALBJMA3Zgvjv/jPRQUdiHprP3sbdfc6IgZPBFdLKFTc9yAA7GMbI4y7LhGMLGOMOqQXs+DOeImfmxEs3ykLXHKNas5ORnZPVnB6E9Qod8KH7UyMmBjQkOZYOOw10X4JZiU6xJp/E+VVWcmeXgNBbj5xOWMSzM+hhoA4wNOzBxACucaKDmqD6qugzebOqyUVSzFnEbquro+MYTWYdUDjZTXdvxgUUo80MGQ164gZhkFUKrmSpUvu3YErFySEGqAdFNwOZ6y/4X3s0BHvQIDAQABAoIBAAZiNhAK5+qXMbr67m8jSimv6YCyf6xXmLKwenTbxofDEl8D7ZbZqYyqeqDmgiFoXSkErhwqa6NGQtQZlxLX+zNvNFLMQ5fkg3MOpZ7vzm7JYN/3p+8EVxhIUJLWkmh8opBBhaioUg1kNUa59W9jp1CTBl0gF4h63JbB/g5kqeVOllUw7J1igAoaX36nOJGOwIynCWdizhDhgyjR4OcYfOLwcPDJueKTc5vM10g3LuMSK/sJmaD3TkJFPtDHw+RMW6wqyjsnkrg2D2oohXEyGWYYIXo2so4HCez0AB1I1JAxtVnRPvSIp7xLMm7+AkDoq12QYDHfxZtDTpfmvJg+Sn0CgYEAxCd+oribtdQW+JUctjsDbSQX5CeRISH5Ith3jveBx2jKIqQVnoVPz6URHOvnlIsqYYLANB8B3JHMWfR2UmkK11x0OcZecB06+oBoCZukvSXF+GqVHzLAQUxaoEBDCCPneskj5w+riMWBiiGDp32rUnkqv0nh7dnH+GfORcJ44L8CgYEA+s5s5EALj1jyU9w4+HVUyVsIrUitFnQg6qw/Td3Kj+8CXImKlS+rlmbQv0m1aOcvtFjQRIjjzZJAf/ausfAME+MayoNODgZsDk5RyDKuSWzMLvZLAa1LD52Uli5Pg8KtpzKVTn4xE1MbjsQcUNhFRAgrNEKNyuzXzdp4uXgGOoMCgYASXwiTQOsEepq0KXMI9jn57Nl3+uSyz7W/t7pq329+N6hG2ktUD3RMJE+X/9gup2IOw+owd377I4SaIDU8vq3PQc944cVShspRT9lunO8u7+y8uW7B/0TWWMpcG+irSIGTlGcSavtL0gOx5jWoaDK1hLemNss8NZtu/nnpOq+LjQKBgDisVozJMBOHPNLYS4NROAR77p0BdCNDwIBmxbM5r+EQWA9DAS6u4+4Lc5YV+MkonG37N6yU5iz4pFyGCHmqzX/c7JvgSc3/g4FED1TWpu1uiUD/ZHmPiAuSRxYchtk2L3k9g+GFwF8mg26iP+fAxv4VfnXDqDi3hhg9CtSWG4ozAoGAOWZXlFKqzGAfcucIe54FVQnweXG9sEuIPAvWvVRs4406ggNmL5eHccXpPHWTgetsr2TYMqPTDVMRmhBzSkyrYgk+b2tme79HPzTWs2Yg/pzjOfTgw7MBX/KlvOW5/J+dvrF3Gx8AHHZ9QQdYqi/MS1NKb2K3IbD0/m5gL5Pwi6A= + signingKey: c3D+0+BCl1xU35KBY+U3GPcU9aXdoLUiD4DJ2jF+IqI3CjGLhet3MBOkPXdIuPq/UpEqlp1k6FjNaU6DEU6Csg== + encryptionKey: MIIEpAIBAAKCAQEAuB7HsXuYmoif6/U4JnjC6L0QMu9qW1aPAxDrxWIedTzQhFZp3F3gYW/Zgdd2hvd0c2xyfhwf9C0X/UzfxWr54dDXzWNLN8BdVTik48cdYlgOmbgejiIjTaqSAlv4RtlqvooxCN0MwR2/RVAG/N5GqcAM7E4kJWPtvQYNl6wWCc92rKdutvmcj73wKzz9Hd/qdF612OVS3zRsjh3tJmYt55oovAUh1TAz/mSTTXjFHy35zLRBP+oQQsAOt2p0BOMSyOKZufGC8l3aZD//dp4/U/MaqCjeNuWxCfAZlSd+vt7T0aqDGdyRtrrGUcu4PCwXpOdbzw+uSZxnKawolYoEHwIDAQABAoIBAQCsxeVpvKtUx8QZrUCFiWiM8W0T/un0z+LfY696xzoBlZGtvVEVQtpdVJHsb31/5RFXhnphsI6jmPUb8llBbcMSjeETkItyw4ZRhBfmzl/aevsocEfr5EjwhpEAucDe6wJpzk95G8TuKrXjmtcTzpjMjbUSwbjVhVH/wIBcxVTg2j6z4AOADDRI5UsvZ0NV//If+nNzMjcuIji95PNk7lAuwsqkX3FycxvqXKUMGxRE2bgGMxaBRAP0kqL2vdxyS1M7wp/x04ZAtSnPXHe4qqmDOt69ec3XqbmZHOsZHzkCFePKcPB472/G0bPJeiq/idevEqS89RwvbphDtq3KGrRBAoGBAOrHqlPh36WZBOi6SueUmcrg579KDMUekgeea5payiySbRWztCL2yCYbSgFqSbyCLRppyXK51xvo8iUejR231or6u/nd7T0CON0Nf/8Qtbb13vtTGpIBiWYGqeDrWucUUlyS+K3sDfNk1AJqjUdaIMVu4yTpgzEvrdYCcT312RBPAoGBAMjC83/0EKnsbypFprxKS3Fbg963HhyKjfffQ2w4yncM6kxXF3ehVjg1LInok/6/dmy2LxkAf3r0YYZrGJWmG4Sv4UqHn6JxAjQgarPbdmGhJ8VIUMvMbZRsX3i8Z8D2o8k1M1kr6MYsQ53iX6q/Cp3gnucMeJPk6Xs9Q4TO7YsxAoGAWrXEOF6X01p4zBZWJH2Eoh8dSwooPuzdzPXHaz7SyD/Wx8DDw5KHqDl48W0Iij3dgUwIGjx1QQJStEbGjQnfaZkQkazOIXk/USELKBhjrQn4GjB0np7bYEEI1673UzrFy6C5VjFS/owhYcGbTksjSETcnAFgv9tFFd+hsyfOsv8CgYALk4o875LiaXrDgj6qDtKo17ET75Ux6h9jkqEtpVyvXrRH8KGuyUPSe+Z0kU+vWdT3Uc4HcArpyRuyh4xkXK6riQTBqm5fDIsm/FOKyXXbDVLgwlm+Vqxe6Zzbtml5K/+nw4SReMG0Y6sGeJ4xl1CCaAhhpEtzo7h+3bp99vylkQKBgQDDdR6N4wb3DHTzrW0EFb8XhXZN7CIE3EWhToNDsCkguUB7lwqD4p2c4yLscS0YAqxk7I3NW0nDaUV/340RrVtPJDqB4NZJ+MvhfvV3TW2FkZmru/iW+DMUsfZGAOPdQz9jLGAzUXrXFw/qGBtLIUL6UWqWLOrBO9QHb21nnB1Ssg== space: gcTTL: 60 - syncPeriod: 11 + syncPeriod: 20 storage: path: db metric: @@ -37,3 +37,6 @@ log: production: false defaultLevel: "" namedLevels: {} +stream: + timeoutMilliseconds: 1000 + maxMsgSizeMb: 256 diff --git a/etc/config.yml b/etc/config.yml index b74fd7b2..447d37ec 100644 --- a/etc/config.yml +++ b/etc/config.yml @@ -5,30 +5,30 @@ grpcServer: - 127.0.0.1:4430 tls: false account: - peerId: 12D3KooWPuwdqpDQxWhD2Vh4yskx2T5VMrwdpTZLfACzgsGfQfNy - peerKey: yOEpD2+cPldXc2urGuU+szunm7fddRa8xew2uVjaxifRcVzNKhSERpOefjrXaky7PcKmSmTsH/5ZFtcrh1uzqg== - signingKey: yOEpD2+cPldXc2urGuU+szunm7fddRa8xew2uVjaxifRcVzNKhSERpOefjrXaky7PcKmSmTsH/5ZFtcrh1uzqg== - encryptionKey: MIIEpAIBAAKCAQEAxnE9Htwto+2fVmonkG9/DxNre33n7kjfrZU73JcHmpKhPlRFirig5T8rs2MaTq1R72/8nGBJuSxsz1PnexI3die39pY1OFYfZCZ59LbT7uH/xHcvkVrK2n50Q41KbbGT9BEzyW+XPkKPDpTq3/igYP+yUQgoWLfMwxCCLKXDe6qUC0fuIxR80fvj3XvorB5dnAiQ01JkH4PtCV1OWT6ZpLGhzcYxsxTHozd6LdMOC7wgGhW26dOSa/vZ1t5avbewFVIz0qfqBncunb7tjO4xa3xVYaA5jBbixDQUYFjVzW7cksrrN4CFNBDBGJ8PLS80MuMg0OG0O+/Qi1mbGb2mUQIDAQABAoIBACODAD0VidVcILeGJ65hRYudHg7raSXrRJv7qMrA/EtdEh3lVsyMXb6on1lq0rphqdf/YmVZldfda1tu2G3dxK8QTIuENeHvB48Uk56HWUXWi77M1WZdqQ+QsZ2lGzymGqQCsBHMNnSd1Jv3alDKXWj+WRrHKvE1cx81RRZYU7M9cpurnF5YNjO7L+7sMxUA9uAQGbe3kDVzrygraicLYQpxSNHytName0A+k3ug0qer4I6PmZhhJykkz6MD3dz/n625HSS+X+TuTm52T2b87tL27xXmSnUK7eYWjZ1vQlP1fWmqnac6u5LApUZaRi0tTjtefSjRW4jr1q20RqOp1kECgYEA7Onh3zM9ejATsjW6WISGKiBPci0D7DUbIuGuJrdQRadlkZzmeQ/VOYAuxIQD4GnQDRhM1FyxsqiAWkJOyCLFiMmsgIEyW9/eRhF8NlCVU+DA/fxy9EagfBbVsgiSBwOex24hPXIVYlaHkLAloNoD4bpw0pQZSDWXr+xvMFNwoGsCgYEA1m3sWA/e8ZuXForaUOoJzBU9nwC79bXv2UNktsVvBlQ1o9pbjoYDcVoAPwuBVUL1UwqDNMzPdhDBKBjZmCyjS6zlYD5ZKjF2m8iTyc4QcaBCdM0iyQpSXTmrfMx+hK1aWwL1p8ssNcednp5ExSAaTyNNGVdbtddiQ6/KMPmhUzMCgYEAwDjLsUNr4BXeBTweo+9yw/9PNn5brm0wRU8C9BrMIJe/izPYs+UqxerBB2Vtl8mCqv1KaQuEika5TYJ7VVsRFvk641DwQScUu5k4RQGBB3tWWz1XL+eWEticLkVR5isDyyAKDEbiHtXCTJz/CtGZUK7rF5BeKv6AwpZ9aKJqwV0CgYEAqXDlQNURu+PR6TtBtoypvz3NmraO0GO7KvipPhAXYm3qkRa8IIxfbhPLfAYQZhpqFvuIoJFzIn2s1I2GbExhoSv3eSzrcn7xlbpSpjYSImeb/AYZhbmFSiuHCi/hjeAaNS7KhZPz1G9vaubvusFaaMyhYPP6AWA4QvpHEJpB06cCgYBqR6/7d2hQiq4MJUrBEzLwG4ijnPeq+UVLQjE598hVIj+8UhRZRRcNWVEJxfcIL1v6Bpo8XISDNVRb30T9bPGVnXvC1jutTUbXKUB1/8iXuyH3IVieobch+bGd4v7ehH/lI7vzB6hjJpFzHopfFUn4wacSQdcFi3tRAwUB/L0S/w== + peerId: 12D3KooWHtnADt84naf6NeejZ1MxYGZPLk5SPEu2DL4ZV948uWPS + peerKey: Fu/H792JFWVYQpOZeLBIr1Y5UuHdZzJxkGO7eakZDaZ3/vIDhjGgNab1+1NMdTJ0IUP6Tv3KQutcRwtX26/wmQ== + signingKey: Fu/H792JFWVYQpOZeLBIr1Y5UuHdZzJxkGO7eakZDaZ3/vIDhjGgNab1+1NMdTJ0IUP6Tv3KQutcRwtX26/wmQ== + encryptionKey: MIIEowIBAAKCAQEAs+N32tT2Q4Nv9MlyH0B34TJZYLh1+Y/4hc0vupiS/Ct0Mt+Rh62KkPy6Hz2JRDd7ryYpz/Un+qAFQBhfugKy6a5R0U/OnaK8/WwJjstTPd59c7iGnCeW9mWumexT2wiQVbWcSdcAE5SPYmBkIPnwzgxZgtNzvEnbdUDWIOsR3ifDAt3iUqqlo+cZWIZaXiTjyrMlaWY/BR/SGrklYzxcUzNj+K6DdY4yFN5/5ywKIe81llooULTyM5U+fWEW5uri4ERgT/YcRAoii2UJ5kHzpIZmGKcrJ4kUdyFLE7VxYIQMHHXRkDlpTEYlAAJGl5frcHvFufTWIJaohBXAxg5tyQIDAQABAoIBAD3TI9I19x1lAwliYrKS+aCQKV+whftrm8KArrK21W2NkbYaWG4FGuaRtXYfNBoZ54xe1Wf/nenpLWTF+8B2RP9DRiNmBmDvGX0PsIk/IDDXUs5+0OTCRoQQll2Yd4mD+/c5H6nRFtmj6VOqRT+AJ17pp6nq+o/v4lj+G5ncsJtlAtq1xb20yHQYEl6sbK2UqYuiFtXpKMCK/8V3hDj+ROM8UMkxMj+qj9NFd2sCk4FEZ+S2QmHIjY55s4Rpe1RzZZZEYOuJ99Fism+HYXtf3JlFORaNIdhdWY1UkVAFuKY/ULoHOhf/RdJ8ZArak3CplpEdPTYC4IRBI1eZDDF2GgECgYEAw0jvV7E1kqfGD5Q1WTFsss4xHQntPtWRfyAI1viy16sqMX6wQ4ZixWXsOeMB1o5azqqjYo0BBiGw6ie1GKl0iZ09FxHmMDqFLf8a0JZXAlTvC/wEHgAXCzg7tpHRJD1B6gAiU6u6ALW14DtWe6tikFehrY0mwGb9koedQNgoGnkCgYEA69EcUTejGm5Hm6ANC5u5Vn1aaB4BrTJ36FGTaxjnSUPePBj0Eo2Bt+c25DiD3uGj2Jws5QrRhpu+NYhOTC+/P1/rm82w9Tpc8z/wA7nUk0gGEncgtJ8RFokom4B+Ui83JJiH0V7puZUhCc/TOmfa5N0SH5gM4q4rBoVDZtnTGdECgYEAlnssW9GlK6Z2++hEF7/7N+mldPACTkn6PRCtXyHzhjdSYyNxpgb3M49vsceY0gGOPfTFxBpNsLDjh/wjE6b4s1ZkDdPwIjfmCmSrABLpZ1WVgxGnBoshNrcVZIEGvTsrAKsryHfq88MSLIDtCo0tfXbZkkfTla2HNpOj/KTUelkCgYBl0pMRlp58qSWOUxuO6ZyrddD1qA89Q892ptKqqcQkZIOvG284G5XpXJLdFHIMaQ2gWD8iXvt9zf3hi4uTZgKEUNyhF73TBXJhLjhqw3DAb5b/niSnGQ/91ReNnXvt7Kk4ygvLIdp14ai0XeJtE672p2ZN8g+OSXoWhLBH1sJKIQKBgA7NH/Y4RbVHIMWY7jH/1d4ODZ4Hr1RK2Q99HJCAurfD5tjhpcMApoQQJKJDpv7J5Ipx6ynQJD7CFfx27+vqBEG4ffAUm66lKM5xrKcOevcyWemppurCLuza64GgWDP6jBRnHeqrUyZUqoI/I0FNwjxIJbu08NpRSt8khq59+iyF apiServer: listenAddrs: - 127.0.0.1:8080 tls: false nodes: - - peerId: 12D3KooWPuwdqpDQxWhD2Vh4yskx2T5VMrwdpTZLfACzgsGfQfNy + - peerId: 12D3KooWHtnADt84naf6NeejZ1MxYGZPLk5SPEu2DL4ZV948uWPS address: 127.0.0.1:4430 - signingKey: yOEpD2+cPldXc2urGuU+szunm7fddRa8xew2uVjaxifRcVzNKhSERpOefjrXaky7PcKmSmTsH/5ZFtcrh1uzqg== - encryptionKey: MIIEpAIBAAKCAQEAxnE9Htwto+2fVmonkG9/DxNre33n7kjfrZU73JcHmpKhPlRFirig5T8rs2MaTq1R72/8nGBJuSxsz1PnexI3die39pY1OFYfZCZ59LbT7uH/xHcvkVrK2n50Q41KbbGT9BEzyW+XPkKPDpTq3/igYP+yUQgoWLfMwxCCLKXDe6qUC0fuIxR80fvj3XvorB5dnAiQ01JkH4PtCV1OWT6ZpLGhzcYxsxTHozd6LdMOC7wgGhW26dOSa/vZ1t5avbewFVIz0qfqBncunb7tjO4xa3xVYaA5jBbixDQUYFjVzW7cksrrN4CFNBDBGJ8PLS80MuMg0OG0O+/Qi1mbGb2mUQIDAQABAoIBACODAD0VidVcILeGJ65hRYudHg7raSXrRJv7qMrA/EtdEh3lVsyMXb6on1lq0rphqdf/YmVZldfda1tu2G3dxK8QTIuENeHvB48Uk56HWUXWi77M1WZdqQ+QsZ2lGzymGqQCsBHMNnSd1Jv3alDKXWj+WRrHKvE1cx81RRZYU7M9cpurnF5YNjO7L+7sMxUA9uAQGbe3kDVzrygraicLYQpxSNHytName0A+k3ug0qer4I6PmZhhJykkz6MD3dz/n625HSS+X+TuTm52T2b87tL27xXmSnUK7eYWjZ1vQlP1fWmqnac6u5LApUZaRi0tTjtefSjRW4jr1q20RqOp1kECgYEA7Onh3zM9ejATsjW6WISGKiBPci0D7DUbIuGuJrdQRadlkZzmeQ/VOYAuxIQD4GnQDRhM1FyxsqiAWkJOyCLFiMmsgIEyW9/eRhF8NlCVU+DA/fxy9EagfBbVsgiSBwOex24hPXIVYlaHkLAloNoD4bpw0pQZSDWXr+xvMFNwoGsCgYEA1m3sWA/e8ZuXForaUOoJzBU9nwC79bXv2UNktsVvBlQ1o9pbjoYDcVoAPwuBVUL1UwqDNMzPdhDBKBjZmCyjS6zlYD5ZKjF2m8iTyc4QcaBCdM0iyQpSXTmrfMx+hK1aWwL1p8ssNcednp5ExSAaTyNNGVdbtddiQ6/KMPmhUzMCgYEAwDjLsUNr4BXeBTweo+9yw/9PNn5brm0wRU8C9BrMIJe/izPYs+UqxerBB2Vtl8mCqv1KaQuEika5TYJ7VVsRFvk641DwQScUu5k4RQGBB3tWWz1XL+eWEticLkVR5isDyyAKDEbiHtXCTJz/CtGZUK7rF5BeKv6AwpZ9aKJqwV0CgYEAqXDlQNURu+PR6TtBtoypvz3NmraO0GO7KvipPhAXYm3qkRa8IIxfbhPLfAYQZhpqFvuIoJFzIn2s1I2GbExhoSv3eSzrcn7xlbpSpjYSImeb/AYZhbmFSiuHCi/hjeAaNS7KhZPz1G9vaubvusFaaMyhYPP6AWA4QvpHEJpB06cCgYBqR6/7d2hQiq4MJUrBEzLwG4ijnPeq+UVLQjE598hVIj+8UhRZRRcNWVEJxfcIL1v6Bpo8XISDNVRb30T9bPGVnXvC1jutTUbXKUB1/8iXuyH3IVieobch+bGd4v7ehH/lI7vzB6hjJpFzHopfFUn4wacSQdcFi3tRAwUB/L0S/w== - - peerId: 12D3KooWBgHmDqtXH9SrZfAmwCFsD8LZhTD5dg5wkhdbqFoS8GBN + signingKey: Fu/H792JFWVYQpOZeLBIr1Y5UuHdZzJxkGO7eakZDaZ3/vIDhjGgNab1+1NMdTJ0IUP6Tv3KQutcRwtX26/wmQ== + encryptionKey: MIIEowIBAAKCAQEAs+N32tT2Q4Nv9MlyH0B34TJZYLh1+Y/4hc0vupiS/Ct0Mt+Rh62KkPy6Hz2JRDd7ryYpz/Un+qAFQBhfugKy6a5R0U/OnaK8/WwJjstTPd59c7iGnCeW9mWumexT2wiQVbWcSdcAE5SPYmBkIPnwzgxZgtNzvEnbdUDWIOsR3ifDAt3iUqqlo+cZWIZaXiTjyrMlaWY/BR/SGrklYzxcUzNj+K6DdY4yFN5/5ywKIe81llooULTyM5U+fWEW5uri4ERgT/YcRAoii2UJ5kHzpIZmGKcrJ4kUdyFLE7VxYIQMHHXRkDlpTEYlAAJGl5frcHvFufTWIJaohBXAxg5tyQIDAQABAoIBAD3TI9I19x1lAwliYrKS+aCQKV+whftrm8KArrK21W2NkbYaWG4FGuaRtXYfNBoZ54xe1Wf/nenpLWTF+8B2RP9DRiNmBmDvGX0PsIk/IDDXUs5+0OTCRoQQll2Yd4mD+/c5H6nRFtmj6VOqRT+AJ17pp6nq+o/v4lj+G5ncsJtlAtq1xb20yHQYEl6sbK2UqYuiFtXpKMCK/8V3hDj+ROM8UMkxMj+qj9NFd2sCk4FEZ+S2QmHIjY55s4Rpe1RzZZZEYOuJ99Fism+HYXtf3JlFORaNIdhdWY1UkVAFuKY/ULoHOhf/RdJ8ZArak3CplpEdPTYC4IRBI1eZDDF2GgECgYEAw0jvV7E1kqfGD5Q1WTFsss4xHQntPtWRfyAI1viy16sqMX6wQ4ZixWXsOeMB1o5azqqjYo0BBiGw6ie1GKl0iZ09FxHmMDqFLf8a0JZXAlTvC/wEHgAXCzg7tpHRJD1B6gAiU6u6ALW14DtWe6tikFehrY0mwGb9koedQNgoGnkCgYEA69EcUTejGm5Hm6ANC5u5Vn1aaB4BrTJ36FGTaxjnSUPePBj0Eo2Bt+c25DiD3uGj2Jws5QrRhpu+NYhOTC+/P1/rm82w9Tpc8z/wA7nUk0gGEncgtJ8RFokom4B+Ui83JJiH0V7puZUhCc/TOmfa5N0SH5gM4q4rBoVDZtnTGdECgYEAlnssW9GlK6Z2++hEF7/7N+mldPACTkn6PRCtXyHzhjdSYyNxpgb3M49vsceY0gGOPfTFxBpNsLDjh/wjE6b4s1ZkDdPwIjfmCmSrABLpZ1WVgxGnBoshNrcVZIEGvTsrAKsryHfq88MSLIDtCo0tfXbZkkfTla2HNpOj/KTUelkCgYBl0pMRlp58qSWOUxuO6ZyrddD1qA89Q892ptKqqcQkZIOvG284G5XpXJLdFHIMaQ2gWD8iXvt9zf3hi4uTZgKEUNyhF73TBXJhLjhqw3DAb5b/niSnGQ/91ReNnXvt7Kk4ygvLIdp14ai0XeJtE672p2ZN8g+OSXoWhLBH1sJKIQKBgA7NH/Y4RbVHIMWY7jH/1d4ODZ4Hr1RK2Q99HJCAurfD5tjhpcMApoQQJKJDpv7J5Ipx6ynQJD7CFfx27+vqBEG4ffAUm66lKM5xrKcOevcyWemppurCLuza64GgWDP6jBRnHeqrUyZUqoI/I0FNwjxIJbu08NpRSt8khq59+iyF + - peerId: 12D3KooWG1r2SVzTMGDhkiw9McbZq98H9C1Ggzp7FSfWDGbVSCbZ address: 127.0.0.1:4431 - signingKey: l6LFiKqr4ZHgcPbL+DR7KwMbzImufQPFgpoHOJ/nvfUbpb76DCADHuT1I4gIs+XByglnY1KV8jbMfW64XRW5XQ== - encryptionKey: MIIEowIBAAKCAQEA4ltcn1AH048bMXcKOOW7/E0TZYPxL3OtcHXWHSAZjeeTA/rc45G2eaNgyY7Ji+feLtZERbXNWGFBdNp31NHDYZAYwbZmjEqTEgV4yVx7BQP3VBEzglTJaNLTf+XIJnVAEkoHS6ogjC0oXTM6paHu64EitoOCzF9zqL023swjE3HU0dm2xwsUdGnKeO5nPMso/6e3VMavkKnFmvB965ECCBujtediP4lVdIABNVtoMHCoeI5Sn+m7TKqJSyDOIEMhHT3orYUNZWVeAHE1YTM2cI5tSnDZP80CHZ674Z/bKL7Jaznmq87mVt1h9Use2EkxR07/dJuTGvFOos4jHoiR9QIDAQABAoIBAHAr8EluooI/j61CnYk2p6LPG0aaTQJD4/YwHuwOBTviP2OghKgthGzg/szDerNfMyaoveqBvoIGqCZdQTbwwE7v1qTgXA83wYwTtBitQLVqkr1RTOJQXAMbPv5Jg5czUY3+q4DejQSKOE9/XJfKGJkSRH6Hy2C2CJ3dLnzYUqWGO3t70RLT1/sC6p6w3lXdy3dKZGkoR2wva+HXQxVrP8X5HOResXgNZwgMHt9KF1QHVCcySKYiEAefEKTSdKD2fOd4FxLgp3zWpvH3jrX0zd/DqzTlFD5Ns6Ayp2sIfHVp3sn99DZZM6DauMepQKtoSCnXZ+qKhekAwNVJnsVQkSECgYEA4spY9araeFUSl4uXCUQOpCkSshYOPRYN6sBbHsx8tV2eQtCT+5SuNYmzur3c5bkiraGEab8rZfGdDL6fLxQyaqbOmN31Db5kNh/2X+sRnxkak8lsROUWQZRF9doH73FDv6ZlI3V/JicZlOUCfN5BYT+x74R4/c1YXfyuD1J9gr0CgYEA/4K4SDwZUY4bOVCmKQz0OM+RW4PAAH6LHKenTAZNTeDNFFxc2nqnzRGMEKZTDGy0kbT5mBhBHFgShXcAiKxc5/MGkpt8Jcq6Fr5KGU9aZtYKji6mwMTsUndPNQydh3vOt5pOmcuMM6ovanNTvI8k6Qo53OY1IpO5CfOROu0hm5kCgYBnWsYd92YnDsYxUEldzKlLgPhnNov4pNNk15LvP0vaL7cPRhUaw1B9T6scAKjp/GxkasZ4lsnFZM4o37qV7wNm/WwL2KN0Rv9Od1SFtBBMzFkDXvk7kJeK/XLAr0OMiLbSYZeYCFUQ4yLSa2et1nA/TJLf0CR/rhSGiMAedX6DlQKBgAx1137OT33GrFUzNacy1oYeuTv5RNfBVA9lrabrd8GggN/JUU3mRWCexnHZaptkgbnJVZKxPBuhv+V6VDBWF4HIPD3SD0/YfxK03PA3CnWRYppkdAValRvAbcBsiRIeW4pgoAyn/IJYfk92qFK9uFMVCJVZNKYnBhMSKbbx8X2hAoGBAKwvzyAImbNB+493q1R/lSayxzG76bRJ/EseiTqwIec9c4C+Bd/sVXR+Re+xZb0FI/va1bz5CrduTzLSKBmf/+0lzl0MJvWY2+SXfGYdbl4+TTyqgDDfwqW0Tj8pDimye2BneyTmXko1rF+2Sxen7kMXnJLwpqjwZ6TZJuoqeK8q - - peerId: 12D3KooWASsipDzkridiMBmE7VSqp8yZvGWPY1VqySgMSZk6tsiL + signingKey: CZTN+NFi4g9MA4BKl3OiCKuzXh63ukIvYWo9D5t9qfZcFwIeOW8eP9W8mtnXaY3JAFyb6GliBW0uCaw4wjRcCA== + encryptionKey: MIIEpAIBAAKCAQEAo9Nuypzg9kZ+LP+8jQgSTaoRUu8VFdJdCOEjuroPQK+2NwBD/Z9BqKiN0Z+jmhkI9yA0/Fwdh21ibAKX3Je9uffAKOhXI2sxIAlccDORu1kGDnhcc7N3L644DK+uFZvKnMQWiCwmtTnNHkoCzWcIE44G56wMa2c4W7mrOuRWqG6a5Z9JUuLqafOIlf6Dw2fiVM6xXiTIMQ0OyXByxFNjsS5O/PYcwoIKMV8MY+gUnAmyPLE0bslvz/8W+3E7d/LDO4lhqW+N1kDmboe6sc7DBf5JD4DLnP2VWV8Ae/rfJvxwu9ZqVT8RdYKMsZqvs9sV+6jQC9UcX+K8Q4Wdo0eMHwIDAQABAoIBAACR57zEtvOkYyP878b91DJ4+P503nno9XHmdp1bsFnlQpkGYzYqq6vOik/EYmlS1PknH4gROfkSpFkD2UtnK73N4tlBlawF33HhFnU9eLBSKvc56/hrE2sTDBbfNZfVpurMs9ddb/UJcnE8iK32QczvnY6IxrJI9aU8DCB0UujbGDnya/HbFU9pLLxu2EUoHNxjSHG/jCx+AR7JRknRA65KPZG7mu5jeAaaklYTY/aLGlctgecDKfNKDsZo6rgAMUW6ZXI8ogNGqfKHUFazCVe0l1tp4hxvgmyjcw79iKvFr4mlpHtgjYTFCeoMJKvOXUImZUJL0vCA6WKvUdIfzAECgYEA0lCTXYwOHqOwYMb1qi8lIIApcI//B/Nzn++MDQ4ZO4SzVJTTv4rSdXAuoihsO6E7LYZK+wdVNjiCbeMukfTqEfaxWXIsIDaHSR3440NsYSwdBz04UhRgpxFE2FwPK7J5dQ57FBaCAgksnO3XjcByBMYgMWVbA+ezIWfVdN96YoECgYEAx2mm/W4ZGdDyJgDonzEGGxfaNqo6DIv+67fDwI6WyqOWFWJTBaVFkm1uPJfcXYuTI9YCNFRKuRU7dyqSPLErMVusC/8Iww8++kqmkc1m04tbkqh4KpREYuMw8/tTYSWDwgpY8ksM5YRpYRJLTuuC0cEmefGco1RsXG8bYYeZXp8CgYBq5fexYcG/gxXgauBtSx9E4L+vbhGD2hNYJKr768GZhf6crDTgs8/7TzT0yTUSLgZlQlAUPgrqz1hEQGfoWiMrVEeanjSdfvnOiUR7R0bsMT7j8hMRbTgfUuC6VDiFzmZ7wAuBD1uvazhY329jpoCNuqKcWNclKfzbqupNSFXtgQKBgQCTlR7Qm0YadChydeOzxX2GWa3XHT7fAFFHNPa8MQtqp40xAFb/a6TEzRZz49RkqyLXt9Bj2CqBNjSPakNWhay41+bJ7hMXAdaTOOJ0L/c1AwNf1C0zHg5KvWgCefPohvIvjqbrkx3VU50GCZsQqn5kLLYENAvAWX/lHRm/obKhcwKBgQC/iAOC8ZdZC5w4F0Mf7roZWa9P/42JWlCMzm/I/5mEIn4mYY6+1C5V+fXoET6845oAh+P8CkH4waJtqqN6BKQhj7SKqoCHgGBCQy+HrSCBtzk7NuXdpz6sk14zfcVpjR3y3l9TuXc4cVQMSLAqg8yUQf+qnEQTit4jyfikV/5XEw== + - peerId: 12D3KooWDXDcBYxtZ8KNRoJebNgNAv9nFbQatQMoWm1BLwmQh6u7 address: 127.0.0.1:4432 - signingKey: /6+uYFwFf9nU6fvXQVtpHhjd8+v4dXc7esZzqkhjyfMJWlMiZOtQeb913FXofD5f20WksU0l6i22B09sFFYwDQ== - encryptionKey: MIIEogIBAAKCAQEAwCy84lzkxtzgn4ixGm0LSUTujOBpOh9m7XDoDPZnMTmExdOe9a5v/LXzdlCOCuBvK5u1T3ALBJMA3Zgvjv/jPRQUdiHprP3sbdfc6IgZPBFdLKFTc9yAA7GMbI4y7LhGMLGOMOqQXs+DOeImfmxEs3ykLXHKNas5ORnZPVnB6E9Qod8KH7UyMmBjQkOZYOOw10X4JZiU6xJp/E+VVWcmeXgNBbj5xOWMSzM+hhoA4wNOzBxACucaKDmqD6qugzebOqyUVSzFnEbquro+MYTWYdUDjZTXdvxgUUo80MGQ164gZhkFUKrmSpUvu3YErFySEGqAdFNwOZ6y/4X3s0BHvQIDAQABAoIBAAZiNhAK5+qXMbr67m8jSimv6YCyf6xXmLKwenTbxofDEl8D7ZbZqYyqeqDmgiFoXSkErhwqa6NGQtQZlxLX+zNvNFLMQ5fkg3MOpZ7vzm7JYN/3p+8EVxhIUJLWkmh8opBBhaioUg1kNUa59W9jp1CTBl0gF4h63JbB/g5kqeVOllUw7J1igAoaX36nOJGOwIynCWdizhDhgyjR4OcYfOLwcPDJueKTc5vM10g3LuMSK/sJmaD3TkJFPtDHw+RMW6wqyjsnkrg2D2oohXEyGWYYIXo2so4HCez0AB1I1JAxtVnRPvSIp7xLMm7+AkDoq12QYDHfxZtDTpfmvJg+Sn0CgYEAxCd+oribtdQW+JUctjsDbSQX5CeRISH5Ith3jveBx2jKIqQVnoVPz6URHOvnlIsqYYLANB8B3JHMWfR2UmkK11x0OcZecB06+oBoCZukvSXF+GqVHzLAQUxaoEBDCCPneskj5w+riMWBiiGDp32rUnkqv0nh7dnH+GfORcJ44L8CgYEA+s5s5EALj1jyU9w4+HVUyVsIrUitFnQg6qw/Td3Kj+8CXImKlS+rlmbQv0m1aOcvtFjQRIjjzZJAf/ausfAME+MayoNODgZsDk5RyDKuSWzMLvZLAa1LD52Uli5Pg8KtpzKVTn4xE1MbjsQcUNhFRAgrNEKNyuzXzdp4uXgGOoMCgYASXwiTQOsEepq0KXMI9jn57Nl3+uSyz7W/t7pq329+N6hG2ktUD3RMJE+X/9gup2IOw+owd377I4SaIDU8vq3PQc944cVShspRT9lunO8u7+y8uW7B/0TWWMpcG+irSIGTlGcSavtL0gOx5jWoaDK1hLemNss8NZtu/nnpOq+LjQKBgDisVozJMBOHPNLYS4NROAR77p0BdCNDwIBmxbM5r+EQWA9DAS6u4+4Lc5YV+MkonG37N6yU5iz4pFyGCHmqzX/c7JvgSc3/g4FED1TWpu1uiUD/ZHmPiAuSRxYchtk2L3k9g+GFwF8mg26iP+fAxv4VfnXDqDi3hhg9CtSWG4ozAoGAOWZXlFKqzGAfcucIe54FVQnweXG9sEuIPAvWvVRs4406ggNmL5eHccXpPHWTgetsr2TYMqPTDVMRmhBzSkyrYgk+b2tme79HPzTWs2Yg/pzjOfTgw7MBX/KlvOW5/J+dvrF3Gx8AHHZ9QQdYqi/MS1NKb2K3IbD0/m5gL5Pwi6A= + signingKey: c3D+0+BCl1xU35KBY+U3GPcU9aXdoLUiD4DJ2jF+IqI3CjGLhet3MBOkPXdIuPq/UpEqlp1k6FjNaU6DEU6Csg== + encryptionKey: MIIEpAIBAAKCAQEAuB7HsXuYmoif6/U4JnjC6L0QMu9qW1aPAxDrxWIedTzQhFZp3F3gYW/Zgdd2hvd0c2xyfhwf9C0X/UzfxWr54dDXzWNLN8BdVTik48cdYlgOmbgejiIjTaqSAlv4RtlqvooxCN0MwR2/RVAG/N5GqcAM7E4kJWPtvQYNl6wWCc92rKdutvmcj73wKzz9Hd/qdF612OVS3zRsjh3tJmYt55oovAUh1TAz/mSTTXjFHy35zLRBP+oQQsAOt2p0BOMSyOKZufGC8l3aZD//dp4/U/MaqCjeNuWxCfAZlSd+vt7T0aqDGdyRtrrGUcu4PCwXpOdbzw+uSZxnKawolYoEHwIDAQABAoIBAQCsxeVpvKtUx8QZrUCFiWiM8W0T/un0z+LfY696xzoBlZGtvVEVQtpdVJHsb31/5RFXhnphsI6jmPUb8llBbcMSjeETkItyw4ZRhBfmzl/aevsocEfr5EjwhpEAucDe6wJpzk95G8TuKrXjmtcTzpjMjbUSwbjVhVH/wIBcxVTg2j6z4AOADDRI5UsvZ0NV//If+nNzMjcuIji95PNk7lAuwsqkX3FycxvqXKUMGxRE2bgGMxaBRAP0kqL2vdxyS1M7wp/x04ZAtSnPXHe4qqmDOt69ec3XqbmZHOsZHzkCFePKcPB472/G0bPJeiq/idevEqS89RwvbphDtq3KGrRBAoGBAOrHqlPh36WZBOi6SueUmcrg579KDMUekgeea5payiySbRWztCL2yCYbSgFqSbyCLRppyXK51xvo8iUejR231or6u/nd7T0CON0Nf/8Qtbb13vtTGpIBiWYGqeDrWucUUlyS+K3sDfNk1AJqjUdaIMVu4yTpgzEvrdYCcT312RBPAoGBAMjC83/0EKnsbypFprxKS3Fbg963HhyKjfffQ2w4yncM6kxXF3ehVjg1LInok/6/dmy2LxkAf3r0YYZrGJWmG4Sv4UqHn6JxAjQgarPbdmGhJ8VIUMvMbZRsX3i8Z8D2o8k1M1kr6MYsQ53iX6q/Cp3gnucMeJPk6Xs9Q4TO7YsxAoGAWrXEOF6X01p4zBZWJH2Eoh8dSwooPuzdzPXHaz7SyD/Wx8DDw5KHqDl48W0Iij3dgUwIGjx1QQJStEbGjQnfaZkQkazOIXk/USELKBhjrQn4GjB0np7bYEEI1673UzrFy6C5VjFS/owhYcGbTksjSETcnAFgv9tFFd+hsyfOsv8CgYALk4o875LiaXrDgj6qDtKo17ET75Ux6h9jkqEtpVyvXrRH8KGuyUPSe+Z0kU+vWdT3Uc4HcArpyRuyh4xkXK6riQTBqm5fDIsm/FOKyXXbDVLgwlm+Vqxe6Zzbtml5K/+nw4SReMG0Y6sGeJ4xl1CCaAhhpEtzo7h+3bp99vylkQKBgQDDdR6N4wb3DHTzrW0EFb8XhXZN7CIE3EWhToNDsCkguUB7lwqD4p2c4yLscS0YAqxk7I3NW0nDaUV/340RrVtPJDqB4NZJ+MvhfvV3TW2FkZmru/iW+DMUsfZGAOPdQz9jLGAzUXrXFw/qGBtLIUL6UWqWLOrBO9QHb21nnB1Ssg== space: gcTTL: 60 - syncPeriod: 11 + syncPeriod: 600 storage: path: db metric: @@ -37,3 +37,6 @@ log: production: false defaultLevel: "" namedLevels: {} +stream: + timeoutMilliseconds: 1000 + maxMsgSizeMb: 256 diff --git a/etc/configs/client1.yml b/etc/configs/client1.yml index 9be9ee38..236f0ef5 100755 --- a/etc/configs/client1.yml +++ b/etc/configs/client1.yml @@ -5,30 +5,30 @@ grpcServer: - 127.0.0.1:4630 tls: false account: - peerId: 12D3KooWFgtCbkf47HhFyQW2cEdAkvaofpokCiaa24Phnz7hpepG - peerKey: 4nWcqWOZxv1iXWYuW35eJlF9nxownm38bZjQ27pmFgVXO26vobKLx70TnNTQzZQdoW/dZtxyE9PO37R74vfPQQ== - signingKey: ULbtmmyFjkJ6Z+54FI1OJWfu0QdIeoCckwcrBZDLGhw2o2cXTFH5KGxQuAruNTbREz9eAVGmhGoBZtKVi6/6ng== - encryptionKey: MIIEowIBAAKCAQEAuGAvw/JQuivjoFIhV9RGkoCjO60jNkQpVPWK52eUtEvKHT2EzufhCRwxhAreajoyzk0PsyJ75FWrrvYs2tkSVHFOSiBkZIsldn5gPg1cnvnJOZ9VKDFp8h85d/4cPQ5tX78043nYTgLje2EmbB83inIr4oiZgxDrtLkozJHleAyWuOLIvlWO1l4Uplf6+uooL/5+WeUCuSGUM0wgXfpn+I2IuRhVDVZiChfp51Q6D6brTdOzNcWq1dw6Vld67u8aCLF1EVZ+xM/rnLLBC7MFvIw44LqHvmvGs/lpE9nMNx5L2KfpbpHSBI0IH3FkLQe2Qz8OMZpIa+aga/DzrBpEdwIDAQABAoIBACudXU898AjKPxN6ujZ7maIoWfTQ9SZuI1TcrNomr4+i6hHWrqb/RUWRbMkuhQSd9czFf/RBMQuHlJBT3bJ7bRGaqAly9iyumdMY/A1RvdpBfm9qGIvkfIpxBngzHVz4H7lpkspI1XlGx6c1CRDEpa/TaDwzUhUmGIvszRDvZlfqQvjPjyYSV5Hdc4ywh5zjuSFlxOD/9gsPRE5v4M4FGrGv8cm859P1u95Wxxo3pWincpzjvWw2LpsUGctyU34MhErxh86vNhP9v+nR4VkdojVKkHQTYnPKUlaKj6F+IUSj8syxuTJb8bs0GBuvcXW9AKp/K0xq/GBC8Cu/XN7Ln7kCgYEAwZoqLnU9OuwkcN5AHYW7XsxmVCEnxOsncrUbIzEKPvy4wELdOCVVrX66zmIjb+1+mhaz+mGMGEpkVMBld3wdDfmGgo0CAPlF4efH1ppMzUm2aZ+HYQR8KMH1XOT9qjbGEnLeWcANQT0vZPpe77PQLNwLJ1zv6EtXMMrEH0s4ijUCgYEA88zCNsBtB07ayFr9r+RCfHx/X9wFkT59t2K+axIfZE02f62WWqJCZYMlZu9XAbYEQ94H43/NAL9wfA8dgnF7mKSL8stJKt0g2iPa3MluF4Gq5Y2XYEVf/EDEhP2jh8p1l+xs18rVzsQQ6b3CEU9ytmBJWvkWnwVXf+ZnsCFECXsCgYBM3YyJzXp1/nOpbFRAZGw0AytNk6xafpK29DjGDB5pS6V+kA2M0SXnMD2y2zv+oGh3fTQP4NLigga7r3eZrOlMNxm0k4+MG2wneQLarYB4sR9/aBsz5bf15qwoKbKc9gpGIN0u/RVGJai/irhOqzGn3eV/x2Jo9CC1+otLcW4NUQKBgQCOOHlnZTN1GuwICwSIkhiy9BF+AyUASLsfuquoXEcRxPUw4DugnZ0sCKhN9vsDlYHBcYmajhgyAnuE83BcgwT906eMOEhzh9G9T0NCnwLpFYxzIvkWgQHwbnv1tNyrv1CAEryf2cSGPNw87qSCYp1hhKPmPP6UP5J+mxMLrSw6dwKBgHHFweDS2tw4TNxJQjhfQOp5t9VQbQffFZAqpXGFTc4vf7XePlxIGoIpOg4ShHCKKHSy0PtsLe7QjLrdbMkyYh8oGqgNe5CYTzFFDeK6Im1DoiqNWT+YUWF/gzVRUSpo0QW+4J1hfChG2URp9KbnditXKsJ5Vh+QayHPoZwN7Kgl + peerId: 12D3KooWQajuCbCYJdh6fhfTQpwJpJ61mV1ZV4F4XuJnFHeVfeSF + peerKey: Gz1ARVeHzdusDtBL0DawuQKoKdKhL827WiCPekOndSnbYb65zdtgoxGP8Y+enTfKksPftODaiqzZr16Dfq+JvA== + signingKey: wKPnynjYCBVqDEiREnMRHz6id1NFNIfjV4XKmB27ave9BSyS8saW71BEb/0XT0IZDJep6oSKr9ua5kAxcr7tQA== + encryptionKey: MIIEpAIBAAKCAQEA1DJ/TtBpSEVZVfPWJdp7tPaGY9d+4zrD91LM/4N4DKKhhSFfcWlHgZeQiEtP6bKCdIp2nPMURiS8hd1JzYmNJNk/hUYlzCUJOZWyduVeaow9rlTT6I9a8BVUBQHtVD+PUu5pkfjLFgAojcSzg/mIPzJ0T76AlsFXBdXRfS2wnVKfF0/V+jHiLB1V2JBLjyuRf2V5HFglEmWfrCoG02Q9OENZJHy02NXGCs7FnZdYhHct9u00dXk6Xp0w+oBD74+h4gsyFAHnRodRnhC0WMSv2LIPIQUh7x5LfvKx85n6LMFk/aYgTNFKQfu15VTzjfbVbeAm8jsHgV/FifRvETHm6QIDAQABAoIBAF6RLqlaOkFqHpkutRZjm1QXtebTCAqOiv0zGocY+SxwYhlpuRZa+/ImMNR8891Ln9X+S0RBFJz6DEaASz7deVidtTBZBclIDCdsrn9MU1qaq3aA+XugP7/VUX91z2YHeYFVHRlfzmo8odYkfnhnga/gdXOAi+Ajw/umwdjOvvItKqzm4FHHrwmqKDGlMfPgVcbkE/1iDRSwGvuEPOtMuNrTGcPyz0w10BO5zfpxgxJ2Esgmg66VG+H/KPSoLCtStZilErC8gRx9AbbJGUJcLkjd3T6A02cS9IS/hyTEK7qjxNjVaW0DfCrjXfIFiVHeXTB1LSS2JR95kArG437WTw0CgYEA/JsW6qDjl1jF7tYr+E6PjnCk/dgm3nlsC8sTbZd5edPN3dp+D6qlwv4KYKDETpxohMMhOdSl5SYp4dirsnyPDF1BcGdrkq73aE6n4Tx7oQBMeuZLvK9hxWprJqRa9WP49CDiLOc/GLOe3N90s8ViSqU08/tqOtQLU4BmjHMCDzcCgYEA1wxpL7XUUeDa+bGXrtii3oXlZpyoUXft3JjhTazC1lQuwp5M5+0HA/BuTpl8b43+0gcgrUjqB7yeKWZ8Us0gE9ZMBPTGNNGjXjGOtOk1Lpm+PHrCxmADzfJ8V+rrQXvW2KcImJ0bZk87eNUKtDSsWy6+NIQ6W66GUFvv8iblit8CgYEAvBVKCedDrqQFtKC5Wog8MYXEA9IWlt33ygwp6ha39zLyfPa7mDSqebanyWzK3fFtjTSxH5sq7qTs2GF47kv6Qu2I1QXcPfqS8pJmQ7nCH43WZEfnKpW3icOEBuCnbUFD05pMbby86UqMxc6H2Xblicja1bNkVGsgB8t6D6duaB8CgYEAq337OA/x1KXTGoJ0avvZzkjK6uyNEgLozh2gtpfJ/K+/ZnZk8CNGj+6hmM6vvCpphsYmWeomr6rMGknfZQytwwQHNYCZu69eb5RnsH+1aIc0fPiM8TPKdOcmH9p4Z41BhR6XLVVEb29KBw8l7RWASWraRfkYrNpdxCG9FMfOD9MCgYBJ6Z7YNZsJq263s9oJ01npT2NlfXORd3KDHi/A6qC8Jx1dK3+Jew2VV53/PeXJKuPuePSV7nEOwA0wpg3+TuEsWHHOZVO4c+ZVJmonO0x0IzjMHzBB/8VZc+5n+yi/UOSupt/WRcoPOTjJ7tQdhc2m9C7YA248laYikbzkW5DHoA== apiServer: listenAddrs: - 127.0.0.1:8090 tls: false nodes: - - peerId: 12D3KooWPuwdqpDQxWhD2Vh4yskx2T5VMrwdpTZLfACzgsGfQfNy + - peerId: 12D3KooWHtnADt84naf6NeejZ1MxYGZPLk5SPEu2DL4ZV948uWPS address: 127.0.0.1:4430 - signingKey: yOEpD2+cPldXc2urGuU+szunm7fddRa8xew2uVjaxifRcVzNKhSERpOefjrXaky7PcKmSmTsH/5ZFtcrh1uzqg== - encryptionKey: MIIEpAIBAAKCAQEAxnE9Htwto+2fVmonkG9/DxNre33n7kjfrZU73JcHmpKhPlRFirig5T8rs2MaTq1R72/8nGBJuSxsz1PnexI3die39pY1OFYfZCZ59LbT7uH/xHcvkVrK2n50Q41KbbGT9BEzyW+XPkKPDpTq3/igYP+yUQgoWLfMwxCCLKXDe6qUC0fuIxR80fvj3XvorB5dnAiQ01JkH4PtCV1OWT6ZpLGhzcYxsxTHozd6LdMOC7wgGhW26dOSa/vZ1t5avbewFVIz0qfqBncunb7tjO4xa3xVYaA5jBbixDQUYFjVzW7cksrrN4CFNBDBGJ8PLS80MuMg0OG0O+/Qi1mbGb2mUQIDAQABAoIBACODAD0VidVcILeGJ65hRYudHg7raSXrRJv7qMrA/EtdEh3lVsyMXb6on1lq0rphqdf/YmVZldfda1tu2G3dxK8QTIuENeHvB48Uk56HWUXWi77M1WZdqQ+QsZ2lGzymGqQCsBHMNnSd1Jv3alDKXWj+WRrHKvE1cx81RRZYU7M9cpurnF5YNjO7L+7sMxUA9uAQGbe3kDVzrygraicLYQpxSNHytName0A+k3ug0qer4I6PmZhhJykkz6MD3dz/n625HSS+X+TuTm52T2b87tL27xXmSnUK7eYWjZ1vQlP1fWmqnac6u5LApUZaRi0tTjtefSjRW4jr1q20RqOp1kECgYEA7Onh3zM9ejATsjW6WISGKiBPci0D7DUbIuGuJrdQRadlkZzmeQ/VOYAuxIQD4GnQDRhM1FyxsqiAWkJOyCLFiMmsgIEyW9/eRhF8NlCVU+DA/fxy9EagfBbVsgiSBwOex24hPXIVYlaHkLAloNoD4bpw0pQZSDWXr+xvMFNwoGsCgYEA1m3sWA/e8ZuXForaUOoJzBU9nwC79bXv2UNktsVvBlQ1o9pbjoYDcVoAPwuBVUL1UwqDNMzPdhDBKBjZmCyjS6zlYD5ZKjF2m8iTyc4QcaBCdM0iyQpSXTmrfMx+hK1aWwL1p8ssNcednp5ExSAaTyNNGVdbtddiQ6/KMPmhUzMCgYEAwDjLsUNr4BXeBTweo+9yw/9PNn5brm0wRU8C9BrMIJe/izPYs+UqxerBB2Vtl8mCqv1KaQuEika5TYJ7VVsRFvk641DwQScUu5k4RQGBB3tWWz1XL+eWEticLkVR5isDyyAKDEbiHtXCTJz/CtGZUK7rF5BeKv6AwpZ9aKJqwV0CgYEAqXDlQNURu+PR6TtBtoypvz3NmraO0GO7KvipPhAXYm3qkRa8IIxfbhPLfAYQZhpqFvuIoJFzIn2s1I2GbExhoSv3eSzrcn7xlbpSpjYSImeb/AYZhbmFSiuHCi/hjeAaNS7KhZPz1G9vaubvusFaaMyhYPP6AWA4QvpHEJpB06cCgYBqR6/7d2hQiq4MJUrBEzLwG4ijnPeq+UVLQjE598hVIj+8UhRZRRcNWVEJxfcIL1v6Bpo8XISDNVRb30T9bPGVnXvC1jutTUbXKUB1/8iXuyH3IVieobch+bGd4v7ehH/lI7vzB6hjJpFzHopfFUn4wacSQdcFi3tRAwUB/L0S/w== - - peerId: 12D3KooWBgHmDqtXH9SrZfAmwCFsD8LZhTD5dg5wkhdbqFoS8GBN + signingKey: Fu/H792JFWVYQpOZeLBIr1Y5UuHdZzJxkGO7eakZDaZ3/vIDhjGgNab1+1NMdTJ0IUP6Tv3KQutcRwtX26/wmQ== + encryptionKey: MIIEowIBAAKCAQEAs+N32tT2Q4Nv9MlyH0B34TJZYLh1+Y/4hc0vupiS/Ct0Mt+Rh62KkPy6Hz2JRDd7ryYpz/Un+qAFQBhfugKy6a5R0U/OnaK8/WwJjstTPd59c7iGnCeW9mWumexT2wiQVbWcSdcAE5SPYmBkIPnwzgxZgtNzvEnbdUDWIOsR3ifDAt3iUqqlo+cZWIZaXiTjyrMlaWY/BR/SGrklYzxcUzNj+K6DdY4yFN5/5ywKIe81llooULTyM5U+fWEW5uri4ERgT/YcRAoii2UJ5kHzpIZmGKcrJ4kUdyFLE7VxYIQMHHXRkDlpTEYlAAJGl5frcHvFufTWIJaohBXAxg5tyQIDAQABAoIBAD3TI9I19x1lAwliYrKS+aCQKV+whftrm8KArrK21W2NkbYaWG4FGuaRtXYfNBoZ54xe1Wf/nenpLWTF+8B2RP9DRiNmBmDvGX0PsIk/IDDXUs5+0OTCRoQQll2Yd4mD+/c5H6nRFtmj6VOqRT+AJ17pp6nq+o/v4lj+G5ncsJtlAtq1xb20yHQYEl6sbK2UqYuiFtXpKMCK/8V3hDj+ROM8UMkxMj+qj9NFd2sCk4FEZ+S2QmHIjY55s4Rpe1RzZZZEYOuJ99Fism+HYXtf3JlFORaNIdhdWY1UkVAFuKY/ULoHOhf/RdJ8ZArak3CplpEdPTYC4IRBI1eZDDF2GgECgYEAw0jvV7E1kqfGD5Q1WTFsss4xHQntPtWRfyAI1viy16sqMX6wQ4ZixWXsOeMB1o5azqqjYo0BBiGw6ie1GKl0iZ09FxHmMDqFLf8a0JZXAlTvC/wEHgAXCzg7tpHRJD1B6gAiU6u6ALW14DtWe6tikFehrY0mwGb9koedQNgoGnkCgYEA69EcUTejGm5Hm6ANC5u5Vn1aaB4BrTJ36FGTaxjnSUPePBj0Eo2Bt+c25DiD3uGj2Jws5QrRhpu+NYhOTC+/P1/rm82w9Tpc8z/wA7nUk0gGEncgtJ8RFokom4B+Ui83JJiH0V7puZUhCc/TOmfa5N0SH5gM4q4rBoVDZtnTGdECgYEAlnssW9GlK6Z2++hEF7/7N+mldPACTkn6PRCtXyHzhjdSYyNxpgb3M49vsceY0gGOPfTFxBpNsLDjh/wjE6b4s1ZkDdPwIjfmCmSrABLpZ1WVgxGnBoshNrcVZIEGvTsrAKsryHfq88MSLIDtCo0tfXbZkkfTla2HNpOj/KTUelkCgYBl0pMRlp58qSWOUxuO6ZyrddD1qA89Q892ptKqqcQkZIOvG284G5XpXJLdFHIMaQ2gWD8iXvt9zf3hi4uTZgKEUNyhF73TBXJhLjhqw3DAb5b/niSnGQ/91ReNnXvt7Kk4ygvLIdp14ai0XeJtE672p2ZN8g+OSXoWhLBH1sJKIQKBgA7NH/Y4RbVHIMWY7jH/1d4ODZ4Hr1RK2Q99HJCAurfD5tjhpcMApoQQJKJDpv7J5Ipx6ynQJD7CFfx27+vqBEG4ffAUm66lKM5xrKcOevcyWemppurCLuza64GgWDP6jBRnHeqrUyZUqoI/I0FNwjxIJbu08NpRSt8khq59+iyF + - peerId: 12D3KooWG1r2SVzTMGDhkiw9McbZq98H9C1Ggzp7FSfWDGbVSCbZ address: 127.0.0.1:4431 - signingKey: l6LFiKqr4ZHgcPbL+DR7KwMbzImufQPFgpoHOJ/nvfUbpb76DCADHuT1I4gIs+XByglnY1KV8jbMfW64XRW5XQ== - encryptionKey: MIIEowIBAAKCAQEA4ltcn1AH048bMXcKOOW7/E0TZYPxL3OtcHXWHSAZjeeTA/rc45G2eaNgyY7Ji+feLtZERbXNWGFBdNp31NHDYZAYwbZmjEqTEgV4yVx7BQP3VBEzglTJaNLTf+XIJnVAEkoHS6ogjC0oXTM6paHu64EitoOCzF9zqL023swjE3HU0dm2xwsUdGnKeO5nPMso/6e3VMavkKnFmvB965ECCBujtediP4lVdIABNVtoMHCoeI5Sn+m7TKqJSyDOIEMhHT3orYUNZWVeAHE1YTM2cI5tSnDZP80CHZ674Z/bKL7Jaznmq87mVt1h9Use2EkxR07/dJuTGvFOos4jHoiR9QIDAQABAoIBAHAr8EluooI/j61CnYk2p6LPG0aaTQJD4/YwHuwOBTviP2OghKgthGzg/szDerNfMyaoveqBvoIGqCZdQTbwwE7v1qTgXA83wYwTtBitQLVqkr1RTOJQXAMbPv5Jg5czUY3+q4DejQSKOE9/XJfKGJkSRH6Hy2C2CJ3dLnzYUqWGO3t70RLT1/sC6p6w3lXdy3dKZGkoR2wva+HXQxVrP8X5HOResXgNZwgMHt9KF1QHVCcySKYiEAefEKTSdKD2fOd4FxLgp3zWpvH3jrX0zd/DqzTlFD5Ns6Ayp2sIfHVp3sn99DZZM6DauMepQKtoSCnXZ+qKhekAwNVJnsVQkSECgYEA4spY9araeFUSl4uXCUQOpCkSshYOPRYN6sBbHsx8tV2eQtCT+5SuNYmzur3c5bkiraGEab8rZfGdDL6fLxQyaqbOmN31Db5kNh/2X+sRnxkak8lsROUWQZRF9doH73FDv6ZlI3V/JicZlOUCfN5BYT+x74R4/c1YXfyuD1J9gr0CgYEA/4K4SDwZUY4bOVCmKQz0OM+RW4PAAH6LHKenTAZNTeDNFFxc2nqnzRGMEKZTDGy0kbT5mBhBHFgShXcAiKxc5/MGkpt8Jcq6Fr5KGU9aZtYKji6mwMTsUndPNQydh3vOt5pOmcuMM6ovanNTvI8k6Qo53OY1IpO5CfOROu0hm5kCgYBnWsYd92YnDsYxUEldzKlLgPhnNov4pNNk15LvP0vaL7cPRhUaw1B9T6scAKjp/GxkasZ4lsnFZM4o37qV7wNm/WwL2KN0Rv9Od1SFtBBMzFkDXvk7kJeK/XLAr0OMiLbSYZeYCFUQ4yLSa2et1nA/TJLf0CR/rhSGiMAedX6DlQKBgAx1137OT33GrFUzNacy1oYeuTv5RNfBVA9lrabrd8GggN/JUU3mRWCexnHZaptkgbnJVZKxPBuhv+V6VDBWF4HIPD3SD0/YfxK03PA3CnWRYppkdAValRvAbcBsiRIeW4pgoAyn/IJYfk92qFK9uFMVCJVZNKYnBhMSKbbx8X2hAoGBAKwvzyAImbNB+493q1R/lSayxzG76bRJ/EseiTqwIec9c4C+Bd/sVXR+Re+xZb0FI/va1bz5CrduTzLSKBmf/+0lzl0MJvWY2+SXfGYdbl4+TTyqgDDfwqW0Tj8pDimye2BneyTmXko1rF+2Sxen7kMXnJLwpqjwZ6TZJuoqeK8q - - peerId: 12D3KooWASsipDzkridiMBmE7VSqp8yZvGWPY1VqySgMSZk6tsiL + signingKey: CZTN+NFi4g9MA4BKl3OiCKuzXh63ukIvYWo9D5t9qfZcFwIeOW8eP9W8mtnXaY3JAFyb6GliBW0uCaw4wjRcCA== + encryptionKey: MIIEpAIBAAKCAQEAo9Nuypzg9kZ+LP+8jQgSTaoRUu8VFdJdCOEjuroPQK+2NwBD/Z9BqKiN0Z+jmhkI9yA0/Fwdh21ibAKX3Je9uffAKOhXI2sxIAlccDORu1kGDnhcc7N3L644DK+uFZvKnMQWiCwmtTnNHkoCzWcIE44G56wMa2c4W7mrOuRWqG6a5Z9JUuLqafOIlf6Dw2fiVM6xXiTIMQ0OyXByxFNjsS5O/PYcwoIKMV8MY+gUnAmyPLE0bslvz/8W+3E7d/LDO4lhqW+N1kDmboe6sc7DBf5JD4DLnP2VWV8Ae/rfJvxwu9ZqVT8RdYKMsZqvs9sV+6jQC9UcX+K8Q4Wdo0eMHwIDAQABAoIBAACR57zEtvOkYyP878b91DJ4+P503nno9XHmdp1bsFnlQpkGYzYqq6vOik/EYmlS1PknH4gROfkSpFkD2UtnK73N4tlBlawF33HhFnU9eLBSKvc56/hrE2sTDBbfNZfVpurMs9ddb/UJcnE8iK32QczvnY6IxrJI9aU8DCB0UujbGDnya/HbFU9pLLxu2EUoHNxjSHG/jCx+AR7JRknRA65KPZG7mu5jeAaaklYTY/aLGlctgecDKfNKDsZo6rgAMUW6ZXI8ogNGqfKHUFazCVe0l1tp4hxvgmyjcw79iKvFr4mlpHtgjYTFCeoMJKvOXUImZUJL0vCA6WKvUdIfzAECgYEA0lCTXYwOHqOwYMb1qi8lIIApcI//B/Nzn++MDQ4ZO4SzVJTTv4rSdXAuoihsO6E7LYZK+wdVNjiCbeMukfTqEfaxWXIsIDaHSR3440NsYSwdBz04UhRgpxFE2FwPK7J5dQ57FBaCAgksnO3XjcByBMYgMWVbA+ezIWfVdN96YoECgYEAx2mm/W4ZGdDyJgDonzEGGxfaNqo6DIv+67fDwI6WyqOWFWJTBaVFkm1uPJfcXYuTI9YCNFRKuRU7dyqSPLErMVusC/8Iww8++kqmkc1m04tbkqh4KpREYuMw8/tTYSWDwgpY8ksM5YRpYRJLTuuC0cEmefGco1RsXG8bYYeZXp8CgYBq5fexYcG/gxXgauBtSx9E4L+vbhGD2hNYJKr768GZhf6crDTgs8/7TzT0yTUSLgZlQlAUPgrqz1hEQGfoWiMrVEeanjSdfvnOiUR7R0bsMT7j8hMRbTgfUuC6VDiFzmZ7wAuBD1uvazhY329jpoCNuqKcWNclKfzbqupNSFXtgQKBgQCTlR7Qm0YadChydeOzxX2GWa3XHT7fAFFHNPa8MQtqp40xAFb/a6TEzRZz49RkqyLXt9Bj2CqBNjSPakNWhay41+bJ7hMXAdaTOOJ0L/c1AwNf1C0zHg5KvWgCefPohvIvjqbrkx3VU50GCZsQqn5kLLYENAvAWX/lHRm/obKhcwKBgQC/iAOC8ZdZC5w4F0Mf7roZWa9P/42JWlCMzm/I/5mEIn4mYY6+1C5V+fXoET6845oAh+P8CkH4waJtqqN6BKQhj7SKqoCHgGBCQy+HrSCBtzk7NuXdpz6sk14zfcVpjR3y3l9TuXc4cVQMSLAqg8yUQf+qnEQTit4jyfikV/5XEw== + - peerId: 12D3KooWDXDcBYxtZ8KNRoJebNgNAv9nFbQatQMoWm1BLwmQh6u7 address: 127.0.0.1:4432 - signingKey: /6+uYFwFf9nU6fvXQVtpHhjd8+v4dXc7esZzqkhjyfMJWlMiZOtQeb913FXofD5f20WksU0l6i22B09sFFYwDQ== - encryptionKey: MIIEogIBAAKCAQEAwCy84lzkxtzgn4ixGm0LSUTujOBpOh9m7XDoDPZnMTmExdOe9a5v/LXzdlCOCuBvK5u1T3ALBJMA3Zgvjv/jPRQUdiHprP3sbdfc6IgZPBFdLKFTc9yAA7GMbI4y7LhGMLGOMOqQXs+DOeImfmxEs3ykLXHKNas5ORnZPVnB6E9Qod8KH7UyMmBjQkOZYOOw10X4JZiU6xJp/E+VVWcmeXgNBbj5xOWMSzM+hhoA4wNOzBxACucaKDmqD6qugzebOqyUVSzFnEbquro+MYTWYdUDjZTXdvxgUUo80MGQ164gZhkFUKrmSpUvu3YErFySEGqAdFNwOZ6y/4X3s0BHvQIDAQABAoIBAAZiNhAK5+qXMbr67m8jSimv6YCyf6xXmLKwenTbxofDEl8D7ZbZqYyqeqDmgiFoXSkErhwqa6NGQtQZlxLX+zNvNFLMQ5fkg3MOpZ7vzm7JYN/3p+8EVxhIUJLWkmh8opBBhaioUg1kNUa59W9jp1CTBl0gF4h63JbB/g5kqeVOllUw7J1igAoaX36nOJGOwIynCWdizhDhgyjR4OcYfOLwcPDJueKTc5vM10g3LuMSK/sJmaD3TkJFPtDHw+RMW6wqyjsnkrg2D2oohXEyGWYYIXo2so4HCez0AB1I1JAxtVnRPvSIp7xLMm7+AkDoq12QYDHfxZtDTpfmvJg+Sn0CgYEAxCd+oribtdQW+JUctjsDbSQX5CeRISH5Ith3jveBx2jKIqQVnoVPz6URHOvnlIsqYYLANB8B3JHMWfR2UmkK11x0OcZecB06+oBoCZukvSXF+GqVHzLAQUxaoEBDCCPneskj5w+riMWBiiGDp32rUnkqv0nh7dnH+GfORcJ44L8CgYEA+s5s5EALj1jyU9w4+HVUyVsIrUitFnQg6qw/Td3Kj+8CXImKlS+rlmbQv0m1aOcvtFjQRIjjzZJAf/ausfAME+MayoNODgZsDk5RyDKuSWzMLvZLAa1LD52Uli5Pg8KtpzKVTn4xE1MbjsQcUNhFRAgrNEKNyuzXzdp4uXgGOoMCgYASXwiTQOsEepq0KXMI9jn57Nl3+uSyz7W/t7pq329+N6hG2ktUD3RMJE+X/9gup2IOw+owd377I4SaIDU8vq3PQc944cVShspRT9lunO8u7+y8uW7B/0TWWMpcG+irSIGTlGcSavtL0gOx5jWoaDK1hLemNss8NZtu/nnpOq+LjQKBgDisVozJMBOHPNLYS4NROAR77p0BdCNDwIBmxbM5r+EQWA9DAS6u4+4Lc5YV+MkonG37N6yU5iz4pFyGCHmqzX/c7JvgSc3/g4FED1TWpu1uiUD/ZHmPiAuSRxYchtk2L3k9g+GFwF8mg26iP+fAxv4VfnXDqDi3hhg9CtSWG4ozAoGAOWZXlFKqzGAfcucIe54FVQnweXG9sEuIPAvWvVRs4406ggNmL5eHccXpPHWTgetsr2TYMqPTDVMRmhBzSkyrYgk+b2tme79HPzTWs2Yg/pzjOfTgw7MBX/KlvOW5/J+dvrF3Gx8AHHZ9QQdYqi/MS1NKb2K3IbD0/m5gL5Pwi6A= + signingKey: c3D+0+BCl1xU35KBY+U3GPcU9aXdoLUiD4DJ2jF+IqI3CjGLhet3MBOkPXdIuPq/UpEqlp1k6FjNaU6DEU6Csg== + encryptionKey: MIIEpAIBAAKCAQEAuB7HsXuYmoif6/U4JnjC6L0QMu9qW1aPAxDrxWIedTzQhFZp3F3gYW/Zgdd2hvd0c2xyfhwf9C0X/UzfxWr54dDXzWNLN8BdVTik48cdYlgOmbgejiIjTaqSAlv4RtlqvooxCN0MwR2/RVAG/N5GqcAM7E4kJWPtvQYNl6wWCc92rKdutvmcj73wKzz9Hd/qdF612OVS3zRsjh3tJmYt55oovAUh1TAz/mSTTXjFHy35zLRBP+oQQsAOt2p0BOMSyOKZufGC8l3aZD//dp4/U/MaqCjeNuWxCfAZlSd+vt7T0aqDGdyRtrrGUcu4PCwXpOdbzw+uSZxnKawolYoEHwIDAQABAoIBAQCsxeVpvKtUx8QZrUCFiWiM8W0T/un0z+LfY696xzoBlZGtvVEVQtpdVJHsb31/5RFXhnphsI6jmPUb8llBbcMSjeETkItyw4ZRhBfmzl/aevsocEfr5EjwhpEAucDe6wJpzk95G8TuKrXjmtcTzpjMjbUSwbjVhVH/wIBcxVTg2j6z4AOADDRI5UsvZ0NV//If+nNzMjcuIji95PNk7lAuwsqkX3FycxvqXKUMGxRE2bgGMxaBRAP0kqL2vdxyS1M7wp/x04ZAtSnPXHe4qqmDOt69ec3XqbmZHOsZHzkCFePKcPB472/G0bPJeiq/idevEqS89RwvbphDtq3KGrRBAoGBAOrHqlPh36WZBOi6SueUmcrg579KDMUekgeea5payiySbRWztCL2yCYbSgFqSbyCLRppyXK51xvo8iUejR231or6u/nd7T0CON0Nf/8Qtbb13vtTGpIBiWYGqeDrWucUUlyS+K3sDfNk1AJqjUdaIMVu4yTpgzEvrdYCcT312RBPAoGBAMjC83/0EKnsbypFprxKS3Fbg963HhyKjfffQ2w4yncM6kxXF3ehVjg1LInok/6/dmy2LxkAf3r0YYZrGJWmG4Sv4UqHn6JxAjQgarPbdmGhJ8VIUMvMbZRsX3i8Z8D2o8k1M1kr6MYsQ53iX6q/Cp3gnucMeJPk6Xs9Q4TO7YsxAoGAWrXEOF6X01p4zBZWJH2Eoh8dSwooPuzdzPXHaz7SyD/Wx8DDw5KHqDl48W0Iij3dgUwIGjx1QQJStEbGjQnfaZkQkazOIXk/USELKBhjrQn4GjB0np7bYEEI1673UzrFy6C5VjFS/owhYcGbTksjSETcnAFgv9tFFd+hsyfOsv8CgYALk4o875LiaXrDgj6qDtKo17ET75Ux6h9jkqEtpVyvXrRH8KGuyUPSe+Z0kU+vWdT3Uc4HcArpyRuyh4xkXK6riQTBqm5fDIsm/FOKyXXbDVLgwlm+Vqxe6Zzbtml5K/+nw4SReMG0Y6sGeJ4xl1CCaAhhpEtzo7h+3bp99vylkQKBgQDDdR6N4wb3DHTzrW0EFb8XhXZN7CIE3EWhToNDsCkguUB7lwqD4p2c4yLscS0YAqxk7I3NW0nDaUV/340RrVtPJDqB4NZJ+MvhfvV3TW2FkZmru/iW+DMUsfZGAOPdQz9jLGAzUXrXFw/qGBtLIUL6UWqWLOrBO9QHb21nnB1Ssg== space: gcTTL: 60 - syncPeriod: 11 + syncPeriod: 20 storage: path: db metric: @@ -37,3 +37,6 @@ log: production: false defaultLevel: "" namedLevels: {} +stream: + timeoutMilliseconds: 1000 + maxMsgSizeMb: 256 diff --git a/etc/configs/client2.yml b/etc/configs/client2.yml index c4577024..ad5dd954 100755 --- a/etc/configs/client2.yml +++ b/etc/configs/client2.yml @@ -5,30 +5,30 @@ grpcServer: - 127.0.0.1:4631 tls: false account: - peerId: 12D3KooWQuD9ShSHt4nb7bXefg8ndpDXCDzwrm9pjHsnDY2khbRi - peerKey: fp/Q18I7TNM4kgKXbbOBQJbJonlrQqAlZwTF6Rx/sKXgHQGZ1dBcS45oXGbTb15Bi2r7sOX+d6HJaaQE29MisQ== - signingKey: ULbtmmyFjkJ6Z+54FI1OJWfu0QdIeoCckwcrBZDLGhw2o2cXTFH5KGxQuAruNTbREz9eAVGmhGoBZtKVi6/6ng== - encryptionKey: MIIEowIBAAKCAQEAuGAvw/JQuivjoFIhV9RGkoCjO60jNkQpVPWK52eUtEvKHT2EzufhCRwxhAreajoyzk0PsyJ75FWrrvYs2tkSVHFOSiBkZIsldn5gPg1cnvnJOZ9VKDFp8h85d/4cPQ5tX78043nYTgLje2EmbB83inIr4oiZgxDrtLkozJHleAyWuOLIvlWO1l4Uplf6+uooL/5+WeUCuSGUM0wgXfpn+I2IuRhVDVZiChfp51Q6D6brTdOzNcWq1dw6Vld67u8aCLF1EVZ+xM/rnLLBC7MFvIw44LqHvmvGs/lpE9nMNx5L2KfpbpHSBI0IH3FkLQe2Qz8OMZpIa+aga/DzrBpEdwIDAQABAoIBACudXU898AjKPxN6ujZ7maIoWfTQ9SZuI1TcrNomr4+i6hHWrqb/RUWRbMkuhQSd9czFf/RBMQuHlJBT3bJ7bRGaqAly9iyumdMY/A1RvdpBfm9qGIvkfIpxBngzHVz4H7lpkspI1XlGx6c1CRDEpa/TaDwzUhUmGIvszRDvZlfqQvjPjyYSV5Hdc4ywh5zjuSFlxOD/9gsPRE5v4M4FGrGv8cm859P1u95Wxxo3pWincpzjvWw2LpsUGctyU34MhErxh86vNhP9v+nR4VkdojVKkHQTYnPKUlaKj6F+IUSj8syxuTJb8bs0GBuvcXW9AKp/K0xq/GBC8Cu/XN7Ln7kCgYEAwZoqLnU9OuwkcN5AHYW7XsxmVCEnxOsncrUbIzEKPvy4wELdOCVVrX66zmIjb+1+mhaz+mGMGEpkVMBld3wdDfmGgo0CAPlF4efH1ppMzUm2aZ+HYQR8KMH1XOT9qjbGEnLeWcANQT0vZPpe77PQLNwLJ1zv6EtXMMrEH0s4ijUCgYEA88zCNsBtB07ayFr9r+RCfHx/X9wFkT59t2K+axIfZE02f62WWqJCZYMlZu9XAbYEQ94H43/NAL9wfA8dgnF7mKSL8stJKt0g2iPa3MluF4Gq5Y2XYEVf/EDEhP2jh8p1l+xs18rVzsQQ6b3CEU9ytmBJWvkWnwVXf+ZnsCFECXsCgYBM3YyJzXp1/nOpbFRAZGw0AytNk6xafpK29DjGDB5pS6V+kA2M0SXnMD2y2zv+oGh3fTQP4NLigga7r3eZrOlMNxm0k4+MG2wneQLarYB4sR9/aBsz5bf15qwoKbKc9gpGIN0u/RVGJai/irhOqzGn3eV/x2Jo9CC1+otLcW4NUQKBgQCOOHlnZTN1GuwICwSIkhiy9BF+AyUASLsfuquoXEcRxPUw4DugnZ0sCKhN9vsDlYHBcYmajhgyAnuE83BcgwT906eMOEhzh9G9T0NCnwLpFYxzIvkWgQHwbnv1tNyrv1CAEryf2cSGPNw87qSCYp1hhKPmPP6UP5J+mxMLrSw6dwKBgHHFweDS2tw4TNxJQjhfQOp5t9VQbQffFZAqpXGFTc4vf7XePlxIGoIpOg4ShHCKKHSy0PtsLe7QjLrdbMkyYh8oGqgNe5CYTzFFDeK6Im1DoiqNWT+YUWF/gzVRUSpo0QW+4J1hfChG2URp9KbnditXKsJ5Vh+QayHPoZwN7Kgl + peerId: 12D3KooWNRjRHDUytVA8gsaUBMfSArFgRSipdfka85KQ7FqL3FK8 + peerKey: 7FV/hHBDlj8uzDm4TBcfE2vmXVJSfvQryruCwcaQKta7W5l+eXQEsfxW46N1PJ+g4MCMIba8lQxQXsWGKXTQEw== + signingKey: wKPnynjYCBVqDEiREnMRHz6id1NFNIfjV4XKmB27ave9BSyS8saW71BEb/0XT0IZDJep6oSKr9ua5kAxcr7tQA== + encryptionKey: MIIEpAIBAAKCAQEA1DJ/TtBpSEVZVfPWJdp7tPaGY9d+4zrD91LM/4N4DKKhhSFfcWlHgZeQiEtP6bKCdIp2nPMURiS8hd1JzYmNJNk/hUYlzCUJOZWyduVeaow9rlTT6I9a8BVUBQHtVD+PUu5pkfjLFgAojcSzg/mIPzJ0T76AlsFXBdXRfS2wnVKfF0/V+jHiLB1V2JBLjyuRf2V5HFglEmWfrCoG02Q9OENZJHy02NXGCs7FnZdYhHct9u00dXk6Xp0w+oBD74+h4gsyFAHnRodRnhC0WMSv2LIPIQUh7x5LfvKx85n6LMFk/aYgTNFKQfu15VTzjfbVbeAm8jsHgV/FifRvETHm6QIDAQABAoIBAF6RLqlaOkFqHpkutRZjm1QXtebTCAqOiv0zGocY+SxwYhlpuRZa+/ImMNR8891Ln9X+S0RBFJz6DEaASz7deVidtTBZBclIDCdsrn9MU1qaq3aA+XugP7/VUX91z2YHeYFVHRlfzmo8odYkfnhnga/gdXOAi+Ajw/umwdjOvvItKqzm4FHHrwmqKDGlMfPgVcbkE/1iDRSwGvuEPOtMuNrTGcPyz0w10BO5zfpxgxJ2Esgmg66VG+H/KPSoLCtStZilErC8gRx9AbbJGUJcLkjd3T6A02cS9IS/hyTEK7qjxNjVaW0DfCrjXfIFiVHeXTB1LSS2JR95kArG437WTw0CgYEA/JsW6qDjl1jF7tYr+E6PjnCk/dgm3nlsC8sTbZd5edPN3dp+D6qlwv4KYKDETpxohMMhOdSl5SYp4dirsnyPDF1BcGdrkq73aE6n4Tx7oQBMeuZLvK9hxWprJqRa9WP49CDiLOc/GLOe3N90s8ViSqU08/tqOtQLU4BmjHMCDzcCgYEA1wxpL7XUUeDa+bGXrtii3oXlZpyoUXft3JjhTazC1lQuwp5M5+0HA/BuTpl8b43+0gcgrUjqB7yeKWZ8Us0gE9ZMBPTGNNGjXjGOtOk1Lpm+PHrCxmADzfJ8V+rrQXvW2KcImJ0bZk87eNUKtDSsWy6+NIQ6W66GUFvv8iblit8CgYEAvBVKCedDrqQFtKC5Wog8MYXEA9IWlt33ygwp6ha39zLyfPa7mDSqebanyWzK3fFtjTSxH5sq7qTs2GF47kv6Qu2I1QXcPfqS8pJmQ7nCH43WZEfnKpW3icOEBuCnbUFD05pMbby86UqMxc6H2Xblicja1bNkVGsgB8t6D6duaB8CgYEAq337OA/x1KXTGoJ0avvZzkjK6uyNEgLozh2gtpfJ/K+/ZnZk8CNGj+6hmM6vvCpphsYmWeomr6rMGknfZQytwwQHNYCZu69eb5RnsH+1aIc0fPiM8TPKdOcmH9p4Z41BhR6XLVVEb29KBw8l7RWASWraRfkYrNpdxCG9FMfOD9MCgYBJ6Z7YNZsJq263s9oJ01npT2NlfXORd3KDHi/A6qC8Jx1dK3+Jew2VV53/PeXJKuPuePSV7nEOwA0wpg3+TuEsWHHOZVO4c+ZVJmonO0x0IzjMHzBB/8VZc+5n+yi/UOSupt/WRcoPOTjJ7tQdhc2m9C7YA248laYikbzkW5DHoA== apiServer: listenAddrs: - 127.0.0.1:8091 tls: false nodes: - - peerId: 12D3KooWPuwdqpDQxWhD2Vh4yskx2T5VMrwdpTZLfACzgsGfQfNy + - peerId: 12D3KooWHtnADt84naf6NeejZ1MxYGZPLk5SPEu2DL4ZV948uWPS address: 127.0.0.1:4430 - signingKey: yOEpD2+cPldXc2urGuU+szunm7fddRa8xew2uVjaxifRcVzNKhSERpOefjrXaky7PcKmSmTsH/5ZFtcrh1uzqg== - encryptionKey: MIIEpAIBAAKCAQEAxnE9Htwto+2fVmonkG9/DxNre33n7kjfrZU73JcHmpKhPlRFirig5T8rs2MaTq1R72/8nGBJuSxsz1PnexI3die39pY1OFYfZCZ59LbT7uH/xHcvkVrK2n50Q41KbbGT9BEzyW+XPkKPDpTq3/igYP+yUQgoWLfMwxCCLKXDe6qUC0fuIxR80fvj3XvorB5dnAiQ01JkH4PtCV1OWT6ZpLGhzcYxsxTHozd6LdMOC7wgGhW26dOSa/vZ1t5avbewFVIz0qfqBncunb7tjO4xa3xVYaA5jBbixDQUYFjVzW7cksrrN4CFNBDBGJ8PLS80MuMg0OG0O+/Qi1mbGb2mUQIDAQABAoIBACODAD0VidVcILeGJ65hRYudHg7raSXrRJv7qMrA/EtdEh3lVsyMXb6on1lq0rphqdf/YmVZldfda1tu2G3dxK8QTIuENeHvB48Uk56HWUXWi77M1WZdqQ+QsZ2lGzymGqQCsBHMNnSd1Jv3alDKXWj+WRrHKvE1cx81RRZYU7M9cpurnF5YNjO7L+7sMxUA9uAQGbe3kDVzrygraicLYQpxSNHytName0A+k3ug0qer4I6PmZhhJykkz6MD3dz/n625HSS+X+TuTm52T2b87tL27xXmSnUK7eYWjZ1vQlP1fWmqnac6u5LApUZaRi0tTjtefSjRW4jr1q20RqOp1kECgYEA7Onh3zM9ejATsjW6WISGKiBPci0D7DUbIuGuJrdQRadlkZzmeQ/VOYAuxIQD4GnQDRhM1FyxsqiAWkJOyCLFiMmsgIEyW9/eRhF8NlCVU+DA/fxy9EagfBbVsgiSBwOex24hPXIVYlaHkLAloNoD4bpw0pQZSDWXr+xvMFNwoGsCgYEA1m3sWA/e8ZuXForaUOoJzBU9nwC79bXv2UNktsVvBlQ1o9pbjoYDcVoAPwuBVUL1UwqDNMzPdhDBKBjZmCyjS6zlYD5ZKjF2m8iTyc4QcaBCdM0iyQpSXTmrfMx+hK1aWwL1p8ssNcednp5ExSAaTyNNGVdbtddiQ6/KMPmhUzMCgYEAwDjLsUNr4BXeBTweo+9yw/9PNn5brm0wRU8C9BrMIJe/izPYs+UqxerBB2Vtl8mCqv1KaQuEika5TYJ7VVsRFvk641DwQScUu5k4RQGBB3tWWz1XL+eWEticLkVR5isDyyAKDEbiHtXCTJz/CtGZUK7rF5BeKv6AwpZ9aKJqwV0CgYEAqXDlQNURu+PR6TtBtoypvz3NmraO0GO7KvipPhAXYm3qkRa8IIxfbhPLfAYQZhpqFvuIoJFzIn2s1I2GbExhoSv3eSzrcn7xlbpSpjYSImeb/AYZhbmFSiuHCi/hjeAaNS7KhZPz1G9vaubvusFaaMyhYPP6AWA4QvpHEJpB06cCgYBqR6/7d2hQiq4MJUrBEzLwG4ijnPeq+UVLQjE598hVIj+8UhRZRRcNWVEJxfcIL1v6Bpo8XISDNVRb30T9bPGVnXvC1jutTUbXKUB1/8iXuyH3IVieobch+bGd4v7ehH/lI7vzB6hjJpFzHopfFUn4wacSQdcFi3tRAwUB/L0S/w== - - peerId: 12D3KooWBgHmDqtXH9SrZfAmwCFsD8LZhTD5dg5wkhdbqFoS8GBN + signingKey: Fu/H792JFWVYQpOZeLBIr1Y5UuHdZzJxkGO7eakZDaZ3/vIDhjGgNab1+1NMdTJ0IUP6Tv3KQutcRwtX26/wmQ== + encryptionKey: MIIEowIBAAKCAQEAs+N32tT2Q4Nv9MlyH0B34TJZYLh1+Y/4hc0vupiS/Ct0Mt+Rh62KkPy6Hz2JRDd7ryYpz/Un+qAFQBhfugKy6a5R0U/OnaK8/WwJjstTPd59c7iGnCeW9mWumexT2wiQVbWcSdcAE5SPYmBkIPnwzgxZgtNzvEnbdUDWIOsR3ifDAt3iUqqlo+cZWIZaXiTjyrMlaWY/BR/SGrklYzxcUzNj+K6DdY4yFN5/5ywKIe81llooULTyM5U+fWEW5uri4ERgT/YcRAoii2UJ5kHzpIZmGKcrJ4kUdyFLE7VxYIQMHHXRkDlpTEYlAAJGl5frcHvFufTWIJaohBXAxg5tyQIDAQABAoIBAD3TI9I19x1lAwliYrKS+aCQKV+whftrm8KArrK21W2NkbYaWG4FGuaRtXYfNBoZ54xe1Wf/nenpLWTF+8B2RP9DRiNmBmDvGX0PsIk/IDDXUs5+0OTCRoQQll2Yd4mD+/c5H6nRFtmj6VOqRT+AJ17pp6nq+o/v4lj+G5ncsJtlAtq1xb20yHQYEl6sbK2UqYuiFtXpKMCK/8V3hDj+ROM8UMkxMj+qj9NFd2sCk4FEZ+S2QmHIjY55s4Rpe1RzZZZEYOuJ99Fism+HYXtf3JlFORaNIdhdWY1UkVAFuKY/ULoHOhf/RdJ8ZArak3CplpEdPTYC4IRBI1eZDDF2GgECgYEAw0jvV7E1kqfGD5Q1WTFsss4xHQntPtWRfyAI1viy16sqMX6wQ4ZixWXsOeMB1o5azqqjYo0BBiGw6ie1GKl0iZ09FxHmMDqFLf8a0JZXAlTvC/wEHgAXCzg7tpHRJD1B6gAiU6u6ALW14DtWe6tikFehrY0mwGb9koedQNgoGnkCgYEA69EcUTejGm5Hm6ANC5u5Vn1aaB4BrTJ36FGTaxjnSUPePBj0Eo2Bt+c25DiD3uGj2Jws5QrRhpu+NYhOTC+/P1/rm82w9Tpc8z/wA7nUk0gGEncgtJ8RFokom4B+Ui83JJiH0V7puZUhCc/TOmfa5N0SH5gM4q4rBoVDZtnTGdECgYEAlnssW9GlK6Z2++hEF7/7N+mldPACTkn6PRCtXyHzhjdSYyNxpgb3M49vsceY0gGOPfTFxBpNsLDjh/wjE6b4s1ZkDdPwIjfmCmSrABLpZ1WVgxGnBoshNrcVZIEGvTsrAKsryHfq88MSLIDtCo0tfXbZkkfTla2HNpOj/KTUelkCgYBl0pMRlp58qSWOUxuO6ZyrddD1qA89Q892ptKqqcQkZIOvG284G5XpXJLdFHIMaQ2gWD8iXvt9zf3hi4uTZgKEUNyhF73TBXJhLjhqw3DAb5b/niSnGQ/91ReNnXvt7Kk4ygvLIdp14ai0XeJtE672p2ZN8g+OSXoWhLBH1sJKIQKBgA7NH/Y4RbVHIMWY7jH/1d4ODZ4Hr1RK2Q99HJCAurfD5tjhpcMApoQQJKJDpv7J5Ipx6ynQJD7CFfx27+vqBEG4ffAUm66lKM5xrKcOevcyWemppurCLuza64GgWDP6jBRnHeqrUyZUqoI/I0FNwjxIJbu08NpRSt8khq59+iyF + - peerId: 12D3KooWG1r2SVzTMGDhkiw9McbZq98H9C1Ggzp7FSfWDGbVSCbZ address: 127.0.0.1:4431 - signingKey: l6LFiKqr4ZHgcPbL+DR7KwMbzImufQPFgpoHOJ/nvfUbpb76DCADHuT1I4gIs+XByglnY1KV8jbMfW64XRW5XQ== - encryptionKey: MIIEowIBAAKCAQEA4ltcn1AH048bMXcKOOW7/E0TZYPxL3OtcHXWHSAZjeeTA/rc45G2eaNgyY7Ji+feLtZERbXNWGFBdNp31NHDYZAYwbZmjEqTEgV4yVx7BQP3VBEzglTJaNLTf+XIJnVAEkoHS6ogjC0oXTM6paHu64EitoOCzF9zqL023swjE3HU0dm2xwsUdGnKeO5nPMso/6e3VMavkKnFmvB965ECCBujtediP4lVdIABNVtoMHCoeI5Sn+m7TKqJSyDOIEMhHT3orYUNZWVeAHE1YTM2cI5tSnDZP80CHZ674Z/bKL7Jaznmq87mVt1h9Use2EkxR07/dJuTGvFOos4jHoiR9QIDAQABAoIBAHAr8EluooI/j61CnYk2p6LPG0aaTQJD4/YwHuwOBTviP2OghKgthGzg/szDerNfMyaoveqBvoIGqCZdQTbwwE7v1qTgXA83wYwTtBitQLVqkr1RTOJQXAMbPv5Jg5czUY3+q4DejQSKOE9/XJfKGJkSRH6Hy2C2CJ3dLnzYUqWGO3t70RLT1/sC6p6w3lXdy3dKZGkoR2wva+HXQxVrP8X5HOResXgNZwgMHt9KF1QHVCcySKYiEAefEKTSdKD2fOd4FxLgp3zWpvH3jrX0zd/DqzTlFD5Ns6Ayp2sIfHVp3sn99DZZM6DauMepQKtoSCnXZ+qKhekAwNVJnsVQkSECgYEA4spY9araeFUSl4uXCUQOpCkSshYOPRYN6sBbHsx8tV2eQtCT+5SuNYmzur3c5bkiraGEab8rZfGdDL6fLxQyaqbOmN31Db5kNh/2X+sRnxkak8lsROUWQZRF9doH73FDv6ZlI3V/JicZlOUCfN5BYT+x74R4/c1YXfyuD1J9gr0CgYEA/4K4SDwZUY4bOVCmKQz0OM+RW4PAAH6LHKenTAZNTeDNFFxc2nqnzRGMEKZTDGy0kbT5mBhBHFgShXcAiKxc5/MGkpt8Jcq6Fr5KGU9aZtYKji6mwMTsUndPNQydh3vOt5pOmcuMM6ovanNTvI8k6Qo53OY1IpO5CfOROu0hm5kCgYBnWsYd92YnDsYxUEldzKlLgPhnNov4pNNk15LvP0vaL7cPRhUaw1B9T6scAKjp/GxkasZ4lsnFZM4o37qV7wNm/WwL2KN0Rv9Od1SFtBBMzFkDXvk7kJeK/XLAr0OMiLbSYZeYCFUQ4yLSa2et1nA/TJLf0CR/rhSGiMAedX6DlQKBgAx1137OT33GrFUzNacy1oYeuTv5RNfBVA9lrabrd8GggN/JUU3mRWCexnHZaptkgbnJVZKxPBuhv+V6VDBWF4HIPD3SD0/YfxK03PA3CnWRYppkdAValRvAbcBsiRIeW4pgoAyn/IJYfk92qFK9uFMVCJVZNKYnBhMSKbbx8X2hAoGBAKwvzyAImbNB+493q1R/lSayxzG76bRJ/EseiTqwIec9c4C+Bd/sVXR+Re+xZb0FI/va1bz5CrduTzLSKBmf/+0lzl0MJvWY2+SXfGYdbl4+TTyqgDDfwqW0Tj8pDimye2BneyTmXko1rF+2Sxen7kMXnJLwpqjwZ6TZJuoqeK8q - - peerId: 12D3KooWASsipDzkridiMBmE7VSqp8yZvGWPY1VqySgMSZk6tsiL + signingKey: CZTN+NFi4g9MA4BKl3OiCKuzXh63ukIvYWo9D5t9qfZcFwIeOW8eP9W8mtnXaY3JAFyb6GliBW0uCaw4wjRcCA== + encryptionKey: MIIEpAIBAAKCAQEAo9Nuypzg9kZ+LP+8jQgSTaoRUu8VFdJdCOEjuroPQK+2NwBD/Z9BqKiN0Z+jmhkI9yA0/Fwdh21ibAKX3Je9uffAKOhXI2sxIAlccDORu1kGDnhcc7N3L644DK+uFZvKnMQWiCwmtTnNHkoCzWcIE44G56wMa2c4W7mrOuRWqG6a5Z9JUuLqafOIlf6Dw2fiVM6xXiTIMQ0OyXByxFNjsS5O/PYcwoIKMV8MY+gUnAmyPLE0bslvz/8W+3E7d/LDO4lhqW+N1kDmboe6sc7DBf5JD4DLnP2VWV8Ae/rfJvxwu9ZqVT8RdYKMsZqvs9sV+6jQC9UcX+K8Q4Wdo0eMHwIDAQABAoIBAACR57zEtvOkYyP878b91DJ4+P503nno9XHmdp1bsFnlQpkGYzYqq6vOik/EYmlS1PknH4gROfkSpFkD2UtnK73N4tlBlawF33HhFnU9eLBSKvc56/hrE2sTDBbfNZfVpurMs9ddb/UJcnE8iK32QczvnY6IxrJI9aU8DCB0UujbGDnya/HbFU9pLLxu2EUoHNxjSHG/jCx+AR7JRknRA65KPZG7mu5jeAaaklYTY/aLGlctgecDKfNKDsZo6rgAMUW6ZXI8ogNGqfKHUFazCVe0l1tp4hxvgmyjcw79iKvFr4mlpHtgjYTFCeoMJKvOXUImZUJL0vCA6WKvUdIfzAECgYEA0lCTXYwOHqOwYMb1qi8lIIApcI//B/Nzn++MDQ4ZO4SzVJTTv4rSdXAuoihsO6E7LYZK+wdVNjiCbeMukfTqEfaxWXIsIDaHSR3440NsYSwdBz04UhRgpxFE2FwPK7J5dQ57FBaCAgksnO3XjcByBMYgMWVbA+ezIWfVdN96YoECgYEAx2mm/W4ZGdDyJgDonzEGGxfaNqo6DIv+67fDwI6WyqOWFWJTBaVFkm1uPJfcXYuTI9YCNFRKuRU7dyqSPLErMVusC/8Iww8++kqmkc1m04tbkqh4KpREYuMw8/tTYSWDwgpY8ksM5YRpYRJLTuuC0cEmefGco1RsXG8bYYeZXp8CgYBq5fexYcG/gxXgauBtSx9E4L+vbhGD2hNYJKr768GZhf6crDTgs8/7TzT0yTUSLgZlQlAUPgrqz1hEQGfoWiMrVEeanjSdfvnOiUR7R0bsMT7j8hMRbTgfUuC6VDiFzmZ7wAuBD1uvazhY329jpoCNuqKcWNclKfzbqupNSFXtgQKBgQCTlR7Qm0YadChydeOzxX2GWa3XHT7fAFFHNPa8MQtqp40xAFb/a6TEzRZz49RkqyLXt9Bj2CqBNjSPakNWhay41+bJ7hMXAdaTOOJ0L/c1AwNf1C0zHg5KvWgCefPohvIvjqbrkx3VU50GCZsQqn5kLLYENAvAWX/lHRm/obKhcwKBgQC/iAOC8ZdZC5w4F0Mf7roZWa9P/42JWlCMzm/I/5mEIn4mYY6+1C5V+fXoET6845oAh+P8CkH4waJtqqN6BKQhj7SKqoCHgGBCQy+HrSCBtzk7NuXdpz6sk14zfcVpjR3y3l9TuXc4cVQMSLAqg8yUQf+qnEQTit4jyfikV/5XEw== + - peerId: 12D3KooWDXDcBYxtZ8KNRoJebNgNAv9nFbQatQMoWm1BLwmQh6u7 address: 127.0.0.1:4432 - signingKey: /6+uYFwFf9nU6fvXQVtpHhjd8+v4dXc7esZzqkhjyfMJWlMiZOtQeb913FXofD5f20WksU0l6i22B09sFFYwDQ== - encryptionKey: MIIEogIBAAKCAQEAwCy84lzkxtzgn4ixGm0LSUTujOBpOh9m7XDoDPZnMTmExdOe9a5v/LXzdlCOCuBvK5u1T3ALBJMA3Zgvjv/jPRQUdiHprP3sbdfc6IgZPBFdLKFTc9yAA7GMbI4y7LhGMLGOMOqQXs+DOeImfmxEs3ykLXHKNas5ORnZPVnB6E9Qod8KH7UyMmBjQkOZYOOw10X4JZiU6xJp/E+VVWcmeXgNBbj5xOWMSzM+hhoA4wNOzBxACucaKDmqD6qugzebOqyUVSzFnEbquro+MYTWYdUDjZTXdvxgUUo80MGQ164gZhkFUKrmSpUvu3YErFySEGqAdFNwOZ6y/4X3s0BHvQIDAQABAoIBAAZiNhAK5+qXMbr67m8jSimv6YCyf6xXmLKwenTbxofDEl8D7ZbZqYyqeqDmgiFoXSkErhwqa6NGQtQZlxLX+zNvNFLMQ5fkg3MOpZ7vzm7JYN/3p+8EVxhIUJLWkmh8opBBhaioUg1kNUa59W9jp1CTBl0gF4h63JbB/g5kqeVOllUw7J1igAoaX36nOJGOwIynCWdizhDhgyjR4OcYfOLwcPDJueKTc5vM10g3LuMSK/sJmaD3TkJFPtDHw+RMW6wqyjsnkrg2D2oohXEyGWYYIXo2so4HCez0AB1I1JAxtVnRPvSIp7xLMm7+AkDoq12QYDHfxZtDTpfmvJg+Sn0CgYEAxCd+oribtdQW+JUctjsDbSQX5CeRISH5Ith3jveBx2jKIqQVnoVPz6URHOvnlIsqYYLANB8B3JHMWfR2UmkK11x0OcZecB06+oBoCZukvSXF+GqVHzLAQUxaoEBDCCPneskj5w+riMWBiiGDp32rUnkqv0nh7dnH+GfORcJ44L8CgYEA+s5s5EALj1jyU9w4+HVUyVsIrUitFnQg6qw/Td3Kj+8CXImKlS+rlmbQv0m1aOcvtFjQRIjjzZJAf/ausfAME+MayoNODgZsDk5RyDKuSWzMLvZLAa1LD52Uli5Pg8KtpzKVTn4xE1MbjsQcUNhFRAgrNEKNyuzXzdp4uXgGOoMCgYASXwiTQOsEepq0KXMI9jn57Nl3+uSyz7W/t7pq329+N6hG2ktUD3RMJE+X/9gup2IOw+owd377I4SaIDU8vq3PQc944cVShspRT9lunO8u7+y8uW7B/0TWWMpcG+irSIGTlGcSavtL0gOx5jWoaDK1hLemNss8NZtu/nnpOq+LjQKBgDisVozJMBOHPNLYS4NROAR77p0BdCNDwIBmxbM5r+EQWA9DAS6u4+4Lc5YV+MkonG37N6yU5iz4pFyGCHmqzX/c7JvgSc3/g4FED1TWpu1uiUD/ZHmPiAuSRxYchtk2L3k9g+GFwF8mg26iP+fAxv4VfnXDqDi3hhg9CtSWG4ozAoGAOWZXlFKqzGAfcucIe54FVQnweXG9sEuIPAvWvVRs4406ggNmL5eHccXpPHWTgetsr2TYMqPTDVMRmhBzSkyrYgk+b2tme79HPzTWs2Yg/pzjOfTgw7MBX/KlvOW5/J+dvrF3Gx8AHHZ9QQdYqi/MS1NKb2K3IbD0/m5gL5Pwi6A= + signingKey: c3D+0+BCl1xU35KBY+U3GPcU9aXdoLUiD4DJ2jF+IqI3CjGLhet3MBOkPXdIuPq/UpEqlp1k6FjNaU6DEU6Csg== + encryptionKey: MIIEpAIBAAKCAQEAuB7HsXuYmoif6/U4JnjC6L0QMu9qW1aPAxDrxWIedTzQhFZp3F3gYW/Zgdd2hvd0c2xyfhwf9C0X/UzfxWr54dDXzWNLN8BdVTik48cdYlgOmbgejiIjTaqSAlv4RtlqvooxCN0MwR2/RVAG/N5GqcAM7E4kJWPtvQYNl6wWCc92rKdutvmcj73wKzz9Hd/qdF612OVS3zRsjh3tJmYt55oovAUh1TAz/mSTTXjFHy35zLRBP+oQQsAOt2p0BOMSyOKZufGC8l3aZD//dp4/U/MaqCjeNuWxCfAZlSd+vt7T0aqDGdyRtrrGUcu4PCwXpOdbzw+uSZxnKawolYoEHwIDAQABAoIBAQCsxeVpvKtUx8QZrUCFiWiM8W0T/un0z+LfY696xzoBlZGtvVEVQtpdVJHsb31/5RFXhnphsI6jmPUb8llBbcMSjeETkItyw4ZRhBfmzl/aevsocEfr5EjwhpEAucDe6wJpzk95G8TuKrXjmtcTzpjMjbUSwbjVhVH/wIBcxVTg2j6z4AOADDRI5UsvZ0NV//If+nNzMjcuIji95PNk7lAuwsqkX3FycxvqXKUMGxRE2bgGMxaBRAP0kqL2vdxyS1M7wp/x04ZAtSnPXHe4qqmDOt69ec3XqbmZHOsZHzkCFePKcPB472/G0bPJeiq/idevEqS89RwvbphDtq3KGrRBAoGBAOrHqlPh36WZBOi6SueUmcrg579KDMUekgeea5payiySbRWztCL2yCYbSgFqSbyCLRppyXK51xvo8iUejR231or6u/nd7T0CON0Nf/8Qtbb13vtTGpIBiWYGqeDrWucUUlyS+K3sDfNk1AJqjUdaIMVu4yTpgzEvrdYCcT312RBPAoGBAMjC83/0EKnsbypFprxKS3Fbg963HhyKjfffQ2w4yncM6kxXF3ehVjg1LInok/6/dmy2LxkAf3r0YYZrGJWmG4Sv4UqHn6JxAjQgarPbdmGhJ8VIUMvMbZRsX3i8Z8D2o8k1M1kr6MYsQ53iX6q/Cp3gnucMeJPk6Xs9Q4TO7YsxAoGAWrXEOF6X01p4zBZWJH2Eoh8dSwooPuzdzPXHaz7SyD/Wx8DDw5KHqDl48W0Iij3dgUwIGjx1QQJStEbGjQnfaZkQkazOIXk/USELKBhjrQn4GjB0np7bYEEI1673UzrFy6C5VjFS/owhYcGbTksjSETcnAFgv9tFFd+hsyfOsv8CgYALk4o875LiaXrDgj6qDtKo17ET75Ux6h9jkqEtpVyvXrRH8KGuyUPSe+Z0kU+vWdT3Uc4HcArpyRuyh4xkXK6riQTBqm5fDIsm/FOKyXXbDVLgwlm+Vqxe6Zzbtml5K/+nw4SReMG0Y6sGeJ4xl1CCaAhhpEtzo7h+3bp99vylkQKBgQDDdR6N4wb3DHTzrW0EFb8XhXZN7CIE3EWhToNDsCkguUB7lwqD4p2c4yLscS0YAqxk7I3NW0nDaUV/340RrVtPJDqB4NZJ+MvhfvV3TW2FkZmru/iW+DMUsfZGAOPdQz9jLGAzUXrXFw/qGBtLIUL6UWqWLOrBO9QHb21nnB1Ssg== space: gcTTL: 60 - syncPeriod: 11 + syncPeriod: 20 storage: path: db metric: @@ -37,3 +37,6 @@ log: production: false defaultLevel: "" namedLevels: {} +stream: + timeoutMilliseconds: 1000 + maxMsgSizeMb: 256 diff --git a/etc/configs/cons1.yml b/etc/configs/cons1.yml index 1ff8aad4..ee100f0a 100755 --- a/etc/configs/cons1.yml +++ b/etc/configs/cons1.yml @@ -3,10 +3,10 @@ grpcServer: - 127.0.0.1:4530 tls: false account: - peerId: 12D3KooWPHN8pCMgVaNfjzuXhHjsacrryW7DCyicurH3uKHXCyE5 - peerKey: yHyVKOM1zEIbaHgwIAcBD/s9TmYQj6dU3dSzs5OHyBTIEpMC+jaTKKmS/5QCzgLzJFBnvayFtXwR/dH9G49M7g== - signingKey: yHyVKOM1zEIbaHgwIAcBD/s9TmYQj6dU3dSzs5OHyBTIEpMC+jaTKKmS/5QCzgLzJFBnvayFtXwR/dH9G49M7g== - encryptionKey: MIIEowIBAAKCAQEAu7C6g3bFuQb113lDuKJKa2zzeZNQxdjEQTcC5NVZkt5Qbz1cV4o1Rav0+nrMYT0mRFz6HPElUM7D1o+e/FIxrCsVnoCm4hinORhpilrR/DBXpnSTMmRyBIocaBK0T8shY4zNMYztQ0eiwkGZnxJSqi3Jk+oa7B871YIVDxzgD3AkOkTcRnFR+5SE+B+2G9qzhvRVj+LvjdEbkgnqMImZOPGsa9sSCfDrC928aSAokick4u8JqCfDnl9lYLlBYaVxGipiMayIg8TgXvUhiNWKrCoNyONHDtAKsmrTDj9DWEWtdX/h01uHrWBGq1/AVUpJ1w/5zHUYKF7kopTEskTYwQIDAQABAoIBAHhmiW817OahwWkFQF0btrOtA48U4nbYdCUFnhSfjEN724tQiIEbhsr34UIhLiSeroKiRkv0oaRxzw0/upRQQc8ZIFg6XVOizvsAXwvC8PtfI4sDMz3bU4z37/sPLJ4XR4bt1t+XcMh9FrqYjGyPu3mxv6LkRXr9Gkv/k3TLaCxd/88AlxLNquCYw5HKzZIN7XxzvYRHgn6YULSE48BewpqPPhSS5APItFyFoE9esafSBAcr54LSlwJ4X0Vee3QCxy1WZl17PzUE3M+lGvQ/gdsm+WrY5zUP0MTz4z95urknrPIP8WDXrfK+SzEXwrBvP1XVk1Sl/KKBJaAf+NMS7cECgYEAw/LEz+TuazDlsSAe1/fx9UNHQOAy5hrNIHd37uWaBUC3DszZEDqenJ6WZhtJD4DHfXwqtvXuj9Ju76YfGInFxxucg8AS4cD4+J+KfZ3p2JmYz9d+f/wPXtvG01HubV/KAPVdpDrN9QF/U+YC3W3QAw30V40X1nzgoZWMcPwjITkCgYEA9TYTh9U1oV23meaXUE8ux2ubufxy+Y/J4x57Zp77ttEU8xRTCKHAPdgm5PbMwhXTsUJEoFrH06iTkbwy9yIjJom4sl00E+p9//fEdCg8sEvpSJms6TwB6CkPsWgkwqNJDYwU5XLXd8EP16WZ83vyewZvCz5ssn7UXq0nKEtk28kCgYEAwHogSfafHDwT5EGhCpRL4JgNzfRtCwsYo+O2s7xl5vMC3k7qib6LP12obvQueEQPsXvemYpKpIwY3N9ZfEkZNdQxklmCMq/T4KUW7P3JTzLRoJgVcrKuhodsbvf0NQv66aYcLc51sU2fPVKbTdcolVeHxNibqd1Q6mh0ZCfIekECgYAsRxl7u5o1izCuD59fFw1BYUL7cIRqX/Z6lnR98VNOja6UviTIODz4beGIErCik0JojajKs9nFdHlBJZSmX3mtacz6GC5hMkSSRfEpcGKVCwAS5fz9GKLXgyKcTEvnAYkdcyAK1pPlwezUacjE2KrOYDkI9Lq3+ILsnaOmeQa7UQKBgGvHLrUvRsi04mB+TVQYwrlwRA0NNsxQTMek1UvFlpx/KN8oaDn7Aylao9zxutXP1jBH3kYmhn56/9lJpluDWJAKtBVXl9a4dh/ppC3WTAloU3+4u0aC0Mk49Hg9730S5LVozqH+q8VWiFh3qbxkrlE/4yocWvm18X5C6+kejKOh + peerId: 12D3KooWCVWC68UrG4yvhuMK3Jz29a5yXGNaMMtVpgabPzRE53Mk + peerKey: +cn5htkdQ4CzBA2z3uW3Cn7HiFVmPqDQL+w+fvDJ5NgnvhjlhFBJH2dm5XKcUZ3RSvb4NT1L9KebJm2Bz1kTqw== + signingKey: +cn5htkdQ4CzBA2z3uW3Cn7HiFVmPqDQL+w+fvDJ5NgnvhjlhFBJH2dm5XKcUZ3RSvb4NT1L9KebJm2Bz1kTqw== + encryptionKey: MIIEowIBAAKCAQEAuowvr/WyEhl7jXKo7flCjH5a21Uyd1V3GUY2M8EaZgl581jGM/FqGGQAyGDc/Go8ml5eTFPqagCkj37crLkQg4tlE3H0JK/Yqw4liBFU0uzXKBsHBtVgyjCgCgtPjzx3VvrfshDDm5YHqfqPsOiqfcbUvgbL24o1KY8SGzAVcTzZSSTr818UZaf5lNLRcQ6/v5dyaHWl+Dt9g2VNNuKAgr/BtvFRErQrOb8UWCGZlUgr8pkOB8E4hWLqqYPd8C50X+J7U5pClNeEodDEl5Y12w+xKLhLXyXuVAYXjmuvo0QhlaimhMh5cR0PJXonoh0JLCtbbFl9I9xqkqV/GFz+OwIDAQABAoIBAGXMKB26UsEDvON0RXEPS1yFeykjddWfAs38/YkCgFhcJXtA32/q9n123OJ70TvA8W8/ve+i/1F3JlXT4bIzjyppf++7iIIYn4DAyIRXCNXNPp/5F72H5TiQjlTM1U6RrYH+huGRulyF44rDW3QrkxXt0Zwc81PLOLWECFpjw9+1aAWW+oXsS9QHU7/Fk39LOMPu7JgMyjEjJ8zmoe5elnMaZNixldeoY97V4YRKJT7mM8DRv7nRmWsZiG+/J2ZF0+8dZhyfumOMXwWUbqkJKiW3YKknPdWIaXX5PnySP608AvZpt/COqqJjUVCFm2RXgf/kj/XJ0RJxpGwB7bprRXkCgYEA8niW97T/UekLeTXGM0TZbW+Tiqd3DiJWWnK+zXmJ2OqcYY93EVRMJNgeGoiiv0Vw/IfEb+tQy4cx5mph10NEM3N1Q2pQoDvAmHG+uuXc1B00nEuGjymWJktWa5GMnAGqchaEEyxE2JNiIfGBZ6pqqqRYNEISD9QaT+8PfLO/KBcCgYEAxPTL8Y9dF2q6nE8mBUCRfZU+qdmCOzkIvhOEiqCWhHbA18SIhp2giuZxyxoQtlsRkf5D38p/GwiFal8ExPIKXwKQjpcXO6HrTatCrSYycp8g/kh9Yi6EJGMA+MaHKE7U9iNkEQywloAodsrpKsEm1qZqQ7AuvT7nEfVlGy30zX0CgYAG38hX6Xe7mMHMg+vElFUdtyYVrj2/1tVf5xTlumZgEfaxBWI4yY0HFmF0Gx+SEKPtZOP60E8QFhsiDy4K7ktGsiVG7gKvKEKDj+X6Yn3qPZG6RKHh+SnamBQxJIU5/woYBe9ko8Kn6TXFBJXInJo9kD837A+bB0ZfscVcobPvrQKBgHF5EB8GF/4r0YPI3gDcqHYQDGBTHoL8YxsPp6cuyklbGdO2OWpFWn9sMVdwlvxZD5BrS7OduQlcKXGVeOv2/x6qHZrpVctXiHfhGbMkdKAxKhMWtJZicmN8Xsz1pF0Gvg9paHeiNgMfpzB5y0iEq9mzWznQQb1qhjqEhVHZclcJAoGBAJPUMuwLsWAkVPg0Nu/uNYnkoves5GQcosbsKs91pMhFpsfr1X7oQLQ4ahRzWd2mWIEOF9moHJn4T5a0ZxPadbLXxjIqTkVKBcuV+WpIH0RvnXxd16LZJc8rCz0up1zvOzz+b1pcsu/6/ehFCJ+AQyqlutPuBNNLPygRVRZLNDvi mongo: connect: mongodb://localhost:27017/?w=majority database: consensus @@ -17,3 +17,6 @@ log: production: false defaultLevel: "" namedLevels: {} +stream: + timeoutMilliseconds: 1000 + maxMsgSizeMb: 256 diff --git a/etc/configs/cons2.yml b/etc/configs/cons2.yml index 3135de05..5b707fc5 100755 --- a/etc/configs/cons2.yml +++ b/etc/configs/cons2.yml @@ -3,10 +3,10 @@ grpcServer: - 127.0.0.1:4531 tls: false account: - peerId: 12D3KooWA5veToUAwEVVXV6PoR4dFH91HQZA339NZzqeT3C6mMS7 - peerKey: gGwpn8J8b1WXK3Lhaq3NnQMix+qQsHNRxAH/DUalvM0D/G9dc/GRiAu+NDtGKRc9z2YAw6HKJ5GJAfzWTMDREA== - signingKey: gGwpn8J8b1WXK3Lhaq3NnQMix+qQsHNRxAH/DUalvM0D/G9dc/GRiAu+NDtGKRc9z2YAw6HKJ5GJAfzWTMDREA== - encryptionKey: MIIEowIBAAKCAQEAw4BsTVcK6Rnt3kYtvMZ7HU3EmD6uQzjn0bqoCsFKFNOMh0x+GE4aDox6j8rEzbeNWFwkn7RI6kPuByuSxe5RPG9QP3mxoIgWc737IKx6X0K9vBc8rLTgbr/OCctQs5zfsvEYZa4sKG+mfXPh5oxNsLfAO87OiPsTEPXLYTrEGZ4GZ71HLO7EBsI8N4JvNWZVQq3bbv+S7kiXtXpI1kdfE1Nu5XZIVw3dSEWoP3X9Tp9zavLM/obwoN8IXFGqAbEKOZE9zZkqvwIVymFxqEn7bcqtkfhbvvyTpg/VSeRAQhJkhmx92QDgz8mt7d2ADan3hgqFO68qHK+VlH7D0eaMOQIDAQABAoIBAQCOG42d8kV2B2kGhxC8BbJ8LIlY+UcGihjINNvtZW8KEHQ37PxDgpIiPS7h0syXlHLj5aahiBTwZIxjHeNEiOT3/xnf6f+Z5xIa89/VckpJcGQmkuWBzMDPABEuwWFaDg/1LJdFYgOrKO1mh5OPWDEo4YiUcNFkdMz5KRG7DVJ6I0NNm2x4sRJf8KVfLiOBDX9CKEUpmXZCciUlA3PnXAiJwpYxHoTSktqMrVj7YWgUuaYB0ZQdaXTG5jPZAL7zdVP3Ub1h5Oc9i56UgP0qAo6uXhQR+Xr7wKptnQk9g27zddx7ofa8NtnDpgzMOfXvJjWsMBB8ego0rQjydUihsvLhAoGBAMree7cd/NgqXgDc8V2zusb1gZ0Ao1uvCcYmp/w7v/tUF/UOuvjYuFkHosvHEOjy3gHNrnFYcj1US3K8OFIRkp7b8TKkEL/ho01SVI9PMfczEws5K6ufBZQ+33hJ7+drOlirRQxW8lIZspL3im/CLxm9K2zSfj/oMreO0ZY5jM4dAoGBAPaz/DJOLSKzeu9LBzFjfDMhYN5N3dLHIG0dPIDYDJYyquXYIARZrOD5wWh3WahX1YyCC5bBgugRi3SG0/IaKZQg2+/X70RdLXNK5sZHxR2ZildGFFaA9ERLYy9Gq75hAGTA0dt4CA4iM90jy0Prwoya32SF+zywoMcGV3LLX0vNAoGAPQya2k5R6pNFWqkikXomuPzklmS8xDh2joTPhJ5Odcmms/5M0doWD+S2XvB27EM5//zvg/iD2GTnl42AvWHAZ8H0YbLxv2ydggVGoSHJ/YQHNRdtRuZB/Yy2HzLQ2Slxk4Fm9AGuRnqpPIT1yg/7sJk22ja1+3Fa4dY+yCBleRkCgYAU9L8Eiu18mCBmOUpYIKpJMZmn6JdiMzYG7sfX7gJLs+wecBhwJinwRmbud8zu5t8l+1n+qVt0WSEuedGBLEXB5nSoUABsHzogJAmsaCZPWF6PAU3y9ytIrdq0Bl3KYzUEWfi5mt2cTb14GHVIxLsW9ITrZhIsWpidr2U4RBxJNQKBgFl5qZd8wFwm1kv8j1BtiGMN3e9cIJlfuIm97SOuaEFSwo/QWnhLQ5QBNwIijXDx+Rx3jPPedMO/fYd8IjFdG1x+1g4XVlnCV8PMCsGFwsu3/Q4Av9q2uflsZlAc+6vdjB9uEr4jhiKd+j7f5SWpPHKCUWyeem47WSjyq3dsM7HG + peerId: 12D3KooWB79zLr5KqDCe3uHkEEZ4EchbdRNMMeZFrcVXeRzpBa8d + peerKey: abZsspXm7Y0Ndl+oADxJskTS76KVvHQ5hBwZI0vOyAkTKMoaL+SMOISDiyPEFDoBQO9xwSXwTF2ES7dultLT/g== + signingKey: abZsspXm7Y0Ndl+oADxJskTS76KVvHQ5hBwZI0vOyAkTKMoaL+SMOISDiyPEFDoBQO9xwSXwTF2ES7dultLT/g== + encryptionKey: MIIEpAIBAAKCAQEA4we17FV9hPMq6jayCoLnWQri1tvZiCtroC5aRnzmosjxM3dBp7rjskQBSC8U89WWTRlQOMDxcCiq7meFiIoLO7nKL6YVw3w5w3hmc1s+/KIXkzMq25VC9OwrUBLR1rL7CR9slwYEYCizl+jS80q+unDqFeKPr9fqY8V6WSOrRRWqQtGLL/6Wq5KrgNc9rKwcIpvtb0w+UHewreVx2UBiasN/seydT0JEihIO0yyPxHtQ9ZtT/QV6IvRG4VE1UmxDAIIPc2gOJN9poiUCDlPDkogU2ZZ6XPUZ/nJwvp1Yh3hS5HjEb/5EiGSGgIQ1+tiKKREE/ZYtj8x8iJI+pnTT8QIDAQABAoIBADccdxAQzLCKav+CGYQttMVLvDcWFV9V0wGGXwm/ZilcCBlLONfjqURr97ezHi32yk6a93tfcvycEqpe3O6BPCradfdNJPlYXZlSz+Pu4YJoQrrL7/pv6FoWPolomCG7Pu8+/phGsKc7GiWlMhg3K8eMg3aekezIyDBCDuo2m2vgWkBzXrFm3s01doDlSkwMwvEx9UQpnekzUEC8qxjyfe9c5mEiN894/qsiiwCXIDwg0av/tu9Xrnz3LyejDoroSUnAKkSNJZJKXdUqxOGHlZSHqibS1H6WNouoQMdIyToQGYThBRBHpU7WynOXQF2jtaX4UUgAxMdUxEPCkmOjm/UCgYEA46Lc2CD/uI4hWT92PKHrZ54Js/V+YbLX7KziYPKQIkuvWIJjK4J6MaU+B7xc/3Thf3FWWv1+gTh3+9Li7swWNb8QEQhG6thz/AJgOSpeq3tvexIohjDhATsTAcnl/LEJ4jN93AJ+pOtqj+bCTFvBKn+w5dMlqaowD1T1G918Rf8CgYEA/1GECle4Xg6y1aMKq4KV2oK45q7X+28Vc6Rf1hfCFO8g7xLy4IfZPb5Ve1UEv76hqICYJpnBKXhB0I3z4Wf9g1nI0shnwve3AhNsw2oe+oMdUhVcbM249+Ppv8ZlUOG470BhCq6Hbzv5owPepxnR80IZw/xu3H7HBv7y6tj3Rg8CgYEA2ESK/OudCIJAPMKGWuSa+j6ziT3bbIa1ji5ShTjupyaw2K5H+bZk0XXkkQTsdeddte6/1IKyBaLYm2+oGqfbEgUMBqKOfeBXkT3QnX8bomALcim2Rod5vemaDUD8OC8a7MVu9e+I0ra27zCVuGYUB4R5VGBej+sY7fgRRwAOaZECgYAoRVI/U2C4LTdV7RaEwN8kDRRfBlr4xKesitO28B5jsOgP7XwzoBnK3FedUWajW80hx8633+6QvPAclhdOiVl6O1IqtQNwxCOwhyHTnMxwFPgt90KRws0XBHLdFczrOf8ydYQY7DheeiZA6R5YWwE7jkSEHi/aRYDdAJ+OHVS7TwKBgQCE6pWmO0g7PD2d4r9NPC6x6rp7KL6NjfYqia1VZJn2yJWikyMDQg0hNj1gTlC4dDpX6RhpFvNThHUPlnl2FHwpRkBe6/+Jv0sMdpB9Bj9nSKNrqOvWrfcIOqjU3D+W5nVM0/YWJAzb4xlC3h5IodEigOJaN+r9Eg8te34nb6lJsw== mongo: connect: mongodb://localhost:27017/?w=majority database: consensus @@ -17,3 +17,6 @@ log: production: false defaultLevel: "" namedLevels: {} +stream: + timeoutMilliseconds: 1000 + maxMsgSizeMb: 256 diff --git a/etc/configs/cons3.yml b/etc/configs/cons3.yml index 318499f5..5eeee947 100755 --- a/etc/configs/cons3.yml +++ b/etc/configs/cons3.yml @@ -3,10 +3,10 @@ grpcServer: - 127.0.0.1:4532 tls: false account: - peerId: 12D3KooWS9fMHSbogWfa2o2NLm2Y7o3SGXojn5anj5zPz1TeZDz7 - peerKey: UYx7nyuYqq2+j/t8kTZczAoXCNflp1FNW60tNUfkEtzyrHQg/MAHjYwYGhYxzQ00xsntqLsuA0FAuyR+YtVrsA== - signingKey: UYx7nyuYqq2+j/t8kTZczAoXCNflp1FNW60tNUfkEtzyrHQg/MAHjYwYGhYxzQ00xsntqLsuA0FAuyR+YtVrsA== - encryptionKey: MIIEpQIBAAKCAQEAvbd32m4jCtCVSPthnycxPmbKNnnLUn8tHNQZr5Sl2cH1MBaRBEo1DBhI9UXIqd0iprFCvTJjo6s6vWVdLAXgkGpKbuWvh1wdVuMOsq5kQ34m+XEWKXVpSkpNboUh8LdBTrk7NqvpMy9vC2aUt6bKY2zPDnRFQKFeRobfapwntWLoIhmAtBJJRbZuvc8OsFHUQRjcN4ZXLBziRcMqG0IBFPstpiXJNp4f7oB/bWGKg9yKM4vkgaIXEq5RXSvtPD+Zx1ovt4YF0vStWxxM9rEIAAK49HlCJ/aQ7+YYpFGjzjMQMVjLlH+8pcP0ZO75/DgJa1YZDiZ6ICPJ7YADTURKQwIDAQABAoIBAQCdAKRzZAoj/RJOX5sedvTNy4s1If4du5m97dmD8OSAHX+n2EUS48aax845DRNPX+45PSEaKgVDgYUPED/XGtYJLa2DsRleT+EH8shLHv9iy5e9ftT0YnJMRMln2U2JRF8Lo0dZq1NGRM8FBFO22JVNStLgB2D4Z5L5ksx6Edjaxh5wIWxs3ETihzNSZFWvh1bVXdUzC0VfxO6VuiiTN7IMAeL7DiM0/QVc8vk4BKG00XtV9KvtnGqnynpHYvWZ4xRU4GYYwDwLZFWDssLgU+3SNJCeucGrrckC1/73B5gjJ3Lq39dbr2maEdKvo6KdE8kOLQyZxTMHWdAVH6MKGmPhAoGBAOZGlR5V6P/cI8d594VHz8txEp72IsK3Y73acbdqkV4kmvQUq36oj3ObO6ZNhaH3/j+M9xw12eizh2KV512aDmywEHGXbs2FY9Flck6fMRAamOrEkGHUUDdACDyyCRtO3EQMMNndy00dPY/Q+nrwHKLfwYcfDcrJXsBVS6Zy+hFdAoGBANLo+sMU4grnp/XurIIB+3Zahzfoeo4xMiLNRDOy0nuwG23mgozZKaRnsiyxrtBQ3un3cjQS3+mggsa+N95mF6h+aNzM98ySqqByw7v7N8c7LQjon/BxonBXLi/bETLS5+cdRRXHD6QbvREtFVtD9oRZJAeLvS++BdtS1s8vOfAfAoGBANh7JHbnVusqXmyKKfsfXqcoPtQ4GsepNlhmQx+mTNEPYqjxwaOJ/Yo2NmaKXIW/KUM/V5QqwBf2puE0gdTKHqNpBZx0O5N0wjk5wLNPDwXPq1CRyBZgTaUTSmsdCFim04YZW9eFnjl5ssVANipbDuDDsCFCPWoV00DHLx5k2th1AoGBAJmwA+rb8MuZex8OyM4Du8XGufnXglbTKoGJqkUx7YcMETDIZCFWra2Lkp5W69gI1icPlTy09E0+FY3VVsjNBDhXxPoAsiF0TrmUZ2U37rFTQcHYIZQIeiH6pUFiFOpAHZSgE5OG9rLTM7asb3+Nyrkua77D6Rw9D+9+MeHPvBxpAoGAPD6fta40UAA/SB8lLmviQ4odWlbbN4AiUO/oIey6PswU2ZJllHEOY67snzhfafdT8y8pHCQQGDnPELfdB/2b/4x7Pi4+xQ6LepxMkIgBnW4zrbsokbvuZ64anCAvK8cfqqvcD4OFEdh/GlTQHGSzlQ/RGbOAuQ7GTAYlsQmb+So= + peerId: 12D3KooWHKcJRGnk5wHYo9Tgy5Dg48pX3D64mQU6yjkWcmzK1R7P + peerKey: VhENG7mg6uNVoor852BDJD68zZpY/2ROX27m6qSf585vf6GkpR/lCL77GSN70ifDEgstGF1f4c3AoVMNYDqOEg== + signingKey: VhENG7mg6uNVoor852BDJD68zZpY/2ROX27m6qSf585vf6GkpR/lCL77GSN70ifDEgstGF1f4c3AoVMNYDqOEg== + encryptionKey: MIIEowIBAAKCAQEAmHu87SqfW1dypmaBGqbwSraRI3DPV3cGObbbf953+AEtbTszx2c6tVJNX+3lpC1D9mZm9iY8MRZjoeUFdOjx0bzE7CIDKgtWixE4tJoEqzpr8UeYKsUYtJeWpANSJGeUUoeBcY1aQKkxJqGTXLxU3faOfxfUyKwlJ1If28pkSeaEPxWtdcgEx7ddKCic0Z7FkjVmqqpoSaSMf7rKByPJL3zHb21FohNQKAyVLoMno7IK6p8oW1TifOcS2f+Bt8nAxt27XJKbCwOoXazsJbm5HXjMNxg4l3riR8BhA38rTvhfb4gblIcF79Lx8W8wvjtoBcBrAcG+HWRc+wXCgim6PwIDAQABAoIBAByx5HrJM5Xv3e58ib0nPz8AHk4KE6rFBlHkHGhyyCbOqerNYlAbGAw5QcBUt4tuzURYPvYBegBO008LFzzJ/X/Xw0Mgn3HREmc3RXGPLmO+qcONEpCx6JVLlZil21Zoe5wQTga9cAeND2fSrjWcZ2gh1u0J4gwlgRRmOwKUkszpHwbjmgs2KwvrCFF145ol7N6z+xnXRKwykXqe5Z1pCfOyy+qY39JWT4DsepjAOpw+g3Z8JXgSp6tauGgcJbGh+lgFtr0g/f1WQw7VxZO+hdCPY1njaxp9i98uz3DJlUddKdoXQBOzr+gVB3wC7I7woNL6ELS36wwmX/wa7lk4TPkCgYEAyeNKiMIu053ON+EKq3deDuNV1p2ER13sfU+bvUPEq0bQCsLQFz6OAR0qOHabvTmYdnvJipE2/xP1/GXX5lbO2mvEgg7adDDWwhOjaT3voeQyj1ezP3r5nvfH6dC04RGegJflLHAzOfcfrjNASbCvJHlQEtOJeJbLhBedp/sIxysCgYEAwVqDqBQYQ1MXc0YIhRo0nJlPPbtGQBFeJTUjAnYOx0tG+MzQHGiVMQB25AfSwTDj4v/aaYnuu6jTHn2GiMOa2zA7xNu5ygTI8eP6GdI4ch5JH/kDhIT2iMWhMFytj3y2xpeuWOFzwBpkBa18YLbh2ebsGy3lP0bCcSy+dyTUTz0CgYAh7DMl75r2q9luwj2Mui3vynst6KHFbB7En4/HqY9uSCPE6x8UCMrLnR7vBd79WKQppHsk8WmQSsZWdrZkWcnAIcOPJvfF9j7ftXULxgBx72ofc9kGnZ87+t54hz0dZFyBtwQnB2NUJhYIq0vuFeYX9tphj3HV9WCU/XLcOu4qqQKBgEeDIbSVkg+8eKzi1x3bfl/49+zeCfKCOe7LA2LSpU6ikeJNZh9LsvpHsLFQD2vymCaJ+I8WO9zeaQ8a4BpPNkQhR8ncdo+4S1Xjusm4DbZvax5PLDTkNIaLib1oWaz7NGKpEQvAft4rJJlQ+/KNUWUVWngG9oX7tsjDAsLwNTIFAoGBAKBhYmGsNn/E6PQGW/I9u1QrAwtB+HyYG4i6aazyonlIfKRaBd4RMTN4twhSilTIZb/1DOyq/yWfANsci03gaH3sv14E4kb0hFyTlDmu+XYJGSh4AKZLVU2fLbZIkSDrWogL8+VZaQy8tdwQAJ3yUpHw5+Aqxv/HE1tinyI+FSqk mongo: connect: mongodb://localhost:27017/?w=majority database: consensus @@ -17,3 +17,6 @@ log: production: false defaultLevel: "" namedLevels: {} +stream: + timeoutMilliseconds: 1000 + maxMsgSizeMb: 256 diff --git a/etc/configs/node1.yml b/etc/configs/node1.yml index b74fd7b2..447d37ec 100755 --- a/etc/configs/node1.yml +++ b/etc/configs/node1.yml @@ -5,30 +5,30 @@ grpcServer: - 127.0.0.1:4430 tls: false account: - peerId: 12D3KooWPuwdqpDQxWhD2Vh4yskx2T5VMrwdpTZLfACzgsGfQfNy - peerKey: yOEpD2+cPldXc2urGuU+szunm7fddRa8xew2uVjaxifRcVzNKhSERpOefjrXaky7PcKmSmTsH/5ZFtcrh1uzqg== - signingKey: yOEpD2+cPldXc2urGuU+szunm7fddRa8xew2uVjaxifRcVzNKhSERpOefjrXaky7PcKmSmTsH/5ZFtcrh1uzqg== - encryptionKey: MIIEpAIBAAKCAQEAxnE9Htwto+2fVmonkG9/DxNre33n7kjfrZU73JcHmpKhPlRFirig5T8rs2MaTq1R72/8nGBJuSxsz1PnexI3die39pY1OFYfZCZ59LbT7uH/xHcvkVrK2n50Q41KbbGT9BEzyW+XPkKPDpTq3/igYP+yUQgoWLfMwxCCLKXDe6qUC0fuIxR80fvj3XvorB5dnAiQ01JkH4PtCV1OWT6ZpLGhzcYxsxTHozd6LdMOC7wgGhW26dOSa/vZ1t5avbewFVIz0qfqBncunb7tjO4xa3xVYaA5jBbixDQUYFjVzW7cksrrN4CFNBDBGJ8PLS80MuMg0OG0O+/Qi1mbGb2mUQIDAQABAoIBACODAD0VidVcILeGJ65hRYudHg7raSXrRJv7qMrA/EtdEh3lVsyMXb6on1lq0rphqdf/YmVZldfda1tu2G3dxK8QTIuENeHvB48Uk56HWUXWi77M1WZdqQ+QsZ2lGzymGqQCsBHMNnSd1Jv3alDKXWj+WRrHKvE1cx81RRZYU7M9cpurnF5YNjO7L+7sMxUA9uAQGbe3kDVzrygraicLYQpxSNHytName0A+k3ug0qer4I6PmZhhJykkz6MD3dz/n625HSS+X+TuTm52T2b87tL27xXmSnUK7eYWjZ1vQlP1fWmqnac6u5LApUZaRi0tTjtefSjRW4jr1q20RqOp1kECgYEA7Onh3zM9ejATsjW6WISGKiBPci0D7DUbIuGuJrdQRadlkZzmeQ/VOYAuxIQD4GnQDRhM1FyxsqiAWkJOyCLFiMmsgIEyW9/eRhF8NlCVU+DA/fxy9EagfBbVsgiSBwOex24hPXIVYlaHkLAloNoD4bpw0pQZSDWXr+xvMFNwoGsCgYEA1m3sWA/e8ZuXForaUOoJzBU9nwC79bXv2UNktsVvBlQ1o9pbjoYDcVoAPwuBVUL1UwqDNMzPdhDBKBjZmCyjS6zlYD5ZKjF2m8iTyc4QcaBCdM0iyQpSXTmrfMx+hK1aWwL1p8ssNcednp5ExSAaTyNNGVdbtddiQ6/KMPmhUzMCgYEAwDjLsUNr4BXeBTweo+9yw/9PNn5brm0wRU8C9BrMIJe/izPYs+UqxerBB2Vtl8mCqv1KaQuEika5TYJ7VVsRFvk641DwQScUu5k4RQGBB3tWWz1XL+eWEticLkVR5isDyyAKDEbiHtXCTJz/CtGZUK7rF5BeKv6AwpZ9aKJqwV0CgYEAqXDlQNURu+PR6TtBtoypvz3NmraO0GO7KvipPhAXYm3qkRa8IIxfbhPLfAYQZhpqFvuIoJFzIn2s1I2GbExhoSv3eSzrcn7xlbpSpjYSImeb/AYZhbmFSiuHCi/hjeAaNS7KhZPz1G9vaubvusFaaMyhYPP6AWA4QvpHEJpB06cCgYBqR6/7d2hQiq4MJUrBEzLwG4ijnPeq+UVLQjE598hVIj+8UhRZRRcNWVEJxfcIL1v6Bpo8XISDNVRb30T9bPGVnXvC1jutTUbXKUB1/8iXuyH3IVieobch+bGd4v7ehH/lI7vzB6hjJpFzHopfFUn4wacSQdcFi3tRAwUB/L0S/w== + peerId: 12D3KooWHtnADt84naf6NeejZ1MxYGZPLk5SPEu2DL4ZV948uWPS + peerKey: Fu/H792JFWVYQpOZeLBIr1Y5UuHdZzJxkGO7eakZDaZ3/vIDhjGgNab1+1NMdTJ0IUP6Tv3KQutcRwtX26/wmQ== + signingKey: Fu/H792JFWVYQpOZeLBIr1Y5UuHdZzJxkGO7eakZDaZ3/vIDhjGgNab1+1NMdTJ0IUP6Tv3KQutcRwtX26/wmQ== + encryptionKey: MIIEowIBAAKCAQEAs+N32tT2Q4Nv9MlyH0B34TJZYLh1+Y/4hc0vupiS/Ct0Mt+Rh62KkPy6Hz2JRDd7ryYpz/Un+qAFQBhfugKy6a5R0U/OnaK8/WwJjstTPd59c7iGnCeW9mWumexT2wiQVbWcSdcAE5SPYmBkIPnwzgxZgtNzvEnbdUDWIOsR3ifDAt3iUqqlo+cZWIZaXiTjyrMlaWY/BR/SGrklYzxcUzNj+K6DdY4yFN5/5ywKIe81llooULTyM5U+fWEW5uri4ERgT/YcRAoii2UJ5kHzpIZmGKcrJ4kUdyFLE7VxYIQMHHXRkDlpTEYlAAJGl5frcHvFufTWIJaohBXAxg5tyQIDAQABAoIBAD3TI9I19x1lAwliYrKS+aCQKV+whftrm8KArrK21W2NkbYaWG4FGuaRtXYfNBoZ54xe1Wf/nenpLWTF+8B2RP9DRiNmBmDvGX0PsIk/IDDXUs5+0OTCRoQQll2Yd4mD+/c5H6nRFtmj6VOqRT+AJ17pp6nq+o/v4lj+G5ncsJtlAtq1xb20yHQYEl6sbK2UqYuiFtXpKMCK/8V3hDj+ROM8UMkxMj+qj9NFd2sCk4FEZ+S2QmHIjY55s4Rpe1RzZZZEYOuJ99Fism+HYXtf3JlFORaNIdhdWY1UkVAFuKY/ULoHOhf/RdJ8ZArak3CplpEdPTYC4IRBI1eZDDF2GgECgYEAw0jvV7E1kqfGD5Q1WTFsss4xHQntPtWRfyAI1viy16sqMX6wQ4ZixWXsOeMB1o5azqqjYo0BBiGw6ie1GKl0iZ09FxHmMDqFLf8a0JZXAlTvC/wEHgAXCzg7tpHRJD1B6gAiU6u6ALW14DtWe6tikFehrY0mwGb9koedQNgoGnkCgYEA69EcUTejGm5Hm6ANC5u5Vn1aaB4BrTJ36FGTaxjnSUPePBj0Eo2Bt+c25DiD3uGj2Jws5QrRhpu+NYhOTC+/P1/rm82w9Tpc8z/wA7nUk0gGEncgtJ8RFokom4B+Ui83JJiH0V7puZUhCc/TOmfa5N0SH5gM4q4rBoVDZtnTGdECgYEAlnssW9GlK6Z2++hEF7/7N+mldPACTkn6PRCtXyHzhjdSYyNxpgb3M49vsceY0gGOPfTFxBpNsLDjh/wjE6b4s1ZkDdPwIjfmCmSrABLpZ1WVgxGnBoshNrcVZIEGvTsrAKsryHfq88MSLIDtCo0tfXbZkkfTla2HNpOj/KTUelkCgYBl0pMRlp58qSWOUxuO6ZyrddD1qA89Q892ptKqqcQkZIOvG284G5XpXJLdFHIMaQ2gWD8iXvt9zf3hi4uTZgKEUNyhF73TBXJhLjhqw3DAb5b/niSnGQ/91ReNnXvt7Kk4ygvLIdp14ai0XeJtE672p2ZN8g+OSXoWhLBH1sJKIQKBgA7NH/Y4RbVHIMWY7jH/1d4ODZ4Hr1RK2Q99HJCAurfD5tjhpcMApoQQJKJDpv7J5Ipx6ynQJD7CFfx27+vqBEG4ffAUm66lKM5xrKcOevcyWemppurCLuza64GgWDP6jBRnHeqrUyZUqoI/I0FNwjxIJbu08NpRSt8khq59+iyF apiServer: listenAddrs: - 127.0.0.1:8080 tls: false nodes: - - peerId: 12D3KooWPuwdqpDQxWhD2Vh4yskx2T5VMrwdpTZLfACzgsGfQfNy + - peerId: 12D3KooWHtnADt84naf6NeejZ1MxYGZPLk5SPEu2DL4ZV948uWPS address: 127.0.0.1:4430 - signingKey: yOEpD2+cPldXc2urGuU+szunm7fddRa8xew2uVjaxifRcVzNKhSERpOefjrXaky7PcKmSmTsH/5ZFtcrh1uzqg== - encryptionKey: MIIEpAIBAAKCAQEAxnE9Htwto+2fVmonkG9/DxNre33n7kjfrZU73JcHmpKhPlRFirig5T8rs2MaTq1R72/8nGBJuSxsz1PnexI3die39pY1OFYfZCZ59LbT7uH/xHcvkVrK2n50Q41KbbGT9BEzyW+XPkKPDpTq3/igYP+yUQgoWLfMwxCCLKXDe6qUC0fuIxR80fvj3XvorB5dnAiQ01JkH4PtCV1OWT6ZpLGhzcYxsxTHozd6LdMOC7wgGhW26dOSa/vZ1t5avbewFVIz0qfqBncunb7tjO4xa3xVYaA5jBbixDQUYFjVzW7cksrrN4CFNBDBGJ8PLS80MuMg0OG0O+/Qi1mbGb2mUQIDAQABAoIBACODAD0VidVcILeGJ65hRYudHg7raSXrRJv7qMrA/EtdEh3lVsyMXb6on1lq0rphqdf/YmVZldfda1tu2G3dxK8QTIuENeHvB48Uk56HWUXWi77M1WZdqQ+QsZ2lGzymGqQCsBHMNnSd1Jv3alDKXWj+WRrHKvE1cx81RRZYU7M9cpurnF5YNjO7L+7sMxUA9uAQGbe3kDVzrygraicLYQpxSNHytName0A+k3ug0qer4I6PmZhhJykkz6MD3dz/n625HSS+X+TuTm52T2b87tL27xXmSnUK7eYWjZ1vQlP1fWmqnac6u5LApUZaRi0tTjtefSjRW4jr1q20RqOp1kECgYEA7Onh3zM9ejATsjW6WISGKiBPci0D7DUbIuGuJrdQRadlkZzmeQ/VOYAuxIQD4GnQDRhM1FyxsqiAWkJOyCLFiMmsgIEyW9/eRhF8NlCVU+DA/fxy9EagfBbVsgiSBwOex24hPXIVYlaHkLAloNoD4bpw0pQZSDWXr+xvMFNwoGsCgYEA1m3sWA/e8ZuXForaUOoJzBU9nwC79bXv2UNktsVvBlQ1o9pbjoYDcVoAPwuBVUL1UwqDNMzPdhDBKBjZmCyjS6zlYD5ZKjF2m8iTyc4QcaBCdM0iyQpSXTmrfMx+hK1aWwL1p8ssNcednp5ExSAaTyNNGVdbtddiQ6/KMPmhUzMCgYEAwDjLsUNr4BXeBTweo+9yw/9PNn5brm0wRU8C9BrMIJe/izPYs+UqxerBB2Vtl8mCqv1KaQuEika5TYJ7VVsRFvk641DwQScUu5k4RQGBB3tWWz1XL+eWEticLkVR5isDyyAKDEbiHtXCTJz/CtGZUK7rF5BeKv6AwpZ9aKJqwV0CgYEAqXDlQNURu+PR6TtBtoypvz3NmraO0GO7KvipPhAXYm3qkRa8IIxfbhPLfAYQZhpqFvuIoJFzIn2s1I2GbExhoSv3eSzrcn7xlbpSpjYSImeb/AYZhbmFSiuHCi/hjeAaNS7KhZPz1G9vaubvusFaaMyhYPP6AWA4QvpHEJpB06cCgYBqR6/7d2hQiq4MJUrBEzLwG4ijnPeq+UVLQjE598hVIj+8UhRZRRcNWVEJxfcIL1v6Bpo8XISDNVRb30T9bPGVnXvC1jutTUbXKUB1/8iXuyH3IVieobch+bGd4v7ehH/lI7vzB6hjJpFzHopfFUn4wacSQdcFi3tRAwUB/L0S/w== - - peerId: 12D3KooWBgHmDqtXH9SrZfAmwCFsD8LZhTD5dg5wkhdbqFoS8GBN + signingKey: Fu/H792JFWVYQpOZeLBIr1Y5UuHdZzJxkGO7eakZDaZ3/vIDhjGgNab1+1NMdTJ0IUP6Tv3KQutcRwtX26/wmQ== + encryptionKey: MIIEowIBAAKCAQEAs+N32tT2Q4Nv9MlyH0B34TJZYLh1+Y/4hc0vupiS/Ct0Mt+Rh62KkPy6Hz2JRDd7ryYpz/Un+qAFQBhfugKy6a5R0U/OnaK8/WwJjstTPd59c7iGnCeW9mWumexT2wiQVbWcSdcAE5SPYmBkIPnwzgxZgtNzvEnbdUDWIOsR3ifDAt3iUqqlo+cZWIZaXiTjyrMlaWY/BR/SGrklYzxcUzNj+K6DdY4yFN5/5ywKIe81llooULTyM5U+fWEW5uri4ERgT/YcRAoii2UJ5kHzpIZmGKcrJ4kUdyFLE7VxYIQMHHXRkDlpTEYlAAJGl5frcHvFufTWIJaohBXAxg5tyQIDAQABAoIBAD3TI9I19x1lAwliYrKS+aCQKV+whftrm8KArrK21W2NkbYaWG4FGuaRtXYfNBoZ54xe1Wf/nenpLWTF+8B2RP9DRiNmBmDvGX0PsIk/IDDXUs5+0OTCRoQQll2Yd4mD+/c5H6nRFtmj6VOqRT+AJ17pp6nq+o/v4lj+G5ncsJtlAtq1xb20yHQYEl6sbK2UqYuiFtXpKMCK/8V3hDj+ROM8UMkxMj+qj9NFd2sCk4FEZ+S2QmHIjY55s4Rpe1RzZZZEYOuJ99Fism+HYXtf3JlFORaNIdhdWY1UkVAFuKY/ULoHOhf/RdJ8ZArak3CplpEdPTYC4IRBI1eZDDF2GgECgYEAw0jvV7E1kqfGD5Q1WTFsss4xHQntPtWRfyAI1viy16sqMX6wQ4ZixWXsOeMB1o5azqqjYo0BBiGw6ie1GKl0iZ09FxHmMDqFLf8a0JZXAlTvC/wEHgAXCzg7tpHRJD1B6gAiU6u6ALW14DtWe6tikFehrY0mwGb9koedQNgoGnkCgYEA69EcUTejGm5Hm6ANC5u5Vn1aaB4BrTJ36FGTaxjnSUPePBj0Eo2Bt+c25DiD3uGj2Jws5QrRhpu+NYhOTC+/P1/rm82w9Tpc8z/wA7nUk0gGEncgtJ8RFokom4B+Ui83JJiH0V7puZUhCc/TOmfa5N0SH5gM4q4rBoVDZtnTGdECgYEAlnssW9GlK6Z2++hEF7/7N+mldPACTkn6PRCtXyHzhjdSYyNxpgb3M49vsceY0gGOPfTFxBpNsLDjh/wjE6b4s1ZkDdPwIjfmCmSrABLpZ1WVgxGnBoshNrcVZIEGvTsrAKsryHfq88MSLIDtCo0tfXbZkkfTla2HNpOj/KTUelkCgYBl0pMRlp58qSWOUxuO6ZyrddD1qA89Q892ptKqqcQkZIOvG284G5XpXJLdFHIMaQ2gWD8iXvt9zf3hi4uTZgKEUNyhF73TBXJhLjhqw3DAb5b/niSnGQ/91ReNnXvt7Kk4ygvLIdp14ai0XeJtE672p2ZN8g+OSXoWhLBH1sJKIQKBgA7NH/Y4RbVHIMWY7jH/1d4ODZ4Hr1RK2Q99HJCAurfD5tjhpcMApoQQJKJDpv7J5Ipx6ynQJD7CFfx27+vqBEG4ffAUm66lKM5xrKcOevcyWemppurCLuza64GgWDP6jBRnHeqrUyZUqoI/I0FNwjxIJbu08NpRSt8khq59+iyF + - peerId: 12D3KooWG1r2SVzTMGDhkiw9McbZq98H9C1Ggzp7FSfWDGbVSCbZ address: 127.0.0.1:4431 - signingKey: l6LFiKqr4ZHgcPbL+DR7KwMbzImufQPFgpoHOJ/nvfUbpb76DCADHuT1I4gIs+XByglnY1KV8jbMfW64XRW5XQ== - encryptionKey: MIIEowIBAAKCAQEA4ltcn1AH048bMXcKOOW7/E0TZYPxL3OtcHXWHSAZjeeTA/rc45G2eaNgyY7Ji+feLtZERbXNWGFBdNp31NHDYZAYwbZmjEqTEgV4yVx7BQP3VBEzglTJaNLTf+XIJnVAEkoHS6ogjC0oXTM6paHu64EitoOCzF9zqL023swjE3HU0dm2xwsUdGnKeO5nPMso/6e3VMavkKnFmvB965ECCBujtediP4lVdIABNVtoMHCoeI5Sn+m7TKqJSyDOIEMhHT3orYUNZWVeAHE1YTM2cI5tSnDZP80CHZ674Z/bKL7Jaznmq87mVt1h9Use2EkxR07/dJuTGvFOos4jHoiR9QIDAQABAoIBAHAr8EluooI/j61CnYk2p6LPG0aaTQJD4/YwHuwOBTviP2OghKgthGzg/szDerNfMyaoveqBvoIGqCZdQTbwwE7v1qTgXA83wYwTtBitQLVqkr1RTOJQXAMbPv5Jg5czUY3+q4DejQSKOE9/XJfKGJkSRH6Hy2C2CJ3dLnzYUqWGO3t70RLT1/sC6p6w3lXdy3dKZGkoR2wva+HXQxVrP8X5HOResXgNZwgMHt9KF1QHVCcySKYiEAefEKTSdKD2fOd4FxLgp3zWpvH3jrX0zd/DqzTlFD5Ns6Ayp2sIfHVp3sn99DZZM6DauMepQKtoSCnXZ+qKhekAwNVJnsVQkSECgYEA4spY9araeFUSl4uXCUQOpCkSshYOPRYN6sBbHsx8tV2eQtCT+5SuNYmzur3c5bkiraGEab8rZfGdDL6fLxQyaqbOmN31Db5kNh/2X+sRnxkak8lsROUWQZRF9doH73FDv6ZlI3V/JicZlOUCfN5BYT+x74R4/c1YXfyuD1J9gr0CgYEA/4K4SDwZUY4bOVCmKQz0OM+RW4PAAH6LHKenTAZNTeDNFFxc2nqnzRGMEKZTDGy0kbT5mBhBHFgShXcAiKxc5/MGkpt8Jcq6Fr5KGU9aZtYKji6mwMTsUndPNQydh3vOt5pOmcuMM6ovanNTvI8k6Qo53OY1IpO5CfOROu0hm5kCgYBnWsYd92YnDsYxUEldzKlLgPhnNov4pNNk15LvP0vaL7cPRhUaw1B9T6scAKjp/GxkasZ4lsnFZM4o37qV7wNm/WwL2KN0Rv9Od1SFtBBMzFkDXvk7kJeK/XLAr0OMiLbSYZeYCFUQ4yLSa2et1nA/TJLf0CR/rhSGiMAedX6DlQKBgAx1137OT33GrFUzNacy1oYeuTv5RNfBVA9lrabrd8GggN/JUU3mRWCexnHZaptkgbnJVZKxPBuhv+V6VDBWF4HIPD3SD0/YfxK03PA3CnWRYppkdAValRvAbcBsiRIeW4pgoAyn/IJYfk92qFK9uFMVCJVZNKYnBhMSKbbx8X2hAoGBAKwvzyAImbNB+493q1R/lSayxzG76bRJ/EseiTqwIec9c4C+Bd/sVXR+Re+xZb0FI/va1bz5CrduTzLSKBmf/+0lzl0MJvWY2+SXfGYdbl4+TTyqgDDfwqW0Tj8pDimye2BneyTmXko1rF+2Sxen7kMXnJLwpqjwZ6TZJuoqeK8q - - peerId: 12D3KooWASsipDzkridiMBmE7VSqp8yZvGWPY1VqySgMSZk6tsiL + signingKey: CZTN+NFi4g9MA4BKl3OiCKuzXh63ukIvYWo9D5t9qfZcFwIeOW8eP9W8mtnXaY3JAFyb6GliBW0uCaw4wjRcCA== + encryptionKey: MIIEpAIBAAKCAQEAo9Nuypzg9kZ+LP+8jQgSTaoRUu8VFdJdCOEjuroPQK+2NwBD/Z9BqKiN0Z+jmhkI9yA0/Fwdh21ibAKX3Je9uffAKOhXI2sxIAlccDORu1kGDnhcc7N3L644DK+uFZvKnMQWiCwmtTnNHkoCzWcIE44G56wMa2c4W7mrOuRWqG6a5Z9JUuLqafOIlf6Dw2fiVM6xXiTIMQ0OyXByxFNjsS5O/PYcwoIKMV8MY+gUnAmyPLE0bslvz/8W+3E7d/LDO4lhqW+N1kDmboe6sc7DBf5JD4DLnP2VWV8Ae/rfJvxwu9ZqVT8RdYKMsZqvs9sV+6jQC9UcX+K8Q4Wdo0eMHwIDAQABAoIBAACR57zEtvOkYyP878b91DJ4+P503nno9XHmdp1bsFnlQpkGYzYqq6vOik/EYmlS1PknH4gROfkSpFkD2UtnK73N4tlBlawF33HhFnU9eLBSKvc56/hrE2sTDBbfNZfVpurMs9ddb/UJcnE8iK32QczvnY6IxrJI9aU8DCB0UujbGDnya/HbFU9pLLxu2EUoHNxjSHG/jCx+AR7JRknRA65KPZG7mu5jeAaaklYTY/aLGlctgecDKfNKDsZo6rgAMUW6ZXI8ogNGqfKHUFazCVe0l1tp4hxvgmyjcw79iKvFr4mlpHtgjYTFCeoMJKvOXUImZUJL0vCA6WKvUdIfzAECgYEA0lCTXYwOHqOwYMb1qi8lIIApcI//B/Nzn++MDQ4ZO4SzVJTTv4rSdXAuoihsO6E7LYZK+wdVNjiCbeMukfTqEfaxWXIsIDaHSR3440NsYSwdBz04UhRgpxFE2FwPK7J5dQ57FBaCAgksnO3XjcByBMYgMWVbA+ezIWfVdN96YoECgYEAx2mm/W4ZGdDyJgDonzEGGxfaNqo6DIv+67fDwI6WyqOWFWJTBaVFkm1uPJfcXYuTI9YCNFRKuRU7dyqSPLErMVusC/8Iww8++kqmkc1m04tbkqh4KpREYuMw8/tTYSWDwgpY8ksM5YRpYRJLTuuC0cEmefGco1RsXG8bYYeZXp8CgYBq5fexYcG/gxXgauBtSx9E4L+vbhGD2hNYJKr768GZhf6crDTgs8/7TzT0yTUSLgZlQlAUPgrqz1hEQGfoWiMrVEeanjSdfvnOiUR7R0bsMT7j8hMRbTgfUuC6VDiFzmZ7wAuBD1uvazhY329jpoCNuqKcWNclKfzbqupNSFXtgQKBgQCTlR7Qm0YadChydeOzxX2GWa3XHT7fAFFHNPa8MQtqp40xAFb/a6TEzRZz49RkqyLXt9Bj2CqBNjSPakNWhay41+bJ7hMXAdaTOOJ0L/c1AwNf1C0zHg5KvWgCefPohvIvjqbrkx3VU50GCZsQqn5kLLYENAvAWX/lHRm/obKhcwKBgQC/iAOC8ZdZC5w4F0Mf7roZWa9P/42JWlCMzm/I/5mEIn4mYY6+1C5V+fXoET6845oAh+P8CkH4waJtqqN6BKQhj7SKqoCHgGBCQy+HrSCBtzk7NuXdpz6sk14zfcVpjR3y3l9TuXc4cVQMSLAqg8yUQf+qnEQTit4jyfikV/5XEw== + - peerId: 12D3KooWDXDcBYxtZ8KNRoJebNgNAv9nFbQatQMoWm1BLwmQh6u7 address: 127.0.0.1:4432 - signingKey: /6+uYFwFf9nU6fvXQVtpHhjd8+v4dXc7esZzqkhjyfMJWlMiZOtQeb913FXofD5f20WksU0l6i22B09sFFYwDQ== - encryptionKey: MIIEogIBAAKCAQEAwCy84lzkxtzgn4ixGm0LSUTujOBpOh9m7XDoDPZnMTmExdOe9a5v/LXzdlCOCuBvK5u1T3ALBJMA3Zgvjv/jPRQUdiHprP3sbdfc6IgZPBFdLKFTc9yAA7GMbI4y7LhGMLGOMOqQXs+DOeImfmxEs3ykLXHKNas5ORnZPVnB6E9Qod8KH7UyMmBjQkOZYOOw10X4JZiU6xJp/E+VVWcmeXgNBbj5xOWMSzM+hhoA4wNOzBxACucaKDmqD6qugzebOqyUVSzFnEbquro+MYTWYdUDjZTXdvxgUUo80MGQ164gZhkFUKrmSpUvu3YErFySEGqAdFNwOZ6y/4X3s0BHvQIDAQABAoIBAAZiNhAK5+qXMbr67m8jSimv6YCyf6xXmLKwenTbxofDEl8D7ZbZqYyqeqDmgiFoXSkErhwqa6NGQtQZlxLX+zNvNFLMQ5fkg3MOpZ7vzm7JYN/3p+8EVxhIUJLWkmh8opBBhaioUg1kNUa59W9jp1CTBl0gF4h63JbB/g5kqeVOllUw7J1igAoaX36nOJGOwIynCWdizhDhgyjR4OcYfOLwcPDJueKTc5vM10g3LuMSK/sJmaD3TkJFPtDHw+RMW6wqyjsnkrg2D2oohXEyGWYYIXo2so4HCez0AB1I1JAxtVnRPvSIp7xLMm7+AkDoq12QYDHfxZtDTpfmvJg+Sn0CgYEAxCd+oribtdQW+JUctjsDbSQX5CeRISH5Ith3jveBx2jKIqQVnoVPz6URHOvnlIsqYYLANB8B3JHMWfR2UmkK11x0OcZecB06+oBoCZukvSXF+GqVHzLAQUxaoEBDCCPneskj5w+riMWBiiGDp32rUnkqv0nh7dnH+GfORcJ44L8CgYEA+s5s5EALj1jyU9w4+HVUyVsIrUitFnQg6qw/Td3Kj+8CXImKlS+rlmbQv0m1aOcvtFjQRIjjzZJAf/ausfAME+MayoNODgZsDk5RyDKuSWzMLvZLAa1LD52Uli5Pg8KtpzKVTn4xE1MbjsQcUNhFRAgrNEKNyuzXzdp4uXgGOoMCgYASXwiTQOsEepq0KXMI9jn57Nl3+uSyz7W/t7pq329+N6hG2ktUD3RMJE+X/9gup2IOw+owd377I4SaIDU8vq3PQc944cVShspRT9lunO8u7+y8uW7B/0TWWMpcG+irSIGTlGcSavtL0gOx5jWoaDK1hLemNss8NZtu/nnpOq+LjQKBgDisVozJMBOHPNLYS4NROAR77p0BdCNDwIBmxbM5r+EQWA9DAS6u4+4Lc5YV+MkonG37N6yU5iz4pFyGCHmqzX/c7JvgSc3/g4FED1TWpu1uiUD/ZHmPiAuSRxYchtk2L3k9g+GFwF8mg26iP+fAxv4VfnXDqDi3hhg9CtSWG4ozAoGAOWZXlFKqzGAfcucIe54FVQnweXG9sEuIPAvWvVRs4406ggNmL5eHccXpPHWTgetsr2TYMqPTDVMRmhBzSkyrYgk+b2tme79HPzTWs2Yg/pzjOfTgw7MBX/KlvOW5/J+dvrF3Gx8AHHZ9QQdYqi/MS1NKb2K3IbD0/m5gL5Pwi6A= + signingKey: c3D+0+BCl1xU35KBY+U3GPcU9aXdoLUiD4DJ2jF+IqI3CjGLhet3MBOkPXdIuPq/UpEqlp1k6FjNaU6DEU6Csg== + encryptionKey: MIIEpAIBAAKCAQEAuB7HsXuYmoif6/U4JnjC6L0QMu9qW1aPAxDrxWIedTzQhFZp3F3gYW/Zgdd2hvd0c2xyfhwf9C0X/UzfxWr54dDXzWNLN8BdVTik48cdYlgOmbgejiIjTaqSAlv4RtlqvooxCN0MwR2/RVAG/N5GqcAM7E4kJWPtvQYNl6wWCc92rKdutvmcj73wKzz9Hd/qdF612OVS3zRsjh3tJmYt55oovAUh1TAz/mSTTXjFHy35zLRBP+oQQsAOt2p0BOMSyOKZufGC8l3aZD//dp4/U/MaqCjeNuWxCfAZlSd+vt7T0aqDGdyRtrrGUcu4PCwXpOdbzw+uSZxnKawolYoEHwIDAQABAoIBAQCsxeVpvKtUx8QZrUCFiWiM8W0T/un0z+LfY696xzoBlZGtvVEVQtpdVJHsb31/5RFXhnphsI6jmPUb8llBbcMSjeETkItyw4ZRhBfmzl/aevsocEfr5EjwhpEAucDe6wJpzk95G8TuKrXjmtcTzpjMjbUSwbjVhVH/wIBcxVTg2j6z4AOADDRI5UsvZ0NV//If+nNzMjcuIji95PNk7lAuwsqkX3FycxvqXKUMGxRE2bgGMxaBRAP0kqL2vdxyS1M7wp/x04ZAtSnPXHe4qqmDOt69ec3XqbmZHOsZHzkCFePKcPB472/G0bPJeiq/idevEqS89RwvbphDtq3KGrRBAoGBAOrHqlPh36WZBOi6SueUmcrg579KDMUekgeea5payiySbRWztCL2yCYbSgFqSbyCLRppyXK51xvo8iUejR231or6u/nd7T0CON0Nf/8Qtbb13vtTGpIBiWYGqeDrWucUUlyS+K3sDfNk1AJqjUdaIMVu4yTpgzEvrdYCcT312RBPAoGBAMjC83/0EKnsbypFprxKS3Fbg963HhyKjfffQ2w4yncM6kxXF3ehVjg1LInok/6/dmy2LxkAf3r0YYZrGJWmG4Sv4UqHn6JxAjQgarPbdmGhJ8VIUMvMbZRsX3i8Z8D2o8k1M1kr6MYsQ53iX6q/Cp3gnucMeJPk6Xs9Q4TO7YsxAoGAWrXEOF6X01p4zBZWJH2Eoh8dSwooPuzdzPXHaz7SyD/Wx8DDw5KHqDl48W0Iij3dgUwIGjx1QQJStEbGjQnfaZkQkazOIXk/USELKBhjrQn4GjB0np7bYEEI1673UzrFy6C5VjFS/owhYcGbTksjSETcnAFgv9tFFd+hsyfOsv8CgYALk4o875LiaXrDgj6qDtKo17ET75Ux6h9jkqEtpVyvXrRH8KGuyUPSe+Z0kU+vWdT3Uc4HcArpyRuyh4xkXK6riQTBqm5fDIsm/FOKyXXbDVLgwlm+Vqxe6Zzbtml5K/+nw4SReMG0Y6sGeJ4xl1CCaAhhpEtzo7h+3bp99vylkQKBgQDDdR6N4wb3DHTzrW0EFb8XhXZN7CIE3EWhToNDsCkguUB7lwqD4p2c4yLscS0YAqxk7I3NW0nDaUV/340RrVtPJDqB4NZJ+MvhfvV3TW2FkZmru/iW+DMUsfZGAOPdQz9jLGAzUXrXFw/qGBtLIUL6UWqWLOrBO9QHb21nnB1Ssg== space: gcTTL: 60 - syncPeriod: 11 + syncPeriod: 600 storage: path: db metric: @@ -37,3 +37,6 @@ log: production: false defaultLevel: "" namedLevels: {} +stream: + timeoutMilliseconds: 1000 + maxMsgSizeMb: 256 diff --git a/etc/configs/node2.yml b/etc/configs/node2.yml index e2a8ecaa..748587c4 100755 --- a/etc/configs/node2.yml +++ b/etc/configs/node2.yml @@ -5,30 +5,30 @@ grpcServer: - 127.0.0.1:4431 tls: false account: - peerId: 12D3KooWBgHmDqtXH9SrZfAmwCFsD8LZhTD5dg5wkhdbqFoS8GBN - peerKey: l6LFiKqr4ZHgcPbL+DR7KwMbzImufQPFgpoHOJ/nvfUbpb76DCADHuT1I4gIs+XByglnY1KV8jbMfW64XRW5XQ== - signingKey: l6LFiKqr4ZHgcPbL+DR7KwMbzImufQPFgpoHOJ/nvfUbpb76DCADHuT1I4gIs+XByglnY1KV8jbMfW64XRW5XQ== - encryptionKey: MIIEowIBAAKCAQEA4ltcn1AH048bMXcKOOW7/E0TZYPxL3OtcHXWHSAZjeeTA/rc45G2eaNgyY7Ji+feLtZERbXNWGFBdNp31NHDYZAYwbZmjEqTEgV4yVx7BQP3VBEzglTJaNLTf+XIJnVAEkoHS6ogjC0oXTM6paHu64EitoOCzF9zqL023swjE3HU0dm2xwsUdGnKeO5nPMso/6e3VMavkKnFmvB965ECCBujtediP4lVdIABNVtoMHCoeI5Sn+m7TKqJSyDOIEMhHT3orYUNZWVeAHE1YTM2cI5tSnDZP80CHZ674Z/bKL7Jaznmq87mVt1h9Use2EkxR07/dJuTGvFOos4jHoiR9QIDAQABAoIBAHAr8EluooI/j61CnYk2p6LPG0aaTQJD4/YwHuwOBTviP2OghKgthGzg/szDerNfMyaoveqBvoIGqCZdQTbwwE7v1qTgXA83wYwTtBitQLVqkr1RTOJQXAMbPv5Jg5czUY3+q4DejQSKOE9/XJfKGJkSRH6Hy2C2CJ3dLnzYUqWGO3t70RLT1/sC6p6w3lXdy3dKZGkoR2wva+HXQxVrP8X5HOResXgNZwgMHt9KF1QHVCcySKYiEAefEKTSdKD2fOd4FxLgp3zWpvH3jrX0zd/DqzTlFD5Ns6Ayp2sIfHVp3sn99DZZM6DauMepQKtoSCnXZ+qKhekAwNVJnsVQkSECgYEA4spY9araeFUSl4uXCUQOpCkSshYOPRYN6sBbHsx8tV2eQtCT+5SuNYmzur3c5bkiraGEab8rZfGdDL6fLxQyaqbOmN31Db5kNh/2X+sRnxkak8lsROUWQZRF9doH73FDv6ZlI3V/JicZlOUCfN5BYT+x74R4/c1YXfyuD1J9gr0CgYEA/4K4SDwZUY4bOVCmKQz0OM+RW4PAAH6LHKenTAZNTeDNFFxc2nqnzRGMEKZTDGy0kbT5mBhBHFgShXcAiKxc5/MGkpt8Jcq6Fr5KGU9aZtYKji6mwMTsUndPNQydh3vOt5pOmcuMM6ovanNTvI8k6Qo53OY1IpO5CfOROu0hm5kCgYBnWsYd92YnDsYxUEldzKlLgPhnNov4pNNk15LvP0vaL7cPRhUaw1B9T6scAKjp/GxkasZ4lsnFZM4o37qV7wNm/WwL2KN0Rv9Od1SFtBBMzFkDXvk7kJeK/XLAr0OMiLbSYZeYCFUQ4yLSa2et1nA/TJLf0CR/rhSGiMAedX6DlQKBgAx1137OT33GrFUzNacy1oYeuTv5RNfBVA9lrabrd8GggN/JUU3mRWCexnHZaptkgbnJVZKxPBuhv+V6VDBWF4HIPD3SD0/YfxK03PA3CnWRYppkdAValRvAbcBsiRIeW4pgoAyn/IJYfk92qFK9uFMVCJVZNKYnBhMSKbbx8X2hAoGBAKwvzyAImbNB+493q1R/lSayxzG76bRJ/EseiTqwIec9c4C+Bd/sVXR+Re+xZb0FI/va1bz5CrduTzLSKBmf/+0lzl0MJvWY2+SXfGYdbl4+TTyqgDDfwqW0Tj8pDimye2BneyTmXko1rF+2Sxen7kMXnJLwpqjwZ6TZJuoqeK8q + peerId: 12D3KooWG1r2SVzTMGDhkiw9McbZq98H9C1Ggzp7FSfWDGbVSCbZ + peerKey: CZTN+NFi4g9MA4BKl3OiCKuzXh63ukIvYWo9D5t9qfZcFwIeOW8eP9W8mtnXaY3JAFyb6GliBW0uCaw4wjRcCA== + signingKey: CZTN+NFi4g9MA4BKl3OiCKuzXh63ukIvYWo9D5t9qfZcFwIeOW8eP9W8mtnXaY3JAFyb6GliBW0uCaw4wjRcCA== + encryptionKey: MIIEpAIBAAKCAQEAo9Nuypzg9kZ+LP+8jQgSTaoRUu8VFdJdCOEjuroPQK+2NwBD/Z9BqKiN0Z+jmhkI9yA0/Fwdh21ibAKX3Je9uffAKOhXI2sxIAlccDORu1kGDnhcc7N3L644DK+uFZvKnMQWiCwmtTnNHkoCzWcIE44G56wMa2c4W7mrOuRWqG6a5Z9JUuLqafOIlf6Dw2fiVM6xXiTIMQ0OyXByxFNjsS5O/PYcwoIKMV8MY+gUnAmyPLE0bslvz/8W+3E7d/LDO4lhqW+N1kDmboe6sc7DBf5JD4DLnP2VWV8Ae/rfJvxwu9ZqVT8RdYKMsZqvs9sV+6jQC9UcX+K8Q4Wdo0eMHwIDAQABAoIBAACR57zEtvOkYyP878b91DJ4+P503nno9XHmdp1bsFnlQpkGYzYqq6vOik/EYmlS1PknH4gROfkSpFkD2UtnK73N4tlBlawF33HhFnU9eLBSKvc56/hrE2sTDBbfNZfVpurMs9ddb/UJcnE8iK32QczvnY6IxrJI9aU8DCB0UujbGDnya/HbFU9pLLxu2EUoHNxjSHG/jCx+AR7JRknRA65KPZG7mu5jeAaaklYTY/aLGlctgecDKfNKDsZo6rgAMUW6ZXI8ogNGqfKHUFazCVe0l1tp4hxvgmyjcw79iKvFr4mlpHtgjYTFCeoMJKvOXUImZUJL0vCA6WKvUdIfzAECgYEA0lCTXYwOHqOwYMb1qi8lIIApcI//B/Nzn++MDQ4ZO4SzVJTTv4rSdXAuoihsO6E7LYZK+wdVNjiCbeMukfTqEfaxWXIsIDaHSR3440NsYSwdBz04UhRgpxFE2FwPK7J5dQ57FBaCAgksnO3XjcByBMYgMWVbA+ezIWfVdN96YoECgYEAx2mm/W4ZGdDyJgDonzEGGxfaNqo6DIv+67fDwI6WyqOWFWJTBaVFkm1uPJfcXYuTI9YCNFRKuRU7dyqSPLErMVusC/8Iww8++kqmkc1m04tbkqh4KpREYuMw8/tTYSWDwgpY8ksM5YRpYRJLTuuC0cEmefGco1RsXG8bYYeZXp8CgYBq5fexYcG/gxXgauBtSx9E4L+vbhGD2hNYJKr768GZhf6crDTgs8/7TzT0yTUSLgZlQlAUPgrqz1hEQGfoWiMrVEeanjSdfvnOiUR7R0bsMT7j8hMRbTgfUuC6VDiFzmZ7wAuBD1uvazhY329jpoCNuqKcWNclKfzbqupNSFXtgQKBgQCTlR7Qm0YadChydeOzxX2GWa3XHT7fAFFHNPa8MQtqp40xAFb/a6TEzRZz49RkqyLXt9Bj2CqBNjSPakNWhay41+bJ7hMXAdaTOOJ0L/c1AwNf1C0zHg5KvWgCefPohvIvjqbrkx3VU50GCZsQqn5kLLYENAvAWX/lHRm/obKhcwKBgQC/iAOC8ZdZC5w4F0Mf7roZWa9P/42JWlCMzm/I/5mEIn4mYY6+1C5V+fXoET6845oAh+P8CkH4waJtqqN6BKQhj7SKqoCHgGBCQy+HrSCBtzk7NuXdpz6sk14zfcVpjR3y3l9TuXc4cVQMSLAqg8yUQf+qnEQTit4jyfikV/5XEw== apiServer: listenAddrs: - 127.0.0.1:8081 tls: false nodes: - - peerId: 12D3KooWPuwdqpDQxWhD2Vh4yskx2T5VMrwdpTZLfACzgsGfQfNy + - peerId: 12D3KooWHtnADt84naf6NeejZ1MxYGZPLk5SPEu2DL4ZV948uWPS address: 127.0.0.1:4430 - signingKey: yOEpD2+cPldXc2urGuU+szunm7fddRa8xew2uVjaxifRcVzNKhSERpOefjrXaky7PcKmSmTsH/5ZFtcrh1uzqg== - encryptionKey: MIIEpAIBAAKCAQEAxnE9Htwto+2fVmonkG9/DxNre33n7kjfrZU73JcHmpKhPlRFirig5T8rs2MaTq1R72/8nGBJuSxsz1PnexI3die39pY1OFYfZCZ59LbT7uH/xHcvkVrK2n50Q41KbbGT9BEzyW+XPkKPDpTq3/igYP+yUQgoWLfMwxCCLKXDe6qUC0fuIxR80fvj3XvorB5dnAiQ01JkH4PtCV1OWT6ZpLGhzcYxsxTHozd6LdMOC7wgGhW26dOSa/vZ1t5avbewFVIz0qfqBncunb7tjO4xa3xVYaA5jBbixDQUYFjVzW7cksrrN4CFNBDBGJ8PLS80MuMg0OG0O+/Qi1mbGb2mUQIDAQABAoIBACODAD0VidVcILeGJ65hRYudHg7raSXrRJv7qMrA/EtdEh3lVsyMXb6on1lq0rphqdf/YmVZldfda1tu2G3dxK8QTIuENeHvB48Uk56HWUXWi77M1WZdqQ+QsZ2lGzymGqQCsBHMNnSd1Jv3alDKXWj+WRrHKvE1cx81RRZYU7M9cpurnF5YNjO7L+7sMxUA9uAQGbe3kDVzrygraicLYQpxSNHytName0A+k3ug0qer4I6PmZhhJykkz6MD3dz/n625HSS+X+TuTm52T2b87tL27xXmSnUK7eYWjZ1vQlP1fWmqnac6u5LApUZaRi0tTjtefSjRW4jr1q20RqOp1kECgYEA7Onh3zM9ejATsjW6WISGKiBPci0D7DUbIuGuJrdQRadlkZzmeQ/VOYAuxIQD4GnQDRhM1FyxsqiAWkJOyCLFiMmsgIEyW9/eRhF8NlCVU+DA/fxy9EagfBbVsgiSBwOex24hPXIVYlaHkLAloNoD4bpw0pQZSDWXr+xvMFNwoGsCgYEA1m3sWA/e8ZuXForaUOoJzBU9nwC79bXv2UNktsVvBlQ1o9pbjoYDcVoAPwuBVUL1UwqDNMzPdhDBKBjZmCyjS6zlYD5ZKjF2m8iTyc4QcaBCdM0iyQpSXTmrfMx+hK1aWwL1p8ssNcednp5ExSAaTyNNGVdbtddiQ6/KMPmhUzMCgYEAwDjLsUNr4BXeBTweo+9yw/9PNn5brm0wRU8C9BrMIJe/izPYs+UqxerBB2Vtl8mCqv1KaQuEika5TYJ7VVsRFvk641DwQScUu5k4RQGBB3tWWz1XL+eWEticLkVR5isDyyAKDEbiHtXCTJz/CtGZUK7rF5BeKv6AwpZ9aKJqwV0CgYEAqXDlQNURu+PR6TtBtoypvz3NmraO0GO7KvipPhAXYm3qkRa8IIxfbhPLfAYQZhpqFvuIoJFzIn2s1I2GbExhoSv3eSzrcn7xlbpSpjYSImeb/AYZhbmFSiuHCi/hjeAaNS7KhZPz1G9vaubvusFaaMyhYPP6AWA4QvpHEJpB06cCgYBqR6/7d2hQiq4MJUrBEzLwG4ijnPeq+UVLQjE598hVIj+8UhRZRRcNWVEJxfcIL1v6Bpo8XISDNVRb30T9bPGVnXvC1jutTUbXKUB1/8iXuyH3IVieobch+bGd4v7ehH/lI7vzB6hjJpFzHopfFUn4wacSQdcFi3tRAwUB/L0S/w== - - peerId: 12D3KooWBgHmDqtXH9SrZfAmwCFsD8LZhTD5dg5wkhdbqFoS8GBN + signingKey: Fu/H792JFWVYQpOZeLBIr1Y5UuHdZzJxkGO7eakZDaZ3/vIDhjGgNab1+1NMdTJ0IUP6Tv3KQutcRwtX26/wmQ== + encryptionKey: MIIEowIBAAKCAQEAs+N32tT2Q4Nv9MlyH0B34TJZYLh1+Y/4hc0vupiS/Ct0Mt+Rh62KkPy6Hz2JRDd7ryYpz/Un+qAFQBhfugKy6a5R0U/OnaK8/WwJjstTPd59c7iGnCeW9mWumexT2wiQVbWcSdcAE5SPYmBkIPnwzgxZgtNzvEnbdUDWIOsR3ifDAt3iUqqlo+cZWIZaXiTjyrMlaWY/BR/SGrklYzxcUzNj+K6DdY4yFN5/5ywKIe81llooULTyM5U+fWEW5uri4ERgT/YcRAoii2UJ5kHzpIZmGKcrJ4kUdyFLE7VxYIQMHHXRkDlpTEYlAAJGl5frcHvFufTWIJaohBXAxg5tyQIDAQABAoIBAD3TI9I19x1lAwliYrKS+aCQKV+whftrm8KArrK21W2NkbYaWG4FGuaRtXYfNBoZ54xe1Wf/nenpLWTF+8B2RP9DRiNmBmDvGX0PsIk/IDDXUs5+0OTCRoQQll2Yd4mD+/c5H6nRFtmj6VOqRT+AJ17pp6nq+o/v4lj+G5ncsJtlAtq1xb20yHQYEl6sbK2UqYuiFtXpKMCK/8V3hDj+ROM8UMkxMj+qj9NFd2sCk4FEZ+S2QmHIjY55s4Rpe1RzZZZEYOuJ99Fism+HYXtf3JlFORaNIdhdWY1UkVAFuKY/ULoHOhf/RdJ8ZArak3CplpEdPTYC4IRBI1eZDDF2GgECgYEAw0jvV7E1kqfGD5Q1WTFsss4xHQntPtWRfyAI1viy16sqMX6wQ4ZixWXsOeMB1o5azqqjYo0BBiGw6ie1GKl0iZ09FxHmMDqFLf8a0JZXAlTvC/wEHgAXCzg7tpHRJD1B6gAiU6u6ALW14DtWe6tikFehrY0mwGb9koedQNgoGnkCgYEA69EcUTejGm5Hm6ANC5u5Vn1aaB4BrTJ36FGTaxjnSUPePBj0Eo2Bt+c25DiD3uGj2Jws5QrRhpu+NYhOTC+/P1/rm82w9Tpc8z/wA7nUk0gGEncgtJ8RFokom4B+Ui83JJiH0V7puZUhCc/TOmfa5N0SH5gM4q4rBoVDZtnTGdECgYEAlnssW9GlK6Z2++hEF7/7N+mldPACTkn6PRCtXyHzhjdSYyNxpgb3M49vsceY0gGOPfTFxBpNsLDjh/wjE6b4s1ZkDdPwIjfmCmSrABLpZ1WVgxGnBoshNrcVZIEGvTsrAKsryHfq88MSLIDtCo0tfXbZkkfTla2HNpOj/KTUelkCgYBl0pMRlp58qSWOUxuO6ZyrddD1qA89Q892ptKqqcQkZIOvG284G5XpXJLdFHIMaQ2gWD8iXvt9zf3hi4uTZgKEUNyhF73TBXJhLjhqw3DAb5b/niSnGQ/91ReNnXvt7Kk4ygvLIdp14ai0XeJtE672p2ZN8g+OSXoWhLBH1sJKIQKBgA7NH/Y4RbVHIMWY7jH/1d4ODZ4Hr1RK2Q99HJCAurfD5tjhpcMApoQQJKJDpv7J5Ipx6ynQJD7CFfx27+vqBEG4ffAUm66lKM5xrKcOevcyWemppurCLuza64GgWDP6jBRnHeqrUyZUqoI/I0FNwjxIJbu08NpRSt8khq59+iyF + - peerId: 12D3KooWG1r2SVzTMGDhkiw9McbZq98H9C1Ggzp7FSfWDGbVSCbZ address: 127.0.0.1:4431 - signingKey: l6LFiKqr4ZHgcPbL+DR7KwMbzImufQPFgpoHOJ/nvfUbpb76DCADHuT1I4gIs+XByglnY1KV8jbMfW64XRW5XQ== - encryptionKey: MIIEowIBAAKCAQEA4ltcn1AH048bMXcKOOW7/E0TZYPxL3OtcHXWHSAZjeeTA/rc45G2eaNgyY7Ji+feLtZERbXNWGFBdNp31NHDYZAYwbZmjEqTEgV4yVx7BQP3VBEzglTJaNLTf+XIJnVAEkoHS6ogjC0oXTM6paHu64EitoOCzF9zqL023swjE3HU0dm2xwsUdGnKeO5nPMso/6e3VMavkKnFmvB965ECCBujtediP4lVdIABNVtoMHCoeI5Sn+m7TKqJSyDOIEMhHT3orYUNZWVeAHE1YTM2cI5tSnDZP80CHZ674Z/bKL7Jaznmq87mVt1h9Use2EkxR07/dJuTGvFOos4jHoiR9QIDAQABAoIBAHAr8EluooI/j61CnYk2p6LPG0aaTQJD4/YwHuwOBTviP2OghKgthGzg/szDerNfMyaoveqBvoIGqCZdQTbwwE7v1qTgXA83wYwTtBitQLVqkr1RTOJQXAMbPv5Jg5czUY3+q4DejQSKOE9/XJfKGJkSRH6Hy2C2CJ3dLnzYUqWGO3t70RLT1/sC6p6w3lXdy3dKZGkoR2wva+HXQxVrP8X5HOResXgNZwgMHt9KF1QHVCcySKYiEAefEKTSdKD2fOd4FxLgp3zWpvH3jrX0zd/DqzTlFD5Ns6Ayp2sIfHVp3sn99DZZM6DauMepQKtoSCnXZ+qKhekAwNVJnsVQkSECgYEA4spY9araeFUSl4uXCUQOpCkSshYOPRYN6sBbHsx8tV2eQtCT+5SuNYmzur3c5bkiraGEab8rZfGdDL6fLxQyaqbOmN31Db5kNh/2X+sRnxkak8lsROUWQZRF9doH73FDv6ZlI3V/JicZlOUCfN5BYT+x74R4/c1YXfyuD1J9gr0CgYEA/4K4SDwZUY4bOVCmKQz0OM+RW4PAAH6LHKenTAZNTeDNFFxc2nqnzRGMEKZTDGy0kbT5mBhBHFgShXcAiKxc5/MGkpt8Jcq6Fr5KGU9aZtYKji6mwMTsUndPNQydh3vOt5pOmcuMM6ovanNTvI8k6Qo53OY1IpO5CfOROu0hm5kCgYBnWsYd92YnDsYxUEldzKlLgPhnNov4pNNk15LvP0vaL7cPRhUaw1B9T6scAKjp/GxkasZ4lsnFZM4o37qV7wNm/WwL2KN0Rv9Od1SFtBBMzFkDXvk7kJeK/XLAr0OMiLbSYZeYCFUQ4yLSa2et1nA/TJLf0CR/rhSGiMAedX6DlQKBgAx1137OT33GrFUzNacy1oYeuTv5RNfBVA9lrabrd8GggN/JUU3mRWCexnHZaptkgbnJVZKxPBuhv+V6VDBWF4HIPD3SD0/YfxK03PA3CnWRYppkdAValRvAbcBsiRIeW4pgoAyn/IJYfk92qFK9uFMVCJVZNKYnBhMSKbbx8X2hAoGBAKwvzyAImbNB+493q1R/lSayxzG76bRJ/EseiTqwIec9c4C+Bd/sVXR+Re+xZb0FI/va1bz5CrduTzLSKBmf/+0lzl0MJvWY2+SXfGYdbl4+TTyqgDDfwqW0Tj8pDimye2BneyTmXko1rF+2Sxen7kMXnJLwpqjwZ6TZJuoqeK8q - - peerId: 12D3KooWASsipDzkridiMBmE7VSqp8yZvGWPY1VqySgMSZk6tsiL + signingKey: CZTN+NFi4g9MA4BKl3OiCKuzXh63ukIvYWo9D5t9qfZcFwIeOW8eP9W8mtnXaY3JAFyb6GliBW0uCaw4wjRcCA== + encryptionKey: MIIEpAIBAAKCAQEAo9Nuypzg9kZ+LP+8jQgSTaoRUu8VFdJdCOEjuroPQK+2NwBD/Z9BqKiN0Z+jmhkI9yA0/Fwdh21ibAKX3Je9uffAKOhXI2sxIAlccDORu1kGDnhcc7N3L644DK+uFZvKnMQWiCwmtTnNHkoCzWcIE44G56wMa2c4W7mrOuRWqG6a5Z9JUuLqafOIlf6Dw2fiVM6xXiTIMQ0OyXByxFNjsS5O/PYcwoIKMV8MY+gUnAmyPLE0bslvz/8W+3E7d/LDO4lhqW+N1kDmboe6sc7DBf5JD4DLnP2VWV8Ae/rfJvxwu9ZqVT8RdYKMsZqvs9sV+6jQC9UcX+K8Q4Wdo0eMHwIDAQABAoIBAACR57zEtvOkYyP878b91DJ4+P503nno9XHmdp1bsFnlQpkGYzYqq6vOik/EYmlS1PknH4gROfkSpFkD2UtnK73N4tlBlawF33HhFnU9eLBSKvc56/hrE2sTDBbfNZfVpurMs9ddb/UJcnE8iK32QczvnY6IxrJI9aU8DCB0UujbGDnya/HbFU9pLLxu2EUoHNxjSHG/jCx+AR7JRknRA65KPZG7mu5jeAaaklYTY/aLGlctgecDKfNKDsZo6rgAMUW6ZXI8ogNGqfKHUFazCVe0l1tp4hxvgmyjcw79iKvFr4mlpHtgjYTFCeoMJKvOXUImZUJL0vCA6WKvUdIfzAECgYEA0lCTXYwOHqOwYMb1qi8lIIApcI//B/Nzn++MDQ4ZO4SzVJTTv4rSdXAuoihsO6E7LYZK+wdVNjiCbeMukfTqEfaxWXIsIDaHSR3440NsYSwdBz04UhRgpxFE2FwPK7J5dQ57FBaCAgksnO3XjcByBMYgMWVbA+ezIWfVdN96YoECgYEAx2mm/W4ZGdDyJgDonzEGGxfaNqo6DIv+67fDwI6WyqOWFWJTBaVFkm1uPJfcXYuTI9YCNFRKuRU7dyqSPLErMVusC/8Iww8++kqmkc1m04tbkqh4KpREYuMw8/tTYSWDwgpY8ksM5YRpYRJLTuuC0cEmefGco1RsXG8bYYeZXp8CgYBq5fexYcG/gxXgauBtSx9E4L+vbhGD2hNYJKr768GZhf6crDTgs8/7TzT0yTUSLgZlQlAUPgrqz1hEQGfoWiMrVEeanjSdfvnOiUR7R0bsMT7j8hMRbTgfUuC6VDiFzmZ7wAuBD1uvazhY329jpoCNuqKcWNclKfzbqupNSFXtgQKBgQCTlR7Qm0YadChydeOzxX2GWa3XHT7fAFFHNPa8MQtqp40xAFb/a6TEzRZz49RkqyLXt9Bj2CqBNjSPakNWhay41+bJ7hMXAdaTOOJ0L/c1AwNf1C0zHg5KvWgCefPohvIvjqbrkx3VU50GCZsQqn5kLLYENAvAWX/lHRm/obKhcwKBgQC/iAOC8ZdZC5w4F0Mf7roZWa9P/42JWlCMzm/I/5mEIn4mYY6+1C5V+fXoET6845oAh+P8CkH4waJtqqN6BKQhj7SKqoCHgGBCQy+HrSCBtzk7NuXdpz6sk14zfcVpjR3y3l9TuXc4cVQMSLAqg8yUQf+qnEQTit4jyfikV/5XEw== + - peerId: 12D3KooWDXDcBYxtZ8KNRoJebNgNAv9nFbQatQMoWm1BLwmQh6u7 address: 127.0.0.1:4432 - signingKey: /6+uYFwFf9nU6fvXQVtpHhjd8+v4dXc7esZzqkhjyfMJWlMiZOtQeb913FXofD5f20WksU0l6i22B09sFFYwDQ== - encryptionKey: MIIEogIBAAKCAQEAwCy84lzkxtzgn4ixGm0LSUTujOBpOh9m7XDoDPZnMTmExdOe9a5v/LXzdlCOCuBvK5u1T3ALBJMA3Zgvjv/jPRQUdiHprP3sbdfc6IgZPBFdLKFTc9yAA7GMbI4y7LhGMLGOMOqQXs+DOeImfmxEs3ykLXHKNas5ORnZPVnB6E9Qod8KH7UyMmBjQkOZYOOw10X4JZiU6xJp/E+VVWcmeXgNBbj5xOWMSzM+hhoA4wNOzBxACucaKDmqD6qugzebOqyUVSzFnEbquro+MYTWYdUDjZTXdvxgUUo80MGQ164gZhkFUKrmSpUvu3YErFySEGqAdFNwOZ6y/4X3s0BHvQIDAQABAoIBAAZiNhAK5+qXMbr67m8jSimv6YCyf6xXmLKwenTbxofDEl8D7ZbZqYyqeqDmgiFoXSkErhwqa6NGQtQZlxLX+zNvNFLMQ5fkg3MOpZ7vzm7JYN/3p+8EVxhIUJLWkmh8opBBhaioUg1kNUa59W9jp1CTBl0gF4h63JbB/g5kqeVOllUw7J1igAoaX36nOJGOwIynCWdizhDhgyjR4OcYfOLwcPDJueKTc5vM10g3LuMSK/sJmaD3TkJFPtDHw+RMW6wqyjsnkrg2D2oohXEyGWYYIXo2so4HCez0AB1I1JAxtVnRPvSIp7xLMm7+AkDoq12QYDHfxZtDTpfmvJg+Sn0CgYEAxCd+oribtdQW+JUctjsDbSQX5CeRISH5Ith3jveBx2jKIqQVnoVPz6URHOvnlIsqYYLANB8B3JHMWfR2UmkK11x0OcZecB06+oBoCZukvSXF+GqVHzLAQUxaoEBDCCPneskj5w+riMWBiiGDp32rUnkqv0nh7dnH+GfORcJ44L8CgYEA+s5s5EALj1jyU9w4+HVUyVsIrUitFnQg6qw/Td3Kj+8CXImKlS+rlmbQv0m1aOcvtFjQRIjjzZJAf/ausfAME+MayoNODgZsDk5RyDKuSWzMLvZLAa1LD52Uli5Pg8KtpzKVTn4xE1MbjsQcUNhFRAgrNEKNyuzXzdp4uXgGOoMCgYASXwiTQOsEepq0KXMI9jn57Nl3+uSyz7W/t7pq329+N6hG2ktUD3RMJE+X/9gup2IOw+owd377I4SaIDU8vq3PQc944cVShspRT9lunO8u7+y8uW7B/0TWWMpcG+irSIGTlGcSavtL0gOx5jWoaDK1hLemNss8NZtu/nnpOq+LjQKBgDisVozJMBOHPNLYS4NROAR77p0BdCNDwIBmxbM5r+EQWA9DAS6u4+4Lc5YV+MkonG37N6yU5iz4pFyGCHmqzX/c7JvgSc3/g4FED1TWpu1uiUD/ZHmPiAuSRxYchtk2L3k9g+GFwF8mg26iP+fAxv4VfnXDqDi3hhg9CtSWG4ozAoGAOWZXlFKqzGAfcucIe54FVQnweXG9sEuIPAvWvVRs4406ggNmL5eHccXpPHWTgetsr2TYMqPTDVMRmhBzSkyrYgk+b2tme79HPzTWs2Yg/pzjOfTgw7MBX/KlvOW5/J+dvrF3Gx8AHHZ9QQdYqi/MS1NKb2K3IbD0/m5gL5Pwi6A= + signingKey: c3D+0+BCl1xU35KBY+U3GPcU9aXdoLUiD4DJ2jF+IqI3CjGLhet3MBOkPXdIuPq/UpEqlp1k6FjNaU6DEU6Csg== + encryptionKey: MIIEpAIBAAKCAQEAuB7HsXuYmoif6/U4JnjC6L0QMu9qW1aPAxDrxWIedTzQhFZp3F3gYW/Zgdd2hvd0c2xyfhwf9C0X/UzfxWr54dDXzWNLN8BdVTik48cdYlgOmbgejiIjTaqSAlv4RtlqvooxCN0MwR2/RVAG/N5GqcAM7E4kJWPtvQYNl6wWCc92rKdutvmcj73wKzz9Hd/qdF612OVS3zRsjh3tJmYt55oovAUh1TAz/mSTTXjFHy35zLRBP+oQQsAOt2p0BOMSyOKZufGC8l3aZD//dp4/U/MaqCjeNuWxCfAZlSd+vt7T0aqDGdyRtrrGUcu4PCwXpOdbzw+uSZxnKawolYoEHwIDAQABAoIBAQCsxeVpvKtUx8QZrUCFiWiM8W0T/un0z+LfY696xzoBlZGtvVEVQtpdVJHsb31/5RFXhnphsI6jmPUb8llBbcMSjeETkItyw4ZRhBfmzl/aevsocEfr5EjwhpEAucDe6wJpzk95G8TuKrXjmtcTzpjMjbUSwbjVhVH/wIBcxVTg2j6z4AOADDRI5UsvZ0NV//If+nNzMjcuIji95PNk7lAuwsqkX3FycxvqXKUMGxRE2bgGMxaBRAP0kqL2vdxyS1M7wp/x04ZAtSnPXHe4qqmDOt69ec3XqbmZHOsZHzkCFePKcPB472/G0bPJeiq/idevEqS89RwvbphDtq3KGrRBAoGBAOrHqlPh36WZBOi6SueUmcrg579KDMUekgeea5payiySbRWztCL2yCYbSgFqSbyCLRppyXK51xvo8iUejR231or6u/nd7T0CON0Nf/8Qtbb13vtTGpIBiWYGqeDrWucUUlyS+K3sDfNk1AJqjUdaIMVu4yTpgzEvrdYCcT312RBPAoGBAMjC83/0EKnsbypFprxKS3Fbg963HhyKjfffQ2w4yncM6kxXF3ehVjg1LInok/6/dmy2LxkAf3r0YYZrGJWmG4Sv4UqHn6JxAjQgarPbdmGhJ8VIUMvMbZRsX3i8Z8D2o8k1M1kr6MYsQ53iX6q/Cp3gnucMeJPk6Xs9Q4TO7YsxAoGAWrXEOF6X01p4zBZWJH2Eoh8dSwooPuzdzPXHaz7SyD/Wx8DDw5KHqDl48W0Iij3dgUwIGjx1QQJStEbGjQnfaZkQkazOIXk/USELKBhjrQn4GjB0np7bYEEI1673UzrFy6C5VjFS/owhYcGbTksjSETcnAFgv9tFFd+hsyfOsv8CgYALk4o875LiaXrDgj6qDtKo17ET75Ux6h9jkqEtpVyvXrRH8KGuyUPSe+Z0kU+vWdT3Uc4HcArpyRuyh4xkXK6riQTBqm5fDIsm/FOKyXXbDVLgwlm+Vqxe6Zzbtml5K/+nw4SReMG0Y6sGeJ4xl1CCaAhhpEtzo7h+3bp99vylkQKBgQDDdR6N4wb3DHTzrW0EFb8XhXZN7CIE3EWhToNDsCkguUB7lwqD4p2c4yLscS0YAqxk7I3NW0nDaUV/340RrVtPJDqB4NZJ+MvhfvV3TW2FkZmru/iW+DMUsfZGAOPdQz9jLGAzUXrXFw/qGBtLIUL6UWqWLOrBO9QHb21nnB1Ssg== space: gcTTL: 60 - syncPeriod: 11 + syncPeriod: 600 storage: path: db metric: @@ -37,3 +37,6 @@ log: production: false defaultLevel: "" namedLevels: {} +stream: + timeoutMilliseconds: 1000 + maxMsgSizeMb: 256 diff --git a/etc/configs/node3.yml b/etc/configs/node3.yml index 4731b7f1..169e4f3f 100755 --- a/etc/configs/node3.yml +++ b/etc/configs/node3.yml @@ -5,30 +5,30 @@ grpcServer: - 127.0.0.1:4432 tls: false account: - peerId: 12D3KooWASsipDzkridiMBmE7VSqp8yZvGWPY1VqySgMSZk6tsiL - peerKey: /6+uYFwFf9nU6fvXQVtpHhjd8+v4dXc7esZzqkhjyfMJWlMiZOtQeb913FXofD5f20WksU0l6i22B09sFFYwDQ== - signingKey: /6+uYFwFf9nU6fvXQVtpHhjd8+v4dXc7esZzqkhjyfMJWlMiZOtQeb913FXofD5f20WksU0l6i22B09sFFYwDQ== - encryptionKey: MIIEogIBAAKCAQEAwCy84lzkxtzgn4ixGm0LSUTujOBpOh9m7XDoDPZnMTmExdOe9a5v/LXzdlCOCuBvK5u1T3ALBJMA3Zgvjv/jPRQUdiHprP3sbdfc6IgZPBFdLKFTc9yAA7GMbI4y7LhGMLGOMOqQXs+DOeImfmxEs3ykLXHKNas5ORnZPVnB6E9Qod8KH7UyMmBjQkOZYOOw10X4JZiU6xJp/E+VVWcmeXgNBbj5xOWMSzM+hhoA4wNOzBxACucaKDmqD6qugzebOqyUVSzFnEbquro+MYTWYdUDjZTXdvxgUUo80MGQ164gZhkFUKrmSpUvu3YErFySEGqAdFNwOZ6y/4X3s0BHvQIDAQABAoIBAAZiNhAK5+qXMbr67m8jSimv6YCyf6xXmLKwenTbxofDEl8D7ZbZqYyqeqDmgiFoXSkErhwqa6NGQtQZlxLX+zNvNFLMQ5fkg3MOpZ7vzm7JYN/3p+8EVxhIUJLWkmh8opBBhaioUg1kNUa59W9jp1CTBl0gF4h63JbB/g5kqeVOllUw7J1igAoaX36nOJGOwIynCWdizhDhgyjR4OcYfOLwcPDJueKTc5vM10g3LuMSK/sJmaD3TkJFPtDHw+RMW6wqyjsnkrg2D2oohXEyGWYYIXo2so4HCez0AB1I1JAxtVnRPvSIp7xLMm7+AkDoq12QYDHfxZtDTpfmvJg+Sn0CgYEAxCd+oribtdQW+JUctjsDbSQX5CeRISH5Ith3jveBx2jKIqQVnoVPz6URHOvnlIsqYYLANB8B3JHMWfR2UmkK11x0OcZecB06+oBoCZukvSXF+GqVHzLAQUxaoEBDCCPneskj5w+riMWBiiGDp32rUnkqv0nh7dnH+GfORcJ44L8CgYEA+s5s5EALj1jyU9w4+HVUyVsIrUitFnQg6qw/Td3Kj+8CXImKlS+rlmbQv0m1aOcvtFjQRIjjzZJAf/ausfAME+MayoNODgZsDk5RyDKuSWzMLvZLAa1LD52Uli5Pg8KtpzKVTn4xE1MbjsQcUNhFRAgrNEKNyuzXzdp4uXgGOoMCgYASXwiTQOsEepq0KXMI9jn57Nl3+uSyz7W/t7pq329+N6hG2ktUD3RMJE+X/9gup2IOw+owd377I4SaIDU8vq3PQc944cVShspRT9lunO8u7+y8uW7B/0TWWMpcG+irSIGTlGcSavtL0gOx5jWoaDK1hLemNss8NZtu/nnpOq+LjQKBgDisVozJMBOHPNLYS4NROAR77p0BdCNDwIBmxbM5r+EQWA9DAS6u4+4Lc5YV+MkonG37N6yU5iz4pFyGCHmqzX/c7JvgSc3/g4FED1TWpu1uiUD/ZHmPiAuSRxYchtk2L3k9g+GFwF8mg26iP+fAxv4VfnXDqDi3hhg9CtSWG4ozAoGAOWZXlFKqzGAfcucIe54FVQnweXG9sEuIPAvWvVRs4406ggNmL5eHccXpPHWTgetsr2TYMqPTDVMRmhBzSkyrYgk+b2tme79HPzTWs2Yg/pzjOfTgw7MBX/KlvOW5/J+dvrF3Gx8AHHZ9QQdYqi/MS1NKb2K3IbD0/m5gL5Pwi6A= + peerId: 12D3KooWDXDcBYxtZ8KNRoJebNgNAv9nFbQatQMoWm1BLwmQh6u7 + peerKey: c3D+0+BCl1xU35KBY+U3GPcU9aXdoLUiD4DJ2jF+IqI3CjGLhet3MBOkPXdIuPq/UpEqlp1k6FjNaU6DEU6Csg== + signingKey: c3D+0+BCl1xU35KBY+U3GPcU9aXdoLUiD4DJ2jF+IqI3CjGLhet3MBOkPXdIuPq/UpEqlp1k6FjNaU6DEU6Csg== + encryptionKey: MIIEpAIBAAKCAQEAuB7HsXuYmoif6/U4JnjC6L0QMu9qW1aPAxDrxWIedTzQhFZp3F3gYW/Zgdd2hvd0c2xyfhwf9C0X/UzfxWr54dDXzWNLN8BdVTik48cdYlgOmbgejiIjTaqSAlv4RtlqvooxCN0MwR2/RVAG/N5GqcAM7E4kJWPtvQYNl6wWCc92rKdutvmcj73wKzz9Hd/qdF612OVS3zRsjh3tJmYt55oovAUh1TAz/mSTTXjFHy35zLRBP+oQQsAOt2p0BOMSyOKZufGC8l3aZD//dp4/U/MaqCjeNuWxCfAZlSd+vt7T0aqDGdyRtrrGUcu4PCwXpOdbzw+uSZxnKawolYoEHwIDAQABAoIBAQCsxeVpvKtUx8QZrUCFiWiM8W0T/un0z+LfY696xzoBlZGtvVEVQtpdVJHsb31/5RFXhnphsI6jmPUb8llBbcMSjeETkItyw4ZRhBfmzl/aevsocEfr5EjwhpEAucDe6wJpzk95G8TuKrXjmtcTzpjMjbUSwbjVhVH/wIBcxVTg2j6z4AOADDRI5UsvZ0NV//If+nNzMjcuIji95PNk7lAuwsqkX3FycxvqXKUMGxRE2bgGMxaBRAP0kqL2vdxyS1M7wp/x04ZAtSnPXHe4qqmDOt69ec3XqbmZHOsZHzkCFePKcPB472/G0bPJeiq/idevEqS89RwvbphDtq3KGrRBAoGBAOrHqlPh36WZBOi6SueUmcrg579KDMUekgeea5payiySbRWztCL2yCYbSgFqSbyCLRppyXK51xvo8iUejR231or6u/nd7T0CON0Nf/8Qtbb13vtTGpIBiWYGqeDrWucUUlyS+K3sDfNk1AJqjUdaIMVu4yTpgzEvrdYCcT312RBPAoGBAMjC83/0EKnsbypFprxKS3Fbg963HhyKjfffQ2w4yncM6kxXF3ehVjg1LInok/6/dmy2LxkAf3r0YYZrGJWmG4Sv4UqHn6JxAjQgarPbdmGhJ8VIUMvMbZRsX3i8Z8D2o8k1M1kr6MYsQ53iX6q/Cp3gnucMeJPk6Xs9Q4TO7YsxAoGAWrXEOF6X01p4zBZWJH2Eoh8dSwooPuzdzPXHaz7SyD/Wx8DDw5KHqDl48W0Iij3dgUwIGjx1QQJStEbGjQnfaZkQkazOIXk/USELKBhjrQn4GjB0np7bYEEI1673UzrFy6C5VjFS/owhYcGbTksjSETcnAFgv9tFFd+hsyfOsv8CgYALk4o875LiaXrDgj6qDtKo17ET75Ux6h9jkqEtpVyvXrRH8KGuyUPSe+Z0kU+vWdT3Uc4HcArpyRuyh4xkXK6riQTBqm5fDIsm/FOKyXXbDVLgwlm+Vqxe6Zzbtml5K/+nw4SReMG0Y6sGeJ4xl1CCaAhhpEtzo7h+3bp99vylkQKBgQDDdR6N4wb3DHTzrW0EFb8XhXZN7CIE3EWhToNDsCkguUB7lwqD4p2c4yLscS0YAqxk7I3NW0nDaUV/340RrVtPJDqB4NZJ+MvhfvV3TW2FkZmru/iW+DMUsfZGAOPdQz9jLGAzUXrXFw/qGBtLIUL6UWqWLOrBO9QHb21nnB1Ssg== apiServer: listenAddrs: - 127.0.0.1:8082 tls: false nodes: - - peerId: 12D3KooWPuwdqpDQxWhD2Vh4yskx2T5VMrwdpTZLfACzgsGfQfNy + - peerId: 12D3KooWHtnADt84naf6NeejZ1MxYGZPLk5SPEu2DL4ZV948uWPS address: 127.0.0.1:4430 - signingKey: yOEpD2+cPldXc2urGuU+szunm7fddRa8xew2uVjaxifRcVzNKhSERpOefjrXaky7PcKmSmTsH/5ZFtcrh1uzqg== - encryptionKey: MIIEpAIBAAKCAQEAxnE9Htwto+2fVmonkG9/DxNre33n7kjfrZU73JcHmpKhPlRFirig5T8rs2MaTq1R72/8nGBJuSxsz1PnexI3die39pY1OFYfZCZ59LbT7uH/xHcvkVrK2n50Q41KbbGT9BEzyW+XPkKPDpTq3/igYP+yUQgoWLfMwxCCLKXDe6qUC0fuIxR80fvj3XvorB5dnAiQ01JkH4PtCV1OWT6ZpLGhzcYxsxTHozd6LdMOC7wgGhW26dOSa/vZ1t5avbewFVIz0qfqBncunb7tjO4xa3xVYaA5jBbixDQUYFjVzW7cksrrN4CFNBDBGJ8PLS80MuMg0OG0O+/Qi1mbGb2mUQIDAQABAoIBACODAD0VidVcILeGJ65hRYudHg7raSXrRJv7qMrA/EtdEh3lVsyMXb6on1lq0rphqdf/YmVZldfda1tu2G3dxK8QTIuENeHvB48Uk56HWUXWi77M1WZdqQ+QsZ2lGzymGqQCsBHMNnSd1Jv3alDKXWj+WRrHKvE1cx81RRZYU7M9cpurnF5YNjO7L+7sMxUA9uAQGbe3kDVzrygraicLYQpxSNHytName0A+k3ug0qer4I6PmZhhJykkz6MD3dz/n625HSS+X+TuTm52T2b87tL27xXmSnUK7eYWjZ1vQlP1fWmqnac6u5LApUZaRi0tTjtefSjRW4jr1q20RqOp1kECgYEA7Onh3zM9ejATsjW6WISGKiBPci0D7DUbIuGuJrdQRadlkZzmeQ/VOYAuxIQD4GnQDRhM1FyxsqiAWkJOyCLFiMmsgIEyW9/eRhF8NlCVU+DA/fxy9EagfBbVsgiSBwOex24hPXIVYlaHkLAloNoD4bpw0pQZSDWXr+xvMFNwoGsCgYEA1m3sWA/e8ZuXForaUOoJzBU9nwC79bXv2UNktsVvBlQ1o9pbjoYDcVoAPwuBVUL1UwqDNMzPdhDBKBjZmCyjS6zlYD5ZKjF2m8iTyc4QcaBCdM0iyQpSXTmrfMx+hK1aWwL1p8ssNcednp5ExSAaTyNNGVdbtddiQ6/KMPmhUzMCgYEAwDjLsUNr4BXeBTweo+9yw/9PNn5brm0wRU8C9BrMIJe/izPYs+UqxerBB2Vtl8mCqv1KaQuEika5TYJ7VVsRFvk641DwQScUu5k4RQGBB3tWWz1XL+eWEticLkVR5isDyyAKDEbiHtXCTJz/CtGZUK7rF5BeKv6AwpZ9aKJqwV0CgYEAqXDlQNURu+PR6TtBtoypvz3NmraO0GO7KvipPhAXYm3qkRa8IIxfbhPLfAYQZhpqFvuIoJFzIn2s1I2GbExhoSv3eSzrcn7xlbpSpjYSImeb/AYZhbmFSiuHCi/hjeAaNS7KhZPz1G9vaubvusFaaMyhYPP6AWA4QvpHEJpB06cCgYBqR6/7d2hQiq4MJUrBEzLwG4ijnPeq+UVLQjE598hVIj+8UhRZRRcNWVEJxfcIL1v6Bpo8XISDNVRb30T9bPGVnXvC1jutTUbXKUB1/8iXuyH3IVieobch+bGd4v7ehH/lI7vzB6hjJpFzHopfFUn4wacSQdcFi3tRAwUB/L0S/w== - - peerId: 12D3KooWBgHmDqtXH9SrZfAmwCFsD8LZhTD5dg5wkhdbqFoS8GBN + signingKey: Fu/H792JFWVYQpOZeLBIr1Y5UuHdZzJxkGO7eakZDaZ3/vIDhjGgNab1+1NMdTJ0IUP6Tv3KQutcRwtX26/wmQ== + encryptionKey: MIIEowIBAAKCAQEAs+N32tT2Q4Nv9MlyH0B34TJZYLh1+Y/4hc0vupiS/Ct0Mt+Rh62KkPy6Hz2JRDd7ryYpz/Un+qAFQBhfugKy6a5R0U/OnaK8/WwJjstTPd59c7iGnCeW9mWumexT2wiQVbWcSdcAE5SPYmBkIPnwzgxZgtNzvEnbdUDWIOsR3ifDAt3iUqqlo+cZWIZaXiTjyrMlaWY/BR/SGrklYzxcUzNj+K6DdY4yFN5/5ywKIe81llooULTyM5U+fWEW5uri4ERgT/YcRAoii2UJ5kHzpIZmGKcrJ4kUdyFLE7VxYIQMHHXRkDlpTEYlAAJGl5frcHvFufTWIJaohBXAxg5tyQIDAQABAoIBAD3TI9I19x1lAwliYrKS+aCQKV+whftrm8KArrK21W2NkbYaWG4FGuaRtXYfNBoZ54xe1Wf/nenpLWTF+8B2RP9DRiNmBmDvGX0PsIk/IDDXUs5+0OTCRoQQll2Yd4mD+/c5H6nRFtmj6VOqRT+AJ17pp6nq+o/v4lj+G5ncsJtlAtq1xb20yHQYEl6sbK2UqYuiFtXpKMCK/8V3hDj+ROM8UMkxMj+qj9NFd2sCk4FEZ+S2QmHIjY55s4Rpe1RzZZZEYOuJ99Fism+HYXtf3JlFORaNIdhdWY1UkVAFuKY/ULoHOhf/RdJ8ZArak3CplpEdPTYC4IRBI1eZDDF2GgECgYEAw0jvV7E1kqfGD5Q1WTFsss4xHQntPtWRfyAI1viy16sqMX6wQ4ZixWXsOeMB1o5azqqjYo0BBiGw6ie1GKl0iZ09FxHmMDqFLf8a0JZXAlTvC/wEHgAXCzg7tpHRJD1B6gAiU6u6ALW14DtWe6tikFehrY0mwGb9koedQNgoGnkCgYEA69EcUTejGm5Hm6ANC5u5Vn1aaB4BrTJ36FGTaxjnSUPePBj0Eo2Bt+c25DiD3uGj2Jws5QrRhpu+NYhOTC+/P1/rm82w9Tpc8z/wA7nUk0gGEncgtJ8RFokom4B+Ui83JJiH0V7puZUhCc/TOmfa5N0SH5gM4q4rBoVDZtnTGdECgYEAlnssW9GlK6Z2++hEF7/7N+mldPACTkn6PRCtXyHzhjdSYyNxpgb3M49vsceY0gGOPfTFxBpNsLDjh/wjE6b4s1ZkDdPwIjfmCmSrABLpZ1WVgxGnBoshNrcVZIEGvTsrAKsryHfq88MSLIDtCo0tfXbZkkfTla2HNpOj/KTUelkCgYBl0pMRlp58qSWOUxuO6ZyrddD1qA89Q892ptKqqcQkZIOvG284G5XpXJLdFHIMaQ2gWD8iXvt9zf3hi4uTZgKEUNyhF73TBXJhLjhqw3DAb5b/niSnGQ/91ReNnXvt7Kk4ygvLIdp14ai0XeJtE672p2ZN8g+OSXoWhLBH1sJKIQKBgA7NH/Y4RbVHIMWY7jH/1d4ODZ4Hr1RK2Q99HJCAurfD5tjhpcMApoQQJKJDpv7J5Ipx6ynQJD7CFfx27+vqBEG4ffAUm66lKM5xrKcOevcyWemppurCLuza64GgWDP6jBRnHeqrUyZUqoI/I0FNwjxIJbu08NpRSt8khq59+iyF + - peerId: 12D3KooWG1r2SVzTMGDhkiw9McbZq98H9C1Ggzp7FSfWDGbVSCbZ address: 127.0.0.1:4431 - signingKey: l6LFiKqr4ZHgcPbL+DR7KwMbzImufQPFgpoHOJ/nvfUbpb76DCADHuT1I4gIs+XByglnY1KV8jbMfW64XRW5XQ== - encryptionKey: MIIEowIBAAKCAQEA4ltcn1AH048bMXcKOOW7/E0TZYPxL3OtcHXWHSAZjeeTA/rc45G2eaNgyY7Ji+feLtZERbXNWGFBdNp31NHDYZAYwbZmjEqTEgV4yVx7BQP3VBEzglTJaNLTf+XIJnVAEkoHS6ogjC0oXTM6paHu64EitoOCzF9zqL023swjE3HU0dm2xwsUdGnKeO5nPMso/6e3VMavkKnFmvB965ECCBujtediP4lVdIABNVtoMHCoeI5Sn+m7TKqJSyDOIEMhHT3orYUNZWVeAHE1YTM2cI5tSnDZP80CHZ674Z/bKL7Jaznmq87mVt1h9Use2EkxR07/dJuTGvFOos4jHoiR9QIDAQABAoIBAHAr8EluooI/j61CnYk2p6LPG0aaTQJD4/YwHuwOBTviP2OghKgthGzg/szDerNfMyaoveqBvoIGqCZdQTbwwE7v1qTgXA83wYwTtBitQLVqkr1RTOJQXAMbPv5Jg5czUY3+q4DejQSKOE9/XJfKGJkSRH6Hy2C2CJ3dLnzYUqWGO3t70RLT1/sC6p6w3lXdy3dKZGkoR2wva+HXQxVrP8X5HOResXgNZwgMHt9KF1QHVCcySKYiEAefEKTSdKD2fOd4FxLgp3zWpvH3jrX0zd/DqzTlFD5Ns6Ayp2sIfHVp3sn99DZZM6DauMepQKtoSCnXZ+qKhekAwNVJnsVQkSECgYEA4spY9araeFUSl4uXCUQOpCkSshYOPRYN6sBbHsx8tV2eQtCT+5SuNYmzur3c5bkiraGEab8rZfGdDL6fLxQyaqbOmN31Db5kNh/2X+sRnxkak8lsROUWQZRF9doH73FDv6ZlI3V/JicZlOUCfN5BYT+x74R4/c1YXfyuD1J9gr0CgYEA/4K4SDwZUY4bOVCmKQz0OM+RW4PAAH6LHKenTAZNTeDNFFxc2nqnzRGMEKZTDGy0kbT5mBhBHFgShXcAiKxc5/MGkpt8Jcq6Fr5KGU9aZtYKji6mwMTsUndPNQydh3vOt5pOmcuMM6ovanNTvI8k6Qo53OY1IpO5CfOROu0hm5kCgYBnWsYd92YnDsYxUEldzKlLgPhnNov4pNNk15LvP0vaL7cPRhUaw1B9T6scAKjp/GxkasZ4lsnFZM4o37qV7wNm/WwL2KN0Rv9Od1SFtBBMzFkDXvk7kJeK/XLAr0OMiLbSYZeYCFUQ4yLSa2et1nA/TJLf0CR/rhSGiMAedX6DlQKBgAx1137OT33GrFUzNacy1oYeuTv5RNfBVA9lrabrd8GggN/JUU3mRWCexnHZaptkgbnJVZKxPBuhv+V6VDBWF4HIPD3SD0/YfxK03PA3CnWRYppkdAValRvAbcBsiRIeW4pgoAyn/IJYfk92qFK9uFMVCJVZNKYnBhMSKbbx8X2hAoGBAKwvzyAImbNB+493q1R/lSayxzG76bRJ/EseiTqwIec9c4C+Bd/sVXR+Re+xZb0FI/va1bz5CrduTzLSKBmf/+0lzl0MJvWY2+SXfGYdbl4+TTyqgDDfwqW0Tj8pDimye2BneyTmXko1rF+2Sxen7kMXnJLwpqjwZ6TZJuoqeK8q - - peerId: 12D3KooWASsipDzkridiMBmE7VSqp8yZvGWPY1VqySgMSZk6tsiL + signingKey: CZTN+NFi4g9MA4BKl3OiCKuzXh63ukIvYWo9D5t9qfZcFwIeOW8eP9W8mtnXaY3JAFyb6GliBW0uCaw4wjRcCA== + encryptionKey: MIIEpAIBAAKCAQEAo9Nuypzg9kZ+LP+8jQgSTaoRUu8VFdJdCOEjuroPQK+2NwBD/Z9BqKiN0Z+jmhkI9yA0/Fwdh21ibAKX3Je9uffAKOhXI2sxIAlccDORu1kGDnhcc7N3L644DK+uFZvKnMQWiCwmtTnNHkoCzWcIE44G56wMa2c4W7mrOuRWqG6a5Z9JUuLqafOIlf6Dw2fiVM6xXiTIMQ0OyXByxFNjsS5O/PYcwoIKMV8MY+gUnAmyPLE0bslvz/8W+3E7d/LDO4lhqW+N1kDmboe6sc7DBf5JD4DLnP2VWV8Ae/rfJvxwu9ZqVT8RdYKMsZqvs9sV+6jQC9UcX+K8Q4Wdo0eMHwIDAQABAoIBAACR57zEtvOkYyP878b91DJ4+P503nno9XHmdp1bsFnlQpkGYzYqq6vOik/EYmlS1PknH4gROfkSpFkD2UtnK73N4tlBlawF33HhFnU9eLBSKvc56/hrE2sTDBbfNZfVpurMs9ddb/UJcnE8iK32QczvnY6IxrJI9aU8DCB0UujbGDnya/HbFU9pLLxu2EUoHNxjSHG/jCx+AR7JRknRA65KPZG7mu5jeAaaklYTY/aLGlctgecDKfNKDsZo6rgAMUW6ZXI8ogNGqfKHUFazCVe0l1tp4hxvgmyjcw79iKvFr4mlpHtgjYTFCeoMJKvOXUImZUJL0vCA6WKvUdIfzAECgYEA0lCTXYwOHqOwYMb1qi8lIIApcI//B/Nzn++MDQ4ZO4SzVJTTv4rSdXAuoihsO6E7LYZK+wdVNjiCbeMukfTqEfaxWXIsIDaHSR3440NsYSwdBz04UhRgpxFE2FwPK7J5dQ57FBaCAgksnO3XjcByBMYgMWVbA+ezIWfVdN96YoECgYEAx2mm/W4ZGdDyJgDonzEGGxfaNqo6DIv+67fDwI6WyqOWFWJTBaVFkm1uPJfcXYuTI9YCNFRKuRU7dyqSPLErMVusC/8Iww8++kqmkc1m04tbkqh4KpREYuMw8/tTYSWDwgpY8ksM5YRpYRJLTuuC0cEmefGco1RsXG8bYYeZXp8CgYBq5fexYcG/gxXgauBtSx9E4L+vbhGD2hNYJKr768GZhf6crDTgs8/7TzT0yTUSLgZlQlAUPgrqz1hEQGfoWiMrVEeanjSdfvnOiUR7R0bsMT7j8hMRbTgfUuC6VDiFzmZ7wAuBD1uvazhY329jpoCNuqKcWNclKfzbqupNSFXtgQKBgQCTlR7Qm0YadChydeOzxX2GWa3XHT7fAFFHNPa8MQtqp40xAFb/a6TEzRZz49RkqyLXt9Bj2CqBNjSPakNWhay41+bJ7hMXAdaTOOJ0L/c1AwNf1C0zHg5KvWgCefPohvIvjqbrkx3VU50GCZsQqn5kLLYENAvAWX/lHRm/obKhcwKBgQC/iAOC8ZdZC5w4F0Mf7roZWa9P/42JWlCMzm/I/5mEIn4mYY6+1C5V+fXoET6845oAh+P8CkH4waJtqqN6BKQhj7SKqoCHgGBCQy+HrSCBtzk7NuXdpz6sk14zfcVpjR3y3l9TuXc4cVQMSLAqg8yUQf+qnEQTit4jyfikV/5XEw== + - peerId: 12D3KooWDXDcBYxtZ8KNRoJebNgNAv9nFbQatQMoWm1BLwmQh6u7 address: 127.0.0.1:4432 - signingKey: /6+uYFwFf9nU6fvXQVtpHhjd8+v4dXc7esZzqkhjyfMJWlMiZOtQeb913FXofD5f20WksU0l6i22B09sFFYwDQ== - encryptionKey: MIIEogIBAAKCAQEAwCy84lzkxtzgn4ixGm0LSUTujOBpOh9m7XDoDPZnMTmExdOe9a5v/LXzdlCOCuBvK5u1T3ALBJMA3Zgvjv/jPRQUdiHprP3sbdfc6IgZPBFdLKFTc9yAA7GMbI4y7LhGMLGOMOqQXs+DOeImfmxEs3ykLXHKNas5ORnZPVnB6E9Qod8KH7UyMmBjQkOZYOOw10X4JZiU6xJp/E+VVWcmeXgNBbj5xOWMSzM+hhoA4wNOzBxACucaKDmqD6qugzebOqyUVSzFnEbquro+MYTWYdUDjZTXdvxgUUo80MGQ164gZhkFUKrmSpUvu3YErFySEGqAdFNwOZ6y/4X3s0BHvQIDAQABAoIBAAZiNhAK5+qXMbr67m8jSimv6YCyf6xXmLKwenTbxofDEl8D7ZbZqYyqeqDmgiFoXSkErhwqa6NGQtQZlxLX+zNvNFLMQ5fkg3MOpZ7vzm7JYN/3p+8EVxhIUJLWkmh8opBBhaioUg1kNUa59W9jp1CTBl0gF4h63JbB/g5kqeVOllUw7J1igAoaX36nOJGOwIynCWdizhDhgyjR4OcYfOLwcPDJueKTc5vM10g3LuMSK/sJmaD3TkJFPtDHw+RMW6wqyjsnkrg2D2oohXEyGWYYIXo2so4HCez0AB1I1JAxtVnRPvSIp7xLMm7+AkDoq12QYDHfxZtDTpfmvJg+Sn0CgYEAxCd+oribtdQW+JUctjsDbSQX5CeRISH5Ith3jveBx2jKIqQVnoVPz6URHOvnlIsqYYLANB8B3JHMWfR2UmkK11x0OcZecB06+oBoCZukvSXF+GqVHzLAQUxaoEBDCCPneskj5w+riMWBiiGDp32rUnkqv0nh7dnH+GfORcJ44L8CgYEA+s5s5EALj1jyU9w4+HVUyVsIrUitFnQg6qw/Td3Kj+8CXImKlS+rlmbQv0m1aOcvtFjQRIjjzZJAf/ausfAME+MayoNODgZsDk5RyDKuSWzMLvZLAa1LD52Uli5Pg8KtpzKVTn4xE1MbjsQcUNhFRAgrNEKNyuzXzdp4uXgGOoMCgYASXwiTQOsEepq0KXMI9jn57Nl3+uSyz7W/t7pq329+N6hG2ktUD3RMJE+X/9gup2IOw+owd377I4SaIDU8vq3PQc944cVShspRT9lunO8u7+y8uW7B/0TWWMpcG+irSIGTlGcSavtL0gOx5jWoaDK1hLemNss8NZtu/nnpOq+LjQKBgDisVozJMBOHPNLYS4NROAR77p0BdCNDwIBmxbM5r+EQWA9DAS6u4+4Lc5YV+MkonG37N6yU5iz4pFyGCHmqzX/c7JvgSc3/g4FED1TWpu1uiUD/ZHmPiAuSRxYchtk2L3k9g+GFwF8mg26iP+fAxv4VfnXDqDi3hhg9CtSWG4ozAoGAOWZXlFKqzGAfcucIe54FVQnweXG9sEuIPAvWvVRs4406ggNmL5eHccXpPHWTgetsr2TYMqPTDVMRmhBzSkyrYgk+b2tme79HPzTWs2Yg/pzjOfTgw7MBX/KlvOW5/J+dvrF3Gx8AHHZ9QQdYqi/MS1NKb2K3IbD0/m5gL5Pwi6A= + signingKey: c3D+0+BCl1xU35KBY+U3GPcU9aXdoLUiD4DJ2jF+IqI3CjGLhet3MBOkPXdIuPq/UpEqlp1k6FjNaU6DEU6Csg== + encryptionKey: MIIEpAIBAAKCAQEAuB7HsXuYmoif6/U4JnjC6L0QMu9qW1aPAxDrxWIedTzQhFZp3F3gYW/Zgdd2hvd0c2xyfhwf9C0X/UzfxWr54dDXzWNLN8BdVTik48cdYlgOmbgejiIjTaqSAlv4RtlqvooxCN0MwR2/RVAG/N5GqcAM7E4kJWPtvQYNl6wWCc92rKdutvmcj73wKzz9Hd/qdF612OVS3zRsjh3tJmYt55oovAUh1TAz/mSTTXjFHy35zLRBP+oQQsAOt2p0BOMSyOKZufGC8l3aZD//dp4/U/MaqCjeNuWxCfAZlSd+vt7T0aqDGdyRtrrGUcu4PCwXpOdbzw+uSZxnKawolYoEHwIDAQABAoIBAQCsxeVpvKtUx8QZrUCFiWiM8W0T/un0z+LfY696xzoBlZGtvVEVQtpdVJHsb31/5RFXhnphsI6jmPUb8llBbcMSjeETkItyw4ZRhBfmzl/aevsocEfr5EjwhpEAucDe6wJpzk95G8TuKrXjmtcTzpjMjbUSwbjVhVH/wIBcxVTg2j6z4AOADDRI5UsvZ0NV//If+nNzMjcuIji95PNk7lAuwsqkX3FycxvqXKUMGxRE2bgGMxaBRAP0kqL2vdxyS1M7wp/x04ZAtSnPXHe4qqmDOt69ec3XqbmZHOsZHzkCFePKcPB472/G0bPJeiq/idevEqS89RwvbphDtq3KGrRBAoGBAOrHqlPh36WZBOi6SueUmcrg579KDMUekgeea5payiySbRWztCL2yCYbSgFqSbyCLRppyXK51xvo8iUejR231or6u/nd7T0CON0Nf/8Qtbb13vtTGpIBiWYGqeDrWucUUlyS+K3sDfNk1AJqjUdaIMVu4yTpgzEvrdYCcT312RBPAoGBAMjC83/0EKnsbypFprxKS3Fbg963HhyKjfffQ2w4yncM6kxXF3ehVjg1LInok/6/dmy2LxkAf3r0YYZrGJWmG4Sv4UqHn6JxAjQgarPbdmGhJ8VIUMvMbZRsX3i8Z8D2o8k1M1kr6MYsQ53iX6q/Cp3gnucMeJPk6Xs9Q4TO7YsxAoGAWrXEOF6X01p4zBZWJH2Eoh8dSwooPuzdzPXHaz7SyD/Wx8DDw5KHqDl48W0Iij3dgUwIGjx1QQJStEbGjQnfaZkQkazOIXk/USELKBhjrQn4GjB0np7bYEEI1673UzrFy6C5VjFS/owhYcGbTksjSETcnAFgv9tFFd+hsyfOsv8CgYALk4o875LiaXrDgj6qDtKo17ET75Ux6h9jkqEtpVyvXrRH8KGuyUPSe+Z0kU+vWdT3Uc4HcArpyRuyh4xkXK6riQTBqm5fDIsm/FOKyXXbDVLgwlm+Vqxe6Zzbtml5K/+nw4SReMG0Y6sGeJ4xl1CCaAhhpEtzo7h+3bp99vylkQKBgQDDdR6N4wb3DHTzrW0EFb8XhXZN7CIE3EWhToNDsCkguUB7lwqD4p2c4yLscS0YAqxk7I3NW0nDaUV/340RrVtPJDqB4NZJ+MvhfvV3TW2FkZmru/iW+DMUsfZGAOPdQz9jLGAzUXrXFw/qGBtLIUL6UWqWLOrBO9QHb21nnB1Ssg== space: gcTTL: 60 - syncPeriod: 11 + syncPeriod: 600 storage: path: db metric: @@ -37,3 +37,6 @@ log: production: false defaultLevel: "" namedLevels: {} +stream: + timeoutMilliseconds: 1000 + maxMsgSizeMb: 256 diff --git a/node/api/service.go b/node/api/service.go index 9b39d618..710e0914 100644 --- a/node/api/service.go +++ b/node/api/service.go @@ -51,13 +51,16 @@ func (s *service) Name() (name string) { } func (s *service) Run(ctx context.Context) (err error) { - err = s.BaseDrpcServer.Run( - ctx, - s.cfg.APIServer.ListenAddrs, - func(handler drpc.Handler) drpc.Handler { + params := server.Params{ + BufferSizeMb: s.cfg.Stream.MaxMsgSizeMb, + TimeoutMillis: s.cfg.Stream.TimeoutMilliseconds, + ListenAddrs: s.cfg.APIServer.ListenAddrs, + Wrapper: func(handler drpc.Handler) drpc.Handler { return handler }, - s.transport.BasicListener) + Converter: s.transport.BasicListener, + } + err = s.BaseDrpcServer.Run(ctx, params) if err != nil { return } diff --git a/playground/Makefile b/playground/Makefile index c702c0c5..31151533 100644 --- a/playground/Makefile +++ b/playground/Makefile @@ -37,3 +37,8 @@ log-client-2: debug: @(echo "To run debug api please run './init.sh debug [params]' with respective args to debug client") + +run-all: nodes-start clients-start + sleep 3000000 + +run-clean: clean-all run-all diff --git a/playground/init.sh b/playground/init.sh index 8937deec..67bc0e2d 100755 --- a/playground/init.sh +++ b/playground/init.sh @@ -21,6 +21,7 @@ do_usage() { do_nodes_start() { for NUMBER in {1..3}; do install -d tmp/node$NUMBER/ tmp/log/ + export ANYPROF="127.0.0.1:607$NUMBER" (cd tmp/node$NUMBER && go run $NODE_GO -c $CONFIGS_DIR/node$NUMBER.yml &>../log/node$NUMBER.log) & NODE_PID=$! echo $NODE_PID >tmp/node$NUMBER.pid @@ -54,6 +55,7 @@ do_config_gen() { do_clients_start() { for NUMBER in {1..2}; do + export ANYPROF="127.0.0.1:606$NUMBER" install -d tmp/client$NUMBER/ tmp/log/ (cd tmp/client$NUMBER && go run $CLIENT_GO -c $CONFIGS_DIR/client$NUMBER.yml &>../log/client$NUMBER.log) & CLIENT_PID=$! diff --git a/util/cmd/debug/commands/scripts.go b/util/cmd/debug/commands/scripts.go index 6431912c..02fb6c55 100644 --- a/util/cmd/debug/commands/scripts.go +++ b/util/cmd/debug/commands/scripts.go @@ -58,7 +58,7 @@ func (s *service) registerScripts() { } for _, p := range addresses { wg.Add(1) - createMany(p) + go createMany(p) } wg.Wait() if mError.Err() != nil { diff --git a/util/cmd/nodesgen/gen.go b/util/cmd/nodesgen/gen.go index 3bbcd4ec..716dc85b 100644 --- a/util/cmd/nodesgen/gen.go +++ b/util/cmd/nodesgen/gen.go @@ -198,7 +198,11 @@ func genNodeConfig(addresses []string, apiAddresses []string) (config.Config, er }, Space: config.Space{ GCTTL: 60, - SyncPeriod: 11, + SyncPeriod: 600, + }, + Stream: config.Stream{ + TimeoutMilliseconds: 1000, + MaxMsgSizeMb: 256, }, }, nil } @@ -248,7 +252,11 @@ func genClientConfig(addresses []string, apiAddresses []string, encKey encryptio }, Space: config.Space{ GCTTL: 60, - SyncPeriod: 11, + SyncPeriod: 20, + }, + Stream: config.Stream{ + TimeoutMilliseconds: 1000, + MaxMsgSizeMb: 256, }, }, nil } @@ -295,5 +303,9 @@ func genConsensusConfig(addresses []string) (cconfig.Config, error) { Database: "consensus", LogCollection: "log", }, + Stream: config.Stream{ + TimeoutMilliseconds: 1000, + MaxMsgSizeMb: 256, + }, }, nil }