예제 #1
0
 def mine(self):
     while True:
         block = self.mine_block()
         if not block:
             continue
         logger.info("Block {} found at height {} and nonce {}"
                     .format(block.block_header.hash, block.height, block.block_header.nonce))
         if self.blockchain.add_block(block):
             self.mempool.remove_unconfirmed_transactions(block.transactions[1:])
             message = {"host": self.HOST, "type": MessageType.BLOCK_HEADER.value, "data": block.block_header.to_json()}
             Queue.enqueue(message)
     return
예제 #2
0
def post_to_inbox():
    body = request.json
    # TODO: validate sender really is who they say they are using signature
    host = request.environ.get('HTTP_X_FORWARDED_FOR') or request.environ.get(
        'REMOTE_ADDR')
    msg_type = body.get('type')
    if MessageType(msg_type) in MessageType:
        msg = {'host': host, 'type': msg_type, 'data': body.get('data')}
        Queue.enqueue(msg)
        response.status = 200
        return json.dumps({'success': True})
    response.status = 400
    return json.dumps({'success': False})
예제 #3
0
 def worker(self):
     while True:
         msg = Queue.dequeue()
         sender = msg.get('host', '')
         msg_type = MessageType(msg.get('type'))
         data = msg.get('data')
         if msg_type == MessageType.BLOCK_HEADER:
             block_header = BlockHeader.from_dict(json.loads(data))
             if sender == self.HOST:
                 self.api_client.broadcast_block_inv([block_header.hash],
                                                     self.HOST)
             else:
                 self.__process_block_header(block_header, sender)
             continue
         elif msg_type == MessageType.UNCONFIRMED_TRANSACTION:
             unconfirmed_transaction = Transaction.from_dict(data)
             if sender == self.HOST:
                 # transaction already validated before being enqueued
                 valid = True
             else:
                 valid = self.validator.validate_transaction(
                     unconfirmed_transaction)
             if valid:
                 self.api_client.broadcast_unconfirmed_transaction_inv(
                     [unconfirmed_transaction.tx_hash], self.HOST)
             continue
         elif msg_type == MessageType.BLOCK_INV:
             missing_block_headers = []
             for block_hash in data:
                 # aggregate unknown block header hashes
                 block_header = self.blockchain.get_block_header_by_hash(
                     block_hash)
                 if block_header is None:
                     missing_block_headers.append(block_hash)
             for block_hash in missing_block_headers:
                 # We don't have these blocks in our database.  Fetch them from the sender
                 block_header = self.api_client.request_block_header(
                     sender, self.FULL_NODE_PORT, block_hash=block_hash)
                 self.__process_block_header(block_header, sender)
             continue
         elif msg_type == MessageType.UNCONFIRMED_TRANSACTION_INV:
             missing_transactions = []
             new_unconfirmed_transactions = []
             for tx_hash in data:
                 # skip known unconfirmed transactions
                 transaction = self.blockchain.get_transaction_by_hash(
                     tx_hash)
                 if transaction:
                     continue
                 unconfirmed_transaction = self.mempool.get_unconfirmed_transaction(
                     tx_hash)
                 if unconfirmed_transaction:
                     continue
                 missing_transactions.append(tx_hash)
             for tx_hash in missing_transactions:
                 # retrieve unknown unconfirmed transactions
                 transaction = self.api_client.request_transaction(
                     sender, self.FULL_NODE_PORT, tx_hash)
                 valid = self.validator.validate_transaction(transaction)
                 if valid:
                     # validate and store retrieved unconfirmed transactions
                     self.mempool.push_unconfirmed_transaction(transaction)
                     new_unconfirmed_transactions.append(tx_hash)
             if len(new_unconfirmed_transactions):
                 # broadcast new unconfirmed transactions
                 self.api_client.broadcast_unconfirmed_transaction_inv(
                     new_unconfirmed_transactions)
             continue
         else:
             logger.warn("Encountered unknown message type %s from %s",
                         msg_type, sender)
             pass