change(rpc): Update `getblock` RPC to more closely match zcashd (#9006)
* rpc: align getblock with zcashd behaviour * Removes handling for verbosity = 3 in getblock method, adds finalorchardroot field, removes unnecessary state request. (#9008) * align final(sapling|orchard)root with zcashd behaviour * fix test * Apply suggestions from code review Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * restore getblock docs; remove unneeded TODOs * Update zebra-rpc/src/methods.rs Co-authored-by: Arya <aryasolhi@gmail.com> * get rif of cloning self (#9044) --------- Co-authored-by: Arya <aryasolhi@gmail.com> Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
parent
e15184d39b
commit
d1ae441ab9
|
@ -11,6 +11,10 @@ use jsonrpc_core::{Error, ErrorCode};
|
|||
/// <https://github.com/s-nomp/node-stratum-pool/blob/d86ae73f8ff968d9355bb61aac05e0ebef36ccb5/lib/pool.js#L459>
|
||||
pub const INVALID_PARAMETERS_ERROR_CODE: ErrorCode = ErrorCode::ServerError(-1);
|
||||
|
||||
/// The RPC error code used by `zcashd` for missing blocks, when looked up
|
||||
/// by hash.
|
||||
pub const INVALID_ADDRESS_OR_KEY_ERROR_CODE: ErrorCode = ErrorCode::ServerError(-5);
|
||||
|
||||
/// The RPC error code used by `zcashd` for missing blocks.
|
||||
///
|
||||
/// `lightwalletd` expects error code `-8` when a block is not found:
|
||||
|
|
|
@ -37,7 +37,9 @@ use zebra_node_services::mempool;
|
|||
use zebra_state::{HashOrHeight, MinedTx, OutputIndex, OutputLocation, TransactionLocation};
|
||||
|
||||
use crate::{
|
||||
constants::{INVALID_PARAMETERS_ERROR_CODE, MISSING_BLOCK_ERROR_CODE},
|
||||
constants::{
|
||||
INVALID_ADDRESS_OR_KEY_ERROR_CODE, INVALID_PARAMETERS_ERROR_CODE, MISSING_BLOCK_ERROR_CODE,
|
||||
},
|
||||
methods::trees::{GetSubtrees, GetTreestate, SubtreeRpcData},
|
||||
queue::Queue,
|
||||
};
|
||||
|
@ -145,7 +147,8 @@ pub trait Rpc {
|
|||
|
||||
/// Returns the requested block by hash or height, as a [`GetBlock`] JSON string.
|
||||
/// If the block is not in Zebra's state, returns
|
||||
/// [error code `-8`.](https://github.com/zcash/zcash/issues/5758)
|
||||
/// [error code `-8`.](https://github.com/zcash/zcash/issues/5758) if a height was
|
||||
/// passed or -5 if a hash was passed.
|
||||
///
|
||||
/// zcashd reference: [`getblock`](https://zcash.github.io/rpc/getblock.html)
|
||||
/// method: post
|
||||
|
@ -158,12 +161,14 @@ pub trait Rpc {
|
|||
///
|
||||
/// # Notes
|
||||
///
|
||||
/// With verbosity=1, [`lightwalletd` only reads the `tx` field of the
|
||||
/// result](https://github.com/zcash/lightwalletd/blob/dfac02093d85fb31fb9a8475b884dd6abca966c7/common/common.go#L152),
|
||||
/// and other clients only read the `hash` and `confirmations` fields,
|
||||
/// so we only return a few fields for now.
|
||||
/// Zebra previously partially supported verbosity=1 by returning only the
|
||||
/// fields required by lightwalletd ([`lightwalletd` only reads the `tx`
|
||||
/// field of the result](https://github.com/zcash/lightwalletd/blob/dfac02093d85fb31fb9a8475b884dd6abca966c7/common/common.go#L152)).
|
||||
/// That verbosity level was migrated to "3"; so while lightwalletd will
|
||||
/// still work by using verbosity=1, it will sync faster if it is changed to
|
||||
/// use verbosity=3.
|
||||
///
|
||||
/// `lightwalletd` and mining clients also do not use verbosity=2, so we don't support it.
|
||||
/// The undocumented `chainwork` field is not returned.
|
||||
#[rpc(name = "getblock")]
|
||||
fn get_block(
|
||||
&self,
|
||||
|
@ -172,6 +177,9 @@ pub trait Rpc {
|
|||
) -> BoxFuture<Result<GetBlock>>;
|
||||
|
||||
/// Returns the requested block header by hash or height, as a [`GetBlockHeader`] JSON string.
|
||||
/// If the block is not in Zebra's state,
|
||||
/// returns [error code `-8`.](https://github.com/zcash/zcash/issues/5758)
|
||||
/// if a height was passed or -5 if a hash was passed.
|
||||
///
|
||||
/// zcashd reference: [`getblockheader`](https://zcash.github.io/rpc/getblockheader.html)
|
||||
/// method: post
|
||||
|
@ -181,6 +189,10 @@ pub trait Rpc {
|
|||
///
|
||||
/// - `hash_or_height`: (string, required, example="1") The hash or height for the block to be returned.
|
||||
/// - `verbose`: (bool, optional, default=false, example=true) false for hex encoded data, true for a json object
|
||||
///
|
||||
/// # Notes
|
||||
///
|
||||
/// The undocumented `chainwork` field is not returned.
|
||||
#[rpc(name = "getblockheader")]
|
||||
fn get_block_header(
|
||||
&self,
|
||||
|
@ -738,6 +750,15 @@ where
|
|||
|
||||
let mut state = self.state.clone();
|
||||
let verbosity = verbosity.unwrap_or(DEFAULT_GETBLOCK_VERBOSITY);
|
||||
let network = self.network.clone();
|
||||
let original_hash_or_height = hash_or_height.clone();
|
||||
|
||||
// If verbosity requires a call to `get_block_header`, resolve it here
|
||||
let get_block_header_future = if matches!(verbosity, 1 | 2) {
|
||||
Some(self.get_block_header(original_hash_or_height.clone(), Some(true)))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
async move {
|
||||
let hash_or_height: HashOrHeight = hash_or_height.parse().map_server_error()?;
|
||||
|
@ -765,58 +786,36 @@ where
|
|||
}),
|
||||
_ => unreachable!("unmatched response to a block request"),
|
||||
}
|
||||
} else if verbosity == 1 || verbosity == 2 {
|
||||
// # Performance
|
||||
//
|
||||
// This RPC is used in `lightwalletd`'s initial sync of 2 million blocks,
|
||||
// so it needs to load all its fields very efficiently.
|
||||
//
|
||||
// Currently, we get the block hash and transaction IDs from indexes,
|
||||
// which is much more efficient than loading all the block data,
|
||||
// then hashing the block header and all the transactions.
|
||||
} else if let Some(get_block_header_future) = get_block_header_future {
|
||||
let get_block_header_result: Result<GetBlockHeader> = get_block_header_future.await;
|
||||
|
||||
// Get the block hash from the height -> hash index, if needed
|
||||
//
|
||||
// # Concurrency
|
||||
//
|
||||
// For consistency, this lookup must be performed first, then all the other
|
||||
// lookups must be based on the hash.
|
||||
//
|
||||
// All possible responses are valid, even if the best chain changes. Clients
|
||||
// must be able to handle chain forks, including a hash for a block that is
|
||||
// later discovered to be on a side chain.
|
||||
|
||||
let should_read_block_header = verbosity == 2;
|
||||
|
||||
let hash = match hash_or_height {
|
||||
HashOrHeight::Hash(hash) => hash,
|
||||
HashOrHeight::Height(height) => {
|
||||
let request = zebra_state::ReadRequest::BestChainBlockHash(height);
|
||||
let response = state
|
||||
.ready()
|
||||
.and_then(|service| service.call(request))
|
||||
.await
|
||||
.map_server_error()?;
|
||||
|
||||
match response {
|
||||
zebra_state::ReadResponse::BlockHash(Some(hash)) => hash,
|
||||
zebra_state::ReadResponse::BlockHash(None) => {
|
||||
return Err(Error {
|
||||
code: MISSING_BLOCK_ERROR_CODE,
|
||||
message: "block height not in best chain".to_string(),
|
||||
data: None,
|
||||
})
|
||||
}
|
||||
_ => unreachable!("unmatched response to a block hash request"),
|
||||
}
|
||||
}
|
||||
let GetBlockHeader::Object(block_header) = get_block_header_result? else {
|
||||
panic!("must return Object")
|
||||
};
|
||||
|
||||
let GetBlockHeaderObject {
|
||||
hash,
|
||||
confirmations,
|
||||
height,
|
||||
version,
|
||||
merkle_root,
|
||||
final_sapling_root,
|
||||
sapling_tree_size,
|
||||
time,
|
||||
nonce,
|
||||
solution,
|
||||
bits,
|
||||
difficulty,
|
||||
previous_block_hash,
|
||||
next_block_hash,
|
||||
} = *block_header;
|
||||
|
||||
// # Concurrency
|
||||
//
|
||||
// We look up by block hash so the hash, transaction IDs, and confirmations
|
||||
// are consistent.
|
||||
let mut requests = vec![
|
||||
let hash_or_height = hash.0.into();
|
||||
let requests = vec![
|
||||
// Get transaction IDs from the transaction index by block hash
|
||||
//
|
||||
// # Concurrency
|
||||
|
@ -824,27 +823,11 @@ where
|
|||
// A block's transaction IDs are never modified, so all possible responses are
|
||||
// valid. Clients that query block heights must be able to handle chain forks,
|
||||
// including getting transaction IDs from any chain fork.
|
||||
zebra_state::ReadRequest::TransactionIdsForBlock(hash.into()),
|
||||
// Sapling trees
|
||||
zebra_state::ReadRequest::SaplingTree(hash.into()),
|
||||
zebra_state::ReadRequest::TransactionIdsForBlock(hash_or_height),
|
||||
// Orchard trees
|
||||
zebra_state::ReadRequest::OrchardTree(hash.into()),
|
||||
// Get block confirmations from the block height index
|
||||
//
|
||||
// # Concurrency
|
||||
//
|
||||
// All possible responses are valid, even if a block is added to the chain, or
|
||||
// the best chain changes. Clients must be able to handle chain forks, including
|
||||
// different confirmation values before or after added blocks, and switching
|
||||
// between -1 and multiple different confirmation values.
|
||||
zebra_state::ReadRequest::Depth(hash),
|
||||
zebra_state::ReadRequest::OrchardTree(hash_or_height),
|
||||
];
|
||||
|
||||
if should_read_block_header {
|
||||
// Block header
|
||||
requests.push(zebra_state::ReadRequest::BlockHeader(hash.into()))
|
||||
}
|
||||
|
||||
let mut futs = FuturesOrdered::new();
|
||||
|
||||
for request in requests {
|
||||
|
@ -861,65 +844,55 @@ where
|
|||
_ => unreachable!("unmatched response to a transaction_ids_for_block request"),
|
||||
};
|
||||
|
||||
let sapling_tree_response = futs.next().await.expect("`futs` should not be empty");
|
||||
let sapling_note_commitment_tree_count =
|
||||
match sapling_tree_response.map_server_error()? {
|
||||
zebra_state::ReadResponse::SaplingTree(Some(nct)) => nct.count(),
|
||||
zebra_state::ReadResponse::SaplingTree(None) => 0,
|
||||
_ => unreachable!("unmatched response to a SaplingTree request"),
|
||||
};
|
||||
|
||||
let orchard_tree_response = futs.next().await.expect("`futs` should not be empty");
|
||||
let orchard_note_commitment_tree_count =
|
||||
match orchard_tree_response.map_server_error()? {
|
||||
zebra_state::ReadResponse::OrchardTree(Some(nct)) => nct.count(),
|
||||
zebra_state::ReadResponse::OrchardTree(None) => 0,
|
||||
_ => unreachable!("unmatched response to a OrchardTree request"),
|
||||
};
|
||||
|
||||
// From <https://zcash.github.io/rpc/getblock.html>
|
||||
const NOT_IN_BEST_CHAIN_CONFIRMATIONS: i64 = -1;
|
||||
|
||||
let depth_response = futs.next().await.expect("`futs` should not be empty");
|
||||
let confirmations = match depth_response.map_server_error()? {
|
||||
// Confirmations are one more than the depth.
|
||||
// Depth is limited by height, so it will never overflow an i64.
|
||||
zebra_state::ReadResponse::Depth(Some(depth)) => i64::from(depth) + 1,
|
||||
zebra_state::ReadResponse::Depth(None) => NOT_IN_BEST_CHAIN_CONFIRMATIONS,
|
||||
_ => unreachable!("unmatched response to a depth request"),
|
||||
let zebra_state::ReadResponse::OrchardTree(orchard_tree) =
|
||||
orchard_tree_response.map_server_error()?
|
||||
else {
|
||||
unreachable!("unmatched response to a OrchardTree request");
|
||||
};
|
||||
|
||||
let (time, height) = if should_read_block_header {
|
||||
let block_header_response =
|
||||
futs.next().await.expect("`futs` should not be empty");
|
||||
let nu5_activation = NetworkUpgrade::Nu5.activation_height(&network);
|
||||
|
||||
match block_header_response.map_server_error()? {
|
||||
zebra_state::ReadResponse::BlockHeader { header, height, .. } => {
|
||||
(Some(header.time.timestamp()), Some(height))
|
||||
}
|
||||
_ => unreachable!("unmatched response to a BlockHeader request"),
|
||||
// This could be `None` if there's a chain reorg between state queries.
|
||||
let orchard_tree =
|
||||
orchard_tree.ok_or_server_error("missing orchard tree for block")?;
|
||||
|
||||
let final_orchard_root = match nu5_activation {
|
||||
Some(activation_height) if height >= activation_height => {
|
||||
Some(orchard_tree.root().into())
|
||||
}
|
||||
} else {
|
||||
(None, hash_or_height.height())
|
||||
_other => None,
|
||||
};
|
||||
|
||||
let sapling = SaplingTrees {
|
||||
size: sapling_note_commitment_tree_count,
|
||||
size: sapling_tree_size,
|
||||
};
|
||||
|
||||
let orchard_tree_size = orchard_tree.count();
|
||||
let orchard = OrchardTrees {
|
||||
size: orchard_note_commitment_tree_count,
|
||||
size: orchard_tree_size,
|
||||
};
|
||||
|
||||
let trees = GetBlockTrees { sapling, orchard };
|
||||
|
||||
Ok(GetBlock::Object {
|
||||
hash: GetBlockHash(hash),
|
||||
hash,
|
||||
confirmations,
|
||||
height,
|
||||
time,
|
||||
height: Some(height),
|
||||
version: Some(version),
|
||||
merkle_root: Some(merkle_root),
|
||||
time: Some(time),
|
||||
nonce: Some(nonce),
|
||||
solution: Some(solution),
|
||||
bits: Some(bits),
|
||||
difficulty: Some(difficulty),
|
||||
tx,
|
||||
trees,
|
||||
size: None,
|
||||
final_sapling_root: Some(final_sapling_root),
|
||||
final_orchard_root,
|
||||
previous_block_hash: Some(previous_block_hash),
|
||||
next_block_hash,
|
||||
})
|
||||
} else {
|
||||
Err(Error {
|
||||
|
@ -952,7 +925,18 @@ where
|
|||
.clone()
|
||||
.oneshot(zebra_state::ReadRequest::BlockHeader(hash_or_height))
|
||||
.await
|
||||
.map_server_error()?
|
||||
.map_err(|_| Error {
|
||||
// Compatibility with zcashd. Note that since this function
|
||||
// is reused by getblock(), we return the errors expected
|
||||
// by it (they differ whether a hash or a height was passed)
|
||||
code: if hash_or_height.hash().is_some() {
|
||||
INVALID_ADDRESS_OR_KEY_ERROR_CODE
|
||||
} else {
|
||||
MISSING_BLOCK_ERROR_CODE
|
||||
},
|
||||
message: "block height not in best chain".to_string(),
|
||||
data: None,
|
||||
})?
|
||||
else {
|
||||
panic!("unexpected response to BlockHeader request")
|
||||
};
|
||||
|
@ -995,13 +979,16 @@ where
|
|||
let mut nonce = *header.nonce;
|
||||
nonce.reverse();
|
||||
|
||||
let final_sapling_root: [u8; 32] = if sapling_tree.position().is_some() {
|
||||
let mut root: [u8; 32] = sapling_tree.root().into();
|
||||
root.reverse();
|
||||
root
|
||||
} else {
|
||||
[0; 32]
|
||||
};
|
||||
let sapling_activation = NetworkUpgrade::Sapling.activation_height(&network);
|
||||
let sapling_tree_size = sapling_tree.count();
|
||||
let final_sapling_root: [u8; 32] =
|
||||
if sapling_activation.is_some() && height >= sapling_activation.unwrap() {
|
||||
let mut root: [u8; 32] = sapling_tree.root().into();
|
||||
root.reverse();
|
||||
root
|
||||
} else {
|
||||
[0; 32]
|
||||
};
|
||||
|
||||
let difficulty = header.difficulty_threshold.relative_to_network(&network);
|
||||
|
||||
|
@ -1012,6 +999,7 @@ where
|
|||
version: header.version,
|
||||
merkle_root: header.merkle_root,
|
||||
final_sapling_root,
|
||||
sapling_tree_size,
|
||||
time: header.time.timestamp(),
|
||||
nonce,
|
||||
solution: header.solution,
|
||||
|
@ -1736,8 +1724,9 @@ impl Default for SentTransactionHash {
|
|||
/// Response to a `getblock` RPC request.
|
||||
///
|
||||
/// See the notes for the [`Rpc::get_block`] method.
|
||||
#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)]
|
||||
#[derive(Clone, Debug, PartialEq, serde::Serialize)]
|
||||
#[serde(untagged)]
|
||||
#[allow(clippy::large_enum_variant)] //TODO: create a struct for the Object and Box it
|
||||
pub enum GetBlock {
|
||||
/// The request block, hex-encoded.
|
||||
Raw(#[serde(with = "hex")] SerializedBlock),
|
||||
|
@ -1750,21 +1739,84 @@ pub enum GetBlock {
|
|||
/// or -1 if it is not in the best chain.
|
||||
confirmations: i64,
|
||||
|
||||
/// The block size. TODO: fill it
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
size: Option<i64>,
|
||||
|
||||
/// The height of the requested block.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
height: Option<Height>,
|
||||
|
||||
/// The version field of the requested block.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
version: Option<u32>,
|
||||
|
||||
/// The merkle root of the requested block.
|
||||
#[serde(with = "opthex", rename = "merkleroot")]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
merkle_root: Option<block::merkle::Root>,
|
||||
|
||||
// `blockcommitments` would be here. Undocumented. TODO: decide if we want to support it
|
||||
// `authdataroot` would be here. Undocumented. TODO: decide if we want to support it
|
||||
//
|
||||
/// The root of the Sapling commitment tree after applying this block.
|
||||
#[serde(with = "opthex", rename = "finalsaplingroot")]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
final_sapling_root: Option<[u8; 32]>,
|
||||
|
||||
/// The root of the Orchard commitment tree after applying this block.
|
||||
#[serde(with = "opthex", rename = "finalorchardroot")]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
final_orchard_root: Option<[u8; 32]>,
|
||||
|
||||
// `chainhistoryroot` would be here. Undocumented. TODO: decide if we want to support it
|
||||
//
|
||||
/// List of transaction IDs in block order, hex-encoded.
|
||||
//
|
||||
// TODO: use a typed Vec<transaction::Hash> here
|
||||
// TODO: support Objects
|
||||
tx: Vec<String>,
|
||||
|
||||
/// The height of the requested block.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
time: Option<i64>,
|
||||
|
||||
/// List of transaction IDs in block order, hex-encoded.
|
||||
//
|
||||
// TODO: use a typed Vec<transaction::Hash> here
|
||||
tx: Vec<String>,
|
||||
/// The nonce of the requested block header.
|
||||
#[serde(with = "opthex")]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
nonce: Option<[u8; 32]>,
|
||||
|
||||
/// The Equihash solution in the requested block header.
|
||||
/// Note: presence of this field in getblock is not documented in zcashd.
|
||||
#[serde(with = "opthex")]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
solution: Option<Solution>,
|
||||
|
||||
/// The difficulty threshold of the requested block header displayed in compact form.
|
||||
#[serde(with = "opthex")]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
bits: Option<CompactDifficulty>,
|
||||
|
||||
/// Floating point number that represents the difficulty limit for this block as a multiple
|
||||
/// of the minimum difficulty for the network.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
difficulty: Option<f64>,
|
||||
|
||||
// `chainwork` would be here, but we don't plan on supporting it
|
||||
// `anchor` would be here. Undocumented. TODO: decide if we want to support it
|
||||
// `chainSupply` would be here, TODO: implement
|
||||
// `valuePools` would be here, TODO: implement
|
||||
//
|
||||
/// Information about the note commitment trees.
|
||||
trees: GetBlockTrees,
|
||||
|
||||
/// The previous block hash of the requested block header.
|
||||
#[serde(rename = "previousblockhash", skip_serializing_if = "Option::is_none")]
|
||||
previous_block_hash: Option<GetBlockHash>,
|
||||
|
||||
/// The next block hash after the requested block header.
|
||||
#[serde(rename = "nextblockhash", skip_serializing_if = "Option::is_none")]
|
||||
next_block_hash: Option<GetBlockHash>,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -1777,6 +1829,17 @@ impl Default for GetBlock {
|
|||
time: None,
|
||||
tx: Vec::new(),
|
||||
trees: GetBlockTrees::default(),
|
||||
size: None,
|
||||
version: None,
|
||||
merkle_root: None,
|
||||
final_sapling_root: None,
|
||||
final_orchard_root: None,
|
||||
nonce: None,
|
||||
bits: None,
|
||||
difficulty: None,
|
||||
previous_block_hash: None,
|
||||
next_block_hash: None,
|
||||
solution: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1820,6 +1883,11 @@ pub struct GetBlockHeaderObject {
|
|||
#[serde(with = "hex", rename = "finalsaplingroot")]
|
||||
pub final_sapling_root: [u8; 32],
|
||||
|
||||
/// The number of Sapling notes in the Sapling note commitment tree
|
||||
/// after applying this block. Used by the `getblock` RPC method.
|
||||
#[serde(skip)]
|
||||
pub sapling_tree_size: u64,
|
||||
|
||||
/// The block time of the requested block header in non-leap seconds since Jan 1 1970 GMT.
|
||||
pub time: i64,
|
||||
|
||||
|
@ -1865,6 +1933,7 @@ impl Default for GetBlockHeaderObject {
|
|||
version: 4,
|
||||
merkle_root: block::merkle::Root([0; 32]),
|
||||
final_sapling_root: Default::default(),
|
||||
sapling_tree_size: Default::default(),
|
||||
time: 0,
|
||||
nonce: [0; 32],
|
||||
solution: Solution::for_proposal(),
|
||||
|
@ -2156,3 +2225,23 @@ pub fn height_from_signed_int(index: i32, tip_height: Height) -> Result<Height>
|
|||
Ok(Height(sanitized_height))
|
||||
}
|
||||
}
|
||||
|
||||
/// A helper module to serialize `Option<T: ToHex>` as a hex string.
|
||||
mod opthex {
|
||||
use hex::ToHex;
|
||||
use serde::Serializer;
|
||||
|
||||
pub fn serialize<S, T>(data: &Option<T>, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
T: ToHex,
|
||||
{
|
||||
match data {
|
||||
Some(data) => {
|
||||
let s = data.encode_hex::<String>();
|
||||
serializer.serialize_str(&s)
|
||||
}
|
||||
None => serializer.serialize_none(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,19 @@ expression: block
|
|||
{
|
||||
"hash": "0007bc227e1c57a4a70e237cad00e7b7ce565155ab49166bc57397a26d339283",
|
||||
"confirmations": 10,
|
||||
"height": 1,
|
||||
"version": 4,
|
||||
"merkleroot": "851bf6fbf7a976327817c738c489d7fa657752445430922d94c983c0b9ed4609",
|
||||
"finalsaplingroot": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"tx": [
|
||||
"851bf6fbf7a976327817c738c489d7fa657752445430922d94c983c0b9ed4609"
|
||||
],
|
||||
"trees": {}
|
||||
"time": 1477671596,
|
||||
"nonce": "9057977ea6d4ae867decc96359fcf2db8cdebcbfb3bd549de4f21f16cfe83475",
|
||||
"solution": "002b2ee0d2f5d0c1ebf5a265b6f5b428f2fdc9aaea07078a6c5cab4f1bbfcd56489863deae6ea3fd8d3d0762e8e5295ff2670c9e90d8e8c68a54a40927e82a65e1d44ced20d835818e172d7b7f5ffe0245d0c3860a3f11af5658d68b6a7253b4684ffef5242fefa77a0bfc3437e8d94df9dc57510f5a128e676dd9ddf23f0ef75b460090f507499585541ab53a470c547ea02723d3a979930941157792c4362e42d3b9faca342a5c05a56909b046b5e92e2870fca7c932ae2c2fdd97d75b6e0ecb501701c1250246093c73efc5ec2838aeb80b59577741aa5ccdf4a631b79f70fc419e28714fa22108d991c29052b2f5f72294c355b57504369313470ecdd8e0ae97fc48e243a38c2ee7315bb05b7de9602047e97449c81e46746513221738dc729d7077a1771cea858865d85261e71e82003ccfbba2416358f023251206d6ef4c5596bc35b2b5bce3e9351798aa2c9904723034e5815c7512d260cc957df5db6adf9ed7272483312d1e68c60955a944e713355089876a704aef06359238f6de5a618f7bd0b4552ba72d05a6165e582f62d55ff2e1b76991971689ba3bee16a520fd85380a6e5a31de4dd4654d561101ce0ca390862d5774921eae2c284008692e9e08562144e8aa1f399a9d3fab0c4559c1f12bc945e626f7a89668613e8829767f4116ee9a4f832cf7c3ade3a7aba8cb04de39edd94d0d05093ed642adf9fbd9d373a80832ffd1c62034e4341546b3515f0e42e6d8570393c6754be5cdb7753b4709527d3f164aebf3d315934f7b3736a1b31052f6cc5699758950331163b3df05b9772e9bf99c8c77f8960e10a15edb06200106f45742d740c422c86b7e4f5a52d3732aa79ee54cfc92f76e03c268ae226477c19924e733caf95b8f350233a5312f4ed349d3ad76f032358f83a6d0d6f83b2a456742aad7f3e615fa72286300f0ea1c9793831ef3a5a4ae08640a6e32f53d1cba0be284b25e923d0d110ba227e54725632efcbbe17c05a9cde976504f6aece0c461b562cfae1b85d5f6782ee27b3e332ac0775f681682ce524b32889f1dc4231226f1aada0703beaf8d41732c9647a0a940a86f8a1be7f239c44fcaa7ed7a055506bdbe1df848f9e047226bee1b6d788a03f6e352eead99b419cfc41741942dbeb7a5c55788d5a3e636d8aab7b36b4db71d16700373bbc1cdeba8f9b1db10bf39a621bc737ea4f4e333698d6e09b51ac7a97fb6fd117ccad1d6b6b3a7451699d5bfe448650396d7b58867b3b0872be13ad0b43da267df0ad77025155f04e20c56d6a9befb3e9c7d23b82cbf3a534295ebda540682cc81be9273781b92519c858f9c25294fbacf75c3b3c15bda6d36de1c83336f93e96910dbdcb190d6ef123c98565ff6df1e903f57d4e4df167ba6b829d6d9713eb2126b0cf869940204137babcc6a1b7cb2f0b94318a7460e5d1a605c249bd2e72123ebad332332c18adcb285ed8874dbde084ebcd4f744465350d57110f037fffed1569d642c258749e65b0d13e117eaa37014a769b5ab479b7c77178880e77099f999abe712e543dbbf626ca9bcfddc42ff2f109d21c8bd464894e55ae504fdf81e1a7694180225da7dac8879abd1036cf26bb50532b8cf138b337a1a1bd1a43f8dd70b7399e2690c8e7a5a1fe099026b8f2a6f65fc0dbedda15ba65e0abd66c7176fb426980549892b4817de78e345a7aeab05744c3def4a2f283b4255b02c91c1af7354a368c67a11703c642a385c7453131ce3a78b24c5e22ab7e136a38498ce82082181884418cb4d6c2920f258a3ad20cfbe7104af1c6c6cb5e58bf29a9901721ad19c0a260cd09a3a772443a45aea4a5c439a95834ef5dc2e26343278947b7b796f796ae9bcadb29e2899a1d7313e6f7bfb6f8b",
|
||||
"bits": "1f07ffff",
|
||||
"difficulty": 1.0,
|
||||
"trees": {},
|
||||
"previousblockhash": "00040fe8ec8471911baa1db1266ea15dd06b4a8a5c453883c000b031973dce08",
|
||||
"nextblockhash": "0002a26c902619fc964443264feb16f1e3e2d71322fc53dcb81cc5d797e273ed"
|
||||
}
|
||||
|
|
|
@ -5,8 +5,19 @@ expression: block
|
|||
{
|
||||
"hash": "025579869bcf52a989337342f5f57a84f3a28b968f7d6a8307902b065a668d23",
|
||||
"confirmations": 10,
|
||||
"height": 1,
|
||||
"version": 4,
|
||||
"merkleroot": "f37e9f691fffb635de0999491d906ee85ba40cd36dae9f6e5911a8277d7c5f75",
|
||||
"finalsaplingroot": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"tx": [
|
||||
"f37e9f691fffb635de0999491d906ee85ba40cd36dae9f6e5911a8277d7c5f75"
|
||||
],
|
||||
"trees": {}
|
||||
"time": 1477674473,
|
||||
"nonce": "0000e5739438a096ca89cde16bcf6001e0c5a7ce6f7c591d26314c26c2560000",
|
||||
"solution": "0053f4438864bc5d6dfc009d4bba545ac5e5feaaf46f9455b975b02115f842a966e26517ce678f1c074d09cc8d0049a190859eb505af5f3e760312fbbe54da115db2bc03c96408f39b679891790b539d2d9d17a801dc6af9af14ca3f6ba060edce2a1dd45aa45f11fe37dbaf1eb2647ae7c393f6680c3d5d7e53687e34530f48edf58924a04d3e0231c150b1c8218998f674bc171edd222bcb4ac4ba4ea52d7baa86399f371d5284043e1e166f9069dd0f2904ff94c7922a70fa7c660e0553cc40a20d9ee08eb3f47278485801ddae9c270411360773f0b74e03db2d92c50952c9bd4924bbca2a260e1235e99df51fe71e75744232f2d641ef94f394110a5ad05f51a057e4cb515b92c16cb1404a8cdcc43d4a4bb2caa54ca35dccf41aa7d832da65123b7029223c46ed2a13387d598d445435d3cb32fdad9e27672903864c90d86353b162033078327b5b7aaffc89b40096ae004f2d5c6bd2c99188574348518db66e9b6020f93f12ee1c06f7b00fe346fefceaffb1da9e3cdf08285057f549733eb10825737fcd1431bfdfb155f323f24e95a869212baacf445b30f2670206645779110e6547d5da90a5f2fe5151da911d5ecd5a833023661d1356b6c395d85968947678d53efd4db7b06f23b21125e74492644277ea0c1131b80d6a4e3e8093b82332556fbb3255a55ac3f0b7e4844c0e12bf577c37fd02323ae5ef4781772ed501d63b568032a3d31576c5104a48c01ac54f715286932351a8adc8cf2467a84a0572e99f366ee00f82c3735545fd4bb941d591ce70070425a81304272db89887949bc7dd8236bb7e82190f9815da938cd6e8fec7660e91354326a7a9bfe38120e97997fca3c289d54513ed00286c2b825fbe84f91a39528f335674b5e957425a6edfdd00f2feb2c2df575616197998c1e964e069875d4d934f419a9b02b100848d023b76d47bd4e284c3895ef9227a40d8ea8826e86c7155d6aa95b8f9175812523a32cd611efc700688e03f7c245c5bff01718281b5d75cefe8318b2c08962236b14a0bf79534c203df735fd9cced97cbae07c2b4ee9cda8c9993f3f6277ff3fec261fb94d3961c4befe4b0893dcf67b312c7d8d6ff7adc8539cb2b1d3534fccf109efddd07a9f1e77b94ab1e505b164221dca1c34621b1e9d234c31a032a401267d95f65b800d579a2482638dfeade804149c81e95d7ef5510ac0b6212231506b1c635a2e1d2f0c9712989f9f246762fadb4c55c20f707dcc0e510a33e9465fc5d5bdbfa524dab0d7a1c6a1baaa36869cf542aa2257c5c44ef07547a570343442c6091e13bc04d559dc0e6db5b001861914bf956816edce2a86b274bd97f27e2dbb08608c16a3e5d8595952faa91fb162d7fa6a7a47e849a1ad8fab3ba620ee3295a04fe13e5fb655ac92ae60d01020b8999526af8d56b28733e69c9ffb285de27c61edc0bf62261ac0787eff347d0fcd62257301ede9603106ea41650a3e3119bd5c4e86a7f6a3f00934f3a545f7f21d41699f3e35d38cf925a8bdaf2bf7eedea11c31c3d8bf6c527c77c6378281cdf02211a58fa5e46d28d7e7c5fb79d69b31703fd752395da115845952cf99aaeb2155c2ab951a69f67d938f223185567e52cfa3e57b62c790bf78674c4b02c12b7d3225fe8f705b408ba11c24245b3924482e2f3480994461b550641a88cd941d371139f3498afacdcba1249631402b20695760eaada5376e68df0e45139c410700effc9420dc3726515e7fcb3f349320f30511451964bd9b6530682efec65910ceb548aa2ab05ac3309e803161697213631ae8e13cc7d223ac28446c1bf94a19a8782ac16ff57df7ee4f10fb6e488c02c68d6b6dee6987f6d2c39227da366c59f54ff67e312ca530e7c467c3dc8",
|
||||
"bits": "2007ffff",
|
||||
"difficulty": 1.0,
|
||||
"trees": {},
|
||||
"previousblockhash": "05a60a92d99d85997cce3b87616c089f6124d7342af37106edc76126334a2c38",
|
||||
"nextblockhash": "00f1a49e54553ac3ef735f2eb1d8247c9a87c22a47dbd7823ae70adcd6c21a18"
|
||||
}
|
||||
|
|
|
@ -6,9 +6,18 @@ expression: block
|
|||
"hash": "0007bc227e1c57a4a70e237cad00e7b7ce565155ab49166bc57397a26d339283",
|
||||
"confirmations": 10,
|
||||
"height": 1,
|
||||
"time": 1477671596,
|
||||
"version": 4,
|
||||
"merkleroot": "851bf6fbf7a976327817c738c489d7fa657752445430922d94c983c0b9ed4609",
|
||||
"finalsaplingroot": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"tx": [
|
||||
"851bf6fbf7a976327817c738c489d7fa657752445430922d94c983c0b9ed4609"
|
||||
],
|
||||
"trees": {}
|
||||
"time": 1477671596,
|
||||
"nonce": "9057977ea6d4ae867decc96359fcf2db8cdebcbfb3bd549de4f21f16cfe83475",
|
||||
"solution": "002b2ee0d2f5d0c1ebf5a265b6f5b428f2fdc9aaea07078a6c5cab4f1bbfcd56489863deae6ea3fd8d3d0762e8e5295ff2670c9e90d8e8c68a54a40927e82a65e1d44ced20d835818e172d7b7f5ffe0245d0c3860a3f11af5658d68b6a7253b4684ffef5242fefa77a0bfc3437e8d94df9dc57510f5a128e676dd9ddf23f0ef75b460090f507499585541ab53a470c547ea02723d3a979930941157792c4362e42d3b9faca342a5c05a56909b046b5e92e2870fca7c932ae2c2fdd97d75b6e0ecb501701c1250246093c73efc5ec2838aeb80b59577741aa5ccdf4a631b79f70fc419e28714fa22108d991c29052b2f5f72294c355b57504369313470ecdd8e0ae97fc48e243a38c2ee7315bb05b7de9602047e97449c81e46746513221738dc729d7077a1771cea858865d85261e71e82003ccfbba2416358f023251206d6ef4c5596bc35b2b5bce3e9351798aa2c9904723034e5815c7512d260cc957df5db6adf9ed7272483312d1e68c60955a944e713355089876a704aef06359238f6de5a618f7bd0b4552ba72d05a6165e582f62d55ff2e1b76991971689ba3bee16a520fd85380a6e5a31de4dd4654d561101ce0ca390862d5774921eae2c284008692e9e08562144e8aa1f399a9d3fab0c4559c1f12bc945e626f7a89668613e8829767f4116ee9a4f832cf7c3ade3a7aba8cb04de39edd94d0d05093ed642adf9fbd9d373a80832ffd1c62034e4341546b3515f0e42e6d8570393c6754be5cdb7753b4709527d3f164aebf3d315934f7b3736a1b31052f6cc5699758950331163b3df05b9772e9bf99c8c77f8960e10a15edb06200106f45742d740c422c86b7e4f5a52d3732aa79ee54cfc92f76e03c268ae226477c19924e733caf95b8f350233a5312f4ed349d3ad76f032358f83a6d0d6f83b2a456742aad7f3e615fa72286300f0ea1c9793831ef3a5a4ae08640a6e32f53d1cba0be284b25e923d0d110ba227e54725632efcbbe17c05a9cde976504f6aece0c461b562cfae1b85d5f6782ee27b3e332ac0775f681682ce524b32889f1dc4231226f1aada0703beaf8d41732c9647a0a940a86f8a1be7f239c44fcaa7ed7a055506bdbe1df848f9e047226bee1b6d788a03f6e352eead99b419cfc41741942dbeb7a5c55788d5a3e636d8aab7b36b4db71d16700373bbc1cdeba8f9b1db10bf39a621bc737ea4f4e333698d6e09b51ac7a97fb6fd117ccad1d6b6b3a7451699d5bfe448650396d7b58867b3b0872be13ad0b43da267df0ad77025155f04e20c56d6a9befb3e9c7d23b82cbf3a534295ebda540682cc81be9273781b92519c858f9c25294fbacf75c3b3c15bda6d36de1c83336f93e96910dbdcb190d6ef123c98565ff6df1e903f57d4e4df167ba6b829d6d9713eb2126b0cf869940204137babcc6a1b7cb2f0b94318a7460e5d1a605c249bd2e72123ebad332332c18adcb285ed8874dbde084ebcd4f744465350d57110f037fffed1569d642c258749e65b0d13e117eaa37014a769b5ab479b7c77178880e77099f999abe712e543dbbf626ca9bcfddc42ff2f109d21c8bd464894e55ae504fdf81e1a7694180225da7dac8879abd1036cf26bb50532b8cf138b337a1a1bd1a43f8dd70b7399e2690c8e7a5a1fe099026b8f2a6f65fc0dbedda15ba65e0abd66c7176fb426980549892b4817de78e345a7aeab05744c3def4a2f283b4255b02c91c1af7354a368c67a11703c642a385c7453131ce3a78b24c5e22ab7e136a38498ce82082181884418cb4d6c2920f258a3ad20cfbe7104af1c6c6cb5e58bf29a9901721ad19c0a260cd09a3a772443a45aea4a5c439a95834ef5dc2e26343278947b7b796f796ae9bcadb29e2899a1d7313e6f7bfb6f8b",
|
||||
"bits": "1f07ffff",
|
||||
"difficulty": 1.0,
|
||||
"trees": {},
|
||||
"previousblockhash": "00040fe8ec8471911baa1db1266ea15dd06b4a8a5c453883c000b031973dce08",
|
||||
"nextblockhash": "0002a26c902619fc964443264feb16f1e3e2d71322fc53dcb81cc5d797e273ed"
|
||||
}
|
||||
|
|
|
@ -6,9 +6,18 @@ expression: block
|
|||
"hash": "025579869bcf52a989337342f5f57a84f3a28b968f7d6a8307902b065a668d23",
|
||||
"confirmations": 10,
|
||||
"height": 1,
|
||||
"time": 1477674473,
|
||||
"version": 4,
|
||||
"merkleroot": "f37e9f691fffb635de0999491d906ee85ba40cd36dae9f6e5911a8277d7c5f75",
|
||||
"finalsaplingroot": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"tx": [
|
||||
"f37e9f691fffb635de0999491d906ee85ba40cd36dae9f6e5911a8277d7c5f75"
|
||||
],
|
||||
"trees": {}
|
||||
"time": 1477674473,
|
||||
"nonce": "0000e5739438a096ca89cde16bcf6001e0c5a7ce6f7c591d26314c26c2560000",
|
||||
"solution": "0053f4438864bc5d6dfc009d4bba545ac5e5feaaf46f9455b975b02115f842a966e26517ce678f1c074d09cc8d0049a190859eb505af5f3e760312fbbe54da115db2bc03c96408f39b679891790b539d2d9d17a801dc6af9af14ca3f6ba060edce2a1dd45aa45f11fe37dbaf1eb2647ae7c393f6680c3d5d7e53687e34530f48edf58924a04d3e0231c150b1c8218998f674bc171edd222bcb4ac4ba4ea52d7baa86399f371d5284043e1e166f9069dd0f2904ff94c7922a70fa7c660e0553cc40a20d9ee08eb3f47278485801ddae9c270411360773f0b74e03db2d92c50952c9bd4924bbca2a260e1235e99df51fe71e75744232f2d641ef94f394110a5ad05f51a057e4cb515b92c16cb1404a8cdcc43d4a4bb2caa54ca35dccf41aa7d832da65123b7029223c46ed2a13387d598d445435d3cb32fdad9e27672903864c90d86353b162033078327b5b7aaffc89b40096ae004f2d5c6bd2c99188574348518db66e9b6020f93f12ee1c06f7b00fe346fefceaffb1da9e3cdf08285057f549733eb10825737fcd1431bfdfb155f323f24e95a869212baacf445b30f2670206645779110e6547d5da90a5f2fe5151da911d5ecd5a833023661d1356b6c395d85968947678d53efd4db7b06f23b21125e74492644277ea0c1131b80d6a4e3e8093b82332556fbb3255a55ac3f0b7e4844c0e12bf577c37fd02323ae5ef4781772ed501d63b568032a3d31576c5104a48c01ac54f715286932351a8adc8cf2467a84a0572e99f366ee00f82c3735545fd4bb941d591ce70070425a81304272db89887949bc7dd8236bb7e82190f9815da938cd6e8fec7660e91354326a7a9bfe38120e97997fca3c289d54513ed00286c2b825fbe84f91a39528f335674b5e957425a6edfdd00f2feb2c2df575616197998c1e964e069875d4d934f419a9b02b100848d023b76d47bd4e284c3895ef9227a40d8ea8826e86c7155d6aa95b8f9175812523a32cd611efc700688e03f7c245c5bff01718281b5d75cefe8318b2c08962236b14a0bf79534c203df735fd9cced97cbae07c2b4ee9cda8c9993f3f6277ff3fec261fb94d3961c4befe4b0893dcf67b312c7d8d6ff7adc8539cb2b1d3534fccf109efddd07a9f1e77b94ab1e505b164221dca1c34621b1e9d234c31a032a401267d95f65b800d579a2482638dfeade804149c81e95d7ef5510ac0b6212231506b1c635a2e1d2f0c9712989f9f246762fadb4c55c20f707dcc0e510a33e9465fc5d5bdbfa524dab0d7a1c6a1baaa36869cf542aa2257c5c44ef07547a570343442c6091e13bc04d559dc0e6db5b001861914bf956816edce2a86b274bd97f27e2dbb08608c16a3e5d8595952faa91fb162d7fa6a7a47e849a1ad8fab3ba620ee3295a04fe13e5fb655ac92ae60d01020b8999526af8d56b28733e69c9ffb285de27c61edc0bf62261ac0787eff347d0fcd62257301ede9603106ea41650a3e3119bd5c4e86a7f6a3f00934f3a545f7f21d41699f3e35d38cf925a8bdaf2bf7eedea11c31c3d8bf6c527c77c6378281cdf02211a58fa5e46d28d7e7c5fb79d69b31703fd752395da115845952cf99aaeb2155c2ab951a69f67d938f223185567e52cfa3e57b62c790bf78674c4b02c12b7d3225fe8f705b408ba11c24245b3924482e2f3480994461b550641a88cd941d371139f3498afacdcba1249631402b20695760eaada5376e68df0e45139c410700effc9420dc3726515e7fcb3f349320f30511451964bd9b6530682efec65910ceb548aa2ab05ac3309e803161697213631ae8e13cc7d223ac28446c1bf94a19a8782ac16ff57df7ee4f10fb6e488c02c68d6b6dee6987f6d2c39227da366c59f54ff67e312ca530e7c467c3dc8",
|
||||
"bits": "2007ffff",
|
||||
"difficulty": 1.0,
|
||||
"trees": {},
|
||||
"previousblockhash": "05a60a92d99d85997cce3b87616c089f6124d7342af37106edc76126334a2c38",
|
||||
"nextblockhash": "00f1a49e54553ac3ef735f2eb1d8247c9a87c22a47dbd7823ae70adcd6c21a18"
|
||||
}
|
||||
|
|
|
@ -5,8 +5,19 @@ expression: block
|
|||
{
|
||||
"hash": "0007bc227e1c57a4a70e237cad00e7b7ce565155ab49166bc57397a26d339283",
|
||||
"confirmations": 10,
|
||||
"height": 1,
|
||||
"version": 4,
|
||||
"merkleroot": "851bf6fbf7a976327817c738c489d7fa657752445430922d94c983c0b9ed4609",
|
||||
"finalsaplingroot": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"tx": [
|
||||
"851bf6fbf7a976327817c738c489d7fa657752445430922d94c983c0b9ed4609"
|
||||
],
|
||||
"trees": {}
|
||||
"time": 1477671596,
|
||||
"nonce": "9057977ea6d4ae867decc96359fcf2db8cdebcbfb3bd549de4f21f16cfe83475",
|
||||
"solution": "002b2ee0d2f5d0c1ebf5a265b6f5b428f2fdc9aaea07078a6c5cab4f1bbfcd56489863deae6ea3fd8d3d0762e8e5295ff2670c9e90d8e8c68a54a40927e82a65e1d44ced20d835818e172d7b7f5ffe0245d0c3860a3f11af5658d68b6a7253b4684ffef5242fefa77a0bfc3437e8d94df9dc57510f5a128e676dd9ddf23f0ef75b460090f507499585541ab53a470c547ea02723d3a979930941157792c4362e42d3b9faca342a5c05a56909b046b5e92e2870fca7c932ae2c2fdd97d75b6e0ecb501701c1250246093c73efc5ec2838aeb80b59577741aa5ccdf4a631b79f70fc419e28714fa22108d991c29052b2f5f72294c355b57504369313470ecdd8e0ae97fc48e243a38c2ee7315bb05b7de9602047e97449c81e46746513221738dc729d7077a1771cea858865d85261e71e82003ccfbba2416358f023251206d6ef4c5596bc35b2b5bce3e9351798aa2c9904723034e5815c7512d260cc957df5db6adf9ed7272483312d1e68c60955a944e713355089876a704aef06359238f6de5a618f7bd0b4552ba72d05a6165e582f62d55ff2e1b76991971689ba3bee16a520fd85380a6e5a31de4dd4654d561101ce0ca390862d5774921eae2c284008692e9e08562144e8aa1f399a9d3fab0c4559c1f12bc945e626f7a89668613e8829767f4116ee9a4f832cf7c3ade3a7aba8cb04de39edd94d0d05093ed642adf9fbd9d373a80832ffd1c62034e4341546b3515f0e42e6d8570393c6754be5cdb7753b4709527d3f164aebf3d315934f7b3736a1b31052f6cc5699758950331163b3df05b9772e9bf99c8c77f8960e10a15edb06200106f45742d740c422c86b7e4f5a52d3732aa79ee54cfc92f76e03c268ae226477c19924e733caf95b8f350233a5312f4ed349d3ad76f032358f83a6d0d6f83b2a456742aad7f3e615fa72286300f0ea1c9793831ef3a5a4ae08640a6e32f53d1cba0be284b25e923d0d110ba227e54725632efcbbe17c05a9cde976504f6aece0c461b562cfae1b85d5f6782ee27b3e332ac0775f681682ce524b32889f1dc4231226f1aada0703beaf8d41732c9647a0a940a86f8a1be7f239c44fcaa7ed7a055506bdbe1df848f9e047226bee1b6d788a03f6e352eead99b419cfc41741942dbeb7a5c55788d5a3e636d8aab7b36b4db71d16700373bbc1cdeba8f9b1db10bf39a621bc737ea4f4e333698d6e09b51ac7a97fb6fd117ccad1d6b6b3a7451699d5bfe448650396d7b58867b3b0872be13ad0b43da267df0ad77025155f04e20c56d6a9befb3e9c7d23b82cbf3a534295ebda540682cc81be9273781b92519c858f9c25294fbacf75c3b3c15bda6d36de1c83336f93e96910dbdcb190d6ef123c98565ff6df1e903f57d4e4df167ba6b829d6d9713eb2126b0cf869940204137babcc6a1b7cb2f0b94318a7460e5d1a605c249bd2e72123ebad332332c18adcb285ed8874dbde084ebcd4f744465350d57110f037fffed1569d642c258749e65b0d13e117eaa37014a769b5ab479b7c77178880e77099f999abe712e543dbbf626ca9bcfddc42ff2f109d21c8bd464894e55ae504fdf81e1a7694180225da7dac8879abd1036cf26bb50532b8cf138b337a1a1bd1a43f8dd70b7399e2690c8e7a5a1fe099026b8f2a6f65fc0dbedda15ba65e0abd66c7176fb426980549892b4817de78e345a7aeab05744c3def4a2f283b4255b02c91c1af7354a368c67a11703c642a385c7453131ce3a78b24c5e22ab7e136a38498ce82082181884418cb4d6c2920f258a3ad20cfbe7104af1c6c6cb5e58bf29a9901721ad19c0a260cd09a3a772443a45aea4a5c439a95834ef5dc2e26343278947b7b796f796ae9bcadb29e2899a1d7313e6f7bfb6f8b",
|
||||
"bits": "1f07ffff",
|
||||
"difficulty": 1.0,
|
||||
"trees": {},
|
||||
"previousblockhash": "00040fe8ec8471911baa1db1266ea15dd06b4a8a5c453883c000b031973dce08",
|
||||
"nextblockhash": "0002a26c902619fc964443264feb16f1e3e2d71322fc53dcb81cc5d797e273ed"
|
||||
}
|
||||
|
|
|
@ -5,8 +5,19 @@ expression: block
|
|||
{
|
||||
"hash": "025579869bcf52a989337342f5f57a84f3a28b968f7d6a8307902b065a668d23",
|
||||
"confirmations": 10,
|
||||
"height": 1,
|
||||
"version": 4,
|
||||
"merkleroot": "f37e9f691fffb635de0999491d906ee85ba40cd36dae9f6e5911a8277d7c5f75",
|
||||
"finalsaplingroot": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"tx": [
|
||||
"f37e9f691fffb635de0999491d906ee85ba40cd36dae9f6e5911a8277d7c5f75"
|
||||
],
|
||||
"trees": {}
|
||||
"time": 1477674473,
|
||||
"nonce": "0000e5739438a096ca89cde16bcf6001e0c5a7ce6f7c591d26314c26c2560000",
|
||||
"solution": "0053f4438864bc5d6dfc009d4bba545ac5e5feaaf46f9455b975b02115f842a966e26517ce678f1c074d09cc8d0049a190859eb505af5f3e760312fbbe54da115db2bc03c96408f39b679891790b539d2d9d17a801dc6af9af14ca3f6ba060edce2a1dd45aa45f11fe37dbaf1eb2647ae7c393f6680c3d5d7e53687e34530f48edf58924a04d3e0231c150b1c8218998f674bc171edd222bcb4ac4ba4ea52d7baa86399f371d5284043e1e166f9069dd0f2904ff94c7922a70fa7c660e0553cc40a20d9ee08eb3f47278485801ddae9c270411360773f0b74e03db2d92c50952c9bd4924bbca2a260e1235e99df51fe71e75744232f2d641ef94f394110a5ad05f51a057e4cb515b92c16cb1404a8cdcc43d4a4bb2caa54ca35dccf41aa7d832da65123b7029223c46ed2a13387d598d445435d3cb32fdad9e27672903864c90d86353b162033078327b5b7aaffc89b40096ae004f2d5c6bd2c99188574348518db66e9b6020f93f12ee1c06f7b00fe346fefceaffb1da9e3cdf08285057f549733eb10825737fcd1431bfdfb155f323f24e95a869212baacf445b30f2670206645779110e6547d5da90a5f2fe5151da911d5ecd5a833023661d1356b6c395d85968947678d53efd4db7b06f23b21125e74492644277ea0c1131b80d6a4e3e8093b82332556fbb3255a55ac3f0b7e4844c0e12bf577c37fd02323ae5ef4781772ed501d63b568032a3d31576c5104a48c01ac54f715286932351a8adc8cf2467a84a0572e99f366ee00f82c3735545fd4bb941d591ce70070425a81304272db89887949bc7dd8236bb7e82190f9815da938cd6e8fec7660e91354326a7a9bfe38120e97997fca3c289d54513ed00286c2b825fbe84f91a39528f335674b5e957425a6edfdd00f2feb2c2df575616197998c1e964e069875d4d934f419a9b02b100848d023b76d47bd4e284c3895ef9227a40d8ea8826e86c7155d6aa95b8f9175812523a32cd611efc700688e03f7c245c5bff01718281b5d75cefe8318b2c08962236b14a0bf79534c203df735fd9cced97cbae07c2b4ee9cda8c9993f3f6277ff3fec261fb94d3961c4befe4b0893dcf67b312c7d8d6ff7adc8539cb2b1d3534fccf109efddd07a9f1e77b94ab1e505b164221dca1c34621b1e9d234c31a032a401267d95f65b800d579a2482638dfeade804149c81e95d7ef5510ac0b6212231506b1c635a2e1d2f0c9712989f9f246762fadb4c55c20f707dcc0e510a33e9465fc5d5bdbfa524dab0d7a1c6a1baaa36869cf542aa2257c5c44ef07547a570343442c6091e13bc04d559dc0e6db5b001861914bf956816edce2a86b274bd97f27e2dbb08608c16a3e5d8595952faa91fb162d7fa6a7a47e849a1ad8fab3ba620ee3295a04fe13e5fb655ac92ae60d01020b8999526af8d56b28733e69c9ffb285de27c61edc0bf62261ac0787eff347d0fcd62257301ede9603106ea41650a3e3119bd5c4e86a7f6a3f00934f3a545f7f21d41699f3e35d38cf925a8bdaf2bf7eedea11c31c3d8bf6c527c77c6378281cdf02211a58fa5e46d28d7e7c5fb79d69b31703fd752395da115845952cf99aaeb2155c2ab951a69f67d938f223185567e52cfa3e57b62c790bf78674c4b02c12b7d3225fe8f705b408ba11c24245b3924482e2f3480994461b550641a88cd941d371139f3498afacdcba1249631402b20695760eaada5376e68df0e45139c410700effc9420dc3726515e7fcb3f349320f30511451964bd9b6530682efec65910ceb548aa2ab05ac3309e803161697213631ae8e13cc7d223ac28446c1bf94a19a8782ac16ff57df7ee4f10fb6e488c02c68d6b6dee6987f6d2c39227da366c59f54ff67e312ca530e7c467c3dc8",
|
||||
"bits": "2007ffff",
|
||||
"difficulty": 1.0,
|
||||
"trees": {},
|
||||
"previousblockhash": "05a60a92d99d85997cce3b87616c089f6124d7342af37106edc76126334a2c38",
|
||||
"nextblockhash": "00f1a49e54553ac3ef735f2eb1d8247c9a87c22a47dbd7823ae70adcd6c21a18"
|
||||
}
|
||||
|
|
|
@ -6,8 +6,18 @@ expression: block
|
|||
"hash": "0007bc227e1c57a4a70e237cad00e7b7ce565155ab49166bc57397a26d339283",
|
||||
"confirmations": 10,
|
||||
"height": 1,
|
||||
"version": 4,
|
||||
"merkleroot": "851bf6fbf7a976327817c738c489d7fa657752445430922d94c983c0b9ed4609",
|
||||
"finalsaplingroot": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"tx": [
|
||||
"851bf6fbf7a976327817c738c489d7fa657752445430922d94c983c0b9ed4609"
|
||||
],
|
||||
"trees": {}
|
||||
"time": 1477671596,
|
||||
"nonce": "9057977ea6d4ae867decc96359fcf2db8cdebcbfb3bd549de4f21f16cfe83475",
|
||||
"solution": "002b2ee0d2f5d0c1ebf5a265b6f5b428f2fdc9aaea07078a6c5cab4f1bbfcd56489863deae6ea3fd8d3d0762e8e5295ff2670c9e90d8e8c68a54a40927e82a65e1d44ced20d835818e172d7b7f5ffe0245d0c3860a3f11af5658d68b6a7253b4684ffef5242fefa77a0bfc3437e8d94df9dc57510f5a128e676dd9ddf23f0ef75b460090f507499585541ab53a470c547ea02723d3a979930941157792c4362e42d3b9faca342a5c05a56909b046b5e92e2870fca7c932ae2c2fdd97d75b6e0ecb501701c1250246093c73efc5ec2838aeb80b59577741aa5ccdf4a631b79f70fc419e28714fa22108d991c29052b2f5f72294c355b57504369313470ecdd8e0ae97fc48e243a38c2ee7315bb05b7de9602047e97449c81e46746513221738dc729d7077a1771cea858865d85261e71e82003ccfbba2416358f023251206d6ef4c5596bc35b2b5bce3e9351798aa2c9904723034e5815c7512d260cc957df5db6adf9ed7272483312d1e68c60955a944e713355089876a704aef06359238f6de5a618f7bd0b4552ba72d05a6165e582f62d55ff2e1b76991971689ba3bee16a520fd85380a6e5a31de4dd4654d561101ce0ca390862d5774921eae2c284008692e9e08562144e8aa1f399a9d3fab0c4559c1f12bc945e626f7a89668613e8829767f4116ee9a4f832cf7c3ade3a7aba8cb04de39edd94d0d05093ed642adf9fbd9d373a80832ffd1c62034e4341546b3515f0e42e6d8570393c6754be5cdb7753b4709527d3f164aebf3d315934f7b3736a1b31052f6cc5699758950331163b3df05b9772e9bf99c8c77f8960e10a15edb06200106f45742d740c422c86b7e4f5a52d3732aa79ee54cfc92f76e03c268ae226477c19924e733caf95b8f350233a5312f4ed349d3ad76f032358f83a6d0d6f83b2a456742aad7f3e615fa72286300f0ea1c9793831ef3a5a4ae08640a6e32f53d1cba0be284b25e923d0d110ba227e54725632efcbbe17c05a9cde976504f6aece0c461b562cfae1b85d5f6782ee27b3e332ac0775f681682ce524b32889f1dc4231226f1aada0703beaf8d41732c9647a0a940a86f8a1be7f239c44fcaa7ed7a055506bdbe1df848f9e047226bee1b6d788a03f6e352eead99b419cfc41741942dbeb7a5c55788d5a3e636d8aab7b36b4db71d16700373bbc1cdeba8f9b1db10bf39a621bc737ea4f4e333698d6e09b51ac7a97fb6fd117ccad1d6b6b3a7451699d5bfe448650396d7b58867b3b0872be13ad0b43da267df0ad77025155f04e20c56d6a9befb3e9c7d23b82cbf3a534295ebda540682cc81be9273781b92519c858f9c25294fbacf75c3b3c15bda6d36de1c83336f93e96910dbdcb190d6ef123c98565ff6df1e903f57d4e4df167ba6b829d6d9713eb2126b0cf869940204137babcc6a1b7cb2f0b94318a7460e5d1a605c249bd2e72123ebad332332c18adcb285ed8874dbde084ebcd4f744465350d57110f037fffed1569d642c258749e65b0d13e117eaa37014a769b5ab479b7c77178880e77099f999abe712e543dbbf626ca9bcfddc42ff2f109d21c8bd464894e55ae504fdf81e1a7694180225da7dac8879abd1036cf26bb50532b8cf138b337a1a1bd1a43f8dd70b7399e2690c8e7a5a1fe099026b8f2a6f65fc0dbedda15ba65e0abd66c7176fb426980549892b4817de78e345a7aeab05744c3def4a2f283b4255b02c91c1af7354a368c67a11703c642a385c7453131ce3a78b24c5e22ab7e136a38498ce82082181884418cb4d6c2920f258a3ad20cfbe7104af1c6c6cb5e58bf29a9901721ad19c0a260cd09a3a772443a45aea4a5c439a95834ef5dc2e26343278947b7b796f796ae9bcadb29e2899a1d7313e6f7bfb6f8b",
|
||||
"bits": "1f07ffff",
|
||||
"difficulty": 1.0,
|
||||
"trees": {},
|
||||
"previousblockhash": "00040fe8ec8471911baa1db1266ea15dd06b4a8a5c453883c000b031973dce08",
|
||||
"nextblockhash": "0002a26c902619fc964443264feb16f1e3e2d71322fc53dcb81cc5d797e273ed"
|
||||
}
|
||||
|
|
|
@ -6,8 +6,18 @@ expression: block
|
|||
"hash": "025579869bcf52a989337342f5f57a84f3a28b968f7d6a8307902b065a668d23",
|
||||
"confirmations": 10,
|
||||
"height": 1,
|
||||
"version": 4,
|
||||
"merkleroot": "f37e9f691fffb635de0999491d906ee85ba40cd36dae9f6e5911a8277d7c5f75",
|
||||
"finalsaplingroot": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"tx": [
|
||||
"f37e9f691fffb635de0999491d906ee85ba40cd36dae9f6e5911a8277d7c5f75"
|
||||
],
|
||||
"trees": {}
|
||||
"time": 1477674473,
|
||||
"nonce": "0000e5739438a096ca89cde16bcf6001e0c5a7ce6f7c591d26314c26c2560000",
|
||||
"solution": "0053f4438864bc5d6dfc009d4bba545ac5e5feaaf46f9455b975b02115f842a966e26517ce678f1c074d09cc8d0049a190859eb505af5f3e760312fbbe54da115db2bc03c96408f39b679891790b539d2d9d17a801dc6af9af14ca3f6ba060edce2a1dd45aa45f11fe37dbaf1eb2647ae7c393f6680c3d5d7e53687e34530f48edf58924a04d3e0231c150b1c8218998f674bc171edd222bcb4ac4ba4ea52d7baa86399f371d5284043e1e166f9069dd0f2904ff94c7922a70fa7c660e0553cc40a20d9ee08eb3f47278485801ddae9c270411360773f0b74e03db2d92c50952c9bd4924bbca2a260e1235e99df51fe71e75744232f2d641ef94f394110a5ad05f51a057e4cb515b92c16cb1404a8cdcc43d4a4bb2caa54ca35dccf41aa7d832da65123b7029223c46ed2a13387d598d445435d3cb32fdad9e27672903864c90d86353b162033078327b5b7aaffc89b40096ae004f2d5c6bd2c99188574348518db66e9b6020f93f12ee1c06f7b00fe346fefceaffb1da9e3cdf08285057f549733eb10825737fcd1431bfdfb155f323f24e95a869212baacf445b30f2670206645779110e6547d5da90a5f2fe5151da911d5ecd5a833023661d1356b6c395d85968947678d53efd4db7b06f23b21125e74492644277ea0c1131b80d6a4e3e8093b82332556fbb3255a55ac3f0b7e4844c0e12bf577c37fd02323ae5ef4781772ed501d63b568032a3d31576c5104a48c01ac54f715286932351a8adc8cf2467a84a0572e99f366ee00f82c3735545fd4bb941d591ce70070425a81304272db89887949bc7dd8236bb7e82190f9815da938cd6e8fec7660e91354326a7a9bfe38120e97997fca3c289d54513ed00286c2b825fbe84f91a39528f335674b5e957425a6edfdd00f2feb2c2df575616197998c1e964e069875d4d934f419a9b02b100848d023b76d47bd4e284c3895ef9227a40d8ea8826e86c7155d6aa95b8f9175812523a32cd611efc700688e03f7c245c5bff01718281b5d75cefe8318b2c08962236b14a0bf79534c203df735fd9cced97cbae07c2b4ee9cda8c9993f3f6277ff3fec261fb94d3961c4befe4b0893dcf67b312c7d8d6ff7adc8539cb2b1d3534fccf109efddd07a9f1e77b94ab1e505b164221dca1c34621b1e9d234c31a032a401267d95f65b800d579a2482638dfeade804149c81e95d7ef5510ac0b6212231506b1c635a2e1d2f0c9712989f9f246762fadb4c55c20f707dcc0e510a33e9465fc5d5bdbfa524dab0d7a1c6a1baaa36869cf542aa2257c5c44ef07547a570343442c6091e13bc04d559dc0e6db5b001861914bf956816edce2a86b274bd97f27e2dbb08608c16a3e5d8595952faa91fb162d7fa6a7a47e849a1ad8fab3ba620ee3295a04fe13e5fb655ac92ae60d01020b8999526af8d56b28733e69c9ffb285de27c61edc0bf62261ac0787eff347d0fcd62257301ede9603106ea41650a3e3119bd5c4e86a7f6a3f00934f3a545f7f21d41699f3e35d38cf925a8bdaf2bf7eedea11c31c3d8bf6c527c77c6378281cdf02211a58fa5e46d28d7e7c5fb79d69b31703fd752395da115845952cf99aaeb2155c2ab951a69f67d938f223185567e52cfa3e57b62c790bf78674c4b02c12b7d3225fe8f705b408ba11c24245b3924482e2f3480994461b550641a88cd941d371139f3498afacdcba1249631402b20695760eaada5376e68df0e45139c410700effc9420dc3726515e7fcb3f349320f30511451964bd9b6530682efec65910ceb548aa2ab05ac3309e803161697213631ae8e13cc7d223ac28446c1bf94a19a8782ac16ff57df7ee4f10fb6e488c02c68d6b6dee6987f6d2c39227da366c59f54ff67e312ca530e7c467c3dc8",
|
||||
"bits": "2007ffff",
|
||||
"difficulty": 1.0,
|
||||
"trees": {},
|
||||
"previousblockhash": "05a60a92d99d85997cce3b87616c089f6124d7342af37106edc76126334a2c38",
|
||||
"nextblockhash": "00f1a49e54553ac3ef735f2eb1d8247c9a87c22a47dbd7823ae70adcd6c21a18"
|
||||
}
|
||||
|
|
|
@ -6,9 +6,18 @@ expression: block
|
|||
"hash": "0007bc227e1c57a4a70e237cad00e7b7ce565155ab49166bc57397a26d339283",
|
||||
"confirmations": 10,
|
||||
"height": 1,
|
||||
"time": 1477671596,
|
||||
"version": 4,
|
||||
"merkleroot": "851bf6fbf7a976327817c738c489d7fa657752445430922d94c983c0b9ed4609",
|
||||
"finalsaplingroot": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"tx": [
|
||||
"851bf6fbf7a976327817c738c489d7fa657752445430922d94c983c0b9ed4609"
|
||||
],
|
||||
"trees": {}
|
||||
"time": 1477671596,
|
||||
"nonce": "9057977ea6d4ae867decc96359fcf2db8cdebcbfb3bd549de4f21f16cfe83475",
|
||||
"solution": "002b2ee0d2f5d0c1ebf5a265b6f5b428f2fdc9aaea07078a6c5cab4f1bbfcd56489863deae6ea3fd8d3d0762e8e5295ff2670c9e90d8e8c68a54a40927e82a65e1d44ced20d835818e172d7b7f5ffe0245d0c3860a3f11af5658d68b6a7253b4684ffef5242fefa77a0bfc3437e8d94df9dc57510f5a128e676dd9ddf23f0ef75b460090f507499585541ab53a470c547ea02723d3a979930941157792c4362e42d3b9faca342a5c05a56909b046b5e92e2870fca7c932ae2c2fdd97d75b6e0ecb501701c1250246093c73efc5ec2838aeb80b59577741aa5ccdf4a631b79f70fc419e28714fa22108d991c29052b2f5f72294c355b57504369313470ecdd8e0ae97fc48e243a38c2ee7315bb05b7de9602047e97449c81e46746513221738dc729d7077a1771cea858865d85261e71e82003ccfbba2416358f023251206d6ef4c5596bc35b2b5bce3e9351798aa2c9904723034e5815c7512d260cc957df5db6adf9ed7272483312d1e68c60955a944e713355089876a704aef06359238f6de5a618f7bd0b4552ba72d05a6165e582f62d55ff2e1b76991971689ba3bee16a520fd85380a6e5a31de4dd4654d561101ce0ca390862d5774921eae2c284008692e9e08562144e8aa1f399a9d3fab0c4559c1f12bc945e626f7a89668613e8829767f4116ee9a4f832cf7c3ade3a7aba8cb04de39edd94d0d05093ed642adf9fbd9d373a80832ffd1c62034e4341546b3515f0e42e6d8570393c6754be5cdb7753b4709527d3f164aebf3d315934f7b3736a1b31052f6cc5699758950331163b3df05b9772e9bf99c8c77f8960e10a15edb06200106f45742d740c422c86b7e4f5a52d3732aa79ee54cfc92f76e03c268ae226477c19924e733caf95b8f350233a5312f4ed349d3ad76f032358f83a6d0d6f83b2a456742aad7f3e615fa72286300f0ea1c9793831ef3a5a4ae08640a6e32f53d1cba0be284b25e923d0d110ba227e54725632efcbbe17c05a9cde976504f6aece0c461b562cfae1b85d5f6782ee27b3e332ac0775f681682ce524b32889f1dc4231226f1aada0703beaf8d41732c9647a0a940a86f8a1be7f239c44fcaa7ed7a055506bdbe1df848f9e047226bee1b6d788a03f6e352eead99b419cfc41741942dbeb7a5c55788d5a3e636d8aab7b36b4db71d16700373bbc1cdeba8f9b1db10bf39a621bc737ea4f4e333698d6e09b51ac7a97fb6fd117ccad1d6b6b3a7451699d5bfe448650396d7b58867b3b0872be13ad0b43da267df0ad77025155f04e20c56d6a9befb3e9c7d23b82cbf3a534295ebda540682cc81be9273781b92519c858f9c25294fbacf75c3b3c15bda6d36de1c83336f93e96910dbdcb190d6ef123c98565ff6df1e903f57d4e4df167ba6b829d6d9713eb2126b0cf869940204137babcc6a1b7cb2f0b94318a7460e5d1a605c249bd2e72123ebad332332c18adcb285ed8874dbde084ebcd4f744465350d57110f037fffed1569d642c258749e65b0d13e117eaa37014a769b5ab479b7c77178880e77099f999abe712e543dbbf626ca9bcfddc42ff2f109d21c8bd464894e55ae504fdf81e1a7694180225da7dac8879abd1036cf26bb50532b8cf138b337a1a1bd1a43f8dd70b7399e2690c8e7a5a1fe099026b8f2a6f65fc0dbedda15ba65e0abd66c7176fb426980549892b4817de78e345a7aeab05744c3def4a2f283b4255b02c91c1af7354a368c67a11703c642a385c7453131ce3a78b24c5e22ab7e136a38498ce82082181884418cb4d6c2920f258a3ad20cfbe7104af1c6c6cb5e58bf29a9901721ad19c0a260cd09a3a772443a45aea4a5c439a95834ef5dc2e26343278947b7b796f796ae9bcadb29e2899a1d7313e6f7bfb6f8b",
|
||||
"bits": "1f07ffff",
|
||||
"difficulty": 1.0,
|
||||
"trees": {},
|
||||
"previousblockhash": "00040fe8ec8471911baa1db1266ea15dd06b4a8a5c453883c000b031973dce08",
|
||||
"nextblockhash": "0002a26c902619fc964443264feb16f1e3e2d71322fc53dcb81cc5d797e273ed"
|
||||
}
|
||||
|
|
|
@ -6,9 +6,18 @@ expression: block
|
|||
"hash": "025579869bcf52a989337342f5f57a84f3a28b968f7d6a8307902b065a668d23",
|
||||
"confirmations": 10,
|
||||
"height": 1,
|
||||
"time": 1477674473,
|
||||
"version": 4,
|
||||
"merkleroot": "f37e9f691fffb635de0999491d906ee85ba40cd36dae9f6e5911a8277d7c5f75",
|
||||
"finalsaplingroot": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"tx": [
|
||||
"f37e9f691fffb635de0999491d906ee85ba40cd36dae9f6e5911a8277d7c5f75"
|
||||
],
|
||||
"trees": {}
|
||||
"time": 1477674473,
|
||||
"nonce": "0000e5739438a096ca89cde16bcf6001e0c5a7ce6f7c591d26314c26c2560000",
|
||||
"solution": "0053f4438864bc5d6dfc009d4bba545ac5e5feaaf46f9455b975b02115f842a966e26517ce678f1c074d09cc8d0049a190859eb505af5f3e760312fbbe54da115db2bc03c96408f39b679891790b539d2d9d17a801dc6af9af14ca3f6ba060edce2a1dd45aa45f11fe37dbaf1eb2647ae7c393f6680c3d5d7e53687e34530f48edf58924a04d3e0231c150b1c8218998f674bc171edd222bcb4ac4ba4ea52d7baa86399f371d5284043e1e166f9069dd0f2904ff94c7922a70fa7c660e0553cc40a20d9ee08eb3f47278485801ddae9c270411360773f0b74e03db2d92c50952c9bd4924bbca2a260e1235e99df51fe71e75744232f2d641ef94f394110a5ad05f51a057e4cb515b92c16cb1404a8cdcc43d4a4bb2caa54ca35dccf41aa7d832da65123b7029223c46ed2a13387d598d445435d3cb32fdad9e27672903864c90d86353b162033078327b5b7aaffc89b40096ae004f2d5c6bd2c99188574348518db66e9b6020f93f12ee1c06f7b00fe346fefceaffb1da9e3cdf08285057f549733eb10825737fcd1431bfdfb155f323f24e95a869212baacf445b30f2670206645779110e6547d5da90a5f2fe5151da911d5ecd5a833023661d1356b6c395d85968947678d53efd4db7b06f23b21125e74492644277ea0c1131b80d6a4e3e8093b82332556fbb3255a55ac3f0b7e4844c0e12bf577c37fd02323ae5ef4781772ed501d63b568032a3d31576c5104a48c01ac54f715286932351a8adc8cf2467a84a0572e99f366ee00f82c3735545fd4bb941d591ce70070425a81304272db89887949bc7dd8236bb7e82190f9815da938cd6e8fec7660e91354326a7a9bfe38120e97997fca3c289d54513ed00286c2b825fbe84f91a39528f335674b5e957425a6edfdd00f2feb2c2df575616197998c1e964e069875d4d934f419a9b02b100848d023b76d47bd4e284c3895ef9227a40d8ea8826e86c7155d6aa95b8f9175812523a32cd611efc700688e03f7c245c5bff01718281b5d75cefe8318b2c08962236b14a0bf79534c203df735fd9cced97cbae07c2b4ee9cda8c9993f3f6277ff3fec261fb94d3961c4befe4b0893dcf67b312c7d8d6ff7adc8539cb2b1d3534fccf109efddd07a9f1e77b94ab1e505b164221dca1c34621b1e9d234c31a032a401267d95f65b800d579a2482638dfeade804149c81e95d7ef5510ac0b6212231506b1c635a2e1d2f0c9712989f9f246762fadb4c55c20f707dcc0e510a33e9465fc5d5bdbfa524dab0d7a1c6a1baaa36869cf542aa2257c5c44ef07547a570343442c6091e13bc04d559dc0e6db5b001861914bf956816edce2a86b274bd97f27e2dbb08608c16a3e5d8595952faa91fb162d7fa6a7a47e849a1ad8fab3ba620ee3295a04fe13e5fb655ac92ae60d01020b8999526af8d56b28733e69c9ffb285de27c61edc0bf62261ac0787eff347d0fcd62257301ede9603106ea41650a3e3119bd5c4e86a7f6a3f00934f3a545f7f21d41699f3e35d38cf925a8bdaf2bf7eedea11c31c3d8bf6c527c77c6378281cdf02211a58fa5e46d28d7e7c5fb79d69b31703fd752395da115845952cf99aaeb2155c2ab951a69f67d938f223185567e52cfa3e57b62c790bf78674c4b02c12b7d3225fe8f705b408ba11c24245b3924482e2f3480994461b550641a88cd941d371139f3498afacdcba1249631402b20695760eaada5376e68df0e45139c410700effc9420dc3726515e7fcb3f349320f30511451964bd9b6530682efec65910ceb548aa2ab05ac3309e803161697213631ae8e13cc7d223ac28446c1bf94a19a8782ac16ff57df7ee4f10fb6e488c02c68d6b6dee6987f6d2c39227da366c59f54ff67e312ca530e7c467c3dc8",
|
||||
"bits": "2007ffff",
|
||||
"difficulty": 1.0,
|
||||
"trees": {},
|
||||
"previousblockhash": "05a60a92d99d85997cce3b87616c089f6124d7342af37106edc76126334a2c38",
|
||||
"nextblockhash": "00f1a49e54553ac3ef735f2eb1d8247c9a87c22a47dbd7823ae70adcd6c21a18"
|
||||
}
|
||||
|
|
|
@ -6,8 +6,18 @@ expression: block
|
|||
"hash": "0007bc227e1c57a4a70e237cad00e7b7ce565155ab49166bc57397a26d339283",
|
||||
"confirmations": 10,
|
||||
"height": 1,
|
||||
"version": 4,
|
||||
"merkleroot": "851bf6fbf7a976327817c738c489d7fa657752445430922d94c983c0b9ed4609",
|
||||
"finalsaplingroot": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"tx": [
|
||||
"851bf6fbf7a976327817c738c489d7fa657752445430922d94c983c0b9ed4609"
|
||||
],
|
||||
"trees": {}
|
||||
"time": 1477671596,
|
||||
"nonce": "9057977ea6d4ae867decc96359fcf2db8cdebcbfb3bd549de4f21f16cfe83475",
|
||||
"solution": "002b2ee0d2f5d0c1ebf5a265b6f5b428f2fdc9aaea07078a6c5cab4f1bbfcd56489863deae6ea3fd8d3d0762e8e5295ff2670c9e90d8e8c68a54a40927e82a65e1d44ced20d835818e172d7b7f5ffe0245d0c3860a3f11af5658d68b6a7253b4684ffef5242fefa77a0bfc3437e8d94df9dc57510f5a128e676dd9ddf23f0ef75b460090f507499585541ab53a470c547ea02723d3a979930941157792c4362e42d3b9faca342a5c05a56909b046b5e92e2870fca7c932ae2c2fdd97d75b6e0ecb501701c1250246093c73efc5ec2838aeb80b59577741aa5ccdf4a631b79f70fc419e28714fa22108d991c29052b2f5f72294c355b57504369313470ecdd8e0ae97fc48e243a38c2ee7315bb05b7de9602047e97449c81e46746513221738dc729d7077a1771cea858865d85261e71e82003ccfbba2416358f023251206d6ef4c5596bc35b2b5bce3e9351798aa2c9904723034e5815c7512d260cc957df5db6adf9ed7272483312d1e68c60955a944e713355089876a704aef06359238f6de5a618f7bd0b4552ba72d05a6165e582f62d55ff2e1b76991971689ba3bee16a520fd85380a6e5a31de4dd4654d561101ce0ca390862d5774921eae2c284008692e9e08562144e8aa1f399a9d3fab0c4559c1f12bc945e626f7a89668613e8829767f4116ee9a4f832cf7c3ade3a7aba8cb04de39edd94d0d05093ed642adf9fbd9d373a80832ffd1c62034e4341546b3515f0e42e6d8570393c6754be5cdb7753b4709527d3f164aebf3d315934f7b3736a1b31052f6cc5699758950331163b3df05b9772e9bf99c8c77f8960e10a15edb06200106f45742d740c422c86b7e4f5a52d3732aa79ee54cfc92f76e03c268ae226477c19924e733caf95b8f350233a5312f4ed349d3ad76f032358f83a6d0d6f83b2a456742aad7f3e615fa72286300f0ea1c9793831ef3a5a4ae08640a6e32f53d1cba0be284b25e923d0d110ba227e54725632efcbbe17c05a9cde976504f6aece0c461b562cfae1b85d5f6782ee27b3e332ac0775f681682ce524b32889f1dc4231226f1aada0703beaf8d41732c9647a0a940a86f8a1be7f239c44fcaa7ed7a055506bdbe1df848f9e047226bee1b6d788a03f6e352eead99b419cfc41741942dbeb7a5c55788d5a3e636d8aab7b36b4db71d16700373bbc1cdeba8f9b1db10bf39a621bc737ea4f4e333698d6e09b51ac7a97fb6fd117ccad1d6b6b3a7451699d5bfe448650396d7b58867b3b0872be13ad0b43da267df0ad77025155f04e20c56d6a9befb3e9c7d23b82cbf3a534295ebda540682cc81be9273781b92519c858f9c25294fbacf75c3b3c15bda6d36de1c83336f93e96910dbdcb190d6ef123c98565ff6df1e903f57d4e4df167ba6b829d6d9713eb2126b0cf869940204137babcc6a1b7cb2f0b94318a7460e5d1a605c249bd2e72123ebad332332c18adcb285ed8874dbde084ebcd4f744465350d57110f037fffed1569d642c258749e65b0d13e117eaa37014a769b5ab479b7c77178880e77099f999abe712e543dbbf626ca9bcfddc42ff2f109d21c8bd464894e55ae504fdf81e1a7694180225da7dac8879abd1036cf26bb50532b8cf138b337a1a1bd1a43f8dd70b7399e2690c8e7a5a1fe099026b8f2a6f65fc0dbedda15ba65e0abd66c7176fb426980549892b4817de78e345a7aeab05744c3def4a2f283b4255b02c91c1af7354a368c67a11703c642a385c7453131ce3a78b24c5e22ab7e136a38498ce82082181884418cb4d6c2920f258a3ad20cfbe7104af1c6c6cb5e58bf29a9901721ad19c0a260cd09a3a772443a45aea4a5c439a95834ef5dc2e26343278947b7b796f796ae9bcadb29e2899a1d7313e6f7bfb6f8b",
|
||||
"bits": "1f07ffff",
|
||||
"difficulty": 1.0,
|
||||
"trees": {},
|
||||
"previousblockhash": "00040fe8ec8471911baa1db1266ea15dd06b4a8a5c453883c000b031973dce08",
|
||||
"nextblockhash": "0002a26c902619fc964443264feb16f1e3e2d71322fc53dcb81cc5d797e273ed"
|
||||
}
|
||||
|
|
|
@ -6,8 +6,18 @@ expression: block
|
|||
"hash": "025579869bcf52a989337342f5f57a84f3a28b968f7d6a8307902b065a668d23",
|
||||
"confirmations": 10,
|
||||
"height": 1,
|
||||
"version": 4,
|
||||
"merkleroot": "f37e9f691fffb635de0999491d906ee85ba40cd36dae9f6e5911a8277d7c5f75",
|
||||
"finalsaplingroot": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"tx": [
|
||||
"f37e9f691fffb635de0999491d906ee85ba40cd36dae9f6e5911a8277d7c5f75"
|
||||
],
|
||||
"trees": {}
|
||||
"time": 1477674473,
|
||||
"nonce": "0000e5739438a096ca89cde16bcf6001e0c5a7ce6f7c591d26314c26c2560000",
|
||||
"solution": "0053f4438864bc5d6dfc009d4bba545ac5e5feaaf46f9455b975b02115f842a966e26517ce678f1c074d09cc8d0049a190859eb505af5f3e760312fbbe54da115db2bc03c96408f39b679891790b539d2d9d17a801dc6af9af14ca3f6ba060edce2a1dd45aa45f11fe37dbaf1eb2647ae7c393f6680c3d5d7e53687e34530f48edf58924a04d3e0231c150b1c8218998f674bc171edd222bcb4ac4ba4ea52d7baa86399f371d5284043e1e166f9069dd0f2904ff94c7922a70fa7c660e0553cc40a20d9ee08eb3f47278485801ddae9c270411360773f0b74e03db2d92c50952c9bd4924bbca2a260e1235e99df51fe71e75744232f2d641ef94f394110a5ad05f51a057e4cb515b92c16cb1404a8cdcc43d4a4bb2caa54ca35dccf41aa7d832da65123b7029223c46ed2a13387d598d445435d3cb32fdad9e27672903864c90d86353b162033078327b5b7aaffc89b40096ae004f2d5c6bd2c99188574348518db66e9b6020f93f12ee1c06f7b00fe346fefceaffb1da9e3cdf08285057f549733eb10825737fcd1431bfdfb155f323f24e95a869212baacf445b30f2670206645779110e6547d5da90a5f2fe5151da911d5ecd5a833023661d1356b6c395d85968947678d53efd4db7b06f23b21125e74492644277ea0c1131b80d6a4e3e8093b82332556fbb3255a55ac3f0b7e4844c0e12bf577c37fd02323ae5ef4781772ed501d63b568032a3d31576c5104a48c01ac54f715286932351a8adc8cf2467a84a0572e99f366ee00f82c3735545fd4bb941d591ce70070425a81304272db89887949bc7dd8236bb7e82190f9815da938cd6e8fec7660e91354326a7a9bfe38120e97997fca3c289d54513ed00286c2b825fbe84f91a39528f335674b5e957425a6edfdd00f2feb2c2df575616197998c1e964e069875d4d934f419a9b02b100848d023b76d47bd4e284c3895ef9227a40d8ea8826e86c7155d6aa95b8f9175812523a32cd611efc700688e03f7c245c5bff01718281b5d75cefe8318b2c08962236b14a0bf79534c203df735fd9cced97cbae07c2b4ee9cda8c9993f3f6277ff3fec261fb94d3961c4befe4b0893dcf67b312c7d8d6ff7adc8539cb2b1d3534fccf109efddd07a9f1e77b94ab1e505b164221dca1c34621b1e9d234c31a032a401267d95f65b800d579a2482638dfeade804149c81e95d7ef5510ac0b6212231506b1c635a2e1d2f0c9712989f9f246762fadb4c55c20f707dcc0e510a33e9465fc5d5bdbfa524dab0d7a1c6a1baaa36869cf542aa2257c5c44ef07547a570343442c6091e13bc04d559dc0e6db5b001861914bf956816edce2a86b274bd97f27e2dbb08608c16a3e5d8595952faa91fb162d7fa6a7a47e849a1ad8fab3ba620ee3295a04fe13e5fb655ac92ae60d01020b8999526af8d56b28733e69c9ffb285de27c61edc0bf62261ac0787eff347d0fcd62257301ede9603106ea41650a3e3119bd5c4e86a7f6a3f00934f3a545f7f21d41699f3e35d38cf925a8bdaf2bf7eedea11c31c3d8bf6c527c77c6378281cdf02211a58fa5e46d28d7e7c5fb79d69b31703fd752395da115845952cf99aaeb2155c2ab951a69f67d938f223185567e52cfa3e57b62c790bf78674c4b02c12b7d3225fe8f705b408ba11c24245b3924482e2f3480994461b550641a88cd941d371139f3498afacdcba1249631402b20695760eaada5376e68df0e45139c410700effc9420dc3726515e7fcb3f349320f30511451964bd9b6530682efec65910ceb548aa2ab05ac3309e803161697213631ae8e13cc7d223ac28446c1bf94a19a8782ac16ff57df7ee4f10fb6e488c02c68d6b6dee6987f6d2c39227da366c59f54ff67e312ca530e7c467c3dc8",
|
||||
"bits": "2007ffff",
|
||||
"difficulty": 1.0,
|
||||
"trees": {},
|
||||
"previousblockhash": "05a60a92d99d85997cce3b87616c089f6124d7342af37106edc76126334a2c38",
|
||||
"nextblockhash": "00f1a49e54553ac3ef735f2eb1d8247c9a87c22a47dbd7823ae70adcd6c21a18"
|
||||
}
|
||||
|
|
|
@ -55,6 +55,37 @@ async fn rpc_getinfo() {
|
|||
assert!(rpc_tx_queue_task_result.is_none());
|
||||
}
|
||||
|
||||
// Helper function that returns the nonce and final sapling root of a given
|
||||
// Block.
|
||||
async fn get_block_data(
|
||||
read_state: &ReadStateService,
|
||||
block: Arc<Block>,
|
||||
height: usize,
|
||||
) -> ([u8; 32], [u8; 32]) {
|
||||
let zebra_state::ReadResponse::SaplingTree(sapling_tree) = read_state
|
||||
.clone()
|
||||
.oneshot(zebra_state::ReadRequest::SaplingTree(HashOrHeight::Height(
|
||||
(height as u32).try_into().unwrap(),
|
||||
)))
|
||||
.await
|
||||
.expect("should have sapling tree for block hash")
|
||||
else {
|
||||
panic!("unexpected response to SaplingTree request")
|
||||
};
|
||||
|
||||
let mut expected_nonce = *block.header.nonce;
|
||||
expected_nonce.reverse();
|
||||
let sapling_tree = sapling_tree.expect("should always have sapling root");
|
||||
let expected_final_sapling_root: [u8; 32] = if sapling_tree.position().is_some() {
|
||||
let mut root: [u8; 32] = sapling_tree.root().into();
|
||||
root.reverse();
|
||||
root
|
||||
} else {
|
||||
[0; 32]
|
||||
};
|
||||
(expected_nonce, expected_final_sapling_root)
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn rpc_getblock() {
|
||||
let _init_guard = zebra_test::init();
|
||||
|
@ -78,7 +109,7 @@ async fn rpc_getblock() {
|
|||
false,
|
||||
true,
|
||||
Buffer::new(mempool.clone(), 1),
|
||||
read_state,
|
||||
read_state.clone(),
|
||||
latest_chain_tip,
|
||||
);
|
||||
|
||||
|
@ -132,53 +163,8 @@ async fn rpc_getblock() {
|
|||
.await
|
||||
.expect("We should have a GetBlock struct");
|
||||
|
||||
assert_eq!(
|
||||
get_block,
|
||||
GetBlock::Object {
|
||||
hash: GetBlockHash(block.hash()),
|
||||
confirmations: (blocks.len() - i).try_into().expect("valid i64"),
|
||||
height: Some(Height(i.try_into().expect("valid u32"))),
|
||||
time: None,
|
||||
tx: block
|
||||
.transactions
|
||||
.iter()
|
||||
.map(|tx| tx.hash().encode_hex())
|
||||
.collect(),
|
||||
trees,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Make hash calls with verbosity=1 and check response
|
||||
for (i, block) in blocks.iter().enumerate() {
|
||||
let get_block = rpc
|
||||
.get_block(blocks[i].hash().to_string(), Some(1u8))
|
||||
.await
|
||||
.expect("We should have a GetBlock struct");
|
||||
|
||||
assert_eq!(
|
||||
get_block,
|
||||
GetBlock::Object {
|
||||
hash: GetBlockHash(block.hash()),
|
||||
confirmations: (blocks.len() - i).try_into().expect("valid i64"),
|
||||
height: None,
|
||||
time: None,
|
||||
tx: block
|
||||
.transactions
|
||||
.iter()
|
||||
.map(|tx| tx.hash().encode_hex())
|
||||
.collect(),
|
||||
trees,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Make height calls with verbosity=2 and check response
|
||||
for (i, block) in blocks.iter().enumerate() {
|
||||
let get_block = rpc
|
||||
.get_block(i.to_string(), Some(2u8))
|
||||
.await
|
||||
.expect("We should have a GetBlock struct");
|
||||
let (expected_nonce, expected_final_sapling_root) =
|
||||
get_block_data(&read_state, block.clone(), i).await;
|
||||
|
||||
assert_eq!(
|
||||
get_block,
|
||||
|
@ -193,6 +179,108 @@ async fn rpc_getblock() {
|
|||
.map(|tx| tx.hash().encode_hex())
|
||||
.collect(),
|
||||
trees,
|
||||
size: None,
|
||||
version: Some(block.header.version),
|
||||
merkle_root: Some(block.header.merkle_root),
|
||||
final_sapling_root: Some(expected_final_sapling_root),
|
||||
final_orchard_root: None,
|
||||
nonce: Some(expected_nonce),
|
||||
bits: Some(block.header.difficulty_threshold),
|
||||
difficulty: Some(
|
||||
block
|
||||
.header
|
||||
.difficulty_threshold
|
||||
.relative_to_network(&Mainnet)
|
||||
),
|
||||
previous_block_hash: Some(GetBlockHash(block.header.previous_block_hash)),
|
||||
next_block_hash: blocks.get(i + 1).map(|b| GetBlockHash(b.hash())),
|
||||
solution: Some(block.header.solution),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Make hash calls with verbosity=1 and check response
|
||||
for (i, block) in blocks.iter().enumerate() {
|
||||
let get_block = rpc
|
||||
.get_block(blocks[i].hash().to_string(), Some(1u8))
|
||||
.await
|
||||
.expect("We should have a GetBlock struct");
|
||||
|
||||
let (expected_nonce, expected_final_sapling_root) =
|
||||
get_block_data(&read_state, block.clone(), i).await;
|
||||
|
||||
assert_eq!(
|
||||
get_block,
|
||||
GetBlock::Object {
|
||||
hash: GetBlockHash(block.hash()),
|
||||
confirmations: (blocks.len() - i).try_into().expect("valid i64"),
|
||||
height: Some(Height(i.try_into().expect("valid u32"))),
|
||||
time: Some(block.header.time.timestamp()),
|
||||
tx: block
|
||||
.transactions
|
||||
.iter()
|
||||
.map(|tx| tx.hash().encode_hex())
|
||||
.collect(),
|
||||
trees,
|
||||
size: None,
|
||||
version: Some(block.header.version),
|
||||
merkle_root: Some(block.header.merkle_root),
|
||||
final_sapling_root: Some(expected_final_sapling_root),
|
||||
final_orchard_root: None,
|
||||
nonce: Some(expected_nonce),
|
||||
bits: Some(block.header.difficulty_threshold),
|
||||
difficulty: Some(
|
||||
block
|
||||
.header
|
||||
.difficulty_threshold
|
||||
.relative_to_network(&Mainnet)
|
||||
),
|
||||
previous_block_hash: Some(GetBlockHash(block.header.previous_block_hash)),
|
||||
next_block_hash: blocks.get(i + 1).map(|b| GetBlockHash(b.hash())),
|
||||
solution: Some(block.header.solution),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Make height calls with verbosity=2 and check response
|
||||
for (i, block) in blocks.iter().enumerate() {
|
||||
let get_block = rpc
|
||||
.get_block(i.to_string(), Some(2u8))
|
||||
.await
|
||||
.expect("We should have a GetBlock struct");
|
||||
|
||||
let (expected_nonce, expected_final_sapling_root) =
|
||||
get_block_data(&read_state, block.clone(), i).await;
|
||||
|
||||
assert_eq!(
|
||||
get_block,
|
||||
GetBlock::Object {
|
||||
hash: GetBlockHash(block.hash()),
|
||||
confirmations: (blocks.len() - i).try_into().expect("valid i64"),
|
||||
height: Some(Height(i.try_into().expect("valid u32"))),
|
||||
time: Some(block.header.time.timestamp()),
|
||||
tx: block
|
||||
.transactions
|
||||
.iter()
|
||||
.map(|tx| tx.hash().encode_hex())
|
||||
.collect(),
|
||||
trees,
|
||||
size: None,
|
||||
version: Some(block.header.version),
|
||||
merkle_root: Some(block.header.merkle_root),
|
||||
final_sapling_root: Some(expected_final_sapling_root),
|
||||
final_orchard_root: None,
|
||||
nonce: Some(expected_nonce),
|
||||
bits: Some(block.header.difficulty_threshold),
|
||||
difficulty: Some(
|
||||
block
|
||||
.header
|
||||
.difficulty_threshold
|
||||
.relative_to_network(&Mainnet)
|
||||
),
|
||||
previous_block_hash: Some(GetBlockHash(block.header.previous_block_hash)),
|
||||
next_block_hash: blocks.get(i + 1).map(|b| GetBlockHash(b.hash())),
|
||||
solution: Some(block.header.solution),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -204,6 +292,9 @@ async fn rpc_getblock() {
|
|||
.await
|
||||
.expect("We should have a GetBlock struct");
|
||||
|
||||
let (expected_nonce, expected_final_sapling_root) =
|
||||
get_block_data(&read_state, block.clone(), i).await;
|
||||
|
||||
assert_eq!(
|
||||
get_block,
|
||||
GetBlock::Object {
|
||||
|
@ -217,6 +308,22 @@ async fn rpc_getblock() {
|
|||
.map(|tx| tx.hash().encode_hex())
|
||||
.collect(),
|
||||
trees,
|
||||
size: None,
|
||||
version: Some(block.header.version),
|
||||
merkle_root: Some(block.header.merkle_root),
|
||||
final_sapling_root: Some(expected_final_sapling_root),
|
||||
final_orchard_root: None,
|
||||
nonce: Some(expected_nonce),
|
||||
bits: Some(block.header.difficulty_threshold),
|
||||
difficulty: Some(
|
||||
block
|
||||
.header
|
||||
.difficulty_threshold
|
||||
.relative_to_network(&Mainnet)
|
||||
),
|
||||
previous_block_hash: Some(GetBlockHash(block.header.previous_block_hash)),
|
||||
next_block_hash: blocks.get(i + 1).map(|b| GetBlockHash(b.hash())),
|
||||
solution: Some(block.header.solution),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -228,19 +335,38 @@ async fn rpc_getblock() {
|
|||
.await
|
||||
.expect("We should have a GetBlock struct");
|
||||
|
||||
let (expected_nonce, expected_final_sapling_root) =
|
||||
get_block_data(&read_state, block.clone(), i).await;
|
||||
|
||||
assert_eq!(
|
||||
get_block,
|
||||
GetBlock::Object {
|
||||
hash: GetBlockHash(block.hash()),
|
||||
confirmations: (blocks.len() - i).try_into().expect("valid i64"),
|
||||
height: Some(Height(i.try_into().expect("valid u32"))),
|
||||
time: None,
|
||||
time: Some(block.header.time.timestamp()),
|
||||
tx: block
|
||||
.transactions
|
||||
.iter()
|
||||
.map(|tx| tx.hash().encode_hex())
|
||||
.collect(),
|
||||
trees,
|
||||
size: None,
|
||||
version: Some(block.header.version),
|
||||
merkle_root: Some(block.header.merkle_root),
|
||||
final_sapling_root: Some(expected_final_sapling_root),
|
||||
final_orchard_root: None,
|
||||
nonce: Some(expected_nonce),
|
||||
bits: Some(block.header.difficulty_threshold),
|
||||
difficulty: Some(
|
||||
block
|
||||
.header
|
||||
.difficulty_threshold
|
||||
.relative_to_network(&Mainnet)
|
||||
),
|
||||
previous_block_hash: Some(GetBlockHash(block.header.previous_block_hash)),
|
||||
next_block_hash: blocks.get(i + 1).map(|b| GetBlockHash(b.hash())),
|
||||
solution: Some(block.header.solution),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -252,19 +378,38 @@ async fn rpc_getblock() {
|
|||
.await
|
||||
.expect("We should have a GetBlock struct");
|
||||
|
||||
let (expected_nonce, expected_final_sapling_root) =
|
||||
get_block_data(&read_state, block.clone(), i).await;
|
||||
|
||||
assert_eq!(
|
||||
get_block,
|
||||
GetBlock::Object {
|
||||
hash: GetBlockHash(block.hash()),
|
||||
confirmations: (blocks.len() - i).try_into().expect("valid i64"),
|
||||
height: None,
|
||||
time: None,
|
||||
height: Some(Height(i.try_into().expect("valid u32"))),
|
||||
time: Some(block.header.time.timestamp()),
|
||||
tx: block
|
||||
.transactions
|
||||
.iter()
|
||||
.map(|tx| tx.hash().encode_hex())
|
||||
.collect(),
|
||||
trees,
|
||||
size: None,
|
||||
version: Some(block.header.version),
|
||||
merkle_root: Some(block.header.merkle_root),
|
||||
final_sapling_root: Some(expected_final_sapling_root),
|
||||
final_orchard_root: None,
|
||||
nonce: Some(expected_nonce),
|
||||
bits: Some(block.header.difficulty_threshold),
|
||||
difficulty: Some(
|
||||
block
|
||||
.header
|
||||
.difficulty_threshold
|
||||
.relative_to_network(&Mainnet)
|
||||
),
|
||||
previous_block_hash: Some(GetBlockHash(block.header.previous_block_hash)),
|
||||
next_block_hash: blocks.get(i + 1).map(|b| GetBlockHash(b.hash())),
|
||||
solution: Some(block.header.solution),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -449,6 +594,7 @@ async fn rpc_getblockheader() {
|
|||
version: 4,
|
||||
merkle_root: block.header.merkle_root,
|
||||
final_sapling_root: expected_final_sapling_root,
|
||||
sapling_tree_size: sapling_tree.count(),
|
||||
time: block.header.time.timestamp(),
|
||||
nonce: expected_nonce,
|
||||
solution: block.header.solution,
|
||||
|
|
|
@ -22,6 +22,9 @@ JQ="${JQ:-jq}"
|
|||
# - Use `-rpccookiefile=your/cookie/file` for a cookie file.
|
||||
# - Use `-rpcpassword=your-password` for a password.
|
||||
ZCASHD_EXTRA_ARGS="${ZCASHD_EXTRA_ARGS:-}"
|
||||
# Zebrad authentication modes:
|
||||
# - Use `-rpccookiefile=your/cookie/file` for a cookie file.
|
||||
ZEBRAD_EXTRA_ARGS="${ZEBRAD_EXTRA_ARGS:-}"
|
||||
# We show this many lines of data, removing excess lines from the middle or end of the output.
|
||||
OUTPUT_DATA_LINE_LIMIT="${OUTPUT_DATA_LINE_LIMIT:-40}"
|
||||
# When checking different mempools, we show this many different transactions.
|
||||
|
@ -49,7 +52,7 @@ ZEBRAD_RELEASE_INFO="$ZCASH_RPC_TMP_DIR/first-node-check-getinfo.json"
|
|||
ZCASHD_RELEASE_INFO="$ZCASH_RPC_TMP_DIR/second-node-check-getinfo.json"
|
||||
|
||||
echo "Checking first node release info..."
|
||||
$ZCASH_CLI -rpcport="$ZEBRAD_RPC_PORT" getinfo > "$ZEBRAD_RELEASE_INFO"
|
||||
$ZCASH_CLI $ZEBRAD_EXTRA_ARGS -rpcport="$ZEBRAD_RPC_PORT" getinfo > "$ZEBRAD_RELEASE_INFO"
|
||||
|
||||
ZEBRAD_NAME=$(cat "$ZEBRAD_RELEASE_INFO" | grep '"subversion"' | cut -d: -f2 | cut -d/ -f2 | \
|
||||
tr 'A-Z' 'a-z' | sed 's/magicbean/zcashd/ ; s/zebra$/zebrad/')
|
||||
|
@ -74,7 +77,7 @@ ZEBRAD_BLOCKCHAIN_INFO="$ZCASH_RPC_TMP_DIR/$ZEBRAD_NAME-check-getblockchaininfo.
|
|||
ZCASHD_BLOCKCHAIN_INFO="$ZCASH_RPC_TMP_DIR/$ZCASHD_NAME-check-getblockchaininfo.json"
|
||||
|
||||
echo "Checking $ZEBRAD network and tip height..."
|
||||
$ZCASH_CLI -rpcport="$ZEBRAD_RPC_PORT" getblockchaininfo > "$ZEBRAD_BLOCKCHAIN_INFO"
|
||||
$ZCASH_CLI $ZEBRAD_EXTRA_ARGS -rpcport="$ZEBRAD_RPC_PORT" getblockchaininfo > "$ZEBRAD_BLOCKCHAIN_INFO"
|
||||
|
||||
ZEBRAD_NET=$(cat "$ZEBRAD_BLOCKCHAIN_INFO" | grep '"chain"' | cut -d: -f2 | tr -d ' ,"')
|
||||
ZEBRAD_HEIGHT=$(cat "$ZEBRAD_BLOCKCHAIN_INFO" | grep '"blocks"' | cut -d: -f2 | tr -d ' ,"')
|
||||
|
@ -109,7 +112,7 @@ echo "$@"
|
|||
echo
|
||||
|
||||
echo "Querying $ZEBRAD $ZEBRAD_NET chain at height >=$ZEBRAD_HEIGHT..."
|
||||
time $ZCASH_CLI -rpcport="$ZEBRAD_RPC_PORT" "$@" > "$ZEBRAD_RESPONSE"
|
||||
time $ZCASH_CLI $ZEBRAD_EXTRA_ARGS -rpcport="$ZEBRAD_RPC_PORT" "$@" > "$ZEBRAD_RESPONSE"
|
||||
echo
|
||||
|
||||
echo "Querying $ZCASHD $ZCASHD_NET chain at height >=$ZCASHD_HEIGHT..."
|
||||
|
@ -166,7 +169,7 @@ echo "$@"
|
|||
echo
|
||||
|
||||
echo "Querying $ZEBRAD $ZEBRAD_NET chain at height >=$ZEBRAD_HEIGHT..."
|
||||
$ZCASH_CLI -rpcport="$ZEBRAD_RPC_PORT" "$@" > "$ZEBRAD_CHECK_RESPONSE"
|
||||
$ZCASH_CLI $ZEBRAD_EXTRA_ARGS -rpcport="$ZEBRAD_RPC_PORT" "$@" > "$ZEBRAD_CHECK_RESPONSE"
|
||||
|
||||
echo "Querying $ZCASHD $ZCASHD_NET chain at height >=$ZCASHD_HEIGHT..."
|
||||
$ZCASH_CLI $ZCASHD_EXTRA_ARGS "$@" > "$ZCASHD_CHECK_RESPONSE"
|
||||
|
@ -257,7 +260,7 @@ if [ "$1" == "getrawmempool" ] && [ $CHECK_EXIT_STATUS != 0 ]; then
|
|||
for TRANSACTION_ID in $ZEBRAD_TRANSACTION_IDS; do
|
||||
TRANSACTION_HEX_FILE="$ZCASH_RPC_TMP_DIR/$ZEBRAD_NAME-$ZEBRAD_NET-$ZEBRAD_HEIGHT-$TRANSACTION_ID.json"
|
||||
|
||||
$ZCASH_CLI -rpcport="$ZEBRAD_RPC_PORT" getrawtransaction $TRANSACTION_ID 0 > $TRANSACTION_HEX_FILE
|
||||
$ZCASH_CLI $ZEBRAD_EXTRA_ARGS -rpcport="$ZEBRAD_RPC_PORT" getrawtransaction $TRANSACTION_ID 0 > $TRANSACTION_HEX_FILE
|
||||
|
||||
echo "## Displaying transaction $TRANSACTION_ID from zebrad (limited to ${OUTPUT_DATA_LINE_LIMIT} lines)"
|
||||
echo
|
||||
|
|
Loading…
Reference in New Issue