Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RELEASE] 0.6.0 #356

Draft
wants to merge 68 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
f218eed
OCT-1516: Improve processing in an asynchronous way (#353)
kgarbacinski Jul 23, 2024
4af8d30
OCT-1750: introduce redis cache
mike-code Jul 23, 2024
77fb77f
trigger CI
mike-code Jul 23, 2024
77741ec
OCT-1768 & OCT-1767: Change the verifier logic for E4 (#344)
kgarbacinski Jul 24, 2024
e53d34e
Merge branch 'master' into develop
aziolek Jul 24, 2024
9068957
Merge branch 'master' into develop
aziolek Jul 24, 2024
917c6da
sanity tests for info endpoints
MateuszStoleckiGLM Jul 19, 2024
21e6d93
fix readme command to run one api test
MateuszStoleckiGLM Jul 19, 2024
ec62975
one left out method not updated for sync status changes
MateuszStoleckiGLM Jul 19, 2024
bef3608
one more regression fix
MateuszStoleckiGLM Jul 19, 2024
d8cb45e
Merge branch 'master' into develop
aziolek Jul 26, 2024
4f60b14
Merge branch 'master' into develop
aziolek Jul 28, 2024
23823b0
multideployer: better handling of errors
paulperegud Jul 26, 2024
48c02ea
bump hardhat version (& bump node for contracts)
paulperegud Jul 26, 2024
dcbb945
Merge branch 'master' into develop
aziolek Jul 29, 2024
5219678
OCT-1596 Implement automated sanity tests for Info API section (#345)
paulperegud Jul 29, 2024
69aad73
Merge branch 'master' into develop
aziolek Jul 30, 2024
306859e
OCT-1750: introduce redis cache (#355)
mike-code Jul 31, 2024
0c40459
Use local IPFS gateway for test envs
mslomnicki Jul 19, 2024
44e57fa
Use local IPFS gateway for test envs (#347)
mslomnicki Aug 1, 2024
0dd53fc
Merge branch 'master' into develop
aziolek Aug 6, 2024
00d8957
OCT-1842: Reduce sentry events flood
mike-code Aug 1, 2024
3ecfda0
Update wording
mike-code Aug 4, 2024
9fcf0a4
Revert "OCT-1842: Reduce sentry events flood"
mike-code Aug 5, 2024
c2bfade
Use local IPFS gateway for test envs
mslomnicki Aug 5, 2024
e583504
Use local IPFS gateway for test envs (#381)
mslomnicki Aug 7, 2024
43ac141
OCT-1730: Improvements for the epoch verifier (#368)
kgarbacinski Aug 7, 2024
329d8d1
basic api tests for history endpoint
MateuszStoleckiGLM May 31, 2024
0c207ba
code review change
MateuszStoleckiGLM Aug 1, 2024
381c857
OCT-1597 Implement automated sanity tests for History endpoint (#369)
MateuszStoleckiGLM Aug 8, 2024
e77fb43
Reapply "OCT-1842: Reduce sentry events flood"
mike-code Aug 8, 2024
2ee40ee
[CI/CD] Update uat.env contracts
housekeeper-bot Aug 9, 2024
6ba54d3
FIX-OCT-1839: Set created_at field (#376)
kgarbacinski Aug 9, 2024
778f0f0
[SYNC] Master to develop (#387)
kgarbacinski Aug 14, 2024
00de2a1
OCT-1842: Reduce sentry events flood (#375)
mike-code Aug 19, 2024
112763e
Bump helm version (0.2.56 -> 0.2.57) - graphnode db memory issues
mslomnicki Aug 21, 2024
656645f
Bump helm version (0.2.57 -> 0.2.58) - graphnode db memory issues
mslomnicki Aug 21, 2024
430d028
Bump helm version (0.2.58 -> 0.2.59) - update graph-node
mslomnicki Aug 21, 2024
f30d798
[CI/CD] Update uat.env contracts
housekeeper-bot Aug 22, 2024
a38af09
Bump helm version (0.2.59 -> 0.2.60) - graph-node db fix
mslomnicki Aug 23, 2024
adb9c3a
OCT-1860: Cover /delegate with API Tests (#391)
kgarbacinski Aug 24, 2024
d28c587
OCT-1863: Cover UQ with API Tests (#390)
kgarbacinski Aug 25, 2024
66314fa
Bump Argo app to 0.2.61
mike-code Aug 25, 2024
dba3c31
Remove debug envs from the graph deployment
mike-code Aug 25, 2024
9cf28d9
Merge remote-tracking branch 'origin/master' into sync/27-08-master-t…
kgarbacinski Aug 27, 2024
25d0207
Bump Argo app to 0.2.62
mike-code Aug 27, 2024
d4bc66d
Bump Argo app to 0.2.62
mike-code Aug 27, 2024
063818f
[SYNC] master => develop (#396)
aziolek Aug 27, 2024
e649fd9
OCT-1864: Add an exception for invalid user address (#389)
kgarbacinski Aug 27, 2024
66f5304
OCT-1862: Cover /check in delegation with API Tests (#392)
kgarbacinski Aug 28, 2024
cbe3583
[CI/CD] Update uat.env contracts
housekeeper-bot Aug 28, 2024
2b0fa2a
wip
MateuszStoleckiGLM Aug 7, 2024
cb11a15
wip
MateuszStoleckiGLM Aug 28, 2024
a12b50e
Bump Argo app to 0.2.63
mike-code Aug 28, 2024
a65a0f3
Merge branch 'develop' of github.com:golemfoundation/octant into develop
mike-code Aug 28, 2024
077ed90
Bump argo app to 0.2.64
mslomnicki Aug 29, 2024
ce20c51
WIP
MateuszStoleckiGLM Aug 30, 2024
44a889f
OCT-1837 & OCT-1838: Upgrade metrics pie chart for unused MR (#383)
kgarbacinski Sep 2, 2024
143eabd
OCT-1861: Cover /recalculate with API Tests (#394)
kgarbacinski Sep 2, 2024
bceb433
OCT-1714 API Tests: Implement tests for epoch4 with capped QF (alloca…
kgarbacinski Sep 2, 2024
c3354b6
[CI/CD] Update uat.env contracts
housekeeper-bot Sep 4, 2024
5eeab89
rewards basics tests + formatting
MateuszStoleckiGLM Sep 9, 2024
ac5bf51
add comment regarding one defect
MateuszStoleckiGLM Sep 9, 2024
ba0958a
Uncommented assertions for budget estimations
MateuszStoleckiGLM Sep 10, 2024
277d02a
OCT-1598 rewards api sanity test (#407)
MateuszStoleckiGLM Sep 16, 2024
785368a
OCT-1938: Propose a changelog (#414)
kgarbacinski Sep 18, 2024
16ac5ae
OCT-1843: Refetch when getting 404 error (#411)
kgarbacinski Sep 18, 2024
67ee7b8
OCT-1943: Add project searching on the server side (#419)
kgarbacinski Sep 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions backend/app/modules/common/synchronized.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from threading import Lock
from functools import wraps
from typing import Callable


def synchronized(wrapped: Callable):
lock = Lock()

@wraps(wrapped)
def _wrap(*args, **kwargs):
with lock:
return wrapped(*args, **kwargs)

return _wrap
2 changes: 2 additions & 0 deletions backend/app/modules/facades/confirm_multisig.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
)
from app.modules.user.allocations import controller as allocations_controller
from app.modules.user.tos import controller as tos_controller
from app.modules.common.synchronized import synchronized


@synchronized
def confirm_multisig():
"""
This is a facade function that is used to confirm (i.e approve and apply) multisig approvals.
Expand Down
11 changes: 4 additions & 7 deletions backend/app/modules/multisig_signatures/service/offchain.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from typing import List
from typing import List, Dict

from app.context.manager import Context
from app.exceptions import InvalidMultisigSignatureRequest, InvalidMultisigAddress
from app.extensions import db
from app.infrastructure import database
from app.infrastructure.database.models import MultisigSignatures
from app.infrastructure.database.multisig_signature import SigStatus, MultisigFilters

from app.infrastructure.external_api.common import retry_request
from app.infrastructure.external_api.safe.message_details import get_message_details
from app.modules.common.allocations.deserializer import deserialize_payload
from app.modules.common.crypto.eip1271 import get_message_hash
from app.modules.common.crypto.signature import (
Expand All @@ -23,16 +23,13 @@
)
from app.modules.multisig_signatures.dto import Signature
from app.pydantic import Model
from app.infrastructure.external_api.safe.message_details import get_message_details


class OffchainMultisigSignatures(Model):
is_mainnet: bool = False
verifiers: dict[SignatureOpType, Verifier]
verifiers: Dict[SignatureOpType, Verifier]

staged_signatures: list[
MultisigSignatures
] = [] # TODO make it invulnerable for data race & race conditions
staged_signatures: List[MultisigSignatures] = []

def get_last_pending_signature(
self, _: Context, user_address: str, op_type: SignatureOpType
Expand Down
63 changes: 63 additions & 0 deletions epoch-verifier/src/_deprecated/epoch3/data/context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import {
Address,
Allocation,
AllocationRecord,
EpochInfo,
Reward,
UserBudget,
UserDonation
} from "./models"

export interface Context {
allocations: Allocation[]
budgets: Map<Address, bigint>
epochInfo: EpochInfo
rewards: Reward[]
}

function transformToAllocations(allocationRecords: AllocationRecord[]): Allocation[] {
const allocations: Map<Address, Allocation> = new Map()

for (const record of allocationRecords) {
const prev = allocations.get(record.user) ?? { donations: [], user: record.user }
prev.donations.push({ amount: record.amount, proposal: record.proposal })
allocations.set(record.user, prev)
}

return Array.from(allocations.values())
}

export function buildContext(userBudgets: UserBudget[], allocations: AllocationRecord[], rewards: Reward[], epochInfo: EpochInfo): Context {

const positiveUserBudgets = userBudgets.filter(positiveUserBudget => positiveUserBudget.amount !== BigInt(0));

return {
allocations: transformToAllocations(allocations),
budgets: new Map(positiveUserBudgets.map(value => [value.user, value.amount] as const)),
epochInfo,
rewards
}
}

export function allocationsByUser(context: Context): Map<Address, UserDonation[]> {
return new Map(context.allocations.map((alloc) => [alloc.user, alloc.donations] as const))
}

export function individualDonationsByProjects(context: Context): Map<Address, bigint> {
const individualDonations: Map<Address, bigint> = new Map()
const donations: UserDonation[] = context.allocations.flatMap((alloc) => alloc.donations)

for (const donation of donations) {
const prev = individualDonations.get(donation.proposal) ?? BigInt(0)
individualDonations.set(donation.proposal, prev + donation.amount)
}

return individualDonations
}

export function rewardsByProject(context: Context): Map<Address, Reward> {
return new Map(context.rewards
.filter(r => r.matched !== BigInt(0))
.map((r) => [r.proposal, r] as const)
);
}
70 changes: 70 additions & 0 deletions epoch-verifier/src/_deprecated/epoch3/data/fetcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/* eslint-disable no-console */
import { Axios } from "axios"

import {
AllocationImpl,
Deserializable,
EpochInfo,
EpochInfoImpl,
RewardImpl,
Reward,
UserBudgetImpl,
UserBudget,
AllocationRecord,
ApiRewardsBudgets, ApiAllocations, ApiRewards,
} from "./models";

const REQUEST_TIMEOUT = 150_000;

export class HttpFetcher {
readonly axios: Axios

constructor(baseUrl: string) {
this.axios = new Axios({ baseURL: baseUrl, timeout: REQUEST_TIMEOUT })
}

async _get<T>(url: string, resource: string, Factory: { new(): Deserializable<T> }): Promise<T | null> {
const mapper = (data: any): T => new Factory().from(JSON.parse(data))
return this._do_get(url, resource, mapper)
}

async _get_array<T>(url: string, resource: string, Factory: { new(): Deserializable<T> }, unwrapper?: (data: any) => any): Promise<Array<T> | null> {

const dataUnwrapper = unwrapper ?? ((data: any) => data)

const mapper = (data: any): Array<T> => dataUnwrapper(JSON.parse(data)).map((elem: any): T => new Factory().from(elem))
return this._do_get(url, resource, mapper)
}

async _do_get<T>(url: string, resource: string, mapper: (data: any) => T): Promise<T | null> {

return this.axios.get(url).then(response => {
if (response.status !== 200) {
throw new Error(response.data)
}
console.log(`✅ Fetched ${resource} ${response.data}`)
return mapper(response.data)

}).catch(reason => {
console.error(`❗ Failed to fetch ${resource} due to: ${reason}`)
return null
})
}


async apiGetUserBudgets(epoch: number): Promise<UserBudget[] | null> {
return this._get_array(`/rewards/budgets/epoch/${epoch}`, "users' budgets", UserBudgetImpl, (data: ApiRewardsBudgets) => data.budgets)
}

async apiGetAllocations(epoch: number): Promise<AllocationRecord[] | null> {
return this._get_array(`/allocations/epoch/${epoch}?includeZeroAllocations=true`, "users' allocations", AllocationImpl, (data: ApiAllocations) => data.allocations)
}

async apiGetRewards(epoch: number): Promise<Reward[] | null> {
return this._get_array(`/rewards/projects/epoch/${epoch}`, "projects rewards", RewardImpl, (data: ApiRewards) => data.rewards)
}

async apiGetEpochInfo(epoch: number): Promise<EpochInfo | null> {
return this._get(`/epochs/info/${epoch}`, "epoch info", EpochInfoImpl)
}
}
158 changes: 158 additions & 0 deletions epoch-verifier/src/_deprecated/epoch3/data/models.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
/* eslint-disable max-classes-per-file */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
export type Address = string;

export interface Deserializable<T> {
from(input: any): T;
}

export interface ApiRewardsBudgets {
budgets: {
address: string;
amount: string; // wei;
}[];
}

export interface ApiAllocations {
allocations: {
amount: string; // wei
donor: string;
proposal: string;
}[];
}

export interface ApiRewards {
rewards: {
address: string;
value: string; // wei;
}[];
}


export interface UserBudget {
amount: bigint;
user: Address;
}

export interface UserDonation {
amount: bigint;
proposal: Address;
}

export interface AllocationRecord {
amount: bigint;
proposal: Address;
user: Address;
}

export interface Allocation {
donations: UserDonation[];
user: Address;
}

export interface Reward {
allocated: bigint;
matched: bigint;
proposal: Address;
}

export interface EpochInfo {
communityFund: bigint;
individualRewards: bigint;
leftover: bigint;
matchedRewards: bigint;
operationalCost: bigint;
patronsRewards: bigint;
ppf: bigint;
stakingProceeds: bigint;
totalEffectiveDeposit: bigint;
totalRewards: bigint;
totalWithdrawals: bigint;
}

export class UserBudgetImpl implements Deserializable<UserBudget> {
user: Address;

amount: bigint;

from(input: any) {
this.user = input.address;
this.amount = BigInt(input.amount)

return this
}
}

export class AllocationImpl implements Deserializable<AllocationRecord> {
user: Address;

proposal: Address;

amount: bigint;

from(input: any) {
this.user = input.donor
this.proposal = input.proposal;
this.amount = BigInt(input.amount ?? 0)

return this
}
}

export class RewardImpl implements Deserializable<Reward> {
allocated: bigint;

matched: bigint;

proposal: Address;

from(input: any) {
this.proposal = input.address
this.allocated = BigInt(input.allocated)
this.matched = BigInt(input.matched)

return this
}
}

export class EpochInfoImpl implements Deserializable<EpochInfo> {
individualRewards: bigint;

matchedRewards: bigint;

patronsRewards: bigint;

stakingProceeds: bigint;

totalEffectiveDeposit: bigint;

totalRewards: bigint;

totalWithdrawals: bigint;

operationalCost: bigint;

leftover: bigint;

ppf: bigint;

communityFund: bigint;


from(input: any) {
this.individualRewards = BigInt(input.vanillaIndividualRewards)
this.matchedRewards = BigInt(input.matchedRewards)
this.patronsRewards = BigInt(input.patronsRewards)
this.stakingProceeds = BigInt(input.stakingProceeds)
this.totalEffectiveDeposit = BigInt(input.totalEffectiveDeposit)
this.totalRewards = BigInt(input.totalRewards)
this.totalWithdrawals = BigInt(input.totalWithdrawals)
this.operationalCost = BigInt(input.operationalCost)
this.leftover = BigInt(input.leftover)
this.ppf = BigInt(input.ppf)
this.communityFund = BigInt(input.communityFund)

return this
}
}

Loading