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);
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…
Cancel
Save