Skip to content

[rpc] Propagate insufficient balance error - #2527

Open
dhil wants to merge 1 commit into
mainfrom
dhil/rpc-insufficient-balance
Open

[rpc] Propagate insufficient balance error#2527
dhil wants to merge 1 commit into
mainfrom
dhil/rpc-insufficient-balance

Conversation

@dhil

@dhil dhil commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

This patch propagates the insufficient balance error through the rpc stack rather than rewriting it to a generic "other" error type with a custom message.

BFT companion patch: category-labs/monad-bft#3234

This patch propagates the insufficient balance error through the rpc
stack rather than rewriting it to a generic "other" error type with a
custom message.
Copilot AI lite review requested due to automatic review settings August 31, 2026 13:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Propagates the “insufficient balance” condition through the eth_call execution path by preserving a dedicated status code from the C++ executor into the Rust monad-ethcall layer (instead of collapsing it into a generic “other” error), aligning with the linked companion change in monad-bft.

Changes:

  • Introduces an EVMC_INSUFFICIENT_BALANCE status code mapping in monad-ethcall and converts it into a dedicated EthCallError::InsufficientBalance.
  • Updates the C++ RPC executor to return EVMC_INSUFFICIENT_BALANCE for TransactionError::InsufficientBalance.
  • Adjusts the C++ RPC test to assert the new status code.

Reviewed changes

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

File Description
rust/crates/monad-ethcall/src/executor/mod.rs Adds the EVMC_INSUFFICIENT_BALANCE status code constant used by the Rust executor layer.
rust/crates/monad-ethcall/src/executor/call.rs Adds EthCallError::InsufficientBalance and handles EVMC_INSUFFICIENT_BALANCE in the result status mapping.
category/rpc/monad_executor.cpp Propagates TransactionError::InsufficientBalance as EVMC_INSUFFICIENT_BALANCE instead of EVMC_REJECTED.
category/rpc/monad_executor_test.cpp Updates the insufficient-balance test expectation to the new status code.

Verdict: NEEDS CHANGES
Generated with Claude Code


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +16 to +17
use std::f32::consts::E;


pub(super) const ETH_CALL_SUCCESS: i32 = 0;
pub(super) const EVMC_OUT_OF_GAS: i32 = 3;
pub(super) const EVMC_INSUFFICIENT_BALANCE: i32 = 4;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[P1] Wrong evmc status-code value — EVMC_INSUFFICIENT_BALANCE is 17 in third_party/evmc/include/evmc/evmc.h, not 4 (4 is EVMC_INVALID_INSTRUCTION). As written, real insufficient-balance results (status 17 from the C++ side) fall through to the _ arm and never produce the new EthCallError::InsufficientBalance variant, while any call that fails with an invalid instruction is misclassified as insufficient balance.

Suggested change
pub(super) const EVMC_INSUFFICIENT_BALANCE: i32 = 4;
pub(super) const EVMC_INSUFFICIENT_BALANCE: i32 = 17;

// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

use std::f32::consts::E;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[P2] Unused import — std::f32::consts::E (Euler's number as an f32) is never used in this file and looks like an accidental IDE auto-import; it will trip the unused_imports lint. Delete the line (and the blank line after it).

Comment on lines +305 to +311
} else {
let trace = result.encoded_trace().map_err(|_| {
warn!("execution error `eth_call` failed: encoded trace pointer is null");
EthCallError::InternalError
})?;
Err(EthCallError::Trace { trace })
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[P2] With a non-NOOP tracer this branch returns InternalError for the validation-path insufficient balance introduced on the C++ side. Unlike EVMC_MONAD_RESERVE_BALANCE_VIOLATION (which only arises during execution, where a trace exists), EVMC_INSUFFICIENT_BALANCE now also arrives from the pre-execution TransactionError path in monad_executor.cpp, where no trace is produced (monad_executor_test.cpp asserts encoded_trace_len == 0 for this case) — so encoded_trace() fails and the caller gets InternalError plus a spurious warn log, where it previously got Other { message: "insufficient balance" } via the _ arm. Consider falling back to EthCallError::InsufficientBalance when the trace is empty.

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