Skip to content

Commit 6898b39

Browse files
authored
Better program (#297)
* Add tests * Add tests to CI * Remote test from precommit hook * New test * Remove merge error * Comments and increase seqno * Remove unnecesary dep * Fix rebase * Fix feedback * Move anchor checks * Fix comment * Restore deny warnings * Better comments * Typo * Improve comments * Better comment * Tests for the remote executor (#298) * Tests * Cleanup * Comments * Comments * Tests complete
1 parent bc48a31 commit 6898b39

File tree

8 files changed

+532
-61
lines changed

8 files changed

+532
-61
lines changed

pythnet/remote-executor/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pythnet/remote-executor/programs/remote-executor/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,4 @@ solana-program-test = "=1.10.31"
2929
tokio = "1.14.1"
3030
solana-sdk = "=1.10.31"
3131
bincode = "1.3.3"
32+
rand = "0.8.5"

pythnet/remote-executor/programs/remote-executor/src/lib.rs

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,23 @@ use anchor_lang::{
66
solana_program::borsh::get_packed_len,
77
system_program,
88
};
9+
use error::ExecutorError;
910
use state::{
1011
claim_record::ClaimRecord,
1112
posted_vaa::AnchorVaa,
1213
};
14+
use wormhole::Chain::{
15+
self,
16+
Solana,
17+
};
1318

1419
mod error;
1520
mod state;
1621

17-
#[cfg(test)] //Conditional compilation of the tests
22+
#[cfg(test)]
1823
mod tests;
1924

25+
//Anchor requires the program to declare its own id
2026
declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
2127

2228
#[program]
@@ -25,32 +31,24 @@ pub mod remote_executor {
2531
instruction::Instruction,
2632
program::invoke_signed,
2733
};
28-
use boolinator::Boolinator;
29-
use wormhole::Chain::{
30-
self,
31-
Solana,
32-
};
3334

34-
use crate::{
35-
error::ExecutorError,
36-
state::governance_payload::ExecutorPayload,
37-
};
35+
use crate::state::governance_payload::ExecutorPayload;
3836

3937
use super::*;
4038

4139
pub fn execute_posted_vaa(ctx: Context<ExecutePostedVaa>) -> Result<()> {
4240
let posted_vaa = &ctx.accounts.posted_vaa;
4341
let claim_record = &mut ctx.accounts.claim_record;
44-
45-
(Chain::from(posted_vaa.emitter_chain) == Solana)
46-
.ok_or(error!(ExecutorError::EmitterChainNotSolana))?;
47-
(posted_vaa.sequence > claim_record.sequence)
48-
.ok_or(error!(ExecutorError::NonIncreasingSequence))?;
4942
claim_record.sequence = posted_vaa.sequence;
5043

5144
let payload = ExecutorPayload::try_from_slice(&posted_vaa.payload)?;
5245
payload.check_header()?;
5346

47+
let (_, bump) = Pubkey::find_program_address(
48+
&[EXECUTOR_KEY_SEED.as_bytes(), &posted_vaa.emitter_address],
49+
&id(),
50+
);
51+
5452
for instruction in payload.instructions.iter().map(Instruction::from) {
5553
// TO DO: We currently pass `remaining_accounts` down to the CPIs, is there a more efficient way to do it?
5654
invoke_signed(
@@ -59,7 +57,7 @@ pub mod remote_executor {
5957
&[&[
6058
EXECUTOR_KEY_SEED.as_bytes(),
6159
&posted_vaa.emitter_address,
62-
&[*ctx.bumps.get("executor_key").unwrap()],
60+
&[bump],
6361
]],
6462
)?;
6563
}
@@ -74,13 +72,16 @@ const CLAIM_RECORD_SEED: &str = "CLAIM_RECORD";
7472
pub struct ExecutePostedVaa<'info> {
7573
#[account(mut)]
7674
pub payer: Signer<'info>,
75+
#[account(constraint = Chain::from(posted_vaa.emitter_chain) == Solana @ ExecutorError::EmitterChainNotSolana, constraint = posted_vaa.sequence > claim_record.sequence @ExecutorError::NonIncreasingSequence )]
7776
pub posted_vaa: Account<'info, AnchorVaa>,
78-
#[account(seeds = [EXECUTOR_KEY_SEED.as_bytes(), &posted_vaa.emitter_address], bump)]
79-
pub executor_key: UncheckedAccount<'info>,
80-
/// The reason claim record is separated from executor_key is that executor key might need to pay in the CPI, so we want it to be a wallet
77+
/// The reason claim_record has different seeds than executor_key is that executor key might need to pay in the CPI, so we want it to be a native wallet
8178
#[account(init_if_needed, space = 8 + get_packed_len::<ClaimRecord>(), payer=payer, seeds = [CLAIM_RECORD_SEED.as_bytes(), &posted_vaa.emitter_address], bump)]
8279
pub claim_record: Account<'info, ClaimRecord>,
8380
pub system_program: Program<'info, System>,
81+
// Additional accounts passed to the instruction will be passed down to the CPIs. Very importantly executor_key needs to be passed as it will be the signer of the CPIs.
82+
// Below is the "anchor specification" of that account
83+
// #[account(seeds = [EXECUTOR_KEY_SEED.as_bytes(), &posted_vaa.emitter_address], bump)]
84+
// pub executor_key: UncheckedAccount<'info>,
8485
}
8586

8687
impl crate::accounts::ExecutePostedVaa {
@@ -90,19 +91,13 @@ impl crate::accounts::ExecutePostedVaa {
9091
emitter: &Pubkey,
9192
posted_vaa: &Pubkey,
9293
) -> Self {
93-
let executor_key = Pubkey::find_program_address(
94-
&[EXECUTOR_KEY_SEED.as_bytes(), &emitter.to_bytes()],
95-
program_id,
96-
)
97-
.0;
9894
let claim_record = Pubkey::find_program_address(
9995
&[CLAIM_RECORD_SEED.as_bytes(), &emitter.to_bytes()],
10096
program_id,
10197
)
10298
.0;
10399
crate::accounts::ExecutePostedVaa {
104100
payer: *payer,
105-
executor_key,
106101
claim_record,
107102
posted_vaa: *posted_vaa,
108103
system_program: system_program::ID,

0 commit comments

Comments
 (0)