Пример #1
0
    def _render_GET_thread(self, request: Request) -> bytes:
        """ GET request /graphviz/full.{format}
            Returns the rendered graph file
        """
        set_cors(request, 'GET')

        tx_storage = self.manager.tx_storage

        graphviz = GraphvizVisualizer(tx_storage)
        if b'weight' in request.args:
            graphviz.show_weight = self.parse_bool_arg(
                request.args[b'weight'][0].decode('utf-8'))
        if b'acc_weight' in request.args:
            graphviz.show_acc_weight = self.parse_bool_arg(
                request.args[b'acc_weight'][0].decode('utf-8'))
        if b'verifications' in request.args:
            graphviz.include_verifications = self.parse_bool_arg(
                request.args[b'verifications'][0].decode('utf-8'))
        if b'funds' in request.args:
            graphviz.include_funds = self.parse_bool_arg(
                request.args[b'funds'][0].decode('utf-8'))
        if b'only_blocks' in request.args:
            graphviz.only_blocks = self.parse_bool_arg(
                request.args[b'only_blocks'][0].decode('utf-8'))
        dot = graphviz.dot(format=self.format.dot)

        request.setHeader(b'content-type', self.format.content_type)
        if self.format is FileFormat.DOT:
            return str(dot).encode('utf-8')
        return dot.pipe()
Пример #2
0
    def on_new_tx(self, key: HathorEvents, args: EventArguments) -> None:
        """ This method is called every change in the DAG. It saves a new snapshot in disk.
        """
        if not self.is_running:
            return

        n = self.sequence

        tx_storage = self.manager.tx_storage

        graphviz = GraphvizVisualizer(tx_storage)
        graphviz.include_verifications = True
        graphviz.include_funds = True
        dot = graphviz.dot(format=self.format)
        dot.render(os.path.join(self.dirname, 'seq_{:010d}'.format(n)))

        self.sequence += 1
Пример #3
0
    def _render_GET_thread(self, request: Request) -> bytes:
        """ GET request /graphviz/
            Expects 'format' parameter in request to set the content-type of the graph
            Format options are 'pdf', 'png' and 'jpg'. Default format is 'pdf'
            Returns the file
        """
        set_cors(request, 'GET')

        contenttype = {
            'pdf': b'application/pdf',
            'png': b'image/png',
            'jpg': b'image/jpeg',
            'dot': b'application/dot',
        }

        dotformat = 'pdf'
        if b'format' in request.args:
            dotformat = request.args[b'format'][0].decode('utf-8')

        tx_storage = self.manager.tx_storage

        if b'tx' in request.args:
            # Getting tx neightborhood
            tx_hex = request.args[b'tx'][0].decode('utf-8')
            success, message = validate_tx_hash(tx_hex, tx_storage)
            if not success:
                return json.dumps({
                    'success': False,
                    'message': message
                },
                                  indent=4).encode('utf-8')
            else:
                graph_type = request.args[b'graph_type'][0].decode('utf-8')
                max_level = int(request.args[b'max_level'][0])
                if max_level > settings.MAX_GRAPH_LEVEL:
                    return json.dumps(
                        {
                            'success':
                            False,
                            'message':
                            'Graph max level is {}'.format(
                                settings.MAX_GRAPH_LEVEL)
                        },
                        indent=4).encode('utf-8')
                tx = tx_storage.get_transaction(bytes.fromhex(tx_hex))

                graphviz = GraphvizVisualizer(tx_storage)
                dot = graphviz.tx_neighborhood(tx,
                                               format=dotformat,
                                               max_level=max_level,
                                               graph_type=graph_type)

        else:
            weight = False
            if b'weight' in request.args:
                weight = self.parseBoolArg(
                    request.args[b'weight'][0].decode('utf-8'))

            acc_weight = False
            if b'acc_weight' in request.args:
                acc_weight = self.parseBoolArg(
                    request.args[b'acc_weight'][0].decode('utf-8'))

            include_verifications = True
            if b'verifications' in request.args:
                include_verifications = self.parseBoolArg(
                    request.args[b'verifications'][0].decode('utf-8'))

            include_funds = False
            if b'funds' in request.args:
                include_funds = self.parseBoolArg(
                    request.args[b'funds'][0].decode('utf-8'))

            only_blocks = False
            if b'only_blocks' in request.args:
                only_blocks = self.parseBoolArg(
                    request.args[b'only_blocks'][0].decode('utf-8'))

            graphviz = GraphvizVisualizer(tx_storage)
            graphviz.include_verifications = include_verifications
            graphviz.include_funds = include_funds
            graphviz.only_blocks = only_blocks
            graphviz.show_weight = weight
            graphviz.show_acc_weight = acc_weight
            dot = graphviz.dot(format=dotformat)

        if dotformat == 'dot':
            request.setHeader(b'content-type', contenttype[dotformat])
            return str(dot).encode('utf-8')

        request.setHeader(b'content-type', contenttype[dotformat])
        return dot.pipe()
Пример #4
0
    def test_double_spending_attempt_1(self):
        manager = self.manager1

        add_new_blocks(manager, 5, advance_clock=15)
        add_blocks_unlock_reward(manager)

        from hathor.crypto.util import decode_address
        from hathor.graphviz import GraphvizVisualizer
        from hathor.transaction import Transaction
        from hathor.wallet.base_wallet import WalletInputInfo, WalletOutputInfo

        graphviz = GraphvizVisualizer(manager.tx_storage,
                                      include_verifications=True,
                                      include_funds=True)

        addr = manager.wallet.get_unused_address()
        outputs = []
        outputs.append(WalletOutputInfo(decode_address(addr), 1, None))
        outputs.append(WalletOutputInfo(decode_address(addr), 1000, None))
        outputs.append(
            WalletOutputInfo(decode_address(addr), 6400 - 1001, None))
        tx_fund0 = manager.wallet.prepare_transaction_compute_inputs(
            Transaction, outputs, manager.tx_storage)
        tx_fund0.weight = 1
        tx_fund0.parents = manager.get_new_tx_parents()
        tx_fund0.timestamp = int(self.clock.seconds())
        tx_fund0.resolve()
        self.assertTrue(manager.propagate_tx(tx_fund0))

        def do_step(tx_fund):
            inputs = [
                WalletInputInfo(tx_fund.hash, 0,
                                manager.wallet.get_private_key(addr))
            ]
            outputs = [WalletOutputInfo(decode_address(addr), 1, None)]
            tx1 = manager.wallet.prepare_transaction(Transaction, inputs,
                                                     outputs,
                                                     tx_fund.timestamp + 1)
            tx1.weight = 1
            tx1.parents = manager.get_new_tx_parents(tx1.timestamp)
            tx1.resolve()
            self.assertTrue(manager.propagate_tx(tx1))

            inputs = []
            inputs.append(
                WalletInputInfo(tx1.hash, 0,
                                manager.wallet.get_private_key(addr)))
            inputs.append(
                WalletInputInfo(tx_fund.hash, 1,
                                manager.wallet.get_private_key(addr)))
            outputs = [
                WalletOutputInfo(decode_address(addr),
                                 tx_fund.outputs[1].value + 1, None)
            ]
            tx2 = manager.wallet.prepare_transaction(Transaction, inputs,
                                                     outputs,
                                                     tx1.timestamp + 1)
            tx2.weight = 1
            tx2.parents = manager.get_new_tx_parents(tx2.timestamp)
            tx2.resolve()
            self.assertTrue(manager.propagate_tx(tx2))

            inputs = [
                WalletInputInfo(tx_fund.hash, 0,
                                manager.wallet.get_private_key(addr))
            ]
            outputs = [WalletOutputInfo(decode_address(addr), 1, None)]
            tx3 = manager.wallet.prepare_transaction(Transaction, inputs,
                                                     outputs,
                                                     tx_fund.timestamp + 1)
            tx3.weight = tx1.weight + tx2.weight + 0.1
            tx3.parents = manager.get_new_tx_parents(tx3.timestamp)
            tx3.resolve()
            self.assertTrue(manager.propagate_tx(tx3))

            inputs = [
                WalletInputInfo(tx_fund.hash, 1,
                                manager.wallet.get_private_key(addr))
            ]
            outputs = [
                WalletOutputInfo(decode_address(addr),
                                 tx_fund.outputs[1].value, None)
            ]
            tx4 = manager.wallet.prepare_transaction(Transaction, inputs,
                                                     outputs,
                                                     tx_fund.timestamp + 1)
            tx4.weight = 1
            tx4.parents = manager.get_new_tx_parents(tx4.timestamp)
            tx4.resolve()
            self.assertTrue(manager.propagate_tx(tx4))

            inputs = []
            inputs.append(
                WalletInputInfo(tx2.hash, 0,
                                manager.wallet.get_private_key(addr)))
            inputs.append(
                WalletInputInfo(tx4.hash, 0,
                                manager.wallet.get_private_key(addr)))
            outputs = []
            outputs.append(WalletOutputInfo(decode_address(addr), 1, None))
            outputs.append(
                WalletOutputInfo(decode_address(addr),
                                 2 * tx_fund.outputs[1].value, None))
            tx5 = manager.wallet.prepare_transaction(Transaction, inputs,
                                                     outputs,
                                                     tx2.timestamp + 1)
            tx5.weight = tx3.weight - tx1.weight + 0.1
            tx5.parents = [tx2.hash, tx4.hash]
            tx5.resolve()
            self.assertTrue(manager.propagate_tx(tx5))
            return tx5

        tx = tx_fund0
        N = 10
        for _ in range(N):
            tx = do_step(tx)

        block = add_new_block(manager)
        self.assertIn(tx.hash, block.parents)

        dot = graphviz.dot()
        dot.render('dot0')

        meta = tx.get_metadata()
        self.assertIsNone(meta.conflict_with)
        self.assertIsNone(meta.voided_by)
        self.assertEqual(tx.outputs[1].value, 1000 * 2**N)

        self.assertConsensusValid(manager)