Skip to content

Commit

Permalink
feat: optimize version limit
Browse files Browse the repository at this point in the history
  • Loading branch information
ByteZhang1024 committed Sep 25, 2024
1 parent 5d8e461 commit cf43422
Show file tree
Hide file tree
Showing 13 changed files with 96 additions and 46 deletions.
58 changes: 57 additions & 1 deletion packages/core/src/api/BaseMethod.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import semver from 'semver';
import { ERRORS, HardwareError, HardwareErrorCode } from '@onekeyfe/hd-shared';
import { supportInputPinOnSoftware, supportModifyHomescreen } from '../utils/deviceFeaturesUtils';
import { createDeviceMessage } from '../events/device';
import { UI_REQUEST } from '../constants/ui-request';
Expand All @@ -6,7 +8,8 @@ import DeviceConnector from '../device/DeviceConnector';
import { DeviceFirmwareRange, KnownDevice } from '../types';
import { CoreMessage, createFirmwareMessage, createUiMessage, DEVICE, FIRMWARE } from '../events';
import { getBleFirmwareReleaseInfo, getFirmwareReleaseInfo } from './firmware/releaseHelper';
import { getLogger, LoggerNames } from '../utils';
import { getDeviceFirmwareVersion, getLogger, getMethodVersionRange, LoggerNames } from '../utils';
import { DataManager } from '../data-manager';

const Log = getLogger(LoggerNames.Method);

Expand Down Expand Up @@ -81,6 +84,12 @@ export abstract class BaseMethod<Params = undefined> {
*/
skipForceUpdateCheck = false;

/**
* 是否需要预先检查版本限制
* @default false
*/
preCheckVersionLimit = false;

// @ts-expect-error: strictPropertyInitialization
postMessage: (message: CoreMessage) => void;

Expand Down Expand Up @@ -127,6 +136,53 @@ export abstract class BaseMethod<Params = undefined> {
);
}

handleUnsupportedMethodError(error?: HardwareError) {
console.log('handleUnsupportedMethodError:', error);

if (
// Not unexpected message is not processed
!error?.message?.includes('Failure_UnexpectedMessage') ||
// Only preCheckVersionLimit will have no error
(error == null && !this.preCheckVersionLimit)
) {
return undefined;
}

const versionRange = getMethodVersionRange(
this.device.features,
type => this.getVersionRange()[type]
);

if (!versionRange || !this.device.features) {
return ERRORS.TypedError(HardwareErrorCode.UnsupportedMethod);
}
const newVersionStatus = DataManager.getFirmwareStatus(this.device.features);
const currentVersion = getDeviceFirmwareVersion(this.device.features).join('.');
if (semver.valid(versionRange.min) && semver.lt(currentVersion, versionRange.min)) {
if (newVersionStatus === 'none' || newVersionStatus === 'valid') {
throw ERRORS.TypedError(HardwareErrorCode.NewFirmwareUnRelease);
}

return ERRORS.TypedError(
HardwareErrorCode.CallMethodNeedUpgradeFirmware,
`Device firmware version is too low, please update to ${versionRange.min}`,
{ current: currentVersion, require: versionRange.min }
);
}

if (
versionRange.max &&
semver.valid(versionRange.max) &&
semver.gte(currentVersion, versionRange.max)
) {
return ERRORS.TypedError(
HardwareErrorCode.CallMethodDeprecated,
`Device firmware version is too high, this method has been deprecated in ${versionRange.max}`,
{ current: currentVersion, deprecated: versionRange.max }
);
}
}

checkDeviceSupportFeature() {
if (!this.device || !this.device.features) return;
const inputPinOnSoftware = supportInputPinOnSoftware(this.device.features);
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/api/btc/BTCGetAddress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { getBitcoinForkVersionRange } from './helpers/versionLimit';
export default class BTCGetAddress extends BaseMethod<GetAddress[]> {
hasBundle = false;

preCheckVersionLimit = true;

init() {
this.checkDeviceId = true;
this.notAllowDeviceMode = [...this.notAllowDeviceMode, UI_REQUEST.INITIALIZE];
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/api/btc/BTCGetPublicKey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { getBitcoinForkVersionRange } from './helpers/versionLimit';
export default class BTCGetPublicKey extends BaseMethod<GetPublicKey[]> {
hasBundle = false;

preCheckVersionLimit = true;

init() {
this.checkDeviceId = true;
this.notAllowDeviceMode = [...this.notAllowDeviceMode, UI_REQUEST.INITIALIZE];
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/api/btc/BTCSignMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { getCoinAndScriptType } from './helpers/btcParamsUtils';
import { getBitcoinForkVersionRange } from './helpers/versionLimit';

export default class BTCSignMessage extends BaseMethod<SignMessage> {
preCheckVersionLimit = true;

init() {
this.checkDeviceId = true;
this.notAllowDeviceMode = [...this.notAllowDeviceMode, UI_REQUEST.INITIALIZE];
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/api/btc/BTCSignPsbt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { formatAnyHex } from '../helpers/hexUtils';
import { getCoinInfo } from './helpers/btcParamsUtils';

export default class BTCSignPsbt extends BaseMethod<SignPsbt> {
preCheckVersionLimit = true;

init() {
this.checkDeviceId = true;
this.notAllowDeviceMode = [...this.notAllowDeviceMode, UI_REQUEST.INITIALIZE];
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/api/btc/BTCSignTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ type Params = {
coinName: string;
};
export default class BTCSignTransaction extends BaseMethod<Params> {
preCheckVersionLimit = true;

init() {
this.checkDeviceId = true;
this.notAllowDeviceMode = [...this.notAllowDeviceMode, UI_REQUEST.INITIALIZE];
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/api/btc/BTCVerifyMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { getCoinInfo } from './helpers/btcParamsUtils';
import { getBitcoinForkVersionRange } from './helpers/versionLimit';

export default class BTCVerifyMessage extends BaseMethod<VerifyMessage> {
preCheckVersionLimit = true;

init() {
this.checkDeviceId = true;
this.notAllowDeviceMode = [...this.notAllowDeviceMode, UI_REQUEST.INITIALIZE];
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/api/evm/EVMSignTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { signTransaction } from './latest/signTransaction';
import { signTransaction as signTransactionLegacyV1 } from './legacyV1/signTransaction';

export default class EVMSignTransaction extends BaseMethod {
preCheckVersionLimit = true;

addressN: number[] = [];

isEIP1559 = false;
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/api/polkadot/PolkadotGetAddress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { getPolkadotVersionRangeWithBundle } from './networks';
export default class PolkadotGetAddress extends BaseMethod<HardwarePolkadotGetAddress[]> {
hasBundle = false;

preCheckVersionLimit = true;

init() {
this.checkDeviceId = true;
this.notAllowDeviceMode = [...this.notAllowDeviceMode];
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/api/polkadot/PolkadotSignTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { getPolkadotVersionRange } from './networks';
export default class PolkadotSignTransaction extends BaseMethod<HardwarePolkadotSignTx> {
hasBundle = false;

preCheckVersionLimit = true;

init() {
this.checkDeviceId = true;
this.notAllowDeviceMode = [...this.notAllowDeviceMode];
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/api/solana/SolSignTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { SolanaSignedTx, SolanaSignTransactionParams } from '../../types';
import { formatAnyHex } from '../helpers/hexUtils';

export default class SolSignTransaction extends BaseMethod<HardwareSolanaSignTx[]> {
preCheckVersionLimit = true;

hasBundle = false;

init() {
Expand Down
57 changes: 13 additions & 44 deletions packages/core/src/core/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import semver from 'semver';
import EventEmitter from 'events';
import { Features, LowlevelTransportSharedPlugin, OneKeyDeviceInfo } from '@onekeyfe/hd-transport';
import {
Expand All @@ -8,15 +7,7 @@ import {
HardwareError,
HardwareErrorCode,
} from '@onekeyfe/hd-shared';
import {
getDeviceFirmwareVersion,
enableLog,
getLogger,
LoggerNames,
setLoggerPostMessage,
wait,
getMethodVersionRange,
} from '../utils';
import { enableLog, getLogger, LoggerNames, setLoggerPostMessage, wait } from '../utils';
import { supportNewPassphrase } from '../utils/deviceFeaturesUtils';
import { Device, DeviceEvents, InitOptions, RunOptions } from '../device/Device';
import { DeviceList } from '../device/DeviceList';
Expand Down Expand Up @@ -108,7 +99,10 @@ export const callAPI = async (message: CoreMessage) => {
const response = await method.run();
return createResponseMessage(method.responseID, true, response);
} catch (error) {
return createResponseMessage(method.responseID, false, { error });
const unsupportedMethodError = method.handleUnsupportedMethodError(error);
return createResponseMessage(method.responseID, false, {
error: unsupportedMethodError ?? error,
});
}
}

Expand Down Expand Up @@ -162,11 +156,6 @@ export const callAPI = async (message: CoreMessage) => {
try {
const inner = async (): Promise<void> => {
// check firmware version
const versionRange = getMethodVersionRange(
device.features,
type => method.getVersionRange()[type]
);

if (device.features) {
await DataManager.checkAndReloadData();
const newVersionStatus = DataManager.getFirmwareStatus(device.features);
Expand All @@ -182,33 +171,10 @@ export const callAPI = async (message: CoreMessage) => {
);
}

if (versionRange) {
const currentVersion = getDeviceFirmwareVersion(device.features).join('.');
if (semver.valid(versionRange.min) && semver.lt(currentVersion, versionRange.min)) {
if (newVersionStatus === 'none' || newVersionStatus === 'valid') {
throw ERRORS.TypedError(HardwareErrorCode.NewFirmwareUnRelease);
}

return Promise.reject(
ERRORS.TypedError(
HardwareErrorCode.CallMethodNeedUpgradeFirmware,
`Device firmware version is too low, please update to ${versionRange.min}`,
{ current: currentVersion, require: versionRange.min }
)
);
}
if (
versionRange.max &&
semver.valid(versionRange.max) &&
semver.gte(currentVersion, versionRange.max)
) {
return Promise.reject(
ERRORS.TypedError(
HardwareErrorCode.CallMethodDeprecated,
`Device firmware version is too high, this method has been deprecated in ${versionRange.max}`,
{ current: currentVersion, deprecated: versionRange.max }
)
);
if (method.preCheckVersionLimit) {
const error = method.handleUnsupportedMethodError();
if (error) {
throw error;
}
}
}
Expand Down Expand Up @@ -306,7 +272,10 @@ export const callAPI = async (message: CoreMessage) => {
_callPromise?.resolve(messageResponse);
} catch (error) {
Log.debug('Call API - Inner Method Run Error: ', error);
messageResponse = createResponseMessage(method.responseID, false, { error });
const unsupportedMethodError = method.handleUnsupportedMethodError(error);
messageResponse = createResponseMessage(method.responseID, false, {
error: unsupportedMethodError ?? error,
});
_callPromise?.resolve(messageResponse);
}
};
Expand Down
7 changes: 6 additions & 1 deletion packages/shared/src/HardwareError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,11 @@ export const HardwareErrorCode = {
*/
BridgeDeviceDisconnected: 817,

/**
* Unsupported Method
*/
UnsupportedMethod: 818,

/**
* Lowlevel transport connect error
*/
Expand Down Expand Up @@ -480,7 +485,7 @@ export const HardwareErrorCodeMessage: HardwareErrorCodeMessageMapping = {
[HardwareErrorCode.CheckDownloadFileError]: 'Check download file error',
[HardwareErrorCode.NotInSigningMode]: 'not in signing mode',
[HardwareErrorCode.DataOverload]: 'Params data overload',

[HardwareErrorCode.UnsupportedMethod]: 'Unsupported method',
/**
* Lowlevel transport
*/
Expand Down

0 comments on commit cf43422

Please sign in to comment.