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
|
||||
```
|
||||
|
||||
# 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
|
||||
|
||||
|
@ -0,0 +1 @@
|
||||
python-dotenv
|
@ -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()
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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')}")
|
||||
|
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