def receive_advertise_block(): jsn = request.get_json() if "block_id" not in jsn or "peer" not in jsn: return "Invalid request", 404 block_id = jsn.get('block_id') if block_id <= blockchain.last_block.index: return json.dumps({"error ": "error"}) if block_id not in blockchain.received_block_advertises: data = {"block_id": block_id, "peer": "http://localhost:" + str(PORT)} headers = {'Content-Type': "application/json"} requested_block = requests.post(jsn["peer"] + '/request_block', data=json.dumps(data), headers=headers).json() block = Block( index=requested_block['index'], transactions=requested_block['transactions'], proof_of_verification=requested_block['proof_of_verification'], timestamp=requested_block['timestamp'], previous_hash=requested_block['previous_hash']) block.hash = requested_block['hash'] verified = utils.is_valid_block(block.__dict__) if not verified: return json.dumps({"error ": "error"}) for transaction in block.transactions: if transaction in blockchain.transactions: del blockchain.transactions[transaction] assert (requested_block["index"] == block_id) blockchain.pending_blocks[block_id] = block blockchain.pending_blocks_counts[block_id] = 1 blockchain.received_block_advertises.add(block_id) for peer in blockchain.peers: requests.post(peer + '/receive_adv_block', data=json.dumps(data), headers=headers) else: blockchain.pending_blocks_counts[block_id] += 1 if (blockchain.pending_blocks_counts[block_id] >= (len(blockchain.peers) + 1) // 2): if block_id in blockchain.pending_blocks: blockchain.add_block(blockchain.pending_blocks[block_id]) del blockchain.pending_blocks[block_id] return str(block_id) else: return json.dumps({"error ": "error"}) else: return json.dumps({"error ": "error"})
def create_chain_from_dump(chain_dump): blockchain = Blockchain(PORT) for idx, block_data in enumerate(chain_dump): block = Block( block_data["index"], block_data["transactions"], block_data["proof_of_verification"], block_data["timestamp"], block_data["previous_hash"], ) block.hash = block_data["hash"] if idx > 0: verified = utils.is_valid_block(block.__dict__) added = blockchain.add_block(block, clone_mode=True) if not added: raise Exception("The chain dump is tampered!!") else: # the block is a genesis block, no verification needed blockchain.chain.append(block) return blockchain
def add_block(self, block, clone_mode=False): if (block.previous_hash != self.last_block.hash): return False if not utils.is_valid_block(block.__dict__): return False if block.index <= self.last_block.index: return True self.chain.append(block) if clone_mode: return True next_index = block.index + 1 while next_index in self.pending_blocks_counts: if (self.pending_blocks_counts[next_index] >= (len(self.peers) + 1) // 2): self.chain.append(block) next_index += 1 else: break return True