Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion apps/price_pusher/src/evm/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ export default {
type: "number",
required: false,
} as Options,
"use-recent-gas-price-estimate": {
description: "Use gas price based on recent blocks",
type: "boolean",
required: false,
default: false,
} as Options,
"update-fee-multiplier": {
description:
"Multiplier for the fee to update the price. It is useful in networks " +
Expand All @@ -77,6 +83,12 @@ export default {
required: false,
default: 1,
} as Options,
"disable-push": {
description: "Dry run without pushing",
type: "boolean",
required: false,
default: false,
} as Options,
...options.priceConfigFile,
...options.priceServiceEndpoint,
...options.mnemonicFile,
Expand Down Expand Up @@ -104,11 +116,13 @@ export default {
overrideGasPriceMultiplierCap,
gasLimit,
gasPrice,
useRecentGasPriceEstimate,
updateFeeMultiplier,
logLevel,
controllerLogLevel,
enableMetrics,
metricsPort,
disablePush,
} = argv;

const logger = pino({
Expand Down Expand Up @@ -151,6 +165,7 @@ export default {
);

const client = await createClient(endpoint, mnemonic);
const network = await client.getChainId().then((id) => id.toString());
const pythContract = createPythContract(client, pythContractAddress);

logger.info(
Expand Down Expand Up @@ -185,6 +200,9 @@ export default {
overrideGasPriceMultiplier,
overrideGasPriceMultiplierCap,
updateFeeMultiplier,
network,
disablePush,
useRecentGasPriceEstimate,
gasLimit,
gasStation,
gasPrice,
Expand All @@ -207,7 +225,7 @@ export default {
const balanceTracker = createEvmBalanceTracker({
client,
address: client.account.address,
network: await client.getChainId().then((id) => id.toString()),
network,
updateInterval: pushingFrequency,
metrics,
logger,
Expand Down
51 changes: 45 additions & 6 deletions apps/price_pusher/src/evm/evm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {

import { PythContract } from "./pyth-contract";
import { SuperWalletClient } from "./super-wallet";
import { PricePusherMetrics } from "../metrics";

export class EvmPriceListener extends ChainPriceListener {
constructor(
Expand Down Expand Up @@ -135,9 +136,13 @@ export class EvmPricePusher implements IPricePusher {
private overrideGasPriceMultiplier: number,
private overrideGasPriceMultiplierCap: number,
private updateFeeMultiplier: number,
private network: string,
private disablePush: boolean,
private useRecentGasPriceEstimate: boolean,
private gasLimit?: number,
private customGasStation?: CustomGasStation,
private gasPrice?: number,
private metrics?: PricePusherMetrics,
) {}

// The pubTimes are passed here to use the values that triggered the push.
Expand Down Expand Up @@ -191,8 +196,11 @@ export class EvmPricePusher implements IPricePusher {
this.gasPrice ??
Number(
await (this.customGasStation?.getCustomGasPrice() ??
this.client.getGasPrice()),
(this.useRecentGasPriceEstimate
? this.getMedianRecentGasPrice()
: this.client.getGasPrice())),
);
this.metrics?.updateGasPrice(this.network, gasPrice);

// Try to re-use the same nonce and increase the gas if the last tx is not landed yet.
if (this.pusherAddress === undefined) {
Expand Down Expand Up @@ -258,11 +266,13 @@ export class EvmPricePusher implements IPricePusher {

this.logger.debug({ request }, "Simulated request successfully");

const hash = await this.client.writeContract(request);

this.logger.info({ hash }, "Price update sent");

this.waitForTransactionReceipt(hash);
if (!this.disablePush) {
const hash = await this.client.writeContract(request);
this.logger.info({ hash }, "Price update sent");
this.waitForTransactionReceipt(hash);
} else {
this.logger.debug("Push disabled, not attempting");
}
} catch (err: any) {
this.logger.debug({ err }, "Simulating or sending transactions failed.");

Expand Down Expand Up @@ -423,4 +433,33 @@ export class EvmPricePusher implements IPricePusher {
});
return response.binary.data;
}

async getMedianRecentGasPrice(blockCount = 5): Promise<bigint> {
this.logger.info({ blockCount });
const { baseFeePerGas, reward } = await this.client.getFeeHistory({
blockCount,
rewardPercentiles: [50],
blockTag: "latest",
});
this.logger.info({ baseFeePerGas, reward }, "feeHistory");
// remove the next block base fee
const trimmedBaseFees = baseFeePerGas.slice(0, -1);
const gasPrices = trimmedBaseFees.map((base, i) => {
const medianTip = reward?.[i]?.[0] ?? 0n;
return base + medianTip;
});
this.logger.info({ gasPrices }, "gasPrices:");

if (gasPrices.length === 0) {
return 0n;
} else {
const sorted = [...gasPrices].sort((a, b) =>
a < b ? -1 : a > b ? 1 : 0,
);
const medianIndex = Math.floor(sorted.length / 2);
const medianPrice = sorted[medianIndex];
this.logger.info({ medianPrice }, "medianPrice:");
return medianPrice;
}
}
}
17 changes: 17 additions & 0 deletions apps/price_pusher/src/metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ export class PricePusherMetrics {
public targetPriceValue: Gauge<string>;
// Wallet metrics
public walletBalance: Gauge<string>;
// gas price
public gasPrice: Gauge<string>;

constructor(logger: Logger) {
this.logger = logger;
Expand Down Expand Up @@ -85,6 +87,13 @@ export class PricePusherMetrics {
registers: [this.registry],
});

this.gasPrice = new Gauge({
name: "pyth_gas_price",
help: "Gas price estimate for this chain",
labelNames: ["network"],
registers: [this.registry],
});

// Setup the metrics endpoint
this.server.get("/metrics", async (req, res) => {
res.set("Content-Type", this.registry.contentType);
Expand Down Expand Up @@ -212,4 +221,12 @@ export class PricePusherMetrics {
`Updated wallet balance metric: ${walletAddress} = ${balanceNum}`,
);
}

public updateGasPrice(network: string, gasPrice: bigint | number): void {
// Convert to number for compatibility with prometheus
const gasPriceNum =
typeof gasPrice === "bigint" ? Number(gasPrice) : gasPrice;
this.gasPrice.set({ network }, gasPriceNum);
this.logger.debug(`Updated gas price metric: ${network} = ${gasPriceNum}`);
}
}
Loading