Download testing/test_chain.py from PYTHAI/bankml: direct link, hf CLI and curl.
- Browser
- Download file 6.77 kB
-
https://huggingface.co/spaces/PYTHAI/bankml/resolve/main/testing/test_chain.py
- Command line
-
hf download hf://spaces/PYTHAI/bankml/testing/test_chain.py
-
curl -L -o test_chain.py https://huggingface.co/spaces/PYTHAI/bankml/resolve/main/testing/test_chain.py
6.77 kB
| #!/usr/bin/env python3 | |
| # SPDX-License-Identifier: MIT OR Apache-2.0 | |
| """The chain side against a throwaway local EVM: anvil on a free port, the house iNFT_7857 (DeltaVerse iNFT4) deployed | |
| from its compiled artifact, a bankml agent minted from its THOT bundle and loaded back. Nothing leaves this computer. | |
| Skips (exit 0) when anvil or the artifact is absent (CI). | |
| run: python3 testing/test_chain.py""" | |
| import json, os, shutil, socket, subprocess, sys, tempfile, time | |
| from pathlib import Path | |
| ART = Path(os.environ.get("BANKML_INFT_ARTIFACT", Path.home() / "DeltaVerse/deploy/iNFT4/out/iNFT_7857.sol/iNFT_7857.json")) | |
| ANVIL = shutil.which("anvil") or str(Path.home() / ".foundry/bin/anvil") | |
| if not ART.is_file() or not Path(ANVIL).is_file(): | |
| print("skip anvil or the iNFT_7857 artifact is not here") | |
| sys.exit(0) | |
| tmp = Path(tempfile.mkdtemp(prefix="bankml-chain-")) | |
| os.environ.update(BANKML_AGENTS=str(tmp / "agents"), BANKML_UI_STATE=str(tmp / "state")) | |
| sys.dont_write_bytecode = True | |
| sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "sAGI")) | |
| import agents, chain, thot # noqa: E402 | |
| s = socket.socket(); s.bind(("127.0.0.1", 0)); port = s.getsockname()[1]; s.close() | |
| url = f"http://127.0.0.1:{port}" | |
| proc = subprocess.Popen([ANVIL, "--port", str(port), "--silent"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) | |
| fails = 0 | |
| def check(name, ok): | |
| global fails | |
| fails += not ok | |
| print(("ok " if ok else "FAIL ") + name) | |
| try: | |
| for _ in range(100): | |
| try: | |
| chain.chain_id(url) | |
| break | |
| except OSError: | |
| time.sleep(0.1) | |
| accts = chain.rpc(url, "eth_accounts", []) | |
| minter, holder, stranger = accts[0], accts[1], accts[2] | |
| check("anvil is a devnet (chain id 31337)", chain.chain_id(url) == 31337) | |
| art = json.loads(ART.read_text()) | |
| ctor = chain.encode(["string", "string", "address", "address", "uint96", "address", "address", "uint256"], | |
| ["bankml agents (devnet)", "BKA", minter, minter, 0, "0x" + "00" * 20, "0x" + "00" * 20, 0]) | |
| h = chain.rpc(url, "eth_sendTransaction", [{"from": minter, "data": art["bytecode"]["object"] + ctor.hex(), "gas": hex(12_000_000)}]) | |
| rc = chain.receipt(url, h) | |
| inft = rc.get("contractAddress") | |
| check("iNFT_7857 deployed from its artifact", int(rc["status"], 16) == 1 and inft) | |
| tpl = {"persona": "tpl", "name": "Template", "source": "s", "format": "f", "system_prompt": "You are the template.", "mantra": "m", "oath": "o", | |
| "bdi": {"beliefs": []}, "skills": {"primary": "p", "taxonomy": [], "defer_triggers": [], "validation": []}, | |
| "safety": {}, "embodiment": {}, "token": {"intelligence": {"tool_allowlist": []}}} | |
| slug = agents.derive(tpl, {}, "Minted Mira", system_prompt="You are Mira.") | |
| m1 = thot.build(slug) | |
| plan = chain.plan_mint(slug, to=holder) | |
| check("the plan's contentRoot is the THOT manifest's", plan["args"]["contentRoot"] == m1["identity"]["contentRoot"]) | |
| sim = chain.simulate(url, inft, minter, plan) | |
| check(f"simulate as the minter: token {sim.get('tokenId')}", sim["ok"]) | |
| bad = chain.simulate(url, inft, stranger, plan) | |
| check(f"simulate without MINTER_ROLE is refused, decoded: {bad.get('error', '')[:60]}", not bad["ok"] and "AccessControl" in bad.get("error", "")) | |
| ut = chain.unsigned_tx(url, inft, minter, plan) | |
| check("unsigned tx for the owner: chain id, calldata, gas estimate, cast line", ut["tx"]["chainId"] == 31337 and ut["tx"]["data"] == plan["calldata"] | |
| and "gas" in ut["tx"] and ut["cast"].startswith("cast send")) | |
| sent = chain.send_devnet(url, inft, minter, plan) | |
| check("minted on the devnet", sent["status"] == 1) | |
| tok = chain.read_token(url, inft, sim["tokenId"]) | |
| check("the token reads back: contentRoot, storageURI, open, owner", tok["contentRoot"] == m1["identity"]["contentRoot"] | |
| and tok["storageURI"] == plan["args"]["storageURI"] and tok["open"] and tok["owner"].lower() == holder.lower() | |
| and tok["dimensions"] == 768 and tok["metadataRoot"] == plan["args"]["metadataRoot"]) | |
| again = chain.simulate(url, inft, minter, plan) | |
| check(f"the same content root cannot be minted twice: {again.get('error', '')[:40]}", not again["ok"] and "ContentRootAlreadyMinted" in again.get("error", "")) | |
| ld = chain.load_from_chain(url, inft, sim["tokenId"]) | |
| check("load from chain finds the agent by contentRoot and verifies it", ld["agent"] == slug and ld["verified"] and ld["generation_on_chain_is_current"]) | |
| for i in range(2): # the agent evolves; the token keeps pointing at the genesis | |
| agents.files(slug)["history"].write_text(agents.files(slug)["history"].read_text() + json.dumps({"n": i}) + "\n") | |
| thot.build(slug) | |
| ld2 = chain.load_from_chain(url, inft, sim["tokenId"]) | |
| check("after two generations the token still loads: lineage walks back to the minted genesis", ld2["agent"] == slug and ld2["verified"] | |
| and ld2["minted_generation"] == 1 and ld2["current_generation"] == 3 and ld2["descends_from_minted"] and not ld2["generation_on_chain_is_current"]) | |
| saved = chain.DEVNET_CHAIN_IDS | |
| chain.DEVNET_CHAIN_IDS = set() # pretend this is a public chain | |
| try: | |
| chain.send_devnet(url, inft, minter, chain.plan_mint(slug, to=holder)) | |
| check("send is refused off a devnet (the owner signs)", False) | |
| except PermissionError: | |
| check("send is refused off a devnet (the owner signs)", True) | |
| finally: | |
| chain.DEVNET_CHAIN_IDS = saved | |
| try: | |
| chain.send_devnet(url.replace("127.0.0.1", "devnet.example.com"), inft, minter, plan) | |
| check("send is refused to a node that is not on this machine, whatever chain id it reports", False) | |
| except PermissionError: | |
| check("send is refused to a node that is not on this machine, whatever chain id it reports", True) | |
| try: | |
| chain.encode(["address"], ["0x" + "11" * 19]) | |
| check("a 19-byte address is refused (it would shift every later argument)", False) | |
| except ValueError: | |
| check("a 19-byte address is refused (it would shift every later argument)", True) | |
| ut2 = chain.unsigned_tx(url, inft, minter, {**plan, "args": {**plan["args"], "tokenURI": "x\"; rm -rf ~; echo \""}}) | |
| check("the cast line quotes every argument", "'x\"; rm -rf ~; echo \"'" in ut2["cast"]) | |
| try: | |
| chain.plan_mint(slug, to=holder, dimensions=100) | |
| check("an invalid dimension is refused before any call", False) | |
| except ValueError: | |
| check("an invalid dimension is refused before any call", True) | |
| finally: | |
| proc.terminate() | |
| proc.wait(timeout=10) | |
| shutil.rmtree(tmp, ignore_errors=True) | |
| print("all ok" if not fails else f"{fails} FAILED") | |
| sys.exit(1 if fails else 0) | |