Skip to content

feat: add erigon_getLatestLogs as a new feature API.#5875

Merged
AskAlexSharov merged 14 commits into
erigontech:develfrom
fenghaojiang:devel
Nov 8, 2022
Merged

feat: add erigon_getLatestLogs as a new feature API.#5875
AskAlexSharov merged 14 commits into
erigontech:develfrom
fenghaojiang:devel

Conversation

@fenghaojiang

Copy link
Copy Markdown
Contributor

feat: add erigon_getLatestLogs as a new feature API.

  1. erigon_getLatestLogs returns latest logs that match the filter with logCount length. Implementation is similar to erigon_getLogs but it uses ReverseIterator which makes it more efficient to fetch the latest logs.

feat: add `erigon_getLatestLogs` as a new feature API.
1. `erigon_getLatestLogs` returns latest logs that match the filter with `logCount` length. Implements is similar to `erigon_getLogs` but it uses `ReverseIterator` which makes it more efficient to fetch latest logs.
fix:
1. logs index should be returned in descend order.
2. return logs and reduce the useless file I/O.
@AskAlexSharov

Copy link
Copy Markdown
Collaborator

@fenghaojiang let's add some test?

1. add simple test for `erigon_getLatestLogs`
@fenghaojiang

Copy link
Copy Markdown
Contributor Author

@fenghaojiang let's add some test?

It's too simple. I am wondering How can I add tests to erigon_getLogs APIs. Cause it seems no tests on eth_getLogs too.

@AskAlexSharov

Copy link
Copy Markdown
Collaborator

Can take TestReplayTransaction as an example

db := m.DB
agg := m.HistoryV3Components()
api := NewErigonAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout), db, nil)
logs, err := api.GetLatestLogs(context.Background(), filters.FilterCriteria{}, 1)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I can see some logs by:

logs, _ := api.GetLogs(ctx, filters.FilterCriteria{FromBlock: big.NewInt(0), ToBlock: big.NewInt(1024)})
	for _, l := range logs {
		fmt.Printf("alex: %v\n", l.BlockNumber)
	}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thank you. Really appreciated for your help. I will add it tomorrow.

fenghaojiang and others added 2 commits November 2, 2022 10:40
1. fix missing `end` block in filter logs
2. add test case for `erigon_getLatestLogs`
@fenghaojiang

Copy link
Copy Markdown
Contributor Author

I am wondering why sometimes CI goes wrong...

@AskAlexSharov

Copy link
Copy Markdown
Collaborator

I am wondering why sometimes CI goes wrong...

seems some unstable test TestEmptyBlock

@fenghaojiang

Copy link
Copy Markdown
Contributor Author

I am wondering why sometimes CI goes wrong...

seems some unstable test TestEmptyBlock

All tests have passed. Plz have a review.

@AskAlexSharov

AskAlexSharov commented Nov 3, 2022

Copy link
Copy Markdown
Collaborator

}
timestamp := header.Time

blockHash, err := rawdb.ReadCanonicalHash(tx, blockNumber)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

can use header.Hash()

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed it in following 2 commits.

fenghaojiang and others added 4 commits November 3, 2022 10:52
1. feature method change in `erigon_getLatestLogs` filtered => logs.filter()
1. use rawdb.ReadCanonicalHash() => header.Hash() to fetch field `blockHash`
@AskAlexSharov AskAlexSharov merged commit 7f9edd6 into erigontech:devel Nov 8, 2022
@AskAlexSharov

Copy link
Copy Markdown
Collaborator

Please add new method with description to cmd/rpcdaemon/readme.md

@fenghaojiang

Copy link
Copy Markdown
Contributor Author

Please add new method with description to cmd/rpcdaemon/readme.md

Done in #5994

@AskAlexSharov

Copy link
Copy Markdown
Collaborator

Fetching indices from 0 to latest may go OOM and in-general very bad. Need optimize it.

@fenghaojiang

Copy link
Copy Markdown
Contributor Author

Fetching indices from 0 to latest may go OOM and in-general very bad. Need optimize it.

How about giving a max blockCount limitation?

@fenghaojiang

Copy link
Copy Markdown
Contributor Author

image

eth_getLogs benchmark

the charts show how many decoded logs/s you can get from geth or erigon with a split up and parallelized query.

didn't expect such abysmal performance from geth. it ended up being 21.4x slower than erigon, with many of the combinations timing out.

Source Tweet: https://twitter.com/bantg/status/1547515905944555520

How about setting up a max blockCount Size about 50000 blocks?

@AskAlexSharov

AskAlexSharov commented Jan 11, 2023

Copy link
Copy Markdown
Collaborator

How about giving a max blockCount limitation?

Now it looks like “post-filter” we need something to avoid passing 0 to getTopicsBitmap. I don’t have opinion.

eth_getLogs has no such problem, only erigon_getLatestLogs

@fenghaojiang

fenghaojiang commented Jan 11, 2023

Copy link
Copy Markdown
Contributor Author

How about giving a max blockCount limitation?

Now it looks like “post-filter” we need something to avoid passing 0 to getTopicsBitmap. I don’t have opinion.

eth_getLogs has no such problem, only erigon_getLatestLogs

Sry I didn't get your point. You mean I should add limitation before the bloom filter, not the block numbers when iterating?
But eth_getLogs has the same way to iterate block number too.
I will add a limitation to avoid empty topics. Thank you for your careful feedback.

@AskAlexSharov

AskAlexSharov commented Jan 11, 2023

Copy link
Copy Markdown
Collaborator

@fenghaojiang i'm about this line: https://github.com/ledgerwatch/erigon/pull/5875/files#diff-8d2abcdcfbc55e04a41440a32062ea49b7aaa4d5d7f5a00279cb62c8c6d8d2dfR233
0, latest means we fetch all historical index of given topic, not some portion of it.

some accounts/topics may be old and popular

@fenghaojiang

Copy link
Copy Markdown
Contributor Author

@fenghaojiang i'm about this line: https://github.com/ledgerwatch/erigon/pull/5875/files#diff-8d2abcdcfbc55e04a41440a32062ea49b7aaa4d5d7f5a00279cb62c8c6d8d2dfR233 0, latest means we fetch all historical index of given topic, not some portion of it.

some accounts/topics may be old and popular

But it's just a bloom filter to calculate the possible block numbers that may have the logs. The real iteration is in the following kv iterate the possible blocks and I add a limitation of blockCount in this line.
https://github.com/ledgerwatch/erigon/pull/5875/files#diff-8d2abcdcfbc55e04a41440a32062ea49b7aaa4d5d7f5a00279cb62c8c6d8d2dfR296

@fenghaojiang

fenghaojiang commented Jan 11, 2023

Copy link
Copy Markdown
Contributor Author

@fenghaojiang i'm about this line: https://github.com/ledgerwatch/erigon/pull/5875/files#diff-8d2abcdcfbc55e04a41440a32062ea49b7aaa4d5d7f5a00279cb62c8c6d8d2dfR233 0, latest means we fetch all historical index of given topic, not some portion of it.

some accounts/topics may be old and popular

I got it. When I looked into the bitmapdb.Get() method, I realize that it is a problem. My bad. I should have considered more about it. What's your enhancement sugguestion?

@fenghaojiang

Copy link
Copy Markdown
Contributor Author

Here is my opinion of enhancement.
I use one for loop to look up the block numbers that may match the filter. When it satisfied the requirement, the count number will increase till the logs return.
So the code would be like:

for i := latest; i >= 0; i-= 50000 {
		end := latest
		if latest >= 50000 {
			begin := latest - 50000
		}
		if err := applyFilters(blockNumbers, tx, begin, end, crit); err != nil {
			return nil, err
		}
	
		...
		iter := blockNumbers.Iterator()
		for iter.HasNext() {

			//if count satisfied break the `for` loop and return
		}
	}

What do you think? Looks not so neat and may need some advice. Thx.

@AskAlexSharov

AskAlexSharov commented Jan 16, 2023

Copy link
Copy Markdown
Collaborator

It’s fine for me.
FYI: kv.Cursor has method .Prev()

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