From bf7e1f8e3b830f6ce5a76cce4f49cd194a913c07 Mon Sep 17 00:00:00 2001 From: Alice Date: Mon, 12 Oct 2026 08:00:16 +0700 Subject: [PATCH] fix: preserve initial validator count on Bradbury --- src/transactions/actions.ts | 1 + src/transactions/decoders.ts | 4 ++-- src/types/transactions.ts | 4 ++-- tests/transactions.test.ts | 38 ++++++++++++++++++++++++++++++++++-- 4 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/transactions/actions.ts b/src/transactions/actions.ts index da32faa..9ddd14e 100644 --- a/src/transactions/actions.ts +++ b/src/transactions/actions.ts @@ -102,6 +102,7 @@ export const transactionActions = (client: GenLayerClient, public const transaction = { ...txData, + numOfInitialValidators: txAllData.numOfInitialValidators ?? txData.numOfInitialValidators, txExecutionResult: Number(txAllData.txExecutionResult), } as GenLayerRawTransaction; return decodeTransaction(transaction); diff --git a/src/transactions/decoders.ts b/src/transactions/decoders.ts index d112a7c..5da7e16 100644 --- a/src/transactions/decoders.ts +++ b/src/transactions/decoders.ts @@ -76,7 +76,7 @@ export const decodeInputData = ( export const decodeTransaction = (tx: GenLayerRawTransaction): GenLayerTransaction => { // Normalize field names across chain ABIs (Bradbury uses different names) const txData = tx.txData ?? (tx as any).txCalldata; - const numOfInitialValidators = tx.numOfInitialValidators ?? (tx as any).initialRotations; + const numOfInitialValidators = tx.numOfInitialValidators; const txDataDecoded = decodeInputData(txData, tx.recipient); @@ -284,4 +284,4 @@ export const decodeLocalnetTransaction = (tx: GenLayerTransaction): GenLayerTran console.error("Error in decodeLocalnetTransaction:", e); } return tx; -}; \ No newline at end of file +}; diff --git a/src/types/transactions.ts b/src/types/transactions.ts index 9e24526..fff44d2 100644 --- a/src/types/transactions.ts +++ b/src/types/transactions.ts @@ -572,8 +572,8 @@ export type GenLayerRawTransaction = { currentTimestamp: bigint; sender: Address; recipient: Address; - numOfInitialValidators?: bigint; // undefined on Bradbury — use `initialRotations` instead - initialRotations?: bigint; // Bradbury equivalent of `numOfInitialValidators` + numOfInitialValidators?: bigint; // undefined in Bradbury's projected transaction data + initialRotations?: bigint; // leader rotations; not the initial validator count txSlot: bigint; createdTimestamp: bigint; lastVoteTimestamp: bigint; diff --git a/tests/transactions.test.ts b/tests/transactions.test.ts index fd1e82b..001482b 100644 --- a/tests/transactions.test.ts +++ b/tests/transactions.test.ts @@ -263,6 +263,40 @@ const makeRawTx = (overrides: Record = {}): GenLayerRawTransact ...overrides, }); +describe("getTransaction", () => { + it.each([0n, 3n])( + "uses the stored validator count instead of %s initial rotations", + async initialRotations => { + const txData = makeRawTx({numOfInitialValidators: undefined, initialRotations}); + const txAllData = { + ...txData, + numOfInitialValidators: 5n, + txExecutionResult: 1, + }; + const publicClient = { + readContract: vi.fn() + .mockResolvedValueOnce(txData) + .mockResolvedValueOnce([txAllData, []]), + }; + const client = { + chain: { + isStudio: false, + consensusDataContract: { + address: "0x0000000000000000000000000000000000000001", + abi: [], + }, + }, + }; + + const decoded = await transactionActions(client as any, publicClient as any).getTransaction({ + hash: txData.txId, + }); + + expect(decoded.numOfInitialValidators).toBe("5"); + }, + ); +}); + describe("decodeTransaction", () => { it("should decode standard field names (localnet/asimov)", () => { const tx = makeRawTx(); @@ -273,11 +307,11 @@ describe("decodeTransaction", () => { expect(decoded.resultName).toBe("AGREE"); }); - it("should handle Bradbury field: initialRotations instead of numOfInitialValidators", () => { + it("should not treat initialRotations as numOfInitialValidators", () => { const tx = makeRawTx({ numOfInitialValidators: undefined }); (tx as any).initialRotations = 5n; const decoded = decodeTransaction(tx); - expect(decoded.numOfInitialValidators).toBe("5"); + expect(decoded.numOfInitialValidators).toBe("0"); }); it("should handle Bradbury field: txCalldata instead of txData", () => {