예제 #1
0
    async def test_assert_time_exceeds_both_cases(self, two_nodes):
        num_blocks = 2

        blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"")
        full_node_1, full_node_2, server_1, server_2 = two_nodes

        block = blocks[1]

        for b in blocks:
            async for _ in full_node_1.respond_block(
                full_node_protocol.RespondBlock(b)
            ):
                pass

        time_now = uint64(int(time() * 1000))
        time_now_plus_3 = time_now + 3000

        cvp = ConditionVarPair(
            ConditionOpcode.ASSERT_TIME_EXCEEDS,
            time_now_plus_3.to_bytes(8, "big"),
            None,
        )
        dic = {cvp.opcode: [cvp]}

        spend_bundle1 = generate_test_spend_bundle(block.get_coinbase(), dic)

        assert spend_bundle1 is not None
        tx1: full_node_protocol.RespondTransaction = (
            full_node_protocol.RespondTransaction(spend_bundle1)
        )
        async for _ in full_node_1.respond_transaction(tx1):
            outbound: OutboundMessage = _
            assert outbound.message.function != "new_transaction"

        # Sleep so that 3 sec passes
        await asyncio.sleep(3)

        tx2: full_node_protocol.RespondTransaction = (
            full_node_protocol.RespondTransaction(spend_bundle1)
        )
        async for _ in full_node_1.respond_transaction(tx2):
            outbound_2: OutboundMessage = _
            # Maybe transaction means that it's accepted in mempool
            assert outbound_2.message.function == "new_transaction"

        sb1 = full_node_1.mempool_manager.get_spendbundle(spend_bundle1.name())

        assert sb1 is spend_bundle1
예제 #2
0
    async def test_assert_fee_condition_wrong_fee(self, two_nodes):
        num_blocks = 2
        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]

        for b in blocks:
            async for _ in full_node_1.respond_block(
                    full_node_protocol.RespondBlock(b)):
                pass

        cvp = ConditionVarPair(
            ConditionOpcode.ASSERT_FEE,
            int_to_bytes(10),
            None,
        )
        dic = {cvp.opcode: [cvp]}

        spend_bundle1 = wallet_a.generate_signed_transaction(
            1000, receiver_puzzlehash, block.header.data.coinbase, dic, 9)

        assert spend_bundle1 is not None

        tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(
            spend_bundle1)

        outbound_messages: List[OutboundMessage] = []
        async for outbound in full_node_1.respond_transaction(tx1):
            outbound_messages.append(outbound)

        new_transaction = False
        for msg in outbound_messages:
            if msg.message.function == "new_transaction":
                new_transaction = True

        assert new_transaction == False

        mempool_bundle = full_node_1.mempool_manager.get_spendbundle(
            spend_bundle1.name())

        assert mempool_bundle is None
예제 #3
0
    async def test_correct_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 = ConditionVarPair(ConditionOpcode.ASSERT_ANNOUNCEMENT,
                               [announce.name()])

        dic = {cvp.opcode: [cvp]}

        cvp2 = ConditionVarPair(ConditionOpcode.CREATE_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
예제 #4
0
    async def test_backtrack_sync_1(self, two_nodes):
        blocks = bt.get_consecutive_blocks(1, skip_slots=1)
        blocks = bt.get_consecutive_blocks(1, blocks, skip_slots=0)
        blocks = bt.get_consecutive_blocks(1, blocks, skip_slots=0)
        full_node_1, full_node_2, server_1, server_2 = two_nodes

        # 3 blocks to node_1 in different sub slots
        for block in blocks:
            await full_node_1.full_node.respond_block(
                full_node_protocol.RespondBlock(block))

        await server_2.start_client(
            PeerInfo(self_hostname, uint16(server_1._port)),
            on_connect=full_node_2.full_node.on_connect,
        )
        await time_out_assert(60, node_height_exactly, True, full_node_2, 2)
예제 #5
0
    async def test_double_spend(self, two_nodes):
        num_blocks = 2
        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.respond_block(
            full_node_protocol.RespondBlock(block)
        ):
            pass

        spend_bundle1 = wallet_a.generate_signed_transaction(
            1000, receiver_puzzlehash, block.header.data.coinbase
        )

        assert spend_bundle1 is not None
        tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(
            spend_bundle1
        )
        async for _ in full_node_1.respond_transaction(tx1):
            outbound: OutboundMessage = _
            # Maybe transaction means that it's accepted in mempool
            assert outbound.message.function == "new_transaction"

        other_receiver = WalletTool()
        spend_bundle2 = wallet_a.generate_signed_transaction(
            1000, other_receiver.get_new_puzzlehash(), block.header.data.coinbase
        )
        assert spend_bundle2 is not None
        tx2: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(
            spend_bundle2
        )
        async for _ in full_node_1.respond_transaction(tx2):
            pass

        sb1 = full_node_1.mempool_manager.get_spendbundle(spend_bundle1.name())
        sb2 = full_node_1.mempool_manager.get_spendbundle(spend_bundle2.name())

        assert sb1 == spend_bundle1
        assert sb2 is None
예제 #6
0
    async def test_assert_time_exceeds_both_cases(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() * 1000))
        time_now_plus_3 = time_now + 3000

        cvp = ConditionVarPair(ConditionOpcode.ASSERT_SECONDS_NOW_EXCEEDS,
                               [time_now_plus_3.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)

        # Sleep so that 3 sec passes
        await asyncio.sleep(3)

        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
예제 #7
0
    async def test_agg_sig_condition(self, two_nodes):
        num_blocks = 2

        blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"")
        full_node_1, full_node_2, server_1, server_2 = two_nodes

        block = blocks[1]
        async for _ in full_node_1.respond_block(
            full_node_protocol.RespondBlock(block)
        ):
            pass

        # this code has been changed to use generate_test_spend_bundle
        # not quite sure why all the gymnastics are being performed
        spend_bundle_0 = generate_test_spend_bundle(
            block.get_coinbase(),
        )
        unsigned: List[CoinSolution] = spend_bundle_0.coin_solutions

        assert len(unsigned) == 1
        coin_solution = unsigned[0]

        err, con, cost = conditions_for_solution(coin_solution.solution)
        assert con is not None

        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.first().get_tree_hash()

        spend_bundle = WALLET_A.sign_transaction(unsigned)
        assert spend_bundle is not None

        tx: full_node_protocol.RespondTransaction = (
            full_node_protocol.RespondTransaction(spend_bundle)
        )
        async for _ in full_node_1.respond_transaction(tx):
            outbound: OutboundMessage = _
            # Maybe transaction means that it's accepted in mempool
            assert outbound.message.function == "new_transaction"

        sb = full_node_1.mempool_manager.get_spendbundle(spend_bundle.name())
        assert sb is spend_bundle
예제 #8
0
    async def test_agg_sig_condition(self, two_nodes):
        num_blocks = 2
        wallet_a = bt.get_pool_wallet_tool()
        wallet_receiver = WalletTool()
        receiver_puzzlehash = wallet_receiver.get_new_puzzlehash()

        blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10,
                                           b"")
        full_node_1, full_node_2, server_1, server_2 = two_nodes

        block = blocks[1]
        async for _ in full_node_1.respond_block(
                full_node_protocol.RespondBlock(block)):
            pass

        unsigned: List[Tuple[
            Program, CoinSolution]] = wallet_a.generate_unsigned_transaction(
                1000, receiver_puzzlehash, block.get_coinbase(), {}, 0)
        assert len(unsigned) == 1

        puzzle, solution = unsigned[0]
        code_ = [puzzle, solution.solution]
        sexp = Program.to(code_)

        err, con, cost = conditions_for_solution(sexp)
        assert con is not None

        conditions_dict = conditions_by_opcode(con)
        pkm_pairs = pkm_pairs_for_conditions_dict(conditions_dict,
                                                  solution.coin.name())
        assert len(pkm_pairs) == 1

        assert pkm_pairs[0][1] == solution.solution.first().get_tree_hash()

        spend_bundle = wallet_a.sign_transaction(unsigned)
        assert spend_bundle is not None

        tx: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(
            spend_bundle)
        async for _ in full_node_1.respond_transaction(tx):
            outbound: OutboundMessage = _
            # Maybe transaction means that it's accepted in mempool
            assert outbound.message.function == "new_transaction"

        sb = full_node_1.mempool_manager.get_spendbundle(spend_bundle.name())
        assert sb is spend_bundle
예제 #9
0
    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)

        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],
                                                   fee=uint64(1))

        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 is None
        assert sb2 == spend_bundle2
예제 #10
0
    async def test_invalid_coin_consumed(self, two_nodes):
        num_blocks = 2
        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]
        block2 = blocks[2]

        for b in blocks:
            async for _ in full_node_1.respond_block(
                full_node_protocol.RespondBlock(b)
            ):
                pass

        cvp = ConditionVarPair(
            ConditionOpcode.ASSERT_COIN_CONSUMED,
            block2.header.data.coinbase.name(),
            None,
        )
        dic = {cvp.opcode: [cvp]}

        spend_bundle1 = wallet_a.generate_signed_transaction(
            1000, receiver_puzzlehash, block.header.data.coinbase, dic
        )

        assert spend_bundle1 is not None
        tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(
            spend_bundle1
        )
        async for _ in full_node_1.respond_transaction(tx1):
            outbound: OutboundMessage = _
            # Maybe transaction means that it's accepted in mempool
            assert outbound.message.function == "new_transaction"

        mempool_bundle = full_node_1.mempool_manager.get_spendbundle(
            spend_bundle1.name()
        )

        assert mempool_bundle is None
예제 #11
0
    async def test_assert_fee_condition(self, two_nodes):
        num_blocks = 2

        blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"")
        full_node_1, full_node_2, server_1, server_2 = two_nodes

        block = blocks[1]

        for b in blocks:
            async for _ in full_node_1.respond_block(
                full_node_protocol.RespondBlock(b)
            ):
                pass

        cvp = ConditionVarPair(
            ConditionOpcode.ASSERT_FEE,
            int_to_bytes(10),
            None,
        )
        dic = {cvp.opcode: [cvp]}

        spend_bundle1 = generate_test_spend_bundle(block.get_coinbase(), dic, 10)

        assert spend_bundle1 is not None

        tx1: full_node_protocol.RespondTransaction = (
            full_node_protocol.RespondTransaction(spend_bundle1)
        )

        outbound_messages: List[OutboundMessage] = []
        async for outbound in full_node_1.respond_transaction(tx1):
            outbound_messages.append(outbound)

        new_transaction = False
        for msg in outbound_messages:
            if msg.message.function == "new_transaction":
                new_transaction = True

        assert new_transaction

        mempool_bundle = full_node_1.mempool_manager.get_spendbundle(
            spend_bundle1.name()
        )

        assert mempool_bundle is not None
예제 #12
0
    async def test_basic_sync(self, two_nodes):
        num_blocks = 40
        blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10)
        full_node_1, full_node_2, server_1, server_2 = two_nodes

        for i in range(1, num_blocks):
            async for _ in full_node_1.respond_block(
                    full_node_protocol.RespondBlock(blocks[i])):
                pass

        await server_2.start_client(
            PeerInfo("localhost", uint16(server_1._port)), None)

        # The second node should eventually catch up to the first one, and have the
        # same tip at height num_blocks - 1 (or at least num_blocks - 3, in case we sync to a
        # worse tip)
        await time_out_assert(60, node_height_at_least, True, full_node_2,
                              num_blocks - 3)
예제 #13
0
    async def test_validate_blockchain_duplicate_output(self, two_nodes):
        num_blocks = 3
        wallet_a = WALLET_A
        coinbase_puzzlehash = WALLET_A_PUZZLE_HASHES[0]
        receiver_puzzlehash = BURN_PUZZLE_HASH

        blocks = bt.get_consecutive_blocks(
            num_blocks,
            farmer_reward_puzzle_hash=coinbase_puzzlehash,
            guarantee_transaction_block=True)
        full_node_api_1, full_node_api_2, server_1, server_2 = two_nodes
        full_node_1 = full_node_api_1.full_node

        for block in blocks:
            await full_node_api_1.full_node.respond_block(
                full_node_protocol.RespondBlock(block))

        spend_block = blocks[2]

        spend_coin = None
        for coin in list(spend_block.get_included_reward_coins()):
            if coin.puzzle_hash == coinbase_puzzlehash:
                spend_coin = coin

        spend_bundle = wallet_a.generate_signed_transaction(
            1000, receiver_puzzlehash, spend_coin)
        spend_bundle_double = wallet_a.generate_signed_transaction(
            1000, receiver_puzzlehash, spend_coin)

        block_spendbundle = SpendBundle.aggregate(
            [spend_bundle, spend_bundle_double])

        new_blocks = bt.get_consecutive_blocks(
            1,
            block_list_input=blocks,
            farmer_reward_puzzle_hash=coinbase_puzzlehash,
            transaction_data=block_spendbundle,
            guarantee_transaction_block=True,
        )

        next_block = new_blocks[-1]
        res, err, _ = await full_node_1.blockchain.receive_block(next_block)
        assert res == ReceiveBlockResult.INVALID_BLOCK
        assert err == Err.DUPLICATE_OUTPUT
    async def test_validate_blockchain_with_double_spend(self, two_nodes):

        num_blocks = 5
        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

        for block in blocks:
            async for _ in full_node_1.respond_block(
                full_node_protocol.RespondBlock(block)
            ):
                pass

        spent_block = blocks[1]

        spend_bundle = wallet_a.generate_signed_transaction(
            1000, receiver_puzzlehash, spent_block.get_coinbase()
        )
        spend_bundle_double = wallet_a.generate_signed_transaction(
            1001, receiver_puzzlehash, spent_block.get_coinbase()
        )

        block_spendbundle = SpendBundle.aggregate([spend_bundle, spend_bundle_double])
        program = best_solution_program(block_spendbundle)
        aggsig = block_spendbundle.aggregated_signature

        dic_h = {(num_blocks + 1): (program, aggsig)}
        new_blocks = bt.get_consecutive_blocks(
            test_constants, 1, blocks, 10, b"", coinbase_puzzlehash, dic_h
        )

        next_block = new_blocks[num_blocks + 1]
        error = await full_node_1.blockchain._validate_transactions(
            next_block, next_block.get_fees_coin().amount
        )

        assert error is Err.DOUBLE_SPEND
예제 #15
0
    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
예제 #16
0
    async def test_assert_time_exceeds(self, two_nodes):
        num_blocks = 2
        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]

        for b in blocks:
            async for _ in full_node_1.respond_block(
                full_node_protocol.RespondBlock(b)
            ):
                pass

        time_now = uint64(int(time() * 1000))

        cvp = ConditionVarPair(
            ConditionOpcode.ASSERT_TIME_EXCEEDS, time_now.to_bytes(8, "big"), None
        )
        dic = {cvp.opcode: [cvp]}

        spend_bundle1 = wallet_a.generate_signed_transaction(
            1000, receiver_puzzlehash, block.header.data.coinbase, dic
        )

        assert spend_bundle1 is not None
        tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(
            spend_bundle1
        )
        async for _ in full_node_1.respond_transaction(tx1):
            outbound: OutboundMessage = _
            # Maybe transaction means that it's accepted in mempool
            assert outbound.message.function == "new_transaction"

        sb1 = full_node_1.mempool_manager.get_spendbundle(spend_bundle1.name())

        assert sb1 is spend_bundle1
예제 #17
0
    async def test_new_pot(self, two_nodes, wallet_blocks):
        full_node_1, full_node_2, server_1, server_2 = two_nodes
        wallet_a, wallet_receiver, _ = wallet_blocks

        no_unf_block = fnp.NewProofOfTime(
            uint32(5), bytes(32 * [1]), uint64(124512), uint8(2)
        )
        assert len([x async for x in full_node_1.new_proof_of_time(no_unf_block)]) == 0

        blocks = await get_block_path(full_node_1)

        blocks_new = bt.get_consecutive_blocks(
            test_constants, 1, blocks[:-1], 10, seed=b"1212412",
        )

        unf_block = FullBlock(
            blocks_new[-1].proof_of_space,
            None,
            blocks_new[-1].header,
            blocks_new[-1].transactions_generator,
            blocks_new[-1].transactions_filter,
        )
        unf_block_req = fnp.RespondUnfinishedBlock(unf_block)
        res = [x async for x in full_node_1.respond_unfinished_block(unf_block_req)]

        dont_have = fnp.NewProofOfTime(
            unf_block.height,
            unf_block.proof_of_space.challenge_hash,
            res[0].message.data.iterations_needed,
            uint8(2),
        )
        assert len([x async for x in full_node_1.new_proof_of_time(dont_have)]) == 1

        [x async for x in full_node_1.respond_block(fnp.RespondBlock(blocks_new[-1]))]
        assert blocks_new[-1].proof_of_time is not None
        already_have = fnp.NewProofOfTime(
            unf_block.height,
            unf_block.proof_of_space.challenge_hash,
            res[0].message.data.iterations_needed,
            blocks_new[-1].proof_of_time.witness_type,
        )
        assert len([x async for x in full_node_1.new_proof_of_time(already_have)]) == 0
예제 #18
0
    async def test_double_spend_same_bundle(self, two_nodes):
        num_blocks = 2
        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.respond_block(
            full_node_protocol.RespondBlock(block)
        ):
            pass

        spend_bundle1 = wallet_a.generate_signed_transaction(
            1000, receiver_puzzlehash, block.header.data.coinbase
        )

        assert spend_bundle1 is not None

        other_receiver = WalletTool()
        spend_bundle2 = wallet_a.generate_signed_transaction(
            1000, other_receiver.get_new_puzzlehash(), block.header.data.coinbase
        )

        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
        )
        messages = []
        async for outbound in full_node_1.respond_transaction(tx):
            messages.append(outbound)

        sb = full_node_1.mempool_manager.get_spendbundle(spend_bundle_combined.name())
        assert sb is None
예제 #19
0
    async def test_invalid_block_index(self, two_nodes):
        num_blocks = 2
        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.respond_block(
            full_node_protocol.RespondBlock(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.header.data.coinbase, dic
        )

        assert spend_bundle1 is not None
        tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(
            spend_bundle1
        )
        async for _ in full_node_1.respond_transaction(tx1):
            outbound: OutboundMessage = _
            # Maybe transaction means that it's accepted in mempool
            assert outbound.message.function != "new_transaction"

        sb1 = full_node_1.mempool_manager.get_spendbundle(spend_bundle1.name())

        assert sb1 is None
예제 #20
0
    async def test_blocks_load(self, two_nodes):
        num_blocks = 50
        full_node_1, full_node_2, server_1, server_2 = two_nodes
        blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10)

        await server_2.start_client(PeerInfo("localhost", uint16(server_1._port)), None)

        async def num_connections():
            return len(server_2.global_connections.get_connections())

        await time_out_assert(10, num_connections, 1)

        start_unf = time.time()
        for i in range(1, num_blocks):
            await time_out_assert(5, node_height_at_least, True, full_node_2, i - 2)
            msg = Message("respond_block", full_node_protocol.RespondBlock(blocks[i]))
            server_1.push_message(
                OutboundMessage(NodeType.FULL_NODE, msg, Delivery.BROADCAST)
            )
        print(f"Time taken to process {num_blocks} is {time.time() - start_unf}")
        assert time.time() - start_unf < 100
예제 #21
0
    async def test_double_spend(self, two_nodes):
        num_blocks = 2

        blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"")
        full_node_1, full_node_2, server_1, server_2 = two_nodes

        block = blocks[1]
        async for _ in full_node_1.respond_block(
            full_node_protocol.RespondBlock(block)
        ):
            pass

        spend_bundle1 = generate_test_spend_bundle(block.get_coinbase())

        assert spend_bundle1 is not None
        tx1: full_node_protocol.RespondTransaction = (
            full_node_protocol.RespondTransaction(spend_bundle1)
        )
        async for _ in full_node_1.respond_transaction(tx1):
            outbound: OutboundMessage = _
            # Maybe transaction means that it's accepted in mempool
            assert outbound.message.function == "new_transaction"

        spend_bundle2 = generate_test_spend_bundle(
            block.get_coinbase(),
            newpuzzlehash=BURN_PUZZLE_HASH_2,
        )
        assert spend_bundle2 is not None
        tx2: full_node_protocol.RespondTransaction = (
            full_node_protocol.RespondTransaction(spend_bundle2)
        )
        async for _ in full_node_1.respond_transaction(tx2):
            pass

        sb1 = full_node_1.mempool_manager.get_spendbundle(spend_bundle1.name())
        sb2 = full_node_1.mempool_manager.get_spendbundle(spend_bundle2.name())

        assert sb1 == spend_bundle1
        assert sb2 is None
예제 #22
0
    async def test_request_unfinished(self, two_nodes, wallet_blocks):
        full_node_1, full_node_2, server_1, server_2 = two_nodes
        wallet_a, wallet_receiver, blocks = wallet_blocks

        blocks_list = await get_block_path(full_node_1)

        blocks_new = bt.get_consecutive_blocks(
            test_constants, 2, blocks_list, 10, seed=b"another seed 3",
        )
        # Add one block
        [_ async for _ in full_node_1.respond_block(fnp.RespondBlock(blocks_new[-2]))]

        unf_block = FullBlock(
            blocks_new[-1].proof_of_space,
            None,
            blocks_new[-1].header,
            blocks_new[-1].transactions_generator,
            blocks_new[-1].transactions_filter,
        )
        unf_block_req = fnp.RespondUnfinishedBlock(unf_block)

        # Don't have
        req = fnp.RequestUnfinishedBlock(unf_block.header_hash)
        res = [x async for x in full_node_1.request_unfinished_block(req)]
        assert len(res) == 1
        assert res[0].message.data == fnp.RejectUnfinishedBlockRequest(
            unf_block.header_hash
        )
        # Have unfinished block
        [x async for x in full_node_1.respond_unfinished_block(unf_block_req)]
        res = [x async for x in full_node_1.request_unfinished_block(req)]
        assert len(res) == 1
        assert res[0].message.data == fnp.RespondUnfinishedBlock(unf_block)

        # Have full block (genesis in this case)
        req = fnp.RequestUnfinishedBlock(blocks_new[0].header_hash)
        res = [x async for x in full_node_1.request_unfinished_block(req)]
        assert len(res) == 1
        assert res[0].message.data.block.header_hash == blocks_new[0].header_hash
예제 #23
0
    async def test_correct_coin_consumed(self, two_nodes):
        num_blocks = 2

        blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"")
        full_node_1, full_node_2, server_1, server_2 = two_nodes

        block = blocks[1]
        block2 = blocks[2]

        for b in blocks:
            async for _ in full_node_1.respond_block(
                full_node_protocol.RespondBlock(b)
            ):
                pass

        cvp = ConditionVarPair(
            ConditionOpcode.ASSERT_COIN_CONSUMED,
            block2.get_coinbase().name(),
            None,
        )
        dic = {cvp.opcode: [cvp]}

        spend_bundle1 = generate_test_spend_bundle(block.get_coinbase(), dic)

        spend_bundle2 = generate_test_spend_bundle(block2.get_coinbase())

        bundle = SpendBundle.aggregate([spend_bundle1, spend_bundle2])

        tx1: full_node_protocol.RespondTransaction = (
            full_node_protocol.RespondTransaction(bundle)
        )
        async for _ in full_node_1.respond_transaction(tx1):
            outbound: OutboundMessage = _
            # Maybe transaction means that it's accepted in mempool
            assert outbound.message.function == "new_transaction"

        mempool_bundle = full_node_1.mempool_manager.get_spendbundle(bundle.name())

        assert mempool_bundle is bundle
예제 #24
0
    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 = ConditionVarPair(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
예제 #25
0
    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 = ConditionVarPair(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
예제 #26
0
    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 = ConditionVarPair(
            ConditionOpcode.ASSERT_HEIGHT_NOW_EXCEEDS,
            [uint64(start_height + 5).to_bytes(4, "big")],
        )
        dic = {ConditionOpcode.ASSERT_HEIGHT_NOW_EXCEEDS: [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
예제 #27
0
    async def test_short_sync_wallet(self, wallet_node):
        num_blocks = 8
        blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10)
        full_node_1, wallet_node, server_1, server_2 = wallet_node

        for i in range(1, len(blocks)):
            async for _ in full_node_1.respond_block(
                    full_node_protocol.RespondBlock(blocks[i])):
                pass

        await server_2.start_client(
            PeerInfo("localhost", uint16(server_1._port)), None)
        start = time.time()
        while time.time() - start < 60:
            # The second node should eventually catch up to the first one, and have the
            # same tip at height num_blocks - 1.
            if (wallet_node.wallet_state_manager.block_records[
                    wallet_node.wallet_state_manager.lca].height == 6):
                return
            await asyncio.sleep(0.1)
        raise Exception(
            f"Took too long to process blocks, stopped at: {time.time() - start}"
        )
예제 #28
0
    async def reorg_from_index_to_new_index(self, request: ReorgProtocol):
        new_index = request.new_index
        old_index = request.old_index
        coinbase_ph = request.puzzle_hash
        top_tip = self.get_tip()

        current_blocks = await self.get_current_blocks(top_tip)
        block_count = new_index - old_index

        more_blocks = self.bt.get_consecutive_blocks(
            self.constants,
            block_count,
            current_blocks[:old_index],
            10,
            seed=token_bytes(),
            reward_puzzlehash=coinbase_ph,
            transaction_data_at_height={},
        )
        assert self.server is not None
        for block in more_blocks:
            async for msg in self.respond_block(full_node_protocol.RespondBlock(block)):
                self.server.push_message(msg)
                self.log.info(f"New message: {msg}")
    async def test_validate_blockchain_duplicate_output(self, two_nodes):
        num_blocks = 10
        wallet_a = WALLET_A
        coinbase_puzzlehash = WALLET_A_PUZZLE_HASHES[0]
        receiver_puzzlehash = BURN_PUZZLE_HASH

        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

        for block in blocks:
            async for _ in full_node_1.respond_block(
                    full_node_protocol.RespondBlock(block)):
                pass

        spent_block = blocks[1]

        spend_bundle = wallet_a.generate_signed_transaction(
            1000, receiver_puzzlehash, spent_block.get_coinbase())
        spend_bundle_double = wallet_a.generate_signed_transaction(
            1000, receiver_puzzlehash, spent_block.get_coinbase())

        block_spendbundle = SpendBundle.aggregate(
            [spend_bundle, spend_bundle_double])
        program = best_solution_program(block_spendbundle)
        aggsig = block_spendbundle.aggregated_signature

        dic_h = {(num_blocks + 1): (program, aggsig)}
        new_blocks = bt.get_consecutive_blocks(test_constants, 1, blocks, 10,
                                               b"", coinbase_puzzlehash, dic_h)

        next_block = new_blocks[(num_blocks + 1)]
        error = await full_node_1.blockchain._validate_transactions(
            next_block,
            next_block.get_fees_coin().amount)

        assert error is Err.DUPLICATE_OUTPUT
예제 #30
0
    async def test_basic_mempool(self, two_nodes):
        num_blocks = 2

        blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"")
        full_node_1, full_node_2, server_1, server_2 = two_nodes

        block = blocks[1]
        async for _ in full_node_1.respond_block(
            full_node_protocol.RespondBlock(block)
        ):
            pass

        spend_bundle = generate_test_spend_bundle(block.get_coinbase())
        assert spend_bundle is not None
        tx: full_node_protocol.RespondTransaction = (
            full_node_protocol.RespondTransaction(spend_bundle)
        )
        async for _ in full_node_1.respond_transaction(tx):
            outbound: OutboundMessage = _
            # Maybe transaction means that it's accepted in mempool
            assert outbound.message.function == "new_transaction"

        sb = full_node_1.mempool_manager.get_spendbundle(spend_bundle.name())
        assert sb is spend_bundle