Skip to content

Commit

Permalink
[CHIA-1976] bump chia_rs to 0.16.0 and introduce soft-fork6 (#18988)
Browse files Browse the repository at this point in the history
* bump chia_rs to 0.16.0 and introduce soft-fork6

* add test for keccak256 operator
  • Loading branch information
arvidn authored Dec 5, 2024
1 parent c59eeec commit f9b7ddc
Show file tree
Hide file tree
Showing 16 changed files with 141 additions and 57 deletions.
10 changes: 5 additions & 5 deletions chia/_tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,12 +197,12 @@ def get_keychain():
class ConsensusMode(ComparableEnum):
PLAIN = 0
HARD_FORK_2_0 = 1
SOFT_FORK_5 = 2
SOFT_FORK_6 = 2


@pytest.fixture(
scope="session",
params=[ConsensusMode.PLAIN, ConsensusMode.HARD_FORK_2_0, ConsensusMode.SOFT_FORK_5],
params=[ConsensusMode.PLAIN, ConsensusMode.HARD_FORK_2_0, ConsensusMode.SOFT_FORK_6],
)
def consensus_mode(request):
return request.param
Expand All @@ -218,9 +218,9 @@ def blockchain_constants(consensus_mode: ConsensusMode) -> ConsensusConstants:
PLOT_FILTER_64_HEIGHT=uint32(15),
PLOT_FILTER_32_HEIGHT=uint32(20),
)
if consensus_mode >= ConsensusMode.SOFT_FORK_5:
if consensus_mode >= ConsensusMode.SOFT_FORK_6:
ret = ret.replace(
SOFT_FORK5_HEIGHT=uint32(2),
SOFT_FORK6_HEIGHT=uint32(2),
)
return ret

Expand Down Expand Up @@ -269,7 +269,7 @@ def db_version(request) -> int:
return request.param


SOFTFORK_HEIGHTS = [1000000, 5496000, 5496100, 5716000, 5940000]
SOFTFORK_HEIGHTS = [1000000, 5496000, 5496100, 5716000, 6800000]


@pytest.fixture(scope="function", params=SOFTFORK_HEIGHTS)
Expand Down
2 changes: 1 addition & 1 deletion chia/_tests/core/full_node/test_generator_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@


def test_tx_removals_and_additions() -> None:
conditions = SpendBundleConditions(spends, uint64(0), uint32(0), uint64(0), None, None, [], uint64(0), 0, 0)
conditions = SpendBundleConditions(spends, uint64(0), uint32(0), uint64(0), None, None, [], uint64(0), 0, 0, False)
expected_rems = [coin_ids[0], coin_ids[1]]
expected_additions = []
for spend in spends:
Expand Down
82 changes: 80 additions & 2 deletions chia/_tests/core/mempool/test_mempool.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
from typing import Callable, Dict, List, Optional, Tuple

import pytest
from chia_rs import G1Element, G2Element
from chia_rs import G1Element, G2Element, get_flags_for_height_and_constants
from clvm.casts import int_to_bytes
from clvm_tools import binutils
from clvm_tools.binutils import assemble

from chia._tests.blockchain.blockchain_test_utils import _validate_and_add_block
from chia._tests.connection_utils import add_dummy_connection, connect_and_get_peer
Expand All @@ -27,6 +28,7 @@
from chia._tests.util.time_out_assert import time_out_assert
from chia.consensus.condition_costs import ConditionCost
from chia.consensus.cost_calculator import NPCResult
from chia.consensus.default_constants import DEFAULT_CONSTANTS
from chia.full_node.bitcoin_fee_estimator import create_bitcoin_fee_estimator
from chia.full_node.fee_estimation import EmptyMempoolInfo, MempoolInfo
from chia.full_node.full_node_api import FullNodeAPI
Expand Down Expand Up @@ -107,7 +109,7 @@ def make_item(
return MempoolItem(
SpendBundle([], G2Element()),
fee,
SpendBundleConditions([], 0, 0, 0, None, None, [], cost, 0, 0),
SpendBundleConditions([], 0, 0, 0, None, None, [], cost, 0, 0, False),
spend_bundle_name,
uint32(0),
assert_height,
Expand Down Expand Up @@ -3178,3 +3180,79 @@ def test_get_puzzle_and_solution_for_coin_failure() -> None:
ValueError, match=f"Failed to get puzzle and solution for coin {TEST_COIN}, error: \\('coin not found', '80'\\)"
):
get_puzzle_and_solution_for_coin(BlockGenerator(SerializedProgram.to(None), []), TEST_COIN, 0, test_constants)


# TODO: import this from chia_rs once we bump the version we depend on
ENABLE_KECCAK = 0x200
ENABLE_KECCAK_OPS_OUTSIDE_GUARD = 0x100


def test_flags_for_height() -> None:

# the keccak operator is supposed to be enabled at soft-fork 6 height
flags = get_flags_for_height_and_constants(DEFAULT_CONSTANTS.SOFT_FORK6_HEIGHT, DEFAULT_CONSTANTS)
print(f"{flags:x}")
assert (flags & ENABLE_KECCAK) != 0

flags = get_flags_for_height_and_constants(DEFAULT_CONSTANTS.SOFT_FORK6_HEIGHT - 1, DEFAULT_CONSTANTS)
print(f"{flags:x}")
assert (flags & ENABLE_KECCAK) == 0


def test_keccak() -> None:

# the keccak operator is 62. The assemble() function doesn't support it
# (yet)

# keccak256 is available when the softfork has activated
keccak_prg = Program.to(
assemble(
"(softfork (q . 1134) (q . 1) (q a (i "
"(= "
'(62 (q . "foobar"))'
"(q . 0x38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e))"
"(q . 0) (q x)) (q . ())) (q . ()))"
)
)

cost, ret = keccak_prg.run_with_flags(1215, ENABLE_KECCAK, [])
assert cost == 1215
assert ret.atom == b""

# keccak is ignored when the softfork has not activated
cost, ret = keccak_prg.run_with_flags(1215, 0, [])
assert cost == 1215
assert ret.atom == b""

# make sure keccak is actually executed, by comparing with the wrong output
keccak_prg = Program.to(
assemble(
"(softfork (q . 1134) (q . 1) (q a (i "
'(= (62 (q . "foobar")) '
"(q . 0x58d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e))"
"(q . 0) (q x)) (q . ())) (q . ()))"
)
)
with pytest.raises(ValueError, match="clvm raise"):
keccak_prg.run_with_flags(1215, ENABLE_KECCAK, [])

# keccak is ignored when the softfork has not activated
cost, ret = keccak_prg.run_with_flags(1215, 0, [])
assert cost == 1215
assert ret.atom == b""

# === HARD FORK ===
# new operators *outside* the softfork guard
# keccak256 is available outside the guard with the appropriate flag
keccak_prg = Program.to(
assemble(
"(a (i (= "
'(62 (q . "foobar")) '
"(q . 0x38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e)) "
"(q . 0) (q x)) (q . ()))"
)
)

cost, ret = keccak_prg.run_with_flags(994, ENABLE_KECCAK | ENABLE_KECCAK_OPS_OUTSIDE_GUARD, [])
assert cost == 994
assert ret.atom == b""
1 change: 1 addition & 0 deletions chia/_tests/core/mempool/test_mempool_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ def make_test_conds(
cost,
0,
0,
False,
)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def make_mempoolitem() -> MempoolItem:

fee = uint64(10000000)
spends: List[SpendConditions] = []
conds = SpendBundleConditions(spends, 0, 0, 0, None, None, [], cost, 0, 0)
conds = SpendBundleConditions(spends, 0, 0, 0, None, None, [], cost, 0, 0, False)
mempool_item = MempoolItem(
spend_bundle,
fee,
Expand Down
4 changes: 2 additions & 2 deletions chia/_tests/util/test_condition_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def mk_agg_sig_conditions(
agg_sig_puzzle_amount=agg_sig_data if opcode == ConditionOpcode.AGG_SIG_PUZZLE_AMOUNT else [],
flags=0,
)
return SpendBundleConditions([spend], 0, 0, 0, None, None, agg_sig_unsafe_data, 0, 0, 0)
return SpendBundleConditions([spend], 0, 0, 0, None, None, agg_sig_unsafe_data, 0, 0, 0, False)


@pytest.mark.parametrize(
Expand Down Expand Up @@ -100,7 +100,7 @@ def test_pkm_pairs_vs_for_conditions_dict(opcode: ConditionOpcode) -> None:

class TestPkmPairs:
def test_empty_list(self) -> None:
conds = SpendBundleConditions([], 0, 0, 0, None, None, [], 0, 0, 0)
conds = SpendBundleConditions([], 0, 0, 0, None, None, [], 0, 0, 0, False)
pks, msgs = pkm_pairs(conds, b"foobar")
assert pks == []
assert msgs == []
Expand Down
2 changes: 1 addition & 1 deletion chia/_tests/util/test_replace_str_to_bytes.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
MAX_GENERATOR_SIZE=uint32(1000000),
MAX_GENERATOR_REF_LIST_SIZE=uint32(512),
POOL_SUB_SLOT_ITERS=uint64(37600000000),
SOFT_FORK5_HEIGHT=uint32(5940000),
SOFT_FORK6_HEIGHT=uint32(6800000),
HARD_FORK_HEIGHT=uint32(5496000),
PLOT_FILTER_128_HEIGHT=uint32(10542000),
PLOT_FILTER_64_HEIGHT=uint32(15592000),
Expand Down
2 changes: 1 addition & 1 deletion chia/_tests/util/test_testnet_overrides.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def test_testnet11() -> None:
overrides: Dict[str, Any] = {}
update_testnet_overrides("testnet11", overrides)
assert overrides == {
"SOFT_FORK5_HEIGHT": 1340000,
"SOFT_FORK6_HEIGHT": 2000000,
}


Expand Down
6 changes: 3 additions & 3 deletions chia/cmds/sim_funcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,10 @@ def create_chia_directory(
# get fork heights then write back to config
if "HARD_FORK_HEIGHT" not in sim_config: # this meh code is done so that we also write to the config file.
sim_config["HARD_FORK_HEIGHT"] = 0
if "SOFT_FORK5_HEIGHT" not in sim_config:
sim_config["SOFT_FORK5_HEIGHT"] = 0
if "SOFT_FORK6_HEIGHT" not in sim_config:
sim_config["SOFT_FORK6_HEIGHT"] = 0
simulator_consts["HARD_FORK_HEIGHT"] = sim_config["HARD_FORK_HEIGHT"]
simulator_consts["SOFT_FORK5_HEIGHT"] = sim_config["SOFT_FORK5_HEIGHT"]
simulator_consts["SOFT_FORK6_HEIGHT"] = sim_config["SOFT_FORK6_HEIGHT"]

# save config and return the config
save_config(chia_root, "config.yaml", config)
Expand Down
6 changes: 3 additions & 3 deletions chia/consensus/default_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
MAX_GENERATOR_SIZE=uint32(1000000),
MAX_GENERATOR_REF_LIST_SIZE=uint32(512), # Number of references allowed in the block generator ref list
POOL_SUB_SLOT_ITERS=uint64(37600000000), # iters limit * NUM_SPS
SOFT_FORK5_HEIGHT=uint32(5940000),
SOFT_FORK6_HEIGHT=uint32(6800000),
# June 2024
HARD_FORK_HEIGHT=uint32(5496000),
# June 2027
Expand All @@ -86,5 +86,5 @@

def update_testnet_overrides(network_id: str, overrides: Dict[str, Any]) -> None:
if network_id == "testnet11":
if "SOFT_FORK5_HEIGHT" not in overrides:
overrides["SOFT_FORK5_HEIGHT"] = 1340000
if "SOFT_FORK6_HEIGHT" not in overrides:
overrides["SOFT_FORK6_HEIGHT"] = 2000000
6 changes: 3 additions & 3 deletions chia/full_node/mempool_check_conditions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import logging
from typing import Dict, List, Optional

from chia_rs import MEMPOOL_MODE, get_flags_for_height_and_constants
from chia_rs import DONT_VALIDATE_SIGNATURE, MEMPOOL_MODE, G2Element, get_flags_for_height_and_constants
from chia_rs import get_puzzle_and_solution_for_coin2 as get_puzzle_and_solution_for_coin_rust
from chia_rs import run_block_generator, run_block_generator2, run_chia_program

Expand Down Expand Up @@ -36,7 +36,7 @@ def get_name_puzzle_conditions(
height: uint32,
constants: ConsensusConstants,
) -> NPCResult:
flags = get_flags_for_height_and_constants(height, constants)
flags = get_flags_for_height_and_constants(height, constants) | DONT_VALIDATE_SIGNATURE

if mempool_mode:
flags = flags | MEMPOOL_MODE
Expand All @@ -48,7 +48,7 @@ def get_name_puzzle_conditions(

try:
block_args = generator.generator_refs
err, result = run_block(bytes(generator.program), block_args, max_cost, flags, constants)
err, result = run_block(bytes(generator.program), block_args, max_cost, flags, G2Element(), None, constants)
assert (err is None) != (result is None)
if err is not None:
return NPCResult(uint16(err), None)
Expand Down
2 changes: 1 addition & 1 deletion chia/rpc/wallet_rpc_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -1574,7 +1574,7 @@ async def get_spendable_coins(self, request: Dict[str, Any]) -> EndpointResult:
excluded_coin_amounts = []
excluded_coins_input: Optional[Dict[str, Dict[str, Any]]] = request.get("excluded_coins")
if excluded_coins_input is not None:
excluded_coins = [Coin.from_json_dict(json_coin) for json_coin in excluded_coins_input]
excluded_coins = [Coin.from_json_dict(json_coin) for json_coin in excluded_coins_input.values()]
else:
excluded_coins = []
excluded_coin_ids_input: Optional[List[str]] = request.get("excluded_coin_ids")
Expand Down
4 changes: 2 additions & 2 deletions chia/util/initial-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ network_overrides: &network_overrides
SUB_SLOT_ITERS_STARTING: 67108864
# Forks activated from the beginning on this network
HARD_FORK_HEIGHT: 0
SOFT_FORK5_HEIGHT: 1340000
SOFT_FORK6_HEIGHT: 2000000
PLOT_FILTER_128_HEIGHT: 6029568
PLOT_FILTER_64_HEIGHT: 11075328
PLOT_FILTER_32_HEIGHT: 16121088
Expand Down Expand Up @@ -672,4 +672,4 @@ simulator:

# Fork Settings
HARD_FORK_HEIGHT: 0
SOFT_FORK5_HEIGHT: 0
SOFT_FORK6_HEIGHT: 0
53 changes: 24 additions & 29 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ bitstring = "4.1.4" # Binary data management library
boto3 = "1.34.143" # AWS S3 for Data Layer S3 plugin
chiabip158 = "1.5.1" # bip158-style wallet filters
chiapos = "2.0.4" # proof of space
chia_rs = "0.14.0"
chia_rs = "0.16.0"
chiavdf = "1.1.6" # timelord and vdf verification
click = "8.1.7" # For the CLI
clvm = "0.9.10"
Expand Down
14 changes: 12 additions & 2 deletions tools/analyze-chain.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,15 @@

import click
import zstd
from chia_rs import MEMPOOL_MODE, AugSchemeMPL, G1Element, SpendBundleConditions, run_block_generator
from chia_rs import (
DONT_VALIDATE_SIGNATURE,
MEMPOOL_MODE,
AugSchemeMPL,
G1Element,
G2Element,
SpendBundleConditions,
run_block_generator,
)

from chia.consensus.default_constants import DEFAULT_CONSTANTS
from chia.types.block_protocol import BlockInfo
Expand All @@ -34,7 +42,9 @@ def run_gen(
bytes(generator_program),
block_program_args,
DEFAULT_CONSTANTS.MAX_BLOCK_COST_CLVM,
flags,
flags | DONT_VALIDATE_SIGNATURE,
G2Element(),
None,
DEFAULT_CONSTANTS,
)
run_time = time() - start_time
Expand Down

0 comments on commit f9b7ddc

Please sign in to comment.