diff --git a/raiden-ts/package.json b/raiden-ts/package.json index 5f0bef6186..28263fa3bb 100644 --- a/raiden-ts/package.json +++ b/raiden-ts/package.json @@ -71,6 +71,7 @@ "memdown": "^5.1.0", "node-pre-gyp": "^0.15.0", "pouchdb-adapter-memory": "^7.2.2", + "pouchdb-debug": "^7.2.1", "prettier": "^2.1.1", "rimraf": "^3.0.2", "rxjs-marbles": "^6.0.1", @@ -207,7 +208,8 @@ ], "globals": { "ts-jest": { - "tsConfig": "/tests/tsconfig.json" + "tsConfig": "/tests/tsconfig.json", + "isolatedModules": true } } }, diff --git a/raiden-ts/tests/e2e/mocks.ts b/raiden-ts/tests/e2e/mocks.ts index 3b8b359ac3..797561680c 100644 --- a/raiden-ts/tests/e2e/mocks.ts +++ b/raiden-ts/tests/e2e/mocks.ts @@ -1,5 +1,4 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { Storage } from 'raiden-ts/utils/types'; export interface RequestOpts { uri: string; @@ -15,22 +14,6 @@ export interface RequestOpts { } export type RequestCallback = (err?: Error, response?: any, body?: any) => void; -export const MockStorage: jest.Mock, [{ [key: string]: string }?]> = jest.fn( - function (init?: { [key: string]: string }) { - const storage: NonNullable = init || {}; - return { - storage, - getItem: jest.fn(async (key: string) => storage[key] || null), - setItem: jest.fn(async (key: string, value: string) => { - storage[key] = value; - }), - removeItem: jest.fn(async (key: string) => { - delete storage[key]; - }), - }; - }, -); - export class MockMatrixRequestFn { public constructor(server: string) { this.endpoints['/login'] = ({}, callback) => diff --git a/raiden-ts/tests/e2e/raiden.spec.ts b/raiden-ts/tests/e2e/raiden.spec.ts index 871a2c6183..542ae69861 100644 --- a/raiden-ts/tests/e2e/raiden.spec.ts +++ b/raiden-ts/tests/e2e/raiden.spec.ts @@ -2,9 +2,12 @@ import { timer } from 'rxjs'; import { first, filter, takeUntil, take, toArray } from 'rxjs/operators'; import { Zero } from 'ethers/constants'; import { parseEther, parseUnits, bigNumberify, BigNumber, keccak256, Network } from 'ethers/utils'; +import PouchDB from 'pouchdb'; +import MemAdapter from 'pouchdb-adapter-memory'; +PouchDB.plugin(MemAdapter); import { TestProvider } from './provider'; -import { MockStorage, MockMatrixRequestFn } from './mocks'; +import { MockMatrixRequestFn } from './mocks'; // mock waitConfirmation Raiden helper to also trigger provider.mine jest.mock('raiden-ts/helpers', () => { @@ -48,7 +51,6 @@ describe('Raiden', () => { contractsInfo: ContractsInfo, snapId: number | undefined, raiden: Raiden, - storage: jest.Mocked, token: string, tokenNetwork: string, partner: string, @@ -74,7 +76,8 @@ describe('Raiden', () => { async function createRaiden( account: number | string, - stateOrStorage?: RaidenState | Storage, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + storage?: { state?: any; storage?: Storage; adapter?: any; prefix?: string }, subkey?: true, ): Promise { const raiden = await Raiden.create( @@ -82,7 +85,7 @@ describe('Raiden', () => { // but with same underlying ganache instance new TestProvider(provider._web3Provider), account, - stateOrStorage, + { adapter: 'memory', ...storage }, contractsInfo, config, subkey, @@ -141,7 +144,6 @@ describe('Raiden', () => { if (snapId !== undefined) await provider.revert(snapId); snapId = await provider.snapshot(); await provider.getBlockNumber(); - storage = new MockStorage(); fetch.mockResolvedValue({ ok: true, @@ -155,7 +157,7 @@ describe('Raiden', () => { httpBackend = new MockMatrixRequestFn(matrixServer); request(httpBackend.requestFn.bind(httpBackend)); - raiden = await createRaiden(0, storage); + raiden = await createRaiden(0); raiden.start(); }); @@ -178,7 +180,7 @@ describe('Raiden', () => { Raiden.create( provider, 0, - { storage, state: { ...raiden0State, blockNumber: raiden0State.blockNumber - 2 } }, + { state: { ...raiden0State, blockNumber: raiden0State.blockNumber - 2 } }, contractsInfo, config, ), @@ -188,24 +190,24 @@ describe('Raiden', () => { Raiden.create( provider, 0, - { storage, state: { ...raiden0State, blockNumber: raiden0State.blockNumber + 2 } }, + { state: { ...raiden0State, blockNumber: raiden0State.blockNumber + 2 } }, contractsInfo, config, ), ).resolves.toBeInstanceOf(Raiden); await expect( - Raiden.create(provider, 0, { storage }, contractsInfo, config), + Raiden.create(provider, 0, undefined, contractsInfo, config), ).resolves.toBeInstanceOf(Raiden); // token address not found as an account in provider - await expect(Raiden.create(provider, token, storage, contractsInfo, config)).rejects.toThrow( + await expect(Raiden.create(provider, token, undefined, contractsInfo, config)).rejects.toThrow( ErrorCodes.RDN_ACCOUNT_NOT_FOUND, ); // neither account index, address nor private key await expect( - Raiden.create(provider, '0x1234', storage, contractsInfo, config), + Raiden.create(provider, '0x1234', undefined, contractsInfo, config), ).rejects.toThrow(ErrorCodes.RDN_STRING_ACCOUNT_INVALID); // from hex-encoded private key, initial unknown state (decodable) but invalid address inside @@ -213,9 +215,11 @@ describe('Raiden', () => { Raiden.create( provider, '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', - JSON.stringify( - makeInitialState({ network, contractsInfo, address: token as Address }, { config }), - ), + { + state: JSON.stringify( + makeInitialState({ network, contractsInfo, address: token as Address }, { config }), + ), + }, contractsInfo, ), ).rejects.toThrow(/Mismatch between provided account and loaded state/i); @@ -224,23 +228,25 @@ describe('Raiden', () => { Raiden.create( provider, 1, - JSON.stringify( - makeInitialState( - { - network, - contractsInfo: { - TokenNetworkRegistry: { address: token as Address, block_number: 0 }, - ServiceRegistry: { address: partner as Address, block_number: 1 }, - UserDeposit: { address: partner as Address, block_number: 2 }, - SecretRegistry: { address: partner as Address, block_number: 3 }, - MonitoringService: { address: partner as Address, block_number: 3 }, - OneToN: { address: partner as Address, block_number: 3 }, + { + state: JSON.stringify( + makeInitialState( + { + network, + contractsInfo: { + TokenNetworkRegistry: { address: token as Address, block_number: 0 }, + ServiceRegistry: { address: partner as Address, block_number: 1 }, + UserDeposit: { address: partner as Address, block_number: 2 }, + SecretRegistry: { address: partner as Address, block_number: 3 }, + MonitoringService: { address: partner as Address, block_number: 3 }, + OneToN: { address: partner as Address, block_number: 3 }, + }, + address: accounts[1] as Address, }, - address: accounts[1] as Address, - }, - { config }, + { config }, + ), ), - ), + }, contractsInfo, ), ).rejects.toThrow(/Mismatch between network or registry address and loaded state/i); @@ -251,7 +257,12 @@ describe('Raiden', () => { const raiden1 = await Raiden.create( provider, accounts[1], - makeInitialState({ network, contractsInfo, address: accounts[1] as Address }, { config }), + { + state: makeInitialState( + { network, contractsInfo, address: accounts[1] as Address }, + { config }, + ), + }, contractsInfo.UserDeposit.address, config, ); @@ -293,7 +304,7 @@ describe('Raiden', () => { expect(raiden1.started).toBe(false); // success when creating using subkey - const raiden2 = await Raiden.create(provider, 0, storage, contractsInfo, config, true); + const raiden2 = await Raiden.create(provider, 0, undefined, contractsInfo, config, true); expect(raiden2).toBeInstanceOf(Raiden); expect(raiden2.mainAddress).toBe(accounts[0]); }); @@ -531,7 +542,7 @@ describe('Raiden', () => { ).blockNumber!; raidenState = undefined; - raiden = await createRaiden(0, storage); + raiden = await createRaiden(0); raiden.state$.subscribe((state) => (raidenState = state)); raiden.start(); @@ -729,10 +740,12 @@ describe('Raiden', () => { await expect(raiden.getAvailability(partner)).rejects.toThrow(ErrorCodes.TRNS_NO_VALID_USER); // success when using address of account on provider and initial state - const raiden1 = await createRaiden( - accounts[2], - makeInitialState({ network, contractsInfo, address: accounts[2] as Address }, { config }), - ); + const raiden1 = await createRaiden(accounts[2], { + state: makeInitialState( + { network, contractsInfo, address: accounts[2] as Address }, + { config }, + ), + }); expect(raiden1).toBeInstanceOf(Raiden); raiden1.start(); @@ -816,10 +829,12 @@ describe('Raiden', () => { let raiden1: Raiden; beforeEach(async () => { - raiden1 = await createRaiden( - partner, - makeInitialState({ network, contractsInfo, address: partner as Address }, { config }), - ); + raiden1 = await createRaiden(partner, { + state: makeInitialState( + { network, contractsInfo, address: partner as Address }, + { config }, + ), + }); raiden1.start(); // await raiden1 client matrix initialization @@ -850,10 +865,7 @@ describe('Raiden', () => { // there's some channel with enough capacity, but not the one returned by PFS const partner3 = accounts[3]; await raiden.openChannel(token, partner3, { deposit: 300 }); - const raiden3 = await createRaiden( - partner3, - makeInitialState({ network, contractsInfo, address: partner3 as Address }, { config }), - ); + const raiden3 = await createRaiden(partner3); raiden3.start(); await raiden3.action$.pipe(filter(isActionOf(matrixSetup)), first()).toPromise(); await expect(raiden.getAvailability(partner3)).resolves.toBeDefined(); @@ -888,10 +900,7 @@ describe('Raiden', () => { expect.assertions(7); const target = accounts[2], - raiden2 = await createRaiden( - target, - makeInitialState({ network, contractsInfo, address: target as Address }, { config }), - ), + raiden2 = await createRaiden(target), matrix2Promise = raiden2.action$ .pipe(filter(isActionOf(matrixSetup)), first()) .toPromise(); @@ -1027,14 +1036,8 @@ describe('Raiden', () => { await raiden.openChannel(token, partner); await raiden.depositChannel(token, partner, 200); - raiden1 = await createRaiden( - partner, - makeInitialState({ network, contractsInfo, address: partner as Address }, { config }), - ); - raiden2 = await createRaiden( - target, - makeInitialState({ network, contractsInfo, address: target as Address }, { config }), - ); + raiden1 = await createRaiden(partner); + raiden2 = await createRaiden(target); raiden1.start(); raiden2.start(); @@ -1177,10 +1180,7 @@ describe('Raiden', () => { // there's some channel with enough capacity, but not the one returned by PFS const partner3 = accounts[3]; await raiden.openChannel(token, partner3, { deposit: 300 }); - const raiden3 = await createRaiden( - partner3, - makeInitialState({ network, contractsInfo, address: partner3 as Address }, { config }), - ); + const raiden3 = await createRaiden(partner3); raiden3.start(); await raiden3.action$.pipe(filter(isActionOf(matrixSetup)), first()).toPromise(); await expect(raiden.getAvailability(partner3)).resolves.toBeDefined(); @@ -1246,7 +1246,7 @@ describe('Raiden', () => { raiden = await Raiden.create( new TestProvider(undefined, { network_id: 1 }), 0, - storage, + undefined, contractsInfo, config, ); @@ -1316,7 +1316,7 @@ describe('Raiden', () => { // stop and restart node raiden.stop(); await provider.mine(confirmationBlocks); - raiden = await createRaiden(0, storage); + raiden = await createRaiden(0); raiden.start(); const result = raiden.action$.pipe(filter(udcWithdrawn.is), take(2), toArray()).toPromise(); @@ -1350,7 +1350,7 @@ describe('Raiden', () => { test('subkey', async () => { expect.assertions(30); - const sub = await createRaiden(0, storage, true); + const sub = await createRaiden(0, undefined, true); const subStarted = sub.action$.pipe(filter(isActionOf(matrixSetup)), first()).toPromise(); sub.start(); diff --git a/raiden-ts/tests/global.d.ts b/raiden-ts/tests/global.d.ts index 604d048c44..88ef820920 100644 --- a/raiden-ts/tests/global.d.ts +++ b/raiden-ts/tests/global.d.ts @@ -40,3 +40,5 @@ declare module 'ganache-cli' { const ganache: Ganache; export default ganache; } + +declare module 'pouchdb-debug'; diff --git a/raiden-ts/tests/unit/epics/channels.spec.ts b/raiden-ts/tests/unit/epics/channels.spec.ts index db1517b866..89e57d1a0f 100644 --- a/raiden-ts/tests/unit/epics/channels.spec.ts +++ b/raiden-ts/tests/unit/epics/channels.spec.ts @@ -38,7 +38,7 @@ import { bigNumberify, BigNumber } from 'ethers/utils'; import { Zero, HashZero } from 'ethers/constants'; import { defaultAbiCoder } from 'ethers/utils/abi-coder'; -import { UInt } from 'raiden-ts/utils/types'; +import { UInt, decode } from 'raiden-ts/utils/types'; import { LocksrootZero } from 'raiden-ts/constants'; import { channelMonitored, @@ -52,9 +52,10 @@ import { import { channelUniqueKey } from 'raiden-ts/channels/utils'; import { ChannelState } from 'raiden-ts/channels'; import { createBalanceHash, getBalanceProofFromEnvelopeMessage } from 'raiden-ts/messages'; -import { getLocksroot } from 'raiden-ts/transfers/utils'; +import { getLocksroot, transferKey } from 'raiden-ts/transfers/utils'; import { ErrorCodes } from 'raiden-ts/utils/error'; import { raidenConfigUpdate } from 'raiden-ts/actions'; +import { Direction, TransferState } from 'raiden-ts/transfers/state'; test('channelSettleableEpic', async () => { expect.assertions(3); @@ -729,14 +730,22 @@ describe('channelSettleEpic', () => { await ensureChannelIsClosed([partner, raiden]); // partner closes channel // LockedTransfer message we sent, not one before latest BP - const locked = partner.store.getState().received[secrethash].transfer; + const locked = decode( + TransferState, + await partner.deps.db.get(transferKey({ direction: Direction.RECEIVED, secrethash })), + ).transfer; // ensure our latest own BP is the unlocked one, the one after Locked expect(getChannel(raiden, partner).own.balanceProof.nonce).toEqual(locked.nonce.add(1)); // lets mock getChannelParticipantInfo to look like partner closed with BP from locked state // instead of current/latest one, which is unlocked const settleTx = makeTransaction(); - tokenNetworkContract.functions.settleChannel.mockResolvedValue(settleTx); + const settled = new Promise((resolve) => { + tokenNetworkContract.functions.settleChannel.mockImplementation(async () => { + ensureChannelIsSettled([raiden, partner]).then(resolve); + return settleTx; + }); + }); tokenNetworkContract.functions.getChannelParticipantInfo.mockImplementation( async ({}, participant, {}) => { // from our perspective, partner closed the channel with wrong balanceProof @@ -758,8 +767,8 @@ describe('channelSettleEpic', () => { raiden.store.dispatch( channelSettle.request(undefined, { tokenNetwork, partner: partner.address }), ); - await ensureChannelIsSettled([raiden, partner]); await waitBlock(); + await settled; // result is undefined on success as the respective channelSettle.success is emitted by the // channelMonitoredEpic, which monitors the blockchain for channel events @@ -798,14 +807,22 @@ describe('channelSettleEpic', () => { await ensureChannelIsClosed([partner, raiden]); // partner closes channel // LockedTransfer message we received, not one before latest BP - const locked = raiden.store.getState().received[secrethash].transfer; + const locked = decode( + TransferState, + await raiden.deps.db.get(transferKey({ direction: Direction.RECEIVED, secrethash })), + ).transfer; // ensure our latest partner BP is the unlocked one, the one after Locked expect(getChannel(raiden, partner).partner.balanceProof.nonce).toEqual(locked.nonce.add(1)); // lets mock getChannelParticipantInfo to look like partner closed with BP from locked state // instead of current/latest one, which is unlocked const settleTx = makeTransaction(); - tokenNetworkContract.functions.settleChannel.mockResolvedValue(settleTx); + const settled = new Promise((resolve) => { + tokenNetworkContract.functions.settleChannel.mockImplementation(async () => { + ensureChannelIsSettled([raiden, partner]).then(resolve); + return settleTx; + }); + }); tokenNetworkContract.functions.getChannelParticipantInfo.mockImplementation( async ({}, participant, {}) => { // from our perspective, partner closed the channel with wrong balanceProof @@ -827,8 +844,8 @@ describe('channelSettleEpic', () => { raiden.store.dispatch( channelSettle.request(undefined, { tokenNetwork, partner: partner.address }), ); - await ensureChannelIsSettled([raiden, partner]); await waitBlock(); + await settled; // result is undefined on success as the respective channelSettle.success is emitted by the // channelMonitoredEpic, which monitors the blockchain for channel events diff --git a/raiden-ts/tests/unit/fixtures.ts b/raiden-ts/tests/unit/fixtures.ts index 3f59500ac1..e40c1572aa 100644 --- a/raiden-ts/tests/unit/fixtures.ts +++ b/raiden-ts/tests/unit/fixtures.ts @@ -12,19 +12,20 @@ import { } from './mocks'; import { Subject } from 'rxjs'; -import { first, scan, pluck } from 'rxjs/operators'; +import { first, scan, map } from 'rxjs/operators'; import { Wallet } from 'ethers'; import { AddressZero, Zero, HashZero } from 'ethers/constants'; import { bigNumberify, defaultAbiCoder } from 'ethers/utils'; import { Filter } from 'ethers/providers'; -import { Address, Hash, Int, UInt, untime } from 'raiden-ts/utils/types'; +import { Address, Hash, Int, UInt, untime, decode } from 'raiden-ts/utils/types'; import { Processed, MessageType } from 'raiden-ts/messages/types'; import { makeMessageId, makePaymentId, makeSecret, getSecrethash, + transferKey, } from 'raiden-ts/transfers/utils'; import { IOU } from 'raiden-ts/services/types'; import { RaidenState } from 'raiden-ts/state'; @@ -40,6 +41,8 @@ import { transfer, transferUnlock } from 'raiden-ts/transfers/actions'; import { messageReceived } from 'raiden-ts/messages/actions'; import { TokenNetwork } from 'raiden-ts/contracts/TokenNetwork'; import { assert } from 'raiden-ts/utils'; +import { get$ } from 'raiden-ts/db/utils'; +import { TransferStateish } from 'raiden-ts/db/types'; /** * Composes several constants used across epics @@ -362,14 +365,19 @@ export async function ensureTransferPending( value = amount, ): Promise { await ensureChannelIsDeposited([raiden, partner], value); // from partner to raiden - if (secrethash in partner.store.getState().received) - return raiden.store.getState().sent[secrethash]; + const transferState = await raiden.deps.db + .get(transferKey({ direction: Direction.SENT, secrethash })) + .catch(() => null); + if (transferState) return decode(TransferState, transferState); const paymentId = makePaymentId(); - const sentPromise = raiden.deps.latest$ + const sentPromise = get$( + raiden.deps.db, + transferKey({ direction: Direction.SENT, secrethash }), + ) .pipe( - first(({ state }) => secrethash in state.sent), - pluck('state', 'sent', secrethash), + first(), + map((doc) => decode(TransferState, doc)), ) .toPromise(); raiden.store.dispatch( @@ -387,8 +395,14 @@ export async function ensureTransferPending( ); const sent = await sentPromise; - const receivedPromise = partner.deps.latest$ - .pipe(first(({ state }) => secrethash in state.received)) + const receivedPromise = get$( + partner.deps.db, + transferKey({ direction: Direction.RECEIVED, secrethash }), + ) + .pipe( + first(), + map((doc) => decode(TransferState, doc)), + ) .toPromise(); partner.store.dispatch( messageReceived( @@ -414,13 +428,18 @@ export async function ensureTransferUnlocked( value = amount, ): Promise { await ensureTransferPending([raiden, partner], value); // from partner to raiden - if (partner.store.getState().received[secrethash]?.unlock) - return partner.store.getState().received[secrethash]; + const transferState = await partner.deps.db + .get(transferKey({ direction: Direction.RECEIVED, secrethash })) + .catch(() => null); + if (transferState?.unlock) return decode(TransferState, transferState); - const sentPromise = raiden.deps.latest$ + const sentPromise = get$( + raiden.deps.db, + transferKey({ direction: Direction.SENT, secrethash }), + ) .pipe( - first(({ state }) => !!state.sent[secrethash]?.unlock), - pluck('state', 'sent', secrethash), + first((doc) => !!doc.unlock), + map((doc) => decode(TransferState, doc)), ) .toPromise(); raiden.store.dispatch( @@ -428,8 +447,14 @@ export async function ensureTransferUnlocked( ); const sent = await sentPromise; - const receivedPromise = partner.deps.latest$ - .pipe(first(({ state }) => !!state.received[secrethash]?.unlock)) + const receivedPromise = get$( + partner.deps.db, + transferKey({ direction: Direction.RECEIVED, secrethash }), + ) + .pipe( + first((doc) => !!doc.unlock), + map((doc) => decode(TransferState, doc)), + ) .toPromise(); partner.store.dispatch( messageReceived( diff --git a/raiden-ts/tests/unit/mocks.ts b/raiden-ts/tests/unit/mocks.ts index 2aaa37c8d2..672852b9cb 100644 --- a/raiden-ts/tests/unit/mocks.ts +++ b/raiden-ts/tests/unit/mocks.ts @@ -5,6 +5,7 @@ patchEthersDefineReadOnly(); patchEthersGetNetwork(); import { AsyncSubject, of, BehaviorSubject, ReplaySubject } from 'rxjs'; +import { filter, take } from 'rxjs/operators'; import { MatrixClient } from 'matrix-js-sdk'; import { EventEmitter } from 'events'; import { memoize } from 'lodash'; @@ -28,6 +29,12 @@ import { } from 'ethers/utils'; import { Contract, EventFilter, ContractTransaction } from 'ethers/contract'; import { Wallet } from 'ethers/wallet'; +import PouchDB from 'pouchdb'; +import MemAdapter from 'pouchdb-adapter-memory'; +PouchDB.plugin(MemAdapter); +import PouchDebug from 'pouchdb-debug'; +PouchDB.plugin(PouchDebug); +// PouchDB.debug.enable('*'); import { TokenNetworkRegistry } from 'raiden-ts/contracts/TokenNetworkRegistry'; import { TokenNetwork } from 'raiden-ts/contracts/TokenNetwork'; @@ -58,9 +65,15 @@ import { raidenReducer } from 'raiden-ts/reducer'; import { ShutdownReason } from 'raiden-ts/constants'; import { createEpicMiddleware } from 'redux-observable'; import { raidenRootEpic } from 'raiden-ts/epics'; -import { filter, take } from 'rxjs/operators'; +import { migrateDatabase, putRaidenState } from 'raiden-ts/db/utils'; +import { RaidenDatabaseConstructor } from 'raiden-ts/db/types'; +import { getNetworkName } from 'raiden-ts/utils/ethers'; logging.setLevel(logging.levels.DEBUG); +const RaidenPouchDB = PouchDB.defaults({ + adapter: 'memory', + log: logging, +} as any) as RaidenDatabaseConstructor; export type MockedTransaction = ContractTransaction & { wait: jest.MockedFunction; @@ -541,6 +554,14 @@ export function raidenEpicDeps(): MockRaidenEpicDeps { }), config$ = latest$.pipe(pluckDistinct('config')); + const dbName = [ + 'raiden', + getNetworkName(network), + contractsInfo.TokenNetworkRegistry.address, + address, + ].join('_'); + const db = new RaidenPouchDB(dbName); + return { latest$, config$, @@ -559,6 +580,7 @@ export function raidenEpicDeps(): MockRaidenEpicDeps { userDepositContract, secretRegistryContract, monitoringServiceContract, + db, }; } @@ -973,6 +995,21 @@ export async function makeRaiden( const latest$ = new ReplaySubject(1); const config$ = latest$.pipe(pluckDistinct('config')); + if (!initialState) + initialState = makeInitialState( + { network, address, contractsInfo }, + { blockNumber: provider.blockNumber }, + ); + + const dbName = [ + 'raiden', + getNetworkName(network), + contractsInfo.TokenNetworkRegistry.address, + address, + ].join('_'); + const db = await migrateDatabase.call(RaidenPouchDB, dbName); + await putRaidenState(db, initialState); + const deps = { latest$, config$, @@ -991,14 +1028,9 @@ export async function makeRaiden( userDepositContract, secretRegistryContract, monitoringServiceContract, + db, }; - if (!initialState) - initialState = makeInitialState( - { network, address, contractsInfo }, - { blockNumber: provider.blockNumber }, - ); - const epicMiddleware = createEpicMiddleware< RaidenAction, RaidenAction, @@ -1060,8 +1092,6 @@ export async function makeRaiden( return raiden; } -const cachedWallets = Array.from({ length: 3 }, makeWallet); - /** * Create multiple mocked clients * @@ -1070,7 +1100,7 @@ const cachedWallets = Array.from({ length: 3 }, makeWallet); * @returns Array of mocked clients */ export async function makeRaidens(length: number, start = true): Promise { - return Promise.all(Array.from({ length }, (_, i) => makeRaiden(cachedWallets[i], start))); + return Promise.all(Array.from({ length }, () => makeRaiden(undefined, start))); } /**