Repository navigation
Description
What would you like?
Add Address Lookup Table roles to the fee-payer drain property test, so the ALT policy matrix is machine-checked rather than relying on hand-written one-flag-at-a-time cases.
Background. The [validation.fee_payer_policy.*] flags in kora.toml decide when the fee payer (the paymaster's own key, which signs every transaction) may appear in a privileged slot of an instruction. Every flag defaults to false. The invariant under test:
The fee payer is gated in a given role exactly when that role's flag is off, and a non-fee-payer is never gated.
The harness already exists. Add one file:
crates/lib/src/validator/transaction_validator/fee_payer_policy_props/alt.rs
implementing the DrainRole trait, and declare it with mod alt; in that directory's mod.rs. system.rs in the same directory is the reference implementation: copy its shape, including the proptest! block at the bottom.
impl DrainRole for AltRole {
const ROLES: &'static [Self] = &[/* one variant per gated account slot */];
fn allowed_programs() -> Vec<String> { /* ALT program id */ }
fn flag(self, policy: &mut FeePayerPolicy) -> &mut bool { /* &mut policy.alt.* */ }
fn instruction(self, actor: &Pubkey) -> Instruction { /* put `actor` in the gated slot */ }
}Flags to cover (5): allow_create, allow_extend, allow_freeze, allow_deactivate, allow_close.
Which slot the validator gates (see validate_fee_payer_usage in crates/lib/src/validator/transaction_validator.rs):
| Instruction | Gated slots |
|---|---|
| CreateLookupTable | authority or payer |
| ExtendLookupTable | authority or payer (payer is optional) |
| FreezeLookupTable | authority |
| DeactivateLookupTable | authority |
| CloseLookupTable | authority |
Where a flag gates more than one slot, add one role variant per slot. system.rs does this with CreateAccountPayer / CreateAccountNewAccount, both mapping to the same flag.
Acceptance criteria
- Every flag above has at least one role, and the two-slot flags have one role per slot.
cargo test -p kora-lib --lib fee_payer_policy_propspasses.just checkis clean.- Mutation proof in the PR description. Point one role's
flag()at a different policy field, show the property failing, then revert. A property test that cannot fail is worse than no test, and this is the one thing review cannot easily verify by reading.
Notes
- Instruction builders live in
solana_address_lookup_table_interface, already used by the unit tests intransaction_validator.rs.create_lookup_tablereturns the instruction alongside the derived table address. - ALT has no unconditional drainage guard, so every case reaches the flag gate. (Some other program types do have one, which is why their issues carry extra warnings.)
- If your property fails against current code, that is a possible fee-payer drain gap, not a PR. Do not post the reproducer, the failing seed, or the
proptest-regressionsfile. Report it privately via the advisory link inSECURITY.md. - Comment to claim. One program type per contributor, please, so the files stay independent.
Area
Transaction handling
Activity
linear commentedon Aug 20, 2026
TOO-621
RlxChap2 commentedon Aug 22, 2026
Claiming this issue. Iβve implemented the ALT role coverage, including the two-slot Create and Extend cases, and verified the requested mutation proof. Iβll open the PR shortly.