state: fill in RFC5-style Request, Response enums
The test transcripts need to be rewritten, so they are removed for now.
This commit is contained in:
parent
98d5351206
commit
070013439e
|
@ -23,7 +23,7 @@ use memory_state::MemoryState;
|
|||
use sled_state::SledState;
|
||||
|
||||
pub use config::Config;
|
||||
pub use request::Request;
|
||||
pub use request::{HashOrHeight, Request};
|
||||
pub use response::Response;
|
||||
pub use service::init;
|
||||
|
||||
|
|
|
@ -1,32 +1,110 @@
|
|||
use std::sync::Arc;
|
||||
use zebra_chain::block::{self, Block};
|
||||
use zebra_chain::{
|
||||
block::{self, Block},
|
||||
transaction,
|
||||
};
|
||||
|
||||
// Allow *only* this unused import, so that rustdoc link resolution
|
||||
// will work with inline links.
|
||||
#[allow(unused_imports)]
|
||||
use crate::Response;
|
||||
|
||||
/// Identify a block by hash or height.
|
||||
///
|
||||
/// This enum implements `From` for [`block::Hash`] and [`block::Height`],
|
||||
/// so it can be created using `hash.into()` or `height.into()`.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum HashOrHeight {
|
||||
/// A block identified by hash.
|
||||
Hash(block::Hash),
|
||||
/// A block identified by height.
|
||||
Height(block::Height),
|
||||
}
|
||||
|
||||
impl From<block::Hash> for HashOrHeight {
|
||||
fn from(hash: block::Hash) -> Self {
|
||||
Self::Hash(hash)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<block::Height> for HashOrHeight {
|
||||
fn from(hash: block::Height) -> Self {
|
||||
Self::Height(hash)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
/// A query about or modification to the chain state.
|
||||
///
|
||||
/// TODO: replace these variants with the ones in RFC5.
|
||||
pub enum Request {
|
||||
// TODO(jlusby): deprecate in the future based on our validation story
|
||||
/// Add a block to the zebra-state
|
||||
AddBlock {
|
||||
/// The block to be added to the state
|
||||
/// Performs contextual validation of the given block, committing it to the
|
||||
/// state if successful.
|
||||
///
|
||||
/// Returns [`Response::Committed`] with the hash of the newly
|
||||
/// committed block, or an error.
|
||||
///
|
||||
/// This request can be made out-of-order; the state service will buffer it
|
||||
/// until its parent is ready.
|
||||
CommitBlock {
|
||||
/// The block to commit to the state.
|
||||
block: Arc<Block>,
|
||||
// TODO: add these parameters when we can compute anchors.
|
||||
// sprout_anchor: sprout::tree::Root,
|
||||
// sapling_anchor: sapling::tree::Root,
|
||||
},
|
||||
/// Get a block from the zebra-state
|
||||
GetBlock {
|
||||
/// The hash used to identify the block
|
||||
hash: block::Hash,
|
||||
},
|
||||
/// Get a block locator list for the current best chain
|
||||
GetBlockLocator {
|
||||
/// The genesis block of the current best chain
|
||||
genesis: block::Hash,
|
||||
},
|
||||
/// Get the block that is the tip of the current chain
|
||||
GetTip,
|
||||
/// Ask the state if the given hash is part of the current best chain
|
||||
GetDepth {
|
||||
/// The hash to check against the current chain
|
||||
hash: block::Hash,
|
||||
|
||||
/// Commit a finalized block to the state, skipping contextual validation.
|
||||
/// This is exposed for use in checkpointing, which produces finalized
|
||||
/// blocks.
|
||||
///
|
||||
/// Returns [`Response::Committed`] with the hash of the newly
|
||||
/// committed block, or an error.
|
||||
///
|
||||
/// This request can be made out-of-order; the state service will buffer it
|
||||
/// until its parent is ready.
|
||||
CommitFinalizedBlock {
|
||||
/// The block to commit to the state.
|
||||
block: Arc<Block>,
|
||||
// TODO: add these parameters when we can compute anchors.
|
||||
// sprout_anchor: sprout::tree::Root,
|
||||
// sapling_anchor: sapling::tree::Root,
|
||||
},
|
||||
|
||||
/// Computes the depth in the best chain of the block identified by the given hash.
|
||||
///
|
||||
/// Returns
|
||||
///
|
||||
/// * [`Response::Depth(Some(depth))`](Response::Depth) if the block is in the main chain;
|
||||
/// * [`Response::Depth(None)`](Response::Depth) otherwise.
|
||||
Depth(block::Hash),
|
||||
|
||||
/// Returns [`Response::Tip`] with the current best chain tip.
|
||||
Tip,
|
||||
|
||||
/// Computes a block locator object based on the current chain state.
|
||||
///
|
||||
/// Returns [`Response::BlockLocator`] with hashes starting
|
||||
/// from the current chain tip and reaching backwards towards the genesis
|
||||
/// block. The first hash is the current chain tip. The last hash is the tip
|
||||
/// of the finalized portion of the state. If the state is empty, the block
|
||||
/// locator is also empty.
|
||||
BlockLocator,
|
||||
|
||||
/// Looks up a transaction by hash.
|
||||
///
|
||||
/// Returns
|
||||
///
|
||||
/// * [`Response::Transaction(Some(Arc<Transaction>))`](Response::Transaction) if the transaction is known;
|
||||
/// * [`Response::Transaction(None)`](Response::Transaction) otherwise.
|
||||
Transaction(transaction::Hash),
|
||||
|
||||
/// Looks up a block by hash or height.
|
||||
///
|
||||
/// Returns
|
||||
///
|
||||
/// * [`Response::Block(Some(Arc<Block>))`](Response::Block) if the block is known;
|
||||
/// * [`Response::Block(None)`](Response::Transaction) otherwise.
|
||||
///
|
||||
/// Note: the [`HashOrHeight`] can be constructed from a [`block::Hash`] or
|
||||
/// [`block::Height`] using `.into()`.
|
||||
Block(HashOrHeight),
|
||||
}
|
||||
|
|
|
@ -1,34 +1,33 @@
|
|||
use std::sync::Arc;
|
||||
use zebra_chain::block::{self, Block};
|
||||
use zebra_chain::{
|
||||
block::{self, Block},
|
||||
transaction::Transaction,
|
||||
};
|
||||
|
||||
// Allow *only* this unused import, so that rustdoc link resolution
|
||||
// will work with inline links.
|
||||
#[allow(unused_imports)]
|
||||
use crate::Request;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
/// A response to a state [`Request`](super::Request).
|
||||
/// A response to a state [`Request`].
|
||||
pub enum Response {
|
||||
/// The response to a `AddBlock` request indicating a block was successfully
|
||||
/// added to the state
|
||||
Added {
|
||||
/// The hash of the block that was added
|
||||
hash: block::Hash,
|
||||
},
|
||||
/// The response to a `GetBlock` request by hash
|
||||
Block {
|
||||
/// The block that was requested
|
||||
block: Arc<Block>,
|
||||
},
|
||||
/// The response to a `GetBlockLocator` request
|
||||
BlockLocator {
|
||||
/// The set of blocks that make up the block locator
|
||||
block_locator: Vec<block::Hash>,
|
||||
},
|
||||
/// The response to a `GetTip` request
|
||||
Tip {
|
||||
/// The hash of the block at the tip of the current chain
|
||||
hash: block::Hash,
|
||||
},
|
||||
/// The response to a `Contains` request indicating that the given has is in
|
||||
/// the current best chain
|
||||
Depth(
|
||||
/// The number of blocks above the given block in the current best chain
|
||||
Option<u32>,
|
||||
),
|
||||
/// Response to [`Request::CommitBlock`] indicating that a block was
|
||||
/// successfully committed to the state.
|
||||
Committed(block::Hash),
|
||||
|
||||
/// Response to [`Request::Depth`] with the depth of the specified block.
|
||||
Depth(Option<block::Height>),
|
||||
|
||||
/// Response to [`Request::Tip`] with the current best chain tip.
|
||||
Tip(Option<block::Hash>),
|
||||
|
||||
/// Response to [`Request::BlockLocator`] with a block locator object.
|
||||
BlockLocator(Vec<block::Hash>),
|
||||
|
||||
/// Response to [`Request::Transaction`] with the specified transaction.
|
||||
Transaction(Option<Arc<Transaction>>),
|
||||
|
||||
/// Response to [`Request::Block`] with the specified block.
|
||||
Block(Option<Arc<Block>>),
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ use std::{
|
|||
use tower::{buffer::Buffer, util::BoxService, Service};
|
||||
use zebra_chain::parameters::Network;
|
||||
|
||||
use crate::{BoxError, Config, MemoryState, Request, Response, SledState};
|
||||
use crate::{BoxError, Config, HashOrHeight, MemoryState, Request, Response, SledState};
|
||||
|
||||
struct StateService {
|
||||
/// Holds data relating to finalized chain state.
|
||||
|
@ -35,11 +35,14 @@ impl Service<Request> for StateService {
|
|||
|
||||
fn call(&mut self, req: Request) -> Self::Future {
|
||||
match req {
|
||||
Request::AddBlock { block } => unimplemented!(),
|
||||
Request::GetBlock { hash } => unimplemented!(),
|
||||
Request::GetTip => unimplemented!(),
|
||||
Request::GetDepth { hash } => unimplemented!(),
|
||||
Request::GetBlockLocator { genesis } => unimplemented!(),
|
||||
Request::CommitBlock { block } => unimplemented!(),
|
||||
Request::CommitFinalizedBlock { block } => unimplemented!(),
|
||||
Request::Depth(hash) => unimplemented!(),
|
||||
Request::Tip => unimplemented!(),
|
||||
Request::BlockLocator => unimplemented!(),
|
||||
Request::Transaction(hash) => unimplemented!(),
|
||||
Request::Block(HashOrHeight::Hash(hash)) => unimplemented!(),
|
||||
Request::Block(HashOrHeight::Height(height)) => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,145 +7,43 @@ use zebra_test::transcript::{TransError, Transcript};
|
|||
|
||||
use zebra_state::*;
|
||||
|
||||
static ADD_BLOCK_TRANSCRIPT_MAINNET: Lazy<Vec<(Request, Result<Response, TransError>)>> =
|
||||
static COMMIT_FINALIZED_BLOCK_MAINNET: Lazy<Vec<(Request, Result<Response, TransError>)>> =
|
||||
Lazy::new(|| {
|
||||
let block: Arc<_> =
|
||||
Block::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_GENESIS_BYTES[..])
|
||||
.unwrap()
|
||||
.into();
|
||||
let hash = block.as_ref().into();
|
||||
let block2 = block.clone();
|
||||
let hash = block.hash();
|
||||
vec![
|
||||
(
|
||||
Request::AddBlock {
|
||||
block: block.clone(),
|
||||
},
|
||||
Ok(Response::Added { hash }),
|
||||
Request::CommitFinalizedBlock { block },
|
||||
Ok(Response::Committed(hash)),
|
||||
),
|
||||
(
|
||||
Request::Block(hash.into()),
|
||||
Ok(Response::Block(Some(block2))),
|
||||
),
|
||||
(Request::GetBlock { hash }, Ok(Response::Block { block })),
|
||||
]
|
||||
});
|
||||
|
||||
static ADD_BLOCK_TRANSCRIPT_TESTNET: Lazy<Vec<(Request, Result<Response, TransError>)>> =
|
||||
static COMMIT_FINALIZED_BLOCK_TESTNET: Lazy<Vec<(Request, Result<Response, TransError>)>> =
|
||||
Lazy::new(|| {
|
||||
let block: Arc<_> =
|
||||
Block::zcash_deserialize(&zebra_test::vectors::BLOCK_TESTNET_GENESIS_BYTES[..])
|
||||
.unwrap()
|
||||
.into();
|
||||
let hash = block.as_ref().into();
|
||||
let block2 = block.clone();
|
||||
let hash = block.hash();
|
||||
vec![
|
||||
(
|
||||
Request::AddBlock {
|
||||
block: block.clone(),
|
||||
},
|
||||
Ok(Response::Added { hash }),
|
||||
),
|
||||
(Request::GetBlock { hash }, Ok(Response::Block { block })),
|
||||
]
|
||||
});
|
||||
|
||||
static GET_TIP_ADD_ORDERED_TRANSCRIPT_MAINNET: Lazy<Vec<(Request, Result<Response, TransError>)>> =
|
||||
Lazy::new(|| {
|
||||
let block0: Arc<_> =
|
||||
Block::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_GENESIS_BYTES[..])
|
||||
.unwrap()
|
||||
.into();
|
||||
let block1: Arc<_> =
|
||||
Block::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_1_BYTES[..])
|
||||
.unwrap()
|
||||
.into();
|
||||
let hash0 = block0.as_ref().into();
|
||||
let hash1 = block1.as_ref().into();
|
||||
vec![
|
||||
// Insert the blocks in order
|
||||
(
|
||||
Request::AddBlock { block: block0 },
|
||||
Ok(Response::Added { hash: hash0 }),
|
||||
Request::CommitFinalizedBlock { block },
|
||||
Ok(Response::Committed(hash)),
|
||||
),
|
||||
(
|
||||
Request::AddBlock { block: block1 },
|
||||
Ok(Response::Added { hash: hash1 }),
|
||||
Request::Block(hash.into()),
|
||||
Ok(Response::Block(Some(block2))),
|
||||
),
|
||||
(Request::GetTip, Ok(Response::Tip { hash: hash1 })),
|
||||
]
|
||||
});
|
||||
|
||||
static GET_TIP_ADD_ORDERED_TRANSCRIPT_TESTNET: Lazy<Vec<(Request, Result<Response, TransError>)>> =
|
||||
Lazy::new(|| {
|
||||
let block0: Arc<_> =
|
||||
Block::zcash_deserialize(&zebra_test::vectors::BLOCK_TESTNET_GENESIS_BYTES[..])
|
||||
.unwrap()
|
||||
.into();
|
||||
let block1: Arc<_> =
|
||||
Block::zcash_deserialize(&zebra_test::vectors::BLOCK_TESTNET_1_BYTES[..])
|
||||
.unwrap()
|
||||
.into();
|
||||
let hash0 = block0.as_ref().into();
|
||||
let hash1 = block1.as_ref().into();
|
||||
vec![
|
||||
// Insert the blocks in order
|
||||
(
|
||||
Request::AddBlock { block: block0 },
|
||||
Ok(Response::Added { hash: hash0 }),
|
||||
),
|
||||
(
|
||||
Request::AddBlock { block: block1 },
|
||||
Ok(Response::Added { hash: hash1 }),
|
||||
),
|
||||
(Request::GetTip, Ok(Response::Tip { hash: hash1 })),
|
||||
]
|
||||
});
|
||||
|
||||
#[allow(dead_code)]
|
||||
static GET_TIP_ADD_REVERSED_TRANSCRIPT_MAINNET: Lazy<Vec<(Request, Result<Response, TransError>)>> =
|
||||
Lazy::new(|| {
|
||||
let block0: Arc<_> =
|
||||
Block::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_GENESIS_BYTES[..])
|
||||
.unwrap()
|
||||
.into();
|
||||
let block1: Arc<_> =
|
||||
Block::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_1_BYTES[..])
|
||||
.unwrap()
|
||||
.into();
|
||||
let hash0 = block0.as_ref().into();
|
||||
let hash1 = block1.as_ref().into();
|
||||
vec![
|
||||
// Insert the blocks in reverse order
|
||||
(
|
||||
Request::AddBlock { block: block1 },
|
||||
Ok(Response::Added { hash: hash1 }),
|
||||
),
|
||||
(
|
||||
Request::AddBlock { block: block0 },
|
||||
Ok(Response::Added { hash: hash0 }),
|
||||
),
|
||||
(Request::GetTip, Ok(Response::Tip { hash: hash1 })),
|
||||
]
|
||||
});
|
||||
|
||||
#[allow(dead_code)]
|
||||
static GET_TIP_ADD_REVERSED_TRANSCRIPT_TESTNET: Lazy<Vec<(Request, Result<Response, TransError>)>> =
|
||||
Lazy::new(|| {
|
||||
let block0: Arc<_> =
|
||||
Block::zcash_deserialize(&zebra_test::vectors::BLOCK_TESTNET_GENESIS_BYTES[..])
|
||||
.unwrap()
|
||||
.into();
|
||||
let block1: Arc<_> =
|
||||
Block::zcash_deserialize(&zebra_test::vectors::BLOCK_TESTNET_1_BYTES[..])
|
||||
.unwrap()
|
||||
.into();
|
||||
let hash0 = block0.as_ref().into();
|
||||
let hash1 = block1.as_ref().into();
|
||||
vec![
|
||||
// Insert the blocks in reverse order
|
||||
(
|
||||
Request::AddBlock { block: block1 },
|
||||
Ok(Response::Added { hash: hash1 }),
|
||||
),
|
||||
(
|
||||
Request::AddBlock { block: block0 },
|
||||
Ok(Response::Added { hash: hash0 }),
|
||||
),
|
||||
(Request::GetTip, Ok(Response::Tip { hash: hash1 })),
|
||||
]
|
||||
});
|
||||
|
||||
|
@ -163,18 +61,8 @@ async fn check_transcripts_testnet() -> Result<(), Report> {
|
|||
async fn check_transcripts(network: Network) -> Result<(), Report> {
|
||||
zebra_test::init();
|
||||
|
||||
let mainnet_transcript = &[
|
||||
&ADD_BLOCK_TRANSCRIPT_MAINNET,
|
||||
&GET_TIP_ADD_ORDERED_TRANSCRIPT_MAINNET,
|
||||
// Temporarily disabled, until the state accepts out-of-order blocks
|
||||
//&GET_TIP_ADD_REVERSED_TRANSCRIPT_MAINNET,
|
||||
];
|
||||
let testnet_transcript = &[
|
||||
&ADD_BLOCK_TRANSCRIPT_TESTNET,
|
||||
&GET_TIP_ADD_ORDERED_TRANSCRIPT_TESTNET,
|
||||
// Temporarily disabled, until the state accepts out-of-order blocks
|
||||
//&GET_TIP_ADD_REVERSED_TRANSCRIPT_TESTNET,
|
||||
];
|
||||
let mainnet_transcript = &[&COMMIT_FINALIZED_BLOCK_MAINNET];
|
||||
let testnet_transcript = &[&COMMIT_FINALIZED_BLOCK_TESTNET];
|
||||
|
||||
for transcript_data in match network {
|
||||
Network::Mainnet => mainnet_transcript,
|
||||
|
|
Loading…
Reference in New Issue