def mine(self, transaction_list):
        if len(transaction_list) > MiningService.TRANSACTIONS_PER_BLOCK:
            raise Exception("Transactions count should be less than " + str(MiningService.TRANSACTIONS_PER_BLOCK) + 1)

        block_number = self.writer_service.get_head_block_number() + 1
        prev_block_hash = self.writer_service.get_head_block_hash()
        block_data_without_nonce = Block.block_data_without_nonce(block_number, prev_block_hash, transaction_list)

        transactions = {}
        for t in transaction_list:
            transactions[t.get_id()] = t

        nonce = 0
        logging.info("Mining block : " + str(block_number))
        while nonce < self.__max_nonce:
            block_data = block_data_without_nonce + str(nonce)
            block_data_hash = md5(block_data.encode()).hexdigest()
            if self.satisfies_difficulty(block_data_hash):
                logging.info("Block " + str(block_number) + " mined with nonce " + str(nonce) + " : ")

                #print(bin(int(block_data_hash, 16))[2:].zfill(len(block_data_hash) * 4))
                block = Block(block_number, prev_block_hash, transactions, nonce, block_data_hash)
                logging.info(block.convert_to_dict())
                self.writer_service.write(block_data_hash, block)
                break
            nonce += 1

        # Ideally, we should shuffle the transactions and repeat the process till we get a valid nonce
        if nonce == self.__max_nonce:
            raise Exception("Couldn't find a valid nonce for the data.")
Ejemplo n.º 2
0
    def mine_new_transaction_set(self, transaction_list):
        if len(transaction_list) > PoolMiningService.TRANSACTIONS_PER_BLOCK:
            raise Exception("Transactions count should be less than " +
                            str(PoolMiningService.TRANSACTIONS_PER_BLOCK) + 1)

        transactions = {}
        for t in transaction_list:
            transactions[t.get_id()] = t
        block_number = self.writer_service.get_head_block_number() + 1
        prev_block_hash = self.writer_service.get_head_block_hash()
        block_data_without_nonce = Block.block_data_without_nonce(
            block_number, prev_block_hash, transaction_list)

        self.cur_block_in_buffer = {
            "block_data_without_nonce": block_data_without_nonce,
            "block_hash": md5(block_data_without_nonce.encode()).hexdigest(),
            "block_number": block_number,
            "prev_block_hash": prev_block_hash,
            "transactions": transactions
        }

        block_with_nonce_range = {"block": block_data_without_nonce}

        for data_node in self.DATA_NODES_ADDRESS:
            block_with_nonce_range["nonce_start"] = self.cur_nonce_start_value
            block_with_nonce_range[
                "nonce_end"] = self.cur_nonce_start_value + self.NONCE_RANGE_PER_NODE

            self.network_service.send_block_for_mining(data_node,
                                                       block_with_nonce_range)
            self.cur_nonce_start_value += self.NONCE_RANGE_PER_NODE
    def fetch_blockchain_from(self, target_peer):
        url = "http://{}/block/all".format(target_peer)
        logging.info("Fetching blockchain from " + url)
        response = requests.get(url=url)
        blockchain_json = response.json()['data']

        blockchain = []
        for block_json in blockchain_json:
            block = Block.load_from_json(block_json)
            blockchain.append(block)

        return blockchain
Ejemplo n.º 4
0
    def validate_and_add_block(self, nonce, block_hash):
        logging.info("\n\n\n")
        if block_hash != self.cur_block_in_buffer["block_hash"]:
            logging.info(block_hash)
            logging.info(self.cur_block_in_buffer["block_hash"])
            logging.error("block_hash not equal to hash in buffer...\n\n\n\n")
            return

        block_data = self.cur_block_in_buffer[
            "block_data_without_nonce"] + str(nonce)
        block_data_hash = md5(block_data.encode()).hexdigest()
        if not self.satisfies_difficulty(block_data_hash):
            logging.error("Nonce of the block does not meet mining criteria")
            return

        self.reset_pool()
        block = Block(self.cur_block_in_buffer["block_number"],
                      self.cur_block_in_buffer["prev_block_hash"],
                      self.cur_block_in_buffer["transactions"], nonce,
                      block_data_hash)
        logging.info(block.convert_to_dict())
        self.writer_service.write(block_data_hash, block)
Ejemplo n.º 5
0
    def on_post(self, req, resp):
        data = json.loads(req.stream.read().decode())

        new_block_json = data['block']
        new_block = Block.load_from_json(new_block_json)

        sender = data['sender']

        logging.info("Received new block")

        validate_and_insert_block(new_block, sender)
        response = {'status': 'success'}
        response = json.dumps(response)
        resp.body = response
Ejemplo n.º 6
0
def validate_block(block):
    logging.info("Validating block...")
    transactions_list = []
    for transaction in block.transactions.values():
        transactions_list.append(transaction)
    block_data_without_nonce = Block.block_data_without_nonce(block.block_number, block.prev_block_hash, transactions_list)
    block_data = block_data_without_nonce + str(block.nonce)
    block_data_hash = hashlib.md5(block_data.encode()).hexdigest()
    
    if not pool_mining_service.satisfies_difficulty(block_data_hash):
        logging.error("Nonce of the block does not meet mining criteria")
        return False

    for transaction in block.transactions.values():
        if not transaction.verify():
            logging.error("Transaction with an invalid signature encountered")
            return False
    logging.info("Block validated successfully.\n")
    return True
Ejemplo n.º 7
0
    def __init__(self):
        if WriterService.__instance is not None:
            raise Exception(
                "Singleton instance already exists. Use WriterService.get_instance() to get that instance."
            )
        WriterService.__instance = self
        with open('./config.json', 'r') as f:
            self.config = json.load(f)

        # The 'head_block_hash' file, if exists, stores the block hash of the head block.
        # Check to see if the file exists, and if so, read the corresponding
        # block, and assign it to the head_block property
        try:
            with open(self.config['LOCAL_PATH'] + "head_block_hash") as f:
                head_block_hash = f.read()

            with open(self.config['LOCAL_PATH'] + head_block_hash +
                      ".json") as f:
                block_json = json.loads(f.read())
                self.head_block = Block.load_from_json(block_json)

        except FileNotFoundError:
            pass