      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

    use serde::{Serialize, Serializer};
    use super::hash::H256;
    use super::uint::U256;
    use super::block::RawBlock;

    /// Response to getblock RPC request
    #[derive(Debug)]
    pub enum GetBlockResponse {
    	/// When asking for short response
    	Raw(RawBlock),
    	/// When asking for verbose response
    	Verbose(VerboseBlock),
    }

    /// Verbose block information
    #[derive(Debug, Default, Serialize, Deserialize, PartialEq)]
    pub struct VerboseBlock {
    	/// Block hash
    	pub hash: H256,
    	/// Number of confirmations. -1 if block is on the side chain
    	pub confirmations: i64,
    	/// Block size
    	pub size: u32,
    	/// Block size, excluding witness data
    	pub strippedsize: u32,
    	/// Block weight
    	pub weight: u32,
    	/// Block height
    	/// TODO: bitcoind always returns value, but we hold this value for main chain blocks only
    	pub height: Option<u32>,
    	/// Block version
    	pub version: u32,
    	/// Block version as hex
    	#[serde(rename = "versionHex")]
    	pub version_hex: String,
    	/// Merkle root of this block
    	pub merkleroot: H256,
    	/// Transactions ids
    	pub tx: Vec<H256>,
    	/// Block time in seconds since epoch (Jan 1 1970 GMT)
    	pub time: u32,
    	/// Median block time in seconds since epoch (Jan 1 1970 GMT)
    	/// TODO: bitcoind always returns value, but we can calculate this only if height(block) > 2
    	pub mediantime: Option<u32>,
    	/// Block nonce
    	pub nonce: u32,
    	/// Block nbits
    	pub bits: u32,
    	/// Block difficulty
    	pub difficulty: f64,
    	/// Expected number of hashes required to produce the chain up to this block (in hex)
    	pub chainwork: U256,
    	/// Hash of previous block
    	pub previousblockhash: Option<H256>,
    	/// Hash of next block
    	pub nextblockhash: Option<H256>,
    }

    impl Serialize for GetBlockResponse {
    	fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
    		match *self {
    			GetBlockResponse::Raw(ref raw_block) => raw_block.serialize(serializer),
    			GetBlockResponse::Verbose(ref verbose_block) => verbose_block.serialize(serializer),
    		}
    	}
    }

    #[cfg(test)]
    mod tests {
    	use super::super::bytes::Bytes;
    	use super::super::hash::H256;
    	use super::super::uint::U256;
    	use serde_json;
    	use super::*;

    	#[test]
    	fn verbose_block_serialize() {
    		let block = VerboseBlock::default();
    		assert_eq!(serde_json::to_string(&block).unwrap(), r#"{"hash":"0000000000000000000000000000000000000000000000000000000000000000","confirmations":0,"size":0,"strippedsize":0,"weight":0,"height":null,"version":0,"versionHex":"","merkleroot":"0000000000000000000000000000000000000000000000000000000000000000","tx":[],"time":0,"mediantime":null,"nonce":0,"bits":0,"difficulty":0.0,"chainwork":"0","previousblockhash":null,"nextblockhash":null}"#);

    		let block = VerboseBlock {
    			hash: H256::from(1),
    			confirmations: -1,
    			size: 500000,
    			strippedsize: 444444,
    			weight: 5236235,
    			height: Some(3513513),
    			version: 1,
    			version_hex: "01".to_owned(),
    			merkleroot: H256::from(2),
    			tx: vec![H256::from(3), H256::from(4)],
    			time: 111,
    			mediantime: Some(100),
    			nonce: 124,
    			bits: 13513,
    			difficulty: 555.555,
    			chainwork: U256::from(3),
    			previousblockhash: Some(H256::from(4)),
    			nextblockhash: Some(H256::from(5)),
    		};
    		assert_eq!(serde_json::to_string(&block).unwrap(), r#"{"hash":"0100000000000000000000000000000000000000000000000000000000000000","confirmations":-1,"size":500000,"strippedsize":444444,"weight":5236235,"height":3513513,"version":1,"versionHex":"01","merkleroot":"0200000000000000000000000000000000000000000000000000000000000000","tx":["0300000000000000000000000000000000000000000000000000000000000000","0400000000000000000000000000000000000000000000000000000000000000"],"time":111,"mediantime":100,"nonce":124,"bits":13513,"difficulty":555.555,"chainwork":"3","previousblockhash":"0400000000000000000000000000000000000000000000000000000000000000","nextblockhash":"0500000000000000000000000000000000000000000000000000000000000000"}"#);
    	}

    	#[test]
    	fn verbose_block_deserialize() {
    		let block = VerboseBlock::default();
    		assert_eq!(
    			serde_json::from_str::<VerboseBlock>(r#"{"hash":"0000000000000000000000000000000000000000000000000000000000000000","confirmations":0,"size":0,"strippedsize":0,"weight":0,"height":null,"version":0,"versionHex":"","merkleroot":"0000000000000000000000000000000000000000000000000000000000000000","tx":[],"time":0,"mediantime":null,"nonce":0,"bits":0,"difficulty":0.0,"chainwork":"0","previousblockhash":null,"nextblockhash":null}"#).unwrap(),
    			block);

    		let block = VerboseBlock {
    			hash: H256::from(1),
    			confirmations: -1,
    			size: 500000,
    			strippedsize: 444444,
    			weight: 5236235,
    			height: Some(3513513),
    			version: 1,
    			version_hex: "01".to_owned(),
    			merkleroot: H256::from(2),
    			tx: vec![H256::from(3), H256::from(4)],
    			time: 111,
    			mediantime: Some(100),
    			nonce: 124,
    			bits: 13513,
    			difficulty: 555.555,
    			chainwork: U256::from(3),
    			previousblockhash: Some(H256::from(4)),
    			nextblockhash: Some(H256::from(5)),
    		};
    		assert_eq!(
    			serde_json::from_str::<VerboseBlock>(r#"{"hash":"0100000000000000000000000000000000000000000000000000000000000000","confirmations":-1,"size":500000,"strippedsize":444444,"weight":5236235,"height":3513513,"version":1,"versionHex":"01","merkleroot":"0200000000000000000000000000000000000000000000000000000000000000","tx":["0300000000000000000000000000000000000000000000000000000000000000","0400000000000000000000000000000000000000000000000000000000000000"],"time":111,"mediantime":100,"nonce":124,"bits":13513,"difficulty":555.555,"chainwork":"3","previousblockhash":"0400000000000000000000000000000000000000000000000000000000000000","nextblockhash":"0500000000000000000000000000000000000000000000000000000000000000"}"#).unwrap(),
    			block);
    	}

    	#[test]
    	fn get_block_response_raw_serialize() {
    		let raw_response = GetBlockResponse::Raw(Bytes::new(vec![0]));
    		assert_eq!(serde_json::to_string(&raw_response).unwrap(), r#""00""#);
    	}

    	#[test]
    	fn get_block_response_verbose_serialize() {
    		let block = VerboseBlock::default();
    		let verbose_response = GetBlockResponse::Verbose(block);
    		assert_eq!(serde_json::to_string(&verbose_response).unwrap(), r#"{"hash":"0000000000000000000000000000000000000000000000000000000000000000","confirmations":0,"size":0,"strippedsize":0,"weight":0,"height":null,"version":0,"versionHex":"","merkleroot":"0000000000000000000000000000000000000000000000000000000000000000","tx":[],"time":0,"mediantime":null,"nonce":0,"bits":0,"difficulty":0.0,"chainwork":"0","previousblockhash":null,"nextblockhash":null}"#);
    	}
    }

# Help

## Keyboard Shortcuts

`?`
  Show this help dialog
`S`
  Focus the search field
`↑`
  Move up in search results
`↓`
  Move down in search results
`↹`
  Switch tab
`⏎`
  Go to active search result
`+`
  Expand all sections
`-`
  Collapse all sections

## Search Tricks

Prefix searches with a type followed by a colon (e.g. `fn:`) to restrict the search to a given type.

Accepted types are: `fn`, `mod`, `struct`, `enum`, `trait`, `type`, `macro`, and `const`.

Search functions by type signature (e.g. `vec -> usize` or `* -> vec`)

Search multiple things at once by splitting your query with comma (e.g. `str,u8` or `String,struct:Vec,test`)