Skip to content

Commit 1e2c340

Browse files
Merge pull request #526 from Cypherock/release/v0.6.768+
Release/v0.6.768+
2 parents 38f2eff + 7ad67f2 commit 1e2c340

35 files changed

+3601
-9
lines changed

apps/btc_family/btc_txn_helpers.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,23 @@ static void update_locktime(btc_verify_input_t *verify_input_data,
390390
return;
391391
}
392392
}
393+
394+
// TODO: Add chunking condition for varint decode
395+
// refer: https://app.clickup.com/t/9002019994/PRF-7288
396+
static int64_t varint_decode(const uint8_t *raw_txn_chunk, int32_t *offset) {
397+
uint8_t first_byte = raw_txn_chunk[*offset];
398+
if (first_byte < 0xFD) {
399+
return first_byte;
400+
} else {
401+
// TODO: var-int varies between 1-9 bytes
402+
// current implementation supports decoding
403+
// upto 3 bytes only
404+
uint8_t result[2];
405+
memcpy(result, raw_txn_chunk + *offset + 1, 2);
406+
*offset += 2;
407+
return U16_READ_LE_ARRAY(result);
408+
}
409+
}
393410
/*****************************************************************************
394411
* GLOBAL FUNCTIONS
395412
*****************************************************************************/
@@ -414,7 +431,7 @@ int btc_verify_input(const uint8_t *raw_txn_chunk,
414431
// store the number of inputs in the raw_txn
415432
verify_input_data->count = raw_txn_chunk[offset++];
416433
// TODO: Improve varint decode.
417-
// size of variable containing ip-count/op-count
434+
// size of variable containing script size and ip-count/op-count
418435
// varies (1-9 Bytes) depending on its value.
419436
// refer:
420437
// https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer
@@ -442,17 +459,18 @@ int btc_verify_input(const uint8_t *raw_txn_chunk,
442459
}
443460

444461
case SCRIPT_LENGTH_CASE: {
445-
if (offset + raw_txn_chunk[offset] + 1 + 4 > CHUNK_SIZE) {
462+
int64_t script_length = varint_decode(raw_txn_chunk, &offset);
463+
if (offset + script_length + 1 + 4 > CHUNK_SIZE) {
446464
verify_input_data->prev_offset =
447-
(offset + raw_txn_chunk[offset] + 1 + 4) - CHUNK_SIZE;
465+
(offset + script_length + 1 + 4) - CHUNK_SIZE;
448466
update_hash(
449467
verify_input_data, raw_txn_chunk, chunk_index, CHUNK_SIZE);
450468
verify_input_data->input_parse =
451469
PREVIOUS_TX_HASH_PLUS_OP_INDEX_CASE;
452470
verify_input_data->input_index++;
453471
return 4;
454472
} else {
455-
offset += (raw_txn_chunk[offset] + 1 + 4);
473+
offset += (script_length + 1 + 4);
456474
}
457475
break;
458476
}

apps/tron_app/tron_api.c

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
2+
/**
3+
* @file tron_api.c
4+
* @author Cypherock X1 Team
5+
* @brief Defines helpers apis for tron app.
6+
* @copyright Copyright (c) 2023 HODL TECH PTE LTD
7+
* <br/> You may obtain a copy of license at <a href="https://mitcc.org/"
8+
*target=_blank>https://mitcc.org/</a>
9+
*
10+
******************************************************************************
11+
* @attention
12+
*
13+
* (c) Copyright 2023 by HODL TECH PTE LTD
14+
*
15+
* Permission is hereby granted, free of charge, to any person obtaining
16+
* a copy of this software and associated documentation files (the
17+
* "Software"), to deal in the Software without restriction, including
18+
* without limitation the rights to use, copy, modify, merge, publish,
19+
* distribute, sublicense, and/or sell copies of the Software, and to
20+
* permit persons to whom the Software is furnished to do so, subject
21+
* to the following conditions:
22+
*
23+
* The above copyright notice and this permission notice shall be
24+
* included in all copies or substantial portions of the Software.
25+
*
26+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
29+
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
30+
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
31+
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32+
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33+
*
34+
*
35+
* "Commons Clause" License Condition v1.0
36+
*
37+
* The Software is provided to you by the Licensor under the License,
38+
* as defined below, subject to the following condition.
39+
*
40+
* Without limiting other conditions in the License, the grant of
41+
* rights under the License will not include, and the License does not
42+
* grant to you, the right to Sell the Software.
43+
*
44+
* For purposes of the foregoing, "Sell" means practicing any or all
45+
* of the rights granted to you under the License to provide to third
46+
* parties, for a fee or other consideration (including without
47+
* limitation fees for hosting or consulting/ support services related
48+
* to the Software), a product or service whose value derives, entirely
49+
* or substantially, from the functionality of the Software. Any license
50+
* notice or attribution required by the License must also include
51+
* this Commons Clause License Condition notice.
52+
*
53+
* Software: All X1Wallet associated files.
54+
* License: MIT
55+
* Licensor: HODL TECH PTE LTD
56+
*
57+
******************************************************************************
58+
*/
59+
60+
/*****************************************************************************
61+
* INCLUDES
62+
*****************************************************************************/
63+
64+
#include "tron_api.h"
65+
66+
#include <pb_decode.h>
67+
#include <pb_encode.h>
68+
69+
#include "common_error.h"
70+
#include "core_api.h"
71+
#include "events.h"
72+
73+
/*****************************************************************************
74+
* EXTERN VARIABLES
75+
*****************************************************************************/
76+
77+
/*****************************************************************************
78+
* PRIVATE MACROS AND DEFINES
79+
*****************************************************************************/
80+
81+
/*****************************************************************************
82+
* PRIVATE TYPEDEFS
83+
*****************************************************************************/
84+
85+
/*****************************************************************************
86+
* STATIC VARIABLES
87+
*****************************************************************************/
88+
89+
/*****************************************************************************
90+
* GLOBAL VARIABLES
91+
*****************************************************************************/
92+
93+
/*****************************************************************************
94+
* STATIC FUNCTION PROTOTYPES
95+
*****************************************************************************/
96+
97+
/*****************************************************************************
98+
* STATIC FUNCTIONS
99+
*****************************************************************************/
100+
101+
/*****************************************************************************
102+
* GLOBAL FUNCTIONS
103+
*****************************************************************************/
104+
bool decode_tron_query(const uint8_t *data,
105+
uint16_t data_size,
106+
tron_query_t *query_out) {
107+
if (NULL == data || NULL == query_out || 0 == data_size) {
108+
tron_send_error(ERROR_COMMON_ERROR_CORRUPT_DATA_TAG,
109+
ERROR_DATA_FLOW_DECODING_FAILED);
110+
return false;
111+
}
112+
113+
// zeroise for safety from garbage in the query reference
114+
memzero(query_out, sizeof(tron_query_t));
115+
116+
/* Create a stream that reads from the buffer. */
117+
pb_istream_t stream = pb_istream_from_buffer(data, data_size);
118+
119+
/* Now we are ready to decode the message. */
120+
bool status = pb_decode(&stream, TRON_QUERY_FIELDS, query_out);
121+
122+
/* Send error to host if status is false*/
123+
if (false == status) {
124+
tron_send_error(ERROR_COMMON_ERROR_CORRUPT_DATA_TAG,
125+
ERROR_DATA_FLOW_DECODING_FAILED);
126+
}
127+
128+
return status;
129+
}
130+
131+
bool encode_tron_result(const tron_result_t *result,
132+
uint8_t *buffer,
133+
uint16_t max_buffer_len,
134+
size_t *bytes_written_out) {
135+
if (NULL == result || NULL == buffer || NULL == bytes_written_out)
136+
return false;
137+
138+
/* Create a stream that will write to our buffer. */
139+
pb_ostream_t stream = pb_ostream_from_buffer(buffer, max_buffer_len);
140+
141+
/* Now we are ready to encode the message! */
142+
bool status = pb_encode(&stream, TRON_RESULT_FIELDS, result);
143+
144+
if (true == status) {
145+
*bytes_written_out = stream.bytes_written;
146+
}
147+
148+
return status;
149+
}
150+
151+
bool check_tron_query(const tron_query_t *query, pb_size_t exp_query_tag) {
152+
if ((NULL == query) || (exp_query_tag != query->which_request)) {
153+
tron_send_error(ERROR_COMMON_ERROR_CORRUPT_DATA_TAG,
154+
ERROR_DATA_FLOW_INVALID_QUERY);
155+
return false;
156+
}
157+
return true;
158+
}
159+
160+
tron_result_t init_tron_result(pb_size_t result_tag) {
161+
tron_result_t result = TRON_RESULT_INIT_ZERO;
162+
result.which_response = result_tag;
163+
return result;
164+
}
165+
166+
void tron_send_error(pb_size_t which_error, uint32_t error_code) {
167+
tron_result_t result = init_tron_result(TRON_RESULT_COMMON_ERROR_TAG);
168+
result.common_error = init_common_error(which_error, error_code);
169+
tron_send_result(&result);
170+
}
171+
172+
void tron_send_result(const tron_result_t *result) {
173+
// TODO: Set the options file for all
174+
uint8_t buffer[1700] = {0};
175+
size_t bytes_encoded = 0;
176+
ASSERT(encode_tron_result(result, buffer, sizeof(buffer), &bytes_encoded));
177+
send_response_to_host(&buffer[0], bytes_encoded);
178+
}
179+
180+
bool tron_get_query(tron_query_t *query, pb_size_t exp_query_tag) {
181+
evt_status_t event = get_events(EVENT_CONFIG_USB, MAX_INACTIVITY_TIMEOUT);
182+
183+
if (true == event.p0_event.flag) {
184+
return false;
185+
}
186+
187+
if (!decode_tron_query(
188+
event.usb_event.p_msg, event.usb_event.msg_size, query)) {
189+
return false;
190+
}
191+
192+
if (!check_tron_query(query, exp_query_tag)) {
193+
return false;
194+
}
195+
196+
return true;
197+
}

apps/tron_app/tron_api.h

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
2+
/**
3+
* @file tron_api.h
4+
* @author Cypherock X1 Team
5+
* @brief Header file to export some helper functions for the TRON app
6+
* @copyright Copyright (c) 2023 HODL TECH PTE LTD
7+
* <br/> You may obtain a copy of license at <a href="https://mitcc.org/"
8+
* target=_blank>https://mitcc.org/</a>
9+
*/
10+
#ifndef TRON_API_H
11+
#define TRON_API_H
12+
13+
/*****************************************************************************
14+
* INCLUDES
15+
*****************************************************************************/
16+
17+
#include <stdint.h>
18+
#include <tron/core.pb.h>
19+
20+
/*****************************************************************************
21+
* MACROS AND DEFINES
22+
*****************************************************************************/
23+
24+
/*****************************************************************************
25+
* TYPEDEFS
26+
*****************************************************************************/
27+
28+
/*****************************************************************************
29+
* EXPORTED VARIABLES
30+
*****************************************************************************/
31+
32+
/*****************************************************************************
33+
* GLOBAL FUNCTION PROTOTYPES
34+
*****************************************************************************/
35+
36+
/**
37+
* @brief API to decode query from host with `TRON_QUERY_FIELDS`
38+
*
39+
* @param[in] data: PB encoded bytestream received from host
40+
* @param[in] data_size: size of pb encoded bytestream
41+
* @param[out] query_out: @ref tron_query_t obj to copy the decoded result to
42+
* @return bool True if decoding was successful, else false
43+
*/
44+
bool decode_tron_query(const uint8_t *data,
45+
uint16_t data_size,
46+
tron_query_t *query_out);
47+
48+
/**
49+
* @brief Encodes the TRON result with `TRON_RESULT_FIELDS` to byte-stream
50+
*
51+
* @param[in] result: object of populated @ref tron_result_t to be encoded
52+
* @param[out] buffer: buffer to fill byte-stream into
53+
* @param[in] max_buffer_len: Max length allowed for writing bytestream to
54+
* buffer
55+
* @param[out] bytes_written_out: bytes written to bytestream
56+
* @return bool True if decoding was successful, else false
57+
*/
58+
bool encode_tron_result(const tron_result_t *result,
59+
uint8_t *buffer,
60+
uint16_t max_buffer_len,
61+
size_t *bytes_written_out);
62+
63+
/**
64+
* @brief This API checks if the `which_request` field of the query of type
65+
* `tron_query_t` matches against the expected tag.
66+
*
67+
* @param query The query of type `tron_query_t` to be checked
68+
* @param exp_query_tag The expected tag of the query
69+
* @return true If the query tag matches the expected tag
70+
* @return false If the query tag does not match the expected tag
71+
*/
72+
bool check_tron_query(const tron_query_t *query, pb_size_t exp_query_tag);
73+
74+
/**
75+
* @brief Returns zero initialized object of type
76+
* tron_result_t result_tag set in result.which_response field
77+
*
78+
* @param result_tag Result tag to be set in the tron_result_t result
79+
* @return tron_result_t Result object of type tron_result_t
80+
*/
81+
tron_result_t init_tron_result(pb_size_t result_tag);
82+
83+
/**
84+
* @brief Send the error to the host.
85+
*
86+
* @param which_error The error type to be sent
87+
* @param error_code The error code to sent to the host
88+
*/
89+
void tron_send_error(pb_size_t which_error, uint32_t error_code);
90+
91+
/**
92+
* @brief This API encodes tron_result_t in protobuf structure.
93+
* @details If the encoding is successful, then it sends the corresponding
94+
* result to the host.
95+
*
96+
* The function ASSERTs the result of encode_tron_result internally.
97+
*
98+
* @param result The result which needs to be sent to the host.
99+
*/
100+
void tron_send_result(const tron_result_t *result);
101+
102+
/**
103+
* @brief This API receives request of type tron_query_t of type
104+
* exp_query_tag from the host.
105+
*
106+
* @param query The reference to which the query needs to be populated
107+
* @param exp_query_tag The expected tag of the query
108+
* @return true If the query was recieved from the host matching the tag
109+
* @return false If the request timed out or the recieved request did not match
110+
* the tag
111+
*/
112+
bool tron_get_query(tron_query_t *query, pb_size_t exp_query_tag);
113+
114+
#endif

0 commit comments

Comments
 (0)