Skip to content

Commit

Permalink
adding consistent hashing for type ids
Browse files Browse the repository at this point in the history
  • Loading branch information
elicbarbieri committed Apr 24, 2024
1 parent 1955f93 commit 2894d82
Showing 1 changed file with 18 additions and 7 deletions.
25 changes: 18 additions & 7 deletions starknet_abi/dispatch.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import hashlib
from dataclasses import dataclass
from typing import Sequence

Expand All @@ -7,15 +8,25 @@
from starknet_abi.decoding_types import DecodedEvent, DecodedFunction
from starknet_abi.exceptions import InvalidCalldataError

consistent_hash = hashlib.md5()
# Python's builtin hash() function is seeded with a random value at startup, so it is not consistent across runs
# Using a consistent hash allows a DecodingDispatcher to be pickled and cached between uses


def _id_hash(id_str: str) -> bytes:
consistent_hash.update(id_str.encode())
# MD5 returns a 16byte digest. We only need the last 8
return consistent_hash.digest()[-8:]


@dataclass(slots=True)
class FunctionDispatchInfo:
"""
Dispatcher storing a function name, and a reference to the type of the event. The reference is the result of
hash(AbiFunction.id_str())
_id_hash(AbiFunction.id_str())
"""

decoder_reference: int # Result of hash(type.id_str())
decoder_reference: bytes # Result of _id_hash(type.id_str())
function_name: str


Expand All @@ -26,7 +37,7 @@ class EventDispatchInfo:
event type id_str(), and is stored in a separate mapping to reduce object size
"""

decoder_reference: int # Result of hash(type.id_str())
decoder_reference: bytes # Result of _id_hash(type.id_str())
event_name: str


Expand Down Expand Up @@ -59,15 +70,15 @@ class DecodingDispatcher:
class_ids: dict[bytes, ClassDispatcher]

function_types: dict[
int, # Result of hash(type.id_str()) --> 8 bytes on 64bit machines
bytes, # Result of _id_hash(type.id_str())
tuple[
Sequence[AbiParameter], # Parameters for Function Inputs
Sequence[StarknetType], # Types of Function Outputs
],
]

event_types: dict[
int, # Result of hash(type.id_str()) --> 8 bytes on 64bit machines
bytes, # Result of _id_hash(type.id_str())
tuple[
Sequence[AbiParameter], # Parameters for Event Data
Sequence[AbiParameter], # Parameters for Event Keys
Expand All @@ -91,7 +102,7 @@ def _add_abi_functions(self, abi: StarknetAbi) -> dict[bytes, FunctionDispatchIn

function_ids = {}
for function in abi.functions.values():
function_type_id = hash(function.id_str())
function_type_id = _id_hash(function.id_str())
if function_type_id not in self.function_types:
self.function_types.update(
{function_type_id: (function.inputs, function.outputs)}
Expand All @@ -117,7 +128,7 @@ def _add_abi_events(self, abi: StarknetAbi) -> dict[bytes, EventDispatchInfo]:
"""
event_ids = {}
for event in abi.events.values():
event_type_id = hash(event.id_str())
event_type_id = _id_hash(event.id_str())
if event_type_id not in self.event_types:
self.event_types.update({event_type_id: (event.data, event.keys)})

Expand Down

0 comments on commit 2894d82

Please sign in to comment.