Repository navigation
Conversation
On top of the executor profile: - `executor-initdb` creates an `executor` database, as bucket-sync-initdb does, and the executor uses it instead of postgres's default one, where a stack upgraded from the delegatee still holds the delegatee's tables. - `--profile delegatee` still works: it resolves to `executor`, so existing scripts and docs keep starting the stack. - EXECUTOR_RESERVE (default 15m, the executor's own) passes through. The executor batches a renewal at expiry less the reserve, so a project whose coins outlive the reserve by much (ARKD_VTXO_TREE_EXPIRY=3072, say) can renew them as soon as they are due.
arkana-ai-bot
left a comment
There was a problem hiding this comment.
Arkana review — PR #87: executor own database, delegatee alias, reserve passthrough
No protocol-critical paths touched; this is regtest tooling only.
✅ What looks good
executor-initdb (docker/compose.ark.yml +290–310)
Idempotent shell one-liner (SELECT 1 … | grep -q 1 || CREATE DATABASE) matches the pattern used by bucket-sync-initdb. restart: 'no' is set, condition: service_completed_successfully is correct. Hardcoded postgres password is fine for regtest.
Database isolation (compose.ark.yml +323)
Changing EXECUTOR_DATABASE_URL from …/postgres to …/executor is the right call. The stated motivation (avoid migration collisions with tables left by an older delegatee) is sound.
EXECUTOR_RESERVE passthrough (compose.ark.yml +326, .env.defaults +141–143)
The env var threads through correctly with the executor's own default as fallback.
Alias resolution (lib/profiles.mjs +10–11)
delegatee: ['executor'] correctly chains through resolveProfiles without collision: since the Docker Compose delegatee service was removed in #85, the extra --profile delegatee flag Docker Compose receives is silently ignored, so no double-start, no port 7280 conflict.
⚠️ Worth addressing before or shortly after merge
delegatee bleeds into DEFAULT_PROFILES (lib/profiles.mjs +10)
DEFAULT_PROFILES is derived as Object.keys(PROFILE_DEPS).filter(p => p !== 'evm-e2e'). Adding the alias to PROFILE_DEPS causes 'delegatee' to appear in DEFAULT_PROFILES, which is used as the full "start everything" fallback in regtest.mjs:348. In practice this is harmless today (no Docker Compose service matches the profile), but:
DEFAULT_PROFILESgrows by one invisible no-op entry;- if a future service ever re-uses the
delegateeDocker Compose profile name, it would silently start by default.
Consider either filtering it out explicitly:
export const DEFAULT_PROFILES = Object.keys(PROFILE_DEPS)
.filter(p => p !== 'evm-e2e' && p !== 'delegatee');or keeping aliases in a separate map so Object.keys(PROFILE_DEPS) stays equal to the set of real tiers.
.env.defaults comment is ambiguous (line ~141)
# Longer than a coin's life (ARKD_VTXO_TREE_EXPIRY) renews it as soon as it is due.
This reads as "if EXECUTOR_RESERVE > ARKD_VTXO_TREE_EXPIRY, renewal fires immediately", which is true but requires the reader to know the arithmetic. The PR body explains it well (3072 s example); a one-liner like # If set above ARKD_VTXO_TREE_EXPIRY the batch fires as soon as VTXOs are created. would save future confusion.
🔍 Test coverage
test/executor-profile.test.mjs covers the happy paths. Two gaps worth considering:
- No assertion that
resolveProfiles(['delegatee'])does not include any unexpected extras beyond['ark', 'base', 'delegatee', 'emulator', 'executor']. - No assertion that
DEFAULT_PROFILESdoes not include'delegatee'(which would catch the bleed-through described above and lock in the intent).
No security findings. No cross-repo API surface changed. Changes are ready to land as-is; the DEFAULT_PROFILES nit can be a follow-up.
Builds on #85. Three small additions to the executor profile, found while moving a project (Portcullis) from the delegatee to the executor.
Own database.
executor-initdbcreates anexecutordatabase before the executor starts, the same waybucket-sync-initdbdoes for bucket-sync, and the executor'sEXECUTOR_DATABASE_URLpoints at it. In #85 the executor writes to postgres's defaultpostgresdatabase, which is where the delegatee kept its tables. A stack upgraded in place from the delegatee would hand the executor's migrations a database that already holds the delegatee's tables. I haven't hit a collision, but a database of its own rules it out.--profile delegateekeeps working. It now resolves toexecutorinstead of failing with "unknown profile", so existing scripts and docs still start the stack.EXECUTOR_RESERVEpasses through (default15m, the executor's own default, also in.env.defaults). The executor batches a renewal at expiry minus the reserve. With the defaultARKD_VTXO_TREE_EXPIRY=180that is immediate. A project running much longer-lived coins (3072 s) otherwise waits until 15 minutes before expiry, and its renewal tests time out. SettingEXECUTOR_RESERVE=50mrenews them as soon as they're due.Tested
node --test: 8/8. The newtest/executor-profile.test.mjsfails on delegatee -> executor #85 (no alias) and passes here.node regtest.mjs start --env <file> --profile ark --profile emulator --profile delegatee, on a separate project with every host port moved: the active profiles resolve toark, base, emulator, delegatee, executor,executor-initdbexits 0, theexecutordatabase exists,/v1/infoanswers (v0.0.4-rc.1, the fixed regtest cosigner key, server key equal to arkd's signer), the admin port's/v1/admin/healthanswers 200, and the container getsEXECUTOR_RESERVEfrom the env file.