Skip to content

Commit f383165

Browse files
committed
chore: move simulator utils functions
1 parent 3794dd5 commit f383165

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+235
-206
lines changed

hathor/cli/events_simulator/scenario.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,15 @@ def simulate_only_load(simulator: 'Simulator', _manager: 'HathorManager') -> Non
4444

4545

4646
def simulate_single_chain_one_block(simulator: 'Simulator', manager: 'HathorManager') -> None:
47-
from tests.utils import add_new_blocks
47+
from hathor.utils.simulator import add_new_blocks
4848
add_new_blocks(manager, 1)
4949
simulator.run(60)
5050

5151

5252
def simulate_single_chain_blocks_and_transactions(simulator: 'Simulator', manager: 'HathorManager') -> None:
5353
from hathor import daa
5454
from hathor.conf.get_settings import get_settings
55-
from tests.utils import add_new_blocks, gen_new_tx
55+
from hathor.utils.simulator import add_new_blocks, gen_new_tx
5656

5757
settings = get_settings()
5858
assert manager.wallet is not None
@@ -79,7 +79,7 @@ def simulate_single_chain_blocks_and_transactions(simulator: 'Simulator', manage
7979

8080
def simulate_reorg(simulator: 'Simulator', manager: 'HathorManager') -> None:
8181
from hathor.simulator import FakeConnection
82-
from tests.utils import add_new_blocks
82+
from hathor.utils.simulator import add_new_blocks
8383

8484
builder = simulator.get_default_builder()
8585
manager2 = simulator.create_peer(builder)

hathor/simulator/tx_generator.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
from hathor.conf.get_settings import get_settings
2222
from hathor.transaction.exceptions import RewardLocked
2323
from hathor.util import Random
24+
from hathor.utils.simulator import NoCandidatesError, gen_new_double_spending, gen_new_tx
2425
from hathor.wallet.exceptions import InsufficientFunds
25-
from tests.utils import NoCandidatesError, gen_new_double_spending, gen_new_tx
2626

2727
if TYPE_CHECKING:
2828
from hathor.manager import HathorManager

hathor/utils/simulator.py

+138
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# Copyright 2023 Hathor Labs
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from typing import Optional, cast
16+
17+
from hathor.crypto.util import decode_address
18+
from hathor.manager import HathorManager
19+
from hathor.transaction import Transaction
20+
21+
22+
def gen_new_tx(manager, address, value, verify=True):
23+
from hathor.transaction import Transaction
24+
from hathor.wallet.base_wallet import WalletOutputInfo
25+
26+
outputs = []
27+
outputs.append(WalletOutputInfo(address=decode_address(address), value=int(value), timelock=None))
28+
29+
tx = manager.wallet.prepare_transaction_compute_inputs(Transaction, outputs, manager.tx_storage)
30+
tx.storage = manager.tx_storage
31+
32+
max_ts_spent_tx = max(tx.get_spent_tx(txin).timestamp for txin in tx.inputs)
33+
tx.timestamp = max(max_ts_spent_tx + 1, int(manager.reactor.seconds()))
34+
35+
tx.weight = 1
36+
tx.parents = manager.get_new_tx_parents(tx.timestamp)
37+
tx.resolve()
38+
if verify:
39+
tx.verify()
40+
return tx
41+
42+
43+
def add_new_blocks(manager, num_blocks, advance_clock=None, *, parent_block_hash=None,
44+
block_data=b'', weight=None, address=None):
45+
""" Create, resolve and propagate some blocks
46+
47+
:param manager: Manager object to handle the creation
48+
:type manager: :py:class:`hathor.manager.HathorManager`
49+
50+
:param num_blocks: Quantity of blocks to be created
51+
:type num_blocks: int
52+
53+
:return: Blocks created
54+
:rtype: list[Block]
55+
"""
56+
blocks = []
57+
for _ in range(num_blocks):
58+
blocks.append(
59+
add_new_block(manager, advance_clock, parent_block_hash=parent_block_hash,
60+
data=block_data, weight=weight, address=address)
61+
)
62+
if parent_block_hash:
63+
parent_block_hash = blocks[-1].hash
64+
return blocks
65+
66+
67+
def add_new_block(manager, advance_clock=None, *, parent_block_hash=None,
68+
data=b'', weight=None, address=None, propagate=True):
69+
""" Create, resolve and propagate a new block
70+
71+
:param manager: Manager object to handle the creation
72+
:type manager: :py:class:`hathor.manager.HathorManager`
73+
74+
:return: Block created
75+
:rtype: :py:class:`hathor.transaction.block.Block`
76+
"""
77+
block = manager.generate_mining_block(parent_block_hash=parent_block_hash, data=data, address=address)
78+
if weight is not None:
79+
block.weight = weight
80+
block.resolve()
81+
block.validate_full()
82+
if propagate:
83+
manager.propagate_tx(block, fails_silently=False)
84+
if advance_clock:
85+
manager.reactor.advance(advance_clock)
86+
return block
87+
88+
89+
class NoCandidatesError(Exception):
90+
pass
91+
92+
93+
def gen_new_double_spending(manager: HathorManager, *, use_same_parents: bool = False,
94+
tx: Optional[Transaction] = None, weight: float = 1) -> Transaction:
95+
if tx is None:
96+
tx_candidates = manager.get_new_tx_parents()
97+
genesis = manager.tx_storage.get_all_genesis()
98+
genesis_txs = [tx for tx in genesis if not tx.is_block]
99+
# XXX: it isn't possible to double-spend a genesis transaction, thus we remove it from tx_candidates
100+
for genesis_tx in genesis_txs:
101+
if genesis_tx.hash in tx_candidates:
102+
tx_candidates.remove(genesis_tx.hash)
103+
if not tx_candidates:
104+
raise NoCandidatesError()
105+
# assert tx_candidates, 'Must not be empty, otherwise test was wrongly set up'
106+
tx_hash = manager.rng.choice(tx_candidates)
107+
tx = cast(Transaction, manager.tx_storage.get_transaction(tx_hash))
108+
109+
txin = manager.rng.choice(tx.inputs)
110+
111+
from hathor.transaction.scripts import P2PKH, parse_address_script
112+
spent_tx = tx.get_spent_tx(txin)
113+
spent_txout = spent_tx.outputs[txin.index]
114+
p2pkh = parse_address_script(spent_txout.script)
115+
assert isinstance(p2pkh, P2PKH)
116+
117+
from hathor.wallet.base_wallet import WalletInputInfo, WalletOutputInfo
118+
value = spent_txout.value
119+
wallet = manager.wallet
120+
assert wallet is not None
121+
private_key = wallet.get_private_key(p2pkh.address)
122+
inputs = [WalletInputInfo(tx_id=txin.tx_id, index=txin.index, private_key=private_key)]
123+
124+
address = wallet.get_unused_address(mark_as_used=True)
125+
outputs = [WalletOutputInfo(address=decode_address(address), value=int(value), timelock=None)]
126+
127+
tx2 = wallet.prepare_transaction(Transaction, inputs, outputs)
128+
tx2.storage = manager.tx_storage
129+
tx2.weight = weight
130+
tx2.timestamp = max(tx.timestamp + 1, int(manager.reactor.seconds()))
131+
132+
if use_same_parents:
133+
tx2.parents = list(tx.parents)
134+
else:
135+
tx2.parents = manager.get_new_tx_parents(tx2.timestamp)
136+
137+
tx2.resolve()
138+
return tx2

tests/cli/test_multisig_signature.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@
99
from structlog.testing import capture_logs
1010

1111
from hathor.cli.multisig_signature import create_parser, execute
12+
from hathor.utils.simulator import add_new_blocks
1213
from hathor.wallet import Wallet
1314
from tests import unittest
14-
from tests.utils import add_blocks_unlock_reward, add_new_blocks, add_new_transactions
15+
from tests.utils import add_blocks_unlock_reward, add_new_transactions
1516

1617

1718
class BaseSignatureTest(unittest.TestCase):

tests/cli/test_multisig_spend.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@
88
from hathor.crypto.util import decode_address
99
from hathor.transaction import Transaction, TxInput, TxOutput
1010
from hathor.transaction.scripts import create_output_script
11+
from hathor.utils.simulator import add_new_blocks
1112
from hathor.wallet.base_wallet import WalletBalance, WalletOutputInfo
1213
from hathor.wallet.util import generate_multisig_address, generate_multisig_redeem_script, generate_signature
1314
from tests import unittest
14-
from tests.utils import add_blocks_unlock_reward, add_new_blocks
15+
from tests.utils import add_blocks_unlock_reward
1516

1617
settings = HathorSettings()
1718

tests/cli/test_twin_tx.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
from hathor.conf import HathorSettings
99
from hathor.transaction import Transaction, TransactionMetadata
1010
from hathor.util import json_loadb
11+
from hathor.utils.simulator import add_new_blocks
1112
from tests import unittest
1213
from tests.utils import (
1314
add_blocks_unlock_reward,
14-
add_new_blocks,
1515
add_new_transactions,
1616
execute_mining,
1717
execute_tx_gen,

tests/consensus/test_consensus.py

+2-8
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,9 @@
22

33
from hathor.conf import HathorSettings
44
from hathor.transaction.storage import TransactionMemoryStorage
5+
from hathor.utils.simulator import add_new_block, add_new_blocks, gen_new_tx
56
from tests import unittest
6-
from tests.utils import (
7-
add_blocks_unlock_reward,
8-
add_new_block,
9-
add_new_blocks,
10-
add_new_double_spending,
11-
add_new_transactions,
12-
gen_new_tx,
13-
)
7+
from tests.utils import add_blocks_unlock_reward, add_new_double_spending, add_new_transactions
148

159
settings = HathorSettings()
1610

tests/consensus/test_consensus2.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
from hathor.graphviz import GraphvizVisualizer
2+
from hathor.utils.simulator import gen_new_tx
23
from tests import unittest
34
from tests.simulation.base import SimulatorTestCase
4-
from tests.utils import add_custom_tx, gen_new_tx
5+
from tests.utils import add_custom_tx
56

67

78
class BaseConsensusSimulatorTestCase(SimulatorTestCase):

tests/consensus/test_consensus3.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import pytest
22

3+
from hathor.utils.simulator import add_new_block, add_new_blocks
34
from tests import unittest
4-
from tests.utils import add_blocks_unlock_reward, add_new_block, add_new_blocks
5+
from tests.utils import add_blocks_unlock_reward
56

67

78
class DoubleSpendingTestCase(unittest.TestCase):

tests/consensus/test_soft_voided.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
from hathor.graphviz import GraphvizVisualizer
33
from hathor.simulator import FakeConnection, Simulator
44
from hathor.simulator.trigger import StopAfterNTransactions
5+
from hathor.utils.simulator import gen_new_tx
56
from tests import unittest
67
from tests.simulation.base import SimulatorTestCase
7-
from tests.utils import add_custom_tx, gen_new_tx
8+
from tests.utils import add_custom_tx
89

910
settings = HathorSettings()
1011

tests/consensus/test_soft_voided2.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
from hathor.conf import HathorSettings
22
from hathor.graphviz import GraphvizVisualizer
33
from hathor.simulator import Simulator
4+
from hathor.utils.simulator import gen_new_tx
45
from tests import unittest
56
from tests.simulation.base import SimulatorTestCase
6-
from tests.utils import BURN_ADDRESS, add_custom_tx, gen_new_tx
7+
from tests.utils import BURN_ADDRESS, add_custom_tx
78

89
settings = HathorSettings()
910

tests/consensus/test_soft_voided3.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
from hathor.graphviz import GraphvizVisualizer
33
from hathor.simulator import FakeConnection, Simulator
44
from hathor.simulator.trigger import StopAfterNTransactions
5+
from hathor.utils.simulator import gen_new_tx
56
from tests import unittest
67
from tests.simulation.base import SimulatorTestCase
7-
from tests.utils import add_custom_tx, gen_custom_tx, gen_new_tx
8+
from tests.utils import add_custom_tx, gen_custom_tx
89

910
settings = HathorSettings()
1011

tests/consensus/test_soft_voided4.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
from hathor.graphviz import GraphvizVisualizer
33
from hathor.simulator import FakeConnection, Simulator
44
from hathor.simulator.trigger import StopAfterNTransactions
5+
from hathor.utils.simulator import gen_new_double_spending
56
from tests import unittest
67
from tests.simulation.base import SimulatorTestCase
7-
from tests.utils import add_custom_tx, gen_new_double_spending
8+
from tests.utils import add_custom_tx
89

910
settings = HathorSettings()
1011

tests/event/test_event_reorg.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
from hathor.conf import HathorSettings
44
from hathor.event.model.event_type import EventType
55
from hathor.event.storage import EventMemoryStorage
6+
from hathor.utils.simulator import add_new_blocks
67
from tests import unittest
7-
from tests.utils import BURN_ADDRESS, add_new_blocks, get_genesis_key
8+
from tests.utils import BURN_ADDRESS, get_genesis_key
89

910
settings = HathorSettings()
1011

tests/others/test_init_manager.py

+2-7
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,10 @@
44
from hathor.pubsub import PubSubManager
55
from hathor.transaction import BaseTransaction
66
from hathor.transaction.storage import TransactionMemoryStorage
7+
from hathor.utils.simulator import add_new_block, add_new_blocks
78
from tests import unittest
89
from tests.unittest import TestBuilder
9-
from tests.utils import (
10-
add_blocks_unlock_reward,
11-
add_new_block,
12-
add_new_blocks,
13-
add_new_double_spending,
14-
add_new_transactions,
15-
)
10+
from tests.utils import add_blocks_unlock_reward, add_new_double_spending, add_new_transactions
1611

1712
settings = HathorSettings()
1813

tests/others/test_metrics.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
from hathor.p2p.protocol import HathorProtocol
99
from hathor.pubsub import HathorEvents
1010
from hathor.transaction.storage import TransactionCacheStorage, TransactionMemoryStorage
11+
from hathor.utils.simulator import add_new_blocks
1112
from hathor.wallet import Wallet
1213
from tests import unittest
13-
from tests.utils import HAS_ROCKSDB, add_new_blocks
14+
from tests.utils import HAS_ROCKSDB
1415

1516

1617
class BaseMetricsTest(unittest.TestCase):

tests/p2p/test_double_spending.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from hathor.crypto.util import decode_address
2+
from hathor.utils.simulator import add_new_blocks
23
from tests import unittest
3-
from tests.utils import add_blocks_unlock_reward, add_new_blocks, add_new_tx
4+
from tests.utils import add_blocks_unlock_reward, add_new_tx
45

56

67
class BaseHathorSyncMethodsTestCase(unittest.TestCase):

tests/p2p/test_split_brain.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
from hathor.daa import TestMode, _set_test_mode
55
from hathor.graphviz import GraphvizVisualizer
66
from hathor.simulator import FakeConnection
7+
from hathor.utils.simulator import add_new_block
78
from hathor.wallet import HDWallet
89
from tests import unittest
9-
from tests.utils import add_blocks_unlock_reward, add_new_block, add_new_double_spending, add_new_transactions
10+
from tests.utils import add_blocks_unlock_reward, add_new_double_spending, add_new_transactions
1011

1112

1213
class BaseHathorSyncMethodsTestCase(unittest.TestCase):

tests/p2p/test_twin_tx.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
from hathor.crypto.util import decode_address
22
from hathor.transaction import Transaction
3+
from hathor.utils.simulator import add_new_blocks
34
from hathor.wallet.base_wallet import WalletOutputInfo
45
from tests import unittest
5-
from tests.utils import add_blocks_unlock_reward, add_new_blocks, add_new_double_spending
6+
from tests.utils import add_blocks_unlock_reward, add_new_double_spending
67

78

89
class BaseTwinTransactionTestCase(unittest.TestCase):

tests/resources/p2p/test_healthcheck.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
from hathor.manager import HathorManager
44
from hathor.p2p.resources.healthcheck import HealthcheckReadinessResource
55
from hathor.simulator import FakeConnection
6+
from hathor.utils.simulator import add_new_blocks
67
from tests import unittest
78
from tests.resources.base_resource import StubSite, _BaseResourceTest
8-
from tests.utils import add_new_blocks
99

1010

1111
class BaseHealthcheckReadinessTest(_BaseResourceTest._ResourceTest):

tests/resources/test_mining_info.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
from hathor.conf import HathorSettings
44
from hathor.p2p.resources import MiningInfoResource
5+
from hathor.utils.simulator import add_new_blocks
56
from tests import unittest
67
from tests.resources.base_resource import StubSite, _BaseResourceTest
7-
from tests.utils import add_new_blocks
88

99
settings = HathorSettings()
1010

0 commit comments

Comments
 (0)