Skip to content
Merged
Changes from all commits
Commits
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
13 changes: 9 additions & 4 deletions src/services/staking_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -414,8 +414,10 @@ async def run_daily_sync(self, db: AsyncSession) -> Dict:
adjustment_factor=str(adj_factor)
)

# Get current balance to check if already refreshed today
balance = await credits_crud.get_or_create_balance(db, user_id)
# Get current balance with row lock to ensure we modify a
# session-tracked object (bypasses Redis cache) and prevent
# concurrent updates from racing with us.
balance = await credits_crud.get_or_create_balance(db, user_id, for_update=True)

# Check if already refreshed today - skip balance update but still update wallet stakes
if balance.staking_refresh_date == today:
Expand All @@ -431,7 +433,9 @@ async def run_daily_sync(self, db: AsyncSession) -> Dict:

idempotency_key = f"staking_sync:{user_id}:{today.isoformat()}"

# Create ledger entry for staking refresh (transaction record)
# Create ledger entry for staking refresh (transaction record).
# Use auto_commit=False so the ledger row and the balance
# update below are committed in a single atomic transaction.
if daily_amount > 0:
await credits_crud.create_ledger_entry(
db=db,
Expand All @@ -442,6 +446,7 @@ async def run_daily_sync(self, db: AsyncSession) -> Dict:
amount_paid=Decimal("0"),
amount_staking=daily_amount, # Positive for credit (in USD)
description=f"Daily staking rewards: {stake_in_mor:.4f} MOR staked ({stake_share*100:.4f}% share), earned {mor_earned:.6f} MOR @ ${mor_price:.2f}",
auto_commit=False,
)

# Update user's staking balance
Expand All @@ -452,7 +457,7 @@ async def run_daily_sync(self, db: AsyncSession) -> Dict:
balance.is_staker = daily_amount > 0
balance.updated_at = datetime.utcnow()

# Commit all changes for this user atomically
# Commit ledger entry + balance update atomically
await db.commit()

users_processed += 1
Expand Down