From 43fc64fe361d10db83b2978bb6bf9110ed938d1b Mon Sep 17 00:00:00 2001 From: Robert Lukotka Date: Wed, 25 May 2022 09:43:43 +0200 Subject: [PATCH 01/12] Compressed transaction data lookup and parsing --- CMakeLists.txt | 1 + app/src/parser_common.h | 5 + app/src/tx_data.c | 189 +++++++++++++++++++++++ app/src/tx_data.h | 69 +++++++++ deps/ledger-zxlib/include/zxmacros_x64.h | 3 + tests/tx_data.cpp | 187 ++++++++++++++++++++++ 6 files changed, 454 insertions(+) create mode 100644 app/src/tx_data.c create mode 100644 app/src/tx_data.h create mode 100644 tests/tx_data.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 5dfbb38d..ed323856 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,6 +96,7 @@ file(GLOB_RECURSE LIB_SRC ${CMAKE_CURRENT_SOURCE_DIR}/app/src/hdpath.c ${CMAKE_CURRENT_SOURCE_DIR}/app/src/parser_impl.c ${CMAKE_CURRENT_SOURCE_DIR}/app/src/json/json_parser.c + ${CMAKE_CURRENT_SOURCE_DIR}/app/src/tx_data.c app/src/base32.c app/src/crypto.c ) diff --git a/app/src/parser_common.h b/app/src/parser_common.h index 2bda1cbd..2dff792e 100644 --- a/app/src/parser_common.h +++ b/app/src/parser_common.h @@ -74,6 +74,11 @@ typedef enum { // Required fields PARSER_REQUIRED_NONCE, PARSER_REQUIRED_METHOD, + //Template errors + PARSER_TEMPLATE_TOO_MANY_HASHES, + PARSER_TEMPLATE_ERROR, + PARSER_TEMPLATE_TOO_MANY_ARGUMENTS + } parser_error_t; typedef struct { diff --git a/app/src/tx_data.c b/app/src/tx_data.c new file mode 100644 index 00000000..c8a9d45a --- /dev/null +++ b/app/src/tx_data.c @@ -0,0 +1,189 @@ +#include "tx_data.h" +#include "zxmacros.h" + +//Known compressed templates + +const uint8_t COMPRESSED_TX_TEMPLATE_CREATE_ACCOUNT[] = { + 1, //number of hashes + hashes + 0xee, 0xf2, 0xd0, 0x49, 0x44, 0x48, 0x55, 0x41, 0x77, 0x61, 0x2e, 0x63, 0x02, 0x62, 0x56, 0x25, 0x83, 0x39, 0x23, 0x0c, 0xbc, 0x69, 0x31, 0xde, 0xd7, 0x8d, 0x61, 0x49, 0x44, 0x3c, 0x61, 0x73, + 'C', 'r', 'e', 'a', 't', 'e', ' ', 'A', 'c', 'c', 'o', 'u', 'n', 't', 0, //tx name (to display) + 1, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_ARRAY, + 'P', 'u', 'b', 'k', 'e', 'y', 0, //arg name (to display) + 0, //argument index + 'S','t', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t COMPRESSED_TX_TEMPLATE_ADD_NEW_KEY[] = { + 1, //number of hashes + hashes + 0x59, 0x5c, 0x86, 0x56, 0x14, 0x41, 0xb3, 0x2b, 0x2b, 0x91, 0xee, 0x03, 0xf9, 0xe1, 0x0c, 0xa6, 0xef, 0xa7, 0xb4, 0x1b, 0xcc, 0x99, 0x4f, 0x51, 0x31, 0x7e, 0xc0, 0xaa, 0x9d, 0x8f, 0x8a, 0x42, + 'A', 'd', 'd', ' ', 'N', 'e', 'w', ' ', 'K', 'e', 'y', 0, //tx name (to display) + 1, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'P', 'u', 'b', ' ', 'k', 'e', 'y', 0, //arg name (to display) + 0, //argument index + 'S','t', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t COMPRESSED_TX_TEMPLATE_TOKEN_TRANSFER[] = { + 3, //number of hashes + hashes + 0xca, 0x80, 0xb6, 0x28, 0xd9, 0x85, 0xb3, 0x58, 0xae, 0x1c, 0xb1, 0x36, 0xbc, 0xd9, 0x76, 0x99, 0x7c, 0x94, 0x2f, 0xa1, 0x0d, 0xba, 0xbf, 0xea, 0xfb, 0x4e, 0x20, 0xfa, 0x66, 0xa5, 0xa5, 0xe2, + 0xd5, 0x6f, 0x4e, 0x1d, 0x23, 0x55, 0xcd, 0xcf, 0xac, 0xfd, 0x01, 0xe4, 0x71, 0x45, 0x9c, 0x6e, 0xf1, 0x68, 0xbf, 0xdf, 0x84, 0x37, 0x1a, 0x68, 0x5c, 0xcf, 0x31, 0xcf, 0x3c, 0xde, 0xdc, 0x2d, + 0x47, 0x85, 0x15, 0x86, 0xd9, 0x62, 0x33, 0x5e, 0x3f, 0x7d, 0x9e, 0x5d, 0x11, 0xa4, 0xc5, 0x27, 0xee, 0x4b, 0x5f, 0xd1, 0xc3, 0x89, 0x5e, 0x3c, 0xe1, 0xb9, 0xc2, 0x82, 0x1f, 0x60, 0xb1, 0x66, + 'T', 'o', 'k', 'e', 'n', ' ', 'T', 'r', 'a', 'n', 's', 'f', 'e', 'r', 0, //tx name (to display) + 2, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 0, //argument index + 'U','I', 'n', 't', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 2 + ARGUMENT_TYPE_NORMAL, + 'D', 'e', 's', 't', 'i', 'n', 'a', 't', 'i', 'o', 'n', 0, //arg name (to display) + 1, //argument index + 'A','d', 'd', 'r', 'e', 's', 's', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + + +//List of known compressed templates +typedef struct { + const uint8_t* template; + uint16_t templateLength; +} known_template_entry_t; + +const known_template_entry_t KNOWN_TEMPLATES[] = { + {COMPRESSED_TX_TEMPLATE_CREATE_ACCOUNT, sizeof(COMPRESSED_TX_TEMPLATE_CREATE_ACCOUNT)}, + {COMPRESSED_TX_TEMPLATE_ADD_NEW_KEY, sizeof(COMPRESSED_TX_TEMPLATE_ADD_NEW_KEY)}, + {COMPRESSED_TX_TEMPLATE_TOKEN_TRANSFER, sizeof(COMPRESSED_TX_TEMPLATE_TOKEN_TRANSFER)}, + // sentinel, do not remove + {NULL, 0} +}; + +parser_error_t _validateHash(uint8_t scriptHash[SCRIPT_HASH_SIZE], const NV_VOLATILE uint8_t *compressedData, uint16_t compressedDataLen) { + if (compressedDataLen < 1) { + return PARSER_TEMPLATE_ERROR; + } + uint8_t numberOfHashes = compressedData[0]; + if (numberOfHashes > MAX_TEMPLATE_NUMBER_OF_HASHES || compressedDataLen < 1+SCRIPT_HASH_SIZE*numberOfHashes) { + return PARSER_TEMPLATE_ERROR; + } + + for(size_t i=0; i MAX_TEMPLATE_STRING_LENGTH) { \ + return PARSER_TEMPLATE_ERROR; \ + } \ + } + #define READ_SKIP(count) { \ + parsed += (count); \ + } + + //read number of hashes and validate script + { + uint8_t numberOfHashes = 0; + READ_CHAR(&numberOfHashes) + if (numberOfHashes > MAX_TEMPLATE_NUMBER_OF_HASHES) { + return PARSER_TEMPLATE_TOO_MANY_HASHES; + } + parser_error_t err = _validateHash(scriptHash, compressedData, compressedDataLen); + if (err != PARSER_OK) { + return err; + } + READ_SKIP(numberOfHashes*SCRIPT_HASH_SIZE) + } + + //read tx name + READ_STRING(&parsedTxTempate->txName, &parsedTxTempate->txNameLength) + + //read Arguments + { + READ_CHAR(&parsedTxTempate->argCount) + if (parsedTxTempate->argCount > PARSER_MAX_ARGCOUNT) { + return PARSER_TEMPLATE_TOO_MANY_ARGUMENTS; + } + STATIC_ASSERT(sizeof(parsedTxTempate->arguments) >= PARSER_MAX_ARGCOUNT, "Too few argumentst in parsed_tx_template_t."); + for(int i=0; iargCount; i++) { + READ_CHAR(&parsedTxTempate->arguments[i].argumentType); + READ_STRING(&parsedTxTempate->arguments[i].displayKey, &parsedTxTempate->arguments[i].displayKeyLength) + READ_CHAR(&parsedTxTempate->arguments[i].argumentIndex); + READ_STRING(&parsedTxTempate->arguments[i].jsonExpectedType, &parsedTxTempate->arguments[i].jsonExpectedTypeLength) + READ_CHAR(&parsedTxTempate->arguments[i].jsonExpectedKind); + } + } + + + #undef READ_CHAR + #undef READ_STRING + + if (parsed != compressedDataLen) { + return PARSER_TEMPLATE_ERROR; + } + + return PARSER_OK; +} + +parser_error_t matchStoredCompressedTxData(uint8_t scriptHash[SCRIPT_HASH_SIZE], parsed_tx_template_t *parsedTxTempate) { + size_t i=0; + while(KNOWN_TEMPLATES[i].template != NULL) { + parser_error_t err = _validateHash(scriptHash, KNOWN_TEMPLATES[i].template, KNOWN_TEMPLATES[i].templateLength); + switch (err) { + case PARSER_OK: + return parseCompressedTxData(scriptHash, KNOWN_TEMPLATES[i].template, KNOWN_TEMPLATES[i].templateLength, parsedTxTempate); + case PARSER_UNEXPECTED_SCRIPT: + break; //break switch + default: + return err; + } + i++; + } + + return PARSER_UNEXPECTED_SCRIPT; +} diff --git a/app/src/tx_data.h b/app/src/tx_data.h new file mode 100644 index 00000000..a04e368b --- /dev/null +++ b/app/src/tx_data.h @@ -0,0 +1,69 @@ +/******************************************************************************* +* (c) 2022 Vacuumlabs +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +********************************************************************************/ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +typedef enum { + ARGUMENT_TYPE_NORMAL = 1, + ARGUMENT_TYPE_OPTIONAL = 2, + ARGUMENT_TYPE_ARRAY = 3, + ARGUMENT_TYPE_OPTIONALARRAY = 4 +} parsed_tx_template_argument_type_e; + +#define MAX_TEMPLATE_NUMBER_OF_HASHES 10 +#define MAX_TEMPLATE_STRING_LENGTH 100 + +typedef struct { + parsed_tx_template_argument_type_e argumentType; + const NV_VOLATILE char *displayKey; + uint8_t displayKeyLength; + uint8_t argumentIndex; //argument index within transaction + const NV_VOLATILE char *jsonExpectedType; //pointer to null terminated string + uint8_t jsonExpectedTypeLength; + jsmntype_t jsonExpectedKind; +} parsed_tx_template_argument_t; + +typedef struct { + script_type_e script; + const NV_VOLATILE char *txName; + uint8_t txNameLength; + uint8_t argCount; + parsed_tx_template_argument_t arguments[PARSER_MAX_ARGCOUNT]; //order of arguments in which they should be displayed +} parsed_tx_template_t; + + +#define SCRIPT_HASH_SIZE 32 + +parser_error_t parseCompressedTxData(uint8_t scriptHash[SCRIPT_HASH_SIZE], const NV_VOLATILE uint8_t *compressedData, uint16_t compressedDataLen, + parsed_tx_template_t *parsedTxTempate); + +parser_error_t matchStoredCompressedTxData(uint8_t scriptHash[SCRIPT_HASH_SIZE], parsed_tx_template_t *parsedTxTempate); + +#ifdef __cplusplus + +//For C++ unit tests +parser_error_t _validateHash(uint8_t scriptHash[SCRIPT_HASH_SIZE], const NV_VOLATILE uint8_t *compressedData, uint16_t compressedDataLen); +} +#endif diff --git a/deps/ledger-zxlib/include/zxmacros_x64.h b/deps/ledger-zxlib/include/zxmacros_x64.h index 22d27dc7..282a9283 100644 --- a/deps/ledger-zxlib/include/zxmacros_x64.h +++ b/deps/ledger-zxlib/include/zxmacros_x64.h @@ -30,6 +30,9 @@ #define CX_ECCINFO_PARITY_ODD 1u #define CX_ECCINFO_xGTn 2u +#define NV_CONST +#define NV_VOLATILE + #ifndef __APPLE__ #define MEMZERO explicit_bzero #else diff --git a/tests/tx_data.cpp b/tests/tx_data.cpp new file mode 100644 index 00000000..ee0f653c --- /dev/null +++ b/tests/tx_data.cpp @@ -0,0 +1,187 @@ +/******************************************************************************* +* (c) 2020 Zondax GmbH +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +********************************************************************************/ + +#include "gmock/gmock.h" +#include +#include +#include +#include +#include +#include + +const uint8_t TEMPLATE_ADD_NEW_KEY[] = { + 1, //number of hashes + hashes + 0x59, 0x5c, 0x86, 0x56, 0x14, 0x41, 0xb3, 0x2b, 0x2b, 0x91, 0xee, 0x03, 0xf9, 0xe1, 0x0c, 0xa6, 0xef, 0xa7, 0xb4, 0x1b, 0xcc, 0x99, 0x4f, 0x51, 0x31, 0x7e, 0xc0, 0xaa, 0x9d, 0x8f, 0x8a, 0x42, + 'A', 'd', 'd', ' ', 'N', 'e', 'w', ' ', 'K', 'e', 'y', 0, //tx name (to display) + 1, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'P', 'u', 'b', ' ', 'k', 'e', 'y', 0, //arg name (to display) + 0, //argument index + 'S','t', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING //expected value json token type +}; + +const uint8_t TEMPLATE_TOKEN_TRANSFER[] = { + 3, //number of hashes + hashes + 0xca, 0x80, 0xb6, 0x28, 0xd9, 0x85, 0xb3, 0x58, 0xae, 0x1c, 0xb1, 0x36, 0xbc, 0xd9, 0x76, 0x99, 0x7c, 0x94, 0x2f, 0xa1, 0x0d, 0xba, 0xbf, 0xea, 0xfb, 0x4e, 0x20, 0xfa, 0x66, 0xa5, 0xa5, 0xe2, + 0xd5, 0x6f, 0x4e, 0x1d, 0x23, 0x55, 0xcd, 0xcf, 0xac, 0xfd, 0x01, 0xe4, 0x71, 0x45, 0x9c, 0x6e, 0xf1, 0x68, 0xbf, 0xdf, 0x84, 0x37, 0x1a, 0x68, 0x5c, 0xcf, 0x31, 0xcf, 0x3c, 0xde, 0xdc, 0x2d, + 0x47, 0x85, 0x15, 0x86, 0xd9, 0x62, 0x33, 0x5e, 0x3f, 0x7d, 0x9e, 0x5d, 0x11, 0xa4, 0xc5, 0x27, 0xee, 0x4b, 0x5f, 0xd1, 0xc3, 0x89, 0x5e, 0x3c, 0xe1, 0xb9, 0xc2, 0x82, 0x1f, 0x60, 0xb1, 0x66, + 'T', 'o', 'k', 'e', 'n', ' ', 'T', 'r', 'a', 'n', 's', 'f', 'e', 'r', 0, //tx name (to display) + 2, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 0, //argument index + 'U','I', 'n', 't', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 2 + ARGUMENT_TYPE_NORMAL, + 'D', 'e', 's', 't', 'i', 'n', 'a', 't', 'i', 'o', 'n', 0, //arg name (to display) + 1, //argument index + 'A','d', 'd', 'r', 'e', 's', 's', 0, //expected value type + JSMN_STRING //expected value json token type +}; + +uint8_t hashAddNewKey[32] = {0x59, 0x5c, 0x86, 0x56, 0x14, 0x41, 0xb3, 0x2b, 0x2b, 0x91, 0xee, 0x03, 0xf9, 0xe1, 0x0c, 0xa6, 0xef, 0xa7, 0xb4, 0x1b, 0xcc, 0x99, 0x4f, 0x51, 0x31, 0x7e, 0xc0, 0xaa, 0x9d, 0x8f, 0x8a, 0x42}; +uint8_t hashTokenTranfer1[32] = {0xca, 0x80, 0xb6, 0x28, 0xd9, 0x85, 0xb3, 0x58, 0xae, 0x1c, 0xb1, 0x36, 0xbc, 0xd9, 0x76, 0x99, 0x7c, 0x94, 0x2f, 0xa1, 0x0d, 0xba, 0xbf, 0xea, 0xfb, 0x4e, 0x20, 0xfa, 0x66, 0xa5, 0xa5, 0xe2}; +uint8_t hashTokenTranfer2[32] = {0xd5, 0x6f, 0x4e, 0x1d, 0x23, 0x55, 0xcd, 0xcf, 0xac, 0xfd, 0x01, 0xe4, 0x71, 0x45, 0x9c, 0x6e, 0xf1, 0x68, 0xbf, 0xdf, 0x84, 0x37, 0x1a, 0x68, 0x5c, 0xcf, 0x31, 0xcf, 0x3c, 0xde, 0xdc, 0x2d}; +uint8_t hashTokenTranfer3[32] = {0x47, 0x85, 0x15, 0x86, 0xd9, 0x62, 0x33, 0x5e, 0x3f, 0x7d, 0x9e, 0x5d, 0x11, 0xa4, 0xc5, 0x27, 0xee, 0x4b, 0x5f, 0xd1, 0xc3, 0x89, 0x5e, 0x3c, 0xe1, 0xb9, 0xc2, 0x82, 0x1f, 0x60, 0xb1, 0x66}; + + +TEST(tx_data, validateHash) { + parser_error_t err; + err = _validateHash(hashAddNewKey, TEMPLATE_ADD_NEW_KEY, sizeof(TEMPLATE_ADD_NEW_KEY)); + EXPECT_THAT(err, PARSER_OK); + + err = _validateHash(hashTokenTranfer1, TEMPLATE_ADD_NEW_KEY, sizeof(TEMPLATE_ADD_NEW_KEY)); + EXPECT_THAT(err, PARSER_UNEXPECTED_SCRIPT); + + err = _validateHash(hashTokenTranfer1, TEMPLATE_TOKEN_TRANSFER, sizeof(TEMPLATE_TOKEN_TRANSFER)); + EXPECT_THAT(err, PARSER_OK); + + err = _validateHash(hashTokenTranfer2, TEMPLATE_TOKEN_TRANSFER, sizeof(TEMPLATE_TOKEN_TRANSFER)); + EXPECT_THAT(err, PARSER_OK); + + err = _validateHash(hashTokenTranfer3, TEMPLATE_TOKEN_TRANSFER, sizeof(TEMPLATE_TOKEN_TRANSFER)); + EXPECT_THAT(err, PARSER_OK); + + err = _validateHash(hashAddNewKey, TEMPLATE_TOKEN_TRANSFER, sizeof(TEMPLATE_TOKEN_TRANSFER)); + EXPECT_THAT(err, PARSER_UNEXPECTED_SCRIPT); + + err = _validateHash(hashTokenTranfer3, TEMPLATE_ADD_NEW_KEY, 0); + EXPECT_THAT(err, PARSER_TEMPLATE_ERROR); + + err = _validateHash(hashTokenTranfer3, TEMPLATE_TOKEN_TRANSFER, 3*32); + EXPECT_THAT(err, PARSER_TEMPLATE_ERROR); + + err = _validateHash(hashTokenTranfer3, TEMPLATE_TOKEN_TRANSFER, 3*32+1); + EXPECT_THAT(err, PARSER_OK); +} + +const uint8_t A[] = { 0, 1 }; + + +TEST(tx_data, parseCompressedTxData) { + parser_error_t err; + parsed_tx_template_t result; + err = parseCompressedTxData(hashTokenTranfer1, TEMPLATE_ADD_NEW_KEY, sizeof(TEMPLATE_ADD_NEW_KEY), &result); + EXPECT_THAT(err, PARSER_UNEXPECTED_SCRIPT); + + err = parseCompressedTxData(hashAddNewKey, TEMPLATE_ADD_NEW_KEY, sizeof(TEMPLATE_ADD_NEW_KEY), &result); + EXPECT_THAT(err, PARSER_OK); + EXPECT_THAT(std::string(result.txName), "Add New Key"); + EXPECT_THAT(result.txNameLength, 11); + EXPECT_THAT(result.argCount, 1); + EXPECT_THAT(result.arguments[0].argumentType, ARGUMENT_TYPE_NORMAL); + EXPECT_THAT(std::string(result.arguments[0].displayKey), "Pub key"); + EXPECT_THAT(result.arguments[0].displayKeyLength, 7); + EXPECT_THAT(result.arguments[0].argumentIndex, 0); + EXPECT_THAT(std::string(result.arguments[0].jsonExpectedType), "String"); + EXPECT_THAT(result.arguments[0].jsonExpectedTypeLength, 6); + EXPECT_THAT(result.arguments[0].jsonExpectedKind, JSMN_STRING); + + err = parseCompressedTxData(hashTokenTranfer3, TEMPLATE_TOKEN_TRANSFER, sizeof(TEMPLATE_TOKEN_TRANSFER), &result); + EXPECT_THAT(err, PARSER_OK); + EXPECT_THAT(std::string(result.txName), "Token Transfer"); + EXPECT_THAT(result.txNameLength, 14); + EXPECT_THAT(result.argCount, 2); + EXPECT_THAT(result.arguments[0].argumentType, ARGUMENT_TYPE_NORMAL); + EXPECT_THAT(std::string(result.arguments[0].displayKey), "Amount"); + EXPECT_THAT(result.arguments[0].displayKeyLength, 6); + EXPECT_THAT(result.arguments[0].argumentIndex, 0); + EXPECT_THAT(std::string(result.arguments[0].jsonExpectedType), "UInt64"); + EXPECT_THAT(result.arguments[0].jsonExpectedTypeLength, 6); + EXPECT_THAT(result.arguments[0].jsonExpectedKind, JSMN_STRING); + EXPECT_THAT(result.arguments[1].argumentType, ARGUMENT_TYPE_NORMAL); + EXPECT_THAT(std::string(result.arguments[1].displayKey), "Destination"); + EXPECT_THAT(result.arguments[1].displayKeyLength, 11); + EXPECT_THAT(result.arguments[1].argumentIndex, 1); + EXPECT_THAT(std::string(result.arguments[1].jsonExpectedType), "Address"); + EXPECT_THAT(result.arguments[1].jsonExpectedTypeLength, 7); + EXPECT_THAT(result.arguments[1].jsonExpectedKind, JSMN_STRING); + + err = parseCompressedTxData(hashAddNewKey, TEMPLATE_ADD_NEW_KEY, sizeof(TEMPLATE_ADD_NEW_KEY)-1, &result); + EXPECT_THAT(err, PARSER_TEMPLATE_ERROR); + err = parseCompressedTxData(hashTokenTranfer3, TEMPLATE_TOKEN_TRANSFER, sizeof(TEMPLATE_TOKEN_TRANSFER)+1, &result); + EXPECT_THAT(err, PARSER_TEMPLATE_ERROR); +} + +TEST(tx_data, matchStoredCompressedTxData) { + parser_error_t err; + parsed_tx_template_t result; + + uint8_t hashWrong[32] = {0x59, 0x5c, 0x86, 0x56, 0x14, 0x41, 0xb3, 0x2b, 0x2b, 0x91, 0xee, 0x03, 0xf9, 0xe1, 0x0c, 0xa6, 0xef, 0xa7, 0xb4, 0x1b, 0xcc, 0x99, 0x4f, 0x51, 0x31, 0x7e, 0xc0, 0xaa, 0x9d, 0x8f, 0x8a, 0x41}; + err = matchStoredCompressedTxData(hashWrong, &result); + EXPECT_THAT(err, PARSER_UNEXPECTED_SCRIPT); + + err = matchStoredCompressedTxData(hashAddNewKey, &result); + EXPECT_THAT(err, PARSER_OK); + EXPECT_THAT(std::string(result.txName), "Add New Key"); + EXPECT_THAT(result.txNameLength, 11); + EXPECT_THAT(result.argCount, 1); + EXPECT_THAT(result.arguments[0].argumentType, ARGUMENT_TYPE_NORMAL); + EXPECT_THAT(std::string(result.arguments[0].displayKey), "Pub key"); + EXPECT_THAT(result.arguments[0].displayKeyLength, 7); + EXPECT_THAT(result.arguments[0].argumentIndex, 0); + EXPECT_THAT(std::string(result.arguments[0].jsonExpectedType), "String"); + EXPECT_THAT(result.arguments[0].jsonExpectedTypeLength, 6); + EXPECT_THAT(result.arguments[0].jsonExpectedKind, JSMN_STRING); + + err = matchStoredCompressedTxData(hashTokenTranfer3, &result); + EXPECT_THAT(err, PARSER_OK); + EXPECT_THAT(std::string(result.txName), "Token Transfer"); + EXPECT_THAT(result.txNameLength, 14); + EXPECT_THAT(result.argCount, 2); + EXPECT_THAT(result.arguments[0].argumentType, ARGUMENT_TYPE_NORMAL); + EXPECT_THAT(std::string(result.arguments[0].displayKey), "Amount"); + EXPECT_THAT(result.arguments[0].displayKeyLength, 6); + EXPECT_THAT(result.arguments[0].argumentIndex, 0); + EXPECT_THAT(std::string(result.arguments[0].jsonExpectedType), "UInt64"); + EXPECT_THAT(result.arguments[0].jsonExpectedTypeLength, 6); + EXPECT_THAT(result.arguments[0].jsonExpectedKind, JSMN_STRING); + EXPECT_THAT(result.arguments[1].argumentType, ARGUMENT_TYPE_NORMAL); + EXPECT_THAT(std::string(result.arguments[1].displayKey), "Destination"); + EXPECT_THAT(result.arguments[1].displayKeyLength, 11); + EXPECT_THAT(result.arguments[1].argumentIndex, 1); + EXPECT_THAT(std::string(result.arguments[1].jsonExpectedType), "Address"); + EXPECT_THAT(result.arguments[1].jsonExpectedTypeLength, 7); + EXPECT_THAT(result.arguments[1].jsonExpectedKind, JSMN_STRING); +} + From fa8e4d434b2c373ccaba61570e1b34b34188ac16 Mon Sep 17 00:00:00 2001 From: Robert Lukotka Date: Wed, 25 May 2022 18:31:18 +0200 Subject: [PATCH 02/12] Introduce PIC into template matching Also fixed some const ness issues to remove C++ warnings. Fixing typos and add missing comments. --- app/src/parser.c | 12 ++++++------ app/src/parser.h | 4 ++-- app/src/parser_impl.c | 18 +++--------------- app/src/parser_impl.h | 6 +++--- app/src/tx_data.c | 6 +++--- app/src/tx_data.h | 2 ++ tests/json.cpp | 6 ++---- tests/tx_data.cpp | 2 -- 8 files changed, 21 insertions(+), 35 deletions(-) diff --git a/app/src/parser.c b/app/src/parser.c index d1b1cfea..c272a7e3 100644 --- a/app/src/parser.c +++ b/app/src/parser.c @@ -163,7 +163,7 @@ parser_error_t parser_printChainID(const flow_payer_t *v, } parser_error_t parser_printArgument(const flow_argument_list_t *v, uint8_t argIndex, - char *expectedType, jsmntype_t jsonType, + const char *expectedType, jsmntype_t jsonType, char *outVal, uint16_t outValLen, uint8_t pageIdx, uint8_t *pageCount) { MEMZERO(outVal, outValLen); @@ -190,9 +190,9 @@ parser_error_t parser_printArgument(const flow_argument_list_t *v, uint8_t argIn } parser_error_t parser_printOptionalArgument(const flow_argument_list_t *v, uint8_t argIndex, - char *expectedType, jsmntype_t jsonType, - char *outVal, uint16_t outValLen, - uint8_t pageIdx, uint8_t *pageCount) { + const char *expectedType, jsmntype_t jsonType, + char *outVal, uint16_t outValLen, + uint8_t pageIdx, uint8_t *pageCount) { MEMZERO(outVal, outValLen); if (argIndex >= v->argCount) { @@ -221,7 +221,7 @@ parser_error_t parser_printOptionalArgument(const flow_argument_list_t *v, uint8 } parser_error_t parser_printArgumentArray(const flow_argument_list_t *v, uint8_t argIndex, uint8_t arrayIndex, - char *expectedType, jsmntype_t jsonType, + const char *expectedType, jsmntype_t jsonType, char *outVal, uint16_t outValLen, uint8_t pageIdx, uint8_t *pageCount) { MEMZERO(outVal, outValLen); @@ -255,7 +255,7 @@ parser_error_t parser_printArgumentArray(const flow_argument_list_t *v, uint8_t } parser_error_t parser_printArgumentOptionalArray(const flow_argument_list_t *v, uint8_t argIndex, uint8_t arrayIndex, - char *expectedType, jsmntype_t jsonType, + const char *expectedType, jsmntype_t jsonType, char *outVal, uint16_t outValLen, uint8_t pageIdx, uint8_t *pageCount) { MEMZERO(outVal, outValLen); diff --git a/app/src/parser.h b/app/src/parser.h index f2d15327..27354373 100644 --- a/app/src/parser.h +++ b/app/src/parser.h @@ -49,12 +49,12 @@ parser_error_t parser_getItem(const parser_context_t *ctx, ////for testing purposes parser_error_t parser_printOptionalArgument(const flow_argument_list_t *v, uint8_t argIndex, - char *expectedType, jsmntype_t jsonType, + const char *expectedType, jsmntype_t jsonType, char *outVal, uint16_t outValLen, uint8_t pageIdx, uint8_t *pageCount); parser_error_t parser_printArgumentOptionalArray(const flow_argument_list_t *v, uint8_t argIndex, uint8_t arrayIndex, - char *expectedType, jsmntype_t jsonType, + const char *expectedType, jsmntype_t jsonType, char *outVal, uint16_t outValLen, uint8_t pageIdx, uint8_t *pageCount); diff --git a/app/src/parser_impl.c b/app/src/parser_impl.c index f8af4dfe..94028ff0 100644 --- a/app/src/parser_impl.c +++ b/app/src/parser_impl.c @@ -159,7 +159,7 @@ parser_error_t json_extractToken(char *outVal, uint16_t outValLen, parsed_json_t return PARSER_OK; } -parser_error_t json_matchToken(parsed_json_t *parsedJson, uint16_t tokenIdx, char *expectedValue) { +parser_error_t json_matchToken(parsed_json_t *parsedJson, uint16_t tokenIdx, const char *expectedValue) { CHECK_PARSER_ERR(json_validateToken(parsedJson, tokenIdx)) const jsmntok_t token = parsedJson->tokens[tokenIdx]; @@ -198,7 +198,7 @@ parser_error_t json_matchNull(parsed_json_t *parsedJson, uint16_t tokenIdx) { } parser_error_t json_matchKeyValue(parsed_json_t *parsedJson, - uint16_t tokenIdx, char *expectedType, jsmntype_t jsonType, uint16_t *valueTokenIdx) { + uint16_t tokenIdx, const char *expectedType, jsmntype_t jsonType, uint16_t *valueTokenIdx) { CHECK_PARSER_ERR(json_validateToken(parsedJson, tokenIdx)) if (! (tokenIdx + 4 < parsedJson->numberOfTokens)) { @@ -229,7 +229,7 @@ parser_error_t json_matchKeyValue(parsed_json_t *parsedJson, //valueTokenIdx is JSON_MATCH_VALUE_IDX_NONE if the optional is null parser_error_t json_matchOptionalKeyValue(parsed_json_t *parsedJson, - uint16_t tokenIdx, char *expectedType, jsmntype_t jsonType, uint16_t *valueTokenIdx) { + uint16_t tokenIdx, const char *expectedType, jsmntype_t jsonType, uint16_t *valueTokenIdx) { CHECK_PARSER_ERR(json_validateToken(parsedJson, tokenIdx)) if (!(tokenIdx + 4 < parsedJson->numberOfTokens)) { @@ -327,18 +327,6 @@ parser_error_t formatStrUInt8AsHex(const char *decStr, char *hexStr) { return PARSER_OK; } -parser_error_t json_extractString(char *outVal, uint16_t outValLen, parsed_json_t *parsedJson, uint16_t tokenIdx) { - MEMZERO(outVal, outValLen); - - uint16_t internalTokenElemIdx; - CHECK_PARSER_ERR(json_matchKeyValue( - parsedJson, tokenIdx, (char *) "String", JSMN_STRING, &internalTokenElemIdx)) - - CHECK_PARSER_ERR(json_extractToken(outVal, outValLen, parsedJson, internalTokenElemIdx)) - - return PARSER_OK; -} - parser_error_t _matchScriptType(uint8_t scriptHash[32], script_type_e *scriptType) { *scriptType = SCRIPT_UNKNOWN; diff --git a/app/src/parser_impl.h b/app/src/parser_impl.h index 89a8b3da..ee1829a2 100644 --- a/app/src/parser_impl.h +++ b/app/src/parser_impl.h @@ -51,16 +51,16 @@ parser_error_t json_validateToken(parsed_json_t *parsedJson, uint16_t tokenIdx); parser_error_t json_extractToken(char *outVal, uint16_t outValLen, parsed_json_t *parsedJson, uint16_t tokenIdx); -parser_error_t json_matchToken(parsed_json_t *parsedJson, uint16_t tokenIdx, char *expectedValue); +parser_error_t json_matchToken(parsed_json_t *parsedJson, uint16_t tokenIdx, const char *expectedValue); parser_error_t json_matchNull(parsed_json_t *parsedJson, uint16_t tokenIdx); parser_error_t json_matchKeyValue(parsed_json_t *parsedJson, - uint16_t tokenIdx, char *expectedType, jsmntype_t jsonType, uint16_t *valueTokenIdx); + uint16_t tokenIdx, const char *expectedType, jsmntype_t jsonType, uint16_t *valueTokenIdx); #define JSON_MATCH_VALUE_IDX_NONE 65535 parser_error_t json_matchOptionalKeyValue(parsed_json_t *parsedJson, - uint16_t tokenIdx, char *expectedType, jsmntype_t jsonType, uint16_t *valueTokenIdx); + uint16_t tokenIdx, const char *expectedType, jsmntype_t jsonType, uint16_t *valueTokenIdx); parser_error_t json_matchOptionalArray(parsed_json_t *parsedJson, uint16_t tokenIdx, uint16_t *valueTokenIdx); diff --git a/app/src/tx_data.c b/app/src/tx_data.c index c8a9d45a..1d7e933e 100644 --- a/app/src/tx_data.c +++ b/app/src/tx_data.c @@ -149,7 +149,7 @@ parser_error_t parseCompressedTxData(uint8_t scriptHash[SCRIPT_HASH_SIZE], const if (parsedTxTempate->argCount > PARSER_MAX_ARGCOUNT) { return PARSER_TEMPLATE_TOO_MANY_ARGUMENTS; } - STATIC_ASSERT(sizeof(parsedTxTempate->arguments) >= PARSER_MAX_ARGCOUNT, "Too few argumentst in parsed_tx_template_t."); + STATIC_ASSERT(sizeof(parsedTxTempate->arguments) >= PARSER_MAX_ARGCOUNT, "Too few arguments in parsed_tx_template_t."); for(int i=0; iargCount; i++) { READ_CHAR(&parsedTxTempate->arguments[i].argumentType); READ_STRING(&parsedTxTempate->arguments[i].displayKey, &parsedTxTempate->arguments[i].displayKeyLength) @@ -173,10 +173,10 @@ parser_error_t parseCompressedTxData(uint8_t scriptHash[SCRIPT_HASH_SIZE], const parser_error_t matchStoredCompressedTxData(uint8_t scriptHash[SCRIPT_HASH_SIZE], parsed_tx_template_t *parsedTxTempate) { size_t i=0; while(KNOWN_TEMPLATES[i].template != NULL) { - parser_error_t err = _validateHash(scriptHash, KNOWN_TEMPLATES[i].template, KNOWN_TEMPLATES[i].templateLength); + parser_error_t err = _validateHash(scriptHash, PIC(KNOWN_TEMPLATES[i].template), KNOWN_TEMPLATES[i].templateLength); switch (err) { case PARSER_OK: - return parseCompressedTxData(scriptHash, KNOWN_TEMPLATES[i].template, KNOWN_TEMPLATES[i].templateLength, parsedTxTempate); + return parseCompressedTxData(scriptHash, PIC(KNOWN_TEMPLATES[i].template), KNOWN_TEMPLATES[i].templateLength, parsedTxTempate); case PARSER_UNEXPECTED_SCRIPT: break; //break switch default: diff --git a/app/src/tx_data.h b/app/src/tx_data.h index a04e368b..85abb32e 100644 --- a/app/src/tx_data.h +++ b/app/src/tx_data.h @@ -35,6 +35,7 @@ typedef enum { #define MAX_TEMPLATE_NUMBER_OF_HASHES 10 #define MAX_TEMPLATE_STRING_LENGTH 100 +//It is planed that all these strings may be on flash, thus they are volatile (for NanoX and NanoSPlus) typedef struct { parsed_tx_template_argument_type_e argumentType; const NV_VOLATILE char *displayKey; @@ -56,6 +57,7 @@ typedef struct { #define SCRIPT_HASH_SIZE 32 +//It is planed that compressedData may be on flash, thus they are volatile (for NanoX and NanoSPlus) parser_error_t parseCompressedTxData(uint8_t scriptHash[SCRIPT_HASH_SIZE], const NV_VOLATILE uint8_t *compressedData, uint16_t compressedDataLen, parsed_tx_template_t *parsedTxTempate); diff --git a/tests/json.cpp b/tests/json.cpp index 1b08ae22..361a8fef 100644 --- a/tests/json.cpp +++ b/tests/json.cpp @@ -212,8 +212,7 @@ TEST(JSON, OptionalArrayNull) { parsed_json_t parsedJson = {false}; auto err = json_parse(&parsedJson, sendToken2, strlen(sendToken2)); - - // We could parse valid JSON + EXPECT_THAT(err, PARSER_OK); uint16_t internalTokenElementIdx; ASSERT_THAT( @@ -226,8 +225,7 @@ TEST(JSON, OptionalArrayNotNull) { parsed_json_t parsedJson = {false}; auto err = json_parse(&parsedJson, sendToken4, strlen(sendToken4)); - - // We could parse valid JSON + EXPECT_THAT(err, PARSER_OK); uint16_t internalTokenElementIdx; ASSERT_THAT( diff --git a/tests/tx_data.cpp b/tests/tx_data.cpp index ee0f653c..376c4c08 100644 --- a/tests/tx_data.cpp +++ b/tests/tx_data.cpp @@ -95,8 +95,6 @@ TEST(tx_data, validateHash) { EXPECT_THAT(err, PARSER_OK); } -const uint8_t A[] = { 0, 1 }; - TEST(tx_data, parseCompressedTxData) { parser_error_t err; From 607263f89eb1ed8a83213a1a66064edb086a80c0 Mon Sep 17 00:00:00 2001 From: Robert Lukotka Date: Thu, 26 May 2022 09:41:16 +0200 Subject: [PATCH 03/12] Improve naming: tx metadata --- CMakeLists.txt | 2 +- app/src/{tx_data.c => tx_metadata.c} | 80 +++++++++++++------------- app/src/{tx_data.h => tx_metadata.h} | 18 +++--- tests/{tx_data.cpp => tx_metadata.cpp} | 44 +++++++------- 4 files changed, 72 insertions(+), 72 deletions(-) rename app/src/{tx_data.c => tx_metadata.c} (63%) rename app/src/{tx_data.h => tx_metadata.h} (75%) rename tests/{tx_data.cpp => tx_metadata.cpp} (82%) diff --git a/CMakeLists.txt b/CMakeLists.txt index ed323856..2d088483 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,7 +96,7 @@ file(GLOB_RECURSE LIB_SRC ${CMAKE_CURRENT_SOURCE_DIR}/app/src/hdpath.c ${CMAKE_CURRENT_SOURCE_DIR}/app/src/parser_impl.c ${CMAKE_CURRENT_SOURCE_DIR}/app/src/json/json_parser.c - ${CMAKE_CURRENT_SOURCE_DIR}/app/src/tx_data.c + ${CMAKE_CURRENT_SOURCE_DIR}/app/src/tx_metadata.c app/src/base32.c app/src/crypto.c ) diff --git a/app/src/tx_data.c b/app/src/tx_metadata.c similarity index 63% rename from app/src/tx_data.c rename to app/src/tx_metadata.c index 1d7e933e..206447bf 100644 --- a/app/src/tx_data.c +++ b/app/src/tx_metadata.c @@ -1,9 +1,9 @@ -#include "tx_data.h" +#include "tx_metadata.h" #include "zxmacros.h" -//Known compressed templates +//Known tx metadata -const uint8_t COMPRESSED_TX_TEMPLATE_CREATE_ACCOUNT[] = { +const uint8_t TX_METADATA_CREATE_ACCOUNT[] = { 1, //number of hashes + hashes 0xee, 0xf2, 0xd0, 0x49, 0x44, 0x48, 0x55, 0x41, 0x77, 0x61, 0x2e, 0x63, 0x02, 0x62, 0x56, 0x25, 0x83, 0x39, 0x23, 0x0c, 0xbc, 0x69, 0x31, 0xde, 0xd7, 0x8d, 0x61, 0x49, 0x44, 0x3c, 0x61, 0x73, 'C', 'r', 'e', 'a', 't', 'e', ' ', 'A', 'c', 'c', 'o', 'u', 'n', 't', 0, //tx name (to display) @@ -17,7 +17,7 @@ const uint8_t COMPRESSED_TX_TEMPLATE_CREATE_ACCOUNT[] = { JSMN_STRING, //expected value json token type }; -const uint8_t COMPRESSED_TX_TEMPLATE_ADD_NEW_KEY[] = { +const uint8_t TX_METADATA_ADD_NEW_KEY[] = { 1, //number of hashes + hashes 0x59, 0x5c, 0x86, 0x56, 0x14, 0x41, 0xb3, 0x2b, 0x2b, 0x91, 0xee, 0x03, 0xf9, 0xe1, 0x0c, 0xa6, 0xef, 0xa7, 0xb4, 0x1b, 0xcc, 0x99, 0x4f, 0x51, 0x31, 0x7e, 0xc0, 0xaa, 0x9d, 0x8f, 0x8a, 0x42, 'A', 'd', 'd', ' ', 'N', 'e', 'w', ' ', 'K', 'e', 'y', 0, //tx name (to display) @@ -31,7 +31,7 @@ const uint8_t COMPRESSED_TX_TEMPLATE_ADD_NEW_KEY[] = { JSMN_STRING, //expected value json token type }; -const uint8_t COMPRESSED_TX_TEMPLATE_TOKEN_TRANSFER[] = { +const uint8_t TX_METADATA_TOKEN_TRANSFER[] = { 3, //number of hashes + hashes 0xca, 0x80, 0xb6, 0x28, 0xd9, 0x85, 0xb3, 0x58, 0xae, 0x1c, 0xb1, 0x36, 0xbc, 0xd9, 0x76, 0x99, 0x7c, 0x94, 0x2f, 0xa1, 0x0d, 0xba, 0xbf, 0xea, 0xfb, 0x4e, 0x20, 0xfa, 0x66, 0xa5, 0xa5, 0xe2, 0xd5, 0x6f, 0x4e, 0x1d, 0x23, 0x55, 0xcd, 0xcf, 0xac, 0xfd, 0x01, 0xe4, 0x71, 0x45, 0x9c, 0x6e, 0xf1, 0x68, 0xbf, 0xdf, 0x84, 0x37, 0x1a, 0x68, 0x5c, 0xcf, 0x31, 0xcf, 0x3c, 0xde, 0xdc, 0x2d, @@ -55,33 +55,33 @@ const uint8_t COMPRESSED_TX_TEMPLATE_TOKEN_TRANSFER[] = { }; -//List of known compressed templates +//List of known compressed metadata typedef struct { - const uint8_t* template; - uint16_t templateLength; -} known_template_entry_t; - -const known_template_entry_t KNOWN_TEMPLATES[] = { - {COMPRESSED_TX_TEMPLATE_CREATE_ACCOUNT, sizeof(COMPRESSED_TX_TEMPLATE_CREATE_ACCOUNT)}, - {COMPRESSED_TX_TEMPLATE_ADD_NEW_KEY, sizeof(COMPRESSED_TX_TEMPLATE_ADD_NEW_KEY)}, - {COMPRESSED_TX_TEMPLATE_TOKEN_TRANSFER, sizeof(COMPRESSED_TX_TEMPLATE_TOKEN_TRANSFER)}, + const uint8_t* metadata; + uint16_t metadataLength; +} known_tx_metadata_entry_t; + +const known_tx_metadata_entry_t KNOWN_TX_METADATA_[] = { + {TX_METADATA_CREATE_ACCOUNT, sizeof(TX_METADATA_CREATE_ACCOUNT)}, + {TX_METADATA_ADD_NEW_KEY, sizeof(TX_METADATA_ADD_NEW_KEY)}, + {TX_METADATA_TOKEN_TRANSFER, sizeof(TX_METADATA_TOKEN_TRANSFER)}, // sentinel, do not remove {NULL, 0} }; -parser_error_t _validateHash(uint8_t scriptHash[SCRIPT_HASH_SIZE], const NV_VOLATILE uint8_t *compressedData, uint16_t compressedDataLen) { - if (compressedDataLen < 1) { +parser_error_t _validateHash(uint8_t scriptHash[SCRIPT_HASH_SIZE], const NV_VOLATILE uint8_t *txMetadata, uint16_t txMetadataLength) { + if (txMetadataLength < 1) { return PARSER_TEMPLATE_ERROR; } - uint8_t numberOfHashes = compressedData[0]; - if (numberOfHashes > MAX_TEMPLATE_NUMBER_OF_HASHES || compressedDataLen < 1+SCRIPT_HASH_SIZE*numberOfHashes) { + uint8_t numberOfHashes = txMetadata[0]; + if (numberOfHashes > MAX_TEMPLATE_NUMBER_OF_HASHES || txMetadataLength < 1+SCRIPT_HASH_SIZE*numberOfHashes) { return PARSER_TEMPLATE_ERROR; } for(size_t i=0; i MAX_TEMPLATE_NUMBER_OF_HASHES) { return PARSER_TEMPLATE_TOO_MANY_HASHES; } - parser_error_t err = _validateHash(scriptHash, compressedData, compressedDataLen); + parser_error_t err = _validateHash(scriptHash, txMetadata, txMetadataLength); if (err != PARSER_OK) { return err; } @@ -141,21 +141,21 @@ parser_error_t parseCompressedTxData(uint8_t scriptHash[SCRIPT_HASH_SIZE], const } //read tx name - READ_STRING(&parsedTxTempate->txName, &parsedTxTempate->txNameLength) + READ_STRING(&parsedTxMetadata->txName, &parsedTxMetadata->txNameLength) //read Arguments { - READ_CHAR(&parsedTxTempate->argCount) - if (parsedTxTempate->argCount > PARSER_MAX_ARGCOUNT) { + READ_CHAR(&parsedTxMetadata->argCount) + if (parsedTxMetadata->argCount > PARSER_MAX_ARGCOUNT) { return PARSER_TEMPLATE_TOO_MANY_ARGUMENTS; } - STATIC_ASSERT(sizeof(parsedTxTempate->arguments) >= PARSER_MAX_ARGCOUNT, "Too few arguments in parsed_tx_template_t."); - for(int i=0; iargCount; i++) { - READ_CHAR(&parsedTxTempate->arguments[i].argumentType); - READ_STRING(&parsedTxTempate->arguments[i].displayKey, &parsedTxTempate->arguments[i].displayKeyLength) - READ_CHAR(&parsedTxTempate->arguments[i].argumentIndex); - READ_STRING(&parsedTxTempate->arguments[i].jsonExpectedType, &parsedTxTempate->arguments[i].jsonExpectedTypeLength) - READ_CHAR(&parsedTxTempate->arguments[i].jsonExpectedKind); + STATIC_ASSERT(sizeof(parsedTxMetadata->arguments) >= PARSER_MAX_ARGCOUNT, "Too few arguments in parsed_tx_metadata_t."); + for(int i=0; iargCount; i++) { + READ_CHAR(&parsedTxMetadata->arguments[i].argumentType); + READ_STRING(&parsedTxMetadata->arguments[i].displayKey, &parsedTxMetadata->arguments[i].displayKeyLength) + READ_CHAR(&parsedTxMetadata->arguments[i].argumentIndex); + READ_STRING(&parsedTxMetadata->arguments[i].jsonExpectedType, &parsedTxMetadata->arguments[i].jsonExpectedTypeLength) + READ_CHAR(&parsedTxMetadata->arguments[i].jsonExpectedKind); } } @@ -163,20 +163,20 @@ parser_error_t parseCompressedTxData(uint8_t scriptHash[SCRIPT_HASH_SIZE], const #undef READ_CHAR #undef READ_STRING - if (parsed != compressedDataLen) { + if (parsed != txMetadataLength) { return PARSER_TEMPLATE_ERROR; } return PARSER_OK; } -parser_error_t matchStoredCompressedTxData(uint8_t scriptHash[SCRIPT_HASH_SIZE], parsed_tx_template_t *parsedTxTempate) { +parser_error_t matchStoredTxMetadata(uint8_t scriptHash[SCRIPT_HASH_SIZE], parsed_tx_metadata_t *parsedTxTempate) { size_t i=0; - while(KNOWN_TEMPLATES[i].template != NULL) { - parser_error_t err = _validateHash(scriptHash, PIC(KNOWN_TEMPLATES[i].template), KNOWN_TEMPLATES[i].templateLength); + while(KNOWN_TX_METADATA_[i].metadata != NULL) { + parser_error_t err = _validateHash(scriptHash, PIC(KNOWN_TX_METADATA_[i].metadata), KNOWN_TX_METADATA_[i].metadataLength); switch (err) { case PARSER_OK: - return parseCompressedTxData(scriptHash, PIC(KNOWN_TEMPLATES[i].template), KNOWN_TEMPLATES[i].templateLength, parsedTxTempate); + return parseTxMetadata(scriptHash, PIC(KNOWN_TX_METADATA_[i].metadata), KNOWN_TX_METADATA_[i].metadataLength, parsedTxTempate); case PARSER_UNEXPECTED_SCRIPT: break; //break switch default: diff --git a/app/src/tx_data.h b/app/src/tx_metadata.h similarity index 75% rename from app/src/tx_data.h rename to app/src/tx_metadata.h index 85abb32e..947dfb64 100644 --- a/app/src/tx_data.h +++ b/app/src/tx_metadata.h @@ -30,42 +30,42 @@ typedef enum { ARGUMENT_TYPE_OPTIONAL = 2, ARGUMENT_TYPE_ARRAY = 3, ARGUMENT_TYPE_OPTIONALARRAY = 4 -} parsed_tx_template_argument_type_e; +} argument_type_e; #define MAX_TEMPLATE_NUMBER_OF_HASHES 10 #define MAX_TEMPLATE_STRING_LENGTH 100 //It is planed that all these strings may be on flash, thus they are volatile (for NanoX and NanoSPlus) typedef struct { - parsed_tx_template_argument_type_e argumentType; + argument_type_e argumentType; const NV_VOLATILE char *displayKey; uint8_t displayKeyLength; uint8_t argumentIndex; //argument index within transaction const NV_VOLATILE char *jsonExpectedType; //pointer to null terminated string uint8_t jsonExpectedTypeLength; jsmntype_t jsonExpectedKind; -} parsed_tx_template_argument_t; +} parsed_tx_metadata_argument_t; typedef struct { script_type_e script; const NV_VOLATILE char *txName; uint8_t txNameLength; uint8_t argCount; - parsed_tx_template_argument_t arguments[PARSER_MAX_ARGCOUNT]; //order of arguments in which they should be displayed -} parsed_tx_template_t; + parsed_tx_metadata_argument_t arguments[PARSER_MAX_ARGCOUNT]; //order of arguments in which they should be displayed +} parsed_tx_metadata_t; #define SCRIPT_HASH_SIZE 32 //It is planed that compressedData may be on flash, thus they are volatile (for NanoX and NanoSPlus) -parser_error_t parseCompressedTxData(uint8_t scriptHash[SCRIPT_HASH_SIZE], const NV_VOLATILE uint8_t *compressedData, uint16_t compressedDataLen, - parsed_tx_template_t *parsedTxTempate); +parser_error_t parseTxMetadata(uint8_t scriptHash[SCRIPT_HASH_SIZE], const NV_VOLATILE uint8_t *txMetadata, uint16_t txMetadataLength, + parsed_tx_metadata_t *parsedTxMetadata); -parser_error_t matchStoredCompressedTxData(uint8_t scriptHash[SCRIPT_HASH_SIZE], parsed_tx_template_t *parsedTxTempate); +parser_error_t matchStoredTxMetadata(uint8_t scriptHash[SCRIPT_HASH_SIZE], parsed_tx_metadata_t *parsedTxMetadata); #ifdef __cplusplus //For C++ unit tests -parser_error_t _validateHash(uint8_t scriptHash[SCRIPT_HASH_SIZE], const NV_VOLATILE uint8_t *compressedData, uint16_t compressedDataLen); +parser_error_t _validateHash(uint8_t scriptHash[SCRIPT_HASH_SIZE], const NV_VOLATILE uint8_t *txMetadata, uint16_t txMetadataLength); } #endif diff --git a/tests/tx_data.cpp b/tests/tx_metadata.cpp similarity index 82% rename from tests/tx_data.cpp rename to tests/tx_metadata.cpp index 376c4c08..dc321c11 100644 --- a/tests/tx_data.cpp +++ b/tests/tx_metadata.cpp @@ -19,10 +19,10 @@ #include #include #include -#include +#include #include -const uint8_t TEMPLATE_ADD_NEW_KEY[] = { +const uint8_t TX_METADATA_ADD_NEW_KEY[] = { 1, //number of hashes + hashes 0x59, 0x5c, 0x86, 0x56, 0x14, 0x41, 0xb3, 0x2b, 0x2b, 0x91, 0xee, 0x03, 0xf9, 0xe1, 0x0c, 0xa6, 0xef, 0xa7, 0xb4, 0x1b, 0xcc, 0x99, 0x4f, 0x51, 0x31, 0x7e, 0xc0, 0xaa, 0x9d, 0x8f, 0x8a, 0x42, 'A', 'd', 'd', ' ', 'N', 'e', 'w', ' ', 'K', 'e', 'y', 0, //tx name (to display) @@ -36,7 +36,7 @@ const uint8_t TEMPLATE_ADD_NEW_KEY[] = { JSMN_STRING //expected value json token type }; -const uint8_t TEMPLATE_TOKEN_TRANSFER[] = { +const uint8_t TX_METADATA_TOKEN_TRANSFER[] = { 3, //number of hashes + hashes 0xca, 0x80, 0xb6, 0x28, 0xd9, 0x85, 0xb3, 0x58, 0xae, 0x1c, 0xb1, 0x36, 0xbc, 0xd9, 0x76, 0x99, 0x7c, 0x94, 0x2f, 0xa1, 0x0d, 0xba, 0xbf, 0xea, 0xfb, 0x4e, 0x20, 0xfa, 0x66, 0xa5, 0xa5, 0xe2, 0xd5, 0x6f, 0x4e, 0x1d, 0x23, 0x55, 0xcd, 0xcf, 0xac, 0xfd, 0x01, 0xe4, 0x71, 0x45, 0x9c, 0x6e, 0xf1, 0x68, 0xbf, 0xdf, 0x84, 0x37, 0x1a, 0x68, 0x5c, 0xcf, 0x31, 0xcf, 0x3c, 0xde, 0xdc, 0x2d, @@ -67,42 +67,42 @@ uint8_t hashTokenTranfer3[32] = {0x47, 0x85, 0x15, 0x86, 0xd9, 0x62, 0x33, 0x5e, TEST(tx_data, validateHash) { parser_error_t err; - err = _validateHash(hashAddNewKey, TEMPLATE_ADD_NEW_KEY, sizeof(TEMPLATE_ADD_NEW_KEY)); + err = _validateHash(hashAddNewKey, TX_METADATA_ADD_NEW_KEY, sizeof(TX_METADATA_ADD_NEW_KEY)); EXPECT_THAT(err, PARSER_OK); - err = _validateHash(hashTokenTranfer1, TEMPLATE_ADD_NEW_KEY, sizeof(TEMPLATE_ADD_NEW_KEY)); + err = _validateHash(hashTokenTranfer1, TX_METADATA_ADD_NEW_KEY, sizeof(TX_METADATA_ADD_NEW_KEY)); EXPECT_THAT(err, PARSER_UNEXPECTED_SCRIPT); - err = _validateHash(hashTokenTranfer1, TEMPLATE_TOKEN_TRANSFER, sizeof(TEMPLATE_TOKEN_TRANSFER)); + err = _validateHash(hashTokenTranfer1, TX_METADATA_TOKEN_TRANSFER, sizeof(TX_METADATA_TOKEN_TRANSFER)); EXPECT_THAT(err, PARSER_OK); - err = _validateHash(hashTokenTranfer2, TEMPLATE_TOKEN_TRANSFER, sizeof(TEMPLATE_TOKEN_TRANSFER)); + err = _validateHash(hashTokenTranfer2, TX_METADATA_TOKEN_TRANSFER, sizeof(TX_METADATA_TOKEN_TRANSFER)); EXPECT_THAT(err, PARSER_OK); - err = _validateHash(hashTokenTranfer3, TEMPLATE_TOKEN_TRANSFER, sizeof(TEMPLATE_TOKEN_TRANSFER)); + err = _validateHash(hashTokenTranfer3, TX_METADATA_TOKEN_TRANSFER, sizeof(TX_METADATA_TOKEN_TRANSFER)); EXPECT_THAT(err, PARSER_OK); - err = _validateHash(hashAddNewKey, TEMPLATE_TOKEN_TRANSFER, sizeof(TEMPLATE_TOKEN_TRANSFER)); + err = _validateHash(hashAddNewKey, TX_METADATA_TOKEN_TRANSFER, sizeof(TX_METADATA_TOKEN_TRANSFER)); EXPECT_THAT(err, PARSER_UNEXPECTED_SCRIPT); - err = _validateHash(hashTokenTranfer3, TEMPLATE_ADD_NEW_KEY, 0); + err = _validateHash(hashTokenTranfer3, TX_METADATA_ADD_NEW_KEY, 0); EXPECT_THAT(err, PARSER_TEMPLATE_ERROR); - err = _validateHash(hashTokenTranfer3, TEMPLATE_TOKEN_TRANSFER, 3*32); + err = _validateHash(hashTokenTranfer3, TX_METADATA_TOKEN_TRANSFER, 3*32); EXPECT_THAT(err, PARSER_TEMPLATE_ERROR); - err = _validateHash(hashTokenTranfer3, TEMPLATE_TOKEN_TRANSFER, 3*32+1); + err = _validateHash(hashTokenTranfer3, TX_METADATA_TOKEN_TRANSFER, 3*32+1); EXPECT_THAT(err, PARSER_OK); } TEST(tx_data, parseCompressedTxData) { parser_error_t err; - parsed_tx_template_t result; - err = parseCompressedTxData(hashTokenTranfer1, TEMPLATE_ADD_NEW_KEY, sizeof(TEMPLATE_ADD_NEW_KEY), &result); + parsed_tx_metadata_t result; + err = parseTxMetadata(hashTokenTranfer1, TX_METADATA_ADD_NEW_KEY, sizeof(TX_METADATA_ADD_NEW_KEY), &result); EXPECT_THAT(err, PARSER_UNEXPECTED_SCRIPT); - err = parseCompressedTxData(hashAddNewKey, TEMPLATE_ADD_NEW_KEY, sizeof(TEMPLATE_ADD_NEW_KEY), &result); + err = parseTxMetadata(hashAddNewKey, TX_METADATA_ADD_NEW_KEY, sizeof(TX_METADATA_ADD_NEW_KEY), &result); EXPECT_THAT(err, PARSER_OK); EXPECT_THAT(std::string(result.txName), "Add New Key"); EXPECT_THAT(result.txNameLength, 11); @@ -115,7 +115,7 @@ TEST(tx_data, parseCompressedTxData) { EXPECT_THAT(result.arguments[0].jsonExpectedTypeLength, 6); EXPECT_THAT(result.arguments[0].jsonExpectedKind, JSMN_STRING); - err = parseCompressedTxData(hashTokenTranfer3, TEMPLATE_TOKEN_TRANSFER, sizeof(TEMPLATE_TOKEN_TRANSFER), &result); + err = parseTxMetadata(hashTokenTranfer3, TX_METADATA_TOKEN_TRANSFER, sizeof(TX_METADATA_TOKEN_TRANSFER), &result); EXPECT_THAT(err, PARSER_OK); EXPECT_THAT(std::string(result.txName), "Token Transfer"); EXPECT_THAT(result.txNameLength, 14); @@ -135,21 +135,21 @@ TEST(tx_data, parseCompressedTxData) { EXPECT_THAT(result.arguments[1].jsonExpectedTypeLength, 7); EXPECT_THAT(result.arguments[1].jsonExpectedKind, JSMN_STRING); - err = parseCompressedTxData(hashAddNewKey, TEMPLATE_ADD_NEW_KEY, sizeof(TEMPLATE_ADD_NEW_KEY)-1, &result); + err = parseTxMetadata(hashAddNewKey, TX_METADATA_ADD_NEW_KEY, sizeof(TX_METADATA_ADD_NEW_KEY)-1, &result); EXPECT_THAT(err, PARSER_TEMPLATE_ERROR); - err = parseCompressedTxData(hashTokenTranfer3, TEMPLATE_TOKEN_TRANSFER, sizeof(TEMPLATE_TOKEN_TRANSFER)+1, &result); + err = parseTxMetadata(hashTokenTranfer3, TX_METADATA_TOKEN_TRANSFER, sizeof(TX_METADATA_TOKEN_TRANSFER)+1, &result); EXPECT_THAT(err, PARSER_TEMPLATE_ERROR); } TEST(tx_data, matchStoredCompressedTxData) { parser_error_t err; - parsed_tx_template_t result; + parsed_tx_metadata_t result; uint8_t hashWrong[32] = {0x59, 0x5c, 0x86, 0x56, 0x14, 0x41, 0xb3, 0x2b, 0x2b, 0x91, 0xee, 0x03, 0xf9, 0xe1, 0x0c, 0xa6, 0xef, 0xa7, 0xb4, 0x1b, 0xcc, 0x99, 0x4f, 0x51, 0x31, 0x7e, 0xc0, 0xaa, 0x9d, 0x8f, 0x8a, 0x41}; - err = matchStoredCompressedTxData(hashWrong, &result); + err = matchStoredTxMetadata(hashWrong, &result); EXPECT_THAT(err, PARSER_UNEXPECTED_SCRIPT); - err = matchStoredCompressedTxData(hashAddNewKey, &result); + err = matchStoredTxMetadata(hashAddNewKey, &result); EXPECT_THAT(err, PARSER_OK); EXPECT_THAT(std::string(result.txName), "Add New Key"); EXPECT_THAT(result.txNameLength, 11); @@ -162,7 +162,7 @@ TEST(tx_data, matchStoredCompressedTxData) { EXPECT_THAT(result.arguments[0].jsonExpectedTypeLength, 6); EXPECT_THAT(result.arguments[0].jsonExpectedKind, JSMN_STRING); - err = matchStoredCompressedTxData(hashTokenTranfer3, &result); + err = matchStoredTxMetadata(hashTokenTranfer3, &result); EXPECT_THAT(err, PARSER_OK); EXPECT_THAT(std::string(result.txName), "Token Transfer"); EXPECT_THAT(result.txNameLength, 14); From e6f759b1924148d859a81676537c147f42495646 Mon Sep 17 00:00:00 2001 From: Robert Lukotka Date: Tue, 7 Jun 2022 12:40:56 +0200 Subject: [PATCH 04/12] Fix various minor review findings --- app/src/tx_metadata.c | 21 +++++++++++---------- app/src/tx_metadata.h | 2 +- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/app/src/tx_metadata.c b/app/src/tx_metadata.c index 206447bf..867bf318 100644 --- a/app/src/tx_metadata.c +++ b/app/src/tx_metadata.c @@ -61,7 +61,7 @@ typedef struct { uint16_t metadataLength; } known_tx_metadata_entry_t; -const known_tx_metadata_entry_t KNOWN_TX_METADATA_[] = { +const known_tx_metadata_entry_t KNOWN_TX_METADATA[] = { {TX_METADATA_CREATE_ACCOUNT, sizeof(TX_METADATA_CREATE_ACCOUNT)}, {TX_METADATA_ADD_NEW_KEY, sizeof(TX_METADATA_ADD_NEW_KEY)}, {TX_METADATA_TOKEN_TRANSFER, sizeof(TX_METADATA_TOKEN_TRANSFER)}, @@ -81,7 +81,7 @@ parser_error_t _validateHash(uint8_t scriptHash[SCRIPT_HASH_SIZE], const NV_VOLA for(size_t i=0; i MAX_TEMPLATE_NUMBER_OF_HASHES) { return PARSER_TEMPLATE_TOO_MANY_HASHES; } @@ -137,7 +137,7 @@ parser_error_t parseTxMetadata(uint8_t scriptHash[SCRIPT_HASH_SIZE], const NV_VO if (err != PARSER_OK) { return err; } - READ_SKIP(numberOfHashes*SCRIPT_HASH_SIZE) + READ_SKIP(numberOfHashes*SCRIPT_HASH_SIZE); } //read tx name @@ -152,9 +152,9 @@ parser_error_t parseTxMetadata(uint8_t scriptHash[SCRIPT_HASH_SIZE], const NV_VO STATIC_ASSERT(sizeof(parsedTxMetadata->arguments) >= PARSER_MAX_ARGCOUNT, "Too few arguments in parsed_tx_metadata_t."); for(int i=0; iargCount; i++) { READ_CHAR(&parsedTxMetadata->arguments[i].argumentType); - READ_STRING(&parsedTxMetadata->arguments[i].displayKey, &parsedTxMetadata->arguments[i].displayKeyLength) + READ_STRING(&parsedTxMetadata->arguments[i].displayKey, &parsedTxMetadata->arguments[i].displayKeyLength); READ_CHAR(&parsedTxMetadata->arguments[i].argumentIndex); - READ_STRING(&parsedTxMetadata->arguments[i].jsonExpectedType, &parsedTxMetadata->arguments[i].jsonExpectedTypeLength) + READ_STRING(&parsedTxMetadata->arguments[i].jsonExpectedType, &parsedTxMetadata->arguments[i].jsonExpectedTypeLength); READ_CHAR(&parsedTxMetadata->arguments[i].jsonExpectedKind); } } @@ -162,6 +162,7 @@ parser_error_t parseTxMetadata(uint8_t scriptHash[SCRIPT_HASH_SIZE], const NV_VO #undef READ_CHAR #undef READ_STRING + #undef READ_SKIP if (parsed != txMetadataLength) { return PARSER_TEMPLATE_ERROR; @@ -172,11 +173,11 @@ parser_error_t parseTxMetadata(uint8_t scriptHash[SCRIPT_HASH_SIZE], const NV_VO parser_error_t matchStoredTxMetadata(uint8_t scriptHash[SCRIPT_HASH_SIZE], parsed_tx_metadata_t *parsedTxTempate) { size_t i=0; - while(KNOWN_TX_METADATA_[i].metadata != NULL) { - parser_error_t err = _validateHash(scriptHash, PIC(KNOWN_TX_METADATA_[i].metadata), KNOWN_TX_METADATA_[i].metadataLength); + while(KNOWN_TX_METADATA[i].metadata != NULL) { + parser_error_t err = _validateHash(scriptHash, PIC(KNOWN_TX_METADATA[i].metadata), KNOWN_TX_METADATA[i].metadataLength); switch (err) { case PARSER_OK: - return parseTxMetadata(scriptHash, PIC(KNOWN_TX_METADATA_[i].metadata), KNOWN_TX_METADATA_[i].metadataLength, parsedTxTempate); + return parseTxMetadata(scriptHash, PIC(KNOWN_TX_METADATA[i].metadata), KNOWN_TX_METADATA[i].metadataLength, parsedTxTempate); case PARSER_UNEXPECTED_SCRIPT: break; //break switch default: diff --git a/app/src/tx_metadata.h b/app/src/tx_metadata.h index 947dfb64..2ac1de2f 100644 --- a/app/src/tx_metadata.h +++ b/app/src/tx_metadata.h @@ -57,7 +57,7 @@ typedef struct { #define SCRIPT_HASH_SIZE 32 -//It is planed that compressedData may be on flash, thus they are volatile (for NanoX and NanoSPlus) +//It is planned that compressedData may be on flash, thus they are volatile (for NanoX and NanoSPlus) parser_error_t parseTxMetadata(uint8_t scriptHash[SCRIPT_HASH_SIZE], const NV_VOLATILE uint8_t *txMetadata, uint16_t txMetadataLength, parsed_tx_metadata_t *parsedTxMetadata); From 53ca57be0b4fc3c768c98bced2e403df12243e0a Mon Sep 17 00:00:00 2001 From: Robert Lukotka Date: Tue, 7 Jun 2022 13:19:42 +0200 Subject: [PATCH 05/12] Ad consts into json parsing --- app/src/parser_common.h | 5 ++--- app/src/parser_impl.c | 14 +++++++------- app/src/parser_impl.h | 16 +++++++--------- 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/app/src/parser_common.h b/app/src/parser_common.h index 2dff792e..806cfd7c 100644 --- a/app/src/parser_common.h +++ b/app/src/parser_common.h @@ -76,9 +76,8 @@ typedef enum { PARSER_REQUIRED_METHOD, //Template errors PARSER_TEMPLATE_TOO_MANY_HASHES, - PARSER_TEMPLATE_ERROR, - PARSER_TEMPLATE_TOO_MANY_ARGUMENTS - + PARSER_TEMPLATE_TOO_MANY_ARGUMENTS, + PARSER_TEMPLATE_ERROR //covers several minor template related errors } parser_error_t; typedef struct { diff --git a/app/src/parser_impl.c b/app/src/parser_impl.c index 94028ff0..833f14d1 100644 --- a/app/src/parser_impl.c +++ b/app/src/parser_impl.c @@ -125,7 +125,7 @@ __Z_INLINE char hexDigit(uint8_t v) { return '?'; } -parser_error_t json_validateToken(parsed_json_t *parsedJson, uint16_t tokenIdx) { +parser_error_t json_validateToken(const parsed_json_t *parsedJson, uint16_t tokenIdx) { if (!parsedJson->isValid) { return PARSER_JSON_INVALID; } @@ -146,7 +146,7 @@ parser_error_t json_validateToken(parsed_json_t *parsedJson, uint16_t tokenIdx) return PARSER_OK; } -parser_error_t json_extractToken(char *outVal, uint16_t outValLen, parsed_json_t *parsedJson, uint16_t tokenIdx) { +parser_error_t json_extractToken(char *outVal, uint16_t outValLen, const parsed_json_t *parsedJson, uint16_t tokenIdx) { MEMZERO(outVal, outValLen); CHECK_PARSER_ERR(json_validateToken(parsedJson, tokenIdx)) @@ -159,7 +159,7 @@ parser_error_t json_extractToken(char *outVal, uint16_t outValLen, parsed_json_t return PARSER_OK; } -parser_error_t json_matchToken(parsed_json_t *parsedJson, uint16_t tokenIdx, const char *expectedValue) { +parser_error_t json_matchToken(const parsed_json_t *parsedJson, uint16_t tokenIdx, const char *expectedValue) { CHECK_PARSER_ERR(json_validateToken(parsedJson, tokenIdx)) const jsmntok_t token = parsedJson->tokens[tokenIdx]; @@ -178,7 +178,7 @@ parser_error_t json_matchToken(parsed_json_t *parsedJson, uint16_t tokenIdx, con return PARSER_OK; } -parser_error_t json_matchNull(parsed_json_t *parsedJson, uint16_t tokenIdx) { +parser_error_t json_matchNull(const parsed_json_t *parsedJson, uint16_t tokenIdx) { CHECK_PARSER_ERR(json_validateToken(parsedJson, tokenIdx)) const jsmntok_t token = parsedJson->tokens[tokenIdx]; @@ -197,7 +197,7 @@ parser_error_t json_matchNull(parsed_json_t *parsedJson, uint16_t tokenIdx) { return PARSER_OK; } -parser_error_t json_matchKeyValue(parsed_json_t *parsedJson, +parser_error_t json_matchKeyValue(const parsed_json_t *parsedJson, uint16_t tokenIdx, const char *expectedType, jsmntype_t jsonType, uint16_t *valueTokenIdx) { CHECK_PARSER_ERR(json_validateToken(parsedJson, tokenIdx)) @@ -228,7 +228,7 @@ parser_error_t json_matchKeyValue(parsed_json_t *parsedJson, } //valueTokenIdx is JSON_MATCH_VALUE_IDX_NONE if the optional is null -parser_error_t json_matchOptionalKeyValue(parsed_json_t *parsedJson, +parser_error_t json_matchOptionalKeyValue(const parsed_json_t *parsedJson, uint16_t tokenIdx, const char *expectedType, jsmntype_t jsonType, uint16_t *valueTokenIdx) { CHECK_PARSER_ERR(json_validateToken(parsedJson, tokenIdx)) @@ -263,7 +263,7 @@ parser_error_t json_matchOptionalKeyValue(parsed_json_t *parsedJson, } //valueTokenIdx is JSON_MATCH_VALUE_IDX_NONE if the optional is null -parser_error_t json_matchOptionalArray(parsed_json_t *parsedJson, +parser_error_t json_matchOptionalArray(const parsed_json_t *parsedJson, uint16_t tokenIdx, uint16_t *valueTokenIdx) { CHECK_PARSER_ERR(json_validateToken(parsedJson, tokenIdx)) diff --git a/app/src/parser_impl.h b/app/src/parser_impl.h index ee1829a2..13b4ec6a 100644 --- a/app/src/parser_impl.h +++ b/app/src/parser_impl.h @@ -47,27 +47,25 @@ parser_error_t _countArgumentItems(const flow_argument_list_t *v, uint8_t argume parser_error_t _countArgumentOptionalItems(const flow_argument_list_t *v, uint8_t argumentIndex, uint8_t max_number_of_items, uint8_t *number_of_items); -parser_error_t json_validateToken(parsed_json_t *parsedJson, uint16_t tokenIdx); +parser_error_t json_validateToken(const parsed_json_t *parsedJson, uint16_t tokenIdx); -parser_error_t json_extractToken(char *outVal, uint16_t outValLen, parsed_json_t *parsedJson, uint16_t tokenIdx); +parser_error_t json_extractToken(char *outVal, uint16_t outValLen, const parsed_json_t *parsedJson, uint16_t tokenIdx); -parser_error_t json_matchToken(parsed_json_t *parsedJson, uint16_t tokenIdx, const char *expectedValue); +parser_error_t json_matchToken(const parsed_json_t *parsedJson, uint16_t tokenIdx, const char *expectedValue); -parser_error_t json_matchNull(parsed_json_t *parsedJson, uint16_t tokenIdx); +parser_error_t json_matchNull(const parsed_json_t *parsedJson, uint16_t tokenIdx); -parser_error_t json_matchKeyValue(parsed_json_t *parsedJson, +parser_error_t json_matchKeyValue(const parsed_json_t *parsedJson, uint16_t tokenIdx, const char *expectedType, jsmntype_t jsonType, uint16_t *valueTokenIdx); #define JSON_MATCH_VALUE_IDX_NONE 65535 -parser_error_t json_matchOptionalKeyValue(parsed_json_t *parsedJson, +parser_error_t json_matchOptionalKeyValue(const parsed_json_t *parsedJson, uint16_t tokenIdx, const char *expectedType, jsmntype_t jsonType, uint16_t *valueTokenIdx); -parser_error_t json_matchOptionalArray(parsed_json_t *parsedJson, uint16_t tokenIdx, uint16_t *valueTokenIdx); +parser_error_t json_matchOptionalArray(const parsed_json_t *parsedJson, uint16_t tokenIdx, uint16_t *valueTokenIdx); parser_error_t formatStrUInt8AsHex(const char *decStr, char *hexStr); -parser_error_t json_extractString(char *outVal, uint16_t outValLen, parsed_json_t *parsedJson, uint16_t tokenIdx); - void checkAddressUsedInTx(); From 3142b37f08e5ffcb792ddd6c6110bc66c9ac43b3 Mon Sep 17 00:00:00 2001 From: Robert Lukotka Date: Tue, 7 Jun 2022 13:32:14 +0200 Subject: [PATCH 06/12] dd static where aplicable in tx_metadata --- app/src/tx_metadata.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/tx_metadata.c b/app/src/tx_metadata.c index 867bf318..f57deca0 100644 --- a/app/src/tx_metadata.c +++ b/app/src/tx_metadata.c @@ -3,7 +3,7 @@ //Known tx metadata -const uint8_t TX_METADATA_CREATE_ACCOUNT[] = { +const static uint8_t TX_METADATA_CREATE_ACCOUNT[] = { 1, //number of hashes + hashes 0xee, 0xf2, 0xd0, 0x49, 0x44, 0x48, 0x55, 0x41, 0x77, 0x61, 0x2e, 0x63, 0x02, 0x62, 0x56, 0x25, 0x83, 0x39, 0x23, 0x0c, 0xbc, 0x69, 0x31, 0xde, 0xd7, 0x8d, 0x61, 0x49, 0x44, 0x3c, 0x61, 0x73, 'C', 'r', 'e', 'a', 't', 'e', ' ', 'A', 'c', 'c', 'o', 'u', 'n', 't', 0, //tx name (to display) @@ -17,7 +17,7 @@ const uint8_t TX_METADATA_CREATE_ACCOUNT[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_ADD_NEW_KEY[] = { +const static uint8_t TX_METADATA_ADD_NEW_KEY[] = { 1, //number of hashes + hashes 0x59, 0x5c, 0x86, 0x56, 0x14, 0x41, 0xb3, 0x2b, 0x2b, 0x91, 0xee, 0x03, 0xf9, 0xe1, 0x0c, 0xa6, 0xef, 0xa7, 0xb4, 0x1b, 0xcc, 0x99, 0x4f, 0x51, 0x31, 0x7e, 0xc0, 0xaa, 0x9d, 0x8f, 0x8a, 0x42, 'A', 'd', 'd', ' ', 'N', 'e', 'w', ' ', 'K', 'e', 'y', 0, //tx name (to display) @@ -31,7 +31,7 @@ const uint8_t TX_METADATA_ADD_NEW_KEY[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_TOKEN_TRANSFER[] = { +const static uint8_t TX_METADATA_TOKEN_TRANSFER[] = { 3, //number of hashes + hashes 0xca, 0x80, 0xb6, 0x28, 0xd9, 0x85, 0xb3, 0x58, 0xae, 0x1c, 0xb1, 0x36, 0xbc, 0xd9, 0x76, 0x99, 0x7c, 0x94, 0x2f, 0xa1, 0x0d, 0xba, 0xbf, 0xea, 0xfb, 0x4e, 0x20, 0xfa, 0x66, 0xa5, 0xa5, 0xe2, 0xd5, 0x6f, 0x4e, 0x1d, 0x23, 0x55, 0xcd, 0xcf, 0xac, 0xfd, 0x01, 0xe4, 0x71, 0x45, 0x9c, 0x6e, 0xf1, 0x68, 0xbf, 0xdf, 0x84, 0x37, 0x1a, 0x68, 0x5c, 0xcf, 0x31, 0xcf, 0x3c, 0xde, 0xdc, 0x2d, @@ -61,7 +61,7 @@ typedef struct { uint16_t metadataLength; } known_tx_metadata_entry_t; -const known_tx_metadata_entry_t KNOWN_TX_METADATA[] = { +const static known_tx_metadata_entry_t KNOWN_TX_METADATA[] = { {TX_METADATA_CREATE_ACCOUNT, sizeof(TX_METADATA_CREATE_ACCOUNT)}, {TX_METADATA_ADD_NEW_KEY, sizeof(TX_METADATA_ADD_NEW_KEY)}, {TX_METADATA_TOKEN_TRANSFER, sizeof(TX_METADATA_TOKEN_TRANSFER)}, @@ -179,7 +179,7 @@ parser_error_t matchStoredTxMetadata(uint8_t scriptHash[SCRIPT_HASH_SIZE], parse case PARSER_OK: return parseTxMetadata(scriptHash, PIC(KNOWN_TX_METADATA[i].metadata), KNOWN_TX_METADATA[i].metadataLength, parsedTxTempate); case PARSER_UNEXPECTED_SCRIPT: - break; //break switch + break; //scripts do not match, we should try next one default: return err; } From ba7d4f0b22a3666c7170c66dea922bd817c80b58 Mon Sep 17 00:00:00 2001 From: Robert Lukotka Date: Thu, 26 May 2022 23:35:03 +0200 Subject: [PATCH 07/12] Refactor transaction displaying using metadata --- app/src/addr.c | 20 +- app/src/parser.c | 1744 +++---------------------------- app/src/parser.h | 3 +- app/src/parser_common.h | 7 +- app/src/parser_impl.c | 356 +------ app/src/parser_impl.h | 8 +- app/src/parser_txdef.h | 60 +- app/src/template_hashes.h | 160 --- app/src/tx_metadata.c | 942 ++++++++++++++++- app/src/tx_metadata.h | 8 +- tests/tx_metadata.cpp | 18 +- tests/utils/expected_output.cpp | 375 +------ 12 files changed, 1155 insertions(+), 2546 deletions(-) delete mode 100644 app/src/template_hashes.h diff --git a/app/src/addr.c b/app/src/addr.c index 125c3484..d66e71d3 100644 --- a/app/src/addr.c +++ b/app/src/addr.c @@ -30,11 +30,16 @@ uint8_t pubkey_to_display[SECP256_PK_LEN]; //In the second case this is used to count the number of pages //If displayIdx is negative, all other values are undefined zxerr_t addr_getItem_internal(int8_t *displayIdx, - char *outKey, uint16_t outKeyLen, - char *outVal, uint16_t outValLen, - uint8_t pageIdx, uint8_t *pageCount) { + char *outKey, uint16_t outKeyLen, + char *outVal, uint16_t outValLen, + uint8_t pageIdx, uint8_t *pageCount) { zemu_log_stack("addr_getItem_internal"); + MEMZERO(outKey, outKeyLen); + MEMZERO(outVal, outValLen); + snprintf(outKey, outKeyLen, "? %d", *displayIdx); + snprintf(outVal, outValLen, "?"); + #define SCREEN(condition) if ((condition) && ((*displayIdx)--==0) && pageCount && (*pageCount = 1)) uint8_t show_address_yes = (show_address == SHOW_ADDRESS_YES || show_address == SHOW_ADDRESS_YES_HASH_MISMATCH); @@ -78,7 +83,7 @@ zxerr_t addr_getItem_internal(int8_t *displayIdx, pageHexString(outVal, outValLen, address_to_display.data, sizeof(address_to_display.data), pageIdx, pageCount); return zxerr_ok; default: - return zxerr_no_data; + return zxerr_unknown; } } @@ -143,9 +148,12 @@ zxerr_t addr_getNumItems(uint8_t *num_items) { return err; } -zxerr_t addr_getItem(int8_t displayIdx, +zxerr_t addr_getItem(uint8_t displayIdx, char *outKey, uint16_t outKeyLen, char *outVal, uint16_t outValLen, uint8_t pageIdx, uint8_t *pageCount) { - return addr_getItem_internal(&displayIdx, outKey, outKeyLen, outVal, outValLen, pageIdx, pageCount); + if (displayIdx > INT8_MAX) { + return zxerr_out_of_bounds; + } + return addr_getItem_internal((int8_t *) &displayIdx, outKey, outKeyLen, outVal, outValLen, pageIdx, pageCount); } diff --git a/app/src/parser.c b/app/src/parser.c index c272a7e3..c4cadf7b 100644 --- a/app/src/parser.c +++ b/app/src/parser.c @@ -58,11 +58,6 @@ parser_error_t parser_validate(const parser_context_t *ctx) { return PARSER_OK; } -parser_error_t parser_getNumItems(const parser_context_t *ctx, uint8_t *num_items) { - CHECK_PARSER_ERR(_getNumItems(ctx, &parser_tx_obj, num_items)) - return PARSER_OK; -} - // based on Dapper provided code at https://github.com/onflow/flow-go-sdk/blob/96796f0cabc1847d7879a5230ab55fd3cdd41ae8/address.go#L286 const uint16_t linearCodeN = 64; @@ -177,6 +172,7 @@ parser_error_t parser_printArgument(const flow_argument_list_t *v, uint8_t argIn char bufferUI[ARGUMENT_BUFFER_SIZE_STRING]; uint16_t valueTokenIndex; + CHECK_PARSER_ERR(json_matchKeyValue(&parsedJson, 0, expectedType, jsonType, &valueTokenIndex)) CHECK_PARSER_ERR(json_extractToken(bufferUI, sizeof(bufferUI), &parsedJson, valueTokenIndex)) pageString(outVal, outValLen, bufferUI, pageIdx, pageCount); @@ -411,44 +407,122 @@ parser_error_t parser_printAuthorizer(const flow_proposal_authorizer_t *v, return PARSER_OK; } -parser_error_t parser_getItemAfterArguments(__Z_UNUSED const parser_context_t *ctx, - uint16_t displayIdx, - char *outKey, uint16_t outKeyLen, - char *outVal, uint16_t outValLen, - uint8_t pageIdx, uint8_t *pageCount) { - switch (displayIdx) { - case 0: - snprintf(outKey, outKeyLen, "Ref Block"); - return parser_printBlockId(&parser_tx_obj.referenceBlockId, outVal, outValLen, pageIdx, pageCount); - case 1: - snprintf(outKey, outKeyLen, "Gas Limit"); - return parser_printGasLimit(&parser_tx_obj.gasLimit, outVal, outValLen, pageIdx, pageCount); - case 2: - snprintf(outKey, outKeyLen, "Prop Key Addr"); - return parser_printPropKeyAddr(&parser_tx_obj.proposalKeyAddress, outVal, outValLen, pageIdx, pageCount); - case 3: - snprintf(outKey, outKeyLen, "Prop Key Id"); - return parser_printPropKeyId(&parser_tx_obj.proposalKeyId, outVal, outValLen, pageIdx, pageCount); - case 4: - snprintf(outKey, outKeyLen, "Prop Key Seq Num"); - return parser_printPropSeqNum(&parser_tx_obj.proposalKeySequenceNumber, outVal, outValLen, pageIdx, - pageCount); - case 5: - snprintf(outKey, outKeyLen, "Payer"); - return parser_printPayer(&parser_tx_obj.payer, outVal, outValLen, pageIdx, pageCount); - default: - break; + +#define CREATE_ACCOUNT_MAX_PUB_KEYS 5 +#define SCO03_REGISTER_NODE_MAX_PUB_KEYS 3 + +parser_error_t parser_getItem_internal(__Z_UNUSED const parser_context_t *ctx, int8_t *displayIdx, + char *outKey, uint16_t outKeyLen, + char *outVal, uint16_t outValLen, + uint8_t pageIdx, uint8_t *pageCount) { + MEMZERO(outKey, outKeyLen); + MEMZERO(outVal, outValLen); + snprintf(outKey, outKeyLen, "? %d", *displayIdx); + snprintf(outVal, outValLen, "?"); + + #define SCREEN(condition) if ((condition) && ((*displayIdx)--==0) && pageCount && (*pageCount = 1)) + + SCREEN(true) { + snprintf(outKey, outKeyLen, "Type"); + snprintf(outVal, outValLen, "%s", parser_tx_obj.metadata.txName); + return PARSER_OK; + } + + SCREEN(true) { + snprintf(outKey, outKeyLen, "ChainID"); + return parser_printChainID(&parser_tx_obj.payer, outVal, outValLen, pageIdx, pageCount); + } + + //Arguments + uint8_t screenCount = 0; + for(size_t i=0; iargumentType) { + case ARGUMENT_TYPE_NORMAL: + SCREEN(true) { + snprintf(outKey, outKeyLen, "%s", marg->displayKey); + return parser_printArgument(&parser_tx_obj.arguments, marg->argumentIndex, + marg->jsonExpectedType, marg->jsonExpectedKind, + outVal, outValLen, pageIdx, pageCount); + } + break; + case ARGUMENT_TYPE_OPTIONAL: + SCREEN(true) { + snprintf(outKey, outKeyLen, "%s", marg->displayKey); + return parser_printOptionalArgument(&parser_tx_obj.arguments, marg->argumentIndex, + marg->jsonExpectedType, marg->jsonExpectedKind, + outVal, outValLen, pageIdx, pageCount); + } + break; + case ARGUMENT_TYPE_ARRAY: + CHECK_PARSER_ERR(_countArgumentItems(&parser_tx_obj.arguments, marg->argumentIndex, + marg->arrayMinElements, marg->arrayMaxElements, &screenCount)); + for(size_t j=0; jdisplayKey, (int)(j+1)); + return parser_printArgumentArray(&parser_tx_obj.arguments, marg->argumentIndex, j, + marg->jsonExpectedType, marg->jsonExpectedKind, + outVal, outValLen, pageIdx, pageCount); + + } + } + break; + case ARGUMENT_TYPE_OPTIONALARRAY: + CHECK_PARSER_ERR(_countArgumentOptionalItems(&parser_tx_obj.arguments, marg->argumentIndex, + marg->arrayMinElements, marg->arrayMaxElements, &screenCount)); + for(size_t j=0; jdisplayKey, (int)(j+1)); + return parser_printArgumentOptionalArray(&parser_tx_obj.arguments, marg->argumentIndex, j, + marg->jsonExpectedType, marg->jsonExpectedKind, + outVal, outValLen, pageIdx, pageCount); + + } + } + break; + default: + return PARSER_METADATA_ERROR; + } + } + + SCREEN(true) { + snprintf(outKey, outKeyLen, "Ref Block"); + return parser_printBlockId(&parser_tx_obj.referenceBlockId, outVal, outValLen, pageIdx, pageCount); + } + + SCREEN(true) { + snprintf(outKey, outKeyLen, "Gas Limit"); + return parser_printGasLimit(&parser_tx_obj.gasLimit, outVal, outValLen, pageIdx, pageCount); + } + + SCREEN(true) { + snprintf(outKey, outKeyLen, "Prop Key Addr"); + return parser_printPropKeyAddr(&parser_tx_obj.proposalKeyAddress, outVal, outValLen, pageIdx, pageCount); } - displayIdx -= 6; - if (displayIdx < parser_tx_obj.authorizers.authorizer_count) { - snprintf(outKey, outKeyLen, "Authorizer %d", displayIdx + 1); - return parser_printAuthorizer(&parser_tx_obj.authorizers.authorizer[displayIdx], outVal, outValLen, pageIdx, - pageCount); + SCREEN(true) { + snprintf(outKey, outKeyLen, "Prop Key Id"); + return parser_printPropKeyId(&parser_tx_obj.proposalKeyId, outVal, outValLen, pageIdx, pageCount); } - displayIdx -= parser_tx_obj.authorizers.authorizer_count; - if (app_mode_expert() && displayIdx-- == 0) { + SCREEN(true) { + snprintf(outKey, outKeyLen, "Prop Key Seq Num"); + return parser_printPropSeqNum(&parser_tx_obj.proposalKeySequenceNumber, outVal, outValLen, pageIdx, pageCount); + } + + SCREEN(true) { + snprintf(outKey, outKeyLen, "Payer"); + return parser_printPayer(&parser_tx_obj.payer, outVal, outValLen, pageIdx, pageCount); + } + + for(size_t i=0; i= numItems) { - return PARSER_NO_DATA; +parser_error_t parser_getItem(const parser_context_t *ctx, uint8_t displayIdx, + char *outKey, uint16_t outKeyLen, + char *outVal, uint16_t outValLen, + uint8_t pageIdx, uint8_t *pageCount) { + if (displayIdx > INT8_MAX) { + return PARSER_DISPLAY_IDX_OUT_OF_RANGE; } - *pageCount = 1; - - switch (parser_tx_obj.script.type) { - case SCRIPT_UNKNOWN: - return PARSER_UNEXPECTED_SCRIPT; - case SCRIPT_TOKEN_TRANSFER: - return parser_getItemTokenTransfer(ctx, displayIdx, outKey, outKeyLen, outVal, outValLen, pageIdx, - pageCount); - case SCRIPT_CREATE_ACCOUNT: - return parser_getItemCreateAccount(ctx, displayIdx, outKey, outKeyLen, outVal, outValLen, pageIdx, - pageCount); - case SCRIPT_ADD_NEW_KEY: - return parser_getItemAddNewKey(ctx, displayIdx, outKey, outKeyLen, outVal, outValLen, pageIdx, - pageCount); - case SCRIPT_TH01_WITHDRAW_UNLOCKED_TOKENS: - return parser_getItemWithdrawUnlockedTokens(ctx, displayIdx, outKey, outKeyLen, outVal, outValLen, - pageIdx, pageCount); - case SCRIPT_TH02_DEPOSIT_UNLOCKED_TOKENS: - return parser_getItemDepositUnlockedTokens(ctx, displayIdx, outKey, outKeyLen, outVal, outValLen, - pageIdx, pageCount); - case SCRIPT_TH06_REGISTER_NODE: - return parser_getItemRegisterNode(ctx, displayIdx, outKey, outKeyLen, outVal, outValLen, - pageIdx, pageCount); - case SCRIPT_TH08_STAKE_NEW_TOKENS: - return parser_getItemStakeNewTokens(ctx, displayIdx, outKey, outKeyLen, outVal, outValLen, - pageIdx, pageCount); - case SCRIPT_TH09_RESTAKE_UNSTAKED_TOKENS: - return parser_getItemRestakeUnstakedTokens(ctx, displayIdx, outKey, outKeyLen, outVal, outValLen, - pageIdx, pageCount); - case SCRIPT_TH10_RESTAKE_REWARDED_TOKENS: - return parser_getItemRestakeRewardedTokens(ctx, displayIdx, outKey, outKeyLen, outVal, outValLen, - pageIdx, pageCount); - case SCRIPT_TH11_UNSTAKE_TOKENS: - return parser_getItemUnstakeTokens(ctx, displayIdx, outKey, outKeyLen, outVal, outValLen, - pageIdx, pageCount); - case SCRIPT_TH12_UNSTAKE_ALL_TOKENS: - return parser_getItemUnstakeAllTokens(ctx, displayIdx, outKey, outKeyLen, outVal, outValLen, - pageIdx, pageCount); - case SCRIPT_TH13_WITHDRAW_UNSTAKED_TOKENS: - return parser_getItemWithdrawUnstakedTokens(ctx, displayIdx, outKey, outKeyLen, outVal, outValLen, - pageIdx, pageCount); - case SCRIPT_TH14_WITHDRAW_REWARDED_TOKENS: - return parser_getItemWithdrawRewardedTokens(ctx, displayIdx, outKey, outKeyLen, outVal, outValLen, - pageIdx, pageCount); - case SCRIPT_TH16_REGISTER_OPERATOR_NODE: - return parser_getItemRegisterOperatorNode(ctx, displayIdx, outKey, outKeyLen, outVal, outValLen, - pageIdx, pageCount); - case SCRIPT_TH17_REGISTER_DELEGATOR: - return parser_getItemRegisterDelegator(ctx, displayIdx, outKey, outKeyLen, outVal, outValLen, - pageIdx, pageCount); - case SCRIPT_TH19_DELEGATE_NEW_TOKENS: - return parser_getItemDelegateNewTokens(ctx, displayIdx, outKey, outKeyLen, outVal, outValLen, - pageIdx, pageCount); - case SCRIPT_TH20_RESTAKE_UNSTAKED_DELEGATED_TOKENS: - return parser_getItemRestakeUnstakedDelegatedTokens(ctx, displayIdx, outKey, outKeyLen, outVal, - outValLen, pageIdx, pageCount); - case SCRIPT_TH21_RESTAKE_REWARDED_DELEGATED_TOKENS: - return parser_getItemRestakeRewardedDelegatedTokens(ctx, displayIdx, outKey, outKeyLen, outVal, - outValLen, pageIdx, pageCount); - case SCRIPT_TH22_UNSTAKE_DELEGATED_TOKENS: - return parser_getItemUnstakeDelegatedTokens(ctx, displayIdx, outKey, outKeyLen, outVal, - outValLen, pageIdx, pageCount); - case SCRIPT_TH23_WITHDRAW_UNSTAKED_DELEGATED_TOKENS: - return parser_getItemWithdrawUnstakedDelegatedTokens(ctx, displayIdx, outKey, outKeyLen, outVal, - outValLen, pageIdx, pageCount); - case SCRIPT_TH24_WITHDRAW_REWARDED_DELEGATED_TOKENS: - return parser_getItemWithdrawRewardedDelegatedTokens(ctx, displayIdx, outKey, outKeyLen, outVal, - outValLen, pageIdx, pageCount); - case SCRIPT_TH25_UPDATE_NETWORKING_ADDRESS: - return parser_getItemUpdateNetworkingAddress(ctx, displayIdx, outKey, outKeyLen, outVal, - outValLen, pageIdx, pageCount); - case SCRIPT_SCO01_SETUP_STAKING_COLLECTION: - return parser_getItemSetupStaingCollection(ctx, displayIdx, outKey, outKeyLen, outVal, - outValLen, pageIdx, pageCount); - case SCRIPT_SCO02_REGISTER_DELEGATOR: - return parser_getItemRegisterDelegatorSCO(ctx, displayIdx, outKey, outKeyLen, outVal, - outValLen, pageIdx, pageCount); - case SCRIPT_SCO03_REGISTER_NODE: - return parser_getItemRegisterNodeSCO(ctx, displayIdx, outKey, outKeyLen, outVal, - outValLen, pageIdx, pageCount); - case SCRIPT_SCO04_CREATE_MACHINE_ACCOUNT: - return parser_getItemCreateMachineAccount(ctx, displayIdx, outKey, outKeyLen, outVal, - outValLen, pageIdx, pageCount); - case SCRIPT_SCO05_REQUEST_UNSTAKING: - return parser_getItemRequestUnstaking(ctx, displayIdx, outKey, outKeyLen, outVal, - outValLen, pageIdx, pageCount); - case SCRIPT_SCO06_STAKE_NEW_TOKENS: - return parser_getItemStakeNewTokensSCO(ctx, displayIdx, outKey, outKeyLen, outVal, - outValLen, pageIdx, pageCount); - case SCRIPT_SCO07_STAKE_REWARD_TOKENS: - return parser_getItemStakeRewardTokens(ctx, displayIdx, outKey, outKeyLen, outVal, - outValLen, pageIdx, pageCount); - case SCRIPT_SCO08_STAKE_UNSTAKED_TOKENS: - return parser_getItemStakeUnstakedTokens(ctx, displayIdx, outKey, outKeyLen, outVal, - outValLen, pageIdx, pageCount); - case SCRIPT_SCO09_UNSTAKE_ALL: - return parser_getItemUnstakeAll(ctx, displayIdx, outKey, outKeyLen, outVal, - outValLen, pageIdx, pageCount); - case SCRIPT_SCO10_WITHDRAW_REWARD_TOKENS: - return parser_getItemWithdrawRewardTokensSCO(ctx, displayIdx, outKey, outKeyLen, outVal, - outValLen, pageIdx, pageCount); - case SCRIPT_SCO11_WITHDRAW_UNSTAKED_TOKENS: - return parser_getItemWithdrawUnstakedTokensSCO(ctx, displayIdx, outKey, outKeyLen, outVal, - outValLen, pageIdx, pageCount); - case SCRIPT_SCO12_CLOSE_STAKE: - return parser_getItemCloseStake(ctx, displayIdx, outKey, outKeyLen, outVal, - outValLen, pageIdx, pageCount); - case SCRIPT_SCO13_TRANSFER_NODE: - return parser_getItemTransferNode(ctx, displayIdx, outKey, outKeyLen, outVal, - outValLen, pageIdx, pageCount); - case SCRIPT_SCO14_TRANSFER_DELEGATOR: - return parser_getItemTransferDelegator(ctx, displayIdx, outKey, outKeyLen, outVal, - outValLen, pageIdx, pageCount); - case SCRIPT_SCO15_WITHDRAW_FROM_MACHINE_ACCOUNT: - return parser_getItemWithdrawFromMachineAccount(ctx, displayIdx, outKey, outKeyLen, outVal, - outValLen, pageIdx, pageCount); - case SCRIPT_SCO16_UPDATE_NETWORKING_ADDRESS: - return parser_getItemUpdateNetworkingAddressSCO(ctx, displayIdx, outKey, outKeyLen, outVal, - outValLen, pageIdx, pageCount); - case SCRIPT_FUSD01_SETUP_FUSD_VAULT: - return parser_getItemSetupFUSDVault(ctx, displayIdx, outKey, outKeyLen, outVal, - outValLen, pageIdx, pageCount); - case SCRIPT_FUSD02_TRANSFER_FUSD: - return parser_getItemTransferFUSD(ctx, displayIdx, outKey, outKeyLen, outVal, - outValLen, pageIdx, pageCount); - case SCRIPT_TS01_SET_UP_TOPSHOT_COLLECTION: - return parser_getItemSetUpTopShotCollection(ctx, displayIdx, outKey, outKeyLen, outVal, - outValLen, pageIdx, pageCount); - case SCRIPT_TS02_TRANSFER_TOP_SHOT_MOMENT: - return parser_getItemTransferTopShotMoment(ctx, displayIdx, outKey, outKeyLen, outVal, - outValLen, pageIdx, pageCount); - case SCRIPT_USDC01_SETUP_USDC_VAULT: - return parser_getItemSetupUSDCVault(ctx, displayIdx, outKey, outKeyLen, outVal, - outValLen, pageIdx, pageCount); - case SCRIPT_USDC02_TRANSFER_USDC: - return parser_getItemTransferUSDC(ctx, displayIdx, outKey, outKeyLen, outVal, - outValLen, pageIdx, pageCount); - } - - return PARSER_UNEXPECTED_SCRIPT; + return parser_getItem_internal(ctx, (int8_t *) &displayIdx, outKey, outKeyLen, outVal, outValLen, pageIdx, pageCount); } diff --git a/app/src/parser.h b/app/src/parser.h index 27354373..d7404298 100644 --- a/app/src/parser.h +++ b/app/src/parser.h @@ -38,8 +38,7 @@ parser_error_t parser_validate(const parser_context_t *ctx); parser_error_t parser_getNumItems(const parser_context_t *ctx, uint8_t *num_items); // retrieves a readable output for each field / page -parser_error_t parser_getItem(const parser_context_t *ctx, - uint16_t displayIdx, +parser_error_t parser_getItem(const parser_context_t *ctx, uint8_t displayIdx, char *outKey, uint16_t outKeyLen, char *outVal, uint16_t outValLen, uint8_t pageIdx, uint8_t *pageCount); diff --git a/app/src/parser_common.h b/app/src/parser_common.h index 806cfd7c..96a6e281 100644 --- a/app/src/parser_common.h +++ b/app/src/parser_common.h @@ -75,9 +75,10 @@ typedef enum { PARSER_REQUIRED_NONCE, PARSER_REQUIRED_METHOD, //Template errors - PARSER_TEMPLATE_TOO_MANY_HASHES, - PARSER_TEMPLATE_TOO_MANY_ARGUMENTS, - PARSER_TEMPLATE_ERROR //covers several minor template related errors + PARSER_METADATA_TOO_MANY_HASHES, + PARSER_METADATA_ERROR, + PARSER_METADATA_TOO_MANY_ARGUMENTS + } parser_error_t; typedef struct { diff --git a/app/src/parser_impl.c b/app/src/parser_impl.c index 833f14d1..423a3750 100644 --- a/app/src/parser_impl.c +++ b/app/src/parser_impl.c @@ -110,6 +110,12 @@ const char *parser_getErrorDescription(parser_error_t err) { return "Required field nonce"; case PARSER_REQUIRED_METHOD: return "Required field method"; + case PARSER_METADATA_TOO_MANY_HASHES: + return "Metadata too many hashes"; + case PARSER_METADATA_ERROR: + return "Metadata unknown error"; + case PARSER_METADATA_TOO_MANY_ARGUMENTS: + return "Metadata too many arguments"; default: return "Unrecognized error code"; } @@ -327,190 +333,21 @@ parser_error_t formatStrUInt8AsHex(const char *decStr, char *hexStr) { return PARSER_OK; } -parser_error_t _matchScriptType(uint8_t scriptHash[32], script_type_e *scriptType) { - *scriptType = SCRIPT_UNKNOWN; - - char buffer[100]; - MEMZERO(buffer, sizeof(buffer)); - - // Check it is a known script digest - if (array_to_hexstr(buffer, sizeof(buffer), scriptHash, CX_SHA256_SIZE) != 64) { - return PARSER_UNEXPECTED_ERROR; - } - - struct known_script_entry { - script_type_e script_type; - char* template; - }; - - const struct known_script_entry KNOWN_TYPES[] = { - {SCRIPT_TOKEN_TRANSFER, TEMPLATE_HASH_TOKEN_TRANSFER_EMULATOR}, - {SCRIPT_TOKEN_TRANSFER, TEMPLATE_HASH_TOKEN_TRANSFER_TESTNET}, - {SCRIPT_TOKEN_TRANSFER, TEMPLATE_HASH_TOKEN_TRANSFER_MAINNET}, - - {SCRIPT_CREATE_ACCOUNT, TEMPLATE_HASH_CREATE_ACCOUNT}, - - {SCRIPT_ADD_NEW_KEY, TEMPLATE_HASH_ADD_NEW_KEY}, - - {SCRIPT_TH01_WITHDRAW_UNLOCKED_TOKENS, TEMPLATE_HASH_TH01_WITHDRAW_UNLOCKED_TOKENS_TESTNET}, - {SCRIPT_TH01_WITHDRAW_UNLOCKED_TOKENS, TEMPLATE_HASH_TH01_WITHDRAW_UNLOCKED_TOKENS_MAINNET}, - - {SCRIPT_TH02_DEPOSIT_UNLOCKED_TOKENS, TEMPLATE_HASH_TH02_DEPOSIT_UNLOCKED_TOKENS_TESTNET}, - {SCRIPT_TH02_DEPOSIT_UNLOCKED_TOKENS, TEMPLATE_HASH_TH02_DEPOSIT_UNLOCKED_TOKENS_MAINNET}, - - {SCRIPT_TH06_REGISTER_NODE, TEMPLATE_HASH_TH06_REGISTER_NODE_TESTNET}, - {SCRIPT_TH06_REGISTER_NODE, TEMPLATE_HASH_TH06_REGISTER_NODE_MAINNET}, - - {SCRIPT_TH08_STAKE_NEW_TOKENS, TEMPLATE_HASH_TH08_STAKE_NEW_TOKENS_TESTNET}, - {SCRIPT_TH08_STAKE_NEW_TOKENS, TEMPLATE_HASH_TH08_STAKE_NEW_TOKENS_MAINNET}, - - {SCRIPT_TH09_RESTAKE_UNSTAKED_TOKENS, TEMPLATE_HASH_TH09_RESTAKE_UNSTAKED_TOKENS_TESTNET}, - {SCRIPT_TH09_RESTAKE_UNSTAKED_TOKENS, TEMPLATE_HASH_TH09_RESTAKE_UNSTAKED_TOKENS_MAINNET}, - - {SCRIPT_TH10_RESTAKE_REWARDED_TOKENS, TEMPLATE_HASH_TH10_RESTAKE_REWARDED_TOKENS_TESTNET}, - {SCRIPT_TH10_RESTAKE_REWARDED_TOKENS, TEMPLATE_HASH_TH10_RESTAKE_REWARDED_TOKENS_MAINNET}, - - {SCRIPT_TH11_UNSTAKE_TOKENS, TEMPLATE_HASH_TH11_UNSTAKE_TOKENS_TESTNET}, - {SCRIPT_TH11_UNSTAKE_TOKENS, TEMPLATE_HASH_TH11_UNSTAKE_TOKENS_MAINNET}, - - {SCRIPT_TH12_UNSTAKE_ALL_TOKENS, TEMPLATE_HASH_TH12_UNSTAKE_ALL_TOKENS_TESTNET}, - {SCRIPT_TH12_UNSTAKE_ALL_TOKENS, TEMPLATE_HASH_TH12_UNSTAKE_ALL_TOKENS_MAINNET}, - - {SCRIPT_TH13_WITHDRAW_UNSTAKED_TOKENS, TEMPLATE_HASH_TH13_WITHDRAW_UNSTAKED_TOKENS_TESTNET}, - {SCRIPT_TH13_WITHDRAW_UNSTAKED_TOKENS, TEMPLATE_HASH_TH13_WITHDRAW_UNSTAKED_TOKENS_MAINNET}, - - {SCRIPT_TH14_WITHDRAW_REWARDED_TOKENS, TEMPLATE_HASH_TH14_WITHDRAW_REWARDED_TOKENS_TESTNET}, - {SCRIPT_TH14_WITHDRAW_REWARDED_TOKENS, TEMPLATE_HASH_TH14_WITHDRAW_REWARDED_TOKENS_MAINNET}, - - {SCRIPT_TH16_REGISTER_OPERATOR_NODE, TEMPLATE_HASH_TH16_REGISTER_OPERATOR_NODE_TESTNET}, - {SCRIPT_TH16_REGISTER_OPERATOR_NODE, TEMPLATE_HASH_TH16_REGISTER_OPERATOR_NODE_MAINNET}, - - {SCRIPT_TH17_REGISTER_DELEGATOR, TEMPLATE_HASH_TH17_REGISTER_DELEGATOR_TESTNET}, - {SCRIPT_TH17_REGISTER_DELEGATOR, TEMPLATE_HASH_TH17_REGISTER_DELEGATOR_MAINNET}, - - {SCRIPT_TH19_DELEGATE_NEW_TOKENS, TEMPLATE_HASH_TH19_DELEGATE_NEW_TOKENS_TESTNET}, - {SCRIPT_TH19_DELEGATE_NEW_TOKENS, TEMPLATE_HASH_TH19_DELEGATE_NEW_TOKENS_MAINNET}, - - {SCRIPT_TH20_RESTAKE_UNSTAKED_DELEGATED_TOKENS, TEMPLATE_HASH_TH20_RESTAKE_UNSTAKED_DELEGATED_TOKENS_TESTNET}, - {SCRIPT_TH20_RESTAKE_UNSTAKED_DELEGATED_TOKENS, TEMPLATE_HASH_TH20_RESTAKE_UNSTAKED_DELEGATED_TOKENS_MAINNET}, - - {SCRIPT_TH21_RESTAKE_REWARDED_DELEGATED_TOKENS, TEMPLATE_HASH_TH21_RESTAKE_REWARDED_DELEGATED_TOKENS_TESTNET}, - {SCRIPT_TH21_RESTAKE_REWARDED_DELEGATED_TOKENS, TEMPLATE_HASH_TH21_RESTAKE_REWARDED_DELEGATED_TOKENS_MAINNET}, - - {SCRIPT_TH22_UNSTAKE_DELEGATED_TOKENS, TEMPLATE_HASH_TH22_UNSTAKE_DELEGATED_TOKENS_TESTNET}, - {SCRIPT_TH22_UNSTAKE_DELEGATED_TOKENS, TEMPLATE_HASH_TH22_UNSTAKE_DELEGATED_TOKENS_MAINNET}, - - {SCRIPT_TH23_WITHDRAW_UNSTAKED_DELEGATED_TOKENS, TEMPLATE_HASH_TH23_WITHDRAW_UNSTAKED_DELEGATED_TOKENS_TESTNET}, - {SCRIPT_TH23_WITHDRAW_UNSTAKED_DELEGATED_TOKENS, TEMPLATE_HASH_TH23_WITHDRAW_UNSTAKED_DELEGATED_TOKENS_MAINNET}, - - {SCRIPT_TH24_WITHDRAW_REWARDED_DELEGATED_TOKENS, TEMPLATE_HASH_TH24_WITHDRAW_REWARDED_DELEGATED_TOKENS_TESTNET}, - {SCRIPT_TH24_WITHDRAW_REWARDED_DELEGATED_TOKENS, TEMPLATE_HASH_TH24_WITHDRAW_REWARDED_DELEGATED_TOKENS_MAINNET}, - - {SCRIPT_TH25_UPDATE_NETWORKING_ADDRESS, TEMPLATE_HASH_TH25_UPDATE_NETWORKING_ADDRESS_TESTNET}, - {SCRIPT_TH25_UPDATE_NETWORKING_ADDRESS, TEMPLATE_HASH_TH25_UPDATE_NETWORKING_ADDRESS_MAINNET}, - - {SCRIPT_SCO01_SETUP_STAKING_COLLECTION, TEMPLATE_HASH_SCO01_SETUP_STAKING_COLLECTION_TESTNET}, - {SCRIPT_SCO01_SETUP_STAKING_COLLECTION, TEMPLATE_HASH_SCO01_SETUP_STAKING_COLLECTION_MAINNET}, - - {SCRIPT_SCO02_REGISTER_DELEGATOR, TEMPLATE_HASH_SCO02_REGISTER_DELEGATOR_TESTNET}, - {SCRIPT_SCO02_REGISTER_DELEGATOR, TEMPLATE_HASH_SCO02_REGISTER_DELEGATOR_MAINNET}, - - {SCRIPT_SCO03_REGISTER_NODE, TEMPLATE_HASH_SCO0301_REGISTER_NODE_TESTNET}, - {SCRIPT_SCO03_REGISTER_NODE, TEMPLATE_HASH_SCO0301_REGISTER_NODE_MAINNET}, - - {SCRIPT_SCO04_CREATE_MACHINE_ACCOUNT, TEMPLATE_HASH_SCO0401_CREATE_MACHINE_ACCOUNT_TESTNET}, - {SCRIPT_SCO04_CREATE_MACHINE_ACCOUNT, TEMPLATE_HASH_SCO0401_CREATE_MACHINE_ACCOUNT_MAINNET}, - - {SCRIPT_SCO05_REQUEST_UNSTAKING, TEMPLATE_HASH_SCO05_REQUEST_UNSTAKING_TESTNET}, - {SCRIPT_SCO05_REQUEST_UNSTAKING, TEMPLATE_HASH_SCO05_REQUEST_UNSTAKING_MAINNET}, - - {SCRIPT_SCO06_STAKE_NEW_TOKENS, TEMPLATE_HASH_SCO06_STAKE_NEW_TOKENS_TESTNET}, - {SCRIPT_SCO06_STAKE_NEW_TOKENS, TEMPLATE_HASH_SCO06_STAKE_NEW_TOKENS_MAINNET}, - - {SCRIPT_SCO07_STAKE_REWARD_TOKENS, TEMPLATE_HASH_SCO07_STAKE_REWARD_TOKENS_TESTNET}, - {SCRIPT_SCO07_STAKE_REWARD_TOKENS, TEMPLATE_HASH_SCO07_STAKE_REWARD_TOKENS_MAINNET}, - - {SCRIPT_SCO08_STAKE_UNSTAKED_TOKENS, TEMPLATE_HASH_SCO08_STAKE_UNSTAKED_TOKENS_TESTNET}, - {SCRIPT_SCO08_STAKE_UNSTAKED_TOKENS, TEMPLATE_HASH_SCO08_STAKE_UNSTAKED_TOKENS_MAINNET}, - - {SCRIPT_SCO09_UNSTAKE_ALL, TEMPLATE_HASH_SCO09_UNSTAKE_ALL_TESTNET}, - {SCRIPT_SCO09_UNSTAKE_ALL, TEMPLATE_HASH_SCO09_UNSTAKE_ALL_MAINNET}, - - {SCRIPT_SCO10_WITHDRAW_REWARD_TOKENS, TEMPLATE_HASH_SCO10_WITHDRAW_REWARD_TOKENS_TESTNET}, - {SCRIPT_SCO10_WITHDRAW_REWARD_TOKENS, TEMPLATE_HASH_SCO10_WITHDRAW_REWARD_TOKENS_MAINNET}, - - {SCRIPT_SCO11_WITHDRAW_UNSTAKED_TOKENS, TEMPLATE_HASH_SCO11_WITHDRAW_UNSTAKED_TOKENS_TESTNET}, - {SCRIPT_SCO11_WITHDRAW_UNSTAKED_TOKENS, TEMPLATE_HASH_SCO11_WITHDRAW_UNSTAKED_TOKENS_MAINNET}, - - {SCRIPT_SCO12_CLOSE_STAKE, TEMPLATE_HASH_SCO12_CLOSE_STAKE_TESTNET}, - {SCRIPT_SCO12_CLOSE_STAKE, TEMPLATE_HASH_SCO12_CLOSE_STAKE_MAINNET}, - - {SCRIPT_SCO13_TRANSFER_NODE, TEMPLATE_HASH_SCO13_TRANSFER_NODE_TESTNET}, - {SCRIPT_SCO13_TRANSFER_NODE, TEMPLATE_HASH_SCO13_TRANSFER_NODE_MAINNET}, - - {SCRIPT_SCO14_TRANSFER_DELEGATOR, TEMPLATE_HASH_SCO14_TRANSFER_DELEGATOR_TESTNET}, - {SCRIPT_SCO14_TRANSFER_DELEGATOR, TEMPLATE_HASH_SCO14_TRANSFER_DELEGATOR_MAINNET}, - - {SCRIPT_SCO15_WITHDRAW_FROM_MACHINE_ACCOUNT, TEMPLATE_HASH_SCO15_WITHDRAW_FROM_MACHINE_ACCOUNT_TESTNET}, - {SCRIPT_SCO15_WITHDRAW_FROM_MACHINE_ACCOUNT, TEMPLATE_HASH_SCO15_WITHDRAW_FROM_MACHINE_ACCOUNT_MAINNET}, - - {SCRIPT_SCO16_UPDATE_NETWORKING_ADDRESS, TEMPLATE_HASH_SCO16_UPDATE_NETWORKING_ADDRESS_TESTNET}, - {SCRIPT_SCO16_UPDATE_NETWORKING_ADDRESS, TEMPLATE_HASH_SCO16_UPDATE_NETWORKING_ADDRESS_MAINNET}, - - {SCRIPT_FUSD01_SETUP_FUSD_VAULT, TEMPLATE_HASH_FUSD01_SETUP_FUSD_VAULT_TESTNET}, - {SCRIPT_FUSD01_SETUP_FUSD_VAULT, TEMPLATE_HASH_FUSD01_SETUP_FUSD_VAULT_MAINNET}, - - {SCRIPT_FUSD02_TRANSFER_FUSD, TEMPLATE_HASH_FUSD02_TRANSFER_FUSD_TESTNET}, - {SCRIPT_FUSD02_TRANSFER_FUSD, TEMPLATE_HASH_FUSD02_TRANSFER_FUSD_MAINNET}, - - {SCRIPT_TS01_SET_UP_TOPSHOT_COLLECTION, TEMPLATE_HASH_TS01_SET_UP_TOPSHOT_COLLECTION_TESTNET}, - {SCRIPT_TS01_SET_UP_TOPSHOT_COLLECTION, TEMPLATE_HASH_TS01_SET_UP_TOPSHOT_COLLECTION_MAINNET}, - - {SCRIPT_TS02_TRANSFER_TOP_SHOT_MOMENT, TEMPLATE_HASH_TS02_TRANSFER_TOP_SHOT_MOMENT_TESTNET}, - {SCRIPT_TS02_TRANSFER_TOP_SHOT_MOMENT, TEMPLATE_HASH_TS02_TRANSFER_TOP_SHOT_MOMENT_MAINNET}, - - {SCRIPT_USDC01_SETUP_USDC_VAULT, TEMPLATE_HASH_USDC01_SETUP_USDC_VAULT_TESTNET}, - {SCRIPT_USDC01_SETUP_USDC_VAULT, TEMPLATE_HASH_USDC01_SETUP_USDC_VAULT_MAINNET}, - - {SCRIPT_USDC02_TRANSFER_USDC, TEMPLATE_HASH_USDC02_TRANSFER_USDC_TESTNET}, - {SCRIPT_USDC02_TRANSFER_USDC, TEMPLATE_HASH_USDC02_TRANSFER_USDC_MAINNET}, - - {SCRIPT_SCO03_REGISTER_NODE, TEMPLATE_HASH_SCO0302_REGISTER_NODE_TESTNET}, - {SCRIPT_SCO03_REGISTER_NODE, TEMPLATE_HASH_SCO0302_REGISTER_NODE_MAINNET}, - - {SCRIPT_SCO04_CREATE_MACHINE_ACCOUNT, TEMPLATE_HASH_SCO0402_CREATE_MACHINE_ACCOUNT_TESTNET}, - {SCRIPT_SCO04_CREATE_MACHINE_ACCOUNT, TEMPLATE_HASH_SCO0402_CREATE_MACHINE_ACCOUNT_MAINNET}, - - // sentinel, do not remove - {0, NULL} - }; - - int i = 0; - while (KNOWN_TYPES[i].template) { - if (MEMCMP(PIC(KNOWN_TYPES[i].template), buffer, 64) == 0) { - *scriptType = KNOWN_TYPES[i].script_type; - return PARSER_OK; - } - i++; - } - - return PARSER_UNEXPECTED_SCRIPT; -} - -parser_error_t _readScript(parser_context_t *c, flow_script_t *v) { +parser_error_t _readScript(parser_context_t *c, parsed_tx_metadata_t *m) { rlp_kind_e kind; + parser_context_t script; uint32_t bytesConsumed; + uint8_t digest[CX_SHA256_SIZE]; - MEMZERO(v, sizeof(flow_script_t)); - - CHECK_PARSER_ERR(rlp_decode(c, &v->ctx, &kind, &bytesConsumed)); + CHECK_PARSER_ERR(rlp_decode(c, &script, &kind, &bytesConsumed)); CTX_CHECK_AND_ADVANCE(c, bytesConsumed) CHECK_KIND(kind, RLP_KIND_STRING) - MEMZERO(v->digest, sizeof(v->digest)); - sha256(v->ctx.buffer, v->ctx.bufferLen, v->digest); + MEMZERO(digest, sizeof(digest)); + sha256(script.buffer, script.bufferLen, digest); - CHECK_PARSER_ERR(_matchScriptType(v->digest, &v->type)) + MEMZERO(m, sizeof(parsed_tx_metadata_t)); + CHECK_PARSER_ERR(matchStoredTxMetadata(digest, m)) return PARSER_OK; } @@ -686,7 +523,7 @@ parser_error_t _read(parser_context_t *c, parser_tx_t *v) { CHECK_KIND(kind, RLP_KIND_LIST) // Go through the inner list - CHECK_PARSER_ERR(_readScript(&ctx_rootInnerList, &v->script)) + CHECK_PARSER_ERR(_readScript(&ctx_rootInnerList, &v->metadata)) CHECK_PARSER_ERR(_readArguments(&ctx_rootInnerList, &v->arguments)) CHECK_PARSER_ERR(_readReferenceBlockId(&ctx_rootInnerList, &v->referenceBlockId)) CHECK_PARSER_ERR(_readGasLimit(&ctx_rootInnerList, &v->gasLimit)) @@ -713,7 +550,7 @@ parser_error_t _validateTx(__Z_UNUSED const parser_context_t *c, __Z_UNUSED cons } parser_error_t _countArgumentItems(const flow_argument_list_t *v, uint8_t argumentIndex, - uint8_t max_number_of_items, uint8_t *number_of_items) { + uint8_t min_number_of_items, uint8_t max_number_of_items, uint8_t *number_of_items) { *number_of_items = 0; parsed_json_t parsedJson = {false}; @@ -729,7 +566,7 @@ parser_error_t _countArgumentItems(const flow_argument_list_t *v, uint8_t argume CHECK_PARSER_ERR(json_matchKeyValue(&parsedJson, 0, (char *) "Array", JSMN_ARRAY, &internalTokenElementIdx)); uint16_t arrayTokenCount; CHECK_PARSER_ERR(array_get_element_count(&parsedJson, internalTokenElementIdx, &arrayTokenCount)); - if (arrayTokenCount > max_number_of_items) { + if (arrayTokenCount < min_number_of_items || arrayTokenCount > max_number_of_items) { return PARSER_UNEXPECTED_NUMBER_ITEMS; } @@ -739,7 +576,7 @@ parser_error_t _countArgumentItems(const flow_argument_list_t *v, uint8_t argume //if Optional is null, number_of_items is set to 1 as one screen is needed to dispay "None" parser_error_t _countArgumentOptionalItems(const flow_argument_list_t *v, uint8_t argumentIndex, - uint8_t max_number_of_items, uint8_t *number_of_items) { + uint8_t min_number_of_items, uint8_t max_number_of_items, uint8_t *number_of_items) { *number_of_items = 0; parsed_json_t parsedJson = {false}; @@ -760,7 +597,7 @@ parser_error_t _countArgumentOptionalItems(const flow_argument_list_t *v, uint8_ // Get numnber of items uint16_t arrayTokenCount; CHECK_PARSER_ERR(array_get_element_count(&parsedJson, internalTokenElementIdx, &arrayTokenCount)); - if (arrayTokenCount > max_number_of_items) { + if (arrayTokenCount < min_number_of_items || arrayTokenCount > max_number_of_items) { return PARSER_UNEXPECTED_NUMBER_ITEMS; } @@ -768,161 +605,6 @@ parser_error_t _countArgumentOptionalItems(const flow_argument_list_t *v, uint8_ return PARSER_OK; } -parser_error_t _getNumItems(__Z_UNUSED const parser_context_t *c, const parser_tx_t *v, uint8_t *numItems) { - uint8_t argArrayLength = 0; - - uint8_t show_address_yes = (show_address == SHOW_ADDRESS_YES || show_address == SHOW_ADDRESS_YES_HASH_MISMATCH); - uint8_t extraItems = v->authorizers.authorizer_count; - extraItems += (show_address_yes && !addressUsedInTx) ? 1 : 0; - extraItems += (show_address == SHOW_ADDRESS_YES_HASH_MISMATCH) ? 1 : 0; - extraItems += show_address_yes ? 0 : 1; - extraItems += app_mode_expert() ? 1 : 0; - - switch (v->script.type) { - case SCRIPT_TOKEN_TRANSFER: - *numItems = 10 + extraItems; - return PARSER_OK; - case SCRIPT_CREATE_ACCOUNT: - //array length is checked while we are parsing it - CHECK_PARSER_ERR(_countArgumentItems(&v->arguments, 0, UINT8_MAX, &argArrayLength)) - *numItems = 8 + argArrayLength + extraItems; - return PARSER_OK; - case SCRIPT_ADD_NEW_KEY: - *numItems = 9 + extraItems; - return PARSER_OK; - case SCRIPT_TH01_WITHDRAW_UNLOCKED_TOKENS: - *numItems = 9 + extraItems; - return PARSER_OK; - case SCRIPT_TH02_DEPOSIT_UNLOCKED_TOKENS: - *numItems = 9 + extraItems; - return PARSER_OK; - case SCRIPT_TH06_REGISTER_NODE: - *numItems = 14 + extraItems; - return PARSER_OK; - case SCRIPT_TH08_STAKE_NEW_TOKENS: - *numItems = 9 + extraItems; - return PARSER_OK; - case SCRIPT_TH09_RESTAKE_UNSTAKED_TOKENS: - *numItems = 9 + extraItems; - return PARSER_OK; - case SCRIPT_TH10_RESTAKE_REWARDED_TOKENS: - *numItems = 9 + extraItems; - return PARSER_OK; - case SCRIPT_TH11_UNSTAKE_TOKENS: - *numItems = 9 + extraItems; - return PARSER_OK; - case SCRIPT_TH12_UNSTAKE_ALL_TOKENS: - *numItems = 8 + extraItems; - return PARSER_OK; - case SCRIPT_TH13_WITHDRAW_UNSTAKED_TOKENS: - *numItems = 9 + extraItems; - return PARSER_OK; - case SCRIPT_TH14_WITHDRAW_REWARDED_TOKENS: - *numItems = 9 + extraItems; - return PARSER_OK; - case SCRIPT_TH16_REGISTER_OPERATOR_NODE: - *numItems = 11 + extraItems; - return PARSER_OK; - case SCRIPT_TH17_REGISTER_DELEGATOR: - *numItems = 10 + extraItems; - return PARSER_OK; - case SCRIPT_TH19_DELEGATE_NEW_TOKENS: - *numItems = 9 + extraItems; - return PARSER_OK; - case SCRIPT_TH20_RESTAKE_UNSTAKED_DELEGATED_TOKENS: - *numItems = 9 + extraItems; - return PARSER_OK; - case SCRIPT_TH21_RESTAKE_REWARDED_DELEGATED_TOKENS: - *numItems = 9 + extraItems; - return PARSER_OK; - case SCRIPT_TH22_UNSTAKE_DELEGATED_TOKENS: - *numItems = 9 + extraItems; - return PARSER_OK; - case SCRIPT_TH23_WITHDRAW_UNSTAKED_DELEGATED_TOKENS: - *numItems = 9 + extraItems; - return PARSER_OK; - case SCRIPT_TH24_WITHDRAW_REWARDED_DELEGATED_TOKENS: - *numItems = 9 + extraItems; - return PARSER_OK; - case SCRIPT_TH25_UPDATE_NETWORKING_ADDRESS: - *numItems = 9 + extraItems; - return PARSER_OK; - case SCRIPT_SCO01_SETUP_STAKING_COLLECTION: - *numItems = 8 + extraItems; - return PARSER_OK; - case SCRIPT_SCO02_REGISTER_DELEGATOR: - *numItems = 10 + extraItems; - return PARSER_OK; - case SCRIPT_SCO03_REGISTER_NODE: - //array length is checked while we are parsing it - CHECK_PARSER_ERR(_countArgumentOptionalItems(&v->arguments, 6, UINT8_MAX, &argArrayLength)); - *numItems = 14 + argArrayLength + extraItems; - return PARSER_OK; - case SCRIPT_SCO04_CREATE_MACHINE_ACCOUNT: - //array length is checked while we are parsing it - CHECK_PARSER_ERR(_countArgumentItems(&v->arguments, 1, UINT8_MAX, &argArrayLength)) - *numItems = 9 + argArrayLength + extraItems; - return PARSER_OK; - case SCRIPT_SCO05_REQUEST_UNSTAKING: - *numItems = 11 + extraItems; - return PARSER_OK; - case SCRIPT_SCO06_STAKE_NEW_TOKENS: - *numItems = 11 + extraItems; - return PARSER_OK; - case SCRIPT_SCO07_STAKE_REWARD_TOKENS: - *numItems = 11 + extraItems; - return PARSER_OK; - case SCRIPT_SCO08_STAKE_UNSTAKED_TOKENS: - *numItems = 11 + extraItems; - return PARSER_OK; - case SCRIPT_SCO09_UNSTAKE_ALL: - *numItems = 9 + extraItems; - return PARSER_OK; - case SCRIPT_SCO10_WITHDRAW_REWARD_TOKENS: - *numItems = 11 + extraItems; - return PARSER_OK; - case SCRIPT_SCO11_WITHDRAW_UNSTAKED_TOKENS: - *numItems = 11 + extraItems; - return PARSER_OK; - case SCRIPT_SCO12_CLOSE_STAKE: - *numItems = 10 + extraItems; - return PARSER_OK; - case SCRIPT_SCO13_TRANSFER_NODE: - *numItems = 10 + extraItems; - return PARSER_OK; - case SCRIPT_SCO14_TRANSFER_DELEGATOR: - *numItems = 11 + extraItems; - return PARSER_OK; - case SCRIPT_SCO15_WITHDRAW_FROM_MACHINE_ACCOUNT: - *numItems = 10 + extraItems; - return PARSER_OK; - case SCRIPT_SCO16_UPDATE_NETWORKING_ADDRESS: - *numItems = 10 + extraItems; - return PARSER_OK; - case SCRIPT_FUSD01_SETUP_FUSD_VAULT: - *numItems = 8 + extraItems; - return PARSER_OK; - case SCRIPT_FUSD02_TRANSFER_FUSD: - *numItems = 10 + extraItems; - return PARSER_OK; - case SCRIPT_TS01_SET_UP_TOPSHOT_COLLECTION: - *numItems = 8 + extraItems; - return PARSER_OK; - case SCRIPT_TS02_TRANSFER_TOP_SHOT_MOMENT: - *numItems = 10 + extraItems; - return PARSER_OK; - case SCRIPT_USDC01_SETUP_USDC_VAULT: - *numItems = 8 + extraItems; - return PARSER_OK; - case SCRIPT_USDC02_TRANSFER_USDC: - *numItems = 10 + extraItems; - return PARSER_OK; - case SCRIPT_UNKNOWN: - default: - return PARSER_UNEXPECTED_SCRIPT; - } -} - void checkAddressUsedInTx() { addressUsedInTx = 0; int authCount = parser_tx_obj.authorizers.authorizer_count; diff --git a/app/src/parser_impl.h b/app/src/parser_impl.h index 13b4ec6a..7d6bae2c 100644 --- a/app/src/parser_impl.h +++ b/app/src/parser_impl.h @@ -30,22 +30,18 @@ extern parser_tx_t parser_tx_obj; parser_error_t parser_init(parser_context_t *ctx, const uint8_t *buffer, uint16_t bufferSize); -parser_error_t _matchScriptType(uint8_t scriptHash[32], script_type_e *scriptType); - parser_error_t _read(parser_context_t *c, parser_tx_t *v); parser_error_t _validateTx(const parser_context_t *c, const parser_tx_t *v); -parser_error_t _getNumItems(const parser_context_t *c, const parser_tx_t *v, uint8_t *numItems); - //Called when argumentIndex-th argument is an array. If the array length is more than max_number_of_items //returns parser error, otherwise it sets number_of_items as the array length. parser_error_t _countArgumentItems(const flow_argument_list_t *v, uint8_t argumentIndex, - uint8_t max_number_of_items, uint8_t *number_of_items); + uint8_t min_number_of_items, uint8_t max_number_of_items, uint8_t *number_of_items); //Same as _countArgumentItems, but the array is optional. parser_error_t _countArgumentOptionalItems(const flow_argument_list_t *v, uint8_t argumentIndex, - uint8_t max_number_of_items, uint8_t *number_of_items); + uint8_t min_number_of_items, uint8_t max_number_of_items, uint8_t *number_of_items); parser_error_t json_validateToken(const parsed_json_t *parsedJson, uint16_t tokenIdx); diff --git a/app/src/parser_txdef.h b/app/src/parser_txdef.h index 6f006de0..e998330b 100644 --- a/app/src/parser_txdef.h +++ b/app/src/parser_txdef.h @@ -24,60 +24,10 @@ extern "C" { #endif +#include #include #include #include "crypto.h" -#include "template_hashes.h" - -#define PARSER_MAX_ARGCOUNT 10 - -typedef enum { - SCRIPT_UNKNOWN, - SCRIPT_TOKEN_TRANSFER, - SCRIPT_CREATE_ACCOUNT, - SCRIPT_ADD_NEW_KEY, - SCRIPT_TH01_WITHDRAW_UNLOCKED_TOKENS, - SCRIPT_TH02_DEPOSIT_UNLOCKED_TOKENS, - SCRIPT_TH06_REGISTER_NODE, - SCRIPT_TH08_STAKE_NEW_TOKENS, - SCRIPT_TH09_RESTAKE_UNSTAKED_TOKENS, - SCRIPT_TH10_RESTAKE_REWARDED_TOKENS, - SCRIPT_TH11_UNSTAKE_TOKENS, - SCRIPT_TH12_UNSTAKE_ALL_TOKENS, - SCRIPT_TH13_WITHDRAW_UNSTAKED_TOKENS, - SCRIPT_TH14_WITHDRAW_REWARDED_TOKENS, - SCRIPT_TH16_REGISTER_OPERATOR_NODE, - SCRIPT_TH17_REGISTER_DELEGATOR, - SCRIPT_TH19_DELEGATE_NEW_TOKENS, - SCRIPT_TH20_RESTAKE_UNSTAKED_DELEGATED_TOKENS, - SCRIPT_TH21_RESTAKE_REWARDED_DELEGATED_TOKENS, - SCRIPT_TH22_UNSTAKE_DELEGATED_TOKENS, - SCRIPT_TH23_WITHDRAW_UNSTAKED_DELEGATED_TOKENS, - SCRIPT_TH24_WITHDRAW_REWARDED_DELEGATED_TOKENS, - SCRIPT_TH25_UPDATE_NETWORKING_ADDRESS, - SCRIPT_SCO01_SETUP_STAKING_COLLECTION, - SCRIPT_SCO02_REGISTER_DELEGATOR, - SCRIPT_SCO03_REGISTER_NODE, - SCRIPT_SCO04_CREATE_MACHINE_ACCOUNT, - SCRIPT_SCO05_REQUEST_UNSTAKING, - SCRIPT_SCO06_STAKE_NEW_TOKENS, - SCRIPT_SCO07_STAKE_REWARD_TOKENS, - SCRIPT_SCO08_STAKE_UNSTAKED_TOKENS, - SCRIPT_SCO09_UNSTAKE_ALL, - SCRIPT_SCO10_WITHDRAW_REWARD_TOKENS, - SCRIPT_SCO11_WITHDRAW_UNSTAKED_TOKENS, - SCRIPT_SCO12_CLOSE_STAKE, - SCRIPT_SCO13_TRANSFER_NODE, - SCRIPT_SCO14_TRANSFER_DELEGATOR, - SCRIPT_SCO15_WITHDRAW_FROM_MACHINE_ACCOUNT, - SCRIPT_SCO16_UPDATE_NETWORKING_ADDRESS, - SCRIPT_FUSD01_SETUP_FUSD_VAULT, - SCRIPT_FUSD02_TRANSFER_FUSD, - SCRIPT_TS01_SET_UP_TOPSHOT_COLLECTION, - SCRIPT_TS02_TRANSFER_TOP_SHOT_MOMENT, - SCRIPT_USDC01_SETUP_USDC_VAULT, - SCRIPT_USDC02_TRANSFER_USDC, -} script_type_e; typedef enum { CHAIN_ID_UNKNOWN, @@ -86,12 +36,6 @@ typedef enum { CHAIN_ID_MAINNET, } chain_id_e; -typedef struct { - parser_context_t ctx; - uint8_t digest[CX_SHA256_SIZE]; - script_type_e type; -} flow_script_t; - typedef struct { parser_context_t ctx; } flow_reference_block_id_t; @@ -127,7 +71,7 @@ typedef struct { } flow_proposal_authorizers_t; typedef struct { - flow_script_t script; + parsed_tx_metadata_t metadata; flow_argument_list_t arguments; flow_reference_block_id_t referenceBlockId; flow_gaslimit_t gasLimit; diff --git a/app/src/template_hashes.h b/app/src/template_hashes.h deleted file mode 100644 index ef5ff06b..00000000 --- a/app/src/template_hashes.h +++ /dev/null @@ -1,160 +0,0 @@ -/******************************************************************************* -* (c) 2019 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#define TEMPLATE_HASH_CREATE_ACCOUNT "eef2d0494448554177612e63026256258339230cbc6931ded78d6149443c6173" -#define TEMPLATE_HASH_ADD_NEW_KEY "595c86561441b32b2b91ee03f9e10ca6efa7b41bcc994f51317ec0aa9d8f8a42" - -#define TEMPLATE_HASH_TOKEN_TRANSFER_EMULATOR "ca80b628d985b358ae1cb136bcd976997c942fa10dbabfeafb4e20fa66a5a5e2" -#define TEMPLATE_HASH_TOKEN_TRANSFER_TESTNET "d56f4e1d2355cdcfacfd01e471459c6ef168bfdf84371a685ccf31cf3cdedc2d" -#define TEMPLATE_HASH_TOKEN_TRANSFER_MAINNET "47851586d962335e3f7d9e5d11a4c527ee4b5fd1c3895e3ce1b9c2821f60b166" - -#define TEMPLATE_HASH_TH01_WITHDRAW_UNLOCKED_TOKENS_TESTNET "6e73db6edd0190f5311f6adc5f2b1f27e9e60c68574b00ee90da867da52cdbb1" -#define TEMPLATE_HASH_TH01_WITHDRAW_UNLOCKED_TOKENS_MAINNET "a2146e3e6e7718779ce59376b88760c154d82b7d132fe2c377114ec7cf434e7b" - -#define TEMPLATE_HASH_TH02_DEPOSIT_UNLOCKED_TOKENS_TESTNET "0cb11c10b86d2afeae086ef511d28b14760eb854935a0b0dcfeecc85db847f48" -#define TEMPLATE_HASH_TH02_DEPOSIT_UNLOCKED_TOKENS_MAINNET "74355dc8df221bc0d170b2fe8deacd6f1f554d6beea58ad9fee7a07f740eaefe" - -#define TEMPLATE_HASH_TH06_REGISTER_NODE_TESTNET "b6a3502d2205eb05ec18772c13b91cc88a056b325c2617c57948d38cab8db600" -#define TEMPLATE_HASH_TH06_REGISTER_NODE_MAINNET "b64e0e3ed9eb28789198f2b0437f55f750bfa76da99450f63be6543bde66122a" - -#define TEMPLATE_HASH_TH08_STAKE_NEW_TOKENS_TESTNET "d5689b89f53214e7ce9ba7be2bb651961f7e3036b85f9250494290da9e9ba989" -#define TEMPLATE_HASH_TH08_STAKE_NEW_TOKENS_MAINNET "1929e4f38894b8641848a3c0a3b9d35495b35083d42e8a3d4c928b9db4174ee8" - -#define TEMPLATE_HASH_TH09_RESTAKE_UNSTAKED_TOKENS_TESTNET "23e5bfd594bb3245090e3e0bafb9cb9246fc84d30e4a35a7fde1b51085624d86" -#define TEMPLATE_HASH_TH09_RESTAKE_UNSTAKED_TOKENS_MAINNET "677cc0ac3962ec136ca26dbec0aa942d926640ecf8418433f0db4b7925f5d0fe" - -#define TEMPLATE_HASH_TH10_RESTAKE_REWARDED_TOKENS_TESTNET "239319825ad68178e76465b5ea18cb43f06c4ee11341f8fe9424809163a027a5" -#define TEMPLATE_HASH_TH10_RESTAKE_REWARDED_TOKENS_MAINNET "28d1719c5b21c88c62665db5ba04886809f3234c27057b057c36d5f265ee9de4" - -#define TEMPLATE_HASH_TH11_UNSTAKE_TOKENS_TESTNET "33e3977c45e7c23c1472bcf334d00b03ebf91b06b67c57b63b562c7b1ff5c59f" -#define TEMPLATE_HASH_TH11_UNSTAKE_TOKENS_MAINNET "4e2a35541453f89c55e5dc6dbc963290380d779c81df0b3bf89c29b2a8d7a9fe" - -#define TEMPLATE_HASH_TH12_UNSTAKE_ALL_TOKENS_TESTNET "f92c4cd663b2e335cd821a656bb2ebcf239b222036a7825af5e512fad4d82035" -#define TEMPLATE_HASH_TH12_UNSTAKE_ALL_TOKENS_MAINNET "7099904b953b062e81e2575a2c2081b3d98bfccf5c743b4bdb224b937e292dad" - -#define TEMPLATE_HASH_TH13_WITHDRAW_UNSTAKED_TOKENS_TESTNET "90097e3aff9b67f65bbada3cdedbb73d45d093ff333aaaff38809bf9910a3e39" -#define TEMPLATE_HASH_TH13_WITHDRAW_UNSTAKED_TOKENS_MAINNET "dcae4faa6d689873f7caf7c5efef669f9fe1d4113e58b474b7aec1e07113a7ff" - -#define TEMPLATE_HASH_TH14_WITHDRAW_REWARDED_TOKENS_TESTNET "f23406ff402f02418629432912ce732be0441b1a7e71f16c03d688a165ff7f49" -#define TEMPLATE_HASH_TH14_WITHDRAW_REWARDED_TOKENS_MAINNET "9bb8f0562eea5e45c11f9289540f39c99a21c9a0fb060a7d3f832e98c2696f2d" - -#define TEMPLATE_HASH_TH16_REGISTER_OPERATOR_NODE_TESTNET "c29d4024aaeb71ab478182542499e0ba3d5d303ec027252e3b8333515ee3de48" -#define TEMPLATE_HASH_TH16_REGISTER_OPERATOR_NODE_MAINNET "97b3436482c5aefc1baf8b850e92c829202e468c57241dec707b6c27bd89d15c" - -#define TEMPLATE_HASH_TH17_REGISTER_DELEGATOR_TESTNET "1378405c85e0c966344b196c0fce602f39e79f3938ec7b689e0c96a8703b018a" -#define TEMPLATE_HASH_TH17_REGISTER_DELEGATOR_MAINNET "3cb357a97a57d9abbe5c68f0df342ee96ba97ade2013753fd2ddf47695a8c08a" - -#define TEMPLATE_HASH_TH19_DELEGATE_NEW_TOKENS_TESTNET "18fad68368a4394b245db91217d7dc979e1316ab757388d416eaef831f565ab3" -#define TEMPLATE_HASH_TH19_DELEGATE_NEW_TOKENS_MAINNET "802354d8b3e7908e584bcb5217637fb9f4ef045427c32d57d81ad4a390ed1a60" - -#define TEMPLATE_HASH_TH20_RESTAKE_UNSTAKED_DELEGATED_TOKENS_TESTNET "8776b1521b04395754734f8f40d4a0482863274f8d832973d9e011b3cbb48c85" -#define TEMPLATE_HASH_TH20_RESTAKE_UNSTAKED_DELEGATED_TOKENS_MAINNET "2027331b72d8710a1a05feb6ecebadb5858d134bc8c95d6f261319cd9fa1bb95" - -#define TEMPLATE_HASH_TH21_RESTAKE_REWARDED_DELEGATED_TOKENS_TESTNET "6b40ffc9169abd75107a45da5974c7e502d38773275abb231d747e4760b7ebee" -#define TEMPLATE_HASH_TH21_RESTAKE_REWARDED_DELEGATED_TOKENS_MAINNET "864edbff384335ef21c26b3bcf17d36b2b1d894afbe2b203f58099cc457971e4" - -#define TEMPLATE_HASH_TH22_UNSTAKE_DELEGATED_TOKENS_TESTNET "61cbcd1c31bbfc9ceb4a5ac726e2f8b3d845a4fdf59b0ab23cbbfa8f16d7a024" -#define TEMPLATE_HASH_TH22_UNSTAKE_DELEGATED_TOKENS_MAINNET "262aeddd3f49fd6222d706c02696bd7d359ba962b6c30232cc93d7cf4166a23e" - -#define TEMPLATE_HASH_TH23_WITHDRAW_UNSTAKED_DELEGATED_TOKENS_TESTNET "2ae983f78e32b989fafa58ee7910b131fb51a2a74356f7916624695cb8bf5964" -#define TEMPLATE_HASH_TH23_WITHDRAW_UNSTAKED_DELEGATED_TOKENS_MAINNET "12675a013c064b6d0ef11dbf13f92210489bf2b3d299b2f14cd09be70b37577f" - -#define TEMPLATE_HASH_TH24_WITHDRAW_REWARDED_DELEGATED_TOKENS_TESTNET "385042aa453566fcff0b2bd418b837d8f46fbc23b1b46e6651b25a395bc04be8" -#define TEMPLATE_HASH_TH24_WITHDRAW_REWARDED_DELEGATED_TOKENS_MAINNET "239ffa449eae5560eec3e99633dcf9c63b1e9c99996d1c5636644dceef9ec44b" - -#define TEMPLATE_HASH_TH25_UPDATE_NETWORKING_ADDRESS_TESTNET "6cbe81c71d2b04dc403ea0db89377f0abc5db14d3d2bd014397b2776aa29bc3e" -#define TEMPLATE_HASH_TH25_UPDATE_NETWORKING_ADDRESS_MAINNET "e79cb076f2f7da7a3039b5061916e081a823087f1560bdf3caea773992892873" - -#define TEMPLATE_HASH_SCO01_SETUP_STAKING_COLLECTION_TESTNET "0e5c2445c0b1016eed4f60c429f233aa0bb223a0d9ff2aedffce00a58037a2bf" -#define TEMPLATE_HASH_SCO01_SETUP_STAKING_COLLECTION_MAINNET "a524b4094fcaf1051dbf43ac33ff80bb2f553670c58eeeb719757972a25d6b50" - -#define TEMPLATE_HASH_SCO02_REGISTER_DELEGATOR_TESTNET "c26f69a33ead535e7d597cec4567c6c70170e86fd85ec708f5381e50d43871e2" -#define TEMPLATE_HASH_SCO02_REGISTER_DELEGATOR_MAINNET "c5636d510872a16eb06996dacb43d6a28f8f72ff1b05b2eb03416cc711d9bb1f" - -#define TEMPLATE_HASH_SCO0301_REGISTER_NODE_TESTNET "f47efa834bc0559afae9a660b2efefddd0c6dc6e1bbcf9c3994e45ea9e5135ec" -#define TEMPLATE_HASH_SCO0301_REGISTER_NODE_MAINNET "99997236b6d76caa298331d5cef77cbdf83c1af64584ece537a780ba4ac46883" - -#define TEMPLATE_HASH_SCO0401_CREATE_MACHINE_ACCOUNT_TESTNET "e79df145af42488e3da1d1b2e50a38a2084229896d670884f278a2119dc3bf9e" -#define TEMPLATE_HASH_SCO0401_CREATE_MACHINE_ACCOUNT_MAINNET "c2442b498eea025099815ea613d6407407192dc12ad70e1a4f47936db804a841" - -#define TEMPLATE_HASH_SCO05_REQUEST_UNSTAKING_TESTNET "b00f6b3b9d8d7d4a9a8ad14fce11ee0edb23c39c56a8c1351e6b597f53f2fb71" -#define TEMPLATE_HASH_SCO05_REQUEST_UNSTAKING_MAINNET "a552951c5e6300a118610fbf2d36b3073ee266e1d26787d04717c141976ef78c" - -#define TEMPLATE_HASH_SCO06_STAKE_NEW_TOKENS_TESTNET "1307928440cee4289235793d6ff860a24315f7b6a5d5907a145dcc5f83702a2c" -#define TEMPLATE_HASH_SCO06_STAKE_NEW_TOKENS_MAINNET "8e10ac56db8ec5d5e0051d3c9608fabc8edd6abed983f6d3a254e7668a54b32b" - -#define TEMPLATE_HASH_SCO07_STAKE_REWARD_TOKENS_TESTNET "d7aca7113a7aa03e0afd20ee36f4873779708a02ac4c6985017740c2ecea3d62" -#define TEMPLATE_HASH_SCO07_STAKE_REWARD_TOKENS_MAINNET "907c4cfd67a98a8003393c64dc74eb7a957b229352a266139a542bb105ac4c40" - -#define TEMPLATE_HASH_SCO08_STAKE_UNSTAKED_TOKENS_TESTNET "3595fcd68cff445c65ad99f8d4d726b5e28807b061800769c41cbe3adb98aeec" -#define TEMPLATE_HASH_SCO08_STAKE_UNSTAKED_TOKENS_MAINNET "082e690b9647182cf6969db1a0fa8e0f1728da6db01fe0d462e9f0841c268cbb" - -#define TEMPLATE_HASH_SCO09_UNSTAKE_ALL_TESTNET "0bde358f3965ba2f4c18fb45b6536857c3f53d7d3b740fe66fe93a4ebf7524c1" -#define TEMPLATE_HASH_SCO09_UNSTAKE_ALL_MAINNET "df9c6486baa6f8f685368ea216659239cb81fa8ebd9062a9723edb54ca0d7525" - -#define TEMPLATE_HASH_SCO10_WITHDRAW_REWARD_TOKENS_TESTNET "3af182f568b37a8067d3fb524afcfe96991c85a928bf7651e730be0e15fdb72d" -#define TEMPLATE_HASH_SCO10_WITHDRAW_REWARD_TOKENS_MAINNET "27a2b60d538b8bb883b602ea83d1697986a29dd69a44a9209dc75affb9e63299" - -#define TEMPLATE_HASH_SCO11_WITHDRAW_UNSTAKED_TOKENS_TESTNET "68879197d961bb104a56e1e7d35660436fe4c52ed78f79d97fa50aa9e96fabf0" -#define TEMPLATE_HASH_SCO11_WITHDRAW_UNSTAKED_TOKENS_MAINNET "6d50ab1ef3d74203081c38306da74f5ad8fdd489e49fba732f8ba194d0c781c8" - -#define TEMPLATE_HASH_SCO12_CLOSE_STAKE_TESTNET "079aaa9cfb22138415056b43d5d91e8d73bd8bd5f37ebff4f4023d33ea6d2f25" -#define TEMPLATE_HASH_SCO12_CLOSE_STAKE_MAINNET "ecdffc1ae67479bc20c06eba6c776ff37b9523660ff1cd3129a3924d92484884" - -#define TEMPLATE_HASH_SCO13_TRANSFER_NODE_TESTNET "2386d7ae1a5b936e3914729ee34e01d53a8fbd2e403512ec1beccb4062c231eb" -#define TEMPLATE_HASH_SCO13_TRANSFER_NODE_MAINNET "cdc3a63d0c75ea95b414becb6fbb8f5a8004236d48661cd3c3d4f540ee4d422e" - -#define TEMPLATE_HASH_SCO14_TRANSFER_DELEGATOR_TESTNET "53b096b4850a30894e7b272ec5c39e2b2f4a23f8c40e76a3c64cfc63dc2999b6" -#define TEMPLATE_HASH_SCO14_TRANSFER_DELEGATOR_MAINNET "b34d6fafcc5a4d0ed9cf92e168a08d0674c93341e2393ee72dde6664918ec240" - -#define TEMPLATE_HASH_SCO15_WITHDRAW_FROM_MACHINE_ACCOUNT_TESTNET "39a126038522c6c964d53aaf78dde55bfe80929091510792fe49678bb22cbd96" -#define TEMPLATE_HASH_SCO15_WITHDRAW_FROM_MACHINE_ACCOUNT_MAINNET "f9c48e18bda7f113e82711a4c95dfd151c6600ed9fbf46ceb22566d6c5728c6f" - -#define TEMPLATE_HASH_SCO16_UPDATE_NETWORKING_ADDRESS_TESTNET "60f2cf219d56b19dc7fd223caed42dda9143c87b1b0d2c21a9652e12a3714133" -#define TEMPLATE_HASH_SCO16_UPDATE_NETWORKING_ADDRESS_MAINNET "ff067b40ac67020ef864cd14842f62023254da34dd2ded56affa1364305bf1c5" - -#define TEMPLATE_HASH_FUSD01_SETUP_FUSD_VAULT_TESTNET "0ffaf77ab320ce4cc9602d39b89c85f094ebcea571ed324537e703bc07b0fdc4" -#define TEMPLATE_HASH_FUSD01_SETUP_FUSD_VAULT_MAINNET "aa7fecdf159e71bd0b029e40b22643fb443161e67796f42bac68e9bab4630e29" - -#define TEMPLATE_HASH_FUSD02_TRANSFER_FUSD_TESTNET "f22ca4b350a79c724f6471d5a6a7a0efa7ba9aeebb7fed2843a3ddd6e42c2e1c" -#define TEMPLATE_HASH_FUSD02_TRANSFER_FUSD_MAINNET "180cef7053a5f0ae66e19e3a96cc3b9eb7da29767fb5d6938239bf1f8e1dc284" - -#define TEMPLATE_HASH_TS01_SET_UP_TOPSHOT_COLLECTION_TESTNET "0f0baeef9353ceee607c5be3b7c0f86792dadf20b9e9c89e831adb0199e75882" -#define TEMPLATE_HASH_TS01_SET_UP_TOPSHOT_COLLECTION_MAINNET "7511848f1c27a173d966f4b868fd7efead7eeb1bbf04fc3f3e60dabc6c7f7593" - -#define TEMPLATE_HASH_TS02_TRANSFER_TOP_SHOT_MOMENT_TESTNET "1ec9aea0b51409610f882f5ae4278567da675542bb378eb999f05b7c4f12f7d8" -#define TEMPLATE_HASH_TS02_TRANSFER_TOP_SHOT_MOMENT_MAINNET "09d5ad21bf70dfe4f8d800db9e61a77f2f64837ae0e818c3cd67e9cea837a1cf" - -#define TEMPLATE_HASH_USDC01_SETUP_USDC_VAULT_TESTNET "2defee818c0c003ca519f83517f4c7bcf9dd8664a562ec80959cb6146428f971" -#define TEMPLATE_HASH_USDC01_SETUP_USDC_VAULT_MAINNET "887673892a2e2c12337394570dfa30c5669e93f537ae426690f402799514a9a1" - -#define TEMPLATE_HASH_USDC02_TRANSFER_USDC_TESTNET "512485ec3f8e007853b0ea2a22fb2b9f7e2fa55fd9819171c5d013282efee60a" -#define TEMPLATE_HASH_USDC02_TRANSFER_USDC_MAINNET "7ff4d9f53ba5eebda556d0ead0ca13911bc8996e2c91c5147f8787d10a324483" - -#define TEMPLATE_HASH_SCO0302_REGISTER_NODE_TESTNET "9246ec9b7a5c81151156e7c2f6d356f68b1b884f88728daca46b968d9a46cd5a" -#define TEMPLATE_HASH_SCO0302_REGISTER_NODE_MAINNET "79de7119aea61bdafb39cc3d1f4fa17ca802c2732726a86d2c636dbc19808b68" - -#define TEMPLATE_HASH_SCO0402_CREATE_MACHINE_ACCOUNT_TESTNET "86c69d731560f3bff549c5f180eb4219bfe650ae4efec8e0c5b5ad3ebed54a92" -#define TEMPLATE_HASH_SCO0402_CREATE_MACHINE_ACCOUNT_MAINNET "dd3b327b09087ea7f8e92a22a6b04a3c6ca33b868b430c4f15f251658c38c1b7" - -#ifdef __cplusplus -} -#endif diff --git a/app/src/tx_metadata.c b/app/src/tx_metadata.c index f57deca0..9ea20d73 100644 --- a/app/src/tx_metadata.c +++ b/app/src/tx_metadata.c @@ -1,6 +1,10 @@ #include "tx_metadata.h" #include "zxmacros.h" +#define MAX_METADATA_NUMBER_OF_HASHES 10 +#define MAX_METADATA_STRING_LENGTH 100 +#define MAX_METADATA_MAX_ARRAY_ITEMS 20 + //Known tx metadata const static uint8_t TX_METADATA_CREATE_ACCOUNT[] = { @@ -10,10 +14,10 @@ const static uint8_t TX_METADATA_CREATE_ACCOUNT[] = { 1, //number of arguments //Argument 1 - ARGUMENT_TYPE_ARRAY, - 'P', 'u', 'b', 'k', 'e', 'y', 0, //arg name (to display) + ARGUMENT_TYPE_ARRAY, 1, 5, + 'P', 'u', 'b', ' ', 'k', 'e', 'y', 0, //arg name (to display) 0, //argument index - 'S','t', 'r', 'i', 'n', 'g', 0, //expected value type + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type JSMN_STRING, //expected value json token type }; @@ -27,7 +31,7 @@ const static uint8_t TX_METADATA_ADD_NEW_KEY[] = { ARGUMENT_TYPE_NORMAL, 'P', 'u', 'b', ' ', 'k', 'e', 'y', 0, //arg name (to display) 0, //argument index - 'S','t', 'r', 'i', 'n', 'g', 0, //expected value type + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type JSMN_STRING, //expected value json token type }; @@ -43,17 +47,864 @@ const static uint8_t TX_METADATA_TOKEN_TRANSFER[] = { ARGUMENT_TYPE_NORMAL, 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) 0, //argument index - 'U','I', 'n', 't', '6', '4', 0, //expected value type + 'U', 'F', 'i', 'x', '6', '4', 0, //expected value type JSMN_STRING, //expected value json token type //Argument 2 ARGUMENT_TYPE_NORMAL, 'D', 'e', 's', 't', 'i', 'n', 'a', 't', 'i', 'o', 'n', 0, //arg name (to display) 1, //argument index - 'A','d', 'd', 'r', 'e', 's', 's', 0, //expected value type + 'A', 'd', 'd', 'r', 'e', 's', 's', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_TH01[] = { + 2, //number of hashes + hashes + 0x6e, 0x73, 0xdb, 0x6e, 0xdd, 0x01, 0x90, 0xf5, 0x31, 0x1f, 0x6a, 0xdc, 0x5f, 0x2b, 0x1f, 0x27, 0xe9, 0xe6, 0x0c, 0x68, 0x57, 0x4b, 0x00, 0xee, 0x90, 0xda, 0x86, 0x7d, 0xa5, 0x2c, 0xdb, 0xb1, + 0xa2, 0x14, 0x6e, 0x3e, 0x6e, 0x77, 0x18, 0x77, 0x9c, 0xe5, 0x93, 0x76, 0xb8, 0x87, 0x60, 0xc1, 0x54, 0xd8, 0x2b, 0x7d, 0x13, 0x2f, 0xe2, 0xc3, 0x77, 0x11, 0x4e, 0xc7, 0xcf, 0x43, 0x4e, 0x7b, + 'W', 'i', 't', 'h', 'd', 'r', 'a', 'w', ' ', 'F', 'L', 'O', 'W', ' ', 'f', 'r', 'o', 'm', ' ', 'L', 'o', 'c', 'k', 'b', 'o', 'x', 0, //tx name (to display) + 1, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 0, //argument index + 'U', 'F', 'i', 'x', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_TH02[] = { + 2, //number of hashes + hashes + 0x0c, 0xb1, 0x1c, 0x10, 0xb8, 0x6d, 0x2a, 0xfe, 0xae, 0x08, 0x6e, 0xf5, 0x11, 0xd2, 0x8b, 0x14, 0x76, 0x0e, 0xb8, 0x54, 0x93, 0x5a, 0x0b, 0x0d, 0xcf, 0xee, 0xcc, 0x85, 0xdb, 0x84, 0x7f, 0x48, + 0x74, 0x35, 0x5d, 0xc8, 0xdf, 0x22, 0x1b, 0xc0, 0xd1, 0x70, 0xb2, 0xfe, 0x8d, 0xea, 0xcd, 0x6f, 0x1f, 0x55, 0x4d, 0x6b, 0xee, 0xa5, 0x8a, 0xd9, 0xfe, 0xe7, 0xa0, 0x7f, 0x74, 0x0e, 0xae, 0xfe, + 'D', 'e', 'p', 'o', 's', 'i', 't', ' ', 'F', 'L', 'O', 'W', ' ', 't', 'o', ' ', 'L', 'o', 'c', 'k', 'b', 'o', 'x', 0, //tx name (to display) + 1, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 0, //argument index + 'U', 'F', 'i', 'x', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_TH06[] = { + 2, //number of hashes + hashes + 0xb6, 0xa3, 0x50, 0x2d, 0x22, 0x05, 0xeb, 0x05, 0xec, 0x18, 0x77, 0x2c, 0x13, 0xb9, 0x1c, 0xc8, 0x8a, 0x05, 0x6b, 0x32, 0x5c, 0x26, 0x17, 0xc5, 0x79, 0x48, 0xd3, 0x8c, 0xab, 0x8d, 0xb6, 0x00, + 0xb6, 0x4e, 0x0e, 0x3e, 0xd9, 0xeb, 0x28, 0x78, 0x91, 0x98, 0xf2, 0xb0, 0x43, 0x7f, 0x55, 0xf7, 0x50, 0xbf, 0xa7, 0x6d, 0xa9, 0x94, 0x50, 0xf6, 0x3b, 0xe6, 0x54, 0x3b, 0xde, 0x66, 0x12, 0x2a, + 'R', 'e', 'g', 'i', 's', 't', 'e', 'r', ' ', 'S', 't', 'a', 'k', 'e', 'd', ' ', 'N', 'o', 'd', 'e', 0, //tx name (to display) + 6, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'N', 'o', 'd', 'e', ' ', 'I', 'D', 0, //arg name (to display) + 0, //argument index + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 2 + ARGUMENT_TYPE_NORMAL, + 'N', 'o', 'd', 'e', ' ', 'R', 'o', 'l', 'e', 0, //arg name (to display) + 1, //argument index + 'U', 'I', 'n', 't', '8', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 3 + ARGUMENT_TYPE_NORMAL, + 'N', 'e', 't', 'w', 'o', 'r', 'k', 'i', 'n', 'g', ' ', 'A', 'd', 'd', 'r', 'e', 's', 's', 0, //arg name (to display) + 2, //argument index + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 4 + ARGUMENT_TYPE_NORMAL, + 'N', 'e', 't', 'w', 'o', 'r', 'k', 'i', 'n', 'g', ' ', 'K', 'e', 'y', 0, //arg name (to display) + 3, //argument index + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 5 + ARGUMENT_TYPE_NORMAL, + 'S', 't', 'a', 'k', 'i', 'n', 'g', ' ', 'K', 'e', 'y', 0, //arg name (to display) + 4, //argument index + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 6 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 5, //argument index + 'U', 'F', 'i', 'x', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_TH08[] = { + 2, //number of hashes + hashes + 0xd5, 0x68, 0x9b, 0x89, 0xf5, 0x32, 0x14, 0xe7, 0xce, 0x9b, 0xa7, 0xbe, 0x2b, 0xb6, 0x51, 0x96, 0x1f, 0x7e, 0x30, 0x36, 0xb8, 0x5f, 0x92, 0x50, 0x49, 0x42, 0x90, 0xda, 0x9e, 0x9b, 0xa9, 0x89, + 0x19, 0x29, 0xe4, 0xf3, 0x88, 0x94, 0xb8, 0x64, 0x18, 0x48, 0xa3, 0xc0, 0xa3, 0xb9, 0xd3, 0x54, 0x95, 0xb3, 0x50, 0x83, 0xd4, 0x2e, 0x8a, 0x3d, 0x4c, 0x92, 0x8b, 0x9d, 0xb4, 0x17, 0x4e, 0xe8, + 'S', 't', 'a', 'k', 'e', ' ', 'F', 'L', 'O', 'W', ' ', 'f', 'r', 'o', 'm', ' ', 'L', 'o', 'c', 'k', 'b', 'o', 'x', 0, //tx name (to display) + 1, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 0, //argument index + 'U', 'F', 'i', 'x', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_TH09[] = { + 2, //number of hashes + hashes + 0x23, 0xe5, 0xbf, 0xd5, 0x94, 0xbb, 0x32, 0x45, 0x09, 0x0e, 0x3e, 0x0b, 0xaf, 0xb9, 0xcb, 0x92, 0x46, 0xfc, 0x84, 0xd3, 0x0e, 0x4a, 0x35, 0xa7, 0xfd, 0xe1, 0xb5, 0x10, 0x85, 0x62, 0x4d, 0x86, + 0x67, 0x7c, 0xc0, 0xac, 0x39, 0x62, 0xec, 0x13, 0x6c, 0xa2, 0x6d, 0xbe, 0xc0, 0xaa, 0x94, 0x2d, 0x92, 0x66, 0x40, 0xec, 0xf8, 0x41, 0x84, 0x33, 0xf0, 0xdb, 0x4b, 0x79, 0x25, 0xf5, 0xd0, 0xfe, + 'R', 'e', 's', 't', 'a', 'k', 'e', ' ', 'U', 'n', 's', 't', 'a', 'k', 'e', 'd', ' ', 'F', 'L', 'O', 'W', 0, //tx name (to display) + 1, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 0, //argument index + 'U', 'F', 'i', 'x', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_TH10[] = { + 2, //number of hashes + hashes + 0x23, 0x93, 0x19, 0x82, 0x5a, 0xd6, 0x81, 0x78, 0xe7, 0x64, 0x65, 0xb5, 0xea, 0x18, 0xcb, 0x43, 0xf0, 0x6c, 0x4e, 0xe1, 0x13, 0x41, 0xf8, 0xfe, 0x94, 0x24, 0x80, 0x91, 0x63, 0xa0, 0x27, 0xa5, + 0x28, 0xd1, 0x71, 0x9c, 0x5b, 0x21, 0xc8, 0x8c, 0x62, 0x66, 0x5d, 0xb5, 0xba, 0x04, 0x88, 0x68, 0x09, 0xf3, 0x23, 0x4c, 0x27, 0x05, 0x7b, 0x05, 0x7c, 0x36, 0xd5, 0xf2, 0x65, 0xee, 0x9d, 0xe4, + 'R', 'e', 's', 't', 'a', 'k', 'e', ' ', 'R', 'e', 'w', 'a', 'r', 'd', 'e', 'd', ' ', 'F', 'L', 'O', 'W', 0, //tx name (to display) + 1, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 0, //argument index + 'U', 'F', 'i', 'x', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_TH11[] = { + 2, //number of hashes + hashes + 0x33, 0xe3, 0x97, 0x7c, 0x45, 0xe7, 0xc2, 0x3c, 0x14, 0x72, 0xbc, 0xf3, 0x34, 0xd0, 0x0b, 0x03, 0xeb, 0xf9, 0x1b, 0x06, 0xb6, 0x7c, 0x57, 0xb6, 0x3b, 0x56, 0x2c, 0x7b, 0x1f, 0xf5, 0xc5, 0x9f, + 0x4e, 0x2a, 0x35, 0x54, 0x14, 0x53, 0xf8, 0x9c, 0x55, 0xe5, 0xdc, 0x6d, 0xbc, 0x96, 0x32, 0x90, 0x38, 0x0d, 0x77, 0x9c, 0x81, 0xdf, 0x0b, 0x3b, 0xf8, 0x9c, 0x29, 0xb2, 0xa8, 0xd7, 0xa9, 0xfe, + 'U', 'n', 's', 't', 'a', 'k', 'e', ' ', 'F', 'L', 'O', 'W', 0, //tx name (to display) + 1, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 0, //argument index + 'U', 'F', 'i', 'x', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_TH12[] = { + 2, //number of hashes + hashes + 0xf9, 0x2c, 0x4c, 0xd6, 0x63, 0xb2, 0xe3, 0x35, 0xcd, 0x82, 0x1a, 0x65, 0x6b, 0xb2, 0xeb, 0xcf, 0x23, 0x9b, 0x22, 0x20, 0x36, 0xa7, 0x82, 0x5a, 0xf5, 0xe5, 0x12, 0xfa, 0xd4, 0xd8, 0x20, 0x35, + 0x70, 0x99, 0x90, 0x4b, 0x95, 0x3b, 0x06, 0x2e, 0x81, 0xe2, 0x57, 0x5a, 0x2c, 0x20, 0x81, 0xb3, 0xd9, 0x8b, 0xfc, 0xcf, 0x5c, 0x74, 0x3b, 0x4b, 0xdb, 0x22, 0x4b, 0x93, 0x7e, 0x29, 0x2d, 0xad, + 'U', 'n', 's', 't', 'a', 'k', 'e', ' ', 'A', 'l', 'l', ' ', 'F', 'L', 'O', 'W', 0, //tx name (to display) + 0, //number of arguments +}; + +const uint8_t TX_METADATA_TH13[] = { + 2, //number of hashes + hashes + 0x90, 0x09, 0x7e, 0x3a, 0xff, 0x9b, 0x67, 0xf6, 0x5b, 0xba, 0xda, 0x3c, 0xde, 0xdb, 0xb7, 0x3d, 0x45, 0xd0, 0x93, 0xff, 0x33, 0x3a, 0xaa, 0xff, 0x38, 0x80, 0x9b, 0xf9, 0x91, 0x0a, 0x3e, 0x39, + 0xdc, 0xae, 0x4f, 0xaa, 0x6d, 0x68, 0x98, 0x73, 0xf7, 0xca, 0xf7, 0xc5, 0xef, 0xef, 0x66, 0x9f, 0x9f, 0xe1, 0xd4, 0x11, 0x3e, 0x58, 0xb4, 0x74, 0xb7, 0xae, 0xc1, 0xe0, 0x71, 0x13, 0xa7, 0xff, + 'W', 'i', 't', 'h', 'd', 'r', 'a', 'w', ' ', 'U', 'n', 's', 't', 'a', 'k', 'e', 'd', ' ', 'F', 'L', 'O', 'W', ' ', 't', 'o', ' ', 'L', 'o', 'c', 'k', 'b', 'o', 'x', 0, //tx name (to display) + 1, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 0, //argument index + 'U', 'F', 'i', 'x', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_TH14[] = { + 2, //number of hashes + hashes + 0xf2, 0x34, 0x06, 0xff, 0x40, 0x2f, 0x02, 0x41, 0x86, 0x29, 0x43, 0x29, 0x12, 0xce, 0x73, 0x2b, 0xe0, 0x44, 0x1b, 0x1a, 0x7e, 0x71, 0xf1, 0x6c, 0x03, 0xd6, 0x88, 0xa1, 0x65, 0xff, 0x7f, 0x49, + 0x9b, 0xb8, 0xf0, 0x56, 0x2e, 0xea, 0x5e, 0x45, 0xc1, 0x1f, 0x92, 0x89, 0x54, 0x0f, 0x39, 0xc9, 0x9a, 0x21, 0xc9, 0xa0, 0xfb, 0x06, 0x0a, 0x7d, 0x3f, 0x83, 0x2e, 0x98, 0xc2, 0x69, 0x6f, 0x2d, + 'W', 'i', 't', 'h', 'd', 'r', 'a', 'w', ' ', 'R', 'e', 'w', 'a', 'r', 'd', 'e', 'd', ' ', 'F', 'L', 'O', 'W', ' ', 't', 'o', ' ', 'L', 'o', 'c', 'k', 'b', 'o', 'x', 0, //tx name (to display) + 1, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 0, //argument index + 'U', 'F', 'i', 'x', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_TH16[] = { + 2, //number of hashes + hashes + 0xc2, 0x9d, 0x40, 0x24, 0xaa, 0xeb, 0x71, 0xab, 0x47, 0x81, 0x82, 0x54, 0x24, 0x99, 0xe0, 0xba, 0x3d, 0x5d, 0x30, 0x3e, 0xc0, 0x27, 0x25, 0x2e, 0x3b, 0x83, 0x33, 0x51, 0x5e, 0xe3, 0xde, 0x48, + 0x97, 0xb3, 0x43, 0x64, 0x82, 0xc5, 0xae, 0xfc, 0x1b, 0xaf, 0x8b, 0x85, 0x0e, 0x92, 0xc8, 0x29, 0x20, 0x2e, 0x46, 0x8c, 0x57, 0x24, 0x1d, 0xec, 0x70, 0x7b, 0x6c, 0x27, 0xbd, 0x89, 0xd1, 0x5c, + 'R', 'e', 'g', 'i', 's', 't', 'e', 'r', ' ', 'O', 'p', 'e', 'r', 'a', 't', 'o', 'r', ' ', 'N', 'o', 'd', 'e', 0, //tx name (to display) + 3, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'O', 'p', 'e', 'r', 'a', 't', 'o', 'r', ' ', 'A', 'd', 'd', 'r', 'e', 's', 's', 0, //arg name (to display) + 0, //argument index + 'A', 'd', 'd', 'r', 'e', 's', 's', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 2 + ARGUMENT_TYPE_NORMAL, + 'N', 'o', 'd', 'e', ' ', 'I', 'D', 0, //arg name (to display) + 1, //argument index + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 3 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 2, //argument index + 'U', 'F', 'i', 'x', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_TH17[] = { + 2, //number of hashes + hashes + 0x13, 0x78, 0x40, 0x5c, 0x85, 0xe0, 0xc9, 0x66, 0x34, 0x4b, 0x19, 0x6c, 0x0f, 0xce, 0x60, 0x2f, 0x39, 0xe7, 0x9f, 0x39, 0x38, 0xec, 0x7b, 0x68, 0x9e, 0x0c, 0x96, 0xa8, 0x70, 0x3b, 0x01, 0x8a, + 0x3c, 0xb3, 0x57, 0xa9, 0x7a, 0x57, 0xd9, 0xab, 0xbe, 0x5c, 0x68, 0xf0, 0xdf, 0x34, 0x2e, 0xe9, 0x6b, 0xa9, 0x7a, 0xde, 0x20, 0x13, 0x75, 0x3f, 0xd2, 0xdd, 0xf4, 0x76, 0x95, 0xa8, 0xc0, 0x8a, + 'R', 'e', 'g', 'i', 's', 't', 'e', 'r', ' ', 'D', 'e', 'l', 'e', 'g', 'a', 't', 'o', 'r', 0, //tx name (to display) + 2, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'N', 'o', 'd', 'e', ' ', 'I', 'D', 0, //arg name (to display) + 0, //argument index + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 2 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 1, //argument index + 'U', 'F', 'i', 'x', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_TH19[] = { + 2, //number of hashes + hashes + 0x18, 0xfa, 0xd6, 0x83, 0x68, 0xa4, 0x39, 0x4b, 0x24, 0x5d, 0xb9, 0x12, 0x17, 0xd7, 0xdc, 0x97, 0x9e, 0x13, 0x16, 0xab, 0x75, 0x73, 0x88, 0xd4, 0x16, 0xea, 0xef, 0x83, 0x1f, 0x56, 0x5a, 0xb3, + 0x80, 0x23, 0x54, 0xd8, 0xb3, 0xe7, 0x90, 0x8e, 0x58, 0x4b, 0xcb, 0x52, 0x17, 0x63, 0x7f, 0xb9, 0xf4, 0xef, 0x04, 0x54, 0x27, 0xc3, 0x2d, 0x57, 0xd8, 0x1a, 0xd4, 0xa3, 0x90, 0xed, 0x1a, 0x60, + 'D', 'e', 'l', 'e', 'g', 'a', 't', 'e', ' ', 'F', 'L', 'O', 'W', ' ', 'f', 'r', 'o', 'm', ' ', 'L', 'o', 'c', 'k', 'b', 'o', 'x', 0, //tx name (to display) + 1, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 0, //argument index + 'U', 'F', 'i', 'x', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_TH20[] = { + 2, //number of hashes + hashes + 0x87, 0x76, 0xb1, 0x52, 0x1b, 0x04, 0x39, 0x57, 0x54, 0x73, 0x4f, 0x8f, 0x40, 0xd4, 0xa0, 0x48, 0x28, 0x63, 0x27, 0x4f, 0x8d, 0x83, 0x29, 0x73, 0xd9, 0xe0, 0x11, 0xb3, 0xcb, 0xb4, 0x8c, 0x85, + 0x20, 0x27, 0x33, 0x1b, 0x72, 0xd8, 0x71, 0x0a, 0x1a, 0x05, 0xfe, 0xb6, 0xec, 0xeb, 0xad, 0xb5, 0x85, 0x8d, 0x13, 0x4b, 0xc8, 0xc9, 0x5d, 0x6f, 0x26, 0x13, 0x19, 0xcd, 0x9f, 0xa1, 0xbb, 0x95, + 'R', 'e', '-', 'd', 'e', 'l', 'e', 'g', 'a', 't', 'e', ' ', 'U', 'n', 's', 't', 'a', 'k', 'e', 'd', ' ', 'F', 'L', 'O', 'W', 0, //tx name (to display) + 1, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 0, //argument index + 'U', 'F', 'i', 'x', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_TH21[] = { + 2, //number of hashes + hashes + 0x6b, 0x40, 0xff, 0xc9, 0x16, 0x9a, 0xbd, 0x75, 0x10, 0x7a, 0x45, 0xda, 0x59, 0x74, 0xc7, 0xe5, 0x02, 0xd3, 0x87, 0x73, 0x27, 0x5a, 0xbb, 0x23, 0x1d, 0x74, 0x7e, 0x47, 0x60, 0xb7, 0xeb, 0xee, + 0x86, 0x4e, 0xdb, 0xff, 0x38, 0x43, 0x35, 0xef, 0x21, 0xc2, 0x6b, 0x3b, 0xcf, 0x17, 0xd3, 0x6b, 0x2b, 0x1d, 0x89, 0x4a, 0xfb, 0xe2, 0xb2, 0x03, 0xf5, 0x80, 0x99, 0xcc, 0x45, 0x79, 0x71, 0xe4, + 'R', 'e', '-', 'd', 'e', 'l', 'e', 'g', 'a', 't', 'e', ' ', 'R', 'e', 'w', 'a', 'r', 'd', 'e', 'd', ' ', 'F', 'L', 'O', 'W', 0, //tx name (to display) + 1, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 0, //argument index + 'U', 'F', 'i', 'x', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_TH22[] = { + 2, //number of hashes + hashes + 0x61, 0xcb, 0xcd, 0x1c, 0x31, 0xbb, 0xfc, 0x9c, 0xeb, 0x4a, 0x5a, 0xc7, 0x26, 0xe2, 0xf8, 0xb3, 0xd8, 0x45, 0xa4, 0xfd, 0xf5, 0x9b, 0x0a, 0xb2, 0x3c, 0xbb, 0xfa, 0x8f, 0x16, 0xd7, 0xa0, 0x24, + 0x26, 0x2a, 0xed, 0xdd, 0x3f, 0x49, 0xfd, 0x62, 0x22, 0xd7, 0x06, 0xc0, 0x26, 0x96, 0xbd, 0x7d, 0x35, 0x9b, 0xa9, 0x62, 0xb6, 0xc3, 0x02, 0x32, 0xcc, 0x93, 0xd7, 0xcf, 0x41, 0x66, 0xa2, 0x3e, + 'U', 'n', 's', 't', 'a', 'k', 'e', ' ', 'D', 'e', 'l', 'e', 'g', 'a', 't', 'e', 'd', ' ', 'F', 'L', 'O', 'W', 0, //tx name (to display) + 1, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 0, //argument index + 'U', 'F', 'i', 'x', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_TH23[] = { + 2, //number of hashes + hashes + 0x2a, 0xe9, 0x83, 0xf7, 0x8e, 0x32, 0xb9, 0x89, 0xfa, 0xfa, 0x58, 0xee, 0x79, 0x10, 0xb1, 0x31, 0xfb, 0x51, 0xa2, 0xa7, 0x43, 0x56, 0xf7, 0x91, 0x66, 0x24, 0x69, 0x5c, 0xb8, 0xbf, 0x59, 0x64, + 0x12, 0x67, 0x5a, 0x01, 0x3c, 0x06, 0x4b, 0x6d, 0x0e, 0xf1, 0x1d, 0xbf, 0x13, 0xf9, 0x22, 0x10, 0x48, 0x9b, 0xf2, 0xb3, 0xd2, 0x99, 0xb2, 0xf1, 0x4c, 0xd0, 0x9b, 0xe7, 0x0b, 0x37, 0x57, 0x7f, + 'W', 'i', 't', 'h', 'd', 'r', 'a', 'w', ' ', 'U', 'n', 'd', 'e', 'l', 'e', 'g', 'a', 't', 'e', 'd', ' ', 'F', 'L', 'O', 'W', ' ', 't', 'o', ' ', 'L', 'o', 'c', 'k', 'b', 'o', 'x', 0, //tx name (to display) + 1, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 0, //argument index + 'U', 'F', 'i', 'x', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_TH24[] = { + 2, //number of hashes + hashes + 0x38, 0x50, 0x42, 0xaa, 0x45, 0x35, 0x66, 0xfc, 0xff, 0x0b, 0x2b, 0xd4, 0x18, 0xb8, 0x37, 0xd8, 0xf4, 0x6f, 0xbc, 0x23, 0xb1, 0xb4, 0x6e, 0x66, 0x51, 0xb2, 0x5a, 0x39, 0x5b, 0xc0, 0x4b, 0xe8, + 0x23, 0x9f, 0xfa, 0x44, 0x9e, 0xae, 0x55, 0x60, 0xee, 0xc3, 0xe9, 0x96, 0x33, 0xdc, 0xf9, 0xc6, 0x3b, 0x1e, 0x9c, 0x99, 0x99, 0x6d, 0x1c, 0x56, 0x36, 0x64, 0x4d, 0xce, 0xef, 0x9e, 0xc4, 0x4b, + 'W', 'i', 't', 'h', 'd', 'r', 'a', 'w', ' ', 'D', 'e', 'l', 'e', 'g', 'a', 't', 'e', ' ', 'R', 'e', 'w', 'a', 'r', 'd', 's', ' ', 't', 'o', ' ', 'L', 'o', 'c', 'k', 'b', 'o', 'x', 0, //tx name (to display) + 1, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 0, //argument index + 'U', 'F', 'i', 'x', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_TH25[] = { + 2, //number of hashes + hashes + 0x6c, 0xbe, 0x81, 0xc7, 0x1d, 0x2b, 0x04, 0xdc, 0x40, 0x3e, 0xa0, 0xdb, 0x89, 0x37, 0x7f, 0x0a, 0xbc, 0x5d, 0xb1, 0x4d, 0x3d, 0x2b, 0xd0, 0x14, 0x39, 0x7b, 0x27, 0x76, 0xaa, 0x29, 0xbc, 0x3e, + 0xe7, 0x9c, 0xb0, 0x76, 0xf2, 0xf7, 0xda, 0x7a, 0x30, 0x39, 0xb5, 0x06, 0x19, 0x16, 0xe0, 0x81, 0xa8, 0x23, 0x08, 0x7f, 0x15, 0x60, 0xbd, 0xf3, 0xca, 0xea, 0x77, 0x39, 0x92, 0x89, 0x28, 0x73, + 'U', 'p', 'd', 'a', 't', 'e', ' ', 'N', 'e', 't', 'w', 'o', 'r', 'k', 'i', 'n', 'g', ' ', 'A', 'd', 'd', 'r', 'e', 's', 's', 0, //tx name (to display) + 1, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'A', 'd', 'd', 'r', 'e', 's', 's', 0, //arg name (to display) + 0, //argument index + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_SCO01[] = { + 2, //number of hashes + hashes + 0x0e, 0x5c, 0x24, 0x45, 0xc0, 0xb1, 0x01, 0x6e, 0xed, 0x4f, 0x60, 0xc4, 0x29, 0xf2, 0x33, 0xaa, 0x0b, 0xb2, 0x23, 0xa0, 0xd9, 0xff, 0x2a, 0xed, 0xff, 0xce, 0x00, 0xa5, 0x80, 0x37, 0xa2, 0xbf, + 0xa5, 0x24, 0xb4, 0x09, 0x4f, 0xca, 0xf1, 0x05, 0x1d, 0xbf, 0x43, 0xac, 0x33, 0xff, 0x80, 0xbb, 0x2f, 0x55, 0x36, 0x70, 0xc5, 0x8e, 0xee, 0xb7, 0x19, 0x75, 0x79, 0x72, 0xa2, 0x5d, 0x6b, 0x50, + 'S', 'e', 't', 'u', 'p', ' ', 'S', 't', 'a', 'k', 'i', 'n', 'g', ' ', 'C', 'o', 'l', 'l', 'e', 'c', 't', 'i', 'o', 'n', 0, //tx name (to display) + 0, //number of arguments +}; + +const uint8_t TX_METADATA_SCO02[] = { + 2, //number of hashes + hashes + 0xc2, 0x6f, 0x69, 0xa3, 0x3e, 0xad, 0x53, 0x5e, 0x7d, 0x59, 0x7c, 0xec, 0x45, 0x67, 0xc6, 0xc7, 0x01, 0x70, 0xe8, 0x6f, 0xd8, 0x5e, 0xc7, 0x08, 0xf5, 0x38, 0x1e, 0x50, 0xd4, 0x38, 0x71, 0xe2, + 0xc5, 0x63, 0x6d, 0x51, 0x08, 0x72, 0xa1, 0x6e, 0xb0, 0x69, 0x96, 0xda, 0xcb, 0x43, 0xd6, 0xa2, 0x8f, 0x8f, 0x72, 0xff, 0x1b, 0x05, 0xb2, 0xeb, 0x03, 0x41, 0x6c, 0xc7, 0x11, 0xd9, 0xbb, 0x1f, + 'R', 'e', 'g', 'i', 's', 't', 'e', 'r', ' ', 'D', 'e', 'l', 'e', 'g', 'a', 't', 'o', 'r', 0, //tx name (to display) + 2, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'N', 'o', 'd', 'e', ' ', 'I', 'D', 0, //arg name (to display) + 0, //argument index + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 2 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 1, //argument index + 'U', 'F', 'i', 'x', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_SCO03[] = { + 4, //number of hashes + hashes + 0xf4, 0x7e, 0xfa, 0x83, 0x4b, 0xc0, 0x55, 0x9a, 0xfa, 0xe9, 0xa6, 0x60, 0xb2, 0xef, 0xef, 0xdd, 0xd0, 0xc6, 0xdc, 0x6e, 0x1b, 0xbc, 0xf9, 0xc3, 0x99, 0x4e, 0x45, 0xea, 0x9e, 0x51, 0x35, 0xec, + 0x99, 0x99, 0x72, 0x36, 0xb6, 0xd7, 0x6c, 0xaa, 0x29, 0x83, 0x31, 0xd5, 0xce, 0xf7, 0x7c, 0xbd, 0xf8, 0x3c, 0x1a, 0xf6, 0x45, 0x84, 0xec, 0xe5, 0x37, 0xa7, 0x80, 0xba, 0x4a, 0xc4, 0x68, 0x83, + 0x92, 0x46, 0xec, 0x9b, 0x7a, 0x5c, 0x81, 0x15, 0x11, 0x56, 0xe7, 0xc2, 0xf6, 0xd3, 0x56, 0xf6, 0x8b, 0x1b, 0x88, 0x4f, 0x88, 0x72, 0x8d, 0xac, 0xa4, 0x6b, 0x96, 0x8d, 0x9a, 0x46, 0xcd, 0x5a, + 0x79, 0xde, 0x71, 0x19, 0xae, 0xa6, 0x1b, 0xda, 0xfb, 0x39, 0xcc, 0x3d, 0x1f, 0x4f, 0xa1, 0x7c, 0xa8, 0x02, 0xc2, 0x73, 0x27, 0x26, 0xa8, 0x6d, 0x2c, 0x63, 0x6d, 0xbc, 0x19, 0x80, 0x8b, 0x68, + 'R', 'e', 'g', 'i', 's', 't', 'e', 'r', ' ', 'N', 'o', 'd', 'e', 0, //tx name (to display) + 7, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'N', 'o', 'd', 'e', ' ', 'I', 'D', 0, //arg name (to display) + 0, //argument index + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 2 + ARGUMENT_TYPE_NORMAL, + 'N', 'o', 'd', 'e', ' ', 'R', 'o', 'l', 'e', 0, //arg name (to display) + 1, //argument index + 'U', 'I', 'n', 't', '8', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 3 + ARGUMENT_TYPE_NORMAL, + 'N', 'e', 't', 'w', '.', ' ', 'A', 'd', 'd', 'r', '.', 0, //arg name (to display) + 2, //argument index + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 4 + ARGUMENT_TYPE_NORMAL, + 'N', 'e', 't', 'w', '.', ' ', 'K', 'e', 'y', 0, //arg name (to display) + 3, //argument index + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 5 + ARGUMENT_TYPE_NORMAL, + 'S', 't', 'a', 'k', 'i', 'n', 'g', ' ', 'K', 'e', 'y', 0, //arg name (to display) + 4, //argument index + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 6 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 5, //argument index + 'U', 'F', 'i', 'x', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 6 + ARGUMENT_TYPE_OPTIONALARRAY, 0, 3, + 'P', 'u', 'b', ' ', 'k', 'e', 'y', 0, //arg name (to display) + 6, //argument index + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_SCO04[] = { + 4, //number of hashes + hashes + 0xe7, 0x9d, 0xf1, 0x45, 0xaf, 0x42, 0x48, 0x8e, 0x3d, 0xa1, 0xd1, 0xb2, 0xe5, 0x0a, 0x38, 0xa2, 0x08, 0x42, 0x29, 0x89, 0x6d, 0x67, 0x08, 0x84, 0xf2, 0x78, 0xa2, 0x11, 0x9d, 0xc3, 0xbf, 0x9e, + 0xc2, 0x44, 0x2b, 0x49, 0x8e, 0xea, 0x02, 0x50, 0x99, 0x81, 0x5e, 0xa6, 0x13, 0xd6, 0x40, 0x74, 0x07, 0x19, 0x2d, 0xc1, 0x2a, 0xd7, 0x0e, 0x1a, 0x4f, 0x47, 0x93, 0x6d, 0xb8, 0x04, 0xa8, 0x41, + 0x86, 0xc6, 0x9d, 0x73, 0x15, 0x60, 0xf3, 0xbf, 0xf5, 0x49, 0xc5, 0xf1, 0x80, 0xeb, 0x42, 0x19, 0xbf, 0xe6, 0x50, 0xae, 0x4e, 0xfe, 0xc8, 0xe0, 0xc5, 0xb5, 0xad, 0x3e, 0xbe, 0xd5, 0x4a, 0x92, + 0xdd, 0x3b, 0x32, 0x7b, 0x09, 0x08, 0x7e, 0xa7, 0xf8, 0xe9, 0x2a, 0x22, 0xa6, 0xb0, 0x4a, 0x3c, 0x6c, 0xa3, 0x3b, 0x86, 0x8b, 0x43, 0x0c, 0x4f, 0x15, 0xf2, 0x51, 0x65, 0x8c, 0x38, 0xc1, 0xb7, + 'C', 'r', 'e', 'a', 't', 'e', ' ', 'M', 'a', 'c', 'h', 'i', 'n', 'e', ' ', 'A', 'c', 'c', 'o', 'u', 'n', 't', 0, //tx name (to display) + 2, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'N', 'o', 'd', 'e', ' ', 'I', 'D', 0, //arg name (to display) + 0, //argument index + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 2 + ARGUMENT_TYPE_ARRAY, 0, 3, + 'P', 'u', 'b', ' ', 'k', 'e', 'y', 0, //arg name (to display) + 1, //argument index + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_SCO05[] = { + 2, //number of hashes + hashes + 0xb0, 0x0f, 0x6b, 0x3b, 0x9d, 0x8d, 0x7d, 0x4a, 0x9a, 0x8a, 0xd1, 0x4f, 0xce, 0x11, 0xee, 0x0e, 0xdb, 0x23, 0xc3, 0x9c, 0x56, 0xa8, 0xc1, 0x35, 0x1e, 0x6b, 0x59, 0x7f, 0x53, 0xf2, 0xfb, 0x71, + 0xa5, 0x52, 0x95, 0x1c, 0x5e, 0x63, 0x00, 0xa1, 0x18, 0x61, 0x0f, 0xbf, 0x2d, 0x36, 0xb3, 0x07, 0x3e, 0xe2, 0x66, 0xe1, 0xd2, 0x67, 0x87, 0xd0, 0x47, 0x17, 0xc1, 0x41, 0x97, 0x6e, 0xf7, 0x8c, + 'R', 'e', 'q', 'u', 'e', 's', 't', ' ', 'U', 'n', 's', 't', 'a', 'k', 'i', 'n', 'g', 0, //tx name (to display) + 3, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'N', 'o', 'd', 'e', ' ', 'I', 'D', 0, //arg name (to display) + 0, //argument index + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 2 + ARGUMENT_TYPE_OPTIONAL, + 'D', 'e', 'l', 'e', 'g', 'a', 't', 'o', 'r', ' ', 'I', 'D', 0, //arg name (to display) + 1, //argument index + 'U', 'I', 'n', 't', '3', '2', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 3 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 2, //argument index + 'U', 'F', 'i', 'x', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_SCO06[] = { + 2, //number of hashes + hashes + 0x13, 0x07, 0x92, 0x84, 0x40, 0xce, 0xe4, 0x28, 0x92, 0x35, 0x79, 0x3d, 0x6f, 0xf8, 0x60, 0xa2, 0x43, 0x15, 0xf7, 0xb6, 0xa5, 0xd5, 0x90, 0x7a, 0x14, 0x5d, 0xcc, 0x5f, 0x83, 0x70, 0x2a, 0x2c, + 0x8e, 0x10, 0xac, 0x56, 0xdb, 0x8e, 0xc5, 0xd5, 0xe0, 0x05, 0x1d, 0x3c, 0x96, 0x08, 0xfa, 0xbc, 0x8e, 0xdd, 0x6a, 0xbe, 0xd9, 0x83, 0xf6, 0xd3, 0xa2, 0x54, 0xe7, 0x66, 0x8a, 0x54, 0xb3, 0x2b, + 'S', 't', 'a', 'k', 'e', ' ', 'N', 'e', 'w', ' ', 'T', 'o', 'k', 'e', 'n', 's', 0, //tx name (to display) + 3, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'N', 'o', 'd', 'e', ' ', 'I', 'D', 0, //arg name (to display) + 0, //argument index + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 2 + ARGUMENT_TYPE_OPTIONAL, + 'D', 'e', 'l', 'e', 'g', 'a', 't', 'o', 'r', ' ', 'I', 'D', 0, //arg name (to display) + 1, //argument index + 'U', 'I', 'n', 't', '3', '2', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 3 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 2, //argument index + 'U', 'F', 'i', 'x', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_SCO07[] = { + 2, //number of hashes + hashes + 0xd7, 0xac, 0xa7, 0x11, 0x3a, 0x7a, 0xa0, 0x3e, 0x0a, 0xfd, 0x20, 0xee, 0x36, 0xf4, 0x87, 0x37, 0x79, 0x70, 0x8a, 0x02, 0xac, 0x4c, 0x69, 0x85, 0x01, 0x77, 0x40, 0xc2, 0xec, 0xea, 0x3d, 0x62, + 0x90, 0x7c, 0x4c, 0xfd, 0x67, 0xa9, 0x8a, 0x80, 0x03, 0x39, 0x3c, 0x64, 0xdc, 0x74, 0xeb, 0x7a, 0x95, 0x7b, 0x22, 0x93, 0x52, 0xa2, 0x66, 0x13, 0x9a, 0x54, 0x2b, 0xb1, 0x05, 0xac, 0x4c, 0x40, + 'S', 't', 'a', 'k', 'e', ' ', 'R', 'e', 'w', 'a', 'r', 'd', ' ', 'T', 'o', 'k', 'e', 'n', 's', 0, //tx name (to display) + 3, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'N', 'o', 'd', 'e', ' ', 'I', 'D', 0, //arg name (to display) + 0, //argument index + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 2 + ARGUMENT_TYPE_OPTIONAL, + 'D', 'e', 'l', 'e', 'g', 'a', 't', 'o', 'r', ' ', 'I', 'D', 0, //arg name (to display) + 1, //argument index + 'U', 'I', 'n', 't', '3', '2', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 3 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 2, //argument index + 'U', 'F', 'i', 'x', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_SCO08[] = { + 2, //number of hashes + hashes + 0x35, 0x95, 0xfc, 0xd6, 0x8c, 0xff, 0x44, 0x5c, 0x65, 0xad, 0x99, 0xf8, 0xd4, 0xd7, 0x26, 0xb5, 0xe2, 0x88, 0x07, 0xb0, 0x61, 0x80, 0x07, 0x69, 0xc4, 0x1c, 0xbe, 0x3a, 0xdb, 0x98, 0xae, 0xec, + 0x08, 0x2e, 0x69, 0x0b, 0x96, 0x47, 0x18, 0x2c, 0xf6, 0x96, 0x9d, 0xb1, 0xa0, 0xfa, 0x8e, 0x0f, 0x17, 0x28, 0xda, 0x6d, 0xb0, 0x1f, 0xe0, 0xd4, 0x62, 0xe9, 0xf0, 0x84, 0x1c, 0x26, 0x8c, 0xbb, + 'S', 't', 'a', 'k', 'e', ' ', 'U', 'n', 's', 't', 'a', 'k', 'e', 'd', ' ', 'T', 'o', 'k', 'e', 'n', 's', 0, //tx name (to display) + 3, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'N', 'o', 'd', 'e', ' ', 'I', 'D', 0, //arg name (to display) + 0, //argument index + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 2 + ARGUMENT_TYPE_OPTIONAL, + 'D', 'e', 'l', 'e', 'g', 'a', 't', 'o', 'r', ' ', 'I', 'D', 0, //arg name (to display) + 1, //argument index + 'U', 'I', 'n', 't', '3', '2', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 3 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 2, //argument index + 'U', 'F', 'i', 'x', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_SCO09[] = { + 2, //number of hashes + hashes + 0x0b, 0xde, 0x35, 0x8f, 0x39, 0x65, 0xba, 0x2f, 0x4c, 0x18, 0xfb, 0x45, 0xb6, 0x53, 0x68, 0x57, 0xc3, 0xf5, 0x3d, 0x7d, 0x3b, 0x74, 0x0f, 0xe6, 0x6f, 0xe9, 0x3a, 0x4e, 0xbf, 0x75, 0x24, 0xc1, + 0xdf, 0x9c, 0x64, 0x86, 0xba, 0xa6, 0xf8, 0xf6, 0x85, 0x36, 0x8e, 0xa2, 0x16, 0x65, 0x92, 0x39, 0xcb, 0x81, 0xfa, 0x8e, 0xbd, 0x90, 0x62, 0xa9, 0x72, 0x3e, 0xdb, 0x54, 0xca, 0x0d, 0x75, 0x25, + 'U', 'n', 's', 't', 'a', 'k', 'e', ' ', 'A', 'l', 'l', 0, //tx name (to display) + 1, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'N', 'o', 'd', 'e', ' ', 'I', 'D', 0, //arg name (to display) + 0, //argument index + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_SCO10[] = { + 2, //number of hashes + hashes + 0x3a, 0xf1, 0x82, 0xf5, 0x68, 0xb3, 0x7a, 0x80, 0x67, 0xd3, 0xfb, 0x52, 0x4a, 0xfc, 0xfe, 0x96, 0x99, 0x1c, 0x85, 0xa9, 0x28, 0xbf, 0x76, 0x51, 0xe7, 0x30, 0xbe, 0x0e, 0x15, 0xfd, 0xb7, 0x2d, + 0x27, 0xa2, 0xb6, 0x0d, 0x53, 0x8b, 0x8b, 0xb8, 0x83, 0xb6, 0x02, 0xea, 0x83, 0xd1, 0x69, 0x79, 0x86, 0xa2, 0x9d, 0xd6, 0x9a, 0x44, 0xa9, 0x20, 0x9d, 0xc7, 0x5a, 0xff, 0xb9, 0xe6, 0x32, 0x99, + 'W', 'i', 't', 'h', 'd', 'r', 'a', 'w', ' ', 'R', 'e', 'w', 'a', 'r', 'd', ' ', 'T', 'o', 'k', 'e', 'n', 's', 0, //tx name (to display) + 3, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'N', 'o', 'd', 'e', ' ', 'I', 'D', 0, //arg name (to display) + 0, //argument index + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 2 + ARGUMENT_TYPE_OPTIONAL, + 'D', 'e', 'l', 'e', 'g', 'a', 't', 'o', 'r', ' ', 'I', 'D', 0, //arg name (to display) + 1, //argument index + 'U', 'I', 'n', 't', '3', '2', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 3 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 2, //argument index + 'U', 'F', 'i', 'x', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_SCO11[] = { + 2, //number of hashes + hashes + 0x68, 0x87, 0x91, 0x97, 0xd9, 0x61, 0xbb, 0x10, 0x4a, 0x56, 0xe1, 0xe7, 0xd3, 0x56, 0x60, 0x43, 0x6f, 0xe4, 0xc5, 0x2e, 0xd7, 0x8f, 0x79, 0xd9, 0x7f, 0xa5, 0x0a, 0xa9, 0xe9, 0x6f, 0xab, 0xf0, + 0x6d, 0x50, 0xab, 0x1e, 0xf3, 0xd7, 0x42, 0x03, 0x08, 0x1c, 0x38, 0x30, 0x6d, 0xa7, 0x4f, 0x5a, 0xd8, 0xfd, 0xd4, 0x89, 0xe4, 0x9f, 0xba, 0x73, 0x2f, 0x8b, 0xa1, 0x94, 0xd0, 0xc7, 0x81, 0xc8, + 'W', 'i', 't', 'h', 'd', 'r', 'a', 'w', ' ', 'U', 'n', 's', 't', 'a', 'k', 'e', 'd', ' ', 'T', 'o', 'k', 'e', 'n', 's', 0, //tx name (to display) + 3, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'N', 'o', 'd', 'e', ' ', 'I', 'D', 0, //arg name (to display) + 0, //argument index + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 2 + ARGUMENT_TYPE_OPTIONAL, + 'D', 'e', 'l', 'e', 'g', 'a', 't', 'o', 'r', ' ', 'I', 'D', 0, //arg name (to display) + 1, //argument index + 'U', 'I', 'n', 't', '3', '2', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 3 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 2, //argument index + 'U', 'F', 'i', 'x', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_SCO12[] = { + 2, //number of hashes + hashes + 0x07, 0x9a, 0xaa, 0x9c, 0xfb, 0x22, 0x13, 0x84, 0x15, 0x05, 0x6b, 0x43, 0xd5, 0xd9, 0x1e, 0x8d, 0x73, 0xbd, 0x8b, 0xd5, 0xf3, 0x7e, 0xbf, 0xf4, 0xf4, 0x02, 0x3d, 0x33, 0xea, 0x6d, 0x2f, 0x25, + 0xec, 0xdf, 0xfc, 0x1a, 0xe6, 0x74, 0x79, 0xbc, 0x20, 0xc0, 0x6e, 0xba, 0x6c, 0x77, 0x6f, 0xf3, 0x7b, 0x95, 0x23, 0x66, 0x0f, 0xf1, 0xcd, 0x31, 0x29, 0xa3, 0x92, 0x4d, 0x92, 0x48, 0x48, 0x84, + 'C', 'l', 'o', 's', 'e', ' ', 'S', 't', 'a', 'k', 'e', 0, //tx name (to display) + 2, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'N', 'o', 'd', 'e', ' ', 'I', 'D', 0, //arg name (to display) + 0, //argument index + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 2 + ARGUMENT_TYPE_OPTIONAL, + 'D', 'e', 'l', 'e', 'g', 'a', 't', 'o', 'r', ' ', 'I', 'D', 0, //arg name (to display) + 1, //argument index + 'U', 'I', 'n', 't', '3', '2', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_SCO13[] = { + 2, //number of hashes + hashes + 0x23, 0x86, 0xd7, 0xae, 0x1a, 0x5b, 0x93, 0x6e, 0x39, 0x14, 0x72, 0x9e, 0xe3, 0x4e, 0x01, 0xd5, 0x3a, 0x8f, 0xbd, 0x2e, 0x40, 0x35, 0x12, 0xec, 0x1b, 0xec, 0xcb, 0x40, 0x62, 0xc2, 0x31, 0xeb, + 0xcd, 0xc3, 0xa6, 0x3d, 0x0c, 0x75, 0xea, 0x95, 0xb4, 0x14, 0xbe, 0xcb, 0x6f, 0xbb, 0x8f, 0x5a, 0x80, 0x04, 0x23, 0x6d, 0x48, 0x66, 0x1c, 0xd3, 0xc3, 0xd4, 0xf5, 0x40, 0xee, 0x4d, 0x42, 0x2e, + 'T', 'r', 'a', 'n', 's', 'f', 'e', 'r', ' ', 'N', 'o', 'd', 'e', 0, //tx name (to display) + 2, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'N', 'o', 'd', 'e', ' ', 'I', 'D', 0, //arg name (to display) + 0, //argument index + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 2 + ARGUMENT_TYPE_NORMAL, + 'A', 'd', 'd', 'r', 'e', 's', 's', 0, //arg name (to display) + 1, //argument index + 'A', 'd', 'd', 'r', 'e', 's', 's', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + + +const uint8_t TX_METADATA_SCO14[] = { + 2, //number of hashes + hashes + 0x53, 0xb0, 0x96, 0xb4, 0x85, 0x0a, 0x30, 0x89, 0x4e, 0x7b, 0x27, 0x2e, 0xc5, 0xc3, 0x9e, 0x2b, 0x2f, 0x4a, 0x23, 0xf8, 0xc4, 0x0e, 0x76, 0xa3, 0xc6, 0x4c, 0xfc, 0x63, 0xdc, 0x29, 0x99, 0xb6, + 0xb3, 0x4d, 0x6f, 0xaf, 0xcc, 0x5a, 0x4d, 0x0e, 0xd9, 0xcf, 0x92, 0xe1, 0x68, 0xa0, 0x8d, 0x06, 0x74, 0xc9, 0x33, 0x41, 0xe2, 0x39, 0x3e, 0xe7, 0x2d, 0xde, 0x66, 0x64, 0x91, 0x8e, 0xc2, 0x40, + 'T', 'r', 'a', 'n', 's', 'f', 'e', 'r', ' ', 'D', 'e', 'l', 'e', 'g', 'a', 't', 'o', 'r', 0, //tx name (to display) + 3, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'N', 'o', 'd', 'e', ' ', 'I', 'D', 0, //arg name (to display) + 0, //argument index + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 2 + ARGUMENT_TYPE_NORMAL, + 'D', 'e', 'l', 'e', 'g', 'a', 't', 'o', 'r', ' ', 'I', 'D', 0, //arg name (to display) + 1, //argument index + 'U', 'I', 'n', 't', '3', '2', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 3 + ARGUMENT_TYPE_NORMAL, + 'A', 'd', 'd', 'r', 'e', 's', 's', 0, //arg name (to display) + 2, //argument index + 'A', 'd', 'd', 'r', 'e', 's', 's', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_SCO15[] = { + 2, //number of hashes + hashes + 0x39, 0xa1, 0x26, 0x03, 0x85, 0x22, 0xc6, 0xc9, 0x64, 0xd5, 0x3a, 0xaf, 0x78, 0xdd, 0xe5, 0x5b, 0xfe, 0x80, 0x92, 0x90, 0x91, 0x51, 0x07, 0x92, 0xfe, 0x49, 0x67, 0x8b, 0xb2, 0x2c, 0xbd, 0x96, + 0xf9, 0xc4, 0x8e, 0x18, 0xbd, 0xa7, 0xf1, 0x13, 0xe8, 0x27, 0x11, 0xa4, 0xc9, 0x5d, 0xfd, 0x15, 0x1c, 0x66, 0x00, 0xed, 0x9f, 0xbf, 0x46, 0xce, 0xb2, 0x25, 0x66, 0xd6, 0xc5, 0x72, 0x8c, 0x6f, + 'W', 'i', 't', 'h', 'd', 'r', 'a', 'w', ' ', 'F', 'r', 'o', 'm', ' ', 'M', 'a', 'c', 'h', 'i', 'n', 'e', ' ', 'A', 'c', 'c', 'o', 'u', 'n', 't', 0, //tx name (to display) + 2, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'N', 'o', 'd', 'e', ' ', 'I', 'D', 0, //arg name (to display) + 0, //argument index + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 2 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 1, //argument index + 'U', 'F', 'i', 'x', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_SCO16[] = { + 2, //number of hashes + hashes + 0x60, 0xf2, 0xcf, 0x21, 0x9d, 0x56, 0xb1, 0x9d, 0xc7, 0xfd, 0x22, 0x3c, 0xae, 0xd4, 0x2d, 0xda, 0x91, 0x43, 0xc8, 0x7b, 0x1b, 0x0d, 0x2c, 0x21, 0xa9, 0x65, 0x2e, 0x12, 0xa3, 0x71, 0x41, 0x33, + 0xff, 0x06, 0x7b, 0x40, 0xac, 0x67, 0x02, 0x0e, 0xf8, 0x64, 0xcd, 0x14, 0x84, 0x2f, 0x62, 0x02, 0x32, 0x54, 0xda, 0x34, 0xdd, 0x2d, 0xed, 0x56, 0xaf, 0xfa, 0x13, 0x64, 0x30, 0x5b, 0xf1, 0xc5, + 'U', 'p', 'd', 'a', 't', 'e', ' ', 'N', 'e', 't', 'w', 'o', 'r', 'k', 'i', 'n', 'g', ' ', 'A', 'd', 'd', 'r', 'e', 's', 's', 0, //tx name (to display) + 2, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'N', 'o', 'd', 'e', ' ', 'I', 'D', 0, //arg name (to display) + 0, //argument index + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 2 + ARGUMENT_TYPE_NORMAL, + 'A', 'd', 'd', 'r', 'e', 's', 's', 0, //arg name (to display) + 1, //argument index + 'S', 't', 'r', 'i', 'n', 'g', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_FUSD01[] = { + 2, //number of hashes + hashes + 0x0f, 0xfa, 0xf7, 0x7a, 0xb3, 0x20, 0xce, 0x4c, 0xc9, 0x60, 0x2d, 0x39, 0xb8, 0x9c, 0x85, 0xf0, 0x94, 0xeb, 0xce, 0xa5, 0x71, 0xed, 0x32, 0x45, 0x37, 0xe7, 0x03, 0xbc, 0x07, 0xb0, 0xfd, 0xc4, + 0xaa, 0x7f, 0xec, 0xdf, 0x15, 0x9e, 0x71, 0xbd, 0x0b, 0x02, 0x9e, 0x40, 0xb2, 0x26, 0x43, 0xfb, 0x44, 0x31, 0x61, 0xe6, 0x77, 0x96, 0xf4, 0x2b, 0xac, 0x68, 0xe9, 0xba, 0xb4, 0x63, 0x0e, 0x29, + 'S', 'e', 't', 'u', 'p', ' ', 'F', 'U', 'S', 'D', ' ', 'V', 'a', 'u', 'l', 't', 0, //tx name (to display) + 0, //number of arguments +}; + +const uint8_t TX_METADATA_FUSD02[] = { + 2, //number of hashes + hashes + 0xf2, 0x2c, 0xa4, 0xb3, 0x50, 0xa7, 0x9c, 0x72, 0x4f, 0x64, 0x71, 0xd5, 0xa6, 0xa7, 0xa0, 0xef, 0xa7, 0xba, 0x9a, 0xee, 0xbb, 0x7f, 0xed, 0x28, 0x43, 0xa3, 0xdd, 0xd6, 0xe4, 0x2c, 0x2e, 0x1c, + 0x18, 0x0c, 0xef, 0x70, 0x53, 0xa5, 0xf0, 0xae, 0x66, 0xe1, 0x9e, 0x3a, 0x96, 0xcc, 0x3b, 0x9e, 0xb7, 0xda, 0x29, 0x76, 0x7f, 0xb5, 0xd6, 0x93, 0x82, 0x39, 0xbf, 0x1f, 0x8e, 0x1d, 0xc2, 0x84, + 'T', 'r', 'a', 'n', 's', 'f', 'e', 'r', ' ', 'F', 'U', 'S', 'D', 0, //tx name (to display) + 2, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 0, //argument index + 'U', 'F', 'i', 'x', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 2 + ARGUMENT_TYPE_NORMAL, + 'R', 'e', 'c', 'i', 'p', 'i', 'e', 'n', 't', 0, //arg name (to display) + 1, //argument index + 'A', 'd', 'd', 'r', 'e', 's', 's', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +const uint8_t TX_METADATA_TS01[] = { + 2, //number of hashes + hashes + 0x0f, 0x0b, 0xae, 0xef, 0x93, 0x53, 0xce, 0xee, 0x60, 0x7c, 0x5b, 0xe3, 0xb7, 0xc0, 0xf8, 0x67, 0x92, 0xda, 0xdf, 0x20, 0xb9, 0xe9, 0xc8, 0x9e, 0x83, 0x1a, 0xdb, 0x01, 0x99, 0xe7, 0x58, 0x82, + 0x75, 0x11, 0x84, 0x8f, 0x1c, 0x27, 0xa1, 0x73, 0xd9, 0x66, 0xf4, 0xb8, 0x68, 0xfd, 0x7e, 0xfe, 0xad, 0x7e, 0xeb, 0x1b, 0xbf, 0x04, 0xfc, 0x3f, 0x3e, 0x60, 0xda, 0xbc, 0x6c, 0x7f, 0x75, 0x93, + 'S', 'e', 't', ' ', 'U', 'p', ' ', 'T', 'o', 'p', ' ', 'S', 'h', 'o', 't', ' ', 'C', 'o', 'l', 'l', 'e', 'c', 't', 'i', 'o', 'n', 0, //tx name (to display) + 0, //number of arguments +}; + +const uint8_t TX_METADATA_TS02[] = { + 2, //number of hashes + hashes + 0x1e, 0xc9, 0xae, 0xa0, 0xb5, 0x14, 0x09, 0x61, 0x0f, 0x88, 0x2f, 0x5a, 0xe4, 0x27, 0x85, 0x67, 0xda, 0x67, 0x55, 0x42, 0xbb, 0x37, 0x8e, 0xb9, 0x99, 0xf0, 0x5b, 0x7c, 0x4f, 0x12, 0xf7, 0xd8, + 0x09, 0xd5, 0xad, 0x21, 0xbf, 0x70, 0xdf, 0xe4, 0xf8, 0xd8, 0x00, 0xdb, 0x9e, 0x61, 0xa7, 0x7f, 0x2f, 0x64, 0x83, 0x7a, 0xe0, 0xe8, 0x18, 0xc3, 0xcd, 0x67, 0xe9, 0xce, 0xa8, 0x37, 0xa1, 0xcf, + 'T', 'r', 'a', 'n', 's', 'f', 'e', 'r', ' ', 'T', 'o', 'p', ' ', 'S', 'h', 'o', 't', ' ', 'M', 'o', 'm', 'e', 'n', 't', 0, //tx name (to display) + 2, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'M', 'o', 'm', 'e', 'n', 't', ' ', 'I', 'D', 0, //arg name (to display) + 1, //argument index + 'U', 'I', 'n', 't', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 2 + ARGUMENT_TYPE_NORMAL, + 'A', 'd', 'd', 'r', 'e', 's', 's', 0, //arg name (to display) + 0, //argument index + 'A', 'd', 'd', 'r', 'e', 's', 's', 0, //expected value type JSMN_STRING, //expected value json token type }; +const uint8_t TX_METADATA_USDC01[] = { + 2, //number of hashes + hashes + 0x2d, 0xef, 0xee, 0x81, 0x8c, 0x0c, 0x00, 0x3c, 0xa5, 0x19, 0xf8, 0x35, 0x17, 0xf4, 0xc7, 0xbc, 0xf9, 0xdd, 0x86, 0x64, 0xa5, 0x62, 0xec, 0x80, 0x95, 0x9c, 0xb6, 0x14, 0x64, 0x28, 0xf9, 0x71, + 0x88, 0x76, 0x73, 0x89, 0x2a, 0x2e, 0x2c, 0x12, 0x33, 0x73, 0x94, 0x57, 0x0d, 0xfa, 0x30, 0xc5, 0x66, 0x9e, 0x93, 0xf5, 0x37, 0xae, 0x42, 0x66, 0x90, 0xf4, 0x02, 0x79, 0x95, 0x14, 0xa9, 0xa1, + 'S', 'e', 't', 'u', 'p', ' ', 'U', 'S', 'D', 'C', ' ', 'V', 'a', 'u', 'l', 't', 0, //tx name (to display) + 0, //number of arguments +}; + +const uint8_t TX_METADATA_USDC02[] = { + 2, //number of hashes + hashes + 0x51, 0x24, 0x85, 0xec, 0x3f, 0x8e, 0x00, 0x78, 0x53, 0xb0, 0xea, 0x2a, 0x22, 0xfb, 0x2b, 0x9f, 0x7e, 0x2f, 0xa5, 0x5f, 0xd9, 0x81, 0x91, 0x71, 0xc5, 0xd0, 0x13, 0x28, 0x2e, 0xfe, 0xe6, 0x0a, + 0x7f, 0xf4, 0xd9, 0xf5, 0x3b, 0xa5, 0xee, 0xbd, 0xa5, 0x56, 0xd0, 0xea, 0xd0, 0xca, 0x13, 0x91, 0x1b, 0xc8, 0x99, 0x6e, 0x2c, 0x91, 0xc5, 0x14, 0x7f, 0x87, 0x87, 0xd1, 0x0a, 0x32, 0x44, 0x83, + 'T', 'r', 'a', 'n', 's', 'f', 'e', 'r', ' ', 'U', 'S', 'D', 'C', 0, //tx name (to display) + 2, //number of arguments + + //Argument 1 + ARGUMENT_TYPE_NORMAL, + 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) + 0, //argument index + 'U', 'F', 'i', 'x', '6', '4', 0, //expected value type + JSMN_STRING, //expected value json token type + + //Argument 2 + ARGUMENT_TYPE_NORMAL, + 'R', 'e', 'c', 'i', 'p', 'i', 'e', 'n', 't', 0, //arg name (to display) + 1, //argument index + 'A', 'd', 'd', 'r', 'e', 's', 's', 0, //expected value type + JSMN_STRING, //expected value json token type +}; + +//-------------------------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------------------------- //List of known compressed metadata typedef struct { @@ -65,17 +916,58 @@ const static known_tx_metadata_entry_t KNOWN_TX_METADATA[] = { {TX_METADATA_CREATE_ACCOUNT, sizeof(TX_METADATA_CREATE_ACCOUNT)}, {TX_METADATA_ADD_NEW_KEY, sizeof(TX_METADATA_ADD_NEW_KEY)}, {TX_METADATA_TOKEN_TRANSFER, sizeof(TX_METADATA_TOKEN_TRANSFER)}, + {TX_METADATA_TH01, sizeof(TX_METADATA_TH01)}, + {TX_METADATA_TH02, sizeof(TX_METADATA_TH02)}, + {TX_METADATA_TH06, sizeof(TX_METADATA_TH06)}, + {TX_METADATA_TH08, sizeof(TX_METADATA_TH08)}, + {TX_METADATA_TH09, sizeof(TX_METADATA_TH09)}, + {TX_METADATA_TH10, sizeof(TX_METADATA_TH10)}, + {TX_METADATA_TH11, sizeof(TX_METADATA_TH11)}, + {TX_METADATA_TH12, sizeof(TX_METADATA_TH12)}, + {TX_METADATA_TH13, sizeof(TX_METADATA_TH13)}, + {TX_METADATA_TH14, sizeof(TX_METADATA_TH14)}, + {TX_METADATA_TH16, sizeof(TX_METADATA_TH16)}, + {TX_METADATA_TH17, sizeof(TX_METADATA_TH17)}, + {TX_METADATA_TH19, sizeof(TX_METADATA_TH19)}, + {TX_METADATA_TH20, sizeof(TX_METADATA_TH20)}, + {TX_METADATA_TH21, sizeof(TX_METADATA_TH21)}, + {TX_METADATA_TH22, sizeof(TX_METADATA_TH22)}, + {TX_METADATA_TH23, sizeof(TX_METADATA_TH23)}, + {TX_METADATA_TH24, sizeof(TX_METADATA_TH24)}, + {TX_METADATA_TH25, sizeof(TX_METADATA_TH25)}, + {TX_METADATA_SCO01, sizeof(TX_METADATA_SCO01)}, + {TX_METADATA_SCO02, sizeof(TX_METADATA_SCO02)}, + {TX_METADATA_SCO03, sizeof(TX_METADATA_SCO03)}, + {TX_METADATA_SCO04, sizeof(TX_METADATA_SCO04)}, + {TX_METADATA_SCO05, sizeof(TX_METADATA_SCO05)}, + {TX_METADATA_SCO06, sizeof(TX_METADATA_SCO06)}, + {TX_METADATA_SCO07, sizeof(TX_METADATA_SCO07)}, + {TX_METADATA_SCO08, sizeof(TX_METADATA_SCO08)}, + {TX_METADATA_SCO09, sizeof(TX_METADATA_SCO09)}, + {TX_METADATA_SCO10, sizeof(TX_METADATA_SCO10)}, + {TX_METADATA_SCO11, sizeof(TX_METADATA_SCO11)}, + {TX_METADATA_SCO12, sizeof(TX_METADATA_SCO12)}, + {TX_METADATA_SCO13, sizeof(TX_METADATA_SCO13)}, + {TX_METADATA_SCO14, sizeof(TX_METADATA_SCO14)}, + {TX_METADATA_SCO15, sizeof(TX_METADATA_SCO15)}, + {TX_METADATA_SCO16, sizeof(TX_METADATA_SCO16)}, + {TX_METADATA_FUSD01, sizeof(TX_METADATA_FUSD01)}, + {TX_METADATA_FUSD02, sizeof(TX_METADATA_FUSD02)}, + {TX_METADATA_TS01, sizeof(TX_METADATA_TS01)}, + {TX_METADATA_TS02, sizeof(TX_METADATA_TS02)}, + {TX_METADATA_USDC01, sizeof(TX_METADATA_USDC01)}, + {TX_METADATA_USDC02, sizeof(TX_METADATA_USDC02)}, // sentinel, do not remove {NULL, 0} }; parser_error_t _validateHash(uint8_t scriptHash[SCRIPT_HASH_SIZE], const NV_VOLATILE uint8_t *txMetadata, uint16_t txMetadataLength) { if (txMetadataLength < 1) { - return PARSER_TEMPLATE_ERROR; + return PARSER_METADATA_ERROR; } uint8_t numberOfHashes = txMetadata[0]; - if (numberOfHashes > MAX_TEMPLATE_NUMBER_OF_HASHES || txMetadataLength < 1+SCRIPT_HASH_SIZE*numberOfHashes) { - return PARSER_TEMPLATE_ERROR; + if (numberOfHashes > MAX_METADATA_NUMBER_OF_HASHES || txMetadataLength < 1+SCRIPT_HASH_SIZE*numberOfHashes) { + return PARSER_METADATA_ERROR; } for(size_t i=0; i MAX_TEMPLATE_STRING_LENGTH) { \ - return PARSER_TEMPLATE_ERROR; \ + if (*(len) > MAX_METADATA_STRING_LENGTH) { \ + return PARSER_METADATA_ERROR; \ } \ } #define READ_SKIP(count) { \ @@ -129,9 +1021,9 @@ parser_error_t parseTxMetadata(uint8_t scriptHash[SCRIPT_HASH_SIZE], const NV_VO //read number of hashes and validate script { uint8_t numberOfHashes = 0; - READ_CHAR(&numberOfHashes); - if (numberOfHashes > MAX_TEMPLATE_NUMBER_OF_HASHES) { - return PARSER_TEMPLATE_TOO_MANY_HASHES; + READ_CHAR(&numberOfHashes) + if (numberOfHashes > MAX_METADATA_NUMBER_OF_HASHES) { + return PARSER_METADATA_TOO_MANY_HASHES; } parser_error_t err = _validateHash(scriptHash, txMetadata, txMetadataLength); if (err != PARSER_OK) { @@ -143,16 +1035,26 @@ parser_error_t parseTxMetadata(uint8_t scriptHash[SCRIPT_HASH_SIZE], const NV_VO //read tx name READ_STRING(&parsedTxMetadata->txName, &parsedTxMetadata->txNameLength) - //read Arguments + //read arguments { READ_CHAR(&parsedTxMetadata->argCount) if (parsedTxMetadata->argCount > PARSER_MAX_ARGCOUNT) { - return PARSER_TEMPLATE_TOO_MANY_ARGUMENTS; + return PARSER_METADATA_TOO_MANY_ARGUMENTS; } STATIC_ASSERT(sizeof(parsedTxMetadata->arguments) >= PARSER_MAX_ARGCOUNT, "Too few arguments in parsed_tx_metadata_t."); for(int i=0; iargCount; i++) { READ_CHAR(&parsedTxMetadata->arguments[i].argumentType); - READ_STRING(&parsedTxMetadata->arguments[i].displayKey, &parsedTxMetadata->arguments[i].displayKeyLength); + argument_type_e argumentType = parsedTxMetadata->arguments[i].argumentType; + if (argumentType == ARGUMENT_TYPE_ARRAY || argumentType == ARGUMENT_TYPE_OPTIONALARRAY) { + READ_CHAR(&parsedTxMetadata->arguments[i].arrayMinElements); + READ_CHAR(&parsedTxMetadata->arguments[i].arrayMaxElements); + uint8_t min = parsedTxMetadata->arguments[i].arrayMinElements; + uint8_t max = parsedTxMetadata->arguments[i].arrayMaxElements; + if (min > max || max > MAX_METADATA_MAX_ARRAY_ITEMS) { + return PARSER_METADATA_ERROR; + } + } + READ_STRING(&parsedTxMetadata->arguments[i].displayKey, &parsedTxMetadata->arguments[i].displayKeyLength) READ_CHAR(&parsedTxMetadata->arguments[i].argumentIndex); READ_STRING(&parsedTxMetadata->arguments[i].jsonExpectedType, &parsedTxMetadata->arguments[i].jsonExpectedTypeLength); READ_CHAR(&parsedTxMetadata->arguments[i].jsonExpectedKind); @@ -165,7 +1067,7 @@ parser_error_t parseTxMetadata(uint8_t scriptHash[SCRIPT_HASH_SIZE], const NV_VO #undef READ_SKIP if (parsed != txMetadataLength) { - return PARSER_TEMPLATE_ERROR; + return PARSER_METADATA_ERROR; } return PARSER_OK; diff --git a/app/src/tx_metadata.h b/app/src/tx_metadata.h index 2ac1de2f..81bc84e9 100644 --- a/app/src/tx_metadata.h +++ b/app/src/tx_metadata.h @@ -21,9 +21,9 @@ extern "C" { #endif #include -#include #include #include +#include typedef enum { ARGUMENT_TYPE_NORMAL = 1, @@ -32,12 +32,13 @@ typedef enum { ARGUMENT_TYPE_OPTIONALARRAY = 4 } argument_type_e; -#define MAX_TEMPLATE_NUMBER_OF_HASHES 10 -#define MAX_TEMPLATE_STRING_LENGTH 100 +#define PARSER_MAX_ARGCOUNT 10 //It is planed that all these strings may be on flash, thus they are volatile (for NanoX and NanoSPlus) typedef struct { argument_type_e argumentType; + uint8_t arrayMinElements; //defined only for ARGUMENT_TYPE_ARRAY and ARGUMENT_TYPE_OPTIOALARRAY + uint8_t arrayMaxElements; //defined only for ARGUMENT_TYPE_ARRAY and ARGUMENT_TYPE_OPTIOALARRAY const NV_VOLATILE char *displayKey; uint8_t displayKeyLength; uint8_t argumentIndex; //argument index within transaction @@ -47,7 +48,6 @@ typedef struct { } parsed_tx_metadata_argument_t; typedef struct { - script_type_e script; const NV_VOLATILE char *txName; uint8_t txNameLength; uint8_t argCount; diff --git a/tests/tx_metadata.cpp b/tests/tx_metadata.cpp index dc321c11..f24c6778 100644 --- a/tests/tx_metadata.cpp +++ b/tests/tx_metadata.cpp @@ -45,7 +45,7 @@ const uint8_t TX_METADATA_TOKEN_TRANSFER[] = { 2, //number of arguments //Argument 1 - ARGUMENT_TYPE_NORMAL, + ARGUMENT_TYPE_OPTIONALARRAY, 5, 10, 'A', 'm', 'o', 'u', 'n', 't', 0, //arg name (to display) 0, //argument index 'U','I', 'n', 't', '6', '4', 0, //expected value type @@ -86,10 +86,10 @@ TEST(tx_data, validateHash) { EXPECT_THAT(err, PARSER_UNEXPECTED_SCRIPT); err = _validateHash(hashTokenTranfer3, TX_METADATA_ADD_NEW_KEY, 0); - EXPECT_THAT(err, PARSER_TEMPLATE_ERROR); + EXPECT_THAT(err, PARSER_METADATA_ERROR); err = _validateHash(hashTokenTranfer3, TX_METADATA_TOKEN_TRANSFER, 3*32); - EXPECT_THAT(err, PARSER_TEMPLATE_ERROR); + EXPECT_THAT(err, PARSER_METADATA_ERROR); err = _validateHash(hashTokenTranfer3, TX_METADATA_TOKEN_TRANSFER, 3*32+1); EXPECT_THAT(err, PARSER_OK); @@ -120,7 +120,9 @@ TEST(tx_data, parseCompressedTxData) { EXPECT_THAT(std::string(result.txName), "Token Transfer"); EXPECT_THAT(result.txNameLength, 14); EXPECT_THAT(result.argCount, 2); - EXPECT_THAT(result.arguments[0].argumentType, ARGUMENT_TYPE_NORMAL); + EXPECT_THAT(result.arguments[0].argumentType, ARGUMENT_TYPE_OPTIONALARRAY); + EXPECT_THAT(result.arguments[0].arrayMinElements, 5); + EXPECT_THAT(result.arguments[0].arrayMaxElements, 10); EXPECT_THAT(std::string(result.arguments[0].displayKey), "Amount"); EXPECT_THAT(result.arguments[0].displayKeyLength, 6); EXPECT_THAT(result.arguments[0].argumentIndex, 0); @@ -136,12 +138,12 @@ TEST(tx_data, parseCompressedTxData) { EXPECT_THAT(result.arguments[1].jsonExpectedKind, JSMN_STRING); err = parseTxMetadata(hashAddNewKey, TX_METADATA_ADD_NEW_KEY, sizeof(TX_METADATA_ADD_NEW_KEY)-1, &result); - EXPECT_THAT(err, PARSER_TEMPLATE_ERROR); + EXPECT_THAT(err, PARSER_METADATA_ERROR); err = parseTxMetadata(hashTokenTranfer3, TX_METADATA_TOKEN_TRANSFER, sizeof(TX_METADATA_TOKEN_TRANSFER)+1, &result); - EXPECT_THAT(err, PARSER_TEMPLATE_ERROR); + EXPECT_THAT(err, PARSER_METADATA_ERROR); } -TEST(tx_data, matchStoredCompressedTxData) { +TEST(tx_data, matchStoreTxMetadata) { parser_error_t err; parsed_tx_metadata_t result; @@ -171,7 +173,7 @@ TEST(tx_data, matchStoredCompressedTxData) { EXPECT_THAT(std::string(result.arguments[0].displayKey), "Amount"); EXPECT_THAT(result.arguments[0].displayKeyLength, 6); EXPECT_THAT(result.arguments[0].argumentIndex, 0); - EXPECT_THAT(std::string(result.arguments[0].jsonExpectedType), "UInt64"); + EXPECT_THAT(std::string(result.arguments[0].jsonExpectedType), "UFix64"); EXPECT_THAT(result.arguments[0].jsonExpectedTypeLength, 6); EXPECT_THAT(result.arguments[0].jsonExpectedKind, JSMN_STRING); EXPECT_THAT(result.arguments[1].argumentType, ARGUMENT_TYPE_NORMAL); diff --git a/tests/utils/expected_output.cpp b/tests/utils/expected_output.cpp index 2882e4de..d9180841 100644 --- a/tests/utils/expected_output.cpp +++ b/tests/utils/expected_output.cpp @@ -78,351 +78,48 @@ std::vector GenerateExpectedUIOutput(const testcaseData_t &tcd) { } uint8_t scriptHash[32]; - script_type_e scriptType = SCRIPT_UNKNOWN; sha256((const uint8_t *) tcd.script.c_str(), tcd.script.length(), scriptHash); - _matchScriptType(scriptHash, &scriptType); uint16_t item = 0; uint8_t dummy; - - switch (scriptType) { - case SCRIPT_UNKNOWN: - addTo(answer, "{} | Type :Unknown", item++); - break; - case SCRIPT_TOKEN_TRANSFER: { - addTo(answer, "{} | Type : Token Transfer", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addTo(answer, "{} | Amount : {}", item++, tcd.arguments[0]["value"].asString()); - addTo(answer, "{} | Destination : {}", item++, tcd.arguments[1]["value"].asString()); - break; - } - case SCRIPT_CREATE_ACCOUNT: { - addTo(answer, "{} | Type : Create Account", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - const auto pks = tcd.arguments[0]["value"]; - - for (uint16_t i = 0; i < (uint16_t) pks.size(); i++) { - addMultiStringArgumentTo(answer, fmt::format("Pub key {}", i + 1), item++, pks[i]["value"]); - } - break; - } - case SCRIPT_ADD_NEW_KEY: { - addTo(answer, "{} | Type : Add New Key", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addMultiStringArgumentTo(answer, "Pub key", item++, tcd.arguments[0]["value"]); - break; - } - case SCRIPT_TH01_WITHDRAW_UNLOCKED_TOKENS: { - addTo(answer, "{} | Type : Withdraw FLOW from Lockbox", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addTo(answer, "{} | Amount : {}", item++, tcd.arguments[0]["value"].asString()); - break; - } - case SCRIPT_TH02_DEPOSIT_UNLOCKED_TOKENS: { - addTo(answer, "{} | Type : Deposit FLOW to Lockbox", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addTo(answer, "{} | Amount : {}", item++, tcd.arguments[0]["value"].asString()); - break; - } - case SCRIPT_TH06_REGISTER_NODE: { - addTo(answer, "{} | Type : Register Staked Node", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addMultiStringArgumentTo(answer, "Node ID", item++, tcd.arguments[0]["value"]); - addTo(answer, "{} | Node Role : {}", item++, tcd.arguments[1]["value"].asString()); - addMultiStringArgumentTo(answer, "Networking Address", item++, tcd.arguments[2]["value"]); - addMultiStringArgumentTo(answer, "Networking Key", item++, tcd.arguments[3]["value"]); - addMultiStringArgumentTo(answer, "Staking Key", item++, tcd.arguments[4]["value"]); - addTo(answer, "{} | Amount : {}", item++, tcd.arguments[5]["value"].asString()); - break; - } - case SCRIPT_TH08_STAKE_NEW_TOKENS: { - addTo(answer, "{} | Type : Stake FLOW from Lockbox", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addTo(answer, "{} | Amount : {}", item++, tcd.arguments[0]["value"].asString()); - break; - } - case SCRIPT_TH09_RESTAKE_UNSTAKED_TOKENS: { - addTo(answer, "{} | Type : Restake Unstaked FLOW", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addTo(answer, "{} | Amount : {}", item++, tcd.arguments[0]["value"].asString()); - break; - } - case SCRIPT_TH10_RESTAKE_REWARDED_TOKENS: { - addTo(answer, "{} | Type : Restake Rewarded FLOW", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addTo(answer, "{} | Amount : {}", item++, tcd.arguments[0]["value"].asString()); - break; - } - case SCRIPT_TH11_UNSTAKE_TOKENS: { - addTo(answer, "{} | Type : Unstake FLOW", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addTo(answer, "{} | Amount : {}", item++, tcd.arguments[0]["value"].asString()); - break; - } - case SCRIPT_TH12_UNSTAKE_ALL_TOKENS: { - addTo(answer, "{} | Type : Unstake All FLOW", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - break; - } - case SCRIPT_TH13_WITHDRAW_UNSTAKED_TOKENS: { - addTo(answer, "{} | Type : Withdraw Unstaked FLOW to Lockbox", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addTo(answer, "{} | Amount : {}", item++, tcd.arguments[0]["value"].asString()); - break; - } - case SCRIPT_TH14_WITHDRAW_REWARDED_TOKENS: { - addTo(answer, "{} | Type : Withdraw Rewarded FLOW to Lockbox", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addTo(answer, "{} | Amount : {}", item++, tcd.arguments[0]["value"].asString()); - break; - } - case SCRIPT_TH16_REGISTER_OPERATOR_NODE: { - addTo(answer, "{} | Type : Register Operator Node", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addTo(answer, "{} | Operator Address : {}", item++, tcd.arguments[0]["value"].asString()); - addMultiStringArgumentTo(answer, "Node ID", item++, tcd.arguments[1]["value"]); - addTo(answer, "{} | Amount : {}", item++, tcd.arguments[2]["value"].asString()); - break; - } - case SCRIPT_TH17_REGISTER_DELEGATOR: { - addTo(answer, "{} | Type : Register Delegator", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addMultiStringArgumentTo(answer, "Node ID", item++, tcd.arguments[0]["value"]); - addTo(answer, "{} | Amount : {}", item++, tcd.arguments[1]["value"].asString()); - break; - } - case SCRIPT_TH19_DELEGATE_NEW_TOKENS: { - addTo(answer, "{} | Type : Delegate FLOW from Lockbox", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addTo(answer, "{} | Amount : {}", item++, tcd.arguments[0]["value"].asString()); - break; - } - case SCRIPT_TH20_RESTAKE_UNSTAKED_DELEGATED_TOKENS: { - addTo(answer, "{} | Type : Re-delegate Unstaked FLOW", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addTo(answer, "{} | Amount : {}", item++, tcd.arguments[0]["value"].asString()); - break; - } - case SCRIPT_TH21_RESTAKE_REWARDED_DELEGATED_TOKENS: { - addTo(answer, "{} | Type : Re-delegate Rewarded FLOW", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addTo(answer, "{} | Amount : {}", item++, tcd.arguments[0]["value"].asString()); - break; - } - case SCRIPT_TH22_UNSTAKE_DELEGATED_TOKENS: { - addTo(answer, "{} | Type : Unstake Delegated FLOW", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addTo(answer, "{} | Amount : {}", item++, tcd.arguments[0]["value"].asString()); - break; - } - case SCRIPT_TH23_WITHDRAW_UNSTAKED_DELEGATED_TOKENS: { - addTo(answer, "{} | Type : Withdraw Undelegated FLOW to Lockbox", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addTo(answer, "{} | Amount : {}", item++, tcd.arguments[0]["value"].asString()); - break; - } - case SCRIPT_TH24_WITHDRAW_REWARDED_DELEGATED_TOKENS: { - addTo(answer, "{} | Type : Withdraw Delegate Rewards to Lockbox", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addTo(answer, "{} | Amount : {}", item++, tcd.arguments[0]["value"].asString()); - break; - } - case SCRIPT_TH25_UPDATE_NETWORKING_ADDRESS: { - addTo(answer, "{} | Type : Update Networking Address", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addMultiStringArgumentTo(answer, "Address", item++, tcd.arguments[0]["value"]); - break; - } - case SCRIPT_SCO01_SETUP_STAKING_COLLECTION: { - addTo(answer, "{} | Type : Setup Staking Collection", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - break; - } - case SCRIPT_SCO02_REGISTER_DELEGATOR: { - addTo(answer, "{} | Type : Register Delegator", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addMultiStringArgumentTo(answer, "Node ID", item++, tcd.arguments[0]["value"]); - addTo(answer, "{} | Amount : {}", item++, tcd.arguments[1]["value"].asString()); - break; - } - case SCRIPT_SCO03_REGISTER_NODE: { - addTo(answer, "{} | Type : Register Node", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addMultiStringArgumentTo(answer, "Node ID", item++, tcd.arguments[0]["value"]); - addTo(answer, "{} | Node Role : {}", item++, tcd.arguments[1]["value"].asString()); - addMultiStringArgumentTo(answer, "Netw. Addr.", item++, tcd.arguments[2]["value"]); - addMultiStringArgumentTo(answer, "Netw. Key", item++, tcd.arguments[3]["value"]); - addMultiStringArgumentTo(answer, "Staking Key", item++, tcd.arguments[4]["value"]); - addTo(answer, "{} | Amount : {}", item++, tcd.arguments[5]["value"].asString()); - if (tcd.arguments[6]["value"].isObject()) { - for (uint16_t i = 0; i < (uint16_t) tcd.arguments[6]["value"]["value"].size(); i++) { - addMultiStringArgumentTo(answer, fmt::format("Pub key {}", i + 1), item++, tcd.arguments[6]["value"]["value"][i]["value"]); + + parsed_tx_metadata_t m; + matchStoredTxMetadata(scriptHash, &m); + + addTo(answer, "{} | Type : {}", item++, m.txName); + addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); + for(int i=0; iargumentIndex; + + switch(ma->argumentType) { + case ARGUMENT_TYPE_NORMAL: + addMultiStringArgumentTo(answer, ma->displayKey, item++, tcd.arguments[argNo]["value"]); + break; + case ARGUMENT_TYPE_OPTIONAL: + if (tcd.arguments[1]["value"].isObject()) { + addMultiStringArgumentTo(answer, ma->displayKey, item++, tcd.arguments[argNo]["value"]["value"]); } - } - else { - addTo(answer, "{} | Pub key 1 : None", item++); - } - break; - } - case SCRIPT_SCO04_CREATE_MACHINE_ACCOUNT: { - addTo(answer, "{} | Type : Create Machine Account", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addMultiStringArgumentTo(answer, "Node ID", item++, tcd.arguments[0]["value"]); - for (uint16_t i = 0; i < (uint16_t) tcd.arguments[1]["value"].size(); i++) { - addMultiStringArgumentTo(answer, fmt::format("Pub key {}", i + 1), item++, tcd.arguments[1]["value"][i]["value"]); - } - break; - } - case SCRIPT_SCO05_REQUEST_UNSTAKING: { - addTo(answer, "{} | Type : Request Unstaking", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addMultiStringArgumentTo(answer, "Node ID", item++, tcd.arguments[0]["value"]); - if (tcd.arguments[1]["value"].isObject()) - addTo(answer, "{} | Delegator ID : {}", item++, tcd.arguments[1]["value"]["value"].asString()); - else - addTo(answer, "{} | Delegator ID : None", item++); - addTo(answer, "{} | Amount : {}", item++, tcd.arguments[2]["value"].asString()); - break; - } - case SCRIPT_SCO06_STAKE_NEW_TOKENS: { - addTo(answer, "{} | Type : Stake New Tokens", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addMultiStringArgumentTo(answer, "Node ID", item++, tcd.arguments[0]["value"]); - if (tcd.arguments[1]["value"].isObject()) - addTo(answer, "{} | Delegator ID : {}", item++, tcd.arguments[1]["value"]["value"].asString()); - else - addTo(answer, "{} | Delegator ID : None", item++); - addTo(answer, "{} | Amount : {}", item++, tcd.arguments[2]["value"].asString()); - break; - } - case SCRIPT_SCO07_STAKE_REWARD_TOKENS: { - addTo(answer, "{} | Type : Stake Reward Tokens", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addMultiStringArgumentTo(answer, "Node ID", item++, tcd.arguments[0]["value"]); - if (tcd.arguments[1]["value"].isObject()) - addTo(answer, "{} | Delegator ID : {}", item++, tcd.arguments[1]["value"]["value"].asString()); - else - addTo(answer, "{} | Delegator ID : None", item++); - addTo(answer, "{} | Amount : {}", item++, tcd.arguments[2]["value"].asString()); - break; - } - case SCRIPT_SCO08_STAKE_UNSTAKED_TOKENS: { - addTo(answer, "{} | Type : Stake Unstaked Tokens", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addMultiStringArgumentTo(answer, "Node ID", item++, tcd.arguments[0]["value"]); - if (tcd.arguments[1]["value"].isObject()) - addTo(answer, "{} | Delegator ID : {}", item++, tcd.arguments[1]["value"]["value"].asString()); - else - addTo(answer, "{} | Delegator ID : None", item++); - addTo(answer, "{} | Amount : {}", item++, tcd.arguments[2]["value"].asString()); - break; - } - case SCRIPT_SCO09_UNSTAKE_ALL: { - addTo(answer, "{} | Type : Unstake All", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addMultiStringArgumentTo(answer, "Node ID", item++, tcd.arguments[0]["value"]); - break; - } - case SCRIPT_SCO10_WITHDRAW_REWARD_TOKENS: { - addTo(answer, "{} | Type : Withdraw Reward Tokens", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addMultiStringArgumentTo(answer, "Node ID", item++, tcd.arguments[0]["value"]); - if (tcd.arguments[1]["value"].isObject()) - addTo(answer, "{} | Delegator ID : {}", item++, tcd.arguments[1]["value"]["value"].asString()); - else - addTo(answer, "{} | Delegator ID : None", item++); - addTo(answer, "{} | Amount : {}", item++, tcd.arguments[2]["value"].asString()); - break; - } - case SCRIPT_SCO11_WITHDRAW_UNSTAKED_TOKENS: { - addTo(answer, "{} | Type : Withdraw Unstaked Tokens", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addMultiStringArgumentTo(answer, "Node ID", item++, tcd.arguments[0]["value"]); - if (tcd.arguments[1]["value"].isObject()) - addTo(answer, "{} | Delegator ID : {}", item++, tcd.arguments[1]["value"]["value"].asString()); - else - addTo(answer, "{} | Delegator ID : None", item++); - addTo(answer, "{} | Amount : {}", item++, tcd.arguments[2]["value"].asString()); - break; - } - case SCRIPT_SCO12_CLOSE_STAKE: { - addTo(answer, "{} | Type : Close Stake", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addMultiStringArgumentTo(answer, "Node ID", item++, tcd.arguments[0]["value"]); - if (tcd.arguments[1]["value"].isObject()) - addTo(answer, "{} | Delegator ID : {}", item++, tcd.arguments[1]["value"]["value"].asString()); - else - addTo(answer, "{} | Delegator ID : None", item++); - break; - } - case SCRIPT_SCO13_TRANSFER_NODE: { - addTo(answer, "{} | Type : Transfer Node", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addMultiStringArgumentTo(answer, "Node ID", item++, tcd.arguments[0]["value"]); - addMultiStringArgumentTo(answer, "Address", item++, tcd.arguments[1]["value"]); - break; - } - case SCRIPT_SCO14_TRANSFER_DELEGATOR: { - addTo(answer, "{} | Type : Transfer Delegator", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addMultiStringArgumentTo(answer, "Node ID", item++, tcd.arguments[0]["value"]); - addTo(answer, "{} | Delegator ID : {}", item++, tcd.arguments[1]["value"].asString()); - addMultiStringArgumentTo(answer, "Address", item++, tcd.arguments[2]["value"]); - break; - } - case SCRIPT_SCO15_WITHDRAW_FROM_MACHINE_ACCOUNT: { - addTo(answer, "{} | Type : Withdraw From Machine Account", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addMultiStringArgumentTo(answer, "Node ID", item++, tcd.arguments[0]["value"]); - addTo(answer, "{} | Amount : {}", item++, tcd.arguments[1]["value"].asString()); - break; - } - case SCRIPT_SCO16_UPDATE_NETWORKING_ADDRESS: { - addTo(answer, "{} | Type : Update Networking Address", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addMultiStringArgumentTo(answer, "Node ID", item++, tcd.arguments[0]["value"]); - addMultiStringArgumentTo(answer, "Address", item++, tcd.arguments[1]["value"]); - break; - } - case SCRIPT_FUSD01_SETUP_FUSD_VAULT: { - addTo(answer, "{} | Type : Setup FUSD Vault", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - break; - } - case SCRIPT_FUSD02_TRANSFER_FUSD: { - addTo(answer, "{} | Type : Transfer FUSD", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addTo(answer, "{} | Amount : {}", item++, tcd.arguments[0]["value"].asString()); - addMultiStringArgumentTo(answer, "Recipient", item++, tcd.arguments[1]["value"]); - break; - } - case SCRIPT_TS01_SET_UP_TOPSHOT_COLLECTION: { - addTo(answer, "{} | Type : Set Up Top Shot Collection", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - break; - } - case SCRIPT_TS02_TRANSFER_TOP_SHOT_MOMENT: { - addTo(answer, "{} | Type : Transfer Top Shot Moment", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addTo(answer, "{} | Moment ID : {}", item++, tcd.arguments[1]["value"].asString()); - addMultiStringArgumentTo(answer, "Address", item++, tcd.arguments[0]["value"]); - break; - } - case SCRIPT_USDC01_SETUP_USDC_VAULT: { - addTo(answer, "{} | Type : Setup USDC Vault", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - break; - } - case SCRIPT_USDC02_TRANSFER_USDC: { - addTo(answer, "{} | Type : Transfer USDC", item++); - addTo(answer, "{} | ChainID : {}", item++, tcd.chainID); - addTo(answer, "{} | Amount : {}", item++, tcd.arguments[0]["value"].asString()); - addMultiStringArgumentTo(answer, "Recipient", item++, tcd.arguments[1]["value"]); - break; + else { + addTo(answer, "{} | {} : None", item++, ma->displayKey); + } + break; + case ARGUMENT_TYPE_ARRAY: + for (uint16_t i = 0; i < (uint16_t) tcd.arguments[argNo]["value"].size(); i++) { + addMultiStringArgumentTo(answer, fmt::format("{} {}", ma->displayKey, i + 1), item++, tcd.arguments[argNo]["value"][i]["value"]); + } + break; + case ARGUMENT_TYPE_OPTIONALARRAY: + if (tcd.arguments[i]["value"].isObject()) { + for (uint16_t i = 0; i < (uint16_t) tcd.arguments[argNo]["value"]["value"].size(); i++) { + addMultiStringArgumentTo(answer, fmt::format("{} {}", ma->displayKey, i + 1), item++, tcd.arguments[argNo]["value"]["value"][i]["value"]); + } + } + else { + addTo(answer, "{} | {} 1 : None", item++, ma->displayKey); + } + break; } - default: - addTo(answer, "{} | Type : ERROR", item++); - break; } addTo(answer, "{} | Ref Block [1/2] : {}", item, formatString(tcd.refBlock, 0, &dummy)); From 94a5db3a148cff3623dd46bc7562825c5c50ee4e Mon Sep 17 00:00:00 2001 From: Robert Lukotka Date: Fri, 27 May 2022 10:17:09 +0200 Subject: [PATCH 08/12] Several mostly data displaying code improvements --- app/src/addr.c | 62 +++++++++++++++++++++++++++++++----------------- app/src/parser.c | 32 ++++++++++++++++++------- 2 files changed, 64 insertions(+), 30 deletions(-) diff --git a/app/src/addr.c b/app/src/addr.c index d66e71d3..33683146 100644 --- a/app/src/addr.c +++ b/app/src/addr.c @@ -26,21 +26,27 @@ bool hasPubkey; uint8_t pubkey_to_display[SECP256_PK_LEN]; //Small trick to avoid duplicated code here which was quite error prone: -//displayIdx is either the index of page to display, or may be a negative integer. +//displayIdx is either the index of page to display, or GET_NUM_ITEMS_DISPLAY_IDX_STARTING_VALUE //In the second case this is used to count the number of pages -//If displayIdx is negative, all other values are undefined +//If displayIdx is GET_NUM_ITEMS_DISPLAY_IDX_STARTING_VALUE, all other values are NULL/0 +//Their use should be hiden behind SCREEN macro +#define GET_NUM_ITEMS_DISPLAY_IDX_STARTING_VALUE (-1) + zxerr_t addr_getItem_internal(int8_t *displayIdx, - char *outKey, uint16_t outKeyLen, - char *outVal, uint16_t outValLen, - uint8_t pageIdx, uint8_t *pageCount) { + char *outKey, uint16_t outKeyLen, + char *outVal, uint16_t outValLen, + uint8_t pageIdx, uint8_t *pageCount) { zemu_log_stack("addr_getItem_internal"); - MEMZERO(outKey, outKeyLen); - MEMZERO(outVal, outValLen); - snprintf(outKey, outKeyLen, "? %d", *displayIdx); - snprintf(outVal, outValLen, "?"); + if ((*displayIdx)!=GET_NUM_ITEMS_DISPLAY_IDX_STARTING_VALUE && (*displayIdx)<0) { + return zxerr_unknown; + } - #define SCREEN(condition) if ((condition) && ((*displayIdx)--==0) && pageCount && (*pageCount = 1)) + //(*displayIdx!=INT8_MIN) : this prevents displayIdx to loop around from negative valiues to positive ones + //(*displayIdx)--==0 : If displayIdx is positive (and not INT8_MAX), this finds the right screen in the end + //pageCount && (*pageCount = 1) : We need to set *pageCount (in case it is not set in the screen) but only if it is not NULL + //Do not forget to break after switch/case even if you return from within SCREEN(true) block + #define SCREEN(condition) if ((condition) && (*displayIdx!=INT8_MIN) && ((*displayIdx)--==0) && pageCount && (*pageCount = 1)) uint8_t show_address_yes = (show_address == SHOW_ADDRESS_YES || show_address == SHOW_ADDRESS_YES_HASH_MISMATCH); @@ -58,13 +64,16 @@ zxerr_t addr_getItem_internal(int8_t *displayIdx, return zxerr_ok; } - SCREEN(true) { - switch(show_address) { - case SHOW_ADDRESS_ERROR: + switch(show_address) { + case SHOW_ADDRESS_ERROR: + SCREEN(true) { snprintf(outKey, outKeyLen, "Error reading"); pageString(outVal, outValLen, "account data.", pageIdx, pageCount); return zxerr_ok; - case SHOW_ADDRESS_EMPTY_SLOT: + } + break; + case SHOW_ADDRESS_EMPTY_SLOT: + SCREEN(true) { #if defined(TARGET_NANOS) snprintf(outKey, outKeyLen, "Account data"); pageString(outVal, outValLen, "not saved on the device.", pageIdx, pageCount); @@ -73,15 +82,22 @@ zxerr_t addr_getItem_internal(int8_t *displayIdx, pageString(outVal, outValLen, "Account data not saved on the device.", pageIdx, pageCount); #endif return zxerr_ok; - case SHOW_ADDRESS_HDPATHS_NOT_EQUAL: + } + break; + case SHOW_ADDRESS_HDPATHS_NOT_EQUAL: + SCREEN(true) { snprintf(outKey, outKeyLen, "Address:"); pageString(outVal, outValLen, "Other path is saved on the device.", pageIdx, pageCount); return zxerr_ok; - case SHOW_ADDRESS_YES: - case SHOW_ADDRESS_YES_HASH_MISMATCH: + } + break; + case SHOW_ADDRESS_YES: + case SHOW_ADDRESS_YES_HASH_MISMATCH: + SCREEN(true) { snprintf(outKey, outKeyLen, "Address:"); pageHexString(outVal, outValLen, address_to_display.data, sizeof(address_to_display.data), pageIdx, pageCount); return zxerr_ok; + break; default: return zxerr_unknown; } @@ -124,15 +140,17 @@ zxerr_t addr_getItem_internal(int8_t *displayIdx, #undef SCREEN } - -#define ARBITRARY_NEGATIVE_INTEGER -1 zxerr_t addr_getNumItems(uint8_t *num_items) { - int8_t displays = ARBITRARY_NEGATIVE_INTEGER; + int8_t displays = GET_NUM_ITEMS_DISPLAY_IDX_STARTING_VALUE; zxerr_t err = addr_getItem_internal(&displays, NULL, 0, NULL, 0, 0, NULL); - int8_t pages = ARBITRARY_NEGATIVE_INTEGER - displays; + if (displays == INT8_MIN) { + return zxerr_unknown; + } + + int8_t pages = GET_NUM_ITEMS_DISPLAY_IDX_STARTING_VALUE - displays; - if (pages < 0) { + if (pages < 0) { num_items = 0; return zxerr_unknown; } diff --git a/app/src/parser.c b/app/src/parser.c index c4cadf7b..9183a5e3 100644 --- a/app/src/parser.c +++ b/app/src/parser.c @@ -411,16 +411,28 @@ parser_error_t parser_printAuthorizer(const flow_proposal_authorizer_t *v, #define CREATE_ACCOUNT_MAX_PUB_KEYS 5 #define SCO03_REGISTER_NODE_MAX_PUB_KEYS 3 +//Small trick to avoid duplicated code here which was quite error prone: +//displayIdx is either the index of page to display, or GET_NUM_ITEMS_DISPLAY_IDX_STARTING_VALUE +//In the second case this is used to count the number of pages +//If displayIdx is GET_NUM_ITEMS_DISPLAY_IDX_STARTING_VALUE, all other values are NULL/0 +//Their use should be hiden behind SCREEN macro +#define GET_NUM_ITEMS_DISPLAY_IDX_STARTING_VALUE (-1) + parser_error_t parser_getItem_internal(__Z_UNUSED const parser_context_t *ctx, int8_t *displayIdx, char *outKey, uint16_t outKeyLen, char *outVal, uint16_t outValLen, uint8_t pageIdx, uint8_t *pageCount) { - MEMZERO(outKey, outKeyLen); - MEMZERO(outVal, outValLen); - snprintf(outKey, outKeyLen, "? %d", *displayIdx); - snprintf(outVal, outValLen, "?"); + zemu_log_stack("parser_getItem_internal"); + + if ((*displayIdx)!=GET_NUM_ITEMS_DISPLAY_IDX_STARTING_VALUE && (*displayIdx)<0) { + return PARSER_UNEXPECTED_ERROR; + } - #define SCREEN(condition) if ((condition) && ((*displayIdx)--==0) && pageCount && (*pageCount = 1)) + //(*displayIdx!=INT8_MIN) : this prevents displayIdx to loop around from negative valiues to positive ones + //(*displayIdx)--==0 : If displayIdx is positive (and not INT8_MAX), this finds the right screen in the end + //pageCount && (*pageCount = 1) : We need to set *pageCount (in case it is not set in the screen) but only if it is not NULL + //Do not forget to break after switch/case even if you return from within SCREEN(true) block + #define SCREEN(condition) if ((condition) && (*displayIdx!=INT8_MIN) && ((*displayIdx)--==0) && pageCount && (*pageCount = 1)) SCREEN(true) { snprintf(outKey, outKeyLen, "Type"); @@ -575,11 +587,15 @@ parser_error_t parser_getItem_internal(__Z_UNUSED const parser_context_t *ctx, i #undef SCREEN } -#define ARBITRARY_NEGATIVE_INTEGER -1 parser_error_t parser_getNumItems(const parser_context_t *ctx, uint8_t *num_items) { - int8_t displays = ARBITRARY_NEGATIVE_INTEGER; + int8_t displays = GET_NUM_ITEMS_DISPLAY_IDX_STARTING_VALUE; parser_error_t err = parser_getItem_internal(ctx, &displays, NULL, 0, NULL, 0, 0, NULL); - int8_t pages = ARBITRARY_NEGATIVE_INTEGER - displays; + + if (displays == INT8_MIN) { + return PARSER_UNEXPECTED_ERROR; + } + + int8_t pages = GET_NUM_ITEMS_DISPLAY_IDX_STARTING_VALUE - displays; if (pages < 0) { *num_items = 0; From b3f43b0184a99eb5bd19948567e3bb2d0bbbc19f Mon Sep 17 00:00:00 2001 From: Robert Lukotka Date: Mon, 30 May 2022 09:41:22 +0200 Subject: [PATCH 09/12] Improve addr internal and parser internal contract validation --- app/src/addr.c | 13 ++++++++++++- app/src/parser.c | 23 +++++++++++++++++------ app/src/parser.h | 4 ++-- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/app/src/addr.c b/app/src/addr.c index 33683146..fe6b32cf 100644 --- a/app/src/addr.c +++ b/app/src/addr.c @@ -38,7 +38,18 @@ zxerr_t addr_getItem_internal(int8_t *displayIdx, uint8_t pageIdx, uint8_t *pageCount) { zemu_log_stack("addr_getItem_internal"); - if ((*displayIdx)!=GET_NUM_ITEMS_DISPLAY_IDX_STARTING_VALUE && (*displayIdx)<0) { + //validate contract + if ((*displayIdx)>=0) { + if (outKey==NULL || outVal==NULL || pageCount==NULL) { + return zxerr_unknown; + } + } + else if ((*displayIdx) == GET_NUM_ITEMS_DISPLAY_IDX_STARTING_VALUE) { + if (outKey!=NULL || outVal!=NULL || pageCount!=NULL || outKeyLen!=0 || outValLen!=0 || pageIdx!=0) { + return zxerr_unknown; + } + } + else { return zxerr_unknown; } diff --git a/app/src/parser.c b/app/src/parser.c index 9183a5e3..d14ff8c0 100644 --- a/app/src/parser.c +++ b/app/src/parser.c @@ -418,13 +418,24 @@ parser_error_t parser_printAuthorizer(const flow_proposal_authorizer_t *v, //Their use should be hiden behind SCREEN macro #define GET_NUM_ITEMS_DISPLAY_IDX_STARTING_VALUE (-1) -parser_error_t parser_getItem_internal(__Z_UNUSED const parser_context_t *ctx, int8_t *displayIdx, +parser_error_t parser_getItem_internal(int8_t *displayIdx, char *outKey, uint16_t outKeyLen, char *outVal, uint16_t outValLen, uint8_t pageIdx, uint8_t *pageCount) { zemu_log_stack("parser_getItem_internal"); - if ((*displayIdx)!=GET_NUM_ITEMS_DISPLAY_IDX_STARTING_VALUE && (*displayIdx)<0) { + //validate contract + if ((*displayIdx)>=0) { + if (outKey==NULL || outVal==NULL || pageCount==NULL) { + return PARSER_UNEXPECTED_ERROR; + } + } + else if ((*displayIdx) == GET_NUM_ITEMS_DISPLAY_IDX_STARTING_VALUE) { + if (outKey!=NULL || outVal!=NULL || pageCount!=NULL || outKeyLen!=0 || outValLen!=0 || pageIdx!=0) { + return PARSER_UNEXPECTED_ERROR; + } + } + else { return PARSER_UNEXPECTED_ERROR; } @@ -587,9 +598,9 @@ parser_error_t parser_getItem_internal(__Z_UNUSED const parser_context_t *ctx, i #undef SCREEN } -parser_error_t parser_getNumItems(const parser_context_t *ctx, uint8_t *num_items) { +parser_error_t parser_getNumItems(__Z_UNUSED const parser_context_t *ctx, uint8_t *num_items) { int8_t displays = GET_NUM_ITEMS_DISPLAY_IDX_STARTING_VALUE; - parser_error_t err = parser_getItem_internal(ctx, &displays, NULL, 0, NULL, 0, 0, NULL); + parser_error_t err = parser_getItem_internal(&displays, NULL, 0, NULL, 0, 0, NULL); if (displays == INT8_MIN) { return PARSER_UNEXPECTED_ERROR; @@ -613,12 +624,12 @@ parser_error_t parser_getNumItems(const parser_context_t *ctx, uint8_t *num_item return err; } -parser_error_t parser_getItem(const parser_context_t *ctx, uint8_t displayIdx, +parser_error_t parser_getItem(__Z_UNUSED const parser_context_t *ctx, uint8_t displayIdx, char *outKey, uint16_t outKeyLen, char *outVal, uint16_t outValLen, uint8_t pageIdx, uint8_t *pageCount) { if (displayIdx > INT8_MAX) { return PARSER_DISPLAY_IDX_OUT_OF_RANGE; } - return parser_getItem_internal(ctx, (int8_t *) &displayIdx, outKey, outKeyLen, outVal, outValLen, pageIdx, pageCount); + return parser_getItem_internal((int8_t *) &displayIdx, outKey, outKeyLen, outVal, outValLen, pageIdx, pageCount); } diff --git a/app/src/parser.h b/app/src/parser.h index d7404298..e42b8919 100644 --- a/app/src/parser.h +++ b/app/src/parser.h @@ -35,10 +35,10 @@ parser_error_t parser_parse(parser_context_t *ctx, parser_error_t parser_validate(const parser_context_t *ctx); //// returns the number of items in the current parsing context -parser_error_t parser_getNumItems(const parser_context_t *ctx, uint8_t *num_items); +parser_error_t parser_getNumItems(__Z_UNUSED const parser_context_t *ctx, uint8_t *num_items); // retrieves a readable output for each field / page -parser_error_t parser_getItem(const parser_context_t *ctx, uint8_t displayIdx, +parser_error_t parser_getItem(__Z_UNUSED const parser_context_t *ctx, uint8_t displayIdx, char *outKey, uint16_t outKeyLen, char *outVal, uint16_t outValLen, uint8_t pageIdx, uint8_t *pageCount); From 7169282892119c765954e1e5303108cd78763fed Mon Sep 17 00:00:00 2001 From: Robert Lukotka Date: Tue, 7 Jun 2022 12:21:50 +0200 Subject: [PATCH 10/12] Minor review fixes --- app/src/parser.c | 3 -- app/src/tx_metadata.c | 82 +++++++++++++++++++++---------------------- app/src/tx_metadata.h | 4 +-- 3 files changed, 43 insertions(+), 46 deletions(-) diff --git a/app/src/parser.c b/app/src/parser.c index d14ff8c0..4dc8af27 100644 --- a/app/src/parser.c +++ b/app/src/parser.c @@ -408,9 +408,6 @@ parser_error_t parser_printAuthorizer(const flow_proposal_authorizer_t *v, } -#define CREATE_ACCOUNT_MAX_PUB_KEYS 5 -#define SCO03_REGISTER_NODE_MAX_PUB_KEYS 3 - //Small trick to avoid duplicated code here which was quite error prone: //displayIdx is either the index of page to display, or GET_NUM_ITEMS_DISPLAY_IDX_STARTING_VALUE //In the second case this is used to count the number of pages diff --git a/app/src/tx_metadata.c b/app/src/tx_metadata.c index 9ea20d73..0ba599e9 100644 --- a/app/src/tx_metadata.c +++ b/app/src/tx_metadata.c @@ -58,7 +58,7 @@ const static uint8_t TX_METADATA_TOKEN_TRANSFER[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_TH01[] = { +const static uint8_t TX_METADATA_TH01[] = { 2, //number of hashes + hashes 0x6e, 0x73, 0xdb, 0x6e, 0xdd, 0x01, 0x90, 0xf5, 0x31, 0x1f, 0x6a, 0xdc, 0x5f, 0x2b, 0x1f, 0x27, 0xe9, 0xe6, 0x0c, 0x68, 0x57, 0x4b, 0x00, 0xee, 0x90, 0xda, 0x86, 0x7d, 0xa5, 0x2c, 0xdb, 0xb1, 0xa2, 0x14, 0x6e, 0x3e, 0x6e, 0x77, 0x18, 0x77, 0x9c, 0xe5, 0x93, 0x76, 0xb8, 0x87, 0x60, 0xc1, 0x54, 0xd8, 0x2b, 0x7d, 0x13, 0x2f, 0xe2, 0xc3, 0x77, 0x11, 0x4e, 0xc7, 0xcf, 0x43, 0x4e, 0x7b, @@ -73,7 +73,7 @@ const uint8_t TX_METADATA_TH01[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_TH02[] = { +const static uint8_t TX_METADATA_TH02[] = { 2, //number of hashes + hashes 0x0c, 0xb1, 0x1c, 0x10, 0xb8, 0x6d, 0x2a, 0xfe, 0xae, 0x08, 0x6e, 0xf5, 0x11, 0xd2, 0x8b, 0x14, 0x76, 0x0e, 0xb8, 0x54, 0x93, 0x5a, 0x0b, 0x0d, 0xcf, 0xee, 0xcc, 0x85, 0xdb, 0x84, 0x7f, 0x48, 0x74, 0x35, 0x5d, 0xc8, 0xdf, 0x22, 0x1b, 0xc0, 0xd1, 0x70, 0xb2, 0xfe, 0x8d, 0xea, 0xcd, 0x6f, 0x1f, 0x55, 0x4d, 0x6b, 0xee, 0xa5, 0x8a, 0xd9, 0xfe, 0xe7, 0xa0, 0x7f, 0x74, 0x0e, 0xae, 0xfe, @@ -88,7 +88,7 @@ const uint8_t TX_METADATA_TH02[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_TH06[] = { +const static uint8_t TX_METADATA_TH06[] = { 2, //number of hashes + hashes 0xb6, 0xa3, 0x50, 0x2d, 0x22, 0x05, 0xeb, 0x05, 0xec, 0x18, 0x77, 0x2c, 0x13, 0xb9, 0x1c, 0xc8, 0x8a, 0x05, 0x6b, 0x32, 0x5c, 0x26, 0x17, 0xc5, 0x79, 0x48, 0xd3, 0x8c, 0xab, 0x8d, 0xb6, 0x00, 0xb6, 0x4e, 0x0e, 0x3e, 0xd9, 0xeb, 0x28, 0x78, 0x91, 0x98, 0xf2, 0xb0, 0x43, 0x7f, 0x55, 0xf7, 0x50, 0xbf, 0xa7, 0x6d, 0xa9, 0x94, 0x50, 0xf6, 0x3b, 0xe6, 0x54, 0x3b, 0xde, 0x66, 0x12, 0x2a, @@ -138,7 +138,7 @@ const uint8_t TX_METADATA_TH06[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_TH08[] = { +const static uint8_t TX_METADATA_TH08[] = { 2, //number of hashes + hashes 0xd5, 0x68, 0x9b, 0x89, 0xf5, 0x32, 0x14, 0xe7, 0xce, 0x9b, 0xa7, 0xbe, 0x2b, 0xb6, 0x51, 0x96, 0x1f, 0x7e, 0x30, 0x36, 0xb8, 0x5f, 0x92, 0x50, 0x49, 0x42, 0x90, 0xda, 0x9e, 0x9b, 0xa9, 0x89, 0x19, 0x29, 0xe4, 0xf3, 0x88, 0x94, 0xb8, 0x64, 0x18, 0x48, 0xa3, 0xc0, 0xa3, 0xb9, 0xd3, 0x54, 0x95, 0xb3, 0x50, 0x83, 0xd4, 0x2e, 0x8a, 0x3d, 0x4c, 0x92, 0x8b, 0x9d, 0xb4, 0x17, 0x4e, 0xe8, @@ -153,7 +153,7 @@ const uint8_t TX_METADATA_TH08[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_TH09[] = { +const static uint8_t TX_METADATA_TH09[] = { 2, //number of hashes + hashes 0x23, 0xe5, 0xbf, 0xd5, 0x94, 0xbb, 0x32, 0x45, 0x09, 0x0e, 0x3e, 0x0b, 0xaf, 0xb9, 0xcb, 0x92, 0x46, 0xfc, 0x84, 0xd3, 0x0e, 0x4a, 0x35, 0xa7, 0xfd, 0xe1, 0xb5, 0x10, 0x85, 0x62, 0x4d, 0x86, 0x67, 0x7c, 0xc0, 0xac, 0x39, 0x62, 0xec, 0x13, 0x6c, 0xa2, 0x6d, 0xbe, 0xc0, 0xaa, 0x94, 0x2d, 0x92, 0x66, 0x40, 0xec, 0xf8, 0x41, 0x84, 0x33, 0xf0, 0xdb, 0x4b, 0x79, 0x25, 0xf5, 0xd0, 0xfe, @@ -168,7 +168,7 @@ const uint8_t TX_METADATA_TH09[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_TH10[] = { +const static uint8_t TX_METADATA_TH10[] = { 2, //number of hashes + hashes 0x23, 0x93, 0x19, 0x82, 0x5a, 0xd6, 0x81, 0x78, 0xe7, 0x64, 0x65, 0xb5, 0xea, 0x18, 0xcb, 0x43, 0xf0, 0x6c, 0x4e, 0xe1, 0x13, 0x41, 0xf8, 0xfe, 0x94, 0x24, 0x80, 0x91, 0x63, 0xa0, 0x27, 0xa5, 0x28, 0xd1, 0x71, 0x9c, 0x5b, 0x21, 0xc8, 0x8c, 0x62, 0x66, 0x5d, 0xb5, 0xba, 0x04, 0x88, 0x68, 0x09, 0xf3, 0x23, 0x4c, 0x27, 0x05, 0x7b, 0x05, 0x7c, 0x36, 0xd5, 0xf2, 0x65, 0xee, 0x9d, 0xe4, @@ -183,7 +183,7 @@ const uint8_t TX_METADATA_TH10[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_TH11[] = { +const static uint8_t TX_METADATA_TH11[] = { 2, //number of hashes + hashes 0x33, 0xe3, 0x97, 0x7c, 0x45, 0xe7, 0xc2, 0x3c, 0x14, 0x72, 0xbc, 0xf3, 0x34, 0xd0, 0x0b, 0x03, 0xeb, 0xf9, 0x1b, 0x06, 0xb6, 0x7c, 0x57, 0xb6, 0x3b, 0x56, 0x2c, 0x7b, 0x1f, 0xf5, 0xc5, 0x9f, 0x4e, 0x2a, 0x35, 0x54, 0x14, 0x53, 0xf8, 0x9c, 0x55, 0xe5, 0xdc, 0x6d, 0xbc, 0x96, 0x32, 0x90, 0x38, 0x0d, 0x77, 0x9c, 0x81, 0xdf, 0x0b, 0x3b, 0xf8, 0x9c, 0x29, 0xb2, 0xa8, 0xd7, 0xa9, 0xfe, @@ -198,7 +198,7 @@ const uint8_t TX_METADATA_TH11[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_TH12[] = { +const static uint8_t TX_METADATA_TH12[] = { 2, //number of hashes + hashes 0xf9, 0x2c, 0x4c, 0xd6, 0x63, 0xb2, 0xe3, 0x35, 0xcd, 0x82, 0x1a, 0x65, 0x6b, 0xb2, 0xeb, 0xcf, 0x23, 0x9b, 0x22, 0x20, 0x36, 0xa7, 0x82, 0x5a, 0xf5, 0xe5, 0x12, 0xfa, 0xd4, 0xd8, 0x20, 0x35, 0x70, 0x99, 0x90, 0x4b, 0x95, 0x3b, 0x06, 0x2e, 0x81, 0xe2, 0x57, 0x5a, 0x2c, 0x20, 0x81, 0xb3, 0xd9, 0x8b, 0xfc, 0xcf, 0x5c, 0x74, 0x3b, 0x4b, 0xdb, 0x22, 0x4b, 0x93, 0x7e, 0x29, 0x2d, 0xad, @@ -206,7 +206,7 @@ const uint8_t TX_METADATA_TH12[] = { 0, //number of arguments }; -const uint8_t TX_METADATA_TH13[] = { +const static uint8_t TX_METADATA_TH13[] = { 2, //number of hashes + hashes 0x90, 0x09, 0x7e, 0x3a, 0xff, 0x9b, 0x67, 0xf6, 0x5b, 0xba, 0xda, 0x3c, 0xde, 0xdb, 0xb7, 0x3d, 0x45, 0xd0, 0x93, 0xff, 0x33, 0x3a, 0xaa, 0xff, 0x38, 0x80, 0x9b, 0xf9, 0x91, 0x0a, 0x3e, 0x39, 0xdc, 0xae, 0x4f, 0xaa, 0x6d, 0x68, 0x98, 0x73, 0xf7, 0xca, 0xf7, 0xc5, 0xef, 0xef, 0x66, 0x9f, 0x9f, 0xe1, 0xd4, 0x11, 0x3e, 0x58, 0xb4, 0x74, 0xb7, 0xae, 0xc1, 0xe0, 0x71, 0x13, 0xa7, 0xff, @@ -221,7 +221,7 @@ const uint8_t TX_METADATA_TH13[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_TH14[] = { +const static uint8_t TX_METADATA_TH14[] = { 2, //number of hashes + hashes 0xf2, 0x34, 0x06, 0xff, 0x40, 0x2f, 0x02, 0x41, 0x86, 0x29, 0x43, 0x29, 0x12, 0xce, 0x73, 0x2b, 0xe0, 0x44, 0x1b, 0x1a, 0x7e, 0x71, 0xf1, 0x6c, 0x03, 0xd6, 0x88, 0xa1, 0x65, 0xff, 0x7f, 0x49, 0x9b, 0xb8, 0xf0, 0x56, 0x2e, 0xea, 0x5e, 0x45, 0xc1, 0x1f, 0x92, 0x89, 0x54, 0x0f, 0x39, 0xc9, 0x9a, 0x21, 0xc9, 0xa0, 0xfb, 0x06, 0x0a, 0x7d, 0x3f, 0x83, 0x2e, 0x98, 0xc2, 0x69, 0x6f, 0x2d, @@ -236,7 +236,7 @@ const uint8_t TX_METADATA_TH14[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_TH16[] = { +const static uint8_t TX_METADATA_TH16[] = { 2, //number of hashes + hashes 0xc2, 0x9d, 0x40, 0x24, 0xaa, 0xeb, 0x71, 0xab, 0x47, 0x81, 0x82, 0x54, 0x24, 0x99, 0xe0, 0xba, 0x3d, 0x5d, 0x30, 0x3e, 0xc0, 0x27, 0x25, 0x2e, 0x3b, 0x83, 0x33, 0x51, 0x5e, 0xe3, 0xde, 0x48, 0x97, 0xb3, 0x43, 0x64, 0x82, 0xc5, 0xae, 0xfc, 0x1b, 0xaf, 0x8b, 0x85, 0x0e, 0x92, 0xc8, 0x29, 0x20, 0x2e, 0x46, 0x8c, 0x57, 0x24, 0x1d, 0xec, 0x70, 0x7b, 0x6c, 0x27, 0xbd, 0x89, 0xd1, 0x5c, @@ -265,7 +265,7 @@ const uint8_t TX_METADATA_TH16[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_TH17[] = { +const static uint8_t TX_METADATA_TH17[] = { 2, //number of hashes + hashes 0x13, 0x78, 0x40, 0x5c, 0x85, 0xe0, 0xc9, 0x66, 0x34, 0x4b, 0x19, 0x6c, 0x0f, 0xce, 0x60, 0x2f, 0x39, 0xe7, 0x9f, 0x39, 0x38, 0xec, 0x7b, 0x68, 0x9e, 0x0c, 0x96, 0xa8, 0x70, 0x3b, 0x01, 0x8a, 0x3c, 0xb3, 0x57, 0xa9, 0x7a, 0x57, 0xd9, 0xab, 0xbe, 0x5c, 0x68, 0xf0, 0xdf, 0x34, 0x2e, 0xe9, 0x6b, 0xa9, 0x7a, 0xde, 0x20, 0x13, 0x75, 0x3f, 0xd2, 0xdd, 0xf4, 0x76, 0x95, 0xa8, 0xc0, 0x8a, @@ -287,7 +287,7 @@ const uint8_t TX_METADATA_TH17[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_TH19[] = { +const static uint8_t TX_METADATA_TH19[] = { 2, //number of hashes + hashes 0x18, 0xfa, 0xd6, 0x83, 0x68, 0xa4, 0x39, 0x4b, 0x24, 0x5d, 0xb9, 0x12, 0x17, 0xd7, 0xdc, 0x97, 0x9e, 0x13, 0x16, 0xab, 0x75, 0x73, 0x88, 0xd4, 0x16, 0xea, 0xef, 0x83, 0x1f, 0x56, 0x5a, 0xb3, 0x80, 0x23, 0x54, 0xd8, 0xb3, 0xe7, 0x90, 0x8e, 0x58, 0x4b, 0xcb, 0x52, 0x17, 0x63, 0x7f, 0xb9, 0xf4, 0xef, 0x04, 0x54, 0x27, 0xc3, 0x2d, 0x57, 0xd8, 0x1a, 0xd4, 0xa3, 0x90, 0xed, 0x1a, 0x60, @@ -302,7 +302,7 @@ const uint8_t TX_METADATA_TH19[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_TH20[] = { +const static uint8_t TX_METADATA_TH20[] = { 2, //number of hashes + hashes 0x87, 0x76, 0xb1, 0x52, 0x1b, 0x04, 0x39, 0x57, 0x54, 0x73, 0x4f, 0x8f, 0x40, 0xd4, 0xa0, 0x48, 0x28, 0x63, 0x27, 0x4f, 0x8d, 0x83, 0x29, 0x73, 0xd9, 0xe0, 0x11, 0xb3, 0xcb, 0xb4, 0x8c, 0x85, 0x20, 0x27, 0x33, 0x1b, 0x72, 0xd8, 0x71, 0x0a, 0x1a, 0x05, 0xfe, 0xb6, 0xec, 0xeb, 0xad, 0xb5, 0x85, 0x8d, 0x13, 0x4b, 0xc8, 0xc9, 0x5d, 0x6f, 0x26, 0x13, 0x19, 0xcd, 0x9f, 0xa1, 0xbb, 0x95, @@ -317,7 +317,7 @@ const uint8_t TX_METADATA_TH20[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_TH21[] = { +const static uint8_t TX_METADATA_TH21[] = { 2, //number of hashes + hashes 0x6b, 0x40, 0xff, 0xc9, 0x16, 0x9a, 0xbd, 0x75, 0x10, 0x7a, 0x45, 0xda, 0x59, 0x74, 0xc7, 0xe5, 0x02, 0xd3, 0x87, 0x73, 0x27, 0x5a, 0xbb, 0x23, 0x1d, 0x74, 0x7e, 0x47, 0x60, 0xb7, 0xeb, 0xee, 0x86, 0x4e, 0xdb, 0xff, 0x38, 0x43, 0x35, 0xef, 0x21, 0xc2, 0x6b, 0x3b, 0xcf, 0x17, 0xd3, 0x6b, 0x2b, 0x1d, 0x89, 0x4a, 0xfb, 0xe2, 0xb2, 0x03, 0xf5, 0x80, 0x99, 0xcc, 0x45, 0x79, 0x71, 0xe4, @@ -332,7 +332,7 @@ const uint8_t TX_METADATA_TH21[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_TH22[] = { +const static uint8_t TX_METADATA_TH22[] = { 2, //number of hashes + hashes 0x61, 0xcb, 0xcd, 0x1c, 0x31, 0xbb, 0xfc, 0x9c, 0xeb, 0x4a, 0x5a, 0xc7, 0x26, 0xe2, 0xf8, 0xb3, 0xd8, 0x45, 0xa4, 0xfd, 0xf5, 0x9b, 0x0a, 0xb2, 0x3c, 0xbb, 0xfa, 0x8f, 0x16, 0xd7, 0xa0, 0x24, 0x26, 0x2a, 0xed, 0xdd, 0x3f, 0x49, 0xfd, 0x62, 0x22, 0xd7, 0x06, 0xc0, 0x26, 0x96, 0xbd, 0x7d, 0x35, 0x9b, 0xa9, 0x62, 0xb6, 0xc3, 0x02, 0x32, 0xcc, 0x93, 0xd7, 0xcf, 0x41, 0x66, 0xa2, 0x3e, @@ -347,7 +347,7 @@ const uint8_t TX_METADATA_TH22[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_TH23[] = { +const static uint8_t TX_METADATA_TH23[] = { 2, //number of hashes + hashes 0x2a, 0xe9, 0x83, 0xf7, 0x8e, 0x32, 0xb9, 0x89, 0xfa, 0xfa, 0x58, 0xee, 0x79, 0x10, 0xb1, 0x31, 0xfb, 0x51, 0xa2, 0xa7, 0x43, 0x56, 0xf7, 0x91, 0x66, 0x24, 0x69, 0x5c, 0xb8, 0xbf, 0x59, 0x64, 0x12, 0x67, 0x5a, 0x01, 0x3c, 0x06, 0x4b, 0x6d, 0x0e, 0xf1, 0x1d, 0xbf, 0x13, 0xf9, 0x22, 0x10, 0x48, 0x9b, 0xf2, 0xb3, 0xd2, 0x99, 0xb2, 0xf1, 0x4c, 0xd0, 0x9b, 0xe7, 0x0b, 0x37, 0x57, 0x7f, @@ -362,7 +362,7 @@ const uint8_t TX_METADATA_TH23[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_TH24[] = { +const static uint8_t TX_METADATA_TH24[] = { 2, //number of hashes + hashes 0x38, 0x50, 0x42, 0xaa, 0x45, 0x35, 0x66, 0xfc, 0xff, 0x0b, 0x2b, 0xd4, 0x18, 0xb8, 0x37, 0xd8, 0xf4, 0x6f, 0xbc, 0x23, 0xb1, 0xb4, 0x6e, 0x66, 0x51, 0xb2, 0x5a, 0x39, 0x5b, 0xc0, 0x4b, 0xe8, 0x23, 0x9f, 0xfa, 0x44, 0x9e, 0xae, 0x55, 0x60, 0xee, 0xc3, 0xe9, 0x96, 0x33, 0xdc, 0xf9, 0xc6, 0x3b, 0x1e, 0x9c, 0x99, 0x99, 0x6d, 0x1c, 0x56, 0x36, 0x64, 0x4d, 0xce, 0xef, 0x9e, 0xc4, 0x4b, @@ -377,7 +377,7 @@ const uint8_t TX_METADATA_TH24[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_TH25[] = { +const static uint8_t TX_METADATA_TH25[] = { 2, //number of hashes + hashes 0x6c, 0xbe, 0x81, 0xc7, 0x1d, 0x2b, 0x04, 0xdc, 0x40, 0x3e, 0xa0, 0xdb, 0x89, 0x37, 0x7f, 0x0a, 0xbc, 0x5d, 0xb1, 0x4d, 0x3d, 0x2b, 0xd0, 0x14, 0x39, 0x7b, 0x27, 0x76, 0xaa, 0x29, 0xbc, 0x3e, 0xe7, 0x9c, 0xb0, 0x76, 0xf2, 0xf7, 0xda, 0x7a, 0x30, 0x39, 0xb5, 0x06, 0x19, 0x16, 0xe0, 0x81, 0xa8, 0x23, 0x08, 0x7f, 0x15, 0x60, 0xbd, 0xf3, 0xca, 0xea, 0x77, 0x39, 0x92, 0x89, 0x28, 0x73, @@ -392,7 +392,7 @@ const uint8_t TX_METADATA_TH25[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_SCO01[] = { +const static uint8_t TX_METADATA_SCO01[] = { 2, //number of hashes + hashes 0x0e, 0x5c, 0x24, 0x45, 0xc0, 0xb1, 0x01, 0x6e, 0xed, 0x4f, 0x60, 0xc4, 0x29, 0xf2, 0x33, 0xaa, 0x0b, 0xb2, 0x23, 0xa0, 0xd9, 0xff, 0x2a, 0xed, 0xff, 0xce, 0x00, 0xa5, 0x80, 0x37, 0xa2, 0xbf, 0xa5, 0x24, 0xb4, 0x09, 0x4f, 0xca, 0xf1, 0x05, 0x1d, 0xbf, 0x43, 0xac, 0x33, 0xff, 0x80, 0xbb, 0x2f, 0x55, 0x36, 0x70, 0xc5, 0x8e, 0xee, 0xb7, 0x19, 0x75, 0x79, 0x72, 0xa2, 0x5d, 0x6b, 0x50, @@ -400,7 +400,7 @@ const uint8_t TX_METADATA_SCO01[] = { 0, //number of arguments }; -const uint8_t TX_METADATA_SCO02[] = { +const static uint8_t TX_METADATA_SCO02[] = { 2, //number of hashes + hashes 0xc2, 0x6f, 0x69, 0xa3, 0x3e, 0xad, 0x53, 0x5e, 0x7d, 0x59, 0x7c, 0xec, 0x45, 0x67, 0xc6, 0xc7, 0x01, 0x70, 0xe8, 0x6f, 0xd8, 0x5e, 0xc7, 0x08, 0xf5, 0x38, 0x1e, 0x50, 0xd4, 0x38, 0x71, 0xe2, 0xc5, 0x63, 0x6d, 0x51, 0x08, 0x72, 0xa1, 0x6e, 0xb0, 0x69, 0x96, 0xda, 0xcb, 0x43, 0xd6, 0xa2, 0x8f, 0x8f, 0x72, 0xff, 0x1b, 0x05, 0xb2, 0xeb, 0x03, 0x41, 0x6c, 0xc7, 0x11, 0xd9, 0xbb, 0x1f, @@ -422,7 +422,7 @@ const uint8_t TX_METADATA_SCO02[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_SCO03[] = { +const static uint8_t TX_METADATA_SCO03[] = { 4, //number of hashes + hashes 0xf4, 0x7e, 0xfa, 0x83, 0x4b, 0xc0, 0x55, 0x9a, 0xfa, 0xe9, 0xa6, 0x60, 0xb2, 0xef, 0xef, 0xdd, 0xd0, 0xc6, 0xdc, 0x6e, 0x1b, 0xbc, 0xf9, 0xc3, 0x99, 0x4e, 0x45, 0xea, 0x9e, 0x51, 0x35, 0xec, 0x99, 0x99, 0x72, 0x36, 0xb6, 0xd7, 0x6c, 0xaa, 0x29, 0x83, 0x31, 0xd5, 0xce, 0xf7, 0x7c, 0xbd, 0xf8, 0x3c, 0x1a, 0xf6, 0x45, 0x84, 0xec, 0xe5, 0x37, 0xa7, 0x80, 0xba, 0x4a, 0xc4, 0x68, 0x83, @@ -481,7 +481,7 @@ const uint8_t TX_METADATA_SCO03[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_SCO04[] = { +const static uint8_t TX_METADATA_SCO04[] = { 4, //number of hashes + hashes 0xe7, 0x9d, 0xf1, 0x45, 0xaf, 0x42, 0x48, 0x8e, 0x3d, 0xa1, 0xd1, 0xb2, 0xe5, 0x0a, 0x38, 0xa2, 0x08, 0x42, 0x29, 0x89, 0x6d, 0x67, 0x08, 0x84, 0xf2, 0x78, 0xa2, 0x11, 0x9d, 0xc3, 0xbf, 0x9e, 0xc2, 0x44, 0x2b, 0x49, 0x8e, 0xea, 0x02, 0x50, 0x99, 0x81, 0x5e, 0xa6, 0x13, 0xd6, 0x40, 0x74, 0x07, 0x19, 0x2d, 0xc1, 0x2a, 0xd7, 0x0e, 0x1a, 0x4f, 0x47, 0x93, 0x6d, 0xb8, 0x04, 0xa8, 0x41, @@ -505,7 +505,7 @@ const uint8_t TX_METADATA_SCO04[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_SCO05[] = { +const static uint8_t TX_METADATA_SCO05[] = { 2, //number of hashes + hashes 0xb0, 0x0f, 0x6b, 0x3b, 0x9d, 0x8d, 0x7d, 0x4a, 0x9a, 0x8a, 0xd1, 0x4f, 0xce, 0x11, 0xee, 0x0e, 0xdb, 0x23, 0xc3, 0x9c, 0x56, 0xa8, 0xc1, 0x35, 0x1e, 0x6b, 0x59, 0x7f, 0x53, 0xf2, 0xfb, 0x71, 0xa5, 0x52, 0x95, 0x1c, 0x5e, 0x63, 0x00, 0xa1, 0x18, 0x61, 0x0f, 0xbf, 0x2d, 0x36, 0xb3, 0x07, 0x3e, 0xe2, 0x66, 0xe1, 0xd2, 0x67, 0x87, 0xd0, 0x47, 0x17, 0xc1, 0x41, 0x97, 0x6e, 0xf7, 0x8c, @@ -534,7 +534,7 @@ const uint8_t TX_METADATA_SCO05[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_SCO06[] = { +const static uint8_t TX_METADATA_SCO06[] = { 2, //number of hashes + hashes 0x13, 0x07, 0x92, 0x84, 0x40, 0xce, 0xe4, 0x28, 0x92, 0x35, 0x79, 0x3d, 0x6f, 0xf8, 0x60, 0xa2, 0x43, 0x15, 0xf7, 0xb6, 0xa5, 0xd5, 0x90, 0x7a, 0x14, 0x5d, 0xcc, 0x5f, 0x83, 0x70, 0x2a, 0x2c, 0x8e, 0x10, 0xac, 0x56, 0xdb, 0x8e, 0xc5, 0xd5, 0xe0, 0x05, 0x1d, 0x3c, 0x96, 0x08, 0xfa, 0xbc, 0x8e, 0xdd, 0x6a, 0xbe, 0xd9, 0x83, 0xf6, 0xd3, 0xa2, 0x54, 0xe7, 0x66, 0x8a, 0x54, 0xb3, 0x2b, @@ -563,7 +563,7 @@ const uint8_t TX_METADATA_SCO06[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_SCO07[] = { +const static uint8_t TX_METADATA_SCO07[] = { 2, //number of hashes + hashes 0xd7, 0xac, 0xa7, 0x11, 0x3a, 0x7a, 0xa0, 0x3e, 0x0a, 0xfd, 0x20, 0xee, 0x36, 0xf4, 0x87, 0x37, 0x79, 0x70, 0x8a, 0x02, 0xac, 0x4c, 0x69, 0x85, 0x01, 0x77, 0x40, 0xc2, 0xec, 0xea, 0x3d, 0x62, 0x90, 0x7c, 0x4c, 0xfd, 0x67, 0xa9, 0x8a, 0x80, 0x03, 0x39, 0x3c, 0x64, 0xdc, 0x74, 0xeb, 0x7a, 0x95, 0x7b, 0x22, 0x93, 0x52, 0xa2, 0x66, 0x13, 0x9a, 0x54, 0x2b, 0xb1, 0x05, 0xac, 0x4c, 0x40, @@ -592,7 +592,7 @@ const uint8_t TX_METADATA_SCO07[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_SCO08[] = { +const static uint8_t TX_METADATA_SCO08[] = { 2, //number of hashes + hashes 0x35, 0x95, 0xfc, 0xd6, 0x8c, 0xff, 0x44, 0x5c, 0x65, 0xad, 0x99, 0xf8, 0xd4, 0xd7, 0x26, 0xb5, 0xe2, 0x88, 0x07, 0xb0, 0x61, 0x80, 0x07, 0x69, 0xc4, 0x1c, 0xbe, 0x3a, 0xdb, 0x98, 0xae, 0xec, 0x08, 0x2e, 0x69, 0x0b, 0x96, 0x47, 0x18, 0x2c, 0xf6, 0x96, 0x9d, 0xb1, 0xa0, 0xfa, 0x8e, 0x0f, 0x17, 0x28, 0xda, 0x6d, 0xb0, 0x1f, 0xe0, 0xd4, 0x62, 0xe9, 0xf0, 0x84, 0x1c, 0x26, 0x8c, 0xbb, @@ -621,7 +621,7 @@ const uint8_t TX_METADATA_SCO08[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_SCO09[] = { +const static uint8_t TX_METADATA_SCO09[] = { 2, //number of hashes + hashes 0x0b, 0xde, 0x35, 0x8f, 0x39, 0x65, 0xba, 0x2f, 0x4c, 0x18, 0xfb, 0x45, 0xb6, 0x53, 0x68, 0x57, 0xc3, 0xf5, 0x3d, 0x7d, 0x3b, 0x74, 0x0f, 0xe6, 0x6f, 0xe9, 0x3a, 0x4e, 0xbf, 0x75, 0x24, 0xc1, 0xdf, 0x9c, 0x64, 0x86, 0xba, 0xa6, 0xf8, 0xf6, 0x85, 0x36, 0x8e, 0xa2, 0x16, 0x65, 0x92, 0x39, 0xcb, 0x81, 0xfa, 0x8e, 0xbd, 0x90, 0x62, 0xa9, 0x72, 0x3e, 0xdb, 0x54, 0xca, 0x0d, 0x75, 0x25, @@ -636,7 +636,7 @@ const uint8_t TX_METADATA_SCO09[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_SCO10[] = { +const static uint8_t TX_METADATA_SCO10[] = { 2, //number of hashes + hashes 0x3a, 0xf1, 0x82, 0xf5, 0x68, 0xb3, 0x7a, 0x80, 0x67, 0xd3, 0xfb, 0x52, 0x4a, 0xfc, 0xfe, 0x96, 0x99, 0x1c, 0x85, 0xa9, 0x28, 0xbf, 0x76, 0x51, 0xe7, 0x30, 0xbe, 0x0e, 0x15, 0xfd, 0xb7, 0x2d, 0x27, 0xa2, 0xb6, 0x0d, 0x53, 0x8b, 0x8b, 0xb8, 0x83, 0xb6, 0x02, 0xea, 0x83, 0xd1, 0x69, 0x79, 0x86, 0xa2, 0x9d, 0xd6, 0x9a, 0x44, 0xa9, 0x20, 0x9d, 0xc7, 0x5a, 0xff, 0xb9, 0xe6, 0x32, 0x99, @@ -665,7 +665,7 @@ const uint8_t TX_METADATA_SCO10[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_SCO11[] = { +const static uint8_t TX_METADATA_SCO11[] = { 2, //number of hashes + hashes 0x68, 0x87, 0x91, 0x97, 0xd9, 0x61, 0xbb, 0x10, 0x4a, 0x56, 0xe1, 0xe7, 0xd3, 0x56, 0x60, 0x43, 0x6f, 0xe4, 0xc5, 0x2e, 0xd7, 0x8f, 0x79, 0xd9, 0x7f, 0xa5, 0x0a, 0xa9, 0xe9, 0x6f, 0xab, 0xf0, 0x6d, 0x50, 0xab, 0x1e, 0xf3, 0xd7, 0x42, 0x03, 0x08, 0x1c, 0x38, 0x30, 0x6d, 0xa7, 0x4f, 0x5a, 0xd8, 0xfd, 0xd4, 0x89, 0xe4, 0x9f, 0xba, 0x73, 0x2f, 0x8b, 0xa1, 0x94, 0xd0, 0xc7, 0x81, 0xc8, @@ -694,7 +694,7 @@ const uint8_t TX_METADATA_SCO11[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_SCO12[] = { +const static uint8_t TX_METADATA_SCO12[] = { 2, //number of hashes + hashes 0x07, 0x9a, 0xaa, 0x9c, 0xfb, 0x22, 0x13, 0x84, 0x15, 0x05, 0x6b, 0x43, 0xd5, 0xd9, 0x1e, 0x8d, 0x73, 0xbd, 0x8b, 0xd5, 0xf3, 0x7e, 0xbf, 0xf4, 0xf4, 0x02, 0x3d, 0x33, 0xea, 0x6d, 0x2f, 0x25, 0xec, 0xdf, 0xfc, 0x1a, 0xe6, 0x74, 0x79, 0xbc, 0x20, 0xc0, 0x6e, 0xba, 0x6c, 0x77, 0x6f, 0xf3, 0x7b, 0x95, 0x23, 0x66, 0x0f, 0xf1, 0xcd, 0x31, 0x29, 0xa3, 0x92, 0x4d, 0x92, 0x48, 0x48, 0x84, @@ -716,7 +716,7 @@ const uint8_t TX_METADATA_SCO12[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_SCO13[] = { +const static uint8_t TX_METADATA_SCO13[] = { 2, //number of hashes + hashes 0x23, 0x86, 0xd7, 0xae, 0x1a, 0x5b, 0x93, 0x6e, 0x39, 0x14, 0x72, 0x9e, 0xe3, 0x4e, 0x01, 0xd5, 0x3a, 0x8f, 0xbd, 0x2e, 0x40, 0x35, 0x12, 0xec, 0x1b, 0xec, 0xcb, 0x40, 0x62, 0xc2, 0x31, 0xeb, 0xcd, 0xc3, 0xa6, 0x3d, 0x0c, 0x75, 0xea, 0x95, 0xb4, 0x14, 0xbe, 0xcb, 0x6f, 0xbb, 0x8f, 0x5a, 0x80, 0x04, 0x23, 0x6d, 0x48, 0x66, 0x1c, 0xd3, 0xc3, 0xd4, 0xf5, 0x40, 0xee, 0x4d, 0x42, 0x2e, @@ -739,7 +739,7 @@ const uint8_t TX_METADATA_SCO13[] = { }; -const uint8_t TX_METADATA_SCO14[] = { +const static uint8_t TX_METADATA_SCO14[] = { 2, //number of hashes + hashes 0x53, 0xb0, 0x96, 0xb4, 0x85, 0x0a, 0x30, 0x89, 0x4e, 0x7b, 0x27, 0x2e, 0xc5, 0xc3, 0x9e, 0x2b, 0x2f, 0x4a, 0x23, 0xf8, 0xc4, 0x0e, 0x76, 0xa3, 0xc6, 0x4c, 0xfc, 0x63, 0xdc, 0x29, 0x99, 0xb6, 0xb3, 0x4d, 0x6f, 0xaf, 0xcc, 0x5a, 0x4d, 0x0e, 0xd9, 0xcf, 0x92, 0xe1, 0x68, 0xa0, 0x8d, 0x06, 0x74, 0xc9, 0x33, 0x41, 0xe2, 0x39, 0x3e, 0xe7, 0x2d, 0xde, 0x66, 0x64, 0x91, 0x8e, 0xc2, 0x40, @@ -768,7 +768,7 @@ const uint8_t TX_METADATA_SCO14[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_SCO15[] = { +const static uint8_t TX_METADATA_SCO15[] = { 2, //number of hashes + hashes 0x39, 0xa1, 0x26, 0x03, 0x85, 0x22, 0xc6, 0xc9, 0x64, 0xd5, 0x3a, 0xaf, 0x78, 0xdd, 0xe5, 0x5b, 0xfe, 0x80, 0x92, 0x90, 0x91, 0x51, 0x07, 0x92, 0xfe, 0x49, 0x67, 0x8b, 0xb2, 0x2c, 0xbd, 0x96, 0xf9, 0xc4, 0x8e, 0x18, 0xbd, 0xa7, 0xf1, 0x13, 0xe8, 0x27, 0x11, 0xa4, 0xc9, 0x5d, 0xfd, 0x15, 0x1c, 0x66, 0x00, 0xed, 0x9f, 0xbf, 0x46, 0xce, 0xb2, 0x25, 0x66, 0xd6, 0xc5, 0x72, 0x8c, 0x6f, @@ -790,7 +790,7 @@ const uint8_t TX_METADATA_SCO15[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_SCO16[] = { +const static uint8_t TX_METADATA_SCO16[] = { 2, //number of hashes + hashes 0x60, 0xf2, 0xcf, 0x21, 0x9d, 0x56, 0xb1, 0x9d, 0xc7, 0xfd, 0x22, 0x3c, 0xae, 0xd4, 0x2d, 0xda, 0x91, 0x43, 0xc8, 0x7b, 0x1b, 0x0d, 0x2c, 0x21, 0xa9, 0x65, 0x2e, 0x12, 0xa3, 0x71, 0x41, 0x33, 0xff, 0x06, 0x7b, 0x40, 0xac, 0x67, 0x02, 0x0e, 0xf8, 0x64, 0xcd, 0x14, 0x84, 0x2f, 0x62, 0x02, 0x32, 0x54, 0xda, 0x34, 0xdd, 0x2d, 0xed, 0x56, 0xaf, 0xfa, 0x13, 0x64, 0x30, 0x5b, 0xf1, 0xc5, @@ -812,7 +812,7 @@ const uint8_t TX_METADATA_SCO16[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_FUSD01[] = { +const static uint8_t TX_METADATA_FUSD01[] = { 2, //number of hashes + hashes 0x0f, 0xfa, 0xf7, 0x7a, 0xb3, 0x20, 0xce, 0x4c, 0xc9, 0x60, 0x2d, 0x39, 0xb8, 0x9c, 0x85, 0xf0, 0x94, 0xeb, 0xce, 0xa5, 0x71, 0xed, 0x32, 0x45, 0x37, 0xe7, 0x03, 0xbc, 0x07, 0xb0, 0xfd, 0xc4, 0xaa, 0x7f, 0xec, 0xdf, 0x15, 0x9e, 0x71, 0xbd, 0x0b, 0x02, 0x9e, 0x40, 0xb2, 0x26, 0x43, 0xfb, 0x44, 0x31, 0x61, 0xe6, 0x77, 0x96, 0xf4, 0x2b, 0xac, 0x68, 0xe9, 0xba, 0xb4, 0x63, 0x0e, 0x29, @@ -820,7 +820,7 @@ const uint8_t TX_METADATA_FUSD01[] = { 0, //number of arguments }; -const uint8_t TX_METADATA_FUSD02[] = { +const static uint8_t TX_METADATA_FUSD02[] = { 2, //number of hashes + hashes 0xf2, 0x2c, 0xa4, 0xb3, 0x50, 0xa7, 0x9c, 0x72, 0x4f, 0x64, 0x71, 0xd5, 0xa6, 0xa7, 0xa0, 0xef, 0xa7, 0xba, 0x9a, 0xee, 0xbb, 0x7f, 0xed, 0x28, 0x43, 0xa3, 0xdd, 0xd6, 0xe4, 0x2c, 0x2e, 0x1c, 0x18, 0x0c, 0xef, 0x70, 0x53, 0xa5, 0xf0, 0xae, 0x66, 0xe1, 0x9e, 0x3a, 0x96, 0xcc, 0x3b, 0x9e, 0xb7, 0xda, 0x29, 0x76, 0x7f, 0xb5, 0xd6, 0x93, 0x82, 0x39, 0xbf, 0x1f, 0x8e, 0x1d, 0xc2, 0x84, @@ -842,7 +842,7 @@ const uint8_t TX_METADATA_FUSD02[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_TS01[] = { +const static uint8_t TX_METADATA_TS01[] = { 2, //number of hashes + hashes 0x0f, 0x0b, 0xae, 0xef, 0x93, 0x53, 0xce, 0xee, 0x60, 0x7c, 0x5b, 0xe3, 0xb7, 0xc0, 0xf8, 0x67, 0x92, 0xda, 0xdf, 0x20, 0xb9, 0xe9, 0xc8, 0x9e, 0x83, 0x1a, 0xdb, 0x01, 0x99, 0xe7, 0x58, 0x82, 0x75, 0x11, 0x84, 0x8f, 0x1c, 0x27, 0xa1, 0x73, 0xd9, 0x66, 0xf4, 0xb8, 0x68, 0xfd, 0x7e, 0xfe, 0xad, 0x7e, 0xeb, 0x1b, 0xbf, 0x04, 0xfc, 0x3f, 0x3e, 0x60, 0xda, 0xbc, 0x6c, 0x7f, 0x75, 0x93, @@ -850,7 +850,7 @@ const uint8_t TX_METADATA_TS01[] = { 0, //number of arguments }; -const uint8_t TX_METADATA_TS02[] = { +const static uint8_t TX_METADATA_TS02[] = { 2, //number of hashes + hashes 0x1e, 0xc9, 0xae, 0xa0, 0xb5, 0x14, 0x09, 0x61, 0x0f, 0x88, 0x2f, 0x5a, 0xe4, 0x27, 0x85, 0x67, 0xda, 0x67, 0x55, 0x42, 0xbb, 0x37, 0x8e, 0xb9, 0x99, 0xf0, 0x5b, 0x7c, 0x4f, 0x12, 0xf7, 0xd8, 0x09, 0xd5, 0xad, 0x21, 0xbf, 0x70, 0xdf, 0xe4, 0xf8, 0xd8, 0x00, 0xdb, 0x9e, 0x61, 0xa7, 0x7f, 0x2f, 0x64, 0x83, 0x7a, 0xe0, 0xe8, 0x18, 0xc3, 0xcd, 0x67, 0xe9, 0xce, 0xa8, 0x37, 0xa1, 0xcf, @@ -872,7 +872,7 @@ const uint8_t TX_METADATA_TS02[] = { JSMN_STRING, //expected value json token type }; -const uint8_t TX_METADATA_USDC01[] = { +const static uint8_t TX_METADATA_USDC01[] = { 2, //number of hashes + hashes 0x2d, 0xef, 0xee, 0x81, 0x8c, 0x0c, 0x00, 0x3c, 0xa5, 0x19, 0xf8, 0x35, 0x17, 0xf4, 0xc7, 0xbc, 0xf9, 0xdd, 0x86, 0x64, 0xa5, 0x62, 0xec, 0x80, 0x95, 0x9c, 0xb6, 0x14, 0x64, 0x28, 0xf9, 0x71, 0x88, 0x76, 0x73, 0x89, 0x2a, 0x2e, 0x2c, 0x12, 0x33, 0x73, 0x94, 0x57, 0x0d, 0xfa, 0x30, 0xc5, 0x66, 0x9e, 0x93, 0xf5, 0x37, 0xae, 0x42, 0x66, 0x90, 0xf4, 0x02, 0x79, 0x95, 0x14, 0xa9, 0xa1, @@ -880,7 +880,7 @@ const uint8_t TX_METADATA_USDC01[] = { 0, //number of arguments }; -const uint8_t TX_METADATA_USDC02[] = { +const static uint8_t TX_METADATA_USDC02[] = { 2, //number of hashes + hashes 0x51, 0x24, 0x85, 0xec, 0x3f, 0x8e, 0x00, 0x78, 0x53, 0xb0, 0xea, 0x2a, 0x22, 0xfb, 0x2b, 0x9f, 0x7e, 0x2f, 0xa5, 0x5f, 0xd9, 0x81, 0x91, 0x71, 0xc5, 0xd0, 0x13, 0x28, 0x2e, 0xfe, 0xe6, 0x0a, 0x7f, 0xf4, 0xd9, 0xf5, 0x3b, 0xa5, 0xee, 0xbd, 0xa5, 0x56, 0xd0, 0xea, 0xd0, 0xca, 0x13, 0x91, 0x1b, 0xc8, 0x99, 0x6e, 0x2c, 0x91, 0xc5, 0x14, 0x7f, 0x87, 0x87, 0xd1, 0x0a, 0x32, 0x44, 0x83, diff --git a/app/src/tx_metadata.h b/app/src/tx_metadata.h index 81bc84e9..69614a4f 100644 --- a/app/src/tx_metadata.h +++ b/app/src/tx_metadata.h @@ -37,8 +37,8 @@ typedef enum { //It is planed that all these strings may be on flash, thus they are volatile (for NanoX and NanoSPlus) typedef struct { argument_type_e argumentType; - uint8_t arrayMinElements; //defined only for ARGUMENT_TYPE_ARRAY and ARGUMENT_TYPE_OPTIOALARRAY - uint8_t arrayMaxElements; //defined only for ARGUMENT_TYPE_ARRAY and ARGUMENT_TYPE_OPTIOALARRAY + uint8_t arrayMinElements; //defined only for ARGUMENT_TYPE_ARRAY and ARGUMENT_TYPE_OPTIONALARRAY + uint8_t arrayMaxElements; //defined only for ARGUMENT_TYPE_ARRAY and ARGUMENT_TYPE_OPTIONALARRAY const NV_VOLATILE char *displayKey; uint8_t displayKeyLength; uint8_t argumentIndex; //argument index within transaction From b20c1178390703c0832645f1a0b63048a1ad863d Mon Sep 17 00:00:00 2001 From: Robert Lukotka Date: Sun, 19 Jun 2022 13:49:34 +0200 Subject: [PATCH 11/12] New general screen macros, applied to addr.c --- app/src/addr.c | 186 ++++++++++++++++------------------------------ app/src/screens.h | 56 ++++++++++++++ 2 files changed, 122 insertions(+), 120 deletions(-) create mode 100644 app/src/screens.h diff --git a/app/src/addr.c b/app/src/addr.c index fe6b32cf..bd2f3cfa 100644 --- a/app/src/addr.c +++ b/app/src/addr.c @@ -22,167 +22,113 @@ #include "app_mode.h" #include "hdpath.h" +#include "screens.h" + bool hasPubkey; uint8_t pubkey_to_display[SECP256_PK_LEN]; -//Small trick to avoid duplicated code here which was quite error prone: -//displayIdx is either the index of page to display, or GET_NUM_ITEMS_DISPLAY_IDX_STARTING_VALUE -//In the second case this is used to count the number of pages -//If displayIdx is GET_NUM_ITEMS_DISPLAY_IDX_STARTING_VALUE, all other values are NULL/0 -//Their use should be hiden behind SCREEN macro -#define GET_NUM_ITEMS_DISPLAY_IDX_STARTING_VALUE (-1) - -zxerr_t addr_getItem_internal(int8_t *displayIdx, - char *outKey, uint16_t outKeyLen, - char *outVal, uint16_t outValLen, - uint8_t pageIdx, uint8_t *pageCount) { - zemu_log_stack("addr_getItem_internal"); - - //validate contract - if ((*displayIdx)>=0) { - if (outKey==NULL || outVal==NULL || pageCount==NULL) { - return zxerr_unknown; - } - } - else if ((*displayIdx) == GET_NUM_ITEMS_DISPLAY_IDX_STARTING_VALUE) { - if (outKey!=NULL || outVal!=NULL || pageCount!=NULL || outKeyLen!=0 || outValLen!=0 || pageIdx!=0) { - return zxerr_unknown; - } - } - else { - return zxerr_unknown; - } - - //(*displayIdx!=INT8_MIN) : this prevents displayIdx to loop around from negative valiues to positive ones - //(*displayIdx)--==0 : If displayIdx is positive (and not INT8_MAX), this finds the right screen in the end - //pageCount && (*pageCount = 1) : We need to set *pageCount (in case it is not set in the screen) but only if it is not NULL - //Do not forget to break after switch/case even if you return from within SCREEN(true) block - #define SCREEN(condition) if ((condition) && (*displayIdx!=INT8_MIN) && ((*displayIdx)--==0) && pageCount && (*pageCount = 1)) +//this defines addr_internal function +BEGIN_SCREENS_FUNCTION(addr, zxerr_t, zxerr_ok, zxerr_unknown) uint8_t show_address_yes = (show_address == SHOW_ADDRESS_YES || show_address == SHOW_ADDRESS_YES_HASH_MISMATCH); - SCREEN(hasPubkey) { - snprintf(outKey, outKeyLen, "Pub Key"); - // +1 is to skip 0x04 prefix that indicates uncompresed key - pageHexString(outVal, outValLen, pubkey_to_display+1, sizeof(pubkey_to_display)-1, pageIdx, pageCount); - return zxerr_ok; + if (hasPubkey) { + BEGIN_SCREEN + snprintf(outKey, outKeyLen, "Pub Key"); + // +1 is to skip 0x04 prefix that indicates uncompresed key + pageHexString(outVal, outValLen, pubkey_to_display+1, sizeof(pubkey_to_display)-1, pageIdx, pageCount); + END_SCREEN } - - //this indicates error in pubkey derivation (possible only when in menu_handler - in apdu_handler we throw) - SCREEN(!hasPubkey && show_address_yes) { - snprintf(outKey, outKeyLen, "Error"); - pageString(outVal, outValLen, " deriving public key.", pageIdx, pageCount); - return zxerr_ok; + + if (!hasPubkey && show_address_yes) { + BEGIN_SCREEN + snprintf(outKey, outKeyLen, "Error"); + pageString(outVal, outValLen, " deriving public key.", pageIdx, pageCount); + END_SCREEN } + //this indicates error in pubkey derivation (possible only when in menu_handler - in apdu_handler we throw) switch(show_address) { case SHOW_ADDRESS_ERROR: - SCREEN(true) { + BEGIN_SCREEN snprintf(outKey, outKeyLen, "Error reading"); pageString(outVal, outValLen, "account data.", pageIdx, pageCount); - return zxerr_ok; - } + END_SCREEN break; case SHOW_ADDRESS_EMPTY_SLOT: - SCREEN(true) { -#if defined(TARGET_NANOS) - snprintf(outKey, outKeyLen, "Account data"); - pageString(outVal, outValLen, "not saved on the device.", pageIdx, pageCount); -#else - snprintf(outKey, outKeyLen, "Address:"); - pageString(outVal, outValLen, "Account data not saved on the device.", pageIdx, pageCount); -#endif - return zxerr_ok; - } + BEGIN_SCREEN + #if defined(TARGET_NANOS) + snprintf(outKey, outKeyLen, "Account data"); + pageString(outVal, outValLen, "not saved on the device.", pageIdx, pageCount); + #else + snprintf(outKey, outKeyLen, "Address:"); + pageString(outVal, outValLen, "Account data not saved on the device.", pageIdx, pageCount); + #endif + END_SCREEN break; case SHOW_ADDRESS_HDPATHS_NOT_EQUAL: - SCREEN(true) { + BEGIN_SCREEN snprintf(outKey, outKeyLen, "Address:"); pageString(outVal, outValLen, "Other path is saved on the device.", pageIdx, pageCount); - return zxerr_ok; - } + END_SCREEN break; case SHOW_ADDRESS_YES: case SHOW_ADDRESS_YES_HASH_MISMATCH: - SCREEN(true) { + BEGIN_SCREEN snprintf(outKey, outKeyLen, "Address:"); pageHexString(outVal, outValLen, address_to_display.data, sizeof(address_to_display.data), pageIdx, pageCount); return zxerr_ok; + END_SCREEN break; - default: - return zxerr_unknown; - } + default: + return zxerr_unknown; } - SCREEN(show_address_yes) { -#if defined(TARGET_NANOS) - snprintf(outKey, outKeyLen, "Verify if this"); - snprintf(outVal, outValLen, " public key was added to"); -#else - snprintf(outKey, outKeyLen, "Warning:"); - snprintf(outVal, outValLen, "Verify if this public key was added to"); -#endif - return zxerr_ok; + if (show_address_yes) { + BEGIN_SCREEN + #if defined(TARGET_NANOS) + snprintf(outKey, outKeyLen, "Verify if this"); + snprintf(outVal, outValLen, " public key was added to"); + #else + snprintf(outKey, outKeyLen, "Warning:"); + snprintf(outVal, outValLen, "Verify if this public key was added to"); + #endif + END_SCREEN } - SCREEN(show_address_yes) { - #if defined(TARGET_NANOS) - array_to_hexstr(outKey, outKeyLen, address_to_display.data, sizeof(address_to_display.data)); - snprintf(outVal, outValLen, " using any Flow blockch. explorer."); - #else - char buffer[2*sizeof(address_to_display.data)+1]; - array_to_hexstr(buffer, sizeof(buffer), address_to_display.data, sizeof(address_to_display.data)); - snprintf(outVal, outValLen, "%s using any Flow blockchain explorer.", buffer); - snprintf(outKey, outKeyLen, ""); - #endif - return zxerr_ok; + if (show_address_yes) { + BEGIN_SCREEN + #if defined(TARGET_NANOS) + array_to_hexstr(outKey, outKeyLen, address_to_display.data, sizeof(address_to_display.data)); + snprintf(outVal, outValLen, " using any Flow blockch. explorer."); + #else + char buffer[2*sizeof(address_to_display.data)+1]; + array_to_hexstr(buffer, sizeof(buffer), address_to_display.data, sizeof(address_to_display.data)); + snprintf(outVal, outValLen, "%s using any Flow blockchain explorer.", buffer); + snprintf(outKey, outKeyLen, ""); + #endif + END_SCREEN } - SCREEN(app_mode_expert() && hasPubkey) { - snprintf(outKey, outKeyLen, "Your Path"); - char buffer[100]; - path_options_to_string(buffer, sizeof(buffer), hdPath.data, HDPATH_LEN_DEFAULT, cryptoOptions & 0xFF00); //show curve only - pageString(outVal, outValLen, buffer, pageIdx, pageCount); - return zxerr_ok; + if (app_mode_expert() && hasPubkey) { + BEGIN_SCREEN + snprintf(outKey, outKeyLen, "Your Path"); + char buffer[100]; + path_options_to_string(buffer, sizeof(buffer), hdPath.data, HDPATH_LEN_DEFAULT, cryptoOptions & 0xFF00); //show curve only + pageString(outVal, outValLen, buffer, pageIdx, pageCount); + END_SCREEN } - return zxerr_no_data; +END_SCREENS_FUNCTION - #undef SCREEN -} zxerr_t addr_getNumItems(uint8_t *num_items) { - int8_t displays = GET_NUM_ITEMS_DISPLAY_IDX_STARTING_VALUE; - zxerr_t err = addr_getItem_internal(&displays, NULL, 0, NULL, 0, 0, NULL); - - if (displays == INT8_MIN) { - return zxerr_unknown; - } - - int8_t pages = GET_NUM_ITEMS_DISPLAY_IDX_STARTING_VALUE - displays; - - if (pages < 0) { - num_items = 0; - return zxerr_unknown; - } - - *num_items = (uint8_t) pages; - - if (err == zxerr_no_data) { - return zxerr_ok; - } - if (err == zxerr_ok) { - return zxerr_unknown; - } - return err; + return addr_internal(MAX_DISPLAYS, NULL, 0, NULL, 0, 0, num_items); } zxerr_t addr_getItem(uint8_t displayIdx, char *outKey, uint16_t outKeyLen, char *outVal, uint16_t outValLen, uint8_t pageIdx, uint8_t *pageCount) { - if (displayIdx > INT8_MAX) { - return zxerr_out_of_bounds; - } - return addr_getItem_internal((int8_t *) &displayIdx, outKey, outKeyLen, outVal, outValLen, pageIdx, pageCount); + return addr_internal(displayIdx, outKey, outKeyLen, outVal, outValLen, pageIdx, pageCount); } diff --git a/app/src/screens.h b/app/src/screens.h new file mode 100644 index 00000000..25fa7c86 --- /dev/null +++ b/app/src/screens.h @@ -0,0 +1,56 @@ +// While displaying screens we need to implemnt *_getItem function and *_getNumItems function. +// There is a big overlap in the logic. These macros generate *_internal function that can be used to implemnt both functions. +// We provide SCREEN macros to achive this efficiently. +// +// Function *_internal parameters: +// displayIdx - display index or MAX_DISPLAYS if we want to count the number of displays +// pageIdx - page index within the display, not used if displayIdx == MAX_DISPLAYS +// outKey, outKeyLen, outVal, outValLen - strings to be displayed, uused if == MAX_DISPLAYS +// pageCount - returns the number of pages (displayIdx Date: Mon, 27 Jun 2022 22:26:50 +0200 Subject: [PATCH 12/12] Make SCREEN macro work for NanoX/S+ --- app/src/addr.c | 2 +- app/src/screens.h | 33 +++++++++++++++++---------------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/app/src/addr.c b/app/src/addr.c index bd2f3cfa..d9ee7797 100644 --- a/app/src/addr.c +++ b/app/src/addr.c @@ -28,7 +28,7 @@ bool hasPubkey; uint8_t pubkey_to_display[SECP256_PK_LEN]; //this defines addr_internal function -BEGIN_SCREENS_FUNCTION(addr, zxerr_t, zxerr_ok, zxerr_unknown) +BEGIN_SCREENS_FUNCTION(addr, zxerr_t, zxerr_ok, zxerr_no_data, zxerr_no_data) uint8_t show_address_yes = (show_address == SHOW_ADDRESS_YES || show_address == SHOW_ADDRESS_YES_HASH_MISMATCH); diff --git a/app/src/screens.h b/app/src/screens.h index 25fa7c86..928fabf5 100644 --- a/app/src/screens.h +++ b/app/src/screens.h @@ -23,20 +23,21 @@ #define MAX_DISPLAYS UINT8_MAX -#define BEGIN_SCREENS_FUNCTION(functionNemePrefix_, errType_, okReturnValue_, errorReturnValue_)\ - static errType_ functionNemePrefix_ ## _internal (uint8_t displayIdx, \ - char *outKey, uint16_t outKeyLen, \ - char *outVal, uint16_t outValLen, \ - uint8_t pageIdx, uint8_t *pageCount) { \ - errType_ okReturnValue = (okReturnValue_); \ - errType_ errorReturnValue = (errorReturnValue_); \ - uint8_t isGetItemMode = (displayIdx != MAX_DISPLAYS); \ - \ - if ((isGetItemMode && !outKey) || (isGetItemMode && !outVal) || !pageCount) { \ - return errorReturnValue; \ - }; \ - \ - uint8_t currentDisplay = 0; \ +#define BEGIN_SCREENS_FUNCTION(functionNemePrefix_, errType_, okReturnValue_, errorReturnValue_, errorNoDataValue_) \ + static errType_ functionNemePrefix_ ## _internal (uint8_t displayIdx, \ + char *outKey, uint16_t outKeyLen, \ + char *outVal, uint16_t outValLen, \ + uint8_t pageIdx, uint8_t *pageCount) { \ + errType_ okReturnValue = (okReturnValue_); \ + errType_ errorReturnValue = (errorReturnValue_); \ + errType_ errorNoDataValue = (errorNoDataValue_); \ + uint8_t isGetItemMode = (displayIdx != MAX_DISPLAYS); \ + \ + if ((isGetItemMode && !outKey) || (isGetItemMode && !outVal) || !pageCount) { \ + return (errorReturnValue); \ + }; \ + \ + uint8_t currentDisplay = 0; \ *pageCount = 1; #define BEGIN_SCREEN \ @@ -47,10 +48,10 @@ #define END_SCREENS_FUNCTION \ if (isGetItemMode) { \ - return errorReturnValue; \ + return (errorNoDataValue); \ } \ else { \ *pageCount = currentDisplay; \ - return okReturnValue; \ + return (okReturnValue); \ } \ }