Skip to content
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

Skip sstore gas metering read for system tx #7958

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

Conversation

benaadams
Copy link
Member

Changes

  • Skip read in SSTORE for Beacon Root tx (happens very early in block and prewarming isn't quite fast enough)
  • Move prewarming a bit earlier
  • Add both Storage slots to Beacon Root access list (trie fill is still needed for the commit)

Before

image

After
image

Types of changes

What types of changes does your code introduce?

  • Optimization

Testing

Requires testing

  • No

@benaadams
Copy link
Member Author

Chain size failure #7959

Comment on lines +44 to +51
// https://eips.ethereum.org/EIPS/eip-4788
// Set the storage value at header.timestamp % HISTORY_BUFFER_LENGTH to be header.timestamp
ulong slotIndex = header.Timestamp % HistoryBufferLength;
UInt256 slot256 = slotIndex;
builder.AddStorage(in slot256);
// Set the storage value at header.timestamp % HISTORY_BUFFER_LENGTH + HISTORY_BUFFER_LENGTH to be calldata[0:32]
slot256 = slotIndex + HistoryBufferLength;
builder.AddStorage(in slot256);
Copy link
Member

Choose a reason for hiding this comment

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

Yes that is correct, but I think Geth adds only 1 of them to access list - can you check?
Having different access list could potentially break on edge case of out of gas - generally shouldn't happen with 30mln gas...

Copy link
Member Author

Choose a reason for hiding this comment

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

Spec doesn't mention Access Lists; no gas is charged 30M should be enough for x2 SSTOREs

Spec is actually more wild and says

Clients may decide to omit an explicit EVM call and directly set the storage values. Note: While this is a valid optimization for Ethereum mainnet, it could be problematic on non-mainnet situations in case a different contract is used.

Copy link
Member

@LukaszRozmej LukaszRozmej Dec 30, 2024

Choose a reason for hiding this comment

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

@MarekM25 WDYT?

Copy link
Contributor

Choose a reason for hiding this comment

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

hmmm I think some chains use a different implementation of this contract, so not sure if we should add anything besides just calling sys call

@LukaszRozmej
Copy link
Member

Don't we use system transactions somewhere where correct gas metering is important? (like estimate gas or some other RPC)?

@@ -107,44 +108,51 @@ the previous head state.*/
preWarmTask = null;
WaitForCacheClear();
Block suggestedBlock = suggestedBlocks[i];
if (blocksCount > 64 && i % 8 == 0)
{
if (_logger.IsInfo) _logger.Info($"Processing part of a long blocks branch {i}/{blocksCount}. Block: {suggestedBlock}");
Copy link
Contributor

Choose a reason for hiding this comment

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

This log was helpful in determining that something went seriously wrong in the past :D

/// <summary>
/// Skip read in SSTORE for calculating gas cost as not charged
/// </summary>
bool IsSystemTransaction { get; }
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks weird, this is added to ReleaseSpec and the field seems to be referenced to Transaction object

Comment on lines +44 to +51
// https://eips.ethereum.org/EIPS/eip-4788
// Set the storage value at header.timestamp % HISTORY_BUFFER_LENGTH to be header.timestamp
ulong slotIndex = header.Timestamp % HistoryBufferLength;
UInt256 slot256 = slotIndex;
builder.AddStorage(in slot256);
// Set the storage value at header.timestamp % HISTORY_BUFFER_LENGTH + HISTORY_BUFFER_LENGTH to be calldata[0:32]
slot256 = slotIndex + HistoryBufferLength;
builder.AddStorage(in slot256);
Copy link
Contributor

Choose a reason for hiding this comment

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

hmmm I think some chains use a different implementation of this contract, so not sure if we should add anything besides just calling sys call

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.

3 participants