Skip to content

refactor: fix state unavailability handling in DebugRpcModule #8432

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 15 commits into
base: master
Choose a base branch
from

Conversation

crStiv
Copy link

@crStiv crStiv commented Mar 27, 2025

Fixes #8174

Changes

  • Added IStateReader parameter to DebugRpcModule constructor
  • Updated DebugModuleFactory to pass IStateReader to DebugRpcModule
  • Added GetStateFailureResult method to provide clear error message when state is unavailable
  • Added state availability checks using HasStateForBlock before executing trace operations in all appropriate debug_* methods
  • Used existing StateReaderExtensions.HasStateForBlock method for consistency with other modules

Types of changes

What types of changes does your code introduce?

  • Bugfix (a non-breaking change that fixes an issue)
  • New feature (a non-breaking change that adds functionality)
  • Breaking change (a change that causes existing functionality not to work as expected)
  • Optimization
  • Refactoring
  • Documentation update
  • Build-related changes
  • Other: Description

Testing

Requires testing

  • Yes
  • No

If yes, did you write tests?

  • Yes
  • No

Documentation

Requires documentation update

  • Yes
  • No

Requires explanation in Release Notes

  • Yes
  • No

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors the DebugRpcModule to improve state unavailability handling by adding state checks and a dedicated error method, and updates related factory and extension methods.

  • Added IStateReader parameter and state availability checks in DebugRpcModule
  • Introduced GetStateFailureResult for uniform error responses when state is missing
  • Updated DebugModuleFactory to pass the IStateReader instance

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
src/Nethermind/Nethermind.State/StateReaderExtensions.cs Added a new GetAccount extension method to retrieve account details without verifying the success of TryGetAccount
src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs Updated various debug_trace* methods to include state availability checks and modified error handling in debug_resetHead and others
src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugModuleFactory.cs Updated the factory to pass IStateReader from the world state manager
Comments suppressed due to low confidence (2)

src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs:399

  • In debug_resetHead, returning a success with a null result when the transaction is not found deviates from the previous error handling pattern. Confirm that this change in behavior is intentional and, if not, consider reverting to a failure response with an appropriate error message.
return ResultWrapper<string?>.Success(null);

src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs:414

  • The updated debug_getRawReceipts method no longer applies the specific RlpBehaviors (e.g., Eip658Receipts) previously used for encoding. Verify that using the default Rlp.Encode is acceptable for all cases or reintroduce the necessary encoding behavior.
TxReceipt[]? receipts = _debugBridge.GetReceiptsForBlock(blockParameter);

@@ -58,5 +58,15 @@ public static TrieStats CollectStats(this IStateReader stateProvider, Hash256 ro
});
return collector.Stats;
}

public static Account GetAccount(this IStateReader stateReader, Hash256 stateRoot, Address address)
Copy link
Preview

Copilot AI Mar 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The GetAccount extension method does not verify the return value of TryGetAccount. Consider checking its success before constructing a new Account to avoid propagating uninitialized or default values.

Copilot uses AI. Check for mistakes.

@crStiv
Copy link
Author

crStiv commented Mar 29, 2025

@benaadams hi, I'm not sure if I have to mention you(sorry if not) but as you launched copilot I thought maybe you can review my changes

Copy link
Contributor

@wurdum wurdum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check the PR #8445 for relevant comments as it aims to fix a similar problem.

Also, please add tests covering your changes.

@@ -65,6 +68,33 @@ public ResultWrapper<int> debug_deleteChainSlice(in long startNumber, bool force

public ResultWrapper<GethLikeTxTrace> debug_traceTransaction(Hash256 transactionHash, GethTraceOptions? options = null)
{
// First, find the block by transaction hash
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please avoid adding unnecessary comments.

}

return ResultWrapper<byte[]>.Success(rlp);
byte[] data = _debugBridge.GetBlockRlp(blockNumber);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check for null is relevant.

}

return ResultWrapper<byte[]>.Success(rlp);
byte[] data = _debugBridge.GetBlockRlp(hash);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check for null is relevant.

@@ -58,5 +58,21 @@ public static TrieStats CollectStats(this IStateReader stateProvider, Hash256 ro
});
return collector.Stats;
}

public static Account GetAccount(this IStateReader stateReader, Hash256 stateRoot, Address address)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you explain why this method was added?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method was added to simplify direct account access. It's basically a cleaner alternative to TryGetAccount when you just need to grab an account at a specific address and state root without dealing with all the success/failure return values. Makes the calling code much more readable.

{
return ResultWrapper<byte[]>.Fail($"Block {blockParameter} was not found", ErrorCodes.ResourceNotFound);
return ResultWrapper<byte[]>.Success(Array.Empty<byte>());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was the error changed to an empty response?

if (block is null)
{
return ResultWrapper<byte[]>.Fail($"Block {blockParameter} was not found", ErrorCodes.ResourceNotFound);
return ResultWrapper<byte[]>.Success(Array.Empty<byte>());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was the error changed to an empty response?

using CancellationTokenSource timeout = BuildTimeoutCancellationTokenSource();
CancellationToken cancellationToken = timeout.Token;
var txTraces = _debugBridge.TraceBadBlockToFile(blockHash, cancellationToken, options);
return ResultWrapper<IEnumerable<string>>.Success(txTraces);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please avoid removing _logger.Trace() calls.

{
return ResultWrapper<string?>.Success(Rlp.Encode(transaction, RlpBehaviors.SkipTypedWrapping).Bytes.ToHexString(true));
}
catch (Exception ex)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use a specific exception type to avoid returning ErrorCodes.InternalError when it's not relevant.

@crStiv crStiv requested a review from wurdum April 23, 2025 19:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

HasStateForBlock in debug module
3 participants