Beispiel #1
0
    async def test_agg_sig_condition(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

        unsigned: List[
            Tuple[Program, CoinSolution]
        ] = wallet_a.generate_unsigned_transaction(
            1000, receiver_puzzlehash, block.header.data.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)
        hash_key_pairs = hash_key_pairs_for_conditions_dict(
            conditions_dict, solution.coin.name()
        )
        assert len(hash_key_pairs) == 1

        pk_pair: BLSSignature.PkMessagePair = hash_key_pairs[0]
        assert pk_pair.message_hash == 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
Beispiel #2
0
    async def test_short_sync_with_transactions_wallet(self, wallet_node):
        full_node_1, wallet_node, server_1, server_2 = wallet_node
        wallet_a = wallet_node.wallet_state_manager.main_wallet
        wallet_a_dummy = WalletTool()
        wallet_b = WalletTool()
        coinbase_puzzlehash = await wallet_a.get_new_puzzlehash()
        coinbase_puzzlehash_rest = wallet_b.get_new_puzzlehash()
        puzzle_hashes = [
            await wallet_a.get_new_puzzlehash() for _ in range(10)
        ]
        puzzle_hashes.append(wallet_b.get_new_puzzlehash())

        blocks = bt.get_consecutive_blocks(test_constants, 3, [], 10, b"",
                                           coinbase_puzzlehash)
        for block in blocks:
            [
                _ async for _ in full_node_1.respond_block(
                    full_node_protocol.RespondBlock(block))
            ]
        await asyncio.sleep(2)
        await server_2.start_client(
            PeerInfo("localhost", uint16(server_1._port)), None)
        await asyncio.sleep(2)
        assert (wallet_node.wallet_state_manager.block_records[
            wallet_node.wallet_state_manager.lca].height == 1)
        server_2.global_connections.close_all_connections()

        dic_h = {}
        prev_coin = blocks[1].header.data.coinbase
        for i in range(11):
            pk, sk = await wallet_a.wallet_state_manager.get_keys(
                prev_coin.puzzle_hash)
            transaction_unsigned = wallet_a_dummy.generate_unsigned_transaction(
                1000, puzzle_hashes[i], prev_coin, {}, 0, secretkey=sk)
            spend_bundle = await wallet_a.sign_transaction(transaction_unsigned
                                                           )
            block_spendbundle = SpendBundle.aggregate([spend_bundle])
            program = best_solution_program(block_spendbundle)
            aggsig = block_spendbundle.aggregated_signature
            prev_coin = Coin(prev_coin.name(), puzzle_hashes[i], uint64(1000))
            dic_h[i + 4] = (program, aggsig)

        blocks = bt.get_consecutive_blocks(test_constants, 13, blocks, 10, b"",
                                           coinbase_puzzlehash_rest, dic_h)
        # Move chain to height 16, with consecutive transactions in blocks 4 to 14
        for block in blocks:
            async for _ in full_node_1.respond_block(
                    full_node_protocol.RespondBlock(block)):
                pass

        # Do a short sync from 0 to 14
        await server_2.start_client(
            PeerInfo("localhost", uint16(server_1._port)), None)
        start = time.time()
        broke = False
        while time.time() - start < 60:
            if (wallet_node.wallet_state_manager.block_records[
                    wallet_node.wallet_state_manager.lca].height >=
                    14  # Tip at 16, LCA at 14
                ):
                broke = True
                break
            await asyncio.sleep(0.1)
        if not broke:
            raise Exception(
                f"Took too long to process blocks, stopped at: {time.time() - start}"
            )

        server_2.global_connections.close_all_connections()

        # 2 block rewards and 3 fees
        assert await wallet_a.get_confirmed_balance() == (
            blocks[1].header.data.coinbase.amount *
            2) + (blocks[1].header.data.fees_coin.amount * 3)
        # All of our coins are spent and puzzle hashes present
        for puzzle_hash in puzzle_hashes[:-1]:
            records = await wallet_node.wallet_state_manager.wallet_store.get_coin_records_by_puzzle_hash(
                puzzle_hash)
            assert len(records) == 1
            assert records[0].spent and not records[0].coinbase

        # Then do the same but in a reorg chain
        dic_h = {}
        prev_coin = blocks[1].header.data.coinbase
        for i in range(11):
            pk, sk = await wallet_a.wallet_state_manager.get_keys(
                prev_coin.puzzle_hash)
            transaction_unsigned = wallet_a_dummy.generate_unsigned_transaction(
                1000, puzzle_hashes[i], prev_coin, {}, 0, secretkey=sk)
            spend_bundle = await wallet_a.sign_transaction(transaction_unsigned
                                                           )
            block_spendbundle = SpendBundle.aggregate([spend_bundle])
            program = best_solution_program(block_spendbundle)
            aggsig = block_spendbundle.aggregated_signature
            prev_coin = Coin(prev_coin.name(), puzzle_hashes[i], uint64(1000))
            dic_h[i + 4] = (program, aggsig)

        blocks = bt.get_consecutive_blocks(
            test_constants,
            31,
            blocks[:4],
            10,
            b"this is a reorg",
            coinbase_puzzlehash_rest,
            dic_h,
        )

        # Move chain to height 34, with consecutive transactions in blocks 4 to 14
        for block in blocks:
            async for _ in full_node_1.respond_block(
                    full_node_protocol.RespondBlock(block)):
                pass

        # Do a sync from 0 to 22
        await server_2.start_client(
            PeerInfo("localhost", uint16(server_1._port)), None)

        broke = False
        while time.time() - start < 60:
            if (wallet_node.wallet_state_manager.block_records[
                    wallet_node.wallet_state_manager.lca].height >=
                    28  # Tip at 34, LCA at least 28
                ):
                broke = True
                break
            await asyncio.sleep(0.1)
        if not broke:
            raise Exception(
                f"Took too long to process blocks, stopped at: {time.time() - start}"
            )
        server_2.global_connections.close_all_connections()

        # 2 block rewards and 3 fees
        assert await wallet_a.get_confirmed_balance() == (
            blocks[1].header.data.coinbase.amount *
            2) + (blocks[1].header.data.fees_coin.amount * 3)
        # All of our coins are spent and puzzle hashes present
        for puzzle_hash in puzzle_hashes[:-1]:
            records = await wallet_node.wallet_state_manager.wallet_store.get_coin_records_by_puzzle_hash(
                puzzle_hash)
            assert len(records) == 1
            assert records[0].spent and not records[0].coinbase

        # Test spending the rewards earned in reorg
        new_coinbase_puzzlehash = await wallet_a.get_new_puzzlehash()
        another_puzzlehash = await wallet_a.get_new_puzzlehash()

        dic_h = {}
        pk, sk = await wallet_a.wallet_state_manager.get_keys(
            new_coinbase_puzzlehash)
        coinbase_coin = create_coinbase_coin(25, new_coinbase_puzzlehash,
                                             uint64(14000000000000))
        transaction_unsigned = wallet_a_dummy.generate_unsigned_transaction(
            7000000000000,
            another_puzzlehash,
            coinbase_coin, {},
            0,
            secretkey=sk)
        spend_bundle = await wallet_a.sign_transaction(transaction_unsigned)
        block_spendbundle = SpendBundle.aggregate([spend_bundle])
        program = best_solution_program(block_spendbundle)
        aggsig = block_spendbundle.aggregated_signature
        dic_h[26] = (program, aggsig)

        # Farm a block (25) to ourselves
        blocks = bt.get_consecutive_blocks(
            test_constants,
            1,
            blocks[:25],
            10,
            b"this is yet another reorg",
            new_coinbase_puzzlehash,
        )

        # Brings height up to 40, with block 31 having half our reward spent to us
        blocks = bt.get_consecutive_blocks(
            test_constants,
            15,
            blocks,
            10,
            b"this is yet another reorg more blocks",
            coinbase_puzzlehash_rest,
            dic_h,
        )
        for block in blocks:
            async for _ in full_node_1.respond_block(
                    full_node_protocol.RespondBlock(block)):
                pass

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

        broke = False
        while time.time() - start < 60:
            if (wallet_node.wallet_state_manager.block_records[
                    wallet_node.wallet_state_manager.lca].height >=
                    38  # Tip at 40, LCA at 38
                ):
                broke = True
                break
            await asyncio.sleep(0.1)
        if not broke:
            raise Exception(
                f"Took too long to process blocks, stopped at: {time.time() - start}"
            )
        # 2 block rewards and 4 fees, plus 7000000000000 coins
        assert (await wallet_a.get_confirmed_balance() ==
                (blocks[1].header.data.coinbase.amount * 2) +
                (blocks[1].header.data.fees_coin.amount * 4) + 7000000000000)
        records = await wallet_node.wallet_state_manager.wallet_store.get_coin_records_by_puzzle_hash(
            new_coinbase_puzzlehash)
        # Fee and coinbase
        assert len(records) == 2
        assert records[0].spent != records[1].spent
        assert records[0].coinbase == records[1].coinbase
        records = await wallet_node.wallet_state_manager.wallet_store.get_coin_records_by_puzzle_hash(
            another_puzzlehash)
        assert len(records) == 1
        assert not records[0].spent
        assert not records[0].coinbase