-
Notifications
You must be signed in to change notification settings - Fork 432
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
Support various eth_call invocations post 1559 #3317
Changes from 17 commits
f5bed91
4dcc4f4
9065595
5574d5a
ab32915
8883dd4
6fff2c1
7611928
0a412ff
78a20f7
03e0b0e
d2fc7ba
0385a18
a4829c2
9d8ac63
c7e8bb2
646834d
394c190
7f46a98
78c8f41
8652d2c
4c62c77
c91715e
7fff105
ac8f321
800b083
9c19612
e1993b2
11f7cf4
b3b8739
1e323ed
cd29e01
f831fe1
b257240
0eac807
77bdd4d
5175f3c
367ab1b
5126e27
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -60,7 +60,17 @@ private enum ExecutionOptions | |
/// <summary> | ||
/// Commit and later restore state, use for CallAndRestore | ||
/// </summary> | ||
CommitAndRestore = Commit | Restore | ||
CommitAndRestore = Commit | Restore, | ||
|
||
/// <summary> | ||
/// Zero Gas price | ||
/// </summary> | ||
ZeroGasPrice = 4, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would prefer flag SkipGasPricingValidation There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. or VerifyGasPricing |
||
|
||
/// <summary> | ||
/// Commit and restore with zero gas price | ||
/// </summary> | ||
CommitAndRestoreWithZeroGasPrice = CommitAndRestore | ZeroGasPrice | ||
} | ||
|
||
public TransactionProcessor( | ||
|
@@ -80,7 +90,17 @@ public TransactionProcessor( | |
|
||
public void CallAndRestore(Transaction transaction, BlockHeader block, ITxTracer txTracer) | ||
{ | ||
Execute(transaction, block, txTracer, ExecutionOptions.CommitAndRestore); | ||
IReleaseSpec spec = _specProvider.GetSpec(block.Number); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Take into account that you will change the behavior of three RPC calls here (eth_call, eth_estimateGas, and eth_createAccessList). Did you verify this behavior with other clients for each of the methods? |
||
spec = new SystemTransactionReleaseSpec(spec); | ||
|
||
bool isZeroGasPrice = spec.IsEip1559Enabled | ||
? (transaction.IsEip1559 | ||
? (transaction.MaxFeePerGas.IsZero && transaction.MaxPriorityFeePerGas.IsZero) | ||
: transaction.GasPrice.IsZero) | ||
: transaction.GasPrice.IsZero; | ||
|
||
Execute(transaction, block, txTracer, | ||
isZeroGasPrice ? ExecutionOptions.CommitAndRestoreWithZeroGasPrice : ExecutionOptions.CommitAndRestore); | ||
} | ||
|
||
public void BuildUp(Transaction transaction, BlockHeader block, ITxTracer txTracer) | ||
|
@@ -123,10 +143,15 @@ private void Execute(Transaction transaction, BlockHeader block, ITxTracer txTra | |
|
||
// restore is CallAndRestore - previous call, we will restore state after the execution | ||
bool restore = (executionOptions & ExecutionOptions.Restore) != ExecutionOptions.None; | ||
|
||
// commit - is for standard execute, we will commit thee state after execution | ||
bool commit = (executionOptions & ExecutionOptions.Commit) != ExecutionOptions.None || eip658NotEnabled; | ||
//!commit - is for build up during block production, we won't commit state after each transaction to support rollbacks | ||
//we commit only after all block is constructed | ||
|
||
// commitAndRestoreWithoutZeroGasPrice is CallAndRestore without a zero gas price | ||
bool isCommitAndRestoreWithoutZeroGasPrice = commit && restore && ((executionOptions & ExecutionOptions.ZeroGasPrice) == ExecutionOptions.None); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we simplify it in any way? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems to me that it looks more understandable in this form. |
||
|
||
bool notSystemTransaction = !transaction.IsSystem(); | ||
bool deleteCallerAccount = false; | ||
|
||
|
@@ -137,9 +162,17 @@ private void Execute(Transaction transaction, BlockHeader block, ITxTracer txTra | |
} | ||
|
||
UInt256 value = transaction.Value; | ||
|
||
if (isCommitAndRestoreWithoutZeroGasPrice && transaction.MaxPriorityFeePerGas > transaction.MaxFeePerGas) | ||
{ | ||
TraceLogInvalidTx(transaction, "MAX PRIORITY FEE PER GAS HIGHER THAN MAX FEE PER GAS"); | ||
QuickFail(transaction, block, txTracer, eip658NotEnabled, "max priority fee per gas higher than max fee per gas"); | ||
return; | ||
} | ||
|
||
if (!transaction.TryCalculatePremiumPerGas(block.BaseFeePerGas, out UInt256 premiumPerGas) && !restore) | ||
if (!transaction.TryCalculatePremiumPerGas(block.BaseFeePerGas, out UInt256 premiumPerGas) && (!restore || isCommitAndRestoreWithoutZeroGasPrice)) | ||
{ | ||
// max fee per gas (feeCap) less than block base fee | ||
TraceLogInvalidTx(transaction, "MINER_PREMIUM_IS_NEGATIVE"); | ||
QuickFail(transaction, block, txTracer, eip658NotEnabled, "miner premium is negative"); | ||
return; | ||
|
@@ -214,17 +247,22 @@ private void Execute(Transaction transaction, BlockHeader block, ITxTracer txTra | |
|
||
UInt256 senderReservedGasPayment = restore ? UInt256.Zero : (ulong) gasLimit * gasPrice; | ||
|
||
if (isCommitAndRestoreWithoutZeroGasPrice) | ||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can merge it with the line 248 |
||
senderReservedGasPayment = (ulong)gasLimit * gasPrice; | ||
} | ||
|
||
if (notSystemTransaction) | ||
{ | ||
UInt256 senderBalance = _stateProvider.GetBalance(caller); | ||
if (!restore && ((ulong) intrinsicGas * gasPrice + value > senderBalance || senderReservedGasPayment + value > senderBalance)) | ||
if ((!restore || isCommitAndRestoreWithoutZeroGasPrice) && ((ulong) intrinsicGas * gasPrice + value > senderBalance || senderReservedGasPayment + value > senderBalance)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am confused. Could we introduce variable like verifyGasPricing? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of combination of restore and isCommitAndRestoreWithoutZeroGasPrice |
||
{ | ||
TraceLogInvalidTx(transaction, $"INSUFFICIENT_SENDER_BALANCE: ({caller})_BALANCE = {senderBalance}"); | ||
QuickFail(transaction, block, txTracer, eip658NotEnabled, "insufficient sender balance"); | ||
return; | ||
} | ||
|
||
if (!restore && spec.IsEip1559Enabled && !transaction.IsServiceTransaction && senderBalance < (UInt256)transaction.GasLimit * transaction.MaxFeePerGas + value) | ||
if ((!restore || isCommitAndRestoreWithoutZeroGasPrice) && spec.IsEip1559Enabled && !transaction.IsServiceTransaction && senderBalance < (UInt256)transaction.GasLimit * transaction.MaxFeePerGas + value) | ||
{ | ||
TraceLogInvalidTx(transaction, $"INSUFFICIENT_MAX_FEE_PER_GAS_FOR_SENDER_BALANCE: ({caller})_BALANCE = {senderBalance}, MAX_FEE_PER_GAS: {transaction.MaxFeePerGas}"); | ||
QuickFail(transaction, block, txTracer, eip658NotEnabled, "insufficient MaxFeePerGas for sender balance"); | ||
|
@@ -327,7 +365,7 @@ private void Execute(Transaction transaction, BlockHeader block, ITxTracer txTra | |
} | ||
else | ||
{ | ||
// tks: there is similar code fo contract creation from init and from CREATE | ||
// tks: there is similar code for contract creation from init and from CREATE | ||
// this may lead to inconsistencies (however it is tested extensively in blockchain tests) | ||
if (transaction.IsContractCreation) | ||
{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,7 +44,7 @@ public async Task Eth_estimateGas_web3_should_return_insufficient_balance_error( | |
string serialized = | ||
ctx._test.TestEthRpc("eth_estimateGas", ctx._test.JsonSerializer.Serialize(transaction)); | ||
Assert.AreEqual( | ||
"{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32000,\"message\":\"insufficient funds for transfer: address 0x0001020304050607080910111213141516171819\"},\"id\":67}", | ||
"{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32603,\"message\":\"insufficient sender balance\"},\"id\":67}", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you explain why we need to change this error message? |
||
serialized); | ||
ctx._test.ReadOnlyState.AccountExists(someAccount).Should().BeFalse(); | ||
} | ||
|
@@ -59,7 +59,7 @@ public async Task Eth_estimateGas_web3_sample_not_enough_gas_system_account() | |
"{\"gasPrice\":\"0x100000\", \"data\": \"0x70a082310000000000000000000000006c1f09f6271fbe133db38db9c9280307f5d22160\", \"to\": \"0x0d8775f648430679a709e98d2b0cb6250d2887ef\"}"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It will be nice to add the same tests like it was before but with skipped gas pricing. One more question: did geth change behavior only for blocks after 1559 or for all blocks? |
||
string serialized = | ||
ctx._test.TestEthRpc("eth_estimateGas", ctx._test.JsonSerializer.Serialize(transaction)); | ||
Assert.AreEqual("{\"jsonrpc\":\"2.0\",\"result\":\"0x53b8\",\"id\":67}", serialized); | ||
Assert.AreEqual("{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32000,\"message\":\"insufficient funds for transfer: address 0xfffffffffffffffffffffffffffffffffffffffe\"},\"id\":67}", serialized); | ||
ctx._test.ReadOnlyState.AccountExists(Address.SystemUser).Should().BeFalse(); | ||
} | ||
|
||
|
@@ -73,7 +73,7 @@ public async Task Eth_estimateGas_web3_sample_not_enough_gas_other_account() | |
"{\"from\":\"0x0001020304050607080910111213141516171819\",\"gasPrice\":\"0x100000\", \"data\": \"0x70a082310000000000000000000000006c1f09f6271fbe133db38db9c9280307f5d22160\", \"to\": \"0x0d8775f648430679a709e98d2b0cb6250d2887ef\"}"); | ||
string serialized = | ||
ctx._test.TestEthRpc("eth_estimateGas", ctx._test.JsonSerializer.Serialize(transaction)); | ||
Assert.AreEqual("{\"jsonrpc\":\"2.0\",\"result\":\"0x53b8\",\"id\":67}", serialized); | ||
Assert.AreEqual("{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32603,\"message\":\"insufficient sender balance\"},\"id\":67}", serialized); | ||
ctx._test.ReadOnlyState.AccountExists(someAccount).Should().BeFalse(); | ||
} | ||
|
||
|
@@ -87,7 +87,7 @@ public async Task Eth_estimateGas_web3_above_block_gas_limit() | |
"{\"from\":\"0x0001020304050607080910111213141516171819\",\"gas\":\"0x100000000\",\"gasPrice\":\"0x100000\", \"data\": \"0x70a082310000000000000000000000006c1f09f6271fbe133db38db9c9280307f5d22160\", \"to\": \"0x0d8775f648430679a709e98d2b0cb6250d2887ef\"}"); | ||
string serialized = | ||
ctx._test.TestEthRpc("eth_estimateGas", ctx._test.JsonSerializer.Serialize(transaction)); | ||
Assert.AreEqual("{\"jsonrpc\":\"2.0\",\"result\":\"0x53b8\",\"id\":67}", serialized); | ||
Assert.AreEqual("{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32603,\"message\":\"insufficient sender balance\"},\"id\":67}", serialized); | ||
ctx._test.ReadOnlyState.AccountExists(someAccount).Should().BeFalse(); | ||
} | ||
|
||
|
@@ -187,15 +187,15 @@ public async Task Estimate_gas_with_gas_pricing() | |
TransactionForRpc transaction = ctx._test.JsonSerializer.Deserialize<TransactionForRpc>( | ||
"{\"from\": \"0x32e4e4c7c5d1cea5db5f9202a9e4d99e56c91a24\", \"to\": \"0x32e4e4c7c5d1cea5db5f9202a9e4d99e56c91a24\", \"gasPrice\": \"0x10\"}"); | ||
string serialized = ctx._test.TestEthRpc("eth_estimateGas", ctx._test.JsonSerializer.Serialize(transaction)); | ||
Assert.AreEqual("{\"jsonrpc\":\"2.0\",\"result\":\"0x5208\",\"id\":67}", serialized); | ||
Assert.AreEqual("{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32603,\"message\":\"insufficient sender balance\"},\"id\":67}", serialized); | ||
} | ||
|
||
[Test] | ||
public async Task Estimate_gas_without_gas_pricing_after_1559_legacy() | ||
{ | ||
using Context ctx = await Context.CreateWithLondonEnabled(); | ||
TransactionForRpc transaction = ctx._test.JsonSerializer.Deserialize<TransactionForRpc>( | ||
"{\"from\": \"0x32e4e4c7c5d1cea5db5f9202a9e4d99e56c91a24\", \"to\": \"0x32e4e4c7c5d1cea5db5f9202a9e4d99e56c91a24\", \"gasPrice\": \"0x10\"}"); | ||
"{\"from\": \"0x32e4e4c7c5d1cea5db5f9202a9e4d99e56c91a24\", \"to\": \"0x32e4e4c7c5d1cea5db5f9202a9e4d99e56c91a24\"}"); | ||
string serialized = ctx._test.TestEthRpc("eth_estimateGas", ctx._test.JsonSerializer.Serialize(transaction)); | ||
Assert.AreEqual("{\"jsonrpc\":\"2.0\",\"result\":\"0x5208\",\"id\":67}", serialized); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is it commented?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you give up the idea of verification of account cleanup, which we discussed?