dubp_block/
block.rs

1//  Copyright (C) 2017-2019  The AXIOM TEAM Association.
2//
3// This program is free software: you can redistribute it and/or modify
4// it under the terms of the GNU Affero General Public License as
5// published by the Free Software Foundation, either version 3 of the
6// License, or (at your option) any later version.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11// GNU Affero General Public License for more details.
12//
13// You should have received a copy of the GNU Affero General Public License
14// along with this program.  If not, see <https://www.gnu.org/licenses/>.
15
16//! Wrappers around Block document.
17
18pub mod v10;
19
20use crate::*;
21use dubp_documents::dubp_wallet::prelude::SourceAmount;
22pub use v10::{
23    DubpBlockV10, DubpBlockV10AfterPowData, DubpBlockV10Builder, DubpBlockV10Content,
24    DubpBlockV10Stringified,
25};
26
27/// Wrap a Block document.
28///
29/// Must be created by parsing a text document or using a builder.
30#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
31pub enum DubpBlock {
32    V10(DubpBlockV10),
33}
34
35#[derive(Debug, Clone, Copy, PartialEq)]
36/// Error when verifying a hash of a block
37pub enum VerifyBlockHashError {
38    /// The hash is missing
39    MissingHash { block_number: BlockNumber },
40    /// Hash is invalid
41    InvalidHash {
42        block_number: BlockNumber,
43        expected_hash: Hash,
44        actual_hash: Hash,
45    },
46}
47
48pub trait DubpBlockTrait {
49    type Signator: Signator;
50
51    /// Common time in block (also known as 'blockchain time')
52    fn common_time(&self) -> u64;
53    /// Compute hash
54    fn compute_hash(&self) -> BlockHash {
55        BlockHash(Hash::compute(self.compute_hashed_string().as_bytes()))
56    }
57    /// Compute inner hash
58    fn compute_inner_hash(&self) -> Hash {
59        Hash::compute(&self.generate_compact_inner_text().as_bytes())
60    }
61    /// Compute the character string that hashed
62    fn compute_hashed_string(&self) -> String;
63    /// Compute the character string that will be signed
64    fn compute_signed_string(&self) -> String;
65    /// Get currency name
66    fn currency_name(&self) -> CurrencyName;
67    /// Get currency parameters
68    fn currency_parameters(&self) -> Option<CurrencyParameters>;
69    /// Get current frame size (in blocks)
70    fn current_frame_size(&self) -> usize;
71    /// Get universal dividend amount
72    fn dividend(&self) -> Option<SourceAmount>;
73    /// Generate compact inner text (for compute inner_hash)
74    fn generate_compact_inner_text(&self) -> String;
75    /// Get block hash
76    fn hash(&self) -> BlockHash;
77    /// Get block inner hash
78    fn inner_hash(&self) -> Hash;
79    /// Get block issuer
80    fn issuer(&self) -> <Self::Signator as Signator>::PublicKey;
81    /// Get number of compute members in the current frame
82    fn issuers_count(&self) -> usize;
83    /// Get size of the current frame (in blocks)
84    fn issuers_frame(&self) -> usize;
85    /// Get local time
86    fn local_time(&self) -> u64;
87    /// Get number of members in wot
88    fn members_count(&self) -> usize;
89    /// Get monetary mass
90    fn monetary_mass(&self) -> u64;
91    /// Get block nonce
92    fn nonce(&self) -> u64;
93    /// Get block number
94    fn number(&self) -> BlockNumber;
95    /// Get common difficulty (PoW)
96    fn pow_min(&self) -> usize;
97    /// Get previous hash
98    fn previous_hash(&self) -> Hash;
99    /// Get previous blockstamp
100    fn previous_blockstamp(&self) -> Blockstamp;
101    /// Lightens the block (for example to store it while minimizing the space required)
102    fn reduce(&mut self);
103    /// Verify inner hash
104    fn verify_inner_hash(&self) -> Result<(), VerifyBlockHashError>;
105    /// Verify signature
106    fn verify_signature(&self) -> Result<(), SigError>;
107    /// Verify block hash
108    fn verify_hash(&self) -> Result<(), VerifyBlockHashError>;
109    /// Sign block
110    fn sign(&mut self, signator: &Self::Signator) -> Result<(), SignError>;
111    /// Get block signature
112    fn signature(&self) -> <<Self::Signator as Signator>::PublicKey as PublicKey>::Signature;
113    /// Get unit base
114    fn unit_base(&self) -> usize;
115}
116
117macro_rules! dubp_block_fn {
118    ($fn_name:ident, $return_type:ty) => {
119        #[inline(always)]
120        fn $fn_name(&self) -> $return_type {
121            match self {
122                DubpBlock::V10(block) => block.$fn_name(),
123            }
124        }
125    };
126}
127macro_rules! dubp_block_fn_mut {
128    ($fn_name:ident) => {
129        #[inline(always)]
130        fn $fn_name(&mut self) {
131            match self {
132                DubpBlock::V10(block) => block.$fn_name(),
133            }
134        }
135    };
136}
137
138impl DubpBlockTrait for DubpBlock {
139    type Signator = SignatorEnum;
140
141    dubp_block_fn!(compute_hash, BlockHash);
142    dubp_block_fn!(compute_hashed_string, String);
143    dubp_block_fn!(compute_signed_string, String);
144    dubp_block_fn!(currency_name, CurrencyName);
145    dubp_block_fn!(currency_parameters, Option<CurrencyParameters>);
146    dubp_block_fn!(current_frame_size, usize);
147    dubp_block_fn!(dividend, Option<SourceAmount>);
148    dubp_block_fn!(generate_compact_inner_text, String);
149    dubp_block_fn!(hash, BlockHash);
150    dubp_block_fn!(inner_hash, Hash);
151    dubp_block_fn!(issuers_count, usize);
152    dubp_block_fn!(issuers_frame, usize);
153    dubp_block_fn!(local_time, u64);
154    dubp_block_fn!(members_count, usize);
155    dubp_block_fn!(monetary_mass, u64);
156    dubp_block_fn!(common_time, u64);
157    dubp_block_fn!(nonce, u64);
158    dubp_block_fn!(number, BlockNumber);
159    dubp_block_fn!(pow_min, usize);
160    dubp_block_fn!(previous_blockstamp, Blockstamp);
161    dubp_block_fn!(previous_hash, Hash);
162    dubp_block_fn_mut!(reduce);
163    dubp_block_fn!(verify_inner_hash, Result<(), VerifyBlockHashError>);
164    dubp_block_fn!(verify_signature, Result<(), SigError>);
165    dubp_block_fn!(verify_hash, Result<(), VerifyBlockHashError>);
166    dubp_block_fn!(unit_base, usize);
167    #[inline]
168    fn issuer(&self) -> PubKeyEnum {
169        match self {
170            DubpBlock::V10(block) => PubKeyEnum::Ed25519(block.issuer()),
171        }
172    }
173    #[inline]
174    fn sign(&mut self, signator: &Self::Signator) -> Result<(), SignError> {
175        match self {
176            DubpBlock::V10(block) => {
177                if let SignatorEnum::Ed25519(ed25519_signator) = signator {
178                    block.sign(ed25519_signator)
179                } else {
180                    Err(SignError::WrongAlgo)
181                }
182            }
183        }
184    }
185    #[inline]
186    fn signature(&self) -> Sig {
187        match self {
188            DubpBlock::V10(block) => Sig::Ed25519(block.signature()),
189        }
190    }
191}
192
193#[derive(Clone, Debug, Deserialize, Serialize)]
194pub enum DubpBlockStringified {
195    V10(DubpBlockV10Stringified),
196}
197
198impl ToStringObject for DubpBlock {
199    type StringObject = DubpBlockStringified;
200
201    fn to_string_object(&self) -> Self::StringObject {
202        match self {
203            DubpBlock::V10(block) => DubpBlockStringified::V10(block.to_string_object()),
204        }
205    }
206}