From ead92f1538da8a4f9d325d0d5a7c5cfa7b527b98 Mon Sep 17 00:00:00 2001 From: IAvecilla Date: Mon, 2 Feb 2026 15:07:33 -0300 Subject: [PATCH 1/5] Make AccountNotInitialized fatal and make the log clear --- architectures/decentralized/solana-common/src/retry.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/architectures/decentralized/solana-common/src/retry.rs b/architectures/decentralized/solana-common/src/retry.rs index 03aa23f39..64077ce4c 100644 --- a/architectures/decentralized/solana-common/src/retry.rs +++ b/architectures/decentralized/solana-common/src/retry.rs @@ -82,6 +82,11 @@ impl From for RetryError { } else if msg.contains("InvalidWitness") { error!("InvalidWitness. Fatal Error."); RetryError::Fatal(ClientError::SolanaClientError(e)) + } else if msg.contains("AccountNotInitialized") { + error!( + "AccountNotInitialized error - your authorization account has not been created. Please ensure you have been authorized to join this run." + ); + RetryError::Fatal(ClientError::SolanaClientError(e)) } else if msg.contains("Failed to tick") { warn!("Failed to tick. Retryable Error."); RetryError::Retryable(ClientError::SolanaClientError(e)) From ba184a9dd4bef8ff42d577d71189ac23f23f1b23 Mon Sep 17 00:00:00 2001 From: IAvecilla Date: Mon, 2 Feb 2026 15:13:12 -0300 Subject: [PATCH 2/5] Change error log for AccountNotInitialized --- architectures/decentralized/solana-common/src/retry.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/architectures/decentralized/solana-common/src/retry.rs b/architectures/decentralized/solana-common/src/retry.rs index 64077ce4c..7a9079f58 100644 --- a/architectures/decentralized/solana-common/src/retry.rs +++ b/architectures/decentralized/solana-common/src/retry.rs @@ -84,7 +84,7 @@ impl From for RetryError { RetryError::Fatal(ClientError::SolanaClientError(e)) } else if msg.contains("AccountNotInitialized") { error!( - "AccountNotInitialized error - your authorization account has not been created. Please ensure you have been authorized to join this run." + "Your authorization account has not been created. Please ensure you have been authorized to join this run. Fatal Error." ); RetryError::Fatal(ClientError::SolanaClientError(e)) } else if msg.contains("Failed to tick") { From 2a2c185fa79d04c493956ec552304025b6ca64aa Mon Sep 17 00:00:00 2001 From: IAvecilla Date: Mon, 2 Feb 2026 17:27:09 -0300 Subject: [PATCH 3/5] Use self address as default if no authorizer provided --- .../solana-common/src/backend.rs | 29 ++++++++++++++--- .../run-manager/src/commands/can_join.rs | 32 ++++++++++++++----- 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/architectures/decentralized/solana-common/src/backend.rs b/architectures/decentralized/solana-common/src/backend.rs index b33d7f4c6..8c52afe8d 100644 --- a/architectures/decentralized/solana-common/src/backend.rs +++ b/architectures/decentralized/solana-common/src/backend.rs @@ -258,8 +258,25 @@ impl SolanaBackend { ) -> Result { let coordinator_instance_state = self.get_coordinator_instance(&coordinator_instance).await?; - let authorization = - Self::find_join_authorization(&coordinator_instance_state.join_authority, authorizer); + + // First try permissionless authorization (system_program::ID) + let permissionless_authorization = Self::find_join_authorization( + &coordinator_instance_state.join_authority, + None, + system_program::ID, + ); + + // Check if permissionless authorization exists, otherwise use the provided + // authorizer or fall back to the payer's key + let authorization = if self.get_balance(&permissionless_authorization).await? > 0 { + permissionless_authorization + } else { + Self::find_join_authorization( + &coordinator_instance_state.join_authority, + authorizer, + self.get_payer(), + ) + }; let instruction = instructions::coordinator_join_run( &coordinator_instance, &coordinator_account, @@ -346,10 +363,14 @@ impl SolanaBackend { self.spawn_scheduled_send("Checkpoint", &[instruction], &[]); } - pub fn find_join_authorization(join_authority: &Pubkey, authorizer: Option) -> Pubkey { + pub fn find_join_authorization( + join_authority: &Pubkey, + authorizer: Option, + authorizer_fallback: Pubkey, + ) -> Pubkey { psyche_solana_authorizer::find_authorization( join_authority, - &authorizer.unwrap_or(system_program::ID), + &authorizer.unwrap_or(authorizer_fallback), psyche_solana_coordinator::logic::JOIN_RUN_AUTHORIZATION_SCOPE, ) } diff --git a/tools/rust-tools/run-manager/src/commands/can_join.rs b/tools/rust-tools/run-manager/src/commands/can_join.rs index 64a6469dd..8befb4a90 100644 --- a/tools/rust-tools/run-manager/src/commands/can_join.rs +++ b/tools/rust-tools/run-manager/src/commands/can_join.rs @@ -1,4 +1,5 @@ use crate::commands::Command; +use anchor_client::anchor_lang::system_program; use anchor_client::solana_sdk::pubkey::Pubkey; use anyhow::Result; use anyhow::bail; @@ -33,16 +34,31 @@ impl Command for CommandCanJoin { .get_coordinator_instance(&coordinator_instance) .await?; - let authorization = SolanaBackend::find_join_authorization( + // First try permissionless authorization (system_program::ID) + let permissionless_authorization = SolanaBackend::find_join_authorization( &coordinator_instance_state.join_authority, - authorizer, + None, + system_program::ID, ); - if backend.get_balance(&authorization).await? == 0 { - bail!( - "Authorization does not exist for authorizer: {authorizer:?} (authorization address: {authorization:?}, join authority: {0:?}). Authorizer must be set to grantee pubkey for permissioned runs", - coordinator_instance_state.join_authority + + // Check if permissionless authorization exists, otherwise use the provided + // authorizer or fall back to the address + let authorization = if backend.get_balance(&permissionless_authorization).await? > 0 { + permissionless_authorization + } else { + let fallback_authorization = SolanaBackend::find_join_authorization( + &coordinator_instance_state.join_authority, + authorizer, + address, ); - } + if backend.get_balance(&fallback_authorization).await? == 0 { + bail!( + "Authorization does not exist for authorizer: {authorizer:?} (authorization address: {fallback_authorization:?}, join authority: {0:?}). Authorizer must be set to grantee pubkey for permissioned runs", + coordinator_instance_state.join_authority + ); + } + fallback_authorization + }; if !backend .get_authorization(&authorization) .await? @@ -54,7 +70,7 @@ impl Command for CommandCanJoin { { bail!("Authorization invalid for run id {run_id} using pubkey {address}"); } - println!("authorization valid for run id {run_id} using pubkey {address}"); + println!("Authorization valid for run id {run_id} using pubkey {address}"); let coordinator_account_state = backend .get_coordinator_account(&coordinator_instance_state.coordinator_account) From 92139186bc4026a1a6af1c05e515ab84f80f1eaa Mon Sep 17 00:00:00 2001 From: IAvecilla Date: Tue, 3 Feb 2026 12:19:01 -0300 Subject: [PATCH 4/5] Check for AccountNotInitialized error only for authorization --- architectures/decentralized/solana-common/src/retry.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/architectures/decentralized/solana-common/src/retry.rs b/architectures/decentralized/solana-common/src/retry.rs index 7a9079f58..a41487299 100644 --- a/architectures/decentralized/solana-common/src/retry.rs +++ b/architectures/decentralized/solana-common/src/retry.rs @@ -82,7 +82,9 @@ impl From for RetryError { } else if msg.contains("InvalidWitness") { error!("InvalidWitness. Fatal Error."); RetryError::Fatal(ClientError::SolanaClientError(e)) - } else if msg.contains("AccountNotInitialized") { + } else if msg.contains("AccountNotInitialized") + && msg.contains("authorization") + { error!( "Your authorization account has not been created. Please ensure you have been authorized to join this run. Fatal Error." ); From 7a74174aaab999794d9ccc90f76a99ccd2d44f19 Mon Sep 17 00:00:00 2001 From: IAvecilla Date: Tue, 3 Feb 2026 13:09:15 -0300 Subject: [PATCH 5/5] Try permissionless only if no authorizer is provided --- .../solana-common/src/backend.rs | 38 +++++++-------- .../run-manager/src/commands/can_join.rs | 47 +++++++++++-------- 2 files changed, 45 insertions(+), 40 deletions(-) diff --git a/architectures/decentralized/solana-common/src/backend.rs b/architectures/decentralized/solana-common/src/backend.rs index 8c52afe8d..2b0bf8a5e 100644 --- a/architectures/decentralized/solana-common/src/backend.rs +++ b/architectures/decentralized/solana-common/src/backend.rs @@ -259,23 +259,23 @@ impl SolanaBackend { let coordinator_instance_state = self.get_coordinator_instance(&coordinator_instance).await?; - // First try permissionless authorization (system_program::ID) - let permissionless_authorization = Self::find_join_authorization( - &coordinator_instance_state.join_authority, - None, - system_program::ID, - ); - - // Check if permissionless authorization exists, otherwise use the provided - // authorizer or fall back to the payer's key - let authorization = if self.get_balance(&permissionless_authorization).await? > 0 { - permissionless_authorization + // If an authorizer is explicitly provided, use it directly. + // Otherwise, try permissionless first, then fall back to payer's key. + let authorization = if authorizer.is_some() { + Self::find_join_authorization(&coordinator_instance_state.join_authority, authorizer) } else { - Self::find_join_authorization( + let permissionless_authorization = Self::find_join_authorization( &coordinator_instance_state.join_authority, - authorizer, - self.get_payer(), - ) + Some(system_program::ID), + ); + if self.get_balance(&permissionless_authorization).await? > 0 { + permissionless_authorization + } else { + Self::find_join_authorization( + &coordinator_instance_state.join_authority, + Some(self.get_payer()), + ) + } }; let instruction = instructions::coordinator_join_run( &coordinator_instance, @@ -363,14 +363,10 @@ impl SolanaBackend { self.spawn_scheduled_send("Checkpoint", &[instruction], &[]); } - pub fn find_join_authorization( - join_authority: &Pubkey, - authorizer: Option, - authorizer_fallback: Pubkey, - ) -> Pubkey { + pub fn find_join_authorization(join_authority: &Pubkey, authorizer: Option) -> Pubkey { psyche_solana_authorizer::find_authorization( join_authority, - &authorizer.unwrap_or(authorizer_fallback), + &authorizer.unwrap_or(system_program::ID), psyche_solana_coordinator::logic::JOIN_RUN_AUTHORIZATION_SCOPE, ) } diff --git a/tools/rust-tools/run-manager/src/commands/can_join.rs b/tools/rust-tools/run-manager/src/commands/can_join.rs index 8befb4a90..77fe02a8a 100644 --- a/tools/rust-tools/run-manager/src/commands/can_join.rs +++ b/tools/rust-tools/run-manager/src/commands/can_join.rs @@ -1,5 +1,4 @@ use crate::commands::Command; -use anchor_client::anchor_lang::system_program; use anchor_client::solana_sdk::pubkey::Pubkey; use anyhow::Result; use anyhow::bail; @@ -34,30 +33,40 @@ impl Command for CommandCanJoin { .get_coordinator_instance(&coordinator_instance) .await?; - // First try permissionless authorization (system_program::ID) - let permissionless_authorization = SolanaBackend::find_join_authorization( - &coordinator_instance_state.join_authority, - None, - system_program::ID, - ); - - // Check if permissionless authorization exists, otherwise use the provided - // authorizer or fall back to the address - let authorization = if backend.get_balance(&permissionless_authorization).await? > 0 { - permissionless_authorization - } else { - let fallback_authorization = SolanaBackend::find_join_authorization( + // If an authorizer is explicitly provided, use it directly. + // Otherwise, try permissionless first, then fall back to the user's address. + let authorization = if let Some(auth) = authorizer { + let authorization = SolanaBackend::find_join_authorization( &coordinator_instance_state.join_authority, - authorizer, - address, + Some(auth), ); - if backend.get_balance(&fallback_authorization).await? == 0 { + if backend.get_balance(&authorization).await? == 0 { bail!( - "Authorization does not exist for authorizer: {authorizer:?} (authorization address: {fallback_authorization:?}, join authority: {0:?}). Authorizer must be set to grantee pubkey for permissioned runs", + "Authorization does not exist for authorizer: {auth} (authorization address: {authorization}, join authority: {}). Authorizer must be set to grantee pubkey for permissioned runs", coordinator_instance_state.join_authority ); } - fallback_authorization + authorization + } else { + let permissionless_authorization = SolanaBackend::find_join_authorization( + &coordinator_instance_state.join_authority, + None, + ); + if backend.get_balance(&permissionless_authorization).await? > 0 { + permissionless_authorization + } else { + let fallback_authorization = SolanaBackend::find_join_authorization( + &coordinator_instance_state.join_authority, + Some(address), + ); + if backend.get_balance(&fallback_authorization).await? == 0 { + bail!( + "No valid authorization found for {address}. The run is permissioned and you must have a valid authorization. (join authority: {})", + coordinator_instance_state.join_authority + ); + } + fallback_authorization + } }; if !backend .get_authorization(&authorization)