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
```
# TODO
- Validate blocks by other users
- add mine fee
- add settings on startup
- create notifications
- cancel transactions
- modify transaction
- check validity of transactions in pool
- remove transaction from pool
# SUMMARY
in dit project moet er een p2p connectie gestart worden door 2 sockets. Deze sockets moeten beide aanstaan om het project functioneel te hebben
deze 2 sockets sturen naar elkaar als er een nieuwe gebruiker aangemaakt wordt, transacties, nieuwe blocks.
Deze sockets versturen geen gehele files. Dit moet per node gedaan worden. Dus alleen transactie data moet genoeg zijn bijvoorbeeld
De connectie wordt gemaakt bij het moment van starten,
User start Applicatie -> User komt in connectie scherm -> user 2 start applicatie -> beide apps starten.
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.MenuHelper import MenuHelper
from helpers import UtilityHelper as utilityHelper
from helpers import SocketHelper as socketHelper
import threading
from time import sleep
import os
from dotenv import load_dotenv
load_dotenv()
if __name__ == "__main__":
port = int(os.getenv("PORT"))
ip = os.getenv("IP")
utilityHelper.clearScreen()
utilityHelper.printLogo()
# start db connection
@ -27,10 +36,26 @@ if __name__ == "__main__":
sleep(1)
def program():
# start menu
menu = MenuHelper(db)
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()

View File

@ -2,6 +2,7 @@ from classes.Transaction import Tx
from classes.TxBlock import TxBlock
from helpers import UtilityHelper as utilityHelper
import time
from helpers import SocketHelper as socketHelper
MIN_MINING_TIME = 10
MAX_MINING_TIME = 20
@ -240,6 +241,9 @@ def createBlock(self):
block.date = time.time()
block.blockHash = block.computeHash()
# NEW SEND BLOCK
socketHelper.sendObj(self.peer_ip_addr, block, self.peer_port)
utilityHelper.addFile("../data/ledger.dat", block)
utilityHelper.resetFile("../data/transaction_pool.dat")
transaction_count = 0
@ -292,6 +296,7 @@ def validateMinedBlock(self):
fees = round(fees, 2)
new_reward = Tx()
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!")
utilityHelper.addFile("../data/transaction_pool.dat", new_reward)
@ -303,6 +308,13 @@ def validateMinedBlock(self):
utilityHelper.resetFile("../data/ledger.dat")
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:
utilityHelper.addFile("../data/ledger.dat", block)
@ -323,6 +335,10 @@ def validateMinedBlock(self):
return False
utilityHelper.resetFile("../data/ledger.dat")
# NEW SEND BLOCK
socketHelper.sendObj(self.peer_ip_addr, new_block, self.peer_port)
for block in blocks:
utilityHelper.addFile("../data/ledger.dat", block)

View File

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

View File

@ -1,5 +1,6 @@
from classes.User import User
from classes.Transaction import Tx
from helpers import SocketHelper as socketHelper
from helpers import TransactionHelper as transactionHelper
from helpers import BlockHelper as blockHelper
from helpers import TaskHelper as taskHelper
@ -10,6 +11,12 @@ class MenuHelper:
self.db = db
self.user = None
self.port = None
self.ip_addr = None
self.peer_port = None
self.peer_ip_addr = None
self.start_menu = {}
self.user_main_menu = {}
self.user_blockchain_menu = {}
@ -83,6 +90,10 @@ class MenuHelper:
new_tx.createRewardTransaction(self.user.public_ser, self.user.private_ser, "SIGNUP")
if new_tx != False and new_tx.is_valid():
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)
return
print(f"{utilityHelper.errorMessage('Transaction is invalid')}")
@ -144,6 +155,10 @@ class MenuHelper:
new_tx = transactionHelper.transaction(self)
if new_tx != False and new_tx.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)
continue
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