use crate::ext::{
Engine,
Error,
};
use secp256k1::{
ecdsa::RecoverableSignature,
Message,
PublicKey,
SecretKey,
SECP256K1,
};
fn get_buffer() -> [u8; 1024] {
[0; 1024]
}
#[test]
fn store_load_clear() {
let mut engine = Engine::new();
engine.set_callee(vec![1; 32]);
let key: &[u8; 32] = &[0x42; 32];
let res = engine.get_storage(key);
assert_eq!(res, Err(Error::KeyNotFound));
engine.set_storage(key, &[0x05_u8; 5]);
let res = engine.get_storage(key);
assert!(res.is_ok());
assert_eq!(res.unwrap()[..5], [0x05; 5]);
engine.clear_storage(key);
let res = engine.get_storage(key);
assert_eq!(res, Err(Error::KeyNotFound));
}
#[test]
fn setting_getting_balance() {
let mut engine = Engine::new();
let account_id = vec![1; 32];
let balance = 1337;
engine.set_callee(account_id.clone());
engine.set_balance(account_id, balance);
let mut output = get_buffer();
engine.balance(&mut &mut output[..]);
let output = <u128 as scale::Decode>::decode(&mut &output[..16])
.unwrap_or_else(|err| panic!("decoding balance failed: {err}"));
assert_eq!(output, balance);
}
#[test]
fn setting_getting_caller() {
let mut engine = Engine::new();
let account_id = vec![1; 32];
engine.set_caller(account_id.clone());
let mut output = get_buffer();
engine.caller(&mut &mut output[..]);
assert_eq!(&output[..account_id.len()], &account_id);
}
#[test]
fn address() {
let mut engine = Engine::new();
let account_id = vec![1; 32];
engine.set_callee(account_id.clone());
let mut output = get_buffer();
engine.address(&mut &mut output[..]);
assert_eq!(&output[..account_id.len()], &account_id);
}
#[test]
fn transfer() {
let mut engine = Engine::new();
let alice = vec![1; 32];
let bob = vec![2; 32];
engine.set_callee(alice.clone());
engine.set_balance(alice.clone(), 1337);
let val = scale::Encode::encode(&337u128);
assert_eq!(engine.transfer(&bob, &val), Ok(()));
assert_eq!(engine.get_balance(alice), Ok(1000));
assert_eq!(engine.get_balance(bob), Ok(337));
}
#[test]
fn debug_messages() {
let mut engine = Engine::new();
engine.debug_message("foobar");
let mut recorded = engine.get_emitted_debug_messages().into_iter();
assert_eq!(recorded.next(), Some("foobar".into()));
assert_eq!(recorded.next(), None);
}
#[test]
fn events() {
let mut engine = Engine::new();
let topics_count: scale::Compact<u32> = scale::Compact(2u32);
let mut enc_topics_count = scale::Encode::encode(&topics_count);
let topic1 = vec![12u8, 13];
let topic2 = vec![14u8, 15];
let data = &vec![21, 22, 23];
let mut enc_topics_info: Vec<u8> = Vec::new();
enc_topics_info.append(&mut enc_topics_count);
enc_topics_info.append(&mut topic1.clone());
enc_topics_info.append(&mut topic2.clone());
engine.deposit_event(&enc_topics_info, data);
let mut events = engine.get_emitted_events();
let event = events.next().expect("event must exist");
assert_eq!(event.topics.len(), 2);
assert_eq!(
event.topics.first().expect("first topic must exist"),
&topic1
);
assert_eq!(
event.topics.get(1).expect("second topic must exist"),
&topic2
);
assert_eq!(&event.data, data);
assert!(events.next().is_none());
}
#[test]
fn value_transferred() {
let mut engine = Engine::new();
let value = 1337;
engine.set_value_transferred(value);
let output = &mut &mut get_buffer()[..];
engine.value_transferred(output);
let output = <u128 as scale::Decode>::decode(&mut &output[..16])
.expect("decoding value transferred failed");
assert_eq!(output, value);
}
#[test]
fn ecdsa_recovery_test_from_contracts_pallet() {
let mut engine = Engine::new();
#[rustfmt::skip]
let signature: [u8; 65] = [
161, 234, 203, 74, 147, 96, 51, 212, 5, 174, 231, 9, 142, 48, 137, 201,
162, 118, 192, 67, 239, 16, 71, 216, 125, 86, 167, 139, 70, 7, 86, 241,
33, 87, 154, 251, 81, 29, 160, 4, 176, 239, 88, 211, 244, 232, 232, 52,
211, 234, 100, 115, 230, 47, 80, 44, 152, 166, 62, 50, 8, 13, 86, 175,
28,
];
#[rustfmt::skip]
let message_hash: [u8; 32] = [
162, 28, 244, 179, 96, 76, 244, 178, 188, 83, 230, 248, 143, 106, 77, 117,
239, 95, 244, 171, 65, 95, 62, 153, 174, 166, 182, 28, 130, 73, 196, 208
];
let mut output = [0; 33];
engine
.ecdsa_recover(&signature, &message_hash, &mut output)
.expect("must work");
#[rustfmt::skip]
const EXPECTED_COMPRESSED_PUBLIC_KEY: [u8; 33] = [
2, 121, 190, 102, 126, 249, 220, 187, 172, 85, 160, 98, 149, 206, 135, 11,
7, 2, 155, 252, 219, 45, 206, 40, 217, 89, 242, 129, 91, 22, 248, 23,
152,
];
assert_eq!(output, EXPECTED_COMPRESSED_PUBLIC_KEY);
}
#[test]
fn ecdsa_recovery_with_secp256k1_crate() {
let mut engine = Engine::new();
let seckey = [
59, 148, 11, 85, 134, 130, 61, 253, 2, 174, 59, 70, 27, 180, 51, 107, 94, 203,
174, 253, 102, 39, 170, 146, 46, 252, 4, 143, 236, 12, 136, 28,
];
let pubkey = PublicKey::from_slice(&[
2, 29, 21, 35, 7, 198, 183, 43, 14, 208, 65, 139, 14, 112, 205, 128, 231, 245,
41, 91, 141, 134, 245, 114, 45, 63, 82, 19, 251, 210, 57, 79, 54,
])
.expect("pubkey creation failed");
let mut msg_hash = [0; 32];
crate::hashing::sha2_256(b"Some message", &mut msg_hash);
let msg = Message::from_digest_slice(&msg_hash).expect("message creation failed");
let seckey = SecretKey::from_slice(&seckey).expect("secret key creation failed");
let recoverable_signature: RecoverableSignature =
SECP256K1.sign_ecdsa_recoverable(&msg, &seckey);
let recovery_id = recoverable_signature.serialize_compact().0.to_i32() as u8;
let mut signature = recoverable_signature.serialize_compact().1.to_vec();
signature.push(recovery_id);
let signature_with_recovery_id: [u8; 65] = signature
.try_into()
.expect("unable to create signature with recovery id");
let mut output = [0; 33];
engine
.ecdsa_recover(&signature_with_recovery_id, msg.as_ref(), &mut output)
.expect("ecdsa recovery failed");
assert_eq!(output, pubkey.serialize());
}
#[test]
fn setting_getting_block_timestamp() {
let mut engine = Engine::new();
let new_block_timestamp: u64 = 1000;
let output = &mut &mut get_buffer()[..];
engine.advance_block();
engine.set_block_timestamp(new_block_timestamp);
engine.block_timestamp(output);
let output = <u64 as scale::Decode>::decode(&mut &output[..16])
.expect("decoding value transferred failed");
assert_eq!(output, new_block_timestamp);
}
#[test]
fn setting_getting_block_number() {
let mut engine = Engine::new();
let new_block_number: u32 = 1000;
let output = &mut &mut get_buffer()[..];
engine.advance_block();
engine.set_block_number(new_block_number);
engine.block_number(output);
let output = <u32 as scale::Decode>::decode(&mut &output[..16])
.expect("decoding value transferred failed");
assert_eq!(output, new_block_number);
}