Skip to content

Commit 9f411d0

Browse files
authored
fix(legacy): adjusted the polkadot transaction parsing logic to make it more general (#572)
1 parent a10ee12 commit 9f411d0

File tree

5 files changed

+127
-109
lines changed

5 files changed

+127
-109
lines changed

legacy/firmware/polkadot/parser.c

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,40 @@
1515
#define FIELD_BLOCK_HASH 6
1616

1717
#define EXPERT_FIELDS_TOTAL_COUNT 5
18-
19-
parser_error_t polkadot_parser_parse(parser_context_t *ctx, const uint8_t *data,
20-
size_t dataLen, parser_tx_t *tx_obj) {
18+
extern uint16_t __address_type;
19+
#define POLKADOT_PARSER_PARSE_V26 \
20+
polkadot_parser_parse_dispatch(ctx, data, dataLen, tx_obj, true);
21+
#define POLKADOT_PARSER_PARSE_V25 \
22+
polkadot_parser_parse_dispatch(ctx, data, dataLen, tx_obj, false);
23+
24+
static parser_error_t polkadot_parser_parse_dispatch(parser_context_t *ctx,
25+
const uint8_t *data,
26+
size_t dataLen,
27+
parser_tx_t *tx_obj,
28+
bool mode_enabled) {
2129
CHECK_PARSER_ERR(polkadot_parser_init(ctx, data, dataLen))
30+
memzero(tx_obj, sizeof(parser_tx_t));
2231
ctx->tx_obj = tx_obj;
2332
ctx->tx_obj->nestCallIdx.slotIdx = 0;
2433
ctx->tx_obj->nestCallIdx._lenBuffer = 0;
2534
ctx->tx_obj->nestCallIdx._ptr = NULL;
2635
ctx->tx_obj->nestCallIdx._nextPtr = NULL;
2736
ctx->tx_obj->nestCallIdx.isTail = true;
28-
parser_error_t err = _polkadot_readTx(ctx, ctx->tx_obj);
37+
parser_error_t err = _polkadot_readTx(ctx, ctx->tx_obj, mode_enabled);
38+
39+
return err;
40+
}
2941

42+
parser_error_t polkadot_parser_parse(parser_context_t *ctx, const uint8_t *data,
43+
size_t dataLen, parser_tx_t *tx_obj) {
44+
__address_type = _detectAddressType(ctx);
45+
parser_error_t err = POLKADOT_PARSER_PARSE_V26;
46+
if (err != parser_ok && err != parser_unexpected_callIndex) {
47+
err = POLKADOT_PARSER_PARSE_V25;
48+
if (err != parser_ok && err != parser_unexpected_callIndex) {
49+
return parser_tx_version_not_supported;
50+
}
51+
}
3052
return err;
3153
}
3254

legacy/firmware/polkadot/parser_impl.c

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,33 +7,25 @@
77
#include "substrate/substrate_dispatch.h"
88
#include "substrate/substrate_types.h"
99

10-
extern uint16_t __address_type;
11-
12-
parser_error_t _polkadot_readTx(parser_context_t *c, parser_tx_t *v) {
10+
parser_error_t _polkadot_readTx(parser_context_t *c, parser_tx_t *v,
11+
bool mode_enabled) {
1312
CHECK_INPUT()
1413

15-
__address_type = _detectAddressType(c);
16-
17-
// Reverse parse to retrieve spec before forward parsing
18-
CHECK_ERROR(_checkVersions(c))
1914
// Now forward parse
2015
CHECK_ERROR(_readCallIndex(c, &v->callIndex))
2116
CHECK_ERROR(
2217
_readMethod(c, v->callIndex.moduleIdx, v->callIndex.idx, &v->method))
2318
CHECK_ERROR(_readEra(c, &v->era))
2419
CHECK_ERROR(_readCompactIndex(c, &v->nonce))
2520
CHECK_ERROR(_readCompactBalance(c, &v->tip))
26-
uint32_t transactionVersion = v->transactionVersion;
27-
if (transactionVersion == SUPPORTED_TX_VERSION_CURRENT ||
28-
transactionVersion == SUPPORTED_TX_VERSION_CURRENT_MANTA) {
21+
if (mode_enabled) {
2922
CHECK_ERROR(_readu8(c, &v->mode))
3023
}
3124
CHECK_ERROR(_readu32(c, &v->specVersion))
3225
CHECK_ERROR(_readu32(c, &v->transactionVersion))
3326
CHECK_ERROR(_readHash(c, &v->genesisHash))
3427
CHECK_ERROR(_readHash(c, &v->blockHash))
35-
if (transactionVersion == SUPPORTED_TX_VERSION_CURRENT ||
36-
transactionVersion == SUPPORTED_TX_VERSION_CURRENT_MANTA) {
28+
if (mode_enabled) {
3729
uint8_t optMetadataHash = 0;
3830
CHECK_ERROR(_readu8(c, &optMetadataHash));
3931
// Reject the transaction if Mode=Enabled or MetadataDigest is present

legacy/firmware/polkadot/parser_impl.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,9 @@ parser_error_t _readCallIndex(parser_context_t *c, pd_CallIndex_t *v);
168168

169169
parser_error_t _readEra(parser_context_t *c, pd_ExtrinsicEra_t *v);
170170

171-
parser_error_t _polkadot_readTx(parser_context_t *c, parser_tx_t *v);
172-
173-
parser_error_t _checkVersions(parser_context_t *c);
171+
parser_error_t _polkadot_readTx(parser_context_t *c, parser_tx_t *v,
172+
bool mode_enabled);
173+
// parser_error_t _checkVersions(parser_context_t *c);
174174

175175
uint16_t _getAddressType(void);
176176

legacy/firmware/polkadot/parser_impl_common.c

Lines changed: 91 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -244,94 +244,97 @@ parser_error_t _toStringCompactBalance(const pd_CompactBalance_t *v,
244244
////////////////////////////////////////////////////////////////
245245
////////////////////////////////////////////////////////////////
246246

247-
static parser_error_t _checkVersionsV26(parser_context_t *c) {
248-
// Methods are not length delimited so in order to retrieve the specVersion
249-
// it is necessary to parse from the back.
250-
// The transaction is expect to end in
251-
// [4 bytes] specVersion
252-
// [4 bytes] transactionVersion
253-
// [32 bytes] genesisHash
254-
// [32 bytes] blockHash
255-
// [1 / 33 bytes] opt<checkMetadataHash> --> Only None is supported
256-
const uint16_t specOffsetFromBack = 4 + 4 + 32 + 32 + 1;
257-
if (c->bufferLen < specOffsetFromBack) {
258-
return parser_unexpected_buffer_end;
259-
}
260-
261-
uint8_t *p = (uint8_t *)(c->buffer + c->bufferLen - specOffsetFromBack);
262-
uint32_t specVersion = 0;
263-
specVersion += (uint32_t)p[0] << 0u;
264-
specVersion += (uint32_t)p[1] << 8u;
265-
specVersion += (uint32_t)p[2] << 16u;
266-
specVersion += (uint32_t)p[3] << 24u;
267-
268-
p += 4;
269-
uint32_t transactionVersion = 0;
270-
transactionVersion += (uint32_t)p[0] << 0u;
271-
transactionVersion += (uint32_t)p[1] << 8u;
272-
transactionVersion += (uint32_t)p[2] << 16u;
273-
transactionVersion += (uint32_t)p[3] << 24u;
274-
if ((transactionVersion != (SUPPORTED_TX_VERSION_CURRENT) ||
275-
specVersion < SUPPORTED_MINIMUM_SPEC_VERSION)) {
276-
if (transactionVersion != (SUPPORTED_TX_VERSION_CURRENT_MANTA) &&
277-
strncmp(polkadot_network, "manta", 5) != 0) {
278-
return parser_tx_version_not_supported;
279-
}
280-
}
281-
c->tx_obj->specVersion = specVersion;
282-
c->tx_obj->transactionVersion = transactionVersion;
283-
c->tx_obj->mode = 0;
284-
return parser_ok;
285-
}
286-
287-
static parser_error_t _checkVersionsV25(parser_context_t *c) {
288-
// Methods are not length delimited so in order to retrieve the specVersion
289-
// it is necessary to parse from the back.
290-
// The transaction is expect to end in
291-
// [4 bytes] specVersion
292-
// [4 bytes] transactionVersion
293-
// [32 bytes] genesisHash
294-
// [32 bytes] blockHash
295-
const uint16_t specOffsetFromBack = 4 + 4 + 32 + 32;
296-
if (c->bufferLen < specOffsetFromBack) {
297-
return parser_unexpected_buffer_end;
298-
}
299-
300-
uint8_t *p = (uint8_t *)(c->buffer + c->bufferLen - specOffsetFromBack);
301-
uint32_t specVersion = 0;
302-
specVersion += (uint32_t)p[0] << 0u;
303-
specVersion += (uint32_t)p[1] << 8u;
304-
specVersion += (uint32_t)p[2] << 16u;
305-
specVersion += (uint32_t)p[3] << 24u;
306-
307-
p += 4;
308-
uint32_t transactionVersion = 0;
309-
transactionVersion += (uint32_t)p[0] << 0u;
310-
transactionVersion += (uint32_t)p[1] << 8u;
311-
transactionVersion += (uint32_t)p[2] << 16u;
312-
transactionVersion += (uint32_t)p[3] << 24u;
313-
if (transactionVersion > (SUPPORTED_TX_VERSION_PREVIOUS)) {
314-
return parser_tx_version_not_supported;
315-
}
316-
317-
if (specVersion < (SUPPORTED_MINIMUM_SPEC_VERSION)) {
318-
return parser_spec_not_supported;
319-
}
320-
c->tx_obj->specVersion = specVersion;
321-
c->tx_obj->transactionVersion = transactionVersion;
322-
323-
return parser_ok;
324-
}
325-
326-
parser_error_t _checkVersions(parser_context_t *c) {
327-
const parser_error_t withoutMode = _checkVersionsV25(c);
328-
const parser_error_t modeDisabled = _checkVersionsV26(c);
329-
330-
if (withoutMode != parser_ok && modeDisabled != parser_ok) {
331-
return parser_tx_version_not_supported;
332-
}
333-
return parser_ok;
334-
}
247+
// static parser_error_t _checkVersionsV26(parser_context_t *c) {
248+
// // Methods are not length delimited so in order to retrieve the specVersion
249+
// // it is necessary to parse from the back.
250+
// // The transaction is expect to end in
251+
// // [4 bytes] specVersion
252+
// // [4 bytes] transactionVersion
253+
// // [32 bytes] genesisHash
254+
// // [32 bytes] blockHash
255+
// // [1 / 33 bytes] opt<checkMetadataHash> --> Only None is supported
256+
// const uint16_t specOffsetFromBack = 4 + 4 + 32 + 32 + 1;
257+
// if (c->bufferLen < specOffsetFromBack) {
258+
// return parser_unexpected_buffer_end;
259+
// }
260+
261+
// uint8_t *p = (uint8_t *)(c->buffer + c->bufferLen - specOffsetFromBack);
262+
// uint32_t specVersion = 0;
263+
// specVersion += (uint32_t)p[0] << 0u;
264+
// specVersion += (uint32_t)p[1] << 8u;
265+
// specVersion += (uint32_t)p[2] << 16u;
266+
// specVersion += (uint32_t)p[3] << 24u;
267+
268+
// p += 4;
269+
// uint32_t transactionVersion = 0;
270+
// transactionVersion += (uint32_t)p[0] << 0u;
271+
// transactionVersion += (uint32_t)p[1] << 8u;
272+
// transactionVersion += (uint32_t)p[2] << 16u;
273+
// transactionVersion += (uint32_t)p[3] << 24u;
274+
// if ((transactionVersion < (SUPPORTED_TX_VERSION_CURRENT) ||
275+
// specVersion < SUPPORTED_MINIMUM_SPEC_VERSION_CURRENT)) {
276+
// if (strncmp(polkadot_network, "manta", 5) == 0) {
277+
// if (transactionVersion < (SUPPORTED_TX_VERSION_CURRENT_MANTA)) {
278+
// return parser_tx_version_not_supported;
279+
// }
280+
// } else {
281+
// return parser_tx_version_not_supported;
282+
// }
283+
// }
284+
// c->tx_obj->specVersion = specVersion;
285+
// c->tx_obj->transactionVersion = transactionVersion;
286+
// c->tx_obj->mode = 0;
287+
// return parser_ok;
288+
// }
289+
290+
// static parser_error_t _checkVersionsV25(parser_context_t *c) {
291+
// // Methods are not length delimited so in order to retrieve the specVersion
292+
// // it is necessary to parse from the back.
293+
// // The transaction is expect to end in
294+
// // [4 bytes] specVersion
295+
// // [4 bytes] transactionVersion
296+
// // [32 bytes] genesisHash
297+
// // [32 bytes] blockHash
298+
// const uint16_t specOffsetFromBack = 4 + 4 + 32 + 32;
299+
// if (c->bufferLen < specOffsetFromBack) {
300+
// return parser_unexpected_buffer_end;
301+
// }
302+
303+
// uint8_t *p = (uint8_t *)(c->buffer + c->bufferLen - specOffsetFromBack);
304+
// uint32_t specVersion = 0;
305+
// specVersion += (uint32_t)p[0] << 0u;
306+
// specVersion += (uint32_t)p[1] << 8u;
307+
// specVersion += (uint32_t)p[2] << 16u;
308+
// specVersion += (uint32_t)p[3] << 24u;
309+
310+
// p += 4;
311+
// uint32_t transactionVersion = 0;
312+
// transactionVersion += (uint32_t)p[0] << 0u;
313+
// transactionVersion += (uint32_t)p[1] << 8u;
314+
// transactionVersion += (uint32_t)p[2] << 16u;
315+
// transactionVersion += (uint32_t)p[3] << 24u;
316+
// if (transactionVersion > (SUPPORTED_TX_VERSION_PREVIOUS)) {
317+
// return parser_tx_version_not_supported;
318+
// }
319+
320+
// if (specVersion < (SUPPORTED_MINIMUM_SPEC_VERSION_PREVIOUS)) {
321+
// return parser_spec_not_supported;
322+
// }
323+
// c->tx_obj->specVersion = specVersion;
324+
// c->tx_obj->transactionVersion = transactionVersion;
325+
326+
// return parser_ok;
327+
// }
328+
329+
// parser_error_t _checkVersions(parser_context_t *c) {
330+
// const parser_error_t modeDisabled = _checkVersionsV26(c);
331+
// const parser_error_t withoutMode = _checkVersionsV25(c);
332+
333+
// if (withoutMode != parser_ok && modeDisabled != parser_ok) {
334+
// return parser_tx_version_not_supported;
335+
// }
336+
// return parser_ok;
337+
// }
335338

336339
uint16_t __address_type;
337340

legacy/firmware/polkadot/substrate/substrate_coin.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33

44
// Coin Specific
55
#define SUPPORTED_TX_VERSION_CURRENT 26
6-
#define SUPPORTED_TX_VERSION_CURRENT_MANTA 9
6+
#define SUPPORTED_TX_VERSION_CURRENT_MANTA 10
77
#define SUPPORTED_TX_VERSION_PREVIOUS (26 - 1)
88
#define SUPPORTED_SPEC_VERSION (1002006)
9-
#define SUPPORTED_MINIMUM_SPEC_VERSION 90
9+
#define SUPPORTED_MINIMUM_SPEC_VERSION_CURRENT 4720 // v26
10+
#define SUPPORTED_MINIMUM_SPEC_VERSION_PREVIOUS 90 // v25
1011

1112
#define COIN_AMOUNT_DECIMAL_PLACES 10
1213
#define COIN_AMOUNT_DECIMAL_PLACES_12 12

0 commit comments

Comments
 (0)