Ejemplo n.º 1
0
    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 = ConditionVarPair(ConditionOpcode.ASSERT_HEIGHT_NOW_EXCEEDS,
                               [uint64(1).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 spend_bundle1
Ejemplo n.º 2
0
    async def test_correct_my_id(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_MY_COIN_ID,
                               block.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"

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

        assert sb1 is spend_bundle1
Ejemplo n.º 3
0
    async def test_correct_block_index(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

        cvp = ConditionVarPair(
            ConditionOpcode.ASSERT_BLOCK_INDEX_EXCEEDS,
            uint64(1).to_bytes(4, "big"),
            None,
        )
        dic = {ConditionOpcode.ASSERT_BLOCK_INDEX_EXCEEDS: [cvp]}

        spend_bundle1 = wallet_a.generate_signed_transaction(
            1000, receiver_puzzlehash, block.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 = _
            # 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
Ejemplo n.º 4
0
    async def test_invalid_coin_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_sub_height = blocks[-1].sub_block_height
        blocks = bt.get_consecutive_blocks(
            4,
            block_list_input=blocks,
            guarantee_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_sub_block(full_node_protocol.RespondSubBlock(block))

        await time_out_assert(60, node_height_at_least, True, full_node_1, start_sub_height + 3)

        for b in blocks:
            await full_node_1.full_node.respond_sub_block(full_node_protocol.RespondSubBlock(b))

        coin_1 = list(blocks[-2].get_included_reward_coins())[0]
        coin_2 = list(blocks[-1].get_included_reward_coins())[0]
        cvp = ConditionVarPair(ConditionOpcode.ASSERT_COIN_CONSUMED, [coin_2.name()])
        dic = {cvp.opcode: [cvp]}

        spend_bundle1 = generate_test_spend_bundle(coin_1, 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)

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

        assert mempool_bundle is None
Ejemplo n.º 5
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
Ejemplo n.º 6
0
    async def test_stealing_fee(self, two_nodes):
        num_blocks = 2
        wallet_a = bt.get_pool_wallet_tool()
        wallet_receiver = bt.get_farmer_wallet_tool()
        receiver_puzzlehash = wallet_receiver.get_new_puzzlehash()

        blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10,
                                           b"")

        blocks = bt.get_consecutive_blocks(test_constants, num_blocks, blocks,
                                           10, b"")

        full_node_1, full_node_2, server_1, server_2 = two_nodes

        block = blocks[1]
        wallet_2_block = blocks[3]

        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]}

        fee = 9
        spend_bundle1 = wallet_a.generate_signed_transaction(
            1000, receiver_puzzlehash, block.get_coinbase(), dic, fee)

        wallet_2_fees = wallet_2_block.get_fees_coin()
        steal_fee_spendbundle = wallet_receiver.generate_signed_transaction(
            wallet_2_fees.amount + fee - 4, receiver_puzzlehash, wallet_2_fees)

        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))

        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 is False

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

        assert mempool_bundle is None
Ejemplo n.º 7
0
    async def test_invalid_filter(self, two_nodes):
        num_blocks = 10
        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())

        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

        last_block = blocks[10]
        next_spendbundle = await full_node_1.mempool_manager.create_bundle_for_tip(
            last_block.header)
        assert next_spendbundle is not None

        program = best_solution_program(next_spendbundle)
        aggsig = next_spendbundle.aggregated_signature

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

        next_block = new_blocks[11]

        bad_header = HeaderData(
            next_block.header.data.height,
            next_block.header.data.prev_header_hash,
            next_block.header.data.timestamp,
            bytes32(bytes([3] * 32)),
            next_block.header.data.proof_of_space_hash,
            next_block.header.data.weight,
            next_block.header.data.total_iters,
            next_block.header.data.additions_root,
            next_block.header.data.removals_root,
            next_block.header.data.farmer_rewards_puzzle_hash,
            next_block.header.data.total_transaction_fees,
            next_block.header.data.pool_target,
            next_block.header.data.aggregated_signature,
            next_block.header.data.cost,
            next_block.header.data.extension_data,
            next_block.header.data.generator_hash,
        )
        bad_block = FullBlock(
            next_block.proof_of_space,
            next_block.proof_of_time,
            Header(
                bad_header,
                bt.get_plot_signature(
                    bad_header, next_block.proof_of_space.plot_public_key),
            ),
            next_block.transactions_generator,
            next_block.transactions_filter,
        )
        result, removed, error_code = await full_node_1.blockchain.receive_block(
            bad_block)
        assert result == ReceiveBlockResult.INVALID_BLOCK
        assert error_code == Err.INVALID_TRANSACTIONS_FILTER_HASH

        result, removed, error_code = await full_node_1.blockchain.receive_block(
            next_block)
        assert result == ReceiveBlockResult.ADDED_TO_HEAD
Ejemplo n.º 8
0
    async def test_basic_blockchain_tx(self, two_nodes):
        num_blocks = 10
        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())

        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

        last_block = blocks[10]
        next_spendbundle = await full_node_1.mempool_manager.create_bundle_for_tip(
            last_block.header)
        assert next_spendbundle is not None

        program = best_solution_program(next_spendbundle)
        aggsig = next_spendbundle.aggregated_signature

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

        next_block = new_blocks[11]
        async for _ in full_node_1.respond_block(
                full_node_protocol.RespondBlock(next_block)):
            pass

        tips = full_node_1.blockchain.get_current_tips()
        assert next_block.header in tips

        added_coins = next_spendbundle.additions()

        # Two coins are added, main spend and change
        assert len(added_coins) == 2
        for coin in added_coins:
            unspent = await full_node_1.coin_store.get_coin_record(
                coin.name(), next_block.header)
            assert unspent is not None

        full_tips = await full_node_1.blockchain.get_full_tips()
        in_full_tips = False

        farmed_block: Optional[FullBlock] = None
        for tip in full_tips:
            if tip.header == next_block.header:
                in_full_tips = True
                farmed_block = tip

        assert in_full_tips
        assert farmed_block is not None
        assert farmed_block.transactions_generator == program
Ejemplo n.º 9
0
    async def test_transaction_freeze(self, wallet_node_30_freeze):
        num_blocks = 5
        full_nodes, wallets = wallet_node_30_freeze
        full_node_api: FullNodeSimulator = full_nodes[0]
        full_node_server = full_node_api.server
        wallet_node, server_2 = wallets[0]
        wallet = wallet_node.wallet_state_manager.main_wallet
        ph = await wallet.get_new_puzzlehash()

        incoming_queue, node_id = await add_dummy_connection(
            full_node_server, 12312)

        await server_2.start_client(
            PeerInfo(self_hostname, uint16(full_node_server._port)), None)
        for i in range(num_blocks):
            await full_node_api.farm_new_transaction_block(
                FarmNewBlockProtocol(ph))

        funds = sum([
            calculate_pool_reward(uint32(i)) +
            calculate_base_farmer_reward(uint32(i))
            for i in range(1, num_blocks)
        ])
        # funds += calculate_base_farmer_reward(0)
        await asyncio.sleep(2)
        print(await wallet.get_confirmed_balance(), funds)
        await time_out_assert(10, wallet.get_confirmed_balance, funds)

        tx: TransactionRecord = await wallet.generate_signed_transaction(
            100, ph, 0)
        spend = wallet_protocol.SendTransaction(tx.spend_bundle)
        response = await full_node_api.send_transaction(spend)
        assert wallet_protocol.TransactionAck.from_bytes(
            response.data).status == MempoolInclusionStatus.FAILED

        new_spend = full_node_protocol.NewTransaction(tx.spend_bundle.name(),
                                                      1, 0)
        response = await full_node_api.new_transaction(new_spend)
        assert response is None

        peer = full_node_server.all_connections[node_id]
        new_spend = full_node_protocol.RespondTransaction(tx.spend_bundle)
        response = await full_node_api.respond_transaction(new_spend,
                                                           peer=peer)
        assert response is None

        for i in range(26):
            await full_node_api.farm_new_transaction_block(
                FarmNewBlockProtocol(ph))

        new_spend = full_node_protocol.NewTransaction(tx.spend_bundle.name(),
                                                      1, 0)
        response = await full_node_api.new_transaction(new_spend)
        assert response is not None
        assert ProtocolMessageTypes(
            response.type) == ProtocolMessageTypes.request_transaction

        tx: TransactionRecord = await wallet.generate_signed_transaction(
            100, ph, 0)
        spend = wallet_protocol.SendTransaction(tx.spend_bundle)
        response = await full_node_api.send_transaction(spend)
        assert response is not None
        assert wallet_protocol.TransactionAck.from_bytes(
            response.data).status == MempoolInclusionStatus.SUCCESS
        assert ProtocolMessageTypes(
            response.type) == ProtocolMessageTypes.transaction_ack
Ejemplo n.º 10
0
    async def test_basic_blockchain_tx(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(
            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
        peer = await connect_and_get_peer(server_1, server_2)
        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), None)

        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)

        assert spend_bundle is not None
        tx: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(
            spend_bundle)
        await full_node_api_1.respond_transaction(tx, peer)

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

        last_block = blocks[-1]
        next_spendbundle, additions, removals = await full_node_1.mempool_manager.create_bundle_from_mempool(
            last_block.header_hash)
        assert next_spendbundle is not None

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

        next_block = new_blocks[-1]
        await full_node_1.respond_block(
            full_node_protocol.RespondBlock(next_block))

        assert next_block.header_hash == full_node_1.blockchain.get_peak(
        ).header_hash

        added_coins = next_spendbundle.additions()

        # Two coins are added, main spend and change
        assert len(added_coins) == 2
        for coin in added_coins:
            unspent = await full_node_1.coin_store.get_coin_record(coin.name())
            assert unspent is not None
            assert not unspent.spent
            assert not unspent.coinbase
Ejemplo n.º 11
0
    async def test_new_transaction(self, two_nodes, wallet_blocks_five):
        full_node_1, full_node_2, server_1, server_2 = two_nodes
        wallet_a, wallet_receiver, blocks = wallet_blocks_five
        conditions_dict: Dict = {ConditionOpcode.CREATE_COIN: []}

        # Mempool has capacity of 100, make 110 unspents that we can use
        puzzle_hashes = []
        for _ in range(110):
            receiver_puzzlehash = wallet_receiver.get_new_puzzlehash()
            puzzle_hashes.append(receiver_puzzlehash)
            output = ConditionVarPair(
                ConditionOpcode.CREATE_COIN, receiver_puzzlehash, int_to_bytes(1000)
            )
            conditions_dict[ConditionOpcode.CREATE_COIN].append(output)

        spend_bundle = wallet_a.generate_signed_transaction(
            100,
            receiver_puzzlehash,
            blocks[1].get_coinbase(),
            condition_dic=conditions_dict,
        )
        assert spend_bundle is not None

        new_transaction = fnp.NewTransaction(
            spend_bundle.get_hash(), uint64(100), uint64(100)
        )
        # Not seen
        msgs = [x async for x in full_node_1.new_transaction(new_transaction)]
        assert len(msgs) == 1
        assert msgs[0].message.data == fnp.RequestTransaction(spend_bundle.get_hash())

        respond_transaction_2 = fnp.RespondTransaction(spend_bundle)
        [x async for x in full_node_1.respond_transaction(respond_transaction_2)]

        program = best_solution_program(spend_bundle)
        aggsig = spend_bundle.aggregated_signature

        dic_h = {5: (program, aggsig)}
        blocks_new = bt.get_consecutive_blocks(
            test_constants, 3, blocks[:-1], 10, transaction_data_at_height=dic_h,
        )
        # Already seen
        msgs = [x async for x in full_node_1.new_transaction(new_transaction)]
        assert len(msgs) == 0

        # Farm one block
        for block in blocks_new:
            [_ async for _ in full_node_1.respond_block(fnp.RespondBlock(block))]

        spend_bundles = []
        total_fee = 0
        # Fill mempool
        for puzzle_hash in puzzle_hashes:
            coin_record = (
                await full_node_1.coin_store.get_coin_records_by_puzzle_hash(
                    puzzle_hash, blocks_new[-3].header
                )
            )[0]
            receiver_puzzlehash = wallet_receiver.get_new_puzzlehash()
            fee = random.randint(2, 499)
            spend_bundle = wallet_receiver.generate_signed_transaction(
                500, receiver_puzzlehash, coin_record.coin, fee=fee
            )
            respond_transaction = fnp.RespondTransaction(spend_bundle)
            res = [
                x async for x in full_node_1.respond_transaction(respond_transaction)
            ]

            # Added to mempool
            if len(res) > 0:
                total_fee += fee
                spend_bundles.append(spend_bundle)

        # Mempool is full
        new_transaction = fnp.NewTransaction(
            token_bytes(32), uint64(1000000), uint64(1)
        )
        msgs = [x async for x in full_node_1.new_transaction(new_transaction)]
        assert len(msgs) == 0

        agg = SpendBundle.aggregate(spend_bundles)
        program = best_solution_program(agg)
        aggsig = agg.aggregated_signature

        dic_h = {8: (program, aggsig)}

        blocks_new = bt.get_consecutive_blocks(
            test_constants,
            1,
            blocks_new,
            10,
            transaction_data_at_height=dic_h,
            fees=uint64(total_fee),
        )
        # Farm one block to clear mempool
        [_ async for _ in full_node_1.respond_block(fnp.RespondBlock(blocks_new[-1]))]