Skip to content

implemented cleanup pda script#36

Open
Akash-Kumar-Sinha wants to merge 1 commit into
entros-protocol:developfrom
Akash-Kumar-Sinha:cleanup-pdas
Open

implemented cleanup pda script#36
Akash-Kumar-Sinha wants to merge 1 commit into
entros-protocol:developfrom
Akash-Kumar-Sinha:cleanup-pdas

Conversation

@Akash-Kumar-Sinha
Copy link
Copy Markdown

Implemented cleanup pdas script

Copy link
Copy Markdown
Member

@zkr99 zkr99 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solid shape - matches the blueprint. Discriminator + offset memcmp filtering is the right approach, the summary output is informative, and the signer-must-match-target check is correct from a Solana mechanics standpoint (the program's close instructions require the owner to sign, so an operator can't run this for someone else's wallet).

Three blockers before merge, plus a few inline polish notes.

Blockers:

  1. Branch is stale. Your cleanup-pdas branch predates Pluto's recent PRs (#29, #30, #31, #32, #35) and the org rebrand (#33, #34). package.json shows litesvm-initial and trustscore.ts which were renamed in PR #29. Rebase against current develop:
git fetch origin develop
git rebase origin/develop
git push --force-with-lease
  1. IDL path doesn't exist on current develop. The Rust crate was renamed iam_verifier -> entros_verifier in PR #33, so Anchor outputs the IDL at target/idl/entros_verifier.json, not iam_verifier.json. Script throws ENOENT at runtime as written. Inline note on the line.

  2. Filter logic contradicts the program's close_challenge constraint. Closing an expired-but-unused challenge fails on-chain with ChallengeNotUsed, because close_challenge requires challenge.used == true. Your filter used || expiresAt <= nowTs includes the unused-expired case, which silently fails in the try/catch and logs spurious errors. Fix inline.

Polish items inline. Once the three blockers land, ready to take another look.

Comment thread scripts/cleanup-pdas.ts
import * as fs from "fs";
import * as path from "path";

const IAM_VERIFIER_PROGRAM_ID = new anchor.web3.PublicKey(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale naming from before the org rebrand. Pluto's PR #35 swept all IAM_* references to ENTROS_* across the codebase. Rename to ENTROS_VERIFIER_PROGRAM_ID. The pubkey itself stays the same (programs were upgraded in place during the rebrand), just the variable name changes.

Comment thread scripts/cleanup-pdas.ts
);
}

const idlPath = path.resolve(__dirname, "../target/idl/iam_verifier.json");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file doesn't exist on current develop. The Rust crate was renamed in PR #33, so Anchor outputs the IDL at target/idl/entros_verifier.json. Script throws ENOENT at runtime. After rebasing:

const idlPath = path.resolve(__dirname, '../target/idl/entros_verifier.json');

Comment thread scripts/cleanup-pdas.ts
const closeableChallenges = challengeAccounts.filter(({ account }) => {
const expiresAt = readI64LE(account.data, EXPIRES_AT_OFFSET);
const used = readBool(account.data, USED_OFFSET);
return used || expiresAt <= nowTs;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This filter doesn't match the program's contract. close_challenge at programs/entros-verifier/src/lib.rs:205 constrains challenge.used and returns ChallengeNotUsed (6005) for unused challenges regardless of expiry. The current logic flags expired-unused challenges as closeable, which silently fails in the try/catch below and logs spurious errors. Fix:

return used;

Expired-unused challenges are a known protocol gap (no instruction exists to close them) - not this script's job to solve.

Comment thread scripts/cleanup-pdas.ts
return used || expiresAt <= nowTs;
});

const verificationAccounts = await provider.connection.getProgramAccounts(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VR closes every result owned by the signer with no filter. The program doesn't constrain this (just the ownership check at programs/entros-verifier/src/lib.rs:218), so it works, but a fresh VR still bound to the current identity.current_commitment represents an unspent proof - closing it discards work the user paid CU for.

Consider filtering for either:

  • VRs whose commitment_prev (offset 56, 32 bytes) no longer matches the current identity state's current_commitment - i.e. already consumed by update_anchor
  • VRs whose verified_at (offset 49, 8 bytes i64) is older than MAX_PROOF_AGE_SECS (600s) and therefore expired anyway

At minimum, add a header comment noting the script is destructive to unspent proofs.

Comment thread package.json
"private": true,
"scripts": {
"test": "anchor test",
"cleanup-pdas": "npx --yes tsx scripts/cleanup-pdas.ts",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

npx --yes tsx silently installs tsx at runtime - slow on first run, no version pinning, and the --yes skips the install confirmation prompt. Add tsx to devDependencies and use it directly:

"cleanup-pdas": "tsx scripts/cleanup-pdas.ts"

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