Skip to content

Commit

Permalink
[RELEASE] 0.8.0 (#504)
Browse files Browse the repository at this point in the history
  • Loading branch information
aziolek authored Oct 11, 2024
2 parents f490614 + 37df6dd commit a5d270e
Show file tree
Hide file tree
Showing 25 changed files with 1,477 additions and 633 deletions.
1,359 changes: 889 additions & 470 deletions backend/app/constants.py

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions backend/app/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,14 @@ def __init__(self):
super().__init__(self.description, self.code)


class InvalidDelegationRequest(OctantException):
code = 400
description = "Invalid delegation request"

def __init__(self):
super().__init__(self.description, self.code)


class InvalidAddressFormat(OctantException):
code = 400
description = "Invalid address format"
Expand Down
1 change: 1 addition & 0 deletions backend/app/modules/modules_factory/current.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ def create(chain_id: int) -> "CurrentServices":
verifier=score_delegation_verifier,
antisybil=user_antisybil_service,
user_deposits_service=user_deposits,
timeout_list=timeout_list,
)

multisig_signatures = OffchainMultisigSignatures(
Expand Down
9 changes: 9 additions & 0 deletions backend/app/modules/score_delegation/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
AntisybilScoreTooLow,
InvalidRecalculationRequest,
InvalidDelegationForLockingAddress,
InvalidDelegationRequest,
)
from app.modules.common.crypto.signature import (
encode_for_signing,
Expand Down Expand Up @@ -53,7 +54,10 @@ def verify_score_delegation(
score: float,
secondary_budget: int,
action: ActionType,
primary_addr: str,
timeout_list: set,
):
_verify_timeout_list(primary_addr, timeout_list)
_verify_hashed_addresses(action, hashed_addresses, all_hashes)
_verify_score(score)
_verify_non_locking(secondary_budget)
Expand Down Expand Up @@ -87,6 +91,11 @@ def verify_signatures(payload: ScoreDelegationPayload, action: ActionType):
raise InvalidSignature(payload.secondary_addr, payload.secondary_addr_signature)


def _verify_timeout_list(primary_addr: str, timeout_list: set):
if primary_addr in timeout_list:
raise InvalidDelegationRequest()


def _verify_hashed_addresses(
action: ActionType, hashed_addresses: HashedAddresses, all_hashes: Set[str]
):
Expand Down
22 changes: 20 additions & 2 deletions backend/app/modules/score_delegation/service/simple_obfuscation.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,30 @@ def update_antisybil_status(

class SimpleObfuscationDelegationVerifier(Verifier, Model):
def _verify_logic(self, context: Context, **kwargs):
hashed_addresses, action_type, score, secondary_budget = (
(
hashed_addresses,
action_type,
score,
secondary_budget,
primary_addr,
timeout_list,
) = (
kwargs["hashed_addresses"],
kwargs["action_type"],
kwargs["score"],
kwargs["secondary_budget"],
kwargs["primary_addr"],
kwargs["timeout_list"],
)
get_all_delegations = database.score_delegation.get_all_delegations()
core.verify_score_delegation(
hashed_addresses, get_all_delegations, score, secondary_budget, action_type
hashed_addresses,
get_all_delegations,
score,
secondary_budget,
action_type,
primary_addr,
timeout_list,
)

def _verify_signature(self, _: Context, **kwargs):
Expand All @@ -56,6 +71,7 @@ class SimpleObfuscationDelegation(Model):
verifier: Verifier
antisybil: Antisybil
user_deposits_service: UserEffectiveDeposits
timeout_list: set

def delegate(self, context: Context, payload: ScoreDelegationPayload):
primary, secondary, both = get_hashed_addresses(
Expand Down Expand Up @@ -98,6 +114,8 @@ def _delegation(
score=score,
secondary_budget=secondary_budget,
action_type=action,
primary_addr=payload.primary_addr,
timeout_list=self.timeout_list,
)
self.antisybil.update_antisybil_status(
context, payload.primary_addr, score, expires_at, stamps
Expand Down
4 changes: 4 additions & 0 deletions backend/app/modules/user/antisybil/service/initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ def _retry_fetch():
expires_at = _parse_expiration_date(
min([stamp["credential"]["expirationDate"] for stamp in valid_stamps])
)

if user_address in self.timeout_list:
score["score"] = 0.0

return float(score["score"]), expires_at, all_stamps

def update_antisybil_status(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"""Remove existing delegations before E5's AW
Revision ID: 5398b1538a31
Revises: 2060b4c232c6
Create Date: 2024-10-11 12:58:19.806125
"""
from alembic import op


revision = "5398b1538a31"
down_revision = "2060b4c232c6"
branch_labels = None
depends_on = None


def upgrade():
op.execute("TRUNCATE TABLE score_delegation")
op.execute("TRUNCATE TABLE gitcoin_passport_stamps")


def downgrade():
pass
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
from app.shared.blockchain_types import ChainTypes
from app.modules.user.budgets.service.upcoming import UpcomingUserBudgets
from app.modules.snapshots.pending.service.simulated import SimulatedPendingSnapshots
from tests.helpers.constants import UQ_THRESHOLD_MAINNET, TIMEOUT_LIST
from app.constants import UQ_THRESHOLD_MAINNET, TIMEOUT_LIST


def test_future_services_factory():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@
from app import exceptions
from app.modules.common.delegation import hash_addresses
from app.modules.score_delegation import core
from app.exceptions import InvalidDelegationForLockingAddress
from tests.helpers.constants import USER1_ADDRESS, USER2_ADDRESS, USER3_ADDRESS
from app.exceptions import InvalidDelegationForLockingAddress, InvalidDelegationRequest
from tests.helpers.constants import (
USER1_ADDRESS,
USER2_ADDRESS,
USER3_ADDRESS,
TIMEOUT_LIST,
)


def test_score_delegation_passes():
Expand All @@ -18,7 +23,13 @@ def test_score_delegation_passes():
USER1_ADDRESS, USER2_ADDRESS, "salt", "salt_primary"
)
core.verify_score_delegation(
hashed_addresses, {hashed_carol}, 20, 0, core.ActionType.DELEGATION
hashed_addresses,
{hashed_carol},
20,
0,
core.ActionType.DELEGATION,
USER1_ADDRESS,
TIMEOUT_LIST,
)


Expand All @@ -27,7 +38,13 @@ def test_score_delegation_passes_when_there_are_no_other_delegations():
USER1_ADDRESS, USER2_ADDRESS, "salt", "salt_primary"
)
core.verify_score_delegation(
hashed_addresses, set(), 20, 0, core.ActionType.DELEGATION
hashed_addresses,
set(),
20,
0,
core.ActionType.DELEGATION,
USER1_ADDRESS,
TIMEOUT_LIST,
)


Expand All @@ -43,6 +60,25 @@ def test_score_delegation_fails_when_secondary_is_locking():
20,
BUDGET_GREATER_THAN_ZERO,
core.ActionType.DELEGATION,
USER1_ADDRESS,
TIMEOUT_LIST,
)


def test_score_delegation_fails_when_primary_is_timeouted():
hashed_addresses = hash_addresses(
USER1_ADDRESS, USER2_ADDRESS, "salt", "salt_primary"
)
TIMEOUT_LIST = {USER1_ADDRESS}
with pytest.raises(InvalidDelegationRequest):
core.verify_score_delegation(
hashed_addresses,
set(),
20,
100,
core.ActionType.DELEGATION,
USER1_ADDRESS,
TIMEOUT_LIST,
)


Expand All @@ -58,6 +94,8 @@ def test_score_delegation_fails():
20,
0,
core.ActionType.DELEGATION,
USER1_ADDRESS,
TIMEOUT_LIST,
)

with pytest.raises(exceptions.DelegationAlreadyExists):
Expand All @@ -67,6 +105,8 @@ def test_score_delegation_fails():
20,
0,
core.ActionType.DELEGATION,
USER1_ADDRESS,
TIMEOUT_LIST,
)


Expand All @@ -80,6 +120,8 @@ def test_score_recalculation_passes():
20,
0,
core.ActionType.RECALCULATION,
USER1_ADDRESS,
TIMEOUT_LIST,
)


Expand All @@ -89,7 +131,13 @@ def test_score_recalculation_fails_when_there_are_no_other_delegations():
)
with pytest.raises(exceptions.DelegationDoesNotExist):
core.verify_score_delegation(
hashed_addresses, set(), 20, 0, core.ActionType.RECALCULATION
hashed_addresses,
set(),
20,
0,
core.ActionType.RECALCULATION,
USER1_ADDRESS,
TIMEOUT_LIST,
)


Expand All @@ -110,6 +158,8 @@ def test_score_recalculation_fails():
20,
0,
core.ActionType.RECALCULATION,
USER1_ADDRESS,
TIMEOUT_LIST,
)


Expand All @@ -120,7 +170,13 @@ def test_score_is_too_low():

with pytest.raises(exceptions.AntisybilScoreTooLow):
core.verify_score_delegation(
hashed_addresses, set(), 19.9, 0, core.ActionType.DELEGATION
hashed_addresses,
set(),
19.9,
0,
core.ActionType.DELEGATION,
USER1_ADDRESS,
TIMEOUT_LIST,
)


Expand All @@ -129,7 +185,13 @@ def test_score_is_sufficient():
USER1_ADDRESS, USER2_ADDRESS, "salt", "salt_primary"
)
core.verify_score_delegation(
hashed_addresses, set(), 20, 0, core.ActionType.DELEGATION
hashed_addresses,
set(),
20,
0,
core.ActionType.DELEGATION,
USER1_ADDRESS,
TIMEOUT_LIST,
)


Expand Down Expand Up @@ -163,16 +225,16 @@ def check(addresses):
assert set() == check([ALICE, ALICE])
assert set() == check([CAROL, BOB])
assert set() == check([CAROL, ALICE])
assert set([(BOB, ALICE)]) == check([ALICE, BOB])
assert set([(BOB, ALICE)]) == check([BOB, ALICE])
assert set([(BOB, ALICE)]) == check([BOB, ALICE, EVE])
assert set([(BOB, ALICE), (EVE, CAROL)]) == check([BOB, EVE, ALICE, CAROL])
assert {(BOB, ALICE)} == check([ALICE, BOB])
assert {(BOB, ALICE)} == check([BOB, ALICE])
assert {(BOB, ALICE)} == check([BOB, ALICE, EVE])
assert {(BOB, ALICE), (EVE, CAROL)} == check([BOB, EVE, ALICE, CAROL])
start = datetime.now()
assert set([(BOB, ALICE), (EVE, CAROL), (ALICE, FRANK)]) == check(
assert {(BOB, ALICE), (EVE, CAROL), (ALICE, FRANK)} == check(
[ALICE, BOB, CAROL, EVE, FRANK, HEIDI, IVAN, JUDY, MALLORY, NICK]
)
finish = datetime.now()
assert finish - start < timedelta(seconds=2)

# check if address checksumming works as expected
assert set([(BOB, ALICE.lower())]) == check([ALICE.lower(), BOB])
assert {(BOB, ALICE.lower())} == check([ALICE.lower(), BOB])
27 changes: 22 additions & 5 deletions backend/tests/modules/score_delegation/test_simple_obfuscation.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@
SimpleObfuscationDelegationVerifier,
)
from app.modules.user.deposits.service.calculated import CalculatedUserDeposits
from tests.helpers.constants import USER1_ADDRESS, USER2_ADDRESS, USER3_ADDRESS
from tests.helpers.constants import (
USER1_ADDRESS,
USER2_ADDRESS,
USER3_ADDRESS,
TIMEOUT_LIST,
)


@pytest.fixture(autouse=True)
Expand Down Expand Up @@ -44,7 +49,10 @@ def test_delegation(
["stamp"],
)
service = SimpleObfuscationDelegation(
verifier=verifier, antisybil=antisybil, user_deposits_service=user_deposits
verifier=verifier,
antisybil=antisybil,
user_deposits_service=user_deposits,
timeout_list=TIMEOUT_LIST,
)
service.delegate(context, payload)

Expand All @@ -70,7 +78,10 @@ def test_delegation_disabled_when_secondary_is_locking(
secondary_addr_signature="0x5e7e86d5acea5cc431b8d148842e21584a7afe16b7de3b5586d20f5de97179f549726baa021dcaf6220ee5116c579df9d40375fa58d3480390289df6a088b9ec1b",
)
service = SimpleObfuscationDelegation(
verifier=verifier, antisybil=antisybil, user_deposits_service=user_deposits
verifier=verifier,
antisybil=antisybil,
user_deposits_service=user_deposits,
timeout_list=TIMEOUT_LIST,
)
with pytest.raises(InvalidDelegationForLockingAddress):
service.delegate(context, payload)
Expand All @@ -88,7 +99,10 @@ def test_disable_recalculation_when_secondary_address_is_used(
["stamp"],
)
service = SimpleObfuscationDelegation(
verifier=verifier, antisybil=antisybil, user_deposits_service=user_deposits
verifier=verifier,
antisybil=antisybil,
user_deposits_service=user_deposits,
timeout_list=TIMEOUT_LIST,
)
service.delegate(context, payload)

Expand Down Expand Up @@ -120,7 +134,10 @@ def test_recalculation_when_delegation_is_not_done(
["stamp"],
)
service = SimpleObfuscationDelegation(
verifier=verifier, antisybil=antisybil, user_deposits_service=user_deposits
verifier=verifier,
antisybil=antisybil,
user_deposits_service=user_deposits,
timeout_list=TIMEOUT_LIST,
)
service.delegate(context, payload)

Expand Down
Loading

0 comments on commit a5d270e

Please sign in to comment.