Skip to content

Commit

Permalink
Use BigInt literal when possible
Browse files Browse the repository at this point in the history
  • Loading branch information
Siegrift committed Feb 7, 2024
1 parent 16be144 commit 6e0b884
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 81 deletions.
2 changes: 1 addition & 1 deletion local-test-configuration/monitoring/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -826,7 +826,7 @@ <h2>Active data feeds</h2>
const absoluteDelta = abs(delta);

// Avoid division by 0
const absoluteInitialValue = initialValue === 0n ? BigInt(1) : abs(initialValue);
const absoluteInitialValue = initialValue === 0n ? 1n : abs(initialValue);

return (absoluteDelta * BigInt(1e8)) / absoluteInitialValue;
};
Expand Down
6 changes: 3 additions & 3 deletions src/data-fetcher-loop/signed-data-state.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ describe('signed data state', () => {
const templateId = generateRandomBytes(32);
const timestamp = Math.floor((Date.now() - 25 * 60 * 60 * 1000) / 1000).toString();
const airnode = signer.address;
const encodedValue = ethers.AbiCoder.defaultAbiCoder().encode(['int256'], [BigInt(1)]);
const encodedValue = ethers.AbiCoder.defaultAbiCoder().encode(['int256'], [1n]);

testDataPoint = {
airnode,
Expand All @@ -44,7 +44,7 @@ describe('signed data state', () => {
const templateId = generateRandomBytes(32);
const timestamp = Math.floor((Date.now() + 61 * 60 * 1000) / 1000).toString();
const airnode = signer.address;
const encodedValue = ethers.AbiCoder.defaultAbiCoder().encode(['int256'], [BigInt(1)]);
const encodedValue = ethers.AbiCoder.defaultAbiCoder().encode(['int256'], [1n]);

const futureTestDataPoint = {
airnode,
Expand All @@ -62,7 +62,7 @@ describe('signed data state', () => {
const templateId = generateRandomBytes(32);
const timestamp = Math.floor((Date.now() + 60 * 60 * 1000) / 1000).toString();
const airnode = ethers.Wallet.createRandom().address;
const encodedValue = ethers.AbiCoder.defaultAbiCoder().encode(['int256'], [BigInt(1)]);
const encodedValue = ethers.AbiCoder.defaultAbiCoder().encode(['int256'], [1n]);

const badTestDataPoint = {
airnode,
Expand Down
58 changes: 28 additions & 30 deletions src/deviation-check/deviation-check.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,40 +8,38 @@ import {
isDataFeedUpdatable,
} from './deviation-check';

const getDeviationThresholdAsBigInt = (input: number) => BigInt(Math.trunc(input * HUNDRED_PERCENT)) / BigInt(100);
const getDeviationThresholdAsBigInt = (input: number) => BigInt(Math.trunc(input * HUNDRED_PERCENT)) / 100n;

describe(isDeviationThresholdExceeded.name, () => {
const onChainValue = BigInt(500);
const onChainValue = 500n;

it('returns true when api value is higher and deviation threshold is reached', () => {
const shouldUpdate = isDeviationThresholdExceeded(onChainValue, getDeviationThresholdAsBigInt(10), BigInt(560));
const shouldUpdate = isDeviationThresholdExceeded(onChainValue, getDeviationThresholdAsBigInt(10), 560n);

expect(shouldUpdate).toBe(true);
});

it('returns true when api value is lower and deviation threshold is reached', () => {
const shouldUpdate = isDeviationThresholdExceeded(onChainValue, getDeviationThresholdAsBigInt(10), BigInt(440));
const shouldUpdate = isDeviationThresholdExceeded(onChainValue, getDeviationThresholdAsBigInt(10), 440n);

expect(shouldUpdate).toBe(true);
});

it('returns false when deviation threshold is not reached', () => {
const shouldUpdate = isDeviationThresholdExceeded(onChainValue, getDeviationThresholdAsBigInt(10), BigInt(480));
const shouldUpdate = isDeviationThresholdExceeded(onChainValue, getDeviationThresholdAsBigInt(10), 480n);

expect(shouldUpdate).toBe(false);
});

it('handles correctly bad JS math', () => {
expect(() =>
isDeviationThresholdExceeded(onChainValue, getDeviationThresholdAsBigInt(0.14), BigInt(560))
).not.toThrow();
expect(() => isDeviationThresholdExceeded(onChainValue, getDeviationThresholdAsBigInt(0.14), 560n)).not.toThrow();
});

it('checks all update conditions | heartbeat exceeded', () => {
const result = isDataFeedUpdatable(
BigInt(10),
10n,
BigInt(Math.floor(Date.now() / 1000) - 60 * 60 * 24),
BigInt(10),
10n,
BigInt(Math.floor(Date.now() / 1000)),
BigInt(60 * 60 * 23),
getDeviationThresholdAsBigInt(2)
Expand All @@ -52,9 +50,9 @@ describe(isDeviationThresholdExceeded.name, () => {

it('checks all update conditions | no update', () => {
const result = isDataFeedUpdatable(
BigInt(10),
10n,
BigInt(Math.floor(Date.now() / 1000)),
BigInt(10),
10n,
BigInt(Date.now() + 60 * 60 * 23),
BigInt(60 * 60 * 24),
getDeviationThresholdAsBigInt(2)
Expand All @@ -66,56 +64,56 @@ describe(isDeviationThresholdExceeded.name, () => {

describe(isOnChainDataFresh.name, () => {
it('returns true if on chain data timestamp is newer than heartbeat interval', () => {
const isFresh = isOnChainDataFresh(BigInt(Math.floor(Date.now() / 1000) - 100), BigInt(200));
const isFresh = isOnChainDataFresh(BigInt(Math.floor(Date.now() / 1000) - 100), 200n);

expect(isFresh).toBe(true);
});

it('returns false if on chain data timestamp is older than heartbeat interval', () => {
const isFresh = isOnChainDataFresh(BigInt(Math.floor(Date.now() / 1000) - 300), BigInt(200));
const isFresh = isOnChainDataFresh(BigInt(Math.floor(Date.now() / 1000) - 300), 200n);

expect(isFresh).toBe(false);
});
});

describe(calculateDeviationPercentage.name, () => {
it('calculates zero change', () => {
const updateInPercentage = calculateDeviationPercentage(BigInt(10), BigInt(10));
const updateInPercentage = calculateDeviationPercentage(10n, 10n);
expect(updateInPercentage).toStrictEqual(BigInt(0 * HUNDRED_PERCENT));
});

it('calculates 100 percent change', () => {
const updateInPercentage = calculateDeviationPercentage(BigInt(10), BigInt(20));
const updateInPercentage = calculateDeviationPercentage(10n, 20n);
expect(updateInPercentage).toStrictEqual(BigInt(1 * HUNDRED_PERCENT));
});

it('calculates positive to negative change', () => {
const updateInPercentage = calculateDeviationPercentage(BigInt(10), BigInt(-5));
const updateInPercentage = calculateDeviationPercentage(10n, BigInt(-5));
expect(updateInPercentage).toStrictEqual(BigInt(1.5 * HUNDRED_PERCENT));
});

it('calculates negative to positive change', () => {
const updateInPercentage = calculateDeviationPercentage(BigInt(-5), BigInt(5));
const updateInPercentage = calculateDeviationPercentage(BigInt(-5), 5n);
expect(updateInPercentage).toStrictEqual(BigInt(2 * HUNDRED_PERCENT));
});

it('calculates initial zero to positive change', () => {
const updateInPercentage = calculateDeviationPercentage(BigInt(0), BigInt(5));
const updateInPercentage = calculateDeviationPercentage(0n, 5n);
expect(updateInPercentage).toStrictEqual(BigInt(5 * HUNDRED_PERCENT));
});

it('calculates initial zero to negative change', () => {
const updateInPercentage = calculateDeviationPercentage(BigInt(0), BigInt(-5));
const updateInPercentage = calculateDeviationPercentage(0n, BigInt(-5));
expect(updateInPercentage).toStrictEqual(BigInt(5 * HUNDRED_PERCENT));
});

it('calculates initial positive to zero change', () => {
const updateInPercentage = calculateDeviationPercentage(BigInt(5), BigInt(0));
const updateInPercentage = calculateDeviationPercentage(5n, 0n);
expect(updateInPercentage).toStrictEqual(BigInt(1 * HUNDRED_PERCENT));
});

it('calculates initial negative to zero change', () => {
const updateInPercentage = calculateDeviationPercentage(BigInt(-5), BigInt(0));
const updateInPercentage = calculateDeviationPercentage(BigInt(-5), 0n);
expect(updateInPercentage).toStrictEqual(BigInt(1 * HUNDRED_PERCENT));
});

Expand All @@ -128,25 +126,25 @@ describe(calculateDeviationPercentage.name, () => {
describe(calculateMedian.name, () => {
describe('for array with odd number of elements', () => {
it('calculates median for sorted array', () => {
const arr = [BigInt(10), BigInt(11), BigInt(24), BigInt(30), BigInt(47)];
expect(calculateMedian(arr)).toStrictEqual(BigInt(24));
const arr = [10n, 11n, 24n, 30n, 47n];
expect(calculateMedian(arr)).toBe(24n);
});

it('calculates median for unsorted array', () => {
const arr = [BigInt(24), BigInt(11), BigInt(10), BigInt(47), BigInt(30)];
expect(calculateMedian(arr)).toStrictEqual(BigInt(24));
const arr = [24n, 11n, 10n, 47n, 30n];
expect(calculateMedian(arr)).toBe(24n);
});
});

describe('for array with even number of elements', () => {
it('calculates median for sorted array', () => {
const arr = [BigInt(10), BigInt(11), BigInt(24), BigInt(30)];
expect(calculateMedian(arr)).toStrictEqual(BigInt(17));
const arr = [10n, 11n, 24n, 30n];
expect(calculateMedian(arr)).toBe(17n);
});

it('calculates median for unsorted array', () => {
const arr = [BigInt(24), BigInt(11), BigInt(10), BigInt(30)];
expect(calculateMedian(arr)).toStrictEqual(BigInt(17));
const arr = [24n, 11n, 10n, 30n];
expect(calculateMedian(arr)).toBe(17n);
});
});
});
2 changes: 1 addition & 1 deletion src/deviation-check/deviation-check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const calculateDeviationPercentage = (initialValue: bigint, updatedValue:
const absoluteDelta = abs(delta);

// Avoid division by 0
const absoluteInitialValue = initialValue === 0n ? BigInt(1) : abs(initialValue);
const absoluteInitialValue = initialValue === 0n ? 1n : abs(initialValue);

return (absoluteDelta * BigInt(HUNDRED_PERCENT)) / absoluteInitialValue;
};
Expand Down
74 changes: 37 additions & 37 deletions src/update-feeds-loops/get-updatable-feeds.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,16 +73,16 @@ describe(multicallBeaconValues.name, () => {

expect(callAndParseMulticallPromise).toStrictEqual({
'0xf5c140bcb4814dfec311d38f6293e86c02d32ba1b7da027fe5b5202cae35dbc6': {
timestamp: BigInt(105),
value: BigInt(100),
timestamp: 105n,
value: 100n,
},
'0xf5c140bcb4814dfec311d38f6293e86c02d32ba1b7da027fe5b5202cae35dbc7': {
timestamp: BigInt(106),
value: BigInt(101),
timestamp: 106n,
value: 101n,
},
'0xf5c140bcb4814dfec311d38f6293e86c02d32ba1b7da027fe5b5202cae35dbc8': {
timestamp: BigInt(107),
value: BigInt(102),
timestamp: 107n,
value: 102n,
},
});
expect(tryMulticallMock).toHaveBeenCalledWith(['0xChain', '0xFirst', '0xSecond', '0xThird']);
Expand Down Expand Up @@ -126,15 +126,15 @@ describe(getUpdatableFeeds.name, () => {
// None of the feeds failed to update
jest.spyOn(getUpdatableFeedsModule, 'multicallBeaconValues').mockResolvedValue({
'0xf5c140bcb4814dfec311d38f6293e86c02d32ba1b7da027fe5b5202cae35dbc6': {
timestamp: BigInt(150),
timestamp: 150n,
value: BigInt('400'),
},
'0xf5c140bcb4814dfec311d38f6293e86c02d32ba1b7da027fe5b5202cae35dbc7': {
timestamp: BigInt(160),
timestamp: 160n,
value: BigInt('500'),
},
'0xf5c140bcb4814dfec311d38f6293e86c02d32ba1b7da027fe5b5202cae35dbc8': {
timestamp: BigInt(170),
timestamp: 170n,
value: BigInt('600'),
},
});
Expand All @@ -143,10 +143,10 @@ describe(getUpdatableFeeds.name, () => {
const batch = allowPartial<contractsModule.DecodedActiveDataFeedResponse[]>([
{
decodedUpdateParameters: {
deviationThresholdInPercentage: BigInt(1),
heartbeatInterval: BigInt(100),
deviationThresholdInPercentage: 1n,
heartbeatInterval: 100n,
},
dataFeedValue: BigInt(10),
dataFeedValue: 10n,
dataFeedTimestamp: 95n,
decodedDataFeed: {
dataFeedId: '0x000',
Expand Down Expand Up @@ -189,8 +189,8 @@ describe(getUpdatableFeeds.name, () => {
dataFeedId: '0x000',
},
decodedUpdateParameters: {
deviationThresholdInPercentage: BigInt(1),
heartbeatInterval: BigInt(100),
deviationThresholdInPercentage: 1n,
heartbeatInterval: 100n,
},
},
},
Expand Down Expand Up @@ -222,15 +222,15 @@ describe(getUpdatableFeeds.name, () => {
// None of the feeds failed to update
jest.spyOn(getUpdatableFeedsModule, 'multicallBeaconValues').mockResolvedValue({
'0xf5c140bcb4814dfec311d38f6293e86c02d32ba1b7da027fe5b5202cae35dbc6': {
timestamp: BigInt(150),
timestamp: 150n,
value: BigInt('400'),
},
'0xf5c140bcb4814dfec311d38f6293e86c02d32ba1b7da027fe5b5202cae35dbc7': {
timestamp: BigInt(160),
timestamp: 160n,
value: BigInt('400'),
},
'0xf5c140bcb4814dfec311d38f6293e86c02d32ba1b7da027fe5b5202cae35dbc8': {
timestamp: BigInt(170),
timestamp: 170n,
value: BigInt('400'),
},
});
Expand All @@ -239,10 +239,10 @@ describe(getUpdatableFeeds.name, () => {
const batch = allowPartial<contractsModule.DecodedActiveDataFeedResponse[]>([
{
decodedUpdateParameters: {
deviationThresholdInPercentage: BigInt(1),
heartbeatInterval: BigInt(1),
deviationThresholdInPercentage: 1n,
heartbeatInterval: 1n,
},
dataFeedValue: BigInt(400),
dataFeedValue: 400n,
dataFeedTimestamp: 90n,
decodedDataFeed: {
dataFeedId: '0x000',
Expand Down Expand Up @@ -285,8 +285,8 @@ describe(getUpdatableFeeds.name, () => {
dataFeedId: '0x000',
},
decodedUpdateParameters: {
deviationThresholdInPercentage: BigInt(1),
heartbeatInterval: BigInt(1),
deviationThresholdInPercentage: 1n,
heartbeatInterval: 1n,
},
},
},
Expand Down Expand Up @@ -319,10 +319,10 @@ describe(getUpdatableFeeds.name, () => {
const batch = allowPartial<contractsModule.DecodedActiveDataFeedResponse[]>([
{
decodedUpdateParameters: {
deviationThresholdInPercentage: BigInt(1),
heartbeatInterval: BigInt(100),
deviationThresholdInPercentage: 1n,
heartbeatInterval: 100n,
},
dataFeedValue: BigInt(200),
dataFeedValue: 200n,
dataFeedTimestamp: 160n,
decodedDataFeed: {
dataFeedId: '0x000',
Expand All @@ -335,15 +335,15 @@ describe(getUpdatableFeeds.name, () => {
// Ensure on-chain values don't trigger an update
jest.spyOn(getUpdatableFeedsModule, 'multicallBeaconValues').mockResolvedValue({
'0xf5c140bcb4814dfec311d38f6293e86c02d32ba1b7da027fe5b5202cae35dbc6': {
timestamp: BigInt(150),
timestamp: 150n,
value: BigInt('200'),
},
'0xf5c140bcb4814dfec311d38f6293e86c02d32ba1b7da027fe5b5202cae35dbc7': {
timestamp: BigInt(155),
timestamp: 155n,
value: BigInt('200'),
},
'0xf5c140bcb4814dfec311d38f6293e86c02d32ba1b7da027fe5b5202cae35dbc8': {
timestamp: BigInt(170),
timestamp: 170n,
value: BigInt('200'),
},
});
Expand Down Expand Up @@ -380,15 +380,15 @@ describe(getUpdatableFeeds.name, () => {
// None of the feeds failed to update
jest.spyOn(getUpdatableFeedsModule, 'multicallBeaconValues').mockResolvedValue({
'0xf5c140bcb4814dfec311d38f6293e86c02d32ba1b7da027fe5b5202cae35dbc6': {
timestamp: BigInt(150),
timestamp: 150n,
value: BigInt('400'),
},
'0xf5c140bcb4814dfec311d38f6293e86c02d32ba1b7da027fe5b5202cae35dbc7': {
timestamp: BigInt(160),
timestamp: 160n,
value: BigInt('400'),
},
'0xf5c140bcb4814dfec311d38f6293e86c02d32ba1b7da027fe5b5202cae35dbc8': {
timestamp: BigInt(170),
timestamp: 170n,
value: BigInt('400'),
},
});
Expand All @@ -397,10 +397,10 @@ describe(getUpdatableFeeds.name, () => {
const batch = allowPartial<contractsModule.DecodedActiveDataFeedResponse[]>([
{
decodedUpdateParameters: {
deviationThresholdInPercentage: BigInt(1),
heartbeatInterval: BigInt(100),
deviationThresholdInPercentage: 1n,
heartbeatInterval: 100n,
},
dataFeedValue: BigInt(400),
dataFeedValue: 400n,
dataFeedTimestamp: 140n,
decodedDataFeed: {
dataFeedId: '0x000',
Expand All @@ -421,10 +421,10 @@ describe(getUpdatableFeeds.name, () => {
const batch = allowPartial<contractsModule.DecodedActiveDataFeedResponse[]>([
{
decodedUpdateParameters: {
deviationThresholdInPercentage: BigInt(1),
heartbeatInterval: BigInt(100),
deviationThresholdInPercentage: 1n,
heartbeatInterval: 100n,
},
dataFeedValue: BigInt(10),
dataFeedValue: 10n,
dataFeedTimestamp: 95n,
decodedDataFeed: {
dataFeedId: '0x000',
Expand Down
Loading

0 comments on commit 6e0b884

Please sign in to comment.