Use pg-type numeric for bigint in entities and use custom decimal in graph-node (#71)

* Use pg-type numeric for bigint columns in typeorm entities

* Use custom decimal implementation from util in graph-node
This commit is contained in:
prathamesh0 2021-12-02 18:07:17 +05:30 committed by nabarun
parent 475c34b3fa
commit 5f03ad5029
26 changed files with 121 additions and 167 deletions

View File

@ -25,7 +25,7 @@ _tsToGql.set('boolean', 'Boolean');
// Typescript to Postgres type-mapping.
_tsToPg.set('string', 'varchar');
_tsToPg.set('number', 'integer');
_tsToPg.set('bigint', 'bigint');
_tsToPg.set('bigint', 'numeric');
_tsToPg.set('boolean', 'boolean');
// Graphql to Typescript type-mapping.

View File

@ -17,9 +17,9 @@ export class Account {
@Column('integer')
blockNumber!: number;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
totalClaimed!: bigint;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
totalSlashed!: bigint;
}

View File

@ -40,24 +40,24 @@ export class Block {
@Column('varchar')
receiptsRoot!: string;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
number!: bigint;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
gasUsed!: bigint;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
gasLimit!: bigint;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
timestamp!: bigint;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
difficulty!: bigint;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
totalDifficulty!: bigint;
@Column('bigint', { nullable: true, transformer: bigintTransformer })
@Column('numeric', { nullable: true, transformer: bigintTransformer })
size!: bigint;
}

View File

@ -17,18 +17,18 @@ export class Claim {
@Column('integer')
blockNumber!: number;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
timestamp!: bigint;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
index!: bigint;
@Column('varchar')
account!: string;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
totalEarned!: bigint;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
claimed!: bigint;
}

View File

@ -20,10 +20,10 @@ export class Distribution {
@Column('varchar')
distributor!: string;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
timestamp!: bigint;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
distributionNumber!: bigint;
@Column('varchar')

View File

@ -21,7 +21,7 @@ export class Epoch {
@Column('boolean')
finalized!: boolean;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
epochNumber!: bigint;
@Column('varchar', { nullable: true })
@ -30,10 +30,10 @@ export class Epoch {
@Column('varchar', { nullable: true })
endBlock!: string;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
producerBlocks!: bigint;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
allBlocks!: bigint;
@Column('numeric', { default: 0, transformer: decimalTransformer })

View File

@ -29,12 +29,12 @@ export class Network {
@Column('varchar', { array: true })
stakers!: string[];
@Column('bigint', { nullable: true, transformer: bigintTransformer })
@Column('numeric', { nullable: true, transformer: bigintTransformer })
numStakers!: bigint;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
totalStaked!: bigint;
@Column('bigint', { transformer: bigintArrayTransformer, array: true })
@Column('numeric', { transformer: bigintArrayTransformer, array: true })
stakedPercentiles!: bigint[];
}

View File

@ -22,12 +22,12 @@ export class Producer {
@Column('varchar', { nullable: true })
rewardCollector!: string;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
rewards!: bigint;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
confirmedBlocks!: bigint;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
pendingEpochBlocks!: bigint;
}

View File

@ -24,10 +24,10 @@ export class ProducerEpoch {
@Column('varchar')
epoch!: string;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
totalRewards!: bigint;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
blocksProduced!: bigint;
@Column('numeric', { default: 0, transformer: decimalTransformer })

View File

@ -16,7 +16,7 @@ export class ProducerRewardCollectorChange {
@Column('integer')
blockNumber!: number;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
_blockNumber!: bigint;
@Column('varchar')

View File

@ -21,7 +21,7 @@ export class ProducerSetChange {
@Column('integer')
blockNumber!: number;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
_blockNumber!: bigint;
@Column('varchar')

View File

@ -16,12 +16,12 @@ export class RewardScheduleEntry {
@Column('integer')
blockNumber!: number;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
startTime!: bigint;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
epochDuration!: bigint;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
rewardsPerEpoch!: bigint;
}

View File

@ -17,12 +17,12 @@ export class Slash {
@Column('integer')
blockNumber!: number;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
timestamp!: bigint;
@Column('varchar')
account!: string;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
slashed!: bigint;
}

View File

@ -24,16 +24,16 @@ export class Slot {
@Column('varchar')
delegate!: string;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
winningBid!: bigint;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
oldBid!: bigint;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
startTime!: bigint;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
expirationTime!: bigint;
@Column('numeric', { default: 0, transformer: decimalTransformer })

View File

@ -24,16 +24,16 @@ export class SlotClaim {
@Column('varchar')
owner!: string;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
winningBid!: bigint;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
oldBid!: bigint;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
startTime!: bigint;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
expirationTime!: bigint;
@Column('numeric', { default: 0, transformer: decimalTransformer })

View File

@ -16,9 +16,9 @@ export class Staker {
@Column('integer')
blockNumber!: number;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
staked!: bigint;
@Column('bigint', { nullable: true, transformer: bigintTransformer })
@Column('numeric', { nullable: true, transformer: bigintTransformer })
rank!: bigint;
}

View File

@ -46,12 +46,10 @@
"@vulcanize/util": "^0.1.0",
"bn.js": "^4.11.9",
"debug": "^4.3.1",
"decimal.js": "^10.3.1",
"fs-extra": "^10.0.0",
"js-yaml": "^4.1.0",
"json-bigint": "^1.0.0",
"json-diff": "^0.5.4",
"lodash": "^4.17.21",
"reflect-metadata": "^0.1.13",
"toml": "^3.0.0",
"typeorm": "^0.2.32",

View File

@ -16,18 +16,14 @@ import BN from 'bn.js';
import debug from 'debug';
import loader from '@vulcanize/assemblyscript/lib/loader';
import { IndexerInterface } from '@vulcanize/util';
import { IndexerInterface, GraphDecimal, getGraphDigitsAndExp } from '@vulcanize/util';
import { TypeId, Level } from './types';
import {
Block,
fromEthereumValue,
toEthereumValue,
resolveEntityFieldConflicts,
GraphDecimal,
digitsToString,
MIN_EXP,
MAX_EXP
resolveEntityFieldConflicts
} from './utils';
import { Database } from './database';
@ -255,15 +251,16 @@ export const instantiate = async (
// Creating decimal x.
const xBigDecimal = await BigDecimal.wrap(x);
const xStringPtr = await xBigDecimal.toString();
const xDecimal = new GraphDecimal(__getString(xStringPtr));
const xDecimalString = __getString(xStringPtr);
const xDecimal = new GraphDecimal(xDecimalString);
// Create decimal y.
const yBigDecimal = await BigDecimal.wrap(y);
const yStringPtr = await yBigDecimal.toString();
const yDecimal = new GraphDecimal(__getString(yStringPtr));
const yDecimalString = __getString(yStringPtr);
// Performing the decimal division operation.
const divResult = xDecimal.dividedBy(yDecimal);
const divResult = xDecimal.dividedBy(yDecimalString);
const ptr = await __newString(divResult.toString());
const divResultBigDecimal = await BigDecimal.fromString(ptr);
@ -284,10 +281,6 @@ export const instantiate = async (
const expStringPtr = await expBigInt.toString();
const exp = __getString(expStringPtr);
if (parseInt(exp) < MIN_EXP || parseInt(exp) > MAX_EXP) {
throw new Error(`Big decimal exponent '${exp}' is outside the '${MIN_EXP}' to '${MAX_EXP}' range`);
}
const decimal = new GraphDecimal(`${digits}e${exp}`);
const ptr = __newString(decimal.toFixed());
@ -296,21 +289,23 @@ export const instantiate = async (
'bigDecimal.fromString': async (s: number) => {
const string = __getString(s);
// Creating a decimal with the configured precision applied.
const decimal = new GraphDecimal(string).toSignificantDigits();
// Creating a decimal using custom decimal implementation.
const decimal = new GraphDecimal(string);
// Convert from digits array to BigInt.
const digits = digitsToString(decimal.d);
// Get digits string and exp using decimal 'd' and 'e' properties.
const { digits, exp } = getGraphDigitsAndExp(decimal.value.d, decimal.value.e);
// Create a digits BigInt using digits string and decimal sign 's' property.
const digitsBigNumber = BigNumber.from(digits);
const signBigNumber = BigNumber.from(decimal.s);
const signBigNumber = BigNumber.from(decimal.value.s);
const digitsStringPtr = await __newString(digitsBigNumber.mul(signBigNumber).toString());
const digitsBigInt = await BigInt.fromString(digitsStringPtr);
// Calculate exp after converting digits to BigInt above.
const exp = decimal.e - digits.length + 1;
// Create an exp BigInt.
const expStringPtr = await __newString(exp.toString());
const expBigInt = await BigInt.fromString(expStringPtr);
// Create a BigDecimal using digits and exp BigInts.
const bigDecimal = await BigDecimal.__new(digitsBigInt);
bigDecimal.exp = expBigInt;
@ -321,14 +316,15 @@ export const instantiate = async (
const xBigDecimal = await BigDecimal.wrap(x);
const xStringPtr = await xBigDecimal.toString();
const xDecimalString = __getString(xStringPtr);
const xDecimal = new GraphDecimal(xDecimalString);
// Create decimal y string.
const yBigDecimal = await BigDecimal.wrap(y);
const yStringPtr = await yBigDecimal.toString();
const yDecimalString = __getString(yStringPtr);
// Perform the decimal sum operation.
const sumResult = GraphDecimal.sum(xDecimalString, yDecimalString);
// Perform the decimal plus operation.
const sumResult = xDecimal.plus(yDecimalString);
const ptr = await __newString(sumResult.toString());
const sumResultBigDecimal = await BigDecimal.fromString(ptr);
@ -339,14 +335,15 @@ export const instantiate = async (
const xBigDecimal = await BigDecimal.wrap(x);
const xStringPtr = await xBigDecimal.toString();
const xDecimalString = __getString(xStringPtr);
const xDecimal = new GraphDecimal(xDecimalString);
// Create decimal y string.
const yBigDecimal = await BigDecimal.wrap(y);
const yStringPtr = await yBigDecimal.toString();
const yDecimalString = __getString(yStringPtr);
// Perform the decimal sub operation.
const subResult = GraphDecimal.sub(xDecimalString, yDecimalString);
// Perform the decimal minus operation.
const subResult = xDecimal.minus(yDecimalString);
const ptr = await __newString(subResult.toString());
const subResultBigDecimal = await BigDecimal.fromString(ptr);
@ -357,14 +354,15 @@ export const instantiate = async (
const xBigDecimal = await BigDecimal.wrap(x);
const xStringPtr = await xBigDecimal.toString();
const xDecimalString = __getString(xStringPtr);
const xDecimal = new GraphDecimal(xDecimalString);
// Create decimal y string.
const yBigDecimal = await BigDecimal.wrap(y);
const yStringPtr = await yBigDecimal.toString();
const yDecimalString = __getString(yStringPtr);
// Perform the decimal mul operation.
const mulResult = GraphDecimal.mul(xDecimalString, yDecimalString);
// Perform the decimal times operation.
const mulResult = xDecimal.times(yDecimalString);
const ptr = await __newString(mulResult.toString());
const mulResultBigDecimal = await BigDecimal.fromString(ptr);

View File

@ -4,15 +4,15 @@
import path from 'path';
import { expect } from 'chai';
import Decimal from 'decimal.js';
import BN from 'bn.js';
import { GraphDecimal } from '@vulcanize/util';
import { instantiate } from './loader';
import { getTestDatabase, getTestIndexer } from '../test/utils';
import { Database } from './database';
import { Indexer } from '../test/utils/indexer';
import {
PRECISION,
UINT128_MAX,
UINT256_MAX,
INT256_MIN,
@ -370,25 +370,25 @@ describe('numbers wasm tests', () => {
it('should get bigDecimal for DECIMAL128_MAX', async () => {
const ptr = await testBigDecimalFromString(await __newString(DECIMAL128_MAX));
const expected = new Decimal(DECIMAL128_MAX).toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal(DECIMAL128_MAX).toFixed();
expect(__getString(ptr)).to.equal(expected);
});
it('should get bigDecimal for DECIMAL128_MIN', async () => {
const ptr = await testBigDecimalFromString(await __newString(DECIMAL128_MIN));
const expected = new Decimal(DECIMAL128_MIN).toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal(DECIMAL128_MIN).toFixed();
expect(__getString(ptr)).to.equal(expected);
});
it('should get bigDecimal for DECIMAL128_NMAX', async () => {
const ptr = await testBigDecimalFromString(await __newString(DECIMAL128_NMAX));
const expected = new Decimal(DECIMAL128_NMAX).toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal(DECIMAL128_NMAX).toFixed();
expect(__getString(ptr)).to.equal(expected);
});
it('should get bigDecimal for DECIMAL128_PMIN', async () => {
const ptr = await testBigDecimalFromString(await __newString(DECIMAL128_PMIN));
const expected = new Decimal(DECIMAL128_PMIN).toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal(DECIMAL128_PMIN).toFixed();
expect(__getString(ptr)).to.equal(expected);
});
});
@ -407,37 +407,37 @@ describe('numbers wasm tests', () => {
it('should execute bigDecimal plus for DECIMAL128_MAX and 0', async () => {
const ptr = await testBigDecimalPlus(await __newString(DECIMAL128_MAX), await __newString('0'));
const expected = new Decimal(DECIMAL128_MAX).toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal(DECIMAL128_MAX).toFixed();
expect(__getString(ptr)).to.equal(expected);
});
it('should execute bigDecimal plus for DECIMAL128_MIN and 0', async () => {
const ptr = await testBigDecimalPlus(await __newString(DECIMAL128_MIN), await __newString('0'));
const expected = new Decimal(DECIMAL128_MIN).toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal(DECIMAL128_MIN).toFixed();
expect(__getString(ptr)).to.equal(expected);
});
it('should execute bigDecimal plus for DECIMAL128_PMIN and 0', async () => {
const ptr = await testBigDecimalPlus(await __newString(DECIMAL128_PMIN), await __newString('0'));
const expected = new Decimal(DECIMAL128_PMIN).toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal(DECIMAL128_PMIN).toFixed();
expect(__getString(ptr)).to.equal(expected);
});
it('should execute bigDecimal plus for DECIMAL128_NMAX and 0', async () => {
const ptr = await testBigDecimalPlus(await __newString(DECIMAL128_NMAX), await __newString('0'));
const expected = new Decimal(DECIMAL128_NMAX).toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal(DECIMAL128_NMAX).toFixed();
expect(__getString(ptr)).to.equal(expected);
});
it('should execute bigDecimal plus for DECIMAL128_MAX and DECIMAL128_MIN', async () => {
const ptr = await testBigDecimalPlus(await __newString(DECIMAL128_MAX), await __newString(DECIMAL128_MIN));
const expected = new Decimal('0').toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal('0').toFixed();
expect(__getString(ptr)).to.equal(expected);
});
it('should execute bigDecimal plus for DECIMAL128_PMIN and DECIMAL128_NMAX', async () => {
const ptr = await testBigDecimalPlus(await __newString(DECIMAL128_PMIN), await __newString(DECIMAL128_NMAX));
const expected = new Decimal('0').toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal('0').toFixed();
expect(__getString(ptr)).to.equal(expected);
});
});
@ -456,61 +456,61 @@ describe('numbers wasm tests', () => {
it('should execute bigDecimal minus for DECIMAL128_MAX and 0', async () => {
const ptr = await testBigDecimalMinus(await __newString(DECIMAL128_MAX), await __newString('0'));
const expected = new Decimal(DECIMAL128_MAX).toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal(DECIMAL128_MAX).toFixed();
expect(__getString(ptr)).to.equal(expected);
});
it('should execute bigDecimal minus for 0 and DECIMAL128_MAX', async () => {
const ptr = await testBigDecimalMinus(await __newString('0'), await __newString(DECIMAL128_MAX));
const expected = new Decimal(DECIMAL128_MIN).toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal(DECIMAL128_MIN).toFixed();
expect(__getString(ptr)).to.equal(expected);
});
it('should execute bigDecimal minus for DECIMAL128_MIN and 0', async () => {
const ptr = await testBigDecimalMinus(await __newString(DECIMAL128_MIN), await __newString('0'));
const expected = new Decimal(DECIMAL128_MIN).toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal(DECIMAL128_MIN).toFixed();
expect(__getString(ptr)).to.equal(expected);
});
it('should execute bigDecimal minus for 0 and DECIMAL128_MIN', async () => {
const ptr = await testBigDecimalMinus(await __newString('0'), await __newString(DECIMAL128_MIN));
const expected = new Decimal(DECIMAL128_MAX).toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal(DECIMAL128_MAX).toFixed();
expect(__getString(ptr)).to.equal(expected);
});
it('should execute bigDecimal minus for DECIMAL128_PMIN and 0', async () => {
const ptr = await testBigDecimalMinus(await __newString(DECIMAL128_PMIN), await __newString('0'));
const expected = new Decimal(DECIMAL128_PMIN).toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal(DECIMAL128_PMIN).toFixed();
expect(__getString(ptr)).to.equal(expected);
});
it('should execute bigDecimal minus for 0 and DECIMAL128_PMIN', async () => {
const ptr = await testBigDecimalMinus(await __newString('0'), await __newString(DECIMAL128_PMIN));
const expected = new Decimal(DECIMAL128_NMAX).toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal(DECIMAL128_NMAX).toFixed();
expect(__getString(ptr)).to.equal(expected);
});
it('should execute bigDecimal minus for DECIMAL128_NMAX and 0', async () => {
const ptr = await testBigDecimalMinus(await __newString(DECIMAL128_NMAX), await __newString('0'));
const expected = new Decimal(DECIMAL128_NMAX).toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal(DECIMAL128_NMAX).toFixed();
expect(__getString(ptr)).to.equal(expected);
});
it('should execute bigDecimal minus for 0 and DECIMAL128_NMAX', async () => {
const ptr = await testBigDecimalMinus(await __newString('0'), await __newString(DECIMAL128_NMAX));
const expected = new Decimal(DECIMAL128_PMIN).toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal(DECIMAL128_PMIN).toFixed();
expect(__getString(ptr)).to.equal(expected);
});
it('should execute bigDecimal minus for DECIMAL128_MIN and DECIMAL128_MIN', async () => {
const ptr = await testBigDecimalMinus(await __newString(DECIMAL128_MIN), await __newString(DECIMAL128_MIN));
const expected = new Decimal('0').toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal('0').toFixed();
expect(__getString(ptr)).to.equal(expected);
});
it('should execute bigDecimal minus for DECIMAL128_PMIN and DECIMAL128_PMIN', async () => {
const ptr = await testBigDecimalMinus(await __newString(DECIMAL128_PMIN), await __newString(DECIMAL128_PMIN));
const expected = new Decimal('0').toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal('0').toFixed();
expect(__getString(ptr)).to.equal(expected);
});
});
@ -544,25 +544,25 @@ describe('numbers wasm tests', () => {
it('should execute bigDecimal times for DECIMAL128_MAX and 1', async () => {
const ptr = await testBigDecimalTimes(await __newString(DECIMAL128_MAX), await __newString('1'));
const expected = new Decimal(DECIMAL128_MAX).toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal(DECIMAL128_MAX).toFixed();
expect(__getString(ptr)).to.equal(expected);
});
it('should execute bigDecimal times for DECIMAL128_MAX and -1', async () => {
const ptr = await testBigDecimalTimes(await __newString(DECIMAL128_MAX), await __newString('-1'));
const expected = new Decimal(DECIMAL128_MIN).toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal(DECIMAL128_MIN).toFixed();
expect(__getString(ptr)).to.equal(expected);
});
it('should execute bigDecimal times for DECIMAL128_PMIN and 1', async () => {
const ptr = await testBigDecimalTimes(await __newString(DECIMAL128_PMIN), await __newString('1'));
const expected = new Decimal(DECIMAL128_PMIN).toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal(DECIMAL128_PMIN).toFixed();
expect(__getString(ptr)).to.equal(expected);
});
it('should execute bigDecimal times for DECIMAL128_PMIN and -1', async () => {
const ptr = await testBigDecimalTimes(await __newString(DECIMAL128_PMIN), await __newString('-1'));
const expected = new Decimal(DECIMAL128_NMAX).toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal(DECIMAL128_NMAX).toFixed();
expect(__getString(ptr)).to.equal(expected);
});
@ -576,7 +576,7 @@ describe('numbers wasm tests', () => {
it('should execute bigDecimal times for DECIMAL128_MAX and DECIMAL128_NMAX', async () => {
const ptr = await testBigDecimalTimes(await __newString(DECIMAL128_MAX), await __newString(DECIMAL128_NMAX));
const expected = new Decimal('-99.99999999999999999999999999999999').toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal('-99.99999999999999999999999999999999').toFixed();
expect(__getString(ptr)).to.equal(expected);
});
});
@ -595,19 +595,19 @@ describe('numbers wasm tests', () => {
it('should execute bigDecimal dividedBy for negative decimal and DECIMAL128_MAX', async () => {
const ptr = await testBigDecimalDividedBy(await __newString('-10000.00'), await __newString(DECIMAL128_MAX));
const expected = new Decimal('-1e-6141').toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal('-1e-6141').toFixed();
expect(__getString(ptr)).to.equal(expected);
});
it('should execute bigDecimal dividedBy for DECIMAL128_MAX and DECIMAL128_MAX', async () => {
const ptr = await testBigDecimalDividedBy(await __newString(DECIMAL128_MAX), await __newString(DECIMAL128_MAX));
const expected = new Decimal('1').toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal('1').toFixed();
expect(__getString(ptr)).to.equal(expected);
});
it('should execute bigDecimal dividedBy for DECIMAL128_MAX and DECIMAL128_MIN', async () => {
const ptr = await testBigDecimalDividedBy(await __newString(DECIMAL128_MAX), await __newString(DECIMAL128_MIN));
const expected = new Decimal('-1').toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal('-1').toFixed();
expect(__getString(ptr)).to.equal(expected);
});
@ -621,13 +621,13 @@ describe('numbers wasm tests', () => {
it('should execute bigDecimal dividedBy for 0 and DECIMAL128_MAX', async () => {
const ptr = await testBigDecimalDividedBy(await __newString('0'), await __newString(DECIMAL128_MAX));
const expected = new Decimal('0').toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal('0').toFixed();
expect(__getString(ptr)).to.equal(expected);
});
it('should execute bigDecimal dividedBy for DECIMAL128_PMIN and DECIMAL128_NMAX', async () => {
const ptr = await testBigDecimalDividedBy(await __newString(DECIMAL128_PMIN), await __newString(DECIMAL128_NMAX));
const expected = new Decimal('-1').toSignificantDigits(PRECISION).toFixed();
const expected = new GraphDecimal('-1').toFixed();
expect(__getString(ptr)).to.equal(expected);
});
});

View File

@ -3,21 +3,15 @@ import path from 'path';
import fs from 'fs-extra';
import debug from 'debug';
import yaml from 'js-yaml';
import Decimal from 'decimal.js';
import { ColumnType } from 'typeorm';
import { ColumnMetadata } from 'typeorm/metadata/ColumnMetadata';
import { GraphDecimal } from '@vulcanize/util';
import { TypeId, EthereumValueKind, ValueKind } from './types';
const log = debug('vulcanize:utils');
// Customize Decimal according the limits of IEEE-754 decimal128.
// Reference: https://github.com/graphprotocol/graph-node/blob/v0.24.2/graph/src/data/store/scalar.rs#L42
export const MIN_EXP = -6143;
export const MAX_EXP = 6144;
export const PRECISION = 34;
export const GraphDecimal = Decimal.clone({ precision: PRECISION });
export const INT256_MIN = '-57896044618658097711785492504343953926634992332820282019728792003956564819968';
export const INT256_MAX = '57896044618658097711785492504343953926634992332820282019728792003956564819967';
export const UINT128_MAX = '340282366920938463463374607431768211455';
@ -33,9 +27,6 @@ export const DECIMAL128_PMIN = '1e-6143';
// Maximum -ve decimal value.
export const DECIMAL128_NMAX = '-1e-6143';
// Constant used in function digitsToString.
const LOG_BASE = 7;
interface Transaction {
hash: string;
index: number;
@ -570,40 +561,3 @@ export const resolveEntityFieldConflicts = (entity: any): any => {
return entity;
};
// Get digits in a string from an array of digit numbers (Decimal().d)
// https://github.com/MikeMcl/decimal.js/blob/master/decimal.mjs#L2516
export function digitsToString (d: any) {
let i, k, ws;
const indexOfLastWord = d.length - 1;
let str = '';
let w = d[0];
if (indexOfLastWord > 0) {
str += w;
for (i = 1; i < indexOfLastWord; i++) {
ws = d[i] + '';
k = LOG_BASE - ws.length;
if (k) str += getZeroString(k);
str += ws;
}
w = d[i];
ws = w + '';
k = LOG_BASE - ws.length;
if (k) str += getZeroString(k);
} else if (w === 0) {
return '0';
}
// Remove trailing zeros of last w.
for (; w % 10 === 0;) w /= 10;
return str + w;
}
function getZeroString (k: any) {
let zs = '';
for (; k--;) zs += '0';
return zs;
}

View File

@ -23,7 +23,8 @@ export const getDummyEventData = (): EventData => {
difficulty: '0',
gasLimit: '0',
gasUsed: '0',
author: ZERO_ADDRESS
author: ZERO_ADDRESS,
size: '0'
};
const tx = {

View File

@ -18,21 +18,21 @@ export class Author {
@Column('integer')
blockNumber!: number;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
blogCount!: bigint;
@Column('varchar')
name!: string
name!: string;
@Column('integer')
paramInt!: number
paramInt!: number;
@Column('bigint', { transformer: bigintTransformer })
paramBigInt!: number
@Column('numeric', { transformer: bigintTransformer })
paramBigInt!: bigint;
@Column('varchar')
paramBytes!: string
paramBytes!: string;
@Column('numeric', { default: 0, transformer: decimalTransformer })
rating!: Decimal
rating!: Decimal;
}

View File

@ -32,7 +32,7 @@ export class Blog {
@Column('boolean')
isActive!: boolean
@Column('bigint', { transformer: bigintArrayTransformer, array: true })
@Column('numeric', { transformer: bigintArrayTransformer, array: true })
reviews!: bigint[];
@Column('varchar')

View File

@ -17,7 +17,7 @@ export class Category {
@Column('integer')
blockNumber!: number;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
count!: bigint;
@Column('varchar')

View File

@ -20,7 +20,7 @@ export class _Test {
@Column('varchar', { length: 42 })
contractAddress!: string;
@Column('bigint', { transformer: bigintTransformer })
@Column('numeric', { transformer: bigintTransformer })
value!: bigint;
@Column('text', { nullable: true })

View File

@ -150,10 +150,10 @@ export class GraphDecimal {
// Return n.value if n is an instance of GraphDecimal.
if (n instanceof GraphDecimal) {
n = n.value;
exp = _getGraphExp(n.d, n.e);
({ exp } = getGraphDigitsAndExp(n.d, n.e));
} else {
const decimal = new Decimal(n);
exp = _getGraphExp(decimal.d, decimal.e);
({ exp } = getGraphDigitsAndExp(decimal.d, decimal.e));
}
if (exp < MIN_EXP || exp > MAX_EXP) {
@ -165,11 +165,14 @@ export class GraphDecimal {
}
// Get exponent from Decimal d and e according to format in graph-node.
function _getGraphExp (d: any, e: number): number {
export function getGraphDigitsAndExp (d: any, e: number): { digits: string, exp: number } {
const digits = _digitsToString(d);
const exp = e - digits.length + 1;
return exp;
return {
digits,
exp
};
}
// Get digits in a string from an array of digit numbers (Decimal().d)