fix(core): preserve remote transaction errors - #764
Conversation
Greptile SummaryThe PR distinguishes valid remote
Confidence Score: 3/5This PR should not merge until provider-controlled RPC error text is sanitized without exposing credential-bearing datasource path or query fragments. The new fallible path correctly preserves provider failures, but it also forwards arbitrary RpcError text to client-visible error data after an exact full-URL replacement that does not remove reflected URL fragments. Files Needing Attention: crates/core/src/surfnet/remote.rs
|
| Filename | Overview |
|---|---|
| crates/core/src/error.rs | Adds a transaction-specific internal error constructor that includes the signature and sanitized remote failure text in JSON-RPC error data. |
| crates/core/src/surfnet/locker.rs | Switches remote transaction fallback to the new fallible method so genuine provider failures reach callers. |
| crates/core/src/surfnet/remote.rs | Separates null responses from transport/provider errors and adds sanitization, but provider-controlled RpcError fragments can still disclose path or query credentials. |
Reviews (1): Last reviewed commit: "fix(core): preserve remote transaction e..." | Re-trigger Greptile
| error.line(), | ||
| error.column() | ||
| ), | ||
| ClientErrorKind::RpcError(error) => error.to_string().replace(datasource_url, &endpoint), |
There was a problem hiding this comment.
When a provider returns a JSON-RPC error containing only a credential-bearing request path or query fragment, the exact full-URL replacement leaves that fragment intact, causing datasource credentials to be disclosed in client-visible error data. How this was verified: The provider message flows from this RpcError branch into SurfpoolError.data and the public RPC response without another redaction step.
Knowledge Base Used: Surfnet Engine (SVM, Locker, Remote Fetch)
Summary
Surfpool's remote
getTransactionpath previously treated every client error as a missing transaction. This conflated two different RPC outcomes:null, meaning the transaction is unavailable; andThe Solana RPC client convenience method deserializes directly into a concrete transaction, so a valid
nullarrives through its error path too.Change
getTransactionresponse asOption<EncodedConfirmedTransactionWithStatusMeta>.nullmapped toGetTransactionResult::None.SurfpoolResultboundary.SurfnetRemoteClient::get_transactionreturn type with a compatibility wrapper; the new fallible method is crate-private.Regression coverage
nullresponse remainsNoneand verifies the exact outgoingGetTransactionrequest/config.None.401 Unauthorizedand the sanitized host but omits every secret.Validation
cargo test -p surfpool-core surfnet::remote::tests::a_ -- --test-threads=1— 5 passedcargo test -p surfpool-core --no-default-features surfnet::remote::tests::a_ -- --test-threads=1— 5 passedcargo +nightly fmt --all -- --checkcargo clippy -p surfpool-core --lib --no-default-features— completed with existing repository warnings onlygit diff --checkThis branch and #762 both add tests to
surfnet/remote.rs; whichever lands second may need a trivial rebase, but the production changes are independent.