Repository: Chia-Network/chia-blockchain
File: chia/full_node/full_node.py (Python)

Code before:

        async with self.blockchain.priority_mutex.acquire(priority=BlockchainMutexPriority.low):
            if self.mempool_manager.get_spendbundle(spend_name) is not None:
                self.mempool_manager.remove_seen(spend_name)
                return MempoolInclusionStatus.SUCCESS, None
            if self.mempool_manager.peak is None:
                return MempoolInclusionStatus.FAILED, Err.MEMPOOL_NOT_INITIALIZED
            info = await self.mempool_manager.add_spend_bundle(
                transaction, cost_result, spend_name, self.mempool_manager.peak.height
            )
            status = info.status
            error = info.error
        if status == MempoolInclusionStatus.SUCCESS:
            self.log.debug(
                f"Added transaction to mempool: {spend_name} mempool size: "
                f"{self.mempool_manager.mempool.total_mempool_cost()} normalized "
                f"{self.mempool_manager.mempool.total_mempool_cost() / 5000000}"
            )

            mempool_item = self.mempool_manager.get_mempool_item(spend_name)
            assert mempool_item is not None
            # Now that we validated this transaction, check what fees and
            # costs the peers have advertised for it.
            for peer_id, entry in peers_with_tx.items():
                # Some older nodes have a specific cost mismatch due to the byte
                # size cost and execution cost of the wrapper quote.
                tolerated_diff = QUOTE_BYTES * self.constants.COST_PER_BYTE + QUOTE_EXECUTION_COST
                cost_diff = entry.advertised_cost - mempool_item.cost
                acceptable_cost_diffs = cost_diff in {0, tolerated_diff}
                if entry.advertised_fee == mempool_item.fee and acceptable_cost_diffs:
                    continue
                self.log.warning(
                    f"Banning peer {peer_id}. Sent us a new tx {spend_name} with mismatch "
                    f"on cost {entry.advertised_cost} vs validation cost {mempool_item.cost} and/or "
                    f"fee {entry.advertised_fee} vs {mempool_item.fee}."
                )
                peer = self.server.all_connections.get(peer_id)
                if peer is None:
                    self.server.ban_peer(entry.peer_host, CONSENSUS_ERROR_BAN_SECONDS)
                else:
                    await peer.close(CONSENSUS_ERROR_BAN_SECONDS)
            # Only broadcast successful transactions, not pending ones. Otherwise it's a DOS
            # vector.
            await self.broadcast_removed_tx(info.removals)
            await self.broadcast_added_tx(mempool_item, current_peer=peer)

            if self.simulator_transaction_callback is not None:  # callback
                await self.simulator_transaction_callback(spend_name)

        else:
            self.mempool_manager.remove_seen(spend_name)

Review comment (suggestion):
I think we should be specific.
```suggestion
                # The 2.4.3 full node, and earlier, computed the cost slightly differently.
                # They did not include byte-cost or execution cost of the quote for the puzzle.
```

Code after:

        async with self.blockchain.priority_mutex.acquire(priority=BlockchainMutexPriority.low):
            if self.mempool_manager.get_spendbundle(spend_name) is not None:
                self.mempool_manager.remove_seen(spend_name)
                return MempoolInclusionStatus.SUCCESS, None
            if self.mempool_manager.peak is None:
                return MempoolInclusionStatus.FAILED, Err.MEMPOOL_NOT_INITIALIZED
            info = await self.mempool_manager.add_spend_bundle(
                transaction, cost_result, spend_name, self.mempool_manager.peak.height
            )
            status = info.status
            error = info.error
        if status == MempoolInclusionStatus.SUCCESS:
            self.log.debug(
                f"Added transaction to mempool: {spend_name} mempool size: "
                f"{self.mempool_manager.mempool.total_mempool_cost()} normalized "
                f"{self.mempool_manager.mempool.total_mempool_cost() / 5000000}"
            )

            mempool_item = self.mempool_manager.get_mempool_item(spend_name)
            assert mempool_item is not None
            # Now that we validated this transaction, check what fees and
            # costs the peers have advertised for it.
            for peer_id, entry in peers_with_tx.items():
                # Older nodes (2.4.3 and earlier) compute the cost slightly
                # differently. They include the byte cost and execution cost of
                # the quote for the puzzle.
                tolerated_diff = QUOTE_BYTES * self.constants.COST_PER_BYTE + QUOTE_EXECUTION_COST
                if entry.advertised_fee == mempool_item.fee and (
                    entry.advertised_cost == mempool_item.cost
                    or entry.advertised_cost == mempool_item.cost + tolerated_diff
                ):
                    continue
                self.log.warning(
                    f"Banning peer {peer_id}. Sent us a new tx {spend_name} with mismatch "
                    f"on cost {entry.advertised_cost} vs validation cost {mempool_item.cost} and/or "
                    f"fee {entry.advertised_fee} vs {mempool_item.fee}."
                )
                peer = self.server.all_connections.get(peer_id)
                if peer is None:
                    self.server.ban_peer(entry.peer_host, CONSENSUS_ERROR_BAN_SECONDS)
                else:
                    await peer.close(CONSENSUS_ERROR_BAN_SECONDS)
            # Only broadcast successful transactions, not pending ones. Otherwise it's a DOS
            # vector.
            await self.broadcast_removed_tx(info.removals)
            await self.broadcast_added_tx(mempool_item, current_peer=peer)

            if self.simulator_transaction_callback is not None:  # callback
                await self.simulator_transaction_callback(spend_name)