Skip to content

Commit

Permalink
fixing bridge
Browse files Browse the repository at this point in the history
  • Loading branch information
szymonlesisz committed Aug 1, 2024
1 parent a064734 commit ae84f83
Show file tree
Hide file tree
Showing 15 changed files with 298 additions and 73 deletions.
3 changes: 3 additions & 0 deletions packages/connect/src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,9 @@ const onPopupClosed = (customErrorMessage?: string) => {
const error = customErrorMessage
? ERRORS.TypedError('Method_Cancel', customErrorMessage)
: ERRORS.TypedError('Method_Interrupted');

uiPromises.rejectAll(error);

// Device was already acquired. Try to interrupt running action which will throw error from onCall try/catch block
if (_deviceList.isConnected() && _deviceList.asArray().length > 0) {
_deviceList.allDevices().forEach(d => {
Expand Down
5 changes: 5 additions & 0 deletions packages/connect/src/device/Device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ export class Device extends TypedEmitter<DeviceEvents> {
}
}

console.log('Device.this.releasePromise');

Check warning on line 264 in packages/connect/src/device/Device.ts

View workflow job for this annotation

GitHub Actions / Linting and formatting

Unexpected console statement
this.releasePromise = this.transport.release({
session: this.activitySessionID,
path: this.originalDescriptor.path,
Expand All @@ -281,6 +282,7 @@ export class Device extends TypedEmitter<DeviceEvents> {
this.removeAllListeners();
// make sure that Device_CallInProgress will not be thrown
delete this.runPromise;
console.log('Device.cleanup.release');

Check warning on line 285 in packages/connect/src/device/Device.ts

View workflow job for this annotation

GitHub Actions / Linting and formatting

Unexpected console statement
await this.release();
// restore DEVICE.ACQUIRED listeners
acquiredListeners.forEach(l => this.once(DEVICE.ACQUIRED, l));
Expand Down Expand Up @@ -451,6 +453,7 @@ export class Device extends TypedEmitter<DeviceEvents> {
options.keepSession === false
) {
this.keepSession = false;
console.log('_runinner.release');

Check warning on line 456 in packages/connect/src/device/Device.ts

View workflow job for this annotation

GitHub Actions / Linting and formatting

Unexpected console statement
await this.release();
}

Expand Down Expand Up @@ -832,6 +835,8 @@ export class Device extends TypedEmitter<DeviceEvents> {
await this.commands.cancel();
}

console.log('Device.this.transport.release');

Check warning on line 838 in packages/connect/src/device/Device.ts

View workflow job for this annotation

GitHub Actions / Linting and formatting

Unexpected console statement

return this.transport.release({
session: this.activitySessionID,
path: this.originalDescriptor.path,
Expand Down
60 changes: 55 additions & 5 deletions packages/connect/src/device/thpCommands.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { createHash, randomBytes } from 'crypto';
import { Messages } from '@trezor/transport';
import { thp as protocolThp } from '@trezor/protocol';
import { createDeferred } from '@trezor/utils';
import type { Device } from './Device';
import { UiResponseThpPairingTag, DEVICE } from '../events';

Expand Down Expand Up @@ -202,6 +203,7 @@ export const initThpChannel = async (device: Device, settings: any) => {
const promptThpPairing = (device: Device) => {
return new Promise<UiResponseThpPairingTag>((resolve, reject) => {
device.emit(DEVICE.THP_PAIRING, device, (err, code) => {
console.warn('--promptThpPairing resolve', err, code);
if (err) {
reject(err);
} else {
Expand Down Expand Up @@ -236,6 +238,7 @@ const thpWaitForThpPairingTag = async (device: Device): Promise<DefaultMessageRe

console.warn('debugState', debugState);

const dfd = createDeferred();
const readCancel = device.transport.receive({
session: device.activitySessionID!,
protocol: device.protocol,
Expand All @@ -247,12 +250,17 @@ const thpWaitForThpPairingTag = async (device: Device): Promise<DefaultMessageRe
if (!r.success) {
console.warn('readCancelPromise resolved with error', r);

//return Promise.resolve();
// never resolve?
return new Promise<DefaultMessageResponse>(() => {});
}
console.warn('readCancelPromise result', r);
console.warn('readCancelPromise result success', r);

// cp.resolve(r as unknown as DefaultMessageResponse);

// TODO: type is wrong, r is a TransportResponse not DefaultMessageResponse
return r as unknown as DefaultMessageResponse;
// return r as unknown as DefaultMessageResponse;
return new Promise<DefaultMessageResponse>(() => {});
})
.catch(e => {
console.warn('readCancelPromise error', e);
Expand All @@ -264,14 +272,56 @@ const thpWaitForThpPairingTag = async (device: Device): Promise<DefaultMessageRe

const pairingPromise = promptThpPairing(device).then(
response => {
response.payload.value = thp_pairing_code_entry_code;

readCancel.abort();

response.payload.value = thp_pairing_code_entry_code;
console.warn('.. waiting for CP');

// return (
// cancelPromise
// .then(cp => {
// console.warn('cancelPromise resolved with error-1', cp);
// })
// .catch(e => {
// console.warn('cancelPromise resolved with error-2', e);
// })
// // eslint-disable-next-line @typescript-eslint/no-use-before-define
// .finally(() => processThpPairingResponse(device, response))
// );

// eslint-disable-next-line @typescript-eslint/no-use-before-define
return processThpPairingResponse(device, response);
return processThpPairingResponse(device, response).then(() => {
throw new Error('End');
});

// const hostKeys = protocolThp.getCpaceHostKeys(
// response.payload.value,
// device.transportState!.handshakeCredentials!.handshakeHash,
// );

// return device.thpCall(device, 'Cancel', {})transport
// .send({
// session: device.activitySessionID!,
// protocol: device.protocol,
// protocolState: device.transportState,
// name: 'ThpCodeEntryCpaceHost',
// data: {
// cpace_host_public_key: hostKeys.publicKey.toString('hex'),
// },
// })
// .promise.then(() => {
// return new Promise<DefaultMessageResponse>(() => {});
// });
},
() => thpCall(device, 'Cancel', {}),
() =>
device.transport.send({
session: device.activitySessionID!,
protocol: device.protocol,
protocolState: device.transportState,
name: 'Cancel',
data: {},
}).promise,
);

console.warn('Waiting....');
Expand Down
26 changes: 14 additions & 12 deletions packages/connect/test-e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,18 @@ const run = async () => {
}

if (event.type === 'ui-request_thp_pairing') {
// TrezorConnect.cancel();
await new Promise(resolve => setTimeout(resolve, 2000));
TrezorConnect.uiResponse({
type: 'ui-receive_thp_pairing_tag',
payload: {
// source: 'qr-code',
// value: '87e2db0f783c1b30c585000f71b7ae28',
source: 'code-entry',
value: 723282, // emu first run only
},
});
TrezorConnect.cancel();

// await new Promise(resolve => setTimeout(resolve, 2000));
// TrezorConnect.uiResponse({
// type: 'ui-receive_thp_pairing_tag',
// payload: {
// // source: 'qr-code',
// // value: '87e2db0f783c1b30c585000f71b7ae28',
// source: 'code-entry',
// value: 723282, // emu first run only
// },
// });
}

if (event.type === 'ui-button') {
Expand All @@ -49,7 +50,8 @@ const run = async () => {

await TrezorConnect.init({
manifest: { appUrl: 'a', email: 'b' },
transports: process.argv[2] === 'udp' ? ['UdpTransport'] : ['NodeUsbTransport'],
// transports: process.argv[2] === 'udp' ? ['UdpTransport'] : ['NodeUsbTransport'],
transports: process.argv[2] === 'udp' ? ['UdpTransport'] : ['BridgeTransport'],
pendingTransportEvent: false,
// lazyLoad: true,
thp: {
Expand Down
39 changes: 37 additions & 2 deletions packages/protocol/src/protocol-thp/ThpProtocolState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,20 @@ export class ThpProtocolState {
}

updateSyncBit(type: 'send' | 'recv', syncBit?: ThpMessageSyncBit) {
const calc = (curr: ThpMessageSyncBit, v?: ThpMessageSyncBit) => {
if (typeof v === 'number') {
return v;
}

return curr > 0 ? 0 : 1;
};
if (type === 'send') {
this._sendBit = syncBit ?? this._sendBit > 0 ? 0 : 1;
// this._sendBit = syncBit ?? this._sendBit > 0 ? 0 : 1;
this._sendBit = calc(this._sendBit, syncBit);
} else {
this._recvBit = syncBit ?? this._recvBit > 0 ? 0 : 1;
console.warn('----> update recv bit', syncBit, syncBit ?? 'a');
// this._recvBit = syncBit ?? this._recvBit > 0 ? 0 : 1;
this._recvBit = calc(this._recvBit, syncBit);
}
}

Expand Down Expand Up @@ -149,6 +159,31 @@ export class ThpProtocolState {
return true;
}

updateState(messageName: string) {
if (
[
'ThpCreateChannelRequest',
'ThpCreateChannelResponse',
'ThpHandshakeInitRequest',
'ThpHandshakeInitResponse',
'ThpHandshakeCompletionRequest',
'ThpHandshakeCompletionResponse',
].includes(messageName)
) {
// keep nonce at initial values for first three messages of the handshake workflow
this._sendNonce = 0;
this._recvNonce = 1;
} else {
this._sendNonce += 1;
this._recvNonce += 1;
}

if (messageName !== 'ThpCreateChannelResponse') {
this._sendBit = this._sendBit > 0 ? 0 : 1;
this._recvBit = this._recvBit > 0 ? 0 : 1;
}
}

toString() {
return JSON.stringify(this.serialize());
}
Expand Down
2 changes: 2 additions & 0 deletions packages/protocol/src/protocol-thp/decode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,8 @@ export const getExpectedResponse = (bytes: Buffer) => {
};

export const isExpectedResponse = (bytes: Buffer, protocolState?: TransportProtocolState) => {
if (bytes.length < 3) return false;

const header = readHeader(bytes);
const magic = clearControlBit(header.magic);
const expectedResponses = protocolState?.expectedResponses || [];
Expand Down
1 change: 1 addition & 0 deletions packages/protocol/src/protocol-thp/encode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ export const encode = (options: {

export const encodeAck = (bytesOrState: Buffer | TransportProtocolState) => {
if (Buffer.isBuffer(bytesOrState)) {
console.warn('encodeAvk', bytesOrState);
// 1 byte
const magic = bytesOrState.readUInt8();
// sequence bit
Expand Down
2 changes: 2 additions & 0 deletions packages/protocol/src/protocol-v2/encode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export const getChunkHeader = (data: Buffer) => {
throw new Error(ERRORS.PROTOCOL_MALFORMED);
}

console.warn('getChunkHeader', data);

const channel = data.subarray(1, 3);
const header = Buffer.concat([Buffer.from([THP_CONTINUATION_PACKET]), channel]);

Expand Down
Loading

0 comments on commit ae84f83

Please sign in to comment.