mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-27 08:38:07 +00:00
nem2: Handle Aggregate Modification transactions
This commit is contained in:
parent
a10e131ecd
commit
2aeeb3f978
@ -1154,7 +1154,11 @@ void fsm_msgNEMSignTx(NEMSignTx *msg) {
|
||||
CHECK_PARAM(msg->has_transaction, _("No common provided"));
|
||||
|
||||
// Ensure exactly one transaction is provided
|
||||
unsigned int provided = msg->has_transfer + msg->has_provision_namespace + msg->has_mosaic_creation + msg->has_supply_change;
|
||||
unsigned int provided = msg->has_transfer +
|
||||
msg->has_provision_namespace +
|
||||
msg->has_mosaic_creation +
|
||||
msg->has_supply_change +
|
||||
msg->has_aggregate_modification;
|
||||
CHECK_PARAM(provided != 0, _("No transaction provided"));
|
||||
CHECK_PARAM(provided == 1, _("More than one transaction provided"));
|
||||
|
||||
@ -1163,6 +1167,7 @@ void fsm_msgNEMSignTx(NEMSignTx *msg) {
|
||||
NEM_CHECK_PARAM_WHEN(msg->has_provision_namespace, nem_validate_provision_namespace(&msg->provision_namespace, msg->transaction.network));
|
||||
NEM_CHECK_PARAM_WHEN(msg->has_mosaic_creation, nem_validate_mosaic_creation(&msg->mosaic_creation, msg->transaction.network));
|
||||
NEM_CHECK_PARAM_WHEN(msg->has_supply_change, nem_validate_supply_change(&msg->supply_change));
|
||||
NEM_CHECK_PARAM_WHEN(msg->has_aggregate_modification, nem_validate_aggregate_modification(&msg->aggregate_modification, !msg->has_multisig));
|
||||
|
||||
bool cosigning = msg->has_cosigning && msg->cosigning;
|
||||
if (msg->has_multisig) {
|
||||
@ -1225,6 +1230,12 @@ void fsm_msgNEMSignTx(NEMSignTx *msg) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg->has_aggregate_modification && !nem_askAggregateModification(common, &msg->aggregate_modification, network, !msg->has_multisig)) {
|
||||
fsm_sendFailure(FailureType_Failure_ActionCancelled, _("Signing cancelled by user"));
|
||||
layoutHome();
|
||||
return;
|
||||
}
|
||||
|
||||
nem_transaction_ctx context;
|
||||
nem_transaction_start(&context, &node->public_key[1], resp->data.bytes, sizeof(resp->data.bytes));
|
||||
|
||||
@ -1254,6 +1265,11 @@ void fsm_msgNEMSignTx(NEMSignTx *msg) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg->has_aggregate_modification && !nem_fsmAggregateModification(&inner, &msg->multisig, &msg->aggregate_modification)) {
|
||||
layoutHome();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!nem_fsmMultisig(&context, &msg->transaction, &inner, cosigning)) {
|
||||
layoutHome();
|
||||
return;
|
||||
@ -1278,6 +1294,11 @@ void fsm_msgNEMSignTx(NEMSignTx *msg) {
|
||||
layoutHome();
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg->has_aggregate_modification && !nem_fsmAggregateModification(&context, &msg->transaction, &msg->aggregate_modification)) {
|
||||
layoutHome();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
resp->has_data = true;
|
||||
|
118
firmware/nem2.c
118
firmware/nem2.c
@ -137,6 +137,26 @@ const char *nem_validate_supply_change(const NEMMosaicSupplyChange *supply_chang
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *nem_validate_aggregate_modification(const NEMAggregateModification *aggregate_modification, bool creation) {
|
||||
if (creation && aggregate_modification->modifications_count == 0) {
|
||||
return _("No modifications provided");
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < aggregate_modification->modifications_count; i++) {
|
||||
const NEMCosignatoryModification *modification = &aggregate_modification->modifications[i];
|
||||
|
||||
if (!modification->has_type) return _("No modification type provided");
|
||||
if (!modification->has_public_key) return _("No cosignatory public key provided");
|
||||
if (modification->public_key.size != 32) return _("Invalid cosignatory public key provided");
|
||||
|
||||
if (creation && modification->type == NEMModificationType_CosignatoryModification_Delete) {
|
||||
return _("Cannot remove cosignatory when converting account");
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool nem_askTransfer(const NEMTransactionCommon *common, const NEMTransfer *transfer, const char *desc) {
|
||||
if (transfer->mosaics_count) {
|
||||
struct {
|
||||
@ -527,6 +547,104 @@ bool nem_fsmSupplyChange(nem_transaction_ctx *context, const NEMTransactionCommo
|
||||
supply_change->delta);
|
||||
}
|
||||
|
||||
bool nem_askAggregateModification(const NEMTransactionCommon *common, const NEMAggregateModification *aggregate_modification, const char *desc, bool creation) {
|
||||
if (creation) {
|
||||
layoutDialogSwipe(&bmp_icon_question,
|
||||
_("Cancel"),
|
||||
_("Next"),
|
||||
desc,
|
||||
_("Convert account to"),
|
||||
_("multisig account?"),
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput, false)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
char address[NEM_ADDRESS_SIZE + 1];
|
||||
|
||||
for (size_t i = 0; i < aggregate_modification->modifications_count; i++) {
|
||||
const NEMCosignatoryModification *modification = &aggregate_modification->modifications[i];
|
||||
nem_get_address(modification->public_key.bytes, common->network, address);
|
||||
|
||||
layoutNEMDialog(&bmp_icon_question,
|
||||
_("Cancel"),
|
||||
_("Next"),
|
||||
desc,
|
||||
modification->type == NEMModificationType_CosignatoryModification_Add ? _("Add cosignatory") : _("Remove cosignatory"),
|
||||
address);
|
||||
if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput, false)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t relative_change = aggregate_modification->relative_change;
|
||||
if (relative_change) {
|
||||
char str_out[32];
|
||||
|
||||
bignum256 amnt;
|
||||
bn_read_uint64(relative_change < 0 ? -relative_change : relative_change, &amnt);
|
||||
bn_format(&amnt, NULL, NULL, 0, str_out, sizeof(str_out));
|
||||
|
||||
char *decimal = strchr(str_out, '.');
|
||||
if (decimal != NULL) {
|
||||
*decimal = '\0';
|
||||
}
|
||||
|
||||
layoutDialogSwipe(&bmp_icon_question,
|
||||
_("Cancel"),
|
||||
_("Next"),
|
||||
desc,
|
||||
creation ? _("Set minimum") : (relative_change < 0 ? _("Decrease minimum") : _("Increase minimum")),
|
||||
creation ? _("cosignatories to") : _("cosignatories by"),
|
||||
str_out,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput, false)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
layoutNEMNetworkFee(desc, true, _("Confirm network fee"), common->fee, NULL, 0);
|
||||
if (!protectButton(ButtonRequestType_ButtonRequest_SignTx, false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nem_fsmAggregateModification(nem_transaction_ctx *context, const NEMTransactionCommon *common, const NEMAggregateModification *aggregate_modification) {
|
||||
bool ret = nem_transaction_create_aggregate_modification(context,
|
||||
common->network,
|
||||
common->timestamp,
|
||||
NULL,
|
||||
common->fee,
|
||||
common->deadline,
|
||||
aggregate_modification->modifications_count,
|
||||
aggregate_modification->relative_change != 0);
|
||||
if (!ret) return false;
|
||||
|
||||
for (size_t i = 0; i < aggregate_modification->modifications_count; i++) {
|
||||
const NEMCosignatoryModification *modification = &aggregate_modification->modifications[i];
|
||||
|
||||
ret = nem_transaction_write_cosignatory_modification(context,
|
||||
modification->type,
|
||||
modification->public_key.bytes);
|
||||
if (!ret) return false;
|
||||
}
|
||||
|
||||
if (aggregate_modification->relative_change) {
|
||||
ret = nem_transaction_write_minimum_cosignatories(context, aggregate_modification->relative_change);
|
||||
if (!ret) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nem_askMultisig(const char *address, const char *desc, bool cosigning, uint64_t fee) {
|
||||
layoutNEMDialog(&bmp_icon_question,
|
||||
_("Cancel"),
|
||||
|
@ -33,6 +33,7 @@ const char *nem_validate_transfer(const NEMTransfer *transfer, uint8_t network);
|
||||
const char *nem_validate_provision_namespace(const NEMProvisionNamespace *provision_namespace, uint8_t network);
|
||||
const char *nem_validate_mosaic_creation(const NEMMosaicCreation *mosaic_creation, uint8_t network);
|
||||
const char *nem_validate_supply_change(const NEMMosaicSupplyChange *supply_change);
|
||||
const char *nem_validate_aggregate_modification(const NEMAggregateModification *aggregate_modification, bool creation);
|
||||
|
||||
bool nem_askTransfer(const NEMTransactionCommon *common, const NEMTransfer *transfer, const char *desc);
|
||||
bool nem_fsmTransfer(nem_transaction_ctx *context, const HDNode *node, const NEMTransactionCommon *common, const NEMTransfer *transfer);
|
||||
@ -46,6 +47,9 @@ bool nem_fsmMosaicCreation(nem_transaction_ctx *context, const NEMTransactionCom
|
||||
bool nem_askSupplyChange(const NEMTransactionCommon *common, const NEMMosaicSupplyChange *supply_change, const char *desc);
|
||||
bool nem_fsmSupplyChange(nem_transaction_ctx *context, const NEMTransactionCommon *common, const NEMMosaicSupplyChange *supply_change);
|
||||
|
||||
bool nem_askAggregateModification(const NEMTransactionCommon *common, const NEMAggregateModification *aggregate_modification, const char *desc, bool creation);
|
||||
bool nem_fsmAggregateModification(nem_transaction_ctx *context, const NEMTransactionCommon *common, const NEMAggregateModification *aggregate_modification);
|
||||
|
||||
bool nem_askMultisig(const char *address, const char *desc, bool cosigning, uint64_t fee);
|
||||
bool nem_fsmMultisig(nem_transaction_ctx *context, const NEMTransactionCommon *common, const nem_transaction_ctx *inner, bool cosigning);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user