Skip to content

Commit d1c03cc

Browse files
authored
math: more type tests (solana-labs#6713)
* math: add u128 and f64 * math: modify inputs * math: fix fmt --------- Co-authored-by: A5 Pickle <[email protected]>
1 parent 355620e commit d1c03cc

File tree

3 files changed

+207
-0
lines changed

3 files changed

+207
-0
lines changed

libraries/math/src/instruction.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,43 @@ pub enum MathInstruction {
107107
exponent: f64,
108108
},
109109

110+
/// Multiply two u128 values
111+
///
112+
/// No accounts required for this instruction
113+
U128Multiply {
114+
/// The multiplicand
115+
multiplicand: u128,
116+
/// The multipier
117+
multiplier: u128,
118+
},
119+
/// Divide two u128 values
120+
///
121+
/// No accounts required for this instruction
122+
U128Divide {
123+
/// The dividend
124+
dividend: u128,
125+
/// The divisor
126+
divisor: u128,
127+
},
128+
/// Multiply two f64 values
129+
///
130+
/// No accounts required for this instruction
131+
F64Multiply {
132+
/// The multiplicand
133+
multiplicand: f64,
134+
/// The multipier
135+
multiplier: f64,
136+
},
137+
/// Divide two f64 values
138+
///
139+
/// No accounts required for this instruction
140+
F64Divide {
141+
/// The dividend
142+
dividend: f64,
143+
/// The divisor
144+
divisor: f64,
145+
},
146+
110147
/// Don't do anything for comparison
111148
///
112149
/// No accounts required for this instruction
@@ -220,6 +257,50 @@ pub fn f64_pow(base: f64, exponent: f64) -> Instruction {
220257
}
221258
}
222259

260+
/// Create U128 Multiplication instruction
261+
pub fn u128_multiply(multiplicand: u128, multiplier: u128) -> Instruction {
262+
Instruction {
263+
program_id: id(),
264+
accounts: vec![],
265+
data: borsh::to_vec(&MathInstruction::U128Multiply {
266+
multiplicand,
267+
multiplier,
268+
})
269+
.unwrap(),
270+
}
271+
}
272+
273+
/// Create U128 Division instruction
274+
pub fn u128_divide(dividend: u128, divisor: u128) -> Instruction {
275+
Instruction {
276+
program_id: id(),
277+
accounts: vec![],
278+
data: borsh::to_vec(&MathInstruction::U128Divide { dividend, divisor }).unwrap(),
279+
}
280+
}
281+
282+
/// Create F64 Multiplication instruction
283+
pub fn f64_multiply(multiplicand: f64, multiplier: f64) -> Instruction {
284+
Instruction {
285+
program_id: id(),
286+
accounts: vec![],
287+
data: borsh::to_vec(&MathInstruction::F64Multiply {
288+
multiplicand,
289+
multiplier,
290+
})
291+
.unwrap(),
292+
}
293+
}
294+
295+
/// Create F64 Division instruction
296+
pub fn f64_divide(dividend: f64, divisor: f64) -> Instruction {
297+
Instruction {
298+
program_id: id(),
299+
accounts: vec![],
300+
data: borsh::to_vec(&MathInstruction::F64Divide { dividend, divisor }).unwrap(),
301+
}
302+
}
303+
223304
/// Create Noop instruction
224305
pub fn noop() -> Instruction {
225306
Instruction {

libraries/math/src/processor.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,30 @@ fn f32_natural_log(argument: f32) -> f32 {
5050
argument.ln()
5151
}
5252

53+
/// u128_multiply
54+
#[inline(never)]
55+
fn u128_multiply(multiplicand: u128, multiplier: u128) -> u128 {
56+
multiplicand * multiplier
57+
}
58+
59+
/// u128_divide
60+
#[inline(never)]
61+
fn u128_divide(dividend: u128, divisor: u128) -> u128 {
62+
dividend / divisor
63+
}
64+
65+
/// f64_multiply
66+
#[inline(never)]
67+
fn f64_multiply(multiplicand: f64, multiplier: f64) -> f64 {
68+
multiplicand * multiplier
69+
}
70+
71+
/// f64_divide
72+
#[inline(never)]
73+
fn f64_divide(dividend: f64, divisor: f64) -> f64 {
74+
dividend / divisor
75+
}
76+
5377
/// Instruction processor
5478
pub fn process_instruction(
5579
_program_id: &Pubkey,
@@ -157,6 +181,44 @@ pub fn process_instruction(
157181
msg!("{}", result as u64);
158182
Ok(())
159183
}
184+
MathInstruction::U128Multiply {
185+
multiplicand,
186+
multiplier,
187+
} => {
188+
msg!("Calculating u128 Multiply");
189+
sol_log_compute_units();
190+
let result = u128_multiply(multiplicand, multiplier);
191+
sol_log_compute_units();
192+
msg!("{}", result);
193+
Ok(())
194+
}
195+
MathInstruction::U128Divide { dividend, divisor } => {
196+
msg!("Calculating u128 Divide");
197+
sol_log_compute_units();
198+
let result = u128_divide(dividend, divisor);
199+
sol_log_compute_units();
200+
msg!("{}", result);
201+
Ok(())
202+
}
203+
MathInstruction::F64Multiply {
204+
multiplicand,
205+
multiplier,
206+
} => {
207+
msg!("Calculating f64 Multiply");
208+
sol_log_compute_units();
209+
let result = f64_multiply(multiplicand, multiplier);
210+
sol_log_compute_units();
211+
msg!("{}", result as u64);
212+
Ok(())
213+
}
214+
MathInstruction::F64Divide { dividend, divisor } => {
215+
msg!("Calculating f64 Divide");
216+
sol_log_compute_units();
217+
let result = f64_divide(dividend, divisor);
218+
sol_log_compute_units();
219+
msg!("{}", result as u64);
220+
Ok(())
221+
}
160222
MathInstruction::Noop => {
161223
msg!("Do nothing");
162224
msg!("{}", 0_u64);

libraries/math/tests/instruction_count.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,70 @@ async fn test_f64_pow() {
214214
banks_client.process_transaction(transaction).await.unwrap();
215215
}
216216

217+
#[tokio::test]
218+
async fn test_u128_multiply() {
219+
let mut pc = ProgramTest::new("spl_math", id(), processor!(process_instruction));
220+
221+
pc.set_compute_max_units(10000);
222+
223+
let (mut banks_client, payer, recent_blockhash) = pc.start().await;
224+
225+
let mut transaction = Transaction::new_with_payer(
226+
&[instruction::u128_multiply(u64::MAX.into(), u64::MAX.into())],
227+
Some(&payer.pubkey()),
228+
);
229+
transaction.sign(&[&payer], recent_blockhash);
230+
banks_client.process_transaction(transaction).await.unwrap();
231+
}
232+
233+
#[tokio::test]
234+
async fn test_u128_divide() {
235+
let mut pc = ProgramTest::new("spl_math", id(), processor!(process_instruction));
236+
237+
pc.set_compute_max_units(10000);
238+
239+
let (mut banks_client, payer, recent_blockhash) = pc.start().await;
240+
241+
let mut transaction = Transaction::new_with_payer(
242+
&[instruction::u128_divide(u128::MAX, u128::MAX / 69)],
243+
Some(&payer.pubkey()),
244+
);
245+
transaction.sign(&[&payer], recent_blockhash);
246+
banks_client.process_transaction(transaction).await.unwrap();
247+
}
248+
249+
#[tokio::test]
250+
async fn test_f64_multiply() {
251+
let mut pc = ProgramTest::new("spl_math", id(), processor!(process_instruction));
252+
253+
pc.set_compute_max_units(10000);
254+
255+
let (mut banks_client, payer, recent_blockhash) = pc.start().await;
256+
257+
let mut transaction = Transaction::new_with_payer(
258+
&[instruction::f64_multiply(f64::powf(2., 42.), 1e-4)],
259+
Some(&payer.pubkey()),
260+
);
261+
transaction.sign(&[&payer], recent_blockhash);
262+
banks_client.process_transaction(transaction).await.unwrap();
263+
}
264+
265+
#[tokio::test]
266+
async fn test_f64_divide() {
267+
let mut pc = ProgramTest::new("spl_math", id(), processor!(process_instruction));
268+
269+
pc.set_compute_max_units(10000);
270+
271+
let (mut banks_client, payer, recent_blockhash) = pc.start().await;
272+
273+
let mut transaction = Transaction::new_with_payer(
274+
&[instruction::f64_divide(f64::powf(2., 42.), 420420.6969)],
275+
Some(&payer.pubkey()),
276+
);
277+
transaction.sign(&[&payer], recent_blockhash);
278+
banks_client.process_transaction(transaction).await.unwrap();
279+
}
280+
217281
#[tokio::test]
218282
async fn test_noop() {
219283
let mut pc = ProgramTest::new("spl_math", id(), processor!(process_instruction));

0 commit comments

Comments
 (0)