fix: wait out processing until the certificate exists
A global stamp now polls status processing the same way as pending and returns only the completed result. The debug trace for Verae-Debug-Test records one receipt id.
This commit is contained in:
parent
c547804835
commit
b89c4ad4d2
5 changed files with 4446 additions and 6 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -375,14 +375,14 @@ class GlobalClient:
|
||||||
raise ValueError(f"global timestamp HTTP {res.status_code}: {res.text}")
|
raise ValueError(f"global timestamp HTTP {res.status_code}: {res.text}")
|
||||||
if not isinstance(parsed, dict):
|
if not isinstance(parsed, dict):
|
||||||
parsed = {}
|
parsed = {}
|
||||||
job_id = parsed.get("jobId") or parsed.get("blockHash") or ""
|
job_id = str(parsed.get("jobId") or parsed.get("blockHash") or "")
|
||||||
if not job_id:
|
if not job_id:
|
||||||
raise ValueError("global timestamp response missing jobId")
|
raise ValueError("global timestamp response missing jobId")
|
||||||
created = str(parsed.get("timestamp") or "")
|
created = str(parsed.get("timestamp") or "")
|
||||||
merkle = str(parsed.get("blockHash") or "")
|
merkle = str(parsed.get("blockHash") or "")
|
||||||
receipt_id = str(job_id)
|
receipt_id = ""
|
||||||
status_url = f"{self.base_url}/api/status/{job_id}"
|
status_url = f"{self.base_url}/api/status/{job_id}"
|
||||||
for _ in range(20):
|
for _ in range(40):
|
||||||
st = self.http.request("GET", status_url, payload={}, headers=self._headers())
|
st = self.http.request("GET", status_url, payload={}, headers=self._headers())
|
||||||
if st.status_code >= 300:
|
if st.status_code >= 300:
|
||||||
break
|
break
|
||||||
|
|
@ -393,15 +393,19 @@ class GlobalClient:
|
||||||
if state == "failed":
|
if state == "failed":
|
||||||
raise ValueError(str(body.get("error") or "global timestamp job failed"))
|
raise ValueError(str(body.get("error") or "global timestamp job failed"))
|
||||||
if state == "completed":
|
if state == "completed":
|
||||||
receipt_id = str(body.get("result") or body.get("id") or job_id)
|
receipt_id = str(body.get("result") or "")
|
||||||
meta = body.get("metadata") or {}
|
meta = body.get("metadata") or {}
|
||||||
created = str(meta.get("timestamp") or body.get("completedAt") or created)
|
created = str(meta.get("timestamp") or body.get("completedAt") or created)
|
||||||
merkle = str(meta.get("blockIndex") or meta.get("blockHash") or merkle)
|
merkle = str(meta.get("blockIndex") or meta.get("blockHash") or merkle)
|
||||||
break
|
if receipt_id:
|
||||||
if state in ("pending", "running", ""):
|
break
|
||||||
|
receipt_id = ""
|
||||||
|
if state in ("pending", "running", "processing", ""):
|
||||||
time.sleep(0.25)
|
time.sleep(0.25)
|
||||||
continue
|
continue
|
||||||
break
|
break
|
||||||
|
if not receipt_id:
|
||||||
|
raise ValueError(f"global timestamp job {job_id} not completed")
|
||||||
return Receipt(
|
return Receipt(
|
||||||
receipt_id=receipt_id,
|
receipt_id=receipt_id,
|
||||||
hash=digest,
|
hash=digest,
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,38 @@ async def test_existing_digest_returns_first_certificate_without_status_poll():
|
||||||
assert len(http.calls) == 1
|
assert len(http.calls) == 1
|
||||||
|
|
||||||
|
|
||||||
|
async def test_processing_status_polls_until_certificate():
|
||||||
|
class ProcessingHttp(FakeHttp):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.status_calls = 0
|
||||||
|
|
||||||
|
def request(self, method, url, payload, headers):
|
||||||
|
self.calls.append((method, url, payload, headers))
|
||||||
|
if url.endswith("/api/timestamp"):
|
||||||
|
return _Resp(202, {"jobId": "job-p"})
|
||||||
|
if url.endswith("/api/status/job-p"):
|
||||||
|
self.status_calls += 1
|
||||||
|
if self.status_calls < 3:
|
||||||
|
return _Resp(200, {"id": "job-p", "status": "processing"})
|
||||||
|
return _Resp(
|
||||||
|
200,
|
||||||
|
{
|
||||||
|
"id": "job-p",
|
||||||
|
"status": "completed",
|
||||||
|
"result": "QmDone",
|
||||||
|
"metadata": {"timestamp": "2026-09-23T00:00:00Z", "blockHash": "0xabc"},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return _Resp(404, {"error": "nope"})
|
||||||
|
|
||||||
|
http = ProcessingHttp()
|
||||||
|
rec = GlobalClient("https://api.veraetime.net", http=http).submit(SHA256_EMPTY)
|
||||||
|
assert rec.receipt_id == "QmDone"
|
||||||
|
assert rec.receipt_id != "job-p"
|
||||||
|
assert http.status_calls == 3
|
||||||
|
|
||||||
|
|
||||||
async def test_existing_without_certificate_polls_job():
|
async def test_existing_without_certificate_polls_job():
|
||||||
class PendingExisting(FakeHttp):
|
class PendingExisting(FakeHttp):
|
||||||
def request(self, method, url, payload, headers):
|
def request(self, method, url, payload, headers):
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue