diff --git a/libraries/math/src/instruction.rs b/libraries/math/src/instruction.rs index 8ba2111e..44e29ab0 100644 --- a/libraries/math/src/instruction.rs +++ b/libraries/math/src/instruction.rs @@ -43,7 +43,16 @@ pub enum MathInstruction { /// The multipier multiplier: u64, }, - /// Multiply two float valies + /// Divide two u64 values + /// + /// No accounts required for this instruction + U64Divide { + /// The dividend + dividend: u64, + /// The divisor + divisor: u64, + }, + /// Multiply two float values /// /// No accounts required for this instruction F32Multiply { @@ -52,7 +61,7 @@ pub enum MathInstruction { /// The multipier multiplier: f32, }, - /// Divide two float valies + /// Divide two float values /// /// No accounts required for this instruction F32Divide { @@ -114,6 +123,17 @@ pub fn u64_multiply(multiplicand: u64, multiplier: u64) -> Instruction { } } +/// Create PreciseSquareRoot instruction +pub fn u64_divide(dividend: u64, divisor: u64) -> Instruction { + Instruction { + program_id: id(), + accounts: vec![], + data: MathInstruction::U64Divide { dividend, divisor } + .try_to_vec() + .unwrap(), + } +} + /// Create PreciseSquareRoot instruction pub fn f32_multiply(multiplicand: f32, multiplier: f32) -> Instruction { Instruction { diff --git a/libraries/math/src/processor.rs b/libraries/math/src/processor.rs index cb1ab601..3d4d8205 100644 --- a/libraries/math/src/processor.rs +++ b/libraries/math/src/processor.rs @@ -3,9 +3,36 @@ use { crate::{approximations::sqrt, instruction::MathInstruction, precise_number::PreciseNumber}, borsh::BorshDeserialize, - solana_program::{account_info::AccountInfo, entrypoint::ProgramResult, msg, pubkey::Pubkey}, + solana_program::{ + account_info::AccountInfo, entrypoint::ProgramResult, log::sol_log_compute_units, msg, + pubkey::Pubkey, + }, }; +/// u64_multiply +#[inline(never)] +fn u64_multiply(multiplicand: u64, multiplier: u64) -> u64 { + multiplicand * multiplier +} + +/// u64_divide +#[inline(never)] +fn u64_divide(dividend: u64, divisor: u64) -> u64 { + dividend / divisor +} + +/// f32_multiply +#[inline(never)] +fn f32_multiply(multiplicand: f32, multiplier: f32) -> f32 { + multiplicand * multiplier +} + +/// f32_divide +#[inline(never)] +fn f32_divide(dividend: f32, divisor: f32) -> f32 { + dividend / divisor +} + /// Instruction processor pub fn process_instruction( _program_id: &Pubkey, @@ -17,19 +44,25 @@ pub fn process_instruction( MathInstruction::PreciseSquareRoot { radicand } => { msg!("Calculating square root using PreciseNumber"); let radicand = PreciseNumber::new(radicand as u128).unwrap(); + sol_log_compute_units(); let result = radicand.sqrt().unwrap().to_imprecise().unwrap() as u64; + sol_log_compute_units(); msg!("{}", result); Ok(()) } MathInstruction::SquareRootU64 { radicand } => { msg!("Calculating u64 square root"); + sol_log_compute_units(); let result = sqrt(radicand).unwrap(); + sol_log_compute_units(); msg!("{}", result); Ok(()) } MathInstruction::SquareRootU128 { radicand } => { msg!("Calculating u128 square root"); + sol_log_compute_units(); let result = sqrt(radicand).unwrap(); + sol_log_compute_units(); msg!("{}", result); Ok(()) } @@ -38,7 +71,17 @@ pub fn process_instruction( multiplier, } => { msg!("Calculating U64 Multiply"); - let result = multiplicand * multiplier; + sol_log_compute_units(); + let result = u64_multiply(multiplicand, multiplier); + sol_log_compute_units(); + msg!("{}", result); + Ok(()) + } + MathInstruction::U64Divide { dividend, divisor } => { + msg!("Calculating U64 Divide"); + sol_log_compute_units(); + let result = u64_divide(dividend, divisor); + sol_log_compute_units(); msg!("{}", result); Ok(()) } @@ -47,13 +90,17 @@ pub fn process_instruction( multiplier, } => { msg!("Calculating f32 Multiply"); - let result = multiplicand * multiplier; + sol_log_compute_units(); + let result = f32_multiply(multiplicand, multiplier); + sol_log_compute_units(); msg!("{}", result as u64); Ok(()) } MathInstruction::F32Divide { dividend, divisor } => { msg!("Calculating f32 Divide"); - let result = dividend / divisor; + sol_log_compute_units(); + let result = f32_divide(dividend, divisor); + sol_log_compute_units(); msg!("{}", result as u64); Ok(()) } diff --git a/libraries/math/tests/instruction_count.rs b/libraries/math/tests/instruction_count.rs index 087f5ac0..97cfd353 100644 --- a/libraries/math/tests/instruction_count.rs +++ b/libraries/math/tests/instruction_count.rs @@ -102,6 +102,20 @@ async fn test_u64_multiply() { banks_client.process_transaction(transaction).await.unwrap(); } +#[tokio::test] +async fn test_u64_divide() { + let mut pc = ProgramTest::new("spl_math", id(), processor!(process_instruction)); + + pc.set_bpf_compute_max_units(1650); + + let (mut banks_client, payer, recent_blockhash) = pc.start().await; + + let mut transaction = + Transaction::new_with_payer(&[instruction::u64_divide(3, 1)], Some(&payer.pubkey())); + transaction.sign(&[&payer], recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); +} + #[tokio::test] async fn test_f32_multiply() { let mut pc = ProgramTest::new("spl_math", id(), processor!(process_instruction));