Ejemplo n.º 1
0
 def setUp(self):
     self.mock_blockchain = Mock(Blockchain)
     self.mock_mempool = Mock(Mempool)
     with patch.object(Blockchain, "__init__", return_value=None) as patched_blockchain, \
         patch.object(Mempool, "__init__", return_value=None) as patched_mempool:
         self.subject = Validator()
     self.subject.blockchain = self.mock_blockchain
     self.subject.mempool = self.mock_mempool
Ejemplo n.º 2
0
def post_transactions():
    mempool = Mempool()
    validator = Validator()
    body = request.json
    transaction = Transaction.from_dict(body['transaction'])
    if transaction.tx_hash != body['transaction']['tx_hash']:
        logger.info("Invalid transaction hash: {} should be {}".format(
            body['transaction']['tx_hash'], transaction.tx_hash))
        response.status = 406
        return json.dumps({'message': 'Invalid transaction hash'})
    if mempool.get_unconfirmed_transaction(transaction.tx_hash) is None \
            and validator.validate_transaction(transaction) \
            and mempool.push_unconfirmed_transaction(transaction):
        response.status = 200
        return json.dumps({'success': True, 'tx_hash': transaction.tx_hash})
    response.status = 406
    return json.dumps({'success': False, 'reason': 'Invalid transaction'})
Ejemplo n.º 3
0
def full():
    helptext = '''
        Available commands:
        ===================
        balance <public key (optional)>
        history <public key (optional)>
        getnodes
        getblock <index (optional)>
        getblocks <start index (optional)> <stop index (optional)>
        mempoolcount
        getmempool
        getunconfirmedtx <tx hash>
        mine <start | stop>
        quit or exit
    '''
    peers = Peers()
    api_client = ApiClient(peers)
    blockchain = Blockchain()
    mempool = Mempool()
    validator = Validator()
    ip = config['user']['ip']
    public_key = config['user']['public_key']
    if ip is None or public_key is None:
        print("\n\npublic key and IP must be provided.\n\n")
        sys.exit(1)
    else:
        print("\n\nfull node starting...\n\n")
        full_node = FullNode(peers, api_client, blockchain, mempool, validator)
        full_node.start()
        miner = Miner(blockchain, mempool)
        mining = False

    while True:
        cmd = input("{} ({}) full node > ".format(
            config['network']['name'], config['network']['ticker_symbol']))
        cmd_split = cmd.split()
        try:
            if cmd_split[0] == "balance":
                if len(cmd_split) == 2:
                    url = full_node.BALANCE_URL.format(
                        "localhost", full_node.FULL_NODE_PORT, cmd_split[1])
                else:
                    url = full_node.BALANCE_URL.format(
                        "localhost", full_node.FULL_NODE_PORT, public_key)
                response = requests.get(url)
                print(response.json())
            elif cmd_split[0] == "history":
                if len(cmd_split) == 2:
                    url = full_node.TRANSACTION_HISTORY_URL.format(
                        "localhost", full_node.FULL_NODE_PORT, cmd_split[1])
                    response = requests.get(url)
                else:
                    url = full_node.TRANSACTION_HISTORY_URL.format(
                        "localhost", full_node.FULL_NODE_PORT, public_key)
                    response = requests.get(url)
                print(response.json())
            elif cmd_split[0] == "getnodes":
                url = full_node.NODES_URL.format("localhost",
                                                 full_node.FULL_NODE_PORT)
                response = requests.get(url)
                print(response.json())
            elif cmd_split[0] == "getblock":
                if len(cmd_split) == 2:
                    url = full_node.BLOCKS_URL.format("localhost",
                                                      full_node.FULL_NODE_PORT,
                                                      cmd_split[1])
                else:
                    url = full_node.BLOCKS_URL.format("localhost",
                                                      full_node.FULL_NODE_PORT,
                                                      "latest")
                response = requests.get(url)
                print(response.json())
            elif cmd_split[0] == "getblocks":
                if len(cmd_split) == 3:
                    url = full_node.BLOCKS_INV_URL.format(
                        "localhost", full_node.FULL_NODE_PORT, cmd_split[1],
                        cmd_split[2])
                else:
                    url = full_node.BLOCKS_URL.format("localhost",
                                                      full_node.FULL_NODE_PORT,
                                                      "")
                response = requests.get(url)
                print(response.json())
            elif cmd_split[0] == "mempoolcount":
                url = full_node.UNCONFIRMED_TRANSACTIONS_URL.format(
                    "localhost", full_node.FULL_NODE_PORT, "count")
                response = requests.get(url)
                print(response.json())
            elif cmd_split[0] == "getmempool":
                url = full_node.UNCONFIRMED_TRANSACTIONS_URL.format(
                    "localhost", full_node.FULL_NODE_PORT, "")
                response = requests.get(url)
                print(response.json())
            elif cmd_split[0] == "getunconfirmedtx":
                if len(cmd_split) == 2:
                    url = full_node.UNCONFIRMED_TRANSACTIONS_URL.format(
                        "localhost", full_node.FULL_NODE_PORT, cmd_split[1])
                    response = requests.get(url)
                    print(response.json())
                else:
                    print("\nRequires tx hash\n")
            elif cmd_split[0] == "mine":
                if len(cmd_split) == 2:
                    if cmd_split[1] == "start":
                        if mining is False:
                            print("\n\nminer starting...\n\n")
                            mining = True
                            miner.start()
                    elif cmd_split[1] == "stop":
                        if mining is True:
                            print("\n\nminer shutting down...\n\n")
                            mining = False
                            miner.shutdown()
                    else:
                        print("\nRequires: start | stop")
                else:
                    print("\nRequires: start | stop")
            elif cmd_split[0] in ("quit", "exit"):
                if mining is True:
                    print("\n\nminer shutting down...\n\n")
                    miner.shutdown()
                    time.sleep(2)
                full_node.shutdown()
                time.sleep(2)
                sys.exit(0)
            else:  # help
                print(helptext)
        except IndexError:
            pass
Ejemplo n.º 4
0
class TestValidator(TestCase):
    def setUp(self):
        self.mock_blockchain = Mock(Blockchain)
        self.mock_mempool = Mock(Mempool)
        with patch.object(Blockchain, "__init__", return_value=None) as patched_blockchain, \
            patch.object(Mempool, "__init__", return_value=None) as patched_mempool:
            self.subject = Validator()
        self.subject.blockchain = self.mock_blockchain
        self.subject.mempool = self.mock_mempool

    def test_check_hash_and_hash_pattern_When_valid_Returns(self):
        self.mock_blockchain.calculate_hash_difficulty.return_value = 4
        mock_block = Mock(Block)
        mock_block_header = Mock(BlockHeader)
        mock_block_header.hash = "0000FFFFFFF999999999999"
        mock_block.block_header = mock_block_header

        response = self.subject.check_hash_and_hash_pattern(mock_block)

    def test_check_height_and_previous_hash_When_valid_Returns(self):
        mock_previous_block_header = Mock(BlockHeader)
        self.mock_blockchain.get_block_header_by_hash.return_value = (
            mock_previous_block_header, 0, 15)
        mock_block_header = Mock(BlockHeader)
        mock_block_header.previous_hash = "0000FFFFFFF999999999999"
        mock_block = Mock(Block)
        mock_block.height = 16
        mock_block.block_header = mock_block_header

        response = self.subject.check_height_and_previous_hash(mock_block)

    def test_check_block_reward(self):
        mock_transaction = Mock(Transaction)
        mock_transaction.tx_type = TransactionType.STANDARD
        mock_transaction.fee = .05
        mock_coinbase_transaction = Mock(Transaction)
        mock_coinbase_transaction.tx_type = TransactionType.COINBASE
        mock_coinbase_transaction.amount = 50.05
        mock_coinbase_transaction.source = "0"
        mock_block = Mock(Block)
        mock_block.height = 16
        mock_block.transactions = [mock_coinbase_transaction, mock_transaction]
        self.mock_blockchain.get_reward.return_value = 50

        response = self.subject.check_block_reward(mock_block)
        self.assertTrue(response)

    def test_validate_block_header(self):
        self.mock_blockchain.get_block_header_by_hash.side_effect = [
            None, (Mock(), 0, 15)
        ]
        self.mock_blockchain.calculate_hash_difficulty.return_value = 4
        mock_block_header = Mock(BlockHeader)
        mock_block_header.version = config['network']['version']
        mock_block_header.merkle_root = "0123456789ABCDEF"
        mock_block_header.hash_difficulty = 4
        mock_block_header.previous_hash = "0000123412341234"

        with patch(
                'crankycoin.services.validator.Validator.calculate_merkle_root',
                return_value="0123456789ABCDEF"
        ) as patched_calculate_merkle_root:
            response = self.subject.validate_block_header(
                mock_block_header, [])

        self.assertTrue(response)

    def test_validate_block(self):
        mock_block_header = Mock(BlockHeader)
        mock_block_header.merkle_root = "0123456789ABCDEF"
        mock_block = Mock(Block)
        mock_block.block_header = mock_block_header

        with patch(
                'crankycoin.services.validator.Validator.check_block_reward',
                return_value=True) as patched_check_block_reward:
            response = self.subject.validate_block(mock_block,
                                                   "0123456789ABCDEF")

        self.assertTrue(response)

    def test_validate_block_transactions_inv(self):
        mock_transaction = Mock(Transaction)
        self.mock_blockchain.find_duplicate_transactions.return_value = False
        self.mock_mempool.get_unconfirmed_transaction.side_effect = [
            None, mock_transaction
        ]

        response = self.subject.validate_block_transactions_inv(
            ['tx_hash_one', 'tx_hash_two'])

        self.assertIn('tx_hash_one', response[1])
        self.assertIn(mock_transaction, response[0])

    def test_validate_transaction(self):
        self.mock_blockchain.find_duplicate_transactions.return_value = False
        self.mock_blockchain.get_balance.return_value = 100
        mock_transaction = Mock(Transaction)
        mock_transaction.tx_hash = "0123456789ABCDEF"
        mock_transaction.verify.return_value = True
        mock_transaction.source = "03dd1e00000000000000000"
        mock_transaction.amount = 95
        mock_transaction.fee = 5

        response = self.subject.validate_transaction(mock_transaction)

        self.assertTrue(response)

    @skip
    def test_calculate_merkle_root(self):
        raise NotImplementedError