pub struct SnapshotFrame {
    pub id: u64,
    pub snapshot: Pubkey,
    pub stake_amount: u64,
    pub stake_offset: u64,
    pub total_entries: u64,
    pub worker: Pubkey,
}
Expand description
  • SnapshotFrame

Fields§

§id: u64§snapshot: Pubkey§stake_amount: u64§stake_offset: u64§total_entries: u64§worker: Pubkey

Implementations§

Examples found in repository?
src/state/snapshot_frame.rs (line 62)
61
62
63
    fn pubkey(&self) -> Pubkey {
        SnapshotFrame::pubkey(self.snapshot, self.id)
    }
More examples
Hide additional examples
src/instructions/snapshot_delete.rs (line 62)
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
pub fn handler(ctx: Context<SnapshotDelete>) -> Result<ThreadResponse> {
    // Get accounts
    let config = &ctx.accounts.config;
    let registry = &ctx.accounts.registry;
    let snapshot = &mut ctx.accounts.snapshot;
    let thread = &mut ctx.accounts.thread;

    // If this snapshot has no entries, then close immediately
    if snapshot.total_frames.eq(&0) {
        let snapshot_lamports = snapshot.to_account_info().lamports();
        **snapshot.to_account_info().lamports.borrow_mut() = 0;
        **thread.to_account_info().lamports.borrow_mut() = thread
            .to_account_info()
            .lamports()
            .checked_add(snapshot_lamports)
            .unwrap();
    }

    // Build next instruction the thread.
    let next_instruction = if snapshot.total_frames.gt(&0) {
        // There are frames in this snapshot. Delete them.
        Some(InstructionData {
            program_id: crate::ID,
            accounts: vec![
                AccountMetaData::new_readonly(config.key(), false),
                AccountMetaData::new_readonly(registry.key(), false),
                AccountMetaData::new(snapshot.key(), false),
                AccountMetaData::new(SnapshotFrame::pubkey(snapshot.key(), 0), false),
                AccountMetaData::new(thread.key(), true),
            ],
            data: anchor_sighash("snapshot_frame_delete").to_vec(),
        })
    } else {
        // This snaphot has no frames. We are done!
        None
    };

    Ok(ThreadResponse { next_instruction, ..ThreadResponse::default() })
}
src/instructions/snapshot_create.rs (line 56)
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
pub fn handler(ctx: Context<SnapshotCreate>) -> Result<ThreadResponse> {
    // Get accounts
    let config = &ctx.accounts.config;
    let registry = &ctx.accounts.registry;
    let snapshot = &mut ctx.accounts.snapshot;
    let system_program = &ctx.accounts.system_program;
    let thread = &ctx.accounts.thread;

    // Start a new snapshot.
    snapshot.init(registry.current_epoch.checked_add(1).unwrap())?;

    // Build next instruction for thread.
    let next_instruction = if registry.total_workers.gt(&0) {
        // The registry has workers. Create a snapshot frame for the zeroth worker.
        let snapshot_frame_pubkey = SnapshotFrame::pubkey(snapshot.key(), 0);
        let worker_pubkey = Worker::pubkey(0);
        Some(InstructionData {
            program_id: crate::ID,
            accounts: vec![
                AccountMetaData::new_readonly(config.key(), false),
                AccountMetaData::new(clockwork_utils::PAYER_PUBKEY, true),
                AccountMetaData::new_readonly(registry.key(), false),
                AccountMetaData::new(snapshot.key(), false),
                AccountMetaData::new(snapshot_frame_pubkey, false),
                AccountMetaData::new_readonly(system_program.key(), false),
                AccountMetaData::new_readonly(thread.key(), true),
                AccountMetaData::new_readonly(worker_pubkey, false),
                AccountMetaData::new_readonly(
                    get_associated_token_address(&worker_pubkey, &config.mint),
                    false,
                ),
            ],
            data: anchor_sighash("snapshot_frame_create").to_vec(),
        })
    } else {
        // The registry has no workers, so the snapshot is done. Start the epoch!
        Some(InstructionData {
            program_id: crate::ID,
            accounts: vec![
                AccountMetaData::new_readonly(config.key(), false),
                AccountMetaData::new(registry.key(), false),
                AccountMetaData::new_readonly(thread.key(), true),
            ],
            data: anchor_sighash("registry_epoch_cutover").to_vec(),
        })
    };

    Ok(ThreadResponse {
        next_instruction,
        ..ThreadResponse::default()
    })
}
src/instructions/registry_epoch_kickoff.rs (line 82)
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
pub fn handler(ctx: Context<RegistryEpochKickoff>) -> Result<ThreadResponse> {
    // Get accounts.
    let config = &ctx.accounts.config;
    let registry = &mut ctx.accounts.registry;
    let snapshot = &ctx.accounts.snapshot;
    let thread = &ctx.accounts.thread;

    // Lock the registry
    registry.locked = true;

    // Setup the next kickoff instruction to use the next snapshot.
    let kickoff_instruction = Some(InstructionData {
        program_id: crate::ID,
        accounts: vec![
            AccountMetaData::new_readonly(config.key(), false),
            AccountMetaData::new(registry.key(), false),
            AccountMetaData::new_readonly(
                Snapshot::pubkey(snapshot.id.checked_add(1).unwrap()),
                false,
            ),
            AccountMetaData::new_readonly(thread.key(), true),
        ],
        data: anchor_sighash("registry_epoch_kickoff").to_vec(),
    });

    // Build the next instruction for thread.
    let next_instruction = if snapshot.total_frames.gt(&0) {
        // The current snapshot has frames. Distribute fees collected by workers.
        Some(InstructionData {
            program_id: crate::ID,
            accounts: vec![
                AccountMetaData::new_readonly(config.key(), false),
                AccountMetaData::new(Fee::pubkey(Worker::pubkey(0)), false),
                AccountMetaData::new_readonly(registry.key(), false),
                AccountMetaData::new_readonly(snapshot.key(), false),
                AccountMetaData::new_readonly(SnapshotFrame::pubkey(snapshot.key(), 0), false),
                AccountMetaData::new_readonly(thread.key(), true),
                AccountMetaData::new(Worker::pubkey(0), false),
            ],
            data: anchor_sighash("worker_fees_distribute").to_vec(),
        })
    } else if registry.total_workers.gt(&0) {
        // The registry has workers. Begin delegating stakes to workers.
        Some(InstructionData {
            program_id: crate::ID,
            accounts: vec![
                AccountMetaData::new_readonly(config.key(), false),
                AccountMetaData::new_readonly(registry.key(), false),
                AccountMetaData::new_readonly(thread.key(), true),
                AccountMetaData::new_readonly(Worker::pubkey(0), false),
            ],
            data: anchor_sighash("worker_delegations_stake").to_vec(),
        })
    } else {
        // Cutover to the next epoch.
        Some(InstructionData {
            program_id: crate::ID,
            accounts: vec![
                AccountMetaData::new_readonly(config.key(), false),
                AccountMetaData::new(registry.key(), false),
                AccountMetaData::new_readonly(thread.key(), true),
            ],
            data: anchor_sighash("registry_epoch_cutover").to_vec(),
        })
    };

    Ok(ThreadResponse {
        kickoff_instruction,
        next_instruction,
    })
}
src/instructions/snapshot_frame_delete.rs (line 100)
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
pub fn handler(ctx: Context<SnapshotFrameDelete>) -> Result<ThreadResponse> {
    // Get accounts
    let config = &ctx.accounts.config;
    let registry = &ctx.accounts.registry;
    let snapshot = &mut ctx.accounts.snapshot;
    let snapshot_frame = &mut ctx.accounts.snapshot_frame;
    let thread = &mut ctx.accounts.thread;

    // If this frame has no entries, then close the frame account.
    if snapshot_frame.total_entries.eq(&0) {
        let snapshot_frame_lamports = snapshot_frame.to_account_info().lamports();
        **snapshot_frame.to_account_info().lamports.borrow_mut() = 0;
        **thread.to_account_info().lamports.borrow_mut() = thread
            .to_account_info()
            .lamports()
            .checked_add(snapshot_frame_lamports)
            .unwrap();


        // If this is also the last frame in the snapshot, then close the snapshot account.
        if snapshot_frame.id.checked_add(1).unwrap().eq(&snapshot.total_frames) {
            let snapshot_lamports = snapshot.to_account_info().lamports();
            **snapshot.to_account_info().lamports.borrow_mut() = 0;
            **thread.to_account_info().lamports.borrow_mut() = thread
                .to_account_info()
                .lamports()
                .checked_add(snapshot_lamports)
                .unwrap();
        }
    }

    // Build the next instruction.
    let next_instruction = if snapshot_frame.total_entries.gt(&0) {
        // This frame has entries. Delete the entries.
        Some(InstructionData {
            program_id: crate::ID,
            accounts: vec![
                AccountMetaData::new_readonly(config.key(), false),
                AccountMetaData::new_readonly(registry.key(), false),
                AccountMetaData::new(snapshot.key(), false),
                AccountMetaData::new(SnapshotEntry::pubkey(snapshot_frame.key(), 0), false),
                AccountMetaData::new(snapshot_frame.key(), false),
                AccountMetaData::new(thread.key(), true),
            ],
            data: anchor_sighash("snapshot_entry_delete").to_vec(),
        })
    } else if snapshot_frame.id.checked_add(1).unwrap().lt(&snapshot.total_frames) {
        // There are no more entries in this frame. Move on to the next frame.
        Some(InstructionData {
            program_id: crate::ID,
            accounts: vec![
                AccountMetaData::new_readonly(config.key(), false),
                AccountMetaData::new_readonly(registry.key(), false),
                AccountMetaData::new(snapshot.key(), false),
                AccountMetaData::new(SnapshotFrame::pubkey(snapshot.key(), snapshot_frame.id.checked_add(1).unwrap()), false),
                AccountMetaData::new(thread.key(), true),
            ],
            data: anchor_sighash("snapshot_frame_delete").to_vec(),
        })
    } else {
        // This frame has no entries, and it was the last frame. We are done!
        None
    };

    Ok( ThreadResponse { next_instruction, ..ThreadResponse::default() } )
}
src/instructions/snapshot_entry_delete.rs (line 122)
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
pub fn handler(ctx: Context<SnapshotEntryDelete>) -> Result<ThreadResponse> {
    // Get accounts
    let config = &ctx.accounts.config;
    let registry = &ctx.accounts.registry;
    let snapshot = &mut ctx.accounts.snapshot;
    let snapshot_entry = &mut ctx.accounts.snapshot_entry;
    let snapshot_frame = &mut ctx.accounts.snapshot_frame;
    let thread = &mut ctx.accounts.thread;

    // Close the snapshot entry account.
    let snapshot_entry_lamports = snapshot_entry.to_account_info().lamports();
    **snapshot_entry.to_account_info().lamports.borrow_mut() = 0;
    **thread.to_account_info().lamports.borrow_mut() = thread
        .to_account_info()
        .lamports()
        .checked_add(snapshot_entry_lamports)
        .unwrap();

    // If this frame has no more entries, then close the frame account.
    if snapshot_entry.id.checked_add(1).unwrap().eq(&snapshot_frame.total_entries) {
        let snapshot_frame_lamports = snapshot_frame.to_account_info().lamports();
        **snapshot_frame.to_account_info().lamports.borrow_mut() = 0;
        **thread.to_account_info().lamports.borrow_mut() = thread
            .to_account_info()
            .lamports()
            .checked_add(snapshot_frame_lamports)
            .unwrap();


        // If this is also the last frame in the snapshot, then close the snapshot account.
        if snapshot_frame.id.checked_add(1).unwrap().eq(&snapshot.total_frames) {
            let snapshot_lamports = snapshot.to_account_info().lamports();
            **snapshot.to_account_info().lamports.borrow_mut() = 0;
            **thread.to_account_info().lamports.borrow_mut() = thread
                .to_account_info()
                .lamports()
                .checked_add(snapshot_lamports)
                .unwrap();
        }
    }

    // Build the next instruction
    let next_instruction = if snapshot_entry.id.checked_add(1).unwrap().lt(&snapshot_frame.total_entries) {
        // Move on to the next entry.
        Some(InstructionData {
            program_id: crate::ID,
            accounts: vec![
                AccountMetaData::new_readonly(config.key(), false),
                AccountMetaData::new_readonly(registry.key(), false),
                AccountMetaData::new(snapshot.key(), false),
                AccountMetaData::new(SnapshotEntry::pubkey(snapshot_frame.key(), snapshot_entry.id.checked_add(1).unwrap()), false),
                AccountMetaData::new(snapshot_frame.key(), false),
                AccountMetaData::new(thread.key(), true),
            ],
            data: anchor_sighash("snapshot_entry_delete").to_vec(),
        })
    } else if snapshot_frame.id.checked_add(1).unwrap().lt(&snapshot.total_frames) {
        // This frame has no more entries. Move onto the next frame.
        Some(InstructionData {
            program_id: crate::ID,
            accounts: vec![
                AccountMetaData::new_readonly(config.key(), false),
                AccountMetaData::new_readonly(registry.key(), false),
                AccountMetaData::new(snapshot.key(), false),
                AccountMetaData::new(SnapshotFrame::pubkey(snapshot.key(), snapshot_frame.id.checked_add(1).unwrap()), false),
                AccountMetaData::new(thread.key(), true),
            ],
            data: anchor_sighash("snapshot_frame_delete").to_vec(),
        })
    } else {
        // This frame as no more entires and it was the last frame in the snapshot. We are done!
        None
    };

    Ok( ThreadResponse { next_instruction, ..ThreadResponse::default() } )
}

Trait Implementations§

Deserializes previously initialized account data. Should fail for all uninitialized accounts, where the bytes are zeroed. Implementations should be unique to a particular account type so that one can never successfully deserialize the data of one account type into another. For example, if the SPL token program were to implement this trait, it should be impossible to deserialize a Mint account into a token Account. Read more
Deserializes account data without checking the account discriminator. This should only be used on account initialization, when the bytes of the account are zeroed. Read more
Serializes the account data into writer.
Deserializes this instance from a given slice of bytes. Updates the buffer to point at the remaining bytes. Read more
Deserialize this instance from a slice of bytes.
Serialize this instance into a vector of bytes.
Returns a copy of the value. Read more
Performs copy-assignment from source. Read more
Formats the value using the given formatter. Read more
The type returned in the event of a conversion error.
Performs the conversion.

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
Should always be Self
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.