fixup and enable condition checking tests (#10888)

* fixup and enable tests for the edge cases of absolute timestamp and absolute height conditions in mempool_manager

* Update chia/full_node/full_node_api.py

Co-authored-by: Adam Kelly <338792+aqk@users.noreply.github.com>

Co-authored-by: Adam Kelly <338792+aqk@users.noreply.github.com>
This commit is contained in:
Arvid Norberg 2022-03-25 18:49:11 -07:00 committed by GitHub
parent 536d7c4e03
commit 7ea074c9e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 24 deletions

View File

@ -1256,11 +1256,10 @@ class FullNodeAPI:
return msg return msg
@api_request @api_request
async def send_transaction(self, request: wallet_protocol.SendTransaction) -> Optional[Message]: async def send_transaction(self, request: wallet_protocol.SendTransaction, *, test=False) -> Optional[Message]:
spend_name = request.transaction.name() spend_name = request.transaction.name()
await self.full_node.transaction_queue.put( await self.full_node.transaction_queue.put(
(0, TransactionQueueEntry(request.transaction, None, spend_name, None, False)) (0, TransactionQueueEntry(request.transaction, None, spend_name, None, test))
) )
# Waits for the transaction to go into the mempool, times out after 45 seconds. # Waits for the transaction to go into the mempool, times out after 45 seconds.
status, error = None, None status, error = None, None

View File

@ -79,7 +79,7 @@ def generate_test_spend_bundle(
return transaction return transaction
@pytest_asyncio.fixture(scope="module") @pytest_asyncio.fixture(scope="function")
async def two_nodes_mempool(bt, wallet_a): async def two_nodes_mempool(bt, wallet_a):
async_gen = setup_simulators_and_wallets(2, 1, {}) async_gen = setup_simulators_and_wallets(2, 1, {})
nodes, _ = await async_gen.__anext__() nodes, _ = await async_gen.__anext__()
@ -94,7 +94,10 @@ async def two_nodes_mempool(bt, wallet_a):
guarantee_transaction_block=True, guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph, farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph, pool_reward_puzzle_hash=reward_ph,
genesis_timestamp=10000,
time_per_block=10,
) )
assert blocks[0].height == 0
for block in blocks: for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block)) await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
@ -235,6 +238,8 @@ async def next_block(full_node_1, wallet_a, bt) -> Coin:
guarantee_transaction_block=True, guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph, farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph, pool_reward_puzzle_hash=reward_ph,
genesis_timestamp=10000,
time_per_block=10,
) )
for block in blocks: for block in blocks:
@ -255,7 +260,7 @@ class TestMempoolManager:
spend_bundle = generate_test_spend_bundle(wallet_a, coin) spend_bundle = generate_test_spend_bundle(wallet_a, coin)
assert spend_bundle is not None assert spend_bundle is not None
tx: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle) tx: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle)
await full_node_1.respond_transaction(tx, peer) await full_node_1.respond_transaction(tx, peer, test=True)
await time_out_assert( await time_out_assert(
10, 10,
@ -277,17 +282,17 @@ class TestMempoolManager:
(ConditionOpcode.ASSERT_HEIGHT_RELATIVE, 0, MempoolInclusionStatus.PENDING), (ConditionOpcode.ASSERT_HEIGHT_RELATIVE, 0, MempoolInclusionStatus.PENDING),
(ConditionOpcode.ASSERT_HEIGHT_RELATIVE, 1, MempoolInclusionStatus.PENDING), (ConditionOpcode.ASSERT_HEIGHT_RELATIVE, 1, MempoolInclusionStatus.PENDING),
# the absolute height and seconds tests require fresh full nodes to # the absolute height and seconds tests require fresh full nodes to
# run the test on. Right now, we just launch two simulations and all # run the test on. The fixture (two_nodes_mempool) creates 3 blocks,
# tests use the same ones. See comment at the two_nodes_mempool fixture # then condition_tester2 creates another 3 blocks
# (ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE, 2, MempoolInclusionStatus.SUCCESS), (ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE, 4, MempoolInclusionStatus.SUCCESS),
# (ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE, 3, MempoolInclusionStatus.SUCCESS), (ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE, 5, MempoolInclusionStatus.SUCCESS),
# (ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE, 4, MempoolInclusionStatus.PENDING), (ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE, 6, MempoolInclusionStatus.PENDING),
# (ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE, 5, MempoolInclusionStatus.PENDING), (ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE, 7, MempoolInclusionStatus.PENDING),
# genesis timestamp is 10000 and each block is 10 seconds # genesis timestamp is 10000 and each block is 10 seconds
# (ConditionOpcode.ASSERT_SECONDS_ABSOLUTE, 10029, MempoolInclusionStatus.SUCCESS), (ConditionOpcode.ASSERT_SECONDS_ABSOLUTE, 10049, MempoolInclusionStatus.SUCCESS),
# (ConditionOpcode.ASSERT_SECONDS_ABSOLUTE, 10030, MempoolInclusionStatus.SUCCESS), (ConditionOpcode.ASSERT_SECONDS_ABSOLUTE, 10050, MempoolInclusionStatus.SUCCESS),
# (ConditionOpcode.ASSERT_SECONDS_ABSOLUTE, 10031, MempoolInclusionStatus.FAILED), (ConditionOpcode.ASSERT_SECONDS_ABSOLUTE, 10051, MempoolInclusionStatus.FAILED),
# (ConditionOpcode.ASSERT_SECONDS_ABSOLUTE, 10032, MempoolInclusionStatus.FAILED), (ConditionOpcode.ASSERT_SECONDS_ABSOLUTE, 10052, MempoolInclusionStatus.FAILED),
], ],
) )
async def test_ephemeral_timelock(self, bt, two_nodes_mempool, wallet_a, opcode, lock_value, expected): async def test_ephemeral_timelock(self, bt, two_nodes_mempool, wallet_a, opcode, lock_value, expected):
@ -392,7 +397,7 @@ class TestMempoolManager:
assert spend_bundle1 is not None assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1) tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
status, err = await respond_transaction(full_node_1, tx1, peer) status, err = await respond_transaction(full_node_1, tx1, peer, test=True)
assert err is None assert err is None
assert status == MempoolInclusionStatus.SUCCESS assert status == MempoolInclusionStatus.SUCCESS
@ -403,7 +408,7 @@ class TestMempoolManager:
) )
assert spend_bundle2 is not None assert spend_bundle2 is not None
tx2: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle2) tx2: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle2)
status, err = await respond_transaction(full_node_1, tx2, peer) status, err = await respond_transaction(full_node_1, tx2, peer, test=True)
sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name()) sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
sb2 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle2.name()) sb2 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle2.name())
@ -415,7 +420,7 @@ class TestMempoolManager:
async def send_sb(self, node: FullNodeAPI, sb: SpendBundle) -> Optional[Message]: async def send_sb(self, node: FullNodeAPI, sb: SpendBundle) -> Optional[Message]:
tx = wallet_protocol.SendTransaction(sb) tx = wallet_protocol.SendTransaction(sb)
return await node.send_transaction(tx) return await node.send_transaction(tx, test=True)
async def gen_and_send_sb(self, node, peer, *args, **kwargs): async def gen_and_send_sb(self, node, peer, *args, **kwargs):
sb = generate_test_spend_bundle(*args, **kwargs) sb = generate_test_spend_bundle(*args, **kwargs)
@ -575,7 +580,7 @@ class TestMempoolManager:
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1) tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
status, err = await respond_transaction(full_node_1, tx1, peer) status, err = await respond_transaction(full_node_1, tx1, peer, test=True)
return blocks, spend_bundle1, peer, status, err return blocks, spend_bundle1, peer, status, err
@pytest.mark.asyncio @pytest.mark.asyncio
@ -590,6 +595,7 @@ class TestMempoolManager:
guarantee_transaction_block=True, guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph, farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph, pool_reward_puzzle_hash=reward_ph,
time_per_block=10,
) )
peer = await connect_and_get_peer(server_1, server_2, bt.config["self_hostname"]) peer = await connect_and_get_peer(server_1, server_2, bt.config["self_hostname"])
@ -919,7 +925,7 @@ class TestMempoolManager:
tx2: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1) tx2: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
status, err = await respond_transaction(full_node_1, tx2, peer) status, err = await respond_transaction(full_node_1, tx2, peer, test=True)
sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name()) sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
assert err is None assert err is None
@ -1459,7 +1465,7 @@ class TestMempoolManager:
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1) tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
status, err = await respond_transaction(full_node_1, tx1, peer) status, err = await respond_transaction(full_node_1, tx1, peer, test=True)
mempool_bundle = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name()) mempool_bundle = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
@ -1506,7 +1512,7 @@ class TestMempoolManager:
tx: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle_combined) tx: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle_combined)
peer = await connect_and_get_peer(server_1, server_2, bt.config["self_hostname"]) peer = await connect_and_get_peer(server_1, server_2, bt.config["self_hostname"])
status, err = await respond_transaction(full_node_1, tx, peer) status, err = await respond_transaction(full_node_1, tx, peer, test=True)
sb = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle_combined.name()) sb = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle_combined.name())
assert err == Err.DOUBLE_SPEND assert err == Err.DOUBLE_SPEND
@ -1556,7 +1562,7 @@ class TestMempoolManager:
# assert spend_bundle is not None # assert spend_bundle is not None
# #
# tx: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle) # tx: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle)
# await full_node_1.respond_transaction(tx, peer) # await full_node_1.respond_transaction(tx, peer, test=True)
# #
# sb = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle.name()) # sb = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle.name())
# assert sb is spend_bundle # assert sb is spend_bundle
@ -2449,7 +2455,7 @@ class TestMaliciousGenerators:
coin_spend_0 = recursive_replace(spend_bundle.coin_spends[0], "coin.puzzle_hash", bytes32([1] * 32)) coin_spend_0 = recursive_replace(spend_bundle.coin_spends[0], "coin.puzzle_hash", bytes32([1] * 32))
new_bundle = recursive_replace(spend_bundle, "coin_spends", [coin_spend_0] + spend_bundle.coin_spends[1:]) new_bundle = recursive_replace(spend_bundle, "coin_spends", [coin_spend_0] + spend_bundle.coin_spends[1:])
assert spend_bundle is not None assert spend_bundle is not None
res = await full_node_1.full_node.respond_transaction(new_bundle, new_bundle.name()) res = await full_node_1.full_node.respond_transaction(new_bundle, new_bundle.name(), test=True)
assert res == (MempoolInclusionStatus.FAILED, Err.INVALID_SPEND_BUNDLE) assert res == (MempoolInclusionStatus.FAILED, Err.INVALID_SPEND_BUNDLE)