cfx_parity_trace_types/
address_pocket.rs1use cfx_types::{Address, AddressSpaceUtil, AddressWithSpace, Space};
2use rlp::{Decodable, DecoderError, Encodable, Rlp, RlpStream};
3
4#[derive(Debug, Clone, Copy, PartialEq)]
5pub enum AddressPocket {
6 Balance(AddressWithSpace),
7 StakingBalance(Address),
8 StorageCollateral(Address),
9 SponsorBalanceForGas(Address),
10 SponsorBalanceForStorage(Address),
11 MintBurn,
12 GasPayment,
13}
14
15impl AddressPocket {
16 pub fn inner_address(&self) -> Option<&Address> {
17 use AddressPocket::*;
18 match self {
19 Balance(AddressWithSpace { address: addr, .. })
20 | StakingBalance(addr)
21 | StorageCollateral(addr)
22 | SponsorBalanceForGas(addr)
23 | SponsorBalanceForStorage(addr) => Some(addr),
24 MintBurn | GasPayment => None,
25 }
26 }
27
28 pub fn inner_address_or_default(&self) -> Address {
29 self.inner_address().cloned().unwrap_or(Address::zero())
30 }
31
32 pub fn pocket(&self) -> &'static str {
33 use AddressPocket::*;
34 match self {
35 Balance(_) => "balance",
36 StakingBalance(_) => "staking_balance",
37 StorageCollateral(_) => "storage_collateral",
38 SponsorBalanceForGas(_) => "sponsor_balance_for_gas",
39 SponsorBalanceForStorage(_) => "sponsor_balance_for_collateral",
40 MintBurn => "mint_or_burn",
41 GasPayment => "gas_payment",
42 }
43 }
44
45 pub fn space(&self) -> &'static str {
46 use AddressPocket::*;
47 match self {
48 Balance(AddressWithSpace { space, .. }) => space.clone().into(),
49 MintBurn | GasPayment => "none",
50 _ => Space::Native.into(),
51 }
52 }
53
54 fn type_number(&self) -> u8 {
55 use AddressPocket::*;
56 match self {
57 Balance(AddressWithSpace {
58 space: Space::Native,
59 ..
60 }) => 0,
61 StakingBalance(_) => 1,
62 StorageCollateral(_) => 2,
63 SponsorBalanceForGas(_) => 3,
64 SponsorBalanceForStorage(_) => 4,
65 MintBurn => 5,
66 GasPayment => 6,
67 Balance(AddressWithSpace {
68 space: Space::Ethereum,
69 ..
70 }) => 7,
71 }
72 }
73}
74
75impl Encodable for AddressPocket {
76 fn rlp_append(&self, s: &mut RlpStream) {
77 let maybe_address = self.inner_address();
78 let type_number = self.type_number();
79 if let Some(address) = maybe_address {
80 s.begin_list(2);
81 s.append(&type_number);
82 s.append(address);
83 } else {
84 s.begin_list(1);
85 s.append(&type_number);
86 }
87 }
88}
89
90impl Decodable for AddressPocket {
91 fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
92 use AddressPocket::*;
93
94 let type_number: u8 = rlp.val_at(0)?;
95 match type_number {
96 0 => rlp
97 .val_at(1)
98 .map(|addr: Address| Balance(addr.with_native_space())),
99 1 => rlp.val_at(1).map(StakingBalance),
100 2 => rlp.val_at(1).map(StorageCollateral),
101 3 => rlp.val_at(1).map(SponsorBalanceForGas),
102 4 => rlp.val_at(1).map(SponsorBalanceForStorage),
103 5 => Ok(MintBurn),
104 6 => Ok(GasPayment),
105 7 => rlp
106 .val_at(1)
107 .map(|addr: Address| Balance(addr.with_evm_space())),
108 _ => {
109 Err(DecoderError::Custom("Invalid internal transfer address."))
110 }
111 }
112 }
113}