Skip to content

Commit 130c052

Browse files
author
Stanisław Drozd
authored
pyth2wormhole: Fix a cfg migration bug, fix cfg lockout (see below) (#253)
This commit resolves a runtime problem in migrate() which occurred on devnet, as well as invalid mutability for the old config and misuse of the checked_sub() method. The runtime problem came from a non-zero balance existing on not-yet-used PDA. Effectively, this means permissionless initialization of PDAs on Solana. Anyone can send lamports to any account on Solana (existing or not), and it doesn't take much funds to keep an empty account exempt. While it is possible to recover from it, this case is relatively rare and takes a lot of code to automate. Instead, we settle for a dumb bump of the config PDA seed (see config.rs). This measure is best used sparingly, as it imposes the same static seed on all SOL networks. This will cause headaches if the attester tooling grows a third-party user base.
1 parent 22cdd5e commit 130c052

File tree

3 files changed

+11
-4
lines changed

3 files changed

+11
-4
lines changed

solana/pyth2wormhole/client/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ pub fn gen_migrate_tx(
143143

144144
let accs = MigrateAccounts {
145145
new_config: Derived(p2w_addr),
146-
old_config: DerivedRO(p2w_addr),
146+
old_config: Derived(p2w_addr),
147147
current_owner: Signer(owner),
148148
payer: Signer(payer),
149149
};

solana/pyth2wormhole/program/src/config.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,13 @@ pub struct Pyth2WormholeConfigV2 {
9191
pub is_active: bool,
9292
}
9393

94+
/// Note: If you get stuck with a pre-existing config account
95+
/// (e.g. someone transfers into a PDA that we're not using yet), it's
96+
/// usually easier to change the seed slightly
97+
/// (e.g. pyth2wormhole-config-v2 -> pyth2wormhole-config-v2.1). This
98+
/// saves a lot of time coding around this edge case.
9499
pub type P2WConfigAccountV2<'b, const IsInitialized: AccountState> =
95-
Derive<Data<'b, Pyth2WormholeConfigV2, { IsInitialized }>, "pyth2wormhole-config-v2">;
100+
Derive<Data<'b, Pyth2WormholeConfigV2, { IsInitialized }>, "pyth2wormhole-config-v2.1">;
96101

97102
impl From<Pyth2WormholeConfigV1> for Pyth2WormholeConfigV2 {
98103
fn from(old: Pyth2WormholeConfigV1) -> Self {

solana/pyth2wormhole/program/src/migrate.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ pub struct Migrate<'b> {
3838
/// New config account to be populated. Must be unused.
3939
pub new_config: Mut<P2WConfigAccount<'b, { AccountState::Uninitialized }>>,
4040
/// Old config using the previous format.
41-
pub old_config: OldP2WConfigAccount<'b>,
41+
pub old_config: Mut<OldP2WConfigAccount<'b>>,
4242
/// Current owner authority of the program
4343
pub current_owner: Mut<Signer<Info<'b>>>,
4444
/// Payer account for updating the account data
@@ -78,7 +78,7 @@ pub fn migrate(ctx: &ExecutionContext, accs: &mut Migrate, data: ()) -> SoliResu
7878
**accs.old_config.info().lamports.borrow_mut() = 0;
7979

8080
// Credit payer with saved balance
81-
accs.payer
81+
let new_payer_balance = accs.payer
8282
.info()
8383
.lamports
8484
.borrow_mut()
@@ -88,5 +88,7 @@ pub fn migrate(ctx: &ExecutionContext, accs: &mut Migrate, data: ()) -> SoliResu
8888
SolitaireError::ProgramError(ProgramError::Custom(0xDEADBEEF))
8989
})?;
9090

91+
**accs.payer.info().lamports.borrow_mut() = new_payer_balance;
92+
9193
Ok(())
9294
}

0 commit comments

Comments
 (0)