Skip to content

Commit 93908a9

Browse files
authored
feat(ironfish): Check if wallet is encrypted when calling setAccount (#5300)
* feat(ironfish): Remove cached accounts when encrypting/decrypting * feat(ironfish): Check if wallet is encrypted when calling setAccount
1 parent f9fbde1 commit 93908a9

File tree

3 files changed

+86
-1
lines changed

3 files changed

+86
-1
lines changed

ironfish/src/wallet/walletdb/__fixtures__/walletdb.test.ts.fixture

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,5 +1150,36 @@
11501150
"sequence": 1
11511151
}
11521152
}
1153+
],
1154+
"WalletDB setAccount throws an error if existing accounts are encrypted": [
1155+
{
1156+
"value": {
1157+
"encrypted": false,
1158+
"version": 4,
1159+
"id": "1326265d-45b5-4646-8bf1-4434c896bcd1",
1160+
"name": "A",
1161+
"spendingKey": "d71768604bc37a2cd7b48e194b58c43bee3aeb398d11b9a0ef998ef759a6e08b",
1162+
"viewKey": "9a1e4d1d5ea401cb0454e95b4681ddd6acef636f3b406f8664f9d2bcccaa979d0495d1e8372407cbb4505a7167232f1d3436d5723bff554f911d96df1d0e2821",
1163+
"incomingViewKey": "64b66b4a68d8eaba6b7bfbd55d59abe794f598750b0dc9f136d2558502c64303",
1164+
"outgoingViewKey": "5d40218d1b4da92ec42c0538380b682c179d44fbd25ef999566539dac1d70d4f",
1165+
"publicAddress": "204b3270b44e987ba022b5b8eda7f41ebf55eb19ce61b7723a031bec9ed5bfcf",
1166+
"createdAt": {
1167+
"hash": {
1168+
"type": "Buffer",
1169+
"data": "base64:R5HXrp+X3xAO8VWOhHctagm0N2I4goP3XG8goyqIqoY="
1170+
},
1171+
"sequence": 1
1172+
},
1173+
"scanningEnabled": true,
1174+
"proofAuthorizingKey": "4ebcb8cbb3bb735f9421ea40538f24ada921c9736889e2a3384ddd3707c0ad05"
1175+
},
1176+
"head": {
1177+
"hash": {
1178+
"type": "Buffer",
1179+
"data": "base64:R5HXrp+X3xAO8VWOhHctagm0N2I4goP3XG8goyqIqoY="
1180+
},
1181+
"sequence": 1
1182+
}
1183+
}
11531184
]
11541185
}

ironfish/src/wallet/walletdb/walletdb.test.ts

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* This Source Code Form is subject to the terms of the Mozilla Public
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4-
import { Asset, multisig } from '@ironfish/rust-nodejs'
4+
import { Asset, generateKey, multisig } from '@ironfish/rust-nodejs'
55
import { randomBytes } from 'crypto'
66
import { Assert } from '../../assert'
77
import {
@@ -14,6 +14,7 @@ import { AsyncUtils } from '../../utils'
1414
import { Account } from '../account/account'
1515
import { EncryptedAccount } from '../account/encryptedAccount'
1616
import { AccountDecryptionFailedError } from '../errors'
17+
import { DecryptedAccountValue } from './accountValue'
1718
import { DecryptedNoteValue } from './decryptedNoteValue'
1819

1920
describe('WalletDB', () => {
@@ -619,4 +620,53 @@ describe('WalletDB', () => {
619620
expect(await walletDb.accountsEncrypted()).toBe(false)
620621
})
621622
})
623+
624+
describe('setAccount', () => {
625+
it('throws an error if existing accounts are encrypted', async () => {
626+
const node = (await nodeTest.createSetup()).node
627+
const walletDb = node.wallet.walletDb
628+
const passphrase = 'foobar'
629+
630+
await useAccountFixture(node.wallet, 'A')
631+
await walletDb.encryptAccounts(passphrase)
632+
633+
const key = generateKey()
634+
const accountValue: DecryptedAccountValue = {
635+
encrypted: false,
636+
id: '0',
637+
name: 'new-account',
638+
version: 1,
639+
createdAt: null,
640+
scanningEnabled: false,
641+
...key,
642+
}
643+
const account = new Account({ accountValue, walletDb })
644+
645+
await expect(walletDb.setAccount(account)).rejects.toThrow()
646+
})
647+
648+
it('saves the account', async () => {
649+
const node = (await nodeTest.createSetup()).node
650+
const walletDb = node.wallet.walletDb
651+
652+
const key = generateKey()
653+
const accountValue: DecryptedAccountValue = {
654+
encrypted: false,
655+
id: '1',
656+
name: 'new-account',
657+
version: 1,
658+
createdAt: null,
659+
scanningEnabled: false,
660+
...key,
661+
}
662+
const account = new Account({ accountValue, walletDb })
663+
664+
await walletDb.setAccount(account)
665+
666+
expect(await walletDb.accounts.get(account.id)).not.toBeUndefined()
667+
expect(
668+
await walletDb.balances.get([account.prefix, Asset.nativeId()]),
669+
).not.toBeUndefined()
670+
})
671+
})
622672
})

ironfish/src/wallet/walletdb/walletdb.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,10 @@ export class WalletDB {
342342

343343
async setAccount(account: Account, tx?: IDatabaseTransaction): Promise<void> {
344344
await this.db.withTransaction(tx, async (tx) => {
345+
if (await this.accountsEncrypted(tx)) {
346+
throw new Error('Cannot save decrypted account when accounts are encrypted')
347+
}
348+
345349
await this.accounts.put(account.id, account.serialize(), tx)
346350

347351
const nativeUnconfirmedBalance = await this.balances.get(

0 commit comments

Comments
 (0)