def create_genesis_block(self): """ A function to generate genesis block and appends it to the chain. The block has index 0, previous_hash as 0, and a valid hash. """ genesis_block = Block(0, [], time.time(), "0") genesis_block.hash = genesis_block.compute_hash() self.chain.append(genesis_block)
def new_block_mined(): # get the block from request block_json = request.get_json() received_block = Block() # load the data from the request to Block object if received_block.load_from(block_json): # this checks if this is a duplicate block we've received. assume we have 3 connected nodes # (A, B, C). if A mines a block and gives it to B and then B gives it to C, C doesn't know if # A already has this block or not. This is a quick fix for this problem, we just discard blocks # that we have received before! hash is a reliable way of ensuring the block is the same as the # received one if node.blockchain.get_blockchain_size( ) > 0 and received_block.compute_hash( ) == node.blockchain.get_last_block().compute_hash(): return 'Accepted', 201 # add_block checks the block and makes sure if can be added to our nodes blockchain if node.blockchain.add_block(received_block): logger.info('Block %d accepted from the network!' % received_block.height) # this flag signals the miner to move to the next block node.new_block_received = True # propagate the new block to other known peers for peer_address in peers: # quick check not to send back a block to the originator # as a side note, this is not a reliable way to identify sender, # but doesn't introduce bugs as we can handle duplicate blocks (see comment a few lines above) if not request.remote_addr in peer_address: try: # call known peers /new_block_mined url = peer_address + '/new_block_mined' requests.post(url, data=request.data, headers=request.headers) logger.info('Forwarded to %s' % peer_address) except: # could not connect to peer! remove it peers.remove(peer_address) logger.info('Could not connect to %s! Peer removed.' % peer_address) return 'Accepted', 201 else: return 'Rejected', 400 else: # could not load the block information from JSON logger.info('Block %d rejected by load_from!' % received_block.height) return 'Rejected', 400
def test_compute_hash(self): block = self.test_create_block() b = Block() b.compute_hash(block)