@parity/api
Version:
The Parity Promise-based API library for interfacing with Ethereum over RPC
592 lines (530 loc) • 15.9 kB
text/typescript
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity.
//
// SPDX-License-Identifier: MIT
import BigNumber from 'bignumber.js';
import { isAddress } from '@parity/abi/lib/util/address';
import { isInstanceOf } from '@parity/abi/lib/util/types';
import { Block, Receipt } from '../types';
import {
outBlock,
outAccountInfo,
outAddress,
outChainStatus,
outDate,
outHistogram,
outHwAccountInfo,
outNodeKind,
outNumber,
outPeer,
outPeers,
outReceipt,
outSyncing,
outTransaction,
outTrace,
outVaultMeta
} from './output';
import {
SerializedBlock,
SerializedReceipt,
SerializedTransaction
} from './types.serialized';
describe('format/output', () => {
const address = '0x63cf90d3f0410092fc0fca41846f596223979195';
const checksum = '0x63Cf90D3f0410092FC0fca41846f596223979195';
describe('outAccountInfo', () => {
it('returns meta objects parsed', () => {
expect(
outAccountInfo({
'0x63cf90d3f0410092fc0fca41846f596223979195': {
name: 'name',
uuid: 'uuid',
meta: '{"name":"456"}'
}
})
).toEqual({
'0x63Cf90D3f0410092FC0fca41846f596223979195': {
name: 'name',
uuid: 'uuid',
meta: { name: '456' }
}
});
});
it('returns objects without meta & uuid as required', () => {
expect(
outAccountInfo({
'0x63cf90d3f0410092fc0fca41846f596223979195': { name: 'name' }
})
).toEqual({
'0x63Cf90D3f0410092FC0fca41846f596223979195': { name: 'name' }
});
});
});
describe('outAddress', () => {
it('retuns the address as checksummed', () => {
expect(outAddress(address)).toEqual(checksum);
});
it('retuns the checksum as checksummed', () => {
expect(outAddress(checksum)).toEqual(checksum);
});
});
describe('outBlock', () => {
['author', 'miner'].forEach(input => {
it(`formats ${input} address as address`, () => {
const block: SerializedBlock = {};
block[input as keyof SerializedBlock] = address;
const formatted = outBlock(block)[input as keyof Block];
expect(isAddress(formatted as string)).toBe(true);
expect(formatted).toEqual(checksum);
});
});
[
'difficulty',
'gasLimit',
'gasUsed',
'number',
'nonce',
'totalDifficulty'
].forEach(input => {
it(`formats ${input} number as hexnumber`, () => {
const block: SerializedBlock = {};
// @ts-ignore
block[input as keyof SerializedBlock] = 0x123;
const formatted = outBlock(block)[input as keyof Block];
expect(isInstanceOf(formatted, BigNumber)).toBe(true);
// @ts-ignore
expect(formatted.toString(16)).toEqual('123');
});
});
['timestamp'].forEach(input => {
it(`formats ${input} number as Date`, () => {
const block: SerializedBlock = {};
// @ts-ignore
block[input as keyof SerializedBlock] = 0x57513668;
const formatted = outBlock(block)[input as keyof Block];
expect(isInstanceOf(formatted, Date)).toBe(true);
expect((formatted as Date).getTime()).toEqual(1464940136000);
});
});
it('ignores and passes through unknown keys', () => {
expect(outBlock({ someRandom: 'someRandom' } as any)).toEqual({
someRandom: 'someRandom'
});
});
it('formats a block with all the info converted', () => {
expect(
outBlock({
author: address,
miner: address,
difficulty: '0x100',
gasLimit: '0x101',
gasUsed: '0x102',
number: '0x103',
nonce: '0x104',
totalDifficulty: '0x105',
timestamp: '0x57513668',
extraData: 'someExtraStuffInHere'
})
).toEqual({
author: checksum,
miner: checksum,
difficulty: new BigNumber('0x100'),
gasLimit: new BigNumber('0x101'),
gasUsed: new BigNumber('0x102'),
number: new BigNumber('0x103'),
nonce: new BigNumber('0x104'),
totalDifficulty: new BigNumber('0x105'),
timestamp: new Date('2016-06-03T07:48:56.000Z'),
extraData: 'someExtraStuffInHere'
});
});
});
describe('outChainStatus', () => {
it('formats blockGap values', () => {
const status = {
blockGap: [0x1234, '0x5678']
};
expect(outChainStatus(status)).toEqual({
blockGap: [new BigNumber(0x1234), new BigNumber(0x5678)]
});
});
it('handles null blockGap values', () => {
const status = {
blockGap: undefined
};
expect(outChainStatus(status)).toEqual(status);
});
});
describe('outDate', () => {
it('converts a second date in unix timestamp', () => {
expect(outDate(0x57513668)).toEqual(new Date('2016-06-03T07:48:56.000Z'));
});
});
describe('outHistogram', () => {
['bucketBounds', 'counts'].forEach(type => {
it(`formats ${type} as number arrays`, () => {
expect(outHistogram({ [type]: [0x123, 0x456, 0x789] })).toEqual({
[type]: [
new BigNumber(0x123),
new BigNumber(0x456),
new BigNumber(0x789)
]
});
});
});
});
describe('outHwAccountInfo', () => {
it('returns objects with formatted addresses', () => {
expect(
outHwAccountInfo({
'0x63cf90d3f0410092fc0fca41846f596223979195': {
manufacturer: 'mfg',
name: 'type'
}
})
).toEqual({
'0x63Cf90D3f0410092FC0fca41846f596223979195': {
manufacturer: 'mfg',
name: 'type'
}
});
});
});
describe('outNodeKind', () => {
it('formats the input as received', () => {
const kind = { availability: 'personal', capability: 'full' };
expect(outNodeKind(kind)).toEqual(kind);
});
});
describe('outNumber', () => {
it('returns a BigNumber equalling the value', () => {
const bn = outNumber('0x123456');
expect(isInstanceOf(bn, BigNumber)).toBe(true);
expect(bn.eq(0x123456)).toBe(true);
});
it('assumes 0 when ivalid input', () => {
expect(outNumber().eq(0)).toBe(true);
});
});
describe('outPeer', () => {
it('converts all internal numbers to BigNumbers', () => {
expect(
outPeer({
caps: ['par/1'],
id: '0x01',
name: 'Parity',
network: {
localAddress: '10.0.0.1',
remoteAddress: '10.0.0.1'
},
protocols: {
par: {
difficulty: '0x0f',
head: '0x02',
version: 63
}
}
})
).toEqual({
caps: ['par/1'],
id: '0x01',
name: 'Parity',
network: {
localAddress: '10.0.0.1',
remoteAddress: '10.0.0.1'
},
protocols: {
par: {
difficulty: new BigNumber(15),
head: '0x02',
version: 63
}
}
});
});
it('does not output null protocols', () => {
expect(
outPeer({
caps: ['par/1'],
id: '0x01',
name: 'Parity',
network: {
localAddress: '10.0.0.1',
remoteAddress: '10.0.0.1'
},
protocols: {
les: null
}
})
).toEqual({
caps: ['par/1'],
id: '0x01',
name: 'Parity',
network: {
localAddress: '10.0.0.1',
remoteAddress: '10.0.0.1'
},
protocols: {}
});
});
});
describe('outPeers', () => {
it('converts all internal numbers to BigNumbers', () => {
expect(
outPeers({
active: 789,
connected: '456',
max: 0x7b,
peers: [
{
caps: ['par/1'],
id: '0x01',
name: 'Parity',
network: {
localAddress: '10.0.0.1',
remoteAddress: '10.0.0.1'
},
protocols: {
par: {
difficulty: '0x0f',
head: '0x02',
version: 63
},
les: null
}
}
]
})
).toEqual({
active: new BigNumber(789),
connected: new BigNumber(456),
max: new BigNumber(123),
peers: [
{
caps: ['par/1'],
id: '0x01',
name: 'Parity',
network: {
localAddress: '10.0.0.1',
remoteAddress: '10.0.0.1'
},
protocols: {
par: {
difficulty: new BigNumber(15),
head: '0x02',
version: 63
}
}
}
]
});
});
});
describe('outReceipt', () => {
['contractAddress'].forEach(input => {
it(`formats ${input} address as address`, () => {
const block: SerializedReceipt = {};
block[input as keyof SerializedReceipt] = address;
const formatted = outReceipt(block)[input as keyof Receipt];
expect(isAddress(formatted as string)).toBe(true);
expect(formatted).toEqual(checksum);
});
});
[
'blockNumber',
'cumulativeGasUsed',
'cumulativeGasUsed',
'gasUsed',
'transactionIndex'
].forEach(input => {
it(`formats ${input} number as hexnumber`, () => {
const block: SerializedReceipt = {};
// @ts-ignore
block[input as keyof SerializedReceipt] = 0x123;
const formatted = outReceipt(block)[input as keyof Receipt];
expect(isInstanceOf(formatted, BigNumber)).toBe(true);
// @ts-ignore
expect(formatted.toString(16)).toEqual('123');
});
});
it('ignores and passes through unknown keys', () => {
// @ts-ignore
expect(outReceipt({ someRandom: 'someRandom' })).toEqual({
someRandom: 'someRandom'
});
});
it('formats a receipt with all the info converted', () => {
expect(
outReceipt({
contractAddress: address,
blockNumber: '0x100',
cumulativeGasUsed: '0x101',
gasUsed: '0x102',
transactionIndex: '0x103',
extraData: 'someExtraStuffInHere'
})
).toEqual({
contractAddress: checksum,
blockNumber: new BigNumber('0x100'),
cumulativeGasUsed: new BigNumber('0x101'),
gasUsed: new BigNumber('0x102'),
transactionIndex: new BigNumber('0x103'),
extraData: 'someExtraStuffInHere'
});
});
});
describe('outSyncing', () => {
[
'currentBlock',
'highestBlock',
'startingBlock',
'warpChunksAmount',
'warpChunksProcessed'
].forEach(input => {
it(`formats ${input} numbers as a number`, () => {
expect(outSyncing({ [input]: '0x123' })).toEqual({
[input]: new BigNumber('0x123')
});
});
});
it('formats blockGap properly', () => {
expect(outSyncing({ blockGap: [0x123, 0x456] })).toEqual({
blockGap: [new BigNumber(0x123), new BigNumber(0x456)]
});
});
});
describe('outTransaction', () => {
['from', 'to'].forEach(input => {
it(`formats ${input} address as address`, () => {
const block: SerializedTransaction = {};
block[input as keyof SerializedTransaction] = address;
const formatted = outTransaction(block)[
input as keyof SerializedTransaction
];
expect(isAddress(formatted as string)).toBe(true);
expect(formatted).toEqual(checksum);
});
});
[
'blockNumber',
'gasPrice',
'gas',
'nonce',
'transactionIndex',
'value'
].forEach(input => {
it(`formats ${input} number as hexnumber`, () => {
const block: SerializedTransaction = {};
// @ts-ignore
block[input as keyof SerializedTransaction] = 0x123;
const formatted = outTransaction(block)[
input as keyof SerializedTransaction
];
expect(isInstanceOf(formatted, BigNumber)).toBe(true);
// @ts-ignore
expect(formatted.toString(16)).toEqual('123');
});
});
it('passes condition as null when null', () => {
expect(outTransaction({ condition: null })).toEqual({ condition: null });
});
it('ignores and passes through unknown keys', () => {
// @ts-ignore
expect(outTransaction({ someRandom: 'someRandom' })).toEqual({
someRandom: 'someRandom'
});
});
it('formats a transaction with all the info converted', () => {
expect(
outTransaction({
from: address,
to: address,
blockNumber: '0x100',
gasPrice: '0x101',
gas: '0x102',
nonce: '0x103',
transactionIndex: '0x104',
value: '0x105',
extraData: 'someExtraStuffInHere'
})
).toEqual({
from: checksum,
to: checksum,
blockNumber: new BigNumber('0x100'),
gasPrice: new BigNumber('0x101'),
gas: new BigNumber('0x102'),
nonce: new BigNumber('0x103'),
transactionIndex: new BigNumber('0x104'),
value: new BigNumber('0x105'),
extraData: 'someExtraStuffInHere'
});
});
});
describe('outTrace', () => {
it('ignores and passes through unknown keys', () => {
// @ts-ignore
expect(outTrace({ someRandom: 'someRandom' })).toEqual({
someRandom: 'someRandom'
});
});
it('formats a trace with all the info converted', () => {
const formatted = outTrace({
type: 'call',
action: {
from: address,
to: address,
value: '0x06',
gas: '0x07',
input: '0x1234',
callType: 'call'
},
result: {
gasUsed: '0x08',
output: '0x5678'
},
traceAddress: ['0x2'],
subtraces: 3,
transactionPosition: '0xb',
transactionHash:
'0x000000000000000000000000000000000000000000000000000000000000000c',
blockNumber: '0x0d',
blockHash:
'0x000000000000000000000000000000000000000000000000000000000000000e'
});
// @ts-ignore
expect(isInstanceOf(formatted.action.gas, BigNumber)).toBe(true);
// @ts-ignore
expect(formatted.action.gas.toNumber()).toEqual(7);
// @ts-ignore
expect(isInstanceOf(formatted.action.value, BigNumber)).toBe(true);
// @ts-ignore
expect(formatted.action.value.toNumber()).toEqual(6);
// @ts-ignore
expect(formatted.action.from).toEqual(checksum);
// @ts-ignore
expect(formatted.action.to).toEqual(checksum);
// @ts-ignore
expect(isInstanceOf(formatted.blockNumber, BigNumber)).toBe(true);
// @ts-ignore
expect(formatted.blockNumber.toNumber()).toEqual(13);
// @ts-ignore
expect(isInstanceOf(formatted.transactionPosition, BigNumber)).toBe(true);
// @ts-ignore
expect(formatted.transactionPosition.toNumber()).toEqual(11);
});
});
describe('outVaultMeta', () => {
it('returns an exmpt object on null', () => {
expect(outVaultMeta(null)).toEqual({});
});
it('returns the original value if not string', () => {
expect(outVaultMeta({ test: 123 })).toEqual({ test: 123 });
});
it('returns an object from JSON string', () => {
expect(outVaultMeta('{"test":123}')).toEqual({ test: 123 });
});
it('returns an empty object on invalid JSON', () => {
expect(outVaultMeta('{"test"}')).toEqual({});
});
});
});