added sockets
This commit is contained in:
parent
4db46705fb
commit
0b9147e84a
@ -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
|
||||||
|
|
||||||
|
|
@ -0,0 +1 @@
|
|||||||
|
python-dotenv
|
@ -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()
|
|
@ -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)
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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')}")
|
||||||
|
97
goodchain/src/helpers/SocketHelper.py
Normal file
97
goodchain/src/helpers/SocketHelper.py
Normal 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
|
Loading…
x
Reference in New Issue
Block a user