@@ -6,7 +6,14 @@ use solana_program::{
66use crate :: {
77 error:: ExecutorQuoterError ,
88 math,
9- state:: { load_account, ChainInfo , Config , QuoteBody } ,
9+ state:: {
10+ pack_quote_body_to_bytes32, read_bytes32, read_u64_le, read_u8, validate_account,
11+ CHAIN_INFO_DISCRIMINATOR , CHAIN_INFO_ENABLED_OFFSET , CHAIN_INFO_GAS_PRICE_DECIMALS_OFFSET ,
12+ CHAIN_INFO_LEN , CHAIN_INFO_NATIVE_DECIMALS_OFFSET , CONFIG_DISCRIMINATOR , CONFIG_LEN ,
13+ CONFIG_PAYEE_ADDRESS_OFFSET , QUOTE_BODY_BASE_FEE_OFFSET , QUOTE_BODY_DISCRIMINATOR ,
14+ QUOTE_BODY_DST_GAS_PRICE_OFFSET , QUOTE_BODY_DST_PRICE_OFFSET , QUOTE_BODY_LEN ,
15+ QUOTE_BODY_SRC_PRICE_OFFSET ,
16+ } ,
1017} ;
1118
1219/// Relay instruction type constants (matching EVM)
@@ -110,15 +117,50 @@ pub fn process_request_quote(
110117 return Err ( ProgramError :: NotEnoughAccountKeys ) ;
111118 } ;
112119
113- // Load accounts (discriminator checked inside load_account)
114- let _config = load_account :: < Config > ( config_account, program_id) ?;
120+ // Validate config account
121+ validate_account ( config_account, program_id, CONFIG_DISCRIMINATOR , CONFIG_LEN ) ?;
115122
116- let chain_info = load_account :: < ChainInfo > ( chain_info_account, program_id) ?;
117- if !chain_info. is_enabled ( ) {
118- return Err ( ExecutorQuoterError :: ChainDisabled . into ( ) ) ;
119- }
123+ // Validate chain_info account and check if enabled
124+ validate_account (
125+ chain_info_account,
126+ program_id,
127+ CHAIN_INFO_DISCRIMINATOR ,
128+ CHAIN_INFO_LEN ,
129+ ) ?;
130+
131+ // Validate quote_body account
132+ validate_account (
133+ quote_body_account,
134+ program_id,
135+ QUOTE_BODY_DISCRIMINATOR ,
136+ QUOTE_BODY_LEN ,
137+ ) ?;
138+
139+ // Read chain_info fields
140+ let ( gas_price_decimals, native_decimals) = {
141+ let chain_info_data = chain_info_account. try_borrow_data ( ) ?;
142+
143+ // Check if chain is enabled
144+ if read_u8 ( & chain_info_data, CHAIN_INFO_ENABLED_OFFSET ) == 0 {
145+ return Err ( ExecutorQuoterError :: ChainDisabled . into ( ) ) ;
146+ }
147+
148+ (
149+ read_u8 ( & chain_info_data, CHAIN_INFO_GAS_PRICE_DECIMALS_OFFSET ) ,
150+ read_u8 ( & chain_info_data, CHAIN_INFO_NATIVE_DECIMALS_OFFSET ) ,
151+ )
152+ } ;
120153
121- let quote_body = load_account :: < QuoteBody > ( quote_body_account, program_id) ?;
154+ // Read quote_body fields
155+ let ( base_fee, src_price, dst_price, dst_gas_price) = {
156+ let quote_body_data = quote_body_account. try_borrow_data ( ) ?;
157+ (
158+ read_u64_le ( & quote_body_data, QUOTE_BODY_BASE_FEE_OFFSET ) ,
159+ read_u64_le ( & quote_body_data, QUOTE_BODY_SRC_PRICE_OFFSET ) ,
160+ read_u64_le ( & quote_body_data, QUOTE_BODY_DST_PRICE_OFFSET ) ,
161+ read_u64_le ( & quote_body_data, QUOTE_BODY_DST_GAS_PRICE_OFFSET ) ,
162+ )
163+ } ;
122164
123165 // Parse instruction data to get relay_instructions
124166 // Skip: dst_chain (2) + dst_addr (32) + refund_addr (32) = 66 bytes
@@ -152,12 +194,12 @@ pub fn process_request_quote(
152194
153195 // Calculate quote - returns u64 in SVM native decimals (lamports)
154196 let required_payment = math:: estimate_quote (
155- quote_body . base_fee ,
156- quote_body . src_price ,
157- quote_body . dst_price ,
158- quote_body . dst_gas_price ,
159- chain_info . gas_price_decimals ,
160- chain_info . native_decimals ,
197+ base_fee,
198+ src_price,
199+ dst_price,
200+ dst_gas_price,
201+ gas_price_decimals,
202+ native_decimals,
161203 gas_limit,
162204 msg_value,
163205 ) ?;
@@ -182,15 +224,50 @@ pub fn process_request_execution_quote(
182224 return Err ( ProgramError :: NotEnoughAccountKeys ) ;
183225 } ;
184226
185- // Load accounts (discriminator checked inside load_account)
186- let config = load_account :: < Config > ( config_account, program_id) ?;
227+ // Validate config account
228+ validate_account ( config_account, program_id, CONFIG_DISCRIMINATOR , CONFIG_LEN ) ?;
187229
188- let chain_info = load_account :: < ChainInfo > ( chain_info_account, program_id) ?;
189- if !chain_info. is_enabled ( ) {
190- return Err ( ExecutorQuoterError :: ChainDisabled . into ( ) ) ;
191- }
230+ // Validate chain_info account
231+ validate_account (
232+ chain_info_account,
233+ program_id,
234+ CHAIN_INFO_DISCRIMINATOR ,
235+ CHAIN_INFO_LEN ,
236+ ) ?;
192237
193- let quote_body = load_account :: < QuoteBody > ( quote_body_account, program_id) ?;
238+ // Validate quote_body account
239+ validate_account (
240+ quote_body_account,
241+ program_id,
242+ QUOTE_BODY_DISCRIMINATOR ,
243+ QUOTE_BODY_LEN ,
244+ ) ?;
245+
246+ // Read chain_info fields
247+ let ( gas_price_decimals, native_decimals) = {
248+ let chain_info_data = chain_info_account. try_borrow_data ( ) ?;
249+
250+ // Check if chain is enabled
251+ if read_u8 ( & chain_info_data, CHAIN_INFO_ENABLED_OFFSET ) == 0 {
252+ return Err ( ExecutorQuoterError :: ChainDisabled . into ( ) ) ;
253+ }
254+
255+ (
256+ read_u8 ( & chain_info_data, CHAIN_INFO_GAS_PRICE_DECIMALS_OFFSET ) ,
257+ read_u8 ( & chain_info_data, CHAIN_INFO_NATIVE_DECIMALS_OFFSET ) ,
258+ )
259+ } ;
260+
261+ // Read quote_body fields and config payee_address
262+ let ( base_fee, src_price, dst_price, dst_gas_price) = {
263+ let quote_body_data = quote_body_account. try_borrow_data ( ) ?;
264+ (
265+ read_u64_le ( & quote_body_data, QUOTE_BODY_BASE_FEE_OFFSET ) ,
266+ read_u64_le ( & quote_body_data, QUOTE_BODY_SRC_PRICE_OFFSET ) ,
267+ read_u64_le ( & quote_body_data, QUOTE_BODY_DST_PRICE_OFFSET ) ,
268+ read_u64_le ( & quote_body_data, QUOTE_BODY_DST_GAS_PRICE_OFFSET ) ,
269+ )
270+ } ;
194271
195272 // Parse instruction data to get relay_instructions
196273 if data. len ( ) < 70 {
@@ -222,12 +299,12 @@ pub fn process_request_execution_quote(
222299
223300 // Calculate quote - returns u64 in SVM native decimals (lamports)
224301 let required_payment = math:: estimate_quote (
225- quote_body . base_fee ,
226- quote_body . src_price ,
227- quote_body . dst_price ,
228- quote_body . dst_gas_price ,
229- chain_info . gas_price_decimals ,
230- chain_info . native_decimals ,
302+ base_fee,
303+ src_price,
304+ dst_price,
305+ dst_gas_price,
306+ gas_price_decimals,
307+ native_decimals,
231308 gas_limit,
232309 msg_value,
233310 ) ?;
@@ -238,8 +315,17 @@ pub fn process_request_execution_quote(
238315 // - bytes 40-71: quote_body (32 bytes, EQ01 format)
239316 let mut return_data = [ 0u8 ; 72 ] ;
240317 return_data[ 0 ..8 ] . copy_from_slice ( & required_payment. to_be_bytes ( ) ) ;
241- return_data[ 8 ..40 ] . copy_from_slice ( & config. payee_address ) ;
242- return_data[ 40 ..72 ] . copy_from_slice ( & quote_body. to_bytes32 ( ) ) ;
318+
319+ // Read payee_address from config
320+ {
321+ let config_data = config_account. try_borrow_data ( ) ?;
322+ let payee_address = read_bytes32 ( & config_data, CONFIG_PAYEE_ADDRESS_OFFSET ) ;
323+ return_data[ 8 ..40 ] . copy_from_slice ( payee_address) ;
324+ }
325+
326+ // Pack quote body to bytes32 (EQ01 format)
327+ let quote_body_bytes32 = pack_quote_body_to_bytes32 ( base_fee, dst_gas_price, src_price, dst_price) ;
328+ return_data[ 40 ..72 ] . copy_from_slice ( & quote_body_bytes32) ;
243329
244330 set_return_data ( & return_data) ;
245331
0 commit comments