mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-23 23:08:14 +00:00
legacy/nem: Refactor nem_canonicalizeMosaics
GCC is able to reason about transfer->mosaics_count using Value Range Propagation. Using transfer->mosaics_count, instead of a mosaics_count argument, satisfies GCC that the variable-length skip array cannot be too large. Renamed variables to old_count and new_count to reduce ambiguity.
This commit is contained in:
parent
9ccde8d853
commit
1ca521eec9
@ -132,8 +132,7 @@ void fsm_msgNEMSignTx(NEMSignTx *msg) {
|
||||
hdnode_get_nem_address(node, common->network, address);
|
||||
|
||||
if (msg->has_transfer) {
|
||||
msg->transfer.mosaics_count = nem_canonicalizeMosaics(
|
||||
msg->transfer.mosaics, msg->transfer.mosaics_count);
|
||||
nem_canonicalizeMosaics(&msg->transfer);
|
||||
}
|
||||
|
||||
if (msg->has_transfer && !nem_askTransfer(common, &msg->transfer, network)) {
|
||||
|
@ -700,27 +700,31 @@ static inline size_t format_amount(const NEMMosaicDefinition *definition,
|
||||
-divisor, false, str_out, size);
|
||||
}
|
||||
|
||||
size_t nem_canonicalizeMosaics(NEMMosaic *mosaics, size_t mosaics_count) {
|
||||
if (mosaics_count <= 1) {
|
||||
return mosaics_count;
|
||||
void nem_canonicalizeMosaics(NEMTransfer *transfer) {
|
||||
size_t old_count = transfer->mosaics_count;
|
||||
|
||||
if (old_count <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t actual_count = 0;
|
||||
NEMMosaic *const mosaics = transfer->mosaics;
|
||||
|
||||
bool skip[mosaics_count];
|
||||
bool skip[old_count];
|
||||
memzero(skip, sizeof(skip));
|
||||
|
||||
size_t new_count = 0;
|
||||
|
||||
// Merge duplicates
|
||||
for (size_t i = 0; i < mosaics_count; i++) {
|
||||
for (size_t i = 0; i < old_count; i++) {
|
||||
if (skip[i]) continue;
|
||||
|
||||
NEMMosaic *mosaic = &mosaics[actual_count];
|
||||
NEMMosaic *mosaic = &mosaics[new_count];
|
||||
|
||||
if (actual_count++ != i) {
|
||||
if (new_count++ != i) {
|
||||
memcpy(mosaic, &mosaics[i], sizeof(NEMMosaic));
|
||||
}
|
||||
|
||||
for (size_t j = i + 1; j < mosaics_count; j++) {
|
||||
for (size_t j = i + 1; j < old_count; j++) {
|
||||
if (skip[j]) continue;
|
||||
|
||||
const NEMMosaic *new_mosaic = &mosaics[j];
|
||||
@ -732,24 +736,23 @@ size_t nem_canonicalizeMosaics(NEMMosaic *mosaics, size_t mosaics_count) {
|
||||
}
|
||||
}
|
||||
|
||||
NEMMosaic temp;
|
||||
transfer->mosaics_count = new_count;
|
||||
|
||||
// Sort mosaics
|
||||
for (size_t i = 0; i < actual_count - 1; i++) {
|
||||
for (size_t i = 0; i < new_count - 1; i++) {
|
||||
NEMMosaic *a = &mosaics[i];
|
||||
|
||||
for (size_t j = i + 1; j < actual_count; j++) {
|
||||
for (size_t j = i + 1; j < new_count; j++) {
|
||||
NEMMosaic *b = &mosaics[j];
|
||||
|
||||
if (nem_mosaicCompare(a, b) > 0) {
|
||||
NEMMosaic temp;
|
||||
memcpy(&temp, a, sizeof(NEMMosaic));
|
||||
memcpy(a, b, sizeof(NEMMosaic));
|
||||
memcpy(b, &temp, sizeof(NEMMosaic));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return actual_count;
|
||||
}
|
||||
|
||||
void nem_mosaicFormatAmount(const NEMMosaicDefinition *definition,
|
||||
|
@ -92,7 +92,7 @@ const NEMMosaicDefinition *nem_mosaicByName(const char *namespace,
|
||||
const char *mosaic,
|
||||
uint8_t network);
|
||||
|
||||
size_t nem_canonicalizeMosaics(NEMMosaic *mosaics, size_t mosaics_count);
|
||||
void nem_canonicalizeMosaics(NEMTransfer *transfer);
|
||||
void nem_mosaicFormatAmount(const NEMMosaicDefinition *definition,
|
||||
uint64_t quantity, const bignum256 *multiplier,
|
||||
char *str_out, size_t size);
|
||||
|
Loading…
Reference in New Issue
Block a user