2023-02-24 12:23:25 +00:00
|
|
|
import builtins
|
2021-02-25 14:37:02 +00:00
|
|
|
import gc
|
2021-12-08 09:10:58 +00:00
|
|
|
from typing import TYPE_CHECKING
|
2021-02-25 14:37:02 +00:00
|
|
|
|
2024-07-22 06:40:27 +00:00
|
|
|
from storage.cache_common import SESSIONLESS_FLAG, SessionlessCache
|
2021-02-25 14:37:02 +00:00
|
|
|
from trezor import utils
|
2018-07-03 14:20:26 +00:00
|
|
|
|
2021-02-25 14:37:02 +00:00
|
|
|
# XXX
|
|
|
|
# Allocation notes:
|
|
|
|
# Instantiation of a DataCache subclass should make as little garbage as possible, so
|
|
|
|
# that the preallocated bytearrays are compact in memory.
|
|
|
|
# That is why the initialization is two-step: first create appropriately sized
|
|
|
|
# bytearrays, then later call `clear()` on all the existing objects, which resets them
|
|
|
|
# to zero length. This is producing some trash - `b[:]` allocates a slice.
|
|
|
|
|
|
|
|
_SESSIONLESS_CACHE = SessionlessCache()
|
|
|
|
|
|
|
|
|
2024-07-22 06:40:27 +00:00
|
|
|
if utils.USE_THP:
|
|
|
|
from storage import cache_thp
|
2021-02-25 14:37:02 +00:00
|
|
|
|
2024-07-22 06:40:27 +00:00
|
|
|
_PROTOCOL_CACHE = cache_thp
|
|
|
|
else:
|
|
|
|
from storage import cache_codec
|
2020-02-13 09:19:07 +00:00
|
|
|
|
2024-07-22 06:40:27 +00:00
|
|
|
_PROTOCOL_CACHE = cache_codec
|
2020-02-13 09:19:07 +00:00
|
|
|
|
2024-07-22 06:40:27 +00:00
|
|
|
_PROTOCOL_CACHE.initialize()
|
|
|
|
_SESSIONLESS_CACHE.clear()
|
2021-06-10 14:13:24 +00:00
|
|
|
|
2024-07-22 06:40:27 +00:00
|
|
|
gc.collect()
|
2022-10-04 13:39:51 +00:00
|
|
|
|
|
|
|
|
2024-07-22 06:40:27 +00:00
|
|
|
def clear_all() -> None:
|
|
|
|
global autolock_last_touch
|
|
|
|
autolock_last_touch = None
|
|
|
|
_SESSIONLESS_CACHE.clear()
|
|
|
|
_PROTOCOL_CACHE.clear_all()
|
2024-04-23 10:26:46 +00:00
|
|
|
|
|
|
|
|
2023-02-24 12:23:25 +00:00
|
|
|
def get_int_all_sessions(key: int) -> builtins.set[int]:
|
2024-07-22 06:40:27 +00:00
|
|
|
if key & SESSIONLESS_FLAG:
|
|
|
|
values = builtins.set()
|
|
|
|
encoded = _SESSIONLESS_CACHE.get(key)
|
2023-02-24 12:23:25 +00:00
|
|
|
if encoded is not None:
|
|
|
|
values.add(int.from_bytes(encoded, "big"))
|
2024-07-22 06:40:27 +00:00
|
|
|
return values
|
|
|
|
return _PROTOCOL_CACHE.get_int_all_sessions(key)
|
2021-10-15 16:27:22 +00:00
|
|
|
|
|
|
|
|
2024-07-22 06:40:27 +00:00
|
|
|
def get_sessionless_cache() -> SessionlessCache:
|
|
|
|
return _SESSIONLESS_CACHE
|
2020-02-13 09:19:07 +00:00
|
|
|
|
2019-11-08 08:43:32 +00:00
|
|
|
|
2021-12-08 09:10:58 +00:00
|
|
|
if TYPE_CHECKING:
|
2024-07-22 06:40:27 +00:00
|
|
|
from typing import Callable, ParamSpec, TypeVar
|
2020-08-03 16:14:48 +00:00
|
|
|
|
2024-07-22 06:40:27 +00:00
|
|
|
T = TypeVar("T")
|
2021-12-08 09:10:58 +00:00
|
|
|
P = ParamSpec("P")
|
2020-04-20 09:36:28 +00:00
|
|
|
|
|
|
|
|
2024-07-22 06:40:27 +00:00
|
|
|
def check_thp_is_not_used(f: Callable[P, T]) -> Callable[P, T]:
|
|
|
|
"""A type-safe decorator to raise an exception when the function is called with THP enabled.
|
2020-04-20 09:36:28 +00:00
|
|
|
|
2024-07-22 06:40:27 +00:00
|
|
|
This decorator should be removed after the caches for Codec_v1 and THP are properly refactored and separated.
|
|
|
|
"""
|
2020-04-20 09:36:28 +00:00
|
|
|
|
2024-07-22 06:40:27 +00:00
|
|
|
def inner(*args: P.args, **kwargs: P.kwargs) -> T:
|
|
|
|
if utils.USE_THP:
|
|
|
|
raise Exception("Cannot call this function with the new THP enabled")
|
|
|
|
return f(*args, **kwargs)
|
2020-04-20 09:36:28 +00:00
|
|
|
|
2024-07-22 06:40:27 +00:00
|
|
|
return inner
|