Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
c0a44ec
feature: support aleph credits
amalcaraz Jul 23, 2025
dcb5986
feat: parse new credit airdrop messages and refactor credit_balances …
amalcaraz Aug 14, 2025
5ac48eb
fix: change credit amount type from Decimal to int
amalcaraz Aug 14, 2025
635619f
fix: lint errors
amalcaraz Aug 14, 2025
8441366
feat: implement credit cost calculation and garbage collector
amalcaraz Aug 11, 2025
a5eeadf
point to tmp branch for aleph-message package
amalcaraz Aug 14, 2025
1cce176
fix: added missing migration for error code
amalcaraz Aug 14, 2025
3270f68
fix: balance Decimal type in http response
amalcaraz Sep 9, 2025
f56efbf
fix: fix migrations order
amalcaraz Sep 9, 2025
706dcc5
feat: filter accepted credit messages with channel + address + post t…
amalcaraz Sep 9, 2025
43458bb
feat: remove /api/v0/addresses/{address}/credit_balance and integrate…
amalcaraz Sep 9, 2025
4ba7edc
feat: support credit distribution, transfer, expense
amalcaraz Sep 9, 2025
a3205e6
fix: added more tests
amalcaraz Sep 9, 2025
46557f8
fix: credit_history table and fifo calculation taking into account ex…
amalcaraz Sep 10, 2025
31580f7
feat: credit history endpoint + lint fixes
amalcaraz Sep 10, 2025
aa32c00
fix: validate_balance_for_payment to take into account all resources …
amalcaraz Sep 12, 2025
5e38efd
fix: validate_balance_for_payment to take into account all resources …
amalcaraz Sep 12, 2025
51148c0
Solve format issue on balance pre-check (#855)
nesitor Sep 18, 2025
d21b272
Fix RabbitMQ connection timeouts during long operations. (#856)
aliel Sep 18, 2025
2df1fb1
Fix IPFS conf: use the recommended method to update IPFS configuratio…
aliel Sep 18, 2025
8799257
Merge branch 'main' into angel-compute_credit_costs
amalcaraz Sep 18, 2025
b8e2a42
fix: lint
amalcaraz Sep 18, 2025
26a970e
fix: pending_message queue getting stuck due to bad error handling
amalcaraz Sep 19, 2025
08d472e
Fix: Added a default internal code for errors.
nesitor Sep 22, 2025
2aca87c
fix: bugfix caching expired credit balances
amalcaraz Sep 23, 2025
81d1f52
fix: lint fix
amalcaraz Sep 23, 2025
9f8f98e
fix: CI fixes due to hatch problematic dep
amalcaraz Sep 23, 2025
8c5266b
feat: new index in credit_history.expiration_date column
amalcaraz Sep 23, 2025
e50dd4a
fix: added cost_credit in cost http response
amalcaraz Sep 23, 2025
152e5b8
fix: change pricing aggregate owner for testing
amalcaraz Sep 23, 2025
4df4ca5
feat: added charged_address in /price and /price/estimate response
amalcaraz Sep 29, 2025
9d72277
Fix: Upgrade `aleph_message` version to `1.0.5`
nesitor Oct 8, 2025
3e2c0a7
Fix: Pin pydantic version to the previous one from latest.
nesitor Oct 8, 2025
53a9ac4
Fix: Solved failing test and put legacy and current PAYG message tests.
nesitor Oct 8, 2025
1514f21
fix: fix account addresses for credit and settings
amalcaraz Oct 8, 2025
de59e7b
Merge branch 'main' into angel-compute_credit_costs
amalcaraz Oct 8, 2025
7c0797b
fix: new credit channel
amalcaraz Oct 8, 2025
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
2 changes: 1 addition & 1 deletion .github/workflows/code-quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- name: Install pip and hatch
run: |
sudo apt-get install -y python3-pip
pip3 install hatch hatch-vcs
pip3 install "click<8.2" hatch hatch-vcs

- name: Cache dependencies
uses: actions/cache@v4
Expand Down
2 changes: 1 addition & 1 deletion deployment/docker-build/dev/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ COPY .git ./.git
COPY src ./src

RUN pip install -e .
RUN pip install hatch
RUN pip install "click<8.2" hatch

FROM base

Expand Down
2 changes: 1 addition & 1 deletion deployment/docker-build/test/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ COPY src ./src

# Install project deps and test deps
RUN pip install -e .[testing,docs]
RUN pip install hatch
RUN pip install "click<8.2" hatch

# Install project test deps
RUN apt-get update && apt-get install -y \
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"""add credit_history and credit_balances tables

Revision ID: a1b2c3d4e5f6
Revises: 35a67ccc4451
Create Date: 2025-07-14 00:00:00.000000

"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.sql import func


# revision identifiers, used by Alembic.
revision = 'a1b2c3d4e5f6'
down_revision = '35a67ccc4451'
branch_labels = None
depends_on = None


def upgrade() -> None:
# Create credit_history table (detailed audit trail)
op.create_table(
'credit_history',
sa.Column('id', sa.BigInteger(), autoincrement=True),
sa.Column('address', sa.String(), nullable=False),
sa.Column('amount', sa.BigInteger(), nullable=False),
sa.Column('ratio', sa.DECIMAL(), nullable=True),
sa.Column('tx_hash', sa.String(), nullable=True),
sa.Column('token', sa.String(), nullable=True),
sa.Column('chain', sa.String(), nullable=True),
sa.Column('provider', sa.String(), nullable=True),
sa.Column('origin', sa.String(), nullable=True),
sa.Column('origin_ref', sa.String(), nullable=True),
sa.Column('payment_method', sa.String(), nullable=True),
sa.Column('credit_ref', sa.String(), nullable=False),
sa.Column('credit_index', sa.Integer(), nullable=False),
sa.Column('expiration_date', sa.TIMESTAMP(timezone=True), nullable=True),
sa.Column('message_timestamp', sa.TIMESTAMP(timezone=True), nullable=False),
sa.Column('last_update', sa.TIMESTAMP(timezone=True), nullable=False,
server_default=func.now(), onupdate=func.now()),
sa.PrimaryKeyConstraint('credit_ref', 'credit_index', name='credit_history_pkey'),
)

# Create indexes on credit_history for efficient lookups
op.create_index('ix_credit_history_address', 'credit_history', ['address'], unique=False)
op.create_index('ix_credit_history_message_timestamp', 'credit_history', ['message_timestamp'], unique=False)

# Create credit_balances table (cached balance summary)
op.create_table(
'credit_balances',
sa.Column('address', sa.String(), nullable=False),
sa.Column('balance', sa.BigInteger(), nullable=False, default=0),
sa.Column('last_update', sa.TIMESTAMP(timezone=True), nullable=False,
server_default=func.now(), onupdate=func.now()),
sa.PrimaryKeyConstraint('address', name='credit_balances_pkey'),
)

# Create index on address for the cached balances table
op.create_index('ix_credit_balances_address', 'credit_balances', ['address'], unique=False)


def downgrade() -> None:
# Drop the credit_balances table
op.drop_index('ix_credit_balances_address', 'credit_balances')
op.drop_table('credit_balances')

# Drop the credit_history table
op.drop_index('ix_credit_history_address', 'credit_history')
op.drop_index('ix_credit_history_message_timestamp', 'credit_history')
op.drop_table('credit_history')
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""add cost_credit column to account_costs table

Revision ID: b7c8d9e0f1a2
Revises: a1b2c3d4e5f6
Create Date: 2025-01-11 00:00:00.000000

"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = 'b7c8d9e0f1a2'
down_revision = 'a1b2c3d4e5f6'
branch_labels = None
depends_on = None


def upgrade() -> None:
# Add cost_credit column to account_costs table
op.add_column('account_costs', sa.Column('cost_credit', sa.DECIMAL(), nullable=False, server_default='0'))

# Add missing CREDIT_INSUFFICIENT error code
op.execute(
"""
INSERT INTO error_codes(code, description) VALUES
(6, 'Insufficient credit')
ON CONFLICT (code) DO NOTHING
"""
)


def downgrade() -> None:
# Remove CREDIT_INSUFFICIENT error code
op.execute("DELETE FROM error_codes WHERE code = 6")

# Remove cost_credit column from account_costs table
op.drop_column('account_costs', 'cost_credit')
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"""add credit_balance cron job

Revision ID: c8d9e0f1a2b3
Revises: b7c8d9e0f1a2
Create Date: 2025-01-11 00:00:00.000000

"""
from alembic import op


# revision identifiers, used by Alembic.
revision = 'c8d9e0f1a2b3'
down_revision = 'b7c8d9e0f1a2'
branch_labels = None
depends_on = None


def upgrade() -> None:
# Add credit_balance cron job to run every hour (3600 seconds)
op.execute(
"""
INSERT INTO cron_jobs(id, interval, last_run)
VALUES ('credit_balance', 3600, '2025-01-01 00:00:00')
"""
)


def downgrade() -> None:
# Remove credit_balance cron job
op.execute(
"""
DELETE FROM cron_jobs WHERE id = 'credit_balance'
"""
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""add credit_history expiration_date index for cache invalidation performance

Revision ID: d0e1f2a3b4c5
Revises: c8d9e0f1a2b3
Create Date: 2025-01-11 00:00:00.000000

"""
from alembic import op


# revision identifiers, used by Alembic.
revision = 'd0e1f2a3b4c5'
down_revision = 'c8d9e0f1a2b3'
branch_labels = None
depends_on = None


def upgrade() -> None:
# Add index on expiration_date for efficient cache invalidation queries
# This index optimizes the query that checks if any credits expired
# after the cached balance was last updated
op.create_index(
'ix_credit_history_expiration_date',
'credit_history',
['expiration_date'],
unique=False
)


def downgrade() -> None:
# Drop the expiration_date index
op.drop_index('ix_credit_history_expiration_date', 'credit_history')
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ dependencies = [
"aiohttp-jinja2==1.6",
"aioipfs~=0.7.1",
"alembic==1.15.1",
"aleph-message~=1.0.2",
"aleph-message~=1.0.5",
"aleph-nuls2==0.1",
"aleph-p2p-client @ git+https://github.com/aleph-im/p2p-service-client-python@cbfebb871db94b2ca580e66104a67cd730c5020c",
"asyncpg==0.30",
Expand All @@ -47,7 +47,7 @@ dependencies = [
"orjson>=3.7.7", # Minimum version for Python 3.11
"psycopg2-binary==2.9.10", # Note: psycopg3 is not yet supported by SQLAlchemy
"pycryptodome==3.22.0",
"pydantic>=2.0.0,<3.0.0",
"pydantic==2.11.10",
"pymultihash==0.8.2", # for libp2p-stubs
"pynacl==1.5",
"pytezos-crypto==3.13.4.1",
Expand Down
6 changes: 5 additions & 1 deletion src/aleph/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from aleph.exceptions import InvalidConfigException, KeyNotFoundException
from aleph.jobs import start_jobs
from aleph.jobs.cron.balance_job import BalanceCronJob
from aleph.jobs.cron.credit_balance_job import CreditBalanceCronJob
from aleph.jobs.cron.cron_job import CronJob, cron_job_task
from aleph.network import listener_tasks
from aleph.services import p2p
Expand Down Expand Up @@ -151,7 +152,10 @@ async def main(args: List[str]) -> None:
)
cron_job = CronJob(
session_factory=session_factory,
jobs={"balance": BalanceCronJob(session_factory=session_factory)},
jobs={
"balance": BalanceCronJob(session_factory=session_factory),
"credit_balance": CreditBalanceCronJob(session_factory=session_factory),
},
)
chain_data_service = ChainDataService(
session_factory=session_factory,
Expand Down
14 changes: 14 additions & 0 deletions src/aleph/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,20 @@ def get_defaults():
# POST message type for balance updates.
"post_type": "balances-update",
},
"credit_balances": {
# Addresses allowed to publish credit balance updates.
"addresses": [
"0x2E4454fAD1906c0Ce6e45cBFA05cE898Ac3AC1dC",
],
# POST message types for credit balance updates.
"post_types": [
"aleph_credit_distribution",
"aleph_credit_transfer",
"aleph_credit_expense",
],
# Allowed channels for credit balance messages.
"channels": ["ALEPH_CREDIT"],
},
"jobs": {
"pending_messages": {
# Maximum number of retries for a message.
Expand Down
Loading
Loading