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
		authorization_list: Vec::new(),
38
2
	}
39
2
}
40

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

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

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

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

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

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

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

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

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