@@ -35,14 +35,71 @@ The node env template `../node.env.tpl` also lives here (one level up) and is sh
3535To regenerate test assets from real TDX attestation:
3636
3737``` bash
38- # Deploy single node
39- bash localnet/tee/scripts/rust-launcher/single-node.sh
38+ # Deploy single node. PRELAUNCH_SCRIPT is what makes the node's signer secret
39+ # key recoverable; see below.
40+ PRELAUNCH_SCRIPT=/path/to/prelaunch.sh bash localnet/tee/scripts/rust-launcher/single-node.sh
4041
4142# Extract assets
4243cp < WORKDIR> /public_data.json crates/test-utils/assets/public_data.json
4344cd crates/test-utils/assets && bash ./create-assets.sh public_data.json .
4445cp crates/test-utils/assets/tcb_info.json crates/attestation/assets/tcb_info.json
4546# Update VALID_ATTESTATION_TIMESTAMP in crates/test-utils/src/attestation.rs
47+ # Regenerate the verifier's borsh arg fixture and the expected report:
48+ UPDATE_FIXTURES=1 cargo test -p tee-verifier --test verify_quote verify_quote_args_fixture
49+ cargo test -p tee-verifier --test verify_quote # update the hardcoded report values it prints
4650```
4751
52+ ### Exporting the node's signer key
53+
54+ Sandbox tests that store a Verified attestation must sign as the fixture node,
55+ because the quote's ` report_data ` binds the node's account key and the contract
56+ reads that key from the transaction signer. That key is generated inside the
57+ CVM, so it has to be exported during collection or the fixture is unusable for
58+ those tests (this is what issue #3787 was about).
59+
60+ ` PRELAUNCH_SCRIPT ` points at a script baked into the app-compose and run inside
61+ the CVM before the node starts. Notes from making this work:
62+
63+ - The guest is BusyBox: stick to shell built-ins and globs. GNU-only options
64+ such as ` head -1 ` fail, and there is no ` sshd ` , no ` /root ` , and no
65+ ` /usr/local/bin ` .
66+ - ` /etc ` (overlay) and ` /dstack/.host-shared ` are writable; ` / ` is not.
67+ - The node writes ` secrets.json ` only after the hook returns, so the wait must
68+ run as its own systemd unit. A plain background process is reaped with
69+ ` app-compose.service ` 's cgroup.
70+ - Anything echoed to ` /dev/console ` lands in the host's
71+ ` run/vm/<id>/serial.log ` , which is the simplest way to read a value out.
72+
73+ A hook that copies the key to the host-visible shared dir:
74+
75+ ``` sh
76+ cat > /etc/fixture-exfil.sh << 'EOF '
77+ #!/bin/sh
78+ i=0
79+ while [ "$i" -lt 900 ]; do
80+ for f in /var/lib/docker/volumes/*/_data/secrets.json; do
81+ [ -f "$f" ] && { cp "$f" /dstack/.host-shared/fixture-secrets.json; exit 0; }
82+ done
83+ i=$((i + 1)); sleep 2
84+ done
85+ EOF
86+ cat > /etc/systemd/system/fixture-exfil.service << 'EOF '
87+ [Unit]
88+ Description=Export the MPC node signer key for test-asset collection
89+ [Service]
90+ Type=oneshot
91+ ExecStart=/bin/sh /etc/fixture-exfil.sh
92+ EOF
93+ systemctl daemon-reload && systemctl start --no-block fixture-exfil.service
94+ ```
95+
96+ Then put ` near_signer_key ` from that file into
97+ ` crates/test-utils/assets/near_account_secret_key ` (one line, ` ed25519:<base58> ` )
98+ and check that its public half equals ` near_account_public_key.pub ` . Only ever do
99+ this for a throwaway localnet node: the key ends up in the repo.
100+
101+ The hook is measured into the app-compose, and production verification rejects any
102+ app-compose carrying a script. Test builds accept this one field via
103+ ` attestation/allow-pre-launch-script ` , so keep the hook to what the export needs.
104+
48105See [ single-node-readme.md] ( single-node-readme.md ) for details.
0 commit comments