mirror of
https://github.com/Chia-Network/chia-blockchain.git
synced 2024-11-24 08:04:35 +03:00
Add .clvm.hex pre-commit check (#12050)
* Add .clvm.hex pre-commit check
* report all results
* stuff
* maybe pass
* add todo
* explicitly define suffixes
* check for (and remove) extra hex and hash files
* remove garbage failure hex and hash files
* provide runner scripts
* matrix pre-commit checks
* maybe now
* more cross platform
* move it
* oops
* shell:
* maybe
* more configurable
* explicitly specify powershell
* tidy
* remove other stuff
* tidy
* remove existing pytest clvm hex etc checker
* add a trailing newline to decompress_block_spends.clvm.hex.sha256tree
* Update activated.ps1
* git config --global core.autocrlf false
* Update pre-commit.yml
* only check `chia/`
* typing_extensions
* typing_extensions
* removing unused typing import
* move top_level out of the rglob
* catchup dl clvm hex files
* Revert "catchup dl clvm hex files"
This reverts commit cd3d4f70b8
.
* now
This commit is contained in:
parent
e588566045
commit
789ee4f415
4
.github/workflows/pre-commit.yml
vendored
4
.github/workflows/pre-commit.yml
vendored
@ -54,6 +54,10 @@ jobs:
|
||||
|
||||
- uses: Chia-Network/actions/git-mark-workspace-safe@main
|
||||
|
||||
- name: disable git autocrlf
|
||||
run: |
|
||||
git config --global core.autocrlf false
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: Chia-Network/actions/setup-python@main
|
||||
|
@ -29,6 +29,13 @@ repos:
|
||||
- id: check-merge-conflict
|
||||
- id: check-ast
|
||||
- id: debug-statements
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: clvm_hex
|
||||
name: .clvm.hex files
|
||||
entry: ./activated.py python tests/check_clvm.py
|
||||
language: python
|
||||
pass_filenames: false
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: mypy
|
||||
|
@ -2,7 +2,11 @@ $ErrorActionPreference = "Stop"
|
||||
|
||||
$script_directory = Split-Path $MyInvocation.MyCommand.Path -Parent
|
||||
|
||||
$command = $args[0]
|
||||
$parameters = [System.Collections.ArrayList]$args
|
||||
$parameters.RemoveAt(0)
|
||||
|
||||
& $script_directory/venv/Scripts/Activate.ps1
|
||||
& @args
|
||||
& $command @parameters
|
||||
|
||||
exit $LASTEXITCODE
|
||||
|
@ -1 +0,0 @@
|
||||
can't compile ("defconstant" "AGG_SIG_UNSAFE" 49), unknown operator
|
@ -1 +0,0 @@
|
||||
ff02ffff01ff04ffff04ff38ffff04ffff02ff3affff04ff02ffff04ff05ffff04ffff02ff2effff04ff02ffff04ff17ffff04ffff02ff26ffff04ff02ffff04ff2fff80808080ff8080808080ff8080808080ffff04ff27ff80808080ffff02ff32ffff04ff02ffff04ff0bffff04ff2fffff01ff01808080808080ffff04ffff01ffffff32ff0233ffff0401ff0102ffffffff02ffff03ff05ffff01ff02ff22ffff04ff02ffff04ff0dffff04ffff0bff3cffff0bff34ff2480ffff0bff3cffff0bff3cffff0bff34ff2c80ff0980ffff0bff3cff0bffff0bff34ff8080808080ff8080808080ffff010b80ff0180ff02ffff03ff0bffff01ff04ffff04ff38ffff04ffff02ff2affff04ff02ffff04ff05ffff04ffff04ffff04ff17ff1380ff8080ff8080808080ffff01ff80808080ffff04ffff04ff10ffff04ff23ffff04ffff02ff3effff04ff02ffff04ffff04ff13ffff04ff17ff808080ff80808080ff80808080ffff02ff32ffff04ff02ffff04ff05ffff04ff1bffff04ffff10ff17ffff010180ff8080808080808080ff8080ff0180ffff02ff36ffff04ff02ffff04ff05ffff04ffff02ff3effff04ff02ffff04ff0bff80808080ff8080808080ff02ff36ffff04ff02ffff04ff05ffff04ffff02ff3effff04ff02ffff04ff0bff80808080ffff04ffff02ff3effff04ff02ffff04ff05ff80808080ff808080808080ffffff02ffff03ffff07ff0580ffff01ff04ff29ffff02ff26ffff04ff02ffff04ff0dff8080808080ff8080ff0180ff0bff3cffff0bff34ff2880ffff0bff3cffff0bff3cffff0bff34ff2c80ff0580ffff0bff3cffff02ff22ffff04ff02ffff04ff07ffff04ffff0bff34ff3480ff8080808080ffff0bff34ff8080808080ffff02ffff03ffff07ff0b80ffff01ff10ff13ffff02ff2effff04ff02ffff04ff05ffff04ff1bff808080808080ffff011580ff0180ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff3effff04ff02ffff04ff09ff80808080ffff02ff3effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080
|
@ -1 +0,0 @@
|
||||
can't compile ("my-id"), unknown operator
|
@ -1 +1 @@
|
||||
f890a7866079009517ae0b652d530268d2531bbac99670aaba461d604bc0ff0c
|
||||
f890a7866079009517ae0b652d530268d2531bbac99670aaba461d604bc0ff0c
|
||||
|
@ -1 +1 @@
|
||||
1720d13250a7c16988eaf530331cefa9dd57a76b2c82236bec8bbbff91499b89
|
||||
1720d13250a7c16988eaf530331cefa9dd57a76b2c82236bec8bbbff91499b89
|
||||
|
@ -1 +1 @@
|
||||
493afb89eed93ab86741b2aa61b8f5de495d33ff9b781dfc8919e602b2afa150
|
||||
493afb89eed93ab86741b2aa61b8f5de495d33ff9b781dfc8919e602b2afa150
|
||||
|
@ -1 +1 @@
|
||||
de5a6e06d41518be97ff6365694f4f89475dda773dede267caa33da63b434e36
|
||||
de5a6e06d41518be97ff6365694f4f89475dda773dede267caa33da63b434e36
|
||||
|
@ -1 +1 @@
|
||||
0893e36a88c064fddfa6f8abdb42c044584a98cb4273b80cccc83b4867b701a1
|
||||
0893e36a88c064fddfa6f8abdb42c044584a98cb4273b80cccc83b4867b701a1
|
||||
|
@ -1 +0,0 @@
|
||||
ff02ffff01ff04ffff04ffff013effff04ffff02ff02ffff04ff02ffff04ff05ff80808080ff808080ff8080ffff04ffff01ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff02ffff04ff02ffff04ff09ff80808080ffff02ff02ffff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080
|
@ -1 +0,0 @@
|
||||
3df9de54667a96f32eba322635f14d3474edadf23f396ba5a3e2e077a89a682a
|
@ -1 +1 @@
|
||||
ff02ffff01ff04ffff04ffff02ffff03ffff22ff27ff3780ffff01ff02ffff03ffff21ffff09ff27ffff01826d7580ffff09ff27ffff01826c7580ffff09ff27ffff01758080ffff01ff02ff02ffff04ff02ffff04ff05ffff04ff27ffff04ff37ff808080808080ffff010580ff0180ffff010580ff0180ffff04ff0bff808080ffff01ff808080ffff04ffff01ff02ffff03ff05ffff01ff02ffff03ffff09ff11ff0b80ffff01ff04ffff04ff0bffff04ff17ff198080ff0d80ffff01ff04ff09ffff02ff02ffff04ff02ffff04ff0dffff04ff0bffff04ff17ff8080808080808080ff0180ff8080ff0180ff018080
|
||||
ff02ffff01ff04ffff04ffff02ffff03ffff22ff27ff3780ffff01ff02ffff03ffff21ffff09ff27ffff01826d7580ffff09ff27ffff01826c7580ffff09ff27ffff01758080ffff01ff02ff02ffff04ff02ffff04ff05ffff04ff27ffff04ff37ff808080808080ffff010580ff0180ffff010580ff0180ffff04ff0bff808080ffff01ff808080ffff04ffff01ff02ffff03ff05ffff01ff02ffff03ffff09ff11ff0b80ffff01ff04ffff04ff0bffff04ff17ff198080ff0d80ffff01ff04ff09ffff02ff02ffff04ff02ffff04ff0dffff04ff0bffff04ff17ff8080808080808080ff0180ff8080ff0180ff018080
|
@ -1 +1 @@
|
||||
ff02ffff01ff04ffff04ffff02ffff03ff27ffff01ff02ff02ffff04ff02ffff04ff05ffff04ff27ff8080808080ffff010580ff0180ffff04ffff02ffff03ffff09ffff0dff5780ffff012080ffff0157ffff010b80ff0180ff808080ffff01ff808080ffff04ffff01ff02ffff03ff05ffff01ff02ffff03ffff09ff11ffff017580ffff01ff04ffff04ffff0175ffff04ff0bff198080ff0d80ffff01ff04ff09ffff02ff02ffff04ff02ffff04ff0dffff04ff0bff80808080808080ff0180ff8080ff0180ff018080
|
||||
ff02ffff01ff04ffff04ffff02ffff03ff27ffff01ff02ff02ffff04ff02ffff04ff05ffff04ff27ff8080808080ffff010580ff0180ffff04ffff02ffff03ffff09ffff0dff5780ffff012080ffff0157ffff010b80ff0180ff808080ffff01ff808080ffff04ffff01ff02ffff03ff05ffff01ff02ffff03ffff09ff11ffff017580ffff01ff04ffff04ffff0175ffff04ff0bff198080ff0d80ffff01ff04ff09ffff02ff02ffff04ff02ffff04ff0dffff04ff0bff80808080808080ff0180ff8080ff0180ff018080
|
@ -1 +1 @@
|
||||
c5abea79afaa001b5427dfa0c8cf42ca6f38f5841b78f9b3c252733eb2de2726
|
||||
c5abea79afaa001b5427dfa0c8cf42ca6f38f5841b78f9b3c252733eb2de2726
|
||||
|
@ -1 +1 @@
|
||||
ff02ffff01ff04ffff04ff04ffff04ff05ffff04ffff02ff06ffff04ff02ffff04ff0bff80808080ff80808080ff0b80ffff04ffff01ff32ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff06ffff04ff02ffff04ff09ff80808080ffff02ff06ffff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080
|
||||
ff02ffff01ff04ffff04ff04ffff04ff05ffff04ffff02ff06ffff04ff02ffff04ff0bff80808080ff80808080ff0b80ffff04ffff01ff32ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff06ffff04ff02ffff04ff09ff80808080ffff02ff06ffff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080
|
@ -1 +1 @@
|
||||
b10ce2d0b18dcf8c21ddfaf55d9b9f0adcbf1e0beb55b1a8b9cad9bbff4e5f22
|
||||
b10ce2d0b18dcf8c21ddfaf55d9b9f0adcbf1e0beb55b1a8b9cad9bbff4e5f22
|
||||
|
@ -1 +1 @@
|
||||
ff02ffff01ff02ffff03ffff09ff81bfff2480ffff01ff04ffff04ff30ffff04ff5fffff04ffff02ff3effff04ff02ffff04ffff04ff81bfff81ff80ff80808080ff80808080ff81ff80ffff01ff04ffff04ff30ffff04ff05ffff04ffff02ff3effff04ff02ffff04ffff04ff81bfff81ff80ff80808080ff80808080ffff02ffff03ffff09ff81bfff3c80ffff01ff02ff2effff04ff02ffff04ff0bffff04ff17ffff04ff2fffff04ff81ffff80808080808080ffff01ff02ff22ffff04ff02ffff04ff2fffff04ff81ffff808080808080ff01808080ff0180ffff04ffff01ffffffffff02ffff03ffff15ff05ff0b80ffff01ff0101ffff01ff02ffff03ffff09ff05ff0b80ffff01ff0101ff8080ff018080ff018031ff5246ffff0333ff3c01ffffffff02ffff03ffff02ffff03ffff09ffff0bff820bfbff13ff8205fb80ff82017b80ffff01ff0101ffff01ff02ffff03ffff09ff05ff82017b80ffff01ff0101ff8080ff018080ff0180ffff01ff04ffff02ff26ffff04ff02ffff04ff82017bffff04ff13ffff04ff8202fbff808080808080ffff04ffff02ff2affff04ff02ffff04ff2bffff04ff5bffff04ff81bbff808080808080ffff04ffff02ff3affff04ff02ffff04ff13ffff04ffff10ff81bbff8202fb80ff8080808080ff80808080ffff01ffff08808080ff0180ff04ff34ffff04ff05ffff04ffff11ff0bffff10ff17ff2f8080ff80808080ffff04ff2cffff04ffff0bff05ff0bff1780ff808080ff04ff34ffff04ff05ffff04ff0bff80808080ffffff04ff38ffff04ffff0bff05ff0bff1780ff808080ff02ffff03ffff02ff20ffff04ff02ffff04ffff12ff05ff1780ffff04ffff12ff0bff2f80ff8080808080ffff01ff04ff28ffff04ff05ff808080ffff01ffff08808080ff0180ffff02ffff03ffff02ffff03ffff09ffff0bff8217efff81afff822fef80ff4f80ffff01ff0101ffff01ff02ffff03ffff09ff17ff4f80ffff01ff0101ff8080ff018080ff0180ffff01ff04ffff02ff36ffff04ff02ffff04ff820befffff04ff8205efffff04ff05ffff04ff0bff80808080808080ffff04ffff02ff32ffff04ff02ffff04ff81afffff04ff82016fffff04ff8205efffff04ff825fefff80808080808080ffff04ffff02ff26ffff04ff02ffff04ff4fffff04ff81afffff04ff82016fff808080808080ffff04ffff02ff3affff04ff02ffff04ff8202efffff04ff8205efff8080808080ff8080808080ffff01ffff08808080ff0180ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff3effff04ff02ffff04ff09ff80808080ffff02ff3effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080
|
||||
ff02ffff01ff02ffff03ffff09ff81bfff2480ffff01ff04ffff04ff30ffff04ff5fffff04ffff02ff3effff04ff02ffff04ffff04ff81bfff81ff80ff80808080ff80808080ff81ff80ffff01ff04ffff04ff30ffff04ff05ffff04ffff02ff3effff04ff02ffff04ffff04ff81bfff81ff80ff80808080ff80808080ffff02ffff03ffff09ff81bfff3c80ffff01ff02ff2effff04ff02ffff04ff0bffff04ff17ffff04ff2fffff04ff81ffff80808080808080ffff01ff02ff22ffff04ff02ffff04ff2fffff04ff81ffff808080808080ff01808080ff0180ffff04ffff01ffffffffff02ffff03ffff15ff05ff0b80ffff01ff0101ffff01ff02ffff03ffff09ff05ff0b80ffff01ff0101ff8080ff018080ff018031ff5246ffff0333ff3c01ffffffff02ffff03ffff02ffff03ffff09ffff0bff820bfbff13ff8205fb80ff82017b80ffff01ff0101ffff01ff02ffff03ffff09ff05ff82017b80ffff01ff0101ff8080ff018080ff0180ffff01ff04ffff02ff26ffff04ff02ffff04ff82017bffff04ff13ffff04ff8202fbff808080808080ffff04ffff02ff2affff04ff02ffff04ff2bffff04ff5bffff04ff81bbff808080808080ffff04ffff02ff3affff04ff02ffff04ff13ffff04ffff10ff81bbff8202fb80ff8080808080ff80808080ffff01ffff08808080ff0180ff04ff34ffff04ff05ffff04ffff11ff0bffff10ff17ff2f8080ff80808080ffff04ff2cffff04ffff0bff05ff0bff1780ff808080ff04ff34ffff04ff05ffff04ff0bff80808080ffffff04ff38ffff04ffff0bff05ff0bff1780ff808080ff02ffff03ffff02ff20ffff04ff02ffff04ffff12ff05ff1780ffff04ffff12ff0bff2f80ff8080808080ffff01ff04ff28ffff04ff05ff808080ffff01ffff08808080ff0180ffff02ffff03ffff02ffff03ffff09ffff0bff8217efff81afff822fef80ff4f80ffff01ff0101ffff01ff02ffff03ffff09ff17ff4f80ffff01ff0101ff8080ff018080ff0180ffff01ff04ffff02ff36ffff04ff02ffff04ff820befffff04ff8205efffff04ff05ffff04ff0bff80808080808080ffff04ffff02ff32ffff04ff02ffff04ff81afffff04ff82016fffff04ff8205efffff04ff825fefff80808080808080ffff04ffff02ff26ffff04ff02ffff04ff4fffff04ff81afffff04ff82016fff808080808080ffff04ffff02ff3affff04ff02ffff04ff8202efffff04ff8205efff8080808080ff8080808080ffff01ffff08808080ff0180ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff3effff04ff02ffff04ff09ff80808080ffff02ff3effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080
|
167
tests/check_clvm.py
Normal file
167
tests/check_clvm.py
Normal file
@ -0,0 +1,167 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import dataclasses
|
||||
import os
|
||||
import pathlib
|
||||
import sys
|
||||
import tempfile
|
||||
import traceback
|
||||
|
||||
import typing_extensions
|
||||
|
||||
here = pathlib.Path(__file__).parent.resolve()
|
||||
root = here.parent
|
||||
|
||||
# This is a work-around for fixing imports so they get the appropriate top level
|
||||
# packages instead of those of the same name in the same directory as this program.
|
||||
# This undoes the Python mis-feature meant to support 'scripts' that have not been
|
||||
# installed by adding the script's directory to the import search path. This is why
|
||||
# it is simpler to just have all code get installed and all things you run be
|
||||
# accessible via entry points.
|
||||
sys.path = [path for path in sys.path if path != os.fspath(here)]
|
||||
|
||||
from clvm_tools_rs import compile_clvm # noqa: E402
|
||||
|
||||
from chia.types.blockchain_format.program import SerializedProgram # noqa: E402
|
||||
|
||||
clvm_suffix = ".clvm"
|
||||
hex_suffix = ".clvm.hex"
|
||||
hash_suffix = ".clvm.hex.sha256tree"
|
||||
|
||||
|
||||
def generate_hash_bytes(hex_bytes: bytes) -> bytes:
|
||||
cleaned_blob = bytes.fromhex(hex_bytes.decode("utf-8"))
|
||||
serialize_program = SerializedProgram.from_bytes(cleaned_blob)
|
||||
result = serialize_program.get_tree_hash().hex()
|
||||
return (result + "\n").encode("utf-8")
|
||||
|
||||
|
||||
@typing_extensions.final
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class ClvmPaths:
|
||||
clvm: pathlib.Path
|
||||
hex: pathlib.Path
|
||||
hash: pathlib.Path
|
||||
|
||||
@classmethod
|
||||
def from_clvm(cls, clvm: pathlib.Path) -> ClvmPaths:
|
||||
return cls(
|
||||
clvm=clvm,
|
||||
hex=clvm.with_name(clvm.name[: -len(clvm_suffix)] + hex_suffix),
|
||||
hash=clvm.with_name(clvm.name[: -len(clvm_suffix)] + hash_suffix),
|
||||
)
|
||||
|
||||
|
||||
@typing_extensions.final
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class ClvmBytes:
|
||||
hex: bytes
|
||||
hash: bytes
|
||||
|
||||
@classmethod
|
||||
def from_clvm_paths(cls, paths: ClvmPaths) -> ClvmBytes:
|
||||
return cls(
|
||||
hex=paths.hex.read_bytes(),
|
||||
hash=paths.hash.read_bytes(),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_hex_bytes(cls, hex_bytes: bytes) -> ClvmBytes:
|
||||
return cls(
|
||||
hex=hex_bytes,
|
||||
hash=generate_hash_bytes(hex_bytes=hex_bytes),
|
||||
)
|
||||
|
||||
|
||||
# These files have the wrong extension for now so we'll just manually exclude them
|
||||
excludes = {"condition_codes.clvm", "create-lock-puzzlehash.clvm"}
|
||||
|
||||
|
||||
def main() -> int:
|
||||
used_excludes = set()
|
||||
overall_fail = False
|
||||
|
||||
suffixes = {"clvm": clvm_suffix, "hex": hex_suffix, "hash": hash_suffix}
|
||||
top_levels = {"chia"}
|
||||
found_stems = {
|
||||
name: {
|
||||
path.with_name(path.name[: -len(suffix)])
|
||||
for top_level in top_levels
|
||||
for path in root.joinpath(top_level).rglob(f"**/*{suffix}")
|
||||
}
|
||||
for name, suffix in suffixes.items()
|
||||
}
|
||||
for name in ["hex", "hash"]:
|
||||
found = found_stems[name]
|
||||
suffix = suffixes[name]
|
||||
extra = found - found_stems["clvm"]
|
||||
|
||||
print()
|
||||
print(f"Extra {suffix} files:")
|
||||
|
||||
if len(extra) == 0:
|
||||
print(" -")
|
||||
else:
|
||||
overall_fail = True
|
||||
for stem in extra:
|
||||
print(f" {stem.with_name(stem.name + suffix)}")
|
||||
|
||||
print()
|
||||
print("Checking that all existing .clvm files compile to .clvm.hex that match existing caches:")
|
||||
for stem_path in sorted(found_stems["clvm"]):
|
||||
clvm_path = stem_path.with_name(stem_path.name + clvm_suffix)
|
||||
if clvm_path.name in excludes:
|
||||
used_excludes.add(clvm_path.name)
|
||||
continue
|
||||
|
||||
file_fail = False
|
||||
error = None
|
||||
|
||||
try:
|
||||
reference_paths = ClvmPaths.from_clvm(clvm=clvm_path)
|
||||
reference_bytes = ClvmBytes.from_clvm_paths(paths=reference_paths)
|
||||
|
||||
with tempfile.TemporaryDirectory() as temporary_directory:
|
||||
generated_paths = ClvmPaths.from_clvm(
|
||||
clvm=pathlib.Path(temporary_directory).joinpath(f"generated{clvm_suffix}")
|
||||
)
|
||||
|
||||
compile_clvm(
|
||||
input_path=os.fspath(reference_paths.clvm),
|
||||
output_path=os.fspath(generated_paths.hex),
|
||||
search_paths=[os.fspath(reference_paths.clvm.parent)],
|
||||
)
|
||||
|
||||
generated_bytes = ClvmBytes.from_hex_bytes(hex_bytes=generated_paths.hex.read_bytes())
|
||||
|
||||
if generated_bytes != reference_bytes:
|
||||
file_fail = True
|
||||
error = f" reference: {reference_bytes!r}\n"
|
||||
error += f" generated: {generated_bytes!r}"
|
||||
except Exception:
|
||||
file_fail = True
|
||||
error = traceback.format_exc()
|
||||
|
||||
if file_fail:
|
||||
print(f"FAIL : {clvm_path}")
|
||||
if error is not None:
|
||||
print(error)
|
||||
else:
|
||||
print(f" pass: {clvm_path}")
|
||||
|
||||
if file_fail:
|
||||
overall_fail = True
|
||||
|
||||
unused_excludes = sorted(excludes - used_excludes)
|
||||
if len(unused_excludes) > 0:
|
||||
overall_fail = True
|
||||
print()
|
||||
print("Unused excludes:")
|
||||
|
||||
for exclude in unused_excludes:
|
||||
print(f" {exclude}")
|
||||
|
||||
return 1 if overall_fail else 0
|
||||
|
||||
|
||||
sys.exit(main())
|
@ -1,187 +0,0 @@
|
||||
from os import remove
|
||||
from pathlib import Path
|
||||
from tempfile import NamedTemporaryFile
|
||||
from unittest import TestCase
|
||||
|
||||
import pytest
|
||||
from clvm_tools.clvmc import compile_clvm
|
||||
|
||||
from chia.types.blockchain_format.program import Program, SerializedProgram
|
||||
|
||||
pytestmark = pytest.mark.data_layer
|
||||
|
||||
|
||||
wallet_program_files = set(
|
||||
[
|
||||
"chia/wallet/puzzles/calculate_synthetic_public_key.clvm",
|
||||
"chia/wallet/puzzles/cat_v2.clvm",
|
||||
"chia/wallet/puzzles/chialisp_deserialisation.clvm",
|
||||
"chia/wallet/puzzles/rom_bootstrap_generator.clvm",
|
||||
"chia/wallet/puzzles/lock.inner.puzzle.clvm",
|
||||
"chia/wallet/puzzles/p2_conditions.clvm",
|
||||
"chia/wallet/puzzles/p2_delegated_conditions.clvm",
|
||||
"chia/wallet/puzzles/p2_delegated_puzzle.clvm",
|
||||
"chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clvm",
|
||||
"chia/wallet/puzzles/p2_m_of_n_delegate_direct.clvm",
|
||||
"chia/wallet/puzzles/p2_puzzle_hash.clvm",
|
||||
"chia/wallet/puzzles/rl_aggregation.clvm",
|
||||
"chia/wallet/puzzles/rl.clvm",
|
||||
"chia/wallet/puzzles/sha256tree_module.clvm",
|
||||
"chia/wallet/puzzles/singleton_top_layer.clvm",
|
||||
"chia/wallet/puzzles/did_innerpuz.clvm",
|
||||
"chia/wallet/puzzles/decompress_puzzle.clvm",
|
||||
"chia/wallet/puzzles/decompress_coin_spend_entry_with_prefix.clvm",
|
||||
"chia/wallet/puzzles/decompress_coin_spend_entry.clvm",
|
||||
"chia/wallet/puzzles/block_program_zero.clvm",
|
||||
"chia/wallet/puzzles/test_generator_deserialize.clvm",
|
||||
"chia/wallet/puzzles/test_multiple_generator_input_arguments.clvm",
|
||||
"chia/wallet/puzzles/p2_singleton.clvm",
|
||||
"chia/wallet/puzzles/pool_waitingroom_innerpuz.clvm",
|
||||
"chia/wallet/puzzles/pool_member_innerpuz.clvm",
|
||||
"chia/wallet/puzzles/singleton_launcher.clvm",
|
||||
"chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clvm",
|
||||
"chia/wallet/puzzles/genesis_by_puzzle_hash.clvm",
|
||||
"chia/wallet/puzzles/everything_with_signature.clvm",
|
||||
"chia/wallet/puzzles/delegated_tail.clvm",
|
||||
"chia/wallet/puzzles/settlement_payments.clvm",
|
||||
"chia/wallet/puzzles/genesis_by_coin_id.clvm",
|
||||
"chia/wallet/puzzles/singleton_top_layer_v1_1.clvm",
|
||||
"chia/wallet/puzzles/nft_metadata_updater_default.clvm",
|
||||
"chia/wallet/puzzles/nft_metadata_updater_updateable.clvm",
|
||||
"chia/wallet/puzzles/nft_state_layer.clvm",
|
||||
"chia/wallet/puzzles/nft_ownership_layer.clvm",
|
||||
"chia/wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clvm",
|
||||
"chia/wallet/puzzles/graftroot_dl_offers.clvm",
|
||||
"chia/wallet/puzzles/p2_parent.clvm",
|
||||
"chia/wallet/puzzles/decompress_block_spends.clvm",
|
||||
]
|
||||
)
|
||||
|
||||
clvm_include_files = set(
|
||||
["chia/wallet/puzzles/create-lock-puzzlehash.clvm", "chia/wallet/puzzles/condition_codes.clvm"]
|
||||
)
|
||||
|
||||
CLVM_PROGRAM_ROOT = "chia/wallet/puzzles"
|
||||
|
||||
|
||||
def list_files(dir, glob):
|
||||
dir = Path(dir)
|
||||
entries = dir.glob(glob)
|
||||
files = [f for f in entries if f.is_file()]
|
||||
return files
|
||||
|
||||
|
||||
def read_file(path):
|
||||
with open(path) as f:
|
||||
return f.read()
|
||||
|
||||
|
||||
def path_with_ext(path, ext):
|
||||
return Path(str(path) + ext)
|
||||
|
||||
|
||||
class TestClvmCompilation(TestCase):
|
||||
"""
|
||||
These are tests, and not just build scripts to regenerate the bytecode, because
|
||||
the developer must be aware if the compiled output changes, for any reason.
|
||||
"""
|
||||
|
||||
def test_all_programs_listed(self):
|
||||
"""
|
||||
Checks to see if a new .clvm file was added to chia/wallet/puzzles, but not added to `wallet_program_files`
|
||||
"""
|
||||
existing_files = list_files(CLVM_PROGRAM_ROOT, "*.clvm")
|
||||
existing_file_paths = set([Path(x).relative_to(CLVM_PROGRAM_ROOT) for x in existing_files])
|
||||
|
||||
expected_files = set(clvm_include_files).union(set(wallet_program_files))
|
||||
expected_file_paths = set([Path(x).relative_to(CLVM_PROGRAM_ROOT) for x in expected_files])
|
||||
|
||||
self.assertEqual(
|
||||
expected_file_paths,
|
||||
existing_file_paths,
|
||||
msg="Please add your new program to `wallet_program_files` or `clvm_include_files.values`",
|
||||
)
|
||||
|
||||
def test_include_and_source_files_separate(self):
|
||||
self.assertEqual(clvm_include_files.intersection(wallet_program_files), set())
|
||||
|
||||
# TODO: Test recompilation with all available compiler configurations & implementations
|
||||
def test_all_programs_are_compiled(self):
|
||||
"""Checks to see if a new .clvm file was added without its .hex file"""
|
||||
all_compiled = True
|
||||
msg = "Please compile your program with:\n"
|
||||
|
||||
# Note that we cannot test all existing .clvm files - some are not
|
||||
# meant to be run as a "module" with load_clvm; some are include files
|
||||
# We test for inclusion in `test_all_programs_listed`
|
||||
for prog_path in wallet_program_files:
|
||||
try:
|
||||
output_path = path_with_ext(prog_path, ".hex")
|
||||
hex = output_path.read_text()
|
||||
self.assertTrue(len(hex) > 0)
|
||||
except Exception as ex:
|
||||
all_compiled = False
|
||||
msg += f" run -i {prog_path.parent} -d {prog_path} > {prog_path}.hex\n"
|
||||
print(ex)
|
||||
msg += "and check it in"
|
||||
self.assertTrue(all_compiled, msg=msg)
|
||||
|
||||
def test_recompilation_matches(self):
|
||||
self.maxDiff = None
|
||||
for f in wallet_program_files:
|
||||
f = Path(f)
|
||||
compile_clvm(f, path_with_ext(f, ".recompiled"), search_paths=[f.parent])
|
||||
orig_hex = path_with_ext(f, ".hex").read_text().strip()
|
||||
new_hex = path_with_ext(f, ".recompiled").read_text().strip()
|
||||
self.assertEqual(orig_hex, new_hex, msg=f"Compilation of {f} does not match {f}.hex")
|
||||
pass
|
||||
|
||||
def test_all_compiled_programs_are_hashed(self):
|
||||
"""Checks to see if a .hex file is missing its .sha256tree file"""
|
||||
all_hashed = True
|
||||
msg = "Please hash your program with:\n"
|
||||
for prog_path in wallet_program_files:
|
||||
try:
|
||||
hex = path_with_ext(prog_path, ".hex.sha256tree").read_text()
|
||||
self.assertTrue(len(hex) > 0)
|
||||
except Exception as ex:
|
||||
print(ex)
|
||||
all_hashed = False
|
||||
msg += f" opd -H {prog_path}.hex | head -1 > {prog_path}.hex.sha256tree\n"
|
||||
msg += "and check it in"
|
||||
self.assertTrue(all_hashed, msg)
|
||||
|
||||
# TODO: Test all available shatree implementations on all progams
|
||||
def test_shatrees_match(self):
|
||||
"""Checks to see that all .sha256tree files match their .hex files"""
|
||||
for prog_path in wallet_program_files:
|
||||
# load the .hex file as a program
|
||||
hex_filename = path_with_ext(prog_path, ".hex")
|
||||
clvm_hex = hex_filename.read_text() # .decode("utf8")
|
||||
clvm_blob = bytes.fromhex(clvm_hex)
|
||||
s = SerializedProgram.from_bytes(clvm_blob)
|
||||
p = Program.from_bytes(clvm_blob)
|
||||
|
||||
# load the checked-in shatree
|
||||
existing_sha = path_with_ext(prog_path, ".hex.sha256tree").read_text().strip()
|
||||
|
||||
self.assertEqual(
|
||||
s.get_tree_hash().hex(),
|
||||
existing_sha,
|
||||
msg=f"Checked-in shatree hash file does not match hash of loaded SerializedProgram: {prog_path}",
|
||||
)
|
||||
self.assertEqual(
|
||||
p.get_tree_hash().hex(),
|
||||
existing_sha,
|
||||
msg=f"Checked-in shatree hash file does not match shatree hash of loaded Program: {prog_path}",
|
||||
)
|
||||
|
||||
def test_017_encoding_bug_fixed(self):
|
||||
with NamedTemporaryFile(delete=False) as tf:
|
||||
tf.write(b"10000000")
|
||||
hexname = tf.name + ".hex"
|
||||
compile_clvm(tf.name, hexname, [])
|
||||
with open(hexname) as f:
|
||||
self.assertEqual(f.read().strip(), "8400989680")
|
||||
remove(tf.name)
|
||||
remove(hexname)
|
Loading…
Reference in New Issue
Block a user