From a2880d5bb2682ae4c61ae15997efb1a44df0efa2 Mon Sep 17 00:00:00 2001 From: SALTWOOD <105980161+SALTWOOD@users.noreply.github.com> Date: Sat, 11 Nov 2023 14:02:16 +0800 Subject: [PATCH] Changed blockchain saving logic Fix: timestamp is not included when calculate genesis block (#59) --- node_server.py | 65 +++++++++++++++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 24 deletions(-) diff --git a/node_server.py b/node_server.py index b059361..bb5ead0 100644 --- a/node_server.py +++ b/node_server.py @@ -5,10 +5,11 @@ from hashlib import sha256 import json import time - from flask import Flask, request import requests +directory = os.path.dirname(os.path.abspath(__file__)) +os.chdir(directory) class Block: def __init__(self, index, transactions, timestamp, previous_hash, nonce=0): @@ -43,13 +44,16 @@ def create_genesis_block(self): the chain. The block has index 0, previous_hash as 0, and a valid hash. """ - genesis_block = Block(0, [], 0, "0") + genesis_block = Block(0, [], time.time(), "0") genesis_block.hash = genesis_block.compute_hash() self.chain.append(genesis_block) @property def last_block(self): - return self.chain[-1] + if len(self.chain) <= 0: + return None + else: + return self.chain[-1] def add_block(self, block, proof): """ @@ -59,13 +63,21 @@ def add_block(self, block, proof): * The previous_hash referred in the block and the hash of latest block in the chain match. """ - previous_hash = self.last_block.hash - - if previous_hash != block.previous_hash: - raise ValueError("Previous hash incorrect") - - if not Blockchain.is_valid_proof(block, proof): - raise ValueError("Block proof invalid") + last_block = self.last_block + + if block.index == 0: # if the block is a genesis block + self.chain.clear() # then give up all the blocks in the chain + block.hash = proof + self.chain.append(block) + return + + if last_block is not None: + previous_hash = last_block.hash + if previous_hash != block.previous_hash: + raise ValueError("Previous hash incorrect") + + if not Blockchain.is_valid_proof(block, proof): + raise ValueError("Block proof invalid") block.hash = proof self.chain.append(block) @@ -173,9 +185,7 @@ def new_transaction(): def create_chain_from_dump(chain_dump): generated_blockchain = Blockchain() - for idx, block_data in enumerate(chain_dump): - if idx == 0: - continue # skip genesis block + for idx, block_data in enumerate(chain_dump): # no longer need to skip genesis block block = Block(block_data["index"], block_data["transactions"], block_data["timestamp"], @@ -213,16 +223,23 @@ def exit_from_signal(signum, stack_frame): signal.signal(signal.SIGTERM, exit_from_signal) signal.signal(signal.SIGINT, exit_from_signal) - -if chain_file_name is None: - data = None -else: - with open(chain_file_name, 'r') as chain_file: - raw_data = chain_file.read() - if raw_data is None or len(raw_data) == 0: +default_template = {"length":0,"chain":[],"peers":[]} +data = None +if chain_file_name is not None: + if os.path.exists(chain_file_name): + if chain_file_name is None: data = None else: - data = json.loads(raw_data) + with open(chain_file_name, 'r') as chain_file: + raw_data = chain_file.read() + if raw_data is None or len(raw_data) == 0: + data = None + else: + data = json.loads(raw_data) + else: + with open(chain_file_name,"w") as f: + f.write(json.dumps(default_template)) + data = default_template if data is None: # the node's copy of blockchain @@ -231,7 +248,6 @@ def exit_from_signal(signum, stack_frame): blockchain = create_chain_from_dump(data['chain']) peers.update(data['peers']) - # endpoint to request the node to mine the unconfirmed # transactions (if any). We'll be using it to initiate # a command to mine from our application itself. @@ -247,7 +263,8 @@ def mine_unconfirmed_transactions(): if chain_length == len(blockchain.chain): # announce the recently mined block to the network announce_new_block(blockchain.last_block) - return "Block #{} is mined.".format(blockchain.last_block.index) + save_chain() + return "Block #{} is mined.".format(blockchain.last_block.index) # endpoint to add new peers to the network. @@ -362,4 +379,4 @@ def announce_new_block(block): headers=headers) # Uncomment this line if you want to specify the port number in the code -#app.run(debug=True, port=8000) +app.run(debug=True, port=8000)