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

perf: cache l2 block range #343

Merged
merged 10 commits into from
Oct 4, 2023
Merged

perf: cache l2 block range #343

merged 10 commits into from
Oct 4, 2023

Conversation

brtkx
Copy link
Contributor

@brtkx brtkx commented Sep 27, 2023

Implements mutex lock to cache l2BlockRange

@cla-bot cla-bot bot added the cla-signed label Sep 27, 2023
@brtkx brtkx changed the title wip: cache l2 block range perf: cache l2 block range Oct 2, 2023
@brtkx brtkx marked this pull request as ready for review October 2, 2023 08:48
@brtkx brtkx requested a review from spsjvc October 2, 2023 08:48
@@ -61,6 +61,8 @@ const ASSERTION_CREATED_PADDING = 50
// expected number of L1 blocks that it takes for a validator to confirm an L1 block after the node deadline is passed
const ASSERTION_CONFIRMED_PADDING = 20

const l2BlockRangeCache: { [key in number]: number[] } = {}
Copy link
Member

Choose a reason for hiding this comment

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

This needs to also be grouped by parent chain

Copy link
Member

Choose a reason for hiding this comment

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

My bad, needs to be grouped by chain, cause one parent chain (e.g. Arb Goerli) can have many Orbit chains

Comment on lines 160 to 162
public setL2BlockRangeCache(l1Block: number, l2BlockRange: number[]) {
l2BlockRangeCache[l1Block] = l2BlockRange
}
Copy link
Member

Choose a reason for hiding this comment

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

I would remove this method and just directly update the cache above from the code

Comment on lines 235 to 238
this.setL2BlockRangeCache(createdAtBlock.toNumber(), [
startBlock,
endBlock,
])
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we should cache it below the try/catch

Comment on lines 221 to 226
const l2BlockRange =
l2BlockRangeCache?.[createdAtBlock.toNumber()] ||
(await getBlockRangesForL1Block({
forL1Block: createdAtBlock.toNumber(),
provider: this.l1Provider as JsonRpcProvider,
}))
Copy link
Member

Choose a reason for hiding this comment

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

nit for readability

Suggested change
const l2BlockRange =
l2BlockRangeCache?.[createdAtBlock.toNumber()] ||
(await getBlockRangesForL1Block({
forL1Block: createdAtBlock.toNumber(),
provider: this.l1Provider as JsonRpcProvider,
}))
const cachedL2BlockRange = l2BlockRangeCache?.[createdAtBlock.toNumber()]
return cachedL2BlockRange ?? (await getBlockRangesForL1Block({
forL1Block: createdAtBlock.toNumber(),
provider: this.l1Provider as JsonRpcProvider,
}))

@brtkx brtkx requested review from spsjvc and gzeoneth October 2, 2023 14:38
Copy link
Member

@gzeoneth gzeoneth left a comment

Choose a reason for hiding this comment

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

While caching (chainId, l1BlockNumber) -> l2BlockRange can save around 50% of the rpc call for unconfirmed node (since we always call getBlockFromNodeNum on latest confirmed), a better way seems to be caching the (chainId, blockNumber) -> l1BlockNumber result.

By using a bitwise binary search, it should be possible to save more than 75% rpc calls for unconfirmed node (50% from the latest confirmed, another 50%+ because of the duplicated binary search in getBlockRangesForL1Block) and the fact that those l2 blocks are nearby

A bitwise binary search improve cache hit since you will have the same midpoint assuming the l2 blocks are in nearby range (which is always >latestConfirmed).

src/lib/message/L2ToL1MessageNitro.ts Outdated Show resolved Hide resolved
src/lib/message/L2ToL1MessageNitro.ts Outdated Show resolved Hide resolved
Copy link
Member

@gzeoneth gzeoneth left a comment

Choose a reason for hiding this comment

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

LGTM

chainId,
l1BlockNumber,
}: {
chainId: number
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
chainId: number
l2ChainId: number

Comment on lines 82 to 90
async function getL2BlockRangeCache({
l1Provider,
l2Provider,
l1BlockNumber,
}: {
l1Provider: JsonRpcProvider
l2Provider: JsonRpcProvider
l1BlockNumber: number
}) {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
async function getL2BlockRangeCache({
l1Provider,
l2Provider,
l1BlockNumber,
}: {
l1Provider: JsonRpcProvider
l2Provider: JsonRpcProvider
l1BlockNumber: number
}) {
async function getBlockRangesForL1BlockWithCache({
l1Provider,
l2Provider,
forL1Block,
}: {
l1Provider: JsonRpcProvider
l2Provider: JsonRpcProvider
forL1Block: number
}) {

@spsjvc spsjvc merged commit 1a43433 into main Oct 4, 2023
@spsjvc spsjvc deleted the cache-l2-block-range branch October 4, 2023 14:47
douglance pushed a commit that referenced this pull request Oct 11, 2023
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