diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index 3cc7bb5e0a..0a62ed442c 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -59,7 +59,7 @@ jobs: python-version: ["3.12"] env: CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet - BLOCKS_AND_PLOTS_VERSION: 0.45.8 + BLOCKS_AND_PLOTS_VERSION: 0.45.12 steps: - name: Clean workspace diff --git a/.github/workflows/test-single.yml b/.github/workflows/test-single.yml index 1ef4533a3f..a956916345 100644 --- a/.github/workflows/test-single.yml +++ b/.github/workflows/test-single.yml @@ -130,7 +130,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.module_import_path }}${{ matrix.configuration.file_name_index }} - BLOCKS_AND_PLOTS_VERSION: 0.45.8 + BLOCKS_AND_PLOTS_VERSION: 0.45.12 steps: - name: Checkout code diff --git a/chia/_tests/blockchain/test_blockchain.py b/chia/_tests/blockchain/test_blockchain.py index eeab7a3d46..ba3674ac81 100644 --- a/chia/_tests/blockchain/test_blockchain.py +++ b/chia/_tests/blockchain/test_blockchain.py @@ -864,7 +864,7 @@ class TestBlockHeaderValidation: @pytest.mark.anyio @pytest.mark.limit_consensus_modes( - allowed=[ConsensusMode.PLAIN, ConsensusMode.HARD_FORK_2_0, ConsensusMode.HARD_FORK_3_0], + allowed=[ConsensusMode.PLAIN, ConsensusMode.HARD_FORK_2_0], reason="After the phase out, when we have v2-only plots. It seems like " "we never get an overflow block. get_consecutive_blocks(..., force_overflow=True) " "loops until we time out", @@ -1497,8 +1497,8 @@ class TestBlockHeaderValidation: @pytest.mark.anyio # todo_v2_plots fix this test and remove limit_consensus_modes @pytest.mark.limit_consensus_modes( - allowed=[ConsensusMode.PLAIN, ConsensusMode.HARD_FORK_2_0, ConsensusMode.HARD_FORK_3_0], - reason="HARD_FORK_3_0_AFTER_PHASE_OUT doesn't work as we keep getting v2 PoS with pool keys, " + allowed=[ConsensusMode.PLAIN, ConsensusMode.HARD_FORK_2_0], + reason="HARD_FORK_3_0*doesn't work as we keep getting v2 PoS with pool keys, " "we need to change the plot setup to increase the chance of getting PoS with pool contracts", ) async def test_pool_target_contract( @@ -2659,7 +2659,7 @@ class TestBodyValidation: @pytest.mark.anyio @pytest.mark.skipif(_is_macos_intel(), reason="Slow on macOS Intel") async def test_cost_exceeds_max( - self, empty_blockchain: Blockchain, softfork_height: uint32, bt: BlockTools + self, empty_blockchain: Blockchain, softfork_height: uint32, bt: BlockTools, consensus_mode: ConsensusMode ) -> None: # 7 b = empty_blockchain @@ -2675,7 +2675,12 @@ class TestBodyValidation: wt: WalletTool = bt.get_pool_wallet_tool() condition_dict: dict[ConditionOpcode, list[ConditionWithArgs]] = {ConditionOpcode.CREATE_COIN: []} - for i in range(7_000): + num_coins = 7_000 + if consensus_mode >= ConsensusMode.HARD_FORK_3_0: + # after the hard fork, CREATE_COIN is 25% cheaper, so we need more + # coins to exceed the block cost + num_coins += num_coins // 3 + for i in range(num_coins): output = ConditionWithArgs(ConditionOpcode.CREATE_COIN, [bt.pool_ph, int_to_bytes(i)]) condition_dict[ConditionOpcode.CREATE_COIN].append(output) diff --git a/chia/_tests/conftest.py b/chia/_tests/conftest.py index c6163d1a09..041821aea1 100644 --- a/chia/_tests/conftest.py +++ b/chia/_tests/conftest.py @@ -255,7 +255,7 @@ def blockchain_constants(consensus_mode: ConsensusMode) -> ConsensusConstants: # we don't have very much v2 space, and no phase-out means the # difficulty won't adjust gradually. We need a lower difficulty # level to start with - DIFFICULTY_STARTING=uint64(2), + DIFFICULTY_STARTING=uint64(64), ) elif consensus_mode >= ConsensusMode.HARD_FORK_3_0: ret = ret.replace( @@ -266,7 +266,7 @@ def blockchain_constants(consensus_mode: ConsensusMode) -> ConsensusConstants: HARD_FORK2_HEIGHT=uint32(0), # we don't have very much v2 space. We need a lower difficulty # level to start with - DIFFICULTY_STARTING=uint64(7), + DIFFICULTY_STARTING=uint64(64), ) elif consensus_mode >= ConsensusMode.HARD_FORK_2_0: ret = ret.replace( @@ -278,6 +278,14 @@ def blockchain_constants(consensus_mode: ConsensusMode) -> ConsensusConstants: return ret +@pytest.fixture(scope="session", autouse=True) +def _install_plot_cache() -> None: + from chia._tests.util.plot_cache import install as install_plot_cache + from chia.util.default_root import DEFAULT_ROOT_PATH + + install_plot_cache(DEFAULT_ROOT_PATH.parent / "test-plots") + + @pytest.fixture(scope="session", name="bt") async def block_tools_fixture( get_keychain, blockchain_constants, anyio_backend, testrun_uid: str diff --git a/chia/_tests/core/custom_types/test_spend_bundle.py b/chia/_tests/core/custom_types/test_spend_bundle.py index 0c507ecbe9..3ea2c2a955 100644 --- a/chia/_tests/core/custom_types/test_spend_bundle.py +++ b/chia/_tests/core/custom_types/test_spend_bundle.py @@ -60,7 +60,7 @@ def test_compute_additions_create_coin() -> None: def test_compute_additions_create_coin_max_cost() -> None: # make a large number of CoinSpends - spends, _ = create_spends(6111) + spends, _ = create_spends(8148) sb = SpendBundle(spends, G2Element()) with pytest.raises(ValueError, match="cost exceeded"): sb.additions() diff --git a/chia/_tests/core/full_node/test_conditions.py b/chia/_tests/core/full_node/test_conditions.py index b51a6f8915..16a1de41f3 100644 --- a/chia/_tests/core/full_node/test_conditions.py +++ b/chia/_tests/core/full_node/test_conditions.py @@ -148,7 +148,7 @@ class TestConditions: block_base_cost = 761056 - 12000 if consensus_mode >= ConsensusMode.HARD_FORK_3_0: - condition_cost = ConditionCost.GENERIC_CONDITION_COST.value + condition_cost = ConditionCost.GENERIC_CONDITION_COST.value + ConditionCost.SPEND_COST.value else: condition_cost = 0 @@ -177,7 +177,7 @@ class TestConditions: block_base_cost = 732064 - 12000 if consensus_mode >= ConsensusMode.HARD_FORK_3_0: - condition_cost = ConditionCost.GENERIC_CONDITION_COST.value + condition_cost = ConditionCost.GENERIC_CONDITION_COST.value + ConditionCost.SPEND_COST.value else: condition_cost = 0 diff --git a/chia/_tests/core/mempool/test_mempool.py b/chia/_tests/core/mempool/test_mempool.py index 7b04163bb5..9ea87d1308 100644 --- a/chia/_tests/core/mempool/test_mempool.py +++ b/chia/_tests/core/mempool/test_mempool.py @@ -3336,18 +3336,20 @@ def test_create_block_generator_custom_spend(puzzle: str, solution: str, old: bo invariant_check_mempool(mempool) create_block = mempool.create_block_generator if old else mempool.create_block_generator2 - generator = create_block(test_constants, test_constants.HARD_FORK2_HEIGHT, 10.0) + height = test_constants.HARD_FORK2_HEIGHT + generator = create_block(test_constants, height, 10.0) assert generator is not None assert generator.signature == G2Element() removals = set(generator.removals) + flags = get_flags_for_height_and_constants(height, test_constants) err, conds = run_block_generator2( bytes(generator.program), generator.generator_refs, test_constants.MAX_BLOCK_COST_CLVM, - 0, + flags, generator.signature, None, test_constants, diff --git a/chia/_tests/util/plot_cache.py b/chia/_tests/util/plot_cache.py new file mode 100644 index 0000000000..fb295302ca --- /dev/null +++ b/chia/_tests/util/plot_cache.py @@ -0,0 +1,169 @@ +""" +Persistent cache for expensive plot operations: get_qualities_for_challenge(), +get_full_proof(), and solve_proof(). + +The cache is stored in the plots directory as `.plot_cache.pickle` and is keyed +by (plot_id, challenge) for qualities and full proofs, and by +(partial_proof_bytes, plot_id) for solve_proof. + +Call install() to monkeypatch the prover classes and solve_proof. The cache is +loaded from disk on first install and saved on process exit. +""" + +from __future__ import annotations + +import atexit +import logging +import pickle # noqa: S403 +from pathlib import Path +from typing import Any + +from chia_rs import PartialProof +from chia_rs import solve_proof as _orig_solve_proof +from chia_rs.sized_bytes import bytes32 +from filelock import FileLock + +from chia.plotting.prover import QualityProtocol, V1Prover, V1Quality, V2Prover, V2Quality + +log = logging.getLogger(__name__) + +CACHE_FILENAME = ".plot_cache.pickle" + +# (plot_id, challenge) -> list of serialized quality data +# V1: each entry is 32 bytes (quality bytes32) +# V2: each entry is serialized PartialProof bytes +_qualities: dict[tuple[bytes, bytes], list[bytes]] = {} + +# (plot_id, challenge, index) -> proof bytes +_full_proofs: dict[tuple[bytes, bytes, int], bytes] = {} + +# (partial_proof_bytes, plot_id) -> proof bytes +_solve_proofs: dict[tuple[bytes, bytes], bytes] = {} + +_installed: bool = False +_cache_path: Path | None = None +_hits: int = 0 +_misses: int = 0 + + +def _load_from_disk(path: Path) -> tuple[dict[Any, Any], dict[Any, Any], dict[Any, Any]]: + if not path.exists(): + return {}, {}, {} + try: + data = pickle.loads(path.read_bytes()) # noqa: S301 + if isinstance(data, tuple) and len(data) == 3: + return data[0], data[1], data[2] + except Exception: + log.exception("plot_cache: failed to read existing cache for merge") + return {}, {}, {} + + +def _save() -> None: + total_lookups = _hits + _misses + hit_pct = f"{_hits * 100 / total_lookups:.1f}%" if total_lookups > 0 else "n/a" + if _misses > 0 and _cache_path is not None: + try: + with FileLock(str(_cache_path) + ".lock"): + disk_q, disk_fp, disk_sp = _load_from_disk(_cache_path) + disk_q.update(_qualities) + disk_fp.update(_full_proofs) + disk_sp.update(_solve_proofs) + data = (disk_q, disk_fp, disk_sp) + _cache_path.write_bytes(pickle.dumps(data, protocol=pickle.HIGHEST_PROTOCOL)) + total = len(disk_q) + len(disk_fp) + len(disk_sp) + print(f"plot_cache: saved {total} entries to {_cache_path}") + except Exception: + log.exception("plot_cache: failed to save") + if total_lookups > 0: + print(f"plot_cache: hits={_hits} misses={_misses} hit_rate={hit_pct}") + + +def load(plot_dir: Path) -> None: + global _cache_path + cache_path = plot_dir / CACHE_FILENAME + if not plot_dir.exists(): + return + _cache_path = cache_path + try: + with FileLock(str(_cache_path) + ".lock"): + disk_q, disk_fp, disk_sp = _load_from_disk(_cache_path) + except Exception: + log.exception("plot_cache: failed to acquire lock for loading") + return + _qualities.update(disk_q) + _full_proofs.update(disk_fp) + _solve_proofs.update(disk_sp) + total = len(_qualities) + len(_full_proofs) + len(_solve_proofs) + if total > 0: + print(f"plot_cache: loaded {total} entries from {_cache_path}") + + +def cached_solve_proof(partial_proof: PartialProof, plot_id: bytes32, strength: int, k: int) -> bytes: + global _hits, _misses + key = (partial_proof.to_bytes(), bytes(plot_id)) + cached = _solve_proofs.get(key) + if cached is not None: + _hits += 1 + return cached + result = _orig_solve_proof(partial_proof, plot_id, strength, k) + _solve_proofs[key] = result + _misses += 1 + return result + + +def install(plot_dir: Path) -> None: + global _installed + if _installed: + return + _installed = True + + load(plot_dir) + + orig_v1_quals = V1Prover.get_qualities_for_challenge + orig_v2_quals = V2Prover.get_qualities_for_challenge + orig_v1_proof = V1Prover.get_full_proof + + def v1_qualities(self: V1Prover, challenge: bytes32) -> list[QualityProtocol]: + global _hits, _misses + key = (bytes(self.get_id()), bytes(challenge)) + cached = _qualities.get(key) + if cached is not None: + _hits += 1 + return [V1Quality(bytes32(q)) for q in cached] + result = orig_v1_quals(self, challenge) + _qualities[key] = [bytes(q.get_string()) for q in result] + _misses += 1 + return result + + def v2_qualities(self: V2Prover, challenge: bytes32) -> list[QualityProtocol]: + global _hits, _misses + key = (bytes(self.get_id()), bytes(challenge)) + cached = _qualities.get(key) + if cached is not None: + _hits += 1 + return [V2Quality(PartialProof.from_bytes(q), self.get_strength()) for q in cached] + result = orig_v2_quals(self, challenge) + _qualities[key] = [q.get_partial_proof().to_bytes() for q in result] # type: ignore[attr-defined] + _misses += 1 + return result + + def v1_full_proof(self: V1Prover, challenge: bytes32, index: int, parallel_read: bool = True) -> bytes: + global _hits, _misses + key = (bytes(self.get_id()), bytes(challenge), index) + cached = _full_proofs.get(key) + if cached is not None: + _hits += 1 + return cached + result = orig_v1_proof(self, challenge, index, parallel_read) + _full_proofs[key] = result + _misses += 1 + return result + + V1Prover.get_qualities_for_challenge = v1_qualities # type: ignore[method-assign] + V2Prover.get_qualities_for_challenge = v2_qualities # type: ignore[method-assign] + V1Prover.get_full_proof = v1_full_proof # type: ignore[method-assign] + + setattr(__import__("chia.simulator.block_tools", fromlist=["solve_proof"]), "solve_proof", cached_solve_proof) + setattr(__import__("chia.solver.solver", fromlist=["solve_proof"]), "solve_proof", cached_solve_proof) + + atexit.register(_save) diff --git a/chia/_tests/util/test_plot_cache.py b/chia/_tests/util/test_plot_cache.py new file mode 100644 index 0000000000..fcbd44afbd --- /dev/null +++ b/chia/_tests/util/test_plot_cache.py @@ -0,0 +1,141 @@ +from __future__ import annotations + +import pickle # noqa: S403 +from pathlib import Path +from unittest.mock import MagicMock + +from chia_rs.sized_bytes import bytes32 + +import chia._tests.util.plot_cache as pc +from chia.plotting.prover import V1Prover + + +class TestLoadFromDisk: + def test_missing_file(self, tmp_path: Path) -> None: + q, fp, sp = pc._load_from_disk(tmp_path / "nonexistent") + assert q == {} and fp == {} and sp == {} + + def test_corrupt_file(self, tmp_path: Path) -> None: + bad = tmp_path / "bad.pickle" + bad.write_bytes(b"not valid pickle") + q, fp, sp = pc._load_from_disk(bad) + assert q == {} and fp == {} and sp == {} + + def test_wrong_shape(self, tmp_path: Path) -> None: + f = tmp_path / "wrong.pickle" + f.write_bytes(pickle.dumps(("only", "two"))) + q, fp, sp = pc._load_from_disk(f) + assert q == {} and fp == {} and sp == {} + + def test_valid_roundtrip(self, tmp_path: Path) -> None: + f = tmp_path / "cache.pickle" + qualities = {(b"plot1", b"ch1"): [b"q1", b"q2"]} + full_proofs = {(b"plot1", b"ch1", 0): b"proof1"} + solve_proofs = {(b"pp1", b"plot1"): b"sp1"} + f.write_bytes(pickle.dumps((qualities, full_proofs, solve_proofs))) + + q, fp, sp = pc._load_from_disk(f) + assert q == qualities + assert fp == full_proofs + assert sp == solve_proofs + + +class TestLoad: + def test_missing_directory(self, tmp_path: Path) -> None: + old_cache_path = pc._cache_path + try: + pc.load(tmp_path / "does_not_exist") + assert pc._cache_path == old_cache_path + finally: + pc._cache_path = old_cache_path + + def test_loads_entries(self, tmp_path: Path) -> None: + cache_file = tmp_path / pc.CACHE_FILENAME + qualities = {(b"id1", b"ch1"): [b"q1"]} + cache_file.write_bytes(pickle.dumps((qualities, {}, {}))) + + old_cache_path = pc._cache_path + old_qualities = dict(pc._qualities) + try: + pc.load(tmp_path) + assert (b"id1", b"ch1") in pc._qualities + finally: + pc._cache_path = old_cache_path + pc._qualities.clear() + pc._qualities.update(old_qualities) + + +class TestSave: + def test_no_misses_skips_write(self, tmp_path: Path) -> None: + old = pc._misses, pc._cache_path + try: + pc._misses = 0 + pc._cache_path = tmp_path / pc.CACHE_FILENAME + pc._save() + assert not pc._cache_path.exists() + finally: + pc._misses, pc._cache_path = old + + def test_merges_with_existing(self, tmp_path: Path) -> None: + cache_file = tmp_path / pc.CACHE_FILENAME + existing = {(b"old_plot", b"old_ch"): [b"old_q"]} + cache_file.write_bytes(pickle.dumps((existing, {}, {}))) + + old = pc._misses, pc._cache_path, dict(pc._qualities) + try: + pc._misses = 1 + pc._cache_path = cache_file + pc._qualities[b"new_plot", b"new_ch"] = [b"new_q"] + pc._save() + + q, _fp, _sp = pc._load_from_disk(cache_file) + assert (b"old_plot", b"old_ch") in q + assert (b"new_plot", b"new_ch") in q + finally: + pc._misses, pc._cache_path = old[0], old[1] + pc._qualities.clear() + pc._qualities.update(old[2]) + + +class TestInstall: + def test_cache_is_installed(self) -> None: + assert pc._installed + + def test_qualities_cache_hit(self) -> None: + plot_id = bytes32(b"\x01" * 32) + challenge = bytes32(b"\x02" * 32) + quality_bytes = bytes32(b"\x03" * 32) + key = (bytes(plot_id), bytes(challenge)) + + old_qualities = dict(pc._qualities) + old_hits = pc._hits + try: + pc._qualities[key] = [bytes(quality_bytes)] + mock_prover = MagicMock(spec=V1Prover) + mock_prover.get_id.return_value = plot_id + result = V1Prover.get_qualities_for_challenge(mock_prover, challenge) + assert len(result) == 1 + assert result[0].get_string() == quality_bytes + assert pc._hits == old_hits + 1 + finally: + pc._qualities.clear() + pc._qualities.update(old_qualities) + + def test_full_proof_cache_hit(self) -> None: + plot_id = bytes32(b"\x04" * 32) + challenge = bytes32(b"\x05" * 32) + proof = b"\x06" * 64 + key = (bytes(plot_id), bytes(challenge), 0) + + old_proofs = dict(pc._full_proofs) + old_hits = pc._hits + try: + pc._full_proofs[key] = proof + mock_prover = MagicMock(spec=V1Prover) + mock_prover.get_id.return_value = plot_id + result = V1Prover.get_full_proof(mock_prover, challenge, 0) + assert result == proof + assert pc._hits == old_hits + 1 + finally: + pc._full_proofs.clear() + pc._full_proofs.update(old_proofs) diff --git a/chia/consensus/condition_costs.py b/chia/consensus/condition_costs.py index bbde9cfed7..8d8d96fb17 100644 --- a/chia/consensus/condition_costs.py +++ b/chia/consensus/condition_costs.py @@ -8,6 +8,10 @@ class ConditionCost(Enum): AGG_SIG = 1200000 # the cost of one G1 subgroup check + aggregated signature validation CREATE_COIN = 1800000 + # with hard fork 2 (Chia 3.0) all spends have a cost + SPEND_COST = CREATE_COIN // 4 + NEW_CREATE_COIN = CREATE_COIN - SPEND_COST + # with hard fork 2 (Chia 3.0) all conditions have a cost # SEND/RECEIVE MESSAGE and CREATE/ASSERT ANNOUNCEMENT MESSAGE_CONDITION_COST = 700 diff --git a/chia/simulator/block_tools.py b/chia/simulator/block_tools.py index 6a463118d8..e267a1d395 100644 --- a/chia/simulator/block_tools.py +++ b/chia/simulator/block_tools.py @@ -2184,14 +2184,16 @@ CONDITION_COSTS = compute_cost_table() def conditions_cost(conds: Program, *, charge_for_conditions: bool) -> uint64: - condition_cost = 0 + condition_cost = ConditionCost.SPEND_COST.value if charge_for_conditions else 0 for cond in conds.as_iter(): condition = cond.first().as_atom() # this is new in hard fork 2 if condition == ConditionOpcode.CREATE_COIN: - condition_cost += ConditionCost.CREATE_COIN.value + condition_cost += ( + ConditionCost.NEW_CREATE_COIN.value if charge_for_conditions else ConditionCost.CREATE_COIN.value + ) # after the 2.0 hard fork, two byte conditions (with no leading 0) # have costs. Account for that. elif len(condition) == 2 and condition[0] != 0: diff --git a/poetry.lock b/poetry.lock index 3cc805a496..2b68f1d3f2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -872,38 +872,38 @@ pytest = ">=8.3.3,<9.0.0" [[package]] name = "chia-rs" -version = "0.41.1" +version = "0.42.0" description = "" optional = false python-versions = "*" groups = ["main"] files = [ - {file = "chia_rs-0.41.1-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:4492844e7deb77bb490b7e1937f88c2264f1c0254be5e13ef4f94cf0812ab5e5"}, - {file = "chia_rs-0.41.1-cp310-cp310-macosx_13_0_x86_64.whl", hash = "sha256:d476a10c6133070b15bf9353debba663af4865a950fca80381d8145d34540629"}, - {file = "chia_rs-0.41.1-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:afe79c7fa2056dea0c949c2695786cc3ce4560f5ec1865fcee9acf737dd19f2f"}, - {file = "chia_rs-0.41.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:044fbf6a823aa56bd05c8b3f3e48d70d4158f827d8d24fa593a1695bec2b5a8d"}, - {file = "chia_rs-0.41.1-cp310-cp310-win_amd64.whl", hash = "sha256:5632f450e272da9dcf6ea6ff884b81363dd2f2ef4194899eb3bbe23584146c58"}, - {file = "chia_rs-0.41.1-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:b0112f4960464bfb2fd221ab4a34b3ed5ca37664dc0afca577bae4b0e2ccf090"}, - {file = "chia_rs-0.41.1-cp311-cp311-macosx_13_0_x86_64.whl", hash = "sha256:1a242d8fdf0a9e76767cdbc59bd46d0d7fe66a7af9a0cb795b6db0e71e03f59f"}, - {file = "chia_rs-0.41.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:21922298b3d4f0436a41862d25b03b4de802c51f25c53665ce3e154b46c89081"}, - {file = "chia_rs-0.41.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:0eefd1a0002c9ea55a3a13b11b3e42338383d86638701ec004df2bc41bd52dd9"}, - {file = "chia_rs-0.41.1-cp311-cp311-win_amd64.whl", hash = "sha256:20a44e3d06b8c931f850bf0547f89463c024f7cb5e9bf104254839dc96c8a074"}, - {file = "chia_rs-0.41.1-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:9f32c527a214a5879a92b24e8f7ade007cf05dd798af56b9c4763e499a5bfe48"}, - {file = "chia_rs-0.41.1-cp312-cp312-macosx_13_0_x86_64.whl", hash = "sha256:1d1e34bb7bae4d510ce58b6118f54841be69ad8b4bc5768365091ab4e8d77ab4"}, - {file = "chia_rs-0.41.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:9b0c5fe7e12f3498ff06e3f8385be04f1d9cf0e10e7f84b74db1091ed1871c0a"}, - {file = "chia_rs-0.41.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:698aab770df1ee9674b7b9f73083da482ab199b98a06dfaed55c3fe0b126f96a"}, - {file = "chia_rs-0.41.1-cp312-cp312-win_amd64.whl", hash = "sha256:73f251ed5e330f66566364e791a78dbaa13cb58ebb0ff0d7e3bedb6c07b61618"}, - {file = "chia_rs-0.41.1-cp313-cp313-macosx_13_0_arm64.whl", hash = "sha256:4fb5108f8ead494cd114c613e558dc9d08ff989aa5dfbf7e3cb4b9022acf1758"}, - {file = "chia_rs-0.41.1-cp313-cp313-macosx_13_0_x86_64.whl", hash = "sha256:3a0d5ff6215dd584bfc2df08932f5922806a9be93417f427a6f43c87c62da3e4"}, - {file = "chia_rs-0.41.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:5bcd599f222ae5de97ca50264ae40f86f77053d6bfb0a85b4f0fd056877be73d"}, - {file = "chia_rs-0.41.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e6f292cdd3fd926f72efedaecf9d22b7274074f35b12ad134a5df8794d137a3b"}, - {file = "chia_rs-0.41.1-cp313-cp313-win_amd64.whl", hash = "sha256:3978dd734469f22d6508c03561c8b528e920cf9a5d5d8d179a2de469f0d7fb9e"}, - {file = "chia_rs-0.41.1-cp314-cp314-macosx_13_0_arm64.whl", hash = "sha256:a72991f4fe8ff749861c9367f7d1056da39f31a7969d47945a5a1a146a15baa0"}, - {file = "chia_rs-0.41.1-cp314-cp314-macosx_13_0_x86_64.whl", hash = "sha256:34276f97312add6c741266880fe0d253a34cc3cef4263944f5ead19e2d17f1b0"}, - {file = "chia_rs-0.41.1-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:31de2990709add5d971178ddb87329eb5cab9372b5ac2c604c74b3d27ff13996"}, - {file = "chia_rs-0.41.1-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:8c6ee0b06b1124b3e82a03882d484cd4d193f6b9a37aa1467b728ef627f01ec9"}, - {file = "chia_rs-0.41.1-cp314-cp314-win_amd64.whl", hash = "sha256:614611c1cd0e4561bcd15abc58ca5198ebd056ee5c1c36ab75244d4b2ff0c2c1"}, - {file = "chia_rs-0.41.1.tar.gz", hash = "sha256:a9fab235ed1bcd9f946d7a5d0671bf6318189f5a9af0196b650c9f0ce4a95017"}, + {file = "chia_rs-0.42.0-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:c7fc1700eba78a6fa2f9884b0d3ff8d6311ab1bb50f870907a1f60a7a05c793a"}, + {file = "chia_rs-0.42.0-cp310-cp310-macosx_13_0_x86_64.whl", hash = "sha256:52948d034993afce118a59172bef237bf862faba885d70bcaca0bd534f870cc9"}, + {file = "chia_rs-0.42.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:52b7628db5df487d517f5b837a501a5ee25dd76c8d10edfd880b271daaa5cb8f"}, + {file = "chia_rs-0.42.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:698121e4ee770dd08f7bdb3c58aa28edcd529513d8392d3308104e423e58a944"}, + {file = "chia_rs-0.42.0-cp310-cp310-win_amd64.whl", hash = "sha256:55c96f7b9c117f5ee2c980ac0ea7ed6641ad72b9071bf8acf78ec72d59acc377"}, + {file = "chia_rs-0.42.0-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:fd158c03f12761c7afafd4fde9b9395cc88bbd4f0678cf1e8e21946873ba8dcd"}, + {file = "chia_rs-0.42.0-cp311-cp311-macosx_13_0_x86_64.whl", hash = "sha256:b5549379810191cac011ea613fed6ab8be9e3e89e8d652485861049cbec5c807"}, + {file = "chia_rs-0.42.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:6515435a1fb5638a0f3eaf69df5a61e70babbd2cb51a469c6be800c6ce2d403a"}, + {file = "chia_rs-0.42.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:e9536e3f252807434aaeaf2ba5984d9f82fcb584ebef8f848b04ecd12c13b0f1"}, + {file = "chia_rs-0.42.0-cp311-cp311-win_amd64.whl", hash = "sha256:e5ec25c43cdc1ca1c7d77a4fd3b3f865f3edd3f5231c4d7fa3d1b6209c2ac591"}, + {file = "chia_rs-0.42.0-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:03ddb1232aeb5c0bc6b4b4472c06e4089140630b39a75053d4189818280683e7"}, + {file = "chia_rs-0.42.0-cp312-cp312-macosx_13_0_x86_64.whl", hash = "sha256:229dce5d26c5dd660fa17e9aaec81ebbc080a4919593d4a9b147f929bcaa613d"}, + {file = "chia_rs-0.42.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:42fe55992ad7ba7eaadbd2a61541a2acfaefe70925df9a6ed3ca65808b35ecea"}, + {file = "chia_rs-0.42.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:d2141d24974265ac47def75d3d9917f7265def851bda6ba1d87f0756881bce9a"}, + {file = "chia_rs-0.42.0-cp312-cp312-win_amd64.whl", hash = "sha256:31955cfcf1a4f523f0907f936aac5f52e74c5606027db0aab2cbffbdb03d2f86"}, + {file = "chia_rs-0.42.0-cp313-cp313-macosx_13_0_arm64.whl", hash = "sha256:50f3ee3349995bf94e9415243814007c303300afbc178a1c6e892cedf14ba75c"}, + {file = "chia_rs-0.42.0-cp313-cp313-macosx_13_0_x86_64.whl", hash = "sha256:5a11ff69b69140d3541a413f19769978152f0d0e6804eb5504595f2cd5dc28a5"}, + {file = "chia_rs-0.42.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:10f2183ca4d96a2617dce4770718b7b558d8c088a155ba43740280f4f21fb3c4"}, + {file = "chia_rs-0.42.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:bc9e5383cd384ce824692f54cc1db0aa9c7cd04d3b008d68be6c11a1359d1f9e"}, + {file = "chia_rs-0.42.0-cp313-cp313-win_amd64.whl", hash = "sha256:2a0cdbc119e67326fca0a81a86f519fe8208ca38e3d12b41f9718e3752acf234"}, + {file = "chia_rs-0.42.0-cp314-cp314-macosx_13_0_arm64.whl", hash = "sha256:186311829e6ba974be34beb749020dbc8ee43a03ec022772a6797c7fccce50d1"}, + {file = "chia_rs-0.42.0-cp314-cp314-macosx_13_0_x86_64.whl", hash = "sha256:fc4c42cfff564aad546751894f7e1b78c508b4b9d5868ddc0574443497b597c0"}, + {file = "chia_rs-0.42.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:9f5393378c9a4316d55fe1676a3dea6d96515e27b443701ccf883daeff2fc108"}, + {file = "chia_rs-0.42.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:0c5f862a3eac12b9c527ecff36e539c4603d0dab00a8eebf6c86bbb869fcd9ba"}, + {file = "chia_rs-0.42.0-cp314-cp314-win_amd64.whl", hash = "sha256:fc0cb9790f7e74f6941d36e53501ab3011947d6e7d7e97a4d769efc08cd7772b"}, + {file = "chia_rs-0.42.0.tar.gz", hash = "sha256:90ce4be20acd5715c190f705377426924400ab825b0a568baf03abc49a80d4c7"}, ] [package.dependencies] @@ -4124,4 +4124,4 @@ upnp = ["miniupnpc"] [metadata] lock-version = "2.1" python-versions = ">=3.10, <4" -content-hash = "77b5577370d0b86d10124905ba5ae416504979c7b9d5dbd6103285b72698f9b1" +content-hash = "494723fc688325b4604dc40787ab5b820c61799cecb30ab7e67e97d3dadc0edb" diff --git a/pyproject.toml b/pyproject.toml index 1f1e85a07a..4c0d1dd213 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,7 +53,7 @@ boto3 = ">=1.35.43" # AWS S3 for Data Layer S3 plugin chiabip158 = ">=1.5.2" # bip158-style wallet filters chiapos = ">=2.0.10" # proof of space chia-puzzles-py = ">=0.20.1" -chia_rs = ">=0.41.1, <0.42" +chia_rs = ">=0.42.0, <0.43" chiavdf = ">=1.1.10" # timelord and vdf verification click = ">=8.1.7" # For the CLI clvm = ">=0.9.14"