forked from bluealloy/revm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patheip7702.rs
106 lines (90 loc) · 3.19 KB
/
eip7702.rs
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
pub use alloy_eip7702::{Authorization, SignedAuthorization};
pub use alloy_primitives::Signature;
use crate::Address;
use core::ops::Deref;
use std::{boxed::Box, vec::Vec};
/// Authorization list for EIP-7702 transaction type.
#[derive(Clone, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum AuthorizationList {
Signed(Vec<SignedAuthorization>),
Recovered(Vec<RecoveredAuthorization>),
}
impl From<Vec<SignedAuthorization>> for AuthorizationList {
fn from(signed: Vec<SignedAuthorization>) -> Self {
Self::Signed(signed)
}
}
impl From<Vec<RecoveredAuthorization>> for AuthorizationList {
fn from(recovered: Vec<RecoveredAuthorization>) -> Self {
Self::Recovered(recovered)
}
}
impl AuthorizationList {
/// Returns length of the authorization list.
pub fn len(&self) -> usize {
match self {
Self::Signed(signed) => signed.len(),
Self::Recovered(recovered) => recovered.len(),
}
}
/// Return empty authorization list.
pub fn empty() -> Self {
Self::Recovered(Vec::new())
}
/// Returns true if the authorization list is empty.
pub fn is_empty(&self) -> bool {
self.len() == 0
}
/// Returns iterator of recovered Authorizations.
pub fn recovered_iter<'a>(&'a self) -> Box<dyn Iterator<Item = RecoveredAuthorization> + 'a> {
match self {
Self::Signed(signed) => Box::new(signed.iter().map(|signed| signed.clone().into())),
Self::Recovered(recovered) => Box::new(recovered.clone().into_iter()),
}
}
/// Returns recovered authorizations list.
pub fn into_recovered(self) -> Self {
let Self::Signed(signed) = self else {
return self;
};
Self::Recovered(signed.into_iter().map(|signed| signed.into()).collect())
}
}
/// A recovered authorization.
#[derive(Debug, Clone, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct RecoveredAuthorization {
#[cfg_attr(feature = "serde", serde(flatten))]
inner: Authorization,
authority: Option<Address>,
}
impl RecoveredAuthorization {
/// Instantiate without performing recovery. This should be used carefully.
pub const fn new_unchecked(inner: Authorization, authority: Option<Address>) -> Self {
Self { inner, authority }
}
/// Get the `authority` for the authorization.
///
/// If this is `None`, then the authority could not be recovered.
pub const fn authority(&self) -> Option<Address> {
self.authority
}
/// Splits the authorization into parts.
pub const fn into_parts(self) -> (Authorization, Option<Address>) {
(self.inner, self.authority)
}
}
impl From<SignedAuthorization> for RecoveredAuthorization {
fn from(signed_auth: SignedAuthorization) -> Self {
let authority = signed_auth.recover_authority().ok();
let (authorization, _) = signed_auth.into_parts();
Self::new_unchecked(authorization, authority)
}
}
impl Deref for RecoveredAuthorization {
type Target = Authorization;
fn deref(&self) -> &Self::Target {
&self.inner
}
}