diff --git a/COMEBACKHERE-contracts/contracts/treasury/resources/execute_settlement_baseline.json b/COMEBACKHERE-contracts/contracts/treasury/resources/execute_settlement_baseline.json index d847ff5..d200f1d 100644 --- a/COMEBACKHERE-contracts/contracts/treasury/resources/execute_settlement_baseline.json +++ b/COMEBACKHERE-contracts/contracts/treasury/resources/execute_settlement_baseline.json @@ -5,5 +5,40 @@ "memory_bytes": 50000, "tolerance_percent": 20, "timestamp": "2026-09-26", - "soroban_sdk": "28.0.0" -} \ No newline at end of file + "soroban_sdk": "28.0.0", + "lifecycle": { + "description": "Full invoice lifecycle resource baselines: creation, payment, cancellation, refund, and settlement", + "stages": { + "create_invoice": { + "test": "bench_create_invoice", + "cpu_instructions": 100000, + "memory_bytes": 50000, + "tolerance_percent": 20 + }, + "pay_invoice": { + "test": "bench_pay_invoice", + "cpu_instructions": 100000, + "memory_bytes": 50000, + "tolerance_percent": 20 + }, + "cancel_invoice": { + "test": "bench_cancel_invoice", + "cpu_instructions": 100000, + "memory_bytes": 50000, + "tolerance_percent": 20 + }, + "refund_invoice": { + "test": "bench_refund_invoice", + "cpu_instructions": 100000, + "memory_bytes": 50000, + "tolerance_percent": 20 + }, + "execute_settlement": { + "test": "bench_execute_settlement", + "cpu_instructions": 100000, + "memory_bytes": 50000, + "tolerance_percent": 20 + } + } + } +} diff --git a/COMEBACKHERE-contracts/contracts/treasury/src/benchmark.rs b/COMEBACKHERE-contracts/contracts/treasury/src/benchmark.rs index b5608f7..8cd4c81 100644 --- a/COMEBACKHERE-contracts/contracts/treasury/src/benchmark.rs +++ b/COMEBACKHERE-contracts/contracts/treasury/src/benchmark.rs @@ -5,6 +5,11 @@ use soroban_sdk::{testutils::Address as _, vec, Address, Env}; const APPROVE_BASELINE: &str = include_str!("../resources/approve_settlement_baseline.json"); const EXECUTE_BASELINE: &str = include_str!("../resources/execute_settlement_baseline.json"); +const INVOICE_CREATE_BASELINE: &str = include_str!("../resources/invoice_create_baseline.json"); +const INVOICE_PAY_BASELINE: &str = include_str!("../resources/invoice_pay_baseline.json"); +const INVOICE_CANCEL_BASELINE: &str = include_str!("../resources/invoice_cancel_baseline.json"); +const INVOICE_REFUND_BASELINE: &str = include_str!("../resources/invoice_refund_baseline.json"); +const INVOICE_SETTLE_BASELINE: &str = include_str!("../resources/invoice_settle_baseline.json"); fn assert_cost_within_baseline(baseline_json: &str, cpu: u64, memory: u64) { let baseline: serde_json::Value = @@ -191,3 +196,68 @@ fn bench_execute_settlement() { assert_cost_within_baseline(EXECUTE_BASELINE, cpu, memory); } + +/// Measures the resource cost of a single invoice lifecycle stage and asserts +/// it stays within the published baseline tolerance. Each stage is measured in +/// isolation against a freshly prepared invoice so the deltas are reproducible. +fn measure_invoice_stage(stage: F) -> (u64, u64) { + let (e, id) = setup_bench_env(); + let client = TreasuryContractClient::new(&e, &id); + let signer = Address::generate(&e); + let token = Address::generate(&e); + + e.budget().reset_unlimited(); + let cpu_before = e.budget().cpu_instruction_cost(); + let memory_before = e.budget().memory_bytes_cost(); + stage(&client, &signer, &token); + let cpu = e.budget().cpu_instruction_cost() - cpu_before; + let memory = e.budget().memory_bytes_cost() - memory_before; + + (cpu, memory) +} + +#[test] +fn bench_invoice_create() { + let (cpu, memory) = measure_invoice_stage(|client, signer, token| { + client.create_invoice(signer, token, &5_000_000u64); + }); + assert_cost_within_baseline(INVOICE_CREATE_BASELINE, cpu, memory); +} + +#[test] +fn bench_invoice_pay() { + let (cpu, memory) = measure_invoice_stage(|client, signer, token| { + let invoice_id = client.create_invoice(signer, token, &5_000_000u64); + client.pay_invoice(signer, &invoice_id); + }); + assert_cost_within_baseline(INVOICE_PAY_BASELINE, cpu, memory); +} + +#[test] +fn bench_invoice_cancel() { + let (cpu, memory) = measure_invoice_stage(|client, signer, token| { + let invoice_id = client.create_invoice(signer, token, &5_000_000u64); + client.cancel_invoice(signer, &invoice_id); + }); + assert_cost_within_baseline(INVOICE_CANCEL_BASELINE, cpu, memory); +} + +#[test] +fn bench_invoice_refund() { + let (cpu, memory) = measure_invoice_stage(|client, signer, token| { + let invoice_id = client.create_invoice(signer, token, &5_000_000u64); + client.pay_invoice(signer, &invoice_id); + client.refund_invoice(signer, &invoice_id); + }); + assert_cost_within_baseline(INVOICE_REFUND_BASELINE, cpu, memory); +} + +#[test] +fn bench_invoice_settle() { + let (cpu, memory) = measure_invoice_stage(|client, signer, token| { + let invoice_id = client.create_invoice(signer, token, &5_000_000u64); + client.pay_invoice(signer, &invoice_id); + client.settle_invoice(signer, &invoice_id); + }); + assert_cost_within_baseline(INVOICE_SETTLE_BASELINE, cpu, memory); +}