1
// Copyright 2019-2025 PureStake Inc.
2
// This file is part of Moonbeam.
3

            
4
// Moonbeam is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8

            
9
// Moonbeam is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13

            
14
// You should have received a copy of the GNU General Public License
15
// along with Moonbeam.  If not, see <http://www.gnu.org/licenses/>.
16
use crate::mock::*;
17
use crate::*;
18
use precompile_utils::testing::*;
19

            
20
use frame_support::assert_ok;
21
use pallet_evm::{Call as EvmCall, Event as EvmEvent};
22

            
23
use sp_core::{Hasher, U256};
24
use sp_runtime::traits::Dispatchable;
25

            
26
2
fn evm_call(input: Vec<u8>) -> EvmCall<Runtime> {
27
2
	EvmCall::call {
28
2
		source: Alice.into(),
29
2
		target: Precompile1.into(),
30
2
		input,
31
2
		value: U256::zero(),
32
2
		gas_limit: u64::max_value(),
33
2
		max_fee_per_gas: 0.into(),
34
2
		max_priority_fee_per_gas: Some(U256::zero()),
35
2
		nonce: None,
36
2
		access_list: Vec::new(),
37
2
	}
38
2
}
39

            
40
1
fn precompiles() -> Precompiles<Runtime> {
41
1
	PrecompilesValue::get()
42
1
}
43

            
44
#[test]
45
1
fn test_solidity_interface_has_all_function_selectors_documented_and_implemented() {
46
1
	check_precompile_implements_solidity_interfaces(&["Preimage.sol"], PCall::supports_selector)
47
1
}
48

            
49
#[test]
50
1
fn note_unnote_preimage_logs_work() {
51
1
	ExtBuilder::default()
52
1
		.with_balances(vec![(Alice.into(), 100_000)])
53
1
		.build()
54
1
		.execute_with(|| {
55
1
			let bytes = vec![1, 2, 3];
56
1
			let expected_hash = sp_runtime::traits::BlakeTwo256::hash(&bytes);
57
1

            
58
1
			// Note preimage
59
1
			let input = PCall::note_preimage {
60
1
				encoded_proposal: bytes.into(),
61
1
			}
62
1
			.into();
63
1
			assert_ok!(RuntimeCall::Evm(evm_call(input)).dispatch(RuntimeOrigin::root()));
64

            
65
			// Assert note preimage event is emited and matching frame event preimage hash.
66
1
			assert!(vec![
67
1
				EvmEvent::Log {
68
1
					log: log1(
69
1
						Precompile1,
70
1
						SELECTOR_LOG_PREIMAGE_NOTED,
71
1
						solidity::encode_event_data(expected_hash)
72
1
					),
73
1
				}
74
1
				.into(),
75
1
				RuntimeEvent::Preimage(pallet_preimage::pallet::Event::Noted {
76
1
					hash: expected_hash
77
1
				})
78
1
			]
79
1
			.iter()
80
2
			.all(|log| events().contains(log)));
81

            
82
			// Unnote preimage
83
1
			let input = PCall::unnote_preimage {
84
1
				hash: expected_hash,
85
1
			}
86
1
			.into();
87
1
			assert_ok!(RuntimeCall::Evm(evm_call(input)).dispatch(RuntimeOrigin::root()));
88

            
89
			// Assert unnote preimage is emited
90
1
			assert!(events().contains(
91
1
				&EvmEvent::Log {
92
1
					log: log1(
93
1
						Precompile1,
94
1
						SELECTOR_LOG_PREIMAGE_UNNOTED,
95
1
						solidity::encode_event_data(expected_hash)
96
1
					),
97
1
				}
98
1
				.into()
99
1
			));
100
1
		})
101
1
}
102

            
103
#[test]
104
1
fn note_preimage_returns_preimage_hash() {
105
1
	ExtBuilder::default()
106
1
		.with_balances(vec![(Alice.into(), 40)])
107
1
		.build()
108
1
		.execute_with(|| {
109
1
			let preimage = [1u8; 32];
110
1
			let preimage_hash = <mock::Runtime as frame_system::Config>::Hashing::hash(&preimage);
111
1

            
112
1
			precompiles()
113
1
				.prepare_test(
114
1
					Alice,
115
1
					Precompile1,
116
1
					PCall::note_preimage {
117
1
						encoded_proposal: BoundedBytes::from(preimage),
118
1
					},
119
1
				)
120
1
				.execute_returns(preimage_hash);
121
1
		})
122
1
}