implement integer parsing
This commit is contained in:
parent
4d4af9d7bc
commit
fbf4a5ac95
24
Inc/eth.h
24
Inc/eth.h
|
@ -29,27 +29,27 @@
|
|||
#include <stdbool.h>
|
||||
|
||||
struct {
|
||||
uint8_t *buffer;
|
||||
uint8_t *barrier;
|
||||
uint8_t* buffer;
|
||||
uint8_t* barrier;
|
||||
|
||||
int list_len;
|
||||
uint8_t *list;
|
||||
uint8_t* list;
|
||||
|
||||
uint8_t *dst_addr;
|
||||
uint8_t* dst_addr;
|
||||
|
||||
int value_len;
|
||||
uint8_t *value;
|
||||
uint8_t* value;
|
||||
|
||||
int data_len;
|
||||
uint8_t *data;
|
||||
uint8_t* data;
|
||||
|
||||
uint8_t *v;
|
||||
uint8_t *r;
|
||||
uint8_t *s;
|
||||
uint8_t* v;
|
||||
uint8_t* r;
|
||||
uint8_t* s;
|
||||
|
||||
bool is_signed;
|
||||
bool is_valid;
|
||||
} typedef EthTx;
|
||||
} typedef eth_tx_t;
|
||||
|
||||
/**
|
||||
* Takes an EthTx structure where the buffer and barrier fields must be populated and fills the other fields by parsing the content of the buffer.
|
||||
|
@ -57,7 +57,7 @@ struct {
|
|||
*
|
||||
* Only accepts unsigned transactions, where v is the chain id (for now on 1 byte only) and r and s are empty as per EIP-155
|
||||
*/
|
||||
int eth_parse(EthTx *tx);
|
||||
int eth_parse(eth_tx_t* tx);
|
||||
|
||||
/**
|
||||
* Signs a previously parsed transaction. The transaction is modified in place.
|
||||
|
@ -67,6 +67,6 @@ int eth_parse(EthTx *tx);
|
|||
* Additionally, it must be possible to increase the barrier pointer by 64 bytes. This will always happen because the
|
||||
* the empty r and s component as substituted by the signature.
|
||||
*/
|
||||
int eth_sign(EthTx *tx, const uint8_t *priv_key);
|
||||
int eth_sign(eth_tx_t* tx, const uint8_t* priv_key);
|
||||
|
||||
#endif /* ETH_H_ */
|
||||
|
|
|
@ -36,7 +36,12 @@
|
|||
* the function will not fail but the next pointer will point to NULL, indicating that this was the last field.
|
||||
*
|
||||
**/
|
||||
int rlp_parse(uint8_t *item, uint8_t **value, uint8_t **next, uint8_t *barrier);
|
||||
int rlp_parse(const uint8_t* item, uint8_t** value, uint8_t** next, const uint8_t* barrier);
|
||||
|
||||
/**
|
||||
* Takes an RLP item and reads its content as a big endian uint32. Returns -1 on failure, 0 otherwise.
|
||||
*/
|
||||
int rlp_read_uint32(const uint8_t* item, uint32_t* value, uint8_t** next, const uint8_t* barrier);
|
||||
|
||||
/**
|
||||
* Returns the number of bytes needed to encode the given len.
|
||||
|
@ -46,6 +51,6 @@ int rlp_len_of_len(int len);
|
|||
/**
|
||||
* Writes the given length to the buffer. The is_list parameter encodes if the element is a list.
|
||||
*/
|
||||
void rlp_write_len(uint8_t *buf, int len, int is_list);
|
||||
void rlp_write_len(uint8_t* buf, int len, int is_list);
|
||||
|
||||
#endif /* RLP_H_ */
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#define ETH_ASSERT_NEXT(len, min, max, next) if (ETH_WRONG_LEN(len, min, max) || next == NULL) return -1;
|
||||
#define ETH_ASSERT_LAST(len, min, max, next) if (ETH_WRONG_LEN(len, min, max) || next != NULL) return -1;
|
||||
|
||||
int eth_parse(EthTx *tx) {
|
||||
int eth_parse(eth_tx_t* tx) {
|
||||
if (tx->buffer == NULL || tx->barrier <= tx->buffer) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -40,8 +40,8 @@ int eth_parse(EthTx *tx) {
|
|||
tx->is_signed = false;
|
||||
tx->is_valid = false;
|
||||
|
||||
uint8_t *value;
|
||||
uint8_t *next;
|
||||
uint8_t* value;
|
||||
uint8_t* next;
|
||||
int len;
|
||||
|
||||
// Enter the list
|
||||
|
@ -89,7 +89,7 @@ int eth_parse(EthTx *tx) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int eth_sign(EthTx *tx, const uint8_t *privkey) {
|
||||
int eth_sign(eth_tx_t* tx, const uint8_t* privkey) {
|
||||
if (!tx->is_valid || tx->is_signed) return -1;
|
||||
|
||||
int tx_len = tx->barrier - tx->buffer;
|
||||
|
|
47
Src/rlp.c
47
Src/rlp.c
|
@ -25,25 +25,25 @@
|
|||
#include <stddef.h>
|
||||
#include "rlp.h"
|
||||
|
||||
static inline int rlp_1_byte_length(uint8_t *item, uint8_t **value) {
|
||||
*value = &item[1];
|
||||
static inline int rlp_1_byte_length(const uint8_t* item, uint8_t** value) {
|
||||
*value = (uint8_t*) &item[1];
|
||||
return item[0] & 0x3f;
|
||||
}
|
||||
|
||||
// length can be up to 4 bytes
|
||||
static inline int rlp_x_bytes_length(uint8_t *item, uint8_t **value) {
|
||||
static inline int rlp_x_bytes_length(const uint8_t* item, uint8_t** value) {
|
||||
switch(item[0] & 0x3f) {
|
||||
case 0x38:
|
||||
*value = &item[2];
|
||||
*value = (uint8_t*) &item[2];
|
||||
return item[1];
|
||||
case 0x39:
|
||||
*value = &item[3];
|
||||
*value = (uint8_t*) &item[3];
|
||||
return (item[1] << 8) | item[2];
|
||||
case 0x3a:
|
||||
*value = &item[4];
|
||||
*value = (uint8_t*) &item[4];
|
||||
return (item[1] << 16) | (item[2] << 8) | item[3];
|
||||
case 0x3b:
|
||||
*value = &item[5];
|
||||
*value = (uint8_t*) &item[5];
|
||||
return (item[1] << 24) | (item[2] << 16) | (item[3] << 8) | item[4];
|
||||
default:
|
||||
*value = NULL;
|
||||
|
@ -51,11 +51,11 @@ static inline int rlp_x_bytes_length(uint8_t *item, uint8_t **value) {
|
|||
}
|
||||
}
|
||||
|
||||
int rlp_parse(uint8_t *item, uint8_t **value, uint8_t **next, uint8_t *barrier) {
|
||||
int rlp_parse(const uint8_t* item, uint8_t** value, uint8_t** next, const uint8_t* barrier) {
|
||||
int len;
|
||||
|
||||
if (item[0] < 0x80) {
|
||||
*value = item;
|
||||
*value = (uint8_t*) item;
|
||||
len = 1;
|
||||
} else if (item[0] < 0xb8) {
|
||||
len = rlp_1_byte_length(item, value);
|
||||
|
@ -84,6 +84,33 @@ int rlp_parse(uint8_t *item, uint8_t **value, uint8_t **next, uint8_t *barrier)
|
|||
return len;
|
||||
}
|
||||
|
||||
int rlp_read_uint32(const uint8_t* item, uint32_t* value, uint8_t** next, const uint8_t* barrier) {
|
||||
uint8_t* v;
|
||||
|
||||
int len = rlp_parse(item, &v, next, barrier);
|
||||
|
||||
switch(len) {
|
||||
case -1:
|
||||
return -1;
|
||||
case 0:
|
||||
*value = 0;
|
||||
break;
|
||||
case 1:
|
||||
*value = v[0];
|
||||
break;
|
||||
case 2:
|
||||
*value = (v[0] << 8 | v[1]);
|
||||
break;
|
||||
case 3:
|
||||
*value = (v[0] << 16 | (v[1] << 8) | v[2]);
|
||||
break;
|
||||
*value = (v[0] << 24 | (v[1] << 16) | (v[2] << 8) | v[3]);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rlp_len_of_len(int len) {
|
||||
if (len < 56) {
|
||||
return 1;
|
||||
|
@ -100,7 +127,7 @@ int rlp_len_of_len(int len) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
void rlp_write_len(uint8_t *buf, int len, int is_list) {
|
||||
void rlp_write_len(uint8_t* buf, int len, int is_list) {
|
||||
uint8_t prefix;
|
||||
|
||||
if (is_list) {
|
||||
|
|
|
@ -121,7 +121,7 @@ void test_rlp_parse(void) {
|
|||
}
|
||||
|
||||
void test_eth_parse(void) {
|
||||
EthTx tx;
|
||||
eth_tx_t tx;
|
||||
tx.buffer = TX2;
|
||||
tx.barrier = &TX2[TX2_LEN];
|
||||
|
||||
|
@ -174,7 +174,7 @@ void test_eth_parse(void) {
|
|||
}
|
||||
|
||||
void test_eth_sign(void) {
|
||||
EthTx tx;
|
||||
eth_tx_t tx;
|
||||
tx.buffer = TX1;
|
||||
tx.barrier = &TX1[TX1_LEN];
|
||||
|
||||
|
|
Loading…
Reference in New Issue