mirror of
https://github.com/trezor/trezor-suite.git
synced 2026-03-07 07:47:59 +01:00
chore(protocol): rename getChunkHeader to getHeaders and return [header, chunkHeader]
This commit is contained in:
committed by
Szymon Lesisz
parent
4b8dbc051e
commit
b893516894
@@ -1,13 +1,13 @@
|
||||
import { HEADER_SIZE } from './constants';
|
||||
import { TransportProtocolEncode } from '../types';
|
||||
import { TransportProtocol } from '../types';
|
||||
|
||||
// for type compatibility, bridge doesn't send chunks
|
||||
export const getChunkHeader = (_data: Buffer) => Buffer.alloc(0);
|
||||
// just for type compatibility, bridge doesn't send headers
|
||||
export const getHeaders: TransportProtocol['getHeaders'] = () => [Buffer.alloc(0), Buffer.alloc(0)];
|
||||
|
||||
// this file is basically combination of "trezor v1 protocol" and "bridge protocol"
|
||||
// there is actually no officially described bridge protocol, but in fact there is one
|
||||
// it is because bridge does some parts of the protocol itself (like chunking)
|
||||
export const encode: TransportProtocolEncode = (data, options) => {
|
||||
export const encode: TransportProtocol['encode'] = (data, options) => {
|
||||
const { messageType } = options;
|
||||
if (typeof messageType === 'string') {
|
||||
throw new Error(`Unsupported message type ${messageType}`);
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
import { HEADER_SIZE, MESSAGE_HEADER_BYTE, MESSAGE_MAGIC_HEADER_BYTE } from './constants';
|
||||
import { TransportProtocolEncode } from '../types';
|
||||
import { TransportProtocol } from '../types';
|
||||
|
||||
export const getChunkHeader = (_data: Buffer) => {
|
||||
const header = Buffer.alloc(1);
|
||||
header.writeUInt8(MESSAGE_MAGIC_HEADER_BYTE);
|
||||
// header: 3f2323 `?##` and chunkHeader: 3f `?`
|
||||
export const getHeaders: TransportProtocol['getHeaders'] = () => {
|
||||
const header = Buffer.alloc(3);
|
||||
// 1 byte
|
||||
header.writeUInt8(MESSAGE_MAGIC_HEADER_BYTE, 0);
|
||||
// 2*1 byte
|
||||
header.writeUInt8(MESSAGE_HEADER_BYTE, 1);
|
||||
header.writeUInt8(MESSAGE_HEADER_BYTE, 2);
|
||||
|
||||
return header;
|
||||
const chunkHeader = Buffer.alloc(1);
|
||||
chunkHeader.writeUInt8(MESSAGE_MAGIC_HEADER_BYTE);
|
||||
|
||||
return [header, chunkHeader];
|
||||
};
|
||||
|
||||
export const encode: TransportProtocolEncode = (data, options) => {
|
||||
export const encode: TransportProtocol['encode'] = (data, options) => {
|
||||
const { messageType } = options;
|
||||
if (typeof messageType === 'string') {
|
||||
throw new Error(`Unsupported message type ${messageType}`);
|
||||
@@ -17,12 +25,8 @@ export const encode: TransportProtocolEncode = (data, options) => {
|
||||
const fullSize = HEADER_SIZE + data.length;
|
||||
|
||||
const encodedBuffer = Buffer.alloc(fullSize);
|
||||
// 1 byte
|
||||
encodedBuffer.writeUInt8(MESSAGE_MAGIC_HEADER_BYTE, 0);
|
||||
|
||||
// 2*1 byte
|
||||
encodedBuffer.writeUInt8(MESSAGE_HEADER_BYTE, 1);
|
||||
encodedBuffer.writeUInt8(MESSAGE_HEADER_BYTE, 2);
|
||||
const [header] = getHeaders(data);
|
||||
header.copy(encodedBuffer);
|
||||
|
||||
// 2 bytes
|
||||
encodedBuffer.writeUInt16BE(messageType, 3);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as ERRORS from '../errors';
|
||||
import { HEADER_SIZE, MESSAGE_LEN_SIZE, MESSAGE_TYPE } from './constants';
|
||||
import { getChunkHeader } from './encode';
|
||||
import { getHeaders } from './encode';
|
||||
import { TransportProtocolDecode } from '../types';
|
||||
|
||||
// Parses raw input from Trezor and returns some information about the whole message
|
||||
@@ -12,9 +12,11 @@ export const decode: TransportProtocolDecode = bytes => {
|
||||
throw new Error(ERRORS.PROTOCOL_MALFORMED);
|
||||
}
|
||||
|
||||
const [header, chunkHeader] = getHeaders(buffer);
|
||||
|
||||
return {
|
||||
header: buffer.subarray(0, HEADER_SIZE),
|
||||
chunkHeader: getChunkHeader(buffer),
|
||||
header,
|
||||
chunkHeader,
|
||||
length: buffer.readUint16BE(HEADER_SIZE),
|
||||
messageType: MESSAGE_TYPE, // will be decoded by `protocol-thp`
|
||||
payload: buffer.subarray(HEADER_SIZE + MESSAGE_LEN_SIZE),
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import * as ERRORS from '../errors';
|
||||
import { HEADER_SIZE, MESSAGE_LEN_SIZE, MESSAGE_TYPE } from './constants';
|
||||
import { TransportProtocolEncode } from '../types';
|
||||
import { TransportProtocol } from '../types';
|
||||
|
||||
export const getChunkHeader = (data: Buffer) => {
|
||||
const getChunkHeader = (data: Buffer) => {
|
||||
// data should have at least 1 control_byte + 2 bytes channel
|
||||
if (data.byteLength < HEADER_SIZE) {
|
||||
throw new Error(ERRORS.PROTOCOL_MALFORMED);
|
||||
@@ -14,8 +14,14 @@ export const getChunkHeader = (data: Buffer) => {
|
||||
return header;
|
||||
};
|
||||
|
||||
export const getHeaders: TransportProtocol['getHeaders'] = data => {
|
||||
const chunkHeader = getChunkHeader(data);
|
||||
|
||||
return [data.subarray(0, HEADER_SIZE), chunkHeader];
|
||||
};
|
||||
|
||||
// encode `protocol-thp` message
|
||||
export const encode: TransportProtocolEncode = (data, options) => {
|
||||
export const encode: TransportProtocol['encode'] = (data, options) => {
|
||||
if (options.messageType === MESSAGE_TYPE) {
|
||||
if (!options.header || options.header.byteLength !== HEADER_SIZE) {
|
||||
throw new Error(
|
||||
|
||||
@@ -26,5 +26,5 @@ export interface TransportProtocol {
|
||||
name: 'bridge' | 'v1' | 'v2';
|
||||
encode: TransportProtocolEncode;
|
||||
decode: TransportProtocolDecode;
|
||||
getChunkHeader: (data: Buffer) => Buffer;
|
||||
getHeaders: (data: Buffer) => [header: Buffer, chunkHeader: Buffer];
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { decode, encode, getChunkHeader } from '../src/protocol-v2';
|
||||
import { decode, encode, getHeaders } from '../src/protocol-v2';
|
||||
|
||||
describe('protocol-v2', () => {
|
||||
it('encode/decode TrezorHostProtocolMessage', () => {
|
||||
@@ -43,11 +43,12 @@ describe('protocol-v2', () => {
|
||||
expect(() => decode(Buffer.alloc(0))).toThrow('Malformed protocol format');
|
||||
});
|
||||
|
||||
it('getChunkHeader', () => {
|
||||
expect(getChunkHeader(Buffer.from('0412380000', 'hex'))).toEqual(
|
||||
it('getHeaders', () => {
|
||||
expect(getHeaders(Buffer.from('0412380000', 'hex'))).toEqual([
|
||||
Buffer.from('041238', 'hex'),
|
||||
Buffer.from('801238', 'hex'),
|
||||
);
|
||||
]);
|
||||
// with error
|
||||
expect(() => getChunkHeader(Buffer.alloc(0))).toThrow('Malformed protocol format');
|
||||
expect(() => getHeaders(Buffer.alloc(0))).toThrow('Malformed protocol format');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -67,10 +67,10 @@ export const createCore = (apiArg: 'usb' | 'udp' | AbstractApi, logger?: Log) =>
|
||||
if (protocol.name === 'bridge') {
|
||||
const { messageType, payload } = protocolBridge.decode(buffer);
|
||||
encodedMessage = protocolV1.encode(payload, { messageType });
|
||||
chunkHeader = protocolV1.getChunkHeader(encodedMessage);
|
||||
[, chunkHeader] = protocolV1.getHeaders(encodedMessage);
|
||||
} else {
|
||||
encodedMessage = buffer;
|
||||
chunkHeader = protocol.getChunkHeader(encodedMessage);
|
||||
[, chunkHeader] = protocol.getHeaders(encodedMessage);
|
||||
}
|
||||
|
||||
const chunks = createChunks(encodedMessage, chunkHeader, api.chunkSize);
|
||||
|
||||
@@ -201,11 +201,8 @@ export abstract class AbstractApiTransport extends AbstractTransport {
|
||||
data,
|
||||
protocol,
|
||||
});
|
||||
const chunks = createChunks(
|
||||
bytes,
|
||||
protocol.getChunkHeader(bytes),
|
||||
this.api.chunkSize,
|
||||
);
|
||||
const [, chunkHeader] = protocol.getHeaders(bytes);
|
||||
const chunks = createChunks(bytes, chunkHeader, this.api.chunkSize);
|
||||
const apiWrite = (chunk: Buffer) => this.api.write(path, chunk, signal);
|
||||
const sendResult = await sendChunks(chunks, apiWrite);
|
||||
|
||||
@@ -257,11 +254,9 @@ export abstract class AbstractApiTransport extends AbstractTransport {
|
||||
data,
|
||||
protocol,
|
||||
});
|
||||
const chunks = createChunks(
|
||||
bytes,
|
||||
protocol.getChunkHeader(bytes),
|
||||
this.api.chunkSize,
|
||||
);
|
||||
const [_, chunkHeader] = protocol.getHeaders(bytes);
|
||||
|
||||
const chunks = createChunks(bytes, chunkHeader, this.api.chunkSize);
|
||||
const apiWrite = (chunk: Buffer) => this.api.write(path, chunk, signal);
|
||||
const sendResult = await sendChunks(chunks, apiWrite);
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ export async function receive<T extends () => ReturnType<AbstractApi['read']>>(
|
||||
const data = readResult.payload;
|
||||
const { length, messageType, payload } = protocol.decode(data);
|
||||
const result = Buffer.alloc(length);
|
||||
const chunkHeader = protocol.getChunkHeader(Buffer.from(data));
|
||||
const [, chunkHeader] = protocol.getHeaders(Buffer.from(data));
|
||||
|
||||
payload.copy(result);
|
||||
let offset = payload.length;
|
||||
|
||||
@@ -130,8 +130,8 @@ describe('encoding json -> protobuf -> json', () => {
|
||||
data: f.in,
|
||||
protocol: v1Protocol,
|
||||
});
|
||||
|
||||
const chunks = createChunks(result, v1Protocol.getChunkHeader(result), 64);
|
||||
const [, chunkHeader] = v1Protocol.getHeaders(result);
|
||||
const chunks = createChunks(result, chunkHeader, 64);
|
||||
// each protocol chunks are equal 64 bytes
|
||||
chunks.forEach(chunk => {
|
||||
expect(chunk.length).toEqual(64);
|
||||
|
||||
Reference in New Issue
Block a user