-
Notifications
You must be signed in to change notification settings - Fork 10
fix: invalidate per-contract ABI cache after metadata update #255
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -175,7 +175,7 @@ async def get_supported_abis(self) -> AsyncIterator[ABI]: | |
| async def get_multisend_abis(self) -> AsyncIterator[ABI]: | ||
| yield get_multi_send_contract(self.dummy_w3).abi | ||
|
|
||
| @alru_cache(maxsize=2048) | ||
| @alru_cache(maxsize=2048, ttl=600) | ||
| async def get_contract_abi( | ||
| self, | ||
| address: Address, | ||
|
|
@@ -190,7 +190,7 @@ async def get_contract_abi( | |
| """ | ||
| return await Contract.get_abi_by_contract_address(HexBytes(address), chain_id) | ||
|
|
||
| @alru_cache(maxsize=2048) | ||
| @alru_cache(maxsize=2048, ttl=600) | ||
| async def get_contract_abi_selectors_with_functions( | ||
| self, address: Address, chain_id: int | None | ||
| ) -> dict[bytes, ABIFunction] | None: | ||
|
|
@@ -498,6 +498,24 @@ async def get_decoding_accuracy( | |
| return DecodingAccuracyEnum.PARTIAL_MATCH | ||
| return DecodingAccuracyEnum.ONLY_FUNCTION_MATCH | ||
|
|
||
| def invalidate_contract_abi_cache( | ||
| self, address: Address | ChecksumAddress, chain_id: int | None | ||
| ) -> None: | ||
| """ | ||
| Evict a specific contract from both per-contract ABI caches. | ||
|
|
||
| Call this whenever a contract's ABI is updated in the database so | ||
| that the next decode request re-fetches the latest ABI rather than | ||
| serving stale data from the in-memory cache. | ||
|
|
||
| :param address: Contract address | ||
| :param chain_id: Chain id for the contract | ||
| """ | ||
| self.get_contract_abi.cache_invalidate(self, address, chain_id) | ||
| self.get_contract_abi_selectors_with_functions.cache_invalidate( | ||
| self, address, chain_id | ||
| ) | ||
|
Comment on lines
+514
to
+517
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Useful? React with 👍 / 👎. |
||
|
|
||
| async def add_abi(self, abi: ABI) -> bool: | ||
| """ | ||
| Add a new abi without rebuilding the entire decoder | ||
|
|
||
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.
process_contract_metadatainvalidates the decoder cache beforeawait contract.update()writes the newabi_idto the database. If a decode request arrives in that gap,get_contract_abiwill repopulate the cache from the still-old DB row, and stale ABI data will remain cached (now for up to the 600s TTL). This makes the “immediate refresh after metadata update” behavior unreliable under concurrent traffic.Useful? React with 👍 / 👎.