diff --git a/api/account/deduplication/__init__.py b/api/account/deduplication/__init__.py
index 8cd025dcb..aed593d86 100644
--- a/api/account/deduplication/__init__.py
+++ b/api/account/deduplication/__init__.py
@@ -3,7 +3,7 @@
class Rules(Enum):
LIFO = "LIFO"
- FIFO = "FIFO"
+ FIFO = "FIFO" # DEPRECATED - this shall not be used any more
@classmethod
def choices(cls):
diff --git a/api/account/deduplication/fifo.py b/api/account/deduplication/fifo.py
deleted file mode 100644
index 2be778c42..000000000
--- a/api/account/deduplication/fifo.py
+++ /dev/null
@@ -1,59 +0,0 @@
-import copy
-from typing import Tuple
-
-import api_logging as logging
-from account.models import Community
-from registry.models import Event, Stamp
-
-log = logging.getLogger(__name__)
-
-
-# --> FIFO deduplication
-async def afifo(
- community: Community, fifo_passport: dict, address: str
-) -> Tuple[dict, list]:
- deduped_passport = copy.deepcopy(fifo_passport)
- affected_passports = []
- if "stamps" in fifo_passport:
- dedup_event_data = []
- new_stamp_hashes = [
- stamp["credential"]["credentialSubject"]["hash"]
- for stamp in fifo_passport["stamps"]
- ]
-
- existing_stamps = (
- Stamp.objects.filter(
- hash__in=new_stamp_hashes, passport__community=community
- )
- .exclude(passport__address=address)
- .select_related("passport")
- )
-
- async for existing_stamp in existing_stamps:
- existing_stamp_passport = existing_stamp.passport
- affected_passports.append(existing_stamp_passport)
- dedup_event_data.append(
- {
- "hash": existing_stamp.hash,
- "provider": existing_stamp.provider,
- "prev_owner": existing_stamp_passport.address,
- "address": address,
- "community_id": community.pk,
- }
- )
-
- await existing_stamps.adelete()
-
- if dedup_event_data:
- await Event.objects.abulk_create(
- [
- Event(
- action=Event.Action.FIFO_DEDUPLICATION,
- address=data["prev_owner"],
- data=data,
- )
- for data in dedup_event_data
- ]
- )
-
- return (deduped_passport, affected_passports)
diff --git a/api/account/test/test_deduplication_fifo.py b/api/account/test/test_deduplication_fifo.py
deleted file mode 100644
index dcc1177f3..000000000
--- a/api/account/test/test_deduplication_fifo.py
+++ /dev/null
@@ -1,178 +0,0 @@
-from datetime import datetime, timedelta
-
-from account.deduplication import Rules
-from account.deduplication.fifo import afifo
-from account.models import Account, Community
-from asgiref.sync import async_to_sync
-from django.contrib.auth import get_user_model
-from django.test import TestCase
-from ninja_jwt.schema import RefreshToken
-from registry.models import Passport, Stamp
-from scorer_weighted.models import Scorer, WeightedScorer
-
-
-class ExistingStamp:
- def __init__(self, hash):
- self.hash = hash
-
-
-User = get_user_model()
-
-mock_community_body = {"name": "test", "description": "test"}
-google_credential = {
- "type": ["VerifiableCredential"],
- "proof": {
- "jws": "eyJhbGciOiJFZERTQSIsImNyaXQiOlsiYjY0Il0sImI2NCI6ZmFsc2V9..UvANt5nz16WNjkGTyUFIxbMBmYdEFZcVrD97L3EzOkvxz8eN-6UKeFZul_uPBfa88h50jKQgVgJlJqxR8kpSAQ",
- "type": "Ed25519Signature2018",
- "created": "2022-06-03T15:33:04.698Z",
- "proofPurpose": "assertionMethod",
- "verificationMethod": "did:key:z6MkghvGHLobLEdj1bgRLhS4LPGJAvbMA1tn2zcRyqmYU5LC#z6MkghvGHLobLEdj1bgRLhS4LPGJAvbMA1tn2zcRyqmYU5LC",
- },
- "issuer": "did:key:z6MkghvGHLobLEdj1bgRLhS4LPGJAvbMA1tn2zcRyqmYU5LC",
- "@context": ["https://www.w3.org/2018/credentials/v1"],
- "issuanceDate": (datetime.utcnow() - timedelta(days=3)).strftime(
- "%Y-%m-%dT%H:%M:%SZ"
- ),
- "expirationDate": (datetime.utcnow() + timedelta(days=30)).strftime(
- "%Y-%m-%dT%H:%M:%SZ"
- ),
- "credentialSubject": {
- "id": "did:pkh:eip155:1:0x0636F974D29d947d4946b2091d769ec6D2d415DE",
- "hash": "v0.0.0:edgFWHsCSaqGxtHSqdiPpEXR06Ejw+YLO9K0BSjz0d8=",
- "@context": [
- {
- "hash": "https://schema.org/Text",
- "provider": "https://schema.org/Text",
- }
- ],
- "provider": "Google",
- },
-}
-
-mock_passport = {
- "issuanceDate": "2022-06-03T15:31:56.944Z",
- "expirationDate": "2022-06-03T15:31:56.944Z",
- "stamps": [
- {"provider": "Google", "credential": google_credential},
- ],
-}
-
-
-class FifoDeduplication(TestCase):
- def setUp(self):
- self.create_test_users()
- self.create_test_communities()
- self.create_sample_passport()
-
- def create_test_users(self):
- User.objects.create_user(username="admin", password="12345")
- self.user = User.objects.create_user(username="testuser-1", password="12345")
- self.user2 = User.objects.create_user(username="testuser-2", password="12345")
-
- refresh = RefreshToken.for_user(self.user)
- refresh["ip_address"] = "127.0.0.1"
- self.access_token = refresh.access_token
-
- def create_test_communities(self):
- (self.account1, _) = Account.objects.get_or_create(
- user=self.user, defaults={"address": "0x0"}
- )
- scorer1 = WeightedScorer.objects.create(
- type=Scorer.Type.WEIGHTED, weights={"test_provider": 10}
- )
- self.community1 = Community.objects.create(
- name="Community1", scorer=scorer1, rule=Rules.FIFO, account=self.account1
- )
-
- (self.account2, _) = Account.objects.get_or_create(
- user=self.user2, defaults={"address": "0x0"}
- )
- scorer2 = WeightedScorer.objects.create(
- type=Scorer.Type.WEIGHTED, weights={"test_provider": 10}
- )
- self.community2 = Community.objects.create(
- name="Community2", scorer=scorer2, rule=Rules.FIFO, account=self.account2
- )
-
- def create_sample_passport(self):
- self.sample_passport = {
- "stamps": [
- {"credential": {"credentialSubject": {"hash": "123"}}},
- {"credential": {"credentialSubject": {"hash": "456"}}},
- {"credential": {"credentialSubject": {"hash": "123"}}},
- ]
- }
-
- @async_to_sync
- async def test_fifo_removes_deduplicate_stamp_from_passport_in_same_community(self):
- """
- Test that the deduplicate stamps are found, deleted, and passport score is updated
- """
- passport1 = await Passport.objects.acreate(
- address="0xaddress_1", community=self.community1
- )
-
- passport2 = await Passport.objects.acreate(
- address="0xaddress_2", community=self.community1
- )
-
- await Stamp.objects.acreate(
- passport=passport1,
- hash=google_credential["credentialSubject"]["hash"],
- provider="test_provider",
- credential=google_credential,
- )
-
- # We call the `fifo` deduplication method
- await afifo(
- community=self.community1,
- fifo_passport=mock_passport,
- address=passport2.address,
- )
-
- updated_passport = await Passport.objects.aget(address="0xaddress_1")
- # We check that the `deduplicated_stamps` queryset contains the stamp we added
-
- self.assertEqual(
- await updated_passport.stamps.acount(),
- 0,
- "The stamp should not have been deleted from the passpo",
- )
-
- @async_to_sync
- async def test_fifo_does_not_remove_deduplicate_stamp_from_passport_in_different_community(
- self,
- ):
- """
- Test that the deduplicate stamps are found, deleted, and passport score is updated
- """
- passport1 = await Passport.objects.acreate(
- address="0xaddress_1", community=self.community2
- )
-
- passport2 = await Passport.objects.acreate(
- address="0xaddress_2", community=self.community1
- )
-
- await Stamp.objects.acreate(
- passport=passport1,
- hash=google_credential["credentialSubject"]["hash"],
- provider="test_provider",
- credential=google_credential,
- )
-
- # We call the `fifo` deduplication method
- await afifo(
- community=self.community1,
- fifo_passport=mock_passport,
- address=passport2.address,
- )
-
- updated_passport = await Passport.objects.aget(address="0xaddress_1")
- # We check that the `deduplicated_stamps` queryset contains the stamp we added
-
- self.assertEqual(
- await updated_passport.stamps.acount(),
- 1,
- "The stamp should not have been deleted from the passpo",
- )
diff --git a/api/registry/api/schema.py b/api/registry/api/schema.py
index a51c01477..11ad13552 100644
--- a/api/registry/api/schema.py
+++ b/api/registry/api/schema.py
@@ -67,7 +67,9 @@ class GenericCommunityResponse(Schema):
class ActionEnum(str, Enum):
- fifo_deduplication = Event.Action.FIFO_DEDUPLICATION
+ fifo_deduplication = (
+ Event.Action.FIFO_DEDUPLICATION
+ ) # DEPRECATED: this deduplication method was deprecated
lifo_deduplication = Event.Action.LIFO_DEDUPLICATION
trustalab_score = Event.Action.TRUSTALAB_SCORE
score_update = Event.Action.SCORE_UPDATE
diff --git a/api/registry/atasks.py b/api/registry/atasks.py
index e14fe374d..67ca8c18e 100644
--- a/api/registry/atasks.py
+++ b/api/registry/atasks.py
@@ -3,7 +3,6 @@
from typing import Dict, List
import api_logging as logging
-from account.deduplication.fifo import afifo
from account.deduplication.lifo import alifo
# --- Deduplication Modules
@@ -75,7 +74,6 @@ async def aprocess_deduplication(passport, community, passport_data, score: Scor
"""
rule_map = {
Rules.LIFO.value: alifo,
- Rules.FIFO.value: afifo,
}
method = rule_map.get(community.rule)
@@ -100,19 +98,19 @@ async def aprocess_deduplication(passport, community, passport_data, score: Scor
)
# If the rule is FIFO, we need to re-score all affected passports
- if community.rule == Rules.FIFO.value:
- for passport in affected_passports:
- log.debug(
- "FIFO scoring selected, rescoring passport='%s'",
- passport,
- )
-
- affected_score, _ = await Score.objects.aupdate_or_create(
- passport=passport,
- defaults=dict(score=None, status=score.status),
- )
- await acalculate_score(passport, passport.community_id, affected_score)
- await affected_score.asave()
+ # if community.rule == Rules.FIFO.value:
+ # for passport in affected_passports:
+ # log.debug(
+ # "FIFO scoring selected, rescoring passport='%s'",
+ # passport,
+ # )
+
+ # affected_score, _ = await Score.objects.aupdate_or_create(
+ # passport=passport,
+ # defaults=dict(score=None, status=score.status),
+ # )
+ # await acalculate_score(passport, passport.community_id, affected_score)
+ # await affected_score.asave()
return deduplicated_passport
diff --git a/api/registry/test/test_passport_submission.py b/api/registry/test/test_passport_submission.py
index 4cb32c962..ed64b7521 100644
--- a/api/registry/test/test_passport_submission.py
+++ b/api/registry/test/test_passport_submission.py
@@ -945,77 +945,6 @@ def test_lifo_deduplication_duplicate_stamps(
self.assertEqual(updated_passport.address, submission_address)
self.assertEqual(updated_passport.stamps.all()[0].provider, "Google")
- @patch("registry.atasks.validate_credential", side_effect=[[], []])
- @patch(
- "registry.atasks.aget_passport",
- return_value=mock_passport_google,
- )
- def test_fifo_deduplication_duplicate_stamps(
- self, aget_passport, validate_credential
- ):
- """
- Test the successful deduplication of stamps by first in first out (FIFO)
- """
- address_1 = self.account.address
- address_2 = self.mock_account.address
-
- fifo_community = Community.objects.create(
- name="My FIFO Community",
- description="My FIFO Community description",
- account=self.user_account,
- rule=Rules.FIFO.value,
- )
-
- # Create first passport
- first_passport = Passport.objects.create(
- address=address_1.lower(),
- community=fifo_community,
- requires_calculation=True,
- )
-
- Stamp.objects.create(
- passport=first_passport,
- hash=ens_credential["credentialSubject"]["hash"],
- provider="Ens",
- credential=ens_credential,
- )
-
- # Create existing stamp that is a duplicate of the one we are going to submit
- Stamp.objects.create(
- passport=first_passport,
- hash=google_credential_2["credentialSubject"]["hash"],
- provider="Google",
- credential=google_credential_2,
- )
-
- # Now we submit a duplicate hash, and expect deduplication to happen
- submission_test_payload = {
- "community": fifo_community.pk,
- "address": address_2,
- "nonce": self.nonce,
- }
-
- submission_response = self.client.post(
- f"{self.base_url}/submit-passport",
- json.dumps(submission_test_payload),
- content_type="application/json",
- HTTP_AUTHORIZATION=f"Token {self.secret}",
- )
-
- self.assertEqual(submission_response.status_code, 200)
-
- # first_passport should have just one stamp and the google stamps should be deleted
- deduped_first_passport = Passport.objects.get(address=address_1)
-
- self.assertEqual(deduped_first_passport.stamps.count(), 1)
- self.assertEqual(deduped_first_passport.stamps.all()[0].provider, "Ens")
-
- # assert submitted passport contains the google stamp
- submitted_passport = Passport.objects.get(address=address_2)
-
- self.assertEqual(submitted_passport.stamps.count(), 1)
- self.assertEqual(submitted_passport.stamps.all()[0].provider, "Google")
-
@patch("registry.atasks.validate_credential", side_effect=[[], []])
@patch(
"registry.atasks.aget_passport",
diff --git a/api/registry/test/test_score_passport.py b/api/registry/test/test_score_passport.py
index 36d348409..5320150e7 100644
--- a/api/registry/test/test_score_passport.py
+++ b/api/registry/test/test_score_passport.py
@@ -3,10 +3,9 @@
from decimal import Decimal
from unittest.mock import call, patch
-from asgiref.sync import async_to_sync
-
from account.deduplication import Rules
from account.models import Account, AccountAPIKey, Community
+from asgiref.sync import async_to_sync
from django.conf import settings
from django.contrib.auth import get_user_model
from django.test import Client, TransactionTestCase
@@ -370,147 +369,6 @@ def test_lifo_duplicate_stamp_scoring(self):
== 2
)
- def test_fifo_duplicate_stamp_scoring(self):
- with patch(
- "scorer_weighted.models.settings.GITCOIN_PASSPORT_WEIGHTS",
- {
- "Google": 1,
- "Ens": 2,
- "POAP": 4,
- },
- ):
- fifo_community = Community.objects.create(
- name="My Community",
- description="My Community description",
- account=self.user_account,
- rule=Rules.FIFO.value,
- )
-
- passport, _ = Passport.objects.update_or_create(
- address=self.account.address,
- community_id=fifo_community.pk,
- requires_calculation=True,
- )
-
- passport_for_already_existing_stamp, _ = Passport.objects.update_or_create(
- address=self.account_2.address,
- community_id=fifo_community.pk,
- requires_calculation=True,
- )
-
- passport_with_duplicates, _ = Passport.objects.update_or_create(
- address=self.account_3.address,
- community_id=fifo_community.pk,
- requires_calculation=True,
- )
-
- already_existing_stamp = {
- "provider": "POAP",
- "credential": {
- "type": ["VerifiableCredential"],
- "credentialSubject": {
- "id": settings.TRUSTED_IAM_ISSUER,
- "hash": "0x1111",
- "provider": "Gitcoin",
- },
- "issuer": settings.TRUSTED_IAM_ISSUER,
- "issuanceDate": "2023-02-06T23:22:58.848Z",
- "expirationDate": "2099-02-06T23:22:58.848Z",
- },
- }
-
- Stamp.objects.update_or_create(
- hash=already_existing_stamp["credential"]["credentialSubject"]["hash"],
- passport=passport_for_already_existing_stamp,
- defaults={
- "provider": already_existing_stamp["provider"],
- "credential": json.dumps(already_existing_stamp["credential"]),
- },
- )
-
- mock_passport_data_with_duplicates = {
- "stamps": [
- mock_passport_data["stamps"][0],
- already_existing_stamp,
- {
- "provider": "Google",
- "credential": {
- "type": ["VerifiableCredential"],
- "credentialSubject": {
- "id": settings.TRUSTED_IAM_ISSUER,
- "hash": "0x12121",
- "provider": "Google",
- },
- "issuer": settings.TRUSTED_IAM_ISSUER,
- "issuanceDate": "2023-02-06T23:22:58.848Z",
- "expirationDate": "2099-02-06T23:22:58.848Z",
- },
- },
- ]
- }
-
- with patch("registry.atasks.validate_credential", side_effect=mock_validate):
- # Score original passport
- with patch(
- "registry.atasks.aget_passport", return_value=mock_passport_data
- ):
- score_registry_passport(fifo_community.pk, passport.address)
-
- assert (
- Event.objects.filter(action=Event.Action.FIFO_DEDUPLICATION).count()
- == 0
- )
-
- assert Stamp.objects.filter(passport=passport).count() == 3
- assert (Score.objects.get(passport=passport).score) == Decimal("3")
-
- # Score passport with duplicates (one duplicate from original passport,
- # one duplicate from already existing stamp)
- with patch(
- "registry.atasks.aget_passport",
- return_value=mock_passport_data_with_duplicates,
- ):
- score_registry_passport(
- fifo_community.pk, passport_with_duplicates.address
- )
-
- # One stamp should be removed from original passport
- original_stamps = Stamp.objects.filter(passport=passport)
- assert len(original_stamps) == 2
-
- assert (Score.objects.get(passport=passport).score) == Decimal("1")
-
- assert (
- Event.objects.filter(action=Event.Action.FIFO_DEDUPLICATION).count()
- == 2
- )
-
- new_stamps = Stamp.objects.filter(passport=passport_with_duplicates)
- assert len(new_stamps) == 3
-
- assert (
- Score.objects.get(passport=passport_with_duplicates).score
- ) == Decimal("7")
-
- passport.requires_calculation = True
- passport.save()
- # Re-score original passport, it should get the full score again
- with patch(
- "registry.atasks.aget_passport", return_value=mock_passport_data
- ):
- score_registry_passport(fifo_community.pk, passport.address)
-
- assert (
- Event.objects.filter(action=Event.Action.FIFO_DEDUPLICATION).count()
- == 3
- )
-
- assert (Score.objects.get(passport=passport).score) == Decimal("3")
-
- assert (
- Score.objects.get(passport=passport_with_duplicates).score
- ) == Decimal("5")
-
def test_score_events(self):
count = Event.objects.filter(action=Event.Action.SCORE_UPDATE).count()
diff --git a/interface/components/NewScorer.tsx b/interface/components/NewScorer.tsx
index 1b00c86a5..db5cf170c 100644
--- a/interface/components/NewScorer.tsx
+++ b/interface/components/NewScorer.tsx
@@ -27,7 +27,7 @@ import { createCommunity } from "../utils/account-requests";
import PopoverInfo from "./PopoverInfo";
import { warningToast } from "./Toasts";
-type DeduplicationType = "FIFO" | "LIFO";
+type DeduplicationType = "LIFO";
interface GitcoinScoringMechanismInterface {
icon: (classes?: string) => JSX.Element;
@@ -273,7 +273,6 @@ const NewScorer = () => {
onChange={(e: any) => setDeduplication(e.target.value)}
>
-