From b2cbee910bbe94adf33574f6e4274b9bb84d52c3 Mon Sep 17 00:00:00 2001 From: Godefroy Ponsinet Date: Thu, 24 Jan 2019 19:03:39 +0100 Subject: [PATCH] feat(chunk): first implementation Signed-off-by: Godefroy Ponsinet --- .../main/java/chat/berty/core/CoreModule.java | 17 +- client/react-native/gomobile/core/core.go | 16 +- .../react-native/gomobile/core/deviceinfo.go | 15 + .../gomobile/core/notification.go | 54 +- client/react-native/gomobile/core/options.go | 10 +- client/react-native/gomobile/go.mod | 2 +- client/react-native/gomobile/go.sum | 5 + .../ios/modules/core/CoreModule.swift | 8 +- core/api/p2p/envelope.proto | 1 + core/chunk/chunk.go | 135 ++++ core/chunk/chunk.pb.go | 617 ++++++++++++++++++ core/chunk/chunk.proto | 20 + core/chunk/logger.gen.go | 9 + core/chunk/pubsub.go | 64 ++ core/chunk/storage.go | 108 +++ core/cmd/berty/daemon.go | 4 +- core/manager/account/account.go | 7 +- core/manager/account/db.go | 9 +- core/node/push.go | 31 +- core/pkg/deviceinfo/storage.go | 29 + core/pkg/errorcodes/errors.pb.go | 287 ++++---- core/pkg/errorcodes/errors.proto | 15 + core/pkg/notification/notification.go | 12 +- core/push/apns.go | 34 +- core/push/fcm.go | 17 +- core/push/push.go | 2 +- go.sum | 19 + 27 files changed, 1331 insertions(+), 216 deletions(-) create mode 100644 client/react-native/gomobile/core/deviceinfo.go create mode 100644 core/chunk/chunk.go create mode 100644 core/chunk/chunk.pb.go create mode 100644 core/chunk/chunk.proto create mode 100644 core/chunk/logger.gen.go create mode 100644 core/chunk/pubsub.go create mode 100644 core/chunk/storage.go create mode 100644 core/pkg/deviceinfo/storage.go create mode 100644 go.sum diff --git a/client/react-native/android/app/src/main/java/chat/berty/core/CoreModule.java b/client/react-native/android/app/src/main/java/chat/berty/core/CoreModule.java index 9f8db91cfe..e494792717 100644 --- a/client/react-native/android/app/src/main/java/chat/berty/core/CoreModule.java +++ b/client/react-native/android/app/src/main/java/chat/berty/core/CoreModule.java @@ -23,12 +23,20 @@ public CoreModule(ReactApplicationContext reactContext) { super(reactContext); this.filesDir = reactContext.getFilesDir().getAbsolutePath(); + String storagePath = reactContext.getFilesDir().getAbsolutePath(); + try { + Core.getDeviceInfo().setStoragePath(storagePath); + } catch (Exception error) { + logger.format(Level.ERROR, this.getName(), error.getMessage()); + } + this.notificationDriver.setNative(new NotificationNative()); + // TODO: Get rid of this and make a proper react-native module that extends ReactContextBaseJavaModule // See https://facebook.github.io/react-native/docs/native-modules-android Object activityAndContextGetter = actGetter(reactContext); BleManager.setReactGetter(activityAndContextGetter, reactContext); - this.notificationDriver.setNative(new NotificationNative()); + } private Object actGetter(final ReactApplicationContext reactContext) { @@ -51,7 +59,7 @@ public String getName() { @ReactMethod public void listAccounts(Promise promise) { try { - String data = Core.listAccounts(this.filesDir); + String data = Core.listAccounts(); promise.resolve(data); } catch (Exception err) { this.logger.format(Level.ERROR, this.getName(), "Unable to list accounts: %s", err); @@ -62,7 +70,7 @@ public void listAccounts(Promise promise) { @ReactMethod public void initialize(Promise promise) { try { - Core.initialize(this.logger, this.filesDir); + Core.initialize(this.logger, Core.getDeviceInfo().getStoragePath()); promise.resolve(null); } catch (Exception err) { this.logger.format(Level.ERROR, this.getName(), "Unable to init core: %s", err); @@ -76,7 +84,6 @@ public void start(String nickname, Promise promise) { try { core.MobileOptions coreOptions = new core.MobileOptions() .withNickname(nickname) - .withDatastorePath(this.filesDir) .withLoggerDriver(this.logger); Core.start(coreOptions); @@ -112,7 +119,7 @@ public void throwException() throws Exception { @ReactMethod public void dropDatabase(Promise promise) { try { - Core.dropDatabase(this.filesDir); + Core.dropDatabase(); promise.resolve(null); } catch (Exception err) { this.logger.format(Level.ERROR, this.getName(), "Unable to drop database: %s", err); diff --git a/client/react-native/gomobile/core/core.go b/client/react-native/gomobile/core/core.go index b955812e55..d010943446 100644 --- a/client/react-native/gomobile/core/core.go +++ b/client/react-native/gomobile/core/core.go @@ -22,6 +22,8 @@ var ( NotificationDriver = MobileNotification{}.New() ) +// Setup call it at first native start + func logger() *zap.Logger { return zap.L().Named(defaultLoggerName) } @@ -81,10 +83,10 @@ func Initialize(loggerNative NativeLogger, datastorePath string) error { return nil } -func ListAccounts(datastorePath string) (string, error) { +func ListAccounts() (string, error) { defer panicHandler() - accounts, err := account.List(rootContext, datastorePath) + accounts, err := account.List(rootContext) if err != nil { return "", err } @@ -92,7 +94,7 @@ func ListAccounts(datastorePath string) (string, error) { return strings.Join(accounts, ":"), nil } -func initOrRestoreAppState(datastorePath string) error { +func initOrRestoreAppState() error { initialJSONNetConf, err := json.Marshal(initialNetConf) if err != nil { return err @@ -105,7 +107,7 @@ func initOrRestoreAppState(datastorePath string) error { LocalGRPC: initiallocalGRPC, } - appState, err := account.OpenStateDB(datastorePath+"/berty.state.db", initialState) + appState, err := account.OpenStateDB("./berty.state.db", initialState) if err != nil { return errors.Wrap(err, "state DB init failed") } @@ -133,7 +135,7 @@ func Start(cfg *MobileOptions) error { return nil } - if err := initOrRestoreAppState(cfg.datastorePath); err != nil { + if err := initOrRestoreAppState(); err != nil { return errors.Wrap(err, "app init/restore state failed") } @@ -154,7 +156,7 @@ func Restart() error { return nil } -func DropDatabase(datastorePath string) error { +func DropDatabase() error { defer panicHandler() currentAccount, err := account.Get(rootContext, accountName) @@ -218,7 +220,7 @@ func daemon(cfg *MobileOptions) error { account.WithPassphrase("secure"), account.WithNotificationDriver(NotificationDriver), account.WithDatabase(&account.DatabaseOptions{ - Path: cfg.datastorePath, + Path: ".", Drop: false, }), account.WithP2PNetwork(netConf), diff --git a/client/react-native/gomobile/core/deviceinfo.go b/client/react-native/gomobile/core/deviceinfo.go new file mode 100644 index 0000000000..10aea83a9a --- /dev/null +++ b/client/react-native/gomobile/core/deviceinfo.go @@ -0,0 +1,15 @@ +package core + +import "berty.tech/core/pkg/deviceinfo" + +type DeviceInfoPkg struct{} + +var DeviceInfo = &DeviceInfoPkg{} + +func (*DeviceInfoPkg) GetStoragePath() string { + return deviceinfo.GetStoragePath() +} + +func (*DeviceInfoPkg) SetStoragePath(path string) error { + return deviceinfo.SetStoragePath(path) +} diff --git a/client/react-native/gomobile/core/notification.go b/client/react-native/gomobile/core/notification.go index 54080de44d..52e213e55f 100644 --- a/client/react-native/gomobile/core/notification.go +++ b/client/react-native/gomobile/core/notification.go @@ -1,11 +1,15 @@ package core import ( - "fmt" + "encoding/base64" + "encoding/json" "sync" + "berty.tech/core/chunk" + "berty.tech/core/pkg/errorcodes" "berty.tech/core/pkg/notification" "berty.tech/core/push" + "github.com/pkg/errors" "go.uber.org/zap" ) @@ -20,28 +24,48 @@ type NativeNotificationDriver interface { type MobileNotification struct { Native NativeNotificationDriver - subscribers []chan *notification.Payload + subscribers []chan []byte subscribersMutex sync.Mutex tokenSubscribers []chan *notification.Token tokenSubscribersMutex sync.Mutex } func (n MobileNotification) New() *MobileNotification { - return &MobileNotification{ - subscribers: []chan *notification.Payload{}, + m := &MobileNotification{ + subscribers: []chan []byte{}, tokenSubscribers: []chan *notification.Token{}, } + return m } func (n *MobileNotification) Receive(data string) { - logger().Debug(fmt.Sprintf("receive notification: %+v", data)) - n.subscribersMutex.Lock() - for i := range n.subscribers { - n.subscribers[i] <- ¬ification.Payload{ - Body: data, - } + payload := push.Payload{} + if err := json.Unmarshal([]byte(data), &payload); err != nil { + logger().Error(errorcodes.ErrNodePushNotifSub.Wrap(err).Error()) + return + } + + b64Chunk := payload.Chunk + if b64Chunk == "" { + logger().Error(errorcodes.ErrNotificationReceive.Wrap(errors.New("chunk is missing")).Error()) + return + } + + bytesChunk, err := base64.StdEncoding.DecodeString(string(b64Chunk)) + if err != nil { + logger().Error(errorcodes.ErrNotificationReceive.Wrap(err).Error()) + return + } + + c := &chunk.Chunk{} + if err := c.Unmarshal(bytesChunk); err != nil { + logger().Error(errorcodes.ErrNotificationReceive.Wrap(err).Error()) + return + } + + if err := chunk.Publish(c); err != nil { + logger().Error(errorcodes.ErrNotificationReceive.Wrap(err).Error()) } - n.subscribersMutex.Unlock() } func (n *MobileNotification) ReceiveAPNSToken(token []byte) { @@ -66,18 +90,18 @@ func (n *MobileNotification) ReceiveToken(token *notification.Token) { n.tokenSubscribers[i] <- token } n.tokenSubscribersMutex.Unlock() - } -func (n *MobileNotification) Subscribe() chan *notification.Payload { - sub := make(chan *notification.Payload, 1) +func (n *MobileNotification) Subscribe() chan []byte { + // let chunk manager send reconstructed data + sub := chunk.Subscribe() n.subscribersMutex.Lock() n.subscribers = append(n.subscribers, sub) n.subscribersMutex.Unlock() return sub } -func (n *MobileNotification) Unsubscribe(sub chan *notification.Payload) { +func (n *MobileNotification) Unsubscribe(sub chan []byte) { n.subscribersMutex.Lock() for i := range n.subscribers { if sub == n.subscribers[i] { diff --git a/client/react-native/gomobile/core/options.go b/client/react-native/gomobile/core/options.go index 50a41d4171..d7a187968c 100644 --- a/client/react-native/gomobile/core/options.go +++ b/client/react-native/gomobile/core/options.go @@ -1,14 +1,8 @@ package core type MobileOptions struct { - logger NativeLogger - datastorePath string - nickname string -} - -func (cfg *MobileOptions) WithDatastorePath(path string) *MobileOptions { - cfg.datastorePath = path - return cfg + logger NativeLogger + nickname string } func (cfg *MobileOptions) WithLoggerDriver(logger NativeLogger) *MobileOptions { diff --git a/client/react-native/gomobile/go.mod b/client/react-native/gomobile/go.mod index caf80274c8..81de782767 100644 --- a/client/react-native/gomobile/go.mod +++ b/client/react-native/gomobile/go.mod @@ -5,7 +5,7 @@ require ( github.com/libp2p/go-buffer-pool v0.1.2-0.20181009094743-058210c5a0d0 // indirect github.com/pkg/errors v0.8.0 go.uber.org/zap v1.9.1 - golang.org/x/mobile v0.0.0-20181026062114-a27dd33d354d // indirect + golang.org/x/mobile v0.0.0-20190127143845-a42111704963 // indirect ) replace berty.tech/core v0.0.0 => ../../../core diff --git a/client/react-native/gomobile/go.sum b/client/react-native/gomobile/go.sum index e18644f53c..c80459caac 100644 --- a/client/react-native/gomobile/go.sum +++ b/client/react-native/gomobile/go.sum @@ -565,7 +565,12 @@ golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 h1:mKdxBk7AujPs8kU4m80U72y/zjbZ3UcXC7dClwKbUI0= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/mobile v0.0.0-20181026062114-a27dd33d354d h1:DuZZDdMFwDrzmycNhCaWSve7Vh+BIrjm7ttgb4fD3Os= golang.org/x/mobile v0.0.0-20181026062114-a27dd33d354d/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190125201028-feefccb6c1c9 h1:guhfyRQZ6kHMDmc247p+xD6JPKdNknxn8CTyEYg59k8= +golang.org/x/mobile v0.0.0-20190125201028-feefccb6c1c9/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190127143845-a42111704963 h1:2HSxAhImj2OpXsNjXSqfnv1xtqeCpDjwPB3o1DnQqKM= +golang.org/x/mobile v0.0.0-20190127143845-a42111704963/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/net v0.0.0-20180524181706-dfa909b99c79/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180816102801-aaf60122140d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= diff --git a/client/react-native/ios/modules/core/CoreModule.swift b/client/react-native/ios/modules/core/CoreModule.swift index 2115e6a6a9..30b7bca48a 100644 --- a/client/react-native/ios/modules/core/CoreModule.swift +++ b/client/react-native/ios/modules/core/CoreModule.swift @@ -22,6 +22,12 @@ class CoreModule: NSObject { override init() { super.init() Core.notificationDriver()?.native = Notification() + let storagePath = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first?.path + do { + try Core.deviceInfo().setStoragePath(storagePath) + } catch let error as NSError { + logger.format("unable to set storage path", level: .error, error.userInfo.description) + } } func getFilesDir() throws -> String { @@ -40,7 +46,7 @@ class CoreModule: NSObject { var err: NSError? do { - CoreInitialize(logger, try self.getFilesDir(), &err) + CoreInitialize(logger, Core.storagePath(), &err) if let error = err { throw error } diff --git a/core/api/p2p/envelope.proto b/core/api/p2p/envelope.proto index cda6733ab6..4af3bf5fe2 100644 --- a/core/api/p2p/envelope.proto +++ b/core/api/p2p/envelope.proto @@ -13,3 +13,4 @@ message Envelope { keypair.Signature signature = 3; string source = 4; } + diff --git a/core/chunk/chunk.go b/core/chunk/chunk.go new file mode 100644 index 0000000000..9fbfd35561 --- /dev/null +++ b/core/chunk/chunk.go @@ -0,0 +1,135 @@ +package chunk + +import ( + fmt "fmt" + "sync" + + "berty.tech/core/pkg/errorcodes" + "github.com/gofrs/uuid" + "github.com/jinzhu/gorm" +) + +var ( + db *gorm.DB + + subscribers = []chan []byte{} + subscribersMutex sync.Mutex +) + +// Validate validate chunk slice +func validate(slice []*Chunk) error { + sliceID := slice[0].SliceID + n := slice[0].SliceLength + + if int(n) != len(slice) { + return errorcodes.ErrChunkSliceNotComplete.New() + } + for i := range slice { + if slice[i].SliceID != sliceID { + return errorcodes.ErrChunkBadSliceID.New() + } + if slice[i].SliceLength != n { + return errorcodes.ErrChunkBadSliceLength.New() + } + if slice[i].Data == nil { + return errorcodes.ErrChunkBadData.New() + } + for j := range slice { + if slice[i] != slice[j] && slice[i].Index == slice[j].Index { + return errorcodes.ErrChunkBadIndex.New() + } + } + } + return nil +} + +func Reconstruct(slice []*Chunk) ([]byte, error) { + err := validate(slice) + if err != nil && err != errorcodes.ErrChunkSliceNotComplete.New() { + logger().Debug("bad chunk slice, delete all chunks") + for i := range slice { + db.Delete(slice[i]) + } + return nil, errorcodes.ErrChunkBadSlice.Wrap(err) + } + if err != nil { + return nil, err + } + + data := []byte{} + for i := range slice { + data = append(data, slice[i].Data...) + } + + return data, nil +} + +func ReconstructMarshal(sliceMarshal [][]byte) ([]byte, error) { + slice := []*Chunk{} + for _, bytes := range sliceMarshal { + chunk := &Chunk{} + if err := chunk.Unmarshal(bytes); err != nil { + return nil, err + } + slice = append(slice, chunk) + } + return Reconstruct(slice) +} + +// Split split data in chunk slice +func Split(data []byte, chunkSize int) ([]*Chunk, error) { + sliceID := uuid.Must(uuid.NewV4()).String() + + // id len = slitID + ":" + index + idLen := len(sliceID) + 20 + + // update the chunkSize based on marshalled size + chunkSize = chunkSize - len(sliceID) - idLen + + // define number of chunk + length := int32(len(data) / chunkSize) + + // if there is a rest, increase n + rest := len(data) % chunkSize + if rest != 0 { + length++ + } + + slice := make([]*Chunk, length) + for i := range slice { + offset := i * chunkSize + + // if it's the last chunk and there is a rest, rest will be its size + isLast := i == (len(slice) - 1) + if isLast && rest != 0 { + chunkSize = rest + } + + slice[i] = &Chunk{ + ID: fmt.Sprintf("%+v:%+v", sliceID, i), + Index: int32(i), + Data: data[offset : offset+chunkSize], + SliceID: sliceID, + SliceLength: int32(length), + } + } + + return slice, nil +} + +func SplitMarshal(data []byte, chunkSize int) ([][]byte, error) { + // split with marshal size + slice, err := Split(data, chunkSize-(&Chunk{ID: "1", Index: 1, Data: []byte{1}, SliceID: "1", SliceLength: 1}).Size()) + if err != nil { + return nil, err + } + marshalSlice := [][]byte{} + for _, chunk := range slice { + bytes, err := chunk.Marshal() + if err != nil { + return nil, err + } + marshalSlice = append(marshalSlice, bytes) + } + return marshalSlice, nil +} diff --git a/core/chunk/chunk.pb.go b/core/chunk/chunk.pb.go new file mode 100644 index 0000000000..a11e67e063 --- /dev/null +++ b/core/chunk/chunk.pb.go @@ -0,0 +1,617 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: chunk/chunk.proto + +package chunk // import "berty.tech/core/chunk" + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "github.com/gogo/protobuf/gogoproto" +import _ "github.com/golang/protobuf/ptypes/timestamp" + +import time "time" + +import github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" + +import io "io" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf +var _ = time.Kitchen + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +type Chunk struct { + ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty" gorm:"primary_key"` + CreatedAt time.Time `protobuf:"bytes,2,opt,name=created_at,json=createdAt,stdtime" json:"created_at"` + UpdatedAt time.Time `protobuf:"bytes,3,opt,name=updated_at,json=updatedAt,stdtime" json:"updated_at"` + Index int32 `protobuf:"varint,4,opt,name=index,proto3" json:"index,omitempty"` + Data []byte `protobuf:"bytes,5,opt,name=data,proto3" json:"data,omitempty"` + SliceID string `protobuf:"bytes,6,opt,name=slice_id,json=sliceId,proto3" json:"slice_id,omitempty"` + SliceLength int32 `protobuf:"varint,7,opt,name=slice_length,json=sliceLength,proto3" json:"slice_length,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Chunk) Reset() { *m = Chunk{} } +func (m *Chunk) String() string { return proto.CompactTextString(m) } +func (*Chunk) ProtoMessage() {} +func (*Chunk) Descriptor() ([]byte, []int) { + return fileDescriptor_chunk_a750599d04cec2fe, []int{0} +} +func (m *Chunk) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Chunk) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Chunk.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (dst *Chunk) XXX_Merge(src proto.Message) { + xxx_messageInfo_Chunk.Merge(dst, src) +} +func (m *Chunk) XXX_Size() int { + return m.Size() +} +func (m *Chunk) XXX_DiscardUnknown() { + xxx_messageInfo_Chunk.DiscardUnknown(m) +} + +var xxx_messageInfo_Chunk proto.InternalMessageInfo + +func (m *Chunk) GetID() string { + if m != nil { + return m.ID + } + return "" +} + +func (m *Chunk) GetCreatedAt() time.Time { + if m != nil { + return m.CreatedAt + } + return time.Time{} +} + +func (m *Chunk) GetUpdatedAt() time.Time { + if m != nil { + return m.UpdatedAt + } + return time.Time{} +} + +func (m *Chunk) GetIndex() int32 { + if m != nil { + return m.Index + } + return 0 +} + +func (m *Chunk) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +func (m *Chunk) GetSliceID() string { + if m != nil { + return m.SliceID + } + return "" +} + +func (m *Chunk) GetSliceLength() int32 { + if m != nil { + return m.SliceLength + } + return 0 +} + +func init() { + proto.RegisterType((*Chunk)(nil), "berty.chunk.Chunk") +} +func (m *Chunk) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Chunk) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.ID) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintChunk(dAtA, i, uint64(len(m.ID))) + i += copy(dAtA[i:], m.ID) + } + dAtA[i] = 0x12 + i++ + i = encodeVarintChunk(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.CreatedAt))) + n1, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreatedAt, dAtA[i:]) + if err != nil { + return 0, err + } + i += n1 + dAtA[i] = 0x1a + i++ + i = encodeVarintChunk(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.UpdatedAt))) + n2, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.UpdatedAt, dAtA[i:]) + if err != nil { + return 0, err + } + i += n2 + if m.Index != 0 { + dAtA[i] = 0x20 + i++ + i = encodeVarintChunk(dAtA, i, uint64(m.Index)) + } + if len(m.Data) > 0 { + dAtA[i] = 0x2a + i++ + i = encodeVarintChunk(dAtA, i, uint64(len(m.Data))) + i += copy(dAtA[i:], m.Data) + } + if len(m.SliceID) > 0 { + dAtA[i] = 0x32 + i++ + i = encodeVarintChunk(dAtA, i, uint64(len(m.SliceID))) + i += copy(dAtA[i:], m.SliceID) + } + if m.SliceLength != 0 { + dAtA[i] = 0x38 + i++ + i = encodeVarintChunk(dAtA, i, uint64(m.SliceLength)) + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func encodeVarintChunk(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *Chunk) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ID) + if l > 0 { + n += 1 + l + sovChunk(uint64(l)) + } + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.CreatedAt) + n += 1 + l + sovChunk(uint64(l)) + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.UpdatedAt) + n += 1 + l + sovChunk(uint64(l)) + if m.Index != 0 { + n += 1 + sovChunk(uint64(m.Index)) + } + l = len(m.Data) + if l > 0 { + n += 1 + l + sovChunk(uint64(l)) + } + l = len(m.SliceID) + if l > 0 { + n += 1 + l + sovChunk(uint64(l)) + } + if m.SliceLength != 0 { + n += 1 + sovChunk(uint64(m.SliceLength)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func sovChunk(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozChunk(x uint64) (n int) { + return sovChunk(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Chunk) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChunk + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Chunk: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Chunk: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChunk + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthChunk + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CreatedAt", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChunk + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthChunk + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.CreatedAt, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UpdatedAt", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChunk + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthChunk + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.UpdatedAt, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType) + } + m.Index = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChunk + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Index |= (int32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChunk + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthChunk + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SliceID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChunk + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthChunk + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SliceID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SliceLength", wireType) + } + m.SliceLength = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChunk + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SliceLength |= (int32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipChunk(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthChunk + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipChunk(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowChunk + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowChunk + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowChunk + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + iNdEx += length + if length < 0 { + return 0, ErrInvalidLengthChunk + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowChunk + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipChunk(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthChunk = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowChunk = fmt.Errorf("proto: integer overflow") +) + +func init() { proto.RegisterFile("chunk/chunk.proto", fileDescriptor_chunk_a750599d04cec2fe) } + +var fileDescriptor_chunk_a750599d04cec2fe = []byte{ + // 332 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x91, 0xbd, 0x4e, 0xfb, 0x30, + 0x14, 0xc5, 0xeb, 0xfc, 0x9b, 0x7e, 0x38, 0x5d, 0xfe, 0x56, 0x91, 0xa2, 0x0a, 0xc5, 0xa1, 0x03, + 0x64, 0x40, 0x89, 0x04, 0x1b, 0x5b, 0x3f, 0x96, 0x4a, 0x4c, 0x81, 0x89, 0xa5, 0x72, 0x63, 0xe3, + 0x5a, 0x6d, 0xea, 0xc8, 0x75, 0x25, 0xfa, 0x16, 0x8c, 0x3c, 0x08, 0x0f, 0xd1, 0x91, 0x27, 0x08, + 0x28, 0xbc, 0x01, 0x4f, 0x80, 0x62, 0xb7, 0x0f, 0xc0, 0x62, 0x1d, 0x9f, 0x7b, 0xef, 0x4f, 0xe7, + 0xea, 0xc2, 0xff, 0xd9, 0x72, 0xb7, 0x59, 0x25, 0xe6, 0x8d, 0x0b, 0x25, 0xb5, 0x44, 0xde, 0x82, + 0x29, 0xbd, 0x8f, 0x8d, 0x35, 0xc0, 0x5c, 0x4a, 0xbe, 0x66, 0x89, 0x29, 0x2d, 0x76, 0xcf, 0x89, + 0x16, 0x39, 0xdb, 0x6a, 0x92, 0x17, 0xb6, 0x7b, 0xd0, 0xe7, 0x92, 0x4b, 0x23, 0x93, 0x5a, 0x59, + 0x77, 0xf8, 0xee, 0x40, 0x77, 0x52, 0x03, 0xd0, 0x35, 0x74, 0x04, 0xf5, 0x41, 0x08, 0xa2, 0xee, + 0xf8, 0xbc, 0x2a, 0xb1, 0x33, 0x9b, 0xfe, 0x94, 0x18, 0x71, 0xa9, 0xf2, 0xbb, 0x61, 0xa1, 0x44, + 0x4e, 0xd4, 0x7e, 0xbe, 0x62, 0xfb, 0x61, 0xea, 0x08, 0x8a, 0x26, 0x10, 0x66, 0x8a, 0x11, 0xcd, + 0xe8, 0x9c, 0x68, 0xdf, 0x09, 0x41, 0xe4, 0xdd, 0x0c, 0x62, 0x9b, 0x21, 0x3e, 0x65, 0x88, 0x1f, + 0x4f, 0x19, 0xc6, 0x9d, 0x43, 0x89, 0x1b, 0xaf, 0x9f, 0x18, 0xa4, 0xdd, 0xe3, 0xdc, 0x48, 0xd7, + 0x90, 0x5d, 0x41, 0x4f, 0x90, 0x7f, 0x7f, 0x81, 0x1c, 0xe7, 0x46, 0x1a, 0xf5, 0xa1, 0x2b, 0x36, + 0x94, 0xbd, 0xf8, 0xcd, 0x10, 0x44, 0x6e, 0x6a, 0x3f, 0x08, 0xc1, 0x26, 0x25, 0x9a, 0xf8, 0x6e, + 0x08, 0xa2, 0x5e, 0x6a, 0x34, 0xba, 0x84, 0x9d, 0xed, 0x5a, 0x64, 0x6c, 0x2e, 0xa8, 0xdf, 0x32, + 0x7b, 0x7a, 0x55, 0x89, 0xdb, 0x0f, 0xb5, 0x37, 0x9b, 0xa6, 0x6d, 0x53, 0x9c, 0x51, 0x74, 0x01, + 0x7b, 0xb6, 0x6f, 0xcd, 0x36, 0x5c, 0x2f, 0xfd, 0xb6, 0x01, 0x7b, 0xc6, 0xbb, 0x37, 0xd6, 0xf8, + 0xea, 0x50, 0x05, 0xe0, 0xa3, 0x0a, 0xc0, 0x57, 0x15, 0x80, 0xb7, 0xef, 0xa0, 0xf1, 0x74, 0x66, + 0x8f, 0xa1, 0x59, 0xb6, 0x4c, 0x32, 0xa9, 0x98, 0xbd, 0xd4, 0xa2, 0x65, 0xd6, 0xb8, 0xfd, 0x0d, + 0x00, 0x00, 0xff, 0xff, 0x46, 0x1e, 0x18, 0xd8, 0xbf, 0x01, 0x00, 0x00, +} diff --git a/core/chunk/chunk.proto b/core/chunk/chunk.proto new file mode 100644 index 0000000000..fdae9e45f5 --- /dev/null +++ b/core/chunk/chunk.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; + +package berty.chunk; + +option go_package = "berty.tech/core/chunk"; + +import "google/protobuf/timestamp.proto"; +import "gogoproto/gogo.proto"; + +message Chunk { + string id = 1 [(gogoproto.moretags) = "gorm:\"primary_key\"", (gogoproto.customname) = "ID"]; + + google.protobuf.Timestamp created_at = 2 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; + google.protobuf.Timestamp updated_at = 3 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; + + int32 index = 4; + bytes data = 5; + string slice_id = 6 [(gogoproto.customname) = "SliceID"]; + int32 slice_length = 7; +} diff --git a/core/chunk/logger.gen.go b/core/chunk/logger.gen.go new file mode 100644 index 0000000000..9f3550df0e --- /dev/null +++ b/core/chunk/logger.gen.go @@ -0,0 +1,9 @@ +// Code generated by berty.tech/core/.scripts/generate-logger.sh + +package chunk + +import "go.uber.org/zap" + +func logger() *zap.Logger { + return zap.L().Named("core.chunk") +} diff --git a/core/chunk/pubsub.go b/core/chunk/pubsub.go new file mode 100644 index 0000000000..1a961876d7 --- /dev/null +++ b/core/chunk/pubsub.go @@ -0,0 +1,64 @@ +package chunk + +import "berty.tech/core/pkg/errorcodes" + +func send(data []byte) { + subscribersMutex.Lock() + for i := range subscribers { + subscribers[i] <- data + } + subscribersMutex.Unlock() +} + +func sendAll() { + slices, err := findAllSlices() + if err != nil { + return + } + for _, slice := range slices { + data, err := Reconstruct(slice) + if err == nil { + send(data) + } + } +} + +func Subscribe() chan []byte { + sub := make(chan []byte, 1) + subscribersMutex.Lock() + subscribers = append(subscribers, sub) + subscribersMutex.Unlock() + go sendAll() + return sub +} + +func Unsubscribe(sub chan []byte) { + subscribersMutex.Lock() + for i := range subscribers { + if sub == subscribers[i] { + subscribers = append(subscribers[:i], subscribers[i+1:]...) + } + } + subscribersMutex.Unlock() + close(sub) +} + +func Publish(chunk *Chunk) error { + err := save(chunk) + if err != nil { + return errorcodes.ErrChunkPublish.Wrap(err) + } + // try to retrieve slice + go func() { + slice, err := findSliceByID(chunk.SliceID) + if err != nil { + return + } + data, err := Reconstruct(slice) + if err != nil { + return + } + send(data) + }() + return nil +} diff --git a/core/chunk/storage.go b/core/chunk/storage.go new file mode 100644 index 0000000000..e9b4dc4852 --- /dev/null +++ b/core/chunk/storage.go @@ -0,0 +1,108 @@ +package chunk + +import ( + time "time" + + "berty.tech/core/pkg/deviceinfo" + "berty.tech/core/pkg/errorcodes" + "berty.tech/core/sql/sqlcipher" + "github.com/go-gormigrate/gormigrate" + "github.com/jinzhu/gorm" + "go.uber.org/zap" +) + +type zapLogger struct { + logger *zap.Logger +} + +func (l *zapLogger) Print(values ...interface{}) { + if len(values) < 2 { + return + } + + switch values[0] { + case "sql": + l.logger.Debug("gorm.debug.sql", + zap.String("query", values[3].(string)), + zap.Any("values", values[4]), + zap.Duration("duration", values[2].(time.Duration)), + zap.Int64("affected-rows", values[5].(int64)), + zap.String("source", values[1].(string)), // if AddCallerSkip(6) is well defined, we can safely remove this field + ) + default: + l.logger.Debug("gorm.debug.other", + zap.Any("values", values[2:]), + zap.String("source", values[1].(string)), // if AddCallerSkip(6) is well defined, we can safely remove this field + ) + } +} + +func openDatabase() error { + var err error + + // create storage directory if not exist + + db, err = sqlcipher.Open(deviceinfo.GetStoragePath()+"/berty.core.chunk.db", []byte("s3cur3")) + if err != nil { + return errorcodes.ErrChunkDaemonOpenDatabase.Wrap(err) + } + + // init db + db = db.Set("gorm:auto_preload", true) + db = db.Set("gorm:association_autoupdate", false) + db = db.Unscoped() + db.SetLogger(&zapLogger{logger: zap.L().Named("chunk.gorm")}) + db.SingularTable(true) + db.BlockGlobalUpdate(true) + db.LogMode(true) + + // migrate db + if err = gormigrate.New(db, gormigrate.DefaultOptions, []*gormigrate.Migration{ + { + ID: "1", + Migrate: func(tx *gorm.DB) error { + return tx.AutoMigrate(&Chunk{}).Error + }, + Rollback: func(tx *gorm.DB) error { return nil }, + }, + }).Migrate(); err != nil { + return err + } + return nil +} + +func save(chunk *Chunk) error { + for db == nil || db.DB().Ping() != nil { + if err := openDatabase(); err == nil { + break + } + } + if err := db.Save(chunk).Error; err != nil { + return errorcodes.ErrChunkSave.Wrap(err) + } + return nil +} + +func findAllSlices() ([][]*Chunk, error) { + firstChunks := []*Chunk{} + if err := db.Where(&Chunk{Index: 0}).Find(firstChunks).Error; err != nil { + return nil, errorcodes.ErrChunkFindAllSlices.Wrap(err) + } + slices := [][]*Chunk{} + for _, chunk := range firstChunks { + slice, err := findSliceByID(chunk.SliceID) + if err != nil { + continue + } + slices = append(slices, slice) + } + return slices, nil +} + +func findSliceByID(sliceID string) ([]*Chunk, error) { + slice := []*Chunk{} + if err := db.Order("index").Where(&Chunk{SliceID: sliceID}).Find(slice).Error; err != nil { + return nil, errorcodes.ErrChunkFindSliceByID.Wrap(err) + } + return slice, nil +} diff --git a/core/cmd/berty/daemon.go b/core/cmd/berty/daemon.go index c026b3d80b..ce341b9cd3 100644 --- a/core/cmd/berty/daemon.go +++ b/core/cmd/berty/daemon.go @@ -11,6 +11,7 @@ import ( "berty.tech/core/manager/account" "berty.tech/core/network/p2p" "berty.tech/core/pkg/banner" + "berty.tech/core/pkg/deviceinfo" "berty.tech/core/pkg/logmanager" "berty.tech/core/pkg/notification" "berty.tech/core/push" @@ -101,13 +102,14 @@ func daemon(opts *daemonOptions) error { defer func() { _ = logmanager.G().LogRotate() }() + deviceinfo.SetStoragePath("/tmp") accountOptions := account.Options{ account.WithJaegerAddrName(jaegerAddr, jaegerName+":node"), account.WithRing(logmanager.G().Ring()), account.WithName(opts.nickname), account.WithPassphrase(opts.sql.key), account.WithDatabase(&account.DatabaseOptions{ - Path: "/tmp", + Path: ".", Drop: opts.dropDatabase, }), account.WithBanner(banner.QOTD()), diff --git a/core/manager/account/account.go b/core/manager/account/account.go index 9abe435698..e778945db7 100644 --- a/core/manager/account/account.go +++ b/core/manager/account/account.go @@ -21,6 +21,7 @@ import ( "berty.tech/core/network" "berty.tech/core/network/netutil" "berty.tech/core/node" + "berty.tech/core/pkg/deviceinfo" "berty.tech/core/pkg/errorcodes" "berty.tech/core/pkg/i18n" "berty.tech/core/pkg/notification" @@ -147,14 +148,14 @@ func Get(ctx context.Context, name string) (*Account, error) { return nil, errorcodes.ErrAccManagerNotOpened.NewArgs(map[string]string{"name": name}) } -func List(ctx context.Context, datastorePath string) ([]string, error) { - tracer := tracing.EnterFunc(ctx, datastorePath) +func List(ctx context.Context) ([]string, error) { + tracer := tracing.EnterFunc(ctx) defer tracer.Finish() // ctx = tracer.Context() var names []string - err := filepath.Walk(datastorePath, func(path string, info os.FileInfo, err error) error { + err := filepath.Walk(deviceinfo.GetStoragePath(), func(path string, info os.FileInfo, err error) error { logger().Debug("List", zap.String("path", path)) name := filepath.Base(path) match, _ := filepath.Match("berty.*.db", name) diff --git a/core/manager/account/db.go b/core/manager/account/db.go index 37413037e7..1c68a4485a 100644 --- a/core/manager/account/db.go +++ b/core/manager/account/db.go @@ -2,9 +2,9 @@ package account import ( "encoding/json" - "errors" "fmt" + "berty.tech/core/pkg/deviceinfo" "berty.tech/core/pkg/tracing" "github.com/jinzhu/gorm" opentracing "github.com/opentracing/opentracing-go" @@ -27,7 +27,7 @@ type StateDB struct { func OpenStateDB(path string, initialState StateDB) (*StateDB, error) { // open db - db, err := gorm.Open("sqlite3", path) + db, err := gorm.Open("sqlite3", deviceinfo.GetStoragePath()+"/"+path) if err != nil { return nil, err } @@ -105,10 +105,7 @@ func WithDatabase(opts *DatabaseOptions) NewOption { opts = &DatabaseOptions{} } - a.dbDir = opts.Path - if a.dbDir == "" { - return errors.New("cannot have empty database path") - } + a.dbDir = deviceinfo.GetStoragePath() + "/" + opts.Path a.dbDrop = opts.Drop if err := a.openDatabase(ctx); err != nil { diff --git a/core/node/push.go b/core/node/push.go index a2e8522d86..5c850d1549 100644 --- a/core/node/push.go +++ b/core/node/push.go @@ -3,8 +3,6 @@ package node import ( "bytes" "context" - "encoding/base64" - "encoding/json" "berty.tech/core/api/node" "berty.tech/core/api/p2p" @@ -12,7 +10,6 @@ import ( "berty.tech/core/pkg/deviceinfo" "berty.tech/core/pkg/errorcodes" "berty.tech/core/push" - "github.com/pkg/errors" "go.uber.org/zap" ) @@ -94,36 +91,16 @@ func (n *Node) UsePushNotificationSubscriber(ctx context.Context) { for { select { - case notification := <-notificationSubscription: + case bytes := <-notificationSubscription: { - logger().Debug("node receive push notification") - - payload := push.Payload{} - if err := json.Unmarshal([]byte(notification.Body), &payload); err != nil { - logger().Error(errorcodes.ErrNodePushNotifSub.Wrap(err).Error()) - continue - } - - b64Envelope := payload.BertyEnvelope - if b64Envelope == "" { - logger().Error(errorcodes.ErrNodePushNotifSub.Wrap(errors.New("berty-envelope is missing")).Error()) - continue - } - - bytesEnvelope, err := base64.StdEncoding.DecodeString(string(b64Envelope)) - if err != nil { - logger().Error(errorcodes.ErrNodePushNotifSub.Wrap(err).Error()) - continue - } - envelope := &p2p.Envelope{} - if err := envelope.Unmarshal(bytesEnvelope); err != nil { - logger().Error(errorcodes.ErrNodePushNotifSub.Wrap(err).Error()) + if err := envelope.Unmarshal(bytes); err != nil { + logger().Warn(errorcodes.ErrNodePushNotifSub.Wrap(err).Error()) continue } if err := n.handleEnvelope(ctx, envelope); err != nil { - logger().Error(errorcodes.ErrNodePushNotifSub.Wrap(err).Error()) + logger().Warn(errorcodes.ErrNodePushNotifSub.Wrap(err).Error()) continue } } diff --git a/core/pkg/deviceinfo/storage.go b/core/pkg/deviceinfo/storage.go new file mode 100644 index 0000000000..90ecbe28b5 --- /dev/null +++ b/core/pkg/deviceinfo/storage.go @@ -0,0 +1,29 @@ +package deviceinfo + +import ( + "errors" + "os" +) + +var storagePath = "" + +func SetStoragePath(path string) error { + stat, err := os.Stat(path) + + if os.IsNotExist(err) { + if err := os.MkdirAll(path, 0600); err != nil { + return err + } + } + + if stat.IsDir() == false { + return errors.New("storage path is not a directory") + } + + storagePath = path + return nil +} + +func GetStoragePath() string { + return storagePath +} diff --git a/core/pkg/errorcodes/errors.pb.go b/core/pkg/errorcodes/errors.pb.go index ec4686c2ac..e2668aa50d 100644 --- a/core/pkg/errorcodes/errors.pb.go +++ b/core/pkg/errorcodes/errors.pb.go @@ -1,15 +1,14 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. // source: pkg/errorcodes/errors.proto -package errorcodes +package errorcodes // import "berty.tech/core/pkg/errorcodes" -import ( - fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/golang/protobuf/proto" - io "io" - math "math" -) +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "github.com/gogo/protobuf/gogoproto" + +import io "io" // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -122,8 +121,23 @@ const ( ErrNotificationUnmarshalFCM Code = 15004 ErrNotificationUnmarshalAPNS Code = 15005 ErrNotificationUnmarshalMQTT Code = 15006 + ErrNotificationReceive Code = 15007 ErrNode Code = 16000 ErrNodePushNotifSub Code = 16001 + ErrChunk Code = 17000 + ErrChunkBadIndex Code = 17001 + ErrChunkBadData Code = 17002 + ErrChunkBadSliceID Code = 17003 + ErrChunkBadSliceLength Code = 17004 + ErrChunkSliceNotComplete Code = 17005 + ErrChunkBadSlice Code = 17006 + ErrChunkDaemonStoragePath Code = 17007 + ErrChunkDaemonOpenDatabase Code = 17008 + ErrChunkSlice Code = 17009 + ErrChunkPublish Code = 17010 + ErrChunkSave Code = 17011 + ErrChunkFindSliceByID Code = 17012 + ErrChunkFindAllSlices Code = 17013 ) var Code_name = map[int32]string{ @@ -224,10 +238,24 @@ var Code_name = map[int32]string{ 15004: "ErrNotificationUnmarshalFCM", 15005: "ErrNotificationUnmarshalAPNS", 15006: "ErrNotificationUnmarshalMQTT", + 15007: "ErrNotificationReceive", 16000: "ErrNode", 16001: "ErrNodePushNotifSub", + 17000: "ErrChunk", + 17001: "ErrChunkBadIndex", + 17002: "ErrChunkBadData", + 17003: "ErrChunkBadSliceID", + 17004: "ErrChunkBadSliceLength", + 17005: "ErrChunkSliceNotComplete", + 17006: "ErrChunkBadSlice", + 17007: "ErrChunkDaemonStoragePath", + 17008: "ErrChunkDaemonOpenDatabase", + 17009: "ErrChunkSlice", + 17010: "ErrChunkPublish", + 17011: "ErrChunkSave", + 17012: "ErrChunkFindSliceByID", + 17013: "ErrChunkFindAllSlices", } - var Code_value = map[string]int32{ "ErrUndefined": 0, "OK": 1, @@ -326,16 +354,30 @@ var Code_value = map[string]int32{ "ErrNotificationUnmarshalFCM": 15004, "ErrNotificationUnmarshalAPNS": 15005, "ErrNotificationUnmarshalMQTT": 15006, + "ErrNotificationReceive": 15007, "ErrNode": 16000, "ErrNodePushNotifSub": 16001, + "ErrChunk": 17000, + "ErrChunkBadIndex": 17001, + "ErrChunkBadData": 17002, + "ErrChunkBadSliceID": 17003, + "ErrChunkBadSliceLength": 17004, + "ErrChunkSliceNotComplete": 17005, + "ErrChunkBadSlice": 17006, + "ErrChunkDaemonStoragePath": 17007, + "ErrChunkDaemonOpenDatabase": 17008, + "ErrChunkSlice": 17009, + "ErrChunkPublish": 17010, + "ErrChunkSave": 17011, + "ErrChunkFindSliceByID": 17012, + "ErrChunkFindAllSlices": 17013, } func (x Code) String() string { return proto.EnumName(Code_name, int32(x)) } - func (Code) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_f04d618bf87de955, []int{0} + return fileDescriptor_errors_2de00bcffb68b009, []int{0} } // Metadata is designed to be used as grpc status detail @@ -343,11 +385,11 @@ type Metadata struct { // unique enum code number to identify the error Code Code `protobuf:"varint,1,opt,name=code,proto3,enum=berty.errorcodes.Code" json:"code,omitempty"` // extended code (see hierarchy.go) - ExtendedCodes []Code `protobuf:"varint,2,rep,packed,name=extended_codes,json=extendedCodes,proto3,enum=berty.errorcodes.Code" json:"extended_codes,omitempty"` + ExtendedCodes []Code `protobuf:"varint,2,rep,packed,name=extended_codes,json=extendedCodes,enum=berty.errorcodes.Code" json:"extended_codes,omitempty"` // used for templated errors (i18n) - Placeholders map[string]string `protobuf:"bytes,3,rep,name=placeholders,proto3" json:"placeholders,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Placeholders map[string]string `protobuf:"bytes,3,rep,name=placeholders" json:"placeholders,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // nested/wraped errors - Parent *Metadata `protobuf:"bytes,4,opt,name=parent,proto3" json:"parent,omitempty"` + Parent *Metadata `protobuf:"bytes,4,opt,name=parent" json:"parent,omitempty"` // this field will be a duplicate for the top-level error and then skipped, // but this field is particularly useful to get debugging info when looking up parent errors. Message string `protobuf:"bytes,5,opt,name=message,proto3" json:"message,omitempty"` @@ -362,7 +404,7 @@ func (m *Metadata) Reset() { *m = Metadata{} } func (m *Metadata) String() string { return proto.CompactTextString(m) } func (*Metadata) ProtoMessage() {} func (*Metadata) Descriptor() ([]byte, []int) { - return fileDescriptor_f04d618bf87de955, []int{0} + return fileDescriptor_errors_2de00bcffb68b009, []int{0} } func (m *Metadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -379,8 +421,8 @@ func (m *Metadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return b[:n], nil } } -func (m *Metadata) XXX_Merge(src proto.Message) { - xxx_messageInfo_Metadata.Merge(m, src) +func (dst *Metadata) XXX_Merge(src proto.Message) { + xxx_messageInfo_Metadata.Merge(dst, src) } func (m *Metadata) XXX_Size() int { return m.Size() @@ -434,109 +476,10 @@ func (m *Metadata) GetCaller() string { } func init() { - proto.RegisterEnum("berty.errorcodes.Code", Code_name, Code_value) proto.RegisterType((*Metadata)(nil), "berty.errorcodes.Metadata") proto.RegisterMapType((map[string]string)(nil), "berty.errorcodes.Metadata.PlaceholdersEntry") + proto.RegisterEnum("berty.errorcodes.Code", Code_name, Code_value) } - -func init() { proto.RegisterFile("pkg/errorcodes/errors.proto", fileDescriptor_f04d618bf87de955) } - -var fileDescriptor_f04d618bf87de955 = []byte{ - // 1458 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x56, 0x5b, 0x6c, 0x1c, 0x49, - 0x15, 0xcd, 0xf8, 0x99, 0x94, 0x1d, 0xfb, 0xa6, 0xe2, 0xd8, 0x13, 0x27, 0xd8, 0x06, 0x21, 0xc5, - 0x8a, 0xc0, 0x46, 0x46, 0xb2, 0x10, 0x12, 0x38, 0x9e, 0xa7, 0xac, 0x68, 0x3a, 0x13, 0x4f, 0x86, - 0x0f, 0xa4, 0x08, 0xd5, 0x74, 0xdf, 0xe9, 0x69, 0xa5, 0xbb, 0x6a, 0xa8, 0xae, 0x1e, 0x32, 0x48, - 0x91, 0xe0, 0x2f, 0x20, 0x40, 0x09, 0xf0, 0x11, 0x20, 0x89, 0x78, 0x8b, 0xf7, 0x33, 0x40, 0xc2, - 0x43, 0xf0, 0x19, 0xf8, 0x4a, 0xc2, 0x0f, 0xec, 0x43, 0xca, 0x3a, 0x3f, 0xbb, 0xab, 0xd5, 0x2a, - 0xbb, 0x5f, 0xfb, 0xf8, 0x59, 0x55, 0x77, 0xcd, 0xcb, 0xf6, 0xe6, 0x6b, 0xe6, 0x9e, 0x73, 0xeb, - 0xde, 0x5b, 0xe7, 0x56, 0xdd, 0x6a, 0x72, 0xa2, 0x79, 0xc9, 0x5d, 0x45, 0x29, 0x85, 0xb4, 0x85, - 0x83, 0x61, 0xf2, 0x37, 0x5c, 0x69, 0x4a, 0xa1, 0x04, 0x85, 0x1a, 0x4a, 0xd5, 0x5e, 0xe9, 0xd1, - 0xf3, 0x1f, 0x75, 0x3d, 0xd5, 0x88, 0x6a, 0x2b, 0xb6, 0x08, 0x56, 0x5d, 0xe1, 0x8a, 0xd5, 0xd8, - 0xb1, 0x16, 0xd5, 0x63, 0x2b, 0x36, 0xe2, 0x7f, 0x49, 0x80, 0x0f, 0xbd, 0x3e, 0x44, 0x0e, 0x96, - 0x50, 0x31, 0x87, 0x29, 0x46, 0x4f, 0x93, 0x11, 0x1d, 0x24, 0x9d, 0x5a, 0x4a, 0x2d, 0x4f, 0xad, - 0xcd, 0xae, 0xec, 0x0e, 0xbe, 0x92, 0x15, 0x0e, 0x6e, 0xc7, 0x3e, 0xf4, 0x53, 0x64, 0x0a, 0x2f, - 0x2b, 0xe4, 0x0e, 0x3a, 0x9f, 0x8b, 0xc9, 0xf4, 0xd0, 0xd2, 0xf0, 0x33, 0x56, 0x1d, 0xee, 0x78, - 0x6b, 0x2b, 0xa4, 0x65, 0x32, 0xd9, 0xf4, 0x99, 0x8d, 0x0d, 0xe1, 0x3b, 0x28, 0xc3, 0xf4, 0xf0, - 0xd2, 0xf0, 0xf2, 0xc4, 0xda, 0x47, 0xf6, 0x2e, 0xee, 0x14, 0xb7, 0x52, 0xee, 0x73, 0xcf, 0x73, - 0x25, 0xdb, 0xdb, 0x03, 0x11, 0xe8, 0x1a, 0x19, 0x6b, 0x32, 0x89, 0x5c, 0xa5, 0x47, 0x96, 0x52, - 0xcb, 0x13, 0x6b, 0xf3, 0xef, 0x1f, 0x6b, 0xdb, 0x78, 0xd2, 0x34, 0x19, 0x0f, 0x30, 0x0c, 0x99, - 0x8b, 0xe9, 0xd1, 0xa5, 0xd4, 0xf2, 0xa1, 0xed, 0x8e, 0x49, 0x67, 0xc9, 0x98, 0xcd, 0x7c, 0x1f, - 0x65, 0x7a, 0x2c, 0x26, 0x8c, 0x35, 0xbf, 0x41, 0x8e, 0xec, 0x29, 0x84, 0x02, 0x19, 0xbe, 0x84, - 0xed, 0x58, 0xb6, 0x43, 0xdb, 0xfa, 0x2f, 0x9d, 0x21, 0xa3, 0x2d, 0xe6, 0x47, 0x98, 0x1e, 0x8a, - 0xb1, 0xc4, 0xf8, 0xe4, 0xd0, 0x27, 0x52, 0xa7, 0xff, 0x49, 0xc9, 0x88, 0x96, 0x80, 0x02, 0x99, - 0xcc, 0x4b, 0x59, 0xe5, 0x0e, 0xd6, 0x3d, 0x8e, 0x0e, 0x1c, 0xa0, 0x63, 0x64, 0xe8, 0xdc, 0x59, - 0x48, 0xd1, 0x09, 0x32, 0x9e, 0x97, 0x32, 0xc3, 0x42, 0x84, 0x21, 0x3a, 0x43, 0x20, 0x76, 0xf3, - 0x82, 0xa6, 0x8f, 0x01, 0x72, 0x85, 0x0e, 0x0c, 0xd3, 0x93, 0x24, 0x9d, 0x97, 0x72, 0x9b, 0x71, - 0x47, 0x04, 0x45, 0xe4, 0x28, 0x99, 0x12, 0xb2, 0xc0, 0x3c, 0x1f, 0x1d, 0x18, 0xa1, 0xf3, 0x64, - 0x56, 0xaf, 0xa9, 0x6e, 0xe5, 0x76, 0x73, 0xa3, 0x26, 0x5e, 0x05, 0xa5, 0xc7, 0x7c, 0xef, 0x8b, - 0x4c, 0x79, 0x82, 0xc3, 0x18, 0x9d, 0x25, 0x34, 0x2f, 0x65, 0x0e, 0xc3, 0x01, 0x7c, 0x9c, 0x4e, - 0x92, 0x83, 0x79, 0x29, 0xcb, 0x8c, 0x7b, 0x36, 0x1c, 0xa4, 0x40, 0x26, 0xf2, 0x52, 0xe6, 0x79, - 0x0b, 0x7d, 0xd1, 0x44, 0x78, 0x79, 0x9c, 0x1e, 0x27, 0x33, 0x7d, 0x48, 0x95, 0x2b, 0x19, 0x85, - 0xba, 0xc2, 0x57, 0xc6, 0xe9, 0x07, 0xe2, 0x12, 0x3b, 0x94, 0x25, 0x72, 0xd8, 0xf2, 0x6c, 0x2c, - 0x88, 0x88, 0x3b, 0xf0, 0xea, 0x38, 0x9d, 0x22, 0x87, 0x62, 0x5a, 0x79, 0xaa, 0x0d, 0x0f, 0xa6, - 0xe9, 0x51, 0x32, 0xd5, 0xb5, 0xb7, 0x78, 0x33, 0x52, 0xf0, 0x70, 0x9a, 0x52, 0x72, 0xb8, 0x0b, - 0xe6, 0x98, 0x62, 0xf0, 0x68, 0x9a, 0xce, 0x90, 0xe9, 0x2e, 0x96, 0xbf, 0xec, 0x85, 0x2a, 0x84, - 0xff, 0x4e, 0xd3, 0x09, 0x32, 0x96, 0x97, 0xd2, 0x42, 0x05, 0x77, 0xe7, 0xe8, 0x07, 0xc9, 0xc9, - 0xc4, 0xd8, 0xe4, 0x42, 0x35, 0x50, 0x66, 0x7d, 0x0f, 0xb9, 0xca, 0x0a, 0xce, 0xd1, 0xd6, 0xd5, - 0xdd, 0x9b, 0xa3, 0x47, 0x62, 0xf5, 0x2d, 0x54, 0x15, 0x25, 0x91, 0x05, 0xf0, 0xd7, 0x39, 0xb3, - 0x3b, 0x0b, 0xd5, 0xf9, 0x08, 0x23, 0x84, 0xbf, 0xcd, 0xd1, 0x69, 0x42, 0x12, 0x24, 0xe7, 0x31, - 0x1f, 0xfe, 0xde, 0x07, 0x94, 0x3d, 0xee, 0xc2, 0x3f, 0xe6, 0xcc, 0x2e, 0x34, 0xb0, 0x56, 0x86, - 0x9b, 0x69, 0x3a, 0x4b, 0x8e, 0x74, 0xed, 0x2d, 0x07, 0x93, 0xdd, 0xdd, 0x4a, 0xd3, 0xb9, 0x58, - 0xdf, 0x04, 0x2f, 0x47, 0x35, 0xdf, 0xb3, 0xcf, 0x62, 0x1b, 0x6e, 0xa7, 0xe9, 0xe1, 0x58, 0xe0, - 0x7c, 0x0b, 0xb9, 0x82, 0xef, 0x2f, 0x76, 0x54, 0xd0, 0x66, 0x45, 0xdf, 0x16, 0x09, 0x3f, 0x58, - 0x34, 0xb5, 0xc6, 0x60, 0x2c, 0xc2, 0x0f, 0x17, 0x8d, 0x30, 0x9f, 0x61, 0xbe, 0xe7, 0x24, 0xad, - 0xba, 0x7a, 0xca, 0xe4, 0xe8, 0x61, 0x89, 0x8a, 0x5f, 0x39, 0x45, 0xd3, 0xe4, 0xe8, 0x00, 0x51, - 0x6a, 0x87, 0xe8, 0xd7, 0xe1, 0xab, 0xa7, 0x4c, 0x98, 0x32, 0x73, 0x3d, 0x9e, 0x84, 0x79, 0xba, - 0x42, 0x09, 0x19, 0xd5, 0x47, 0xa1, 0x06, 0xff, 0x5b, 0x37, 0x92, 0xe4, 0x6a, 0x59, 0x89, 0x4c, - 0x21, 0xfc, 0xbf, 0x87, 0x54, 0x9b, 0x8e, 0x46, 0x9e, 0xeb, 0x21, 0x39, 0xf4, 0x51, 0x21, 0x3c, - 0xbf, 0x6e, 0x44, 0xc8, 0xd5, 0x2c, 0xa1, 0x1a, 0x1e, 0x77, 0x93, 0x96, 0xbf, 0xb0, 0x6e, 0x0a, - 0xcc, 0xd5, 0xb6, 0xb8, 0x42, 0xc9, 0x99, 0x9f, 0xd7, 0x37, 0x13, 0x5e, 0x5c, 0x37, 0x2a, 0x66, - 0x65, 0xbb, 0xa9, 0x04, 0xfc, 0xeb, 0xd3, 0x66, 0xc3, 0x89, 0x5d, 0xf1, 0x5c, 0xf8, 0xf1, 0x86, - 0x39, 0x68, 0x5d, 0xa8, 0xe4, 0x85, 0x01, 0x53, 0x76, 0x03, 0x7e, 0xb2, 0x61, 0xc2, 0x76, 0xa9, - 0x82, 0x90, 0x01, 0x53, 0xf0, 0xd3, 0x0d, 0x7a, 0x2c, 0x3e, 0xea, 0x09, 0x91, 0xe7, 0xb6, 0xfe, - 0x85, 0xab, 0x67, 0x06, 0xe0, 0x1c, 0x26, 0xf0, 0x6b, 0x67, 0x06, 0x92, 0xea, 0xe6, 0x3c, 0xd8, - 0x34, 0x47, 0xad, 0x0b, 0x15, 0x91, 0xc3, 0xc3, 0xcd, 0x81, 0x7c, 0x67, 0xb1, 0x9d, 0x43, 0x3d, - 0x5c, 0xe0, 0xd1, 0xa6, 0xd9, 0x77, 0xb7, 0x10, 0xbb, 0xc1, 0x3c, 0x0e, 0x77, 0x32, 0x46, 0xe5, - 0x4d, 0xdb, 0x2e, 0x31, 0xce, 0x5c, 0x94, 0xf0, 0xb3, 0x02, 0x9d, 0x27, 0xc7, 0x06, 0xb0, 0x2d, - 0xee, 0x29, 0x4b, 0xc7, 0xf9, 0x79, 0xc1, 0xa4, 0xed, 0x71, 0xb9, 0x1a, 0xfc, 0xa2, 0x60, 0xba, - 0xd8, 0x8f, 0xea, 0x35, 0xf0, 0xcb, 0xfd, 0x98, 0x9c, 0x14, 0x4d, 0xf8, 0x55, 0xc1, 0x94, 0xda, - 0xcf, 0x94, 0x3c, 0x17, 0x7e, 0xbd, 0x1f, 0x91, 0xf3, 0x24, 0xfc, 0xa6, 0x40, 0x4f, 0xc4, 0xa3, - 0xa3, 0x47, 0x58, 0x42, 0x9d, 0x6b, 0xa2, 0x9e, 0x4f, 0xbf, 0x2d, 0x18, 0xe5, 0x7a, 0x64, 0xb6, - 0xee, 0xc2, 0xd7, 0x8a, 0xa6, 0x37, 0x03, 0xb0, 0xc5, 0x02, 0x84, 0xaf, 0x17, 0xe9, 0x22, 0x99, - 0xdf, 0x4d, 0x95, 0x59, 0x18, 0x36, 0x1b, 0x52, 0x4f, 0xb7, 0x6f, 0x14, 0xf7, 0xd4, 0xae, 0xd7, - 0xa2, 0x82, 0x6b, 0x45, 0x7a, 0x92, 0xcc, 0xed, 0x66, 0x8a, 0xb2, 0x69, 0x57, 0x64, 0x0b, 0xae, - 0x17, 0xf7, 0x94, 0x92, 0x11, 0x0a, 0x9e, 0xee, 0x2d, 0x25, 0x23, 0x54, 0xac, 0xd2, 0x1b, 0xc5, - 0x3d, 0x3b, 0xcb, 0x08, 0x95, 0xbf, 0xec, 0xe9, 0x71, 0xf0, 0x66, 0xd1, 0xb4, 0x28, 0x2b, 0xb8, - 0x62, 0xb6, 0xda, 0xc6, 0xcf, 0xc3, 0x35, 0xab, 0x73, 0x4e, 0xba, 0x98, 0x3e, 0x14, 0xd7, 0x2d, - 0x53, 0xd7, 0x00, 0x5c, 0xf2, 0xc2, 0x50, 0x0f, 0x84, 0x6f, 0x5a, 0xa6, 0xaf, 0x3d, 0x36, 0x9e, - 0x50, 0x9a, 0xfb, 0x96, 0x65, 0xf6, 0xda, 0xe3, 0xcc, 0x3d, 0xfc, 0xb6, 0x65, 0xa6, 0x97, 0x96, - 0xf3, 0xad, 0x6a, 0xa7, 0x96, 0xba, 0xdb, 0x09, 0xfb, 0x76, 0xb5, 0x73, 0x38, 0xeb, 0xae, 0x59, - 0xf3, 0x4e, 0x9f, 0x5b, 0x32, 0x58, 0x43, 0x78, 0xb7, 0x6a, 0xc6, 0x47, 0x32, 0x39, 0x36, 0x7d, - 0x8f, 0x85, 0xf0, 0xf8, 0xa2, 0x39, 0x96, 0x7d, 0xa0, 0x3e, 0xc7, 0x2f, 0x5d, 0x34, 0xbd, 0xe9, - 0xc3, 0x2d, 0x91, 0x65, 0xdc, 0xd1, 0x43, 0x02, 0x43, 0xd8, 0xd9, 0xc7, 0x21, 0xb9, 0xf4, 0xe6, - 0x29, 0x79, 0x72, 0xb1, 0x73, 0x3f, 0x04, 0x6f, 0xa1, 0x0c, 0x93, 0x01, 0x72, 0x1f, 0x8d, 0xd0, - 0xfd, 0x68, 0x09, 0x83, 0x1a, 0xca, 0x10, 0xfe, 0x8d, 0xf4, 0xc3, 0x64, 0x71, 0x17, 0x69, 0x09, - 0x95, 0xe7, 0x22, 0x72, 0x1b, 0x1d, 0xaf, 0xff, 0x20, 0x9d, 0x8c, 0x5f, 0xc0, 0x72, 0x14, 0x36, - 0xe0, 0x77, 0x81, 0x09, 0xa8, 0xad, 0x2a, 0xbf, 0xc4, 0xc5, 0x17, 0x78, 0x59, 0x8a, 0x96, 0xa7, - 0x87, 0xe3, 0xef, 0x03, 0x53, 0x83, 0x26, 0xbb, 0xe8, 0x1f, 0x02, 0xf3, 0xf8, 0x68, 0x74, 0x8b, - 0xb7, 0xf4, 0xe0, 0x4b, 0x86, 0x71, 0xdd, 0x43, 0x09, 0x7f, 0x0c, 0xcc, 0xce, 0xfa, 0xe8, 0x0a, - 0xca, 0x16, 0xea, 0xb2, 0xea, 0x9e, 0x0b, 0x77, 0xfa, 0x53, 0x9a, 0x26, 0x64, 0x22, 0xee, 0xf8, - 0xb8, 0xe5, 0xc0, 0x9f, 0x02, 0xba, 0x40, 0x8e, 0x0f, 0xd6, 0x93, 0x43, 0xdd, 0xe3, 0x44, 0x80, - 0x3f, 0xf7, 0x47, 0xcf, 0x48, 0xc1, 0x1c, 0x9b, 0x85, 0xaa, 0x2f, 0xfd, 0x5f, 0x02, 0x73, 0xfb, - 0xfa, 0xd2, 0x5f, 0x68, 0x37, 0x11, 0xee, 0x06, 0xe6, 0xc8, 0x0d, 0xac, 0x84, 0x7b, 0x9d, 0x3d, - 0x5a, 0x42, 0x47, 0xb0, 0x93, 0x34, 0x37, 0x22, 0x53, 0x46, 0x3f, 0x5a, 0x62, 0x32, 0x6c, 0x30, - 0xbf, 0x90, 0x2d, 0xc1, 0x77, 0x22, 0x53, 0xc6, 0x3e, 0xfc, 0x66, 0xd9, 0xaa, 0xc0, 0x77, 0x9f, - 0xe1, 0x50, 0x3a, 0x7f, 0xe1, 0x02, 0x7c, 0x2f, 0xa2, 0x4b, 0xe4, 0xc4, 0x2e, 0x87, 0x2a, 0x0f, - 0x7a, 0x39, 0x6e, 0x46, 0x9d, 0x97, 0x76, 0x3f, 0x8f, 0x38, 0xcb, 0xad, 0x67, 0xba, 0xc4, 0x79, - 0x6e, 0x47, 0xa6, 0xdd, 0xf1, 0xf8, 0xfb, 0xd2, 0x15, 0x73, 0x4d, 0xb4, 0xa5, 0x85, 0x88, 0x17, - 0x56, 0xa2, 0x1a, 0x7c, 0xf9, 0xca, 0xfc, 0xc8, 0xd5, 0x1f, 0x2d, 0x1c, 0xc8, 0x7c, 0xec, 0xfe, - 0xce, 0x42, 0xea, 0xc1, 0xce, 0x42, 0xea, 0xf1, 0xce, 0x42, 0xea, 0xc6, 0x93, 0x85, 0x03, 0x9f, - 0x5d, 0x48, 0xbe, 0xf4, 0x14, 0xda, 0x8d, 0x55, 0x5b, 0x48, 0x5c, 0x1d, 0xfc, 0x64, 0xae, 0x8d, - 0xc5, 0xdf, 0xba, 0x1f, 0x7f, 0x2f, 0x00, 0x00, 0xff, 0xff, 0xf1, 0x3c, 0xc5, 0xb8, 0x4b, 0x0b, - 0x00, 0x00, -} - func (m *Metadata) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1132,3 +1075,113 @@ var ( ErrInvalidLengthErrors = fmt.Errorf("proto: negative length found during unmarshaling") ErrIntOverflowErrors = fmt.Errorf("proto: integer overflow") ) + +func init() { proto.RegisterFile("pkg/errorcodes/errors.proto", fileDescriptor_errors_2de00bcffb68b009) } + +var fileDescriptor_errors_2de00bcffb68b009 = []byte{ + // 1657 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x57, 0x5d, 0x6c, 0x5c, 0x47, + 0x15, 0xee, 0xb5, 0x1d, 0x3b, 0x19, 0x27, 0xf6, 0xc9, 0x24, 0xb1, 0xb7, 0x4e, 0xb0, 0x0d, 0x42, + 0x4a, 0x54, 0x81, 0x8d, 0x8c, 0x14, 0x21, 0x24, 0x48, 0xbd, 0xbf, 0x5a, 0x85, 0xbd, 0xdd, 0x7a, + 0x63, 0x1e, 0x90, 0x22, 0x34, 0x7b, 0xef, 0xf1, 0xdd, 0xab, 0xdc, 0x3b, 0xb3, 0xcc, 0x9d, 0xbb, + 0x64, 0x91, 0x2a, 0x81, 0xb4, 0x0f, 0x01, 0x01, 0x6a, 0x81, 0x87, 0x02, 0x6d, 0xf9, 0x47, 0xfc, + 0xff, 0x16, 0x68, 0xf9, 0x91, 0x78, 0x0c, 0x3c, 0xa5, 0xe5, 0x85, 0x5f, 0xa9, 0xa4, 0x2f, 0x6d, + 0x29, 0x25, 0x2d, 0x20, 0xf1, 0xf3, 0x82, 0x66, 0xee, 0xec, 0xee, 0x5d, 0xdb, 0xe4, 0xc9, 0x7b, + 0xbe, 0xef, 0xcc, 0x99, 0x33, 0xe7, 0x9c, 0xf9, 0xe6, 0x9a, 0x9c, 0xed, 0x5e, 0x0b, 0x36, 0x51, + 0x4a, 0x21, 0x3d, 0xe1, 0x63, 0x92, 0xfd, 0x4c, 0x36, 0xba, 0x52, 0x28, 0x41, 0xa1, 0x8d, 0x52, + 0xf5, 0x37, 0xc6, 0xf4, 0xca, 0x9b, 0x83, 0x50, 0x75, 0xd2, 0xf6, 0x86, 0x27, 0xe2, 0xcd, 0x40, + 0x04, 0x62, 0xd3, 0x38, 0xb6, 0xd3, 0x3d, 0x63, 0x19, 0xc3, 0xfc, 0xca, 0x02, 0xbc, 0xe1, 0x95, + 0x29, 0x72, 0xb4, 0x81, 0x8a, 0xf9, 0x4c, 0x31, 0x7a, 0x1f, 0x99, 0xd1, 0x41, 0x0a, 0xce, 0xba, + 0x73, 0x61, 0x61, 0x6b, 0x69, 0x63, 0x7f, 0xf0, 0x8d, 0x92, 0xf0, 0x71, 0xc7, 0xf8, 0xd0, 0x77, + 0x90, 0x05, 0xbc, 0xae, 0x90, 0xfb, 0xe8, 0xbf, 0xd7, 0x90, 0x85, 0xa9, 0xf5, 0xe9, 0xbb, 0xac, + 0x3a, 0x31, 0xf4, 0xd6, 0x56, 0x42, 0x9b, 0xe4, 0x78, 0x37, 0x62, 0x1e, 0x76, 0x44, 0xe4, 0xa3, + 0x4c, 0x0a, 0xd3, 0xeb, 0xd3, 0x17, 0xe6, 0xb7, 0xde, 0x74, 0x70, 0xf1, 0x30, 0xb9, 0x8d, 0x66, + 0xce, 0xbd, 0xc2, 0x95, 0xec, 0xef, 0x4c, 0x44, 0xa0, 0x5b, 0x64, 0xb6, 0xcb, 0x24, 0x72, 0x55, + 0x98, 0x59, 0x77, 0x2e, 0xcc, 0x6f, 0xad, 0xfc, 0xff, 0x58, 0x3b, 0xd6, 0x93, 0x16, 0xc8, 0x5c, + 0x8c, 0x49, 0xc2, 0x02, 0x2c, 0x1c, 0x59, 0x77, 0x2e, 0x1c, 0xdb, 0x19, 0x9a, 0x74, 0x89, 0xcc, + 0x7a, 0x2c, 0x8a, 0x50, 0x16, 0x66, 0x0d, 0x61, 0xad, 0x95, 0x4b, 0xe4, 0xe4, 0x81, 0x44, 0x28, + 0x90, 0xe9, 0x6b, 0xd8, 0x37, 0x65, 0x3b, 0xb6, 0xa3, 0x7f, 0xd2, 0xd3, 0xe4, 0x48, 0x8f, 0x45, + 0x29, 0x16, 0xa6, 0x0c, 0x96, 0x19, 0x6f, 0x9f, 0x7a, 0x9b, 0x73, 0xdf, 0xcd, 0x33, 0x64, 0x46, + 0x97, 0x80, 0x02, 0x39, 0x5e, 0x91, 0x72, 0x97, 0xfb, 0xb8, 0x17, 0x72, 0xf4, 0xe1, 0x1e, 0x3a, + 0x4b, 0xa6, 0x1e, 0xb8, 0x0c, 0x0e, 0x9d, 0x27, 0x73, 0x15, 0x29, 0x8b, 0x2c, 0x41, 0x98, 0xa2, + 0xa7, 0x09, 0x18, 0xb7, 0x30, 0xee, 0x46, 0x18, 0x23, 0x57, 0xe8, 0xc3, 0x34, 0x3d, 0x47, 0x0a, + 0x15, 0x29, 0x77, 0x18, 0xf7, 0x45, 0x5c, 0x43, 0x8e, 0x92, 0x29, 0x21, 0xab, 0x2c, 0x8c, 0xd0, + 0x87, 0x19, 0xba, 0x42, 0x96, 0xf4, 0x9a, 0xdd, 0x7a, 0x79, 0x3f, 0x77, 0xc4, 0xc6, 0x6b, 0xa1, + 0x0c, 0x59, 0x14, 0x7e, 0x80, 0xa9, 0x50, 0x70, 0x98, 0xa5, 0x4b, 0x84, 0x56, 0xa4, 0x2c, 0x63, + 0x32, 0x81, 0xcf, 0xd1, 0xe3, 0xe4, 0x68, 0x45, 0xca, 0x26, 0xe3, 0xa1, 0x07, 0x47, 0x29, 0x90, + 0xf9, 0x8a, 0x94, 0x15, 0xde, 0xc3, 0x48, 0x74, 0x11, 0x5e, 0x98, 0xa3, 0xf7, 0x92, 0xd3, 0x39, + 0x64, 0x97, 0x2b, 0x99, 0x26, 0x3a, 0xc3, 0x17, 0xe7, 0xe8, 0xeb, 0x4c, 0x8a, 0x43, 0xca, 0x15, + 0x65, 0xec, 0x85, 0x1e, 0x56, 0x45, 0xca, 0x7d, 0x78, 0x69, 0x8e, 0x2e, 0x90, 0x63, 0x86, 0x56, + 0xa1, 0xea, 0xc3, 0xad, 0x45, 0x7a, 0x8a, 0x2c, 0x8c, 0xec, 0x3a, 0xef, 0xa6, 0x0a, 0x9e, 0x59, + 0xa4, 0x94, 0x9c, 0x18, 0x81, 0x65, 0xa6, 0x18, 0x3c, 0xbb, 0x48, 0x4f, 0x93, 0xc5, 0x11, 0x56, + 0xb9, 0x1e, 0x26, 0x2a, 0x81, 0xdf, 0x2c, 0xd2, 0x79, 0x32, 0x5b, 0x91, 0xd2, 0x45, 0x05, 0x4f, + 0x2d, 0xd3, 0xd7, 0x93, 0x73, 0x99, 0xb1, 0xcd, 0x85, 0xea, 0xa0, 0x2c, 0x45, 0x21, 0x72, 0x55, + 0x12, 0x9c, 0xa3, 0xa7, 0xb3, 0x7b, 0x7a, 0x99, 0x9e, 0x34, 0xd5, 0x77, 0x51, 0xb5, 0x94, 0x44, + 0x16, 0xc3, 0x4f, 0x97, 0xed, 0xe9, 0x5c, 0x54, 0x0f, 0xa6, 0x98, 0x22, 0xfc, 0x6c, 0x99, 0x2e, + 0x12, 0x92, 0x21, 0xe5, 0x90, 0x45, 0xf0, 0xf3, 0x1c, 0xd0, 0x0c, 0x79, 0x00, 0xbf, 0x58, 0xb6, + 0xa7, 0xd0, 0xc0, 0x56, 0x13, 0x1e, 0x2b, 0xd0, 0x25, 0x72, 0x72, 0x64, 0xd7, 0x7d, 0xcc, 0x4e, + 0xf7, 0x78, 0x81, 0x2e, 0x9b, 0xfa, 0x66, 0x78, 0x33, 0x6d, 0x47, 0xa1, 0x77, 0x19, 0xfb, 0xf0, + 0x44, 0x81, 0x9e, 0x30, 0x05, 0xae, 0xf4, 0x90, 0x2b, 0xf8, 0xfc, 0xda, 0xb0, 0x0a, 0xda, 0x6c, + 0xe9, 0xdb, 0x22, 0xe1, 0x0b, 0x6b, 0x36, 0x57, 0x03, 0x9a, 0x22, 0x7c, 0x71, 0xcd, 0x16, 0xe6, + 0xdd, 0x2c, 0x0a, 0xfd, 0xac, 0x55, 0x37, 0xce, 0xdb, 0x3d, 0xc6, 0x58, 0x56, 0xc5, 0x0f, 0x9f, + 0xa7, 0x05, 0x72, 0x6a, 0x82, 0x68, 0xf4, 0x13, 0x8c, 0xf6, 0xe0, 0x23, 0xe7, 0x6d, 0x98, 0x26, + 0x0b, 0x42, 0x9e, 0x85, 0xb9, 0xb3, 0x41, 0x09, 0x39, 0xa2, 0x47, 0xa1, 0x0d, 0xbf, 0xbd, 0x68, + 0x4b, 0x52, 0x6e, 0x97, 0x24, 0x32, 0x85, 0xf0, 0xbb, 0x31, 0xb2, 0xdb, 0xf5, 0x35, 0xf2, 0xfb, + 0x31, 0x52, 0xc6, 0x08, 0x15, 0xc2, 0x1f, 0x2e, 0xda, 0x22, 0x94, 0xdb, 0xae, 0x50, 0x9d, 0x90, + 0x07, 0x59, 0xcb, 0xff, 0x78, 0xd1, 0x26, 0x58, 0x6e, 0xd7, 0xb9, 0x42, 0xc9, 0x59, 0x54, 0xd1, + 0x37, 0x13, 0xfe, 0x74, 0xd1, 0x56, 0xb1, 0x24, 0xfb, 0x5d, 0x25, 0xe0, 0x97, 0xef, 0xb4, 0x07, + 0xce, 0xec, 0x56, 0x18, 0xc0, 0x97, 0x2f, 0xd9, 0x41, 0x1b, 0x41, 0x8d, 0x30, 0x89, 0x99, 0xf2, + 0x3a, 0xf0, 0x95, 0x4b, 0x36, 0xec, 0x88, 0xaa, 0x0a, 0x19, 0x33, 0x05, 0x5f, 0xbd, 0x44, 0xcf, + 0x98, 0x51, 0xcf, 0x88, 0x0a, 0xf7, 0xf4, 0x5f, 0xb8, 0x71, 0xff, 0x04, 0x5c, 0xc6, 0x0c, 0x7e, + 0xf9, 0xfe, 0x89, 0x4d, 0x75, 0x73, 0x6e, 0x6d, 0xdb, 0x51, 0x1b, 0x41, 0x35, 0xe4, 0xf0, 0xcc, + 0xf6, 0xc4, 0x7e, 0x97, 0xb1, 0x5f, 0x46, 0x2d, 0x2e, 0xf0, 0xec, 0xb6, 0x3d, 0xf7, 0x28, 0x11, + 0xaf, 0xc3, 0x42, 0x0e, 0x4f, 0x16, 0x6d, 0x95, 0xb7, 0x3d, 0xaf, 0xc1, 0x38, 0x0b, 0x50, 0xc2, + 0xd7, 0xaa, 0x74, 0x85, 0x9c, 0x99, 0xc0, 0xea, 0x3c, 0x54, 0xae, 0x8e, 0xf3, 0xf5, 0xaa, 0xdd, + 0x76, 0xcc, 0x95, 0xdb, 0xf0, 0x8d, 0xaa, 0xed, 0x62, 0x1e, 0xd5, 0x6b, 0xe0, 0x9b, 0x87, 0x31, + 0x65, 0x29, 0xba, 0xf0, 0xad, 0xaa, 0x4d, 0x35, 0xcf, 0x34, 0xc2, 0x00, 0xbe, 0x7d, 0x18, 0x51, + 0x0e, 0x25, 0x7c, 0xa7, 0x4a, 0xcf, 0x1a, 0xe9, 0x18, 0x13, 0xae, 0x50, 0x0f, 0x74, 0x51, 0xeb, + 0xd3, 0x77, 0xab, 0xb6, 0x72, 0x63, 0xb2, 0xb4, 0x17, 0xc0, 0x47, 0x6b, 0xb6, 0x37, 0x13, 0xb0, + 0xcb, 0x62, 0x84, 0x8f, 0xd5, 0xe8, 0x1a, 0x59, 0xd9, 0x4f, 0x35, 0x59, 0x92, 0x74, 0x3b, 0x52, + 0xab, 0xdb, 0xc7, 0x6b, 0x07, 0x72, 0xd7, 0x6b, 0x51, 0xc1, 0xc3, 0x35, 0x7a, 0x8e, 0x2c, 0xef, + 0x67, 0x6a, 0xb2, 0xeb, 0xb5, 0x64, 0x0f, 0x1e, 0xa9, 0x1d, 0x48, 0xa5, 0x28, 0x14, 0xdc, 0x39, + 0x98, 0x4a, 0x51, 0x28, 0x53, 0xa5, 0x57, 0x6b, 0x07, 0x4e, 0x56, 0x14, 0xaa, 0x72, 0x3d, 0xd4, + 0x72, 0xf0, 0x5a, 0xcd, 0xb6, 0xa8, 0x24, 0xb8, 0x62, 0x9e, 0xda, 0xc1, 0xf7, 0xc1, 0xc3, 0xee, + 0x70, 0x4e, 0x46, 0x98, 0x1e, 0x8a, 0x47, 0x5c, 0x9b, 0xd7, 0x04, 0xdc, 0x08, 0x93, 0x44, 0x0b, + 0xc2, 0x27, 0x5c, 0xdb, 0xd7, 0x31, 0x6b, 0x14, 0x4a, 0x73, 0x9f, 0x74, 0xed, 0x59, 0xc7, 0x9c, + 0xbd, 0x87, 0x9f, 0x72, 0xad, 0x7a, 0xe9, 0x72, 0xfe, 0x6b, 0x77, 0x98, 0xcb, 0x5e, 0x30, 0x0c, + 0xfb, 0xef, 0xdd, 0xe1, 0x70, 0xee, 0x05, 0x76, 0xcd, 0x7f, 0x72, 0x6e, 0x99, 0xb0, 0x26, 0xf0, + 0xdf, 0x5d, 0x2b, 0x1f, 0x99, 0x72, 0x6c, 0x47, 0x21, 0x4b, 0xe0, 0xb9, 0xab, 0x76, 0x2c, 0x73, + 0xa0, 0x9e, 0xe3, 0x3f, 0x5f, 0xb5, 0xbd, 0xc9, 0xe1, 0xae, 0x28, 0x31, 0xee, 0x6b, 0x91, 0xc0, + 0x04, 0x6e, 0x1f, 0xe2, 0x90, 0x5d, 0x7a, 0xfb, 0x94, 0x3c, 0x7f, 0x75, 0x78, 0x3f, 0x04, 0xef, + 0xa1, 0x4c, 0x32, 0x01, 0xb9, 0x89, 0xb6, 0xd0, 0x79, 0xb4, 0x81, 0x71, 0x1b, 0x65, 0x02, 0xbf, + 0x42, 0xfa, 0x46, 0xb2, 0xb6, 0x8f, 0x74, 0x85, 0xaa, 0x70, 0x91, 0x06, 0x9d, 0xa1, 0xd7, 0xaf, + 0x91, 0x1e, 0x37, 0x2f, 0x60, 0x33, 0x4d, 0x3a, 0xf0, 0xbd, 0xd8, 0x06, 0xd4, 0xd6, 0x2e, 0xbf, + 0xc6, 0xc5, 0xfb, 0x79, 0x53, 0x8a, 0x5e, 0xa8, 0xc5, 0xf1, 0xfb, 0xb1, 0xcd, 0x41, 0x93, 0x23, + 0xf4, 0x07, 0xb1, 0x7d, 0x7c, 0x34, 0x5a, 0xe7, 0x3d, 0x2d, 0x7c, 0x99, 0x18, 0xef, 0x85, 0x28, + 0xe1, 0x87, 0xb1, 0x3d, 0x59, 0x8e, 0x6e, 0xa1, 0xec, 0xa1, 0x4e, 0x6b, 0x2f, 0x0c, 0xe0, 0xc9, + 0xfc, 0x96, 0xb6, 0x09, 0xc5, 0x94, 0xfb, 0x11, 0xd6, 0x7d, 0xf8, 0x51, 0x4c, 0x57, 0xc9, 0xbd, + 0x93, 0xf9, 0x94, 0x51, 0xf7, 0x38, 0x2b, 0xc0, 0x8f, 0xf3, 0xd1, 0x8b, 0x52, 0x30, 0xdf, 0x63, + 0x89, 0xca, 0x6d, 0xff, 0x93, 0xd8, 0xde, 0xbe, 0xdc, 0xf6, 0x57, 0xfa, 0x5d, 0x84, 0xa7, 0x62, + 0x3b, 0x72, 0x13, 0x2b, 0xe1, 0xe9, 0xe1, 0x19, 0x5d, 0xa1, 0x23, 0x78, 0xd9, 0x36, 0x8f, 0xa6, + 0x36, 0x8d, 0x3c, 0xda, 0x60, 0x32, 0xe9, 0xb0, 0xa8, 0x5a, 0x6a, 0xc0, 0xa7, 0x53, 0x9b, 0xc6, + 0x21, 0xfc, 0x76, 0xd3, 0x6d, 0xc1, 0x67, 0xee, 0xe2, 0xd0, 0x78, 0xf0, 0xca, 0x15, 0xf8, 0x6c, + 0x4a, 0xd7, 0xc9, 0xd9, 0x7d, 0x0e, 0xbb, 0x3c, 0x1e, 0xef, 0xf1, 0x58, 0x3a, 0x7c, 0x69, 0x0f, + 0xf3, 0x30, 0xbb, 0x3c, 0x7e, 0x57, 0x17, 0xb3, 0xcf, 0x13, 0xa9, 0xad, 0x76, 0xde, 0x65, 0x07, + 0x3d, 0x0c, 0x7b, 0x08, 0x9f, 0x4b, 0xed, 0x2c, 0x18, 0x6d, 0xfc, 0xe0, 0x43, 0xf6, 0x0e, 0x69, + 0x4b, 0x57, 0xc9, 0x2c, 0x69, 0xa5, 0x6d, 0xf8, 0xd0, 0x43, 0x74, 0xc1, 0xbc, 0xa4, 0xa5, 0x4e, + 0xca, 0xaf, 0xc1, 0x0b, 0x03, 0x87, 0x2e, 0x65, 0xd7, 0x57, 0xdb, 0x45, 0xe6, 0xd7, 0xb9, 0x8f, + 0xd7, 0xe1, 0xc5, 0x81, 0x43, 0xcf, 0x64, 0x43, 0x6b, 0x71, 0xf3, 0xa0, 0xbe, 0x34, 0x70, 0x68, + 0x21, 0x53, 0x75, 0x0b, 0xb7, 0xa2, 0xd0, 0xc3, 0x7a, 0x19, 0xfe, 0x32, 0x70, 0xe8, 0xb9, 0x6c, + 0x9e, 0xf3, 0xcc, 0xbb, 0x90, 0x07, 0xaa, 0x03, 0x2f, 0x0f, 0x1c, 0xba, 0x6a, 0x26, 0xcd, 0xb0, + 0x86, 0x72, 0x85, 0x2a, 0x09, 0xfd, 0xad, 0xa6, 0x10, 0xfe, 0x7a, 0x20, 0x0d, 0xe3, 0x02, 0xaf, + 0x0c, 0x1c, 0xba, 0x66, 0xba, 0x67, 0xf0, 0x32, 0xc3, 0x58, 0xf0, 0x96, 0x12, 0x92, 0x05, 0xd8, + 0x64, 0xaa, 0x03, 0x7f, 0x1b, 0x38, 0x74, 0xdd, 0x74, 0x27, 0xe7, 0xa0, 0x75, 0x58, 0xa7, 0xdb, + 0xd6, 0xd2, 0x79, 0x67, 0xe0, 0xd0, 0x53, 0x99, 0x02, 0x8c, 0xb6, 0x86, 0x57, 0x27, 0x8f, 0x67, + 0x3e, 0x34, 0x92, 0x0e, 0xbc, 0x36, 0x70, 0x28, 0xcd, 0x04, 0xc4, 0xf8, 0xb2, 0x1e, 0xc2, 0xdf, + 0x07, 0x0e, 0x3d, 0x9b, 0x69, 0x95, 0xc6, 0xaa, 0x21, 0xcf, 0x72, 0x2b, 0xf6, 0xeb, 0x65, 0xf8, + 0xc7, 0x41, 0x72, 0x3b, 0x8a, 0x0c, 0x9f, 0xc0, 0x3f, 0x07, 0xce, 0xca, 0xcc, 0x8d, 0x2f, 0xad, + 0xde, 0x53, 0x7c, 0xcb, 0xcd, 0xdb, 0xab, 0xce, 0xad, 0xdb, 0xab, 0xce, 0x73, 0xb7, 0x57, 0x9d, + 0x47, 0x9f, 0x5f, 0xbd, 0xe7, 0x3d, 0xab, 0xd9, 0x27, 0xb7, 0x42, 0xaf, 0xb3, 0xe9, 0x09, 0x89, + 0x9b, 0x93, 0xff, 0xbb, 0xb4, 0x67, 0xcd, 0x3f, 0x1d, 0x6f, 0xfd, 0x5f, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xe6, 0xee, 0x81, 0xab, 0xd4, 0x0c, 0x00, 0x00, +} diff --git a/core/pkg/errorcodes/errors.proto b/core/pkg/errorcodes/errors.proto index 90e9c742ae..6b4236372a 100644 --- a/core/pkg/errorcodes/errors.proto +++ b/core/pkg/errorcodes/errors.proto @@ -126,10 +126,25 @@ enum Code { ErrNotificationUnmarshalFCM = 15004; ErrNotificationUnmarshalAPNS = 15005; ErrNotificationUnmarshalMQTT = 15006; + ErrNotificationReceive = 15007; ErrNode = 16000; ErrNodePushNotifSub = 16001; + ErrChunk = 17000; + ErrChunkBadIndex = 17001; + ErrChunkBadData = 17002; + ErrChunkBadSliceID = 17003; + ErrChunkBadSliceLength = 17004; + ErrChunkSliceNotComplete = 17005; + ErrChunkBadSlice = 17006; + ErrChunkDaemonStoragePath = 17007; + ErrChunkDaemonOpenDatabase = 17008; + ErrChunkSlice = 17009; + ErrChunkPublish = 17010; + ErrChunkSave = 17011; + ErrChunkFindSliceByID = 17012; + ErrChunkFindAllSlices = 17013; } // Metadata is designed to be used as grpc status detail diff --git a/core/pkg/notification/notification.go b/core/pkg/notification/notification.go index 538cd3d580..043e26324d 100644 --- a/core/pkg/notification/notification.go +++ b/core/pkg/notification/notification.go @@ -17,8 +17,8 @@ type Driver interface { Display(*Payload) error Register() error Unregister() error - Subscribe() chan *Payload - Unsubscribe(chan *Payload) + Subscribe() chan []byte + Unsubscribe(chan []byte) SubscribeToken() chan *Token UnsubscribeToken(chan *Token) RefreshToken() error @@ -86,12 +86,12 @@ func (n *NoopNotification) RefreshToken() error { return nil } -func (n *NoopNotification) Subscribe() chan *Payload { +func (n *NoopNotification) Subscribe() chan []byte { logger().Debug("noop notification handler not implemented") return nil } -func (n *NoopNotification) Unsubscribe(chan *Payload) { +func (n *NoopNotification) Unsubscribe(chan []byte) { } @@ -142,12 +142,12 @@ func (n *DesktopNotification) RefreshToken() error { return nil } -func (n *DesktopNotification) Subscribe() chan *Payload { +func (n *DesktopNotification) Subscribe() chan []byte { logger().Debug("noop notification handler not implemented") return nil } -func (n *DesktopNotification) Unsubscribe(chan *Payload) { +func (n *DesktopNotification) Unsubscribe(chan []byte) { } diff --git a/core/push/apns.go b/core/push/apns.go index b896c52a40..4fd38cd0fc 100644 --- a/core/push/apns.go +++ b/core/push/apns.go @@ -2,9 +2,11 @@ package push import ( "encoding/base64" - "github.com/pkg/errors" "strings" + "github.com/pkg/errors" + + "berty.tech/core/chunk" "berty.tech/core/pkg/errorcodes" "github.com/sideshow/apns2" "github.com/sideshow/apns2/certificate" @@ -82,22 +84,28 @@ func (d *APNSDispatcher) Dispatch(pushAttrs *PushData, pushDestination *PushDest return errorcodes.ErrPushUnknownDestination.Wrap(err) } - pushPayload := payload.NewPayload().Custom("berty-envelope", base64.StdEncoding.EncodeToString(pushAttrs.Envelope)) - if pushAttrs.Priority == Priority_Normal { - pushPayload = pushPayload.Alert("test berty notif") + chunks, err := chunk.SplitMarshal(pushAttrs.Envelope, 2000) + if err != nil { + return err } + for _, chunk := range chunks { + pushPayload := payload.NewPayload().Custom("chunk", base64.StdEncoding.EncodeToString(chunk)) + if pushAttrs.Priority == Priority_Normal { + pushPayload = pushPayload.Alert("test berty notif") + } - notification := &apns2.Notification{} - notification.DeviceToken = apnsIdentifier.DeviceToken - notification.Topic = d.bundleID - notification.Payload = pushPayload + notification := &apns2.Notification{} + notification.DeviceToken = apnsIdentifier.DeviceToken + notification.Topic = d.bundleID + notification.Payload = pushPayload - response, err := d.client.Push(notification) + response, err := d.client.Push(notification) - if err != nil { - return errorcodes.ErrPushProvider.Wrap(err) - } else if response.StatusCode != 200 { - return errorcodes.ErrPushProvider.Wrap(errors.New(response.Reason)) + if err != nil { + return errorcodes.ErrPushProvider.Wrap(err) + } else if response.StatusCode != 200 { + return errorcodes.ErrPushProvider.Wrap(errors.New(response.Reason)) + } } return nil diff --git a/core/push/fcm.go b/core/push/fcm.go index da9df03b0b..ecca36bdf2 100644 --- a/core/push/fcm.go +++ b/core/push/fcm.go @@ -4,8 +4,9 @@ import ( "encoding/base64" "strings" + "berty.tech/core/chunk" "berty.tech/core/pkg/errorcodes" - "github.com/NaySoftware/go-fcm" + fcm "github.com/NaySoftware/go-fcm" ) type FCMDispatcher struct { @@ -55,12 +56,18 @@ func (d *FCMDispatcher) Dispatch(pushAttrs *PushData, pushDestination *PushDesti return errorcodes.ErrPushUnknownDestination.Wrap(err) } - payload := Payload{BertyEnvelope: base64.StdEncoding.EncodeToString(pushAttrs.Envelope)} + chunks, err := chunk.SplitMarshal(pushAttrs.Envelope, 2000) + if err != nil { + return err + } + for _, chunk := range chunks { + payload := Payload{Chunk: base64.StdEncoding.EncodeToString(chunk)} - deviceToken := fcmIdentifier.DeviceToken + deviceToken := fcmIdentifier.DeviceToken - if _, err := d.client.NewFcmMsgTo(deviceToken, payload).Send(); err != nil { - return errorcodes.ErrPushProvider.Wrap(err) + if _, err := d.client.NewFcmMsgTo(deviceToken, payload).Send(); err != nil { + return errorcodes.ErrPushProvider.Wrap(err) + } } return nil diff --git a/core/push/push.go b/core/push/push.go index 28432965ca..24d543adf5 100644 --- a/core/push/push.go +++ b/core/push/push.go @@ -19,7 +19,7 @@ type Manager struct { } type Payload struct { - BertyEnvelope string `json:"berty-envelope"` + Chunk string `json:"chunk"` } func (m *Manager) Dispatch(push *PushData, pushDestination *PushDestination) error { diff --git a/go.sum b/go.sum new file mode 100644 index 0000000000..8487937e6d --- /dev/null +++ b/go.sum @@ -0,0 +1,19 @@ +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/saibing/bingo v1.1.0/go.mod h1:kPUuE8jwIRE8KldxfQN6kzUxAZRo1pzuXU/EBbQR5NU= +github.com/slimsag/godocmd v0.0.0-20161025000126-a1005ad29fe3/go.mod h1:AIBPxLCkKUFc2ZkjCXzs/Kk9OUhQLw/Zicdd0Rhqz2U= +github.com/sourcegraph/go-lsp v0.0.0-20181119182933-0c7d621186c1/go.mod h1:tpps84QRlOVVLYk5QpKYX8Tr289D1v/UTWDLqeguiqM= +github.com/sourcegraph/jsonrpc2 v0.0.0-20180831160525-549eb959f029/go.mod h1:eESpbCslcLDs8j2D7IEdGVgul7xuk9odqDTaor30IUU= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/mobile v0.0.0-20190125201028-feefccb6c1c9 h1:guhfyRQZ6kHMDmc247p+xD6JPKdNknxn8CTyEYg59k8= +golang.org/x/mobile v0.0.0-20190125201028-feefccb6c1c9/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/tools v0.0.0-20181122213734-04b5d21e00f1/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190124004107-78ee07aa9465/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=