Skip to content
This repository has been archived by the owner on Jul 9, 2024. It is now read-only.

Commit

Permalink
Merge in main
Browse files Browse the repository at this point in the history
  • Loading branch information
aquarat committed Jun 6, 2022
2 parents 6ccf8bc + 56ec371 commit b2bc28b
Show file tree
Hide file tree
Showing 20 changed files with 1,840 additions and 513 deletions.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,25 @@ read from the environment variables. When running locally, either just with `yar
are automatically loaded from `config/secrets.env` file. Take a look at `config/secrets.example.env` for an example
secrets file.

### Gas oracle options

- `fallbackGasPrice`: (required) - The gas price to use for beacon update transactions if fetching both blocks and
fallback gas prices fails. Defined as an object, e.g. `{"value": 10, "unit": "gwei"}`.
- `maxTimeout`: (optional) - The maximum timeout (in seconds) for fetching a block or fallback gas price (defaults to
`3`).
- `recommendedGasPriceMultiplier`: (optional) - The multiplier to apply to the fallback gas price reported by the
provider. The multiplier will not be applied to the config `fallbackGasPrice`.

- `latestGasPriceOptions`: (optional) - An object containing the following configuration options for calculating a gas
price:
- `percentile`: (optional) - The percentile of gas prices to return from a block (defaults to `60`).
- `minTransactionCount`: (optional) - The minimum amount of transactions required in a block to use for calculating a
gas price percentile (defaults to `10`).
- `pastToCompareInBlocks`: (optional) - The number of blocks to look back for the reference block (defaults to `20`).
- `maxDeviationMultiplier`: (optional) - The maximum deviation multiplier of the latest block gas price percentile
compared to the reference block gas price percentile (defaults to `2`). Used to protect against large gas price
spikes.

## Usage

```sh
Expand Down
46 changes: 32 additions & 14 deletions config/airseeker.example.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,22 @@
}
},
"options": {
"txType": "eip1559",
"priorityFee": {
"value": 3.12,
"unit": "gwei"
},
"baseFeeMultiplier": 2,
"fulfillmentGasLimit": 500000
"txType": "legacy",
"fulfillmentGasLimit": 500000,
"gasOracle": {
"maxTimeout": 3,
"fallbackGasPrice": {
"value": 10,
"unit": "gwei"
},
"recommendedGasPriceMultiplier": 1.2,
"latestGasPriceOptions": {
"percentile": 60,
"minTransactionCount": 10,
"pastToCompareInBlocks": 20,
"maxDeviationMultiplier": 2
}
}
}
},
"3": {
Expand All @@ -45,13 +54,22 @@
}
},
"options": {
"txType": "eip1559",
"priorityFee": {
"value": 3.12,
"unit": "gwei"
},
"baseFeeMultiplier": 2,
"fulfillmentGasLimit": 500000
"txType": "legacy",
"fulfillmentGasLimit": 500000,
"gasOracle": {
"maxTimeout": 3,
"fallbackGasPrice": {
"value": 10,
"unit": "gwei"
},
"recommendedGasPriceMultiplier": 1.2,
"latestGasPriceOptions": {
"percentile": 60,
"minTransactionCount": 10,
"pastToCompareInBlocks": 20,
"maxDeviationMultiplier": 2
}
}
}
}
},
Expand Down
16 changes: 8 additions & 8 deletions src/check-condition.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,26 +63,26 @@ describe('calculateUpdateInPercentage', () => {
describe('checkUpdateCondition', () => {
const onChainValue = ethers.BigNumber.from(500);

it('reads dapiserver value and checks the threshold condition to be true for increase', async () => {
const shouldUpdate = await checkUpdateCondition(onChainValue, 10, ethers.BigNumber.from(560));
it('reads dapiserver value and checks the threshold condition to be true for increase', () => {
const shouldUpdate = checkUpdateCondition(onChainValue, 10, ethers.BigNumber.from(560));

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

it('reads dapiserver value and checks the threshold condition to be true for decrease', async () => {
const shouldUpdate = await checkUpdateCondition(onChainValue, 10, ethers.BigNumber.from(440));
it('reads dapiserver value and checks the threshold condition to be true for decrease', () => {
const shouldUpdate = checkUpdateCondition(onChainValue, 10, ethers.BigNumber.from(440));

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

it('reads dapiserver value and checks the threshold condition to be false', async () => {
const shouldUpdate = await checkUpdateCondition(onChainValue, 10, ethers.BigNumber.from(480));
it('reads dapiserver value and checks the threshold condition to be false', () => {
const shouldUpdate = checkUpdateCondition(onChainValue, 10, ethers.BigNumber.from(480));

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

it('handles correctly bad JS math', async () => {
await expect(checkUpdateCondition(onChainValue, 0.14, ethers.BigNumber.from(560))).resolves.not.toThrow();
it('handles correctly bad JS math', () => {
expect(() => checkUpdateCondition(onChainValue, 0.14, ethers.BigNumber.from(560))).not.toThrow();
});
});

Expand Down
8 changes: 4 additions & 4 deletions src/check-condition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ export const calculateUpdateInPercentage = (initialValue: ethers.BigNumber, upda
return absoluteDelta.mul(ethers.BigNumber.from(HUNDRED_PERCENT)).div(absoluteInitialValue);
};

export const checkUpdateCondition = async (
onChainVale: ethers.BigNumber,
export const checkUpdateCondition = (
onChainValue: ethers.BigNumber,
deviationThreshold: number,
apiValue: ethers.BigNumber
): Promise<boolean> => {
const updateInPercentage = calculateUpdateInPercentage(onChainVale, apiValue);
) => {
const updateInPercentage = calculateUpdateInPercentage(onChainValue, apiValue);
const threshold = ethers.BigNumber.from(Math.trunc(deviationThreshold * HUNDRED_PERCENT)).div(
ethers.BigNumber.from(100)
);
Expand Down
7 changes: 7 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,10 @@ export const INT224_MIN = ethers.BigNumber.from(2).pow(ethers.BigNumber.from(223
export const INT224_MAX = ethers.BigNumber.from(2).pow(ethers.BigNumber.from(223)).sub(ethers.BigNumber.from(1));
export const NO_BEACONS_EXIT_CODE = 1;
export const NO_FETCH_EXIT_CODE = 2;
export const GAS_ORACLE_MAX_TIMEOUT_S = 3;
// Percentage value to check that latest block gas prices are not too large compared to (latest - pastToCompareInBlocks) block
export const GAS_PRICE_MAX_DEVIATION_MULTIPLIER = 2;
export const GAS_PRICE_PERCENTILE = 60;
// The minimum number of transactions required in a block before falling back to getGasPrice
export const MIN_TRANSACTION_COUNT = 10;
export const PAST_TO_COMPARE_IN_BLOCKS = 20;
28 changes: 28 additions & 0 deletions src/fetch-beacon-data.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,20 @@ const config: Config = {
},
baseFeeMultiplier: 2,
fulfillmentGasLimit: 500_000,
gasOracle: {
maxTimeout: 3,
fallbackGasPrice: {
value: 10,
unit: 'gwei',
},
recommendedGasPriceMultiplier: 1.2,
latestGasPriceOptions: {
percentile: 60,
minTransactionCount: 10,
pastToCompareInBlocks: 20,
maxDeviationMultiplier: 2,
},
},
},
},
'3': {
Expand All @@ -75,6 +89,20 @@ const config: Config = {
},
baseFeeMultiplier: 2,
fulfillmentGasLimit: 500_000,
gasOracle: {
maxTimeout: 3,
fallbackGasPrice: {
value: 10,
unit: 'gwei',
},
recommendedGasPriceMultiplier: 1.2,
latestGasPriceOptions: {
percentile: 60,
minTransactionCount: 10,
pastToCompareInBlocks: 20,
maxDeviationMultiplier: 2,
},
},
},
},
},
Expand Down
Loading

0 comments on commit b2bc28b

Please sign in to comment.