// Copyright 2017-2018 @polkadot/api-provider authors & contributors // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. // FIXME: This file is way too long and way too messy import { StorageFunction } from '@polkadot/types/StorageKey'; import { KeyringPair } from '@polkadot/util-keyring/types'; import { ProviderInterface$Emitted } from '../types'; import { MockState, MockState$Db, MockState$Subscriptions } from './types'; import BN from 'bn.js'; import storage from '@polkadot/storage/static'; import Header from '@polkadot/types/Header'; import bnToU8a from '@polkadot/util/bn/toU8a'; import u8aToHex from '@polkadot/util/u8a/toHex'; import randomAsU8a from '@polkadot/util-crypto/random/asU8a'; import testKeyring from '@polkadot/util-keyring/testing'; const keyring = testKeyring(); const emitEvents: Array = ['connected', 'disconnected']; let emitIndex = 0; function makeBlockHeader (prevNumber: BN) { const blockNumber = prevNumber.addn(1); return { digest: { logs: [] }, extrinsicsRoot: randomAsU8a(), number: blockNumber, parentHash: prevNumber.eqn(-1) ? new Uint8Array(32) : bnToU8a(prevNumber, 256, false), stateRoot: bnToU8a(blockNumber, 256, false) }; } function updateSubs (subscriptions: MockState$Subscriptions, method: string, value: any) { subscriptions[method].lastValue = value; Object .values(subscriptions[method].callbacks) .forEach((cb) => { try { cb(null, value); } catch (error) { console.error(`Error on '${method}' subscription`, error); } }); } function setStorageBn (db: MockState$Db, createKey: StorageFunction, value: BN | number, ...keyParams: Array): void { const keyValue = u8aToHex( createKey(...keyParams) ); db[keyValue] = bnToU8a(value, 64, true); } export default function mocks ({ emitter, db, subscriptions }: MockState): void { let newHead = makeBlockHeader(new BN(-1)); setInterval(() => { if (++emitIndex === emitEvents.length) { emitIndex = 0; } emitter.emit(emitEvents[emitIndex]); newHead = makeBlockHeader(newHead.number); keyring.getPairs().forEach(({ publicKey }: KeyringPair, index: number) => { setStorageBn(db, storage.balances.freeBalance, newHead.number.muln(3).iaddn(index), publicKey()); setStorageBn(db, storage.system.accountNonce, newHead.number.addn(index), publicKey()); }); setStorageBn(db, storage.timestamp.now, Math.floor(Date.now() / 1000)); updateSubs(subscriptions, 'chain_newHead', new Header(newHead).toJSON()); }, 5000); }