Skip to content

Commit

Permalink
Immer state (#59)
Browse files Browse the repository at this point in the history
* Use timestamp to check for pending txs

* Add immer for state manamgement

* Refactor setting state

* Remove unnecessary draft return, add updateState unit test
  • Loading branch information
vponline authored Nov 2, 2023
1 parent 07b24de commit 6c6e2af
Show file tree
Hide file tree
Showing 13 changed files with 189 additions and 337 deletions.
3 changes: 3 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ module.exports = {
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-dynamic-delete': 'off',

// Lodash
'lodash/prefer-immutable-method': 'off',

// Jest
'jest/no-hooks': 'off',
},
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
"axios": "^1.5.1",
"dotenv": "^16.3.1",
"ethers": "^5.7.2",
"immer": "^10.0.3",
"lodash": "^4.17.21",
"zod": "^3.22.3"
}
Expand Down
7 changes: 7 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

173 changes: 27 additions & 146 deletions src/gas-price/gas-price.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ethers } from 'ethers';

import { init } from '../../test/fixtures/mock-config';
import { getState, setState } from '../state';
import { getState, updateState } from '../state';

import {
getAirseekerRecommendedGasPrice,
Expand Down Expand Up @@ -53,16 +53,8 @@ describe('gas price', () => {
beforeEach(() => {
initializeGasStore(chainId, providerName);
// Reset the gasPriceStore
const state = getState();
setState({
...state,
gasPriceStore: {
...state.gasPriceStore,
[chainId]: {
...state.gasPriceStore[chainId],
[providerName]: { gasPrices: [], sponsorLastUpdateTimestampMs: {} },
},
},
updateState((draft) => {
draft.gasPriceStore[chainId] = { [providerName]: { gasPrices: [], sponsorLastUpdateTimestampMs: {} } };
});
});

Expand All @@ -76,19 +68,8 @@ describe('gas price', () => {
.spyOn(ethers.providers.StaticJsonRpcProvider.prototype, 'getGasPrice')
.mockResolvedValueOnce(ethers.BigNumber.from(gasPriceMock));

const state = getState();
setState({
...state,
gasPriceStore: {
...state.gasPriceStore,
[chainId]: {
...state.gasPriceStore[chainId],
[providerName]: {
...state.gasPriceStore[chainId]![providerName]!,
gasPrices: [oldGasPriceMock, ...state.gasPriceStore[chainId]![providerName]!.gasPrices],
},
},
},
updateState((draft) => {
draft.gasPriceStore[chainId]![providerName]!.gasPrices.unshift(oldGasPriceMock);
});
clearExpiredStoreGasPrices(chainId, providerName, gasSettings.sanitizationSamplingWindow);
setStoreGasPrices(chainId, providerName, gasPriceMock);
Expand All @@ -103,16 +84,8 @@ describe('gas price', () => {
beforeEach(() => {
initializeGasStore(chainId, providerName);
// Reset the gasPriceStore
const state = getState();
setState({
...state,
gasPriceStore: {
...state.gasPriceStore,
[chainId]: {
...state.gasPriceStore[chainId],
[providerName]: { gasPrices: [], sponsorLastUpdateTimestampMs: {} },
},
},
updateState((draft) => {
draft.gasPriceStore[chainId] = { [providerName]: { gasPrices: [], sponsorLastUpdateTimestampMs: {} } };
});
});

Expand All @@ -134,16 +107,8 @@ describe('gas price', () => {
beforeEach(() => {
initializeGasStore(chainId, providerName);
// Reset the gasPriceStore
const state = getState();
setState({
...state,
gasPriceStore: {
...state.gasPriceStore,
[chainId]: {
...state.gasPriceStore[chainId],
[providerName]: { gasPrices: [], sponsorLastUpdateTimestampMs: {} },
},
},
updateState((draft) => {
draft.gasPriceStore[chainId] = { [providerName]: { gasPrices: [], sponsorLastUpdateTimestampMs: {} } };
});
});

Expand Down Expand Up @@ -171,19 +136,8 @@ describe('gas price', () => {
.spyOn(ethers.providers.StaticJsonRpcProvider.prototype, 'getGasPrice')
.mockResolvedValueOnce(ethers.BigNumber.from(gasPriceMock));

const state = getState();
setState({
...state,
gasPriceStore: {
...state.gasPriceStore,
[chainId]: {
...state.gasPriceStore[chainId],
[providerName]: {
...state.gasPriceStore[chainId]![providerName]!,
gasPrices: [oldGasPriceMock, ...state.gasPriceStore[chainId]![providerName]!.gasPrices],
},
},
},
updateState((draft) => {
draft.gasPriceStore[chainId]![providerName]!.gasPrices.unshift(oldGasPriceMock);
});
clearExpiredStoreGasPrices(chainId, providerName, gasSettings.sanitizationSamplingWindow);
const gasPrice = await updateGasPriceStore(chainId, providerName, rpcUrl);
Expand Down Expand Up @@ -222,16 +176,8 @@ describe('gas price', () => {
beforeEach(() => {
initializeGasStore(chainId, providerName);
// Reset the gasPriceStore
const state = getState();
setState({
...state,
gasPriceStore: {
...state.gasPriceStore,
[chainId]: {
...state.gasPriceStore[chainId],
[providerName]: { gasPrices: [], sponsorLastUpdateTimestampMs: {} },
},
},
updateState((draft) => {
draft.gasPriceStore[chainId] = { [providerName]: { gasPrices: [], sponsorLastUpdateTimestampMs: {} } };
});
});

Expand All @@ -245,19 +191,8 @@ describe('gas price', () => {
.spyOn(ethers.providers.StaticJsonRpcProvider.prototype, 'getGasPrice')
.mockResolvedValueOnce(ethers.BigNumber.from(gasPriceMock));

const state = getState();
setState({
...state,
gasPriceStore: {
...state.gasPriceStore,
[chainId]: {
...state.gasPriceStore[chainId],
[providerName]: {
...state.gasPriceStore[chainId]![providerName]!,
gasPrices: [oldGasPriceMock, ...state.gasPriceStore[chainId]![providerName]!.gasPrices],
},
},
},
updateState((draft) => {
draft.gasPriceStore[chainId]![providerName]!.gasPrices.unshift(oldGasPriceMock);
});
await gasPriceCollector(chainId, providerName, rpcUrl, gasSettings.sanitizationSamplingWindow);

Expand All @@ -271,16 +206,8 @@ describe('gas price', () => {
beforeEach(() => {
initializeGasStore(chainId, providerName);
// Reset the gasPriceStore
const state = getState();
setState({
...state,
gasPriceStore: {
...state.gasPriceStore,
[chainId]: {
...state.gasPriceStore[chainId],
[providerName]: { gasPrices: [], sponsorLastUpdateTimestampMs: {} },
},
},
updateState((draft) => {
draft.gasPriceStore[chainId] = { [providerName]: { gasPrices: [], sponsorLastUpdateTimestampMs: {} } };
});
});

Expand Down Expand Up @@ -314,19 +241,8 @@ describe('gas price', () => {
.spyOn(ethers.providers.StaticJsonRpcProvider.prototype, 'getGasPrice')
.mockResolvedValueOnce(ethers.BigNumber.from(gasPriceMock));

const state = getState();
setState({
...state,
gasPriceStore: {
...state.gasPriceStore,
[chainId]: {
...state.gasPriceStore[chainId],
[providerName]: {
...state.gasPriceStore[chainId]![providerName]!,
gasPrices: gasPricesMock,
},
},
},
updateState((draft) => {
draft.gasPriceStore[chainId]![providerName]!.gasPrices = gasPricesMock;
});
const gasPrice = await getAirseekerRecommendedGasPrice(
chainId,
Expand Down Expand Up @@ -356,19 +272,8 @@ describe('gas price', () => {
.spyOn(ethers.providers.StaticJsonRpcProvider.prototype, 'getGasPrice')
.mockResolvedValueOnce(ethers.BigNumber.from(gasPriceMock));

const state = getState();
setState({
...state,
gasPriceStore: {
...state.gasPriceStore,
[chainId]: {
...state.gasPriceStore[chainId],
[providerName]: {
...state.gasPriceStore[chainId]![providerName]!,
gasPrices: [oldGasPriceMock, ...state.gasPriceStore[chainId]![providerName]!.gasPrices],
},
},
},
updateState((draft) => {
draft.gasPriceStore[chainId]![providerName]!.gasPrices.unshift(oldGasPriceMock);
});
const gasPrice = await getAirseekerRecommendedGasPrice(
chainId,
Expand Down Expand Up @@ -396,19 +301,8 @@ describe('gas price', () => {
.spyOn(ethers.providers.StaticJsonRpcProvider.prototype, 'getGasPrice')
.mockResolvedValueOnce(ethers.BigNumber.from(gasPriceMock));

const state = getState();
setState({
...state,
gasPriceStore: {
...state.gasPriceStore,
[chainId]: {
...state.gasPriceStore[chainId],
[providerName]: {
...state.gasPriceStore[chainId]![providerName]!,
gasPrices: [oldGasPriceMock, ...state.gasPriceStore[chainId]![providerName]!.gasPrices],
},
},
},
updateState((draft) => {
draft.gasPriceStore[chainId]![providerName]!.gasPrices.unshift(oldGasPriceMock);
});
const gasPrice = await getAirseekerRecommendedGasPrice(
chainId,
Expand Down Expand Up @@ -436,23 +330,10 @@ describe('gas price', () => {
.spyOn(ethers.providers.StaticJsonRpcProvider.prototype, 'getGasPrice')
.mockResolvedValueOnce(ethers.BigNumber.from(gasPriceMock));

const state = getState();
setState({
...state,
gasPriceStore: {
...state.gasPriceStore,
[chainId]: {
...state.gasPriceStore[chainId],
[providerName]: {
...state.gasPriceStore[chainId]![providerName]!,
gasPrices: [oldGasPriceMock, ...state.gasPriceStore[chainId]![providerName]!.gasPrices],
sponsorLastUpdateTimestampMs: {
...state.gasPriceStore[chainId]![providerName]!.sponsorLastUpdateTimestampMs,
[sponsorWalletAddress]: timestampMock - gasSettings.scalingWindow * 60 * 1000 - 1,
},
},
},
},
updateState((draft) => {
draft.gasPriceStore[chainId]![providerName]!.gasPrices.unshift(oldGasPriceMock);
draft.gasPriceStore[chainId]![providerName]!.sponsorLastUpdateTimestampMs[sponsorWalletAddress] =
timestampMock - gasSettings.scalingWindow * 60 * 1000 - 1;
});
const gasPrice = await getAirseekerRecommendedGasPrice(
chainId,
Expand Down
Loading

0 comments on commit 6c6e2af

Please sign in to comment.