Skip to content

Commit 10a101f

Browse files
committed
Bump web3 to v7 and HexBytes to v1
- Update safe-eth-py - Fix some method names - Refactor `.hex()` calls to don't depend on `HexBytes`
1 parent 704cb81 commit 10a101f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+500
-328
lines changed

requirements.txt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ drf-spectacular==0.28.0
2424
firebase-admin==6.6.0
2525
flower==2.0.1
2626
gunicorn[gevent]==22.0.0
27-
hexbytes==0.3.1
2827
hiredis==3.0.0
2928
packaging>=21.0
3029
pika==1.3.2
@@ -33,5 +32,5 @@ psycogreen==1.0.2
3332
psycopg[binary]==3.2.3
3433
redis==5.2.1
3534
requests==2.32.3
36-
safe-eth-py[django]==6.4.0
37-
web3==6.20.2
35+
safe-eth-py[django]==7.0.0
36+
web3==7.8.0

safe_transaction_service/account_abstraction/admin.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from eth_typing import ChecksumAddress
44
from hexbytes import HexBytes
55
from safe_eth.eth.django.admin import AdvancedAdminSearchMixin
6+
from safe_eth.util.util import to_0x_hex_str
67

78
from .models import SafeOperation, UserOperation, UserOperationReceipt
89

@@ -42,11 +43,11 @@ class ForeignClassToUserOperationAdmin(AdvancedAdminSearchMixin, admin.ModelAdmi
4243

4344
@admin.display()
4445
def ethereum_tx(self, obj: ForeignClassToUserOperationType) -> str:
45-
return HexBytes(obj.user_operation.ethereum_tx.tx_hash).hex()
46+
return to_0x_hex_str(HexBytes(obj.user_operation.ethereum_tx.tx_hash))
4647

4748
@admin.display()
4849
def user_operation_hash(self, obj: ForeignClassToUserOperationType) -> str:
49-
return HexBytes(obj.user_operation.hash).hex()
50+
return to_0x_hex_str(HexBytes(obj.user_operation.hash))
5051

5152
@admin.display()
5253
def user_operation_sender(

safe_transaction_service/account_abstraction/management/commands/reindex_4337.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from eth_typing import ChecksumAddress
66
from safe_eth.eth.utils import fast_to_checksum_address
7+
from safe_eth.util.util import to_0x_hex_str
78

89
from safe_transaction_service.history.models import EthereumTx
910

@@ -39,7 +40,7 @@ def reindex(
3940
self,
4041
addresses: Optional[Sequence[ChecksumAddress]],
4142
) -> None:
42-
topic = USER_OPERATION_EVENT_TOPIC.hex()
43+
topic = to_0x_hex_str(USER_OPERATION_EVENT_TOPIC)
4344
aa_processor_service = get_aa_processor_service()
4445
processed_user_operations = 0
4546
for tx in EthereumTx.objects.account_abstraction_txs():

safe_transaction_service/account_abstraction/models.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
)
1919
from safe_eth.safe.account_abstraction import SafeOperation as SafeOperationClass
2020
from safe_eth.safe.safe_signature import SafeSignatureType
21+
from safe_eth.util.util import to_0x_hex_str
2122

2223
from safe_transaction_service.history import models as history_models
2324
from safe_transaction_service.utils.constants import SIGNATURE_LENGTH
@@ -58,7 +59,7 @@ class Meta:
5859
]
5960

6061
def __str__(self) -> str:
61-
return f"{HexBytes(self.hash).hex()} UserOperation for sender={self.sender} with nonce={self.nonce}"
62+
return f"{to_0x_hex_str(HexBytes(self.hash))} UserOperation for sender={self.sender} with nonce={self.nonce}"
6263

6364
@cached_property
6465
def paymaster_and_data(self) -> Optional[HexBytes]:
@@ -123,7 +124,7 @@ class UserOperationReceipt(models.Model):
123124
deposited = Uint256Field()
124125

125126
def __str__(self) -> str:
126-
return f"{HexBytes(self.user_operation_id).hex()} UserOperationReceipt"
127+
return f"{to_0x_hex_str(HexBytes(self.user_operation_id))} UserOperationReceipt"
127128

128129

129130
class SafeOperationQuerySet(models.QuerySet):
@@ -151,7 +152,7 @@ class SafeOperation(TimeStampedModel):
151152
module_address = EthereumAddressBinaryField(db_index=True)
152153

153154
def __str__(self) -> str:
154-
return f"{HexBytes(self.hash).hex()} SafeOperation for user-operation={HexBytes(self.user_operation_id).hex()}"
155+
return f"{to_0x_hex_str(HexBytes(self.hash))} SafeOperation for user-operation={to_0x_hex_str(HexBytes(self.user_operation_id))}"
155156

156157
def build_signature_prefix(self) -> bytes:
157158
"""
@@ -217,5 +218,5 @@ class Meta:
217218
def __str__(self):
218219
return (
219220
f"Safe Operation Confirmation of owner={self.owner} for "
220-
f"safe-operation={HexBytes(self.safe_operation_id).hex()}"
221+
f"safe-operation={to_0x_hex_str(HexBytes(self.safe_operation_id))}"
221222
)

safe_transaction_service/account_abstraction/serializers.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from safe_eth.eth.utils import fast_keccak, fast_to_checksum_address
1616
from safe_eth.safe.account_abstraction import SafeOperation as SafeOperationClass
1717
from safe_eth.safe.safe_signature import SafeSignature, SafeSignatureType
18+
from safe_eth.util.util import to_0x_hex_str
1819

1920
from safe_transaction_service.utils.constants import SIGNATURE_LENGTH
2021
from safe_transaction_service.utils.ethereum import get_chain_id
@@ -72,11 +73,11 @@ def _validate_signature(
7273
if owner not in safe_owners:
7374
raise ValidationError(
7475
f"Signer={owner} is not an owner. Current owners={safe_owners}. "
75-
f"Safe-operation-hash={safe_operation_hash.hex()}"
76+
f"Safe-operation-hash={to_0x_hex_str(safe_operation_hash)}"
7677
)
7778
if not safe_signature.is_valid(self.ethereum_client, safe_address):
7879
raise ValidationError(
79-
f"Signature={safe_signature.signature.hex()} for owner={owner} is not valid"
80+
f"Signature={to_0x_hex_str(safe_signature.signature)} for owner={owner} is not valid"
8081
)
8182
if owner in owners_processed:
8283
raise ValidationError(f"Signature for owner={owner} is duplicated")
@@ -241,7 +242,7 @@ def validate(self, attrs):
241242

242243
if SafeOperationModel.objects.filter(hash=safe_operation_hash).exists():
243244
raise ValidationError(
244-
f"SafeOperation with hash={safe_operation_hash.hex()} already exists"
245+
f"SafeOperation with hash={to_0x_hex_str(safe_operation_hash)} already exists"
245246
)
246247

247248
safe_signatures = self._validate_signature(
@@ -456,7 +457,7 @@ def get_prepared_signature(self, obj: SafeOperationModel) -> HexStr:
456457
:return: Serialized queryset
457458
"""
458459
signature = obj.build_signature()
459-
return HexStr(HexBytes(signature).hex())
460+
return to_0x_hex_str(HexBytes(signature))
460461

461462

462463
class SafeOperationWithUserOperationResponseSerializer(SafeOperationResponseSerializer):

safe_transaction_service/account_abstraction/services/aa_processor_service.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from safe_eth.eth.utils import fast_to_checksum_address
1919
from safe_eth.safe.account_abstraction import SafeOperation
2020
from safe_eth.safe.safe_signature import SafeSignature
21+
from safe_eth.util.util import to_0x_hex_str
2122
from web3.types import LogReceipt
2223

2324
from safe_transaction_service.history import models as history_models
@@ -161,15 +162,15 @@ def index_safe_operation(
161162
"[%s] Cannot find ExecutionFromModuleSuccess or ExecutionFromModuleFailure "
162163
"events for user-operation-hash=%s , it seems like UserOperation was reverted",
163164
user_operation_model.sender,
164-
user_operation.user_operation_hash.hex(),
165+
to_0x_hex_str(user_operation.user_operation_hash),
165166
)
166167
if user_operation_receipt.get_deployed_account():
167168
# UserOperation `initCode` was executed but `callData` failed, so account was deployed but
168169
# SafeOperation was reverted
169170
logger.info(
170171
"[%s] user-operation-hash=%s was reverted but contract was deployed",
171172
user_operation_model.sender,
172-
user_operation.user_operation_hash.hex(),
173+
to_0x_hex_str(user_operation.user_operation_hash),
173174
)
174175
# As `module_address` cannot be detected there's not enough data to index the SafeOperation
175176
return None
@@ -195,8 +196,8 @@ def index_safe_operation(
195196
logger.debug(
196197
"[%s] safe-operation-hash=%s for user-operation-hash=%s was already indexed",
197198
user_operation_model.sender,
198-
HexBytes(safe_operation_hash).hex(),
199-
user_operation.user_operation_hash.hex(),
199+
to_0x_hex_str(HexBytes(safe_operation_hash)),
200+
to_0x_hex_str(user_operation.user_operation_hash),
200201
)
201202
self.index_safe_operation_confirmations(
202203
HexBytes(safe_operation.signature), safe_operation_model, safe_operation
@@ -214,8 +215,8 @@ def index_user_operation_receipt(
214215
:return: Tuple with ``UserOperation`` and ``UserOperationReceipt``
215216
"""
216217
safe_address = user_operation_model.sender
217-
user_operation_hash_hex = HexBytes(user_operation_model.hash).hex()
218-
tx_hash = HexBytes(user_operation_model.ethereum_tx_id).hex()
218+
user_operation_hash_hex = to_0x_hex_str(HexBytes(user_operation_model.hash))
219+
tx_hash = to_0x_hex_str(HexBytes(user_operation_model.ethereum_tx_id))
219220
logger.debug(
220221
"[%s] Retrieving UserOperation Receipt with user-operation-hash=%s on tx-hash=%s",
221222
safe_address,
@@ -285,7 +286,7 @@ def index_user_operation(
285286
:param ethereum_tx: Stored EthereumTx in database containing the ``UserOperation``
286287
:return: tuple of ``UserOperationModel`` and ``UserOperation``
287288
"""
288-
user_operation_hash_hex = user_operation_hash.hex()
289+
user_operation_hash_hex = to_0x_hex_str(user_operation_hash)
289290
# If the UserOperationReceipt is present, UserOperation was already processed and mined
290291
if self.is_user_operation_indexed(user_operation_hash_hex):
291292
logger.warning(

safe_transaction_service/account_abstraction/tests/factories.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from safe_eth.eth.constants import NULL_ADDRESS
99
from safe_eth.eth.utils import fast_keccak_text
1010
from safe_eth.safe.safe_signature import SafeSignatureType
11+
from safe_eth.util.util import to_0x_hex_str
1112

1213
from safe_transaction_service.history.tests import factories as history_factories
1314

@@ -23,7 +24,9 @@ class Params:
2324
valid_after = 0
2425
valid_until = 0
2526

26-
hash = factory.Sequence(lambda n: fast_keccak_text(f"user-operation-{n}").hex())
27+
hash = factory.Sequence(
28+
lambda n: to_0x_hex_str(fast_keccak_text(f"user-operation-{n}"))
29+
)
2730
ethereum_tx = factory.SubFactory(history_factories.EthereumTxFactory)
2831
sender = factory.LazyFunction(lambda: Account.create().address)
2932
nonce = factory.Sequence(lambda n: n)
@@ -59,7 +62,9 @@ class SafeOperationFactory(DjangoModelFactory):
5962
class Meta:
6063
model = models.SafeOperation
6164

62-
hash = factory.Sequence(lambda n: fast_keccak_text(f"safe-operation-{n}").hex())
65+
hash = factory.Sequence(
66+
lambda n: to_0x_hex_str(fast_keccak_text(f"safe-operation-{n}"))
67+
)
6368
user_operation = factory.SubFactory(UserOperationFactory)
6469
valid_after = factory.LazyFunction(timezone.now)
6570
valid_until = factory.LazyFunction(timezone.now)
@@ -76,6 +81,6 @@ class Params:
7681
safe_operation = factory.SubFactory(SafeOperationFactory)
7782
owner = factory.LazyAttribute(lambda o: o.signing_owner.address)
7883
signature = factory.LazyAttribute(
79-
lambda o: o.signing_owner.signHash(o.safe_operation.hash)["signature"]
84+
lambda o: o.signing_owner.unsafe_sign_hash(o.safe_operation.hash)["signature"]
8085
)
8186
signature_type = SafeSignatureType.EOA.value

safe_transaction_service/account_abstraction/tests/services/test_aa_processor_service.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
user_operation_v07_hash,
1818
user_operation_v07_mock,
1919
)
20+
from safe_eth.util.util import to_0x_hex_str
2021

2122
from safe_transaction_service.account_abstraction.services import (
2223
get_aa_processor_service,
@@ -71,7 +72,8 @@ def tearDown(self):
7172
"get_user_operation_by_hash",
7273
autospec=True,
7374
return_value=UserOperationClass.from_bundler_response(
74-
safe_4337_user_operation_hash_mock.hex(), user_operation_mock["result"]
75+
to_0x_hex_str(safe_4337_user_operation_hash_mock),
76+
user_operation_mock["result"],
7577
),
7678
)
7779
@mock.patch.object(
@@ -97,10 +99,10 @@ def test_process_aa_transaction(
9799
user_operation_confirmation_model = SafeOperationConfirmationModel.objects.get()
98100

99101
self.assertEqual(
100-
user_operation_model.hash, aa_expected_user_operation_hash.hex()
102+
user_operation_model.hash, to_0x_hex_str(aa_expected_user_operation_hash)
101103
)
102104
self.assertEqual(
103-
safe_operation_model.hash, aa_expected_safe_operation_hash.hex()
105+
safe_operation_model.hash, to_0x_hex_str(aa_expected_safe_operation_hash)
104106
)
105107
self.assertEqual(user_operation_receipt_model.deposited, 759940285250436)
106108
self.assertEqual(
@@ -128,7 +130,8 @@ def test_process_aa_transaction(
128130
"get_user_operation_by_hash",
129131
autospec=True,
130132
return_value=UserOperationClass.from_bundler_response(
131-
user_operation_v07_hash.hex(), user_operation_v07_mock["result"]
133+
to_0x_hex_str(user_operation_v07_hash),
134+
user_operation_v07_mock["result"],
132135
),
133136
)
134137
@mock.patch.object(

safe_transaction_service/account_abstraction/tests/test_models.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
user_operation_mock,
99
)
1010
from safe_eth.safe.account_abstraction import SafeOperation as SafeOperationClass
11+
from safe_eth.util.util import to_0x_hex_str
1112

1213
from safe_transaction_service.history.tests import factories as history_factories
1314

@@ -20,7 +21,8 @@ class TestModels(TestCase):
2021
def test_user_operation(self):
2122
expected_user_operation_hash = safe_4337_user_operation_hash_mock
2223
expected_user_operation = UserOperationClass.from_bundler_response(
23-
expected_user_operation_hash.hex(), user_operation_mock["result"]
24+
to_0x_hex_str(expected_user_operation_hash),
25+
user_operation_mock["result"],
2426
)
2527
expected_safe_operation = SafeOperationClass.from_user_operation(
2628
expected_user_operation

0 commit comments

Comments
 (0)