From 753b69995b18f08a16c6bb37f2b84bea24d91089 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 14 Jan 2019 13:50:41 +0300 Subject: [PATCH] getblock RPC --- JSON-RPC.md | 2 +- chain/src/block_header.rs | 8 +- rpc/src/v1/impls/blockchain.rs | 119 +++++++++++++------------ rpc/src/v1/traits/blockchain.rs | 7 +- rpc/src/v1/types/block.rs | 39 ++++++++ rpc/src/v1/types/get_block_response.rs | 30 ++----- rpc/src/v1/types/mod.rs | 2 +- test-data/src/block.rs | 2 +- verification/src/deployments.rs | 2 +- verification/src/work.rs | 4 +- 10 files changed, 123 insertions(+), 92 deletions(-) diff --git a/JSON-RPC.md b/JSON-RPC.md index c20f2cda..6518e16a 100644 --- a/JSON-RPC.md +++ b/JSON-RPC.md @@ -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 diff --git a/chain/src/block_header.rs b/chain/src/block_header.rs index 488c4cf4..81ebd9bb 100644 --- a/chain/src/block_header.rs +++ b/chain/src/block_header.rs @@ -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(), diff --git a/rpc/src/v1/impls/blockchain.rs b/rpc/src/v1/impls/blockchain.rs index a409c3fb..a08e7224 100644 --- a/rpc/src/v1/impls/blockchain.rs +++ b/rpc/src/v1/impls/blockchain.rs @@ -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 BlockChain for BlockChainClient where T: BlockChainClientCoreApi { Ok(self.core.difficulty()) } - fn block(&self, hash: H256, verbose: Option) -> Result { - 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) -> Result { + 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) -> Result { @@ -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(); diff --git a/rpc/src/v1/traits/blockchain.rs b/rpc/src/v1/traits/blockchain.rs index 811bb189..f4d43681 100644 --- a/rpc/src/v1/traits/blockchain.rs +++ b/rpc/src/v1/traits/blockchain.rs @@ -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; /// 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) -> Result; + fn block(&self, BlockRef, Option) -> Result; /// 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")] diff --git a/rpc/src/v1/types/block.rs b/rpc/src/v1/types/block.rs index e79fc43d..a0ae518f 100644 --- a/rpc/src/v1/types/block.rs +++ b/rpc/src/v1/types/block.rs @@ -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(deserializer: D) -> Result 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(self, value: &str) -> Result 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) + } +} \ No newline at end of file diff --git a/rpc/src/v1/types/get_block_response.rs b/rpc/src/v1/types/get_block_response.rs index 859a8251..42251c1b 100644 --- a/rpc/src/v1/types/get_block_response.rs +++ b/rpc/src/v1/types/get_block_response.rs @@ -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, /// 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, /// 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, /// 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, /// 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::(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::(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::(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::(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}"#); } } diff --git a/rpc/src/v1/types/mod.rs b/rpc/src/v1/types/mod.rs index 8e4bee7f..8dc37d39 100644 --- a/rpc/src/v1/types/mod.rs +++ b/rpc/src/v1/types/mod.rs @@ -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; diff --git a/test-data/src/block.rs b/test-data/src/block.rs index 6b44f3da..8ada48f9 100644 --- a/test-data/src/block.rs +++ b/test-data/src/block.rs @@ -254,7 +254,7 @@ impl BlockHeaderBuilder where F: Invoke { 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(), } ) diff --git a/verification/src/deployments.rs b/verification/src/deployments.rs index 09f350bd..de02743b 100644 --- a/verification/src/deployments.rs +++ b/verification/src/deployments.rs @@ -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(); diff --git a/verification/src/work.rs b/verification/src/work.rs index 1d673958..23fcf3fc 100644 --- a/verification/src/work.rs +++ b/verification/src/work.rs @@ -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);