use neo_vm_core::StackItem;
use neo_vm_guest::{execute, ProofInput};
use neo_zkvm_prover::{NeoProver, ProverConfig};
use neo_zkvm_verifier::verify;
#[test]
fn test_full_prove_verify_cycle() {
let script = vec![
0x12, 0x13, 0x9E, 0x40, ];
let input = ProofInput {
script,
arguments: vec![],
gas_limit: 1_000_000,
};
let prover = NeoProver::new(ProverConfig::default());
let proof = prover.prove(input);
assert_eq!(proof.output.state, 0);
assert!(verify(&proof));
}
#[test]
fn test_complex_arithmetic() {
let script = vec![
0x14, 0x15, 0xA0, 0x12, 0xA1, 0x40, ];
let input = ProofInput {
script,
arguments: vec![],
gas_limit: 1_000_000,
};
let output = execute(input);
assert_eq!(output.state, 0);
assert_eq!(output.result, Some(StackItem::Integer(10)));
}
#[test]
fn test_comparison_operations() {
let script = vec![
0x13, 0x15, 0xB5, 0x40, ];
let input = ProofInput {
script,
arguments: vec![],
gas_limit: 1_000_000,
};
let output = execute(input);
assert_eq!(output.result, Some(StackItem::Boolean(true)));
}
#[test]
fn test_prove_verify_with_arguments() {
let script = vec![
0x57, 0x00, 0x02, 0x74, 0x75, 0x9E, 0x40, ];
let input = ProofInput {
script,
arguments: vec![StackItem::Integer(10), StackItem::Integer(20)],
gas_limit: 1_000_000,
};
let prover = NeoProver::new(ProverConfig::default());
let proof = prover.prove(input);
assert_eq!(proof.output.state, 0);
assert_eq!(proof.output.result, Some(StackItem::Integer(30)));
assert!(verify(&proof));
}
#[test]
fn test_prove_verify_hash_operation() {
let script = vec![
0x0C, 0x05, b'h', b'e', b'l', b'l', b'o', 0xF0, 0x40, ];
let input = ProofInput {
script,
arguments: vec![],
gas_limit: 1_000_000,
};
let prover = NeoProver::new(ProverConfig::default());
let proof = prover.prove(input);
assert_eq!(proof.output.state, 0);
assert!(verify(&proof));
}
#[test]
fn test_prove_verify_array_operations() {
let script = vec![
0x13, 0xC3, 0xCA, 0x40, ];
let input = ProofInput {
script,
arguments: vec![],
gas_limit: 1_000_000,
};
let prover = NeoProver::new(ProverConfig::default());
let proof = prover.prove(input);
assert_eq!(proof.output.state, 0);
assert_eq!(proof.output.result, Some(StackItem::Integer(3)));
assert!(verify(&proof));
}
#[test]
fn test_prove_verify_control_flow() {
let script = vec![
0x15, 0x13, 0xB7, 0x24, 0x03, 0x10, 0x22, 0x02, 0x11, 0x40, ];
let input = ProofInput {
script,
arguments: vec![],
gas_limit: 1_000_000,
};
let prover = NeoProver::new(ProverConfig::default());
let proof = prover.prove(input);
assert_eq!(proof.output.state, 0);
assert!(verify(&proof));
}
#[test]
fn test_execute_faulted_script() {
let script = vec![
0x15, 0x10, 0xA1, 0x40, ];
let input = ProofInput {
script,
arguments: vec![],
gas_limit: 1_000_000,
};
let output = execute(input);
assert_eq!(output.state, 1); }
#[test]
fn test_gas_tracking_in_proof() {
let script = vec![
0x15, 0x13, 0x9E, 0x12, 0xA0, 0x40, ];
let input = ProofInput {
script,
arguments: vec![],
gas_limit: 1_000_000,
};
let prover = NeoProver::new(ProverConfig::default());
let proof = prover.prove(input);
assert!(proof.output.gas_consumed > 0);
assert!(proof.public_inputs.gas_consumed > 0);
}
#[test]
fn test_script_size_limit() {
let script = vec![0x42; 1024 * 1024 + 1]; let input = ProofInput {
script,
arguments: vec![],
gas_limit: 1_000_000,
};
let output = execute(input);
assert_eq!(output.state, 1); }
#[test]
fn test_stack_underflow_handling() {
let script = vec![0x45, 0x40]; let input = ProofInput {
script,
arguments: vec![],
gas_limit: 1_000_000,
};
let output = execute(input);
assert_eq!(output.state, 1); }
#[test]
fn test_division_by_zero() {
let script = vec![0x15, 0x10, 0xA1, 0x40]; let input = ProofInput {
script,
arguments: vec![],
gas_limit: 1_000_000,
};
let output = execute(input);
assert_eq!(output.state, 1); }
#[test]
fn test_gas_exhaustion() {
let script = vec![0x42; 100]; let input = ProofInput {
script,
arguments: vec![],
gas_limit: 10, };
let output = execute(input);
assert_eq!(output.state, 1); }
#[test]
fn test_pushdata_boundary() {
let mut script = vec![0x0C, 0x05]; script.extend_from_slice(b"hello");
script.push(0x40); let input = ProofInput {
script,
arguments: vec![],
gas_limit: 1_000_000,
};
let output = execute(input);
assert_eq!(output.state, 0); }
#[test]
fn test_pushdata_truncated() {
let script = vec![0x0C, 0x0A, 0x42, 0x42, 0x42, 0x42, 0x42]; let input = ProofInput {
script,
arguments: vec![],
gas_limit: 1_000_000,
};
let output = execute(input);
assert_eq!(output.state, 1); }
#[test]
fn test_loop_detection_by_gas() {
let script = vec![0x22, 0xFE]; let input = ProofInput {
script,
arguments: vec![],
gas_limit: 100,
};
let output = execute(input);
assert!(output.state == 0 || output.state == 1);
assert!(output.gas_consumed > 0);
}
#[test]
fn test_control_flow_jump_valid() {
let script = vec![
0x21, 0x40, ];
let input = ProofInput {
script,
arguments: vec![],
gas_limit: 1_000_000,
};
let output = execute(input);
assert_eq!(output.state, 0);
}
#[test]
fn test_control_flow_abort() {
let script = vec![
0x15, 0x38, 0x40, ];
let input = ProofInput {
script,
arguments: vec![],
gas_limit: 1_000_000,
};
let output = execute(input);
assert_eq!(output.state, 1); }
#[test]
fn test_control_flow_assert() {
let script = vec![
0x10, 0x39, 0x40, ];
let input = ProofInput {
script,
arguments: vec![],
gas_limit: 1_000_000,
};
let output = execute(input);
assert_eq!(output.state, 1); }
#[test]
fn test_control_flow_jump_backward() {
let script = vec![
0x12, 0x4A, 0x26, 0x05, 0x9D, 0x22, 0xFC, 0x40, ];
let input = ProofInput {
script,
arguments: vec![],
gas_limit: 1_000_000,
};
let output = execute(input);
assert_eq!(output.state, 0);
}
#[test]
fn test_bitwise_operations() {
let script = vec![
0x14, 0x13, 0x91, 0x40, ];
let input = ProofInput {
script,
arguments: vec![],
gas_limit: 1_000_000,
};
let output = execute(input);
assert_eq!(output.state, 0);
assert_eq!(output.result, Some(StackItem::Integer(0)));
}
#[test]
fn test_shift_operations() {
let script = vec![
0x12, 0x11, 0xA8, 0x40, ];
let input = ProofInput {
script,
arguments: vec![],
gas_limit: 1_000_000,
};
let output = execute(input);
assert_eq!(output.state, 0);
assert_eq!(output.result, Some(StackItem::Integer(4)));
}
#[test]
fn test_modulo_operations() {
let script = vec![
0x17, 0x13, 0xA2, 0x40, ];
let input = ProofInput {
script,
arguments: vec![],
gas_limit: 1_000_000,
};
let output = execute(input);
assert_eq!(output.state, 0);
assert_eq!(output.result, Some(StackItem::Integer(1)));
}
#[test]
fn test_power_operations() {
let script = vec![
0x12, 0x11, 0xA3, 0x40, ];
let input = ProofInput {
script,
arguments: vec![],
gas_limit: 1_000_000,
};
let output = execute(input);
assert_eq!(output.state, 0);
assert_eq!(output.result, Some(StackItem::Integer(2)));
}
#[test]
fn test_min_max_operations() {
let script = vec![
0x0F, 0x11, 0xB9, 0x40, ];
let input = ProofInput {
script,
arguments: vec![],
gas_limit: 1_000_000,
};
let output = execute(input);
assert_eq!(output.state, 0);
assert_eq!(output.result, Some(StackItem::Integer(-1)));
}
#[test]
fn test_within_range_check() {
let script = vec![
0x15, 0x10, 0x17, 0xBB, 0x40, ];
let input = ProofInput {
script,
arguments: vec![],
gas_limit: 1_000_000,
};
let output = execute(input);
assert_eq!(output.state, 0);
assert_eq!(output.result, Some(StackItem::Boolean(true)));
}
#[test]
fn test_native_stdlib_serialize() {
}
#[test]
fn test_native_crypto_sha256() {
let script = vec![
0x0C, 0x04, b't', b'e', b's', b't', 0xF0, 0xCA, 0x40, ];
let input = ProofInput {
script,
arguments: vec![],
gas_limit: 1_000_000,
};
let output = execute(input);
assert_eq!(output.state, 0);
assert_eq!(output.result, Some(StackItem::Integer(32))); }
#[test]
fn test_native_crypto_ripemd160() {
let script = vec![
0x0C, 0x03, b'a', b'b', b'c', 0xF1, 0x40, ];
let input = ProofInput {
script,
arguments: vec![],
gas_limit: 1_000_000,
};
let output = execute(input);
assert_eq!(output.state, 0);
if let Some(StackItem::ByteString(hash)) = &output.result {
assert_eq!(hash.len(), 20); } else {
panic!("Expected ByteString result");
}
}