ergo_lib/chain/
block.rs

1//! Block on the Ergo chain
2
3use bounded_vec::BoundedVec;
4use ergo_chain_types::Header;
5
6use super::transaction::Transaction;
7
8/// Maximum number of transactions that can be contained in a block. See
9/// https://github.com/ergoplatform/ergo/blob/fc292f6bc2d3c6ca27ce5f6a316186d8459150cc/src/main/scala/org/ergoplatform/modifiers/history/BlockTransactions.scala#L157
10const MAX_NUM_TRANSACTIONS: usize = 10_000_000;
11
12/// Transactions in a block
13#[cfg_attr(feature = "json", derive(serde::Serialize, serde::Deserialize))]
14#[derive(Debug, Clone, PartialEq, Eq)]
15pub struct BlockTransactions {
16    /// Transactions contained in the block
17    pub transactions: BoundedVec<Transaction, 1, MAX_NUM_TRANSACTIONS>,
18}
19
20/// A block on the Ergo chain
21#[cfg_attr(feature = "json", derive(serde::Serialize, serde::Deserialize))]
22#[derive(Debug, Clone, PartialEq, Eq)]
23pub struct FullBlock {
24    /// Block header
25    pub header: Header,
26    /// Transactions in this block
27    #[cfg_attr(feature = "json", serde(rename = "blockTransactions"))]
28    pub block_transactions: BlockTransactions,
29}
30
31#[cfg(test)]
32mod tests {
33    use super::FullBlock;
34
35    #[test]
36    #[allow(clippy::unwrap_used)]
37    fn test_parse_full_block() {
38        // Following JSON taken from the node by:
39        //   curl -X GET "https://node.ergo.watch/blocks/96911575efdceb082b974aa3042263be07632de48031aa2204d77d8d5a8240b8" -H "accept: application/json"
40
41        let json: &str = r#"
42        {
43            "header": {
44              "extensionId": "a1c5a5f409fce4d16a501371b11aaaf0e0a44609d8436958c383e12f9c14528c",
45              "difficulty": "1371769604669440",
46              "votes": "000000",
47              "timestamp": 1627249021284,
48              "size": 221,
49              "stateRoot": "1d3d031ba060245d8184948c6f726a8bb98a1bc621affc4a1dcf0e20226eb27716",
50              "height": 540000,
51              "nBits": 117759902,
52              "version": 2,
53              "id": "96911575efdceb082b974aa3042263be07632de48031aa2204d77d8d5a8240b8",
54              "adProofsRoot": "aa0d212ec398d9558b2b2f24239963bdd8d2d22f70b6e8b5cfff3474609bcdde",
55              "transactionsRoot": "235a6e8f28f54fef5fbcd17d2638eb03ef9cfb331f4b5a50fbb74df4a524dcb4",
56              "extensionHash": "badffc4d646e1c2babcf1ce8422b4f2430b6262c947c964671e97486d8bdb601",
57              "powSolutions": {
58                "pk": "02b3a06d6eaa8671431ba1db4dd427a77f75a5c2acbd71bfb725d38adc2b55f669",
59                "w": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
60                "n": "0537288a2c246648",
61                "d": 0
62              },
63              "adProofsId": "13856ec4123971268ff0d7493bfa520021c6328ceba648bf39484b45761f4edf",
64              "transactionsId": "5871d44565a08892d03f3e4f53a3d98a7f21e549738fff0864bce205916a5bfb",
65              "parentId": "c55f05c91fea37f95eff73dfa62e8745f54db6dff5e9f257e39b9c0cfbfd8133"
66            },
67            "blockTransactions": {
68              "headerId": "96911575efdceb082b974aa3042263be07632de48031aa2204d77d8d5a8240b8",
69              "transactions": [
70                {
71                  "id": "d301f351d5d74aa314edd19914e4e593bd0316166c25a09aa222f9b519ee5fdf",
72                  "inputs": [
73                    {
74                      "boxId": "805a5a5293a38c4ef872f5a1b392404a2808f7ca1f149f0874dbddd31a30677f",
75                      "spendingProof": {
76                        "proofBytes": "",
77                        "extension": {}
78                      }
79                    }
80                  ],
81                  "dataInputs": [],
82                  "outputs": [
83                    {
84                      "boxId": "b00eee09bb8ad9b3b4d93042fd28c966aa9b225c228732c69cb74656788ae8f0",
85                      "value": 56959132500000000,
86                      "ergoTree": "101004020e36100204a00b08cd0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ea02d192a39a8cc7a7017300730110010204020404040004c0fd4f05808c82f5f6030580b8c9e5ae040580f882ad16040204c0944004c0f407040004000580f882ad16d19683030191a38cc7a7019683020193c2b2a57300007473017302830108cdeeac93a38cc7b2a573030001978302019683040193b1a5730493c2a7c2b2a573050093958fa3730673079973089c73097e9a730a9d99a3730b730c0599c1a7c1b2a5730d00938cc7b2a5730e0001a390c1a7730f",
87                      "assets": [],
88                      "creationHeight": 540000,
89                      "additionalRegisters": {},
90                      "transactionId": "d301f351d5d74aa314edd19914e4e593bd0316166c25a09aa222f9b519ee5fdf",
91                      "index": 0
92                    },
93                    {
94                      "boxId": "9c700fdcfa7cb5fa83df806b30f69bc1a4690e33b1af77076ced4f7b28c76e37",
95                      "value": 67500000000,
96                      "ergoTree": "100204a00b08cd02b3a06d6eaa8671431ba1db4dd427a77f75a5c2acbd71bfb725d38adc2b55f669ea02d192a39a8cc7a70173007301",
97                      "assets": [],
98                      "creationHeight": 540000,
99                      "additionalRegisters": {},
100                      "transactionId": "d301f351d5d74aa314edd19914e4e593bd0316166c25a09aa222f9b519ee5fdf",
101                      "index": 1
102                    }
103                  ],
104                  "size": 344
105                }
106              ],
107              "blockVersion": 2,
108              "size": 381
109            },
110            "extension": {
111              "headerId": "96911575efdceb082b974aa3042263be07632de48031aa2204d77d8d5a8240b8",
112              "digest": "badffc4d646e1c2babcf1ce8422b4f2430b6262c947c964671e97486d8bdb601",
113              "fields": [
114                [
115                  "0100",
116                  "01b0244dfc267baca974a4caee06120321562784303a8a688976ae56170e4d175b"
117                ],
118                [
119                  "0101",
120                  "01557fd0590616b4f6e51eaf54436d61e5585eebfc5a9e860861fc0876064bd3d9"
121                ],
122                [
123                  "0102",
124                  "03296e2707cf72b6a2c71e4966028d8786c7f5425850e9609757ce8b3713f548fe"
125                ],
126                [
127                  "0105",
128                  "027ddba9db07cce855cd911c9bee9376be9e16cedf66eeed2175072816c5678cdb"
129                ],
130                [
131                  "0107",
132                  "05e31fdeefaee294c99d11cdfcf8a7c28158ba16c7b7ccce6ff98c4bf1b8b65873"
133                ],
134                [
135                  "010c",
136                  "01dcf7326a3daf36f5f49e279e24f335a3947bec606eacd722637e45f0cbc8ecd9"
137                ],
138                [
139                  "010d",
140                  "013a9bb64834421e8ab964dfb5fcc6f808027559ad7901ccacf6d283d57f069c83"
141                ],
142                [
143                  "010e",
144                  "03338bd47eca3694f9e5d2f146abef73582a6520adc4369ec624ccd3343afb598b"
145                ],
146                [
147                  "0111",
148                  "018f9b36c08403f4088d31e2f331b136a9b2b0f6c05cd110546d517860c977d49d"
149                ],
150                [
151                  "0112",
152                  "02c55f05c91fea37f95eff73dfa62e8745f54db6dff5e9f257e39b9c0cfbfd8133"
153                ]
154              ]
155            },
156            "adProofs": null,
157            "size": 602
158          }
159        "#;
160
161        let block_0: FullBlock = serde_json::from_str(json).unwrap();
162        let encoded_json = serde_json::to_string(&block_0).unwrap();
163        let block_1: FullBlock = serde_json::from_str(&encoded_json).unwrap();
164        assert_eq!(block_0, block_1);
165    }
166}