1
// Copyright (C) Moondance Labs Ltd.
2
// This file is part of Tanssi.
3

            
4
// Tanssi is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8

            
9
// Tanssi is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13

            
14
// You should have received a copy of the GNU General Public License
15
// along with Tanssi.  If not, see <http://www.gnu.org/licenses/>
16

            
17
//! Data structures used to store a ContainerChain ChainSpec in the registrar pallet
18

            
19
#![cfg_attr(not(feature = "std"), no_std)]
20

            
21
use frame_support::{CloneNoBound, DebugNoBound, DefaultNoBound, EqNoBound, PartialEqNoBound};
22

            
23
use {
24
    frame_support::BoundedVec,
25
    parity_scale_codec::{Decode, Encode},
26
    sp_std::vec::Vec,
27
};
28

            
29
#[cfg(feature = "json")]
30
pub mod json;
31

            
32
// TODO: improve serialization of storage field
33
// Currently it looks like this:
34
/*
35
"storage": [
36
    {
37
      "key": "0x0d715f2646c8f85767b5d2764bb2782604a74d81251e398fd8a0a4d55023bb3f"
38
      "value": "0xd1070000"
39
    },
40
    {
41
      "key": "0x0d715f2646c8f85767b5d2764bb278264e7b9012096b41c4eb3aaf947f6ea429"
42
      "value": "0x0000"
43
    }
44
]
45
 */
46
// Ideally it would be:
47
/*
48
"storage": {
49
    "0x0d715f2646c8f85767b5d2764bb2782604a74d81251e398fd8a0a4d55023bb3f": "0xd1070000",
50
    "0x0d715f2646c8f85767b5d2764bb278264e7b9012096b41c4eb3aaf947f6ea429": "0x0000"
51
}
52
 */
53
// This is just so it looks nicer on polkadot.js, the functionality is the same
54
// The original approach of using `storage: BTreeMap<Vec<u8>, Vec<u8>>` looks very bad
55
// in polkadot.js, because `Vec<u8>` is serialized as `[12, 51, 124]` instead of hex.
56
// That's why we use `serde(with = "sp_core::bytes")` everywhere, to convert it to hex.
57
#[derive(
58
    DebugNoBound,
59
    CloneNoBound,
60
    EqNoBound,
61
    DefaultNoBound,
62
    PartialEqNoBound,
63
    Encode,
64
    Decode,
65
    scale_info::TypeInfo,
66
    serde::Deserialize,
67
    serde::Serialize,
68
)]
69
#[serde(bound = "")]
70
pub struct ContainerChainGenesisData {
71
    pub storage: Vec<ContainerChainGenesisDataItem>,
72
    // TODO: make all these Vec<u8> bounded
73
    #[serde(with = "sp_core::bytes")]
74
    pub name: Vec<u8>,
75
    #[serde(with = "sp_core::bytes")]
76
    pub id: Vec<u8>,
77
    pub fork_id: Option<Vec<u8>>,
78
    #[serde(with = "sp_core::bytes")]
79
    pub extensions: Vec<u8>,
80
    pub properties: Properties,
81
}
82

            
83
#[derive(
84
    DebugNoBound,
85
    CloneNoBound,
86
    EqNoBound,
87
    DefaultNoBound,
88
    PartialEqNoBound,
89
    Encode,
90
    Decode,
91
    scale_info::TypeInfo,
92
    serde::Deserialize,
93
    serde::Serialize,
94
)]
95
#[serde(bound = "")]
96
pub struct Properties {
97
    pub token_metadata: TokenMetadata,
98
    pub is_ethereum: bool,
99
}
100

            
101
#[derive(
102
    DebugNoBound,
103
    CloneNoBound,
104
    EqNoBound,
105
    PartialEqNoBound,
106
    Encode,
107
    Decode,
108
    scale_info::TypeInfo,
109
    serde::Deserialize,
110
    serde::Serialize,
111
)]
112
#[serde(bound = "")]
113
pub struct TokenMetadata {
114
    pub token_symbol: BoundedVec<u8, sp_core::ConstU32<255>>,
115
    pub ss58_format: u32,
116
    pub token_decimals: u32,
117
}
118

            
119
impl Default for TokenMetadata {
120
    fn default() -> Self {
121
        // Default values from polkadot.js
122
        Self {
123
            token_symbol: BoundedVec::truncate_from(b"UNIT".to_vec()),
124
            ss58_format: 42,
125
            token_decimals: 12,
126
        }
127
    }
128
}
129

            
130
#[derive(
131
    Debug,
132
    Clone,
133
    Eq,
134
    PartialEq,
135
    Ord,
136
    PartialOrd,
137
    Encode,
138
    Decode,
139
    scale_info::TypeInfo,
140
    serde::Deserialize,
141
    serde::Serialize,
142
)]
143
pub struct ContainerChainGenesisDataItem {
144
    #[serde(with = "sp_core::bytes")]
145
    pub key: Vec<u8>,
146
    #[serde(with = "sp_core::bytes")]
147
    pub value: Vec<u8>,
148
}
149

            
150
impl From<(Vec<u8>, Vec<u8>)> for ContainerChainGenesisDataItem {
151
    fn from(x: (Vec<u8>, Vec<u8>)) -> Self {
152
        Self {
153
            key: x.0,
154
            value: x.1,
155
        }
156
    }
157
}
158

            
159
impl From<ContainerChainGenesisDataItem> for (Vec<u8>, Vec<u8>) {
160
    fn from(x: ContainerChainGenesisDataItem) -> Self {
161
        (x.key, x.value)
162
    }
163
}