Skip to content

Commit

Permalink
oct-1499: merge develop
Browse files Browse the repository at this point in the history
  • Loading branch information
jmikolajczyk committed Apr 5, 2024
2 parents 4f240a6 + 71b9690 commit af55048
Show file tree
Hide file tree
Showing 80 changed files with 1,672 additions and 289 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci-run.yml
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ jobs:
secrets: inherit
with:
image-tag: ${{ github.sha }}
git-ref: ${{ github.ref }}

# +-------------------------
# | Tests: NodeJS
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/deploy-master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ jobs:
secrets: inherit
with:
image-tag: ${{ github.sha }}
git-ref: ${{ github.ref }}
run:
name: Run
uses: ./.github/workflows/tpl-start-env.yml
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
secrets: inherit
with:
image-tag: ${{ needs.run.outputs.sha }}

git-ref: ${{ needs.run.outputs.ref }}
deploy:
name: Deploy
needs:
Expand Down
42 changes: 20 additions & 22 deletions .github/workflows/deploy-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,29 @@ on:
tags:
- v[0-9]+.[0-9]+.[0-9]+

env:
IMAGE_TAG: "${{ github.sha }}"
GIT_TAG: "${{ github.ref }}"

jobs:
build:
name: Build
uses: ./.github/workflows/tpl-images.yml
secrets: inherit
with:
image-tag: ${{ github.sha }}
output:
name: Output Variables
needs:
- build
run-deployment:
name: Run Deployment
runs-on:
- metal
steps:
- name: Show variables for the CI pipeline
run : |
echo '================================'
echo ' Use the following variables'
echo ''
echo "CI_PIPELINE_SOURCE: pipeline"
echo "DEV_IMAGE_TAG: ${{ github.sha }}"
echo "PROD_IMAGE_TAG: ${GIT_TAG##*/}"
- name: Sanitise variables
id: sanitise-vars
env:
IMAGE_TAG: "${{ github.ref }}"
GIT_REF: "${{ github.sha }}"
run: |
set -ex
echo "IMAGE_TAG=${IMAGE_TAG##*/}" >> $GITHUB_OUTPUT
echo "GIT_REF=${GIT_REF}" >> $GITHUB_OUTPUT
shell: bash

- name: Invoke octant-pipelines workflow
uses: benc-uk/workflow-dispatch@v1
with:
workflow: deploy-prod.yml
repo: golemfoundation/octant-pipelines
ref: master
inputs: '{"image_tag":"${{ steps.sanitise-vars.outputs.IMAGE_TAG }}","git_ref":"${{ steps.sanitise-vars.outputs.GIT_REF }}"}'
token: "${{ secrets.GH_BOT_TOKEN }}"
1 change: 1 addition & 0 deletions .github/workflows/deploy-rc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ jobs:
secrets: inherit
with:
image-tag: ${{ github.sha }}
git-ref: ${{ github.ref }}
deploy:
name: Deploy
needs:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/deploy-uat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ jobs:
secrets: inherit
with:
image-tag: ${{ github.sha }}
git-ref: ${{ github.ref }}
run:
name: Run
uses: ./.github/workflows/tpl-start-env.yml
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/tpl-images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ on:
image-tag:
required: true
type: string
git-ref:
required: true
type: string
concurrency:
group: "${{ github.ref }}-images"
cancel-in-progress: true
Expand All @@ -31,6 +34,8 @@ jobs:
# account
# see: https://github.com/actions/checkout/issues/211
path: __local
ref: ${{ inputs.git-ref }}

- name: Login to Docker registry
uses: docker/login-action@v3
with:
Expand Down
2 changes: 2 additions & 0 deletions backend/app/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@
BEACONCHAIN_API = "https://beaconcha.in/api"
ETHERSCAN_API = "https://api.etherscan.io/api"
BITQUERY_API = "https://graphql.bitquery.io"
SAFE_API_MAINNET = "https://safe-transaction-mainnet.safe.global/api/v1"
SAFE_API_SEPOLIA = "https://safe-transaction-sepolia.safe.global/api/v1"
13 changes: 12 additions & 1 deletion backend/app/engine/epochs_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
from app.engine.octant_rewards.total_and_individual.preliminary import (
PreliminaryTotalAndAllIndividualRewards,
)
from app.engine.projects import ProjectSettings
from app.engine.projects import ProjectSettings, DefaultProjectRewards
from app.engine.projects.rewards.threshold.default import DefaultProjectThreshold
from app.engine.user.budget.preliminary import PreliminaryUserBudget
from app.engine.user import UserSettings, DefaultWeightedAverageEffectiveDeposit
from app.engine.user.effective_deposit.weighted_average.weights.timebased.default import (
Expand Down Expand Up @@ -54,6 +55,11 @@ def register_epoch_settings():
timebased_weights=DefaultTimebasedWeights(),
),
),
project=ProjectSettings(
rewards=DefaultProjectRewards(
projects_threshold=DefaultProjectThreshold(2),
),
),
)

SETTINGS[2] = EpochSettings(
Expand All @@ -64,6 +70,11 @@ def register_epoch_settings():
community_fund=NotSupportedCFCalculator(),
),
user=UserSettings(budget=PreliminaryUserBudget()),
project=ProjectSettings(
rewards=DefaultProjectRewards(
projects_threshold=DefaultProjectThreshold(2),
),
),
)

SETTINGS[3] = EpochSettings()
4 changes: 4 additions & 0 deletions backend/app/engine/projects/rewards/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,7 @@ def calculate_project_rewards(
self, payload: ProjectRewardsPayload
) -> ProjectRewardsResult:
pass

@abstractmethod
def calculate_threshold(self, total_allocated: int, projects: list[str]) -> int:
pass
15 changes: 9 additions & 6 deletions backend/app/engine/projects/rewards/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,16 @@ class DefaultProjectRewards(ProjectRewards):
default_factory=DefaultProjectAllocations
)
projects_threshold: ProjectThreshold = field(
default_factory=DefaultProjectThreshold
default_factory=lambda: DefaultProjectThreshold(1)
)

def calculate_threshold(self, total_allocated: int, projects: list[str]) -> int:
return self.projects_threshold.calculate_threshold(
ProjectThresholdPayload(
total_allocated=total_allocated, projects_count=len(projects)
)
)

def calculate_project_rewards(
self, payload: ProjectRewardsPayload
) -> ProjectRewardsResult:
Expand All @@ -37,11 +44,7 @@ def calculate_project_rewards(
) = self.projects_allocations.group_allocations_by_projects(
ProjectAllocationsPayload(allocations=payload.allocations)
)
threshold = self.projects_threshold.calculate_threshold(
ProjectThresholdPayload(
total_allocated=total_allocated, projects_count=len(payload.projects)
)
)
threshold = self.calculate_threshold(total_allocated, payload.projects)

total_allocated_above_threshold = sum(
[allocated for _, allocated in allocated_by_addr if allocated > threshold]
Expand Down
10 changes: 9 additions & 1 deletion backend/app/engine/projects/rewards/threshold/default.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
from dataclasses import dataclass

from app.engine.projects.rewards.threshold import (
ProjectThreshold,
ProjectThresholdPayload,
)


@dataclass
class DefaultProjectThreshold(ProjectThreshold):
PROJECTS_COUNT_MULTIPLIER: int

def calculate_threshold(self, payload: ProjectThresholdPayload) -> int:
return (
int(payload.total_allocated / (payload.projects_count * 2))
int(
payload.total_allocated
/ (payload.projects_count * self.PROJECTS_COUNT_MULTIPLIER)
)
if payload.projects_count
else 0
)
16 changes: 12 additions & 4 deletions backend/app/infrastructure/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def __init__(self, *args, **kwargs):
Resource.__init__(self, *args, *kwargs)

@classmethod
def canonize_address(cls, field_name: str = "user_address", force=True):
def canonize_address(cls, field_name: str, force=True):
def _add_address_canonization(handler):
def _decorated(*args, **kwargs):
field_value = kwargs.get(field_name)
Expand All @@ -36,14 +36,22 @@ def _decorated(*args, **kwargs):

return _add_address_canonization

def __getattribute__(self, name):
user_address_canonizer = OctantResource.canonize_address(force=False)
@classmethod
def _default_address_canonizer(cls, attr):
user_address_canonizer = OctantResource.canonize_address(
field_name="user_address", force=False
)
proposal_address_canonizer = OctantResource.canonize_address(
field_name="proposal_address", force=False
)
return user_address_canonizer(proposal_address_canonizer(attr))

def __getattribute__(self, name):
attr = object.__getattribute__(self, name)

decorator = default_decorators.get(name)
if decorator is not None:
attr = user_address_canonizer(decorator(attr))
attr = OctantResource._default_address_canonizer(decorator(attr))

return attr

Expand Down
7 changes: 3 additions & 4 deletions backend/app/infrastructure/database/allocations.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from app.infrastructure.database.models import Allocation, User, AllocationRequest
from app.infrastructure.database.user import get_by_address
from app.modules.dto import (
AllocationItem,
AllocationDTO,
AccountFundsDTO,
UserAllocationRequestPayload,
Expand Down Expand Up @@ -64,7 +63,7 @@ def get_user_allocations_history(

def get_all_by_user_addr_and_epoch(
user_address: str, epoch: int
) -> List[AllocationItem]:
) -> List[AccountFundsDTO]:
allocations: List[Allocation] = (
Allocation.query.join(User, User.id == Allocation.user_id)
.filter(User.address == user_address)
Expand All @@ -74,8 +73,8 @@ def get_all_by_user_addr_and_epoch(
)

return [
AllocationItem(
proposal_address=alloc.proposal_address,
AccountFundsDTO(
address=alloc.proposal_address,
amount=int(alloc.amount),
)
for alloc in allocations
Expand Down
3 changes: 2 additions & 1 deletion backend/app/infrastructure/database/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class AllocationRequest(BaseModel):
user = relationship("User", backref=db.backref("allocations_requests", lazy=True))
nonce = Column(db.Integer, nullable=False)
epoch = Column(db.Integer, nullable=False)
signature = Column(db.String(132), nullable=False)
signature = Column(db.String, nullable=False)
is_manually_edited = Column(db.Boolean, nullable=True)

__table_args__ = (
Expand Down Expand Up @@ -170,3 +170,4 @@ class MultisigSignatures(BaseModel):
message = Column(db.String, nullable=False)
hash = Column(db.String, nullable=False)
status = Column(db.String, nullable=False)
user_ip = Column(db.String, nullable=False)
6 changes: 6 additions & 0 deletions backend/app/infrastructure/database/multisig_signature.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,24 @@ def get_last_pending_signature(
return last_signature.first()


def get_all_pending_signatures() -> list[MultisigSignatures]:
return MultisigSignatures.query.filter_by(status=SigStatus.PENDING).all()


def save_signature(
user_address: str,
op_type: SignatureOpType,
message: str,
msg_hash: str,
user_ip: str,
status: SigStatus = SigStatus.PENDING,
):
signature = MultisigSignatures(
address=user_address,
type=op_type,
message=message,
hash=msg_hash,
user_ip=user_ip,
status=status,
)
db.session.add(signature)
11 changes: 6 additions & 5 deletions backend/app/infrastructure/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@
from app.exceptions import OctantException
from app.extensions import socketio, epochs
from app.infrastructure.exception_handler import UNEXPECTED_EXCEPTION, ExceptionHandler
from app.modules.dto import ProposalDonationDTO
from app.modules.user.allocations import controller

from app.legacy.controllers.rewards import (
from app.modules.project_rewards.controller import (
get_allocation_threshold,
)
from app.modules.dto import ProposalDonationDTO
from app.modules.project_rewards.controller import get_estimated_project_rewards
from app.modules.user.allocations import controller


@socketio.on("connect")
Expand All @@ -38,8 +37,10 @@ def handle_disconnect():
def handle_allocate(msg):
msg = json.loads(msg)
is_manually_edited = msg["isManuallyEdited"] if "isManuallyEdited" in msg else None
user_address = msg["userAddress"]
app.logger.info(f"User allocation payload: {msg}")
user_address = controller.allocate(
controller.allocate(
user_address,
msg,
is_manually_edited=is_manually_edited,
)
Expand Down
File renamed without changes.
27 changes: 27 additions & 0 deletions backend/app/infrastructure/external_api/safe/message_details.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import requests

import app as app_module
from app.constants import SAFE_API_MAINNET, SAFE_API_SEPOLIA
from app.exceptions import ExternalApiException


def get_message_details(message_hash: str, is_mainnet: bool) -> dict:
api_url = _get_api_url(message_hash, is_mainnet)

try:
response = requests.request("GET", api_url)
response.raise_for_status()
json_response = response.json()
except requests.exceptions.RequestException as e:
app_module.ExceptionHandler.print_stacktrace(e)
raise ExternalApiException(api_url, e, 500)

return json_response


def _get_api_url(
message_hash: str,
is_mainnet: bool,
) -> str:
base_url = SAFE_API_MAINNET if is_mainnet else SAFE_API_SEPOLIA
return f"{base_url}/messages/{message_hash}"
24 changes: 24 additions & 0 deletions backend/app/infrastructure/external_api/safe/user_details.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import requests

import app as app_module
from app.constants import SAFE_API_MAINNET, SAFE_API_SEPOLIA
from app.exceptions import ExternalApiException


def get_user_details(user_address: str, is_mainnet: bool) -> dict:
api_url = _get_api_url(user_address, is_mainnet)

try:
response = requests.request("GET", api_url)
response.raise_for_status()
json_response = response.json()
except requests.exceptions.RequestException as e:
app_module.ExceptionHandler.print_stacktrace(e)
raise ExternalApiException(api_url, e, 500)

return json_response


def _get_api_url(user_address: str, is_mainnet: bool) -> str:
base_url = SAFE_API_MAINNET if is_mainnet else SAFE_API_SEPOLIA
return f"{base_url}/safes/{user_address}"
Loading

0 comments on commit af55048

Please sign in to comment.