Skip to content

Commit b91d42a

Browse files
committed
refactor: split processor
1 parent 775c24f commit b91d42a

17 files changed

+1174
-996
lines changed

program/rust/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ mod deserialize;
1111
mod error;
1212
mod instruction;
1313
mod processor;
14-
mod rust_oracle;
1514
mod time_machine_types;
1615
mod utils;
1716

program/rust/src/processor.rs

Lines changed: 56 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,6 @@ use {
55
load_command_header_checked,
66
OracleCommand,
77
},
8-
rust_oracle::{
9-
add_mapping,
10-
add_price,
11-
add_product,
12-
add_publisher,
13-
del_price,
14-
del_product,
15-
del_publisher,
16-
init_mapping,
17-
init_price,
18-
resize_price_account,
19-
set_min_pub,
20-
upd_permissions,
21-
upd_price,
22-
upd_price_no_fail_on_error,
23-
upd_product,
24-
},
258
},
269
solana_program::{
2710
entrypoint::ProgramResult,
@@ -30,34 +13,68 @@ use {
3013
},
3114
};
3215

16+
mod add_mapping;
17+
mod add_price;
18+
mod add_product;
19+
mod add_publisher;
20+
mod del_price;
21+
mod del_product;
22+
mod del_publisher;
23+
mod init_mapping;
24+
mod init_price;
25+
mod resize_price_account;
26+
mod set_min_pub;
27+
mod upd_permissions;
28+
mod upd_price;
29+
mod upd_product;
30+
31+
pub use {
32+
add_mapping::add_mapping,
33+
add_price::add_price,
34+
add_product::add_product,
35+
add_publisher::add_publisher,
36+
del_price::del_price,
37+
del_product::del_product,
38+
del_publisher::del_publisher,
39+
init_mapping::init_mapping,
40+
init_price::init_price,
41+
resize_price_account::resize_price_account,
42+
set_min_pub::set_min_pub,
43+
upd_permissions::upd_permissions,
44+
upd_price::{
45+
c_upd_aggregate,
46+
upd_price,
47+
upd_price_no_fail_on_error,
48+
},
49+
upd_product::upd_product,
50+
};
51+
3352
/// Dispatch to the right instruction in the oracle.
3453
pub fn process_instruction(
3554
program_id: &Pubkey,
3655
accounts: &[AccountInfo],
3756
instruction_data: &[u8],
3857
) -> ProgramResult {
58+
use OracleCommand::*;
59+
3960
match load_command_header_checked(instruction_data)? {
40-
OracleCommand::InitMapping => init_mapping(program_id, accounts, instruction_data),
41-
OracleCommand::AddMapping => add_mapping(program_id, accounts, instruction_data),
42-
OracleCommand::AddProduct => add_product(program_id, accounts, instruction_data),
43-
OracleCommand::UpdProduct => upd_product(program_id, accounts, instruction_data),
44-
OracleCommand::AddPrice => add_price(program_id, accounts, instruction_data),
45-
OracleCommand::AddPublisher => add_publisher(program_id, accounts, instruction_data),
46-
OracleCommand::DelPublisher => del_publisher(program_id, accounts, instruction_data),
47-
OracleCommand::UpdPrice => upd_price(program_id, accounts, instruction_data),
48-
OracleCommand::AggPrice => upd_price(program_id, accounts, instruction_data),
49-
OracleCommand::InitPrice => init_price(program_id, accounts, instruction_data),
50-
OracleCommand::InitTest => Err(OracleError::UnrecognizedInstruction.into()),
51-
OracleCommand::UpdTest => Err(OracleError::UnrecognizedInstruction.into()),
52-
OracleCommand::SetMinPub => set_min_pub(program_id, accounts, instruction_data),
53-
OracleCommand::UpdPriceNoFailOnError => {
54-
upd_price_no_fail_on_error(program_id, accounts, instruction_data)
55-
}
56-
OracleCommand::ResizePriceAccount => {
57-
resize_price_account(program_id, accounts, instruction_data)
58-
}
59-
OracleCommand::DelPrice => del_price(program_id, accounts, instruction_data),
60-
OracleCommand::DelProduct => del_product(program_id, accounts, instruction_data),
61-
OracleCommand::UpdPermissions => upd_permissions(program_id, accounts, instruction_data),
61+
InitMapping => init_mapping(program_id, accounts, instruction_data),
62+
AddMapping => add_mapping(program_id, accounts, instruction_data),
63+
AddProduct => add_product(program_id, accounts, instruction_data),
64+
UpdProduct => upd_product(program_id, accounts, instruction_data),
65+
AddPrice => add_price(program_id, accounts, instruction_data),
66+
AddPublisher => add_publisher(program_id, accounts, instruction_data),
67+
DelPublisher => del_publisher(program_id, accounts, instruction_data),
68+
UpdPrice => upd_price(program_id, accounts, instruction_data),
69+
AggPrice => upd_price(program_id, accounts, instruction_data),
70+
InitPrice => init_price(program_id, accounts, instruction_data),
71+
InitTest => Err(OracleError::UnrecognizedInstruction.into()),
72+
UpdTest => Err(OracleError::UnrecognizedInstruction.into()),
73+
SetMinPub => set_min_pub(program_id, accounts, instruction_data),
74+
UpdPriceNoFailOnError => upd_price_no_fail_on_error(program_id, accounts, instruction_data),
75+
ResizePriceAccount => resize_price_account(program_id, accounts, instruction_data),
76+
DelPrice => del_price(program_id, accounts, instruction_data),
77+
DelProduct => del_product(program_id, accounts, instruction_data),
78+
UpdPermissions => upd_permissions(program_id, accounts, instruction_data),
6279
}
6380
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
use {
2+
crate::{
3+
accounts::{
4+
MappingAccount,
5+
PythAccount,
6+
},
7+
c_oracle_header::PC_MAP_TABLE_SIZE,
8+
deserialize::{
9+
load,
10+
load_checked,
11+
},
12+
instruction::CommandHeader,
13+
utils::{
14+
check_valid_funding_account,
15+
check_valid_signable_account_or_permissioned_funding_account,
16+
pyth_assert,
17+
},
18+
OracleError,
19+
},
20+
solana_program::{
21+
account_info::AccountInfo,
22+
entrypoint::ProgramResult,
23+
program_error::ProgramError,
24+
pubkey::Pubkey,
25+
},
26+
};
27+
28+
pub fn add_mapping(
29+
program_id: &Pubkey,
30+
accounts: &[AccountInfo],
31+
instruction_data: &[u8],
32+
) -> ProgramResult {
33+
let (funding_account, cur_mapping, next_mapping, permissions_account_option) = match accounts {
34+
[x, y, z] => Ok((x, y, z, None)),
35+
[x, y, z, p] => Ok((x, y, z, Some(p))),
36+
_ => Err(OracleError::InvalidNumberOfAccounts),
37+
}?;
38+
39+
let hdr = load::<CommandHeader>(instruction_data)?;
40+
41+
check_valid_funding_account(funding_account)?;
42+
check_valid_signable_account_or_permissioned_funding_account(
43+
program_id,
44+
cur_mapping,
45+
funding_account,
46+
permissions_account_option,
47+
hdr,
48+
)?;
49+
check_valid_signable_account_or_permissioned_funding_account(
50+
program_id,
51+
next_mapping,
52+
funding_account,
53+
permissions_account_option,
54+
hdr,
55+
)?;
56+
57+
let mut cur_mapping = load_checked::<MappingAccount>(cur_mapping, hdr.version)?;
58+
pyth_assert(
59+
cur_mapping.number_of_products == PC_MAP_TABLE_SIZE
60+
&& cur_mapping.next_mapping_account == Pubkey::default(),
61+
ProgramError::InvalidArgument,
62+
)?;
63+
64+
MappingAccount::initialize(next_mapping, hdr.version)?;
65+
cur_mapping.next_mapping_account = *next_mapping.key;
66+
67+
Ok(())
68+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
use {
2+
crate::{
3+
accounts::{
4+
PriceAccount,
5+
ProductAccount,
6+
PythAccount,
7+
},
8+
c_oracle_header::PC_PTYPE_UNKNOWN,
9+
deserialize::{
10+
load,
11+
load_checked,
12+
},
13+
instruction::AddPriceArgs,
14+
utils::{
15+
check_exponent_range,
16+
check_valid_funding_account,
17+
check_valid_signable_account_or_permissioned_funding_account,
18+
pyth_assert,
19+
},
20+
OracleError,
21+
},
22+
solana_program::{
23+
account_info::AccountInfo,
24+
entrypoint::ProgramResult,
25+
program_error::ProgramError,
26+
pubkey::Pubkey,
27+
},
28+
};
29+
30+
/// Add a price account to a product account
31+
/// accounts[0] funding account [signer writable]
32+
/// accounts[1] product account to add the price account to [signer writable]
33+
/// accounts[2] newly created price account [signer writable]
34+
pub fn add_price(
35+
program_id: &Pubkey,
36+
accounts: &[AccountInfo],
37+
instruction_data: &[u8],
38+
) -> ProgramResult {
39+
let cmd_args = load::<AddPriceArgs>(instruction_data)?;
40+
41+
check_exponent_range(cmd_args.exponent)?;
42+
pyth_assert(
43+
cmd_args.price_type != PC_PTYPE_UNKNOWN,
44+
ProgramError::InvalidArgument,
45+
)?;
46+
47+
48+
let (funding_account, product_account, price_account, permissions_account_option) =
49+
match accounts {
50+
[x, y, z] => Ok((x, y, z, None)),
51+
[x, y, z, p] => Ok((x, y, z, Some(p))),
52+
_ => Err(OracleError::InvalidNumberOfAccounts),
53+
}?;
54+
55+
check_valid_funding_account(funding_account)?;
56+
check_valid_signable_account_or_permissioned_funding_account(
57+
program_id,
58+
product_account,
59+
funding_account,
60+
permissions_account_option,
61+
&cmd_args.header,
62+
)?;
63+
check_valid_signable_account_or_permissioned_funding_account(
64+
program_id,
65+
price_account,
66+
funding_account,
67+
permissions_account_option,
68+
&cmd_args.header,
69+
)?;
70+
71+
let mut product_data =
72+
load_checked::<ProductAccount>(product_account, cmd_args.header.version)?;
73+
74+
let mut price_data = PriceAccount::initialize(price_account, cmd_args.header.version)?;
75+
price_data.exponent = cmd_args.exponent;
76+
price_data.price_type = cmd_args.price_type;
77+
price_data.product_account = *product_account.key;
78+
price_data.next_price_account = product_data.first_price_account;
79+
product_data.first_price_account = *price_account.key;
80+
81+
Ok(())
82+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
use {
2+
crate::{
3+
accounts::{
4+
MappingAccount,
5+
ProductAccount,
6+
PythAccount,
7+
},
8+
c_oracle_header::PC_MAP_TABLE_SIZE,
9+
deserialize::{
10+
load,
11+
load_checked,
12+
},
13+
instruction::CommandHeader,
14+
utils::{
15+
check_valid_funding_account,
16+
check_valid_signable_account_or_permissioned_funding_account,
17+
pyth_assert,
18+
try_convert,
19+
},
20+
OracleError,
21+
},
22+
solana_program::{
23+
account_info::AccountInfo,
24+
entrypoint::ProgramResult,
25+
program_error::ProgramError,
26+
pubkey::Pubkey,
27+
},
28+
std::mem::{
29+
size_of,
30+
size_of_val,
31+
},
32+
};
33+
34+
pub fn add_product(
35+
program_id: &Pubkey,
36+
accounts: &[AccountInfo],
37+
instruction_data: &[u8],
38+
) -> ProgramResult {
39+
let (funding_account, tail_mapping_account, new_product_account, permissions_account_option) =
40+
match accounts {
41+
[x, y, z] => Ok((x, y, z, None)),
42+
[x, y, z, p] => Ok((x, y, z, Some(p))),
43+
_ => Err(OracleError::InvalidNumberOfAccounts),
44+
}?;
45+
46+
let hdr = load::<CommandHeader>(instruction_data)?;
47+
48+
check_valid_funding_account(funding_account)?;
49+
check_valid_signable_account_or_permissioned_funding_account(
50+
program_id,
51+
tail_mapping_account,
52+
funding_account,
53+
permissions_account_option,
54+
hdr,
55+
)?;
56+
check_valid_signable_account_or_permissioned_funding_account(
57+
program_id,
58+
new_product_account,
59+
funding_account,
60+
permissions_account_option,
61+
hdr,
62+
)?;
63+
64+
65+
let mut mapping_data = load_checked::<MappingAccount>(tail_mapping_account, hdr.version)?;
66+
// The mapping account must have free space to add the product account
67+
pyth_assert(
68+
mapping_data.number_of_products < PC_MAP_TABLE_SIZE,
69+
ProgramError::InvalidArgument,
70+
)?;
71+
72+
ProductAccount::initialize(new_product_account, hdr.version)?;
73+
74+
let current_index: usize = try_convert(mapping_data.number_of_products)?;
75+
mapping_data.products_list[current_index] = *new_product_account.key;
76+
mapping_data.number_of_products += 1;
77+
mapping_data.header.size = try_convert::<_, u32>(
78+
size_of::<MappingAccount>() - size_of_val(&mapping_data.products_list),
79+
)? + mapping_data.number_of_products
80+
* try_convert::<_, u32>(size_of::<Pubkey>())?;
81+
82+
Ok(())
83+
}

0 commit comments

Comments
 (0)