From ab0dd057dc41e627e11c5f02fb9ea56207c8fa45 Mon Sep 17 00:00:00 2001 From: Nathan Faber Date: Sat, 23 Apr 2022 17:43:13 -0400 Subject: [PATCH 01/10] base queue --- src/core/utils/CMakeLists.txt | 8 ++- src/core/utils/queue.c | 92 +++++++++++++++++++++++++++++ src/includes/utils/queue.h | 36 +++++++++++ src/tests/core/utils/CMakeLists.txt | 6 ++ src/tests/core/utils/test_queue.c | 13 ++++ 5 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 src/core/utils/queue.c create mode 100644 src/includes/utils/queue.h create mode 100644 src/tests/core/utils/test_queue.c diff --git a/src/core/utils/CMakeLists.txt b/src/core/utils/CMakeLists.txt index e179bc8..ea6d65a 100644 --- a/src/core/utils/CMakeLists.txt +++ b/src/core/utils/CMakeLists.txt @@ -8,4 +8,10 @@ target_link_libraries(crypto add_library(init_db STATIC init_db.c) target_include_directories(init_db PUBLIC ${INCLUDE_ALL}) target_link_libraries(init_db - leveldb) \ No newline at end of file + leveldb) + +add_library(queue STATIC queue.c) +target_include_directories(queue PUBLIC ${INCLUDE_ALL}) +target_link_libraries(init_db + core_tx + core_block) \ No newline at end of file diff --git a/src/core/utils/queue.c b/src/core/utils/queue.c new file mode 100644 index 0000000..1237084 --- /dev/null +++ b/src/core/utils/queue.c @@ -0,0 +1,92 @@ +#include +#include +#include +#include "queue.h" +#include "base_tx.h" +#include "base_block.h" + +Queue *queue_init(){ + Queue *new_q = malloc(sizeof(Queue)); + new_q->head = NULL; + new_q->tail = NULL; + //INitialize sepmaphores and lock + new_q->semaphore = 0;//0 + if (pthread_mutex_init(&new_q->lock, NULL) != 0) { + printf("\n mutex init has failed\n"); + return NULL; + } + //pthread_mutex_unlock(&new_q->lock); + return new_q; +} + +void queue_destroy(Queue *exisiting_q){ + pthread_mutex_destroy(&exisiting_q->lock); + QueueItem *cur_item = exisiting_q->head; + QueueItem *next_item = NULL; + while(cur_item != NULL){ + next_item = cur_item->next; + free(cur_item); + cur_item = next_item; + } + free(exisiting_q); +} + +int queue_add(Queue *existing_q, QueueItem *new_item){ + // Somehow we must Lock! + if(!existing_q->tail && !existing_q->head){ + existing_q->tail = new_item; + existing_q->head = new_item; + } + existing_q->tail->next = new_item; + return 0; +} + +QueueItem *queue_pop(Queue *existing_q){ + // Somehow we must Lock! + QueueItem *ret = existing_q->head; + existing_q->head = existing_q->head->next; + // Check to see if tail should be set to Null + if(!existing_q->head){ + existing_q->tail = NULL; + } + return ret; +} + +int queue_add_int(Queue *existing_q, int *i){ + QueueItem *new_item = malloc(sizeof(QueueItem)); + new_item->item = (void *)i; + return queue_add(existing_q, new_item); +} + +int *queue_pop_int(Queue *existing_q){ + QueueItem *popped_item = queue_pop(existing_q); + int *ret = (int *)popped_item->item; + free(popped_item); + return ret; +} + +int queue_add_tx(Queue *existing_q, Transaction *tx){ + QueueItem *new_item = malloc(sizeof(Transaction)); + new_item->item = (void *)i; + return queue_add(existing_q, new_item); +} + +Transaction *queue_pop_tx(Queue *existing_q){ + QueueItem *popped_item = queue_pop(existing_q); + Transaction *ret = (Transaction *)popped_item->item; + free(popped_item); + return ret; +} + +int queue_add_block(Queue *existing_q, Transaction *tx){ + QueueItem *new_item = malloc(sizeof(Transaction)); + new_item->item = (void *)i; + return queue_add(existing_q, new_item); +} + +Block *queue_pop_block(Queue *existing_q){ + QueueItem *popped_item = queue_pop(existing_q); + Block *ret = (Block *)popped_item->item; + free(popped_item); + return ret; +} \ No newline at end of file diff --git a/src/includes/utils/queue.h b/src/includes/utils/queue.h new file mode 100644 index 0000000..6702e4d --- /dev/null +++ b/src/includes/utils/queue.h @@ -0,0 +1,36 @@ +#pragma once +#include +#include +#include + +typedef struct QueueItem{ + void *item; + struct QueueItem *next; +} QueueItem; + +typedef struct Queue { + QueueItem *head; + QueueItem *tail; + pthread_mutex_t lock; + int semaphore; +} Queue; + +Queue *queue_init(); + +void queue_destroy(Queue *exisiting_q); + +int queue_add(Queue *existing_q, QueueItem *new_item); + +QueueItem *queue_pop(Queue *existing_q); + +int queue_add_int(Queue *existing_q, int *i); + +int *queue_pop_int(Queue *existing_q); + +int queue_add_tx(Queue *existing_q, Transaction *tx); + +Transaction *queue_pop_tx(Queue *existing_q); + +int queue_add_block(Queue *existing_q, Transaction *tx); + +Block *queue_pop_block(Queue *existing_q); \ No newline at end of file diff --git a/src/tests/core/utils/CMakeLists.txt b/src/tests/core/utils/CMakeLists.txt index b21d85e..484d476 100644 --- a/src/tests/core/utils/CMakeLists.txt +++ b/src/tests/core/utils/CMakeLists.txt @@ -12,3 +12,9 @@ target_link_libraries(test_ser_key add_test(test_crypto ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test_crypto) add_test(test_ser_key ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test_ser_key) + +add_executable(test_queue test_queue.c) +target_compile_options(test_queue PRIVATE ${COMPILE_OPTIONS_STD}) +target_include_directories(test_queue PUBLIC ${INCLUDE_ALL}) +target_link_libraries(test_queue + queue) \ No newline at end of file diff --git a/src/tests/core/utils/test_queue.c b/src/tests/core/utils/test_queue.c new file mode 100644 index 0000000..cc11d6c --- /dev/null +++ b/src/tests/core/utils/test_queue.c @@ -0,0 +1,13 @@ +#include "queue.h" + +int main() { + + Queue *test_q = queue_init(); + + int *test1 = malloc(sizeof(int)); + *test1 = 4; + int add_ret = queue_add_int(test_q, test1); + int *pop_int = queue_pop_int(test_q); + printf("Popped val: %i", *pop_int); + return 0; +} From f664f52430b231ee03fd1a350f0b1f0e69c78c6a Mon Sep 17 00:00:00 2001 From: Nathan Faber Date: Sat, 23 Apr 2022 19:03:05 -0400 Subject: [PATCH 02/10] threaded queue implementation --- CMakeLists.txt | 2 ++ src/core/utils/CMakeLists.txt | 2 +- src/core/utils/queue.c | 25 +++++++++------ src/includes/utils/queue.h | 4 ++- src/tests/core/utils/CMakeLists.txt | 3 +- src/tests/core/utils/test_queue.c | 47 +++++++++++++++++++++++++++-- 6 files changed, 68 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9e8563d..813e26a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,8 @@ set(INCLUDE_TX "" CACHE INTERNAL "used internally") set(INCLUDE_BLOCK "" CACHE INTERNAL "used internally") set(INCLUDE_GLOBAL "" CACHE INTERNAL "used internally") set(INCLUDE_TEST "" CACHE INTERNAL "used internally") +set(THREADS_PREFER_PTHREAD_FLAG ON) +find_package(Threads REQUIRED) set(UTHASH_IN_PROJ "src/includes/uthash/") set(INCLUDE_ALL diff --git a/src/core/utils/CMakeLists.txt b/src/core/utils/CMakeLists.txt index ea6d65a..e3ad9b4 100644 --- a/src/core/utils/CMakeLists.txt +++ b/src/core/utils/CMakeLists.txt @@ -12,6 +12,6 @@ target_link_libraries(init_db add_library(queue STATIC queue.c) target_include_directories(queue PUBLIC ${INCLUDE_ALL}) -target_link_libraries(init_db +target_link_libraries(queue core_tx core_block) \ No newline at end of file diff --git a/src/core/utils/queue.c b/src/core/utils/queue.c index 1237084..5039e8c 100644 --- a/src/core/utils/queue.c +++ b/src/core/utils/queue.c @@ -4,6 +4,7 @@ #include "queue.h" #include "base_tx.h" #include "base_block.h" +#include Queue *queue_init(){ Queue *new_q = malloc(sizeof(Queue)); @@ -19,36 +20,40 @@ Queue *queue_init(){ return new_q; } -void queue_destroy(Queue *exisiting_q){ - pthread_mutex_destroy(&exisiting_q->lock); - QueueItem *cur_item = exisiting_q->head; +void queue_destroy(Queue *existing_q){ + pthread_mutex_lock(&existing_q->lock); // Maybe we don't need to lock if we are destroying? + pthread_mutex_destroy(&existing_q->lock); + QueueItem *cur_item = existing_q->head; QueueItem *next_item = NULL; while(cur_item != NULL){ next_item = cur_item->next; free(cur_item); cur_item = next_item; } - free(exisiting_q); + free(existing_q); } int queue_add(Queue *existing_q, QueueItem *new_item){ - // Somehow we must Lock! + pthread_mutex_lock(&existing_q->lock); if(!existing_q->tail && !existing_q->head){ existing_q->tail = new_item; existing_q->head = new_item; } existing_q->tail->next = new_item; + sleep(4); + pthread_mutex_unlock(&existing_q->lock); return 0; } QueueItem *queue_pop(Queue *existing_q){ - // Somehow we must Lock! + pthread_mutex_lock(&existing_q->lock); QueueItem *ret = existing_q->head; existing_q->head = existing_q->head->next; // Check to see if tail should be set to Null if(!existing_q->head){ existing_q->tail = NULL; } + pthread_mutex_unlock(&existing_q->lock); return ret; } @@ -67,7 +72,7 @@ int *queue_pop_int(Queue *existing_q){ int queue_add_tx(Queue *existing_q, Transaction *tx){ QueueItem *new_item = malloc(sizeof(Transaction)); - new_item->item = (void *)i; + new_item->item = (void *)tx; return queue_add(existing_q, new_item); } @@ -78,9 +83,9 @@ Transaction *queue_pop_tx(Queue *existing_q){ return ret; } -int queue_add_block(Queue *existing_q, Transaction *tx){ - QueueItem *new_item = malloc(sizeof(Transaction)); - new_item->item = (void *)i; +int queue_add_block(Queue *existing_q, Block *block){ + QueueItem *new_item = malloc(sizeof(Block)); + new_item->item = (void *)block; return queue_add(existing_q, new_item); } diff --git a/src/includes/utils/queue.h b/src/includes/utils/queue.h index 6702e4d..7573bff 100644 --- a/src/includes/utils/queue.h +++ b/src/includes/utils/queue.h @@ -2,6 +2,8 @@ #include #include #include +#include "base_tx.h" +#include "base_block.h" typedef struct QueueItem{ void *item; @@ -31,6 +33,6 @@ int queue_add_tx(Queue *existing_q, Transaction *tx); Transaction *queue_pop_tx(Queue *existing_q); -int queue_add_block(Queue *existing_q, Transaction *tx); +int queue_add_block(Queue *existing_q, Block *block); Block *queue_pop_block(Queue *existing_q); \ No newline at end of file diff --git a/src/tests/core/utils/CMakeLists.txt b/src/tests/core/utils/CMakeLists.txt index 484d476..c4cf7d6 100644 --- a/src/tests/core/utils/CMakeLists.txt +++ b/src/tests/core/utils/CMakeLists.txt @@ -17,4 +17,5 @@ add_executable(test_queue test_queue.c) target_compile_options(test_queue PRIVATE ${COMPILE_OPTIONS_STD}) target_include_directories(test_queue PUBLIC ${INCLUDE_ALL}) target_link_libraries(test_queue - queue) \ No newline at end of file + queue + Threads::Threads) \ No newline at end of file diff --git a/src/tests/core/utils/test_queue.c b/src/tests/core/utils/test_queue.c index cc11d6c..d699593 100644 --- a/src/tests/core/utils/test_queue.c +++ b/src/tests/core/utils/test_queue.c @@ -1,4 +1,30 @@ #include "queue.h" +#include +#include "pthread.h" + +void *add_and_delay(void *queue){ + Queue *thread_queue = (Queue *) queue; + int *test1 = malloc(sizeof(int)); + *test1 = 5; + printf("Starting thread 1\n"); + queue_add_int(thread_queue, test1); + printf("Done Adding thread 1\n"); + + printf("Add and Delay Returns ...\n"); + return NULL; +} + +void *add(void *queue){ + Queue *thread_queue = (Queue *) queue; + + int *test1 = malloc(sizeof(int)); + *test1 = 90; + printf("Starting thread 2\n"); + queue_add_int(thread_queue, test1); + printf("Done Adding thread 2\n"); + printf("Add Returns ...\n"); + return NULL; +} int main() { @@ -6,8 +32,25 @@ int main() { int *test1 = malloc(sizeof(int)); *test1 = 4; - int add_ret = queue_add_int(test_q, test1); + queue_add_int(test_q, test1); int *pop_int = queue_pop_int(test_q); - printf("Popped val: %i", *pop_int); + printf("Popped val: %i\n", *pop_int); + + pthread_t thread1, thread2; + int iret1, iret2; + /* Create independent threads each of which will execute function */ + + iret1 = pthread_create( &thread1, NULL, add_and_delay, (void*) test_q); + iret2 = pthread_create( &thread2, NULL, add, (void*) test_q); + + /* Wait till threads are complete before main continues. Unless we */ + /* wait we run the risk of executing an exit which will terminate */ + /* the process and all threads before the threads have completed. */ + + pthread_join( thread1, NULL); + pthread_join( thread2, NULL); + + printf("Thread 1 returns: %d\n",iret1); + printf("Thread 2 returns: %d\n",iret2); return 0; } From ecd5781fd9eff7eb3087d2d584750e6f5b0c4487 Mon Sep 17 00:00:00 2001 From: Nathan Faber Date: Sun, 24 Apr 2022 11:47:06 -0400 Subject: [PATCH 03/10] added sempahore --- src/core/utils/queue.c | 2 +- src/includes/utils/queue.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/utils/queue.c b/src/core/utils/queue.c index 5039e8c..0632ca9 100644 --- a/src/core/utils/queue.c +++ b/src/core/utils/queue.c @@ -11,7 +11,7 @@ Queue *queue_init(){ new_q->head = NULL; new_q->tail = NULL; //INitialize sepmaphores and lock - new_q->semaphore = 0;//0 + sem_init(&new_q->sem_len, 0, 0); if (pthread_mutex_init(&new_q->lock, NULL) != 0) { printf("\n mutex init has failed\n"); return NULL; diff --git a/src/includes/utils/queue.h b/src/includes/utils/queue.h index 7573bff..b0bca6b 100644 --- a/src/includes/utils/queue.h +++ b/src/includes/utils/queue.h @@ -2,6 +2,7 @@ #include #include #include +#include #include "base_tx.h" #include "base_block.h" @@ -14,7 +15,7 @@ typedef struct Queue { QueueItem *head; QueueItem *tail; pthread_mutex_t lock; - int semaphore; + sem_t sem_len; } Queue; Queue *queue_init(); From c61d21b220508684c726ad35f1379e2171ba1c78 Mon Sep 17 00:00:00 2001 From: Nathan Faber Date: Sun, 24 Apr 2022 15:46:30 -0400 Subject: [PATCH 04/10] void add and semaphore test --- src/core/utils/queue.c | 67 ++++++++++--------------------- src/includes/utils/queue.h | 17 +------- src/tests/core/utils/test_queue.c | 20 ++++----- 3 files changed, 33 insertions(+), 71 deletions(-) diff --git a/src/core/utils/queue.c b/src/core/utils/queue.c index 0632ca9..4012645 100644 --- a/src/core/utils/queue.c +++ b/src/core/utils/queue.c @@ -33,65 +33,40 @@ void queue_destroy(Queue *existing_q){ free(existing_q); } -int queue_add(Queue *existing_q, QueueItem *new_item){ +int queue_add_void(Queue *existing_q, void *new_item){ pthread_mutex_lock(&existing_q->lock); + QueueItem *new_entry = malloc(sizeof(QueueItem)); + new_entry->item = new_item; + new_entry->next = NULL; if(!existing_q->tail && !existing_q->head){ - existing_q->tail = new_item; - existing_q->head = new_item; + existing_q->tail = new_entry; + existing_q->head = new_entry; + } + else{ + existing_q->tail->next = new_entry; + existing_q->tail = new_entry; } - existing_q->tail->next = new_item; - sleep(4); pthread_mutex_unlock(&existing_q->lock); + int ret = sem_post(&existing_q->sem_len); return 0; } -QueueItem *queue_pop(Queue *existing_q){ +void *queue_pop_void(Queue *existing_q){ + sem_wait(&existing_q->sem_len); pthread_mutex_lock(&existing_q->lock); - QueueItem *ret = existing_q->head; + if(!existing_q->head){ + fprintf(stderr, "Popping off empty Queue"); + exit(1); + } + + QueueItem *popped_item = existing_q->head; existing_q->head = existing_q->head->next; // Check to see if tail should be set to Null if(!existing_q->head){ existing_q->tail = NULL; } - pthread_mutex_unlock(&existing_q->lock); - return ret; -} - -int queue_add_int(Queue *existing_q, int *i){ - QueueItem *new_item = malloc(sizeof(QueueItem)); - new_item->item = (void *)i; - return queue_add(existing_q, new_item); -} - -int *queue_pop_int(Queue *existing_q){ - QueueItem *popped_item = queue_pop(existing_q); - int *ret = (int *)popped_item->item; - free(popped_item); - return ret; -} - -int queue_add_tx(Queue *existing_q, Transaction *tx){ - QueueItem *new_item = malloc(sizeof(Transaction)); - new_item->item = (void *)tx; - return queue_add(existing_q, new_item); -} - -Transaction *queue_pop_tx(Queue *existing_q){ - QueueItem *popped_item = queue_pop(existing_q); - Transaction *ret = (Transaction *)popped_item->item; + void *ret = popped_item->item; free(popped_item); + pthread_mutex_unlock(&existing_q->lock); return ret; } - -int queue_add_block(Queue *existing_q, Block *block){ - QueueItem *new_item = malloc(sizeof(Block)); - new_item->item = (void *)block; - return queue_add(existing_q, new_item); -} - -Block *queue_pop_block(Queue *existing_q){ - QueueItem *popped_item = queue_pop(existing_q); - Block *ret = (Block *)popped_item->item; - free(popped_item); - return ret; -} \ No newline at end of file diff --git a/src/includes/utils/queue.h b/src/includes/utils/queue.h index b0bca6b..b6f3c58 100644 --- a/src/includes/utils/queue.h +++ b/src/includes/utils/queue.h @@ -22,18 +22,5 @@ Queue *queue_init(); void queue_destroy(Queue *exisiting_q); -int queue_add(Queue *existing_q, QueueItem *new_item); - -QueueItem *queue_pop(Queue *existing_q); - -int queue_add_int(Queue *existing_q, int *i); - -int *queue_pop_int(Queue *existing_q); - -int queue_add_tx(Queue *existing_q, Transaction *tx); - -Transaction *queue_pop_tx(Queue *existing_q); - -int queue_add_block(Queue *existing_q, Block *block); - -Block *queue_pop_block(Queue *existing_q); \ No newline at end of file +int queue_add_void(Queue *existing_q, void *new_item); +void *queue_pop_void(Queue *existing_q); \ No newline at end of file diff --git a/src/tests/core/utils/test_queue.c b/src/tests/core/utils/test_queue.c index d699593..b15c60a 100644 --- a/src/tests/core/utils/test_queue.c +++ b/src/tests/core/utils/test_queue.c @@ -7,21 +7,19 @@ void *add_and_delay(void *queue){ int *test1 = malloc(sizeof(int)); *test1 = 5; printf("Starting thread 1\n"); - queue_add_int(thread_queue, test1); + queue_add_void(thread_queue, test1); printf("Done Adding thread 1\n"); printf("Add and Delay Returns ...\n"); return NULL; } -void *add(void *queue){ +void *pop(void *queue){ Queue *thread_queue = (Queue *) queue; - int *test1 = malloc(sizeof(int)); - *test1 = 90; - printf("Starting thread 2\n"); - queue_add_int(thread_queue, test1); - printf("Done Adding thread 2\n"); + printf("Starting thread pop\n"); + int *ret = queue_pop_void(thread_queue); + printf("Done pop thread 2, popped: %i\n", *ret); printf("Add Returns ...\n"); return NULL; } @@ -32,16 +30,18 @@ int main() { int *test1 = malloc(sizeof(int)); *test1 = 4; - queue_add_int(test_q, test1); - int *pop_int = queue_pop_int(test_q); + queue_add_void(test_q, test1); + int *pop_int = queue_pop_void(test_q); printf("Popped val: %i\n", *pop_int); pthread_t thread1, thread2; int iret1, iret2; /* Create independent threads each of which will execute function */ + iret2 = pthread_create( &thread2, NULL, pop, (void*) test_q); + sleep(1); iret1 = pthread_create( &thread1, NULL, add_and_delay, (void*) test_q); - iret2 = pthread_create( &thread2, NULL, add, (void*) test_q); + /* Wait till threads are complete before main continues. Unless we */ /* wait we run the risk of executing an exit which will terminate */ From 2e45c808196ac4c58d7cb3aefb9f98436d1ca0c0 Mon Sep 17 00:00:00 2001 From: Nathan Faber Date: Sun, 24 Apr 2022 17:35:28 -0400 Subject: [PATCH 05/10] runtime wip --- src/core/utils/queue.c | 3 +- src/runtime/CMakeLists.txt | 7 +++ src/runtime/includes/runtime.h | 0 src/runtime/runtime.c | 97 +++++++++++++++++++++++++++++++ src/tests/core/utils/test_queue.c | 40 ------------- 5 files changed, 106 insertions(+), 41 deletions(-) create mode 100644 src/runtime/includes/runtime.h create mode 100644 src/runtime/runtime.c diff --git a/src/core/utils/queue.c b/src/core/utils/queue.c index 4012645..022cfa7 100644 --- a/src/core/utils/queue.c +++ b/src/core/utils/queue.c @@ -1,6 +1,7 @@ #include #include -#include +#include +#include "pthread.h" #include "queue.h" #include "base_tx.h" #include "base_block.h" diff --git a/src/runtime/CMakeLists.txt b/src/runtime/CMakeLists.txt index 1849eb5..bd3f0bc 100644 --- a/src/runtime/CMakeLists.txt +++ b/src/runtime/CMakeLists.txt @@ -14,3 +14,10 @@ target_link_libraries(shell wallet handle_block init_globals) + +add_executable(runtime runtime.c) +target_compile_options(runtime PRIVATE ${COMPILE_OPTIONS_STD}) +target_include_directories(runtime PUBLIC ${INCLUDE_ALL}) +target_link_libraries(runtime + queue + Threads::Threads) \ No newline at end of file diff --git a/src/runtime/includes/runtime.h b/src/runtime/includes/runtime.h new file mode 100644 index 0000000..e69de29 diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c new file mode 100644 index 0000000..341411c --- /dev/null +++ b/src/runtime/runtime.c @@ -0,0 +1,97 @@ +#include "queue.h" +#include +#include "pthread.h" + +typedef struct Globals { + Queue *queue_block; + Queue *queue_tx; + pthread_mutex_t utxo_pool_lock; + pthread_mutex_t utxo_to_tx_lock; + pthread_mutex_t blockchain_lock; + pthread_mutex_t wallet_pool_lock; + pthread_mutex_t key_pool_lock; + pthread_mutex_t mempool_lock; +} Globals; + +Globals *init_globals(){ + Globals *new_globals = malloc(sizeof(Globals)); + new_globals->queue_block = queue_init(); + new_globals->queue_tx = queue_init(); + int mutex_fail = 0; + if (pthread_mutex_init(&new_globals->utxo_pool_lock, NULL) != 0) { + mutex_fail = 1; + } + if (pthread_mutex_init(&new_globals->utxo_to_tx_lock, NULL) != 0) { + mutex_fail = 1; + } + if (pthread_mutex_init(&new_globals->blockchain_lock, NULL) != 0) { + mutex_fail = 1; + } + if (pthread_mutex_init(&new_globals->wallet_pool_lock, NULL) != 0) { + mutex_fail = 1; + } + if (pthread_mutex_init(&new_globals->key_pool_lock, NULL) != 0) { + mutex_fail = 1; + } + if (pthread_mutex_init(&new_globals->mempool_lock, NULL) != 0) { + mutex_fail = 1; + } + if (mutex_fail == 1){ + fprintf(stderr,"mutex init has failed\n"); + return NULL; + } + return new_globals; +} + +void *add_and_delay(void *queue){ + Queue *thread_queue = (Queue *) queue; + int *test1 = malloc(sizeof(int)); + *test1 = 5; + printf("Starting thread 1\n"); + queue_add_void(thread_queue, test1); + printf("Done Adding thread 1\n"); + + printf("Add and Delay Returns ...\n"); + return NULL; +} + +void *pop(void *queue){ + Queue *thread_queue = (Queue *) queue; + + printf("Starting thread pop\n"); + int *ret = queue_pop_void(thread_queue); + printf("Done pop thread 2, popped: %i\n", *ret); + printf("Add Returns ...\n"); + return NULL; +} + +int main() { + + Globals *globals = init_globals(); + + int *test1 = malloc(sizeof(int)); + *test1 = 4; + queue_add_void(globals->queue_block, test1); + int *pop_int = queue_pop_void(globals->queue_block); + printf("Popped val: %i\n", *pop_int); + + pthread_t node_block, node_tx, shell, miner; + int node_block_ret, node_tx_ret, shell_ret, miner_ret; + /* Create independent threads each of which will execute function */ + + node_block_ret = pthread_create( &node_block, NULL, pop, (void*) globals->queue_block); + sleep(1); + node_tx_ret = pthread_create( &node_tx, NULL, add_and_delay, (void*) globals->queue_block); + + + /* Wait till threads are complete before main continues. Unless we */ + /* wait we run the risk of executing an exit which will terminate */ + /* the process and all threads before the threads have completed. */ + + pthread_join( node_block, NULL); + pthread_join( node_tx, NULL); + + printf("Thread 1 returns: %d\n",node_block_ret); + printf("Thread 2 returns: %d\n", node_tx_ret); + return 0; +} diff --git a/src/tests/core/utils/test_queue.c b/src/tests/core/utils/test_queue.c index b15c60a..d1d56c3 100644 --- a/src/tests/core/utils/test_queue.c +++ b/src/tests/core/utils/test_queue.c @@ -1,28 +1,4 @@ #include "queue.h" -#include -#include "pthread.h" - -void *add_and_delay(void *queue){ - Queue *thread_queue = (Queue *) queue; - int *test1 = malloc(sizeof(int)); - *test1 = 5; - printf("Starting thread 1\n"); - queue_add_void(thread_queue, test1); - printf("Done Adding thread 1\n"); - - printf("Add and Delay Returns ...\n"); - return NULL; -} - -void *pop(void *queue){ - Queue *thread_queue = (Queue *) queue; - - printf("Starting thread pop\n"); - int *ret = queue_pop_void(thread_queue); - printf("Done pop thread 2, popped: %i\n", *ret); - printf("Add Returns ...\n"); - return NULL; -} int main() { @@ -34,23 +10,7 @@ int main() { int *pop_int = queue_pop_void(test_q); printf("Popped val: %i\n", *pop_int); - pthread_t thread1, thread2; - int iret1, iret2; - /* Create independent threads each of which will execute function */ - - iret2 = pthread_create( &thread2, NULL, pop, (void*) test_q); - sleep(1); - iret1 = pthread_create( &thread1, NULL, add_and_delay, (void*) test_q); - - - /* Wait till threads are complete before main continues. Unless we */ - /* wait we run the risk of executing an exit which will terminate */ - /* the process and all threads before the threads have completed. */ - pthread_join( thread1, NULL); - pthread_join( thread2, NULL); - printf("Thread 1 returns: %d\n",iret1); - printf("Thread 2 returns: %d\n",iret2); return 0; } From 21be1b736de5b723dee385158aa9a3968e78ac6b Mon Sep 17 00:00:00 2001 From: Nathan Faber Date: Sun, 24 Apr 2022 20:40:11 -0400 Subject: [PATCH 06/10] Added block freeing function --- src/core/blocks/base_block.c | 13 +++++++++++++ src/includes/blocks/base_block.h | 7 +++++++ 2 files changed, 20 insertions(+) diff --git a/src/core/blocks/base_block.c b/src/core/blocks/base_block.c index 3a093b5..98d50cf 100644 --- a/src/core/blocks/base_block.c +++ b/src/core/blocks/base_block.c @@ -3,6 +3,7 @@ #include #include "base_block.h" +#include "base_tx.h" #include "ser_block.h" #include "crypto.h" @@ -56,3 +57,15 @@ void pretty_print_block(Block *block, char *prefix){ printf(LINE_BREAK); } } + +void free_block(Block *block){ + if(block != NULL){ + if(block->txs != NULL){ + for(unsigned int i = 0; i < block->num_txs; i++ ){ + free_tx(block->txs[i]); + } + free(block->txs); + } + free(block); + } +} \ No newline at end of file diff --git a/src/includes/blocks/base_block.h b/src/includes/blocks/base_block.h index 2233563..2325b3f 100644 --- a/src/includes/blocks/base_block.h +++ b/src/includes/blocks/base_block.h @@ -22,6 +22,13 @@ typedef struct Block{ */ void hash_blockheader(unsigned char *dest, BlockHeader *header); +/** + * @brief Frees a block and it's containing transactions safely + * + * @param block to free + */ +void free_block(Block *block); + /* Prints a Block Header to stdout so data can be visualized From b1bf4f5c1e91020155573bc02c0c99de530bca6b Mon Sep 17 00:00:00 2001 From: Nathan Faber Date: Sun, 24 Apr 2022 20:40:37 -0400 Subject: [PATCH 07/10] miner and node_block runtime --- src/runtime/CMakeLists.txt | 1 + src/runtime/runtime.c | 61 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/src/runtime/CMakeLists.txt b/src/runtime/CMakeLists.txt index bd3f0bc..af6f052 100644 --- a/src/runtime/CMakeLists.txt +++ b/src/runtime/CMakeLists.txt @@ -20,4 +20,5 @@ target_compile_options(runtime PRIVATE ${COMPILE_OPTIONS_STD}) target_include_directories(runtime PUBLIC ${INCLUDE_ALL}) target_link_libraries(runtime queue + handle_block Threads::Threads) \ No newline at end of file diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c index 341411c..9b17e77 100644 --- a/src/runtime/runtime.c +++ b/src/runtime/runtime.c @@ -1,6 +1,9 @@ #include "queue.h" #include #include "pthread.h" +#include "validate_block.h" +#include "handle_block.h" +#include "create_block.h" typedef struct Globals { Queue *queue_block; @@ -65,6 +68,60 @@ void *pop(void *queue){ return NULL; } +void *node_block_thread(void *arg){ + Globals *globals = arg; + while(1){ + Block *popped_block = queue_pop_void(globals->queue_block); + + //Now aquire locks for validation (Utxo pool and blockcahin) + pthread_mutex_lock(&globals->utxo_pool_lock); + pthread_mutex_lock(&globals->blockchain_lock); + int block_valid = validate_block(popped_block); + + + if(block_valid == 0){ + //Now aquire additional locks for handling + pthread_mutex_lock(&globals->utxo_to_tx_lock); + pthread_mutex_lock(&globals->wallet_pool_lock); + pthread_mutex_lock(&globals->key_pool_lock); + pthread_mutex_lock(&globals->mempool_lock); + accept_block(popped_block); + free_block(popped_block); + pthread_mutex_unlock(&globals->utxo_to_tx_lock); + pthread_mutex_unlock(&globals->wallet_pool_lock); + pthread_mutex_unlock(&globals->key_pool_lock); + pthread_mutex_unlock(&globals->mempool_lock); + } + pthread_mutex_unlock(&globals->utxo_pool_lock); + pthread_mutex_unlock(&globals->blockchain_lock); + } + return NULL; +} + +void *miner_thread(void *arg){ + Globals *globals = arg; + + //Now aquire locks for creating a block! + pthread_mutex_lock(&globals->utxo_pool_lock); + pthread_mutex_lock(&globals->blockchain_lock); + pthread_mutex_lock(&globals->key_pool_lock) ; + pthread_mutex_lock(&globals->mempool_lock); + + Block *new_block = create_block_alloc(); + + pthread_mutex_unlock(&globals->utxo_pool_lock); + pthread_mutex_unlock(&globals->blockchain_lock); + pthread_mutex_unlock(&globals->key_pool_lock) ; + pthread_mutex_unlock(&globals->mempool_lock); + + while(try_header_hash(&(new_block->header)) != 0){ + change_nonce(new_block); + } + + queue_add_void(globals->queue_block, new_block); + return NULL; +} + int main() { Globals *globals = init_globals(); @@ -88,8 +145,8 @@ int main() { /* wait we run the risk of executing an exit which will terminate */ /* the process and all threads before the threads have completed. */ - pthread_join( node_block, NULL); - pthread_join( node_tx, NULL); + pthread_join(node_block, NULL); + pthread_join(node_tx, NULL); printf("Thread 1 returns: %d\n",node_block_ret); printf("Thread 2 returns: %d\n", node_tx_ret); From 4e3614a48a4f2a137aa52410f5ae92fd5033565b Mon Sep 17 00:00:00 2001 From: Nathan Faber Date: Mon, 25 Apr 2022 14:08:07 -0400 Subject: [PATCH 08/10] concurrent miner and block processor --- src/core/globals/init_globals.c | 3 ++ src/runtime/CMakeLists.txt | 3 +- src/runtime/runtime.c | 87 ++++++++++++++------------------- 3 files changed, 43 insertions(+), 50 deletions(-) diff --git a/src/core/globals/init_globals.c b/src/core/globals/init_globals.c index 204ba04..f30f7f9 100644 --- a/src/core/globals/init_globals.c +++ b/src/core/globals/init_globals.c @@ -4,11 +4,14 @@ #include "utxo_pool.h" #include "mempool.h" #include "init_db.h" +#include "wallet_pool.h" void node_init(char *db_env) { // Read from file for chain height and top block hash blockchain_init_leveldb(db_env); utxo_pool_init_leveldb(db_env); + wallet_init_leveldb(db_env); + mempool_init(); } void miner_init() { diff --git a/src/runtime/CMakeLists.txt b/src/runtime/CMakeLists.txt index af6f052..25189b6 100644 --- a/src/runtime/CMakeLists.txt +++ b/src/runtime/CMakeLists.txt @@ -21,4 +21,5 @@ target_include_directories(runtime PUBLIC ${INCLUDE_ALL}) target_link_libraries(runtime queue handle_block - Threads::Threads) \ No newline at end of file + Threads::Threads + init_globals) \ No newline at end of file diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c index 9b17e77..a63910d 100644 --- a/src/runtime/runtime.c +++ b/src/runtime/runtime.c @@ -5,6 +5,9 @@ #include "handle_block.h" #include "create_block.h" +#include "init_globals.h" +#include "init_db.h" + typedef struct Globals { Queue *queue_block; Queue *queue_tx; @@ -46,34 +49,14 @@ Globals *init_globals(){ return new_globals; } -void *add_and_delay(void *queue){ - Queue *thread_queue = (Queue *) queue; - int *test1 = malloc(sizeof(int)); - *test1 = 5; - printf("Starting thread 1\n"); - queue_add_void(thread_queue, test1); - printf("Done Adding thread 1\n"); - - printf("Add and Delay Returns ...\n"); - return NULL; -} - -void *pop(void *queue){ - Queue *thread_queue = (Queue *) queue; - - printf("Starting thread pop\n"); - int *ret = queue_pop_void(thread_queue); - printf("Done pop thread 2, popped: %i\n", *ret); - printf("Add Returns ...\n"); - return NULL; -} - void *node_block_thread(void *arg){ Globals *globals = arg; while(1){ + printf("Node Thread Waiting to pop Block\n"); Block *popped_block = queue_pop_void(globals->queue_block); - + printf("Node Thread Block Popped\n"); //Now aquire locks for validation (Utxo pool and blockcahin) + printf("Node Thread Waiting on lock for validation\n"); pthread_mutex_lock(&globals->utxo_pool_lock); pthread_mutex_lock(&globals->blockchain_lock); int block_valid = validate_block(popped_block); @@ -81,6 +64,7 @@ void *node_block_thread(void *arg){ if(block_valid == 0){ //Now aquire additional locks for handling + printf("Node Thread Waiting on lock for Handling\n"); pthread_mutex_lock(&globals->utxo_to_tx_lock); pthread_mutex_lock(&globals->wallet_pool_lock); pthread_mutex_lock(&globals->key_pool_lock); @@ -91,6 +75,7 @@ void *node_block_thread(void *arg){ pthread_mutex_unlock(&globals->wallet_pool_lock); pthread_mutex_unlock(&globals->key_pool_lock); pthread_mutex_unlock(&globals->mempool_lock); + printf("Node Thread unlockedr Handling\n"); } pthread_mutex_unlock(&globals->utxo_pool_lock); pthread_mutex_unlock(&globals->blockchain_lock); @@ -100,25 +85,29 @@ void *node_block_thread(void *arg){ void *miner_thread(void *arg){ Globals *globals = arg; + while(1){ + printf("Miner Thread waiting on lock to create Block\n"); + //Now aquire locks for creating a block! + pthread_mutex_lock(&globals->utxo_pool_lock); + pthread_mutex_lock(&globals->blockchain_lock); + pthread_mutex_lock(&globals->key_pool_lock) ; + pthread_mutex_lock(&globals->mempool_lock); + printf("Miner Thread got lock to create Block\n"); + Block *new_block = create_block_alloc(); - //Now aquire locks for creating a block! - pthread_mutex_lock(&globals->utxo_pool_lock); - pthread_mutex_lock(&globals->blockchain_lock); - pthread_mutex_lock(&globals->key_pool_lock) ; - pthread_mutex_lock(&globals->mempool_lock); - - Block *new_block = create_block_alloc(); + pthread_mutex_unlock(&globals->utxo_pool_lock); + pthread_mutex_unlock(&globals->blockchain_lock); + pthread_mutex_unlock(&globals->key_pool_lock) ; + pthread_mutex_unlock(&globals->mempool_lock); + printf("Miner Thread done creating Block\n"); - pthread_mutex_unlock(&globals->utxo_pool_lock); - pthread_mutex_unlock(&globals->blockchain_lock); - pthread_mutex_unlock(&globals->key_pool_lock) ; - pthread_mutex_unlock(&globals->mempool_lock); - - while(try_header_hash(&(new_block->header)) != 0){ - change_nonce(new_block); - } + while(try_header_hash(&(new_block->header)) != 0){ + change_nonce(new_block); + } - queue_add_void(globals->queue_block, new_block); + printf("Miner mined a block Block\n"); + queue_add_void(globals->queue_block, new_block); + } return NULL; } @@ -126,29 +115,29 @@ int main() { Globals *globals = init_globals(); - int *test1 = malloc(sizeof(int)); - *test1 = 4; - queue_add_void(globals->queue_block, test1); - int *pop_int = queue_pop_void(globals->queue_block); - printf("Popped val: %i\n", *pop_int); + // Intitialize the globabls! + node_init(PROD_DB_LOC); pthread_t node_block, node_tx, shell, miner; int node_block_ret, node_tx_ret, shell_ret, miner_ret; /* Create independent threads each of which will execute function */ - node_block_ret = pthread_create( &node_block, NULL, pop, (void*) globals->queue_block); + // node_block_ret = pthread_create( &node_block, NULL, pop, (void*) globals->queue_block); + // sleep(1); + // node_tx_ret = pthread_create( &node_tx, NULL, add_and_delay, (void*) globals->queue_block); + + node_block_ret = pthread_create( &node_block, NULL, node_block_thread, (void*) globals); sleep(1); - node_tx_ret = pthread_create( &node_tx, NULL, add_and_delay, (void*) globals->queue_block); + miner_ret = pthread_create( &miner, NULL, miner_thread, (void*) globals); - /* Wait till threads are complete before main continues. Unless we */ /* wait we run the risk of executing an exit which will terminate */ /* the process and all threads before the threads have completed. */ pthread_join(node_block, NULL); - pthread_join(node_tx, NULL); + pthread_join(miner, NULL); printf("Thread 1 returns: %d\n",node_block_ret); - printf("Thread 2 returns: %d\n", node_tx_ret); + printf("Thread 2 returns: %d\n", miner_ret); return 0; } From 19cc6ee1ba9429378522fe6033cd5b0298b19fff Mon Sep 17 00:00:00 2001 From: Nathan Faber Date: Mon, 25 Apr 2022 22:02:35 -0400 Subject: [PATCH 09/10] set difficulty higher --- src/includes/globals/constants.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/includes/globals/constants.h b/src/includes/globals/constants.h index 85a8f90..9277c5f 100644 --- a/src/includes/globals/constants.h +++ b/src/includes/globals/constants.h @@ -10,7 +10,7 @@ #define ERR_BUF 1024 #define BLOCK_REWARD 100 #define DESIRED_NUM_TX 10 -#define HASH_DIFFICULTY 2 +#define HASH_DIFFICULTY 3 #define MINING_NODE 1 #define WALLET_NODE 1 From 995b74591cdf6c9738b8eba5c8963f352f3ab5fb Mon Sep 17 00:00:00 2001 From: Nathan Faber Date: Wed, 27 Apr 2022 15:53:12 -0400 Subject: [PATCH 10/10] Shell concurrent --- src/core/txs/handle_tx.c | 3 +- src/runtime/CMakeLists.txt | 7 ++- src/runtime/includes/runtime.h | 17 ++++++ src/runtime/includes/shell.h | 19 +++---- src/runtime/runtime.c | 95 ++++++++++++++++++++++++++++------ src/runtime/shell.c | 92 ++++++++++++++++++-------------- 6 files changed, 165 insertions(+), 68 deletions(-) diff --git a/src/core/txs/handle_tx.c b/src/core/txs/handle_tx.c index c8d2009..2af37ca 100644 --- a/src/core/txs/handle_tx.c +++ b/src/core/txs/handle_tx.c @@ -4,7 +4,8 @@ #include "utxo_to_tx.h" int handle_tx(Transaction *tx){ - if(mempool_add(tx) == NULL){ + Transaction *coppied_tx = copy_tx(tx); + if(mempool_add(coppied_tx) == NULL){ return 1; } return 0; diff --git a/src/runtime/CMakeLists.txt b/src/runtime/CMakeLists.txt index 25189b6..f4ed096 100644 --- a/src/runtime/CMakeLists.txt +++ b/src/runtime/CMakeLists.txt @@ -4,7 +4,7 @@ message(STATUS "Building Runtime") # Add inlcudes for the runtime headers add_subdirectory(includes) -add_executable(shell shell.c) +add_library(shell shell.c) target_compile_options(shell PRIVATE ${COMPILE_OPTIONS_STD}) target_include_directories(shell PUBLIC ${INCLUDE_ALL} @@ -22,4 +22,7 @@ target_link_libraries(runtime queue handle_block Threads::Threads - init_globals) \ No newline at end of file + init_globals + validate_tx + handle_tx + shell) \ No newline at end of file diff --git a/src/runtime/includes/runtime.h b/src/runtime/includes/runtime.h index e69de29..d3a9cfc 100644 --- a/src/runtime/includes/runtime.h +++ b/src/runtime/includes/runtime.h @@ -0,0 +1,17 @@ +#pragma once +#include "queue.h" +#include "pthread.h" +#include "semaphore.h" + +typedef struct Globals { + Queue *queue_block; + Queue *queue_tx; + pthread_mutex_t utxo_pool_lock; + pthread_mutex_t utxo_to_tx_lock; + pthread_mutex_t blockchain_lock; + pthread_mutex_t wallet_pool_lock; + pthread_mutex_t key_pool_lock; + pthread_mutex_t mempool_lock; + int *miner_update; + pthread_mutex_t miner_update_lock; +} Globals; \ No newline at end of file diff --git a/src/runtime/includes/shell.h b/src/runtime/includes/shell.h index 35663cd..c46b60b 100644 --- a/src/runtime/includes/shell.h +++ b/src/runtime/includes/shell.h @@ -16,12 +16,13 @@ #pragma once #include +#include "runtime.h" #define COMMAND_NAME_LEN 128 typedef struct { char *name; - int (*func)(char **); + int (*func)(Globals *, char **); size_t num_args; char *help; } Command; @@ -37,17 +38,17 @@ void str_to_buf( size_t dest_len, size_t src_len ); -int shell_mine(char **args); -int shell_build_tx(char **args); -int shell_print_chain(char **args); -int shell_print_block(char **args); -int shell_exit(char **args); -int shell_help(char **args); +int shell_mine(Globals *globals, char **args); +int shell_build_tx(Globals *globals, char **args); +int shell_print_chain(Globals *globals, char **args); +int shell_print_block(Globals *globals, char **args); +int shell_exit(Globals *globals, char **args); +int shell_help(Globals *globals, char **args); char *shell_read_line(); char **shell_tokenize(char *line); -int shell_execute(size_t num_args, char **args); -void shell_loop(); +int shell_execute(Globals *globals, size_t num_args, char **args); +void shell_loop(Globals *globals); void shell_init_globals(); void shell_init_commands(); diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c index a63910d..8d86527 100644 --- a/src/runtime/runtime.c +++ b/src/runtime/runtime.c @@ -3,22 +3,14 @@ #include "pthread.h" #include "validate_block.h" #include "handle_block.h" +#include "validate_tx.h" +#include "handle_tx.h" #include "create_block.h" - +#include "shell.h" +#include "runtime.h" #include "init_globals.h" #include "init_db.h" -typedef struct Globals { - Queue *queue_block; - Queue *queue_tx; - pthread_mutex_t utxo_pool_lock; - pthread_mutex_t utxo_to_tx_lock; - pthread_mutex_t blockchain_lock; - pthread_mutex_t wallet_pool_lock; - pthread_mutex_t key_pool_lock; - pthread_mutex_t mempool_lock; -} Globals; - Globals *init_globals(){ Globals *new_globals = malloc(sizeof(Globals)); new_globals->queue_block = queue_init(); @@ -42,10 +34,16 @@ Globals *init_globals(){ if (pthread_mutex_init(&new_globals->mempool_lock, NULL) != 0) { mutex_fail = 1; } + if (pthread_mutex_init(&new_globals->miner_update_lock, NULL) != 0) { + mutex_fail = 1; + } if (mutex_fail == 1){ fprintf(stderr,"mutex init has failed\n"); return NULL; } + new_globals->miner_update = malloc(sizeof(int)); + *new_globals->miner_update = 1; + return new_globals; } @@ -71,6 +69,9 @@ void *node_block_thread(void *arg){ pthread_mutex_lock(&globals->mempool_lock); accept_block(popped_block); free_block(popped_block); + pthread_mutex_lock(&globals->miner_update_lock); + *globals->miner_update = 0; + pthread_mutex_unlock(&globals->miner_update_lock); pthread_mutex_unlock(&globals->utxo_to_tx_lock); pthread_mutex_unlock(&globals->wallet_pool_lock); pthread_mutex_unlock(&globals->key_pool_lock); @@ -83,8 +84,40 @@ void *node_block_thread(void *arg){ return NULL; } +void *node_tx_thread(void *arg){ + Globals *globals = arg; + while(1){ + printf("NodeTX Thread Waiting to pop TX\n"); + Transaction *popped_tx = queue_pop_void(globals->queue_tx); + printf("NodeTX Thread TX Popped\n"); + //Now aquire locks for validation (Utxo pool and blockcahin) + printf("NodeTX Thread Waiting on lock for validation\n"); + + + pthread_mutex_lock(&globals->utxo_pool_lock); + pthread_mutex_lock(&globals->utxo_to_tx_lock); + pthread_mutex_lock(&globals->mempool_lock); + + int tx_valid = validate_tx_incoming(popped_tx); + + + if(tx_valid == 0){ + //Now aquire additional locks for handling + handle_tx(popped_tx); + free_tx(popped_tx); + } + pthread_mutex_unlock(&globals->mempool_lock); + pthread_mutex_unlock(&globals->utxo_to_tx_lock); + pthread_mutex_unlock(&globals->utxo_pool_lock); + printf("NodeTX Thread unlocked from validation\n"); + } + return NULL; +} + void *miner_thread(void *arg){ Globals *globals = arg; + unsigned long hash_check_flag = 10000; + int new_block_in_chain = 1; //1 is false 0 is true while(1){ printf("Miner Thread waiting on lock to create Block\n"); //Now aquire locks for creating a block! @@ -103,14 +136,37 @@ void *miner_thread(void *arg){ while(try_header_hash(&(new_block->header)) != 0){ change_nonce(new_block); + if(new_block->header.nonce % hash_check_flag == 0){ + pthread_mutex_lock(&globals->miner_update_lock); + if(globals->miner_update == 0){ + new_block_in_chain = 0; + *globals->miner_update = 1; + } + pthread_mutex_unlock(&globals->miner_update_lock); + if(new_block_in_chain == 0){ + break; + } + } } - + if(new_block_in_chain == 0){ + free_block(new_block); + continue; + new_block_in_chain = 1; + } + print_block(new_block,""); printf("Miner mined a block Block\n"); queue_add_void(globals->queue_block, new_block); } return NULL; } +void *shell_thread(void *arg){ + Globals *globals = arg; + shell_init(); + shell_loop(globals); + return NULL; +} + int main() { Globals *globals = init_globals(); @@ -127,17 +183,22 @@ int main() { // node_tx_ret = pthread_create( &node_tx, NULL, add_and_delay, (void*) globals->queue_block); node_block_ret = pthread_create( &node_block, NULL, node_block_thread, (void*) globals); - sleep(1); + node_tx_ret = pthread_create( &node_tx, NULL, node_tx_thread, (void*) globals); + shell_ret = pthread_create( &shell, NULL, shell_thread, (void*) globals); miner_ret = pthread_create( &miner, NULL, miner_thread, (void*) globals); /* Wait till threads are complete before main continues. Unless we */ /* wait we run the risk of executing an exit which will terminate */ /* the process and all threads before the threads have completed. */ + pthread_join(shell, NULL); pthread_join(node_block, NULL); + pthread_join(node_tx, NULL); pthread_join(miner, NULL); - printf("Thread 1 returns: %d\n",node_block_ret); - printf("Thread 2 returns: %d\n", miner_ret); - return 0; + printf("Node Block returns: %d\n",node_block_ret); + printf("Node TX returns: %d\n", node_tx_ret); + printf("Shell returns: %d\n", shell_ret); + printf("Miner returns: %d\n", miner_ret); + return 0; } diff --git a/src/runtime/shell.c b/src/runtime/shell.c index 6ed200f..bef76f8 100644 --- a/src/runtime/shell.c +++ b/src/runtime/shell.c @@ -8,7 +8,7 @@ #include "init_globals.h" #include "mempool.h" #include "blockchain.h" - +#include "runtime.h" #include "wallet.h" #include "create_block.h" #include "handle_block.h" @@ -19,10 +19,10 @@ #define ARG_SIZE 32 Command shell_commands[] = { - { - .name = "mine", .func = &shell_mine, .num_args = 1, - .help = "Usage: mine\nMine a new block" - }, + // { + // .name = "mine", .func = &shell_mine, .num_args = 1, + // .help = "Usage: mine\nMine a new block" + // }, { .name = "create_tx", .func = &shell_build_tx, .num_args = 4, .help = "Usage: create_tx ADDRESS AMT FEE\nCreate a new transaction" @@ -83,27 +83,27 @@ void str_to_buf( } } -int shell_mine(char **args) { - (void)args; - Block *block; - unsigned char header_hash[BLOCK_HASH_LEN]; +// int shell_mine(Globals *globals, char **args) { +// (void)args; +// Block *block; +// unsigned char header_hash[BLOCK_HASH_LEN]; - printf("Mining...\n"); - block = mine_block(); - handle_new_block(block); +// printf("Mining...\n"); +// block = mine_block(); +// handle_new_block(block); - // This might not be needed anymore... - hash_blockheader(header_hash, &block->header); - printf("Block mined!\n\n"); - dump_buf("", "Hash: ", header_hash, BLOCK_HASH_LEN); - pretty_print_block(block, ""); +// // This might not be needed anymore... +// hash_blockheader(header_hash, &block->header); +// printf("Block mined!\n\n"); +// dump_buf("", "Hash: ", header_hash, BLOCK_HASH_LEN); +// pretty_print_block(block, ""); - unsigned char tx_hash[TX_HASH_LEN]; - hash_tx(tx_hash, block->txs[0]); - return 0; -} +// unsigned char tx_hash[TX_HASH_LEN]; +// hash_tx(tx_hash, block->txs[0]); +// return 0; +// } -int shell_build_tx(char **args) { +int shell_build_tx(Globals *globals, char **args) { Transaction *tx; TxOptions *options; Output *output; @@ -121,10 +121,14 @@ int shell_build_tx(char **args) { options->dests = output; options->tx_fee = strtoul(args[3], &end, 10); - tx = build_tx(options); - mempool_add(tx); + pthread_mutex_lock(&globals->wallet_pool_lock); + pthread_mutex_lock(&globals->key_pool_lock); - printf("Transaction created!\n\n"); + tx = build_tx(options); + queue_add_void(globals->queue_tx, tx); + pthread_mutex_unlock(&globals->wallet_pool_lock); + pthread_mutex_unlock(&globals->key_pool_lock); + printf("Transaction added to buffer!\n\n"); pretty_print_tx(tx, ""); free(output); @@ -133,13 +137,15 @@ int shell_build_tx(char **args) { return 0; } -int shell_print_chain(char **args) { +int shell_print_chain(Globals *globals, char **args) { (void)args; + pthread_mutex_lock(&globals->blockchain_lock); pretty_print_blockchain_hashmap(); + pthread_mutex_unlock(&globals->blockchain_lock); return 0; } -int shell_print_block(char **args) { +int shell_print_block(Globals *globals, char **args) { unsigned char buf[BLOCK_HASH_LEN]; Block *block; @@ -147,7 +153,9 @@ int shell_print_block(char **args) { buf, args[1], BLOCK_HASH_LEN, strlen(args[1]) ); + pthread_mutex_lock(&globals->blockchain_lock); int ret_find = blockchain_find_leveldb(&block, buf); + pthread_mutex_unlock(&globals->blockchain_lock); if (!block || ret_find != 0) { printf("%s: block not found\n", args[0]); return 0; @@ -159,12 +167,18 @@ int shell_print_block(char **args) { return 0; } -int shell_exit(char **args) { +int shell_exit(Globals *globals, char **args) { + pthread_mutex_lock(&globals->utxo_pool_lock); + pthread_mutex_lock(&globals->blockchain_lock); + pthread_mutex_lock(&globals->utxo_to_tx_lock); + pthread_mutex_lock(&globals->wallet_pool_lock); + pthread_mutex_lock(&globals->key_pool_lock); + pthread_mutex_lock(&globals->mempool_lock); (void)args; return 1; } -int shell_help(char **args) { +int shell_help(Globals *globals, char **args) { int len; (void)args; @@ -227,7 +241,7 @@ char **shell_tokenize(char *line) { return args; } -int shell_execute(size_t num_args, char **args) { +int shell_execute(Globals *globals, size_t num_args, char **args) { CommandPool *entry; Command *cmd; int len, i; @@ -254,10 +268,10 @@ int shell_execute(size_t num_args, char **args) { return 0; } - return cmd->func(args); + return cmd->func(globals, args); } -void shell_loop() { +void shell_loop(Globals *globals) { char *line; char **args; int status; @@ -272,7 +286,7 @@ void shell_loop() { continue; args = shell_tokenize(line); num_args = arg_len(args); - status = shell_execute(num_args, args); + status = shell_execute(globals, num_args, args); free(line); free(args); @@ -303,12 +317,12 @@ void shell_init_commands() { } void shell_init() { - shell_init_globals(); + //shell_init_globals(); shell_init_commands(); } -int main() { - shell_init(); - shell_loop(); - return 1; -} +// int main() { +// // shell_init(); +// // shell_loop(); +// return 1; +// }