chia-blockchain/tests/core/full_node/test_mempool.py

1327 lines
53 KiB
Python

import asyncio
import logging
from time import time
from typing import Dict, List
import pytest
from chia.full_node.mempool import Mempool
from chia.protocols import full_node_protocol
from chia.simulator.simulator_protocol import FarmNewBlockProtocol
from chia.types.announcement import Announcement
from chia.types.blockchain_format.coin import Coin
from chia.types.coin_solution import CoinSolution
from chia.types.condition_opcodes import ConditionOpcode
from chia.types.condition_with_args import ConditionWithArgs
from chia.types.spend_bundle import SpendBundle
from chia.util.clvm import int_to_bytes
from chia.util.condition_tools import conditions_for_solution
from chia.util.errors import Err
from chia.util.ints import uint64
from tests.connection_utils import connect_and_get_peer
from tests.core.node_height import node_height_at_least
from tests.setup_nodes import bt, setup_simulators_and_wallets
from tests.time_out_assert import time_out_assert
from chia.types.blockchain_format.program import Program, INFINITE_COST
BURN_PUZZLE_HASH = b"0" * 32
BURN_PUZZLE_HASH_2 = b"1" * 32
WALLET_A = bt.get_pool_wallet_tool()
log = logging.getLogger(__name__)
def generate_test_spend_bundle(
coin: Coin,
condition_dic: Dict[ConditionOpcode, List[ConditionWithArgs]] = None,
fee: uint64 = uint64(0),
amount: uint64 = uint64(1000),
new_puzzle_hash=BURN_PUZZLE_HASH,
) -> SpendBundle:
if condition_dic is None:
condition_dic = {}
transaction = WALLET_A.generate_signed_transaction(amount, new_puzzle_hash, coin, condition_dic, fee)
assert transaction is not None
return transaction
@pytest.fixture(scope="module")
def event_loop():
loop = asyncio.get_event_loop()
yield loop
@pytest.fixture(scope="module")
async def two_nodes():
async_gen = setup_simulators_and_wallets(2, 1, {})
nodes, _ = await async_gen.__anext__()
full_node_1 = nodes[0]
full_node_2 = nodes[1]
server_1 = full_node_1.full_node.server
server_2 = full_node_2.full_node.server
yield full_node_1, full_node_2, server_1, server_2
async for _ in async_gen:
yield _
class TestMempool:
@pytest.mark.asyncio
async def test_basic_mempool(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
blocks = bt.get_consecutive_blocks(
3,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
full_node_1, _, server_1, _ = two_nodes
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, blocks[-1].height)
max_mempool_cost = 40000000 * 5
mempool = Mempool(max_mempool_cost)
assert mempool.get_min_fee_rate(104000) == 0
with pytest.raises(ValueError):
mempool.get_min_fee_rate(max_mempool_cost + 1)
spend_bundle = generate_test_spend_bundle(list(blocks[-1].get_included_reward_coins())[0])
assert spend_bundle is not None
class TestMempoolManager:
@pytest.mark.asyncio
async def test_basic_mempool_manager(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
blocks = bt.get_consecutive_blocks(
5,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
full_node_1, full_node_2, server_1, server_2 = two_nodes
peer = await connect_and_get_peer(server_1, server_2)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_2, blocks[-1].height)
spend_bundle = generate_test_spend_bundle(list(blocks[-1].get_included_reward_coins())[0])
assert spend_bundle is not None
tx: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle)
res = await full_node_1.respond_transaction(tx, peer)
log.info(f"Res {res}")
await time_out_assert(
10,
full_node_1.full_node.mempool_manager.get_spendbundle,
spend_bundle,
spend_bundle.name(),
)
@pytest.mark.asyncio
async def test_double_spend(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
full_node_1, full_node_2, server_1, server_2 = two_nodes
blocks = await full_node_1.get_all_full_blocks()
start_height = blocks[-1].height
blocks = bt.get_consecutive_blocks(
3,
block_list_input=blocks,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
peer = await connect_and_get_peer(server_1, server_2)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
spend_bundle1 = generate_test_spend_bundle(list(blocks[-1].get_included_reward_coins())[0])
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1, peer)
spend_bundle2 = generate_test_spend_bundle(
list(blocks[-1].get_included_reward_coins())[0],
new_puzzle_hash=BURN_PUZZLE_HASH_2,
)
assert spend_bundle2 is not None
tx2: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle2)
await full_node_1.respond_transaction(tx2, peer)
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())
assert sb1 == spend_bundle1
assert sb2 is None
async def send_sb(self, node, peer, sb):
tx = full_node_protocol.RespondTransaction(sb)
await node.respond_transaction(tx, peer)
async def gen_and_send_sb(self, node, peer, *args, **kwargs):
sb = generate_test_spend_bundle(*args, **kwargs)
assert sb is not None
await self.send_sb(node, peer, sb)
return sb
def assert_sb_in_pool(self, node, sb):
assert sb == node.full_node.mempool_manager.get_spendbundle(sb.name())
def assert_sb_not_in_pool(self, node, sb):
assert node.full_node.mempool_manager.get_spendbundle(sb.name()) is None
@pytest.mark.asyncio
async def test_double_spend_with_higher_fee(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
full_node_1, full_node_2, server_1, server_2 = two_nodes
blocks = await full_node_1.get_all_full_blocks()
start_height = blocks[-1].height
blocks = bt.get_consecutive_blocks(
3,
block_list_input=blocks,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
peer = await connect_and_get_peer(server_1, server_2)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
coins = iter(blocks[-1].get_included_reward_coins())
coin1, coin2 = next(coins), next(coins)
coins = iter(blocks[-2].get_included_reward_coins())
coin3, coin4 = next(coins), next(coins)
sb1_1 = await self.gen_and_send_sb(full_node_1, peer, coin1)
sb1_2 = await self.gen_and_send_sb(full_node_1, peer, coin1, fee=uint64(1))
# Fee increase is insufficient, the old spendbundle must stay
self.assert_sb_in_pool(full_node_1, sb1_1)
self.assert_sb_not_in_pool(full_node_1, sb1_2)
min_fee_increase = full_node_1.full_node.mempool_manager.get_min_fee_increase()
sb1_3 = await self.gen_and_send_sb(full_node_1, peer, coin1, fee=uint64(min_fee_increase))
# Fee increase is sufficiently high, sb1_1 gets replaced with sb1_3
self.assert_sb_not_in_pool(full_node_1, sb1_1)
self.assert_sb_in_pool(full_node_1, sb1_3)
sb2 = generate_test_spend_bundle(coin2, fee=uint64(min_fee_increase))
sb12 = SpendBundle.aggregate((sb2, sb1_3))
await self.send_sb(full_node_1, peer, sb12)
# Aggregated spendbundle sb12 replaces sb1_3 since it spends a superset
# of coins spent in sb1_3
self.assert_sb_in_pool(full_node_1, sb12)
self.assert_sb_not_in_pool(full_node_1, sb1_3)
sb3 = generate_test_spend_bundle(coin3, fee=uint64(min_fee_increase * 2))
sb23 = SpendBundle.aggregate((sb2, sb3))
await self.send_sb(full_node_1, peer, sb23)
# sb23 must not replace existing sb12 as the former does not spend all
# coins that are spent in the latter (specifically, coin1)
self.assert_sb_in_pool(full_node_1, sb12)
self.assert_sb_not_in_pool(full_node_1, sb23)
await self.send_sb(full_node_1, peer, sb3)
# Adding non-conflicting sb3 should succeed
self.assert_sb_in_pool(full_node_1, sb3)
sb4_1 = generate_test_spend_bundle(coin4, fee=uint64(min_fee_increase))
sb1234_1 = SpendBundle.aggregate((sb12, sb3, sb4_1))
await self.send_sb(full_node_1, peer, sb1234_1)
# sb1234_1 should not be in pool as it decreases total fees per cost
self.assert_sb_not_in_pool(full_node_1, sb1234_1)
sb4_2 = generate_test_spend_bundle(coin4, fee=uint64(min_fee_increase * 2))
sb1234_2 = SpendBundle.aggregate((sb12, sb3, sb4_2))
await self.send_sb(full_node_1, peer, sb1234_2)
# sb1234_2 has a higher fee per cost than its conflicts and should get
# into mempool
self.assert_sb_in_pool(full_node_1, sb1234_2)
self.assert_sb_not_in_pool(full_node_1, sb12)
self.assert_sb_not_in_pool(full_node_1, sb3)
@pytest.mark.asyncio
async def test_invalid_block_index(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
full_node_1, full_node_2, server_1, server_2 = two_nodes
blocks = await full_node_1.get_all_full_blocks()
start_height = blocks[-1].height
blocks = bt.get_consecutive_blocks(
3,
block_list_input=blocks,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
peer = await connect_and_get_peer(server_1, server_2)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
cvp = ConditionWithArgs(
ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE,
[uint64(start_height + 5).to_bytes(4, "big")],
)
dic = {ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE: [cvp]}
spend_bundle1 = generate_test_spend_bundle(list(blocks[-1].get_included_reward_coins())[0], dic)
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1, peer)
sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
assert sb1 is None
@pytest.mark.asyncio
async def test_correct_block_index(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
full_node_1, full_node_2, server_1, server_2 = two_nodes
blocks = await full_node_1.get_all_full_blocks()
start_height = blocks[-1].height
blocks = bt.get_consecutive_blocks(
3,
block_list_input=blocks,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
peer = await connect_and_get_peer(server_1, server_2)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE, [uint64(1).to_bytes(4, "big")])
dic = {ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE: [cvp]}
spend_bundle1 = generate_test_spend_bundle(list(blocks[-1].get_included_reward_coins())[0], dic)
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1, peer)
sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
assert sb1 is spend_bundle1
@pytest.mark.asyncio
async def test_invalid_block_age(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
blocks = bt.get_consecutive_blocks(
3,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
full_node_1, full_node_2, server_1, server_2 = two_nodes
peer = await connect_and_get_peer(server_1, server_2)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, 2)
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_HEIGHT_RELATIVE, [uint64(5).to_bytes(4, "big")])
dic = {cvp.opcode: [cvp]}
spend_bundle1 = generate_test_spend_bundle(list(blocks[-1].get_included_reward_coins())[0], dic)
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1, peer)
sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
assert sb1 is None
@pytest.mark.asyncio
async def test_correct_block_age(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
full_node_1, full_node_2, server_1, server_2 = two_nodes
blocks = await full_node_1.get_all_full_blocks()
start_height = blocks[-1].height
blocks = bt.get_consecutive_blocks(
4,
block_list_input=blocks,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
peer = await connect_and_get_peer(server_1, server_2)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 4)
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_HEIGHT_RELATIVE, [uint64(1).to_bytes(4, "big")])
dic = {cvp.opcode: [cvp]}
spend_bundle1 = generate_test_spend_bundle(list(blocks[-2].get_included_reward_coins())[0], dic)
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1, peer)
sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
assert sb1 is spend_bundle1
@pytest.mark.asyncio
async def test_correct_my_id(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
full_node_1, full_node_2, server_1, server_2 = two_nodes
blocks = await full_node_1.get_all_full_blocks()
start_height = blocks[-1].height
blocks = bt.get_consecutive_blocks(
3,
block_list_input=blocks,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
full_node_1, full_node_2, server_1, server_2 = two_nodes
peer = await connect_and_get_peer(server_1, server_2)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
coin = list(blocks[-1].get_included_reward_coins())[0]
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_MY_COIN_ID, [coin.name()])
dic = {cvp.opcode: [cvp]}
spend_bundle1 = generate_test_spend_bundle(coin, dic)
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1, peer)
sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
assert sb1 is spend_bundle1
@pytest.mark.asyncio
async def test_invalid_my_id(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
full_node_1, full_node_2, server_1, server_2 = two_nodes
blocks = await full_node_1.get_all_full_blocks()
start_height = blocks[-1].height if len(blocks) > 0 else -1
blocks = bt.get_consecutive_blocks(
3,
block_list_input=blocks,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
peer = await connect_and_get_peer(server_1, server_2)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
coin = list(blocks[-1].get_included_reward_coins())[0]
coin_2 = list(blocks[-2].get_included_reward_coins())[0]
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_MY_COIN_ID, [coin_2.name()])
dic = {cvp.opcode: [cvp]}
spend_bundle1 = generate_test_spend_bundle(coin, dic)
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1, peer)
sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
assert sb1 is None
@pytest.mark.asyncio
async def test_assert_time_exceeds(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
full_node_1, full_node_2, server_1, server_2 = two_nodes
blocks = await full_node_1.get_all_full_blocks()
start_height = blocks[-1].height if len(blocks) > 0 else -1
blocks = bt.get_consecutive_blocks(
3,
block_list_input=blocks,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
peer = await connect_and_get_peer(server_1, server_2)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
time_now = uint64(int(time()))
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_SECONDS_ABSOLUTE, [time_now.to_bytes(8, "big")])
dic = {cvp.opcode: [cvp]}
spend_bundle1 = generate_test_spend_bundle(list(blocks[-1].get_included_reward_coins())[0], dic)
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1, peer)
sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
assert sb1 is spend_bundle1
@pytest.mark.asyncio
async def test_assert_time_relative_exceeds(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
full_node_1, full_node_2, server_1, server_2 = two_nodes
blocks = await full_node_1.get_all_full_blocks()
start_height = blocks[-1].height if len(blocks) > 0 else -1
blocks = bt.get_consecutive_blocks(
3,
block_list_input=blocks,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
peer = await connect_and_get_peer(server_1, server_2)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
time_relative = uint64(3)
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_SECONDS_RELATIVE, [time_relative.to_bytes(8, "big")])
dic = {cvp.opcode: [cvp]}
spend_bundle1 = generate_test_spend_bundle(list(blocks[-1].get_included_reward_coins())[0], dic)
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1, peer)
sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
assert sb1 is None
for i in range(0, 4):
await full_node_1.farm_new_transaction_block(FarmNewBlockProtocol(32 * b"0"))
tx2: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx2, peer)
sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
assert sb1 is spend_bundle1
@pytest.mark.asyncio
async def test_correct_coin_announcement_consumed(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
full_node_1, full_node_2, server_1, server_2 = two_nodes
blocks = await full_node_1.get_all_full_blocks()
start_height = blocks[-1].height if len(blocks) > 0 else -1
blocks = bt.get_consecutive_blocks(
3,
block_list_input=blocks,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
peer = await connect_and_get_peer(server_1, server_2)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
coin_1 = list(blocks[-2].get_included_reward_coins())[0]
coin_2 = list(blocks[-1].get_included_reward_coins())[0]
announce = Announcement(coin_2.name(), bytes("test", "utf-8"))
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_COIN_ANNOUNCEMENT, [announce.name()])
dic = {cvp.opcode: [cvp]}
cvp2 = ConditionWithArgs(ConditionOpcode.CREATE_COIN_ANNOUNCEMENT, [bytes("test", "utf-8")])
dic2 = {cvp.opcode: [cvp2]}
spend_bundle1 = generate_test_spend_bundle(coin_1, dic)
spend_bundle2 = generate_test_spend_bundle(coin_2, dic2)
bundle = SpendBundle.aggregate([spend_bundle1, spend_bundle2])
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(bundle)
await full_node_1.respond_transaction(tx1, peer)
mempool_bundle = full_node_1.full_node.mempool_manager.get_spendbundle(bundle.name())
assert mempool_bundle is bundle
@pytest.mark.asyncio
async def test_coin_announcement_too_big(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
full_node_1, full_node_2, server_1, server_2 = two_nodes
blocks = await full_node_1.get_all_full_blocks()
start_height = blocks[-1].height if len(blocks) > 0 else -1
blocks = bt.get_consecutive_blocks(
3,
block_list_input=blocks,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
peer = await connect_and_get_peer(server_1, server_2)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
coin_1 = list(blocks[-2].get_included_reward_coins())[0]
coin_2 = list(blocks[-1].get_included_reward_coins())[0]
announce = Announcement(coin_2.name(), bytes([1] * 10000))
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_COIN_ANNOUNCEMENT, [announce.name()])
dic = {cvp.opcode: [cvp]}
cvp2 = ConditionWithArgs(ConditionOpcode.CREATE_COIN_ANNOUNCEMENT, [bytes("test", "utf-8")])
dic2 = {cvp.opcode: [cvp2]}
spend_bundle1 = generate_test_spend_bundle(coin_1, dic)
spend_bundle2 = generate_test_spend_bundle(coin_2, dic2)
bundle = SpendBundle.aggregate([spend_bundle1, spend_bundle2])
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(bundle)
await full_node_1.respond_transaction(tx1, peer)
assert full_node_1.full_node.mempool_manager.get_spendbundle(bundle.name()) is None
blocks = bt.get_consecutive_blocks(
1, block_list_input=blocks, guarantee_transaction_block=True, transaction_data=bundle
)
try:
await full_node_1.full_node.blockchain.receive_block(blocks[-1])
assert False
except AssertionError:
pass
@pytest.mark.asyncio
async def test_invalid_coin_announcement_rejected(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
full_node_1, full_node_2, server_1, server_2 = two_nodes
blocks = await full_node_1.get_all_full_blocks()
start_height = blocks[-1].height if len(blocks) > 0 else -1
blocks = bt.get_consecutive_blocks(
3,
block_list_input=blocks,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
peer = await connect_and_get_peer(server_1, server_2)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
coin_1 = list(blocks[-2].get_included_reward_coins())[0]
coin_2 = list(blocks[-1].get_included_reward_coins())[0]
announce = Announcement(coin_2.name(), bytes("test", "utf-8"))
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_COIN_ANNOUNCEMENT, [announce.name()])
dic = {cvp.opcode: [cvp]}
# Wrong message
cvp2 = ConditionWithArgs(
ConditionOpcode.CREATE_COIN_ANNOUNCEMENT,
[bytes("wrong test", "utf-8")],
)
dic2 = {cvp.opcode: [cvp2]}
spend_bundle1 = generate_test_spend_bundle(coin_1, dic)
spend_bundle2 = generate_test_spend_bundle(coin_2, dic2)
bundle = SpendBundle.aggregate([spend_bundle1, spend_bundle2])
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1, peer)
mempool_bundle = full_node_1.full_node.mempool_manager.get_spendbundle(bundle.name())
assert mempool_bundle is None
@pytest.mark.asyncio
async def test_invalid_coin_announcement_rejected_two(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
full_node_1, full_node_2, server_1, server_2 = two_nodes
blocks = await full_node_1.get_all_full_blocks()
start_height = blocks[-1].height if len(blocks) > 0 else -1
blocks = bt.get_consecutive_blocks(
3,
block_list_input=blocks,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
peer = await connect_and_get_peer(server_1, server_2)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
coin_1 = list(blocks[-2].get_included_reward_coins())[0]
coin_2 = list(blocks[-1].get_included_reward_coins())[0]
announce = Announcement(coin_1.name(), bytes("test", "utf-8"))
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_COIN_ANNOUNCEMENT, [announce.name()])
dic = {cvp.opcode: [cvp]}
cvp2 = ConditionWithArgs(
ConditionOpcode.CREATE_COIN_ANNOUNCEMENT,
[bytes("test", "utf-8")],
)
dic2 = {cvp.opcode: [cvp2]}
spend_bundle1 = generate_test_spend_bundle(coin_1, dic)
# coin 2 is making the announcement, right message wrong coin
spend_bundle2 = generate_test_spend_bundle(coin_2, dic2)
bundle = SpendBundle.aggregate([spend_bundle1, spend_bundle2])
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1, peer)
mempool_bundle = full_node_1.full_node.mempool_manager.get_spendbundle(bundle.name())
assert mempool_bundle is None
@pytest.mark.asyncio
async def test_correct_puzzle_announcement(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
full_node_1, full_node_2, server_1, server_2 = two_nodes
blocks = await full_node_1.get_all_full_blocks()
start_height = blocks[-1].height if len(blocks) > 0 else -1
blocks = bt.get_consecutive_blocks(
3,
block_list_input=blocks,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
peer = await connect_and_get_peer(server_1, server_2)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
coin_1 = list(blocks[-2].get_included_reward_coins())[0]
coin_2 = list(blocks[-1].get_included_reward_coins())[0]
announce = Announcement(coin_2.puzzle_hash, bytes(0x80))
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_PUZZLE_ANNOUNCEMENT, [announce.name()])
dic = {cvp.opcode: [cvp]}
cvp2 = ConditionWithArgs(ConditionOpcode.CREATE_PUZZLE_ANNOUNCEMENT, [bytes(0x80)])
dic2 = {cvp.opcode: [cvp2]}
spend_bundle1 = generate_test_spend_bundle(coin_1, dic)
spend_bundle2 = generate_test_spend_bundle(coin_2, dic2)
bundle = SpendBundle.aggregate([spend_bundle1, spend_bundle2])
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(bundle)
await full_node_1.respond_transaction(tx1, peer)
mempool_bundle = full_node_1.full_node.mempool_manager.get_spendbundle(bundle.name())
assert mempool_bundle is bundle
@pytest.mark.asyncio
async def test_invalid_puzzle_announcement_rejected(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
full_node_1, full_node_2, server_1, server_2 = two_nodes
blocks = await full_node_1.get_all_full_blocks()
start_height = blocks[-1].height if len(blocks) > 0 else -1
blocks = bt.get_consecutive_blocks(
3,
block_list_input=blocks,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
peer = await connect_and_get_peer(server_1, server_2)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
coin_1 = list(blocks[-2].get_included_reward_coins())[0]
coin_2 = list(blocks[-1].get_included_reward_coins())[0]
announce = Announcement(coin_2.puzzle_hash, bytes("test", "utf-8"))
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_PUZZLE_ANNOUNCEMENT, [announce.name()])
dic = {cvp.opcode: [cvp]}
cvp2 = ConditionWithArgs(
ConditionOpcode.CREATE_PUZZLE_ANNOUNCEMENT,
[bytes("wrong test", "utf-8")],
)
dic2 = {cvp.opcode: [cvp2]}
spend_bundle1 = generate_test_spend_bundle(coin_1, dic)
spend_bundle2 = generate_test_spend_bundle(coin_2, dic2)
bundle = SpendBundle.aggregate([spend_bundle1, spend_bundle2])
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1, peer)
mempool_bundle = full_node_1.full_node.mempool_manager.get_spendbundle(bundle.name())
assert mempool_bundle is None
@pytest.mark.asyncio
async def test_invalid_puzzle_announcement_rejected_two(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
full_node_1, full_node_2, server_1, server_2 = two_nodes
blocks = await full_node_1.get_all_full_blocks()
start_height = blocks[-1].height if len(blocks) > 0 else -1
blocks = bt.get_consecutive_blocks(
3,
block_list_input=blocks,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
peer = await connect_and_get_peer(server_1, server_2)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
coin_1 = list(blocks[-2].get_included_reward_coins())[0]
coin_2 = list(blocks[-1].get_included_reward_coins())[0]
announce = Announcement(coin_2.puzzle_hash, bytes("test", "utf-8"))
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_PUZZLE_ANNOUNCEMENT, [announce.name()])
dic = {cvp.opcode: [cvp]}
# Wrong type of Create_announcement
cvp2 = ConditionWithArgs(
ConditionOpcode.CREATE_COIN_ANNOUNCEMENT,
[bytes("test", "utf-8")],
)
dic2 = {cvp.opcode: [cvp2]}
spend_bundle1 = generate_test_spend_bundle(coin_1, dic)
spend_bundle2 = generate_test_spend_bundle(coin_2, dic2)
bundle = SpendBundle.aggregate([spend_bundle1, spend_bundle2])
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1, peer)
mempool_bundle = full_node_1.full_node.mempool_manager.get_spendbundle(bundle.name())
assert mempool_bundle is None
@pytest.mark.asyncio
async def test_assert_fee_condition(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
full_node_1, full_node_2, server_1, server_2 = two_nodes
blocks = await full_node_1.get_all_full_blocks()
start_height = blocks[-1].height
blocks = bt.get_consecutive_blocks(
3,
block_list_input=blocks,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
peer = await connect_and_get_peer(server_1, server_2)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
cvp = ConditionWithArgs(ConditionOpcode.RESERVE_FEE, [int_to_bytes(10)])
dic = {cvp.opcode: [cvp]}
spend_bundle1 = generate_test_spend_bundle(list(blocks[-1].get_included_reward_coins())[0], dic, uint64(10))
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1, peer)
mempool_bundle = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
assert mempool_bundle is not None
@pytest.mark.asyncio
async def test_assert_fee_condition_negative_fee(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
full_node_1, full_node_2, server_1, server_2 = two_nodes
blocks = await full_node_1.get_all_full_blocks()
start_height = blocks[-1].height
blocks = bt.get_consecutive_blocks(
3,
block_list_input=blocks,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
peer = await connect_and_get_peer(server_1, server_2)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
cvp = ConditionWithArgs(ConditionOpcode.RESERVE_FEE, [int_to_bytes(-1)])
dic = {cvp.opcode: [cvp]}
spend_bundle1 = generate_test_spend_bundle(list(blocks[-1].get_included_reward_coins())[0], dic, uint64(10))
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1, peer)
assert full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name()) is None
blocks = bt.get_consecutive_blocks(
1, block_list_input=blocks, guarantee_transaction_block=True, transaction_data=spend_bundle1
)
assert (await full_node_1.full_node.blockchain.receive_block(blocks[-1]))[1] == Err.RESERVE_FEE_CONDITION_FAILED
@pytest.mark.asyncio
async def test_assert_fee_condition_wrong_fee(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
full_node_1, full_node_2, server_1, server_2 = two_nodes
blocks = await full_node_1.get_all_full_blocks()
start_height = blocks[-1].height
blocks = bt.get_consecutive_blocks(
3,
block_list_input=blocks,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
peer = await connect_and_get_peer(server_1, server_2)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
cvp = ConditionWithArgs(ConditionOpcode.RESERVE_FEE, [int_to_bytes(10)])
dic = {cvp.opcode: [cvp]}
spend_bundle1 = generate_test_spend_bundle(list(blocks[-1].get_included_reward_coins())[0], dic, uint64(9))
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1, peer)
mempool_bundle = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
assert mempool_bundle is None
@pytest.mark.asyncio
async def test_stealing_fee(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
full_node_1, full_node_2, server_1, server_2 = two_nodes
blocks = await full_node_1.get_all_full_blocks()
start_height = blocks[-1].height
blocks = bt.get_consecutive_blocks(
5,
block_list_input=blocks,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
full_node_1, full_node_2, server_1, server_2 = two_nodes
peer = await connect_and_get_peer(server_1, server_2)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 5)
receiver_puzzlehash = BURN_PUZZLE_HASH
cvp = ConditionWithArgs(ConditionOpcode.RESERVE_FEE, [int_to_bytes(10)])
dic = {cvp.opcode: [cvp]}
fee = 9
coin_1 = list(blocks[-2].get_included_reward_coins())[0]
coin_2 = None
for coin in list(blocks[-1].get_included_reward_coins()):
if coin.amount == coin_1.amount:
coin_2 = coin
spend_bundle1 = generate_test_spend_bundle(coin_1, dic, uint64(fee))
steal_fee_spendbundle = WALLET_A.generate_signed_transaction(
coin_1.amount + fee - 4, receiver_puzzlehash, coin_2
)
assert spend_bundle1 is not None
assert steal_fee_spendbundle is not None
combined = SpendBundle.aggregate([spend_bundle1, steal_fee_spendbundle])
assert combined.fees() == 4
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1, peer)
mempool_bundle = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
assert mempool_bundle is None
@pytest.mark.asyncio
async def test_double_spend_same_bundle(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
full_node_1, full_node_2, server_1, server_2 = two_nodes
blocks = await full_node_1.get_all_full_blocks()
start_height = blocks[-1].height
blocks = bt.get_consecutive_blocks(
3,
block_list_input=blocks,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
peer = await connect_and_get_peer(server_1, server_2)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
coin = list(blocks[-1].get_included_reward_coins())[0]
spend_bundle1 = generate_test_spend_bundle(coin)
assert spend_bundle1 is not None
spend_bundle2 = generate_test_spend_bundle(
coin,
new_puzzle_hash=BURN_PUZZLE_HASH_2,
)
assert spend_bundle2 is not None
spend_bundle_combined = SpendBundle.aggregate([spend_bundle1, spend_bundle2])
tx: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle_combined)
await full_node_1.respond_transaction(tx, peer)
sb = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle_combined.name())
assert sb is None
@pytest.mark.asyncio
async def test_agg_sig_condition(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
full_node_1, full_node_2, server_1, server_2 = two_nodes
blocks = await full_node_1.get_all_full_blocks()
start_height = blocks[-1].height
blocks = bt.get_consecutive_blocks(
3,
block_list_input=blocks,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
# this code has been changed to use generate_test_spend_bundle
# not quite sure why all the gymnastics are being performed
coin = list(blocks[-1].get_included_reward_coins())[0]
spend_bundle_0 = generate_test_spend_bundle(coin)
unsigned: List[CoinSolution] = spend_bundle_0.coin_solutions
assert len(unsigned) == 1
coin_solution: CoinSolution = unsigned[0]
err, con, cost = conditions_for_solution(coin_solution.puzzle_reveal, coin_solution.solution, INFINITE_COST)
assert con is not None
# TODO(straya): fix this test
# puzzle, solution = list(coin_solution.solution.as_iter())
# conditions_dict = conditions_by_opcode(con)
# pkm_pairs = pkm_pairs_for_conditions_dict(conditions_dict, coin_solution.coin.name())
# assert len(pkm_pairs) == 1
#
# assert pkm_pairs[0][1] == solution.rest().first().get_tree_hash() + coin_solution.coin.name()
#
# spend_bundle = WALLET_A.sign_transaction(unsigned)
# assert spend_bundle is not None
#
# tx: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle)
# await full_node_1.respond_transaction(tx, peer)
#
# sb = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle.name())
# assert sb is spend_bundle
@pytest.mark.asyncio
async def test_correct_my_parent(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
full_node_1, full_node_2, server_1, server_2 = two_nodes
blocks = await full_node_1.get_all_full_blocks()
start_height = blocks[-1].height
blocks = bt.get_consecutive_blocks(
3,
block_list_input=blocks,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
full_node_1, full_node_2, server_1, server_2 = two_nodes
peer = await connect_and_get_peer(server_1, server_2)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
coin = list(blocks[-1].get_included_reward_coins())[0]
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_MY_PARENT_ID, [coin.parent_coin_info])
dic = {cvp.opcode: [cvp]}
spend_bundle1 = generate_test_spend_bundle(coin, dic)
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1, peer)
sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
assert sb1 is spend_bundle1
@pytest.mark.asyncio
async def test_invalid_my_parent(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
full_node_1, full_node_2, server_1, server_2 = two_nodes
blocks = await full_node_1.get_all_full_blocks()
start_height = blocks[-1].height if len(blocks) > 0 else -1
blocks = bt.get_consecutive_blocks(
3,
block_list_input=blocks,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
peer = await connect_and_get_peer(server_1, server_2)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
coin = list(blocks[-1].get_included_reward_coins())[0]
coin_2 = list(blocks[-2].get_included_reward_coins())[0]
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_MY_PARENT_ID, [coin_2.parent_coin_info])
dic = {cvp.opcode: [cvp]}
spend_bundle1 = generate_test_spend_bundle(coin, dic)
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1, peer)
sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
assert sb1 is None
@pytest.mark.asyncio
async def test_correct_my_puzhash(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
full_node_1, full_node_2, server_1, server_2 = two_nodes
blocks = await full_node_1.get_all_full_blocks()
start_height = blocks[-1].height
blocks = bt.get_consecutive_blocks(
3,
block_list_input=blocks,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
full_node_1, full_node_2, server_1, server_2 = two_nodes
peer = await connect_and_get_peer(server_1, server_2)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
coin = list(blocks[-1].get_included_reward_coins())[0]
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_MY_PUZZLEHASH, [coin.puzzle_hash])
dic = {cvp.opcode: [cvp]}
spend_bundle1 = generate_test_spend_bundle(coin, dic)
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1, peer)
sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
assert sb1 is spend_bundle1
@pytest.mark.asyncio
async def test_invalid_my_puzhash(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
full_node_1, full_node_2, server_1, server_2 = two_nodes
blocks = await full_node_1.get_all_full_blocks()
start_height = blocks[-1].height if len(blocks) > 0 else -1
blocks = bt.get_consecutive_blocks(
3,
block_list_input=blocks,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
peer = await connect_and_get_peer(server_1, server_2)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
coin = list(blocks[-1].get_included_reward_coins())[0]
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_MY_PUZZLEHASH, [Program.to([]).get_tree_hash()])
dic = {cvp.opcode: [cvp]}
spend_bundle1 = generate_test_spend_bundle(coin, dic)
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1, peer)
sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
assert sb1 is None
@pytest.mark.asyncio
async def test_correct_my_amount(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
full_node_1, full_node_2, server_1, server_2 = two_nodes
blocks = await full_node_1.get_all_full_blocks()
start_height = blocks[-1].height
blocks = bt.get_consecutive_blocks(
3,
block_list_input=blocks,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
full_node_1, full_node_2, server_1, server_2 = two_nodes
peer = await connect_and_get_peer(server_1, server_2)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
coin = list(blocks[-1].get_included_reward_coins())[0]
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_MY_AMOUNT, [coin.amount])
dic = {cvp.opcode: [cvp]}
spend_bundle1 = generate_test_spend_bundle(coin, dic)
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1, peer)
sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
assert sb1 is spend_bundle1
@pytest.mark.asyncio
async def test_invalid_my_amount(self, two_nodes):
reward_ph = WALLET_A.get_new_puzzlehash()
full_node_1, full_node_2, server_1, server_2 = two_nodes
blocks = await full_node_1.get_all_full_blocks()
start_height = blocks[-1].height if len(blocks) > 0 else -1
blocks = bt.get_consecutive_blocks(
3,
block_list_input=blocks,
guarantee_transaction_block=True,
farmer_reward_puzzle_hash=reward_ph,
pool_reward_puzzle_hash=reward_ph,
)
peer = await connect_and_get_peer(server_1, server_2)
for block in blocks:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
coin = list(blocks[-1].get_included_reward_coins())[0]
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_MY_AMOUNT, [1000])
dic = {cvp.opcode: [cvp]}
spend_bundle1 = generate_test_spend_bundle(coin, dic)
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
await full_node_1.respond_transaction(tx1, peer)
sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
assert sb1 is None