@@ -126,6 +126,8 @@ async fn assert_submission_failed_cleanly(
126126 !failures. is_empty( ) ,
127127 "expected the promise chain to fail on a receipt, got: {result:#?}"
128128 ) ;
129+ // Substring-match: near-workspaces keeps `ExecutionOutcome.status`
130+ // `pub(crate)`, so the error is only reachable via the Debug dump.
129131 let rendered = format ! ( "{failures:?}" ) ;
130132 let expected = expected_error. to_string ( ) ;
131133 assert ! (
@@ -229,13 +231,13 @@ async fn submit_participant_info__should_fail_and_store_nothing_on_verifier_cras
229231 . await ;
230232}
231233
232- // TODO(#3738 ): un-ignore once the fixture allowlist setup lands. A Verified
234+ // TODO(#3787 ): un-ignore once the fixture allowlist setup lands. A Verified
233235// verdict routes through `verify_post_dcap_and_store`, whose allowlist checks
234236// (fixture image/launcher hashes and measurements voted in, submitter using the
235237// fixture keys) must pass before the attestation is stored. With an empty
236238// allowlist the post-DCAP check fails and the submission is rejected instead of
237239// stored, so the happy path cannot be exercised here yet.
238- #[ ignore = "needs fixture allowlist setup to pass the post-DCAP checks; tracked in #3738 " ]
240+ #[ ignore = "needs fixture allowlist setup to pass the post-DCAP checks; tracked in #3787 " ]
239241#[ tokio:: test]
240242async fn submit_participant_info__should_store_attestation_on_verified_quote ( ) {
241243 // Given: a verifier that returns the report the real verifier would produce
@@ -247,8 +249,8 @@ async fn submit_participant_info__should_store_attestation_on_verified_quote() {
247249 let result = submit_dstack ( & submitter, & contract) . await ;
248250
249251 // Then: the chain succeeds and the attestation is stored; storage is charged
250- // and the excess deposit refunded ( net spend is storage + gas, well under the
251- // full deposit) .
252+ // and the excess deposit refunded, so net spend is storage + gas, well under
253+ // the full deposit.
252254 assert ! (
253255 result. failures( ) . is_empty( ) ,
254256 "the verified submission chain must succeed, got: {result:#?}"
@@ -257,14 +259,24 @@ async fn submit_participant_info__should_store_attestation_on_verified_quote() {
257259 . await
258260 . unwrap ( ) ;
259261 assert ! ( stored. is_some( ) , "a verified attestation must be stored" ) ;
262+
263+ // Bound net spend both sides: storage was charged (> 0), but the excess was
264+ // refunded (< floor). The upper bound catches a wrongly-retained deposit.
260265 let balance_after = submitter. view_account ( ) . await . unwrap ( ) . balance ;
266+ let net_spent = balance_before. as_yoctonear ( ) - balance_after. as_yoctonear ( ) ;
267+ let refund_floor = NearToken :: from_millinear ( 100 ) . as_yoctonear ( ) ;
261268 assert ! (
262- balance_after < balance_before ,
269+ net_spent > 0 ,
263270 "storage must be charged from the attached deposit"
264271 ) ;
272+ assert ! (
273+ net_spent < refund_floor,
274+ "excess deposit must be refunded (net spent {net_spent} yoctoNEAR should be \
275+ storage + gas, < {refund_floor}); a retained {SUBMIT_DEPOSIT} deposit would exceed this"
276+ ) ;
265277}
266278
267- // TODO(#3738 ): un-ignore once the fixture allowlist setup lands. To OOG,
279+ // TODO(#3787 ): un-ignore once the fixture allowlist setup lands. To OOG,
268280// `resolve_verification` must reach the heavy RTMR3 replay in the post-DCAP
269281// checks, which needs the allowlist populated and the submitter using the fixture
270282// keys. With an empty allowlist the post-DCAP check fails fast and
@@ -273,7 +285,7 @@ async fn submit_participant_info__should_store_attestation_on_verified_quote() {
273285// receipt back atomically: nothing is stored, the runtime refunds the attached
274286// deposit to the predecessor, and `fail_attestation_submission` never fires, so
275287// the chain still surfaces a failed receipt. No timeout is involved.
276- #[ ignore = "needs fixture allowlist setup to reach the gas-heavy post-DCAP path; tracked in #3738 " ]
288+ #[ ignore = "needs fixture allowlist setup to reach the gas-heavy post-DCAP path; tracked in #3787 " ]
277289#[ tokio:: test]
278290async fn submit_participant_info__should_fail_and_store_nothing_when_resolve_verification_runs_out_of_gas ( )
279291 {
0 commit comments