|
| 1 | +/******************************************************************************* |
| 2 | + * (c) 2018 - 2025 Zondax AG |
| 3 | + * |
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | + * you may not use this file except in compliance with the License. |
| 6 | + * You may obtain a copy of the License at |
| 7 | + * |
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | + * |
| 10 | + * Unless required by applicable law or agreed to in writing, software |
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | + * See the License for the specific language governing permissions and |
| 14 | + * limitations under the License. |
| 15 | + ********************************************************************************/ |
| 16 | + |
| 17 | +#include "schema_helper.h" |
| 18 | + |
| 19 | +#include "borsh.h" |
| 20 | + |
| 21 | +// parser_error_t get_enum_runtime_call_link_index(schema_enum_t *schema_enum, uint32_t field_index[], uint16_t *qty, |
| 22 | +// uint16_t max_indexes) { |
| 23 | +// CHECK_INPUT(schema_enum); |
| 24 | +// CHECK_INPUT(field_index); |
| 25 | +// CHECK_INPUT(qty); |
| 26 | + |
| 27 | +// for (uint32_t i = 0; i < schema_enum->variants_qty; i++) { |
| 28 | +// if (schema_enum->variants[i].discriminant == RUNTIME_CALL_BANK) { |
| 29 | +// if (schema_enum->variants[i].value.tag == LINK_BY_INDEX) { |
| 30 | +// field_index[(*qty)++] = schema_enum->variants[i].value.data.by_index; |
| 31 | +// } |
| 32 | +// } |
| 33 | +// } |
| 34 | + |
| 35 | +// return (*qty >= max_indexes) ? parser_unexpected_error : parser_ok; |
| 36 | +// } |
| 37 | + |
| 38 | +// parser_error_t get_enum_transfer_index(schema_enum_t *schema_enum, uint32_t field_index[], uint16_t *qty, uint16_t |
| 39 | +// max_indexes) { |
| 40 | +// CHECK_INPUT(schema_enum); |
| 41 | +// CHECK_INPUT(field_index); |
| 42 | +// CHECK_INPUT(qty); |
| 43 | + |
| 44 | +// for (uint32_t i = 0; i < schema_enum->variants_qty; i++) { |
| 45 | +// if (schema_enum->variants[i].discriminant == BANK_CALL_MESSAGE_TRANSFER) { |
| 46 | +// if (schema_enum->variants[i].value.tag == LINK_BY_INDEX) { |
| 47 | +// field_index[(*qty)++] = schema_enum->variants[i].value.data.by_index; |
| 48 | +// } |
| 49 | +// } |
| 50 | +// } |
| 51 | + |
| 52 | +// return (*qty >= max_indexes) ? parser_unexpected_error : parser_ok; |
| 53 | +// } |
| 54 | + |
| 55 | +// parser_error_t get_enum_link_index(schema_enum_t *schema_enum, uint64_t field_index[], uint16_t *qty, uint16_t |
| 56 | +// max_indexes) { |
| 57 | +// CHECK_INPUT(schema_enum); |
| 58 | +// CHECK_INPUT(field_index); |
| 59 | +// CHECK_INPUT(qty); |
| 60 | + |
| 61 | +// for (uint32_t i = 0; i < schema_enum->variants_qty; i++) { |
| 62 | +// if (schema_enum->variants[i].value.tag == LINK_BY_INDEX) { |
| 63 | +// field_index[(*qty)++] = schema_enum->variants[i].value.data.by_index; |
| 64 | +// } |
| 65 | +// } |
| 66 | + |
| 67 | +// return (*qty >= max_indexes) ? parser_unexpected_error : parser_ok; |
| 68 | +// } |
| 69 | + |
| 70 | +// parser_error_t get_struct_link_index(schema_struct_t *schema_struct, uint32_t field_index[], uint16_t *qty, uint16_t |
| 71 | +// max_indexes) { |
| 72 | +// CHECK_INPUT(schema_struct); |
| 73 | +// CHECK_INPUT(field_index); |
| 74 | +// CHECK_INPUT(qty); |
| 75 | + |
| 76 | +// named_field_t *field = schema_struct->fields; |
| 77 | +// named_field_t *end = field + schema_struct->fields_qty; |
| 78 | + |
| 79 | +// while (field < end && *qty < max_indexes) { |
| 80 | +// if (field->value.tag == LINK_BY_INDEX) { |
| 81 | +// field_index[(*qty)++] = field->value.data.by_index; |
| 82 | +// } |
| 83 | +// field++; |
| 84 | +// } |
| 85 | + |
| 86 | +// return (*qty >= max_indexes) ? parser_unexpected_error : parser_ok; |
| 87 | +// } |
| 88 | + |
| 89 | +// parser_error_t get_tuple_link_index(schema_tuple_t *schema_tuple, uint32_t field_index[], uint16_t *qty, uint16_t |
| 90 | +// max_indexes) { |
| 91 | +// CHECK_INPUT(schema_tuple); |
| 92 | +// CHECK_INPUT(field_index); |
| 93 | +// CHECK_INPUT(qty); |
| 94 | + |
| 95 | +// for (uint32_t i = 0; i < schema_tuple->fields_qty; i++) { |
| 96 | +// if (schema_tuple->fields[i].value.tag == LINK_BY_INDEX) { |
| 97 | +// field_index[(*qty)++] = schema_tuple->fields[i].value.data.by_index; |
| 98 | +// } |
| 99 | +// } |
| 100 | + |
| 101 | +// return (*qty >= max_indexes) ? parser_unexpected_error : parser_ok; |
| 102 | +// } |
| 103 | + |
| 104 | +// parser_error_t get_schema_indexes_recursive(parser_tx_t *txObj, uint32_t index, uint32_t runtime_call_index, uint32_t |
| 105 | +// field_index[], uint16_t *qty, uint8_t *visited, uint16_t max_indexes) { |
| 106 | +// CHECK_INPUT(txObj); |
| 107 | +// CHECK_INPUT(field_index); |
| 108 | +// CHECK_INPUT(qty); |
| 109 | +// CHECK_INPUT(visited); |
| 110 | + |
| 111 | +// // Check array bounds and visited status |
| 112 | +// if (index >= MAX_SCHEMES_QTY || *qty >= max_indexes) { |
| 113 | +// return parser_unexpected_error; |
| 114 | +// } |
| 115 | + |
| 116 | +// // Check if we've already visited this index |
| 117 | +// if (visited[index]) { |
| 118 | +// return parser_ok; |
| 119 | +// } |
| 120 | +// visited[index] = 1; |
| 121 | + |
| 122 | +// // Get linking scheme data |
| 123 | +// linking_scheme_t *scheme = &txObj->schema.types.schemes[index]; |
| 124 | +// print_u32("SEARCHING index:", index); |
| 125 | +// print_u8("scheme->type:", scheme->type); |
| 126 | + |
| 127 | +// uint16_t current_qty = *qty; |
| 128 | +// switch (scheme->type) { |
| 129 | +// case LINKING_SCHEME_ENUM: { |
| 130 | +// schema_enum_t enum_type = {0}; |
| 131 | +// CHECK_ERROR(read_enum(&scheme->data, &enum_type)); |
| 132 | +// if (index == runtime_call_index) { |
| 133 | +// CHECK_ERROR(get_enum_runtime_call_link_index(&enum_type, field_index, qty, max_indexes)); |
| 134 | +// } else if (index == 4) { |
| 135 | +// CHECK_ERROR(get_enum_link_index(&enum_type, field_index, qty, max_indexes)); |
| 136 | +// } else if (index == 5) { |
| 137 | +// CHECK_ERROR(get_enum_transfer_index(&enum_type, field_index, qty, max_indexes)); |
| 138 | +// } else { |
| 139 | +// CHECK_ERROR(get_enum_link_index(&enum_type, field_index, qty, max_indexes)); |
| 140 | +// } |
| 141 | +// break; |
| 142 | +// } |
| 143 | +// case LINKING_SCHEME_STRUCT: { |
| 144 | +// schema_struct_t struct_type = {0}; |
| 145 | +// CHECK_ERROR(read_struct(&scheme->data, &struct_type)); |
| 146 | +// CHECK_ERROR(get_struct_link_index(&struct_type, field_index, qty, max_indexes)); |
| 147 | +// break; |
| 148 | +// } |
| 149 | +// case LINKING_SCHEME_TUPLE: { |
| 150 | +// schema_tuple_t tuple_type = {0}; |
| 151 | +// CHECK_ERROR(read_tuple(&scheme->data, &tuple_type)); |
| 152 | +// CHECK_ERROR(get_tuple_link_index(&tuple_type, field_index, qty, max_indexes)); |
| 153 | +// break; |
| 154 | +// } |
| 155 | + |
| 156 | +// default: |
| 157 | +// break; |
| 158 | +// } |
| 159 | + |
| 160 | +// for (uint16_t i = current_qty; i < *qty && i < max_indexes; i++) { |
| 161 | +// print_u32("Recursive Local field_index:", field_index[i]); |
| 162 | +// } |
| 163 | + |
| 164 | +// for (uint16_t i = current_qty; i < *qty && i < max_indexes; i++) { |
| 165 | +// CHECK_ERROR(get_schema_indexes_recursive(txObj, field_index[i], runtime_call_index, field_index, qty, visited, |
| 166 | +// max_indexes)); |
| 167 | +// } |
| 168 | + |
| 169 | +// return parser_ok; |
| 170 | +// } |
| 171 | + |
| 172 | +// parser_error_t get_schema_unsigned_transaction_index(parser_tx_t *txObj, uint8_t *indices, uint32_t qty) { |
| 173 | +// CHECK_INPUT(indices); |
| 174 | +// CHECK_INPUT(txObj); |
| 175 | + |
| 176 | +// // Get root index |
| 177 | +// if (txObj->merkle_proofs.root_type_indices.qty <= ROLLUP_ROOTS_UNSIGNED_TRANSACTION || |
| 178 | +// txObj->merkle_proofs.root_type_indices.qty <= ROLLUP_ROOTS_RUNTIME_CALL) { |
| 179 | +// return parser_root_type_indices_overflow; |
| 180 | +// } |
| 181 | + |
| 182 | +// uint64_t root_index; |
| 183 | +// txObj->merkle_proofs.root_type_indices.indices.offset = OFFSET_U64 * ROLLUP_ROOTS_UNSIGNED_TRANSACTION; |
| 184 | +// CHECK_ERROR(read_u64(&txObj->merkle_proofs.root_type_indices.indices, &root_index)); |
| 185 | +// txObj->merkle_proofs.root_type_indices.indices.offset = 0; |
| 186 | + |
| 187 | +// print_u64("root_index:", root_index); |
| 188 | + |
| 189 | +// return parser_ok; |
| 190 | +// } |
| 191 | + |
| 192 | +// parser_error_t get_call_message_index(parser_tx_t *txObj) { |
| 193 | +// CHECK_INPUT(txObj); |
| 194 | + |
| 195 | +// // Get root index |
| 196 | +// if (txObj->schema.root_type_indices.qty <= ROLLUP_ROOTS_RUNTIME_CALL) { |
| 197 | +// return parser_root_type_indices_overflow; |
| 198 | +// } |
| 199 | + |
| 200 | +// uint32_t runtime_call_index = txObj->schema.root_type_indices.indices[ROLLUP_ROOTS_RUNTIME_CALL]; |
| 201 | + |
| 202 | +// if (runtime_call_index > txObj->schema.types.qty) { |
| 203 | +// return parser_scheme_indices_overflow; |
| 204 | +// } |
| 205 | + |
| 206 | +// uint16_t field_count = 0; |
| 207 | +// schema_enum_t enum_type = {0}; |
| 208 | +// CHECK_ERROR(read_enum(&txObj->schema.types.schemes[runtime_call_index].data, &enum_type)); |
| 209 | +// txObj->schema.types.schemes[runtime_call_index].data.offset = 0; |
| 210 | +// CHECK_ERROR(get_enum_link_index(&enum_type, &txObj->schema.call_message_index, &field_count, MAX_FIELDS_QTY)); |
| 211 | + |
| 212 | +// return parser_ok; |
| 213 | +// } |
| 214 | + |
| 215 | +/** |
| 216 | + * @brief Find an index in the indices array. |
| 217 | + * |
| 218 | + * @param index The index to find. |
| 219 | + * @param indices The indices array. |
| 220 | + * @return bool True if the index is found, false otherwise. |
| 221 | + */ |
| 222 | +bool schema_find_index(uint64_t index_leaf, merkle_leaves_indices_t *indices, uint64_t *index_vec) { |
| 223 | + CHECK_INPUT(indices); |
| 224 | + CHECK_INPUT(index_vec); |
| 225 | + |
| 226 | + *index_vec = 0; |
| 227 | + for (uint64_t i = 0; i < indices->entries; i++) { |
| 228 | + uint64_t index_tmp = 0; |
| 229 | + CHECK_ERROR(read_u64(&indices->indices, &index_tmp)); |
| 230 | + if (index_tmp == index_leaf) { |
| 231 | + *index_vec = i; |
| 232 | + indices->indices.offset = 0; |
| 233 | + return true; |
| 234 | + } |
| 235 | + } |
| 236 | + |
| 237 | + // reset offset |
| 238 | + indices->indices.offset = 0; |
| 239 | + return false; |
| 240 | +} |
| 241 | + |
| 242 | +parser_error_t schema_move_leaf_offset(merkle_leaves_data_t *leaves, uint64_t index) { |
| 243 | + CHECK_INPUT(leaves); |
| 244 | + uint32_t data_length = 0; |
| 245 | + for (uint64_t i = 0; i < index; i++) { |
| 246 | + CHECK_ERROR(read_u32(&leaves->data, &data_length)); |
| 247 | + if (leaves->data.offset + data_length > leaves->data.buffer.len) { |
| 248 | + return parser_unexpected_buffer_end; |
| 249 | + } |
| 250 | + leaves->data.offset += data_length; |
| 251 | + } |
| 252 | + return parser_ok; |
| 253 | +} |
| 254 | + |
| 255 | +parser_error_t schema_reset_leaf_offset(merkle_leaves_data_t *leaves) { |
| 256 | + CHECK_INPUT(leaves); |
| 257 | + leaves->data.offset = 0; |
| 258 | + return parser_ok; |
| 259 | +} |
0 commit comments