Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
ef19949
feat(backup)_: local user data backups (#6722)
jrainville Aug 5, 2025
e6d89c1
chore(backup)_: enable local backup feature flag
jrainville Aug 1, 2025
feab3a8
chore(backup)_: double interval in between waku backups
jrainville Aug 1, 2025
a871761
fix(backup)_: fix missing image in group events
jrainville Aug 5, 2025
8e5103d
fix_: fix import
jrainville Aug 6, 2025
f6d9686
test_: android path
jrainville Aug 6, 2025
71f0e59
fix(backup)_: ignore already backed up watch accounts
jrainville Aug 5, 2025
4e531ef
fix(backup)_: process all backups before throwing an error
jrainville Aug 5, 2025
9019b37
fix(backup): backup import fails if the community was left
jrainville Aug 28, 2025
978b96e
feat(backup): set backup path to user's config folder if not set
jrainville Aug 27, 2025
a28e71c
fix(backup)_: use compressed pubkey for the local backup name
jrainville Oct 1, 2025
5f1cbef
feat(backup): implement messages backup poc
jrainville Oct 1, 2025
1dbf178
fix(settings): fix wrongly named reactFieldName for messages backup
jrainville Sep 11, 2025
f5098e2
feat(pairing): enable syncing messages during local pairing
jrainville Sep 22, 2025
aca442a
feat(pairing): add config to let users enable message syncing
jrainville Oct 1, 2025
36623ab
fix(backup): add missing clock on backup messages
jrainville Sep 25, 2025
5152e00
test(backup): improve tests by using a map instead of a loop
jrainville Oct 1, 2025
13db971
chore: fix issues with cherry-picks
jrainville Oct 1, 2025
e8547f3
fix path
jrainville Oct 2, 2025
2f47fa8
hardcode for testing
jrainville Oct 2, 2025
b565110
fix(pairing): fix pairing messages using wrong chat ID for 1-1
jrainville Oct 2, 2025
d1ff352
fix test
jrainville Oct 2, 2025
b7c853d
Revert "hardcode for testing"
jrainville Oct 2, 2025
42ddea9
fix: linter
igor-sirotin Oct 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions account/accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
gethkeystore "github.com/ethereum/go-ethereum/accounts/keystore"
gethcommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"

"github.com/status-im/status-go/account/generator"
gocommon "github.com/status-im/status-go/common"
"github.com/status-im/status-go/eth-node/crypto"
Expand Down
12 changes: 12 additions & 0 deletions api/geth_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ func (b *GethStatusBackend) initialize() {
b.statusNode.SetMultiaccountsDB(b.multiaccountsDB)
b.LocalPairingStateManager = new(statecontrol.ProcessStateManager)
b.LocalPairingStateManager.SetPairing(false)
b.LocalPairingStateManager.SetMessageSyncEnabled(false)
}

// StatusNode returns reference to node manager
Expand Down Expand Up @@ -2773,6 +2774,16 @@ func (b *GethStatusBackend) SelectAccount(loginParams account.LoginParams) error
return err
}

chatAccount, err := b.accountManager.SelectedChatAccount()
if err != nil {
return err
}

if err = b.statusNode.StartLocalBackup(chatAccount.AccountKey.PrivateKey); err != nil {
b.logger.Error("failed to start local backup", zap.Error(err))
// we don't return the error to avoid login failure
}

return nil
}

Expand Down Expand Up @@ -2881,6 +2892,7 @@ func (b *GethStatusBackend) ExtractGroupMembershipSignatures(signaturePairs [][2

// SignGroupMembership signs a piece of data containing membership information
func (b *GethStatusBackend) SignGroupMembership(content string) (string, error) {
fmt.Println("SignGroupMembership")
selectedChatAccount, err := b.accountManager.SelectedChatAccount()
if err != nil {
return "", err
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE settings ADD COLUMN backup_path VARCHAR DEFAULT '';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE settings ADD COLUMN messages_backup_enabled BOOLEAN DEFAULT FALSE;
34 changes: 34 additions & 0 deletions mobile/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -2429,3 +2429,37 @@ func IntendedPanic(message string) string {
panic(err)
})
}

func performLocalBackup() string {
filePath, err := statusBackend.StatusNode().PerformLocalBackup()
if err != nil {
return makeJSONResponse(err)
}

respJSON, err := json.Marshal(map[string]interface{}{
"filePath": filePath,
})
if err != nil {
return makeJSONResponse(err)
}

return string(respJSON)
}

func PerformLocalBackup() string {
return callWithResponse(performLocalBackup)
}

func LoadLocalBackup(requestJSON string) string {
var request requests.LoadLocalBackup
err := json.Unmarshal([]byte(requestJSON), &request)
if err != nil {
return makeJSONResponse(err)
}
err = request.Validate()
if err != nil {
return makeJSONResponse(err)
}
err = statusBackend.StatusNode().LoadLocalBackup(request.FilePath)
return makeJSONResponse(err)
}
11 changes: 11 additions & 0 deletions multiaccounts/settings/columns.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ var (
dBColumnName: "backup_fetched",
valueHandler: BoolHandler,
}
BackupPath = SettingField{
reactFieldName: "backup-path",
dBColumnName: "backup_path",
}
ChaosMode = SettingField{
reactFieldName: "chaos-mode?",
dBColumnName: "chaos_mode",
Expand Down Expand Up @@ -181,6 +185,11 @@ var (
reactFieldName: "log-level",
dBColumnName: "log_level",
}
MessagesBackupEnabled = SettingField{
reactFieldName: "messages-backup-enabled?",
dBColumnName: "messages_backup_enabled",
valueHandler: BoolHandler,
}
MessagesFromContactsOnly = SettingField{
reactFieldName: "messages-from-contacts-only",
dBColumnName: "messages_from_contacts_only",
Expand Down Expand Up @@ -548,6 +557,7 @@ var (
AutoMessageEnabled,
BackupEnabled,
BackupFetched,
BackupPath,
Bio,
ChaosMode,
CollectibleGroupByCollection,
Expand Down Expand Up @@ -577,6 +587,7 @@ var (
LinkPreviewRequestEnabled,
LinkPreviewsEnabledSites,
LogLevel,
MessagesBackupEnabled,
MessagesFromContactsOnly,
Mnemonic,
MnemonicRemoved,
Expand Down
39 changes: 34 additions & 5 deletions multiaccounts/settings/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import (
"context"
"database/sql"
"encoding/json"
"errors"
"fmt"
"sync"
"time"

"github.com/status-im/status-go/common/dbsetup"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/logutils"
"github.com/status-im/status-go/multiaccounts/errors"
maErrors "github.com/status-im/status-go/multiaccounts/errors"
"github.com/status-im/status-go/nodecfg"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/sqlite"
Expand Down Expand Up @@ -213,7 +214,7 @@ func (db *Database) getSettingFieldFromReactName(reactName string) (SettingField
return s, nil
}
}
return SettingField{}, errors.ErrInvalidConfig
return SettingField{}, maErrors.ErrInvalidConfig
}

func (db *Database) makeSelectRow(setting SettingField) *sql.Row {
Expand Down Expand Up @@ -243,12 +244,21 @@ func (db *Database) saveSetting(setting SettingField, value interface{}) error {
return err
}

_, err = update.Exec(value)
result, err := update.Exec(value)
if err != nil {
return err
}

rowsAffected, err := result.RowsAffected()
if err != nil {
return err
}

if rowsAffected == 0 {
// If no rows were affected, it means the setting does not exist
return errors.New("settings not initialized, please call CreateSettings first")
}

if db.notifier != nil {
db.notifier(setting, value)
}
Expand Down Expand Up @@ -334,7 +344,7 @@ func (db *Database) SaveSyncSetting(setting SettingField, value interface{}, clo
return err
}
if clock <= ls {
return errors.ErrNewClockOlderThanCurrent
return maErrors.ErrNewClockOlderThanCurrent
}

err = db.SetSettingLastSynced(setting, clock)
Expand Down Expand Up @@ -398,7 +408,8 @@ func (db *Database) GetSettings() (Settings, error) {
test_networks_enabled, mutual_contact_enabled, profile_migration_needed, wallet_token_preferences_group_by_community, url_unfurling_mode,
mnemonic_was_not_shown, wallet_show_community_asset_when_sending_tokens, wallet_display_assets_below_balance,
wallet_display_assets_below_balance_threshold, wallet_collectible_preferences_group_by_collection, wallet_collectible_preferences_group_by_community,
peer_syncing_enabled, auto_refresh_tokens_enabled, last_tokens_update, news_feed_enabled, news_feed_last_fetched_timestamp, news_rss_enabled
peer_syncing_enabled, auto_refresh_tokens_enabled, last_tokens_update, news_feed_enabled, news_feed_last_fetched_timestamp, news_rss_enabled, backup_path,
messages_backup_enabled
FROM
settings
WHERE
Expand Down Expand Up @@ -488,6 +499,8 @@ func (db *Database) GetSettings() (Settings, error) {
&s.NewsFeedEnabled,
&newsFeedLastFetchedTimestamp,
&s.NewsRSSEnabled,
&s.BackupPath,
&s.MessagesBackupEnabled,
)

if err != nil {
Expand Down Expand Up @@ -929,3 +942,19 @@ func (db *Database) NewsRSSEnabled() (result bool, err error) {
}
return result, err
}

func (db *Database) BackupPath() (result string, err error) {
err = db.makeSelectRow(BackupPath).Scan(&result)
if err == sql.ErrNoRows {
return result, nil
}
return result, err
}

func (db *Database) MessagesBackupEnabled() (result bool, err error) {
err = db.makeSelectRow(MessagesBackupEnabled).Scan(&result)
if err == sql.ErrNoRows {
return result, nil
}
return result, err
}
2 changes: 2 additions & 0 deletions multiaccounts/settings/database_settings_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ type DatabaseSettingsManager interface {
CanSyncOnMobileNetwork() (result bool, err error)
ShouldBroadcastUserStatus() (result bool, err error)
BackupEnabled() (result bool, err error)
BackupPath() (result string, err error)
MessagesBackupEnabled() (result bool, err error)
AutoMessageEnabled() (result bool, err error)
LastBackup() (result uint64, err error)
BackupFetched() (result bool, err error)
Expand Down
43 changes: 43 additions & 0 deletions multiaccounts/settings/database_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ package settings

import (
"encoding/json"
"net/url"
"os"
"testing"
"time"

"github.com/brianvoe/gofakeit/v6"

"github.com/stretchr/testify/require"

"github.com/status-im/status-go/appdatabase"
Expand Down Expand Up @@ -296,3 +299,43 @@ func TestDatabase_NewsRSSEnabled(t *testing.T) {
require.NoError(t, err)
require.Equal(t, false, settings.NewsRSSEnabled)
}

func TestDatabase_BackupPath(t *testing.T) {
db, stop := setupTestDB(t)
defer stop()

require.NoError(t, db.CreateSettings(settings, config))

path, err := db.BackupPath()
require.NoError(t, err)
// The default backup path is empty
require.Equal(t, "", path)

testPath, err := url.JoinPath(gofakeit.LetterN(3), gofakeit.LetterN(3))
require.NoError(t, err)
require.NotEmpty(t, testPath)
err = db.SaveSetting(BackupPath.GetReactName(), testPath)
require.NoError(t, err)

settings, err = db.GetSettings()
require.NoError(t, err)
require.Equal(t, testPath, settings.BackupPath)
}

func TestDatabase_MessagesBackupEnabled(t *testing.T) {
db, stop := setupTestDB(t)
defer stop()

require.NoError(t, db.CreateSettings(settings, config))

enabled, err := db.MessagesBackupEnabled()
require.NoError(t, err)
require.Equal(t, false, enabled)

err = db.SaveSetting(MessagesBackupEnabled.GetReactName(), true)
require.NoError(t, err)

settings, err = db.GetSettings()
require.NoError(t, err)
require.Equal(t, true, settings.MessagesBackupEnabled)
}
2 changes: 2 additions & 0 deletions multiaccounts/settings/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ type Settings struct {
LastBackup uint64 `json:"last-backup,omitempty"`
BackupEnabled bool `json:"backup-enabled?,omitempty"`
BackupFetched bool `json:"backup-fetched?,omitempty"`
BackupPath string `json:"backup-path,omitempty"`
MessagesBackupEnabled bool `json:"messages-backup-enabled?,omitempty"`
AutoMessageEnabled bool `json:"auto-message-enabled?,omitempty"`
GifAPIKey string `json:"gifs/api-key"`
TestNetworksEnabled bool `json:"test-networks-enabled?,omitempty"`
Expand Down
Loading
Loading