ChronoeffectorAI
  • Welcome
  • Getting Started
    • Quickstart
    • Chronoeffector AI - Vision
  • Technical Implementation
    • Aetherforge MVP 1
    • Markdown
    • Images & media
    • Interactive blocks
    • OpenAPI
    • Integrations
Powered by GitBook
On this page
Export as PDF
  1. Technical Implementation

Aetherforge MVP 1

MVP 1

PreviousChronoeffector AI - VisionNextMarkdown

Last updated 2 months ago

This is MVP 1 implementation of the Aetherforge

1

Aetherforge MVP 1 Project Review

Overview

Aetherforge is a Solana blockchain project that implements a decentralized consensus mechanism for distributed work validation and reward distribution. The project is designed for a system where:

  1. Miners submit work (possibly computational tasks or AI model training)

  2. Validators score the quality of the miners' work

  3. The system distributes token rewards based on these scores

The project uses the Anchor framework, which is a popular development framework for Solana programs (smart contracts).

Project Structure

The project follows a standard Anchor project structure:

  • programs/aetherforge-mvp/src/lib.rs: The main Solana program (smart contract)

  • app/client.ts: A TypeScript client for interacting with the program

  • programs/aetherforge-mvp/Cargo.toml: Rust dependencies for the program

  • programs/aetherforge-mvp/Xargo.toml: Configuration for cross-compilation

Detailed Functionality

Solana Program (lib.rs)

The program defines four main instructions:

1. initialize

pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
    let consensus = &mut ctx.accounts.consensus;
    consensus.authority = *ctx.accounts.authority.key;
    consensus.round = 0;
    Ok(())
}
  • Creates a new consensus account

  • Sets the authority (admin) of the consensus

  • Initializes the round counter to 0

2. submit_work

pub fn submit_work(ctx: Context<SubmitWork>, work_hash: String) -> Result<()> {
    let submission = &mut ctx.accounts.submission;
    submission.miner = *ctx.accounts.miner.key;
    submission.work_hash = work_hash;
    submission.round = ctx.accounts.consensus.round;
    Ok(())
}
  • Allows miners to submit their work as a hash

  • Records the miner's public key, the work hash, and the current round

3. submit_score

pub fn submit_score(ctx: Context<SubmitScore>, miner: Pubkey, score: u8) -> Result<()> {
    let score_account = &mut ctx.accounts.score;
    score_account.validator = *ctx.accounts.validator.key;
    score_account.miner = miner;
    score_account.score = score;
    score_account.round = ctx.accounts.consensus.round;
    Ok(())
}
  • Allows validators to score a miner's work

  • Records the validator's public key, the miner being scored, the score (0-255), and the current round

4. finalize_round

pub fn finalize_round(ctx: Context<FinalizeRound>) -> Result<()> {
    let consensus = &mut ctx.accounts.consensus;
    
    // For simplicity in this MVP, we'll just reward a fixed amount to the first token account
    // In a real implementation, you'd need to properly process submissions and scores
    
    let token_program = &ctx.accounts.token_program;
    let authority = &ctx.accounts.authority;
    let token_account = &ctx.accounts.token_account;
    
    // Find a token account in the remaining accounts
    for miner_account_info in ctx.remaining_accounts.iter() {
        // Check if this is a token account (simplified check)
        if miner_account_info.owner == &token_program.key() {
            // Assume this is a token account and send a reward
            let reward = 1000; // Fixed reward for MVP
            
            let cpi_accounts = Transfer {
                from: token_account.to_account_info(),
                to: miner_account_info.to_account_info(),
                authority: authority.to_account_info(),
            };
            let cpi_program = token_program.to_account_info();
            let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts);
            token::transfer(cpi_ctx, reward)?;
            
            // Just reward one account for simplicity
            break;
        }
    }
    
    consensus.round += 1;
    Ok(())
}
  • Finalizes the current round and distributes rewards

  • In the current simplified MVP implementation, it just sends a fixed reward (1000 tokens) to the first token account in the remaining accounts

  • Increments the round counter

Account Structures

The program defines three main account structures:

1. Consensus

#[account]
pub struct Consensus {
    pub authority: Pubkey,
    pub round: u64,
}
  • Stores the authority (admin) of the consensus

  • Tracks the current round number

2. Submission

#[account]
pub struct Submission {
    pub miner: Pubkey,
    pub work_hash: String,
    pub round: u64,
}
  • Stores a work submission from a miner

  • Contains the miner's public key, the work hash, and the round number

3. Score

#[account]
pub struct Score {
    pub validator: Pubkey,
    pub miner: Pubkey,
    pub score: u8,
    pub round: u64,
}
  • Stores a score given by a validator to a miner

  • Contains the validator's public key, the miner's public key, the score, and the round number

Client (client.ts)

The TypeScript client demonstrates how to interact with the program:

  1. It initializes the program with a new consensus account

  2. It creates a submission from a miner

  3. It submits a score from a validator

  4. It finalizes the round and distributes rewards

The client uses hardcoded token addresses for demonstration purposes:

const tokenMint = new PublicKey("67mTYzJcDgo72NCnrFRs4fTYYoonL8PLrSUGjB7C1WS2");
const tokenAccount = new PublicKey("6VgvLuaLeM7GLEfss5jHTjSboiZYDEED5Zwuczrj5kcj");
const minerTokenAccount = new PublicKey("6VgvLuaLeM7GLEfss5jHTjSboiZYDEED5Zwuczrj5kcj");

Areas for Improvement

1. Reward Distribution Logic

The current implementation of finalize_round is highly simplified and just sends a fixed reward to the first token account. A more robust implementation would:

  • Process all submissions and scores for the current round

  • Calculate rewards based on the average scores received by each miner

  • Distribute rewards proportionally to all miners based on their scores

Here's how it can be improved for MVP2:

pub fn finalize_round(ctx: Context<FinalizeRound>) -> Result<()> {
    let consensus = &mut ctx.accounts.consensus;
    
    // Clone remaining accounts to avoid lifetime issues
    let remaining_accounts = ctx.remaining_accounts.to_vec();
    
    // Create maps to store submissions and scores by miner
    let mut miner_submissions: std::collections::HashMap<Pubkey, Vec<Pubkey>> = std::collections::HashMap::new();
    let mut miner_scores: std::collections::HashMap<Pubkey, Vec<u8>> = std::collections::HashMap::new();
    let mut miner_token_accounts: std::collections::HashMap<Pubkey, Pubkey> = std::collections::HashMap::new();
    
    // Process all accounts
    for account_info in remaining_accounts.iter() {
        if let Ok(submission) = Account::<Submission>::try_from(account_info) {
            if submission.round == consensus.round {
                miner_submissions.entry(submission.miner)
                    .or_insert_with(Vec::new)
                    .push(account_info.key());
            }
        } else if let Ok(score) = Account::<Score>::try_from(account_info) {
            if score.round == consensus.round {
                miner_scores.entry(score.miner)
                    .or_insert_with(Vec::new)
                    .push(score.score);
            }
        } else {
            // Assume it's a token account - in a real implementation, you'd need to verify this
            // and map it to the correct miner
            // This is just a placeholder
            if let Some(owner_key) = account_info.owner.key() {
                miner_token_accounts.insert(owner_key, account_info.key());
            }
        }
    }
    
    // Calculate rewards
    for (miner, scores) in miner_scores.iter() {
        if scores.is_empty() {
            continue;
        }
        
        // Calculate average score
        let total_score: u64 = scores.iter().map(|&s| s as u64).sum();
        let avg_score = total_score / scores.len() as u64;
        
        // Calculate reward (100 tokens per score point)
        let reward = avg_score * 100;
        
        // Find miner's token account
        if let Some(token_account_key) = miner_token_accounts.get(miner) {
            // Send reward
            // ... (token transfer logic)
        }
    }
    
    consensus.round += 1;
    Ok(())
}

2. Security Improvements

The current implementation has several security concerns:

  • No validation that the authority is the one finalizing the round

  • No checks to prevent duplicate submissions or scores

  • No validation of the scores (e.g., ensuring they're within a valid range)

these security checks will be added:

#[derive(Accounts)]
pub struct FinalizeRound<'info> {
    #[account(mut, has_one = authority)]
    pub consensus: Account<'info, Consensus>,
    #[account(mut)]
    pub authority: Signer<'info>,
    // ... other accounts
}

3. Scalability

The current approach of passing all submissions and scores as remaining accounts won't scale well. We consider:

  • Using a more efficient data structure to store submissions and scores

  • Implementing pagination for processing large numbers of submissions and scores

  • Using Solana's PDAs (Program Derived Addresses) to organize data more efficiently

4. Token Management

The current implementation assumes token accounts are already created. We can improve this by:

  • Adding instructions to create token accounts for miners

  • Implementing proper token account validation

  • Adding support for different token types or NFTs as rewards

5. Validator Reputation

We will add reputation system for validators:

#[account]
pub struct ValidatorReputation {
    pub validator: Pubkey,
    pub reputation: u64,
    pub total_scores: u64,
}

6. Error Handling

We will improve error handling with custom error types:

#[error_code]
pub enum AetherforgeError {
    #[msg("Invalid score value")]
    InvalidScore,
    #[msg("Unauthorized access")]
    Unauthorized,
    #[msg("Duplicate submission")]
    DuplicateSubmission,
    // ... other errors
}

7. Testing

We will add comprehensive tests for all functionality:

  • Unit tests for each instruction

  • Integration tests for the complete workflow

  • Stress tests for handling large numbers of submissions and scores

Next Steps for Development (MVP2)

  1. Implement the improved reward distribution logic described above

  2. Add proper validation and security checks for all instructions

  3. Create a more user-friendly client interface with better error handling and documentation

  4. Implement a proper token account creation flow for miners

  5. Add a validator reputation system to incentivize honest validation

  6. Develop a front-end application for easier interaction with the program

  7. Add comprehensive testing to ensure reliability

  8. Document the API and usage patterns for developers

Conclusion

Aetherforge provides a solid foundation for a decentralized work validation and reward system on Solana. The current implementation which is currently at the MVP 1 stage, is simplified but demonstrates the core functionality. With the improvements suggested above, it could be developed into a robust and scalable system for distributed work validation and reward distribution.

The project has potential applications in distributed computing, AI model training, content moderation, or any scenario where work needs to be validated by multiple parties before rewards are distributed.