Skip to content

Commit db307e3

Browse files
committed
Merge remote-tracking branch 'benma/syncstarted'
2 parents 367bb1b + 2171c23 commit db307e3

34 files changed

+244
-464
lines changed

backend/accounts.go

+10-10
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,16 @@ func (backend *Backend) addAccount(account accounts.Interface) {
742742
backend.accounts = append(backend.accounts, account)
743743
sortAccounts(backend.accounts)
744744

745-
account.Observe(backend.Notify)
745+
account.Observe(func(event observable.Event) {
746+
backend.Notify(observable.Event{
747+
Subject: fmt.Sprintf("account/%s/%s", account.Config().Config.Code, event.Subject),
748+
Action: event.Action,
749+
Object: event.Object,
750+
})
751+
if event.Subject == string(accountsTypes.EventSyncDone) {
752+
backend.notifyNewTxs(account)
753+
}
754+
})
746755
if backend.onAccountInit != nil {
747756
backend.onAccountInit(account)
748757
}
@@ -856,15 +865,6 @@ func (backend *Backend) createAndAddAccount(coin coinpkg.Coin, persistedConfig *
856865
}
857866
return ks, err
858867
},
859-
OnEvent: func(event accountsTypes.Event) {
860-
backend.events <- AccountEvent{
861-
Type: "account", Code: persistedConfig.Code,
862-
Data: string(event),
863-
}
864-
if account != nil && event == accountsTypes.EventSyncDone {
865-
backend.notifyNewTxs(account)
866-
}
867-
},
868868
RateUpdater: backend.ratesUpdater,
869869
GetNotifier: func(configurations signing.Configurations) accounts.Notifier {
870870
return backend.notifier.ForAccount(persistedConfig.Code)

backend/accounts/baseaccount.go

+26-7
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/signing"
3434
"github.com/BitBoxSwiss/bitbox-wallet-app/util/errp"
3535
"github.com/BitBoxSwiss/bitbox-wallet-app/util/observable"
36+
"github.com/BitBoxSwiss/bitbox-wallet-app/util/observable/action"
3637
"github.com/sirupsen/logrus"
3738
)
3839

@@ -45,7 +46,6 @@ type AccountConfig struct {
4546
// NotesFolder is the folder where the transaction notes are stored. Full path.
4647
NotesFolder string
4748
ConnectKeystore func() (keystore.Keystore, error)
48-
OnEvent func(types.Event)
4949
RateUpdater *rates.RateUpdater
5050
GetNotifier func(signing.Configurations) Notifier
5151
GetSaveFilename func(suggestedFilename string) string
@@ -83,12 +83,15 @@ func NewBaseAccount(config *AccountConfig, coin coin.Coin, log *logrus.Entry) *B
8383
log: log,
8484
}
8585
account.Synchronizer = synchronizer.NewSynchronizer(
86-
func() { config.OnEvent(types.EventSyncStarted) },
8786
func() {
8887
if account.synced.CompareAndSwap(false, true) {
89-
config.OnEvent(types.EventStatusChanged)
88+
account.Notify(observable.Event{
89+
Subject: string(types.EventStatusChanged),
90+
Action: action.Replace,
91+
Object: nil,
92+
})
9093
}
91-
config.OnEvent(types.EventSyncDone)
94+
account.notifySyncDone()
9295
},
9396
log,
9497
)
@@ -129,7 +132,11 @@ func (account *BaseAccount) Offline() error {
129132
// changed.
130133
func (account *BaseAccount) SetOffline(offline error) {
131134
account.offline = offline
132-
account.config.OnEvent(types.EventStatusChanged)
135+
account.Notify(observable.Event{
136+
Subject: string(types.EventStatusChanged),
137+
Action: action.Replace,
138+
Object: nil,
139+
})
133140
}
134141

135142
// Initialize initializes the account. `accountIdentifier` is used as part of the filename of
@@ -153,7 +160,7 @@ func (account *BaseAccount) Initialize(accountIdentifier string) error {
153160
if account.config.RateUpdater != nil {
154161
account.config.RateUpdater.Observe(func(e observable.Event) {
155162
if e.Subject == rates.RatesEventSubject {
156-
account.config.OnEvent(types.EventSyncDone)
163+
account.notifySyncDone()
157164
}
158165
})
159166
}
@@ -227,7 +234,11 @@ func (account *BaseAccount) SetTxNote(txID string, note string) error {
227234
return err
228235
}
229236
// Prompt refresh.
230-
account.config.OnEvent(types.EventStatusChanged)
237+
account.Notify(observable.Event{
238+
Subject: string(types.EventStatusChanged),
239+
Action: action.Replace,
240+
Object: nil,
241+
})
231242
return nil
232243
}
233244

@@ -311,3 +322,11 @@ func (account *BaseAccount) ExportCSV(w io.Writer, transactions []*TransactionDa
311322
writer.Flush()
312323
return writer.Error()
313324
}
325+
326+
func (account *BaseAccount) notifySyncDone() {
327+
account.Notify(observable.Event{
328+
Subject: string(types.EventSyncDone),
329+
Action: action.Replace,
330+
Object: nil,
331+
})
332+
}

backend/accounts/baseaccount_test.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/config"
2929
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/signing"
3030
"github.com/BitBoxSwiss/bitbox-wallet-app/util/logging"
31+
"github.com/BitBoxSwiss/bitbox-wallet-app/util/observable"
3132
"github.com/BitBoxSwiss/bitbox-wallet-app/util/test"
3233
"github.com/btcsuite/btcd/btcutil/hdkeychain"
3334
"github.com/stretchr/testify/require"
@@ -65,7 +66,6 @@ func TestBaseAccount(t *testing.T) {
6566
},
6667
DBFolder: test.TstTempDir("baseaccount_test_dbfolder"),
6768
NotesFolder: test.TstTempDir("baseaccount_test_notesfolder"),
68-
OnEvent: func(event types.Event) { events <- event },
6969
RateUpdater: nil,
7070
GetNotifier: nil,
7171
GetSaveFilename: func(suggestedFilename string) string { return suggestedFilename },
@@ -122,6 +122,9 @@ func TestBaseAccount(t *testing.T) {
122122
},
123123
}
124124
account := NewBaseAccount(cfg, mockCoin, logging.Get().WithGroup("baseaccount_test"))
125+
account.Observe(func(event observable.Event) {
126+
events <- types.Event(event.Subject)
127+
})
125128
require.NoError(t, account.Initialize(accountIdentifier))
126129

127130
t.Run("config", func(t *testing.T) {
@@ -132,7 +135,6 @@ func TestBaseAccount(t *testing.T) {
132135
t.Run("synchronizer", func(t *testing.T) {
133136
require.False(t, account.Synced())
134137
done := account.Synchronizer.IncRequestsCounter()
135-
require.Equal(t, types.EventSyncStarted, checkEvent())
136138
require.False(t, account.Synced())
137139
done()
138140
require.Equal(t, types.EventStatusChanged, checkEvent()) // synced changed
@@ -141,7 +143,6 @@ func TestBaseAccount(t *testing.T) {
141143

142144
// no status changed event when syncing again (syncing is already true)
143145
done = account.Synchronizer.IncRequestsCounter()
144-
require.Equal(t, types.EventSyncStarted, checkEvent())
145146
done()
146147
require.Equal(t, types.EventSyncDone, checkEvent())
147148

backend/accounts/types/event.go

+5-9
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,12 @@ type Event string
1919

2020
const (
2121
// EventStatusChanged is fired when the status changes. Check the status using Initialized().
22-
EventStatusChanged Event = "statusChanged"
22+
EventStatusChanged Event = "status-changed"
2323

24-
// EventSyncStarted is fired when syncing with the blockchain starts. This happens in the very
25-
// beginning for the initial sync, and repeatedly afterwards when the wallet is updated (new
24+
// EventSyncDone happens when a sync is completed, i.e. when the wallet is updated (new
2625
// transactions, confirmations, etc.).
27-
EventSyncStarted Event = "syncstarted"
26+
EventSyncDone Event = "sync-done"
2827

29-
// EventSyncDone follows EventSyncStarted.
30-
EventSyncDone Event = "syncdone"
31-
32-
// EventHeadersSynced is fired when the headers finished syncing.
33-
EventHeadersSynced Event = "headersSynced"
28+
// EventSyncedAddressesCount is emitted when the frontend should receives a sync progress update.
29+
EventSyncedAddressesCount Event = "synced-addresses-count"
3430
)

backend/backend.go

+34-38
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,13 @@ var fixedURLWhitelist = []string{
106106
"https://cointracking.info/import/bitbox/",
107107
}
108108

109-
type backendEvent struct {
110-
Type string `json:"type"`
111-
Data string `json:"data"`
112-
Meta interface{} `json:"meta"`
113-
}
109+
// event are events emitted by the backend.
110+
type event string
111+
112+
const (
113+
// eventNewTxs is emitted when the user should be notified of new transactions.
114+
eventNewTxs event = "new-txs"
115+
)
114116

115117
type deviceEvent struct {
116118
DeviceID string `json:"deviceID"`
@@ -120,13 +122,6 @@ type deviceEvent struct {
120122
Meta interface{} `json:"meta"`
121123
}
122124

123-
// AccountEvent models an event triggered by an account.
124-
type AccountEvent struct {
125-
Type string `json:"type"`
126-
Code accountsTypes.Code `json:"code"`
127-
Data string `json:"data"`
128-
}
129-
130125
type authEventType string
131126

132127
const (
@@ -332,11 +327,14 @@ func (backend *Backend) notifyNewTxs(account accounts.Interface) {
332327
return
333328
}
334329
if unnotifiedCount != 0 {
335-
backend.events <- backendEvent{Type: "backend", Data: "newTxs", Meta: map[string]interface{}{
336-
"count": unnotifiedCount,
337-
"accountName": account.Config().Config.Name,
338-
}}
339-
330+
backend.Notify(observable.Event{
331+
Subject: string(eventNewTxs),
332+
Action: action.Replace,
333+
Object: map[string]interface{}{
334+
"count": unnotifiedCount,
335+
"accountName": account.Config().Config.Name,
336+
},
337+
})
340338
if err := notifier.MarkAllNotified(); err != nil {
341339
backend.log.WithError(err).Error("error marking notified")
342340
}
@@ -774,7 +772,15 @@ func (backend *Backend) Register(theDevice device.Interface) error {
774772

775773
mainKeystore := len(backend.devices) == 1
776774
theDevice.SetOnEvent(func(event deviceevent.Event, data interface{}) {
777-
switch event {
775+
backend.events <- deviceEvent{
776+
DeviceID: theDevice.Identifier(),
777+
Type: "device",
778+
Data: string(event),
779+
Meta: data,
780+
}
781+
})
782+
theDevice.Observe(func(event observable.Event) {
783+
switch deviceevent.Event(event.Subject) {
778784
case deviceevent.EventKeystoreGone:
779785
backend.DeregisterKeystore()
780786
case deviceevent.EventKeystoreAvailable:
@@ -783,30 +789,23 @@ func (backend *Backend) Register(theDevice device.Interface) error {
783789
backend.registerKeystore(theDevice.Keystore())
784790
}
785791
}
786-
backend.events <- deviceEvent{
787-
DeviceID: theDevice.Identifier(),
788-
Type: "device",
789-
Data: string(event),
790-
Meta: data,
791-
}
792+
backend.Notify(observable.Event{
793+
Subject: fmt.Sprintf(
794+
"devices/%s/%s/%s",
795+
theDevice.ProductName(),
796+
theDevice.Identifier(),
797+
event.Subject),
798+
Action: event.Action,
799+
Object: event.Object,
800+
})
792801
})
793802

794803
backend.onDeviceInit(theDevice)
795804
if err := theDevice.Init(backend.Testing()); err != nil {
796805
backend.onDeviceUninit(theDevice.Identifier())
797806
return err
798807
}
799-
theDevice.Observe(backend.Notify)
800-
801-
// Old-school
802-
select {
803-
case backend.events <- backendEvent{
804-
Type: "devices",
805-
Data: "registeredChanged",
806-
}:
807-
default:
808-
}
809-
// New-school
808+
810809
backend.Notify(observable.Event{
811810
Subject: "devices/registered",
812811
Action: action.Reload,
@@ -828,9 +827,6 @@ func (backend *Backend) Deregister(deviceID string) {
828827
delete(backend.devices, deviceID)
829828
backend.DeregisterKeystore()
830829

831-
// Old-school
832-
backend.events <- backendEvent{Type: "devices", Data: "registeredChanged"}
833-
// New-school
834830
backend.Notify(observable.Event{
835831
Subject: "devices/registered",
836832
Action: action.Reload,

backend/coins/btc/account.go

+11-9
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import (
3030
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/btc/addresses"
3131
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/btc/blockchain"
3232
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/btc/db/transactionsdb"
33-
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/btc/headers"
3433
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/btc/maketx"
3534
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/btc/transactions"
3635
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/btc/types"
@@ -325,11 +324,6 @@ func (account *Account) Initialize() error {
325324
account.SetOffline(account.coin.Blockchain().ConnectionError())
326325
account.coin.Blockchain().RegisterOnConnectionErrorChangedEvent(onConnectionStatusChanged)
327326
theHeaders := account.coin.Headers()
328-
theHeaders.SubscribeEvent(func(event headers.Event) {
329-
if event == headers.EventSynced {
330-
account.Config().OnEvent(accountsTypes.EventHeadersSynced)
331-
}
332-
})
333327
account.transactions = transactions.NewTransactions(
334328
account.coin.Net(), account.db, theHeaders, account.Synchronizer,
335329
account.coin.Blockchain(), account.notifier, account.log)
@@ -451,7 +445,11 @@ func (account *Account) Close() {
451445
account.log.Info("Closed DB")
452446
}
453447

454-
account.Config().OnEvent(accountsTypes.EventStatusChanged)
448+
account.Notify(observable.Event{
449+
Subject: string(accountsTypes.EventStatusChanged),
450+
Action: action.Replace,
451+
Object: nil,
452+
})
455453
account.closed = true
456454
}
457455

@@ -588,7 +586,7 @@ func (account *Account) incAndEmitSyncCounter() {
588586
if !account.Synced() {
589587
synced := atomic.AddUint32(&account.syncedAddressesCount, 1)
590588
account.Notify(observable.Event{
591-
Subject: fmt.Sprintf("account/%s/synced-addresses-count", account.Config().Config.Code),
589+
Subject: string(accountsTypes.EventSyncedAddressesCount),
592590
Action: action.Replace,
593591
Object: synced,
594592
})
@@ -642,7 +640,11 @@ func (account *Account) onAddressStatus(address *addresses.AccountAddress, statu
642640
// We are not closing client.blockchain here, as it is reused per coin with
643641
// different accounts.
644642
account.fatalError.Store(true)
645-
account.Config().OnEvent(accountsTypes.EventStatusChanged)
643+
account.Notify(observable.Event{
644+
Subject: string(accountsTypes.EventStatusChanged),
645+
Action: action.Replace,
646+
Object: nil,
647+
})
646648
return
647649
}
648650
// Safe some work in case account was closed in the meantime.

backend/coins/btc/account_test.go

-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import (
2424
"time"
2525

2626
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/accounts"
27-
accountsTypes "github.com/BitBoxSwiss/bitbox-wallet-app/backend/accounts/types"
2827
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/btc/blockchain"
2928
blockchainMock "github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/btc/blockchain/mocks"
3029
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/coin"
@@ -93,7 +92,6 @@ func mockAccount(t *testing.T, accountConfig *config.Account) *Account {
9392
&accounts.AccountConfig{
9493
Config: accountConfig,
9594
DBFolder: dbFolder,
96-
OnEvent: func(accountsTypes.Event) {},
9795
RateUpdater: nil,
9896
GetNotifier: func(signing.Configurations) accounts.Notifier { return nil },
9997
GetSaveFilename: func(suggestedFilename string) string { return suggestedFilename },

0 commit comments

Comments
 (0)