getblock RPC

This commit is contained in:
Svyatoslav Nikolsky 2019-01-14 13:50:41 +03:00
parent 9651e4b270
commit 753b69995b
10 changed files with 123 additions and 92 deletions

View File

@ -68,7 +68,7 @@ Get proof-of-work difficulty as a multiple of the minimum difficulty
Get information on given block.
curl -H 'content-type: application/json' --data-binary '{"jsonrpc": "2.0", "method": "getblock", "params": ["000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"], "id":1 }' localhost:8332
curl -H 'content-type: application/json' --data-binary '{"jsonrpc": "2.0", "method": "getblock", "params": ["0002a26c902619fc964443264feb16f1e3e2d71322fc53dcb81cc5d797e273ed"], "id":1 }' localhost:8332
#### gettxout

View File

@ -13,7 +13,7 @@ pub struct BlockHeader {
pub version: u32,
pub previous_header_hash: H256,
pub merkle_root_hash: H256,
pub reserved_hash: H256,
pub final_sapling_root: H256,
pub time: u32,
pub bits: Compact,
pub nonce: H256,
@ -30,7 +30,7 @@ impl BlockHeader {
stream.append(&self.version)
.append(&self.previous_header_hash)
.append(&self.merkle_root_hash)
.append(&self.reserved_hash)
.append(&self.final_sapling_root)
.append(&self.time)
.append(&self.bits)
.append(&self.nonce);
@ -85,7 +85,7 @@ mod tests {
version: 1,
previous_header_hash: [2; 32].into(),
merkle_root_hash: [3; 32].into(),
reserved_hash: Default::default(),
final_sapling_root: Default::default(),
time: 4,
bits: 5.into(),
nonce: 6.into(),
@ -107,7 +107,7 @@ mod tests {
version: 1,
previous_header_hash: [2; 32].into(),
merkle_root_hash: [3; 32].into(),
reserved_hash: Default::default(),
final_sapling_root: Default::default(),
time: 4,
bits: 5.into(),
nonce: 6.into(),

View File

@ -1,12 +1,11 @@
use v1::traits::BlockChain;
use v1::types::{GetBlockResponse, VerboseBlock, RawBlock};
use v1::types::{BlockRef, GetBlockResponse, VerboseBlock, RawBlock};
use v1::types::{GetTxOutResponse, TransactionOutputScript};
use v1::types::GetTxOutSetInfoResponse;
use v1::types::H256;
use v1::types::U256;
use keys::{self, Address};
use v1::helpers::errors::{block_not_found, block_at_height_not_found, transaction_not_found,
transaction_output_not_found, transaction_of_side_branch};
transaction_output_not_found, transaction_of_side_branch, invalid_params};
use jsonrpc_core::Error;
use {storage, chain};
use global_script::Script;
@ -88,28 +87,22 @@ impl BlockChainClientCoreApi for BlockChainClientCore {
None => -1,
};
let block_size = block.size();
let median_time = verification::median_timestamp(
&block.header.raw,
self.storage.as_block_header_provider()
);
VerboseBlock {
confirmations: confirmations,
size: block_size as u32,
height: height,
mediantime: Some(median_time),
difficulty: block.header.raw.bits.to_f64(self.consensus.network.max_bits().into()),
chainwork: U256::default(), // TODO: read from storage
previousblockhash: Some(block.header.raw.previous_header_hash.clone().into()),
nextblockhash: height.and_then(|h| self.storage.block_hash(h + 1).map(|h| h.into())),
bits: block.header.raw.bits.into(),
hash: block.hash().clone().into(),
merkleroot: block.header.raw.merkle_root_hash.clone().into(),
finalsaplingroot: block.header.raw.final_sapling_root.into(),
nonce: block.header.raw.nonce.clone().into(),
time: block.header.raw.time,
tx: block.transactions.into_iter().map(|t| t.hash.into()).collect(),
version: block.header.raw.version,
version_hex: format!("{:x}", &block.header.raw.version),
}
})
}
@ -201,25 +194,43 @@ impl<T> BlockChain for BlockChainClient<T> where T: BlockChainClientCoreApi {
Ok(self.core.difficulty())
}
fn block(&self, hash: H256, verbose: Option<bool>) -> Result<GetBlockResponse, Error> {
let global_hash: GlobalH256 = hash.clone().into();
if verbose.unwrap_or_default() {
let verbose_block = self.core.verbose_block(global_hash.reversed());
if let Some(mut verbose_block) = verbose_block {
verbose_block.previousblockhash = verbose_block.previousblockhash.map(|h| h.reversed());
verbose_block.nextblockhash = verbose_block.nextblockhash.map(|h| h.reversed());
verbose_block.hash = verbose_block.hash.reversed();
verbose_block.merkleroot = verbose_block.merkleroot.reversed();
verbose_block.tx = verbose_block.tx.into_iter().map(|h| h.reversed()).collect();
Some(GetBlockResponse::Verbose(verbose_block))
} else {
None
}
} else {
self.core.raw_block(global_hash.reversed())
.map(|block| GetBlockResponse::Raw(block))
fn block(&self, block: BlockRef, verbosity: Option<u8>) -> Result<GetBlockResponse, Error> {
let global_hash = match block {
BlockRef::Number(number) => self.core
.block_hash(number)
.ok_or(block_not_found(number))?,
BlockRef::Hash(hash) => {
let h: GlobalH256 = hash.into();
h.reversed()
},
};
match verbosity {
// if verbosity is 0, returns a string that is serialized, hex-encoded data for the block.
Some(0) => self.core
.raw_block(global_hash)
.map(GetBlockResponse::Raw)
.ok_or(block_not_found(global_hash.reversed())),
// if verbosity is 1, returns an Object with information about the block.
None | Some(1) => {
let verbose_block = self.core.verbose_block(global_hash);
if let Some(mut verbose_block) = verbose_block {
verbose_block.previousblockhash = verbose_block.previousblockhash.map(|h| h.reversed());
verbose_block.nextblockhash = verbose_block.nextblockhash.map(|h| h.reversed());
verbose_block.hash = verbose_block.hash.reversed();
verbose_block.merkleroot = verbose_block.merkleroot.reversed();
verbose_block.finalsaplingroot = verbose_block.finalsaplingroot.reversed();
verbose_block.tx = verbose_block.tx.into_iter().map(|h| h.reversed()).collect();
Some(GetBlockResponse::Verbose(verbose_block))
} else {
None
}.ok_or(block_not_found(global_hash.reversed()))
},
// if verbosity is 2, returns an Object with information about the block and information about each transaction.
// we do not (yet?) support getrawtransaction call => nothing to return
Some(2) => rpc_unimplemented!(),
_ => Err(invalid_params("verbosity", verbosity)),
}
.ok_or(block_not_found(hash))
}
fn transaction_out(&self, transaction_hash: H256, out_index: u32, _include_mempool: Option<bool>) -> Result<GetTxOutResponse, Error> {
@ -295,17 +306,15 @@ pub mod tests {
size: 215,
height: Some(2),
version: 1,
version_hex: "1".to_owned(),
merkleroot: "d5fdcc541e25de1c7a5addedf24858b8bb665c9f36ef744ee42c316022c90f9b".into(),
tx: vec!["d5fdcc541e25de1c7a5addedf24858b8bb665c9f36ef744ee42c316022c90f9b".into()],
time: 1231469744,
mediantime: None,
nonce: 42.into(),
bits: 486604799,
difficulty: 1.0,
chainwork: 0.into(),
previousblockhash: Some("4860eb18bf1b1620e37e9490fc8a427514416fd75159ab86688e9a8300000000".into()),
nextblockhash: None,
finalsaplingroot: "a5556cd346010000000000000000000000000000000000000000000000000002".into(),
})
}
@ -455,9 +464,7 @@ pub mod tests {
let core = BlockChainClientCore::new(ConsensusParams::new(Network::Mainnet), storage);
// get info on block #1:
// https://blockexplorer.com/block/00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048
// https://blockchain.info/block/00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048
// https://webbtc.com/block/00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048.json
// https://zcash.blockexplorer.com/block/0007bc227e1c57a4a70e237cad00e7b7ce565155ab49166bc57397a26d339283
let verbose_block = core.verbose_block("8392336da29773c56b1649ab555156ceb7e700ad7c230ea7a4571c7e22bc0700".into());
assert_eq!(verbose_block, Some(VerboseBlock {
hash: "8392336da29773c56b1649ab555156ceb7e700ad7c230ea7a4571c7e22bc0700".into(),
@ -465,23 +472,19 @@ pub mod tests {
size: 1617,
height: Some(1),
version: 4,
version_hex: "4".to_owned(),
merkleroot: "0946edb9c083c9942d92305444527765fad789c438c717783276a9f7fbf61b85".into(),
tx: vec!["0946edb9c083c9942d92305444527765fad789c438c717783276a9f7fbf61b85".into()],
time: 1477671596,
mediantime: Some(1477641360),
nonce: "7534e8cf161ff2e49d54bdb3bfbcde8cdbf2fc5963c9ec7d86aed4a67e975790".into(),
bits: 520617983,
difficulty: 1.0,
chainwork: 0.into(),
previousblockhash: Some("08ce3d9731b000c08338455c8a4a6bd05da16e26b11daa1b917184ece80f0400".into()),
nextblockhash: Some("ed73e297d7c51cb8dc53fc2213d7e2e3f116eb4f26434496fc1926906ca20200".into()),
finalsaplingroot: "0000000000000000000000000000000000000000000000000000000000000000".into(),
}));
// get info on block #2:
// https://blockexplorer.com/block/000000006a625f06636b8bb6ac7b960a8d03705d1ace08b1a19da3fdcc99ddbd
// https://blockchain.info/ru/block/000000006a625f06636b8bb6ac7b960a8d03705d1ace08b1a19da3fdcc99ddbd
// https://webbtc.com/block/000000006a625f06636b8bb6ac7b960a8d03705d1ace08b1a19da3fdcc99ddbd.json
// https://zcash.blockexplorer.com/block/0002a26c902619fc964443264feb16f1e3e2d71322fc53dcb81cc5d797e273ed
let verbose_block = core.verbose_block("ed73e297d7c51cb8dc53fc2213d7e2e3f116eb4f26434496fc1926906ca20200".into());
assert_eq!(verbose_block, Some(VerboseBlock {
hash: "ed73e297d7c51cb8dc53fc2213d7e2e3f116eb4f26434496fc1926906ca20200".into(),
@ -489,17 +492,15 @@ pub mod tests {
size: 1617,
height: Some(2),
version: 4,
version_hex: "4".to_owned(),
merkleroot: "f4b084a7c2fc5a5aa2985f2bcb1d4a9a65562a589d628b0d869c5f1c8dd07489".into(),
tx: vec!["f4b084a7c2fc5a5aa2985f2bcb1d4a9a65562a589d628b0d869c5f1c8dd07489".into()],
time: 1477671626,
mediantime: Some(1477671596),
nonce: "a5556cd346010000000000000000000000000000000000000000000000000002".into(),
bits: 520617983,
difficulty: 1.0,
chainwork: 0.into(),
previousblockhash: Some("8392336da29773c56b1649ab555156ceb7e700ad7c230ea7a4571c7e22bc0700".into()),
nextblockhash: None,
finalsaplingroot: "0000000000000000000000000000000000000000000000000000000000000000".into(),
}));
}
@ -515,17 +516,7 @@ pub mod tests {
{
"jsonrpc": "2.0",
"method": "getblock",
"params": ["000000006a625f06636b8bb6ac7b960a8d03705d1ace08b1a19da3fdcc99ddbd", false],
"id": 1
}"#)).unwrap();
assert_eq!(&sample, expected);
// try without optional parameter
let sample = handler.handle_request_sync(&(r#"
{
"jsonrpc": "2.0",
"method": "getblock",
"params": ["000000006a625f06636b8bb6ac7b960a8d03705d1ace08b1a19da3fdcc99ddbd"],
"params": ["000000006a625f06636b8bb6ac7b960a8d03705d1ace08b1a19da3fdcc99ddbd", 0],
"id": 1
}"#)).unwrap();
assert_eq!(&sample, expected);
@ -541,7 +532,7 @@ pub mod tests {
{
"jsonrpc": "2.0",
"method": "getblock",
"params": ["000000006a625f06636b8bb6ac7b960a8d03705d1ace08b1a19da3fdcc99ddbd", false],
"params": ["000000006a625f06636b8bb6ac7b960a8d03705d1ace08b1a19da3fdcc99ddbd", 0],
"id": 1
}"#)).unwrap();
@ -554,15 +545,27 @@ pub mod tests {
let mut handler = IoHandler::new();
handler.extend_with(client.to_delegate());
let expected = r#"{"jsonrpc":"2.0","result":{"bits":486604799,"confirmations":1,"difficulty":1.0,"finalsaplingroot":"02000000000000000000000000000000000000000000000000000146d36c55a5","hash":"000000006a625f06636b8bb6ac7b960a8d03705d1ace08b1a19da3fdcc99ddbd","height":2,"merkleroot":"9b0fc92260312ce44e74ef369f5c66bbb85848f2eddd5a7a1cde251e54ccfdd5","nextblockhash":null,"nonce":"2a00000000000000000000000000000000000000000000000000000000000000","previousblockhash":"00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048","size":215,"time":1231469744,"tx":["9b0fc92260312ce44e74ef369f5c66bbb85848f2eddd5a7a1cde251e54ccfdd5"],"version":1},"id":1}"#;
let sample = handler.handle_request_sync(&(r#"
{
"jsonrpc": "2.0",
"method": "getblock",
"params": ["000000006a625f06636b8bb6ac7b960a8d03705d1ace08b1a19da3fdcc99ddbd",true],
"params": ["000000006a625f06636b8bb6ac7b960a8d03705d1ace08b1a19da3fdcc99ddbd",1],
"id": 1
}"#)).unwrap();
assert_eq!(&sample, r#"{"jsonrpc":"2.0","result":{"bits":486604799,"chainwork":"0","confirmations":1,"difficulty":1.0,"hash":"000000006a625f06636b8bb6ac7b960a8d03705d1ace08b1a19da3fdcc99ddbd","height":2,"mediantime":null,"merkleroot":"9b0fc92260312ce44e74ef369f5c66bbb85848f2eddd5a7a1cde251e54ccfdd5","nextblockhash":null,"nonce":"2a00000000000000000000000000000000000000000000000000000000000000","previousblockhash":"00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048","size":215,"time":1231469744,"tx":["9b0fc92260312ce44e74ef369f5c66bbb85848f2eddd5a7a1cde251e54ccfdd5"],"version":1,"versionHex":"1"},"id":1}"#);
assert_eq!(&sample, expected);
// try without optional parameter
let sample = handler.handle_request_sync(&(r#"
{
"jsonrpc": "2.0",
"method": "getblock",
"params": ["000000006a625f06636b8bb6ac7b960a8d03705d1ace08b1a19da3fdcc99ddbd"],
"id": 1
}"#)).unwrap();
assert_eq!(&sample, expected);
}
#[test]
@ -575,7 +578,7 @@ pub mod tests {
{
"jsonrpc": "2.0",
"method": "getblock",
"params": ["000000006a625f06636b8bb6ac7b960a8d03705d1ace08b1a19da3fdcc99ddbd", true],
"params": ["000000006a625f06636b8bb6ac7b960a8d03705d1ace08b1a19da3fdcc99ddbd", 1],
"id": 1
}"#)).unwrap();

View File

@ -1,7 +1,7 @@
use jsonrpc_derive::rpc;
use jsonrpc_core::Error;
use v1::types::H256;
use v1::types::{BlockRef, H256};
use v1::types::GetBlockResponse;
use v1::types::GetTxOutResponse;
use v1::types::GetTxOutSetInfoResponse;
@ -26,9 +26,10 @@ pub trait BlockChain {
#[rpc(name = "getdifficulty")]
fn difficulty(&self) -> Result<f64, Error>;
/// Get information on given block.
/// @curl-example: curl --data-binary '{"jsonrpc": "2.0", "method": "getblock", "params": ["000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"], "id":1 }' -H 'content-type: application/json' http://127.0.0.1:8332/
/// @curl-example: curl --data-binary '{"jsonrpc": "2.0", "method": "getblock", "params": ["0002a26c902619fc964443264feb16f1e3e2d71322fc53dcb81cc5d797e273ed", 0], "id":1 }' -H 'content-type: application/json' http://127.0.0.1:8332/
/// @curl-example: curl --data-binary '{"jsonrpc": "2.0", "method": "getblock", "params": ["0002a26c902619fc964443264feb16f1e3e2d71322fc53dcb81cc5d797e273ed"], "id":1 }' -H 'content-type: application/json' http://127.0.0.1:8332/
#[rpc(name = "getblock")]
fn block(&self, H256, Option<bool>) -> Result<GetBlockResponse, Error>;
fn block(&self, BlockRef, Option<u8>) -> Result<GetBlockResponse, Error>;
/// Get details about an unspent transaction output.
/// @curl-example: curl --data-binary '{"jsonrpc": "2.0", "method": "gettxout", "params": ["4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b", 0], "id":1 }' -H 'content-type: application/json' http://127.0.0.1:8332/
#[rpc(name = "gettxout")]

View File

@ -1,4 +1,43 @@
use std::fmt;
use std::str::FromStr;
use serde::de::{Deserialize, Deserializer, Unexpected};
use super::bytes::Bytes;
use super::hash::H256;
/// Hex-encoded block
pub type RawBlock = Bytes;
/// Block reference
#[derive(Debug)]
pub enum BlockRef {
Number(u32),
Hash(H256),
}
impl<'a> Deserialize<'a> for BlockRef {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'a> {
use serde::de::Visitor;
struct DummyVisitor;
impl<'b> Visitor<'b> for DummyVisitor {
type Value = BlockRef;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("either block number of hash")
}
fn visit_str<E>(self, value: &str) -> Result<BlockRef, E> where E: ::serde::de::Error {
if value.len() == 64 {
H256::from_str(value).map(BlockRef::Hash)
.map_err(|_| E::invalid_value(Unexpected::Str(value), &self))
} else {
u32::from_str(value).map(BlockRef::Number)
.map_err(|_| E::invalid_value(Unexpected::Str(value), &self))
}
}
}
deserializer.deserialize_identifier(DummyVisitor)
}
}

View File

@ -1,6 +1,5 @@
use serde::{Serialize, Serializer};
use super::hash::H256;
use super::uint::U256;
use super::block::RawBlock;
/// Response to getblock RPC request
@ -26,26 +25,20 @@ pub struct VerboseBlock {
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,
/// The root of the Sapling commitment tree after applying this block.
pub finalsaplingroot: 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: H256,
/// 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
@ -65,14 +58,13 @@ impl Serialize for GetBlockResponse {
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,"height":null,"version":0,"versionHex":"","merkleroot":"0000000000000000000000000000000000000000000000000000000000000000","tx":[],"time":0,"mediantime":null,"nonce":"0000000000000000000000000000000000000000000000000000000000000000","bits":0,"difficulty":0.0,"chainwork":"0","previousblockhash":null,"nextblockhash":null}"#);
assert_eq!(serde_json::to_string(&block).unwrap(), r#"{"hash":"0000000000000000000000000000000000000000000000000000000000000000","confirmations":0,"size":0,"height":null,"version":0,"merkleroot":"0000000000000000000000000000000000000000000000000000000000000000","finalsaplingroot":"0000000000000000000000000000000000000000000000000000000000000000","tx":[],"time":0,"nonce":"0000000000000000000000000000000000000000000000000000000000000000","bits":0,"difficulty":0.0,"previousblockhash":null,"nextblockhash":null}"#);
let block = VerboseBlock {
hash: H256::from(1),
@ -80,26 +72,24 @@ mod tests {
size: 500000,
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.into(),
bits: 13513,
difficulty: 555.555,
chainwork: U256::from(3),
previousblockhash: Some(H256::from(4)),
nextblockhash: Some(H256::from(5)),
finalsaplingroot: H256::from(3),
};
assert_eq!(serde_json::to_string(&block).unwrap(), r#"{"hash":"0100000000000000000000000000000000000000000000000000000000000000","confirmations":-1,"size":500000,"height":3513513,"version":1,"versionHex":"01","merkleroot":"0200000000000000000000000000000000000000000000000000000000000000","tx":["0300000000000000000000000000000000000000000000000000000000000000","0400000000000000000000000000000000000000000000000000000000000000"],"time":111,"mediantime":100,"nonce":"7c00000000000000000000000000000000000000000000000000000000000000","bits":13513,"difficulty":555.555,"chainwork":"3","previousblockhash":"0400000000000000000000000000000000000000000000000000000000000000","nextblockhash":"0500000000000000000000000000000000000000000000000000000000000000"}"#);
assert_eq!(serde_json::to_string(&block).unwrap(), r#"{"hash":"0100000000000000000000000000000000000000000000000000000000000000","confirmations":-1,"size":500000,"height":3513513,"version":1,"merkleroot":"0200000000000000000000000000000000000000000000000000000000000000","finalsaplingroot":"0300000000000000000000000000000000000000000000000000000000000000","tx":["0300000000000000000000000000000000000000000000000000000000000000","0400000000000000000000000000000000000000000000000000000000000000"],"time":111,"nonce":"7c00000000000000000000000000000000000000000000000000000000000000","bits":13513,"difficulty":555.555,"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,"height":null,"version":0,"versionHex":"","merkleroot":"0000000000000000000000000000000000000000000000000000000000000000","tx":[],"time":0,"mediantime":null,"nonce":"0000000000000000000000000000000000000000000000000000000000000000","bits":0,"difficulty":0.0,"chainwork":"0","previousblockhash":null,"nextblockhash":null}"#).unwrap(),
serde_json::from_str::<VerboseBlock>(r#"{"hash":"0000000000000000000000000000000000000000000000000000000000000000","confirmations":0,"size":0,"height":null,"version":0,"merkleroot":"0000000000000000000000000000000000000000000000000000000000000000","finalsaplingroot":"0000000000000000000000000000000000000000000000000000000000000000","tx":[],"time":0,"nonce":"0000000000000000000000000000000000000000000000000000000000000000","bits":0,"difficulty":0.0,"previousblockhash":null,"nextblockhash":null}"#).unwrap(),
block);
let block = VerboseBlock {
@ -108,20 +98,18 @@ mod tests {
size: 500000,
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.into(),
bits: 13513,
difficulty: 555.555,
chainwork: U256::from(3),
previousblockhash: Some(H256::from(4)),
nextblockhash: Some(H256::from(5)),
finalsaplingroot: H256::from(3),
};
assert_eq!(
serde_json::from_str::<VerboseBlock>(r#"{"hash":"0100000000000000000000000000000000000000000000000000000000000000","confirmations":-1,"size":500000,"height":3513513,"version":1,"versionHex":"01","merkleroot":"0200000000000000000000000000000000000000000000000000000000000000","tx":["0300000000000000000000000000000000000000000000000000000000000000","0400000000000000000000000000000000000000000000000000000000000000"],"time":111,"mediantime":100,"nonce":"7c00000000000000000000000000000000000000000000000000000000000000","bits":13513,"difficulty":555.555,"chainwork":"3","previousblockhash":"0400000000000000000000000000000000000000000000000000000000000000","nextblockhash":"0500000000000000000000000000000000000000000000000000000000000000"}"#).unwrap(),
serde_json::from_str::<VerboseBlock>(r#"{"hash":"0100000000000000000000000000000000000000000000000000000000000000","confirmations":-1,"size":500000,"height":3513513,"version":1,"merkleroot":"0200000000000000000000000000000000000000000000000000000000000000","finalsaplingroot":"0300000000000000000000000000000000000000000000000000000000000000","tx":["0300000000000000000000000000000000000000000000000000000000000000","0400000000000000000000000000000000000000000000000000000000000000"],"time":111,"nonce":"7c00000000000000000000000000000000000000000000000000000000000000","bits":13513,"difficulty":555.555,"previousblockhash":"0400000000000000000000000000000000000000000000000000000000000000","nextblockhash":"0500000000000000000000000000000000000000000000000000000000000000"}"#).unwrap(),
block);
}
@ -135,6 +123,6 @@ mod tests {
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,"height":null,"version":0,"versionHex":"","merkleroot":"0000000000000000000000000000000000000000000000000000000000000000","tx":[],"time":0,"mediantime":null,"nonce":"0000000000000000000000000000000000000000000000000000000000000000","bits":0,"difficulty":0.0,"chainwork":"0","previousblockhash":null,"nextblockhash":null}"#);
assert_eq!(serde_json::to_string(&verbose_response).unwrap(), r#"{"hash":"0000000000000000000000000000000000000000000000000000000000000000","confirmations":0,"size":0,"height":null,"version":0,"merkleroot":"0000000000000000000000000000000000000000000000000000000000000000","finalsaplingroot":"0000000000000000000000000000000000000000000000000000000000000000","tx":[],"time":0,"nonce":"0000000000000000000000000000000000000000000000000000000000000000","bits":0,"difficulty":0.0,"previousblockhash":null,"nextblockhash":null}"#);
}
}

View File

@ -12,7 +12,7 @@ mod transaction;
mod uint;
mod nodes;
pub use self::block::RawBlock;
pub use self::block::{BlockRef, RawBlock};
pub use self::block_template::{BlockTemplate, BlockTemplateTransaction};
pub use self::block_template_request::{BlockTemplateRequest, BlockTemplateRequestMode};
pub use self::bytes::Bytes;

View File

@ -254,7 +254,7 @@ impl<F> BlockHeaderBuilder<F> where F: Invoke<chain::BlockHeader> {
nonce: self.nonce.into(),
merkle_root_hash: self.merkle_root,
version: self.version,
reserved_hash: Default::default(),
final_sapling_root: Default::default(),
solution: chain::EquihashSolution::default(),
}
)

View File

@ -279,7 +279,7 @@ mod tests {
time: time,
bits: 0.into(),
nonce: (height as u8).into(),
reserved_hash: Default::default(),
final_sapling_root: Default::default(),
solution: Default::default(),
};
previous_header_hash = header.hash();

View File

@ -193,7 +193,7 @@ mod tests {
previous_header_hash: 0.into(),
merkle_root_hash: 0.into(),
nonce: 0.into(),
reserved_hash: Default::default(),
final_sapling_root: Default::default(),
solution: Default::default(),
});
@ -206,7 +206,7 @@ mod tests {
previous_header_hash: header_provider.by_height[i as usize - 1].hash(),
merkle_root_hash: 0.into(),
nonce: 0.into(),
reserved_hash: Default::default(),
final_sapling_root: Default::default(),
solution: Default::default(),
};
header_provider.insert(header);