Skip to content

smartcontract,sdk: fix user update tenant reassignment for initial assignment#3707

Merged
juan-malbeclabs merged 1 commit into
mainfrom
jo/fix_user_update
May 15, 2026
Merged

smartcontract,sdk: fix user update tenant reassignment for initial assignment#3707
juan-malbeclabs merged 1 commit into
mainfrom
jo/fix_user_update

Conversation

@juan-malbeclabs
Copy link
Copy Markdown
Contributor

Summary of Changes

  • Fix user update failing with Invalid Old Tenant Account Owner when the user being reassigned has no current tenant (user.tenant_pk == Pubkey::default()). The SDK was pushing Pubkey::default() (the System Program ID) as the old tenant account, and the program asserted that account was owned by the serviceability program, which fails because the System Program account is owned by NativeLoader1111111111111111111111111111111.
  • Rust SDK now omits the old-tenant AccountMeta when the user has no current tenant; it still pushes the new tenant.
  • Serviceability process_update_user accepts three remaining-account layouts ([payer, system], [new_tenant, payer, system], [old_tenant, new_tenant, payer, system]), increments the new tenant's reference count whenever tenant_pk is set, and decrements the old tenant's reference count only when the user currently has one. Existing tenant-reassignment behavior is unchanged.

Diff Breakdown

Category Files Lines (+/-) Net
Core logic 2 +50 / -59 -9
Tests 1 +170 / -0 +170
Docs 1 +1 / -0 +1
Total 3 +221 / -59 +162

Net diff is dominated by new SDK unit tests covering the initial-assignment and reassignment paths; the actual behavior change is small.

Key files (click to expand)
  • smartcontract/sdk/rs/src/commands/user/update.rs - gate the old_tenant AccountMeta push on user.tenant_pk != Pubkey::default(); add test_commands_user_update_tenant_initial_assignment_omits_old_tenant and test_commands_user_update_tenant_reassignment_includes_old_and_new.
  • smartcontract/programs/doublezero-serviceability/src/processors/user/update.rs - replace the binary "tenants present / absent" branch with a 3-way layout match (2/3/4 remaining accounts); restructure the if let Some(new_tenant_pk) block to mandate the new-tenant account and conditionally validate/decrement the old tenant only when user.tenant_pk != Pubkey::default(); reuse validate_program_account! for owner+writability checks.
  • CHANGELOG.md - add Unreleased entry describing the fix.

Testing Verification

  • cargo test -p doublezero_sdk --lib commands::user::update - 5/5 tests pass, including the two new tenant-update tests.
  • cargo test -p doublezero-serviceability --tests - all serviceability integration test suites pass (user, tenant, accesspass, onchain-allocation, etc.).
  • Reproduced the original failure on testnet (panic at update.rs:354 with left: NativeLoader1111111111111111111111111111111). End-to-end verification on testnet requires redeploying the serviceability program with this fix.

Note: this branch does not include the CLI --tenant flag itself (that lives on jo/set_user_tenant). The fix is only reachable through the CLI once both land.

@juan-malbeclabs juan-malbeclabs enabled auto-merge (squash) May 14, 2026 20:38
@elitegreg
Copy link
Copy Markdown
Contributor

I approve, but did you consider checking in the program if the old tenant account is Pubkey::default() before checking the ownership? Seems a little simpler.

Allows initial tenant assignment: when the user has no prior tenant
(tenant_pk == Pubkey::default()), the SDK passes the placeholder readonly
and the processor skips old tenant validation, ownership, writability
and reference count decrement. The new tenant is always processed.

Adds integration tests for both initial assignment and reassignment paths.
@juan-malbeclabs juan-malbeclabs merged commit fbbe4d6 into main May 15, 2026
32 of 33 checks passed
@juan-malbeclabs juan-malbeclabs deleted the jo/fix_user_update branch May 15, 2026 12:03
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