chia-blockchain/tests/test_mempool.py

176 lines
7.3 KiB
Python
Raw Normal View History

2020-01-30 04:28:53 +03:00
import asyncio
import pytest
2020-01-31 23:44:04 +03:00
from src.farming.farming_tools import best_solution_program
2020-01-30 04:28:53 +03:00
from src.server.outbound_message import OutboundMessage
from src.protocols import peer_protocol
2020-01-31 23:44:04 +03:00
from src.util.Conditions import ConditionVarPair, ConditionOpcode
from src.util.ints import uint64
from src.util.mempool_check_conditions import get_name_puzzle_conditions
2020-01-30 04:28:53 +03:00
from src.wallet.wallets.standard_wallet.wallet import Wallet
from tests.setup_nodes import setup_two_nodes, test_constants, bt
2020-01-31 03:56:24 +03:00
from tests.wallet_tools import WalletTool
2020-01-30 04:28:53 +03:00
@pytest.fixture(scope="module")
def event_loop():
loop = asyncio.get_event_loop()
yield loop
class TestMempool:
@pytest.fixture(scope="function")
async def two_nodes(self):
async for _ in setup_two_nodes():
yield _
@pytest.mark.asyncio
async def test_basic_mempool(self, two_nodes):
num_blocks = 3
2020-01-31 03:56:24 +03:00
wallet_a = WalletTool()
2020-01-30 04:28:53 +03:00
coinbase_puzzlehash = wallet_a.get_new_puzzlehash()
wallet_receiver = Wallet()
receiver_puzzlehash = wallet_receiver.get_new_puzzlehash()
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"", coinbase_puzzlehash)
full_node_1, full_node_2, server_1, server_2 = two_nodes
block = blocks[1]
async for _ in full_node_1.block(peer_protocol.Block(block)):
2020-01-31 23:03:52 +03:00
spend_bundle = wallet_a.generate_signed_transaction(1000, receiver_puzzlehash, block.body.coinbase)
2020-01-30 04:28:53 +03:00
tx: peer_protocol.Transaction = peer_protocol.Transaction(spend_bundle)
async for _ in full_node_1.transaction(tx):
outbound: OutboundMessage = _
# Maybe transaction means that it's accepted in mempool
assert outbound.message.function == "maybe_transaction"
@pytest.mark.asyncio
async def test_double_spend(self, two_nodes):
num_blocks = 3
2020-01-31 03:56:24 +03:00
wallet_a = WalletTool()
2020-01-30 04:28:53 +03:00
coinbase_puzzlehash = wallet_a.get_new_puzzlehash()
2020-01-31 03:56:24 +03:00
wallet_receiver = WalletTool()
2020-01-30 04:28:53 +03:00
receiver_puzzlehash = wallet_receiver.get_new_puzzlehash()
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"", coinbase_puzzlehash)
full_node_1, full_node_2, server_1, server_2 = two_nodes
block = blocks[1]
async for _ in full_node_1.block(peer_protocol.Block(block)):
pass
2020-01-31 23:03:52 +03:00
spend_bundle1 = wallet_a.generate_signed_transaction(1000, receiver_puzzlehash, block.body.coinbase)
2020-01-30 04:28:53 +03:00
tx1: peer_protocol.Transaction = peer_protocol.Transaction(spend_bundle1)
async for _ in full_node_1.transaction(tx1):
outbound: OutboundMessage = _
# Maybe transaction means that it's accepted in mempool
assert outbound.message.function == "maybe_transaction"
2020-01-31 03:56:24 +03:00
other_receiver = WalletTool()
2020-01-31 23:03:52 +03:00
spend_bundle2 = wallet_a.generate_signed_transaction(1000, other_receiver.get_new_puzzlehash(), block.body.coinbase)
2020-01-30 04:28:53 +03:00
tx2: peer_protocol.Transaction = peer_protocol.Transaction(spend_bundle2)
async for _ in full_node_1.transaction(tx2):
pass
sb1 = await full_node_1.mempool.get_spendbundle(spend_bundle1.name())
sb2 = await full_node_1.mempool.get_spendbundle(spend_bundle2.name())
assert sb1 == spend_bundle1
assert sb2 is None
2020-01-31 03:56:24 +03:00
@pytest.mark.asyncio
async def test_double_spend_with_higher_fee(self, two_nodes):
num_blocks = 3
wallet_a = WalletTool()
coinbase_puzzlehash = wallet_a.get_new_puzzlehash()
wallet_receiver = WalletTool()
receiver_puzzlehash = wallet_receiver.get_new_puzzlehash()
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"", coinbase_puzzlehash)
full_node_1, full_node_2, server_1, server_2 = two_nodes
block = blocks[1]
async for _ in full_node_1.block(peer_protocol.Block(block)):
pass
2020-01-31 23:03:52 +03:00
spend_bundle1 = wallet_a.generate_signed_transaction(1000, receiver_puzzlehash, block.body.coinbase)
2020-01-31 03:56:24 +03:00
tx1: peer_protocol.Transaction = peer_protocol.Transaction(spend_bundle1)
async for _ in full_node_1.transaction(tx1):
outbound: OutboundMessage = _
# Maybe transaction means that it's accepted in mempool
assert outbound.message.function == "maybe_transaction"
2020-01-31 23:03:52 +03:00
spend_bundle2 = wallet_a.generate_signed_transaction(1000, receiver_puzzlehash, block.body.coinbase, fee=1)
2020-01-31 03:56:24 +03:00
tx2: peer_protocol.Transaction = peer_protocol.Transaction(spend_bundle2)
async for _ in full_node_1.transaction(tx2):
pass
sb1 = await full_node_1.mempool.get_spendbundle(spend_bundle1.name())
sb2 = await full_node_1.mempool.get_spendbundle(spend_bundle2.name())
assert sb1 is None
assert sb2 == spend_bundle2
2020-01-31 23:44:04 +03:00
@pytest.mark.asyncio
async def test_invalid_block_index(self, two_nodes):
num_blocks = 3
wallet_a = WalletTool()
coinbase_puzzlehash = wallet_a.get_new_puzzlehash()
wallet_receiver = WalletTool()
receiver_puzzlehash = wallet_receiver.get_new_puzzlehash()
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"", coinbase_puzzlehash)
full_node_1, full_node_2, server_1, server_2 = two_nodes
block = blocks[1]
async for _ in full_node_1.block(peer_protocol.Block(block)):
pass
cvp = ConditionVarPair(ConditionOpcode.ASSERT_BLOCK_INDEX_EXCEEDS, uint64(2).to_bytes(4, 'big'), None)
dic = {ConditionOpcode.ASSERT_BLOCK_INDEX_EXCEEDS: [cvp]}
spend_bundle1 = wallet_a.generate_signed_transaction(1000, receiver_puzzlehash, block.body.coinbase, dic)
tx1: peer_protocol.Transaction = peer_protocol.Transaction(spend_bundle1)
async for _ in full_node_1.transaction(tx1):
outbound: OutboundMessage = _
# Maybe transaction means that it's accepted in mempool
assert outbound.message.function != "maybe_transaction"
sb1 = await full_node_1.mempool.get_spendbundle(spend_bundle1.name())
assert sb1 is None
@pytest.mark.asyncio
async def test_correct_block_index(self, two_nodes):
num_blocks = 3
wallet_a = WalletTool()
coinbase_puzzlehash = wallet_a.get_new_puzzlehash()
wallet_receiver = WalletTool()
receiver_puzzlehash = wallet_receiver.get_new_puzzlehash()
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"", coinbase_puzzlehash)
full_node_1, full_node_2, server_1, server_2 = two_nodes
block = blocks[1]
async for _ in full_node_1.block(peer_protocol.Block(block)):
pass
cvp = ConditionVarPair(ConditionOpcode.ASSERT_BLOCK_INDEX_EXCEEDS, uint64(1).to_bytes(4, 'big'), None)
dic = {ConditionOpcode.ASSERT_BLOCK_INDEX_EXCEEDS: [cvp]}
spend_bundle1 = wallet_a.generate_signed_transaction(1000, receiver_puzzlehash, block.body.coinbase, dic)
tx1: peer_protocol.Transaction = peer_protocol.Transaction(spend_bundle1)
async for _ in full_node_1.transaction(tx1):
outbound: OutboundMessage = _
# Maybe transaction means that it's accepted in mempool
assert outbound.message.function == "maybe_transaction"
sb1 = await full_node_1.mempool.get_spendbundle(spend_bundle1.name())
assert sb1 is spend_bundle1