diff --git a/BlockChain/Chain.py b/BlockChain/Chain.py index fcd48b2..434cb13 100644 --- a/BlockChain/Chain.py +++ b/BlockChain/Chain.py @@ -49,6 +49,7 @@ def __init__(self): def sync_chain(self, current_chain): self.chain = current_chain.chain self.pendingTransactions = current_chain.pendingTransactions + self.account_model = current_chain.account_model def genesis(self): block_to_add = Block( @@ -71,21 +72,6 @@ def get_wallet_data(self, wallet_address): def get_last_hash(self): return Utils.hash(self._last_block.payload()).hexdigest() - # def new_block(self, block): - # self.next_block_chooser.scan_block(block) - - """ - # check that the signature corresponds to transaction - # signed by the public key (sender_address) - def addBlock(self, senderKey, signature, transaction): - publicKey = RSA.importKey(binascii.unhexlify(senderKey)) - verifier = PKCS1_v1_5.new(publicKey) - _hash = SHA.new(transaction.toString().encode('utf8')) - - if verifier.verify(_hash, binascii.unhexlify(signature)): - self.pendingTransactions.append(transaction) - """ - def insert_transaction(self, transaction: Transaction): # check transaction signature signature_valid = self.transaction_validation(transaction) @@ -94,11 +80,6 @@ def insert_transaction(self, transaction: Transaction): if signature_valid and transaction_exists: self.pendingTransactions.append(transaction) - else: - print() - raise TransactionValidationError( - "Transaction signature not valid or already existing !" - ) def remove_transactions(self, transactions): for transaction in transactions: @@ -192,7 +173,7 @@ def check_transaction(self, transaction): return False return True - def check_block_transaction(self, transaction): + def check_block_transaction(self, transaction: Transaction): for block in self.chain: for curr_transaction in block.get_transactions(): if curr_transaction.equals(transaction): @@ -267,6 +248,11 @@ def transaction_validation(self, transaction): return True + def check_block_count(self, block: Block): + if self.chain[-1].get_index() == block.get_index() - 1: + return True + return False + def last_index(self): return self._last_block.get_index() diff --git a/BlockChain/Node.py b/BlockChain/Node.py index 02b8852..5959fd8 100644 --- a/BlockChain/Node.py +++ b/BlockChain/Node.py @@ -1,3 +1,4 @@ +from email import message from quopri import encodestring from Chain import Chain from Wallet.Wallet import Wallet @@ -49,17 +50,24 @@ def handle_transaction(self, transaction): self.forge_block() def handle_block(self, block: Block): - signature_valid = Wallet.check_verified( - block.payload(), block.get_signature(), block.get_forger() - ) - if signature_valid: - self.blockchain.push_block(block) + # signature_valid = Wallet.check_verified( + # block.payload(), block.get_signature(), block.get_forger() + # ) + # if signature_valid: - message = Message(self.p2p.socketConnector, "BLOCK", block) - # Encode the message - message_encoded = Utils.encode(message) - # Broadcast the encoded message - self.p2p.broadcast(message_encoded) + # check of a a blockchain is in sync with the network + # if not, update the blocks + if not self.blockchain.check_block_count(block): + print("BLOCKCHAIN REQUEST") + self.request_chain() + + self.blockchain.push_block(block) + + message = Message(self.p2p.socketConnector, "BLOCK", block) + # Encode the message + message_encoded = Utils.encode(message) + # Broadcast the encoded message + self.p2p.broadcast(message_encoded) # notifies the blockchain that is time to forge a new block def forge_block(self): @@ -72,6 +80,22 @@ def forge_block(self): encoded_message = Utils.encode(message) self.p2p.broadcast(encoded_message) + # request the blockchain from other nodes + def request_chain(self): + message = Message(self.p2p.socketConnector, "BLOCKCHAINREQUEST", None) + encoded_message = Utils.encode(message) + self.p2p.broadcast(encoded_message) + + # send blockchain data to a certain node + def handle_chain_request(self, request_node): + message = Message(self.p2p.socketConnector, "BLOCKCHAIN", self.blockchain) + encoded_message = Utils.encode(message) + self.p2p.send(request_node, encoded_message) + + # update current blockchain from fetched one + def handle_received_blockchain(self, blockchain): + self.blockchain.sync_chain(blockchain) + def startP2P(self): self.p2p = SocketCommunication(self.ip, self.port) self.p2p.startSocketCommunication(self) diff --git a/BlockChain/P2P/SocketCommunication.py b/BlockChain/P2P/SocketCommunication.py index bf6822c..245abd5 100644 --- a/BlockChain/P2P/SocketCommunication.py +++ b/BlockChain/P2P/SocketCommunication.py @@ -42,6 +42,11 @@ def node_message(self, node, data): elif message.message_type == "BLOCK": block = message.data self.node.handle_block(block) + elif message.message_type == "BLOCKCHAINREQUEST": + self.node.handle_chain_request(node) + elif message.message_type == "BLOCKCHAIN": + blockchain = message.data + self.node.handle_received_blockchain(blockchain) def send(self, receiver, data): self.send_to_node(receiver, data) diff --git a/BlockChain/Trans_api.py b/BlockChain/Trans_api.py index 583bac2..831faeb 100644 --- a/BlockChain/Trans_api.py +++ b/BlockChain/Trans_api.py @@ -33,6 +33,6 @@ def postTransaction(sender, receiver, amount, type): postTransaction(exchange, wallet1, 100, "EXCHANGE") postTransaction(exchange, wallet1, 10, "EXCHANGE") - # postTransaction(wallet1, wallet1, 25, "STAKE") - # postTransaction(wallet2, wallet1, 1, "TRANSFER") - # postTransaction(wallet2, wallet1, 1, "TRANSFER") + postTransaction(wallet1, wallet1, 25, "STAKE") + postTransaction(wallet2, wallet1, 10, "TRANSFER") + postTransaction(wallet2, wallet1, 10, "TRANSFER")