Skip to content

Commit

Permalink
LIVE-13040: polkadot code cleanup (#7812)
Browse files Browse the repository at this point in the history
* fix: polkadot code cleanup

* fix: typo

* fix: polkadot integration tests

* fix: polkadot unit tests

* fix: integration tests

* fix: polkadot coin-tester
  • Loading branch information
hzheng-ledger authored Sep 30, 2024
1 parent 7c12a08 commit 307f467
Show file tree
Hide file tree
Showing 24 changed files with 120 additions and 239 deletions.
7 changes: 7 additions & 0 deletions .changeset/tasty-brooms-chew.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@ledgerhq/hw-app-polkadot": minor
"@ledgerhq/coin-polkadot": minor
"@ledgerhq/live-common": minor
---

polkadot code cleanup
12 changes: 6 additions & 6 deletions libs/coin-modules/coin-polkadot/src/api/index.integ.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,11 @@ describe("Polkadot Api", () => {
electionStatusThreshold: 25,
},
metadataShortener: {
url: "https://api.zondax.ch/polkadot/transaction/metadata",
url: "https://polkadot-metadata-shortener.api.live.ledger.com/transaction/metadata",
},
metadataHash: {
url: "https://api.zondax.ch/polkadot/node/metadata/hash",
url: "https://polkadot-metadata-shortener.api.live.ledger.com/node/metadata/hash",
},
runtimeUpgraded: false,
});
});

Expand All @@ -35,7 +34,8 @@ describe("Polkadot Api", () => {
const result = await module.estimateFees(address, amount);

// Then
expect(result).toEqual(BigInt(154107779));
expect(result).toBeGreaterThanOrEqual(BigInt(100000000));
expect(result).toBeLessThanOrEqual(BigInt(200000000));
});
});

Expand Down Expand Up @@ -74,7 +74,7 @@ describe("Polkadot Api", () => {

// Then
expect(result).toBeGreaterThan(0);
});
}, 10000);
});

describe("craftTransaction", () => {
Expand All @@ -89,7 +89,7 @@ describe("Polkadot Api", () => {

// Then
expect(result).toEqual(
"6c0053ddb3b3a89ed5c8d8326066032beac6de225c9e010300000a0000a31e81ac3425310e3274a4698a793b2839dc0afa00",
"0x9404050300f578e65647d6c76b4d05a74e6c2d33d87f32d8d16959400b38ab97d758eb061928",
);
});
});
Expand Down
2 changes: 1 addition & 1 deletion libs/coin-modules/coin-polkadot/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ async function craft(
): Promise<string> {
const extrinsicArg = defaultExtrinsicArg(transaction.amount, transaction.recipient);
//TODO: Retrieve correctly the nonce via a call to the node `await api.rpc.system.accountNextIndex(address)`
const nonce = -1;
const nonce = 0;
const tx = await craftTransaction(address, nonce, extrinsicArg);
const extrinsic = tx.registry.createType("Extrinsic", tx.unsigned, {
version: tx.unsigned.version,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ jest.mock("../network", () => {
extrinsics: mockExtrinsics(),
}),
getTransactionParams: () => mockGetTransactionParams(),
metadataHash: () => "0x12345678",
};
});

Expand All @@ -45,12 +46,11 @@ describe("buildTransaction", () => {
electionStatusThreshold: 25,
},
metadataShortener: {
url: "https://api.zondax.ch/polkadot/transaction/metadata",
url: "https://polkadot-metadata-shortener.api.live.ledger.com/transaction/metadata",
},
metadataHash: {
url: "https://api.zondax.ch/polkadot/node/metadata/hash",
url: "https://polkadot-metadata-shortener.api.live.ledger.com/node/metadata/hash",
},
runtimeUpgraded: false,
};
});
});
Expand Down Expand Up @@ -89,16 +89,14 @@ describe("buildTransaction", () => {
const result = await buildTransaction(account, transaction);

// THEN
expect(spyRegistry).toHaveBeenCalledTimes(6);
expect(spyRegistry).toHaveBeenCalledWith("BlockNumber", 12);
expect(spyRegistry).toHaveBeenCalledTimes(3);
expect(spyRegistry).toHaveBeenCalledWith("ExtrinsicEra", {
current: 12,
period: 64,
});
expect(spyRegistry).toHaveBeenCalledWith("u32", 42);
expect(spyRegistry).toHaveBeenCalledWith("Compact<Balance>", 0);
expect(spyRegistry).toHaveBeenCalledWith("u32", 22);
expect(mockCodec).toHaveBeenCalledTimes(6);
expect(mockCodec).toHaveBeenCalledTimes(3);
expect(mockExtrinsics).toHaveBeenCalledTimes(1);
expect(mockTransferKeepAlive).toHaveBeenCalledTimes(1);
expect(mockTransferKeepAlive.mock.calls[0][0]).toEqual("WHATEVER");
Expand All @@ -111,25 +109,16 @@ describe("buildTransaction", () => {
blockHash: "0xb10c4a54",
genesisHash: "0x83835154a54",
method: expectExtrinsicMethodHex,
signedExtensions: [
"CheckVersion",
"CheckGenesis",
"CheckEra",
"CheckNonce",
"CheckWeight",
"ChargeTransactionPayment",
"CheckBlockGasLimit",
],
blockNumber: "HexCodec 4 BlockNumber",
era: "HexCodec 4 ExtrinsicEra",
nonce: "HexCodec 4 Compact<Index>",
nonce: expect.any(Number),
mode: 1,
metadataHash: new Uint8Array([1, 0, 18, 52, 86, 120]),
specVersion: "HexCodec 4 u32",
tip: "HexCodec 4 Compact<Balance>",
transactionVersion: "HexCodec 4 u32",
version: 4,
},
};
expect(result).toEqual(expectedResult);
expect(result.unsigned).toEqual(expectedResult.unsigned);
});

it('returns an unsigned with all validators when transaction has mode "nominate"', async () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { PolkadotAccount, Transaction } from "../types";
import { craftTransaction, type CreateExtrinsicArg } from "../logic";
import { isFirstBond, getNonce } from "./utils";
import coinConfig from "../config";

export const extractExtrinsicArg = (
account: PolkadotAccount,
Expand Down Expand Up @@ -29,12 +28,10 @@ export const buildTransaction = async (
transaction: Transaction,
forceLatestParams = false,
) => {
const runtimeUpgraded = coinConfig.getCoinConfig().runtimeUpgraded;
return craftTransaction(
account.freshAddress,
getNonce(account),
extractExtrinsicArg(account, transaction),
forceLatestParams,
runtimeUpgraded,
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,11 @@ describe("getEstimatedFees", () => {
electionStatusThreshold: 25,
},
metadataShortener: {
url: "https://api.zondax.ch/polkadot/transaction/metadata",
url: "https://polkadot-metadata-shortener.api.live.ledger.com/transaction/metadata",
},
metadataHash: {
url: "https://api.zondax.ch/polkadot/node/metadata/hash",
url: "https://polkadot-metadata-shortener.api.live.ledger.com/node/metadata/hash",
},
runtimeUpgraded: false,
};
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,11 @@ describe("prepareTransaction", () => {
electionStatusThreshold: 25,
},
metadataShortener: {
url: "https://api.zondax.ch/polkadot/transaction/metadata",
url: "https://polkadot-metadata-shortener.api.live.ledger.com/transaction/metadata",
},
metadataHash: {
url: "https://api.zondax.ch/polkadot/node/metadata/hash",
url: "https://polkadot-metadata-shortener.api.live.ledger.com/node/metadata/hash",
},
runtimeUpgraded: false,
};
});
});
Expand Down
33 changes: 16 additions & 17 deletions libs/coin-modules/coin-polkadot/src/bridge/signOperation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,34 @@ import type { PolkadotOperationMode, PolkadotSigner, PolkadotOperationExtra } fr
import { createFixtureAccount, createFixtureTransaction } from "../types/bridge.fixture";
import buildSignOperation from "./signOperation";
import { createRegistryAndExtrinsics } from "../network/common";

import {
fixtureChainSpec,
fixtureTransactionParams,
fixtureTxMaterialWithMetadata,
} from "../network/sidecar.fixture";
import coinConfig from "../config";

jest.mock("../config");
const mockGetConfig = jest.mocked(coinConfig.getCoinConfig);
const mockRegistry = jest
.fn()
.mockResolvedValue(createRegistryAndExtrinsics(fixtureTxMaterialWithMetadata, fixtureChainSpec));
const mockTransactionParams = jest.fn().mockResolvedValue(fixtureTransactionParams);
const mockPaymentInfo = jest.fn().mockResolvedValue({
weight: "WHATEVER",
class: "WHATEVER",
partialFee: "155099814",
});
const mockRegistry = jest
.fn()
.mockResolvedValue(createRegistryAndExtrinsics(fixtureTxMaterialWithMetadata, fixtureChainSpec));
const mockTransactionParams = jest.fn().mockResolvedValue(fixtureTransactionParams);

jest.mock("../network/sidecar", () => ({
getRegistry: () => mockRegistry(),
paymentInfo: (args: any) => mockPaymentInfo(args),
getTransactionParams: () => mockTransactionParams(),
}));

jest.mock("../config");
const mockGetConfig = jest.mocked(coinConfig.getCoinConfig);

describe("signOperation", () => {
// Global setup
jest.setTimeout(20000);
jest.mock("../network/sidecar", () => ({
getRegistry: () => mockRegistry(),
paymentInfo: (args: any) => mockPaymentInfo(args),
getTransactionParams: () => mockTransactionParams(),
fetchTransactionMaterial: () => fixtureTxMaterialWithMetadata,
}));
const fakeSignature = u8aConcat(new Uint8Array([1]), new Uint8Array(64).fill(0x42));
const fakeSigner = {
getAddress: jest.fn(),
Expand All @@ -59,12 +59,11 @@ describe("signOperation", () => {
electionStatusThreshold: 25,
},
metadataShortener: {
url: "https://api.zondax.ch/polkadot/transaction/metadata",
url: "https://polkadot-metadata-shortener.api.live.ledger.com/transaction/metadata",
},
metadataHash: {
url: "https://api.zondax.ch/polkadot/node/metadata/hash",
url: "https://polkadot-metadata-shortener.api.live.ledger.com/node/metadata/hash",
},
runtimeUpgraded: false,
};
});
});
Expand Down
10 changes: 2 additions & 8 deletions libs/coin-modules/coin-polkadot/src/bridge/signOperation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { buildTransaction } from "./buildTransaction";
import { calculateAmount } from "./utils";
import { signExtrinsic } from "../logic";
import polkadotAPI from "../network";
import coinConfig from "../config";

/**
* Sign Transaction with Ledger hardware
Expand All @@ -21,7 +20,6 @@ export const buildSignOperation =
({ account, deviceId, transaction }) =>
new Observable(o => {
async function main() {
const runtimeUpgraded = coinConfig.getCoinConfig().runtimeUpgraded;
o.next({
type: "device-signature-requested",
});
Expand All @@ -46,13 +44,9 @@ export const buildSignOperation =
.toU8a({
method: true,
});
let metadata = "";
if (runtimeUpgraded) {
const payloadString = Buffer.from(payload).toString("hex");
metadata = await polkadotAPI.shortenMetadata(payloadString);
}
const payloadString = Buffer.from(payload).toString("hex");
const metadata = await polkadotAPI.shortenMetadata(payloadString);
const r = await signerContext(deviceId, signer =>
// FIXME: the type of payload Uint8Array is not compatible with the signature of sign which accept a string
signer.sign(account.freshAddressPath, payload, metadata),
);

Expand Down
1 change: 0 additions & 1 deletion libs/coin-modules/coin-polkadot/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ export type PolkadotConfig = {
metadataHash: {
url: string;
};
runtimeUpgraded: boolean;
};

export type PolkadotCoinConfig = CurrencyConfig & PolkadotConfig;
Expand Down
44 changes: 16 additions & 28 deletions libs/coin-modules/coin-polkadot/src/logic/craftTransaction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ jest.mock("../network", () => {
extrinsics: mockExtrinsics(),
}),
getTransactionParams: () => mockGetTransactionParams(),
metadataHash: () => "0x12345678",
};
});

Expand Down Expand Up @@ -60,48 +61,35 @@ describe("craftTransaction", () => {
});

// WHEN
const result = await craftTransaction(address, 0, defaultExtrinsicArg(amount, recipient));
const result = (await craftTransaction(address, 0, defaultExtrinsicArg(amount, recipient)))
.unsigned;

// THEN
expect(spyRegistry).toHaveBeenCalledTimes(6);
expect(spyRegistry).toHaveBeenCalledWith("BlockNumber", 12);
expect(spyRegistry).toHaveBeenCalledTimes(3);
expect(spyRegistry).toHaveBeenCalledWith("ExtrinsicEra", {
current: 12,
period: 64,
});
expect(spyRegistry).toHaveBeenCalledWith("u32", 42);
expect(spyRegistry).toHaveBeenCalledWith("Compact<Balance>", 0);
expect(spyRegistry).toHaveBeenCalledWith("u32", 22);
expect(mockCodec).toHaveBeenCalledTimes(6);
expect(mockCodec).toHaveBeenCalledTimes(3);
expect(mockExtrinsics).toHaveBeenCalledTimes(1);
expect(mockTransferKeepAlive).toHaveBeenCalledTimes(1);
expect(mockTransferKeepAlive.mock.lastCall[0]).toEqual(recipient);
expect(mockTransferKeepAlive.mock.lastCall[1]).toEqual(amount.toString());

const expectedResult = {
registry: registry,
unsigned: {
address,
blockHash: "0xb10c4a54",
genesisHash: "0x83835154a54",
method: expectExtrinsicMethodHex,
signedExtensions: [
"CheckVersion",
"CheckGenesis",
"CheckEra",
"CheckNonce",
"CheckWeight",
"ChargeTransactionPayment",
"CheckBlockGasLimit",
],
blockNumber: "HexCodec 4 BlockNumber",
era: "HexCodec 4 ExtrinsicEra",
nonce: "HexCodec 4 Compact<Index>",
specVersion: "HexCodec 4 u32",
tip: "HexCodec 4 Compact<Balance>",
transactionVersion: "HexCodec 4 u32",
version: 4,
},
address: "5D4yQHKfqCQYThhHmTfN1JEDi47uyDJc1xg9eZfAG1R7FC7J",
blockHash: "0xb10c4a54",
era: "HexCodec 4 ExtrinsicEra",
genesisHash: "0x83835154a54",
method: expectExtrinsicMethodHex,
nonce: 0,
transactionVersion: "HexCodec 4 u32",
specVersion: "HexCodec 4 u32",
version: 4,
metadataHash: new Uint8Array([1, 0, 18, 52, 86, 120]),
mode: 1,
};
expect(result).toEqual(expectedResult);
});
Expand Down
Loading

0 comments on commit 307f467

Please sign in to comment.