state_getStorage mock (#67)

This commit is contained in:
Jaco Greeff
2018-04-17 12:23:02 +02:00
committed by GitHub
parent 41431f1921
commit 47ead04dae
10 changed files with 108 additions and 33 deletions
+37 -17
View File
@@ -3,12 +3,20 @@
// of the ISC license. See the LICENSE file for details.
// @flow
// FIME: This file is way too long and way too messy
import type { KeyringPair } from '@polkadot/util-keyring/types';
import type { MockState, MockState$Subscription$Callback } from './types';
const BN = require('bn.js');
const headerEncode = require('@polkadot/primitives-json/header/encode');
const bnToU8a = require('@polkadot/util/bn/toU8a');
const randomAsU8a = require('@polkadot/util-crypto/random/asU8a');
const testKeyring = require('@polkadot/util-keyring/testing');
const storageKey = require('./storageKey');
const keyring = testKeyring();
function makeBlockHeader (prevNumber: BN) {
const blockNumber = prevNumber.addn(1);
@@ -26,27 +34,39 @@ function makeBlockHeader (prevNumber: BN) {
};
}
module.exports = function mocks ({ subscriptions }: MockState): void {
function updateSubs (subscriptions, method, value) {
subscriptions[method].lastValue = value;
Object
.values(subscriptions[method].callbacks)
.forEach((cb) => {
try {
// flowlint-next-line unclear-type:off
((cb: any): MockState$Subscription$Callback)(null, value);
} catch (error) {
console.error(`Error on '${method}' subscription`, error);
}
});
}
function setStorageBn (storage, prefix: string, key: Uint8Array, value: BN): void {
storage[storageKey(prefix, key)] = bnToU8a(value, 64, true);
}
module.exports = function mocks ({ storage, subscriptions }: MockState): void {
let newHead = makeBlockHeader(new BN(-1));
const updateSubs = (method, value) => {
subscriptions[method].lastValue = value;
Object
.values(subscriptions[method].callbacks)
.forEach((cb) => {
try {
// flowlint-next-line unclear-type:off
((cb: any): MockState$Subscription$Callback)(null, value);
} catch (error) {
console.error(`Error on '${method}' subscription`, error);
}
});
};
setInterval(() => {
newHead = makeBlockHeader(newHead.number);
updateSubs('subscribe_newHead', headerEncode(newHead));
Object.values(keyring).forEach((pair, index) => {
// flowlint-next-line unclear-type:off
const publicKey = ((pair: any): KeyringPair).publicKey();
const balance = newHead.number.muln(3).iaddn(index);
setStorageBn(storage, 'sta:bal:', publicKey, balance);
});
updateSubs(subscriptions, 'subscribe_newHead', headerEncode(newHead));
}, 5000);
};
+6 -2
View File
@@ -5,6 +5,10 @@
import type { MockState } from './types';
module.exports = async function send (self: MockState, method: string, params: Array<mixed>): Promise<mixed> {
throw new Error('provider.send not implemented');
module.exports = async function send ({ requests, storage }: MockState, method: string, params: Array<mixed>): Promise<mixed> {
if (!requests[method]) {
throw new Error(`provider.send: Invalid method '${method}'`);
}
return requests[method](storage, params);
};
+13 -3
View File
@@ -3,12 +3,12 @@
// of the ISC license. See the LICENSE file for details.
// @flow
import type { MockState } from './types';
import type { MockState, MockState$Storage } from './types';
const interfaces = require('@polkadot/api-jsonrpc');
const l = require('@polkadot/util/logger')('api-mock');
const METHODS = Array.prototype.concat.apply(
const SUBSCRIPTIONS = Array.prototype.concat.apply(
[], Object.keys(interfaces).map((section) => {
return Object
.keys(interfaces[section].methods)
@@ -17,8 +17,16 @@ const METHODS = Array.prototype.concat.apply(
})
);
const REQUESTS = {
'state_getStorage': (storage: MockState$Storage, params: Array<mixed>): Uint8Array => {
// flowlint-next-line unclear-type:off
return storage[((params[0]: any): string)];
}
};
module.exports = function state (): MockState {
const subscriptions = METHODS.reduce((subscriptions, name) => {
const storage = {};
const subscriptions = SUBSCRIPTIONS.reduce((subscriptions, name) => {
subscriptions[name] = {
callbacks: {},
lastValue: null
@@ -29,6 +37,8 @@ module.exports = function state (): MockState {
return {
l,
requests: Object.assign({}, REQUESTS),
storage,
subscriptionId: 0,
subscriptionMap: {},
subscriptions
@@ -0,0 +1,20 @@
// Copyright 2017-2018 Jaco Greeff
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
// @flow
const u8aConcat = require('@polkadot/util/u8a/concat');
const u8aFromString = require('@polkadot/util/u8a/fromString');
const u8aToHex = require('@polkadot/util/u8a/toHex');
const xxhash = require('@polkadot/util-crypto/xxhash/asU8a128');
module.exports = function storageKey (prefix: string, key: Uint8Array | string): string {
return u8aToHex(
xxhash(
u8aConcat(
u8aFromString(prefix),
key
)
)
);
};
+10
View File
@@ -16,8 +16,18 @@ export type MockState$Subscriptions = {
}
};
export type MockState$Storage = {
[string]: Uint8Array
};
export type MockState$Requests = {
[string]: (storage: MockState$Storage, params: Array<mixed>) => mixed
};
export type MockState = {
l: Logger,
requests: MockState$Requests,
storage: MockState$Storage,
subscriptionId: number,
subscriptionMap: {
[number]: string