Skip to content

Conversation

@antonis19
Copy link
Member

@antonis19 antonis19 commented Oct 27, 2025

Fixes #17488, and is a prerequisite for fixing:
#17561

In GetAsOf() if a value is not found in history, DomainRoTx.GetLatest() is called. However, for commitment domain AggregatorRoTx.GetLatest() needs to be called instead, which handles foreign key dereferencing (account and storage offsets).

Copy link
Member

@yperbasis yperbasis left a comment

Choose a reason for hiding this comment

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

Please add a test

@antonis19 antonis19 requested a review from canepat as a code owner October 27, 2025 18:20
@antonis19
Copy link
Member Author

@yperbasis just added some more test cases. The last test case will fetch branch data at blockNum=5 via getLatestFromDB() because that prefix was last updated at blockNum=4, so even though blockNum=5 is historical, because there hasn't been any further update for this key the value is still in latest domain.

So the test case tests exactly the scenario in the PR description.

@AskAlexSharov
Copy link
Collaborator

  1. this condition was introduced in historical eth_getProof fails on some requests on hoodi #15924 -> historical eth_getProof fails on some requests on hoodi #15924 and it also has link to 4 other issues historical eth_getProof fails on some requests on hoodi #15924 (comment) need to re-check them?

  2. I guess we need some test which will create commitment.kv file with refferences to acc.kv - so AggregatorRoTx.replaceShortenedKeysInBranch will be triggered and reads from commitment.v/commitment.kv files will happen.

I see that rpc package tests do not trigger replaceShortenedKeysInBranch method:

Screenshot 2025-10-28 at 09 38 32 Screenshot 2025-10-28 at 09 39 22

Maybe rpc package tests not the best place for it (up to you). Also we have TestAggregatorV3_Merge test - which does call domains.GetLatest(kv.CommitmentDomain and replaceShortenedKeysInBranch but doesn't call lookupByShortenedKey. Also weFuzz_AggregatorV3_MergeValTransform

Copy link
Member

@awskii awskii left a comment

Choose a reason for hiding this comment

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

reading from commitment domain required to be done on aggregator or shared domain level - this is lowest possible level where we have access to other domains as well,but here if we read the value, it will contain accounts and storage file pointers and will become error on another level - while unfolding the branch

@antonis19
Copy link
Member Author

reading from commitment domain required to be done on aggregator or shared domain level - this is lowest possible level where we have access to other domains as well,but here if we read the value, it will contain accounts and storage file pointers and will become error on another level - while unfolding the branch

So what is the change you would like me to make? Even with this if guard not removed, I don't see the read from shared domains happening.

As I see it this is a separate issue, I don't see any fallback to shared domains.

@antonis19 antonis19 changed the title Remove early return in GetAsOf() for commitment Fix GetAsOf() for commitment , so that it handles dereferencing Oct 30, 2025
@antonis19 antonis19 requested a review from awskii October 31, 2025 09:24
func (at *AggregatorRoTx) GetAsOf(name kv.Domain, k []byte, ts uint64, tx kv.Tx) (v []byte, ok bool, err error) {
return at.d[name].GetAsOf(k, ts, tx)
v, ok, err = at.d[name].GetAsOf(k, ts, tx)
if name == kv.CommitmentDomain && !ok {
Copy link
Member

Choose a reason for hiding this comment

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

please move !ok as first condition - it just almost slit from me when i started CR

Copy link
Member

Choose a reason for hiding this comment

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

but with !ok && commitmentDomain it looks cleaner. Also you have to make sure [Commitment].GetAsOf returns nil, false right before domain reading with proper comment about branch plain keys dereferencing bad reads protection.

Currently this fix wount work - OK=true in case of successful reading from commtiment domain - value will contain references and this fallback will not take place

Copy link
Member Author

Choose a reason for hiding this comment

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

I thought the theory was that that when [Commitment].GetAsOf() returns nil, false then we fall back to func (at *AggregatorRoTx) GetLatest() . I already put back this code in DomainRoTx.GetAsOf() :

	if dt.name == kv.CommitmentDomain {
		// we need to dereference commitment keys to get actual value. DomainRoTx itself does not have
		// pointers to storage and account domains to do the reference. Aggregator tx must be called instead
		return nil, false, nil
	}

Are you saying that if Commitment].GetAsOf() returns ok = true from history, that still needs special handling???

Copy link
Member

Choose a reason for hiding this comment

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

yes indeed that was introduced way ago 0774823
no problem then

func (at *AggregatorRoTx) GetAsOf(name kv.Domain, k []byte, ts uint64, tx kv.Tx) (v []byte, ok bool, err error) {
return at.d[name].GetAsOf(k, ts, tx)
v, ok, err = at.d[name].GetAsOf(k, ts, tx)
if name == kv.CommitmentDomain && !ok {
Copy link
Member

Choose a reason for hiding this comment

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

but with !ok && commitmentDomain it looks cleaner. Also you have to make sure [Commitment].GetAsOf returns nil, false right before domain reading with proper comment about branch plain keys dereferencing bad reads protection.

Currently this fix wount work - OK=true in case of successful reading from commtiment domain - value will contain references and this fallback will not take place

func (at *AggregatorRoTx) GetAsOf(name kv.Domain, k []byte, ts uint64, tx kv.Tx) (v []byte, ok bool, err error) {
return at.d[name].GetAsOf(k, ts, tx)
v, ok, err = at.d[name].GetAsOf(k, ts, tx)
if name == kv.CommitmentDomain && !ok {
Copy link
Member

Choose a reason for hiding this comment

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

yes indeed that was introduced way ago 0774823
no problem then

@awskii awskii merged commit 3e2ccf8 into main Oct 31, 2025
17 checks passed
@awskii awskii deleted the fix-getAsOf-commitment branch October 31, 2025 12:32
mh0lt pushed a commit that referenced this pull request Nov 4, 2025
…7687)

Fixes #17488, and is a
prerequisite for fixing:
#17561

In `GetAsOf()` if a value is not found in history,
`DomainRoTx.GetLatest()` is called. However, for commitment domain
`AggregatorRoTx.GetLatest()` needs to be called instead, which handles
foreign key dereferencing (account and storage offsets).

---------

Co-authored-by: antonis19 <[email protected]>
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.

empty branch data read during unfold

5 participants