Skip to content

feat: optimize version limit #365

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: onekey
Choose a base branch
from
Draft
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
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
Loading