Skip to content

Commit

Permalink
Only return trusted multisig txs by default
Browse files Browse the repository at this point in the history
- Currently all txs were returned in multisig-txs endpoint
  • Loading branch information
Uxio0 committed Jan 26, 2024
1 parent 6681c3d commit 773ab9d
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 24 deletions.
18 changes: 14 additions & 4 deletions safe_transaction_service/history/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,20 +103,30 @@ class MultisigTransactionFilter(filters.FilterSet):
)
transaction_hash = Keccak256Filter(field_name="ethereum_tx_id")

def filter_confirmations(self, queryset, name: str, value: bool):
def __init__(self, data=None, *args, **kwargs):
if data is not None:
data = data.copy()
data.setdefault("trusted", True)

super().__init__(data, *args, **kwargs)

def filter_confirmations(self, queryset, _name: str, value: bool):
if value:
return queryset.with_confirmations()
else:
return queryset.without_confirmations()

def filter_executed(self, queryset, name: str, value: bool):
def filter_executed(self, queryset, _name: str, value: bool):
if value:
return queryset.executed()
else:
return queryset.not_executed()

def filter_trusted(self, queryset, name: str, value: bool):
return queryset.filter(trusted=value)
def filter_trusted(self, queryset, _name: str, value: bool):
if value:
return queryset.trusted()
else:
return queryset

class Meta:
model = MultisigTransaction
Expand Down
57 changes: 39 additions & 18 deletions safe_transaction_service/history/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1007,7 +1007,11 @@ def test_get_multisig_transactions(self):
self.assertEqual(response.data["count"], 0)
self.assertEqual(response.data["count_unique_nonce"], 0)

multisig_tx = MultisigTransactionFactory(safe=safe_address, proposer=proposer)
multisig_tx = MultisigTransactionFactory(
safe=safe_address, proposer=proposer, trusted=True
)
# Not trusted multisig transaction should not be returned by default
MultisigTransactionFactory(safe=safe_address, proposer=proposer, trusted=False)
response = self.client.get(
reverse("v1:history:multisig-transactions", args=(safe_address,)),
format="json",
Expand Down Expand Up @@ -1041,7 +1045,18 @@ def test_get_multisig_transactions(self):
self.assertEqual(len(response.data["results"][0]["confirmations"]), 1)
self.assertEqual(response.data["results"][0]["proposer"], proposer)

MultisigTransactionFactory(safe=safe_address, nonce=multisig_tx.nonce)
# Check not trusted
response = self.client.get(
reverse("v1:history:multisig-transactions", args=(safe_address,))
+ "?trusted=False",
format="json",
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data["count"], 2)

MultisigTransactionFactory(
safe=safe_address, nonce=multisig_tx.nonce, trusted=True
)
response = self.client.get(
reverse("v1:history:multisig-transactions", args=(safe_address,)),
format="json",
Expand All @@ -1067,21 +1082,23 @@ def test_get_multisig_transactions_unique_nonce(self):

MultisigTransactionFactory(safe=safe_address, nonce=6, trusted=True)
MultisigTransactionFactory(safe=safe_address, nonce=12, trusted=False)

# Unique nonce ignores not trusted transactions by default
response = self.client.get(
url,
format="json",
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data["count"], 2)
self.assertEqual(response.data["count_unique_nonce"], 2)
self.assertEqual(response.data["count"], 1)
self.assertEqual(response.data["count_unique_nonce"], 1)

response = self.client.get(
url + "?trusted=True",
url + "?trusted=False",
format="json",
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data["count"], 1)
self.assertEqual(response.data["count_unique_nonce"], 1)
self.assertEqual(response.data["count"], 2)
self.assertEqual(response.data["count_unique_nonce"], 2)

@mock.patch.object(
DbTxDecoder, "get_data_decoded", return_value={"param1": "value"}
Expand All @@ -1092,7 +1109,7 @@ def test_get_multisig_transactions_not_decoded(
try:
ContractQuerySet.cache_trusted_addresses_for_delegate_call.clear()
multisig_transaction = MultisigTransactionFactory(
operation=SafeOperation.CALL.value, data=b"abcd"
operation=SafeOperation.CALL.value, data=b"abcd", trusted=True
)
safe_address = multisig_transaction.safe
response = self.client.get(
Expand Down Expand Up @@ -1138,7 +1155,7 @@ def test_get_multisig_transactions_filters(self):
self.assertEqual(response.data["count"], 0)

multisig_transaction = MultisigTransactionFactory(
safe=safe_address, nonce=0, ethereum_tx=None
safe=safe_address, nonce=0, ethereum_tx=None, trusted=True
)
response = self.client.get(
reverse("v1:history:multisig-transactions", args=(safe_address,))
Expand Down Expand Up @@ -1259,13 +1276,15 @@ def test_post_multisig_transactions_null_signature(self):
self.assertFalse(multisig_transaction_db.trusted)

response = self.client.get(
reverse("v1:history:multisig-transactions", args=(safe_address,)),
reverse(
"v1:history:multisig-transaction",
args=(data["contractTransactionHash"],),
),
format="json",
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(len(response.data["results"]), 1)
self.assertIsNone(response.data["results"][0]["executor"])
self.assertEqual(len(response.data["results"][0]["confirmations"]), 0)
self.assertIsNone(response.data["executor"])
self.assertEqual(len(response.data["confirmations"]), 0)

def test_post_multisig_transactions(self):
safe_owner_1 = Account.create()
Expand Down Expand Up @@ -1317,14 +1336,16 @@ def test_post_multisig_transactions(self):
self.assertFalse(multisig_transaction_db.trusted)

response = self.client.get(
reverse("v1:history:multisig-transactions", args=(safe_address,)),
reverse(
"v1:history:multisig-transaction",
args=(data["contractTransactionHash"],),
),
format="json",
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(len(response.data["results"]), 1)
self.assertIsNone(response.data["results"][0]["executor"])
self.assertEqual(len(response.data["results"][0]["confirmations"]), 0)
self.assertEqual(response.data["results"][0]["proposer"], data["sender"])
self.assertIsNone(response.data["executor"])
self.assertEqual(len(response.data["confirmations"]), 0)
self.assertEqual(response.data["proposer"], data["sender"])

# Test confirmation with signature
data["signature"] = safe_owner_1.signHash(safe_tx.safe_tx_hash)[
Expand Down
5 changes: 3 additions & 2 deletions safe_transaction_service/history/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,7 @@ def get_unique_nonce(self, address: str):
:return: Number of Multisig Transactions with different nonce
"""
only_trusted = parse_boolean_query_param(
self.request.query_params.get("trusted", False)
self.request.query_params.get("trusted", True)
)
queryset = MultisigTransaction.objects.filter(safe=address)
if only_trusted:
Expand All @@ -696,7 +696,8 @@ def get_serializer_class(self):
)
def get(self, request, *args, **kwargs):
"""
Returns the history of a multisig tx (safe)
Returns a paginated list of Multisig Transactions for a Safe.
By default only ``trusted`` multisig transactions are returned.
"""
address = kwargs["address"]
if not fast_is_checksum_address(address):
Expand Down

0 comments on commit 773ab9d

Please sign in to comment.