1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
// Copyright 2019-2024 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

use crate::beacon::BeaconEntry;
use crate::lotus_json::*;
use crate::shim::sector::PoStProof;
use crate::{
    blocks::{ElectionProof, Ticket, TipsetKey},
    shim::address::Address,
    shim::{crypto::Signature, econ::TokenAmount},
};
use ::cid::Cid;
use num::BigInt;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

use crate::blocks::{CachingBlockHeader, RawBlockHeader};

#[derive(Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "PascalCase")]
#[schemars(rename = "BlockHeader")]
pub struct BlockHeaderLotusJson {
    #[schemars(with = "LotusJson<Address>")]
    #[serde(with = "crate::lotus_json")]
    miner: Address,
    #[schemars(with = "LotusJson<Option<Ticket>>")]
    #[serde(
        with = "crate::lotus_json",
        skip_serializing_if = "Option::is_none",
        default
    )]
    ticket: Option<Ticket>,
    #[schemars(with = "LotusJson<Option<ElectionProof>>")]
    #[serde(
        with = "crate::lotus_json",
        skip_serializing_if = "Option::is_none",
        default
    )]
    election_proof: Option<ElectionProof>,
    #[schemars(with = "LotusJson<Vec<BeaconEntry>>")]
    #[serde(with = "crate::lotus_json")]
    beacon_entries: Vec<BeaconEntry>,
    #[schemars(with = "LotusJson<Vec<PoStProof>>")]
    #[serde(with = "crate::lotus_json")]
    win_po_st_proof: Vec<PoStProof>,
    #[schemars(with = "LotusJson<TipsetKey>")]
    #[serde(with = "crate::lotus_json")]
    parents: TipsetKey,
    #[schemars(with = "LotusJson<BigInt>")]
    #[serde(with = "crate::lotus_json")]
    parent_weight: BigInt,
    height: i64,
    #[schemars(with = "LotusJson<Cid>")]
    #[serde(with = "crate::lotus_json")]
    parent_state_root: Cid,
    #[schemars(with = "LotusJson<Cid>")]
    #[serde(with = "crate::lotus_json")]
    parent_message_receipts: Cid,
    #[schemars(with = "LotusJson<Cid>")]
    #[serde(with = "crate::lotus_json")]
    messages: Cid,
    #[schemars(with = "LotusJson<Option<Signature>>")]
    #[serde(
        with = "crate::lotus_json",
        skip_serializing_if = "Option::is_none",
        default
    )]
    b_l_s_aggregate: Option<Signature>,
    timestamp: u64,
    #[schemars(with = "LotusJson<Option<Signature>>")]
    #[serde(
        with = "crate::lotus_json",
        skip_serializing_if = "Option::is_none",
        default
    )]
    block_sig: Option<Signature>,
    fork_signaling: u64,
    #[schemars(with = "LotusJson<TokenAmount>")]
    #[serde(with = "crate::lotus_json")]
    parent_base_fee: TokenAmount,
}

impl HasLotusJson for CachingBlockHeader {
    type LotusJson = BlockHeaderLotusJson;

    #[cfg(test)]
    fn snapshots() -> Vec<(serde_json::Value, Self)> {
        use serde_json::json;

        vec![(
            json!({
                "BeaconEntries": null,
                "Miner": "f00",
                "Parents": [{"/":"bafyreiaqpwbbyjo4a42saasj36kkrpv4tsherf2e7bvezkert2a7dhonoi"}],
                "ParentWeight": "0",
                "Height": 0,
                "ParentStateRoot": {
                    "/": "baeaaaaa"
                },
                "ParentMessageReceipts": {
                    "/": "baeaaaaa"
                },
                "Messages": {
                    "/": "baeaaaaa"
                },
                "WinPoStProof": null,
                "Timestamp": 0,
                "ForkSignaling": 0,
                "ParentBaseFee": "0",
            }),
            CachingBlockHeader::default(),
        )]
    }

    fn into_lotus_json(self) -> Self::LotusJson {
        let RawBlockHeader {
            miner_address,
            ticket,
            election_proof,
            beacon_entries,
            winning_post_proof,
            parents,
            weight,
            epoch,
            state_root,
            message_receipts,
            messages,
            bls_aggregate,
            timestamp,
            signature,
            fork_signal,
            parent_base_fee,
        } = self.into_raw();
        Self::LotusJson {
            miner: miner_address,
            ticket,
            election_proof,
            beacon_entries,
            win_po_st_proof: winning_post_proof,
            parents,
            parent_weight: weight,
            height: epoch,
            parent_state_root: state_root,
            parent_message_receipts: message_receipts,
            messages,
            b_l_s_aggregate: bls_aggregate,
            timestamp,
            block_sig: signature,
            fork_signaling: fork_signal,
            parent_base_fee,
        }
    }

    fn from_lotus_json(lotus_json: Self::LotusJson) -> Self {
        let Self::LotusJson {
            miner,
            ticket,
            election_proof,
            beacon_entries,
            win_po_st_proof,
            parents,
            parent_weight,
            height,
            parent_state_root,
            parent_message_receipts,
            messages,
            b_l_s_aggregate,
            timestamp,
            block_sig,
            fork_signaling,
            parent_base_fee,
        } = lotus_json;
        Self::new(RawBlockHeader {
            parents,
            weight: parent_weight,
            epoch: height,
            beacon_entries,
            winning_post_proof: win_po_st_proof,
            miner_address: miner,
            messages,
            message_receipts: parent_message_receipts,
            state_root: parent_state_root,
            fork_signal: fork_signaling,
            signature: block_sig,
            election_proof,
            timestamp,
            ticket,
            bls_aggregate: b_l_s_aggregate,
            parent_base_fee,
        })
    }
}