Skip to content

Commit

Permalink
feat: 🎸 skip RPC version check
Browse files Browse the repository at this point in the history
SDK now uses runtime API so the RPC version check is redundant
  • Loading branch information
polymath-eric committed Nov 25, 2024
1 parent 7978957 commit 6acdfed
Show file tree
Hide file tree
Showing 5 changed files with 12 additions and 189 deletions.
12 changes: 5 additions & 7 deletions src/api/client/__tests__/Polymesh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { Polymesh } from '~/api/client/Polymesh';
import { PolymeshError, PolymeshTransactionBatch } from '~/internal';
import { dsMockUtils, entityMockUtils, procedureMockUtils } from '~/testUtils/mocks';
import { ErrorCode, TransactionArray } from '~/types';
import { SUPPORTED_NODE_VERSION_RANGE } from '~/utils/constants';
import * as internalUtils from '~/utils/internal';

jest.mock(
Expand Down Expand Up @@ -44,9 +43,9 @@ jest.mock(
);

describe('Polymesh Class', () => {
let versionSpy: jest.SpyInstance;
let assertExpectedChainVersionSpy: jest.SpyInstance;
beforeEach(() => {
versionSpy = jest
assertExpectedChainVersionSpy = jest
.spyOn(internalUtils, 'assertExpectedChainVersion')
.mockClear()
.mockImplementation()
Expand Down Expand Up @@ -154,10 +153,9 @@ describe('Polymesh Class', () => {
it('should throw if the Polymesh version does not satisfy the supported version range', async () => {
const error = new PolymeshError({
code: ErrorCode.FatalError,
message: 'Unsupported Polymesh RPC node version. Please upgrade the SDK',
data: { supportedVersionRange: SUPPORTED_NODE_VERSION_RANGE },
message: 'Unsupported Polymesh spec version. Please upgrade the SDK',
});
versionSpy.mockImplementation(() => {
assertExpectedChainVersionSpy.mockImplementation(() => {
throw error;
});

Expand All @@ -173,7 +171,7 @@ describe('Polymesh Class', () => {
code: ErrorCode.FatalError,
message: 'Unable to connect',
});
versionSpy.mockImplementation(() => {
assertExpectedChainVersionSpy.mockImplementation(() => {
throw error;
});

Expand Down
28 changes: 4 additions & 24 deletions src/testUtils/mocks/dataSources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,11 +199,7 @@ import {
} from '~/types';
import { Calls, Consts, Extrinsics, PolymeshTx, Queries, Rpcs } from '~/types/internal';
import { ArgsType, Mutable, tuple } from '~/types/utils';
import {
CONFIDENTIAL_ASSETS_SUPPORTED_CALL,
STATE_RUNTIME_VERSION_CALL,
SYSTEM_VERSION_RPC_CALL,
} from '~/utils/constants';
import { CONFIDENTIAL_ASSETS_SUPPORTED_CALL, STATE_RUNTIME_VERSION_CALL } from '~/utils/constants';

let apiEmitter: EventEmitter;

Expand Down Expand Up @@ -287,16 +283,9 @@ export class MockWebSocket {
* @hidden
*/
send(msg: string): void {
let response;
const nodeVersionId = SYSTEM_VERSION_RPC_CALL.id;

if (msg.indexOf(nodeVersionId) >= 0) {
response = { data: `{ "result": "6.0.0", "id": "${nodeVersionId}" }` };
} else {
response = {
data: `{ "result": { "specVersion": "6000000"}, "id": "${STATE_RUNTIME_VERSION_CALL.id}" }`,
};
}
const response = {
data: `{ "result": { "specVersion": "6000000"}, "id": "${STATE_RUNTIME_VERSION_CALL.id}" }`,
};

this.onmessage(response);
}
Expand All @@ -310,15 +299,6 @@ export class MockWebSocket {
this.onerror(err);
}

/**
* @hidden
* Calls onmessage with the given version
*/
sendRpcVersion(version: string): void {
const response = { data: `{ "result": "${version}", "id": "${SYSTEM_VERSION_RPC_CALL.id}" }` };
this.onmessage(response);
}

/**
* @hidden
* Calls onmessage with the given version
Expand Down
70 changes: 1 addition & 69 deletions src/utils/__tests__/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,13 @@ import {
DUMMY_ACCOUNT_ID,
MAX_TICKER_LENGTH,
MINIMUM_SQ_VERSION,
PRIVATE_SUPPORTED_NODE_SEMVER,
PRIVATE_SUPPORTED_SPEC_SEMVER,
STATE_RUNTIME_VERSION_CALL,
SUPPORTED_NODE_SEMVER,
SUPPORTED_SPEC_SEMVER,
SYSTEM_VERSION_RPC_CALL,
} from '~/utils/constants';
import * as utilsConversionModule from '~/utils/conversion';

import { SUPPORTED_NODE_VERSION_RANGE, SUPPORTED_SPEC_VERSION_RANGE } from '../constants';
import { SUPPORTED_SPEC_VERSION_RANGE } from '../constants';
import {
areSameClaims,
asAccount,
Expand Down Expand Up @@ -1296,18 +1293,6 @@ describe('assertExpectedChainVersion', () => {
}),
} as Response);

when(crossFetch)
.calledWith(url, {
...requestBase,
body: JSON.stringify(SYSTEM_VERSION_RPC_CALL),
})
.mockResolvedValue({
status: 200,
json: async () => ({
result: SUPPORTED_NODE_SEMVER,
}),
} as Response);

const signal = assertExpectedChainVersion('http://example.com');

return expect(signal).resolves.not.toThrow();
Expand All @@ -1332,25 +1317,6 @@ describe('assertExpectedChainVersion', () => {
return expect(signal).rejects.toThrow();
});

it('should be rejected if there is an error in node version call', () => {
const url = 'http://example.com';
// eslint-disable-next-line @typescript-eslint/naming-convention
const requestBase = { headers: { 'Content-Type': 'application/json' }, method: 'POST' };

when(crossFetch)
.calledWith(url, {
...requestBase,
body: JSON.stringify(SYSTEM_VERSION_RPC_CALL),
})
.mockRejectedValueOnce({
msg: 'some error',
});

const signal = assertExpectedChainVersion('http://example.com');

return expect(signal).rejects.toThrow();
});

it('should be rejected if there is an error in spec version call', () => {
const url = 'http://example.com';
// eslint-disable-next-line @typescript-eslint/naming-convention
Expand All @@ -1374,7 +1340,6 @@ describe('assertExpectedChainVersion', () => {
it('should resolve if it receives both expected RPC node and chain spec version', () => {
const signal = assertExpectedChainVersion('ws://example.com');
client.onopen();
client.sendRpcVersion(SUPPORTED_NODE_SEMVER);
client.sendSpecVersion(getSpecVersion(SUPPORTED_SPEC_SEMVER));
client.sendIsPrivateSupported(false);

Expand All @@ -1384,7 +1349,6 @@ describe('assertExpectedChainVersion', () => {
it('should resolve if it receives both expected RPC node and chain spec version for a private node', () => {
const signal = assertExpectedChainVersion('ws://example.com');
client.onopen();
client.sendRpcVersion(PRIVATE_SUPPORTED_NODE_SEMVER);
client.sendSpecVersion(getSpecVersion(PRIVATE_SUPPORTED_SPEC_SEMVER));
client.sendIsPrivateSupported(true);

Expand All @@ -1402,40 +1366,10 @@ describe('assertExpectedChainVersion', () => {
return expect(signal).rejects.toThrow(expectedError);
});

it('should throw an error given a major RPC node version mismatch', () => {
const signal = assertExpectedChainVersion('ws://example.com');
const mismatchedVersion = getMismatchedVersion(SUPPORTED_NODE_SEMVER, 0);
client.sendRpcVersion(mismatchedVersion);
client.sendSpecVersion(getSpecVersion(SUPPORTED_SPEC_SEMVER));
client.sendIsPrivateSupported(false);
const expectedError = new PolymeshError({
code: ErrorCode.FatalError,
message: 'Unsupported Polymesh RPC node version. Please upgrade the SDK',
});
return expect(signal).rejects.toThrowError(expectedError);
});

it('should log a warning given a minor or patch RPC node version mismatch', async () => {
const signal = assertExpectedChainVersion('ws://example.com');

client.sendSpecVersion(getSpecVersion(SUPPORTED_SPEC_SEMVER));

const mockRpcVersion = getMismatchedVersion(SUPPORTED_NODE_SEMVER);
client.sendRpcVersion(mockRpcVersion);
client.sendIsPrivateSupported(false);

await signal;
expect(warnSpy).toHaveBeenCalledTimes(1);
expect(warnSpy).toHaveBeenCalledWith(
`This version of the SDK supports Polymesh RPC node version "${SUPPORTED_NODE_VERSION_RANGE}". The node is at version ${mockRpcVersion}. Please upgrade the SDK`
);
});

it('should throw an error given a major chain spec version mismatch', () => {
const signal = assertExpectedChainVersion('ws://example.com');
const mismatchedSpecVersion = getMismatchedVersion(SUPPORTED_SPEC_SEMVER, 0);
client.sendSpecVersion(getSpecVersion(mismatchedSpecVersion));
client.sendRpcVersion(SUPPORTED_NODE_SEMVER);
client.sendIsPrivateSupported(false);
const expectedError = new PolymeshError({
code: ErrorCode.FatalError,
Expand All @@ -1448,7 +1382,6 @@ describe('assertExpectedChainVersion', () => {
const signal = assertExpectedChainVersion('ws://example.com');
const mockSpecVersion = getMismatchedVersion(SUPPORTED_SPEC_SEMVER);
client.sendSpecVersion(getSpecVersion(mockSpecVersion));
client.sendRpcVersion(SUPPORTED_NODE_SEMVER);
client.sendIsPrivateSupported(false);
await signal;
expect(warnSpy).toHaveBeenCalledTimes(1);
Expand All @@ -1461,7 +1394,6 @@ describe('assertExpectedChainVersion', () => {
const signal = assertExpectedChainVersion('ws://example.com');
const mockSpecVersion = getMismatchedVersion(SUPPORTED_SPEC_SEMVER, 2);
client.sendSpecVersion(getSpecVersion(mockSpecVersion));
client.sendRpcVersion(SUPPORTED_NODE_SEMVER);
client.sendIsPrivateSupported(false);
await signal;
expect(warnSpy).toHaveBeenCalledTimes(0);
Expand Down
23 changes: 0 additions & 23 deletions src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,22 +108,6 @@ dateTypes.forEach(type => {
*/
export const ROOT_TYPES = rootTypes;

/**
* The Polymesh RPC node version range that is compatible with this version of the SDK
*/
export const SUPPORTED_NODE_VERSION_RANGE = '6.2 || 6.3 || 7.0';

/**
* The Polymesh Private RPC node version range that is compatible with this version of the SDK
*/
export const PRIVATE_SUPPORTED_NODE_VERSION_RANGE = '1.0 || 1.1 || 2.0';

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
export const SUPPORTED_NODE_SEMVER = coerce(SUPPORTED_NODE_VERSION_RANGE)!.version;

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
export const PRIVATE_SUPPORTED_NODE_SEMVER = coerce(PRIVATE_SUPPORTED_NODE_VERSION_RANGE)!.version;

/**
* The Polymesh chain spec version range that is compatible with this version of the SDK
*/
Expand All @@ -140,13 +124,6 @@ export const SUPPORTED_SPEC_SEMVER = coerce(SUPPORTED_SPEC_VERSION_RANGE)!.versi
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
export const PRIVATE_SUPPORTED_SPEC_SEMVER = coerce(PRIVATE_SUPPORTED_SPEC_VERSION_RANGE)!.version;

export const SYSTEM_VERSION_RPC_CALL = {
jsonrpc: '2.0',
method: 'system_version',
params: [],
id: 'systemVersion',
};

export const STATE_RUNTIME_VERSION_CALL = {
jsonrpc: '2.0',
method: 'state_getRuntimeVersion',
Expand Down
68 changes: 2 additions & 66 deletions src/utils/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,16 +117,11 @@ import {
CONFIDENTIAL_ASSETS_SUPPORTED_CALL,
MAX_TICKER_LENGTH,
MINIMUM_SQ_VERSION,
PRIVATE_SUPPORTED_NODE_SEMVER,
PRIVATE_SUPPORTED_NODE_VERSION_RANGE,
PRIVATE_SUPPORTED_SPEC_SEMVER,
PRIVATE_SUPPORTED_SPEC_VERSION_RANGE,
STATE_RUNTIME_VERSION_CALL,
SUPPORTED_NODE_SEMVER,
SUPPORTED_NODE_VERSION_RANGE,
SUPPORTED_SPEC_SEMVER,
SUPPORTED_SPEC_VERSION_RANGE,
SYSTEM_VERSION_RPC_CALL,
} from '~/utils/constants';
import {
assetIdToString,
Expand Down Expand Up @@ -1465,46 +1460,6 @@ const getAllowedMajors = (range: string, supportedSpecSemver: string): string[]
return [lowMajor, highMajor];
};

/**
* @hidden
*/
function assertExpectedNodeVersion(
data: { result: string },
reject: (reason?: unknown) => void,
isPrivateSupported: boolean
): void {
const { result: version } = data;

const supportedSemver = isPrivateSupported
? PRIVATE_SUPPORTED_NODE_SEMVER
: SUPPORTED_NODE_SEMVER;

const supportedSpecVersionRange = isPrivateSupported
? PRIVATE_SUPPORTED_NODE_VERSION_RANGE
: SUPPORTED_NODE_VERSION_RANGE;

const neededMajors = getAllowedMajors(supportedSpecVersionRange, supportedSemver);

if (neededMajors.every(neededMajor => !satisfies(version, neededMajor))) {
const error = new PolymeshError({
code: ErrorCode.FatalError,
message: 'Unsupported Polymesh RPC node version. Please upgrade the SDK',
data: {
rpcNodeVersion: version,
supportedVersionRange: supportedSpecVersionRange,
},
});

reject(error);
}

if (!satisfies(version, supportedSpecVersionRange)) {
console.warn(
`This version of the SDK supports Polymesh RPC node version "${supportedSpecVersionRange}". The node is at version ${version}. Please upgrade the SDK`
);
}
}

/**
* @hidden
*
Expand Down Expand Up @@ -1646,14 +1601,11 @@ export function assertExpectedChainVersion(nodeUrl: string): Promise<number> {

let confidentialAssetsSupported: boolean;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let nodeResponse: any;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let specResponse: any;

const checkResponses = (cleanup?: () => void): void => {
if (specResponse && nodeResponse && typeof confidentialAssetsSupported !== 'undefined') {
if (specResponse && typeof confidentialAssetsSupported !== 'undefined') {
assertExpectedSpecVersion(specResponse, reject, confidentialAssetsSupported);
assertExpectedNodeVersion(nodeResponse, reject, confidentialAssetsSupported);

if (cleanup) {
cleanup();
Expand All @@ -1676,17 +1628,14 @@ export function assertExpectedChainVersion(nodeUrl: string): Promise<number> {
const client = new W3CWebSocket(nodeUrl);
client.onopen = (): void => {
client.send(JSON.stringify(CONFIDENTIAL_ASSETS_SUPPORTED_CALL));
client.send(JSON.stringify(SYSTEM_VERSION_RPC_CALL));
client.send(JSON.stringify(STATE_RUNTIME_VERSION_CALL));
};

client.onmessage = (msg): void => {
const data = JSON.parse(msg.data.toString());
const { id } = data;

if (id === SYSTEM_VERSION_RPC_CALL.id) {
nodeResponse = data;
} else if (id === CONFIDENTIAL_ASSETS_SUPPORTED_CALL.id) {
if (id === CONFIDENTIAL_ASSETS_SUPPORTED_CALL.id) {
confidentialAssetsSupported = !!data.result;
} else {
specResponse = data;
Expand Down Expand Up @@ -1715,19 +1664,6 @@ export function assertExpectedChainVersion(nodeUrl: string): Promise<number> {
})
.catch(error => handleError(error));

fetch(nodeUrl, {
method: 'POST',
headers,
body: JSON.stringify(SYSTEM_VERSION_RPC_CALL),
})
.then(response => response.json())
.then(data => {
nodeResponse = data;

checkResponses();
})
.catch(error => handleError(error));

fetch(nodeUrl, {
method: 'POST',
headers,
Expand Down

0 comments on commit 6acdfed

Please sign in to comment.