cyfs_base_meta/
block.rs

1use sha2::{Digest, Sha256};
2// use merkletree::merkle::{MerkleTree};
3use crate::*;
4use async_trait::async_trait;
5use cyfs_base::*;
6use cyfs_core::CoreObjectType;
7
8pub type TxHash = ObjectId;
9pub type StateHash = HashValue;
10
11pub type BlockHash = ObjectId;
12
13type ReceiptHash = HashValue;
14type TransactionHash = HashValue;
15
16pub trait BlockDescTrait {
17    fn hash(&self) -> BlockHash;
18    fn hash_str(&self) -> String;
19    fn pre_block_hash(&self) -> &BlockHash;
20    fn pre_block_hash_str(&self) -> String;
21    fn number(&self) -> i64;
22    fn coinbase(&self) -> &ObjectId;
23    fn is_pre_block_of(&self, other: &Self) -> bool;
24    fn state_hash(&self) -> &HashValue;
25    fn transactions_hash(&self) -> &HashValue;
26    fn receipts_hash(&self) -> &HashValue;
27    fn event_records_hash(&self) -> &HashValue;
28}
29
30pub trait BlockBodyTrait {
31    type Receipt;
32    fn transactions(&self) -> &Vec<MetaTx>;
33    fn receipts(&self) -> Vec<Self::Receipt>;
34    // return index
35    fn add_transaction(&mut self, tx: MetaTx) -> Result<usize, u32>;
36    fn add_receipts(&mut self, receipts: Vec<Self::Receipt>) -> Result<(), u32>;
37    fn add_event_record(&mut self, event_record: EventRecord);
38    fn set_event_records(&mut self, event_records: Vec<EventRecord>);
39    fn event_records(&self) -> &Vec<EventRecord>;
40}
41
42#[async_trait]
43pub trait BlockTrait {
44    type BlockDesc;
45    type BlockBody;
46    type BlockBuilder;
47    type Receipt;
48    fn new(
49        coinbase: ObjectId,
50        pre_block: Option<&Self::BlockDesc>,
51        state_hash: StateHash,
52        body: Self::BlockBody,
53    ) -> BuckyResult<Self::BlockBuilder>;
54    fn new2(
55        src_desc: &Self::BlockDesc,
56        state_hash: StateHash,
57        body: Self::BlockBody,
58    ) -> BuckyResult<Self::BlockBuilder>;
59    fn header(&self) -> &Self::BlockDesc;
60    fn transactions(&self) -> &Vec<MetaTx>;
61    fn receipts(&self) -> Vec<Self::Receipt>;
62    fn event_records(&self) -> &Vec<EventRecord>;
63    async fn sign(
64        &mut self,
65        private_key: PrivateKey,
66        sign_source: &SignatureSource,
67    ) -> BuckyResult<Signature>;
68    fn version(&self) -> u64;
69}
70
71// pub type BlockDesc = BlockDescV2;
72// pub type BlockType = BlockTypeV2;
73// pub type BlockId = BlockIdV2;
74// pub type Block = BlockV2;
75// pub type BlockBuilder = BlockBuilderV2;
76// pub type BlockDescContent = BlockDescContentV2;
77// pub type BlockBody = BlockBodyV2;
78
79type TxList = Vec<MetaTx>;
80type ReceiptList = Vec<Receipt>;
81type EventRecordList = Vec<EventRecord>;
82
83// type MerkleHash = GenericArray<u8, <Sha256 as Digest>::OutputSize>;
84
85#[derive(Clone, RawEncode, RawDecode)]
86pub struct BlockDescContentV1 {
87    pub number: i64,
88    pub coinbase: ObjectId,
89    pub state_hash: StateHash,
90    pub pre_block_hash: BlockHash,
91    //tx_merkle_root: MerkleHash,
92    pub transactions_hash: TransactionHash,
93    pub receipts_hash: ReceiptHash,
94    // pub event_records_hash: HashValue,
95}
96
97impl BlockDescContentV1 {
98    pub fn new(coinbase: ObjectId, pre_block: Option<&BlockDescV1>) -> Self {
99        let mut desc_content = BlockDescContentV1 {
100            number: 0,
101            coinbase,
102            state_hash: HashValue::default(),
103            pre_block_hash: BlockHash::default(),
104            transactions_hash: HashValue::default(),
105            receipts_hash: HashValue::default(),
106            // event_records_hash: HashValue::default()
107        };
108
109        if let Some(pre_header) = pre_block {
110            desc_content.number = pre_header.number() + 1;
111            desc_content.pre_block_hash = pre_header.calculate_id();
112        }
113
114        desc_content
115    }
116}
117
118impl DescContent for BlockDescContentV1 {
119    fn obj_type() -> u16 {
120        CoreObjectType::BlockV1 as u16
121    }
122
123    type OwnerType = SubDescNone;
124    type AreaType = SubDescNone;
125    type AuthorType = SubDescNone;
126    type PublicKeyType = SubDescNone;
127}
128
129#[derive(Clone, RawEncode, RawDecode)]
130pub struct BlockBodyV1 {
131    pub transactions: TxList,
132    pub receipts: Vec<ReceiptV1>,
133    // pub event_records: EventRecordList,
134}
135
136impl BodyContent for BlockBodyV1 {}
137
138impl BlockBodyV1 {
139    pub fn new() -> Self {
140        BlockBodyV1 {
141            transactions: vec![],
142            receipts: vec![],
143        }
144    }
145}
146
147impl BlockBodyTrait for BlockBodyV1 {
148    type Receipt = ReceiptV1;
149    fn transactions(&self) -> &Vec<MetaTx> {
150        &self.transactions
151    }
152
153    fn receipts(&self) -> Vec<Self::Receipt> {
154        self.receipts.clone()
155    }
156    // return index
157    fn add_transaction(&mut self, tx: MetaTx) -> Result<usize, u32> {
158        self.transactions.push(tx);
159        Ok(self.transactions.len() - 1)
160    }
161
162    fn add_receipts(&mut self, receipts: Vec<Self::Receipt>) -> Result<(), u32> {
163        for receipt in receipts {
164            self.receipts.push(receipt);
165        }
166        Ok(())
167    }
168
169    fn add_event_record(&mut self, _event_record: EventRecord) {
170        // self.event_records.push(event_record);
171    }
172
173    fn set_event_records(&mut self, _event_records: Vec<EventRecord>) {
174        // self.event_records = event_records;
175    }
176
177    fn event_records(&self) -> &Vec<EventRecord> {
178        unimplemented!()
179    }
180}
181
182pub type BlockDescV1 = NamedObjectDesc<BlockDescContentV1>;
183pub type BlockTypeV1 = NamedObjType<BlockDescContentV1, BlockBodyV1>;
184pub type BlockIdV1 = NamedObjectId<BlockTypeV1>;
185pub type BlockV1 = NamedObjectBase<BlockTypeV1>;
186pub type BlockBuilderV1 = NamedObjectBuilder<BlockDescContentV1, BlockBodyV1>;
187
188impl BlockDescTrait for NamedObjectDesc<BlockDescContentV1> {
189    fn hash(&self) -> BlockHash {
190        self.calculate_id()
191    }
192
193    fn hash_str(&self) -> String {
194        self.calculate_id().to_string()
195    }
196
197    fn pre_block_hash(&self) -> &BlockHash {
198        &self.content().pre_block_hash
199    }
200
201    fn pre_block_hash_str(&self) -> String {
202        self.content().pre_block_hash.to_hex().unwrap()
203    }
204
205    fn number(&self) -> i64 {
206        self.content().number
207    }
208
209    fn coinbase(&self) -> &ObjectId {
210        &self.content().coinbase
211    }
212
213    fn is_pre_block_of(&self, other: &Self) -> bool {
214        return (self.content().number == other.content().number + 1)
215            && (self.calculate_id().eq(&other.content().pre_block_hash));
216    }
217
218    fn state_hash(&self) -> &HashValue {
219        &self.content().state_hash
220    }
221
222    fn transactions_hash(&self) -> &HashValue {
223        &self.content().transactions_hash
224    }
225
226    fn receipts_hash(&self) -> &HashValue {
227        &self.content().receipts_hash
228    }
229
230    fn event_records_hash(&self) -> &HashValue {
231        unimplemented!()
232    }
233}
234
235#[async_trait]
236impl BlockTrait for NamedObjectBase<BlockTypeV1> {
237    type BlockDesc = BlockDescV1;
238    type BlockBody = BlockBodyV1;
239    type BlockBuilder = BlockBuilderV1;
240    type Receipt = ReceiptV1;
241
242    fn new(
243        coinbase: ObjectId,
244        pre_block: Option<&Self::BlockDesc>,
245        state_hash: StateHash,
246        body: Self::BlockBody,
247    ) -> BuckyResult<Self::BlockBuilder> {
248        let mut transactions_hasher = Sha256::new();
249        for tx in &body.transactions {
250            transactions_hasher.input(tx.desc().calculate_id().to_string())
251        }
252        let transactions_hash = HashValue::from(transactions_hasher.result());
253
254        let mut receipts_hasher = Sha256::new();
255        for receipt in &body.receipts {
256            receipts_hasher.input(receipt.to_vec()?);
257        }
258        let receipts_hash = HashValue::from(receipts_hasher.result());
259
260        let mut header = BlockDescContentV1 {
261            number: 0,
262            coinbase,
263            state_hash,
264            pre_block_hash: BlockHash::default(),
265            transactions_hash,
266            receipts_hash,
267            // event_records_hash
268        };
269        if let Some(pre_header) = pre_block {
270            header.number = pre_header.content().number + 1;
271            header.pre_block_hash = pre_header.calculate_id();
272        }
273
274        Ok(BlockBuilderV1::new(header, body))
275    }
276
277    fn new2(
278        src_desc: &Self::BlockDesc,
279        state_hash: StateHash,
280        body: Self::BlockBody,
281    ) -> BuckyResult<Self::BlockBuilder> {
282        let mut transactions_hasher = Sha256::new();
283        for tx in &body.transactions {
284            transactions_hasher.input(tx.desc().calculate_id().to_string())
285        }
286        let transactions_hash = HashValue::from(transactions_hasher.result());
287
288        let mut receipts_hasher = Sha256::new();
289        for receipt in &body.receipts {
290            receipts_hasher.input(receipt.to_vec()?);
291        }
292        let receipts_hash = HashValue::from(receipts_hasher.result());
293
294        let header = BlockDescContentV1 {
295            number: src_desc.number(),
296            coinbase: src_desc.coinbase().clone(),
297            state_hash,
298            pre_block_hash: src_desc.pre_block_hash().clone(),
299            transactions_hash,
300            receipts_hash,
301            // event_records_hash
302        };
303        let builder = BlockBuilderV1::new(header, body).create_time(src_desc.create_time());
304        Ok(builder)
305    }
306
307    fn header(&self) -> &Self::BlockDesc {
308        self.desc()
309    }
310
311    fn transactions(&self) -> &Vec<MetaTx> {
312        &self.body().as_ref().unwrap().content().transactions
313    }
314
315    fn receipts(&self) -> Vec<Self::Receipt> {
316        self.body().as_ref().unwrap().content().receipts.clone()
317    }
318
319    fn event_records(&self) -> &Vec<EventRecord> {
320        unreachable!()
321    }
322
323    async fn sign(
324        &mut self,
325        private_key: PrivateKey,
326        sign_source: &SignatureSource,
327    ) -> BuckyResult<Signature> {
328        let signer = RsaCPUObjectSigner::new(private_key.public(), private_key);
329        let sign = sign_named_object_desc(&signer, self, sign_source).await?;
330        self.signs_mut().push_desc_sign(sign.clone());
331        Ok(sign)
332    }
333
334    fn version(&self) -> u64 {
335        1
336    }
337}
338
339#[derive(Clone, RawEncode, RawDecode)]
340pub struct BlockDescContentV2 {
341    pub number: i64,
342    pub coinbase: ObjectId,
343    pub state_hash: StateHash,
344    pub pre_block_hash: BlockHash,
345    //tx_merkle_root: MerkleHash,
346    pub transactions_hash: TransactionHash,
347    pub receipts_hash: ReceiptHash,
348    pub event_records_hash: HashValue,
349}
350
351impl BlockDescContent {
352    pub fn new(coinbase: ObjectId, pre_block: Option<&BlockDesc>) -> Self {
353        if let Some(pre_header) = pre_block {
354            BlockDescContent::V2(BlockDescContentV2 {
355                number: pre_header.number() + 1,
356                coinbase,
357                state_hash: HashValue::default(),
358                pre_block_hash: pre_header.hash(),
359                transactions_hash: HashValue::default(),
360                receipts_hash: HashValue::default(),
361                event_records_hash: HashValue::default(),
362            })
363        } else {
364            BlockDescContent::V2(BlockDescContentV2 {
365                number: 0,
366                coinbase,
367                state_hash: HashValue::default(),
368                pre_block_hash: BlockHash::default(),
369                transactions_hash: HashValue::default(),
370                receipts_hash: HashValue::default(),
371                event_records_hash: HashValue::default(),
372            })
373        }
374    }
375}
376
377#[derive(Clone, RawEncode, RawDecode)]
378pub enum BlockDescContent {
379    V1(BlockDescV1),
380    V2(BlockDescContentV2),
381}
382
383impl DescContent for BlockDescContent {
384    fn obj_type() -> u16 {
385        CoreObjectType::BlockV2 as u16
386    }
387
388    type OwnerType = SubDescNone;
389    type AreaType = SubDescNone;
390    type AuthorType = SubDescNone;
391    type PublicKeyType = SubDescNone;
392}
393
394#[derive(Clone, RawEncode, RawDecode)]
395pub struct BlockBodyV2 {
396    pub transactions: TxList,
397    pub receipts: Vec<ReceiptV2>,
398    pub event_records: EventRecordList,
399}
400
401#[derive(Clone, RawEncode, RawDecode)]
402pub struct BlockBodyV3 {
403    pub transactions: TxList,
404    pub receipts: ReceiptList,
405    pub event_records: EventRecordList,
406}
407
408#[derive(Clone, RawEncode, RawDecode)]
409pub enum BlockBody {
410    V1(BlockV1, Vec<Receipt>),
411    V2(BlockBodyV2),
412    V3(BlockBodyV3),
413}
414
415impl BodyContent for BlockBody {}
416
417impl BlockBody {
418    pub fn new() -> Self {
419        BlockBody::V3(BlockBodyV3 {
420            transactions: vec![],
421            receipts: vec![],
422            event_records: vec![],
423        })
424    }
425}
426
427impl BlockBodyTrait for BlockBody {
428    type Receipt = crate::Receipt;
429    fn transactions(&self) -> &Vec<MetaTx> {
430        match self {
431            BlockBody::V1(body, _) => body.transactions(),
432            BlockBody::V2(body) => &body.transactions,
433            BlockBody::V3(body) => &body.transactions,
434        }
435    }
436
437    fn receipts(&self) -> Vec<Self::Receipt> {
438        match self {
439            BlockBody::V1(_, receipts) => receipts.clone(),
440            BlockBody::V2(body) => body.receipts.iter().map(|r| r.into()).collect(),
441            BlockBody::V3(body) => body.receipts.clone(),
442        }
443    }
444    // return index
445    fn add_transaction(&mut self, tx: MetaTx) -> Result<usize, u32> {
446        match self {
447            BlockBody::V1(body, _) => body
448                .body_mut()
449                .as_mut()
450                .unwrap()
451                .content_mut()
452                .add_transaction(tx),
453            BlockBody::V2(body) => {
454                body.transactions.push(tx);
455                Ok(body.transactions.len() - 1)
456            }
457            BlockBody::V3(body) => {
458                body.transactions.push(tx);
459                Ok(body.transactions.len() - 1)
460            }
461        }
462    }
463
464    fn add_receipts(&mut self, receipts: Vec<Receipt>) -> Result<(), u32> {
465        match self {
466            BlockBody::V3(body) => {
467                for receipt in receipts {
468                    body.receipts.push(receipt);
469                }
470                Ok(())
471            }
472            _ => {
473                unreachable!()
474            }
475        }
476    }
477
478    fn add_event_record(&mut self, event_record: EventRecord) {
479        match self {
480            BlockBody::V3(body) => {
481                body.event_records.push(event_record);
482            }
483            _ => {
484                unreachable!()
485            }
486        }
487    }
488
489    fn set_event_records(&mut self, event_records: Vec<EventRecord>) {
490        match self {
491            BlockBody::V3(body) => {
492                body.event_records = event_records;
493            }
494            _ => {
495                unreachable!()
496            }
497        }
498    }
499
500    fn event_records(&self) -> &Vec<EventRecord> {
501        match self {
502            BlockBody::V3(body) => &body.event_records,
503            _ => {
504                unreachable!()
505            }
506        }
507    }
508}
509
510pub type BlockDesc = NamedObjectDesc<BlockDescContent>;
511pub type BlockType = NamedObjType<BlockDescContent, BlockBody>;
512pub type BlockId = NamedObjectId<BlockType>;
513pub type Block = NamedObjectBase<BlockType>;
514pub type BlockBuilder = NamedObjectBuilder<BlockDescContent, BlockBody>;
515
516impl BlockDescTrait for NamedObjectDesc<BlockDescContent> {
517    fn hash(&self) -> BlockHash {
518        match self.content() {
519            BlockDescContent::V1(desc) => desc.calculate_id(),
520            BlockDescContent::V2(_) => self.calculate_id(),
521        }
522    }
523
524    fn hash_str(&self) -> String {
525        self.hash().to_hex().unwrap()
526    }
527
528    fn pre_block_hash(&self) -> &BlockHash {
529        match self.content() {
530            BlockDescContent::V1(desc) => desc.pre_block_hash(),
531            BlockDescContent::V2(desc) => &desc.pre_block_hash,
532        }
533    }
534
535    fn pre_block_hash_str(&self) -> String {
536        match self.content() {
537            BlockDescContent::V1(desc) => desc.pre_block_hash_str(),
538            BlockDescContent::V2(desc) => desc.pre_block_hash.to_hex().unwrap(),
539        }
540    }
541
542    fn number(&self) -> i64 {
543        match self.content() {
544            BlockDescContent::V1(desc) => desc.number(),
545            BlockDescContent::V2(desc) => desc.number,
546        }
547    }
548
549    fn coinbase(&self) -> &ObjectId {
550        match self.content() {
551            BlockDescContent::V1(desc) => desc.coinbase(),
552            BlockDescContent::V2(desc) => &desc.coinbase,
553        }
554    }
555
556    fn is_pre_block_of(&self, other: &Self) -> bool {
557        return (self.number() == other.number() + 1)
558            && (self.calculate_id().eq(other.pre_block_hash()));
559    }
560
561    fn state_hash(&self) -> &HashValue {
562        match self.content() {
563            BlockDescContent::V1(desc) => desc.state_hash(),
564            BlockDescContent::V2(desc) => &desc.state_hash,
565        }
566    }
567
568    fn transactions_hash(&self) -> &HashValue {
569        match self.content() {
570            BlockDescContent::V1(desc) => desc.transactions_hash(),
571            BlockDescContent::V2(desc) => &desc.transactions_hash,
572        }
573    }
574
575    fn receipts_hash(&self) -> &HashValue {
576        match self.content() {
577            BlockDescContent::V1(desc) => desc.receipts_hash(),
578            BlockDescContent::V2(desc) => &desc.receipts_hash,
579        }
580    }
581
582    fn event_records_hash(&self) -> &HashValue {
583        match self.content() {
584            BlockDescContent::V2(desc) => &desc.event_records_hash,
585            _ => {
586                unreachable!()
587            }
588        }
589    }
590}
591
592#[async_trait]
593impl BlockTrait for NamedObjectBase<BlockType> {
594    type BlockDesc = BlockDesc;
595    type BlockBody = BlockBody;
596    type BlockBuilder = BlockBuilder;
597    type Receipt = crate::Receipt;
598
599    fn new(
600        coinbase: ObjectId,
601        pre_block: Option<&Self::BlockDesc>,
602        state_hash: StateHash,
603        body: Self::BlockBody,
604    ) -> BuckyResult<Self::BlockBuilder> {
605        let mut transactions_hasher = Sha256::new();
606        for tx in body.transactions() {
607            transactions_hasher.input(tx.desc().calculate_id().to_string())
608        }
609        let transactions_hash = HashValue::from(transactions_hasher.result());
610
611        let mut receipts_hasher = Sha256::new();
612        for receipt in body.receipts() {
613            receipts_hasher.input(receipt.to_vec()?);
614        }
615        let receipts_hash = HashValue::from(receipts_hasher.result());
616
617        let mut event_records_haser = Sha256::new();
618        for record in body.event_records() {
619            event_records_haser.input(record.to_vec()?);
620        }
621        let event_records_hash = HashValue::from(event_records_haser.result());
622
623        let header = if let Some(pre_header) = pre_block {
624            BlockDescContent::V2(BlockDescContentV2 {
625                number: pre_header.number() + 1,
626                coinbase,
627                state_hash,
628                pre_block_hash: pre_header.hash(),
629                transactions_hash,
630                receipts_hash,
631                event_records_hash,
632            })
633        } else {
634            BlockDescContent::V2(BlockDescContentV2 {
635                number: 0,
636                coinbase,
637                state_hash,
638                pre_block_hash: BlockHash::default(),
639                transactions_hash,
640                receipts_hash,
641                event_records_hash,
642            })
643        };
644
645        Ok(BlockBuilder::new(header, body))
646    }
647
648    fn new2(
649        src_desc: &Self::BlockDesc,
650        state_hash: StateHash,
651        body: Self::BlockBody,
652    ) -> BuckyResult<Self::BlockBuilder> {
653        let mut transactions_hasher = Sha256::new();
654        for tx in body.transactions() {
655            transactions_hasher.input(tx.desc().calculate_id().to_string())
656        }
657        let transactions_hash = HashValue::from(transactions_hasher.result());
658
659        let mut receipts_hasher = Sha256::new();
660        for receipt in body.receipts() {
661            receipts_hasher.input(receipt.to_vec()?);
662        }
663        let receipts_hash = HashValue::from(receipts_hasher.result());
664
665        let mut event_records_haser = Sha256::new();
666        for record in body.event_records() {
667            event_records_haser.input(record.to_vec()?);
668        }
669        let event_records_hash = HashValue::from(event_records_haser.result());
670
671        let header = BlockDescContent::V2(BlockDescContentV2 {
672            number: src_desc.number(),
673            coinbase: src_desc.coinbase().clone(),
674            state_hash,
675            pre_block_hash: src_desc.pre_block_hash().clone(),
676            transactions_hash,
677            receipts_hash,
678            event_records_hash,
679        });
680        let builder = BlockBuilder::new(header, body).create_time(src_desc.create_time());
681        Ok(builder)
682    }
683
684    fn header(&self) -> &BlockDesc {
685        self.desc()
686    }
687
688    fn transactions(&self) -> &Vec<MetaTx> {
689        &self.body().as_ref().unwrap().content().transactions()
690    }
691
692    fn receipts(&self) -> Vec<Self::Receipt> {
693        self.body().as_ref().unwrap().content().receipts()
694    }
695
696    fn event_records(&self) -> &Vec<EventRecord> {
697        &self.body().as_ref().unwrap().content().event_records()
698    }
699
700    async fn sign(
701        &mut self,
702        private_key: PrivateKey,
703        sign_source: &SignatureSource,
704    ) -> BuckyResult<Signature> {
705        let signer = RsaCPUObjectSigner::new(private_key.public(), private_key);
706        let sign = sign_named_object_desc(&signer, self, sign_source).await?;
707        self.signs_mut().push_desc_sign(sign.clone());
708        Ok(sign)
709    }
710
711    fn version(&self) -> u64 {
712        match self.desc().content() {
713            BlockDescContent::V1(_) => 1,
714            BlockDescContent::V2(_) => 2,
715        }
716    }
717}