chia-blockchain/tests/full_node/test_transactions.py

210 lines
7.2 KiB
Python

import asyncio
from secrets import token_bytes
import pytest
from src.protocols import full_node_protocol
from src.simulator.simulator_protocol import FarmNewBlockProtocol
from src.types.peer_info import PeerInfo
from src.util.ints import uint16, uint32
from tests.setup_nodes import setup_simulators_and_wallets
from src.consensus.block_rewards import calculate_base_fee, calculate_block_reward
@pytest.fixture(scope="module")
def event_loop():
loop = asyncio.get_event_loop()
yield loop
class TestTransactions:
@pytest.fixture(scope="function")
async def wallet_node(self):
async for _ in setup_simulators_and_wallets(1, 1, {}):
yield _
@pytest.fixture(scope="function")
async def two_wallet_nodes(self):
async for _ in setup_simulators_and_wallets(
1, 2, {"COINBASE_FREEZE_PERIOD": 0}
):
yield _
@pytest.fixture(scope="function")
async def three_nodes_two_wallets(self):
async for _ in setup_simulators_and_wallets(
3, 2, {"COINBASE_FREEZE_PERIOD": 0}
):
yield _
@pytest.mark.asyncio
async def test_wallet_coinbase(self, wallet_node):
num_blocks = 10
full_nodes, wallets = wallet_node
full_node_1, server_1 = full_nodes[0]
wallet_node, server_2 = wallets[0]
wallet = wallet_node.wallet_state_manager.main_wallet
ph = await wallet.get_new_puzzlehash()
await server_2.start_client(PeerInfo("localhost", uint16(server_1._port)), None)
for i in range(1, num_blocks):
await full_node_1.farm_new_block(FarmNewBlockProtocol(ph))
await asyncio.sleep(3)
funds = sum(
[
calculate_base_fee(uint32(i)) + calculate_block_reward(uint32(i))
for i in range(1, num_blocks - 2)
]
)
assert await wallet.get_confirmed_balance() == funds
@pytest.mark.asyncio
async def test_tx_propagation(self, three_nodes_two_wallets):
num_blocks = 10
full_nodes, wallets = three_nodes_two_wallets
wallet_0, wallet_server_0 = wallets[0]
wallet_1, wallet_server_1 = wallets[1]
full_node_0, server_0 = full_nodes[0]
full_node_1, server_1 = full_nodes[1]
full_node_2, server_2 = full_nodes[2]
ph = await wallet_0.wallet_state_manager.main_wallet.get_new_puzzlehash()
ph1 = await wallet_1.wallet_state_manager.main_wallet.get_new_puzzlehash()
#
# wallet0 <-> sever0 <-> server1 <-> server2 <-> wallet1
#
await wallet_server_0.start_client(
PeerInfo("localhost", uint16(server_0._port)), None
)
await server_0.start_client(PeerInfo("localhost", uint16(server_1._port)), None)
await server_1.start_client(PeerInfo("localhost", uint16(server_2._port)), None)
await wallet_server_1.start_client(
PeerInfo("localhost", uint16(server_2._port)), None
)
for i in range(1, num_blocks):
await full_node_0.farm_new_block(FarmNewBlockProtocol(ph))
await asyncio.sleep(3)
funds = sum(
[
calculate_base_fee(uint32(i)) + calculate_block_reward(uint32(i))
for i in range(1, num_blocks - 2)
]
)
assert (
await wallet_0.wallet_state_manager.main_wallet.get_confirmed_balance()
== funds
)
spend_bundle = await wallet_0.wallet_state_manager.main_wallet.generate_signed_transaction(
10, ph1, 0
)
await wallet_0.wallet_state_manager.main_wallet.push_transaction(spend_bundle)
await asyncio.sleep(3)
bundle0 = full_node_0.mempool_manager.get_spendbundle(spend_bundle.name())
bundle1 = full_node_1.mempool_manager.get_spendbundle(spend_bundle.name())
bundle2 = full_node_2.mempool_manager.get_spendbundle(spend_bundle.name())
assert spend_bundle == bundle0
assert spend_bundle == bundle1
assert spend_bundle == bundle2
# Farm another block
for i in range(1, 8):
await full_node_1.farm_new_block(FarmNewBlockProtocol(token_bytes()))
await asyncio.sleep(2)
funds = sum(
[
calculate_base_fee(uint32(i)) + calculate_block_reward(uint32(i))
for i in range(1, num_blocks)
]
)
assert (
await wallet_0.wallet_state_manager.main_wallet.get_confirmed_balance()
== funds - 10
)
assert (
await wallet_1.wallet_state_manager.main_wallet.get_confirmed_balance()
== 10
)
@pytest.mark.asyncio
async def test_mempool_tx_sync(self, three_nodes_two_wallets):
num_blocks = 10
full_nodes, wallets = three_nodes_two_wallets
wallet_0, wallet_server_0 = wallets[0]
full_node_0, server_0 = full_nodes[0]
full_node_1, server_1 = full_nodes[1]
full_node_2, server_2 = full_nodes[2]
ph = await wallet_0.wallet_state_manager.main_wallet.get_new_puzzlehash()
# wallet0 <-> sever0 <-> server1
await wallet_server_0.start_client(
PeerInfo("localhost", uint16(server_0._port)), None
)
await server_0.start_client(PeerInfo("localhost", uint16(server_1._port)), None)
for i in range(1, num_blocks):
await full_node_0.farm_new_block(FarmNewBlockProtocol(ph))
all_blocks = await full_node_0.get_current_blocks(full_node_0.get_tip())
for block in all_blocks:
async for _ in full_node_2.respond_block(
full_node_protocol.RespondBlock(block)
):
pass
await asyncio.sleep(2)
funds = sum(
[
calculate_base_fee(uint32(i)) + calculate_block_reward(uint32(i))
for i in range(1, num_blocks - 2)
]
)
assert (
await wallet_0.wallet_state_manager.main_wallet.get_confirmed_balance()
== funds
)
spend_bundle = await wallet_0.wallet_state_manager.main_wallet.generate_signed_transaction(
10, token_bytes(), 0
)
await wallet_0.wallet_state_manager.main_wallet.push_transaction(spend_bundle)
await asyncio.sleep(2)
bundle0 = full_node_0.mempool_manager.get_spendbundle(spend_bundle.name())
bundle1 = full_node_1.mempool_manager.get_spendbundle(spend_bundle.name())
bundle2 = full_node_2.mempool_manager.get_spendbundle(spend_bundle.name())
assert spend_bundle == bundle0
assert spend_bundle == bundle1
assert None is bundle2
# make a final connection.
# wallet0 <-> sever0 <-> server1 <-> server2
await server_1.start_client(PeerInfo("localhost", uint16(server_2._port)), None)
await asyncio.sleep(2)
bundle0 = full_node_0.mempool_manager.get_spendbundle(spend_bundle.name())
bundle1 = full_node_1.mempool_manager.get_spendbundle(spend_bundle.name())
bundle2 = full_node_2.mempool_manager.get_spendbundle(spend_bundle.name())
assert spend_bundle == bundle0
assert spend_bundle == bundle1
assert spend_bundle == bundle2