-
Notifications
You must be signed in to change notification settings - Fork 8
[Feat]:: Implemented "Ban Expert" Logic #10
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 |
|---|---|---|
|
|
@@ -3,6 +3,7 @@ use crate::storage; | |
| use crate::events; | ||
| use crate::{error::RegistryError, types::ExpertStatus}; | ||
|
|
||
| /// Initialize the registry with an admin address | ||
| pub fn initialize_registry(env: &Env, admin: &Address) -> Result<(), RegistryError> { | ||
| if storage::has_admin(env) { | ||
| return Err(RegistryError::AlreadyInitialized); | ||
|
|
@@ -13,6 +14,7 @@ pub fn initialize_registry(env: &Env, admin: &Address) -> Result<(), RegistryErr | |
| Ok(()) | ||
| } | ||
|
|
||
| /// Verify an expert by setting their status to Verified (Admin only) | ||
| /// Batch Verification | ||
| pub fn batch_add_experts(env:Env, experts: Vec<Address>) -> Result<(), RegistryError> { | ||
| if experts.len() > 20 { | ||
|
|
@@ -36,18 +38,53 @@ pub fn batch_add_experts(env:Env, experts: Vec<Address>) -> Result<(), RegistryE | |
|
|
||
| pub fn verify_expert(env: &Env, expert: &Address) -> Result<(), RegistryError> { | ||
| let admin = storage::get_admin(env).ok_or(RegistryError::NotInitialized)?; | ||
|
|
||
| admin.require_auth(); | ||
|
|
||
| let current_status = storage::get_expert_status(env, expert); | ||
|
|
||
| if current_status == ExpertStatus::Verified { | ||
| return Err(RegistryError::AlreadyVerified); | ||
| } | ||
|
|
||
| storage::set_expert_record(env, expert, ExpertStatus::Verified); | ||
|
|
||
| events::emit_status_change(env, expert.clone(), current_status, ExpertStatus::Verified, admin); | ||
|
|
||
|
|
||
| events::emit_status_change( | ||
| env, | ||
| expert.clone(), | ||
| current_status, | ||
| ExpertStatus::Verified, | ||
| admin, | ||
| ); | ||
|
|
||
| Ok(()) | ||
| } | ||
| } | ||
|
|
||
| /// Ban an expert by setting their status to Banned (Admin only) | ||
| pub fn ban_expert(env: &Env, expert: &Address) -> Result<(), RegistryError> { | ||
| let admin = storage::get_admin(env).ok_or(RegistryError::NotInitialized)?; | ||
| admin.require_auth(); | ||
|
|
||
| let current_status = storage::get_expert_status(env, expert); | ||
|
|
||
| if current_status == ExpertStatus::Banned { | ||
| return Err(RegistryError::AlreadyBanned); | ||
| } | ||
|
|
||
| storage::set_expert_record(env, expert, ExpertStatus::Banned); | ||
|
|
||
| events::emit_status_change( | ||
| env, | ||
| expert.clone(), | ||
| current_status, | ||
| ExpertStatus::Banned, | ||
| admin, | ||
| ); | ||
|
|
||
| Ok(()) | ||
| } | ||
|
Comment on lines
+64
to
+85
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. π§© Analysis chainπ Script executed: # First, let's look at the verify_expert function implementation
cat -n contracts/identity-registry-contract/src/contract.rs | sed -n '1,80p'Repository: LightForgeHub/SkillSphere-Contracts Length of output: 2208 π Script executed: # Search for test files related to ban and verify operations
fd -e rs -path "*/test*" | head -20Repository: LightForgeHub/SkillSphere-Contracts Length of output: 247 π Script executed: # Look for any tests that mention ban_expert or the interaction between ban and verify
rg "ban_expert|Banned.*Verified|verify.*ban" -B 3 -A 3 --type rustRepository: LightForgeHub/SkillSphere-Contracts Length of output: 7289 π Script executed: # Check if there's a verify_expert function and see its implementation
ast-grep --pattern 'fn verify_expert($_) { $$$ }'Repository: LightForgeHub/SkillSphere-Contracts Length of output: 61 π Script executed: # Look for any comments, TODOs, or documentation about expert status handling
rg "TODO|FIXME|NOTE|preemptive|unbann" --type rust -iRepository: LightForgeHub/SkillSphere-Contracts Length of output: 61 π Script executed: # Search more thoroughly for tests that might cover re-verification of banned experts
cat -n contracts/identity-registry-contract/src/test.rs | head -300Repository: LightForgeHub/SkillSphere-Contracts Length of output: 9485 π Script executed: # Look for the complete test_ban_expert_workflow test
rg "test_ban_expert_workflow" -A 50 -B 5Repository: LightForgeHub/SkillSphere-Contracts Length of output: 4640 π Script executed: # Check ExpertStatus enum to understand all possible states
rg "enum ExpertStatus" -A 10Repository: LightForgeHub/SkillSphere-Contracts Length of output: 847 π Script executed: # Look for any documentation or comments about the intended behavior of ban/verify
rg "Ban|Verified|expert" contracts/identity-registry-contract/src/lib.rs -B 2 -A 2Repository: LightForgeHub/SkillSphere-Contracts Length of output: 600 π Script executed: # Check if there's any test for re-verifying a banned expert (verify after ban)
rg "ban_expert.*verify_expert|verify_expert.*ban_expert" -B 5 -A 5Repository: LightForgeHub/SkillSphere-Contracts Length of output: 61 π Script executed: # Search more comprehensively for any mention of re-verification after ban
rg "Verified.*Banned|Banned.*Verified" -B 3 -A 3Repository: LightForgeHub/SkillSphere-Contracts Length of output: 61 π Script executed: # Check if there's documentation or requirements about the design
find . -name "README*" -o -name "REQUIREMENTS*" -o -name "*.md" | head -10Repository: LightForgeHub/SkillSphere-Contracts Length of output: 125 π Script executed: # Look for any TODOs or FIXMEs related to ban/verify logic
rg "TODO|FIXME" contracts/identity-registry-contract/ -B 2 -A 2Repository: LightForgeHub/SkillSphere-Contracts Length of output: 61 π Script executed: # Check the README for design documentation or requirements
cat README.mdRepository: LightForgeHub/SkillSphere-Contracts Length of output: 8315 π Script executed: # Look specifically for the PR template to understand requirements
cat ./.github/pull_request_template.mdRepository: LightForgeHub/SkillSphere-Contracts Length of output: 1480 π Script executed: # Check if there's any test attempting to re-verify a banned expert
rg "ban_expert" -A 20 contracts/identity-registry-contract/src/test.rs | rg -A 15 "verify_expert|add_expert"Repository: LightForgeHub/SkillSphere-Contracts Length of output: 1605 π Script executed: # Look at complete_expert_lifecycle test to confirm it doesn't test re-verification after ban
cat -n contracts/identity-registry-contract/src/test.rs | sed -n '238,261p'Repository: LightForgeHub/SkillSphere-Contracts Length of output: 971 Add a check in The implementation currently allows re-verifying a π€ Prompt for AI Agents |
||
|
|
||
| /// Get the current status of an expert | ||
| pub fn get_expert_status(env: &Env, expert: &Address) -> ExpertStatus { | ||
| storage::get_expert_status(env, expert) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,4 +16,4 @@ pub enum RegistryError { | |
| AlreadyVerified = 5, | ||
| AlreadyBanned = 6, | ||
| ExpertVecMax = 7, | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,12 @@ | ||
| use crate::types::{ExpertRecord, ExpertStatus}; | ||
| use soroban_sdk::{contracttype, Address, Env}; | ||
| use crate::types::{ExpertStatus, ExpertRecord}; | ||
|
|
||
| // 1. Data Keys | ||
| #[contracttype] | ||
| #[derive(Clone)] | ||
| pub enum DataKey { | ||
| Admin, | ||
| Expert(Address), | ||
| Admin, | ||
| Expert(Address), | ||
|
Comment on lines
7
to
+9
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. π§© Analysis chainπ Script executed: cat -n contracts/identity-registry-contract/src/storage.rs | head -50Repository: LightForgeHub/SkillSphere-Contracts Length of output: 214 π Script executed: cat contracts/identity-registry-contract/src/storage.rsRepository: LightForgeHub/SkillSphere-Contracts Length of output: 2568 Extend admin instance TTL to prevent silent expiration. Admin is stored in instance storage without TTL extension. Unlike expert records which correctly call TTL extension for admin storage pub fn has_admin(env: &Env) -> bool {
- env.storage().instance().has(&DataKey::Admin)
+ let has = env.storage().instance().has(&DataKey::Admin);
+ if has {
+ env.storage().instance().extend_ttl(LEDGERS_THRESHOLD, LEDGERS_EXTEND_TO);
+ }
+ has
}
pub fn set_admin(env: &Env, admin: &Address) {
env.storage().instance().set(&DataKey::Admin, admin);
+ env.storage().instance().extend_ttl(LEDGERS_THRESHOLD, LEDGERS_EXTEND_TO);
}
pub fn get_admin(env: &Env) -> Option<Address> {
- env.storage().instance().get(&DataKey::Admin)
+ let admin = env.storage().instance().get(&DataKey::Admin);
+ if admin.is_some() {
+ env.storage().instance().extend_ttl(LEDGERS_THRESHOLD, LEDGERS_EXTEND_TO);
+ }
+ admin
}π€ Prompt for AI Agents |
||
| } | ||
|
|
||
| // Constants for TTL (Time To Live) | ||
|
|
@@ -23,23 +23,27 @@ const LEDGERS_EXTEND_TO: u32 = 6_300_000; // ~1 year | |
|
|
||
| // ... [Admin Helpers] ... | ||
|
|
||
| /// Check if the admin has been set | ||
| pub fn has_admin(env: &Env) -> bool { | ||
| env.storage().instance().has(&DataKey::Admin) | ||
| } | ||
|
|
||
| /// Set the admin address | ||
| pub fn set_admin(env: &Env, admin: &Address) { | ||
| env.storage().instance().set(&DataKey::Admin, admin); | ||
| } | ||
|
|
||
| /// Get the admin address | ||
| pub fn get_admin(env: &Env) -> Option<Address> { | ||
| env.storage().instance().get(&DataKey::Admin) | ||
| } | ||
|
|
||
| // ... [Expert Helpers] ... | ||
|
|
||
| /// Set the expert record with status and timestamp | ||
| pub fn set_expert_record(env: &Env, expert: &Address, status: ExpertStatus) { | ||
| let key = DataKey::Expert(expert.clone()); | ||
|
|
||
| let record = ExpertRecord { | ||
| status, | ||
| updated_at: env.ledger().timestamp(), | ||
|
|
@@ -49,26 +53,23 @@ pub fn set_expert_record(env: &Env, expert: &Address, status: ExpertStatus) { | |
| env.storage().persistent().set(&key, &record); | ||
|
|
||
| // 2. Extend the TTL | ||
| // This tells the network: "If this data is going to die in less than 2 months, | ||
| // This tells the network: "If this data is going to die in less than 2 months, | ||
| // extend its life to 1 full year from now." | ||
| env.storage().persistent().extend_ttl( | ||
| &key, | ||
| LEDGERS_THRESHOLD, | ||
| LEDGERS_EXTEND_TO | ||
| ); | ||
| env.storage() | ||
| .persistent() | ||
| .extend_ttl(&key, LEDGERS_THRESHOLD, LEDGERS_EXTEND_TO); | ||
| } | ||
|
|
||
| /// Get the expert record, extending TTL if exists | ||
| pub fn get_expert_record(env: &Env, expert: &Address) -> ExpertRecord { | ||
| let key = DataKey::Expert(expert.clone()); | ||
|
|
||
| // We also bump TTL on reads | ||
| // If an expert is being checked frequently, they should stay alive. | ||
| if env.storage().persistent().has(&key) { | ||
| env.storage().persistent().extend_ttl( | ||
| &key, | ||
| LEDGERS_THRESHOLD, | ||
| LEDGERS_EXTEND_TO | ||
| ); | ||
| env.storage() | ||
| .persistent() | ||
| .extend_ttl(&key, LEDGERS_THRESHOLD, LEDGERS_EXTEND_TO); | ||
| } | ||
|
|
||
| env.storage() | ||
|
|
@@ -80,6 +81,7 @@ pub fn get_expert_record(env: &Env, expert: &Address) -> ExpertRecord { | |
| }) | ||
| } | ||
|
|
||
| /// Get the expert status | ||
| pub fn get_expert_status(env: &Env, expert: &Address) -> ExpertStatus { | ||
| get_expert_record(env, expert).status | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix the batch function doc comment.
The doc comment says βVerify an expertβ but this function batch-verifies. Consider updating for accuracy.
π€ Prompt for AI Agents