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.
pull/604/head
Saleem Rashid 5 years ago committed by Pavol Rusnak
parent 9ccde8d853
commit 1ca521eec9
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D

@ -132,8 +132,7 @@ void fsm_msgNEMSignTx(NEMSignTx *msg) {
hdnode_get_nem_address(node, common->network, address); hdnode_get_nem_address(node, common->network, address);
if (msg->has_transfer) { if (msg->has_transfer) {
msg->transfer.mosaics_count = nem_canonicalizeMosaics( nem_canonicalizeMosaics(&msg->transfer);
msg->transfer.mosaics, msg->transfer.mosaics_count);
} }
if (msg->has_transfer && !nem_askTransfer(common, &msg->transfer, network)) { 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); -divisor, false, str_out, size);
} }
size_t nem_canonicalizeMosaics(NEMMosaic *mosaics, size_t mosaics_count) { void nem_canonicalizeMosaics(NEMTransfer *transfer) {
if (mosaics_count <= 1) { size_t old_count = transfer->mosaics_count;
return 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)); memzero(skip, sizeof(skip));
size_t new_count = 0;
// Merge duplicates // Merge duplicates
for (size_t i = 0; i < mosaics_count; i++) { for (size_t i = 0; i < old_count; i++) {
if (skip[i]) continue; 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)); 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; if (skip[j]) continue;
const NEMMosaic *new_mosaic = &mosaics[j]; 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 // 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]; 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]; NEMMosaic *b = &mosaics[j];
if (nem_mosaicCompare(a, b) > 0) { if (nem_mosaicCompare(a, b) > 0) {
NEMMosaic temp;
memcpy(&temp, a, sizeof(NEMMosaic)); memcpy(&temp, a, sizeof(NEMMosaic));
memcpy(a, b, sizeof(NEMMosaic)); memcpy(a, b, sizeof(NEMMosaic));
memcpy(b, &temp, sizeof(NEMMosaic)); memcpy(b, &temp, sizeof(NEMMosaic));
} }
} }
} }
return actual_count;
} }
void nem_mosaicFormatAmount(const NEMMosaicDefinition *definition, void nem_mosaicFormatAmount(const NEMMosaicDefinition *definition,

@ -92,7 +92,7 @@ const NEMMosaicDefinition *nem_mosaicByName(const char *namespace,
const char *mosaic, const char *mosaic,
uint8_t network); uint8_t network);
size_t nem_canonicalizeMosaics(NEMMosaic *mosaics, size_t mosaics_count); void nem_canonicalizeMosaics(NEMTransfer *transfer);
void nem_mosaicFormatAmount(const NEMMosaicDefinition *definition, void nem_mosaicFormatAmount(const NEMMosaicDefinition *definition,
uint64_t quantity, const bignum256 *multiplier, uint64_t quantity, const bignum256 *multiplier,
char *str_out, size_t size); char *str_out, size_t size);

Loading…
Cancel
Save