-
Notifications
You must be signed in to change notification settings - Fork 190
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
Conversation
@@ -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[] } = {} |
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.
This needs to also be grouped by parent chain
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.
My bad, needs to be grouped by chain, cause one parent chain (e.g. Arb Goerli) can have many Orbit chains
public setL2BlockRangeCache(l1Block: number, l2BlockRange: number[]) { | ||
l2BlockRangeCache[l1Block] = l2BlockRange | ||
} |
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.
I would remove this method and just directly update the cache above from the code
this.setL2BlockRangeCache(createdAtBlock.toNumber(), [ | ||
startBlock, | ||
endBlock, | ||
]) |
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.
Maybe we should cache it below the try/catch
const l2BlockRange = | ||
l2BlockRangeCache?.[createdAtBlock.toNumber()] || | ||
(await getBlockRangesForL1Block({ | ||
forL1Block: createdAtBlock.toNumber(), | ||
provider: this.l1Provider as JsonRpcProvider, | ||
})) |
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.
nit for readability
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, | |
})) |
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.
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
).
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.
LGTM
chainId, | ||
l1BlockNumber, | ||
}: { | ||
chainId: number |
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.
chainId: number | |
l2ChainId: number |
async function getL2BlockRangeCache({ | ||
l1Provider, | ||
l2Provider, | ||
l1BlockNumber, | ||
}: { | ||
l1Provider: JsonRpcProvider | ||
l2Provider: JsonRpcProvider | ||
l1BlockNumber: number | ||
}) { |
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.
async function getL2BlockRangeCache({ | |
l1Provider, | |
l2Provider, | |
l1BlockNumber, | |
}: { | |
l1Provider: JsonRpcProvider | |
l2Provider: JsonRpcProvider | |
l1BlockNumber: number | |
}) { | |
async function getBlockRangesForL1BlockWithCache({ | |
l1Provider, | |
l2Provider, | |
forL1Block, | |
}: { | |
l1Provider: JsonRpcProvider | |
l2Provider: JsonRpcProvider | |
forL1Block: number | |
}) { |
…o cache-l2-block-range
Implements mutex lock to cache l2BlockRange