diff --git a/packages/validator/src/services/block.ts b/packages/validator/src/services/block.ts index a9663c69aa6c..71a06b4af773 100644 --- a/packages/validator/src/services/block.ts +++ b/packages/validator/src/services/block.ts @@ -17,10 +17,14 @@ import {Api, ApiError, ServerApi} from "@lodestar/api"; import {IClock, LoggerVc} from "../util/index.js"; import {PubkeyHex} from "../types.js"; import {Metrics} from "../metrics.js"; +import {formatBigDecimal} from "../util/format.js"; import {ValidatorStore, BuilderSelection} from "./validatorStore.js"; import {BlockDutiesService, GENESIS_SLOT} from "./blockDuties.js"; const ETH_TO_WEI = BigInt("1000000000000000000"); +// display upto 5 decimal places +const MAX_DECIMAL_FACTOR = BigInt("100000"); + /** * Cutoff time to wait for execution and builder block production apis to resolve * Post this time, race execution and builder to pick whatever resolves first @@ -243,7 +247,7 @@ export class BlockProposingService { const debugLogCtx = { source: source, // winston logger doesn't like bigint - "blockValue(eth)": `${fullOrBlindedBlock.blockValue / ETH_TO_WEI}`, + blockValue: `${formatBigDecimal(fullOrBlindedBlock.blockValue, ETH_TO_WEI, MAX_DECIMAL_FACTOR)} ETH`, }; const blockFeeRecipient = (fullOrBlindedBlock.data as bellatrix.BeaconBlock).body.executionPayload?.feeRecipient; const feeRecipient = blockFeeRecipient !== undefined ? toHexString(blockFeeRecipient) : undefined; diff --git a/packages/validator/src/util/format.ts b/packages/validator/src/util/format.ts index a405383232c9..63a9997848bc 100644 --- a/packages/validator/src/util/format.ts +++ b/packages/validator/src/util/format.ts @@ -1,3 +1,9 @@ export function isValidatePubkeyHex(pubkeyHex: string): boolean { return /^0x[0-9a-fA-F]{96}$/.test(pubkeyHex); } + +export function formatBigDecimal(numerator: bigint, denominator: bigint, maxDecimalFactor: bigint): string { + const full = numerator / denominator; + const fraction = ((numerator - full * denominator) * maxDecimalFactor) / denominator; + return `${full}.${fraction}`; +} diff --git a/packages/validator/test/unit/utils/format.test.ts b/packages/validator/test/unit/utils/format.test.ts new file mode 100644 index 000000000000..d080d040c358 --- /dev/null +++ b/packages/validator/test/unit/utils/format.test.ts @@ -0,0 +1,17 @@ +import {expect} from "chai"; +import {formatBigDecimal} from "../../../src/util/format.js"; + +describe("util / formatBigDecimal", function () { + const testCases: [bigint, bigint, bigint, string][] = [ + [BigInt("103797739275696858"), BigInt("1000000000000000000"), BigInt("100000"), "0.10379"], + [BigInt("103797739275696858"), BigInt("1000000000000000000"), BigInt("1000"), "0.103"], + [BigInt("111103797739275696858"), BigInt("1000000000000000000"), BigInt("100000"), "111.10379"], + [BigInt("111103797739275696858"), BigInt("1000000000000000000"), BigInt("1000"), "111.103"], + [BigInt("1037977392756"), BigInt("1000000000000000000"), BigInt("100000"), "0.0"], + ]; + for (const [numerator, denominator, decimalFactor, expectedString] of testCases) { + it(`format ${numerator} / ${denominator} correctly to ${expectedString}`, () => { + expect(formatBigDecimal(numerator, denominator, decimalFactor)).to.be.equal(expectedString); + }); + } +});