Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tip support #47

Merged
merged 5 commits into from
Feb 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,10 @@ file(GLOB_RECURSE LIB_SRC
${CMAKE_CURRENT_SOURCE_DIR}/app/src/parser.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/formatting.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/parser_impl.c
app/src/json/json_parser.c
app/src/tx_parser.c
app/src/tx_display.c
app/src/tx_validate.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/json/json_parser.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/tx_parser.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/tx_display.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/tx_validate.c
)

add_library(app_lib STATIC
Expand Down Expand Up @@ -138,6 +138,7 @@ target_link_libraries(unittests PRIVATE
CONAN_PKG::jsoncpp)

add_compile_definitions(TESTVECTORS_DIR="${CMAKE_CURRENT_SOURCE_DIR}/tests/")
add_compile_definitions(APP_TESTING=1)
add_test(unittests ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/unittests)
set_tests_properties(unittests PROPERTIES WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests)

Expand Down
4 changes: 2 additions & 2 deletions app/Makefile.version
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This is the `transaction_version` field of `Runtime`
APPVERSION_M=2
# This is the `spec_version` field of `Runtime`
APPVERSION_N=32
APPVERSION_N=33
# This is the patch version of this release
APPVERSION_P=1
APPVERSION_P=0
10 changes: 7 additions & 3 deletions app/src/addr.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,35 +26,39 @@ zxerr_t addr_getNumItems(uint8_t *num_items) {
zemu_log_stack("addr_getNumItems");
*num_items = 1;
if (app_mode_expert()) {
zemu_log("num_items 2\n");
*num_items = 2;
}
zemu_log("num_items 1\n");
return zxerr_ok;
}

zxerr_t addr_getItem(int8_t displayIdx,
char *outKey, uint16_t outKeyLen,
char *outVal, uint16_t outValLen,
uint8_t pageIdx, uint8_t *pageCount) {
char buffer[300];
snprintf(buffer, sizeof(buffer), "addr_getItem %d/%d", displayIdx, pageIdx);
zemu_log_stack(buffer);
ZEMU_LOGF(200, "[addr_getItem] %d/%d\n", displayIdx, pageIdx)

switch (displayIdx) {
case 0:
snprintf(outKey, outKeyLen, "Address");
pageString(outVal, outValLen, (char *) (G_io_apdu_buffer + VIEW_ADDRESS_OFFSET_SECP256K1), pageIdx, pageCount);
ZEMU_LOGF(200, "[addr_getItem] pageCount %d\n", *pageCount)
return zxerr_ok;
case 1: {
if (!app_mode_expert()) {
return zxerr_no_data;
}

char buffer[300];
snprintf(outKey, outKeyLen, "Path");
bip32_to_str(buffer, sizeof(buffer), hdPath, HDPATH_LEN_DEFAULT);
pageString(outVal, outValLen, buffer, pageIdx, pageCount);
ZEMU_LOGF(200, "[addr_getItem] pageCount %d\n", *pageCount)
return zxerr_ok;
}
default:
zemu_log("[addr_getItem] no data\n");
return zxerr_no_data;
}
}
6 changes: 6 additions & 0 deletions app/src/json/json_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ parser_error_t json_parse(parsed_json_t *parsed_json, const char *buffer, uint16
parsed_json->tokens,
MAX_NUMBER_OF_TOKENS);

#ifdef APP_TESTING
char tmpBuffer[100];
snprintf(tmpBuffer, sizeof(tmpBuffer), "tokens: %d", num_tokens);
zemu_log(tmpBuffer);
#endif

if (num_tokens < 0) {
switch (num_tokens) {
case JSMN_ERROR_NOMEM:
Expand Down
109 changes: 86 additions & 23 deletions app/src/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ parser_error_t parser_getNumItems(const parser_context_t *ctx __attribute__((unu
return tx_display_numItems(num_items);
}

__Z_INLINE bool_t parser_areEqual(uint16_t tokenidx, char *expected) {
if (parser_tx_obj.json.tokens[tokenidx].type != JSMN_STRING) {
__Z_INLINE bool_t parser_areEqual(uint16_t tokenIdx, char *expected) {
if (parser_tx_obj.json.tokens[tokenIdx].type != JSMN_STRING) {
return bool_false;
}

int32_t len = parser_tx_obj.json.tokens[tokenidx].end - parser_tx_obj.json.tokens[tokenidx].start;
int32_t len = parser_tx_obj.json.tokens[tokenIdx].end - parser_tx_obj.json.tokens[tokenIdx].start;
if (len < 0) {
return bool_false;
}
Expand All @@ -69,7 +69,7 @@ __Z_INLINE bool_t parser_areEqual(uint16_t tokenidx, char *expected) {
return bool_false;
}

const char *p = parser_tx_obj.tx + parser_tx_obj.json.tokens[tokenidx].start;
const char *p = parser_tx_obj.tx + parser_tx_obj.json.tokens[tokenIdx].start;
for (int32_t i = 0; i < len; i++) {
if (expected[i] != *(p + i)) {
return bool_false;
Expand All @@ -80,17 +80,25 @@ __Z_INLINE bool_t parser_areEqual(uint16_t tokenidx, char *expected) {
}

__Z_INLINE bool_t parser_isAmount(char *key) {
if (strcmp(key, "fee/amount") == 0)
if (strcmp(key, "fee/amount") == 0) {
return bool_true;
}

if (strcmp(key, "msgs/inputs/coins") == 0)
if (strcmp(key, "msgs/inputs/coins") == 0) {
return bool_true;
}

if (strcmp(key, "msgs/outputs/coins") == 0)
if (strcmp(key, "msgs/outputs/coins") == 0) {
return bool_true;
}

if (strcmp(key, "msgs/value/amount") == 0)
if (strcmp(key, "msgs/value/amount") == 0) {
return bool_true;
}

if (strcmp(key, "tip/amount") == 0) {
return bool_true;
}

return bool_false;
}
Expand All @@ -110,16 +118,12 @@ __Z_INLINE bool_t is_default_denom_base(const char *denom, uint8_t denom_len) {
return bool_false;
}

__Z_INLINE parser_error_t parser_formatAmount(uint16_t amountToken,
char *outVal, uint16_t outValLen,
uint8_t pageIdx, uint8_t *pageCount) {
__Z_INLINE parser_error_t parser_formatAmountItem(uint16_t amountToken,
char *outVal, uint16_t outValLen,
uint8_t pageIdx, uint8_t *pageCount) {
*pageCount = 0;
if (parser_tx_obj.json.tokens[amountToken].type == JSMN_ARRAY) {
amountToken++;
}

uint16_t numElements;

CHECK_PARSER_ERR(array_get_element_count(&parser_tx_obj.json, amountToken, &numElements))

if (numElements == 0) {
Expand All @@ -128,17 +132,21 @@ __Z_INLINE parser_error_t parser_formatAmount(uint16_t amountToken,
return parser_ok;
}

if (numElements != 4)
if (numElements != 4) {
return parser_unexpected_field;
}

if (parser_tx_obj.json.tokens[amountToken].type != JSMN_OBJECT)
if (parser_tx_obj.json.tokens[amountToken].type != JSMN_OBJECT) {
return parser_unexpected_field;
}

if (!parser_areEqual(amountToken + 1u, "amount"))
if (!parser_areEqual(amountToken + 1u, "amount")) {
return parser_unexpected_field;
}

if (!parser_areEqual(amountToken + 3u, "denom"))
if (!parser_areEqual(amountToken + 3u, "denom")) {
return parser_unexpected_field;
}

char bufferUI[160];
char tmpDenom[COIN_DENOM_MAXSIZE];
Expand Down Expand Up @@ -191,6 +199,62 @@ __Z_INLINE parser_error_t parser_formatAmount(uint16_t amountToken,
return parser_ok;
}

__Z_INLINE parser_error_t parser_formatAmount(uint16_t amountToken,
char *outVal, uint16_t outValLen,
uint8_t pageIdx, uint8_t *pageCount) {
ZEMU_LOGF(200, "[formatAmount] ------- pageidx %d", pageIdx)

*pageCount = 0;
if (parser_tx_obj.json.tokens[amountToken].type != JSMN_ARRAY) {
return parser_formatAmountItem(amountToken, outVal, outValLen, pageIdx, pageCount);
}

uint8_t totalPages = 0;
bool_t showItemSet = false;
uint8_t showPageIdx = pageIdx;
uint16_t showItemTokenIdx = 0;

uint16_t numberAmounts;
CHECK_PARSER_ERR(array_get_element_count(&parser_tx_obj.json, amountToken, &numberAmounts))

// Count total subpagesCount and calculate correct page and TokenIdx
for (uint16_t i = 0; i < numberAmounts; i++) {
uint16_t itemTokenIdx;
uint8_t subpagesCount;

CHECK_PARSER_ERR(array_get_nth_element(&parser_tx_obj.json, amountToken, i, &itemTokenIdx));
CHECK_PARSER_ERR(parser_formatAmountItem(itemTokenIdx, outVal, outValLen, 0, &subpagesCount));
totalPages += subpagesCount;

ZEMU_LOGF(200, "[formatAmount] [%d] TokenIdx: %d - PageIdx: %d - Pages: %d - Total %d", i, itemTokenIdx,
showPageIdx, subpagesCount, totalPages)

if (!showItemSet) {
if (showPageIdx < subpagesCount) {
showItemSet = true;
showItemTokenIdx = itemTokenIdx;
ZEMU_LOGF(200, "[formatAmount] [%d] [SET] TokenIdx %d - PageIdx: %d", i, showItemTokenIdx,
showPageIdx)
} else {
showPageIdx -= subpagesCount;
}
}
}
*pageCount = totalPages;
if (pageIdx > totalPages) {
return parser_unexpected_value;
}

if (totalPages == 0) {
*pageCount = 1;
snprintf(outVal, outValLen, "Empty");
return parser_ok;
}

uint8_t dummy;
return parser_formatAmountItem(showItemTokenIdx, outVal, outValLen, showPageIdx, &dummy);
}

parser_error_t parser_getItem(const parser_context_t *ctx,
uint8_t displayIdx,
char *outKey, uint16_t outKeyLen,
Expand Down Expand Up @@ -221,10 +285,9 @@ parser_error_t parser_getItem(const parser_context_t *ctx,
snprintf(outKey, outKeyLen, "%s", tmpKey);

if (parser_isAmount(tmpKey)) {
CHECK_PARSER_ERR(
parser_formatAmount(ret_value_token_index,
outVal, outValLen,
pageIdx, pageCount))
CHECK_PARSER_ERR(parser_formatAmount(ret_value_token_index,
outVal, outValLen,
pageIdx, pageCount))
} else {
CHECK_PARSER_ERR(tx_getToken(ret_value_token_index,
outVal, outValLen,
Expand Down
Loading