cfx_rpc_eth_types/
authorization.rs

1use 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    /// The chain ID of the authorization.
11    pub chain_id: U256,
12    /// The address of the authorization.
13    pub address: Address,
14    /// The nonce for the authorization.
15    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    /// Inner authorization.
24    #[serde(flatten)]
25    inner: Authorization,
26    /// Signature parity value. Must be `0` or `1`.
27    #[serde(deserialize_with = "parse_and_validate_y_parity")]
28    pub y_parity: U64,
29    /// Signature `r` value.
30    pub r: U256,
31    /// Signature `s` value.
32    pub s: U256,
33}
34
35impl SignedAuthorization {
36    /// Returns the inner authorization.
37    pub const fn inner(&self) -> &Authorization { &self.inner }
38
39    /// Returns the signature parity value.
40    pub fn y_parity(&self) -> u8 { self.y_parity.as_u32() as u8 }
41
42    /// Returns the signature `r` value.
43    pub const fn r(&self) -> U256 { self.r }
44
45    /// Returns the signature `s` value.
46    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}