async def test_basic_sync_wallet(self, wallet_node, default_400_blocks):

        full_node_api, wallet_node, full_node_server, wallet_server = wallet_node

        for block in default_400_blocks:
            await full_node_api.full_node.respond_block(
                full_node_protocol.RespondBlock(block))

        await wallet_server.start_client(
            PeerInfo(self_hostname, uint16(full_node_server._port)), None)

        # The second node should eventually catch up to the first one, and have the
        # same tip at height num_blocks - 1.
        await time_out_assert(100, wallet_height_at_least, True, wallet_node,
                              len(default_400_blocks) - 1)

        # Tests a reorg with the wallet
        num_blocks = 30
        blocks_reorg = bt.get_consecutive_blocks(
            num_blocks, block_list_input=default_400_blocks[:-5])
        for i in range(1, len(blocks_reorg)):
            await full_node_api.full_node.respond_block(
                full_node_protocol.RespondBlock(blocks_reorg[i]))

        await disconnect_all_and_reconnect(wallet_server, full_node_server)

        await time_out_assert(100, wallet_height_at_least, True, wallet_node,
                              len(default_400_blocks) + num_blocks - 5 - 1)
Example #2
0
    async def test_mempool_update_performance(self, wallet_nodes, default_400_blocks):
        blocks = default_400_blocks
        full_nodes, wallets = wallet_nodes
        wallet_node = wallets[0][0]
        wallet_server = wallets[0][1]
        full_node_api_1 = full_nodes[0]
        full_node_api_2 = full_nodes[1]
        server_1 = full_node_api_1.full_node.server
        server_2 = full_node_api_2.full_node.server
        wallet = wallet_node.wallet_state_manager.main_wallet
        ph = await wallet.get_new_puzzlehash()

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

        await wallet_server.start_client(PeerInfo(self_hostname, uint16(server_1._port)), None)
        await time_out_assert(60, wallet_height_at_least, True, wallet_node, 399)

        big_transaction: TransactionRecord = await wallet.generate_signed_transaction(40000000000000, ph, 2213)

        peer = await connect_and_get_peer(server_1, server_2)
        await full_node_api_1.respond_transaction(
            full_node_protocol.RespondTransaction(big_transaction.spend_bundle), peer, test=True
        )
        cons = list(server_1.all_connections.values())[:]
        for con in cons:
            await con.close()

        blocks = bt.get_consecutive_blocks(3, blocks)
        await full_node_api_1.full_node.respond_block(full_node_protocol.RespondBlock(blocks[-3]))

        for block in blocks[-2:]:
            start_t_2 = time.time()
            await full_node_api_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
            assert time.time() - start_t_2 < 1
    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(num_blocks)
        peer = await connect_and_get_peer(server_1, server_2)
        await full_node_1.full_node.respond_block(
            full_node_protocol.RespondBlock(blocks[0]), peer)

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

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

        await time_out_assert(10, num_connections, 1)

        start_unf = time.time()
        for i in range(1, num_blocks):
            await full_node_1.full_node.respond_block(
                full_node_protocol.RespondBlock(blocks[i]))
            await full_node_2.full_node.respond_block(
                full_node_protocol.RespondBlock(blocks[i]))
        print(
            f"Time taken to process {num_blocks} is {time.time() - start_unf}")
        assert time.time() - start_unf < 100
    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
Example #5
0
    async def test_wallet_reorg_sync(self, wallet_node_simulator,
                                     default_400_blocks, trusted):
        num_blocks = 5
        full_nodes, wallets = wallet_node_simulator
        full_node_api = full_nodes[0]
        wallet_node, server_2 = wallets[0]
        fn_server = full_node_api.full_node.server
        wsm: WalletStateManager = wallet_node.wallet_state_manager
        wallet = wsm.main_wallet
        ph = await wallet.get_new_puzzlehash()

        if trusted:
            wallet_node.config["trusted_peers"] = {
                fn_server.node_id.hex(): fn_server.node_id.hex()
            }
        else:
            wallet_node.config["trusted_peers"] = {}

        await server_2.start_client(
            PeerInfo(self_hostname, uint16(fn_server._port)), None)

        # Insert 400 blocks
        for block in default_400_blocks:
            await full_node_api.full_node.respond_block(
                full_node_protocol.RespondBlock(block))

        # Farm few more with reward
        for i in range(0, num_blocks):
            await full_node_api.farm_new_transaction_block(
                FarmNewBlockProtocol(ph))

        # Confirm we have the funds
        funds = sum([
            calculate_pool_reward(uint32(i)) +
            calculate_base_farmer_reward(uint32(i))
            for i in range(1, num_blocks)
        ])

        await time_out_assert(5, wallet.get_confirmed_balance, funds)

        async def get_tx_count(wallet_id):
            txs = await wsm.get_all_transactions(wallet_id)
            return len(txs)

        await time_out_assert(5, get_tx_count, 2 * (num_blocks - 1), 1)

        # Reorg blocks that carry reward
        num_blocks = 30
        blocks_reorg = bt.get_consecutive_blocks(
            num_blocks, block_list_input=default_400_blocks[:-5])

        for block in blocks_reorg[-30:]:
            await full_node_api.full_node.respond_block(
                full_node_protocol.RespondBlock(block))

        await time_out_assert(5, get_tx_count, 0, 1)
        await time_out_assert(5, wallet.get_confirmed_balance, 0)
Example #6
0
    async def test_validate_blockchain_spend_reorg_since_genesis(
            self, two_nodes):
        num_blocks = 10
        wallet_a = WALLET_A
        coinbase_puzzlehash = WALLET_A_PUZZLE_HASHES[0]
        receiver_1_puzzlehash = WALLET_A_PUZZLE_HASHES[1]

        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

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

        spend_block = blocks[-1]
        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_1_puzzlehash, spend_coin)

        new_blocks = bt.get_consecutive_blocks(
            1,
            blocks,
            seed=b"",
            farmer_reward_puzzle_hash=coinbase_puzzlehash,
            transaction_data=spend_bundle)
        await full_node_api_1.full_node.respond_block(
            full_node_protocol.RespondBlock(new_blocks[-1]))

        # Spends a coin in a genesis reorg, that was already spent
        new_blocks = bt.get_consecutive_blocks(
            12,
            [],
            seed=b"reorg since genesis",
            farmer_reward_puzzle_hash=coinbase_puzzlehash,
            guarantee_transaction_block=True,
        )

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

        new_blocks = bt.get_consecutive_blocks(
            1,
            new_blocks,
            seed=b"reorg since genesis",
            farmer_reward_puzzle_hash=coinbase_puzzlehash,
            transaction_data=spend_bundle,
        )

        await full_node_api_1.full_node.respond_block(
            full_node_protocol.RespondBlock(new_blocks[-1]))
    async def test_wallet_reorg_get_coinbase(self, wallet_node_simulator,
                                             default_400_blocks):
        full_nodes, wallets = wallet_node_simulator
        full_node_api = full_nodes[0]
        wallet_node, server_2 = wallets[0]
        fn_server = full_node_api.full_node.server
        wsm = wallet_node.wallet_state_manager
        wallet = wallet_node.wallet_state_manager.main_wallet
        ph = await wallet.get_new_puzzlehash()

        await server_2.start_client(
            PeerInfo(self_hostname, uint16(fn_server._port)), None)

        # Insert 400 blocks
        for block in default_400_blocks:
            await full_node_api.full_node.respond_block(
                full_node_protocol.RespondBlock(block))

        # Reorg blocks that carry reward
        num_blocks_reorg = 30
        blocks_reorg = bt.get_consecutive_blocks(
            num_blocks_reorg, block_list_input=default_400_blocks[:-5])

        for block in blocks_reorg[:-5]:
            await full_node_api.full_node.respond_block(
                full_node_protocol.RespondBlock(block))

        async def get_tx_count(wallet_id):
            txs = await wsm.get_all_transactions(wallet_id)
            return len(txs)

        await time_out_assert(10, get_tx_count, 0, 1)

        num_blocks_reorg_1 = 40
        blocks_reorg_1 = bt.get_consecutive_blocks(
            1,
            pool_reward_puzzle_hash=ph,
            farmer_reward_puzzle_hash=ph,
            block_list_input=blocks_reorg[:-30])
        blocks_reorg_2 = bt.get_consecutive_blocks(
            num_blocks_reorg_1, block_list_input=blocks_reorg_1)

        for block in blocks_reorg_2[-41:]:
            await full_node_api.full_node.respond_block(
                full_node_protocol.RespondBlock(block))

        await disconnect_all_and_reconnect(server_2, fn_server)

        # Confirm we have the funds
        funds = calculate_pool_reward(uint32(
            len(blocks_reorg_1))) + calculate_base_farmer_reward(
                uint32(len(blocks_reorg_1)))

        await time_out_assert(10, get_tx_count, 2, 1)
        await time_out_assert(10, wallet.get_confirmed_balance, funds)
Example #8
0
    async def test_sync_bad_peak_while_synced(self, three_nodes,
                                              default_1000_blocks,
                                              default_10000_blocks):
        # Must be larger than "sync_block_behind_threshold" in the config
        num_blocks_initial = len(default_1000_blocks) - 250
        blocks_750 = default_1000_blocks[:num_blocks_initial]
        full_node_1, full_node_2, full_node_3 = three_nodes
        server_1 = full_node_1.full_node.server
        server_2 = full_node_2.full_node.server
        server_3 = full_node_3.full_node.server
        full_node_3.full_node.weight_proof_handler = None
        for block in blocks_750:
            await full_node_1.full_node.respond_block(
                full_node_protocol.RespondBlock(block))
        # Node 3 syncs from a different blockchain

        for block in default_10000_blocks[:1100]:
            await full_node_3.full_node.respond_block(
                full_node_protocol.RespondBlock(block))

        await server_2.start_client(
            PeerInfo(self_hostname, uint16(server_1._port)),
            full_node_2.full_node.on_connect)

        # The second node should eventually catch up to the first one, and have the
        # same tip at height num_blocks - 1
        await time_out_assert(180, node_height_exactly, True, full_node_2,
                              num_blocks_initial - 1)
        # set new heavy peak, fn3 cannot serve wp's
        # node 2 should keep being synced and receive blocks
        await server_3.start_client(
            PeerInfo(self_hostname, uint16(server_3._port)),
            full_node_3.full_node.on_connect)
        # trigger long sync in full node 2
        peak_block = default_10000_blocks[1050]
        await server_2.start_client(
            PeerInfo(self_hostname, uint16(server_3._port)),
            full_node_2.full_node.on_connect)
        con = server_2.all_connections[full_node_3.full_node.server.node_id]
        peak = full_node_protocol.NewPeak(
            peak_block.header_hash,
            peak_block.height,
            peak_block.weight,
            peak_block.height,
            peak_block.reward_chain_block.get_unfinished().get_hash(),
        )
        await full_node_2.full_node.new_peak(peak, con)
        await asyncio.sleep(2)
        assert not full_node_2.full_node.sync_store.get_sync_mode()
        for block in default_1000_blocks[1000 - num_blocks_initial:]:
            await full_node_2.full_node.respond_block(
                full_node_protocol.RespondBlock(block))

        assert node_height_exactly(full_node_2, 999)
Example #9
0
    async def test_validate_blockchain_spend_reorg_cb_coin(self, two_nodes):
        num_blocks = 15
        wallet_a = WALLET_A
        coinbase_puzzlehash = WALLET_A_PUZZLE_HASHES[0]
        receiver_1_puzzlehash = WALLET_A_PUZZLE_HASHES[1]

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

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

        # Spends a coinbase created in reorg
        new_blocks = bt.get_consecutive_blocks(
            5,
            blocks[:6],
            seed=b"reorg cb coin",
            farmer_reward_puzzle_hash=coinbase_puzzlehash,
            guarantee_transaction_block=True,
        )

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

        spend_block = new_blocks[-1]
        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_1_puzzlehash, spend_coin)

        new_blocks = bt.get_consecutive_blocks(
            1,
            new_blocks,
            seed=b"reorg cb coin",
            farmer_reward_puzzle_hash=coinbase_puzzlehash,
            transaction_data=spend_bundle,
            guarantee_transaction_block=True,
        )

        await full_node_api_1.full_node.respond_block(
            full_node_protocol.RespondBlock(new_blocks[-1]))

        coins_created = []
        for coin in new_blocks[-1].additions():
            if coin.puzzle_hash == receiver_1_puzzlehash:
                coins_created.append(coin)
        assert len(coins_created) == 1
Example #10
0
    async def test_long_sync_wallet(self, wallet_node, default_1000_blocks,
                                    default_400_blocks, trusted):

        full_node_api, wallet_node, full_node_server, wallet_server = wallet_node

        for block in default_400_blocks:
            await full_node_api.full_node.respond_block(
                full_node_protocol.RespondBlock(block))
        if trusted:
            wallet_node.config["trusted_peers"] = {
                full_node_server.node_id.hex(): full_node_server.node_id.hex()
            }
        else:
            wallet_node.config["trusted_peers"] = {}

        await wallet_server.start_client(
            PeerInfo(self_hostname, uint16(full_node_server._port)), None)

        # The second node should eventually catch up to the first one, and have the
        # same tip at height num_blocks - 1.
        await time_out_assert(600, wallet_height_at_least, True, wallet_node,
                              len(default_400_blocks) - 1)

        # Tests a long reorg
        for block in default_1000_blocks:
            await full_node_api.full_node.respond_block(
                full_node_protocol.RespondBlock(block))

        await disconnect_all_and_reconnect(wallet_server, full_node_server)

        log.info(
            f"wallet node height is {wallet_node.wallet_state_manager.blockchain.get_peak_height()}"
        )
        await time_out_assert(600, wallet_height_at_least, True, wallet_node,
                              len(default_1000_blocks) - 1)

        await disconnect_all_and_reconnect(wallet_server, full_node_server)

        # Tests a short reorg
        num_blocks = 30
        blocks_reorg = bt.get_consecutive_blocks(
            num_blocks, block_list_input=default_1000_blocks[:-5])

        for i in range(1, len(blocks_reorg)):
            await full_node_api.full_node.respond_block(
                full_node_protocol.RespondBlock(blocks_reorg[i]))

        await time_out_assert(600, wallet_height_at_least, True, wallet_node,
                              len(default_1000_blocks) + num_blocks - 5 - 1)
Example #11
0
    async def test_block_ses_mismatch(self, two_nodes, default_1000_blocks):
        full_node_1, full_node_2, server_1, server_2 = two_nodes
        blocks = default_1000_blocks

        for block in blocks[:501]:
            await full_node_1.full_node.respond_block(
                full_node_protocol.RespondBlock(block))

        peak1 = full_node_1.full_node.blockchain.get_peak()
        full_node_2.full_node.sync_store.set_long_sync(True)
        await server_2.start_client(
            PeerInfo(self_hostname, uint16(server_1._port)),
            full_node_2.full_node.on_connect)
        wp = await full_node_1.full_node.weight_proof_handler.get_proof_of_weight(
            peak1.header_hash)
        summaries1, _ = _validate_sub_epoch_summaries(
            full_node_1.full_node.weight_proof_handler.constants, wp)
        summaries2 = summaries1
        s = summaries1[1]
        # change summary so check would fail on 2 sub epoch
        summaries2[1] = SubEpochSummary(
            s.prev_subepoch_summary_hash,
            s.reward_chain_hash,
            s.num_blocks_overflow,
            s.new_difficulty * 2,
            s.new_sub_slot_iters * 2,
        )
        await full_node_2.full_node.sync_from_fork_point(
            0, 500, peak1.header_hash, summaries2)
        log.info(
            f"full node height {full_node_2.full_node.blockchain.get_peak().height}"
        )
        assert node_height_between(full_node_2, 320, 400)
Example #12
0
    async def condition_tester2(self, two_nodes, test_fun: Callable[[Coin, Coin], SpendBundle]):
        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]

        bundle = test_fun(coin_1, coin_2)

        tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(bundle)
        status, err = await respond_transaction(full_node_1, tx1, peer)

        return blocks, bundle, status, err
    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)
        assert con is not None
    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, 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, 2)

        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)
        await full_node_1.respond_transaction(tx, peer)

        await time_out_assert(
            10,
            full_node_1.full_node.mempool_manager.get_spendbundle,
            spend_bundle,
            spend_bundle.name(),
        )
    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 = ConditionVarPair(ConditionOpcode.ASSERT_HEIGHT_AGE_EXCEEDS,
                               [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
    async def test_assert_seconds_absolute(self, two_nodes):

        num_blocks = 10
        wallet_a = WALLET_A
        coinbase_puzzlehash = WALLET_A_PUZZLE_HASHES[0]
        receiver_puzzlehash = BURN_PUZZLE_HASH

        # Farm blocks
        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))

        # Coinbase that gets spent
        block1 = blocks[2]
        spend_coin_block_1 = None
        for coin in list(block1.get_included_reward_coins()):
            if coin.puzzle_hash == coinbase_puzzlehash:
                spend_coin_block_1 = coin

        # This condition requires block1 coinbase to be spent after 30 seconds from now
        current_time_plus3 = uint64(blocks[-1].foliage_transaction_block.timestamp + 30)
        block1_cvp = ConditionWithArgs(ConditionOpcode.ASSERT_SECONDS_ABSOLUTE, [int_to_bytes(current_time_plus3)])
        block1_dic = {block1_cvp.opcode: [block1_cvp]}
        block1_spend_bundle = wallet_a.generate_signed_transaction(
            1000, receiver_puzzlehash, spend_coin_block_1, block1_dic
        )

        # program that will be sent to early
        assert block1_spend_bundle is not None
        invalid_new_blocks = bt.get_consecutive_blocks(
            1,
            blocks,
            farmer_reward_puzzle_hash=coinbase_puzzlehash,
            transaction_data=block1_spend_bundle,
            time_per_block=20,
            guarantee_transaction_block=True,
        )

        # Try to validate that block before 30 sec
        res, err, _ = await full_node_1.blockchain.receive_block(invalid_new_blocks[-1])
        assert res == ReceiveBlockResult.INVALID_BLOCK
        assert err == Err.ASSERT_SECONDS_ABSOLUTE_FAILED

        valid_new_blocks = bt.get_consecutive_blocks(
            1,
            blocks,
            farmer_reward_puzzle_hash=coinbase_puzzlehash,
            transaction_data=block1_spend_bundle,
            guarantee_transaction_block=True,
            time_per_block=31,
        )
        res, err, _ = await full_node_1.blockchain.receive_block(valid_new_blocks[-1])
        assert err is None
        assert res == ReceiveBlockResult.NEW_PEAK
    async def test_assert_fee_condition(self, two_nodes):

        num_blocks = 10
        wallet_a = WALLET_A
        coinbase_puzzlehash = WALLET_A_PUZZLE_HASHES[0]
        receiver_puzzlehash = BURN_PUZZLE_HASH

        # Farm blocks
        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))

        # Coinbase that gets spent
        block1 = blocks[2]
        spend_coin_block_1 = None
        for coin in list(block1.get_included_reward_coins()):
            if coin.puzzle_hash == coinbase_puzzlehash:
                spend_coin_block_1 = coin

        # This condition requires fee to be 10 mojo
        cvp_fee = ConditionWithArgs(ConditionOpcode.RESERVE_FEE, [int_to_bytes(10)])
        # This spend bundle has 9 mojo as fee
        block1_dic_bad = {cvp_fee.opcode: [cvp_fee]}
        block1_dic_good = {cvp_fee.opcode: [cvp_fee]}
        block1_spend_bundle_bad = wallet_a.generate_signed_transaction(
            1000, receiver_puzzlehash, spend_coin_block_1, block1_dic_bad, fee=9
        )
        block1_spend_bundle_good = wallet_a.generate_signed_transaction(
            1000, receiver_puzzlehash, spend_coin_block_1, block1_dic_good, fee=10
        )
        log.warning(block1_spend_bundle_good.additions())
        log.warning(f"Spend bundle fees: {block1_spend_bundle_good.fees()}")
        invalid_new_blocks = bt.get_consecutive_blocks(
            1,
            blocks,
            farmer_reward_puzzle_hash=coinbase_puzzlehash,
            transaction_data=block1_spend_bundle_bad,
            guarantee_transaction_block=True,
        )

        res, err, _ = await full_node_1.blockchain.receive_block(invalid_new_blocks[-1])
        assert res == ReceiveBlockResult.INVALID_BLOCK
        assert err == Err.RESERVE_FEE_CONDITION_FAILED

        valid_new_blocks = bt.get_consecutive_blocks(
            1,
            blocks,
            farmer_reward_puzzle_hash=coinbase_puzzlehash,
            transaction_data=block1_spend_bundle_good,
            guarantee_transaction_block=True,
        )
        res, err, _ = await full_node_1.blockchain.receive_block(valid_new_blocks[-1])
        assert err is None
        assert res == ReceiveBlockResult.NEW_PEAK
Example #18
0
    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
Example #19
0
    async def test_almost_recent(self, wallet_node, default_1000_blocks,
                                 trusted):
        # Tests the edge case of receiving funds right before the recent blocks  in weight proof
        full_node_api, wallet_node, full_node_server, wallet_server = wallet_node

        for block in default_1000_blocks:
            await full_node_api.full_node.respond_block(
                full_node_protocol.RespondBlock(block))

        wallet = wallet_node.wallet_state_manager.main_wallet
        ph = await wallet.get_new_puzzlehash()

        if trusted:
            wallet_node.config["trusted_peers"] = {
                full_node_server.node_id.hex(): full_node_server.node_id.hex()
            }
        else:
            wallet_node.config["trusted_peers"] = {}

        # Tests a reorg with the wallet
        num_blocks = 20
        new_blocks = bt.get_consecutive_blocks(
            num_blocks,
            block_list_input=default_1000_blocks,
            pool_reward_puzzle_hash=ph)
        for i in range(1000, len(new_blocks)):
            await full_node_api.full_node.respond_block(
                full_node_protocol.RespondBlock(new_blocks[i]))

        new_blocks = bt.get_consecutive_blocks(
            test_constants.WEIGHT_PROOF_RECENT_BLOCKS + 10,
            block_list_input=new_blocks)
        for i in range(1020, len(new_blocks)):
            await full_node_api.full_node.respond_block(
                full_node_protocol.RespondBlock(new_blocks[i]))

        await wallet_server.start_client(
            PeerInfo(self_hostname, uint16(full_node_server._port)), None)

        await time_out_assert(30, wallet.get_confirmed_balance,
                              20 * calculate_pool_reward(1000))
Example #20
0
    async def test_close_height_but_big_reorg(self, three_nodes):
        blocks_a = bt.get_consecutive_blocks(50)
        blocks_b = bt.get_consecutive_blocks(51, seed=b"B")
        blocks_c = bt.get_consecutive_blocks(90, seed=b"C")
        full_node_1, full_node_2, full_node_3 = three_nodes
        server_1 = full_node_1.full_node.server
        server_2 = full_node_2.full_node.server
        server_3 = full_node_3.full_node.server

        for block in blocks_a:
            await full_node_1.full_node.respond_block(
                full_node_protocol.RespondBlock(block))
        for block in blocks_b:
            await full_node_2.full_node.respond_block(
                full_node_protocol.RespondBlock(block))
        for block in blocks_c:
            await full_node_3.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_1, 50)
        await time_out_assert(60, node_height_exactly, True, full_node_2, 50)
        await time_out_assert(60, node_height_exactly, True, full_node_3, 89)

        await server_3.start_client(
            PeerInfo(self_hostname, uint16(server_1._port)),
            on_connect=full_node_3.full_node.on_connect,
        )

        await server_3.start_client(
            PeerInfo(self_hostname, uint16(server_2._port)),
            on_connect=full_node_3.full_node.on_connect,
        )
        await time_out_assert(60, node_height_exactly, True, full_node_1, 89)
        await time_out_assert(60, node_height_exactly, True, full_node_2, 89)
        await time_out_assert(60, node_height_exactly, True, full_node_3, 89)
    async def test_invalid_announcement_consumed_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 = 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(
            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
Example #22
0
    async def test_batch_sync(self, two_nodes):
        # Must be below "sync_block_behind_threshold" in the config
        num_blocks = 20
        num_blocks_2 = 9
        blocks = bt.get_consecutive_blocks(num_blocks)
        blocks_2 = bt.get_consecutive_blocks(num_blocks_2, seed=b"123")
        full_node_1, full_node_2, server_1, server_2 = two_nodes

        # 12 blocks to node_1
        for block in blocks:
            await full_node_1.full_node.respond_block(
                full_node_protocol.RespondBlock(block))

        # 9 different blocks to node_2
        for block in blocks_2:
            await full_node_2.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,
                              num_blocks - 1)
    async def test_backtrack_sync_wallet(self, wallet_node,
                                         default_400_blocks):

        full_node_api, wallet_node, full_node_server, wallet_server = wallet_node
        for block in default_400_blocks[:20]:
            await full_node_api.full_node.respond_block(
                full_node_protocol.RespondBlock(block))

        await wallet_server.start_client(
            PeerInfo(self_hostname, uint16(full_node_server._port)), None)

        # The second node should eventually catch up to the first one, and have the
        # same tip at height num_blocks - 1.
        await time_out_assert(100, wallet_height_at_least, True, wallet_node,
                              19)
Example #24
0
    async def test_backtrack_sync_2(self, two_nodes):
        blocks = bt.get_consecutive_blocks(1, skip_slots=3)
        blocks = bt.get_consecutive_blocks(8, 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, 8)
    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
    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
Example #27
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_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
Example #29
0
    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)
        status, err = await respond_transaction(full_node_1, tx1, peer)
        assert status == MempoolInclusionStatus.SUCCESS
        assert err is None

        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)
        status, err = await respond_transaction(full_node_1, 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
        assert status == MempoolInclusionStatus.PENDING
        assert err == Err.MEMPOOL_CONFLICT
Example #30
0
    async def test_short_batch_sync_wallet(self, wallet_node,
                                           default_400_blocks, trusted):
        full_node_api, wallet_node, full_node_server, wallet_server = wallet_node

        for block in default_400_blocks[:200]:
            await full_node_api.full_node.respond_block(
                full_node_protocol.RespondBlock(block))
        if trusted:
            wallet_node.config["trusted_peers"] = {
                full_node_server.node_id.hex(): full_node_server.node_id.hex()
            }
        else:
            wallet_node.config["trusted_peers"] = {}

        await wallet_server.start_client(
            PeerInfo(self_hostname, uint16(full_node_server._port)), None)

        # The second node should eventually catch up to the first one, and have the
        # same tip at height num_blocks - 1.
        await time_out_assert(100, wallet_height_at_least, True, wallet_node,
                              199)