1use crate::*;
2
3use serde::{Deserialize, Serialize};
4use std::convert::TryFrom;
5use bucky_crypto::PublicKey;
6use crate::signature::SignatureSource;
7
8#[derive(Clone, Debug, RawEncode, RawDecode)]
9pub enum TxCondition {
10 }
13
14#[derive(Copy, Clone, Debug, Serialize, Deserialize, RawEncode, RawDecode, Eq, PartialEq)]
15pub enum CoinTokenId {
16 Coin(u8),
17 Token(ObjectId),
18}
19
20impl ProtobufTransform<CoinTokenId> for Vec<u8> {
21 fn transform(value: CoinTokenId) -> BuckyResult<Self> {
22 value.to_vec()
23 }
24}
25
26impl ProtobufTransform<&CoinTokenId> for Vec<u8> {
27 fn transform(value: &CoinTokenId) -> BuckyResult<Self> {
28 value.to_vec()
29 }
30}
31
32impl ProtobufTransform<Vec<u8>> for CoinTokenId {
33 fn transform(value: Vec<u8>) -> BuckyResult<Self> {
34 CoinTokenId::clone_from_slice(value.as_slice())
35 }
36}
37
38#[derive(Clone, Debug, RawEncode, RawDecode)]
39pub enum TxCaller {
40 People(PeopleDesc),
41 Device(DeviceDesc),
42 Group(GroupDesc),
43 Union(UnionAccountDesc),
44 Miner(ObjectId),
45 Id(ObjectId),
46}
47
48impl TryFrom<&StandardObject> for TxCaller {
49 type Error = BuckyError;
50 fn try_from(obj: &StandardObject) -> Result<Self, Self::Error> {
51 match obj {
52 StandardObject::People(desc) => Ok(Self::People(desc.desc().clone())),
53 StandardObject::Device(desc) => Ok(Self::Device(desc.desc().clone())),
54 StandardObject::Group(desc) => Ok(Self::Group(desc.desc().clone())),
55 StandardObject::UnionAccount(desc) => Ok(Self::Union(desc.desc().clone())),
56 _ => Err(BuckyError::new(BuckyErrorCode::Failed, "Failed")),
57 }
58 }
59}
60
61impl TxCaller {
62 pub fn id(&self) -> BuckyResult<ObjectId> {
63 let id = match self {
64 Self::People(desc) => desc.calculate_id(),
65 Self::Device(desc) => desc.calculate_id(),
66 Self::Group(desc) => desc.calculate_id(),
67 Self::Union(desc) => desc.calculate_id(),
68 Self::Miner(id) => id.clone(),
69 Self::Id(id) => id.clone(),
70 };
71 Ok(id)
72 }
73
74 pub fn get_public_key(&self) -> BuckyResult<&PublicKey> {
75 match self {
76 Self::People(desc) => Ok(desc.public_key()),
77 Self::Device(desc) => Ok(desc.public_key()),
78 Self::Group(_desc) => Err(BuckyError::new(BuckyErrorCode::Failed, "Failed")),
79 Self::Union(_desc) => Err(BuckyError::new(BuckyErrorCode::Failed, "Failed")),
80 Self::Miner(_) => Err(BuckyError::new(BuckyErrorCode::Failed, "Failed")),
81 Self::Id(id) => {
82 if id.is_default() {
83 Ok(&PublicKey::Invalid)
84 } else {
85 Err(BuckyError::new(BuckyErrorCode::Failed, "Failed"))
86 }
87 },
88 }
89 }
90
91 pub fn is_miner(&self) -> bool {
92 match self {
93 Self::Miner(_) => true,
94 _ => false,
95 }
96 }
97
98 pub fn is_fake(&self) -> bool {
99 match self {
100 Self::Id(id) => {
101 id.is_default()
102 },
103 _ => false
104 }
105 }
106}
107
108#[derive(Clone, Debug, RawEncode, RawDecode)]
109pub struct TxDescContent<T> {
110 pub nonce: i64,
111 pub caller: TxCaller,
112 pub gas_coin_id: u8, pub gas_price: u16, pub max_fee: u32,
115 pub condition: Option<TxCondition>, pub body: T,
117 }
120
121impl<T> DescContent for TxDescContent<T> {
122 fn obj_type() -> u16 {
123 ObjectTypeCode::Tx.into()
124 }
125
126 type OwnerType = SubDescNone;
127 type AreaType = SubDescNone;
128 type AuthorType = SubDescNone;
129 type PublicKeyType = SubDescNone;
130}
131
132#[derive(Clone, Debug)]
133pub struct TxBodyContent {
134 pub data: Vec<u8>,
135}
136
137impl BodyContent for TxBodyContent {
138 fn format(&self) -> u8 {
139 OBJECT_CONTENT_CODEC_FORMAT_PROTOBUF
140 }
141}
142
143impl TxBodyContent {
144 pub fn new(data: Vec<u8>) -> Self {
145 Self { data }
146 }
147}
148
149impl TryFrom<protos::TxBodyContent> for TxBodyContent {
151 type Error = BuckyError;
152
153 fn try_from(mut value: protos::TxBodyContent) -> BuckyResult<Self> {
154 Ok(Self {
155 data: value.take_data(),
156 })
157 }
158}
159
160impl TryFrom<&TxBodyContent> for protos::TxBodyContent {
161 type Error = BuckyError;
162
163 fn try_from(value: &TxBodyContent) -> BuckyResult<Self> {
164 let mut ret = Self::new();
165
166 ret.set_data(value.data.to_owned());
167
168 Ok(ret)
169 }
170}
171
172crate::inner_impl_default_protobuf_raw_codec!(TxBodyContent);
173
174#[derive(Clone, Debug, RawEncode, RawDecode)]
175pub struct TxBody {
176 body: Vec<u8>,
177}
178
179pub type TxDesc = NamedObjectDesc<TxDescContent<TxBody>>;
180pub type TxType = NamedObjType<TxDescContent<TxBody>, TxBodyContent>;
181pub type TxId = NamedObjectId<TxType>;
182pub type Tx = NamedObjectBase<TxType>;
183pub type TxBuilder = NamedObjectBuilder<TxDescContent<TxBody>, TxBodyContent>;
184
185impl NamedObjectDesc<TxDescContent<Vec<u8>>> {
186 pub fn tx_id(&self) -> TxId {
187 TxId::try_from(self.calculate_id()).unwrap()
188 }
189}
190
191impl NamedObjectBase<TxType> {
197 pub fn new(
198 nonce: i64,
199 caller: TxCaller,
200 gas_coin_id: u8,
201 gas_price: u16,
202 max_fee: u32,
203 condition: Option<TxCondition>,
204 body: Vec<u8>,
205 data: Vec<u8>,
206 ) -> TxBuilder {
207 let desc_content = TxDescContent {
208 nonce,
209 caller,
210 gas_coin_id,
211 gas_price,
212 max_fee,
213 condition,
214 body: TxBody { body },
215 };
216
217 let body_content = TxBodyContent { data };
218
219 TxBuilder::new(desc_content, body_content)
220 }
221
222 pub fn verify_signature(&self, public_key: PublicKey) -> BuckyResult<bool> {
223 if self.desc().content().caller.is_miner() {
224 return Ok(true);
225 }
226 let desc_signs = self.signs().desc_signs();
227 if desc_signs.is_none() {
228 return Ok(false);
229 }
230
231 let signs = desc_signs.as_ref().unwrap();
232 if signs.len() == 0 {
233 return Ok(false);
234 }
235
236 let sign = signs.get(0).unwrap();
237 let verifier = RsaCPUObjectVerifier::new(public_key);
238
239 async_std::task::block_on(verify_object_desc_sign(&verifier, self, sign))
240 }
241
242 pub async fn async_verify_signature(&self, public_key: PublicKey) -> BuckyResult<bool> {
243 if self.desc().content().caller.is_miner() {
244 return Ok(true);
245 }
246 let desc_signs = self.signs().desc_signs();
247 if desc_signs.is_none() {
248 return Ok(false);
249 }
250
251 let signs = desc_signs.as_ref().unwrap();
252 if signs.len() == 0 {
253 return Ok(false);
254 }
255
256 let sign = signs.get(0).unwrap();
257 let verifier = RsaCPUObjectVerifier::new(public_key);
258 verify_object_desc_sign(&verifier, self, sign).await
259 }
260
261 pub fn sign(&mut self, secret: &PrivateKey) -> BuckyResult<()> {
262 let signer = RsaCPUObjectSigner::new(secret.public(), secret.clone());
263 async_std::task::block_on(sign_and_set_named_object(
264 &signer,
265 self,
266 &SignatureSource::RefIndex(0),
267 ))
268 }
269}