cfx_rpc_eth_types/
authorization.rs1use cfx_types::{Address, U256, U64};
2use primitives::transaction::AuthorizationListItem;
3use serde::{Deserialize, Deserializer};
4
5#[derive(
6 Debug, Default, PartialEq, Eq, serde::Deserialize, serde::Serialize, Clone,
7)]
8#[serde(rename_all = "camelCase")]
9pub struct Authorization {
10 pub chain_id: U256,
12 pub address: Address,
14 pub nonce: U64,
16}
17
18#[derive(
19 Debug, Default, PartialEq, Eq, serde::Deserialize, serde::Serialize, Clone,
20)]
21#[serde(rename_all = "camelCase")]
22pub struct SignedAuthorization {
23 #[serde(flatten)]
25 inner: Authorization,
26 #[serde(deserialize_with = "parse_and_validate_y_parity")]
28 pub y_parity: U64,
29 pub r: U256,
31 pub s: U256,
33}
34
35impl SignedAuthorization {
36 pub const fn inner(&self) -> &Authorization { &self.inner }
38
39 pub fn y_parity(&self) -> u8 { self.y_parity.as_u32() as u8 }
41
42 pub const fn r(&self) -> U256 { self.r }
44
45 pub const fn s(&self) -> U256 { self.s }
47}
48
49impl From<AuthorizationListItem> for SignedAuthorization {
50 fn from(item: AuthorizationListItem) -> Self {
51 Self {
52 inner: Authorization {
53 chain_id: item.chain_id.into(),
54 address: item.address.into(),
55 nonce: item.nonce.into(),
56 },
57 y_parity: item.y_parity.into(),
58 r: item.r,
59 s: item.s,
60 }
61 }
62}
63
64fn parse_and_validate_y_parity<'de, D>(
65 deserializer: D,
66) -> Result<U64, D::Error>
67where D: Deserializer<'de> {
68 let v = U64::deserialize(deserializer)?;
69 if v.as_u64() > 1 {
70 return Err(serde::de::Error::custom(format!(
71 "invalid yParity: expected 0 or 1, got {}",
72 v
73 )));
74 }
75 Ok(v)
76}
77
78impl Into<AuthorizationListItem> for SignedAuthorization {
79 fn into(self) -> AuthorizationListItem {
80 AuthorizationListItem {
81 chain_id: self.inner.chain_id,
82 address: self.inner.address,
83 nonce: self.inner.nonce.as_u64(),
84 y_parity: self.y_parity(),
85 r: self.r,
86 s: self.s,
87 }
88 }
89}