From 0943ea37d5fea1b45103695f519504718d22880b Mon Sep 17 00:00:00 2001 From: arvidn Date: Tue, 12 Sep 2023 09:10:03 +0200 Subject: [PATCH 1/6] fix BlockTools to add time_per_block to every block when generating test chains, not just transaction blocks --- chia/simulator/block_tools.py | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/chia/simulator/block_tools.py b/chia/simulator/block_tools.py index eaca62e30d4b..fee7a381eb61 100644 --- a/chia/simulator/block_tools.py +++ b/chia/simulator/block_tools.py @@ -757,7 +757,12 @@ def get_consecutive_blocks( if not use_timestamp_residual: self._block_time_residual = 0.0 - full_block, block_record, self._block_time_residual = get_full_block_and_block_record( + ( + full_block, + block_record, + self._block_time_residual, + new_timestamp, + ) = get_full_block_and_block_record( constants, blocks, sub_slot_start_total_iters, @@ -793,10 +798,9 @@ def get_consecutive_blocks( previous_generator = None keep_going_until_tx_block = False assert full_block.foliage_transaction_block is not None - last_timestamp = full_block.foliage_transaction_block.timestamp - else: - if guarantee_transaction_block: - continue + elif guarantee_transaction_block: + continue + last_timestamp = new_timestamp block_list.append(full_block) if full_block.transactions_generator is not None: compressor_arg = detect_potential_template_generator( @@ -1043,7 +1047,12 @@ def get_consecutive_blocks( if not use_timestamp_residual: self._block_time_residual = 0.0 - full_block, block_record, self._block_time_residual = get_full_block_and_block_record( + ( + full_block, + block_record, + self._block_time_residual, + new_timestamp, + ) = get_full_block_and_block_record( constants, blocks, sub_slot_start_total_iters, @@ -1082,9 +1091,9 @@ def get_consecutive_blocks( previous_generator = None keep_going_until_tx_block = False assert full_block.foliage_transaction_block is not None - last_timestamp = full_block.foliage_transaction_block.timestamp elif guarantee_transaction_block: continue + last_timestamp = new_timestamp block_list.append(full_block) if full_block.transactions_generator is not None: @@ -1696,7 +1705,7 @@ def get_full_block_and_block_record( normalized_to_identity_cc_ip: bool = False, current_time: bool = False, block_time_residual: float = 0.0, -) -> Tuple[FullBlock, BlockRecord, float]: +) -> Tuple[FullBlock, BlockRecord, float, uint64]: time_delta, block_time_residual = round_timestamp(time_per_block, block_time_residual) if current_time is True: timestamp = uint64(max(int(time.time()), last_timestamp + time_delta)) @@ -1752,7 +1761,7 @@ def get_full_block_and_block_record( normalized_to_identity_cc_ip, ) - return full_block, block_record, block_time_residual + return full_block, block_record, block_time_residual, timestamp # these are the costs of unknown conditions, as defined chia_rs here: From b42dec0cf7009933b6846623409a2740c71a4c96 Mon Sep 17 00:00:00 2001 From: arvidn Date: Tue, 12 Sep 2023 09:26:19 +0200 Subject: [PATCH 2/6] update BlockTools to adjust simulated time per block based on the number of VDF iterations per block --- chia/simulator/block_tools.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/chia/simulator/block_tools.py b/chia/simulator/block_tools.py index fee7a381eb61..31e4faec9389 100644 --- a/chia/simulator/block_tools.py +++ b/chia/simulator/block_tools.py @@ -1706,6 +1706,11 @@ def get_full_block_and_block_record( current_time: bool = False, block_time_residual: float = 0.0, ) -> Tuple[FullBlock, BlockRecord, float, uint64]: + # we're simulating time between blocks here. The more VDF iterations the + # blocks advances, the longer it should have taken (and vice versa). This + # formula is meant to converge at 1024 iters per the specified + # time_per_block (which defaults to 18.75 seconds) + time_per_block *= (((sub_slot_iters / 1024) - 1) * 0.2) + 1 time_delta, block_time_residual = round_timestamp(time_per_block, block_time_residual) if current_time is True: timestamp = uint64(max(int(time.time()), last_timestamp + time_delta)) From cea5f1a2586f49436efdd184e09b1fd72bc9bff3 Mon Sep 17 00:00:00 2001 From: arvidn Date: Tue, 12 Sep 2023 10:01:09 +0200 Subject: [PATCH 3/6] use floating point for timestamps in BlockTools, to replace the previous (more complicated) block-time-residual field, tracking fractions of seconds. This also makes high precision (simulated) timestamps mandatory in BlockTools --- chia/simulator/block_tools.py | 35 ++++++++--------------------------- tools/generate_chain.py | 2 -- 2 files changed, 8 insertions(+), 29 deletions(-) diff --git a/chia/simulator/block_tools.py b/chia/simulator/block_tools.py index 31e4faec9389..e1a595ca8072 100644 --- a/chia/simulator/block_tools.py +++ b/chia/simulator/block_tools.py @@ -4,7 +4,6 @@ import copy import dataclasses import logging -import math import os import random import shutil @@ -207,7 +206,6 @@ def __init__( self.root_path = root_path self.log = log self.local_keychain = keychain - self._block_time_residual = 0.0 self.local_sk_cache: Dict[bytes32, Tuple[PrivateKey, Any]] = {} self.automated_testing = automated_testing self.plot_dir_name = plot_dir @@ -575,7 +573,6 @@ def get_consecutive_blocks( previous_generator: Optional[Union[CompressorArg, List[uint32]]] = None, genesis_timestamp: Optional[uint64] = None, force_plot_id: Optional[bytes32] = None, - use_timestamp_residual: bool = False, ) -> List[FullBlock]: assert num_blocks > 0 if block_list_input is not None: @@ -625,7 +622,8 @@ def get_consecutive_blocks( curr = latest_block while not curr.is_transaction_block: curr = blocks[curr.prev_hash] - last_timestamp = curr.timestamp + assert curr.timestamp is not None + last_timestamp = float(curr.timestamp) start_height = curr.height curr = latest_block @@ -754,13 +752,9 @@ def get_consecutive_blocks( block_generator = None aggregate_signature = G2Element() - if not use_timestamp_residual: - self._block_time_residual = 0.0 - ( full_block, block_record, - self._block_time_residual, new_timestamp, ) = get_full_block_and_block_record( constants, @@ -791,7 +785,6 @@ def get_consecutive_blocks( seed, normalized_to_identity_cc_ip=normalized_to_identity_cc_ip, current_time=current_time, - block_time_residual=self._block_time_residual, ) if block_record.is_transaction_block: transaction_data_included = True @@ -1044,13 +1037,9 @@ def get_consecutive_blocks( block_generator = None aggregate_signature = G2Element() - if not use_timestamp_residual: - self._block_time_residual = 0.0 - ( full_block, block_record, - self._block_time_residual, new_timestamp, ) = get_full_block_and_block_record( constants, @@ -1083,7 +1072,6 @@ def get_consecutive_blocks( overflow_rc_challenge=overflow_rc_challenge, normalized_to_identity_cc_ip=normalized_to_identity_cc_ip, current_time=current_time, - block_time_residual=self._block_time_residual, ) if block_record.is_transaction_block: @@ -1667,11 +1655,6 @@ def get_icc( ) -def round_timestamp(timestamp: float, residual: float) -> Tuple[int, float]: - mod = math.modf(timestamp + residual) - return (int(mod[1]), mod[0]) - - def get_full_block_and_block_record( constants: ConsensusConstants, blocks: Dict[bytes32, BlockRecord], @@ -1682,7 +1665,7 @@ def get_full_block_and_block_record( slot_rc_challenge: bytes32, farmer_reward_puzzle_hash: bytes32, pool_target: PoolTarget, - last_timestamp: uint64, + last_timestamp: float, start_height: uint32, time_per_block: float, block_generator: Optional[BlockGenerator], @@ -1704,18 +1687,16 @@ def get_full_block_and_block_record( overflow_rc_challenge: Optional[bytes32] = None, normalized_to_identity_cc_ip: bool = False, current_time: bool = False, - block_time_residual: float = 0.0, -) -> Tuple[FullBlock, BlockRecord, float, uint64]: +) -> Tuple[FullBlock, BlockRecord, float]: # we're simulating time between blocks here. The more VDF iterations the # blocks advances, the longer it should have taken (and vice versa). This # formula is meant to converge at 1024 iters per the specified # time_per_block (which defaults to 18.75 seconds) time_per_block *= (((sub_slot_iters / 1024) - 1) * 0.2) + 1 - time_delta, block_time_residual = round_timestamp(time_per_block, block_time_residual) if current_time is True: - timestamp = uint64(max(int(time.time()), last_timestamp + time_delta)) + timestamp = max(int(time.time()), last_timestamp + time_per_block) else: - timestamp = uint64(last_timestamp + time_delta) + timestamp = last_timestamp + time_per_block sp_iters = calculate_sp_iters(constants, sub_slot_iters, signage_point_index) ip_iters = calculate_ip_iters(constants, sub_slot_iters, signage_point_index, required_iters) @@ -1733,7 +1714,7 @@ def get_full_block_and_block_record( get_plot_signature, get_pool_signature, signage_point, - timestamp, + uint64(timestamp), BlockCache(blocks), seed, block_generator, @@ -1766,7 +1747,7 @@ def get_full_block_and_block_record( normalized_to_identity_cc_ip, ) - return full_block, block_record, block_time_residual, timestamp + return full_block, block_record, timestamp # these are the costs of unknown conditions, as defined chia_rs here: diff --git a/tools/generate_chain.py b/tools/generate_chain.py index 629c8bf696b7..d0eb42ded6c9 100644 --- a/tools/generate_chain.py +++ b/tools/generate_chain.py @@ -105,7 +105,6 @@ def main(length: int, fill_rate: int, profile: bool, block_refs: bool, output: O pool_reward_puzzle_hash=pool_puzzlehash, keep_going_until_tx_block=True, genesis_timestamp=uint64(1234567890), - use_timestamp_residual=True, ) unspent_coins: List[Coin] = [] @@ -164,7 +163,6 @@ def main(length: int, fill_rate: int, profile: bool, block_refs: bool, output: O keep_going_until_tx_block=True, transaction_data=SpendBundle.aggregate(spend_bundles), previous_generator=block_references, - use_timestamp_residual=True, ) prev_tx_block = b prev_block = blocks[-2] From 18ba95e3bf8d4beb45191802204978ec99d88b5d Mon Sep 17 00:00:00 2001 From: arvidn Date: Tue, 12 Sep 2023 11:46:44 +0200 Subject: [PATCH 4/6] fix test_filter_prefix_bits --- tests/farmer_harvester/test_filter_prefix_bits.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/farmer_harvester/test_filter_prefix_bits.py b/tests/farmer_harvester/test_filter_prefix_bits.py index 11b12dff59d5..039195acb777 100644 --- a/tests/farmer_harvester/test_filter_prefix_bits.py +++ b/tests/farmer_harvester/test_filter_prefix_bits.py @@ -32,7 +32,7 @@ # this test @pytest.mark.limit_consensus_modes(allowed=[ConsensusMode.PLAIN]) @pytest.mark.parametrize( - argnames=["filter_prefix_bits", "should_pass"], argvalues=[(9, 33), (8, 66), (7, 138), (6, 265), (5, 607)] + argnames=["filter_prefix_bits", "should_pass"], argvalues=[(9, 34), (8, 89), (7, 162), (6, 295), (5, 579)] ) def test_filter_prefix_bits_on_blocks( default_10000_blocks: List[FullBlock], filter_prefix_bits: uint8, should_pass: int From e36051c1f8a3ccb83a7e3e650239bb7744d69fd8 Mon Sep 17 00:00:00 2001 From: arvidn Date: Wed, 13 Sep 2023 19:36:52 +0200 Subject: [PATCH 5/6] add (commented-out) debug logging for generating test block chains in BlockTools --- chia/simulator/block_tools.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/chia/simulator/block_tools.py b/chia/simulator/block_tools.py index e1a595ca8072..f5cdf9cf49d5 100644 --- a/chia/simulator/block_tools.py +++ b/chia/simulator/block_tools.py @@ -793,6 +793,9 @@ def get_consecutive_blocks( assert full_block.foliage_transaction_block is not None elif guarantee_transaction_block: continue + # print(f"{full_block.height}: difficulty {difficulty} " + # f"time: {new_timestamp - last_timestamp:0.2f} " + # f"tx: {block_record.is_transaction_block}") last_timestamp = new_timestamp block_list.append(full_block) if full_block.transactions_generator is not None: @@ -1081,6 +1084,9 @@ def get_consecutive_blocks( assert full_block.foliage_transaction_block is not None elif guarantee_transaction_block: continue + # print(f"{full_block.height}: difficulty {difficulty} " + # f"time: {new_timestamp - last_timestamp:0.2f} " + # f"tx: {block_record.is_transaction_block}") last_timestamp = new_timestamp block_list.append(full_block) From d76b206368d627a8ee91b6592a9192cda10bb550 Mon Sep 17 00:00:00 2001 From: arvidn Date: Fri, 15 Sep 2023 09:27:45 +0200 Subject: [PATCH 6/6] use updated test chains from the latest version of test-cache --- .github/workflows/benchmarks.yml | 2 +- .github/workflows/test-single.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index 70c2ac7ad5c1..6357f4a930be 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -34,7 +34,7 @@ jobs: python-version: [ 3.9 ] env: CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet - BLOCKS_AND_PLOTS_VERSION: 0.32.0 + BLOCKS_AND_PLOTS_VERSION: 0.33.0 steps: - name: Clean workspace diff --git a/.github/workflows/test-single.yml b/.github/workflows/test-single.yml index 28c280fe9452..3d7dd132a354 100644 --- a/.github/workflows/test-single.yml +++ b/.github/workflows/test-single.yml @@ -113,7 +113,7 @@ jobs: CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet CHIA_SIMULATOR_ROOT: ${{ github.workspace }}/.chia/simulator JOB_FILE_NAME: tests_${{ matrix.os.file_name }}_python-${{ matrix.python.file_name }}_${{ matrix.configuration.name }} - BLOCKS_AND_PLOTS_VERSION: 0.32.0 + BLOCKS_AND_PLOTS_VERSION: 0.33.0 steps: - name: Configure git