// Copyright 2015-2020 Parity Technologies (UK) Ltd. // This file is part of OpenEthereum. // OpenEthereum is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // OpenEthereum is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with OpenEthereum. If not, see . //! Debug APIs RPC implementation 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}, }; /// Debug rpc implementation. pub struct DebugClient { client: Arc, } impl DebugClient { /// Creates new debug client. pub fn new(client: Arc) -> Self { Self { client } } } impl Debug for DebugClient { fn bad_blocks(&self) -> Result> { fn cast>(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: &T) -> String { ::serde_json::to_string(t).expect("RPC types serialization is non-fallible.") }