Struct clockwork_network_program::state::Worker
source · pub struct Worker {
pub authority: Pubkey,
pub commission_balance: u64,
pub commission_rate: u64,
pub id: u64,
pub signatory: Pubkey,
pub total_delegations: u64,
}
Expand description
Worker
Fields§
The worker’s authority (owner).
commission_balance: u64
The number of lamports claimable by the authority as commission for running the worker.
commission_rate: u64
Integer between 0 and 100 determining the percentage of fees worker will keep as commission.
id: u64
The worker’s id.
signatory: Pubkey
The worker’s signatory address (used to sign txs).
total_delegations: u64
The number delegations allocated to this worker.
Implementations§
source§impl Worker
impl Worker
sourcepub fn pubkey(id: u64) -> Pubkey
pub fn pubkey(id: u64) -> Pubkey
Examples found in repository?
More examples
src/instructions/snapshot_create.rs (line 57)
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 79)
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/worker_delegations_stake.rs (line 71)
26 27 28 29 30 31 32 33 34 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 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
pub fn handler(ctx: Context<WorkerStakeDelegations>) -> Result<ThreadResponse> {
// Get accounts.
let config = &ctx.accounts.config;
let registry = &ctx.accounts.registry;
let thread = &ctx.accounts.thread;
let worker = &ctx.accounts.worker;
// Build the next instruction for the thread.
let next_instruction = if worker.total_delegations.gt(&0) {
// This worker has delegations. Stake their deposits.
let delegation_pubkey = Delegation::pubkey(worker.key(), 0);
Some(InstructionData {
program_id: crate::ID,
accounts: vec![
AccountMetaData::new_readonly(config.key(), false),
AccountMetaData::new(delegation_pubkey, false),
AccountMetaData::new(
get_associated_token_address(&delegation_pubkey, &config.mint),
false,
),
AccountMetaData::new_readonly(registry.key(), false),
AccountMetaData::new_readonly(thread.key(), true),
AccountMetaData::new_readonly(anchor_spl::token::ID, false),
AccountMetaData::new_readonly(worker.key(), false),
AccountMetaData::new(
get_associated_token_address(&worker.key(), &config.mint),
false,
),
],
data: anchor_sighash("delegation_stake").to_vec(),
})
} else if worker
.id
.checked_add(1)
.unwrap()
.lt(®istry.total_workers)
{
// This worker has no delegations. Move on to the next worker.
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(worker.id.checked_add(1).unwrap()),
false,
),
],
data: anchor_sighash("worker_delegations_stake").to_vec(),
})
} else {
// This worker has no delegations and it is the last worker. Move on to the snapshot job!
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::pubkey(registry.current_epoch.checked_add(1).unwrap()),
false,
),
AccountMetaData::new_readonly(system_program::ID, false),
AccountMetaData::new_readonly(thread.key(), true),
],
data: anchor_sighash("snapshot_create").to_vec(),
})
};
Ok(ThreadResponse {
next_instruction,
..ThreadResponse::default()
})
}
src/instructions/unstake_process.rs (line 162)
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 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
pub fn handler(ctx: Context<UnstakeProcess>) -> Result<ThreadResponse> {
// Get accounts.
let authority = &ctx.accounts.authority;
let authority_tokens = &ctx.accounts.authority_tokens;
let config = &ctx.accounts.config;
let delegation = &mut ctx.accounts.delegation;
let registry = &mut ctx.accounts.registry;
let thread = &ctx.accounts.thread;
let token_program = &ctx.accounts.token_program;
let unstake = &ctx.accounts.unstake;
let worker = &ctx.accounts.worker;
let worker_tokens = &ctx.accounts.worker_tokens;
// Verify the unstake amount is valid.
require!(
unstake.amount.le(&delegation.stake_amount),
ClockworkError::InvalidUnstakeAmount
);
// Transfer tokens from the worker to the authority.
transfer(
CpiContext::new_with_signer(
token_program.to_account_info(),
Transfer {
from: worker_tokens.to_account_info(),
to: authority_tokens.to_account_info(),
authority: worker.to_account_info(),
},
&[&[SEED_WORKER, worker.id.to_be_bytes().as_ref()]],
),
unstake.amount,
)?;
// Decrement the delegations locked stake balacne by the requested unstake amount.
delegation.stake_amount = delegation.stake_amount.checked_sub(unstake.amount).unwrap();
// Close the unstake account by transfering all lamports to the authority.
let balance = unstake.to_account_info().lamports();
**unstake.to_account_info().try_borrow_mut_lamports()? = unstake
.to_account_info()
.lamports()
.checked_sub(balance)
.unwrap();
**authority.to_account_info().try_borrow_mut_lamports()? = authority
.to_account_info()
.lamports()
.checked_add(balance)
.unwrap();
// If this is the last unstake, then reset the registry's unstake counter.
if unstake
.id
.checked_add(1)
.unwrap()
.eq(®istry.total_unstakes)
{
registry.total_unstakes = 0;
}
// Build next instruction for the thread.
let next_instruction = if unstake
.id
.checked_add(1)
.unwrap()
.lt(®istry.total_unstakes)
{
let next_unstake_pubkey = Unstake::pubkey(unstake.id.checked_add(1).unwrap());
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(next_unstake_pubkey, false),
],
data: anchor_sighash("unstake_preprocess").to_vec(),
})
} else {
// This is the last unstake. Reset the registry's unstake counter.
registry.total_unstakes = 0;
// Move on to staking delegations.
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(),
})
};
Ok(ThreadResponse {
next_instruction,
..ThreadResponse::default()
})
}
src/instructions/snapshot_frame_create.rs (line 119)
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 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
pub fn handler(ctx: Context<SnapshotFrameCreate>) -> 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 system_program = &ctx.accounts.system_program;
let thread = &ctx.accounts.thread;
let worker = &ctx.accounts.worker;
let worker_stake = &ctx.accounts.worker_stake;
// Initialize snapshot frame account.
snapshot_frame.init(
snapshot.total_frames,
snapshot.key(),
worker_stake.amount,
snapshot.total_stake,
worker.key(),
)?;
// Update snapshot total workers.
snapshot.total_stake = snapshot
.total_stake
.checked_add(worker_stake.amount)
.unwrap();
snapshot.total_frames = snapshot.total_frames.checked_add(1).unwrap();
// Build the next instruction for the thread.
let next_instruction = if worker.total_delegations.gt(&0) {
// This worker has delegations. Create a snapshot entry for each delegation associated with this worker.
let zeroth_delegation_pubkey = Delegation::pubkey(worker.pubkey(), 0);
let zeroth_snapshot_entry_pubkey = SnapshotEntry::pubkey(snapshot_frame.key(), 0);
Some(InstructionData {
program_id: crate::ID,
accounts: vec![
AccountMetaData::new_readonly(config.key(), false),
AccountMetaData::new_readonly(zeroth_delegation_pubkey, false),
AccountMetaData::new(clockwork_utils::PAYER_PUBKEY, true),
AccountMetaData::new_readonly(registry.key(), false),
AccountMetaData::new_readonly(snapshot.key(), false),
AccountMetaData::new(zeroth_snapshot_entry_pubkey, false),
AccountMetaData::new(snapshot_frame.key(), false),
AccountMetaData::new_readonly(system_program.key(), false),
AccountMetaData::new_readonly(thread.key(), true),
AccountMetaData::new_readonly(worker.key(), false),
],
data: anchor_sighash("snapshot_entry_create").to_vec(),
})
} else if snapshot.total_frames.lt(®istry.total_workers) {
// This worker has no delegations. Create a snapshot frame for the next worker.
let next_snapshot_frame_pubkey =
SnapshotFrame::pubkey(snapshot.key(), snapshot_frame.id.checked_add(1).unwrap());
let next_worker_pubkey = Worker::pubkey(worker.id.checked_add(1).unwrap());
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(next_snapshot_frame_pubkey, false),
AccountMetaData::new_readonly(system_program.key(), false),
AccountMetaData::new_readonly(thread.key(), true),
AccountMetaData::new_readonly(next_worker_pubkey, false),
AccountMetaData::new_readonly(
get_associated_token_address(&next_worker_pubkey, &config.mint),
false,
),
],
data: anchor_sighash("snapshot_frame_create").to_vec(),
})
} else {
// This worker has no delegations and this is the last frame, so the snapshot is done. 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 {
next_instruction,
..ThreadResponse::default()
})
}
Trait Implementations§
source§impl AccountDeserialize for Worker
impl AccountDeserialize for Worker
source§fn try_deserialize(buf: &mut &[u8]) -> Result<Self>
fn try_deserialize(buf: &mut &[u8]) -> Result<Self>
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