Merge pull request #35 from paritytech/rpc_getblock
Updated getblock RPC
This commit is contained in:
commit
e50dc7be14
|
@ -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
|
||||
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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());
|
||||
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)),
|
||||
}
|
||||
} else {
|
||||
self.core.raw_block(global_hash.reversed())
|
||||
.map(|block| GetBlockResponse::Raw(block))
|
||||
}
|
||||
.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();
|
||||
|
||||
|
|
|
@ -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")]
|
||||
|
|
|
@ -1,4 +1,45 @@
|
|||
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 {
|
||||
/// References block by its number
|
||||
Number(u32),
|
||||
/// References block by its hash
|
||||
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 BlockRefVisitor;
|
||||
|
||||
impl<'b> Visitor<'b> for BlockRefVisitor {
|
||||
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(BlockRefVisitor)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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}"#);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(),
|
||||
}
|
||||
)
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue