1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-22 07:28:10 +00:00

feat(all): make Stellar timebounds required

This commit is contained in:
matejcik 2021-08-06 14:12:07 +02:00 committed by matejcik
parent 4b8f52cd2f
commit 1dcfdebf7a
8 changed files with 63 additions and 73 deletions

View File

@ -52,8 +52,8 @@ message StellarSignTx {
required string source_account = 4; // source account address required string source_account = 4; // source account address
required uint32 fee = 5; // Fee (in stroops) for the transaction required uint32 fee = 5; // Fee (in stroops) for the transaction
required uint64 sequence_number = 6; // transaction sequence number required uint64 sequence_number = 6; // transaction sequence number
optional uint32 timebounds_start = 8; // unix timestamp (client must truncate this to 32 bytes) required uint32 timebounds_start = 8; // unix timestamp (client must truncate this to 32 bytes)
optional uint32 timebounds_end = 9; // unix timestamp (client must truncate this to 32 bytes) required uint32 timebounds_end = 9; // unix timestamp (client must truncate this to 32 bytes)
required StellarMemoType memo_type = 10; // type of memo attached to the transaction required StellarMemoType memo_type = 10; // type of memo attached to the transaction
optional string memo_text = 11; // up to 28 characters (4 bytes are for length) optional string memo_text = 11; // up to 28 characters (4 bytes are for length)
optional uint64 memo_id = 12; // 8-byte uint64 optional uint64 memo_id = 12; // 8-byte uint64

View File

@ -0,0 +1 @@
Most Stellar fields are now required on protobuf level

View File

@ -0,0 +1 @@
Timebounds must be set for a Stellar transaction

View File

@ -70,20 +70,14 @@ async def _init(ctx: Context, w: bytearray, pubkey: bytes, msg: StellarSignTx) -
) )
async def _timebounds( async def _timebounds(ctx: Context, w: bytearray, start: int, end: int) -> None:
ctx: Context, w: bytearray, start: int | None, end: int | None # confirm dialog
) -> None: await layout.require_confirm_timebounds(ctx, start, end)
# timebounds are only present if timebounds_start or timebounds_end is non-zero
if start is not None and end is not None:
# confirm dialog
await layout.require_confirm_timebounds(ctx, start, end)
writers.write_bool(w, True)
# timebounds are sent as uint32s since that's all we can display, but they must be hashed as 64bit # timebounds are sent as uint32s since that's all we can display, but they must be hashed as 64bit
writers.write_uint64(w, start) writers.write_bool(w, True)
writers.write_uint64(w, end) writers.write_uint64(w, start)
else: writers.write_uint64(w, end)
writers.write_bool(w, False)
async def _operations(ctx: Context, w: bytearray, num_operations: int) -> None: async def _operations(ctx: Context, w: bytearray, num_operations: int) -> None:

View File

@ -4485,8 +4485,8 @@ if TYPE_CHECKING:
source_account: "str" source_account: "str"
fee: "int" fee: "int"
sequence_number: "int" sequence_number: "int"
timebounds_start: "int | None" timebounds_start: "int"
timebounds_end: "int | None" timebounds_end: "int"
memo_type: "StellarMemoType" memo_type: "StellarMemoType"
memo_text: "str | None" memo_text: "str | None"
memo_id: "int | None" memo_id: "int | None"
@ -4500,11 +4500,11 @@ if TYPE_CHECKING:
source_account: "str", source_account: "str",
fee: "int", fee: "int",
sequence_number: "int", sequence_number: "int",
timebounds_start: "int",
timebounds_end: "int",
memo_type: "StellarMemoType", memo_type: "StellarMemoType",
num_operations: "int", num_operations: "int",
address_n: "list[int] | None" = None, address_n: "list[int] | None" = None,
timebounds_start: "int | None" = None,
timebounds_end: "int | None" = None,
memo_text: "str | None" = None, memo_text: "str | None" = None,
memo_id: "int | None" = None, memo_id: "int | None" = None,
memo_hash: "bytes | None" = None, memo_hash: "bytes | None" = None,

View File

@ -0,0 +1 @@
Timebounds must be set for a Stellar transaction

View File

@ -101,21 +101,16 @@ bool stellar_signingInit(const StellarSignTx *msg) {
// Hash: sequence number // Hash: sequence number
stellar_hashupdate_uint64(msg->sequence_number); stellar_hashupdate_uint64(msg->sequence_number);
// Timebounds are only present if timebounds_start or timebounds_end is
// non-zero
uint8_t has_timebounds =
(msg->timebounds_start > 0 || msg->timebounds_end > 0);
// Hash: the "has timebounds?" boolean // Hash: the "has timebounds?" boolean
stellar_hashupdate_bool(has_timebounds); stellar_hashupdate_bool(true);
if (has_timebounds) {
// Timebounds are sent as uint32s since that's all we can display, but they
// must be hashed as 64-bit values
stellar_hashupdate_uint32(0);
stellar_hashupdate_uint32(msg->timebounds_start);
stellar_hashupdate_uint32(0); // Timebounds are sent as uint32s since that's all we can display, but they
stellar_hashupdate_uint32(msg->timebounds_end); // must be hashed as 64-bit values
} stellar_hashupdate_uint32(0);
stellar_hashupdate_uint32(msg->timebounds_start);
stellar_hashupdate_uint32(0);
stellar_hashupdate_uint32(msg->timebounds_end);
// Hash: memo // Hash: memo
stellar_hashupdate_uint32(msg->memo_type); stellar_hashupdate_uint32(msg->memo_type);
@ -1297,7 +1292,8 @@ void stellar_format_asset(const StellarAsset *asset, char *str_formatted,
memzero(str_asset_issuer_trunc, sizeof(str_asset_issuer_trunc)); memzero(str_asset_issuer_trunc, sizeof(str_asset_issuer_trunc));
// Validate issuer account for non-native assets // Validate issuer account for non-native assets
if (asset->type != StellarAssetType_NATIVE && !stellar_validateAddress(asset->issuer)) { if (asset->type != StellarAssetType_NATIVE &&
!stellar_validateAddress(asset->issuer)) {
stellar_signingAbort(_("Invalid asset issuer")); stellar_signingAbort(_("Invalid asset issuer"));
return; return;
} }
@ -1323,7 +1319,8 @@ void stellar_format_asset(const StellarAsset *asset, char *str_formatted,
memcpy(str_asset_issuer_trunc, asset->issuer, 5); memcpy(str_asset_issuer_trunc, asset->issuer, 5);
} }
// Issuer is read the same way for both types of custom assets // Issuer is read the same way for both types of custom assets
if (asset->type == StellarAssetType_ALPHANUM4 || asset->type == StellarAssetType_ALPHANUM12) { if (asset->type == StellarAssetType_ALPHANUM4 ||
asset->type == StellarAssetType_ALPHANUM12) {
strlcat(str_formatted, _(" ("), len); strlcat(str_formatted, _(" ("), len);
strlcat(str_formatted, str_asset_issuer_trunc, len); strlcat(str_formatted, str_asset_issuer_trunc, len);
strlcat(str_formatted, _(")"), len); strlcat(str_formatted, _(")"), len);
@ -1676,42 +1673,38 @@ void stellar_layoutTransactionSummary(const StellarSignTx *msg) {
memzero(str_lines, sizeof(str_lines)); memzero(str_lines, sizeof(str_lines));
// Timebound: lower // Timebound: lower
if (msg->timebounds_start || msg->timebounds_end) { time_t timebound;
time_t timebound; char str_timebound[32] = {0};
char str_timebound[32] = {0}; const struct tm *tm = NULL;
const struct tm *tm = NULL;
timebound = (time_t)msg->timebounds_start; timebound = (time_t)msg->timebounds_start;
strlcpy(str_lines[0], _("Valid from:"), sizeof(str_lines[0])); strlcpy(str_lines[0], _("Valid from:"), sizeof(str_lines[0]));
if (timebound) { if (timebound) {
tm = gmtime(&timebound); tm = gmtime(&timebound);
strftime(str_timebound, sizeof(str_timebound), "%F %T (UTC)", tm); strftime(str_timebound, sizeof(str_timebound), "%F %T (UTC)", tm);
strlcpy(str_lines[1], str_timebound, sizeof(str_lines[1])); strlcpy(str_lines[1], str_timebound, sizeof(str_lines[1]));
} else { } else {
strlcpy(str_lines[1], _("[no restriction]"), sizeof(str_lines[1])); strlcpy(str_lines[1], _("[no restriction]"), sizeof(str_lines[1]));
}
// Reset for timebound_max
memzero(str_timebound, sizeof(str_timebound));
timebound = (time_t)msg->timebounds_end;
strlcpy(str_lines[2], _("Valid to:"), sizeof(str_lines[2]));
if (timebound) {
tm = gmtime(&timebound);
strftime(str_timebound, sizeof(str_timebound), "%F %T (UTC)", tm);
strlcpy(str_lines[3], str_timebound, sizeof(str_lines[3]));
} else {
strlcpy(str_lines[3], _("[no restriction]"), sizeof(str_lines[3]));
}
} }
if (msg->timebounds_start || msg->timebounds_end) { // Reset for timebound_max
stellar_layoutTransactionDialog(_("Confirm Time Bounds"), str_lines[0], memzero(str_timebound, sizeof(str_timebound));
str_lines[1], str_lines[2], str_lines[3]);
if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { timebound = (time_t)msg->timebounds_end;
stellar_signingAbort(_("User canceled")); strlcpy(str_lines[2], _("Valid to:"), sizeof(str_lines[2]));
return; if (timebound) {
} tm = gmtime(&timebound);
strftime(str_timebound, sizeof(str_timebound), "%F %T (UTC)", tm);
strlcpy(str_lines[3], str_timebound, sizeof(str_lines[3]));
} else {
strlcpy(str_lines[3], _("[no restriction]"), sizeof(str_lines[3]));
}
stellar_layoutTransactionDialog(_("Confirm Time Bounds"), str_lines[0],
str_lines[1], str_lines[2], str_lines[3]);
if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) {
stellar_signingAbort(_("User canceled"));
return;
} }
} }

View File

@ -5966,8 +5966,8 @@ class StellarSignTx(protobuf.MessageType):
4: protobuf.Field("source_account", "string", repeated=False, required=True), 4: protobuf.Field("source_account", "string", repeated=False, required=True),
5: protobuf.Field("fee", "uint32", repeated=False, required=True), 5: protobuf.Field("fee", "uint32", repeated=False, required=True),
6: protobuf.Field("sequence_number", "uint64", repeated=False, required=True), 6: protobuf.Field("sequence_number", "uint64", repeated=False, required=True),
8: protobuf.Field("timebounds_start", "uint32", repeated=False, required=False), 8: protobuf.Field("timebounds_start", "uint32", repeated=False, required=True),
9: protobuf.Field("timebounds_end", "uint32", repeated=False, required=False), 9: protobuf.Field("timebounds_end", "uint32", repeated=False, required=True),
10: protobuf.Field("memo_type", "StellarMemoType", repeated=False, required=True), 10: protobuf.Field("memo_type", "StellarMemoType", repeated=False, required=True),
11: protobuf.Field("memo_text", "string", repeated=False, required=False), 11: protobuf.Field("memo_text", "string", repeated=False, required=False),
12: protobuf.Field("memo_id", "uint64", repeated=False, required=False), 12: protobuf.Field("memo_id", "uint64", repeated=False, required=False),
@ -5982,11 +5982,11 @@ class StellarSignTx(protobuf.MessageType):
source_account: "str", source_account: "str",
fee: "int", fee: "int",
sequence_number: "int", sequence_number: "int",
timebounds_start: "int",
timebounds_end: "int",
memo_type: "StellarMemoType", memo_type: "StellarMemoType",
num_operations: "int", num_operations: "int",
address_n: Optional[List["int"]] = None, address_n: Optional[List["int"]] = None,
timebounds_start: Optional["int"] = None,
timebounds_end: Optional["int"] = None,
memo_text: Optional["str"] = None, memo_text: Optional["str"] = None,
memo_id: Optional["int"] = None, memo_id: Optional["int"] = None,
memo_hash: Optional["bytes"] = None, memo_hash: Optional["bytes"] = None,
@ -5996,10 +5996,10 @@ class StellarSignTx(protobuf.MessageType):
self.source_account = source_account self.source_account = source_account
self.fee = fee self.fee = fee
self.sequence_number = sequence_number self.sequence_number = sequence_number
self.memo_type = memo_type
self.num_operations = num_operations
self.timebounds_start = timebounds_start self.timebounds_start = timebounds_start
self.timebounds_end = timebounds_end self.timebounds_end = timebounds_end
self.memo_type = memo_type
self.num_operations = num_operations
self.memo_text = memo_text self.memo_text = memo_text
self.memo_id = memo_id self.memo_id = memo_id
self.memo_hash = memo_hash self.memo_hash = memo_hash