Skip to content

Commit

Permalink
Attestation: Add ops owner and set-is-active ix (#295)
Browse files Browse the repository at this point in the history
* Attestation: Add ops owner and set-is-active ix

* Update solana/pyth2wormhole/client/src/cli.rs

Co-authored-by: Stanisław Drozd <[email protected]>

* Fix typos

* Add a test without owner

Co-authored-by: Stanisław Drozd <[email protected]>
  • Loading branch information
ali-bahjati and Stanisław Drozd authored Sep 21, 2022
1 parent bf032f0 commit 77083cf
Show file tree
Hide file tree
Showing 9 changed files with 392 additions and 8 deletions.
23 changes: 23 additions & 0 deletions solana/pyth2wormhole/client/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ pub enum Action {
/// Option<> makes sure not specifying this flag does not imply "false"
#[clap(long = "is-active")]
is_active: Option<bool>,
#[clap(long = "ops-owner")]
ops_owner_addr: Option<Pubkey>,
},
#[clap(
about = "Use an existing pyth2wormhole program to attest product price information to another chain"
Expand Down Expand Up @@ -115,6 +117,10 @@ pub enum Action {
new_pyth_owner_addr: Option<Pubkey>,
#[clap(long = "is-active")]
is_active: Option<bool>,
#[clap(long = "ops-owner")]
ops_owner_addr: Option<Pubkey>,
#[clap(long = "remove-ops-owner", conflicts_with = "ops_owner_addr")]
remove_ops_owner: bool,
},
#[clap(
about = "Migrate existing pyth2wormhole program settings to a newer format version. Client version must match the deployed contract."
Expand All @@ -130,4 +136,21 @@ pub enum Action {
},
#[clap(about = "Print out emitter address for the specified pyth2wormhole contract")]
GetEmitter,
#[clap(
about = "Set the value of is_active config as ops_owner"
)]
SetIsActive {
/// Current ops owner keypair path
#[clap(
long,
default_value = "~/.config/solana/id.json",
help = "Keypair file for the current ops owner"
)]
ops_owner: String,
#[clap(
index = 1,
possible_values = ["true", "false"],
)]
new_is_active: String,
}
}
39 changes: 39 additions & 0 deletions solana/pyth2wormhole/client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,45 @@ pub fn gen_set_config_tx(
Ok(tx_signed)
}


pub fn gen_set_is_active_tx(
payer: Keypair,
p2w_addr: Pubkey,
ops_owner: Keypair,
new_is_active: bool,
latest_blockhash: Hash,
) -> Result<Transaction, ErrBox> {
let payer_pubkey = payer.pubkey();

let acc_metas = vec![
// config
AccountMeta::new(
P2WConfigAccount::<{ AccountState::Initialized }>::key(None, &p2w_addr),
false,
),
// ops_owner
AccountMeta::new(ops_owner.pubkey(), true),
// payer
AccountMeta::new(payer.pubkey(), true),
];

let ix_data = (
pyth2wormhole::instruction::Instruction::SetIsActive,
new_is_active,
);

let ix = Instruction::new_with_bytes(p2w_addr, ix_data.try_to_vec()?.as_slice(), acc_metas);

let signers = vec![&ops_owner, &payer];
let tx_signed = Transaction::new_signed_with_payer::<Vec<&Keypair>>(
&[ix],
Some(&payer_pubkey),
&signers,
latest_blockhash,
);
Ok(tx_signed)
}

pub fn gen_migrate_tx(
payer: Keypair,
p2w_addr: Pubkey,
Expand Down
36 changes: 32 additions & 4 deletions solana/pyth2wormhole/client/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ async fn main() -> Result<(), ErrBox> {
pyth_owner_addr,
wh_prog,
is_active,
ops_owner_addr,
} => {
let tx = gen_init_tx(
payer,
Expand All @@ -107,14 +108,15 @@ async fn main() -> Result<(), ErrBox> {
pyth_owner: pyth_owner_addr,
is_active: is_active.unwrap_or(true),
max_batch_size: P2W_MAX_BATCH_SIZE,
ops_owner: ops_owner_addr,
},
latest_blockhash,
)?;
rpc_client
.send_and_confirm_transaction_with_spinner(&tx)
.await?;
println!(
"Initialized with conifg:\n{:?}",
"Initialized with config:\n{:?}",
get_config_account(&rpc_client, &p2w_addr).await?
);
}
Expand All @@ -127,8 +129,17 @@ async fn main() -> Result<(), ErrBox> {
new_wh_prog,
new_pyth_owner_addr,
is_active,
ops_owner_addr,
remove_ops_owner,
} => {
let old_config = get_config_account(&rpc_client, &p2w_addr).await?;

let new_ops_owner = if remove_ops_owner {
None
} else {
ops_owner_addr
};

let tx = gen_set_config_tx(
payer,
p2w_addr,
Expand All @@ -139,14 +150,15 @@ async fn main() -> Result<(), ErrBox> {
pyth_owner: new_pyth_owner_addr.unwrap_or(old_config.pyth_owner),
is_active: is_active.unwrap_or(old_config.is_active),
max_batch_size: P2W_MAX_BATCH_SIZE,
ops_owner: new_ops_owner,
},
latest_blockhash,
)?;
rpc_client
.send_and_confirm_transaction_with_spinner(&tx)
.await?;
println!(
"Applied conifg:\n{:?}",
"Applied config:\n{:?}",
get_config_account(&rpc_client, &p2w_addr).await?
);
}
Expand All @@ -161,7 +173,7 @@ async fn main() -> Result<(), ErrBox> {
.send_and_confirm_transaction_with_spinner(&tx)
.await?;
println!(
"Applied conifg:\n{:?}",
"Applied config:\n{:?}",
get_config_account(&rpc_client, &p2w_addr).await?
);
}
Expand Down Expand Up @@ -196,7 +208,23 @@ async fn main() -> Result<(), ErrBox> {
)
.await?;
}
Action::GetEmitter => unreachable! {},
Action::GetEmitter => unreachable! {}, // It is handled early in this function.
Action::SetIsActive { ops_owner, new_is_active } => {
let tx = gen_set_is_active_tx(
payer,
p2w_addr,
read_keypair_file(&*shellexpand::tilde(&ops_owner))?,
new_is_active.eq_ignore_ascii_case("true"),
latest_blockhash,
)?;
rpc_client
.send_and_confirm_transaction_with_spinner(&tx)
.await?;
println!(
"Applied config:\n{:?}",
get_config_account(&rpc_client, &p2w_addr).await?
);
},
}

Ok(())
Expand Down
2 changes: 2 additions & 0 deletions solana/pyth2wormhole/client/tests/test_attest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ async fn test_happy_path() -> Result<(), p2wc::ErrBoxSend> {
// Authorities
let p2w_owner = Pubkey::new_unique();
let pyth_owner = Pubkey::new_unique();
let ops_owner = Pubkey::new_unique();

// On-chain state
let p2w_config = Pyth2WormholeConfig {
Expand All @@ -55,6 +56,7 @@ async fn test_happy_path() -> Result<(), p2wc::ErrBoxSend> {
max_batch_size: pyth2wormhole::attest::P2W_MAX_BATCH_SIZE,
pyth_owner,
is_active: true,
ops_owner: Some(ops_owner),
};

let bridge_config = BridgeData {
Expand Down
4 changes: 4 additions & 0 deletions solana/pyth2wormhole/client/tests/test_migrate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ async fn test_migrate_works() -> Result<(), solitaire::ErrBox> {
wh_prog: wh_fixture_program_id,
max_batch_size: pyth2wormhole::attest::P2W_MAX_BATCH_SIZE,
pyth_owner,
is_active: true,
};

info!("Before ProgramTest::new()");
Expand Down Expand Up @@ -114,13 +115,15 @@ async fn test_migrate_already_migrated() -> Result<(), solitaire::ErrBox> {
// Authorities
let p2w_owner = Keypair::new();
let pyth_owner = Pubkey::new_unique();
let ops_owner = Keypair::new();

// On-chain state
let old_p2w_config = OldPyth2WormholeConfig {
owner: p2w_owner.pubkey(),
wh_prog: wh_fixture_program_id,
max_batch_size: pyth2wormhole::attest::P2W_MAX_BATCH_SIZE,
pyth_owner,
is_active: true,
};

let new_p2w_config = Pyth2WormholeConfig {
Expand All @@ -129,6 +132,7 @@ async fn test_migrate_already_migrated() -> Result<(), solitaire::ErrBox> {
max_batch_size: pyth2wormhole::attest::P2W_MAX_BATCH_SIZE,
pyth_owner,
is_active: true,
ops_owner: Some(ops_owner.pubkey()),
};

info!("Before ProgramTest::new()");
Expand Down
Loading

0 comments on commit 77083cf

Please sign in to comment.