zebra_consensus/
script.rs
1use std::{future::Future, pin::Pin, sync::Arc};
2
3use tracing::Instrument;
4
5use zebra_chain::transparent;
6use zebra_script::CachedFfiTransaction;
7
8use crate::BoxError;
9
10#[derive(Debug, Clone, Default, Copy, PartialEq, Eq)]
22pub struct Verifier;
23
24#[derive(Debug)]
26pub struct Request {
27 pub cached_ffi_transaction: Arc<CachedFfiTransaction>,
29 pub input_index: usize,
33}
34
35impl tower::Service<Request> for Verifier {
36 type Response = ();
37 type Error = BoxError;
38 type Future =
39 Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + 'static>>;
40
41 fn poll_ready(
42 &mut self,
43 _cx: &mut std::task::Context<'_>,
44 ) -> std::task::Poll<Result<(), Self::Error>> {
45 std::task::Poll::Ready(Ok(()))
46 }
47
48 fn call(&mut self, req: Request) -> Self::Future {
49 use futures_util::FutureExt;
50
51 let Request {
52 cached_ffi_transaction,
53 input_index,
54 } = req;
55 let input = &cached_ffi_transaction.inputs()[input_index];
56 match input {
57 transparent::Input::PrevOut { outpoint, .. } => {
58 let outpoint = *outpoint;
59
60 let span = tracing::trace_span!("script", ?outpoint);
62
63 async move {
64 cached_ffi_transaction.is_valid(input_index)?;
65 tracing::trace!("script verification succeeded");
66
67 Ok(())
68 }
69 .instrument(span)
70 .boxed()
71 }
72 transparent::Input::Coinbase { .. } => {
73 async { Err("unexpected coinbase input".into()) }.boxed()
74 }
75 }
76 }
77}