From 621c75e4ba0b3208cf4b5a502ed2aa39e1f4e1ab Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Fri, 19 May 2023 03:20:11 +0200 Subject: [PATCH] Fork infrastructure (#15299) * remove softfork-logic for 1.7 softfork (which has already activated) * add new constants for soft-fork3, hard-fork and the other plot-filter adjustments --- chia/consensus/block_body_validation.py | 4 +-- chia/consensus/constants.py | 14 +++++++-- chia/consensus/default_constants.py | 11 ++++++- chia/consensus/multiprocess_validation.py | 6 +--- chia/full_node/full_node.py | 6 +--- chia/full_node/mempool_check_conditions.py | 4 +-- chia/full_node/mempool_manager.py | 2 +- chia/server/start_full_node.py | 2 -- chia/util/condition_tools.py | 6 ++-- chia/util/initial-config.yaml | 1 - tests/conftest.py | 2 +- tests/core/mempool/test_mempool.py | 36 +++++++++------------- tools/analyze-chain.py | 2 +- 13 files changed, 45 insertions(+), 51 deletions(-) diff --git a/chia/consensus/block_body_validation.py b/chia/consensus/block_body_validation.py index 72c6f0a63d9c..72f1b27d371f 100644 --- a/chia/consensus/block_body_validation.py +++ b/chia/consensus/block_body_validation.py @@ -480,9 +480,7 @@ async def validate_block_body( pairs_msgs: List[bytes] = [] if npc_result: assert npc_result.conds is not None - pairs_pks, pairs_msgs = pkm_pairs( - npc_result.conds, constants.AGG_SIG_ME_ADDITIONAL_DATA, soft_fork=height >= constants.SOFT_FORK_HEIGHT - ) + pairs_pks, pairs_msgs = pkm_pairs(npc_result.conds, constants.AGG_SIG_ME_ADDITIONAL_DATA) # 22. Verify aggregated signature # TODO: move this to pre_validate_blocks_multiprocessing so we can sync faster diff --git a/chia/consensus/constants.py b/chia/consensus/constants.py index f9b07015df82..490ce436369b 100644 --- a/chia/consensus/constants.py +++ b/chia/consensus/constants.py @@ -62,12 +62,22 @@ class ConsensusConstants: MAX_GENERATOR_SIZE: uint32 MAX_GENERATOR_REF_LIST_SIZE: uint32 POOL_SUB_SLOT_ITERS: uint64 - # soft fork initiated in 1.7.0 release - SOFT_FORK_HEIGHT: uint32 # soft fork initiated in 1.8.0 release SOFT_FORK2_HEIGHT: uint32 + # soft fork initiated in 2.0 release + SOFT_FORK3_HEIGHT: uint32 + + # the hard fork planned with the 2.0 release + # this is the block with the first plot filter adjustment + HARD_FORK_HEIGHT: uint32 + + # the plot filter adjustment heights + PLOT_FILTER_128_HEIGHT: uint32 + PLOT_FILTER_64_HEIGHT: uint32 + PLOT_FILTER_32_HEIGHT: uint32 + def replace(self, **changes: object) -> "ConsensusConstants": return dataclasses.replace(self, **changes) diff --git a/chia/consensus/default_constants.py b/chia/consensus/default_constants.py index 92180ab09d88..f58ceb016c74 100644 --- a/chia/consensus/default_constants.py +++ b/chia/consensus/default_constants.py @@ -56,8 +56,17 @@ "MAX_GENERATOR_SIZE": 1000000, "MAX_GENERATOR_REF_LIST_SIZE": 512, # Number of references allowed in the block generator ref list "POOL_SUB_SLOT_ITERS": 37600000000, # iters limit * NUM_SPS - "SOFT_FORK_HEIGHT": 3630000, "SOFT_FORK2_HEIGHT": 3886635, + # Spetember 2023 + "SOFT_FORK3_HEIGHT": 4200000, + # June 2024 + "HARD_FORK_HEIGHT": 5496000, + # June 2027 + "PLOT_FILTER_128_HEIGHT": 10542000, + # June 2030 + "PLOT_FILTER_64_HEIGHT": 15592000, + # June 2033 + "PLOT_FILTER_32_HEIGHT": 20643000, } diff --git a/chia/consensus/multiprocess_validation.py b/chia/consensus/multiprocess_validation.py index 667f8d6d27ab..de8b0403d621 100644 --- a/chia/consensus/multiprocess_validation.py +++ b/chia/consensus/multiprocess_validation.py @@ -122,11 +122,7 @@ def batch_pre_validate_blocks( if validate_signatures: if npc_result is not None and block.transactions_info is not None: assert npc_result.conds - pairs_pks, pairs_msgs = pkm_pairs( - npc_result.conds, - constants.AGG_SIG_ME_ADDITIONAL_DATA, - soft_fork=block.height >= constants.SOFT_FORK_HEIGHT, - ) + pairs_pks, pairs_msgs = pkm_pairs(npc_result.conds, constants.AGG_SIG_ME_ADDITIONAL_DATA) # Using AugSchemeMPL.aggregate_verify, so it's safe to use from_bytes_unchecked pks_objects: List[G1Element] = [G1Element.from_bytes_unchecked(pk) for pk in pairs_pks] if not AugSchemeMPL.aggregate_verify( diff --git a/chia/full_node/full_node.py b/chia/full_node/full_node.py index badc42079577..3a231cb2b797 100644 --- a/chia/full_node/full_node.py +++ b/chia/full_node/full_node.py @@ -1879,11 +1879,7 @@ async def add_unfinished_block( # blockchain.run_generator throws on errors, so npc_result is # guaranteed to represent a successful run assert npc_result.conds is not None - pairs_pks, pairs_msgs = pkm_pairs( - npc_result.conds, - self.constants.AGG_SIG_ME_ADDITIONAL_DATA, - soft_fork=height >= self.constants.SOFT_FORK_HEIGHT, - ) + pairs_pks, pairs_msgs = pkm_pairs(npc_result.conds, self.constants.AGG_SIG_ME_ADDITIONAL_DATA) if not cached_bls.aggregate_verify( pairs_pks, pairs_msgs, block.transactions_info.aggregated_signature, True ): diff --git a/chia/full_node/mempool_check_conditions.py b/chia/full_node/mempool_check_conditions.py index 798010c167ce..2ec2f3dd0bc9 100644 --- a/chia/full_node/mempool_check_conditions.py +++ b/chia/full_node/mempool_check_conditions.py @@ -40,10 +40,8 @@ def get_name_puzzle_conditions( ) -> NPCResult: if mempool_mode: flags = MEMPOOL_MODE - elif height >= constants.SOFT_FORK_HEIGHT: - flags = LIMIT_STACK else: - flags = 0 + flags = LIMIT_STACK if height >= constants.SOFT_FORK2_HEIGHT: flags = flags | ENABLE_ASSERT_BEFORE | NO_RELATIVE_CONDITIONS_ON_EPHEMERAL diff --git a/chia/full_node/mempool_manager.py b/chia/full_node/mempool_manager.py index 1bffa34de46b..812ff1ab0d3d 100644 --- a/chia/full_node/mempool_manager.py +++ b/chia/full_node/mempool_manager.py @@ -76,7 +76,7 @@ def validate_clvm_and_signature( pks: List[bytes48] = [] msgs: List[bytes] = [] assert result.conds is not None - pks, msgs = pkm_pairs(result.conds, additional_data, soft_fork=True) + pks, msgs = pkm_pairs(result.conds, additional_data) # Verify aggregated signature cache: LRUCache[bytes32, GTElement] = LRUCache(10000) diff --git a/chia/server/start_full_node.py b/chia/server/start_full_node.py index 2e297149babb..0edaa6a40ae8 100644 --- a/chia/server/start_full_node.py +++ b/chia/server/start_full_node.py @@ -77,8 +77,6 @@ async def async_main(service_config: Dict[str, Any]) -> int: # activate softforks immediately on testnet if "SOFT_FORK2_HEIGHT" not in overrides: overrides["SOFT_FORK2_HEIGHT"] = 0 - if "SOFT_FORK_HEIGHT" not in overrides: - overrides["SOFT_FORK_HEIGHT"] = 0 updated_constants = DEFAULT_CONSTANTS.replace_str_to_bytes(**overrides) initialize_service_logging(service_name=SERVICE_NAME, config=config) service = create_full_node_service(DEFAULT_ROOT_PATH, config, updated_constants) diff --git a/chia/util/condition_tools.py b/chia/util/condition_tools.py index e64faf9b13fe..2b7d20122057 100644 --- a/chia/util/condition_tools.py +++ b/chia/util/condition_tools.py @@ -55,15 +55,13 @@ def parse_sexp_to_conditions(sexp: Program) -> List[ConditionWithArgs]: return [parse_sexp_to_condition(s) for s in sexp.as_iter()] -def pkm_pairs( - conditions: SpendBundleConditions, additional_data: bytes, *, soft_fork: bool -) -> Tuple[List[bytes48], List[bytes]]: +def pkm_pairs(conditions: SpendBundleConditions, additional_data: bytes) -> Tuple[List[bytes48], List[bytes]]: ret: Tuple[List[bytes48], List[bytes]] = ([], []) for pk, msg in conditions.agg_sig_unsafe: ret[0].append(bytes48(pk)) ret[1].append(msg) - if soft_fork and msg.endswith(additional_data): + if msg.endswith(additional_data): raise ConsensusError(Err.INVALID_CONDITION) for spend in conditions.spends: diff --git a/chia/util/initial-config.yaml b/chia/util/initial-config.yaml index 23224d5d2c79..686efd71809c 100644 --- a/chia/util/initial-config.yaml +++ b/chia/util/initial-config.yaml @@ -71,7 +71,6 @@ network_overrides: &network_overrides GENESIS_PRE_FARM_POOL_PUZZLE_HASH: d23da14695a188ae5708dd152263c4db883eb27edeb936178d4d988b8f3ce5fc MEMPOOL_BLOCK_BUFFER: 10 MIN_PLOT_SIZE: 18 - SOFT_FORK_HEIGHT: 0 SOFT_FORK2_HEIGHT: 0 config: mainnet: diff --git a/tests/conftest.py b/tests/conftest.py index 13877ac043ee..cba331f92de6 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -133,7 +133,7 @@ def db_version(request) -> int: return request.param -@pytest.fixture(scope="function", params=[1000000, 3630000, 3886635]) +@pytest.fixture(scope="function", params=[1000000, 3886635, 4200000, 5496000]) def softfork_height(request) -> int: return request.param diff --git a/tests/core/mempool/test_mempool.py b/tests/core/mempool/test_mempool.py index 815577871661..3ca2a3b86160 100644 --- a/tests/core/mempool/test_mempool.py +++ b/tests/core/mempool/test_mempool.py @@ -2525,21 +2525,21 @@ class TestPkmPairs: pk1 = G1Element.generator() pk2 = G1Element.generator() - def test_empty_list(self, softfork): + def test_empty_list(self): conds = SpendBundleConditions([], 0, 0, 0, None, None, [], 0, 0, 0) - pks, msgs = pkm_pairs(conds, b"foobar", soft_fork=softfork) + pks, msgs = pkm_pairs(conds, b"foobar") assert pks == [] assert msgs == [] - def test_no_agg_sigs(self, softfork): + def test_no_agg_sigs(self): # one create coin: h1 amount: 1 and not hint spends = [Spend(self.h3, self.h4, None, None, None, None, None, None, [(self.h1, 1, b"")], [], 0)] conds = SpendBundleConditions(spends, 0, 0, 0, None, None, [], 0, 0, 0) - pks, msgs = pkm_pairs(conds, b"foobar", soft_fork=softfork) + pks, msgs = pkm_pairs(conds, b"foobar") assert pks == [] assert msgs == [] - def test_agg_sig_me(self, softfork): + def test_agg_sig_me(self): spends = [ Spend( self.h1, @@ -2556,22 +2556,22 @@ def test_agg_sig_me(self, softfork): ) ] conds = SpendBundleConditions(spends, 0, 0, 0, None, None, [], 0, 0, 0) - pks, msgs = pkm_pairs(conds, b"foobar", soft_fork=softfork) + pks, msgs = pkm_pairs(conds, b"foobar") assert [bytes(pk) for pk in pks] == [bytes(self.pk1), bytes(self.pk2)] assert msgs == [b"msg1" + self.h1 + b"foobar", b"msg2" + self.h1 + b"foobar"] - def test_agg_sig_unsafe(self, softfork): + def test_agg_sig_unsafe(self): conds = SpendBundleConditions( [], 0, 0, 0, None, None, [(bytes48(self.pk1), b"msg1"), (bytes48(self.pk2), b"msg2")], 0, 0, 0 ) - pks, msgs = pkm_pairs(conds, b"foobar", soft_fork=softfork) + pks, msgs = pkm_pairs(conds, b"foobar") assert [bytes(pk) for pk in pks] == [bytes(self.pk1), bytes(self.pk2)] assert msgs == [b"msg1", b"msg2"] - def test_agg_sig_mixed(self, softfork): + def test_agg_sig_mixed(self): spends = [Spend(self.h1, self.h2, None, None, None, None, None, None, [], [(bytes48(self.pk1), b"msg1")], 0)] conds = SpendBundleConditions(spends, 0, 0, 0, None, None, [(bytes48(self.pk2), b"msg2")], 0, 0, 0) - pks, msgs = pkm_pairs(conds, b"foobar", soft_fork=softfork) + pks, msgs = pkm_pairs(conds, b"foobar") assert [bytes(pk) for pk in pks] == [bytes(self.pk2), bytes(self.pk1)] assert msgs == [b"msg2", b"msg1" + self.h1 + b"foobar"] @@ -2579,25 +2579,17 @@ def test_agg_sig_unsafe_restriction(self) -> None: conds = SpendBundleConditions( [], 0, 0, 0, None, None, [(bytes48(self.pk1), b"msg1"), (bytes48(self.pk2), b"msg2")], 0, 0, 0 ) - pks, msgs = pkm_pairs(conds, b"msg1", soft_fork=False) - assert [bytes(pk) for pk in pks] == [bytes(self.pk1), bytes(self.pk2)] - assert msgs == [b"msg1", b"msg2"] - - pks, msgs = pkm_pairs(conds, b"msg2", soft_fork=False) - assert [bytes(pk) for pk in pks] == [bytes(self.pk1), bytes(self.pk2)] - assert msgs == [b"msg1", b"msg2"] - with pytest.raises(ConsensusError, match="INVALID_CONDITION"): - pkm_pairs(conds, b"msg1", soft_fork=True) + pkm_pairs(conds, b"msg1") with pytest.raises(ConsensusError, match="INVALID_CONDITION"): - pkm_pairs(conds, b"sg1", soft_fork=True) + pkm_pairs(conds, b"sg1") with pytest.raises(ConsensusError, match="INVALID_CONDITION"): - pkm_pairs(conds, b"msg2", soft_fork=True) + pkm_pairs(conds, b"msg2") with pytest.raises(ConsensusError, match="INVALID_CONDITION"): - pkm_pairs(conds, b"g2", soft_fork=True) + pkm_pairs(conds, b"g2") class TestPkmPairsForConditionDict: diff --git a/tools/analyze-chain.py b/tools/analyze-chain.py index b12736622e9a..972f3bea4fde 100755 --- a/tools/analyze-chain.py +++ b/tools/analyze-chain.py @@ -140,7 +140,7 @@ def default_call( # create hash_key list for aggsig check pairs_pks: List[bytes48] = [] pairs_msgs: List[bytes] = [] - pairs_pks, pairs_msgs = pkm_pairs(result, DEFAULT_CONSTANTS.AGG_SIG_ME_ADDITIONAL_DATA, soft_fork=False) + pairs_pks, pairs_msgs = pkm_pairs(result, DEFAULT_CONSTANTS.AGG_SIG_ME_ADDITIONAL_DATA) pairs_g1s = [G1Element.from_bytes(x) for x in pairs_pks] assert block.transactions_info is not None assert block.transactions_info.aggregated_signature is not None