Skip to content
This repository was archived by the owner on Jun 7, 2023. It is now read-only.

Commit

Permalink
Fix invalid address data issue (#1089)
Browse files Browse the repository at this point in the history
Interrupting new account onboarding (on loading screen) leads wallet to throw continuous exceptions. The reason for exceptions was missing "completed" property in realm schema. This commit fixes the issue and also adds realm migration from schema version 0 to latest schema.
  • Loading branch information
laumair authored and cvarley100 committed Feb 18, 2019
1 parent 5e357e5 commit 30e63dd
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 7 deletions.
7 changes: 7 additions & 0 deletions src/shared/schema/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,13 @@ export const AccountInfoDuringSetupSchema = {
default: false,
},
meta: 'AccountMeta',
/**
* Determines if the account info is complete and account ready to be created and synced
*/
completed: {
type: 'bool',
default: false,
},
},
};

Expand Down
89 changes: 82 additions & 7 deletions src/shared/storage/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import isEmpty from 'lodash/isEmpty';
import isUndefined from 'lodash/isUndefined';
import map from 'lodash/map';
import merge from 'lodash/merge';
import omit from 'lodash/omit';
import values from 'lodash/values';
import size from 'lodash/size';
import {
Expand All @@ -26,12 +27,12 @@ import {
import { __MOBILE__, __TEST__, __DEV__ } from '../config';
import { preserveAddressLocalSpendStatus } from '../libs/iota/addresses';

const SCHEMA_VERSION = 0;
const SCHEMA_VERSION = 1;

const STORAGE_PATH =
const getStoragePath = (schemaVersion = SCHEMA_VERSION) =>
__MOBILE__ || __TEST__
? `trinity-${SCHEMA_VERSION}.realm`
: `${Electron.getUserDataPath()}/trinity${__DEV__ ? '-dev' : ''}-${SCHEMA_VERSION}.realm`;
? `trinity-${schemaVersion}.realm`
: `${Electron.getUserDataPath()}/trinity${__DEV__ ? '-dev' : ''}-${schemaVersion}.realm`;

// Initialise realm instance
let realm = {}; // eslint-disable-line import/no-mutable-exports
Expand Down Expand Up @@ -110,6 +111,18 @@ class Account {
realm.write(() => realm.create('Account', data));
}

/**
* Creates multiple accounts.
* @method createMultiple
*
* @param {object} data
*/
static createMultiple(accountsData) {
realm.write(() => {
each(accountsData, (data) => realm.create('Account', data));
});
}

/**
* Creates an account if it does not already exist.
*
Expand Down Expand Up @@ -716,7 +729,7 @@ class ErrorLog {
* Realm storage default configuration.
*/
export const config = {
path: STORAGE_PATH,
path: getStoragePath(),
schema: [
AccountSchema,
AddressSchema,
Expand Down Expand Up @@ -763,17 +776,79 @@ const purge = () =>
const initialise = (getEncryptionKeyPromise) =>
getEncryptionKeyPromise().then((encryptionKey) => {
realm = new Realm(assign({}, config, { encryptionKey }));
initialiseSync();
initialiseSync(encryptionKey);
});

/**
* Initialises storage.
*
* @method initialiseSync
*
* @param {array} encryptionKey
*
* @returns {Promise}
*/
const initialiseSync = () => {
const initialiseSync = (encryptionKey) => {
Wallet.createIfNotExists();

// FIXME (laumair) - Realm migration setup needs improvement.
// This is just a quick way to migrate realm data from schema version 0 to 1
// Schema version 1 adds (missing) "completed" property to AccountInfoDuringSetup schema
// If onboarding is interrupted on loading (without "completed" property), the wallet throws continuous exceptions
// See #isSettingUpNewAccount in shared/selectors/accounts
if (realm.schemaVersion >= 1) {
const schema = map(config.schema, (object) => {
// Omit "completed" property from AccountInfoDuringSetup schema because it wasn't defined in schema version 0
if (object.name === 'AccountInfoDuringSetup') {
return omit(object, ['properties.completed']);
}

return object;
});

const versionZeroConfig = assign({}, config, {
encryptionKey,
schemaVersion: 0,
path: getStoragePath(0),
schema,
});

const oldRealm = new Realm(versionZeroConfig);

const accountsData = oldRealm.objects('Account');
const versionZeroWalletData = oldRealm.objectForPrimaryKey('Wallet', 0);
const nodesData = oldRealm.objects('Node');

if (!isEmpty(accountsData)) {
Account.createMultiple(accountsData);
}

if (!isEmpty(versionZeroWalletData)) {
Wallet.updateLatest(
assign(
{},
versionZeroWalletData,
// Use latest schema version
{ version: Wallet.version },
),
);

// Check if accountInfoDuringSetup.name was set in scheme version 0
// If it was set, then that means there exists an account that hasn't been loaded properly in the wallet
// It also means that "completed" property isn't set to true
if (!isEmpty(versionZeroWalletData.accountInfoDuringSetup.name)) {
Wallet.updateAccountInfoDuringSetup({ completed: true });
}
}

if (!isEmpty(nodesData)) {
Node.addNodes(nodesData);
}

oldRealm.write(() => oldRealm.deleteAll());

Realm.deleteFile(versionZeroConfig);
}
};

/**
Expand Down

0 comments on commit 30e63dd

Please sign in to comment.