added sockets

This commit is contained in:
Spekulaas 2024-01-03 20:55:40 +01:00
parent 4db46705fb
commit 0b9147e84a
7 changed files with 214 additions and 16 deletions

View File

@ -7,13 +7,40 @@ This is the final assesment of the blockchain minor of period 1. [EXPLANATION FI
pip install -r requirements.txt pip install -r requirements.txt
``` ```
# TODO # SUMMARY
- Validate blocks by other users in dit project moet er een p2p connectie gestart worden door 2 sockets. Deze sockets moeten beide aanstaan om het project functioneel te hebben
- add mine fee deze 2 sockets sturen naar elkaar als er een nieuwe gebruiker aangemaakt wordt, transacties, nieuwe blocks.
- add settings on startup Deze sockets versturen geen gehele files. Dit moet per node gedaan worden. Dus alleen transactie data moet genoeg zijn bijvoorbeeld
- create notifications
- cancel transactions De connectie wordt gemaakt bij het moment van starten,
- modify transaction User start Applicatie -> User komt in connectie scherm -> user 2 start applicatie -> beide apps starten.
- check validity of transactions in pool
- remove transaction from pool Wanneer een connectie verbroken wordt tussen de 2 komt er een mooie melding waarop tezien wordt dat de chain gesloten wordt
Werking:
Node start python programma,
Server start
Client start
Client zoekt naar een server waarmee hij kan connecten
client kan niks vinden en blijft proberen
Node 2 start python
server van node 2 start
Node 1 connect met server van node 2
Client van node 2 start
client van node 2 connect met server van node 1
wanneer beide welkoms meldingen gestuurd zijn start de applicatie
# TODO
- Maak een server socket
- Maak een client socket
- Maak een docker env
- Maak de opstart functionaliteit
- maak de verstuur ontvang functionaliteiten van users en transacties

View File

@ -0,0 +1 @@
python-dotenv

View File

@ -11,10 +11,19 @@
from helpers.DatabaseHelper import DatabaseHelper from helpers.DatabaseHelper import DatabaseHelper
from helpers.MenuHelper import MenuHelper from helpers.MenuHelper import MenuHelper
from helpers import UtilityHelper as utilityHelper from helpers import UtilityHelper as utilityHelper
from helpers import SocketHelper as socketHelper
import threading
from time import sleep from time import sleep
import os
from dotenv import load_dotenv
load_dotenv()
if __name__ == "__main__": if __name__ == "__main__":
port = int(os.getenv("PORT"))
ip = os.getenv("IP")
utilityHelper.clearScreen() utilityHelper.clearScreen()
utilityHelper.printLogo() utilityHelper.printLogo()
# start db connection # start db connection
@ -27,10 +36,26 @@ if __name__ == "__main__":
sleep(1) sleep(1)
# start menu def program():
menu = MenuHelper(db) # start menu
while(True): menu = MenuHelper(db)
menu.runStartMenu()
menu.port = int(os.getenv("PORT"))
menu.ip_addr = os.getenv("IP")
menu.peer_port = int(os.getenv("PEER_PORT"))
menu.peer_ip_addr = os.getenv("PEER_IP")
while(True):
menu.runStartMenu()
if menu.user != None:
menu.runUserMainMenu()
program_thread = threading.Thread(target=program)
program_thread.start()
connection_thread = threading.Thread(target=socketHelper.connection, args=(ip,port,db,))
connection_thread.start()
if menu.user != None:
menu.runUserMainMenu()

View File

@ -2,6 +2,7 @@ from classes.Transaction import Tx
from classes.TxBlock import TxBlock from classes.TxBlock import TxBlock
from helpers import UtilityHelper as utilityHelper from helpers import UtilityHelper as utilityHelper
import time import time
from helpers import SocketHelper as socketHelper
MIN_MINING_TIME = 10 MIN_MINING_TIME = 10
MAX_MINING_TIME = 20 MAX_MINING_TIME = 20
@ -240,6 +241,9 @@ def createBlock(self):
block.date = time.time() block.date = time.time()
block.blockHash = block.computeHash() block.blockHash = block.computeHash()
# NEW SEND BLOCK
socketHelper.sendObj(self.peer_ip_addr, block, self.peer_port)
utilityHelper.addFile("../data/ledger.dat", block) utilityHelper.addFile("../data/ledger.dat", block)
utilityHelper.resetFile("../data/transaction_pool.dat") utilityHelper.resetFile("../data/transaction_pool.dat")
transaction_count = 0 transaction_count = 0
@ -292,6 +296,7 @@ def validateMinedBlock(self):
fees = round(fees, 2) fees = round(fees, 2)
new_reward = Tx() new_reward = Tx()
new_reward.createRewardTransaction(new_block.metadata['miner'], self.user.private_ser, "MINE", fees) new_reward.createRewardTransaction(new_block.metadata['miner'], self.user.private_ser, "MINE", fees)
self.db.createLog(new_block.metadata['miner'], time.time(), f"Block id {new_block.id}, is validated! You received a reward of {fees + 25} coins!") self.db.createLog(new_block.metadata['miner'], time.time(), f"Block id {new_block.id}, is validated! You received a reward of {fees + 25} coins!")
utilityHelper.addFile("../data/transaction_pool.dat", new_reward) utilityHelper.addFile("../data/transaction_pool.dat", new_reward)
@ -303,6 +308,13 @@ def validateMinedBlock(self):
utilityHelper.resetFile("../data/ledger.dat") utilityHelper.resetFile("../data/ledger.dat")
blocks.append(new_block) blocks.append(new_block)
# NEW SEND BLOCK
socketHelper.sendObj(self.peer_ip_addr, new_block, self.peer_port)
# NEW SEND TRANSACTION
socketHelper.sendObj(self.peer_ip_addr, new_reward, self.peer_port)
for block in blocks: for block in blocks:
utilityHelper.addFile("../data/ledger.dat", block) utilityHelper.addFile("../data/ledger.dat", block)
@ -323,6 +335,10 @@ def validateMinedBlock(self):
return False return False
utilityHelper.resetFile("../data/ledger.dat") utilityHelper.resetFile("../data/ledger.dat")
# NEW SEND BLOCK
socketHelper.sendObj(self.peer_ip_addr, new_block, self.peer_port)
for block in blocks: for block in blocks:
utilityHelper.addFile("../data/ledger.dat", block) utilityHelper.addFile("../data/ledger.dat", block)

View File

@ -1,5 +1,6 @@
import sqlite3 import sqlite3
from helpers import UtilityHelper as utilityHelper from helpers import UtilityHelper as utilityHelper
from helpers import SocketHelper as socketHelper
class DatabaseHelper: class DatabaseHelper:
def __init__(self, db=None): def __init__(self, db=None):
@ -17,7 +18,7 @@ class DatabaseHelper:
def open(self, db): def open(self, db):
try: try:
self.conn = sqlite3.connect(db) self.conn = sqlite3.connect(db, check_same_thread=False)
self.cursor = self.conn.cursor() self.cursor = self.conn.cursor()
except: except:
pass pass
@ -56,6 +57,9 @@ class DatabaseHelper:
try: try:
self.cursor.execute("INSERT INTO `users` (private_key, public_key, username, password) VALUES (?, ?, ?, ?)", (private_key, public_key, username, password,)) self.cursor.execute("INSERT INTO `users` (private_key, public_key, username, password) VALUES (?, ?, ?, ?)", (private_key, public_key, username, password,))
self.commit() self.commit()
# NEW SEND USER
socketHelper.sendObj("localhost", ["USER CREATE",private_key, public_key, username, password], 5050)
return True return True
except sqlite3.Error as error: except sqlite3.Error as error:
return False return False
@ -70,6 +74,8 @@ class DatabaseHelper:
if self.cursor.rowcount < 1: if self.cursor.rowcount < 1:
return False return False
# NEW SEND USER
socketHelper.sendObj("localhost", ["USER CHANGE PASSWORD",user_privatekey, old_password, password], 5050)
return True return True
except sqlite3.Error as error: except sqlite3.Error as error:
@ -84,6 +90,9 @@ class DatabaseHelper:
self.cursor.execute("UPDATE `users` SET username = ? WHERE `private_key` = ?", (username, user_privatekey,)) self.cursor.execute("UPDATE `users` SET username = ? WHERE `private_key` = ?", (username, user_privatekey,))
self.commit() self.commit()
# NEW SEND USER
socketHelper.sendObj("localhost", ["USER CHANGE USERNAME",user_privatekey, username], 5050)
return True return True
except sqlite3.Error as error: except sqlite3.Error as error:
@ -99,6 +108,8 @@ class DatabaseHelper:
self.cursor.execute("DELETE FROM `users` WHERE `private_key` = ?", (user_privatekey, )) self.cursor.execute("DELETE FROM `users` WHERE `private_key` = ?", (user_privatekey, ))
self.commit() self.commit()
# NEW SEND USER
socketHelper.sendObj("localhost", ["USER DELETE",user_privatekey], 5050)
return True return True
except sqlite3.Error as error: except sqlite3.Error as error:
@ -124,6 +135,9 @@ class DatabaseHelper:
self.cursor.execute("INSERT INTO `logs` (public_key, date, info, unread) VALUES (?, ?, ?, ?)", (public_key, date, info, unread,)) self.cursor.execute("INSERT INTO `logs` (public_key, date, info, unread) VALUES (?, ?, ?, ?)", (public_key, date, info, unread,))
self.commit() self.commit()
# NEW SEND USER
socketHelper.sendObj("localhost", ["CREATE LOG",public_key,date,info,unread], 5050)
except sqlite3.Error as error: except sqlite3.Error as error:
return None return None
@ -161,6 +175,9 @@ class DatabaseHelper:
self.cursor.execute("UPDATE `logs` SET `unread` = ? WHERE `id` = ?", (unread, id, )) self.cursor.execute("UPDATE `logs` SET `unread` = ? WHERE `id` = ?", (unread, id, ))
self.commit() self.commit()
# NEW SEND USER
socketHelper.sendObj("localhost", ["UPDATE LOG STATUS",id,unread], 5050)
except sqlite3.Error as error: except sqlite3.Error as error:
return False return False

View File

@ -1,5 +1,6 @@
from classes.User import User from classes.User import User
from classes.Transaction import Tx from classes.Transaction import Tx
from helpers import SocketHelper as socketHelper
from helpers import TransactionHelper as transactionHelper from helpers import TransactionHelper as transactionHelper
from helpers import BlockHelper as blockHelper from helpers import BlockHelper as blockHelper
from helpers import TaskHelper as taskHelper from helpers import TaskHelper as taskHelper
@ -10,6 +11,12 @@ class MenuHelper:
self.db = db self.db = db
self.user = None self.user = None
self.port = None
self.ip_addr = None
self.peer_port = None
self.peer_ip_addr = None
self.start_menu = {} self.start_menu = {}
self.user_main_menu = {} self.user_main_menu = {}
self.user_blockchain_menu = {} self.user_blockchain_menu = {}
@ -83,6 +90,10 @@ class MenuHelper:
new_tx.createRewardTransaction(self.user.public_ser, self.user.private_ser, "SIGNUP") new_tx.createRewardTransaction(self.user.public_ser, self.user.private_ser, "SIGNUP")
if new_tx != False and new_tx.is_valid(): if new_tx != False and new_tx.is_valid():
print(f"{utilityHelper.blinkMessage('Added sign up bonus transaction to pool')}") print(f"{utilityHelper.blinkMessage('Added sign up bonus transaction to pool')}")
# NEW SEND TRANSACTION
socketHelper.sendObj(self.peer_ip_addr, new_tx, self.peer_port)
utilityHelper.addFile("../data/transaction_pool.dat", new_tx) utilityHelper.addFile("../data/transaction_pool.dat", new_tx)
return return
print(f"{utilityHelper.errorMessage('Transaction is invalid')}") print(f"{utilityHelper.errorMessage('Transaction is invalid')}")
@ -144,6 +155,10 @@ class MenuHelper:
new_tx = transactionHelper.transaction(self) new_tx = transactionHelper.transaction(self)
if new_tx != False and new_tx.is_valid(): if new_tx != False and new_tx.is_valid():
print(f"{utilityHelper.successMessage('Transaction is valid')}") print(f"{utilityHelper.successMessage('Transaction is valid')}")
# NEW SEND TRANSACTION
socketHelper.sendObj(self.peer_ip_addr, new_tx, self.peer_port)
utilityHelper.addFile("../data/transaction_pool.dat", new_tx) utilityHelper.addFile("../data/transaction_pool.dat", new_tx)
continue continue
print(f"{utilityHelper.errorMessage('Transaction is invalid')}") print(f"{utilityHelper.errorMessage('Transaction is invalid')}")

View File

@ -0,0 +1,97 @@
from classes.User import User
from classes.Transaction import Tx
from classes.TxBlock import TxBlock
from helpers import DatabaseHelper as databaseHelper
from helpers import UtilityHelper as utilityHelper
import socket
import pickle
import select
BUFFER_SIZE = 1024
def newServerSocket(ip_addr, port):
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((ip_addr, port))
server_socket.listen()
return server_socket
def recvObj(socket):
inputs, outputs, errs = select.select([socket], [], [socket], 6)
if socket in inputs:
connected_socket, addr = socket.accept()
all_data = b''
while True:
data = connected_socket.recv(BUFFER_SIZE)
if not data:
break
all_data = all_data + data
return pickle.loads(all_data)
return None
def sendObj(ip_addr, blk, port):
try:
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
soc.connect((ip_addr, port))
data = pickle.dumps(blk)
soc.send(data)
soc.close()
return True
except:
print("Could not connect to peer")
return False
def connection(ip, port, db):
server_socket = newServerSocket(ip, port)
while(True):
item = recvObj(server_socket)
if not item:
continue
if type(item) == Tx:
print(f"{utilityHelper.blinkMessage('Received transaction from peer')}")
utilityHelper.addFile("../data/transaction_pool.dat", item)
continue
if type(item) == TxBlock:
print(f"{utilityHelper.blinkMessage('Received block from peer')}")
utilityHelper.addFile("../data/ledger.dat", item)
continue
# DATABASE STUFF
if type(item) == list:
match item[0]:
case "USER CREATE":
db.createUser(item[1], item[2], item[3], item[4])
continue
case "USER DELETE":
db.deleteUser(item[1])
continue
case "USER CHANGE PASSWORD":
db.changePassword(item[1], item[2], item[3])
continue
case "USER CHANGE USERNAME":
db.changeUsername(item[1], item[2])
continue
case "CREATE LOG":
db.createLog(item[1], item[2], item[3])
continue
case "UPDATE LOG STATUS":
db.updateLogStatus(item[1], item[2])
continue
# changes on newServerConnection
# We modified it to accept port number as a parameter, such that when
# we make a server we can specify on which port bind it