Skip to content
Merged
2 changes: 1 addition & 1 deletion BackendAcademy/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,4 +265,4 @@ Base score is 50. Final score is clamped to [0, 100]. A `confidence` of `0.7` is
- **Dynamic hint generation** — when no hint is stored for a `challengeId`, fall through to the AI provider to generate one on-demand using the task description as context.
- **Per-user hint gating** — track how many hints a learner has consumed per challenge and reduce XP payout accordingly.
- **Database persistence** — migrate `hints` and `chatHistory` maps to PostgreSQL via the Supabase client.
- **Streaming responses** — switch the chat endpoint to Server-Sent Events for real-time token streaming.
- **Streaming responses** — switch the chat endpoint to Server-Sent Events for real-time token streaming.
6 changes: 2 additions & 4 deletions app/contract/contracts/Folder/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
name = "RustAcademy"
name = "rust_academy"
version = "0.1.0"
edition = "2021"
description = "X-Ray privacy Soroban contract for RustAcademy"
Expand All @@ -22,6 +22,4 @@ serde_json = "1.0"

[dev-dependencies]
soroban-sdk = { version = "23", features = ["testutils"] }
proptest = { version = "1.5.0", default-features = false, features = ["std"] }


proptest = { version = "1.5.0", default-features = false, features = ["std"] }
3 changes: 2 additions & 1 deletion app/contract/contracts/Folder/src/bench_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ fn seed_escrow(
#[allow(clippy::needless_borrow)]
arbiters: Vec::new(&env),
arbiter_threshold: 0,
schema_version: crate::types::ESCROW_SCHEMA_VERSION,
};
env.as_contract(contract_id, || {
let key: Bytes = commitment.into();
Expand Down Expand Up @@ -369,4 +370,4 @@ fn bench_resolve_dispute_recipient() {
env.cost_estimate().budget().reset_default();
client.resolve_dispute(&arbiter, &commitment, &false, &recipient);
print_budget(&env, "resolve_dispute_recipient");
}
}
42 changes: 29 additions & 13 deletions app/contract/contracts/Folder/src/escrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,18 +64,16 @@ use soroban_sdk::{token, Address, Bytes, BytesN, Env, Vec};

use crate::{
admin, commitment, dispute,
errors:: RustAcademyError,
errors::RustAcademyError,
escrow_id, events, fee_router, hook,
storage::{
count_dispute_votes, get_dispute_vote, get_escrow, get_escrow_id_mapping, has_dispute_vote,
has_escrow, put_dispute_vote, put_escrow, put_escrow_id_mapping, remove_dispute_votes_for_escrow,
remove_escrow, DataKey, LEDGER_THRESHOLD, SIX_MONTHS_IN_LEDGERS,
clear_dispute_state, count_dispute_votes, get_commitment_escrow_id, get_dispute_vote,
get_escrow, get_escrow_id_mapping, get_fee_config, get_oracle_fee_config,
get_per_asset_fee, get_platform_wallet, has_dispute_vote, has_escrow,
put_commitment_escrow_id, put_dispute_vote, put_escrow, put_escrow_id_mapping,
remove_commitment_escrow_id, remove_dispute_vote, remove_escrow,
remove_escrow_id_mapping, LEDGER_THRESHOLD, SIX_MONTHS_IN_LEDGERS,
clear_dispute_state, count_dispute_votes, get_commitment_escrow_id,
get_dispute_vote, get_escrow, get_escrow_id_mapping, get_fee_config,
get_oracle_fee_config, get_per_asset_fee, get_platform_wallet, has_dispute_vote,
has_escrow, put_commitment_escrow_id, put_dispute_vote, put_escrow,
put_escrow_id_mapping, remove_commitment_escrow_id,
remove_dispute_votes_for_escrow, remove_escrow, remove_escrow_id_mapping, DataKey,
LEDGER_THRESHOLD, SIX_MONTHS_IN_LEDGERS,
},
types::{
DisputeVote, EscrowEntry, EscrowOperationEstimate, EscrowOperationLimits, EscrowStatus,
Expand Down Expand Up @@ -501,6 +499,7 @@ pub fn deposit_with_arbiters(
arbiter: None,
arbiters,
arbiter_threshold: threshold,
schema_version: crate::types::ESCROW_SCHEMA_VERSION,
};

put_escrow(env, &commitment_bytes, &entry);
Expand Down Expand Up @@ -1036,21 +1035,38 @@ pub fn cleanup_escrow(env: &Env, commitment: BytesN<32>) -> Result<(), RustAcad

match entry.status {
EscrowStatus::Spent | EscrowStatus::Refunded => {
let mut indices_removed: u32 = 0;

// Dedup mapping (escrow_id → commitment) plus its reverse index.
if let Some(escrow_id) = get_commitment_escrow_id(env, &commitment_bytes) {
remove_escrow_id_mapping(env, &escrow_id);
remove_commitment_escrow_id(env, &commitment_bytes);
indices_removed += 2;
}

// Remove dispute votes if this was a disputed escrow that was resolved.
if matches!(entry.status, EscrowStatus::Refunded) && entry.arbiter.is_some() {
// Single arbiter mode - remove the vote if it exists
let arbiter = entry.arbiter.unwrap();
let key = DataKey::DisputeVote(commitment_bytes.clone(), arbiter);
env.storage().persistent().remove(&key);
if env.storage().persistent().has(&key) {
env.storage().persistent().remove(&key);
indices_removed += 1;
}
} else if entry.arbiter_threshold > 0 {
// Multi-sig mode - remove all votes for this escrow
for arbiter in entry.arbiters.iter() {
if has_dispute_vote(env, &commitment_bytes, &arbiter) {
indices_removed += 1;
}
}
remove_dispute_votes_for_escrow(env, &commitment_bytes, &entry.arbiters);
}

remove_escrow(env, &commitment_bytes);

// Publish cleanup event for indexers
events::publish_escrow_cleanup(env, commitment);
events::publish_escrow_cleanup(env, commitment.clone());

// Issue #49: reclaim dispute expiry metadata storage rent.
clear_dispute_state(env, &commitment_bytes, &entry.arbiters);
Expand Down Expand Up @@ -1479,4 +1495,4 @@ pub fn resolve_dispute_multi_sig(
clear_dispute_state(env, &commitment_bytes, &entry.arbiters);

Ok(())
}
}
Loading
Loading