Skip to content

Commit fbc1508

Browse files
Corrected error codes for eth simulate (#11430)
* added eth_simulate_error_code * remove wrong claude commits and do changes * correct sender_is_not_eoa test * add hive test failure to known failing tests --------- Co-authored-by: Stavros Vlachakis <89769224+svlachakis@users.noreply.github.com>
1 parent f080d64 commit fbc1508

4 files changed

Lines changed: 160 additions & 7 deletions

File tree

scripts/known-failing-hive-tests.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ eth_simulateV1/ethSimulate-check-invalid-nonce (nethermind)
1010
eth_simulateV1/ethSimulate-gas-fees-and-value-error-38014-with-validation (nethermind)
1111
eth_simulateV1/ethSimulate-simple-no-funds-with-validation (nethermind)
1212
eth_simulateV1/ethSimulate-simple-no-funds-with-validation-without-nonces (nethermind)
13+
eth_simulateV1/ethSimulate-simple-send-from-contract-with-validation (nethermind)
1314

1415
# graphql
1516

src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,4 +702,141 @@ public async Task eth_simulateV1_intrinsic_gas_returns_spec_error_code_and_messa
702702
Assert.That(result.Result!.Error, Is.EqualTo(SimulateErrorMessages.IntrinsicGas));
703703
}
704704

705+
/// <summary>
706+
/// Regression test: eth_simulateV1 with validation:true and a nonce below the account's current
707+
/// nonce must return -38010 (NonceTooLow).
708+
/// </summary>
709+
[Test]
710+
public async Task eth_simulateV1_nonce_too_low_returns_spec_error_code()
711+
{
712+
TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain();
713+
714+
// Set the account's nonce to 10, then send a tx with nonce 0 (below current).
715+
SimulatePayload<TransactionForRpc> payload = new()
716+
{
717+
BlockStateCalls =
718+
[
719+
new()
720+
{
721+
StateOverrides = new Dictionary<Address, AccountOverride>
722+
{
723+
{ TestItem.AddressA, new AccountOverride { Balance = 1.Ether, Nonce = 10 } }
724+
},
725+
Calls =
726+
[
727+
new LegacyTransactionForRpc
728+
{
729+
From = TestItem.AddressA,
730+
To = TestItem.AddressB,
731+
Value = UInt256.Zero,
732+
Nonce = 0,
733+
GasPrice = UInt256.Zero,
734+
Gas = 21_000
735+
}
736+
]
737+
}
738+
],
739+
Validation = true
740+
};
741+
742+
ResultWrapper<IReadOnlyList<SimulateBlockResult<SimulateCallResult>>> result =
743+
chain.EthRpcModule.eth_simulateV1(payload, BlockParameter.Latest);
744+
745+
Assert.That(result.ErrorCode, Is.EqualTo(ErrorCodes.NonceTooLow));
746+
}
747+
748+
/// <summary>
749+
/// Regression test: eth_simulateV1 with validation:true and a nonce above the account's current
750+
/// nonce must return -38011 (NonceTooHigh).
751+
/// </summary>
752+
[Test]
753+
public async Task eth_simulateV1_nonce_too_high_returns_spec_error_code()
754+
{
755+
TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain();
756+
757+
// Account nonce is 0; send a tx with nonce 100 (way above current).
758+
SimulatePayload<TransactionForRpc> payload = new()
759+
{
760+
BlockStateCalls =
761+
[
762+
new()
763+
{
764+
StateOverrides = new Dictionary<Address, AccountOverride>
765+
{
766+
{ TestItem.AddressA, new AccountOverride { Balance = 1.Ether } }
767+
},
768+
Calls =
769+
[
770+
new LegacyTransactionForRpc
771+
{
772+
From = TestItem.AddressA,
773+
To = TestItem.AddressB,
774+
Value = UInt256.Zero,
775+
Nonce = 100,
776+
GasPrice = UInt256.Zero,
777+
Gas = 21_000
778+
}
779+
]
780+
}
781+
],
782+
Validation = true
783+
};
784+
785+
ResultWrapper<IReadOnlyList<SimulateBlockResult<SimulateCallResult>>> result =
786+
chain.EthRpcModule.eth_simulateV1(payload, BlockParameter.Latest);
787+
788+
Assert.That(result.ErrorCode, Is.EqualTo(ErrorCodes.NonceTooHigh));
789+
}
790+
791+
/// <summary>
792+
/// Regression test: eth_simulateV1 with validation:true and a sender address that has deployed
793+
/// code (EIP-3607) must return -38024 (SenderIsNotEoa).
794+
/// </summary>
795+
[Test]
796+
public async Task eth_simulateV1_sender_is_not_eoa_returns_spec_error_code()
797+
{
798+
OverridableReleaseSpec spec = new(London.Instance) { IsEip3607Enabled = true };
799+
TestSpecProvider specProvider = new(spec) { AllowTestChainOverride = false };
800+
TestRpcBlockchain chain = await TestRpcBlockchain.ForTest(new TestRpcBlockchain()).Build(specProvider);
801+
802+
// Override TestItem.AddressC with contract code — makes it a non-EOA sender.
803+
SimulatePayload<TransactionForRpc> payload = new()
804+
{
805+
BlockStateCalls =
806+
[
807+
new()
808+
{
809+
StateOverrides = new Dictionary<Address, AccountOverride>
810+
{
811+
{
812+
TestItem.AddressC,
813+
new AccountOverride
814+
{
815+
Balance = 1.Ether,
816+
Code = Bytes.FromHexString("0x60006000")
817+
}
818+
}
819+
},
820+
Calls =
821+
[
822+
new LegacyTransactionForRpc
823+
{
824+
From = TestItem.AddressC,
825+
To = TestItem.AddressB,
826+
Value = UInt256.Zero,
827+
GasPrice = UInt256.Zero,
828+
Gas = 21_000
829+
}
830+
]
831+
}
832+
],
833+
Validation = true
834+
};
835+
836+
ResultWrapper<IReadOnlyList<SimulateBlockResult<SimulateCallResult>>> result =
837+
chain.EthRpcModule.eth_simulateV1(payload, BlockParameter.Latest);
838+
839+
Assert.That(result.ErrorCode, Is.EqualTo(ErrorCodes.SenderIsNotEoa));
840+
}
841+
705842
}

src/Nethermind/Nethermind.JsonRpc/ErrorCodes.cs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,28 +122,43 @@ public static class ErrorCodes
122122
/// </summary>
123123
public const int Default = -32000;
124124

125+
/// <summary>
126+
/// Transaction nonce is lower than the account's current nonce — eth_simulateV1 spec error
127+
/// </summary>
128+
public const int NonceTooLow = -38010;
129+
130+
/// <summary>
131+
/// Transaction nonce is higher than the account's current nonce — eth_simulateV1 spec error
132+
/// </summary>
133+
public const int NonceTooHigh = -38011;
134+
125135
/// <summary>
126136
/// Transaction maxFeePerGas is below the block base fee — eth_simulateV1 spec error
127137
/// </summary>
128138
public const int FeeCapBelowBaseFee = -38012;
129139

130140
/// <summary>
131-
/// Transaction gas limit is below the intrinsic gas cost
141+
/// Transaction gas limit is below the intrinsic gas cost — eth_simulateV1 spec error
132142
/// </summary>
133143
public const int IntrinsicGas = -38013;
134144

135145
/// <summary>
136-
/// Not enough value to cover transaction costs
146+
/// Not enough value to cover transaction costs — eth_simulateV1 spec error
137147
/// </summary>
138148
public const int InsufficientFunds = -38014;
139149

140150
/// <summary>
141-
/// Gas limit reached
151+
/// Gas limit reached — eth_simulateV1 spec error
142152
/// </summary>
143153
public const int BlockGasLimitReached = -38015;
144154

145155
/// <summary>
146-
/// EIP-3860. Code size is to big
156+
/// Sender account has deployed code (is not an EOA) — eth_simulateV1 spec error
157+
/// </summary>
158+
public const int SenderIsNotEoa = -38024;
159+
160+
/// <summary>
161+
/// EIP-3860. Code size is too big — eth_simulateV1 spec error
147162
/// </summary>
148163
public const int MaxInitCodeSizeExceeded = -38025;
149164

src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -255,11 +255,11 @@ private static int MapSimulateErrorCode(TransactionResult txResult)
255255
TransactionResult.ErrorType.MaxFeePerGasBelowBaseFee
256256
or TransactionResult.ErrorType.MinerPremiumNegative => ErrorCodes.FeeCapBelowBaseFee,
257257
TransactionResult.ErrorType.NonceOverflow => ErrorCodes.InternalError,
258-
TransactionResult.ErrorType.SenderHasDeployedCode => ErrorCodes.InvalidParams,
258+
TransactionResult.ErrorType.SenderHasDeployedCode => ErrorCodes.SenderIsNotEoa,
259259
TransactionResult.ErrorType.SenderNotSpecified => ErrorCodes.InternalError,
260260
TransactionResult.ErrorType.TransactionSizeOverMaxInitCodeSize => ErrorCodes.MaxInitCodeSizeExceeded,
261-
TransactionResult.ErrorType.TransactionNonceTooHigh => ErrorCodes.InternalError,
262-
TransactionResult.ErrorType.TransactionNonceTooLow => ErrorCodes.InternalError,
261+
TransactionResult.ErrorType.TransactionNonceTooHigh => ErrorCodes.NonceTooHigh,
262+
TransactionResult.ErrorType.TransactionNonceTooLow => ErrorCodes.NonceTooLow,
263263
_ => ErrorCodes.InternalError
264264
};
265265
}

0 commit comments

Comments
 (0)