NethermindEth / NethermindEth/juno
Expand usage of `validate` struct tags across RPC methods and clean up redundant custom validation
@thiagodeev is already working on this.
Since May 26, 2026.
- Dominant language
- Go
- Stars
- 444
- Forks
- 244
- Avg merge
- 2d 15h
- Merged PRs (30d)
- 78
Description
Context
We use the go-playground/validator library to validate incoming RPC request structs via struct tags. The validator is integrated into the jsonrpc.Server and each RPC version has its own singleton (rpc/v10/validator.go, rpc/v9/validator.go, rpc/v8/validator.go). When a struct is a handler parameter, the server automatically calls validator.Struct() on it before the handler runs (jsonrpc/server.go#L655-L672).
You can see good examples of validate tags already in use:
rpc/v10/transaction_types.go#L402-L424— theTransactionstruct uses tags likevalidate:"required",validate:"required_if=Type DECLARE",validate:"excluded_unless=Type INVOKE", etc.rpc/v10/transaction_types.go#L449-L454— theBroadcastedTransactionstruct usesvalidate:"required_if=Transaction.Type DECLARE".rpc/v10/events.go#L22—ResultPageRequest.ChunkSizeusesvalidate:"min=1".rpc/v10/estimate_fee.go#L14-L22—MsgFromL1fields usevalidate:"required".rpc/v10/trace.go#L27-L30—TransactionTraceusesvalidate:"required_if=Type INVOKE"on invocation fields.- BroadcastedTx doesn't need a hash field
Task 1: Audit all RPC handler methods for missing validation tag opportunities
Go through every handler method registered in rpc/v10/, rpc/v9/, and rpc/v8/ (you can find the full list in each version's Methods() function) and check the starkent API specification for each one of them (refs for v10, v9, and v8). For each handler, look at the input parameter structs and check:
- Are there fields that should be
requiredbut have no validate tag? - Are there conditional requirements (e.g., "field X is required when Type is Y") that are not expressed via
required_if,required_unless,excluded_unless, etc.? - Are there range/size constraints (like the
min=1onChunkSize) that are not being enforced via tags?
For each finding, make the appropriate improvements.
Task 2: Identify and remove dead/redundant custom validation code
There is already custom validation logic that duplicates what the validate tags should handle. A clear example is in rpc/v10/simulation.go#L261-L272:
func checkTxHasSenderAddress(tx *BroadcastedTransaction) bool {
return (tx.Type == TxnDeclare ||
tx.Type == TxnInvoke) &&
tx.SenderAddress == nil
}
func checkTxHasResourceBounds(tx *BroadcastedTransaction) bool {
return (tx.Type == TxnInvoke ||
tx.Type == TxnDeployAccount ||
tx.Type == TxnDeclare) &&
tx.ResourceBounds == nil
}
These are called in prepareTransactions() (rpc/v10/simulation.go#L283-L301) and are checking conditions that are already expressed in the validate tags on the Transaction struct (rpc/v10/transaction_types.go#L402-L424):
SenderAddresshasvalidate:"required_if=Type DECLARE,required_if=Type INVOKE"(line 412)ResourceBoundshasvalidate:"required"(line 417)
Search the codebase for other patterns like:
- Manual nil checks that mirror
requiredtags - Manual type-conditional checks that mirror
required_iftags - Any
if field == nil { return error }blocks on fields that already have validate tags - Verify existing validate tags are up-to-date. Cross-reference the current validate tags against the Starknet API spec. Some tags may be stale or incorrect — for example, a field that was once optional may now be required (or vice versa), or a
required_ifcondition may reference transaction types that have changed. Compare what the tags enforce vs. what the spec actually demands for each field and transaction type.
For each finding, make the appropriate improvements.
Task 3: Add tests for every validation tag
For every struct that has validate tags (existing or newly added), write unit tests that:
- Test the happy path — a fully valid struct passes validation.
- Test each validate rule — for every tagged field, submit a struct that violates that specific rule and assert the validator returns an error.
- Test conditional rules — for
required_ifandexcluded_unlesstags, test both sides of the condition (e.g., forrequired_if=Type DECLARE, test that the field IS required whenType=DECLAREand is NOT required whenType=INVOKE). - Add a sentinel test that fails when new validate tags are added without corresponding tests.. If someone adds a new validate tag to any struct in the future and doesn't update the test, the test will fail, reminding them to add coverage.
References
- go-playground/validator docs — full list of available built-in tags
rpc/v10/validator.go— custom validator setup withversion_0x3rule and custom type registrations forfelt.FeltandTransactionTypejsonrpc/server.go#L655-L672— where the server callsvalidator.Struct()on handler paramsrpc/handlers_test.go#L78-L137—TestHandlerParamValidatorCompatibilityshows how the validator is tested for type safety across versions
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.