Skip to content
Merged
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
5 changes: 3 additions & 2 deletions cicd/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const fs = require("node:fs");
const dotenv = require("dotenv")
const { ethers } = require("ethers");
const axios = require("axios");
const { getNumberField } = require("../scripts/utils/rpcResultFields");

function writeEnv(key, path) {
content = "PRIVATE_KEY=" + key;
Expand Down Expand Up @@ -78,7 +79,7 @@ async function getGapSubnet(config) {
console.log("response.data.error", response.data.error)
throw Error("error in subnet gapblock response")
}
epochBlockNum = response.data.result.EpochBlockNumber;
epochBlockNum = getNumberField(response.data.result, "EpochBlockNumber");
gapBlockNum = epochBlockNum-450+1
if (gapBlockNum < 1){
gapBlockNum = 1
Expand All @@ -104,7 +105,7 @@ async function getEpochParentnet(config) {
};
await axios.post(config.parentnetURL, data, {timeout: 10000}).then((response) => {
if (response.status == 200) {
epochBlockNum = response.data.result.EpochBlockNumber;
epochBlockNum = getNumberField(response.data.result, "EpochBlockNumber");
console.log("epochBlockNum", epochBlockNum)
} else {
console.log("response.status", response.status);
Expand Down
24 changes: 24 additions & 0 deletions scripts/utils/rpcResultFields.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// XDPoS RPC responses differ by client: XDPoSChain returns PascalCase keys ("EncodedRLP") and JSON
// numbers, while Nethermind returns camelCase keys ("encodedRLP") and hex strings ("0x47").
// These helpers read a field from either shape, as the relayer does.

function getField(result, key) {
if (result === null || typeof result !== "object") {
return undefined;
}
if (key in result) {
return result[key];
}
const lowerKey = key.toLowerCase();
const match = Object.keys(result).find((k) => k.toLowerCase() === lowerKey);
return match === undefined ? undefined : result[match];
}

// Number() parses both decimal and "0x" hex strings; a missing value stays undefined so callers can
// tell it apart from zero.
function getNumberField(result, key) {
const value = getField(result, key);
return value === undefined || value === null ? undefined : Number(value);
}

module.exports = { getField, getNumberField };
10 changes: 6 additions & 4 deletions scripts/utils/xdcnet.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const fetch = require("node-fetch").default;
const { getField } = require("./rpcResultFields");

function base64ToHex(base64String) {
// Step 1: Decode base64 string to binary data
Expand All @@ -24,12 +25,13 @@ async function validators(url, number) {

const data0 = await send(url, block0);

if (!data0["result"]["Masternodes"]) {
const masternodes = getField(data0["result"], "Masternodes");
if (!masternodes) {
console.error("remote node block " + number + " no validators");
return;
}

return data0["result"]["Masternodes"];
return masternodes;
}

async function data(url, number) {
Expand All @@ -42,11 +44,11 @@ async function data(url, number) {

const data0 = await send(url, block0);

if (!data0["result"]["Committed"]) {
if (!getField(data0["result"], "Committed")) {
console.error("remote node block " + number + " is not committed");
return;
}
const data0Encoded = "0x" + base64ToHex(data0["result"]["EncodedRLP"]);
const data0Encoded = "0x" + base64ToHex(getField(data0["result"], "EncodedRLP"));

return { data0Encoded };
}
Expand Down
37 changes: 37 additions & 0 deletions test/RpcResultFields.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
const { expect } = require("chai");
const { getField, getNumberField } = require("../scripts/utils/rpcResultFields");

describe("XDPoS RPC result fields", () => {
const xdposchain = {
Committed: true,
EncodedRLP: "+QMY",
Masternodes: ["0x25c65b4b379ac37cf78357c4915f73677022eaff"],
EpochBlockNumber: 84999559,
};
const nethermind = {
committed: true,
encodedRLP: "+QMY",
masternodes: ["0x25c65b4b379ac37cf78357c4915f73677022eaff"],
epochBlockNumber: "0x510fd87",
};

[
["XDPoSChain", xdposchain],
["Nethermind", nethermind],
].forEach(([client, result]) => {
it(`reads ${client} results`, () => {
expect(getField(result, "Committed")).to.equal(true);
expect(getField(result, "EncodedRLP")).to.equal("+QMY");
expect(getField(result, "Masternodes")).to.deep.equal([
"0x25c65b4b379ac37cf78357c4915f73677022eaff",
]);
expect(getNumberField(result, "EpochBlockNumber")).to.equal(84999559);
});
});

it("leaves missing fields and failed calls undefined", () => {
expect(getField(xdposchain, "Round")).to.be.undefined;
expect(getNumberField(nethermind, "Round")).to.be.undefined;
expect(getField(undefined, "Committed")).to.be.undefined;
});
});