Skip to content

Commit

Permalink
Merge pull request #30 from kostaleonard/blockchain-verify
Browse files Browse the repository at this point in the history
Adds blockchain serialization and deserialization
  • Loading branch information
kostaleonard authored Feb 16, 2024
2 parents 6e44a38 + 9b73bfc commit 6018199
Show file tree
Hide file tree
Showing 26 changed files with 1,144 additions and 16 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

build
scrap
tests/output

### C ###
# Prerequisites
Expand Down
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,13 @@ target_link_libraries(main hash)
add_library(base64 src/base64.c)
target_link_libraries(base64 OpenSSL::Crypto)
target_link_libraries(main base64)
add_library(endian src/endian.c)
target_link_libraries(main endian)
include_directories(${CMOCKA_INCLUDE_DIR})
find_package(cmocka REQUIRED)
add_executable(tests tests/main.c)
add_library(test_file_paths tests/file_paths.c)
target_link_libraries(tests test_file_paths)
add_library(test_linked_list tests/test_linked_list.c)
target_link_libraries(test_linked_list linked_list)
target_link_libraries(tests test_linked_list)
Expand All @@ -41,4 +45,7 @@ target_link_libraries(tests test_transaction)
add_library(test_base64 tests/test_base64.c)
target_link_libraries(test_base64 base64)
target_link_libraries(tests test_base64)
add_library(test_endian tests/test_endian.c)
target_link_libraries(test_endian endian)
target_link_libraries(tests test_endian)
target_link_libraries(tests cmocka)
10 changes: 6 additions & 4 deletions include/block.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
*
* @param created_at The datetime at which the user created this block.
* @param transaction_list A list of the transactions this block contains.
* @param proof_of_work A number p' such that hash(pp') contains some number of
* leading zeros, where p is the previous block's proof of work.
* @param proof_of_work A number such that the hash of the block_t contains
* some number of leading zeros. It has no meaning other than as part of the
* hash.
* @param previous_block_hash The hash of the previous block.
*/
typedef struct block_t {
Expand All @@ -33,8 +34,9 @@ typedef struct block_t {
*
* @param block The pointer to fill with the new block.
* @param transaction_list A list of the transactions this block contains.
* @param proof_of_work A number p' such that hash(pp') contains some number of
* leading zeros, where p is the previous block's proof of work.
* @param proof_of_work A number such that the hash of the block_t contains
* some number of leading zeros. It has no meaning other than as part of the
* hash.
* @param previous_block_hash The hash of the previous block.
* @return return_code_t A return code indicating success or failure.
*/
Expand Down
57 changes: 57 additions & 0 deletions include/blockchain.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,61 @@ return_code_t blockchain_mine_block(
*/
void blockchain_print(blockchain_t *blockchain);

/**
* @brief Serializes the blockchain into a buffer for file or network I/O.
*
* @param blockchain The blockchain.
* @param buffer A pointer to fill with the bytes representing the blockchain.
* Callers can write the bytes to a file or send on the network and reconstruct
* the original blockchain with blockchain_deserialize. Callers are responsible
* for freeing the buffer.
* @param buffer_size A pointer to fill with the final size of the buffer.
* @return return_code_t A return code indicating success or failure.
*/
return_code_t blockchain_serialize(
blockchain_t *blockchain,
unsigned char **buffer,
uint64_t *buffer_size
);

/**
* @brief Reconstructs the blockchain from a buffer.
*
* @param blockchain A pointer to fill with the reconstructed blockchain.
* Callers are responsible for calling blockchain_destroy when finished.
* @param buffer An array containing the serialized blockchain.
* @param buffer_size The length of the serialized blockchain.
* @return return_code_t A return code indicating success or failure.
*/
return_code_t blockchain_deserialize(
blockchain_t **blockchain,
unsigned char *buffer,
uint64_t buffer_size
);

/**
* @brief Saves the blockchain to a file.
*
* @param blockchain The blockchain.
* @param outfile The path to the file to which to write the blockchain.
* @return return_code_t A return code indicating success or failure.
*/
return_code_t blockchain_write_to_file(
blockchain_t *blockchain,
char *outfile
);

/**
* @brief Reads the blockchain from a file.
*
* @param blockchain A pointer to fill with the reconstructed blockchain.
* Callers are responsible for calling blockchain_destroy when finished.
* @param infile The path to the file from which to read the blockchain.
* @return return_code_t A return code indicating success or failure.
*/
return_code_t blockchain_read_from_file(
blockchain_t **blockchain,
char *infile
);

#endif // INCLUDE_BLOCKCHAIN_H_
25 changes: 25 additions & 0 deletions include/endian.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* @brief Defines functions for working with endianness.
*/

#ifndef INCLUDE_ENDIAN_H_
#define INCLUDE_ENDIAN_H_
#include <stdint.h>

/**
* @brief Returns the big endian representation of data.
*
* @param data A 64 bit piece of data. Its endianness does not matter.
* @return uint64_t The big endian representation of data.
*/
uint64_t htobe64(uint64_t data);

/**
* @brief Returns the host representation of big endian data.
*
* @param data A 64 bit piece of data in big endian representation.
* @return uint64_t The host representation of data.
*/
uint64_t betoh64(uint64_t data);

#endif // INCLUDE_ENDIAN_H_
10 changes: 10 additions & 0 deletions include/linked_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define INCLUDE_LINKED_LIST_H_

#include <stdbool.h>
#include <stdint.h>
#include "include/return_codes.h"

/**
Expand Down Expand Up @@ -148,4 +149,13 @@ return_code_t linked_list_append(linked_list_t *linked_list, void *data);
*/
return_code_t linked_list_get_last(linked_list_t *linked_list, node_t **node);

/**
* @brief Fills length with the number of items in the linked list.
*
* @param linked_list The linked list.
* @param length A pointer to fill with the length of the list.
* @return return_code_t A return code indicating success or failure.
*/
return_code_t linked_list_length(linked_list_t *linked_list, uint64_t *length);

#endif // INCLUDE_LINKED_LIST_H_
3 changes: 3 additions & 0 deletions include/return_codes.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ typedef enum return_code_t {
FAILURE_COULD_NOT_FIND_VALID_PROOF_OF_WORK,
FAILRE_INVALID_COMMAND_LINE_ARGS,
FAILURE_OPENSSL_FUNCTION,
FAILURE_FILE_IO,
FAILURE_SIGNATURE_TOO_LONG,
FAILURE_BUFFER_TOO_SMALL,
} return_code_t;

#endif // INCLUDE_RETURN_CODES_H_
4 changes: 2 additions & 2 deletions include/transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ typedef struct transaction_t {
time_t created_at;
ssh_key_t sender_public_key;
ssh_key_t recipient_public_key;
uint32_t amount;
uint64_t amount;
ssh_signature_t sender_signature;
} transaction_t;

Expand All @@ -51,7 +51,7 @@ return_code_t transaction_create(
transaction_t **transaction,
ssh_key_t *sender_public_key,
ssh_key_t *recipient_public_key,
uint32_t amount,
uint64_t amount,
ssh_key_t *sender_private_key
);

Expand Down
3 changes: 3 additions & 0 deletions src/block.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ return_code_t block_hash(block_t *block, sha_256_t *hash) {
NULL != node;
node = node->next) {
transaction_t *transaction = (transaction_t *)node->data;
// We can just hash the entire transaction directly because it contains
// no pointers. Memory locations don't have meaning, so we can't hash
// pointers.
EVP_DigestUpdate(mdctx, (void *)transaction, sizeof(*transaction));
}
EVP_DigestFinal_ex(mdctx, hash->digest, NULL);
Expand Down
Loading

0 comments on commit 6018199

Please sign in to comment.