Skip to content

Commit b157a1a

Browse files
committed
create schema helper
1 parent 3e51ac9 commit b157a1a

10 files changed

Lines changed: 415 additions & 78 deletions

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ file(GLOB_RECURSE LIB_SRC
145145
${CMAKE_CURRENT_SOURCE_DIR}/app/src/modules/bank_reader.c
146146
${CMAKE_CURRENT_SOURCE_DIR}/app/src/modules/paymaster_reader.c
147147
${CMAKE_CURRENT_SOURCE_DIR}/app/src/schema_proof.c
148+
${CMAKE_CURRENT_SOURCE_DIR}/app/src/schema_helper.c
148149
)
149150

150151
add_library(app_lib STATIC ${LIB_SRC})

app/src/schema_helper.c

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
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+
}

app/src/schema_helper.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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+
#pragma once
18+
19+
#ifdef __cplusplus
20+
extern "C" {
21+
#endif
22+
23+
#include "parser_common.h"
24+
25+
bool schema_find_index(uint64_t index_leaf, merkle_leaves_indices_t *indices, uint64_t *index_vec);
26+
parser_error_t schema_move_leaf_offset(merkle_leaves_data_t *leaves, uint64_t index);
27+
parser_error_t schema_reset_leaf_offset(merkle_leaves_data_t *leaves);
28+
29+
#ifdef __cplusplus
30+
}
31+
#endif

app/src/schema_proof.c

Lines changed: 5 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "borsh.h"
2424
#include "parser_common.h"
2525
#include "parser_impl.h"
26+
#include "schema_helper.h"
2627
#include "schema_reader.h"
2728
#include "stack_manager.h"
2829

@@ -103,16 +104,10 @@ static parser_error_t hash_index_leaf(merkle_leaves_data_t *leaves, uint64_t ind
103104
CHECK_INPUT(hash);
104105

105106
// move the offset where leaves_data[index] starts
106-
uint32_t data_length = 0;
107-
for (uint64_t i = 0; i < index; i++) {
108-
CHECK_ERROR(read_u32(&leaves->data, &data_length));
109-
if (leaves->data.offset + data_length > leaves->data.buffer.len) {
110-
return parser_unexpected_buffer_end;
111-
}
112-
leaves->data.offset += data_length;
113-
}
107+
CHECK_ERROR(schema_move_leaf_offset(leaves, index));
114108

115109
// get data length
110+
uint32_t data_length = 0;
116111
CHECK_ERROR(read_u32(&leaves->data, &data_length));
117112

118113
// Compute hash from entry and store it in proof->hash
@@ -122,7 +117,7 @@ static parser_error_t hash_index_leaf(merkle_leaves_data_t *leaves, uint64_t ind
122117
crypto_sha256_final(hash);
123118

124119
// reset offset
125-
leaves->data.offset = 0;
120+
CHECK_ERROR(schema_reset_leaf_offset(leaves));
126121

127122
return parser_ok;
128123
}
@@ -186,33 +181,6 @@ static parser_error_t get_next_lemma_hash(merkle_lemmas_t *lemmas, uint8_t *hash
186181
return parser_ok;
187182
}
188183

189-
/**
190-
* @brief Find an index in the indices array.
191-
*
192-
* @param index The index to find.
193-
* @param indices The indices array.
194-
* @return bool True if the index is found, false otherwise.
195-
*/
196-
bool find_index(uint64_t index_leaf, merkle_leaves_indices_t *indices, uint64_t *index_vec) {
197-
CHECK_INPUT(indices);
198-
CHECK_INPUT(index_vec);
199-
200-
*index_vec = 0;
201-
for (uint64_t i = 0; i < indices->entries; i++) {
202-
uint64_t index_tmp = 0;
203-
CHECK_ERROR(read_u64(&indices->indices, &index_tmp));
204-
if (index_tmp == index_leaf) {
205-
*index_vec = i;
206-
indices->indices.offset = 0;
207-
return true;
208-
}
209-
}
210-
211-
// reset offset
212-
indices->indices.offset = 0;
213-
return false;
214-
}
215-
216184
/**
217185
* @brief Check if there are leaves in the range.
218186
*
@@ -257,7 +225,7 @@ static parser_error_t verify_multiproof_inner(proof_t *proof, uint64_t index_sta
257225
// If this is a single node, return the hash of the node
258226
if (index_end - index_start == 1) {
259227
uint64_t index_vec = 0;
260-
if (find_index(index_start, &proof->indices, &index_vec)) {
228+
if (schema_find_index(index_start, &proof->indices, &index_vec)) {
261229
CHECK_ERROR(hash_index_leaf(&proof->leaves, index_vec, hash));
262230

263231
return parser_ok;

0 commit comments

Comments
 (0)