23#define ITEMS_BUF_MAX 320U
32#define ITEMS_FIXED_MAX 160U
33#define CALLDATA_MAX (ITEMS_BUF_MAX - ITEMS_FIXED_MAX)
61 tmp[0] =
static_cast<uint8_t
>((value >> 56U) & 0xFFU);
62 tmp[1] =
static_cast<uint8_t
>((value >> 48U) & 0xFFU);
63 tmp[2] =
static_cast<uint8_t
>((value >> 40U) & 0xFFU);
64 tmp[3] =
static_cast<uint8_t
>((value >> 32U) & 0xFFU);
65 tmp[4] =
static_cast<uint8_t
>((value >> 24U) & 0xFFU);
66 tmp[5] =
static_cast<uint8_t
>((value >> 16U) & 0xFFU);
67 tmp[6] =
static_cast<uint8_t
>((value >> 8U) & 0xFFU);
68 tmp[7] =
static_cast<uint8_t
>(value & 0xFFU);
70 while ((first < 7U) && (tmp[first] == 0U)) {
73 uint8_t count =
static_cast<uint8_t
>(8U - first);
74 for (i = 0U; i < count; i++) {
75 out[i] = tmp[
static_cast<size_t>(first) + i];
89static size_t rlp_bytes(
const uint8_t *data,
size_t data_len,
90 uint8_t *out,
size_t out_cap)
95 if (out_cap < 1U) {
return 0U; }
98 }
else if ((data_len == 1U) && (data[0] < 0x80U)) {
99 if (out_cap < 1U) {
return 0U; }
102 }
else if (data_len <= 55U) {
103 if (out_cap < 1U) {
return 0U; }
104 out[0] =
static_cast<uint8_t
>(0x80U + data_len);
105 if (!CW_Utils::safe_memcpy(out + 1U, out_cap - 1U, data, data_len)) {
108 written = 1U + data_len;
111 uint8_t len_bytes[8];
112 uint8_t num_lb =
be_minimal(
static_cast<uint64_t
>(data_len), len_bytes);
113 if (out_cap < (
static_cast<size_t>(num_lb) + 1U)) {
return 0U; }
114 out[0] =
static_cast<uint8_t
>(0xB7U + num_lb);
115 if (!CW_Utils::safe_memcpy(out + 1U, out_cap - 1U, len_bytes, num_lb)) {
118 if (!CW_Utils::safe_memcpy(out + 1U + num_lb,
119 out_cap - 1U - num_lb, data, data_len)) {
122 written = 1U + num_lb + data_len;
137static size_t rlp_uint64(uint64_t value, uint8_t *out,
size_t out_cap)
140 if (out_cap < 1U) {
return 0U; }
146 return rlp_bytes(be, be_len, out, out_cap);
159static size_t rlp_int256(
const uint8_t data[32], uint8_t *out,
size_t out_cap)
162 while ((first < 31U) && (data[first] == 0U)) {
165 if ((first == 31U) && (data[31] == 0U)) {
167 if (out_cap < 1U) {
return 0U; }
171 return rlp_bytes(data + first, 32U - first, out, out_cap);
184 if (content_len <= 55U) {
185 if (out_cap < 1U) {
return 0U; }
186 out[0] =
static_cast<uint8_t
>(0xC0U + content_len);
189 uint8_t len_bytes[8];
190 uint8_t num_lb =
be_minimal(
static_cast<uint64_t
>(content_len), len_bytes);
191 if (out_cap < (
static_cast<size_t>(num_lb) + 1U)) {
return 0U; }
192 out[0] =
static_cast<uint8_t
>(0xF7U + num_lb);
193 if (!CW_Utils::safe_memcpy(out + 1U, out_cap - 1U, len_bytes, num_lb)) {
216 uint8_t *items,
size_t items_cap)
224 w =
rlp_uint64(tx->
chain_id, items + n, items_cap - n);
if (w == 0U) {
return 0U; } n += w;
225 w =
rlp_uint64(tx->
nonce, items + n, items_cap - n);
if (w == 0U) {
return 0U; } n += w;
227 w =
rlp_uint64(tx->
max_fee, items + n, items_cap - n);
if (w == 0U) {
return 0U; } n += w;
228 w =
rlp_uint64(tx->
gas_limit, items + n, items_cap - n);
if (w == 0U) {
return 0U; } n += w;
229 w =
rlp_bytes(tx->
to, 20U, items + n, items_cap - n);
if (w == 0U) {
return 0U; } n += w;
230 w =
rlp_uint64(tx->
eth_value, items + n, items_cap - n);
if (w == 0U) {
return 0U; } n += w;
232 items + n, items_cap - n);
if (w == 0U) {
return 0U; } n += w;
234 if ((items_cap - n) < 1U) {
return 0U; }
248 if (items_len == 0U) {
return 0U; }
252 if (hdr_len == 0U) {
return 0U; }
254 size_t total = 1U + hdr_len + items_len;
255 if (total > out_max) {
return 0U; }
258 if (!CW_Utils::safe_memcpy(out + 1U, out_max - 1U, hdr, hdr_len)) {
261 if (!CW_Utils::safe_memcpy(out + 1U + hdr_len,
262 out_max - 1U - hdr_len, items, items_len)) {
269 const uint8_t r[32],
const uint8_t s[32],
270 uint8_t *out,
size_t out_max)
274 if (items_len == 0U) {
return 0U; }
278 items + items_len,
sizeof(items) - items_len);
279 if (w == 0U) {
return 0U; } items_len += w;
280 w =
rlp_int256(r, items + items_len,
sizeof(items) - items_len);
281 if (w == 0U) {
return 0U; } items_len += w;
282 w =
rlp_int256(s, items + items_len,
sizeof(items) - items_len);
283 if (w == 0U) {
return 0U; } items_len += w;
287 if (hdr_len == 0U) {
return 0U; }
289 size_t total = 1U + hdr_len + items_len;
290 if (total > out_max) {
return 0U; }
293 if (!CW_Utils::safe_memcpy(out + 1U, out_max - 1U, hdr, hdr_len)) {
296 if (!CW_Utils::safe_memcpy(out + 1U + hdr_len,
297 out_max - 1U - hdr_len, items, items_len)) {
static size_t rlp_bytes(const uint8_t *data, size_t data_len, uint8_t *out, size_t out_cap)
RLP-encode a byte string.
size_t eth_rlp_encode_signed(const eth_tx_t *tx, uint8_t v, const uint8_t r[32], const uint8_t s[32], uint8_t *out, size_t out_max)
Encode a signed EIP-1559 transaction: 0x02 || RLP([..., v, r, s]).
static uint8_t be_minimal(uint64_t value, uint8_t out[8])
Write value as a minimal big-endian byte sequence.
static size_t encode_common_fields(const eth_tx_t *tx, uint8_t *items, size_t items_cap)
Encode the nine common EIP-1559 fields into the items buffer.
static size_t rlp_uint64(uint64_t value, uint8_t *out, size_t out_cap)
RLP-encode a non-negative integer.
static size_t rlp_int256(const uint8_t data[32], uint8_t *out, size_t out_cap)
RLP-encode a 32-byte big-endian integer (e.g. ECDSA r or s).
size_t eth_rlp_encode_unsigned(const eth_tx_t *tx, uint8_t *out, size_t out_max)
Encode an unsigned EIP-1559 transaction: 0x02 || RLP([chainId, nonce, ...]).
static size_t rlp_list_header(size_t content_len, uint8_t *out, size_t out_cap)
Write the RLP list header for a list of content_len bytes.
Minimal RLP encoder for EIP-1559 (type 2) Ethereum transactions.
EIP-1559 (type 2) transaction parameters.
uint64_t max_priority_fee