From 709190bbfd86f108435c8da705062e754927b177 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Thu, 26 Oct 2023 22:33:58 +0200 Subject: [PATCH] Sync no farmer (#16698) --- chia/full_node/full_node.py | 3 +- chia/simulator/setup_nodes.py | 4 +++ chia/util/initial-config.yaml | 4 +++ tests/core/full_node/test_full_node.py | 40 ++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 1 deletion(-) diff --git a/chia/full_node/full_node.py b/chia/full_node/full_node.py index 80a535810f79..41ff46d5f906 100644 --- a/chia/full_node/full_node.py +++ b/chia/full_node/full_node.py @@ -897,8 +897,9 @@ async def _sync(self) -> None: self.log.info("Waiting to receive peaks from peers.") # Wait until we have 3 peaks or up to a max of 30 seconds + max_iterations = int(self.config.get("max_sync_wait", 30)) * 10 peaks = [] - for i in range(300): + for i in range(max_iterations): peaks = [peak.header_hash for peak in self.sync_store.get_peak_of_each_peer().values()] if len(self.sync_store.get_peers_that_have_peak(peaks)) < 3: if self._shut_down: diff --git a/chia/simulator/setup_nodes.py b/chia/simulator/setup_nodes.py index b15194c8c4b1..4432ae09b056 100644 --- a/chia/simulator/setup_nodes.py +++ b/chia/simulator/setup_nodes.py @@ -143,6 +143,10 @@ async def setup_simulators_and_wallets( disable_capabilities: Optional[List[Capability]] = None, ) -> AsyncIterator[Tuple[List[FullNodeSimulator], List[Tuple[WalletNode, ChiaServer]], BlockTools]]: with TempKeyring(populate=True) as keychain1, TempKeyring(populate=True) as keychain2: + if config_overrides is None: + config_overrides = {} + if "full_node.max_sync_wait" not in config_overrides: + config_overrides["full_node.max_sync_wait"] = 1 async with setup_simulators_and_wallets_inner( db_version, consensus_constants, diff --git a/chia/util/initial-config.yaml b/chia/util/initial-config.yaml index 307fea73d256..45bdc6da1ce1 100644 --- a/chia/util/initial-config.yaml +++ b/chia/util/initial-config.yaml @@ -411,6 +411,10 @@ full_node: # timeout for weight proof request weight_proof_timeout: &weight_proof_timeout 360 + # when the full node enters sync-mode, we wait until we have collected peaks + # from at least 3 peers, or until we've waitied this many seconds + max_sync_wait: 30 + # when enabled, the full node will print a pstats profile to the root_dir/profile every second # analyze with chia/utils/profiler.py enable_profiler: False diff --git a/tests/core/full_node/test_full_node.py b/tests/core/full_node/test_full_node.py index 2dd2a83c10f4..dc7aa4e86ff7 100644 --- a/tests/core/full_node/test_full_node.py +++ b/tests/core/full_node/test_full_node.py @@ -54,6 +54,7 @@ from chia.util.hash import std_hash from chia.util.ints import uint8, uint16, uint32, uint64, uint128 from chia.util.limited_semaphore import LimitedSemaphore +from chia.util.misc import to_batches from chia.util.recursive_replace import recursive_replace from chia.util.vdf_prover import get_vdf_info_and_proof from chia.wallet.util.tx_config import DEFAULT_TX_CONFIG @@ -106,6 +107,45 @@ async def get_block_path(full_node: FullNodeAPI): return blocks_list +@pytest.mark.asyncio +async def test_sync_no_farmer( + setup_two_nodes_and_wallet, + default_1000_blocks: List[FullBlock], + self_hostname: str, + seeded_random: random.Random, +): + nodes, wallets, bt = setup_two_nodes_and_wallet + server_1 = nodes[0].full_node.server + server_2 = nodes[1].full_node.server + full_node_1 = nodes[0] + full_node_2 = nodes[1] + + blocks = default_1000_blocks + + # full node 1 has the complete chain + for block_batch in to_batches(blocks, 64): + await full_node_1.full_node.add_block_batch(block_batch.entries, PeerInfo("0.0.0.0", 8884), None) + + target_peak = full_node_1.full_node.blockchain.get_peak() + + # full node 2 is behind by 800 blocks + for block_batch in to_batches(blocks[:-800], 64): + await full_node_2.full_node.add_block_batch(block_batch.entries, PeerInfo("0.0.0.0", 8884), None) + + # connect the nodes and wait for node 2 to sync up to node 1 + await connect_and_get_peer(server_1, server_2, self_hostname) + + def check_nodes_in_sync(): + p1 = full_node_2.full_node.blockchain.get_peak() + p2 = full_node_1.full_node.blockchain.get_peak() + return p1 == p2 + + await time_out_assert(40, check_nodes_in_sync) + + assert full_node_1.full_node.blockchain.get_peak() == target_peak + assert full_node_2.full_node.blockchain.get_peak() == target_peak + + class TestFullNodeBlockCompression: @pytest.mark.asyncio @pytest.mark.parametrize("tx_size", [3000000000000])