diff --git a/hathor/builder/builder.py b/hathor/builder/builder.py
index d86d85ace..f12764594 100644
--- a/hathor/builder/builder.py
+++ b/hathor/builder/builder.py
@@ -30,6 +30,7 @@
 from hathor.feature_activation.feature_service import FeatureService
 from hathor.indexes import IndexesManager, MemoryIndexesManager, RocksDBIndexesManager
 from hathor.manager import HathorManager
+from hathor.mining.cpu_mining_service import CpuMiningService
 from hathor.p2p.manager import ConnectionsManager
 from hathor.p2p.peer_id import PeerId
 from hathor.pubsub import PubSubManager
@@ -104,6 +105,7 @@ def __init__(self) -> None:
         self._bit_signaling_service: Optional[BitSignalingService] = None
 
         self._daa: Optional[DifficultyAdjustmentAlgorithm] = None
+        self._cpu_mining_service: Optional[CpuMiningService] = None
 
         self._vertex_verifiers: Optional[VertexVerifiers] = None
         self._verification_service: Optional[VerificationService] = None
@@ -166,6 +168,7 @@ def build(self) -> BuildArtifacts:
         bit_signaling_service = self._get_or_create_bit_signaling_service(tx_storage)
         verification_service = self._get_or_create_verification_service()
         daa = self._get_or_create_daa()
+        cpu_mining_service = self._get_or_create_cpu_mining_service()
 
         if self._enable_address_index:
             indexes.enable_address_index(pubsub)
@@ -203,6 +206,7 @@ def build(self) -> BuildArtifacts:
             feature_service=feature_service,
             bit_signaling_service=bit_signaling_service,
             verification_service=verification_service,
+            cpu_mining_service=cpu_mining_service,
             **kwargs
         )
 
@@ -458,6 +462,12 @@ def _get_or_create_daa(self) -> DifficultyAdjustmentAlgorithm:
 
         return self._daa
 
+    def _get_or_create_cpu_mining_service(self) -> CpuMiningService:
+        if self._cpu_mining_service is None:
+            self._cpu_mining_service = CpuMiningService()
+
+        return self._cpu_mining_service
+
     def use_memory(self) -> 'Builder':
         self.check_if_can_modify()
         self._storage_type = StorageType.MEMORY
@@ -565,6 +575,11 @@ def set_daa(self, daa: DifficultyAdjustmentAlgorithm) -> 'Builder':
         self._daa = daa
         return self
 
+    def set_cpu_mining_service(self, cpu_mining_service: CpuMiningService) -> 'Builder':
+        self.check_if_can_modify()
+        self._cpu_mining_service = cpu_mining_service
+        return self
+
     def set_reactor(self, reactor: Reactor) -> 'Builder':
         self.check_if_can_modify()
         self._reactor = reactor
diff --git a/hathor/builder/cli_builder.py b/hathor/builder/cli_builder.py
index 58336af07..5a4a80c7c 100644
--- a/hathor/builder/cli_builder.py
+++ b/hathor/builder/cli_builder.py
@@ -30,6 +30,7 @@
 from hathor.feature_activation.feature_service import FeatureService
 from hathor.indexes import IndexesManager, MemoryIndexesManager, RocksDBIndexesManager
 from hathor.manager import HathorManager
+from hathor.mining.cpu_mining_service import CpuMiningService
 from hathor.p2p.manager import ConnectionsManager
 from hathor.p2p.peer_id import PeerId
 from hathor.p2p.utils import discover_hostname, get_genesis_short_hash
@@ -214,6 +215,8 @@ def create_manager(self, reactor: Reactor) -> HathorManager:
         vertex_verifiers = VertexVerifiers.create_defaults(settings=settings, daa=daa)
         verification_service = VerificationService(verifiers=vertex_verifiers)
 
+        cpu_mining_service = CpuMiningService()
+
         p2p_manager = ConnectionsManager(
             reactor,
             network=network,
@@ -247,6 +250,7 @@ def create_manager(self, reactor: Reactor) -> HathorManager:
             feature_service=self.feature_service,
             bit_signaling_service=bit_signaling_service,
             verification_service=verification_service,
+            cpu_mining_service=cpu_mining_service
         )
 
         p2p_manager.set_manager(self.manager)
diff --git a/hathor/cli/mining.py b/hathor/cli/mining.py
index 7b723fc44..a050e0af8 100644
--- a/hathor/cli/mining.py
+++ b/hathor/cli/mining.py
@@ -26,6 +26,7 @@
 
 from hathor.conf.get_settings import get_settings
 from hathor.daa import DifficultyAdjustmentAlgorithm
+from hathor.mining.cpu_mining_service import CpuMiningService
 from hathor.verification.block_verifier import BlockVerifier
 
 _SLEEP_ON_ERROR_SECONDS = 5
@@ -39,7 +40,7 @@ def signal_handler(sig, frame):
 def worker(q_in, q_out):
     signal.signal(signal.SIGINT, signal_handler)
     block, start, end, sleep_seconds = q_in.get()
-    block.start_mining(start, end, sleep_seconds=sleep_seconds)
+    CpuMiningService().start_mining(block, start=start, end=end, sleep_seconds=sleep_seconds)
     q_out.put(block)
 
 
diff --git a/hathor/cli/multisig_spend.py b/hathor/cli/multisig_spend.py
index 24281f233..cd9600097 100644
--- a/hathor/cli/multisig_spend.py
+++ b/hathor/cli/multisig_spend.py
@@ -14,6 +14,8 @@
 
 from argparse import ArgumentParser, Namespace
 
+from hathor.mining.cpu_mining_service import CpuMiningService
+
 
 def create_parser() -> ArgumentParser:
     from hathor.cli.util import create_parser
@@ -36,7 +38,7 @@ def execute(args: Namespace) -> None:
     input_data = MultiSig.create_input_data(bytes.fromhex(args.redeem_script), signatures)
     tx.inputs[0].data = input_data
 
-    tx.resolve()
+    CpuMiningService().resolve(tx)
     print('Transaction after POW: ', tx.get_struct().hex())
 
 
diff --git a/hathor/cli/twin_tx.py b/hathor/cli/twin_tx.py
index a57a2c8f6..f55274368 100644
--- a/hathor/cli/twin_tx.py
+++ b/hathor/cli/twin_tx.py
@@ -19,6 +19,8 @@
 
 import requests
 
+from hathor.mining.cpu_mining_service import CpuMiningService
+
 
 def create_parser() -> ArgumentParser:
     from hathor.cli.util import create_parser
@@ -89,7 +91,7 @@ def execute(args: Namespace) -> None:
         if args.weight:
             twin.weight = args.weight
 
-        twin.resolve()
+        CpuMiningService().resolve(twin)
         if args.human:
             print(twin.to_json())
         else:
diff --git a/hathor/manager.py b/hathor/manager.py
index 3c0dfa0e3..f753ce782 100644
--- a/hathor/manager.py
+++ b/hathor/manager.py
@@ -43,6 +43,7 @@
 from hathor.feature_activation.feature import Feature
 from hathor.feature_activation.feature_service import FeatureService
 from hathor.mining import BlockTemplate, BlockTemplates
+from hathor.mining.cpu_mining_service import CpuMiningService
 from hathor.p2p.manager import ConnectionsManager
 from hathor.p2p.peer_id import PeerId
 from hathor.p2p.protocol import HathorProtocol
@@ -97,6 +98,7 @@ def __init__(self,
                  feature_service: FeatureService,
                  bit_signaling_service: BitSignalingService,
                  verification_service: VerificationService,
+                 cpu_mining_service: CpuMiningService,
                  network: str,
                  hostname: Optional[str] = None,
                  wallet: Optional[BaseWallet] = None,
@@ -175,6 +177,7 @@ def __init__(self,
         self._feature_service = feature_service
         self._bit_signaling_service = bit_signaling_service
         self.verification_service = verification_service
+        self.cpu_mining_service = cpu_mining_service
 
         self.consensus_algorithm = consensus_algorithm
 
diff --git a/hathor/mining/cpu_mining_service.py b/hathor/mining/cpu_mining_service.py
new file mode 100644
index 000000000..fb84bb405
--- /dev/null
+++ b/hathor/mining/cpu_mining_service.py
@@ -0,0 +1,91 @@
+#  Copyright 2023 Hathor Labs
+#
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+
+import time
+from typing import Callable, Optional
+
+from hathor.transaction import BaseTransaction
+from hathor.transaction.token_creation_tx import TokenCreationTransaction
+from hathor.types import VertexId
+
+MAX_NONCE = 2**32
+
+
+class CpuMiningService:
+    def resolve(self, vertex: BaseTransaction, *, update_time: bool = False) -> bool:
+        """Run a CPU mining looking for the nonce that solves the proof-of-work
+
+        The `vertex.weight` must be set before calling this method.
+
+        :param update_time: update timestamp every 2 seconds
+        :return: True if a solution was found
+        :rtype: bool
+        """
+        hash_bytes = self.start_mining(vertex, update_time=update_time)
+
+        if hash_bytes:
+            vertex.hash = hash_bytes
+            metadata = getattr(vertex, '_metadata', None)
+            if metadata is not None and metadata.hash is not None:
+                metadata.hash = hash_bytes
+
+            if isinstance(vertex, TokenCreationTransaction):
+                vertex.tokens = [vertex.hash]
+
+            return True
+        else:
+            return False
+
+    @staticmethod
+    def start_mining(
+        vertex: BaseTransaction,
+        *,
+        start: int = 0,
+        end: int = MAX_NONCE,
+        sleep_seconds: float = 0.0,
+        update_time: bool = True,
+        should_stop: Callable[[], bool] = lambda: False
+    ) -> Optional[VertexId]:
+        """Starts mining until it solves the problem, i.e., finds the nonce that satisfies the conditions
+
+        :param start: beginning of the search interval
+        :param end: end of the search interval
+        :param sleep_seconds: the number of seconds it will sleep after each attempt
+        :param update_time: update timestamp every 2 seconds
+        :return The hash of the solved PoW or None when it is not found
+        """
+        pow_part1 = vertex.calculate_hash1()
+        target = vertex.get_target()
+        vertex.nonce = start
+        last_time = time.time()
+        while vertex.nonce < end:
+            if update_time:
+                now = time.time()
+                if now - last_time > 2:
+                    if should_stop():
+                        return None
+                    vertex.timestamp = int(now)
+                    pow_part1 = vertex.calculate_hash1()
+                    last_time = now
+                    vertex.nonce = start
+
+            result = vertex.calculate_hash2(pow_part1.copy())
+            if int(result.hex(), vertex.HEX_BASE) < target:
+                return result
+            vertex.nonce += 1
+            if sleep_seconds > 0:
+                time.sleep(sleep_seconds)
+                if should_stop():
+                    return None
+        return None
diff --git a/hathor/simulator/verification.py b/hathor/simulator/patches.py
similarity index 76%
rename from hathor/simulator/verification.py
rename to hathor/simulator/patches.py
index 849a9a0e9..1f9fdd1d3 100644
--- a/hathor/simulator/verification.py
+++ b/hathor/simulator/patches.py
@@ -16,6 +16,7 @@
 
 from structlog import get_logger
 
+from hathor.mining.cpu_mining_service import CpuMiningService
 from hathor.transaction import BaseTransaction
 from hathor.verification.block_verifier import BlockVerifier
 from hathor.verification.merge_mined_block_verifier import MergeMinedBlockVerifier
@@ -25,30 +26,37 @@
 logger = get_logger()
 
 
-def verify_pow(vertex: BaseTransaction) -> None:
+def _verify_pow(vertex: BaseTransaction) -> None:
     assert vertex.hash is not None
-    logger.new().debug('Skipping BaseTransaction.verify_pow() for simulator')
+    logger.new().debug('Skipping VertexVerifier.verify_pow() for simulator')
 
 
 class SimulatorBlockVerifier(BlockVerifier):
     @classmethod
     def verify_pow(cls, vertex: BaseTransaction, *, override_weight: Optional[float] = None) -> None:
-        verify_pow(vertex)
+        _verify_pow(vertex)
 
 
 class SimulatorMergeMinedBlockVerifier(MergeMinedBlockVerifier):
     @classmethod
     def verify_pow(cls, vertex: BaseTransaction, *, override_weight: Optional[float] = None) -> None:
-        verify_pow(vertex)
+        _verify_pow(vertex)
 
 
 class SimulatorTransactionVerifier(TransactionVerifier):
     @classmethod
     def verify_pow(cls, vertex: BaseTransaction, *, override_weight: Optional[float] = None) -> None:
-        verify_pow(vertex)
+        _verify_pow(vertex)
 
 
 class SimulatorTokenCreationTransactionVerifier(TokenCreationTransactionVerifier):
     @classmethod
     def verify_pow(cls, vertex: BaseTransaction, *, override_weight: Optional[float] = None) -> None:
-        verify_pow(vertex)
+        _verify_pow(vertex)
+
+
+class SimulatorCpuMiningService(CpuMiningService):
+    def resolve(self, vertex: BaseTransaction, *, update_time: bool = False) -> bool:
+        vertex.update_hash()
+        logger.new().debug('Skipping CpuMiningService.resolve() for simulator')
+        return True
diff --git a/hathor/simulator/simulator.py b/hathor/simulator/simulator.py
index a37b8edd8..d5bdbd93f 100644
--- a/hathor/simulator/simulator.py
+++ b/hathor/simulator/simulator.py
@@ -27,13 +27,14 @@
 from hathor.p2p.peer_id import PeerId
 from hathor.simulator.clock import HeapClock, MemoryReactorHeapClock
 from hathor.simulator.miner.geometric_miner import GeometricMiner
-from hathor.simulator.tx_generator import RandomTransactionGenerator
-from hathor.simulator.verification import (
+from hathor.simulator.patches import (
     SimulatorBlockVerifier,
+    SimulatorCpuMiningService,
     SimulatorMergeMinedBlockVerifier,
     SimulatorTokenCreationTransactionVerifier,
     SimulatorTransactionVerifier,
 )
+from hathor.simulator.tx_generator import RandomTransactionGenerator
 from hathor.util import Random
 from hathor.verification.verification_service import VertexVerifiers
 from hathor.wallet import HDWallet
@@ -51,52 +52,6 @@
 
 
 class Simulator:
-    # used to concilite monkeypatching and multiple instances
-    _patches_rc: int = 0
-
-    @classmethod
-    def _apply_patches(cls):
-        """ Applies global patches on modules that aren't easy/possible to configure otherwise.
-
-        Patches:
-
-        - disable Transaction.resolve method
-        """
-        from hathor.transaction import BaseTransaction
-
-        def resolve(self: BaseTransaction, update_time: bool = True) -> bool:
-            self.update_hash()
-            logger.new().debug('Skipping BaseTransaction.resolve() for simulator')
-            return True
-
-        cls._original_resolve = BaseTransaction.resolve
-        BaseTransaction.resolve = resolve
-
-    @classmethod
-    def _remove_patches(cls):
-        """ Remove the patches previously applied.
-        """
-        from hathor.transaction import BaseTransaction
-        BaseTransaction.resolve = cls._original_resolve
-
-    @classmethod
-    def _patches_rc_increment(cls):
-        """ This is used by when starting instances of Simulator to determine when to run _apply_patches"""
-        assert cls._patches_rc >= 0
-        cls._patches_rc += 1
-        if cls._patches_rc == 1:
-            # patches not yet applied
-            cls._apply_patches()
-
-    @classmethod
-    def _patches_rc_decrement(cls):
-        """ This is used by when stopping instances of Simulator to determine when to run _remove_patches"""
-        assert cls._patches_rc > 0
-        cls._patches_rc -= 1
-        if cls._patches_rc == 0:
-            # patches not needed anymore
-            cls._remove_patches()
-
     def __init__(self, seed: Optional[int] = None):
         self.log = logger.new()
         if seed is None:
@@ -114,7 +69,6 @@ def start(self) -> None:
         """Has to be called before any other method can be called."""
         assert not self._started
         self._started = True
-        self._patches_rc_increment()
         first_timestamp = self.settings.GENESIS_BLOCK_TIMESTAMP
         dt = self.rng.randint(3600, 120 * 24 * 3600)
         self._clock.advance(first_timestamp + dt)
@@ -124,7 +78,6 @@ def stop(self) -> None:
         """Can only stop after calling start, but it doesn't matter if it's paused or not"""
         assert self._started
         self._started = False
-        self._patches_rc_decrement()
 
     def get_default_builder(self) -> Builder:
         """
@@ -159,6 +112,7 @@ def create_artifacts(self, builder: Optional[Builder] = None) -> BuildArtifacts:
         wallet = HDWallet(gap_limit=2)
         wallet._manually_initialize()
 
+        cpu_mining_service = SimulatorCpuMiningService()
         daa = DifficultyAdjustmentAlgorithm(settings=self.settings)
         vertex_verifiers = VertexVerifiers(
             block=SimulatorBlockVerifier(settings=self.settings, daa=daa),
@@ -173,6 +127,7 @@ def create_artifacts(self, builder: Optional[Builder] = None) -> BuildArtifacts:
             .set_wallet(wallet) \
             .set_vertex_verifiers(vertex_verifiers) \
             .set_daa(daa) \
+            .set_cpu_mining_service(cpu_mining_service) \
             .build()
 
         artifacts.manager.start()
diff --git a/hathor/transaction/base_transaction.py b/hathor/transaction/base_transaction.py
index 02de172a7..103faeb2d 100644
--- a/hathor/transaction/base_transaction.py
+++ b/hathor/transaction/base_transaction.py
@@ -22,7 +22,7 @@
 from itertools import chain
 from math import inf, isfinite, log
 from struct import error as StructError, pack
-from typing import TYPE_CHECKING, Any, Callable, ClassVar, Iterator, Optional
+from typing import TYPE_CHECKING, Any, ClassVar, Iterator, Optional
 
 from structlog import get_logger
 
@@ -42,8 +42,6 @@
 
 logger = get_logger()
 
-MAX_NONCE = 2**32
-
 MAX_OUTPUT_VALUE = 2**63  # max value (inclusive) that is possible to encode: 9223372036854775808 ~= 9.22337e+18
 _MAX_OUTPUT_VALUE_32 = 2**31 - 1  # max value (inclusive) before having to use 8 bytes: 2147483647 ~= 2.14748e+09
 
@@ -520,26 +518,6 @@ def verify_checkpoint(self, checkpoints: list[Checkpoint]) -> None:
         To be implemented by tx/block, used by `self.validate_checkpoint`. Should not modify the validation state."""
         raise NotImplementedError
 
-    def resolve(self, update_time: bool = False) -> bool:
-        """Run a CPU mining looking for the nonce that solves the proof-of-work
-
-        The `self.weight` must be set before calling this method.
-
-        :param update_time: update timestamp every 2 seconds
-        :return: True if a solution was found
-        :rtype: bool
-        """
-        hash_bytes = self.start_mining(update_time=update_time)
-
-        if hash_bytes:
-            self.hash = hash_bytes
-            metadata = getattr(self, '_metadata', None)
-            if metadata is not None and metadata.hash is not None:
-                metadata.hash = hash_bytes
-            return True
-        else:
-            return False
-
     def get_funds_hash(self) -> bytes:
         """Return the sha256 of the funds part of the transaction
 
@@ -609,41 +587,6 @@ def update_hash(self) -> None:
         """
         self.hash = self.calculate_hash()
 
-    def start_mining(self, start: int = 0, end: int = MAX_NONCE, sleep_seconds: float = 0.0, update_time: bool = True,
-                     *, should_stop: Callable[[], bool] = lambda: False) -> Optional[VertexId]:
-        """Starts mining until it solves the problem, i.e., finds the nonce that satisfies the conditions
-
-        :param start: beginning of the search interval
-        :param end: end of the search interval
-        :param sleep_seconds: the number of seconds it will sleep after each attempt
-        :param update_time: update timestamp every 2 seconds
-        :return The hash of the solved PoW or None when it is not found
-        """
-        pow_part1 = self.calculate_hash1()
-        target = self.get_target()
-        self.nonce = start
-        last_time = time.time()
-        while self.nonce < end:
-            if update_time:
-                now = time.time()
-                if now - last_time > 2:
-                    if should_stop():
-                        return None
-                    self.timestamp = int(now)
-                    pow_part1 = self.calculate_hash1()
-                    last_time = now
-                    self.nonce = start
-
-            result = self.calculate_hash2(pow_part1.copy())
-            if int(result.hex(), self.HEX_BASE) < target:
-                return result
-            self.nonce += 1
-            if sleep_seconds > 0:
-                time.sleep(sleep_seconds)
-                if should_stop():
-                    return None
-        return None
-
     def get_metadata(self, *, force_reload: bool = False, use_storage: bool = True) -> TransactionMetadata:
         """Return this tx's metadata.
 
diff --git a/hathor/transaction/token_creation_tx.py b/hathor/transaction/token_creation_tx.py
index 5bcc672a8..65f0a0cf0 100644
--- a/hathor/transaction/token_creation_tx.py
+++ b/hathor/transaction/token_creation_tx.py
@@ -65,12 +65,6 @@ def update_hash(self) -> None:
         assert self.hash is not None
         self.tokens = [self.hash]
 
-    def resolve(self, update_time: bool = True) -> bool:
-        ret = super().resolve(update_time)
-        assert self.hash is not None
-        self.tokens = [self.hash]
-        return ret
-
     def get_funds_fields_from_struct(self, buf: bytes, *, verbose: VerboseCallback = None) -> bytes:
         """ Gets all funds fields for a transaction from a buffer.
 
diff --git a/hathor/wallet/resources/nano_contracts/execute.py b/hathor/wallet/resources/nano_contracts/execute.py
index 46cce3ad6..ebf2c143c 100644
--- a/hathor/wallet/resources/nano_contracts/execute.py
+++ b/hathor/wallet/resources/nano_contracts/execute.py
@@ -99,7 +99,7 @@ def render_POST(self, request):
         tx.parents = self.manager.get_new_tx_parents()
         tx.update_timestamp(int(self.manager.reactor.seconds()))
         tx.weight = self.manager.daa.minimum_tx_weight(tx)
-        tx.resolve()
+        self.manager.cpu_mining_service.resolve(tx)
         success = self.manager.propagate_tx(tx)
 
         ret = {'success': success, 'hex_tx': tx.get_struct().hex()}
diff --git a/hathor/wallet/resources/send_tokens.py b/hathor/wallet/resources/send_tokens.py
index 268292c12..16bd97355 100644
--- a/hathor/wallet/resources/send_tokens.py
+++ b/hathor/wallet/resources/send_tokens.py
@@ -126,7 +126,7 @@ def _render_POST_thread(self, values: dict[str, Any], request: Request) -> Union
         if weight is None:
             weight = self.manager.daa.minimum_tx_weight(tx)
         tx.weight = weight
-        tx.resolve()
+        self.manager.cpu_mining_service.resolve(tx)
         self.manager.verification_service.verify(tx)
         return tx
 
diff --git a/hathor/wallet/resources/sign_tx.py b/hathor/wallet/resources/sign_tx.py
index b70ccb76b..8b86c6af4 100644
--- a/hathor/wallet/resources/sign_tx.py
+++ b/hathor/wallet/resources/sign_tx.py
@@ -67,7 +67,7 @@ def render_GET(self, request):
                     tx.parents = self.manager.get_new_tx_parents()
                     tx.update_timestamp(int(self.manager.reactor.seconds()))
                     tx.weight = self.manager.daa.minimum_tx_weight(tx)
-                    tx.resolve()
+                    self.manager.cpu_mining_service.resolve(tx)
 
                 data = {'hex_tx': tx.get_struct().hex(), 'success': True}
             except struct.error:
diff --git a/hathor/wallet/resources/thin_wallet/send_tokens.py b/hathor/wallet/resources/thin_wallet/send_tokens.py
index 136791f47..65136c1b6 100644
--- a/hathor/wallet/resources/thin_wallet/send_tokens.py
+++ b/hathor/wallet/resources/thin_wallet/send_tokens.py
@@ -260,7 +260,11 @@ def _render_POST_thread(self, context: _Context) -> _Context:
         # TODO Tx should be resolved in the frontend
         def _should_stop():
             return context.should_stop_mining_thread
-        context.tx.start_mining(sleep_seconds=self.sleep_seconds, should_stop=_should_stop)
+        self.manager.cpu_mining_service.start_mining(
+            context.tx,
+            sleep_seconds=self.sleep_seconds,
+            should_stop=_should_stop
+        )
         if context.should_stop_mining_thread:
             raise CancelledError()
         context.tx.update_hash()
diff --git a/tests/cli/test_multisig_spend.py b/tests/cli/test_multisig_spend.py
index d76187e6d..2d1940dcd 100644
--- a/tests/cli/test_multisig_spend.py
+++ b/tests/cli/test_multisig_spend.py
@@ -74,7 +74,7 @@ def test_spend_multisig(self):
         tx1.weight = 10
         tx1.parents = self.manager.get_new_tx_parents()
         tx1.timestamp = int(self.clock.seconds())
-        tx1.resolve()
+        self.manager.cpu_mining_service.resolve(tx1)
         self.manager.propagate_tx(tx1)
         self.clock.advance(10)
 
diff --git a/tests/consensus/test_consensus.py b/tests/consensus/test_consensus.py
index 048a3a440..0143e93a0 100644
--- a/tests/consensus/test_consensus.py
+++ b/tests/consensus/test_consensus.py
@@ -82,7 +82,7 @@ def test_revert_block_high_weight(self):
         tb0 = manager.make_custom_block_template(blocks[-1].hash, [conflicting_tx.hash, conflicting_tx.parents[0]])
         b0 = tb0.generate_mining_block(manager.rng, storage=manager.tx_storage)
         b0.weight = 10
-        b0.resolve()
+        manager.cpu_mining_service.resolve(b0)
         manager.verification_service.verify(b0)
         manager.propagate_tx(b0, fails_silently=False)
 
@@ -144,7 +144,7 @@ def test_dont_revert_block_low_weight(self):
         # So, it is not enough to revert and this block will be voided as well.
         b0 = manager.generate_mining_block()
         b0.parents = [blocks[-1].hash, conflicting_tx.hash, conflicting_tx.parents[0]]
-        b0.resolve()
+        manager.cpu_mining_service.resolve(b0)
         manager.verification_service.verify(b0)
         manager.propagate_tx(b0, fails_silently=False)
 
@@ -200,7 +200,7 @@ def test_dont_revert_block_high_weight_transaction_verify_other(self):
         tb0 = manager.make_custom_block_template(blocks[-1].hash, [conflicting_tx.hash, conflicting_tx.parents[0]])
         b0 = tb0.generate_mining_block(manager.rng, storage=manager.tx_storage)
         b0.weight = 10
-        b0.resolve()
+        manager.cpu_mining_service.resolve(b0)
         manager.verification_service.verify(b0)
         manager.propagate_tx(b0, fails_silently=False)
 
@@ -254,7 +254,7 @@ def test_dont_revert_block_high_weight_verify_both(self):
         b0 = manager.generate_mining_block()
         b0.parents = [b0.parents[0], conflicting_tx.hash, conflicting_tx.parents[0]]
         b0.weight = 10
-        b0.resolve()
+        manager.cpu_mining_service.resolve(b0)
         manager.verification_service.verify(b0)
         manager.propagate_tx(b0, fails_silently=False)
 
diff --git a/tests/consensus/test_consensus3.py b/tests/consensus/test_consensus3.py
index 0aaaac1be..4c7f37add 100644
--- a/tests/consensus/test_consensus3.py
+++ b/tests/consensus/test_consensus3.py
@@ -34,7 +34,7 @@ def test_double_spending_attempt_1(self):
         tx_fund0.weight = 1
         tx_fund0.parents = manager.get_new_tx_parents()
         tx_fund0.timestamp = int(self.clock.seconds())
-        tx_fund0.resolve()
+        manager.cpu_mining_service.resolve(tx_fund0)
         self.assertTrue(manager.propagate_tx(tx_fund0))
 
         def do_step(tx_fund):
@@ -43,7 +43,7 @@ def do_step(tx_fund):
             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()
+            manager.cpu_mining_service.resolve(tx1)
             self.assertTrue(manager.propagate_tx(tx1))
 
             inputs = []
@@ -53,7 +53,7 @@ def do_step(tx_fund):
             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()
+            manager.cpu_mining_service.resolve(tx2)
             self.assertTrue(manager.propagate_tx(tx2))
 
             inputs = [WalletInputInfo(tx_fund.hash, 0, manager.wallet.get_private_key(addr))]
@@ -61,7 +61,7 @@ def do_step(tx_fund):
             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()
+            manager.cpu_mining_service.resolve(tx3)
             self.assertTrue(manager.propagate_tx(tx3))
 
             inputs = [WalletInputInfo(tx_fund.hash, 1, manager.wallet.get_private_key(addr))]
@@ -69,7 +69,7 @@ def do_step(tx_fund):
             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()
+            manager.cpu_mining_service.resolve(tx4)
             self.assertTrue(manager.propagate_tx(tx4))
 
             inputs = []
@@ -81,7 +81,7 @@ def do_step(tx_fund):
             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()
+            manager.cpu_mining_service.resolve(tx5)
             self.assertTrue(manager.propagate_tx(tx5))
             return tx5
 
@@ -124,7 +124,7 @@ def test_double_spending_attempt_2(self):
         tx_fund0.weight = 1
         tx_fund0.parents = manager.get_new_tx_parents()
         tx_fund0.timestamp = int(self.clock.seconds())
-        tx_fund0.resolve()
+        manager.cpu_mining_service.resolve(tx_fund0)
         self.assertTrue(manager.propagate_tx(tx_fund0))
 
         def do_step(tx_fund):
@@ -133,7 +133,7 @@ def do_step(tx_fund):
             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()
+            manager.cpu_mining_service.resolve(tx1)
             self.assertTrue(manager.propagate_tx(tx1))
 
             inputs = []
@@ -143,7 +143,7 @@ def do_step(tx_fund):
             tx2 = manager.wallet.prepare_transaction(Transaction, inputs, outputs, tx1.timestamp+1)
             tx2.weight = 1.1
             tx2.parents = manager.get_new_tx_parents(tx2.timestamp)
-            tx2.resolve()
+            manager.cpu_mining_service.resolve(tx2)
             self.assertTrue(manager.propagate_tx(tx2))
 
             inputs = []
@@ -153,7 +153,7 @@ def do_step(tx_fund):
             tx3 = manager.wallet.prepare_transaction(Transaction, inputs, outputs, tx_fund.timestamp+1)
             tx3.weight = 1
             tx3.parents = manager.get_new_tx_parents(tx3.timestamp)
-            tx3.resolve()
+            manager.cpu_mining_service.resolve(tx3)
             self.assertTrue(manager.propagate_tx(tx3))
 
             inputs = []
@@ -163,7 +163,7 @@ def do_step(tx_fund):
             tx4 = manager.wallet.prepare_transaction(Transaction, inputs, outputs, tx_fund.timestamp+1)
             tx4.weight = tx1.weight + tx2.weight + 0.1
             tx4.parents = manager.get_new_tx_parents(tx4.timestamp)
-            tx4.resolve()
+            manager.cpu_mining_service.resolve(tx4)
             self.assertTrue(manager.propagate_tx(tx4))
 
             inputs = []
@@ -176,7 +176,7 @@ def do_step(tx_fund):
             tx5 = manager.wallet.prepare_transaction(Transaction, inputs, outputs, tx4.timestamp+1)
             tx5.weight = 1
             tx5.parents = manager.get_new_tx_parents(tx5.timestamp)
-            tx5.resolve()
+            manager.cpu_mining_service.resolve(tx5)
             self.assertTrue(manager.propagate_tx(tx5))
             return tx5
 
diff --git a/tests/event/test_event_reorg.py b/tests/event/test_event_reorg.py
index 7d145482b..535014801 100644
--- a/tests/event/test_event_reorg.py
+++ b/tests/event/test_event_reorg.py
@@ -37,7 +37,7 @@ def test_reorg_events(self):
         tb0 = self.manager.make_custom_block_template(block_to_replace.parents[0], block_to_replace.parents[1:])
         b0 = tb0.generate_mining_block(self.manager.rng, storage=self.manager.tx_storage, address=BURN_ADDRESS)
         b0.weight = 10
-        b0.resolve()
+        self.manager.cpu_mining_service.resolve(b0)
         self.manager.verification_service.verify(b0)
         self.manager.propagate_tx(b0, fails_silently=False)
         self.log.debug('reorg block propagated')
diff --git a/tests/p2p/test_double_spending.py b/tests/p2p/test_double_spending.py
index 02c4b7441..003b287fb 100644
--- a/tests/p2p/test_double_spending.py
+++ b/tests/p2p/test_double_spending.py
@@ -42,19 +42,19 @@ def test_simple_double_spending(self):
         tx1.weight = 10
         tx1.parents = self.manager1.get_new_tx_parents()
         tx1.timestamp = int(self.clock.seconds())
-        tx1.resolve()
+        self.manager1.cpu_mining_service.resolve(tx1)
 
         tx2 = Transaction.create_from_struct(tx1.get_struct())
         tx2.weight = 10
         tx2.parents = tx2.parents[::-1]
         tx2.timestamp = int(self.clock.seconds())
-        tx2.resolve()
+        self.manager1.cpu_mining_service.resolve(tx2)
         self.assertNotEqual(tx1.hash, tx2.hash)
 
         tx3 = Transaction.create_from_struct(tx1.get_struct())
         tx3.weight = 11
         tx3.timestamp = int(self.clock.seconds())
-        tx3.resolve()
+        self.manager1.cpu_mining_service.resolve(tx3)
         self.assertNotEqual(tx1.hash, tx3.hash)
         self.assertNotEqual(tx2.hash, tx3.hash)
 
@@ -156,7 +156,7 @@ def test_double_spending_propagation(self):
         tx1.weight = 5
         tx1.parents = self.manager1.get_new_tx_parents()
         tx1.timestamp = int(self.clock.seconds())
-        tx1.resolve()
+        self.manager1.cpu_mining_service.resolve(tx1)
 
         address = self.manager1.wallet.get_unused_address_bytes()
         value = 500
@@ -170,7 +170,7 @@ def test_double_spending_propagation(self):
         tx4.weight = 5
         tx4.parents = self.manager1.get_new_tx_parents()
         tx4.timestamp = int(self.clock.seconds())
-        tx4.resolve()
+        self.manager1.cpu_mining_service.resolve(tx4)
 
         self.assertEqual(tx1.inputs[0].tx_id, tx4.inputs[0].tx_id)
         self.assertEqual(tx1.inputs[0].index, tx4.inputs[0].index)
@@ -193,7 +193,7 @@ def test_double_spending_propagation(self):
         tx2.weight = 5
         tx2.parents = tx1.parents
         tx2.timestamp = int(self.clock.seconds())
-        tx2.resolve()
+        self.manager1.cpu_mining_service.resolve(tx2)
         self.clock.advance(15)
         self.manager1.propagate_tx(tx2)
         self.clock.advance(15)
@@ -212,7 +212,7 @@ def test_double_spending_propagation(self):
         tx3.weight = 5
         tx3.parents = [tx1.hash, tx1.parents[0]]
         tx3.timestamp = int(self.clock.seconds())
-        tx3.resolve()
+        self.manager1.cpu_mining_service.resolve(tx3)
         self.clock.advance(15)
         self.assertTrue(self.manager1.propagate_tx(tx3))
         self.clock.advance(15)
@@ -243,7 +243,7 @@ def test_double_spending_propagation(self):
         tx5.weight = 5
         tx5.parents = tx1.parents
         tx5.timestamp = int(self.clock.seconds())
-        tx5.resolve()
+        self.manager1.cpu_mining_service.resolve(tx5)
         self.clock.advance(15)
         self.manager1.propagate_tx(tx5)
         self.clock.advance(15)
@@ -259,7 +259,7 @@ def test_double_spending_propagation(self):
         tx6.weight = 1
         tx6.parents = [tx4.hash, tx5.hash]
         tx6.timestamp = int(self.clock.seconds())
-        tx6.resolve()
+        self.manager1.cpu_mining_service.resolve(tx6)
         self.clock.advance(15)
         self.manager1.propagate_tx(tx6)
         self.clock.advance(15)
@@ -280,7 +280,7 @@ def test_double_spending_propagation(self):
         tx7.weight = 10
         tx7.parents = [tx4.hash, tx5.hash]
         tx7.timestamp = int(self.clock.seconds())
-        tx7.resolve()
+        self.manager1.cpu_mining_service.resolve(tx7)
         self.clock.advance(15)
         self.manager1.propagate_tx(tx7, False)
         self.clock.advance(15)
diff --git a/tests/p2p/test_split_brain.py b/tests/p2p/test_split_brain.py
index e649fafa3..6ad377850 100644
--- a/tests/p2p/test_split_brain.py
+++ b/tests/p2p/test_split_brain.py
@@ -293,7 +293,7 @@ def test_split_brain_only_blocks_bigger_score(self):
         # will be bigger than the other one
         b = add_new_block(manager2, advance_clock=1, propagate=False)
         b.weight = 5
-        b.resolve()
+        manager2.cpu_mining_service.resolve(b)
         manager2.propagate_tx(b)
         manager2_blocks += 1
 
diff --git a/tests/p2p/test_sync.py b/tests/p2p/test_sync.py
index ae8af2bb6..2cea1c7cf 100644
--- a/tests/p2p/test_sync.py
+++ b/tests/p2p/test_sync.py
@@ -43,7 +43,7 @@ def _add_new_tx(self, address, value):
         tx.storage = self.manager1.tx_storage
         tx.weight = 10
         tx.parents = self.manager1.get_new_tx_parents()
-        tx.resolve()
+        self.manager1.cpu_mining_service.resolve(tx)
         self.manager1.verification_service.verify(tx)
         self.manager1.propagate_tx(tx)
         self.clock.advance(10)
@@ -60,7 +60,7 @@ def _add_new_transactions(self, num_txs):
 
     def _add_new_block(self, propagate=True):
         block = self.manager1.generate_mining_block()
-        self.assertTrue(block.resolve())
+        self.assertTrue(self.manager1.cpu_mining_service.resolve(block))
         self.manager1.verification_service.verify(block)
         self.manager1.on_new_tx(block, propagate_to_peers=propagate)
         self.clock.advance(10)
diff --git a/tests/p2p/test_sync_mempool.py b/tests/p2p/test_sync_mempool.py
index ac4fc9bb1..f2a0219b3 100644
--- a/tests/p2p/test_sync_mempool.py
+++ b/tests/p2p/test_sync_mempool.py
@@ -31,7 +31,7 @@ def _add_new_tx(self, address, value):
         tx.storage = self.manager1.tx_storage
         tx.weight = 10
         tx.parents = self.manager1.get_new_tx_parents()
-        tx.resolve()
+        self.manager1.cpu_mining_service.resolve(tx)
         self.manager1.verification_service.verify(tx)
         self.manager1.propagate_tx(tx)
         self.clock.advance(10)
@@ -48,7 +48,7 @@ def _add_new_transactions(self, num_txs):
 
     def _add_new_block(self, propagate=True):
         block = self.manager1.generate_mining_block()
-        self.assertTrue(block.resolve())
+        self.assertTrue(self.manager1.cpu_mining_service.resolve(block))
         self.manager1.verification_service.verify(block)
         self.manager1.on_new_tx(block, propagate_to_peers=propagate)
         self.clock.advance(10)
diff --git a/tests/p2p/test_twin_tx.py b/tests/p2p/test_twin_tx.py
index e326e5756..1e7da4658 100644
--- a/tests/p2p/test_twin_tx.py
+++ b/tests/p2p/test_twin_tx.py
@@ -36,12 +36,12 @@ def test_twin_tx(self):
         tx1.weight = 10
         tx1.parents = self.manager.get_new_tx_parents()
         tx1.timestamp = int(self.clock.seconds())
-        tx1.resolve()
+        self.manager.cpu_mining_service.resolve(tx1)
 
         # Change of parents only, so it's a twin
         tx2 = Transaction.create_from_struct(tx1.get_struct())
         tx2.parents = [tx1.parents[1], tx1.parents[0]]
-        tx2.resolve()
+        self.manager.cpu_mining_service.resolve(tx2)
         self.assertNotEqual(tx1.hash, tx2.hash)
 
         # The same as tx1 but with one input different, so it's not a twin
@@ -50,7 +50,7 @@ def test_twin_tx(self):
         tx3.weight = tx1.weight
         tx3.parents = tx1.parents
         tx3.timestamp = tx1.timestamp
-        tx3.resolve()
+        self.manager.cpu_mining_service.resolve(tx3)
 
         self.manager.propagate_tx(tx1)
         meta1 = tx1.get_metadata()
diff --git a/tests/resources/p2p/test_mining.py b/tests/resources/p2p/test_mining.py
index 19e77f40f..b0d559f90 100644
--- a/tests/resources/p2p/test_mining.py
+++ b/tests/resources/p2p/test_mining.py
@@ -31,7 +31,7 @@ def test_post(self):
         block_bytes = base64.b64decode(block_bytes_str)
         block = Block.create_from_struct(block_bytes)
         block.weight = 4
-        block.resolve()
+        self.manager.cpu_mining_service.resolve(block)
 
         block_bytes = bytes(block)
         block_bytes_str = base64.b64encode(block_bytes).decode('ascii')
@@ -56,7 +56,7 @@ def test_post_invalid_data(self):
         block_bytes = base64.b64decode(block_bytes_str)
         block = Block.create_from_struct(block_bytes)
         block.weight = 4
-        block.resolve()
+        self.manager.cpu_mining_service.resolve(block)
 
         block_bytes = bytes(block)
         block_bytes_str = base64.b64encode(block_bytes).decode('ascii')
diff --git a/tests/resources/transaction/test_create_tx.py b/tests/resources/transaction/test_create_tx.py
index b42e83c73..ebe1e5393 100644
--- a/tests/resources/transaction/test_create_tx.py
+++ b/tests/resources/transaction/test_create_tx.py
@@ -228,7 +228,7 @@ def test_tx_propagate(self):
         input_data = P2PKH.create_input_data(public_key_bytes, signature_bytes)
         tx.inputs[0].data = input_data
         # XXX: tx.resolve is a bit CPU intensive, but not so much as to make this test disabled by default
-        tx.resolve(False)
+        self.manager.cpu_mining_service.resolve(tx, update_time=False)
         self.assertTrue(self.manager.propagate_tx(tx))
 
     @inlineCallbacks
@@ -275,7 +275,7 @@ def test_tx_propagate_multiple_inputs(self):
         tx.inputs[1].data = input_data
         tx.inputs[2].data = input_data
         # XXX: tx.resolve is a bit CPU intensive, but not so much as to make this test disabled by default
-        tx.resolve(False)
+        self.manager.cpu_mining_service.resolve(tx, update_time=False)
         self.assertTrue(self.manager.propagate_tx(tx))
 
     @inlineCallbacks
diff --git a/tests/resources/transaction/test_graphviz.py b/tests/resources/transaction/test_graphviz.py
index e2b736927..9118f1e09 100644
--- a/tests/resources/transaction/test_graphviz.py
+++ b/tests/resources/transaction/test_graphviz.py
@@ -26,7 +26,7 @@ def setUp(self):
 
         self.tx2 = Transaction.create_from_struct(tx.get_struct())
         self.tx2.parents = [tx.parents[1], tx.parents[0]]
-        self.tx2.resolve()
+        self.manager.cpu_mining_service.resolve(self.tx2)
 
         self.manager.propagate_tx(self.tx2)
 
diff --git a/tests/resources/transaction/test_mining.py b/tests/resources/transaction/test_mining.py
index 0981794bd..e412f9043 100644
--- a/tests/resources/transaction/test_mining.py
+++ b/tests/resources/transaction/test_mining.py
@@ -1,5 +1,6 @@
 from twisted.internet.defer import inlineCallbacks
 
+from hathor.mining.cpu_mining_service import CpuMiningService
 from hathor.transaction.resources import mining
 from tests import unittest
 from tests.resources.base_resource import StubSite, _BaseResourceTest
@@ -95,7 +96,7 @@ def test_get_block_template_and_submit_block(self):
         resp = yield self.get_block_template.get('', {b'address': b'HC7w4j7mPet49BBN5a2An3XUiPvK6C1TL7'})
         data = resp.json_value()
         block = create_tx_from_dict(data)
-        block.resolve(False)
+        CpuMiningService().resolve(block, update_time=False)
         self.assertTrue(self.manager.propagate_tx(block))
 
 
diff --git a/tests/resources/transaction/test_pushtx.py b/tests/resources/transaction/test_pushtx.py
index 314e7445f..d3c94c36c 100644
--- a/tests/resources/transaction/test_pushtx.py
+++ b/tests/resources/transaction/test_pushtx.py
@@ -48,7 +48,7 @@ def get_tx(self, inputs: Optional[list[WalletInputInfo]] = None,
         max_ts_spent_tx = max(tx.get_spent_tx(txin).timestamp for txin in tx.inputs)
         tx.timestamp = max(max_ts_spent_tx + 1, int(self.manager.reactor.seconds()))
         tx.parents = self.manager.get_new_tx_parents(tx.timestamp)
-        tx.resolve()
+        self.manager.cpu_mining_service.resolve(tx)
         return tx
 
     def push_tx(self, data=None):
@@ -92,7 +92,7 @@ def test_push_tx(self) -> Generator:
 
         # modify tx so it will be a double spending, then rejected
         tx.weight += 0.1
-        tx.resolve()
+        self.manager.cpu_mining_service.resolve(tx)
 
         tx_hex = tx.get_struct().hex()
         response_success = yield self.push_tx({'hex_tx': tx_hex})
@@ -183,7 +183,7 @@ def test_script_too_big(self) -> Generator:
 
         # Invalid tx (output script is too long)
         tx.outputs[0].script = b'*' * (settings.PUSHTX_MAX_OUTPUT_SCRIPT_SIZE + 1)
-        tx.resolve()
+        self.manager.cpu_mining_service.resolve(tx)
         tx_hex = tx.get_struct().hex()
         response = yield self.push_tx({'hex_tx': tx_hex})
         data = response.json_value()
@@ -199,7 +199,7 @@ def test_non_standard_script(self) -> Generator:
 
         # Invalid tx (output script is too long)
         tx.outputs[0].script = b'*' * 5
-        tx.resolve()
+        self.manager.cpu_mining_service.resolve(tx)
         tx_hex = tx.get_struct().hex()
         response = yield self.push_tx({'hex_tx': tx_hex})
         data = response.json_value()
diff --git a/tests/resources/transaction/test_tx.py b/tests/resources/transaction/test_tx.py
index c6a2e72d9..51f2ffe97 100644
--- a/tests/resources/transaction/test_tx.py
+++ b/tests/resources/transaction/test_tx.py
@@ -52,7 +52,7 @@ def test_get_one(self):
 
         tx2 = Transaction.create_from_struct(tx.get_struct())
         tx2.parents = [tx.parents[1], tx.parents[0]]
-        tx2.resolve()
+        self.manager.cpu_mining_service.resolve(tx2)
 
         self.manager.propagate_tx(tx2)
 
diff --git a/tests/resources/wallet/test_balance.py b/tests/resources/wallet/test_balance.py
index 7732caa21..42532c7e7 100644
--- a/tests/resources/wallet/test_balance.py
+++ b/tests/resources/wallet/test_balance.py
@@ -2,6 +2,7 @@
 
 from twisted.internet.defer import inlineCallbacks
 
+from hathor.mining.cpu_mining_service import CpuMiningService
 from hathor.p2p.resources import MiningResource
 from hathor.wallet.resources import BalanceResource
 from tests import unittest
@@ -27,7 +28,10 @@ def test_get(self):
         # Mining new block
         response_mining = yield self.web_mining.get("mining")
         data_mining = response_mining.json_value()
-        block_bytes = resolve_block_bytes(block_bytes=data_mining['block_bytes'])
+        block_bytes = resolve_block_bytes(
+            block_bytes=data_mining['block_bytes'],
+            cpu_mining_service=CpuMiningService()
+        )
         yield self.web_mining.post("mining", {'block_bytes': base64.b64encode(block_bytes).decode('utf-8')})
 
         # Get new balance after block
diff --git a/tests/resources/wallet/test_history.py b/tests/resources/wallet/test_history.py
index 83bdb26dc..7b7e398c7 100644
--- a/tests/resources/wallet/test_history.py
+++ b/tests/resources/wallet/test_history.py
@@ -2,6 +2,7 @@
 
 from twisted.internet.defer import inlineCallbacks
 
+from hathor.mining.cpu_mining_service import CpuMiningService
 from hathor.p2p.resources import MiningResource
 from hathor.wallet.resources import HistoryResource
 from tests import unittest
@@ -22,7 +23,10 @@ def test_get(self):
         # Mining new block
         response_mining = yield self.web_mining.get("mining")
         data_mining = response_mining.json_value()
-        block_bytes = resolve_block_bytes(block_bytes=data_mining['block_bytes'])
+        block_bytes = resolve_block_bytes(
+            block_bytes=data_mining['block_bytes'],
+            cpu_mining_service=CpuMiningService()
+        )
         yield self.web_mining.post("mining", {'block_bytes': base64.b64encode(block_bytes).decode('utf-8')})
 
         # Getting wallet history
diff --git a/tests/resources/wallet/test_send_tokens.py b/tests/resources/wallet/test_send_tokens.py
index 7136fc85d..3162195fc 100644
--- a/tests/resources/wallet/test_send_tokens.py
+++ b/tests/resources/wallet/test_send_tokens.py
@@ -3,6 +3,7 @@
 from twisted.internet.defer import inlineCallbacks
 
 from hathor.daa import TestMode
+from hathor.mining.cpu_mining_service import CpuMiningService
 from hathor.p2p.resources import MiningResource
 from hathor.wallet.resources import BalanceResource, HistoryResource, SendTokensResource
 from tests import unittest
@@ -25,7 +26,10 @@ def test_post(self):
         # Mining new block
         response_mining = yield self.web_mining.get("mining")
         data_mining = response_mining.json_value()
-        block_bytes = resolve_block_bytes(block_bytes=data_mining['block_bytes'])
+        block_bytes = resolve_block_bytes(
+            block_bytes=data_mining['block_bytes'],
+            cpu_mining_service=CpuMiningService()
+        )
         yield self.web_mining.post("mining", {'block_bytes': base64.b64encode(block_bytes).decode('utf-8')})
         add_blocks_unlock_reward(self.manager)
         self.reactor.advance(10)
diff --git a/tests/resources/wallet/test_thin_wallet.py b/tests/resources/wallet/test_thin_wallet.py
index 73a582194..dd226f13b 100644
--- a/tests/resources/wallet/test_thin_wallet.py
+++ b/tests/resources/wallet/test_thin_wallet.py
@@ -424,7 +424,7 @@ def test_token_history(self):
         tx2.timestamp = int(self.clock.seconds())
         tx2.weight = self.manager.daa.minimum_tx_weight(tx2)
         tx2.parents = self.manager.get_new_tx_parents()
-        tx2.resolve()
+        self.manager.cpu_mining_service.resolve(tx2)
         self.manager.propagate_tx(tx2)
 
         # Now we have 2 txs with this token
diff --git a/tests/tx/test_blockchain.py b/tests/tx/test_blockchain.py
index f758706d3..032eb6510 100644
--- a/tests/tx/test_blockchain.py
+++ b/tests/tx/test_blockchain.py
@@ -115,7 +115,7 @@ def test_single_fork_not_best(self):
         # Change the order of the transactions to change the hash
         fork_block1 = manager.generate_mining_block()
         fork_block1.parents = [fork_block1.parents[0]] + fork_block1.parents[:0:-1]
-        fork_block1.resolve()
+        manager.cpu_mining_service.resolve(fork_block1)
         manager.verification_service.verify(fork_block1)
 
         # Mine 8 blocks in a row
@@ -167,7 +167,7 @@ def test_single_fork_not_best(self):
         # Propagate a block connected to the voided chain
         # This block belongs to case (iv).
         fork_block3 = manager.generate_mining_block(parent_block_hash=fork_block1.hash)
-        fork_block3.resolve()
+        manager.cpu_mining_service.resolve(fork_block3)
         manager.verification_service.verify(fork_block3)
         self.assertTrue(manager.propagate_tx(fork_block3))
         fork_meta3 = fork_block3.get_metadata()
@@ -237,7 +237,7 @@ def test_multiple_forks(self):
 
         # Propagate a block connected to the voided chain, case (iii).
         fork_block2 = manager.generate_mining_block(parent_block_hash=sidechain[-1].hash)
-        fork_block2.resolve()
+        manager.cpu_mining_service.resolve(fork_block2)
         manager.verification_service.verify(fork_block2)
         self.assertTrue(manager.propagate_tx(fork_block2))
         sidechain.append(fork_block2)
@@ -285,7 +285,7 @@ def test_multiple_forks(self):
 
         # Propagate a block connected to the side chain, case (v).
         fork_block3 = manager.generate_mining_block(parent_block_hash=fork_block2.hash)
-        fork_block3.resolve()
+        manager.cpu_mining_service.resolve(fork_block3)
         manager.verification_service.verify(fork_block3)
         self.assertTrue(manager.propagate_tx(fork_block3))
         sidechain.append(fork_block3)
@@ -311,7 +311,7 @@ def test_multiple_forks(self):
         # Another side chain has direcly exceeded the best score.
         fork_block4 = manager.generate_mining_block(parent_block_hash=sidechain3[-1].hash)
         fork_block4.weight = 10
-        fork_block4.resolve()
+        manager.cpu_mining_service.resolve(fork_block4)
         manager.verification_service.verify(fork_block4)
         self.assertTrue(manager.propagate_tx(fork_block4))
         sidechain3.append(fork_block4)
diff --git a/tests/tx/test_indexes.py b/tests/tx/test_indexes.py
index 5227b525d..fc1d03c6e 100644
--- a/tests/tx/test_indexes.py
+++ b/tests/tx/test_indexes.py
@@ -40,7 +40,7 @@ def test_tx_tips_with_conflict(self):
         tx1.weight = 2.0
         tx1.parents = self.manager.get_new_tx_parents()
         tx1.timestamp = int(self.clock.seconds())
-        tx1.resolve()
+        self.manager.cpu_mining_service.resolve(tx1)
         self.assertTrue(self.manager.propagate_tx(tx1, False))
         if self.manager.tx_storage.indexes.mempool_tips is not None:
             self.assertEqual(
@@ -55,7 +55,7 @@ def test_tx_tips_with_conflict(self):
         tx2.parents = [tx1.hash] + self.manager.get_new_tx_parents()[1:]
         self.assertIn(tx1.hash, tx2.parents)
         tx2.timestamp = int(self.clock.seconds()) + 1
-        tx2.resolve()
+        self.manager.cpu_mining_service.resolve(tx2)
         self.assertTrue(self.manager.propagate_tx(tx2, False))
         if self.manager.tx_storage.indexes.mempool_tips is not None:
             self.assertEqual(
@@ -66,7 +66,7 @@ def test_tx_tips_with_conflict(self):
         tx3 = Transaction.create_from_struct(tx2.get_struct())
         tx3.timestamp = tx2.timestamp + 1
         self.assertIn(tx1.hash, tx3.parents)
-        tx3.resolve()
+        self.manager.cpu_mining_service.resolve(tx3)
         self.assertNotEqual(tx2.hash, tx3.hash)
         self.assertTrue(self.manager.propagate_tx(tx3, False))
         self.assertIn(tx3.hash, tx2.get_metadata().conflict_with)
@@ -97,7 +97,7 @@ def test_tx_tips_voided(self):
         tx1.weight = 2.0
         tx1.parents = self.manager.get_new_tx_parents()
         tx1.timestamp = int(self.clock.seconds())
-        tx1.resolve()
+        self.manager.cpu_mining_service.resolve(tx1)
         self.assertTrue(self.manager.propagate_tx(tx1, False))
         if self.manager.tx_storage.indexes.mempool_tips is not None:
             self.assertEqual(
@@ -110,7 +110,7 @@ def test_tx_tips_voided(self):
         tx2.parents = [tx1.hash] + self.manager.get_new_tx_parents()[1:]
         self.assertIn(tx1.hash, tx2.parents)
         tx2.timestamp = int(self.clock.seconds()) + 1
-        tx2.resolve()
+        self.manager.cpu_mining_service.resolve(tx2)
         self.assertTrue(self.manager.propagate_tx(tx2, False))
         if self.manager.tx_storage.indexes.mempool_tips is not None:
             self.assertEqual(
@@ -123,7 +123,7 @@ def test_tx_tips_voided(self):
         # tx3.timestamp = tx2.timestamp + 1
         tx3.parents = tx1.parents
         # self.assertIn(tx1.hash, tx3.parents)
-        tx3.resolve()
+        self.manager.cpu_mining_service.resolve(tx3)
         self.assertNotEqual(tx2.hash, tx3.hash)
         self.assertTrue(self.manager.propagate_tx(tx3, False))
         # self.assertIn(tx3.hash, tx2.get_metadata().voided_by)
@@ -178,7 +178,7 @@ def _test_confirmed_tx_that_spends_unconfirmed_tx(self, debug=False):
         tx0.weight = 1.0
         tx0.parents = self.manager.get_new_tx_parents()
         tx0.timestamp = int(self.clock.seconds())
-        tx0.resolve()
+        self.manager.cpu_mining_service.resolve(tx0)
         # XXX: tx0.outputs[0] is always the change output for some reason
         self.assertEqual(len(tx0.outputs), 4)
         self.assertEqual(tx0.outputs[1], tx0.outputs[2])
@@ -201,7 +201,7 @@ def _test_confirmed_tx_that_spends_unconfirmed_tx(self, debug=False):
         self.tx_A.inputs[0].data = P2PKH.create_input_data(
             *self.wallet.get_input_aux_data(self.tx_A.get_sighash_all(), private_key)
         )
-        self.tx_A.resolve()
+        self.manager.cpu_mining_service.resolve(self.tx_A)
         if debug:
             self.assertTrue(self.manager.propagate_tx(self.tx_A, False))
             self.assertFalse(self.tx_A.get_metadata().voided_by)
@@ -218,7 +218,7 @@ def _test_confirmed_tx_that_spends_unconfirmed_tx(self, debug=False):
         self.tx_B.inputs[0].data = P2PKH.create_input_data(
             *self.wallet.get_input_aux_data(self.tx_B.get_sighash_all(), private_key)
         )
-        self.tx_B.resolve()
+        self.manager.cpu_mining_service.resolve(self.tx_B)
         if debug:
             self.assertTrue(self.manager.propagate_tx(self.tx_B, False))
             self.assertFalse(self.tx_B.get_metadata().voided_by)
@@ -237,7 +237,7 @@ def _test_confirmed_tx_that_spends_unconfirmed_tx(self, debug=False):
         self.tx_C.inputs[0].data = P2PKH.create_input_data(
             *self.wallet.get_input_aux_data(self.tx_C.get_sighash_all(), private_key)
         )
-        self.tx_C.resolve()
+        self.manager.cpu_mining_service.resolve(self.tx_C)
         if debug:
             self.assertTrue(self.manager.propagate_tx(self.tx_C, False))
             self.assertFalse(self.tx_C.get_metadata().voided_by)
@@ -262,7 +262,7 @@ def _test_confirmed_tx_that_spends_unconfirmed_tx(self, debug=False):
             self.tx_D.inputs[i].data = P2PKH.create_input_data(
                 *self.wallet.get_input_aux_data(self.tx_D.get_sighash_all(), private_key)
             )
-        self.tx_D.resolve()
+        self.manager.cpu_mining_service.resolve(self.tx_D)
         if debug:
             self.assertTrue(self.manager.propagate_tx(self.tx_D, False))
             self.assertFalse(self.tx_D.get_metadata().voided_by)
@@ -275,7 +275,7 @@ def _test_confirmed_tx_that_spends_unconfirmed_tx(self, debug=False):
             weight=1.0,
             storage=self.tx_storage,
         )
-        self.block_E.resolve()
+        self.manager.cpu_mining_service.resolve(self.block_E)
         if debug:
             self.assertTrue(self.manager.propagate_tx(self.block_E, False))
             self.assertFalse(self.block_E.get_metadata().voided_by)
@@ -438,7 +438,7 @@ def check_utxos(*args):
         block2.parents[1:] = [txA2.hash, txB2.hash]
         block2.timestamp = block1.timestamp
         block2.weight = 1.2
-        block2.resolve()
+        self.manager.cpu_mining_service.resolve(block2)
         self.manager.verification_service.validate_full(block2)
         self.manager.propagate_tx(block2, fails_silently=False)
         self.graphviz.labels[block2.hash] = 'block2'
@@ -658,7 +658,7 @@ def test_utxo_index_after_push_tx(self):
         tx1.inputs[0].data = P2PKH.create_input_data(
             *wallet.get_input_aux_data(tx1.get_sighash_all(), wallet.get_private_key(address))
         )
-        tx1.resolve()
+        self.manager.cpu_mining_service.resolve(tx1)
         self.assertTrue(self.manager.propagate_tx(tx1, False))
 
         self.assertEqual(
@@ -733,7 +733,7 @@ def test_utxo_index_last(self):
         tx1.inputs[0].data = P2PKH.create_input_data(
             *wallet.get_input_aux_data(tx1.get_sighash_all(), wallet.get_private_key(address))
         )
-        tx1.resolve()
+        self.manager.cpu_mining_service.resolve(tx1)
         self.assertTrue(self.manager.propagate_tx(tx1, False))
 
         # querying for exact values
diff --git a/tests/tx/test_indexes4.py b/tests/tx/test_indexes4.py
index 2e9290c0d..7625e84a9 100644
--- a/tests/tx/test_indexes4.py
+++ b/tests/tx/test_indexes4.py
@@ -29,7 +29,7 @@ def _build_randomized_blockchain(self, *, utxo_index=False):
         tx1.weight = 2.0
         tx1.parents = manager.get_new_tx_parents()
         tx1.timestamp = int(self.clock.seconds())
-        tx1.resolve()
+        manager.cpu_mining_service.resolve(tx1)
         assert manager.propagate_tx(tx1, False)
 
         tx2 = manager.wallet.prepare_transaction_compute_inputs(Transaction, outputs, manager.tx_storage)
@@ -37,13 +37,13 @@ def _build_randomized_blockchain(self, *, utxo_index=False):
         tx2.parents = [tx1.hash] + manager.get_new_tx_parents()[1:]
         self.assertIn(tx1.hash, tx2.parents)
         tx2.timestamp = int(self.clock.seconds()) + 1
-        tx2.resolve()
+        manager.cpu_mining_service.resolve(tx2)
         assert manager.propagate_tx(tx2, False)
 
         tx3 = Transaction.create_from_struct(tx2.get_struct())
         tx3.weight = 3.0
         tx3.parents = tx1.parents
-        tx3.resolve()
+        manager.cpu_mining_service.resolve(tx3)
         assert manager.propagate_tx(tx3, False)
 
         for _ in range(100):
diff --git a/tests/tx/test_multisig.py b/tests/tx/test_multisig.py
index 82e257052..b9dea1f18 100644
--- a/tests/tx/test_multisig.py
+++ b/tests/tx/test_multisig.py
@@ -72,7 +72,7 @@ def test_spend_multisig(self):
         tx1.weight = 10
         tx1.parents = self.manager.get_new_tx_parents()
         tx1.timestamp = int(self.clock.seconds())
-        tx1.resolve()
+        self.manager.cpu_mining_service.resolve(tx1)
         self.manager.propagate_tx(tx1)
         self.clock.advance(10)
 
@@ -104,13 +104,13 @@ def test_spend_multisig(self):
         input_data = MultiSig.create_input_data(self.redeem_script, signatures)
         tx.inputs[0].data = input_data
 
-        tx.resolve()
+        self.manager.cpu_mining_service.resolve(tx)
         # Transaction is still locked
         self.assertFalse(self.manager.propagate_tx(tx))
 
         self.clock.advance(6)
         tx.timestamp = int(self.clock.seconds())
-        tx.resolve()
+        self.manager.cpu_mining_service.resolve(tx)
 
         # First we try to propagate with a P2PKH input
         private_key_obj = get_private_key_from_bytes(bytes.fromhex(self.private_keys[0]), password=b'1234')
@@ -119,7 +119,7 @@ def test_spend_multisig(self):
         p2pkh_input_data = P2PKH.create_input_data(public_key_compressed, signatures[0])
         tx2 = Transaction.create_from_struct(tx.get_struct())
         tx2.inputs[0].data = p2pkh_input_data
-        tx2.resolve()
+        self.manager.cpu_mining_service.resolve(tx2)
         self.assertFalse(self.manager.propagate_tx(tx2))
 
         # Now we propagate the correct
diff --git a/tests/tx/test_reward_lock.py b/tests/tx/test_reward_lock.py
index ceb27b90f..7f853a338 100644
--- a/tests/tx/test_reward_lock.py
+++ b/tests/tx/test_reward_lock.py
@@ -37,7 +37,7 @@ def _add_reward_block(self):
         reward_block = self.manager.generate_mining_block(
             address=get_address_from_public_key(self.genesis_public_key)
         )
-        reward_block.resolve()
+        self.manager.cpu_mining_service.resolve(reward_block)
         self.assertTrue(self.manager.propagate_tx(reward_block))
         # XXX: calculate unlock height AFTER adding the block so the height is correctly calculated
         unlock_height = reward_block.get_metadata().height + settings.REWARD_SPEND_MIN_BLOCKS + 1
@@ -60,7 +60,7 @@ def _spend_reward_tx(self, manager, reward_block):
         data_to_sign = tx.get_sighash_all()
         public_bytes, signature = self.wallet.get_input_aux_data(data_to_sign, self.genesis_private_key)
         input_.data = P2PKH.create_input_data(public_bytes, signature)
-        tx.resolve()
+        self.manager.cpu_mining_service.resolve(tx)
         tx.update_initial_metadata(save=False)
         return tx
 
@@ -160,7 +160,7 @@ def test_mempool_tx_invalid_after_reorg(self):
         tb0 = self.manager.make_custom_block_template(block_to_replace.parents[0], block_to_replace.parents[1:])
         b0 = tb0.generate_mining_block(self.manager.rng, storage=self.manager.tx_storage)
         b0.weight = 10
-        b0.resolve()
+        self.manager.cpu_mining_service.resolve(b0)
         self.manager.verification_service.verify(b0)
         self.manager.propagate_tx(b0, fails_silently=False)
 
@@ -187,7 +187,7 @@ def test_classic_reward_lock_timestamp_expected_to_fail(self):
         # be greater, so it'll fail
         tx = self._spend_reward_tx(self.manager, reward_block)
         tx.timestamp = blocks[-1].timestamp
-        tx.resolve()
+        self.manager.cpu_mining_service.resolve(tx)
         self.assertEqual(tx.get_metadata().min_height, unlock_height)
         with self.assertRaises(RewardLocked):
             self.manager.verification_service.verify(tx)
diff --git a/tests/tx/test_timelock.py b/tests/tx/test_timelock.py
index ed85a9396..af0d5f602 100644
--- a/tests/tx/test_timelock.py
+++ b/tests/tx/test_timelock.py
@@ -41,7 +41,7 @@ def test_timelock(self):
         tx1.weight = 10
         tx1.parents = self.manager.get_new_tx_parents()
         tx1.timestamp = int(self.clock.seconds())
-        tx1.resolve()
+        self.manager.cpu_mining_service.resolve(tx1)
         self.manager.propagate_tx(tx1)
 
         self.assertEqual(self.manager.wallet.balance[settings.HATHOR_TOKEN_UID],
@@ -60,7 +60,7 @@ def test_timelock(self):
         tx2.weight = 10
         tx2.parents = self.manager.get_new_tx_parents()
         tx2.timestamp = int(self.clock.seconds())
-        tx2.resolve()
+        self.manager.cpu_mining_service.resolve(tx2)
         propagated = self.manager.propagate_tx(tx2)
 
         self.assertEqual(self.manager.wallet.balance[settings.HATHOR_TOKEN_UID],
@@ -80,7 +80,7 @@ def test_timelock(self):
         tx3.weight = 10
         tx3.parents = self.manager.get_new_tx_parents()
         tx3.timestamp = int(self.clock.seconds())
-        tx3.resolve()
+        self.manager.cpu_mining_service.resolve(tx3)
         propagated = self.manager.propagate_tx(tx3, False)
         self.assertEqual(self.manager.wallet.balance[settings.HATHOR_TOKEN_UID],
                          WalletBalance(500, sum(blocks_tokens) - 500 - 700))
@@ -100,7 +100,7 @@ def test_timelock(self):
         tx4.weight = 10
         tx4.parents = self.manager.get_new_tx_parents()
         tx4.timestamp = int(self.clock.seconds())
-        tx4.resolve()
+        self.manager.cpu_mining_service.resolve(tx4)
         propagated = self.manager.propagate_tx(tx4, False)
         self.assertEqual(self.manager.wallet.balance[settings.HATHOR_TOKEN_UID],
                          WalletBalance(500, sum(blocks_tokens[:3])))
@@ -108,7 +108,7 @@ def test_timelock(self):
 
         self.clock.advance(8)
         tx2.timestamp = int(self.clock.seconds())
-        tx2.resolve()
+        self.manager.cpu_mining_service.resolve(tx2)
         propagated = self.manager.propagate_tx(tx2, False)
         self.assertEqual(self.manager.wallet.balance[settings.HATHOR_TOKEN_UID],
                          WalletBalance(0, sum(blocks_tokens[:3])))
@@ -131,7 +131,7 @@ def test_choose_inputs(self):
         tx1.weight = 10
         tx1.parents = self.manager.get_new_tx_parents()
         tx1.timestamp = int(self.clock.seconds())
-        tx1.resolve()
+        self.manager.cpu_mining_service.resolve(tx1)
         self.manager.propagate_tx(tx1)
         self.clock.advance(1)
 
@@ -149,7 +149,7 @@ def test_choose_inputs(self):
         tx2.weight = 10
         tx2.parents = self.manager.get_new_tx_parents()
         tx2.timestamp = int(self.clock.seconds())
-        tx2.resolve()
+        self.manager.cpu_mining_service.resolve(tx2)
         self.manager.propagate_tx(tx2)
 
         self.assertEqual(self.manager.wallet.balance[settings.HATHOR_TOKEN_UID],
diff --git a/tests/tx/test_tips.py b/tests/tx/test_tips.py
index 6242bebf5..61267888a 100644
--- a/tests/tx/test_tips.py
+++ b/tests/tx/test_tips.py
@@ -53,7 +53,7 @@ def test_tips_winner(self):
 
         tx3 = Transaction.create_from_struct(tx2.get_struct())
         tx3.parents = [tx2.parents[1], tx2.parents[0]]
-        tx3.resolve()
+        self.manager.cpu_mining_service.resolve(tx3)
 
         # Propagate a conflicting twin transaction with tx2
         self.manager.propagate_tx(tx3)
@@ -69,7 +69,7 @@ def test_tips_winner(self):
         # Creating a new block that confirms tx3, then is will become valid and voiding tx2
         new_block = add_new_block(self.manager, propagate=False)
         new_block.parents = [new_block.parents[0], tx1.hash, tx3.hash]
-        new_block.resolve()
+        self.manager.cpu_mining_service.resolve(new_block)
         self.manager.verification_service.verify(new_block)
         self.manager.propagate_tx(new_block, fails_silently=False)
 
@@ -138,7 +138,7 @@ def test_tips_twin(self):
         # A new tx with custom parents, so tx3 and tx4 will become two tips
         tx4 = add_new_transactions(self.manager, 1, advance_clock=1, propagate=False)[0]
         tx4.parents = [tx1.hash, tx2.hash]
-        tx4.resolve()
+        self.manager.cpu_mining_service.resolve(tx4)
         self.manager.propagate_tx(tx4, fails_silently=False)
         self.manager.reactor.advance(10)
         self.assertCountEqual(self.get_tips(), set([tx4.hash, tx3.hash]))
@@ -146,7 +146,7 @@ def test_tips_twin(self):
         # A twin tx with tx4, that will be voided initially, then won't change the tips
         tx5 = Transaction.create_from_struct(tx4.get_struct())
         tx5.parents = [tx2.hash, tx3.hash]
-        tx5.resolve()
+        self.manager.cpu_mining_service.resolve(tx5)
         self.manager.propagate_tx(tx5)
         self.manager.reactor.advance(10)
 
@@ -158,7 +158,7 @@ def test_tips_twin(self):
         # add new tx confirming tx5, which will become valid and tx4 becomes voided
         tx6 = add_new_transactions(self.manager, 1, advance_clock=1, propagate=False)[0]
         tx6.parents = [tx5.hash, tx2.hash]
-        tx6.resolve()
+        self.manager.cpu_mining_service.resolve(tx6)
         self.manager.propagate_tx(tx6, fails_silently=False)
         self.manager.reactor.advance(10)
         self.assertIsNotNone(tx4.get_metadata(force_reload=True).voided_by)
diff --git a/tests/tx/test_tokens.py b/tests/tx/test_tokens.py
index b3b036f2f..f4626e3f8 100644
--- a/tests/tx/test_tokens.py
+++ b/tests/tx/test_tokens.py
@@ -52,7 +52,7 @@ def test_tokens_in_block(self):
             weight=1,  # low weight so we don't waste time with PoW
             storage=self.manager.tx_storage)
 
-        block.resolve()
+        self.manager.cpu_mining_service.resolve(block)
         with self.assertRaises(BlockWithTokensError):
             self.manager.verification_service.verify(block)
 
@@ -72,7 +72,7 @@ def test_tx_token_outputs(self):
         data_to_sign = tx.get_sighash_all()
         public_bytes, signature = self.manager.wallet.get_input_aux_data(data_to_sign, self.genesis_private_key)
         tx.inputs[0].data = P2PKH.create_input_data(public_bytes, signature)
-        tx.resolve()
+        self.manager.cpu_mining_service.resolve(tx)
         with self.assertRaises(InvalidToken):
             self.manager.verification_service.verify(tx)
 
@@ -82,7 +82,7 @@ def test_tx_token_outputs(self):
         data_to_sign = tx.get_sighash_all()
         public_bytes, signature = self.manager.wallet.get_input_aux_data(data_to_sign, self.genesis_private_key)
         tx.inputs[0].data = P2PKH.create_input_data(public_bytes, signature)
-        tx.resolve()
+        self.manager.cpu_mining_service.resolve(tx)
         with self.assertRaises(InvalidToken):
             self.manager.verification_service.verify(tx)
 
@@ -92,7 +92,7 @@ def test_tx_token_outputs(self):
         data_to_sign = tx.get_sighash_all()
         public_bytes, signature = self.manager.wallet.get_input_aux_data(data_to_sign, self.genesis_private_key)
         tx.inputs[0].data = P2PKH.create_input_data(public_bytes, signature)
-        tx.resolve()
+        self.manager.cpu_mining_service.resolve(tx)
         with self.assertRaises(InvalidToken):
             self.manager.verification_service.verify(tx)
 
@@ -113,7 +113,7 @@ def test_token_transfer(self):
         data_to_sign = tx2.get_sighash_all()
         public_bytes, signature = wallet.get_input_aux_data(data_to_sign, wallet.get_private_key(self.address_b58))
         tx2.inputs[0].data = P2PKH.create_input_data(public_bytes, signature)
-        tx2.resolve()
+        self.manager.cpu_mining_service.resolve(tx2)
         self.manager.verification_service.verify(tx2)
 
         # missing tokens
@@ -123,7 +123,7 @@ def test_token_transfer(self):
         data_to_sign = tx3.get_sighash_all()
         public_bytes, signature = wallet.get_input_aux_data(data_to_sign, wallet.get_private_key(self.address_b58))
         tx3.inputs[0].data = P2PKH.create_input_data(public_bytes, signature)
-        tx3.resolve()
+        self.manager.cpu_mining_service.resolve(tx3)
         with self.assertRaises(InputOutputMismatch):
             self.manager.verification_service.verify(tx3)
 
@@ -156,7 +156,7 @@ def test_token_mint(self):
         data = P2PKH.create_input_data(public_bytes, signature)
         tx2.inputs[0].data = data
         tx2.inputs[1].data = data
-        tx2.resolve()
+        self.manager.cpu_mining_service.resolve(tx2)
         self.manager.verification_service.verify(tx2)
         self.manager.propagate_tx(tx2)
         self.run_to_completion()
@@ -191,7 +191,7 @@ def test_token_mint(self):
         public_bytes, signature = wallet.get_input_aux_data(data_to_sign, wallet.get_private_key(self.address_b58))
         data = P2PKH.create_input_data(public_bytes, signature)
         tx3.inputs[0].data = data
-        tx3.resolve()
+        self.manager.cpu_mining_service.resolve(tx3)
         with self.assertRaises(InputOutputMismatch):
             self.manager.verification_service.verify(tx3)
 
@@ -217,7 +217,7 @@ def test_token_mint(self):
         data = P2PKH.create_input_data(public_bytes, signature)
         tx4.inputs[0].data = data
         tx4.inputs[1].data = data
-        tx4.resolve()
+        self.manager.cpu_mining_service.resolve(tx4)
         with self.assertRaises(InputOutputMismatch):
             self.manager.verification_service.verify(tx4)
 
@@ -229,7 +229,7 @@ def test_token_mint(self):
         data_to_sign = tx5.get_sighash_all()
         public_bytes, signature = wallet.get_input_aux_data(data_to_sign, wallet.get_private_key(self.address_b58))
         tx5.inputs[0].data = P2PKH.create_input_data(public_bytes, signature)
-        tx5.resolve()
+        self.manager.cpu_mining_service.resolve(tx5)
         with self.assertRaises(InputOutputMismatch):
             self.manager.verification_service.verify(tx5)
 
@@ -263,7 +263,7 @@ def test_token_melt(self):
         data = P2PKH.create_input_data(public_bytes, signature)
         tx2.inputs[0].data = data
         tx2.inputs[1].data = data
-        tx2.resolve()
+        self.manager.cpu_mining_service.resolve(tx2)
         self.manager.verification_service.verify(tx2)
         self.manager.propagate_tx(tx2)
         self.run_to_completion()
@@ -302,7 +302,7 @@ def test_token_melt(self):
         data = P2PKH.create_input_data(public_bytes, signature)
         tx3.inputs[0].data = data
         tx3.inputs[1].data = data
-        tx3.resolve()
+        self.manager.cpu_mining_service.resolve(tx3)
         with self.assertRaises(InputOutputMismatch):
             self.manager.verification_service.verify(tx3)
 
@@ -317,7 +317,7 @@ def test_token_melt(self):
         data = P2PKH.create_input_data(public_bytes, signature)
         tx4.inputs[0].data = data
         tx4.inputs[1].data = data
-        tx4.resolve()
+        self.manager.cpu_mining_service.resolve(tx4)
         with self.assertRaises(InputOutputMismatch):
             self.manager.verification_service.verify(tx4)
 
@@ -336,7 +336,7 @@ def test_token_transfer_authority(self):
         data_to_sign = tx2.get_sighash_all()
         public_bytes, signature = wallet.get_input_aux_data(data_to_sign, wallet.get_private_key(self.address_b58))
         tx2.inputs[0].data = P2PKH.create_input_data(public_bytes, signature)
-        tx2.resolve()
+        self.manager.cpu_mining_service.resolve(tx2)
         with self.assertRaises(InvalidToken):
             self.manager.verification_service.verify(tx2)
 
@@ -348,7 +348,7 @@ def test_token_transfer_authority(self):
         data_to_sign = tx3.get_sighash_all()
         public_bytes, signature = wallet.get_input_aux_data(data_to_sign, wallet.get_private_key(self.address_b58))
         tx3.inputs[0].data = P2PKH.create_input_data(public_bytes, signature)
-        tx3.resolve()
+        self.manager.cpu_mining_service.resolve(tx3)
         with self.assertRaises(InvalidToken):
             self.manager.verification_service.verify(tx3)
 
@@ -402,7 +402,7 @@ def test_token_index_with_conflict(self, mint_amount=0):
         tx2.inputs[0].data = data
         tx2.inputs[1].data = data
         tx2.inputs[2].data = data
-        tx2.resolve()
+        self.manager.cpu_mining_service.resolve(tx2)
         self.manager.verification_service.verify(tx2)
         self.manager.propagate_tx(tx2)
         self.run_to_completion()
@@ -422,7 +422,7 @@ def test_token_index_with_conflict(self, mint_amount=0):
         tx3 = Transaction.create_from_struct(tx2.get_struct())
         tx3.parents = [tx.parents[1], tx.parents[0]]
         tx3.weight = 3
-        tx3.resolve()
+        self.manager.cpu_mining_service.resolve(tx3)
         self.assertNotEqual(tx3.hash, tx2.hash)
         self.assertTrue(tx3.weight > tx2.weight)
         self.manager.propagate_tx(tx3)
@@ -447,7 +447,7 @@ def update_tx(tx):
             data_to_sign = tx.get_sighash_all()
             public_bytes, signature = self.manager.wallet.get_input_aux_data(data_to_sign, self.genesis_private_key)
             tx.inputs[0].data = P2PKH.create_input_data(public_bytes, signature)
-            tx.resolve()
+            self.manager.cpu_mining_service.resolve(tx)
 
         # test token name and symbol
         tx = create_tokens(self.manager, self.address_b58)
@@ -540,7 +540,7 @@ def test_unknown_authority(self):
         data = P2PKH.create_input_data(public_bytes, signature)
         tx2.inputs[0].data = data
         tx2.inputs[1].data = data
-        tx2.resolve()
+        self.manager.cpu_mining_service.resolve(tx2)
         with self.assertRaises(InvalidToken):
             self.manager.verification_service.verify(tx2)
 
@@ -593,7 +593,7 @@ def test_block_with_htr_authority(self):
             weight=1,  # low weight so we don't waste time with PoW
             storage=self.manager.tx_storage)
 
-        block.resolve()
+        self.manager.cpu_mining_service.resolve(block)
         with self.assertRaises(InvalidToken):
             self.manager.verification_service.verify(block)
 
diff --git a/tests/tx/test_tx.py b/tests/tx/test_tx.py
index d12c59808..f276f2923 100644
--- a/tests/tx/test_tx.py
+++ b/tests/tx/test_tx.py
@@ -217,7 +217,7 @@ def test_block_inputs(self):
 
         block.inputs = tx_inputs
 
-        block.resolve()
+        self.manager.cpu_mining_service.resolve(block)
 
         with self.assertRaises(BlockWithInputs):
             self.manager.verification_service.verify(block)
@@ -387,21 +387,21 @@ def test_tx_number_parents(self):
         tx.inputs[0].data = P2PKH.create_input_data(public_bytes, signature)
 
         # in first test, only with 1 parent
-        tx.resolve()
+        self.manager.cpu_mining_service.resolve(tx)
         with self.assertRaises(IncorrectParents):
             self.manager.verification_service.verify(tx)
 
         # test with 3 parents
         parents = [tx.hash for tx in self.genesis]
         tx.parents = parents
-        tx.resolve()
+        self.manager.cpu_mining_service.resolve(tx)
         with self.assertRaises(IncorrectParents):
             self.manager.verification_service.verify(tx)
 
         # 2 parents, 1 tx and 1 block
         parents = [self.genesis_txs[0].hash, self.genesis_blocks[0].hash]
         tx.parents = parents
-        tx.resolve()
+        self.manager.cpu_mining_service.resolve(tx)
         with self.assertRaises(IncorrectParents):
             self.manager.verification_service.verify(tx)
 
@@ -420,7 +420,7 @@ def test_block_unknown_parent(self):
             weight=1,  # low weight so we don't waste time with PoW
             storage=self.tx_storage)
 
-        block.resolve()
+        self.manager.cpu_mining_service.resolve(block)
         with self.assertRaises(ParentDoesNotExist):
             self.manager.verification_service.verify(block)
 
@@ -438,7 +438,7 @@ def test_block_number_parents(self):
             weight=1,  # low weight so we don't waste time with PoW
             storage=self.tx_storage)
 
-        block.resolve()
+        self.manager.cpu_mining_service.resolve(block)
         with self.assertRaises(IncorrectParents):
             self.manager.verification_service.verify(block)
 
@@ -461,7 +461,7 @@ def test_tx_inputs_out_of_range(self):
         tx.inputs[0].data = data
 
         # test with an inexistent index
-        tx.resolve()
+        self.manager.cpu_mining_service.resolve(tx)
         with self.assertRaises(InexistentInput):
             self.manager.verification_service.verify(tx)
 
@@ -469,7 +469,7 @@ def test_tx_inputs_out_of_range(self):
         _input = [TxInput(genesis_block.hash, len(genesis_block.outputs), data)]
         tx.inputs = _input
         # test with an inexistent index
-        tx.resolve()
+        self.manager.cpu_mining_service.resolve(tx)
         with self.assertRaises(InexistentInput):
             self.manager.verification_service.verify(tx)
 
@@ -477,7 +477,7 @@ def test_tx_inputs_out_of_range(self):
         random_bytes = bytes.fromhex('0000184e64683b966b4268f387c269915cc61f6af5329823a93e3696cb0fe902')
         _input = [TxInput(random_bytes, 3, data)]
         tx.inputs = _input
-        tx.resolve()
+        self.manager.cpu_mining_service.resolve(tx)
         with self.assertRaises(InexistentInput):
             self.manager.verification_service.verify(tx)
 
@@ -500,7 +500,7 @@ def test_tx_inputs_conflict(self):
         public_bytes, signature = self.wallet.get_input_aux_data(data_to_sign, self.genesis_private_key)
         _input.data = P2PKH.create_input_data(public_bytes, signature)
 
-        tx.resolve()
+        self.manager.cpu_mining_service.resolve(tx)
         with self.assertRaises(ConflictingInputs):
             self.manager.verification_service.verify(tx)
 
@@ -522,7 +522,7 @@ def test_regular_tx(self):
         public_bytes, signature = self.wallet.get_input_aux_data(data_to_sign, self.genesis_private_key)
         _input.data = P2PKH.create_input_data(public_bytes, signature)
 
-        tx.resolve()
+        self.manager.cpu_mining_service.resolve(tx)
         self.manager.verification_service.verify(tx)
 
     def test_tx_weight_too_high(self):
@@ -601,7 +601,7 @@ def test_tx_duplicated_parents(self):
         public_bytes, signature = self.wallet.get_input_aux_data(data_to_sign, self.genesis_private_key)
         _input.data = P2PKH.create_input_data(public_bytes, signature)
 
-        tx.resolve()
+        self.manager.cpu_mining_service.resolve(tx)
         with self.assertRaises(DuplicatedParents):
             self.manager.verification_service.verify(tx)
 
@@ -641,20 +641,20 @@ def test_propagation_error(self):
         # 2. propagate block with weight 1
         block = manager.generate_mining_block()
         block.weight = 1
-        block.resolve()
+        self.manager.cpu_mining_service.resolve(block)
         self.assertFalse(manager.propagate_tx(block))
 
         # 3. propagate block with wrong amount of tokens
         block = manager.generate_mining_block()
         output = TxOutput(1, block.outputs[0].script)
         block.outputs = [output]
-        block.resolve()
+        self.manager.cpu_mining_service.resolve(block)
         self.assertFalse(manager.propagate_tx(block))
 
         # 4. propagate block from the future
         block = manager.generate_mining_block()
         block.timestamp = int(self.clock.seconds()) + self._settings.MAX_FUTURE_TIMESTAMP_ALLOWED + 100
-        block.resolve(update_time=False)
+        manager.cpu_mining_service.resolve(block, update_time=False)
         self.assertFalse(manager.propagate_tx(block))
 
     def test_tx_methods(self):
@@ -719,7 +719,7 @@ def test_block_big_nonce(self):
         start = 1 << (8 * 12)
         end = start + 1 << (8*4)
 
-        hash = block.start_mining(start, end)
+        hash = self.manager.cpu_mining_service.start_mining(block, start=start, end=end)
         assert hash is not None
 
         block.hash = hash
@@ -803,7 +803,7 @@ def test_output_value(self):
         _input = TxInput(random_bytes, 0, random_bytes)
         tx = Transaction(inputs=[_input], outputs=[output], parents=parents, storage=self.tx_storage)
         with self.assertRaises(InvalidOutputValue):
-            tx.resolve()
+            self.manager.cpu_mining_service.resolve(tx)
 
         # 'Manually resolving', to validate verify method
         tx.hash = bytes.fromhex('012cba011be3c29f1c406f9015e42698b97169dbc6652d1f5e4d5c5e83138858')
@@ -944,7 +944,7 @@ def test_wallet_index(self):
         public_bytes, signature = self.wallet.get_input_aux_data(data_to_sign, self.genesis_private_key)
         _input.data = P2PKH.create_input_data(public_bytes, signature)
 
-        tx.resolve()
+        self.manager.cpu_mining_service.resolve(tx)
         self.manager.propagate_tx(tx)
 
         # This transaction has an output to address_b58, so we need one more element on the index
@@ -968,7 +968,7 @@ def test_wallet_index(self):
         public_bytes, signature = self.wallet.get_input_aux_data(data_to_sign, self.genesis_private_key)
         input1.data = P2PKH.create_input_data(public_bytes, signature)
 
-        tx2.resolve()
+        self.manager.cpu_mining_service.resolve(tx2)
         self.manager.propagate_tx(tx2)
 
         # tx2 has two outputs, for address_b58 and new_address_b58
@@ -991,7 +991,7 @@ def test_wallet_index(self):
         public_bytes, signature = self.wallet.get_input_aux_data(data_to_sign, self.genesis_private_key)
         input2.data = P2PKH.create_input_data(public_bytes, signature)
 
-        tx3.resolve()
+        self.manager.cpu_mining_service.resolve(tx3)
         self.manager.propagate_tx(tx3)
 
         # tx3 has one output, for another new address (output3_address_b58) and it's spending an output of address_b58
diff --git a/tests/tx/test_tx_serialization.py b/tests/tx/test_tx_serialization.py
index 0c72ae0f6..6d2451014 100644
--- a/tests/tx/test_tx_serialization.py
+++ b/tests/tx/test_tx_serialization.py
@@ -30,7 +30,7 @@ def setUp(self):
         self.tx1.weight = 10
         self.tx1.parents = self.manager.get_new_tx_parents()
         self.tx1.timestamp = int(self.clock.seconds())
-        self.tx1.resolve()
+        self.manager.cpu_mining_service.resolve(self.tx1)
         self.manager.propagate_tx(self.tx1)
 
         # Change of parents only, so it's a twin.
@@ -38,7 +38,7 @@ def setUp(self):
         self.tx2 = Transaction.create_from_struct(self.tx1.get_struct())
         self.tx2.parents = [self.tx1.parents[1], self.tx1.parents[0]]
         self.tx2.weight = 9
-        self.tx2.resolve()
+        self.manager.cpu_mining_service.resolve(self.tx2)
 
         # Propagate a conflicting twin transaction
         self.manager.propagate_tx(self.tx2)
diff --git a/tests/tx/test_tx_storage.py b/tests/tx/test_tx_storage.py
index d8a6aa848..4de80157a 100644
--- a/tests/tx/test_tx_storage.py
+++ b/tests/tx/test_tx_storage.py
@@ -63,7 +63,7 @@ def setUp(self):
         previous_timestamp = artifacts.settings.GENESIS_TX2_TIMESTAMP
         self.block = Block(timestamp=previous_timestamp + 1, weight=12, outputs=[output], parents=block_parents,
                            nonce=100781, storage=self.tx_storage)
-        self.block.resolve()
+        self.manager.cpu_mining_service.resolve(self.block)
         self.manager.verification_service.verify(self.block)
         self.block.get_metadata().validation = ValidationState.FULL
 
@@ -80,7 +80,7 @@ def setUp(self):
             timestamp=previous_timestamp + 2, weight=10, nonce=932049, inputs=[tx_input], outputs=[output],
             tokens=[bytes.fromhex('0023be91834c973d6a6ddd1a0ae411807b7c8ef2a015afb5177ee64b666ce602')],
             parents=tx_parents, storage=self.tx_storage)
-        self.tx.resolve()
+        self.manager.cpu_mining_service.resolve(self.tx)
         self.tx.get_metadata().validation = ValidationState.FULL
 
         # Disable weakref to test the internal methods. Otherwise, most methods return objects from weakref.
@@ -500,12 +500,12 @@ def test_token_list(self):
         self.validate_save(tx)
         # 2 token uids
         tx.tokens.append(bytes.fromhex('00001c5c0b69d13b05534c94a69b2c8272294e6b0c536660a3ac264820677024'))
-        tx.resolve()
+        self.manager.cpu_mining_service.resolve(tx)
         tx._metadata.hash = tx.hash
         self.validate_save(tx)
         # no tokens
         tx.tokens = []
-        tx.resolve()
+        self.manager.cpu_mining_service.resolve(tx)
         tx._metadata.hash = tx.hash
         self.validate_save(tx)
 
@@ -515,7 +515,7 @@ def _add_new_block(self, parents=None):
         if parents is not None:
             block.parents = parents
         block.weight = 10
-        self.assertTrue(block.resolve())
+        self.assertTrue(self.manager.cpu_mining_service.resolve(block))
         self.manager.verification_service.verify(block)
         self.manager.propagate_tx(block, fails_silently=False)
         self.reactor.advance(5)
diff --git a/tests/utils.py b/tests/utils.py
index 6a9403666..c71172070 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -18,6 +18,7 @@
 from hathor.event.model.event_data import TxData, TxMetadata
 from hathor.event.model.event_type import EventType
 from hathor.manager import HathorManager
+from hathor.mining.cpu_mining_service import CpuMiningService
 from hathor.transaction import BaseTransaction, Transaction, TxInput, TxOutput
 from hathor.transaction.scripts import P2PKH, HathorScript, Opcode, parse_address_script
 from hathor.transaction.token_creation_tx import TokenCreationTransaction
@@ -41,7 +42,7 @@ class NoCandidatesError(Exception):
     pass
 
 
-def resolve_block_bytes(block_bytes):
+def resolve_block_bytes(*, block_bytes: bytes, cpu_mining_service: CpuMiningService) -> bytes:
     """ From block bytes we create a block and resolve pow
         Return block bytes with hash and nonce after pow
         :rtype: bytes
@@ -49,7 +50,7 @@ def resolve_block_bytes(block_bytes):
     from hathor.transaction import Block
     block_bytes = base64.b64decode(block_bytes)
     block = Block.create_from_struct(block_bytes)
-    block.resolve()
+    cpu_mining_service.resolve(block)
     return block.get_struct()
 
 
@@ -124,7 +125,7 @@ def gen_custom_tx(manager: HathorManager, tx_inputs: list[tuple[BaseTransaction,
     tx2.weight = weight or 25
     tx2.timestamp += inc_timestamp
     if resolve:
-        tx2.resolve()
+        manager.cpu_mining_service.resolve(tx2)
     else:
         tx2.update_hash()
     return tx2
@@ -174,7 +175,7 @@ def gen_new_double_spending(manager: HathorManager, *, use_same_parents: bool =
     else:
         tx2.parents = manager.get_new_tx_parents(tx2.timestamp)
 
-    tx2.resolve()
+    manager.cpu_mining_service.resolve(tx2)
     return tx2
 
 
@@ -200,7 +201,7 @@ def gen_new_tx(manager, address, value, verify=True):
 
     tx.weight = 1
     tx.parents = manager.get_new_tx_parents(tx.timestamp)
-    tx.resolve()
+    manager.cpu_mining_service.resolve(tx)
     if verify:
         manager.verification_service.verify(tx)
     return tx
@@ -263,7 +264,7 @@ def add_new_block(manager, advance_clock=None, *, parent_block_hash=None,
     block = manager.generate_mining_block(parent_block_hash=parent_block_hash, data=data, address=address)
     if weight is not None:
         block.weight = weight
-    block.resolve()
+    manager.cpu_mining_service.resolve(block)
     manager.verification_service.validate_full(block)
     if propagate:
         manager.propagate_tx(block, fails_silently=False)
@@ -550,7 +551,7 @@ def create_tokens(manager: 'HathorManager', address_b58: Optional[str] = None, m
     for input_ in tx.inputs:
         input_.data = P2PKH.create_input_data(public_bytes, signature)
 
-    tx.resolve()
+    manager.cpu_mining_service.resolve(tx)
     if propagate:
         manager.verification_service.verify(tx)
         manager.propagate_tx(tx, fails_silently=False)
@@ -638,7 +639,7 @@ def add_tx_with_data_script(manager: 'HathorManager', data: list[str], propagate
     for input_ in tx.inputs:
         input_.data = P2PKH.create_input_data(public_bytes, signature)
 
-    tx.resolve()
+    manager.cpu_mining_service.resolve(tx)
 
     if propagate:
         manager.verification_service.verify(tx)
diff --git a/tests/wallet/test_balance_update.py b/tests/wallet/test_balance_update.py
index 15aad3e6b..dc65ba6b0 100644
--- a/tests/wallet/test_balance_update.py
+++ b/tests/wallet/test_balance_update.py
@@ -38,7 +38,7 @@ def setUp(self):
         self.tx1.weight = 10
         self.tx1.parents = self.manager.get_new_tx_parents()
         self.tx1.timestamp = int(self.clock.seconds())
-        self.tx1.resolve()
+        self.manager.cpu_mining_service.resolve(self.tx1)
         self.manager.propagate_tx(self.tx1)
         self.run_to_completion()
 
@@ -54,7 +54,7 @@ def test_balance_update1(self):
         tx2 = Transaction.create_from_struct(self.tx1.get_struct())
         tx2.parents = [self.tx1.parents[1], self.tx1.parents[0]]
         tx2.weight = 9
-        tx2.resolve()
+        self.manager.cpu_mining_service.resolve(tx2)
 
         # Propagate a conflicting twin transaction
         self.manager.propagate_tx(tx2)
@@ -100,7 +100,7 @@ def test_balance_update2(self):
         # Same weight, so both will be voided then the balance increases
         tx2 = Transaction.create_from_struct(self.tx1.get_struct())
         tx2.parents = [self.tx1.parents[1], self.tx1.parents[0]]
-        tx2.resolve()
+        self.manager.cpu_mining_service.resolve(tx2)
 
         # Propagate a conflicting twin transaction
         self.manager.propagate_tx(tx2)
@@ -129,7 +129,7 @@ def test_balance_update3(self):
         tx2 = Transaction.create_from_struct(self.tx1.get_struct())
         tx2.parents = [self.tx1.parents[1], self.tx1.parents[0]]
         tx2.weight = 13
-        tx2.resolve()
+        self.manager.cpu_mining_service.resolve(tx2)
 
         # Propagate a conflicting twin transaction
         self.manager.propagate_tx(tx2)
@@ -165,7 +165,7 @@ def test_balance_update4(self):
         tx2.weight = 10
         tx2.parents = [self.tx1.hash, self.tx1.parents[0]]
         tx2.timestamp = int(self.clock.seconds())
-        tx2.resolve()
+        self.manager.cpu_mining_service.resolve(tx2)
         self.manager.propagate_tx(tx2)
         self.run_to_completion()
 
@@ -184,7 +184,7 @@ def test_balance_update4(self):
         # Change of parents only, so it's a twin.
         tx3 = Transaction.create_from_struct(tx2.get_struct())
         tx3.parents = [tx2.parents[1], tx2.parents[0]]
-        tx3.resolve()
+        self.manager.cpu_mining_service.resolve(tx3)
 
         # Propagate a conflicting twin transaction
         self.manager.propagate_tx(tx3)
@@ -221,12 +221,12 @@ def test_balance_update5(self):
         tx2.weight = 10
         tx2.parents = [self.tx1.hash, self.tx1.parents[0]]
         tx2.timestamp = int(self.clock.seconds())
-        tx2.resolve()
+        self.manager.cpu_mining_service.resolve(tx2)
 
         # Change of parents only, so it's a twin.
         tx3 = Transaction.create_from_struct(self.tx1.get_struct())
         tx3.parents = [self.tx1.parents[1], self.tx1.parents[0]]
-        tx3.resolve()
+        self.manager.cpu_mining_service.resolve(tx3)
 
         # Propagate a conflicting twin transaction
         self.manager.propagate_tx(tx2)
@@ -258,7 +258,7 @@ def test_balance_update6(self):
         # Change of parents only, so it's a twin.
         tx2 = Transaction.create_from_struct(self.tx1.get_struct())
         tx2.parents = [self.tx1.parents[1], self.tx1.parents[0]]
-        tx2.resolve()
+        self.manager.cpu_mining_service.resolve(tx2)
 
         address = self.get_address(0)
         value = 100
@@ -271,7 +271,7 @@ def test_balance_update6(self):
         tx3.weight = 10
         tx3.parents = [self.tx1.hash, self.tx1.parents[0]]
         tx3.timestamp = int(self.clock.seconds())
-        tx3.resolve()
+        self.manager.cpu_mining_service.resolve(tx3)
 
         # Propagate a conflicting twin transaction
         self.manager.propagate_tx(tx2)
@@ -301,13 +301,13 @@ def test_balance_update7(self):
         tx2.weight = 10
         tx2.parents = [self.tx1.hash, self.tx1.parents[0]]
         tx2.timestamp = int(self.clock.seconds())
-        tx2.resolve()
+        self.manager.cpu_mining_service.resolve(tx2)
 
         # Change of parents only, so it's a twin.
         tx3 = Transaction.create_from_struct(self.tx1.get_struct())
         tx3.parents = [self.tx1.parents[1], self.tx1.parents[0]]
         tx3.weight = 14
-        tx3.resolve()
+        self.manager.cpu_mining_service.resolve(tx3)
 
         # Propagate a conflicting twin transaction
         self.manager.propagate_tx(tx2)
@@ -341,7 +341,7 @@ def test_balance_update_twin_tx(self):
         tx2.weight = 10
         tx2.parents = self.manager.get_new_tx_parents()
         tx2.timestamp = int(self.clock.seconds())
-        tx2.resolve()
+        self.manager.cpu_mining_service.resolve(tx2)
         self.manager.propagate_tx(tx2)
         self.run_to_completion()
 
@@ -352,7 +352,7 @@ def test_balance_update_twin_tx(self):
         tx3.weight = 10
         tx3.parents = self.manager.get_new_tx_parents()
         tx3.timestamp = int(self.clock.seconds())
-        tx3.resolve()
+        self.manager.cpu_mining_service.resolve(tx3)
         self.manager.propagate_tx(tx3)
         self.run_to_completion()
 
@@ -365,7 +365,7 @@ def test_balance_update_twin_tx(self):
         tx4.weight = 10
         tx4.parents = [tx3.hash, tx3.parents[0]]
         tx4.timestamp = int(self.clock.seconds())
-        tx4.resolve()
+        self.manager.cpu_mining_service.resolve(tx4)
         self.manager.propagate_tx(tx4)
         self.run_to_completion()
 
@@ -373,7 +373,7 @@ def test_balance_update_twin_tx(self):
         tx5 = Transaction.create_from_struct(tx4.get_struct())
         tx5.parents = [tx4.parents[1], tx4.parents[0]]
         tx5.weight = 10
-        tx5.resolve()
+        self.manager.cpu_mining_service.resolve(tx5)
 
         # Propagate a conflicting twin transaction
         self.manager.propagate_tx(tx5)
@@ -427,7 +427,7 @@ def test_tokens_balance(self):
                                       self.manager.wallet.get_private_key(address_b58)
                                   )
         tx2.inputs[0].data = P2PKH.create_input_data(public_bytes, signature)
-        tx2.resolve()
+        self.manager.cpu_mining_service.resolve(tx2)
         self.manager.verification_service.verify(tx2)
         self.manager.propagate_tx(tx2)
         self.run_to_completion()
diff --git a/tests/wallet/test_index.py b/tests/wallet/test_index.py
index f13b427f6..2ce9d6567 100644
--- a/tests/wallet/test_index.py
+++ b/tests/wallet/test_index.py
@@ -31,12 +31,12 @@ def test_twin_tx(self):
         tx1.weight = 10
         tx1.parents = self.manager.get_new_tx_parents()
         tx1.timestamp = int(self.clock.seconds())
-        tx1.resolve()
+        self.manager.cpu_mining_service.resolve(tx1)
 
         # Change of parents only, so it's a twin
         tx2 = Transaction.create_from_struct(tx1.get_struct())
         tx2.parents = [tx1.parents[1], tx1.parents[0]]
-        tx2.resolve()
+        self.manager.cpu_mining_service.resolve(tx2)
         self.assertNotEqual(tx1.hash, tx2.hash)
 
         self.manager.propagate_tx(tx1)
diff --git a/tests/wallet/test_wallet.py b/tests/wallet/test_wallet.py
index 5add4f3ad..a17861837 100644
--- a/tests/wallet/test_wallet.py
+++ b/tests/wallet/test_wallet.py
@@ -207,7 +207,7 @@ def test_create_token_transaction(self):
         tx2.storage = self.manager.tx_storage
         tx2.timestamp = tx.timestamp + 1
         tx2.parents = self.manager.get_new_tx_parents()
-        tx2.resolve()
+        self.manager.cpu_mining_service.resolve(tx2)
         self.manager.verification_service.verify(tx2)
 
         self.assertNotEqual(len(tx2.inputs), 0)
@@ -265,7 +265,7 @@ def test_maybe_spent_txs(self):
         tx2.parents = self.manager.get_new_tx_parents(tx2.timestamp)
         tx2.weight = 1
         tx2.timestamp = blocks[-1].timestamp + 1
-        tx2.resolve()
+        self.manager.cpu_mining_service.resolve(tx2)
         self.assertTrue(self.manager.on_new_tx(tx2, fails_silently=False))
         self.clock.advance(2)
         self.assertEqual(0, len(w.maybe_spent_txs[settings.HATHOR_TOKEN_UID]))