Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions include/serialize.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,50 @@ echo_result_t varint_write(uint8_t *buf, size_t buf_len, uint64_t value,
echo_result_t varint_read(const uint8_t *buf, size_t buf_len, uint64_t *value,
size_t *consumed);

/*
* Deserialize a uint32_t from buffer (little-endian).
* For trusted data only - no bounds checking performed.
*/
static inline uint32_t deserialize_u32_le(const uint8_t *p) {
return (uint32_t)p[0] | ((uint32_t)p[1] << 8) | ((uint32_t)p[2] << 16) |
((uint32_t)p[3] << 24);
}

/*
* Deserialize a uint64_t from buffer (little-endian).
* For trusted data only - no bounds checking performed.
*/
static inline uint64_t deserialize_u64_le(const uint8_t *p) {
return (uint64_t)p[0] | ((uint64_t)p[1] << 8) | ((uint64_t)p[2] << 16) |
((uint64_t)p[3] << 24) | ((uint64_t)p[4] << 32) |
((uint64_t)p[5] << 40) | ((uint64_t)p[6] << 48) |
((uint64_t)p[7] << 56);
}

/*
* Serialize a uint32_t to buffer (little-endian).
* Buffer must have at least 4 bytes available.
*/
static inline void serialize_u32_le(uint8_t *p, uint32_t v) {
p[0] = (uint8_t)(v & 0xFF);
p[1] = (uint8_t)((v >> 8) & 0xFF);
p[2] = (uint8_t)((v >> 16) & 0xFF);
p[3] = (uint8_t)((v >> 24) & 0xFF);
}

/*
* Serialize a uint64_t to buffer (little-endian).
* Buffer must have at least 8 bytes available.
*/
static inline void serialize_u64_le(uint8_t *p, uint64_t v) {
p[0] = (uint8_t)(v & 0xFF);
p[1] = (uint8_t)((v >> 8) & 0xFF);
p[2] = (uint8_t)((v >> 16) & 0xFF);
p[3] = (uint8_t)((v >> 24) & 0xFF);
p[4] = (uint8_t)((v >> 32) & 0xFF);
p[5] = (uint8_t)((v >> 40) & 0xFF);
p[6] = (uint8_t)((v >> 48) & 0xFF);
p[7] = (uint8_t)((v >> 56) & 0xFF);
}

#endif /* ECHO_SERIALIZE_H */
33 changes: 8 additions & 25 deletions src/consensus/block.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,6 @@
#include <stdlib.h>
#include <string.h>

/*
* Helper: read a 32-bit little-endian value.
*/
static uint32_t read_u32_le(const uint8_t *p) {
return (uint32_t)p[0] | ((uint32_t)p[1] << 8) | ((uint32_t)p[2] << 16) |
((uint32_t)p[3] << 24);
}

/*
* Helper: write a 32-bit little-endian value.
*/
static void write_u32_le(uint8_t *p, uint32_t v) {
p[0] = (uint8_t)(v & 0xFF);
p[1] = (uint8_t)((v >> 8) & 0xFF);
p[2] = (uint8_t)((v >> 16) & 0xFF);
p[3] = (uint8_t)((v >> 24) & 0xFF);
}

/*
* Initialize a block structure.
Expand Down Expand Up @@ -78,7 +61,7 @@ echo_result_t block_header_parse(const uint8_t *data, size_t data_len,
}

/* Version (4 bytes) */
header->version = (int32_t)read_u32_le(data);
header->version = (int32_t)deserialize_u32_le(data);

/* Previous block hash (32 bytes) */
memcpy(header->prev_hash.bytes, data + 4, 32);
Expand All @@ -87,13 +70,13 @@ echo_result_t block_header_parse(const uint8_t *data, size_t data_len,
memcpy(header->merkle_root.bytes, data + 36, 32);

/* Timestamp (4 bytes) */
header->timestamp = read_u32_le(data + 68);
header->timestamp = deserialize_u32_le(data + 68);

/* Bits (4 bytes) */
header->bits = read_u32_le(data + 72);
header->bits = deserialize_u32_le(data + 72);

/* Nonce (4 bytes) */
header->nonce = read_u32_le(data + 76);
header->nonce = deserialize_u32_le(data + 76);

return ECHO_OK;
}
Expand All @@ -112,7 +95,7 @@ echo_result_t block_header_serialize(const block_header_t *header, uint8_t *buf,
}

/* Version (4 bytes) */
write_u32_le(buf, (uint32_t)header->version);
serialize_u32_le(buf, (uint32_t)header->version);

/* Previous block hash (32 bytes) */
memcpy(buf + 4, header->prev_hash.bytes, 32);
Expand All @@ -121,13 +104,13 @@ echo_result_t block_header_serialize(const block_header_t *header, uint8_t *buf,
memcpy(buf + 36, header->merkle_root.bytes, 32);

/* Timestamp (4 bytes) */
write_u32_le(buf + 68, header->timestamp);
serialize_u32_le(buf + 68, header->timestamp);

/* Bits (4 bytes) */
write_u32_le(buf + 72, header->bits);
serialize_u32_le(buf + 72, header->bits);

/* Nonce (4 bytes) */
write_u32_le(buf + 76, header->nonce);
serialize_u32_le(buf + 76, header->nonce);

return ECHO_OK;
}
Expand Down
62 changes: 10 additions & 52 deletions src/consensus/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,48 +20,6 @@
#define SEGWIT_MARKER 0x00
#define SEGWIT_FLAG 0x01

/*
* Helper: read a 32-bit little-endian value.
*/
static uint32_t read_u32_le(const uint8_t *p) {
return (uint32_t)p[0] | ((uint32_t)p[1] << 8) | ((uint32_t)p[2] << 16) |
((uint32_t)p[3] << 24);
}

/*
* Helper: read a 64-bit little-endian value.
*/
static uint64_t read_u64_le(const uint8_t *p) {
return (uint64_t)p[0] | ((uint64_t)p[1] << 8) | ((uint64_t)p[2] << 16) |
((uint64_t)p[3] << 24) | ((uint64_t)p[4] << 32) |
((uint64_t)p[5] << 40) | ((uint64_t)p[6] << 48) |
((uint64_t)p[7] << 56);
}

/*
* Helper: write a 32-bit little-endian value.
*/
static void write_u32_le(uint8_t *p, uint32_t v) {
p[0] = (uint8_t)(v & 0xFF);
p[1] = (uint8_t)((v >> 8) & 0xFF);
p[2] = (uint8_t)((v >> 16) & 0xFF);
p[3] = (uint8_t)((v >> 24) & 0xFF);
}

/*
* Helper: write a 64-bit little-endian value.
*/
static void write_u64_le(uint8_t *p, uint64_t v) {
p[0] = (uint8_t)(v & 0xFF);
p[1] = (uint8_t)((v >> 8) & 0xFF);
p[2] = (uint8_t)((v >> 16) & 0xFF);
p[3] = (uint8_t)((v >> 24) & 0xFF);
p[4] = (uint8_t)((v >> 32) & 0xFF);
p[5] = (uint8_t)((v >> 40) & 0xFF);
p[6] = (uint8_t)((v >> 48) & 0xFF);
p[7] = (uint8_t)((v >> 56) & 0xFF);
}

/*
* Helper: free witness stack.
*/
Expand Down Expand Up @@ -176,7 +134,7 @@ static echo_result_t parse_inputs(const uint8_t *data, size_t data_len,
if (*offset + 4 > data_len) {
return ECHO_ERR_TRUNCATED;
}
input->prevout.vout = read_u32_le(data + *offset);
input->prevout.vout = deserialize_u32_le(data + *offset);
*offset += 4;

/* ScriptSig length and data */
Expand Down Expand Up @@ -209,7 +167,7 @@ static echo_result_t parse_inputs(const uint8_t *data, size_t data_len,
if (*offset + 4 > data_len) {
return ECHO_ERR_TRUNCATED;
}
input->sequence = read_u32_le(data + *offset);
input->sequence = deserialize_u32_le(data + *offset);
*offset += 4;
}

Expand Down Expand Up @@ -255,7 +213,7 @@ static echo_result_t parse_outputs(const uint8_t *data, size_t data_len,
if (*offset + 8 > data_len) {
return ECHO_ERR_TRUNCATED;
}
output->value = (satoshi_t)read_u64_le(data + *offset);
output->value = (satoshi_t)deserialize_u64_le(data + *offset);
*offset += 8;

/* ScriptPubKey length and data */
Expand Down Expand Up @@ -369,7 +327,7 @@ echo_result_t tx_parse(const uint8_t *data, size_t data_len, tx_t *tx,
if (data_len < 4) {
return ECHO_ERR_TRUNCATED;
}
tx->version = (int32_t)read_u32_le(data);
tx->version = (int32_t)deserialize_u32_le(data);
offset = 4;

/* Check for SegWit marker/flag */
Expand Down Expand Up @@ -420,7 +378,7 @@ echo_result_t tx_parse(const uint8_t *data, size_t data_len, tx_t *tx,
tx_free(tx);
return ECHO_ERR_TRUNCATED;
}
tx->locktime = read_u32_le(data + offset);
tx->locktime = deserialize_u32_le(data + offset);
offset += 4;

if (consumed != NULL) {
Expand Down Expand Up @@ -523,7 +481,7 @@ echo_result_t tx_serialize(const tx_t *tx, echo_bool_t with_witness,
has_witness = with_witness && tx->has_witness;

/* Version */
write_u32_le(buf + offset, (uint32_t)tx->version);
serialize_u32_le(buf + offset, (uint32_t)tx->version);
offset += 4;

/* Marker and flag for SegWit */
Expand All @@ -548,7 +506,7 @@ echo_result_t tx_serialize(const tx_t *tx, echo_bool_t with_witness,
offset += 32;

/* Prevout vout */
write_u32_le(buf + offset, input->prevout.vout);
serialize_u32_le(buf + offset, input->prevout.vout);
offset += 4;

/* ScriptSig */
Expand All @@ -564,7 +522,7 @@ echo_result_t tx_serialize(const tx_t *tx, echo_bool_t with_witness,
}

/* Sequence */
write_u32_le(buf + offset, input->sequence);
serialize_u32_le(buf + offset, input->sequence);
offset += 4;
}

Expand All @@ -580,7 +538,7 @@ echo_result_t tx_serialize(const tx_t *tx, echo_bool_t with_witness,
const tx_output_t *output = &tx->outputs[i];

/* Value */
write_u64_le(buf + offset, (uint64_t)output->value);
serialize_u64_le(buf + offset, (uint64_t)output->value);
offset += 8;

/* ScriptPubKey */
Expand Down Expand Up @@ -623,7 +581,7 @@ echo_result_t tx_serialize(const tx_t *tx, echo_bool_t with_witness,
}

/* Locktime */
write_u32_le(buf + offset, tx->locktime);
serialize_u32_le(buf + offset, tx->locktime);
offset += 4;

if (written != NULL) {
Expand Down
14 changes: 6 additions & 8 deletions src/storage/block_index_db.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "block_index_db.h"
#include "block.h"
#include "chainstate.h"
#include "serialize.h"
#include "db.h"
#include "echo_types.h"
#include <stdbool.h>
Expand Down Expand Up @@ -208,15 +209,15 @@ static void serialize_header(const block_header_t *header, uint8_t *buf) {
buf[pos++] = (uint8_t)(header->nonce >> 24);
}


/*
* Deserialize a block header from 80 bytes.
*/
static void deserialize_header(const uint8_t *buf, block_header_t *header) {
size_t pos = 0;

/* version (4 bytes, little-endian) */
header->version = (int32_t)(buf[pos] | (buf[pos + 1] << 8) |
(buf[pos + 2] << 16) | (buf[pos + 3] << 24));
header->version = (int32_t)deserialize_u32_le(&buf[pos]);
pos += 4;

/* prev_hash (32 bytes) */
Expand All @@ -228,18 +229,15 @@ static void deserialize_header(const uint8_t *buf, block_header_t *header) {
pos += 32;

/* timestamp (4 bytes, little-endian) */
header->timestamp = (uint32_t)(buf[pos] | (buf[pos + 1] << 8) |
(buf[pos + 2] << 16) | (buf[pos + 3] << 24));
header->timestamp = deserialize_u32_le(&buf[pos]);
pos += 4;

/* bits (4 bytes, little-endian) */
header->bits = (uint32_t)(buf[pos] | (buf[pos + 1] << 8) |
(buf[pos + 2] << 16) | (buf[pos + 3] << 24));
header->bits = deserialize_u32_le(&buf[pos]);
pos += 4;

/* nonce (4 bytes, little-endian) */
header->nonce = (uint32_t)(buf[pos] | (buf[pos + 1] << 8) |
(buf[pos + 2] << 16) | (buf[pos + 3] << 24));
header->nonce = deserialize_u32_le(&buf[pos]);
}

/*
Expand Down