From 9fce41cfb7ee2803bbb1456949e5b2ec7c4eee92 Mon Sep 17 00:00:00 2001 From: Mariano Sorgente <3069354+mariano54@users.noreply.github.com> Date: Wed, 21 Apr 2021 09:51:48 +0900 Subject: [PATCH] Assert small messages (#2213) * Assert small messages * Update condition_tools.py Add `TODO`. Co-authored-by: Richard Kiss --- chia/util/condition_tools.py | 7 ++++ tests/core/full_node/test_mempool.py | 51 ++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/chia/util/condition_tools.py b/chia/util/condition_tools.py index 064482997a6f..c01d2b2ce555 100644 --- a/chia/util/condition_tools.py +++ b/chia/util/condition_tools.py @@ -12,6 +12,9 @@ from chia.util.errors import ConsensusError, Err from chia.util.ints import uint64 +# TODO: review each `assert` and consider replacing with explicit checks +# since asserts can be stripped with python `-OO` flag + def parse_sexp_to_condition( sexp: Program, @@ -111,6 +114,7 @@ def coin_announcements_for_conditions_dict( output_announcements: Set[Announcement] = set() for cvp in conditions_dict.get(ConditionOpcode.CREATE_COIN_ANNOUNCEMENT, []): message = cvp.vars[0] + assert len(message) <= 1024 announcement = Announcement(input_coin.name(), message) output_announcements.add(announcement) return output_announcements @@ -123,6 +127,7 @@ def puzzle_announcements_for_conditions_dict( output_announcements: Set[Announcement] = set() for cvp in conditions_dict.get(ConditionOpcode.CREATE_PUZZLE_ANNOUNCEMENT, []): message = cvp.vars[0] + assert len(message) <= 1024 announcement = Announcement(input_coin.puzzle_hash, message) output_announcements.add(announcement) return output_announcements @@ -135,6 +140,7 @@ def coin_announcements_names_for_npc(npc_list) -> Set[bytes32]: if condition == ConditionOpcode.CREATE_COIN_ANNOUNCEMENT: for cvp in cvp_list: message = cvp.vars[0] + assert len(message) <= 1024 announcement = Announcement(npc.coin_name, message) output_announcements.add(announcement.name()) return output_announcements @@ -147,6 +153,7 @@ def puzzle_announcements_names_for_npc(npc_list) -> Set[bytes32]: if condition == ConditionOpcode.CREATE_PUZZLE_ANNOUNCEMENT: for cvp in cvp_list: message = cvp.vars[0] + assert len(message) <= 1024 announcement = Announcement(npc.puzzle_hash, message) output_announcements.add(announcement.name()) return output_announcements diff --git a/tests/core/full_node/test_mempool.py b/tests/core/full_node/test_mempool.py index ecfc1cf2797c..0c8b7f0a0555 100644 --- a/tests/core/full_node/test_mempool.py +++ b/tests/core/full_node/test_mempool.py @@ -559,6 +559,57 @@ async def test_correct_coin_announcement_consumed(self, two_nodes): 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()