1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#![allow(unused_variables)]
#![cfg_attr(not(feature = "std"), no_std)]
use frame_system as system;
use frame_support::{decl_module, decl_storage, decl_event, decl_error,
dispatch::DispatchResult};
use sp_runtime::traits::Hash;
use sp_std::prelude::*;
use artemis_core::{AppId, Message, Verifier, VerificationInput};
#[cfg(test)]
mod mock;
#[cfg(test)]
mod tests;
pub trait Trait: system::Trait {
type Event: From<Event> + Into<<Self as system::Trait>::Event>;
}
decl_storage! {
trait Store for Module<T: Trait> as VerifierModule {
RelayKey get(fn key) config(): T::AccountId;
pub VerifiedPayloads: map hasher(blake2_128_concat) T::Hash => ();
}
}
decl_event!(
pub enum Event {
}
);
decl_error! {
pub enum Error for Module<T: Trait> {
NotSupported,
Invalid
}
}
decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
type Error = Error<T>;
fn deposit_event() = default;
}
}
impl<T: Trait> Module<T> {
fn do_verify(sender: T::AccountId, app_id: AppId, message: &Message) -> DispatchResult {
Self::verify_sender(sender)?;
let (block_no, event_idx) = match message.verification {
VerificationInput::Basic { block_number, event_index } => (block_number, event_index),
VerificationInput::None => return Err(Error::<T>::NotSupported.into())
};
let key_input = (app_id, message.payload.clone(), block_no, event_idx);
let key = T::Hashing::hash_of(&key_input);
if <VerifiedPayloads<T>>::contains_key(key) {
return Err(Error::<T>::Invalid.into())
} else {
<VerifiedPayloads<T>>::insert(key, ());
}
Ok(())
}
fn verify_sender(sender: T::AccountId) -> DispatchResult {
if sender != RelayKey::<T>::get() {
return Err(Error::<T>::Invalid.into())
}
Ok(())
}
}
impl<T: Trait> Verifier<T::AccountId> for Module<T> {
fn verify(sender: T::AccountId, app_id: AppId, message: &Message) -> DispatchResult {
Self::do_verify(sender, app_id, message)?;
Ok(())
}
}