Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
760a65f
[CHIA-1313] Port NFT RPCs to `@marshal` decorator (#19617)
Quexington Jun 24, 2025
f5fe748
less response failure error consumption (#19282)
altendky Jun 24, 2025
1224006
more memoryview (#19759)
altendky Jun 25, 2025
6e7fcf3
drop universal mypy ignore missing imports (#19750)
altendky Jun 25, 2025
60e4f85
[CHIA-1314] Port pooling RPC endpoints to `@marshal` decorator (#19683)
Quexington Jun 25, 2025
25e240f
log the route when an RPC API server handler fails (#19718)
altendky Jun 25, 2025
565c06f
more more memoryview (#19763)
altendky Jun 26, 2025
257ba70
CHIA-3217 Simplify SpendSim's farm_block (#19760)
AmineKhaldi Jun 26, 2025
5d8b3c8
bump chia_rs to 0.26.0 (#19746)
arvidn Jun 26, 2025
80d3820
Migrate away from `clvm` imports (#19730)
matt-o-how Jun 26, 2025
224fb82
require block generators to use canonical CLVM serialization after 3.…
arvidn Jun 26, 2025
8a87462
compute plot filter on the harvester (#19765)
arvidn Jun 26, 2025
1fa2887
use poetry sync in install scripts (#19762)
altendky Jun 26, 2025
91e4c16
CHIA-3207 Pass coin IDs from Blockchain's _reconsider_peak to CoinSto…
AmineKhaldi Jun 26, 2025
777884f
CHIA-3250 Unify fork peak and reward coins handling between ForkInfo'…
AmineKhaldi Jun 27, 2025
9d8c170
Fix plot size override (#19771)
arvidn Jun 27, 2025
f782fa8
[CHIA-1315] Port (wallet) DataLayer endpoints to `@marshal` (#19689)
Quexington Jun 27, 2025
47d5ce8
nft wallet job timeout reduced to 25 minutes (#19694)
altendky Jun 27, 2025
a125e7b
Create `CoinStoreProtocol` to remove a dependencies on `chia.full_nod…
richardkiss Jun 30, 2025
1d77f5a
build(deps): bump aiohttp from 3.12.2 to 3.12.13 (#19753)
dependabot[bot] Jun 30, 2025
793303c
build(deps): bump diff-cover from 9.3.2 to 9.4.1 (#19756)
dependabot[bot] Jun 30, 2025
0864c34
[CHIA-3205] unify test constants on the ones used by `BlockTools` (#1…
arvidn Jul 2, 2025
3491f1a
Plot v2 quality string (#19769)
arvidn Jul 3, 2025
77bfa9c
build(deps): bump pytest-mock from 3.14.0 to 3.14.1 (#19755)
dependabot[bot] Jul 3, 2025
213fd85
build(deps): bump pytest-cov from 6.1.1 to 6.2.1 (#19754)
dependabot[bot] Jul 3, 2025
af9ee10
build(deps): bump lxml from 5.4.0 to 6.0.0 (#19781)
dependabot[bot] Jul 3, 2025
3d4edb3
build(deps): bump boto3 from 1.38.34 to 1.39.1 (#19779)
dependabot[bot] Jul 3, 2025
9ab42fb
update constant testnet overrides for timelord (#19783)
arvidn Jul 7, 2025
387d807
[CHIA-2639] drop spends we can't serialize rather than the whole requ…
arvidn Jul 7, 2025
13d9d62
[CHIA-1311] Port DID RPCs to `@marshal` decorator (#19708)
Quexington Jul 8, 2025
3eb4707
Replace `CATWallet.create_new_cat_wallet` in `test_cat_wallet.py` (#1…
Quexington Jul 8, 2025
37d0a3c
update testnet overrides in wallet (#19796)
arvidn Jul 10, 2025
5c6c75c
CHIA-2638 Full Node RPC Validation Tool (#19743)
jack60612 Jul 10, 2025
c609d0b
CHIA-2900 Fast forward mempool optimization (#19713)
AmineKhaldi Jul 10, 2025
33a74cd
build(deps): bump pytest-xdist from 3.7.0 to 3.8.0 (#19777)
dependabot[bot] Jul 10, 2025
64702fe
build(deps): bump coverage from 7.9.1 to 7.9.2 (#19789)
dependabot[bot] Jul 10, 2025
1fba37e
build(deps): bump pytest from 8.3.5 to 8.4.1 (#19751)
dependabot[bot] Jul 10, 2025
b9710b1
Add RCATs to wallet (#19795)
Quexington Jul 10, 2025
dac837e
bump chia_rs (#19802)
arvidn Jul 10, 2025
fb8de7a
Merge commit 'dac837e79961fa5ce9611d5531d789211031c465' into catchup/…
altendky Jul 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ foreach ($extra in $extras)
./Setup-poetry.ps1 -pythonVersion "$pythonVersion"

.penv/Scripts/poetry env use $(py -"$pythonVersion" -c 'import sys; print(sys.executable)')
.penv/Scripts/poetry install @extras_cli
.penv/Scripts/poetry sync @extras_cli

if ($i)
{
Expand Down
11 changes: 6 additions & 5 deletions benchmarks/coin_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,14 @@ def make_coin() -> Coin:
return Coin(rand_hash(), rand_hash(), uint64(1))


def make_coins(num: int) -> tuple[list[Coin], list[bytes32]]:
additions: list[Coin] = []
def make_coins(num: int) -> tuple[list[tuple[bytes32, Coin, bool]], list[bytes32]]:
additions: list[tuple[bytes32, Coin, bool]] = []
hashes: list[bytes32] = []
for i in range(num):
c = make_coin()
additions.append(c)
hashes.append(c.name())
coin_id = c.name()
additions.append((coin_id, c, False))
hashes.append(coin_id)

return additions, hashes

Expand Down Expand Up @@ -145,7 +146,7 @@ async def run_new_block_benchmark(version: int) -> None:
# add one new coins
c = make_coin()
coin_id = c.name()
additions.append(c)
additions.append((coin_id, c, False))
total_add += 1

farmer_coin, pool_coin = rewards(uint32(height))
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/mempool-long-lived.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from chia_rs import CoinSpend, G2Element, SpendBundle
from chia_rs.sized_bytes import bytes32
from chia_rs.sized_ints import uint32, uint64
from clvm.casts import int_to_bytes

from chia.consensus.default_constants import DEFAULT_CONSTANTS
from chia.full_node.mempool_manager import MempoolManager
Expand All @@ -18,6 +17,7 @@
from chia.types.coin_record import CoinRecord
from chia.types.condition_opcodes import ConditionOpcode
from chia.types.mempool_item import UnspentLineageInfo
from chia.util.casts import int_to_bytes

# this is one week worth of blocks
NUM_ITERS = 32256
Expand Down
217 changes: 214 additions & 3 deletions chia/_tests/blockchain/test_blockchain.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
from __future__ import annotations

import asyncio
import copy
import logging
import random
import time
from collections.abc import AsyncIterator, Awaitable
from contextlib import asynccontextmanager
from dataclasses import replace
from dataclasses import dataclass, replace
from typing import Optional

import pytest
Expand All @@ -20,12 +21,14 @@
InfusedChallengeChainSubSlot,
MerkleSet,
SpendBundle,
SpendBundleConditions,
SpendConditions,
TransactionsInfo,
UnfinishedBlock,
is_canonical_serialization,
)
from chia_rs.sized_bytes import bytes32
from chia_rs.sized_ints import uint8, uint32, uint64
from clvm.casts import int_to_bytes

from chia._tests.blockchain.blockchain_test_utils import (
_validate_and_add_block,
Expand All @@ -38,7 +41,7 @@
from chia._tests.util.blockchain import create_blockchain
from chia._tests.util.get_name_puzzle_conditions import get_name_puzzle_conditions
from chia.consensus.augmented_chain import AugmentedBlockchain
from chia.consensus.block_body_validation import ForkInfo
from chia.consensus.block_body_validation import ForkAdd, ForkInfo
from chia.consensus.block_header_validation import validate_finished_header_block
from chia.consensus.block_rewards import calculate_base_farmer_reward
from chia.consensus.blockchain import AddBlockResult, Blockchain
Expand All @@ -61,6 +64,7 @@
from chia.types.condition_with_args import ConditionWithArgs
from chia.types.generator_types import BlockGenerator
from chia.types.validation_state import ValidationState
from chia.util.casts import int_to_bytes
from chia.util.errors import Err
from chia.util.hash import std_hash
from chia.util.keychain import Keychain
Expand Down Expand Up @@ -3648,6 +3652,41 @@ async def test_get_blocks_at(self, empty_blockchain: Blockchain, default_1000_bl
assert len(blocks) == 200
assert blocks[-1].height == 199

@pytest.mark.anyio
async def test_overlong_generator_encoding(
self, empty_blockchain: Blockchain, bt: BlockTools, consensus_mode: ConsensusMode
) -> None:
# add enough blocks to pass the hard fork
blocks = bt.get_consecutive_blocks(10)
for b in blocks[:-1]:
await _validate_and_add_block(empty_blockchain, b)

while not blocks[-1].is_transaction_block():
await _validate_and_add_block(empty_blockchain, blocks[-1])
blocks = bt.get_consecutive_blocks(1, block_list_input=blocks)
original_block: FullBlock = blocks[-1]

# overlong encoding
generator = SerializedProgram.fromhex("c00101")
assert not is_canonical_serialization(bytes(generator))

block = recursive_replace(original_block, "transactions_generator", generator)
block = recursive_replace(block, "transactions_info.generator_root", std_hash(bytes(generator)))
block = recursive_replace(
block, "foliage_transaction_block.transactions_info_hash", std_hash(bytes(block.transactions_info))
)
block = recursive_replace(
block, "foliage.foliage_transaction_block_hash", std_hash(bytes(block.foliage_transaction_block))
)

# overlong encoding became invalid in the 3.0 hard fork
if consensus_mode == ConsensusMode.HARD_FORK_3_0:
expected_error = Err.INVALID_TRANSACTIONS_GENERATOR_ENCODING
else:
expected_error = None

await _validate_and_add_block(empty_blockchain, block, expected_error=expected_error, skip_prevalidation=True)


@pytest.mark.anyio
async def test_reorg_new_ref(empty_blockchain: Blockchain, bt: BlockTools) -> None:
Expand Down Expand Up @@ -4199,3 +4238,175 @@ async def test_get_header_blocks_in_range_tx_filter_non_tx_block(empty_blockchai
blocks_with_filter = await b.get_header_blocks_in_range(0, 42, tx_filter=True)
empty_tx_filter = b"\x00"
assert blocks_with_filter[non_tx_block.header_hash].transactions_filter == empty_tx_filter


@dataclass(frozen=True)
class ForkInfoTestSetup:
fork_info: ForkInfo
initial_additions_since_fork: dict[bytes32, ForkAdd]
test_block: FullBlock
coin: Coin
child_coin: Coin

@classmethod
def create(cls, same_ph_as_parent: bool, same_amount_as_parent: bool) -> ForkInfoTestSetup:
from chia._tests.util.network_protocol_data import full_block as test_block

unrelated_coin = Coin(bytes32([0] * 32), bytes32([1] * 32), uint64(42))
# We add this initial state with an unrelated addition, to create a
# difference between the `rollback` state and the completely empty
# `reset` state.
initial_additions_since_fork = {
unrelated_coin.name(): ForkAdd(
coin=unrelated_coin,
confirmed_height=uint32(1),
timestamp=uint64(0),
hint=None,
is_coinbase=False,
same_as_parent=False,
)
}
fork_info = ForkInfo(
test_block.height - 1,
test_block.height - 1,
test_block.prev_header_hash,
additions_since_fork=copy.copy(initial_additions_since_fork),
)
puzzle_hash = bytes32([2] * 32)
amount = uint64(1337)
coin = Coin(bytes32([3] * 32), puzzle_hash, amount)
child_coin_ph = puzzle_hash if same_ph_as_parent else bytes32([4] * 32)
child_coin_amount = amount if same_amount_as_parent else uint64(0)
child_coin = Coin(coin.name(), child_coin_ph, child_coin_amount)
return cls(
fork_info=fork_info,
initial_additions_since_fork=initial_additions_since_fork,
test_block=test_block,
coin=coin,
child_coin=child_coin,
)

def check_additions(self, expected_same_parent_additions: set[bytes32]) -> None:
assert all(
a in self.fork_info.additions_since_fork and self.fork_info.additions_since_fork[a].same_as_parent
for a in expected_same_parent_additions
)
remaining_additions = set(self.fork_info.additions_since_fork) - expected_same_parent_additions
assert not any(self.fork_info.additions_since_fork[a].same_as_parent for a in remaining_additions)


@pytest.mark.parametrize("same_ph_as_parent", [True, False])
@pytest.mark.parametrize("same_amount_as_parent", [True, False])
@pytest.mark.parametrize("rollback", [True, False])
@pytest.mark.parametrize("reset", [True, False])
@pytest.mark.anyio
async def test_include_spends_same_as_parent(
same_ph_as_parent: bool, same_amount_as_parent: bool, rollback: bool, reset: bool
) -> None:
"""
Tests that `ForkInfo` properly tracks same-as-parent created coins.
A created coin is tracked as such if its puzzle hash and amount match the
parent. We're covering here `include_spends`, `rollback` and `reset` in the
context of same-as-parent coins.
"""
test_setup = ForkInfoTestSetup.create(same_ph_as_parent, same_amount_as_parent)
# Now let's prepare the test spend bundle conditions
create_coin = [(test_setup.child_coin.puzzle_hash, test_setup.child_coin.amount, None)]
conds = SpendBundleConditions(
[
SpendConditions(
test_setup.coin.name(),
test_setup.coin.parent_coin_info,
test_setup.coin.puzzle_hash,
test_setup.coin.amount,
None,
None,
None,
None,
None,
None,
create_coin,
[],
[],
[],
[],
[],
[],
[],
0,
0,
0,
)
],
0,
0,
0,
None,
None,
[],
0,
0,
0,
True,
0,
0,
)
# Now let's run the test
test_setup.fork_info.include_spends(conds, test_setup.test_block, test_setup.test_block.header_hash)
# Let's make sure the results are as expected
expected_same_parent_additions = (
{test_setup.child_coin.name()} if same_ph_as_parent and same_amount_as_parent else set()
)
test_setup.check_additions(expected_same_parent_additions)
if rollback:
# Now we rollback before the spend that belongs to the test conditions
test_setup.fork_info.rollback(test_setup.test_block.prev_header_hash, test_setup.test_block.height - 1)
# That should leave only the initial additions we started with, which
# are unrelated to the test conditions. We added this initial state to
# create a difference between `rollback` state and the completely empty
# `reset` state.
assert test_setup.fork_info.additions_since_fork == test_setup.initial_additions_since_fork
if reset:
# Now we reset to a test height and header hash
test_setup.fork_info.reset(1, bytes32([0] * 32))
# That should leave this empty
assert test_setup.fork_info.additions_since_fork == {}


@pytest.mark.parametrize("same_ph_as_parent", [True, False])
@pytest.mark.parametrize("same_amount_as_parent", [True, False])
@pytest.mark.parametrize("rollback", [True, False])
@pytest.mark.parametrize("reset", [True, False])
@pytest.mark.anyio
async def test_include_block_same_as_parent_coins(
same_ph_as_parent: bool, same_amount_as_parent: bool, rollback: bool, reset: bool
) -> None:
"""
Tests that `ForkInfo` properly tracks same-as-parent created coins.
A created coin is tracked as such if its puzzle hash and amount match the
parent. We're covering here `include_block`, `rollback` and `reset` in the
context of such coins.
"""
test_setup = ForkInfoTestSetup.create(same_ph_as_parent, same_amount_as_parent)
# Now let's run the test
test_setup.fork_info.include_block(
[(test_setup.child_coin, None)],
[(test_setup.coin.name(), test_setup.coin)],
test_setup.test_block,
test_setup.test_block.header_hash,
)
# Let's make sure the results are as expected
expected_same_as_parent_additions = (
{test_setup.child_coin.name()} if same_ph_as_parent and same_amount_as_parent else set()
)
test_setup.check_additions(expected_same_as_parent_additions)
if rollback:
# Now we rollback before the spend that belongs to the test conditions
test_setup.fork_info.rollback(test_setup.test_block.prev_header_hash, test_setup.test_block.height - 1)
# That should leave only the initial additions we started with
assert test_setup.fork_info.additions_since_fork == test_setup.initial_additions_since_fork
if reset:
# Now we reset to a test height and header hash
test_setup.fork_info.reset(1, bytes32([0] * 32))
# That should leave this empty
assert test_setup.fork_info.additions_since_fork == {}
2 changes: 1 addition & 1 deletion chia/_tests/blockchain/test_blockchain_transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from chia_rs import SpendBundle
from chia_rs.sized_bytes import bytes32
from chia_rs.sized_ints import uint32, uint64
from clvm.casts import int_to_bytes

from chia._tests.blockchain.blockchain_test_utils import _validate_and_add_block
from chia._tests.util.generator_tools_testing import run_and_get_removals_and_additions
Expand All @@ -19,6 +18,7 @@
from chia.simulator.wallet_tools import WalletTool
from chia.types.condition_opcodes import ConditionOpcode
from chia.types.condition_with_args import ConditionWithArgs
from chia.util.casts import int_to_bytes
from chia.util.errors import Err
from chia.wallet.conditions import AssertCoinAnnouncement, AssertPuzzleAnnouncement
from chia.wallet.estimate_fees import estimate_fees
Expand Down
2 changes: 1 addition & 1 deletion chia/_tests/blockchain/test_build_chains.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def validate_coins(constants: ConsensusConstants, blocks: list[FullBlock]) -> No
constants,
)

for rem in removals:
for _, rem in removals:
try:
unspent_coins.remove(rem)
except KeyError: # pragma: no cover
Expand Down
2 changes: 1 addition & 1 deletion chia/_tests/blockchain/test_get_block_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
import pytest
from chia_rs.sized_bytes import bytes32
from chia_rs.sized_ints import uint32
from clvm.casts import int_to_bytes

from chia.consensus.get_block_generator import get_block_generator
from chia.types.blockchain_format.serialized_program import SerializedProgram
from chia.types.generator_types import BlockGenerator
from chia.util.casts import int_to_bytes


@dataclass(frozen=True)
Expand Down
Loading
Loading