Repository navigation
feat: submit review logic #61
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,6 +9,7 @@ mod test; | |
| mod types; | ||
|
|
||
| use crate::error::ReputationError; | ||
| use crate::types::{ExpertStats, ReviewRecord}; | ||
| use soroban_sdk::{contract, contractimpl, Address, BytesN, Env}; | ||
|
|
||
| #[contract] | ||
|
|
@@ -43,4 +44,21 @@ impl ReputationScoringContract { | |
| ) -> Result<(), ReputationError> { | ||
| contract::penalize_expert(&env, &expert, penalty_points) | ||
| } | ||
|
|
||
| pub fn submit_review( | ||
| env: Env, | ||
| reviewer: Address, | ||
| booking_id: u64, | ||
| score: u32, | ||
| ) -> Result<(), ReputationError> { | ||
| contract::submit_review(&env, &reviewer, booking_id, score) | ||
| } | ||
|
arandomogg marked this conversation as resolved.
Comment on lines
+48
to
+55
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
Issue 🤖 Prompt for AI Agents |
||
|
|
||
| pub fn get_review(env: Env, booking_id: u64) -> Option<ReviewRecord> { | ||
| contract::get_review(&env, booking_id) | ||
| } | ||
|
|
||
| pub fn get_expert_stats(env: Env, expert: Address) -> ExpertStats { | ||
| contract::get_expert_stats(&env, &expert) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| use crate::types::{ExpertStats, ReviewRecord}; | ||
| use soroban_sdk::{contracttype, Address, Env}; | ||
|
|
||
| #[contracttype] | ||
|
|
@@ -8,8 +9,12 @@ pub enum DataKey { | |
| IsPaused, | ||
| ExpertScore(Address), | ||
| ExpertReviews(Address), | ||
| Review(u64), // booking_id → ReviewRecord | ||
| ExpertStats(Address), // expert → ExpertStats | ||
| } | ||
|
|
||
| // --- Admin --- | ||
|
|
||
| pub fn has_admin(env: &Env) -> bool { | ||
| env.storage().instance().has(&DataKey::Admin) | ||
| } | ||
|
|
@@ -22,10 +27,18 @@ pub fn get_admin(env: &Env) -> Option<Address> { | |
| env.storage().instance().get(&DataKey::Admin) | ||
| } | ||
|
|
||
| // --- Vault --- | ||
|
|
||
| pub fn set_vault_address(env: &Env, vault: &Address) { | ||
| env.storage().instance().set(&DataKey::VaultAddress, vault); | ||
| } | ||
|
|
||
| pub fn get_vault_address(env: &Env) -> Option<Address> { | ||
| env.storage().instance().get(&DataKey::VaultAddress) | ||
| } | ||
|
|
||
| // --- Pause --- | ||
|
|
||
| pub fn is_paused(env: &Env) -> bool { | ||
| env.storage() | ||
| .instance() | ||
|
|
@@ -37,6 +50,8 @@ pub fn set_paused(env: &Env, paused: bool) { | |
| env.storage().instance().set(&DataKey::IsPaused, &paused); | ||
| } | ||
|
|
||
| // --- Expert Score (dispute penalties) --- | ||
|
|
||
| pub fn get_expert_score(env: &Env, expert: &Address) -> u64 { | ||
| env.storage() | ||
| .instance() | ||
|
|
@@ -63,6 +78,40 @@ pub fn set_expert_reviews(env: &Env, expert: &Address, count: u64) { | |
| .set(&DataKey::ExpertReviews(expert.clone()), &count); | ||
| } | ||
|
Comment on lines
53
to
79
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "## Locate storage.rs"
fd -a 'storage\.rs$' . | sed 's#^\./##'
echo
echo "## Outline storage.rs"
ast-grep outline contracts/reputation-scoring-contract/src/storage.rs --view compact || true
echo
echo "## Relevant section"
sed -n '1,130p' contracts/reputation-scoring-contract/src/storage.rs
echo
echo "## DataKey definitions"
rg -n "enum DataKey|ExpertScore|ExpertReviews|Review|ExpertStats|instance|persistent" contracts/reputation-scoring-contract/src/storage.rsRepository: LightForgeHub/SkillSphere-Contracts Length of output: 5296 🌐 Web query:
💡 Result: In Soroban, Instance storage is physically stored within a single ledger entry associated with the contract instance [1][2]. Because it resides in this shared entry, it is subject to a hard size limit defined by the network's maximum ledger entry size (typically in the order of 100 KB) [1][3][4]. Due to this structural limitation, Instance storage is not suitable for data that can grow in an unbounded fashion, such as user balances or large lists of records [3][4][5]. Attempting to store unbounded data in Instance storage can lead to Denial of Service (DoS) risks where the contract becomes unable to function once the ledger entry reaches its capacity [5]. For unbounded data like user balances, Persistent storage should be used instead [6][5]. Unlike Instance storage, Persistent storage allows each key-value pair to reside in its own separate ledger entry [6][7]. This design provides effectively unbounded aggregate capacity because each entry has its own independent lifetime (TTL) and capacity limit [6][7]. Using separate entries also avoids the performance overhead of loading the entire Instance storage map on every contract invocation, as the host only loads the specific entry required for the transaction [3][4][7]. Citations:
Move per-expert scoring/counters to persistent storage.
🤖 Prompt for AI Agents |
||
|
|
||
| pub fn get_vault_address(env: &Env) -> Option<Address> { | ||
| env.storage().instance().get(&DataKey::VaultAddress) | ||
| // --- Reviews --- | ||
|
|
||
| pub fn has_review(env: &Env, booking_id: u64) -> bool { | ||
| env.storage() | ||
| .persistent() | ||
| .has(&DataKey::Review(booking_id)) | ||
| } | ||
|
|
||
| pub fn set_review(env: &Env, booking_id: u64, review: &ReviewRecord) { | ||
| env.storage() | ||
| .persistent() | ||
| .set(&DataKey::Review(booking_id), review); | ||
| } | ||
|
|
||
| pub fn get_review(env: &Env, booking_id: u64) -> Option<ReviewRecord> { | ||
| env.storage() | ||
| .persistent() | ||
| .get(&DataKey::Review(booking_id)) | ||
| } | ||
|
|
||
| // --- Expert Stats --- | ||
|
|
||
| pub fn get_expert_stats(env: &Env, expert: &Address) -> ExpertStats { | ||
| env.storage() | ||
| .persistent() | ||
| .get(&DataKey::ExpertStats(expert.clone())) | ||
| .unwrap_or(ExpertStats { | ||
| total_score: 0, | ||
| review_count: 0, | ||
| }) | ||
| } | ||
|
|
||
| pub fn set_expert_stats(env: &Env, expert: &Address, stats: &ExpertStats) { | ||
| env.storage() | ||
| .persistent() | ||
| .set(&DataKey::ExpertStats(expert.clone()), stats); | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.