Planetarium
Live · block #5066119 Lab bench →
Job atlas / Job #123457 / E·1762ac5e1f
r:o:1762ac5e1f5136d645fc8841ff242a3b38f42c8ae0c86e2709cd1da21fb2d073

Artifact E·1762ac5e1f

Artifact retrieval for job #123457. An immutable observation by ✦peer-9c421e at 25 Oct 14:12 UTC: chain data, retrieval provenance and exact source spans are retained without executing source.

Recorded fields

{
  "evidence": {
    "artifact_bytes": 2225,
    "artifact_sha256": "cbca208683c4690ea20fefa0ec373546d04ffed6458e15acef16de1c084a35b8",
    "cid_verified": false,
    "files": [
      {
        "bytes": 3868,
        "name": "acurast.sh",
        "sha256": "1c7a080219896c1d5c6d8f12263a20403dddbacaf8187d8cdcd45011ca16b9de",
        "text": "#!/bin/sh\n# Pre-warm pool runner: starts idle on the device and long-polls the server\n# for a task. When one arrives it runs the buyer script, signs the output\n# (including the buyer script's hash) and delivers the receipt. One-shot:\n# exits after the task, or when the idle budget runs out.\n# Runner ref, poll token, server base URL and idle budget are baked in as\n# placeholders at package-build time.\ncd \"$(dirname \"$0\")\"\npython3 << 'PYEOF'\nimport socket, json, os, hashlib, subprocess, urllib.request, urllib.error, time\n\nRUNNER_REF = \"054cbac296cd77bb\"\nPOLL_TOKEN = \"c16cf549d4b3d70a957f955d81b40071\"\nSERVER_BASE = \"https://tee.papers.tech\"\nIDLE_BUDGET_S = int(\"3540\")\nMAX_CAPTURE = 64 * 1024\n\ndef call_bridge(method, params=None):\n    s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)\n    s.connect('\\0' + os.environ['BRIDGE_SOCKET'])\n    req = json.dumps({\"jsonrpc\": \"2.0\", \"id\": 1, \"method\": method, \"params\": params or []})\n    s.sendall((req + \"\\n\").encode())\n    res = json.loads(s.recv(65536).decode())\n    s.close()\n    if \"error\" in res:\n        raise Exception(\"Bridge error: \" + str(res[\"error\"]))\n    return res[\"result\"]\n\n# 1. Long-poll the server until a task arrives or the idle budget runs out.\n#    The server holds each poll up to ~55s, so this stays well within the\n#    deployment's network budget.\npoll_url = \"%s/pool/task/%s?token=%s\" % (SERVER_BASE, RUNNER_REF, POLL_TOKEN)\ndeadline = time.time() + IDLE_BUDGET_S\ntask = None\nwhile time.time() < deadline:\n    try:\n        res = urllib.request.urlopen(poll_url, timeout=70)\n        body = res.read().decode()\n        if res.status == 200 and body.strip():\n            task = json.loads(body)\n            break\n    except urllib.error.HTTPError as e:\n        if e.code == 410:  # server does not know us anymore: stop politely\n            raise SystemExit(0)\n        time.sleep(10)\n    except Exception:\n        time.sleep(10)\n\nif task is None:\n    print(\"idle budget exhausted, exiting unused\")\n    raise SystemExit(0)\n\n# 2. Run the buyer script, hash it so the signature covers what we executed\nbuyer_script = task[\"script\"]\nbuyer_hash = hashlib.sha256(buyer_script.encode()).hexdigest()\nwith open(\"buyer.sh\", \"w\") as f:\n    f.write(buyer_script)\n\ntry:\n    proc = subprocess.run([\"sh\", \"buyer.sh\"], capture_output=True, timeout=int(task[\"timeoutS\"]))\n    exit_code = proc.returncode\n    stdout = proc.stdout.decode(\"utf-8\", \"replace\")[:MAX_CAPTURE]\n    stderr = proc.stderr.decode(\"utf-8\", \"replace\")[:MAX_CAPTURE]\nexcept subprocess.TimeoutExpired as e:\n    exit_code = -1\n    stdout = (e.stdout or b\"\").decode(\"utf-8\", \"replace\")[:MAX_CAPTURE]\n    stderr = \"buyer script timed out after %ss\" % task[\"timeoutS\"]\n\n# 3. Canonicalize, sign via the bridge socket, deliver\noutput = {\n    \"ref\": task[\"taskRef\"],\n    \"exitCode\": exit_code,\n    \"stdout\": stdout,\n    \"stderr\": stderr,\n    \"buyerScriptSha256\": buyer_hash,\n}\noutput_json = json.dumps(output, sort_keys=True, separators=(\",\", \":\"))\ndigest = hashlib.sha256(output_json.encode()).hexdigest()\n\npublic_key = call_bridge(\"signer_publicKey\", [{\"curve\": \"secp256k1\"}])[\"publicKey\"]\nsignature = call_bridge(\"signer_sign\", [{\"curve\": \"secp256k1\", \"bytes\": digest}])[\"bytes\"]\n\nreceipt = {\n    \"output\": output_json,\n    \"sha256\": digest,\n    \"signature\": signature,\n    \"publicKey\": public_key,\n}\nprint(\"receipt:\", json.dumps(receipt))\n\nbody = json.dumps(receipt).encode()\nfor url in task[\"deliveryUrls\"]:\n    for attempt in range(3):\n        try:\n            req = urllib.request.Request(url, data=body, headers={\"Content-Type\": \"application/json\"})\n            status = urllib.request.urlopen(req, timeout=30).status\n            print(\"delivered to %s: %s\" % (url, status))\n            break\n        except Exception as e:\n            print(\"delivery attempt %d to %s failed: %s\" % (attempt + 1, url, e))\n            time.sleep(5)\nPYEOF\n",
        "truncated": false
      },
      {
        "bytes": 294,
        "name": "manifest.json",
        "sha256": "4d19eb43aa04a9e64a9d7ce2e6737fdc90602368526042af59840bf8f9e1e09a",
        "text": "{\n  \"version\": 1,\n  \"restartPolicy\": \"No\",\n  \"entrypoint\": \"acurast.sh\",\n  \"image\": {\n    \"url\": \"https://github.com/termux/proot-distro/releases/download/v4.30.1/ubuntu-questing-aarch64-pd-v4.30.1.tar.xz\",\n    \"sha256\": \"5ab35b90cd9a9f180656261ba400a135c4c01c2da4b74522118342f985c2d328\"\n  }\n}\n",
        "truncated": false
      }
    ],
    "image_url": "https://github.com/termux/proot-distro/releases/download/v4.30.1/ubuntu-questing-aarch64-pd-v4.30.1.tar.xz",
    "job": {
      "job_id": "acurast:5HNL1Jezm6t8oeKZe126xr1AsMvLd61Eg6z4bDHskGWB1ctb:123457",
      "observed_block": "0xc101cf484ab6b51ca0d51d26613f0d7e23f3584e5c647b6d3e26cf5776941ff9",
      "script_uri": "ipfs://QmPPHYp4UVDJdCg6iwHQM48dwv2f93PkxxKJXvn7a3HmbU"
    },
    "kind": "cargo_zip"
  },
  "identity": {
    "address": "5HNL1Jezm6t8oeKZe126xr1AsMvLd61Eg6z4bDHskGWB1ctb",
    "address_hex": "0xea9e06f6856ad09c6e2b435db6b265c4e3bd2605ae5500153e4e3bc35b96cb00",
    "id": "acurast:5HNL1Jezm6t8oeKZe126xr1AsMvLd61Eg6z4bDHskGWB1ctb:123457",
    "origin_variant": "Acurast",
    "sequence": "123457"
  },
  "outcome": "retrieved",
  "registration_id": "r:o:1a6edb9e34694ea41b625b7215d459b27abf243a13ea03ff7b88908b88e72907",
  "retrieval": {
    "cid_verified": false,
    "downloaded_bytes": 2225,
    "downloaded_sha256": "cbca208683c4690ea20fefa0ec373546d04ffed6458e15acef16de1c084a35b8",
    "failures": [],
    "gateway_index": 0,
    "inspection_error": null,
    "retrieved_at_ms": 1792937560909,
    "state": "retrieved",
    "trust": "trusted gateway; UnixFS root not independently verified"
  },
  "type": "artifact"
}

Configured RPC responses are not independently storage-proof verified. Reported outcomes retain their reported semantics. Only successfully covered history ranges support absence claims.

Observation

Job
acurast:5HNL1Jezm6t8oeKZe126xr1AsMvLd61Eg6z4bDHskGWB1ctb:123457
Script
ipfs://QmPPHYp4UVDJdCg6iwHQM48dwv2f93PkxxKJXvn7a3HmbU
Artifact
cargo_zip
Downloaded bytes
2225
SHA-256
cbca208683c4690ea20fefa0ec373546d04ffed6458e15acef16de1c084a35b8
CID byte verification
Not verified against CID (download hash retained)
PRoot image reference
https://github.com/termux/proot-distro/releases/download/v4.30.1/ubuntu-questing-aarch64-pd-v4.30.1.tar.xz

Source previews

acurast.sh

3868 bytes · SHA-256 1c7a080219896c1d5c6d8f12263a20403dddbacaf8187d8cdcd45011ca16b9de

#!/bin/sh
# Pre-warm pool runner: starts idle on the device and long-polls the server
# for a task. When one arrives it runs the buyer script, signs the output
# (including the buyer script's hash) and delivers the receipt. One-shot:
# exits after the task, or when the idle budget runs out.
# Runner ref, poll token, server base URL and idle budget are baked in as
# placeholders at package-build time.
cd "$(dirname "$0")"
python3 << 'PYEOF'
import socket, json, os, hashlib, subprocess, urllib.request, urllib.error, time

RUNNER_REF = "054cbac296cd77bb"
POLL_TOKEN = "c16cf549d4b3d70a957f955d81b40071"
SERVER_BASE = "https://tee.papers.tech"
IDLE_BUDGET_S = int("3540")
MAX_CAPTURE = 64 * 1024

def call_bridge(method, params=None):
    s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    s.connect('\0' + os.environ['BRIDGE_SOCKET'])
    req = json.dumps({"jsonrpc": "2.0", "id": 1, "method": method, "params": params or []})
    s.sendall((req + "\n").encode())
    res = json.loads(s.recv(65536).decode())
    s.close()
    if "error" in res:
        raise Exception("Bridge error: " + str(res["error"]))
    return res["result"]

# 1. Long-poll the server until a task arrives or the idle budget runs out.
#    The server holds each poll up to ~55s, so this stays well within the
#    deployment's network budget.
poll_url = "%s/pool/task/%s?token=%s" % (SERVER_BASE, RUNNER_REF, POLL_TOKEN)
deadline = time.time() + IDLE_BUDGET_S
task = None
while time.time() < deadline:
    try:
        res = urllib.request.urlopen(poll_url, timeout=70)
        body = res.read().decode()
        if res.status == 200 and body.strip():
            task = json.loads(body)
            break
    except urllib.error.HTTPError as e:
        if e.code == 410:  # server does not know us anymore: stop politely
            raise SystemExit(0)
        time.sleep(10)
    except Exception:
        time.sleep(10)

if task is None:
    print("idle budget exhausted, exiting unused")
    raise SystemExit(0)

# 2. Run the buyer script, hash it so the signature covers what we executed
buyer_script = task["script"]
buyer_hash = hashlib.sha256(buyer_script.encode()).hexdigest()
with open("buyer.sh", "w") as f:
    f.write(buyer_script)

try:
    proc = subprocess.run(["sh", "buyer.sh"], capture_output=True, timeout=int(task["timeoutS"]))
    exit_code = proc.returncode
    stdout = proc.stdout.decode("utf-8", "replace")[:MAX_CAPTURE]
    stderr = proc.stderr.decode("utf-8", "replace")[:MAX_CAPTURE]
except subprocess.TimeoutExpired as e:
    exit_code = -1
    stdout = (e.stdout or b"").decode("utf-8", "replace")[:MAX_CAPTURE]
    stderr = "buyer script timed out after %ss" % task["timeoutS"]

# 3. Canonicalize, sign via the bridge socket, deliver
output = {
    "ref": task["taskRef"],
    "exitCode": exit_code,
    "stdout": stdout,
    "stderr": stderr,
    "buyerScriptSha256": buyer_hash,
}
output_json = json.dumps(output, sort_keys=True, separators=(",", ":"))
digest = hashlib.sha256(output_json.encode()).hexdigest()

public_key = call_bridge("signer_publicKey", [{"curve": "secp256k1"}])["publicKey"]
signature = call_bridge("signer_sign", [{"curve": "secp256k1", "bytes": digest}])["bytes"]

receipt = {
    "output": output_json,
    "sha256": digest,
    "signature": signature,
    "publicKey": public_key,
}
print("receipt:", json.dumps(receipt))

body = json.dumps(receipt).encode()
for url in task["deliveryUrls"]:
    for attempt in range(3):
        try:
            req = urllib.request.Request(url, data=body, headers={"Content-Type": "application/json"})
            status = urllib.request.urlopen(req, timeout=30).status
            print("delivered to %s: %s" % (url, status))
            break
        except Exception as e:
            print("delivery attempt %d to %s failed: %s" % (attempt + 1, url, e))
            time.sleep(5)
PYEOF

manifest.json

294 bytes · SHA-256 4d19eb43aa04a9e64a9d7ce2e6737fdc90602368526042af59840bf8f9e1e09a

{
  "version": 1,
  "restartPolicy": "No",
  "entrypoint": "acurast.sh",
  "image": {
    "url": "https://github.com/termux/proot-distro/releases/download/v4.30.1/ubuntu-questing-aarch64-pd-v4.30.1.tar.xz",
    "sha256": "5ab35b90cd9a9f180656261ba400a135c4c01c2da4b74522118342f985c2d328"
  }
}

Provenance

Observed by
✦peer-9c421e
Recorded
25 Oct 14:12 UTC
Submitted block
0xc101cf484ab6b51ca0d51d26613f0d7e23f3584e5c647b6d3e26cf5776941ff9

The artifact script and block came from its linked finalized registration observation. Historical execution is a separate observation.

Local copy & sync

Available on peer-51887a.

Last successful database sync: 25 Oct 15:58 UTC.

A sync timestamp does not confirm remote copies of this object.