Skip to content

Commit cca02cb

Browse files
committed
Build in migration rejection
1 parent 2ddca77 commit cca02cb

File tree

4 files changed

+54
-2
lines changed

4 files changed

+54
-2
lines changed

programs/migrator/src/account_contexts.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,16 @@ pub struct ApproveMigration<'info> {
9595
pub approver: Signer<'info>,
9696
}
9797

98+
#[derive(Accounts)]
99+
pub struct RejectMigration<'info> {
100+
/// The migrator.
101+
pub migrator: Account<'info, Migrator>,
102+
/// The migration.
103+
pub migration: Account<'info, Migration>,
104+
/// [Migrator::approver].
105+
pub approver: Signer<'info>,
106+
}
107+
98108
#[derive(Accounts)]
99109
#[instruction(bump: u8, title: String, description: String)]
100110
pub struct ProposeMigration<'info> {

programs/migrator/src/account_validators.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use solana_program::{
66
use vipers::{assert_keys, invariant, program_err, unwrap_opt, validate::Validate};
77

88
use crate::{
9-
account_contexts::{NewMigrator, ReserveProgramID},
9+
account_contexts::{NewMigrator, RejectMigration, ReserveProgramID},
1010
bpf_loader_upgradeable::UpgradeableLoaderAccount,
1111
ApproveMigration, ApprovedMigration, DeployProgram, LiveProgram, ProposeMigration,
1212
UndeployedProgram, UpgradeProgram,
@@ -79,6 +79,22 @@ impl<'info> Validate<'info> for ApproveMigration<'info> {
7979
"migration.migrator"
8080
);
8181
assert_keys!(self.migrator.approver, self.approver, "migrator.approver");
82+
require!(self.migration.executed_at == -1, MigrationAlreadyExecuted);
83+
84+
Ok(())
85+
}
86+
}
87+
88+
impl<'info> Validate<'info> for RejectMigration<'info> {
89+
fn validate(&self) -> ProgramResult {
90+
assert_keys!(
91+
self.migration.migrator,
92+
self.migration,
93+
"migration.migrator"
94+
);
95+
assert_keys!(self.migrator.approver, self.approver, "migrator.approver");
96+
require!(self.migration.executed_at == -1, MigrationAlreadyExecuted);
97+
8298
Ok(())
8399
}
84100
}

programs/migrator/src/instructions/approver.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,30 @@ pub fn approve_migration(ctx: Context<ApproveMigration>, deadline: i64) -> Progr
129129
deadline > Clock::get()?.unix_timestamp,
130130
ExpiryMustBeInFuture
131131
);
132+
133+
// un-reject if the migration was rejected.
134+
let migration = &mut ctx.accounts.migration;
135+
if migration.rejected_at != -1 {
136+
migration.rejected_at = -1;
137+
}
138+
132139
let migrator = &mut ctx.accounts.migrator;
133-
migrator.approver = ctx.accounts.approver.key();
134140
migrator.pending_migration = ctx.accounts.migration.key();
135141
migrator.approval_expires_at = deadline;
136142
Ok(())
137143
}
144+
145+
/// Rejects the current [Migration].
146+
pub fn reject_migration(ctx: Context<RejectMigration>) -> ProgramResult {
147+
let migration = &mut ctx.accounts.migration;
148+
migration.rejected_at = Clock::get()?.unix_timestamp;
149+
150+
// cancel migration if it's the pending one
151+
let migrator = &mut ctx.accounts.migrator;
152+
if migrator.pending_migration.key() == migration.key() {
153+
migrator.pending_migration = Pubkey::default();
154+
migrator.approval_expires_at = -1;
155+
}
156+
157+
Ok(())
158+
}

programs/migrator/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ pub mod migrator {
5353
ctx.accounts.validate()?;
5454
instructions::approver::approve_migration(ctx, deadline)
5555
}
56+
/// Approves a [Migration].
57+
pub fn reject_migration(ctx: Context<RejectMigration>) -> ProgramResult {
58+
ctx.accounts.validate()?;
59+
instructions::approver::reject_migration(ctx)
60+
}
5661

5762
//////////////////////////////////////////
5863
// Public instructions

0 commit comments

Comments
 (0)