Chia Blockchain

repository·main·Indexed 27 days ago

https://github.com/chia-network/chia-blockchain

The core implementation of the Chia Network, a cryptocurrency utilizing Proof of Space and Time. This repository provides the infrastructure for full nodes, farmers, timelords, and wallets. It includes the `chia` CLI for managing blockchain infrastructure, a WebSocket-based RPC interface for daemon communication via the `DaemonProxy` class, and implementations for CHIP-43 custody-based wallet puzzles.

Tokens
13.7K
Snippets
17
Records
91
Agent score
95%

What's inside chia-blockchain

  1. Understand the Chia Blockchain Legacy Software and OS Support Policy

    main

    Chia Blockchain ends software support when the original maintainer of a dependency (such as Python, Node.js, or an operating system) declares it End of Life (EOL) or ceases providing support.

    To prevent breaking critical operating system components, Chia will also end support for specific operating system versions if those versions rely on a default Python version that has reached EOL. This ensures that users do not encounter issues when attempting to install new Python versions via the Chia installation process.

  2. Handle expensive construction using `@classmethods`

    main

    Keep __init__ trivial by avoiding expensive operations (like disk I/O, network calls, or complex parsing) during instantiation. Instead, use @classmethod to provide alternative constructors for non-trivial creation logic. This keeps the primary constructor fast and predictable.

    import json
    from dataclasses import dataclass
    from typing import TypeVar, Type
    
    _T_Coin = TypeVar("_T_Coin", bound="Coin")
    
    @dataclass(frozen=True)
    class Coin:
        hash: bytes
        value: int
    
        @classmethod
        def from_json(cls: Type[_T_Coin], text: str) -> _T_Coin:
            decoded = json.loads(text)
            return cls(
                hash=bytes.fromhex(decoded["hash"]),
                value=decoded["value"],
            )
  3. Write tests using pytest

    main

    When contributing tests to the repository, follow these patterns:

    • Do not import test_* modules. Instead, locate shared tooling in non-test files within the tests/ directory or its subdirectories.
    • Do not import fixtures. Use conftest.py files at the appropriate directory layer to make fixtures recursively available.
    • Do not use test classes. The project is fully dependent on pytest, so avoid unittest compatibility to maintain consistency.
  4. Use `Union` for multiple possible types

    main

    Use Union[TypeA, TypeB] when a function or variable can accept or return multiple distinct types that do not share a common inheritance hierarchy.

    from os import PathLike
    from pathlib import Path
    from typing import Union
    
    
    def read_file(path: Union[str, PathLike]) -> str:
        return Path(path).read_text(encoding="utf-8")
  5. Handle Async tasks and cancellation

    main

    When working with asynchronous code:

    • Do not catch asyncio.CancelledError unless you are at a high-level boundary (like an RPC framework) and explicitly re-raise it.
    • Store references to all spawned tasks to ensure they can be cleaned up properly.
    • Consider shielding cancellation during shutdown cleanup code.
  6. Best practices for Python type hinting

    main

    To ensure rigorous static analysis with mypy, follow these type hinting guidelines:

    • Avoid Any: Do not use Any as it defeats type checking. If the type is unknown or irrelevant, use object instead.
    • Explicit None returns: If a function does not have a return statement or uses a bare return, explicitly hint the return type as -> None:.
    • Prefer object over Any: When you don't care about the specific type, object is safer than Any because it still requires type checks before performing operations.
    • Use from __future__ import annotations: This is the recommended way to handle forward references (referencing a class within its own definition) without using string literals like -> "C".
  7. Prerequisites for Chia Blockchain

    main

    To run Chia blockchain components, you must have Python 3.10 or higher installed. You can verify your default Python version by running:

    python3 --version

    Network Configuration (NAT/Firewall)

    If you are operating behind a NAT, peers outside your subnet may have difficulty reaching you. To resolve this:

    • Enable UPnP on your router.
    • Or, add a NAT/firewall rule to allow incoming traffic on TCP port 8444 (IPv4 only).
    python3
  8. Relate types using `TypeVar`

    main

    Use TypeVar to indicate a relationship between multiple elements, such as ensuring a function returns the same type it received as an input.

    from typing import TypeVar
    
    
    T = TypeVar("T")
    
    
    def double(original: T) -> T:
        return 2 * original
    
    
    an_int = double(original=2)
    a_list = double(original=["a", "b"])
  9. Define data-centric classes using `dataclasses`

    main

    Use the dataclasses module to define classes. This promotes consistency, provides clear type hints, and ensures that all attributes are present from the moment of instantiation. For classes that should not be modified after creation, use @dataclass(frozen=True) to enforce immutability.

    from dataclasses import dataclass
    
    @dataclass(frozen=True)
    class Developer:
        name: str
        words_per_minute: float
        primary_language: str
  10. Implement Generics with `Generic`

    main

    Use Generic to create container classes (like caches or wrappers) where the types of the contents are defined at instantiation time.

    from dataclasses import dataclass, field
    from typing import Generic, Optional, TypeVar, Dict
    
    KT = TypeVar("KT")
    VT = TypeVar("VT")
    
    
    @dataclass
    class Cache(Generic[KT, VT]):
        _mapping: Dict[KT, VT] = field(default_factory=dict)
    
        def get(self, key: KT, default: Optional[VT] = None) -> Optional[VT]:
            ...
    
        def set(self, key: KT, value: VT) -> None:
            ...
    
    
    c = Cache[int, str]()
    
    # error: Argument 1 to "get" of "Cache" has incompatible type "str"; expected "int"
    c.get("abc")