Skip to content

feat(ant-core): Client::finalize_chunk for external-signer single-chunk publish#89

Merged
Nic-dorman merged 2 commits into
WithAutonomi:mainfrom
Nic-dorman:feat/external-signer-finalize-chunk
May 13, 2026
Merged

feat(ant-core): Client::finalize_chunk for external-signer single-chunk publish#89
Nic-dorman merged 2 commits into
WithAutonomi:mainfrom
Nic-dorman:feat/external-signer-finalize-chunk

Conversation

@Nic-dorman
Copy link
Copy Markdown
Contributor

@Nic-dorman Nic-dorman commented May 13, 2026

Summary

Adds Client::finalize_chunk(prepared, tx_hash_map) -> XorName on ant-core's data client. Single-chunk analogue of Client::finalize_upload: takes a PreparedChunk (from prepare_chunk_payment) and a quote_hash -> tx_hash map, builds the PaymentProof via the existing finalize_batch_payment helper, stores on CLOSE_GROUP_MAJORITY peers via the existing chunk_put_to_close_group primitive, and returns the BLAKE3 address.

Wave-batch only. Single-chunk publishes don't need merkle batching — one chunk's worth of quotes is well below the wave-batch threshold.

Why

prepare_chunk_payment already exists publicly (ant-core/src/data/client/batch.rs:167) but the second half of the external-signer flow — paying then storing — is gated behind pub(crate) helpers (chunk_put_to_close_group, store_paid_chunks_with_events). Downstream daemons can collect quotes but can't finish the upload without re-implementing the close-group fallback logic. This PR exposes the composition under a single public method that mirrors the file-level finalize_upload.

Concrete consumer: WithAutonomi/ant-sdk will add POST /v1/chunks/prepare + POST /v1/chunks/finalize REST endpoints on top of this, so daemons running wallet-less (e.g. Indelible) can publish single chunks paid by their own EVM signer rather than the daemon's.

What's not in this PR

  • No new types — composes PreparedChunk, finalize_batch_payment, chunk_put_to_close_group that already exist.
  • No merkle path — explicit out-of-scope. Single chunks are always wave-batch.
  • No antd-side wiring — that's the next PR, in ant-sdk.

Test plan

  • cargo build -p ant-core clean
  • cargo test -p ant-core --lib data::client::chunk — 3 existing chunk tests pass
  • Full cargo test -p ant-core — 248 tests pass
  • Reviewer: end-to-end smoke against a real network via the antd PR once it's up

🤖 Generated with Claude Code

Nic-dorman and others added 2 commits May 12, 2026 11:40
Add --port and --listen-addr flags to `ant node daemon start` and the
hidden `daemon run` so the node-management HTTP API can be pinned to a
predictable bind. Default behaviour is unchanged (loopback,
OS-assigned). Flags are forwarded from the detached `start` path
through to the spawned `run` child via a new `daemon_run_args` helper.

Use case: running the daemon inside a container with a `-p` mapping.
Example: `ant node daemon start --listen-addr 0.0.0.0 --port 8765`.

The daemon has no authentication, so the README and clap help text
flag the security implications of binding to a non-loopback address.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Nic-dorman Nic-dorman merged commit c0f6a81 into WithAutonomi:main May 13, 2026
12 checks passed
Nic-dorman added a commit to WithAutonomi/ant-sdk that referenced this pull request May 13, 2026
* ci: authenticate arduino/setup-protoc on ci.yml too

Mirrors PR #31's release.yml fix — without `repo-token`, the action
issues the GitHub release-list API call anonymously and shares the
~60/hr per-IP quota with every other runner on the same egress IP.
release.yml has had the auth since 2026-04-28; ci.yml didn't, and
PR #57's post-merge CI run flaked here on 2026-05-06 (run 25447450352
job 'API contract tests (antd-rust)' — exact `arduino/setup-protoc@v3
... API rate limit exceeded` message reproduced from PR #31's
investigation).

Adds `repo-token: \${{ secrets.GITHUB_TOKEN }}` to both occurrences
in ci.yml — the Check (antd) job at line 33 and the API contract tests
job at line 75. No semantic change to either workflow; just shifts
the action onto our 5,000/hr token quota.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(antd, antd-go): external-signer single-chunk publish

Adds `POST /v1/chunks/prepare` + `POST /v1/chunks/finalize` to the antd REST
surface and `PrepareChunkUpload` + `FinalizeChunkUpload` to antd-go, giving
external signers a way to publish a single chunk paid through their own EVM
wallet rather than the daemon's.

## antd (Rust)

- `state.rs`: new `pending_chunks: Mutex<HashMap<String, TimestampedChunk>>`
  map alongside `pending_uploads`, with matching `cleanup_stale_chunks`.
  Single periodic cleanup task in `main.rs` now sweeps both.
- `types.rs`: `PrepareChunkRequest/Response` + `FinalizeChunkRequest/Response`.
  Response uses `skip_serializing_if` heavily so an already-on-network reply
  (`already_stored: true`) carries only `address` — no upload_id, no payments.
- `rest/chunks.rs::chunk_prepare`: calls `Client::prepare_chunk_payment`,
  computes the BLAKE3 address up-front (so the already-stored exit can still
  return it), filters zero-amount quotes from the external-signer payment
  list, and stashes the PreparedChunk under a fresh upload_id.
- `rest/chunks.rs::chunk_finalize`: looks up by upload_id, parses tx_hashes,
  calls the new `Client::finalize_chunk`, returns the chunk address.

Unlike `POST /v1/chunks` (which requires `AUTONOMI_WALLET_KEY` on the daemon),
neither new endpoint touches the daemon's wallet — funds flow through the
external signer.

## antd-go

- New `PrepareChunkResult` type mirroring the response shape.
- `PrepareChunkUpload(ctx, content)` + `FinalizeChunkUpload(ctx, uploadID, txHashes)`.
- `boolField` helper joins the existing `str`/`num64`/`unum64` helpers.
- Three new httptest-backed tests: happy-path prepare, already-stored prepare,
  finalize round-trip.

## Dep pin

`antd/Cargo.toml` pins ant-core to the merge commit of WithAutonomi/ant-client#89
(`c0f6a81`) which adds the `Client::finalize_chunk` primitive this PR consumes.
The pin should be bumped to a tag once ant-core cuts a release containing
that commit; the rev pin keeps reproducibility in the meantime.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* style: cargo fmt fixes for chunks prepare/finalize

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants