Skip to content
Merged
Show file tree
Hide file tree
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
43 changes: 43 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: CI

on:
push:
branches: [main, dev, "fix/**"]
pull_request:
branches: [main, dev]

env:
CARGO_TERM_COLOR: always

jobs:
check-and-test:
name: Build & Test
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy

- name: Cache cargo registry & build
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-

- name: Check compilation
run: cargo check --workspace --exclude program_methods

- name: Run tests
run: cargo test --workspace --exclude program_methods

- name: Check formatting
run: cargo fmt --all -- --check
5 changes: 4 additions & 1 deletion e_identity_sdk/src/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,10 @@ pub unsafe extern "C" fn ffi_username_registry_lookup_by_username(
Err(_) => return error_json("invalid UTF-8"),
};
match (*handle).inner.lookup_by_username(name) {
Some(commitment) => ok_json(&format!("{{\"commitment\":\"{}\"}}", hex::encode(commitment))),
Some(commitment) => ok_json(&format!(
"{{\"commitment\":\"{}\"}}",
hex::encode(commitment)
)),
None => ok_json("{\"commitment\":null}"),
}
}
Expand Down
12 changes: 7 additions & 5 deletions program_methods/guest/src/bin/membership_registry.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
#![no_main]

use membership_registry::{
state::ForumInstance,
initialize, join_room, record_strike, register,
register_room, slash, verify_post,
use membership_registry::{
initialize, join_room, record_strike, register, register_room, slash, state::ForumInstance,
verify_post,
};
use nssa_core::account::AccountWithMetadata;
use spel_framework::prelude::*;
Expand Down Expand Up @@ -136,7 +135,10 @@ mod forum_registry {
message: "Data too large".into(),
})?;

Ok(SpelOutput::execute(vec![state.account, member.account], vec![]))
Ok(SpelOutput::execute(
vec![state.account, member.account],
vec![],
))
}

#[instruction]
Expand Down
2 changes: 1 addition & 1 deletion programs/membership_registry/src/join_room.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::state::{ForumInstance, OnChainMembership};

/// Process a room join instruction.
/// Process a room join instruction.
/// Validates that:
/// 1. The room exists on-chain
/// 2. The member commitment is registered and not revoked
Expand Down
49 changes: 49 additions & 0 deletions programs/membership_registry/src/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,58 @@ pub fn process_register(
return Err("Registration failed: This commitment is already registered.");
}

// Reject commitments that were previously revoked via slashing.
// This prevents re-use of a compromised identity whose NSK was exposed.
if forum.revoked_commitments.contains(&commitment_bytes) {
return Err("Registration failed: This commitment has been revoked.");
}

forum.registered_commitments.push(commitment_bytes);
forum.member_stakes.push((commitment_bytes, stake_amount));
forum.total_staked += stake_amount;

Ok(())
}

#[cfg(test)]
mod tests {
use super::*;
use crate::initialize::process_initialize;

#[test]
fn test_register_success() {
let mut forum = process_initialize(3, 2, 3).unwrap();
let commitment = [1u8; 32];
assert!(process_register(&mut forum, commitment, 1000).is_ok());
assert_eq!(forum.registered_commitments.len(), 1);
assert_eq!(forum.total_staked, 1000);
}

#[test]
fn test_register_insufficient_stake() {
let mut forum = process_initialize(3, 2, 3).unwrap();
let commitment = [1u8; 32];
assert!(process_register(&mut forum, commitment, 999).is_err());
}

#[test]
fn test_register_duplicate_commitment() {
let mut forum = process_initialize(3, 2, 3).unwrap();
let commitment = [1u8; 32];
assert!(process_register(&mut forum, commitment, 1000).is_ok());
assert!(process_register(&mut forum, commitment, 1000).is_err());
}

#[test]
fn test_register_revoked_commitment_rejected() {
let mut forum = process_initialize(3, 2, 3).unwrap();
let commitment = [2u8; 32];
forum.revoked_commitments.push(commitment);
let res = process_register(&mut forum, commitment, 1000);
assert!(res.is_err());
assert_eq!(
res.unwrap_err(),
"Registration failed: This commitment has been revoked."
);
}
}
Loading