Skip to content

Conversation

@ttdonovan
Copy link
Member

@ttdonovan ttdonovan commented Aug 29, 2025

This pull request introduces a comprehensive Star Frame tutorial series and comparison documentation, aimed at helping developers understand and migrate from Anchor to Star Frame. It adds new tutorial modules, detailed guides, and example code, establishing a clear learning path and highlighting key differences between the frameworks.

Documentation and Guides

  • Added docs/star-frame-vs-anchor.md: A thorough guide comparing Star Frame and Anchor, explaining architectural differences, performance characteristics, migration steps, and when to choose each framework.
  • Added docs/tutorial-comparison.md: Side-by-side code comparisons for common Solana program patterns in Anchor vs Star Frame, covering data storage, access control, CPI, PDAs, error handling, and state management.
  • Added tutorial/README.md: An overview of the tutorial series, progression, build/test instructions, and conceptual mapping between Anchor and Star Frame.

Tutorial Modules

  • Introduced tutorial/basic-0 and tutorial/basic-1 directories with their own Cargo.toml, source code, and test files, providing step-by-step examples for minimal and basic Star Frame programs. [1] [2] [3] [4]
  • Added IDL generation and example output for the minimal program (tutorial/basic-0/idl.json).

Workspace Configuration

  • Updated Cargo.toml to exclude the tutorial directory from the workspace, ensuring clean builds and separation from main example programs.

#226

@ttdonovan ttdonovan force-pushed the ttdonovan/tutorials branch from 553d354 to 8f3eaee Compare August 29, 2025 06:25
@ttdonovan
Copy link
Member Author

ttdonovan commented Aug 29, 2025

@stegaBOB this is still a work in progress and me pairing with Claude to produce tutorials that mimic what is done in the Anchor repo. I would be appreciative if you could give it a look over and provide feedback. Specifically could you look at the basic-5 tutorial I'm not certain if this is a potential bug or if I'm using Star Frame incorrectly.

#226 (comment)

Summary

The issue you discovered is indeed a bug in star_frame with how it handles packed structs that have i64 fields at the end. Specifically:

  1. The Bug: When a struct marked with #[repr(C, packed)] ends with an i64 field, star_frame fails to properly serialize/deserialize that field. The field appears as zeros when
    written to storage.
  2. Evidence:
    - RobotAccount's last_action_time: i64 field at the end doesn't work
    - VaultAccount in basic-4 works because it ends with bump: u8 instead of i64
    - The serialized data shows zeros where the timestamp should be
  3. Impact: This affects any time-based logic that relies on reading the timestamp field, causing validation failures.
  4. Workarounds:
    - Add a dummy u8 field after the i64 (like VaultAccount's bump)
    - Reorder fields so i64 isn't last
    - Remove the packed attribute if not essential
    - For tests: zero out the affected bytes to match what the program writes
  5. Recommendation: You should report this bug to the star_frame maintainers. It's a serious issue that could affect other programs using packed structs with i64 or other 8-byte
    fields at the end.

@ttdonovan ttdonovan requested a review from stegaBOB August 29, 2025 06:31
@ttdonovan ttdonovan self-assigned this Aug 29, 2025
@ttdonovan ttdonovan added the documentation Improvements or additions to documentation label Aug 29, 2025
@ttdonovan ttdonovan requested a review from Copilot August 29, 2025 06:36
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This pull request introduces a comprehensive Star Frame tutorial series and comparison documentation, aimed at helping developers understand and migrate from Anchor to Star Frame. It establishes a progressive learning path through practical examples while providing detailed guides for understanding architectural differences between the frameworks.

  • Introduces 6 tutorial modules (basic-0 through basic-5) with increasing complexity covering core Solana programming patterns
  • Adds comprehensive documentation comparing Star Frame and Anchor approaches with side-by-side code examples
  • Provides automated build/test infrastructure with shell scripts and justfile for efficient development workflow

Reviewed Changes

Copilot reviewed 34 out of 42 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tutorial/scripts/ Build automation scripts for compiling, testing, and validating all tutorial programs
tutorial/justfile Task runner configuration providing convenient commands for development workflow
tutorial/basic-0/ Minimal program demonstrating basic Star Frame setup with empty instruction set
tutorial/basic-1/ Data storage and PDA patterns with initialization and update operations
tutorial/basic-2/ Authority-based access control using AccountValidate trait and ValidatedAccount wrapper
tutorial/basic-3/ Cross-program invocation (CPI) examples with puppet/puppet-master architecture
tutorial/basic-4/ Advanced PDA patterns and time-locked vault functionality with complex validation
tutorial/basic-5/ State machines and game logic with energy systems and cooldown mechanics

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +10 to +21
// Helper function to work around star_frame serialization bug with packed structs
// The last_action_time field (i64) is not being written correctly - it's always zeros
fn serialize_robot_account_workaround(robot: RobotAccount) -> Vec<u8> {
let mut data = RobotAccount::serialize_account(robot)
.expect("Failed to serialize");
// The program writes the timestamp field as all zeros
// Zero out bytes 61-69 (where timestamp should be)
for i in 61..69 {
if i < data.len() {
data[i] = 0;
}
}
Copy link

Copilot AI Aug 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This workaround function indicates a serialization bug with packed structs containing i64 fields. The hardcoded byte offsets (61-69) are fragile and could break if the struct layout changes. Consider filing a bug report for the underlying serialization issue and using a more robust workaround that doesn't rely on magic numbers.

Suggested change
// Helper function to work around star_frame serialization bug with packed structs
// The last_action_time field (i64) is not being written correctly - it's always zeros
fn serialize_robot_account_workaround(robot: RobotAccount) -> Vec<u8> {
let mut data = RobotAccount::serialize_account(robot)
.expect("Failed to serialize");
// The program writes the timestamp field as all zeros
// Zero out bytes 61-69 (where timestamp should be)
for i in 61..69 {
if i < data.len() {
data[i] = 0;
}
}
// Helper function to robustly serialize RobotAccount, avoiding hardcoded offsets
fn serialize_robot_account_workaround(robot: RobotAccount) -> Vec<u8> {
let mut data = Vec::new();
// Serialize each field in the order defined in RobotAccount
data.extend_from_slice(&robot.owner.to_bytes());
data.push(robot.state);
data.extend_from_slice(&robot.energy.to_le_bytes());
data.extend_from_slice(&robot.distance_traveled.to_le_bytes());
data.extend_from_slice(&robot.jumps_made.to_le_bytes());
data.extend_from_slice(&robot.last_action_time.to_le_bytes());

Copilot uses AI. Check for mistakes.
Comment on lines +184 to +210
for i in {0..5}; do
if [ -d "basic-$i" ]; then
# Special handling for basic-3 which has two sub-projects
if [ $i -eq 3 ]; then
if [ -d "basic-3/puppet" ]; then
if [ "$PARALLEL" = true ]; then
check_tutorial_parallel "basic-3/puppet"
else
check_tutorial "basic-3/puppet"
fi
fi
if [ -d "basic-3/puppet-master" ]; then
if [ "$PARALLEL" = true ]; then
check_tutorial_parallel "basic-3/puppet-master"
else
check_tutorial "basic-3/puppet-master"
fi
fi
else
if [ "$PARALLEL" = true ]; then
check_tutorial_parallel "basic-$i"
else
check_tutorial "basic-$i"
fi
fi
fi
done
Copy link

Copilot AI Aug 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The special case handling for basic-3 duplicates the parallel/sequential logic, making the code harder to maintain. Consider extracting a helper function that handles the parallel/sequential decision to reduce duplication and improve readability.

Copilot uses AI. Check for mistakes.
Comment on lines +43 to +45
if [ -f "$dir/target/deploy/${name//-/_}.so" ]; then
print_color "$GREEN" "✓ $name built successfully"
local size=$(du -h "$dir/target/deploy/${name//-/_}.so" | cut -f1)
Copy link

Copilot AI Aug 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bash parameter expansion ${name//-/_} replaces hyphens with underscores, but this transformation logic is hardcoded and may not work for all naming patterns. Consider using a more robust naming convention or adding validation to ensure the expected .so file exists.

Suggested change
if [ -f "$dir/target/deploy/${name//-/_}.so" ]; then
print_color "$GREEN" "$name built successfully"
local size=$(du -h "$dir/target/deploy/${name//-/_}.so" | cut -f1)
# Try both possible file names
local so_file=""
if [ -f "$dir/target/deploy/${name//-/_}.so" ]; then
so_file="$dir/target/deploy/${name//-/_}.so"
elif [ -f "$dir/target/deploy/${name}.so" ]; then
so_file="$dir/target/deploy/${name}.so"
else
# Fallback: find any .so file in deploy directory
so_file=$(ls "$dir/target/deploy/"*.so 2>/dev/null | head -n 1)
fi
if [ -n "$so_file" ] && [ -f "$so_file" ]; then
print_color "$GREEN" "$name built successfully"
local size=$(du -h "$so_file" | cut -f1)

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants