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
use std::sync::Arc;
use ethcore::client::BlockChainClient;
use types::{header::Header, transaction::LocalizedTransaction};
use jsonrpc_core::Result;
use v1::{
traits::Debug,
types::{Block, BlockTransactions, Bytes, RichBlock, Transaction},
};
pub struct DebugClient<C> {
client: Arc<C>,
}
impl<C> DebugClient<C> {
pub fn new(client: Arc<C>) -> Self {
Self { client }
}
}
impl<C: BlockChainClient + 'static> Debug for DebugClient<C> {
fn bad_blocks(&self) -> Result<Vec<RichBlock>> {
fn cast<O, T: Copy + Into<O>>(t: &T) -> O {
(*t).into()
}
Ok(self
.client
.bad_blocks()
.into_iter()
.map(|(block, reason)| {
let number = block.header.number();
let hash = block.header.hash();
let base_fee = block.header.base_fee();
RichBlock {
inner: Block {
hash: Some(hash),
size: Some(block.bytes.len().into()),
parent_hash: cast(block.header.parent_hash()),
uncles_hash: cast(block.header.uncles_hash()),
author: cast(block.header.author()),
miner: cast(block.header.author()),
state_root: cast(block.header.state_root()),
receipts_root: cast(block.header.receipts_root()),
number: Some(number.into()),
gas_used: cast(block.header.gas_used()),
gas_limit: cast(block.header.gas_limit()),
logs_bloom: Some(cast(block.header.log_bloom())),
timestamp: block.header.timestamp().into(),
difficulty: cast(block.header.difficulty()),
total_difficulty: None,
seal_fields: block
.header
.seal()
.iter()
.cloned()
.map(Into::into)
.collect(),
base_fee_per_gas: base_fee,
uncles: block.uncles.iter().map(Header::hash).collect(),
transactions: BlockTransactions::Full(
block
.transactions
.into_iter()
.enumerate()
.map(|(transaction_index, signed)| {
Transaction::from_localized(
LocalizedTransaction {
block_number: number,
block_hash: hash,
transaction_index,
signed,
cached_sender: None,
},
base_fee,
)
})
.collect(),
),
transactions_root: cast(block.header.transactions_root()),
extra_data: block.header.extra_data().clone().into(),
},
extra_info: vec![
("reason".to_owned(), reason),
("rlp".to_owned(), serialize(&Bytes(block.bytes))),
("hash".to_owned(), format!("{:#x}", hash)),
]
.into_iter()
.collect(),
}
})
.collect())
}
}
fn serialize<T: ::serde::Serialize>(t: &T) -> String {
::serde_json::to_string(t).expect("RPC types serialization is non-fallible.")
}