-
Notifications
You must be signed in to change notification settings - Fork 102
/
Copy pathexecution.rs
149 lines (131 loc) · 4.65 KB
/
execution.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
use std::{convert::TryFrom, str::FromStr};
use raiko_lib::{
builder::{BlockBuilderStrategy, TaikoStrategy},
consts::Network,
input::{GuestInput, GuestOutput, TaikoProverData, WrappedHeader},
protocol_instance::{assemble_protocol_instance, ProtocolInstance},
prover::{to_proof, Proof, Prover, ProverResult},
taiko_utils::HeaderHasher,
Measurement,
};
use raiko_primitives::B256;
use serde::{Deserialize, Serialize};
use tracing::{info, warn};
use super::error::Result;
use crate::{error::HostError, memory, preflight::preflight, request::ProofRequest};
/// Execute the proof generation process
pub async fn execute<D: Prover>(
config: &Config,
cached_input: Option<GuestInput>,
) -> Result<(GuestInput, Proof)> {
let total_proving_time = Measurement::start("", false);
// Generate the input
let input = match cached_input {
Some(cached_input) => {
println!("Using cached input");
cached_input
}
None => {
memory::reset_stats();
let measurement = Measurement::start("Generating input...", false);
let input = prepare_input(config).await?;
measurement.stop_with("=> Input generated");
memory::print_stats("Input generation peak memory used: ");
input
}
};
// Test run the block
memory::reset_stats();
match TaikoStrategy::build_from(&input) {
Ok((header, _mpt_node)) => {
info!("Verifying final state using provider data ...");
info!("Final block hash derived successfully. {}", header.hash());
info!("Final block header derived successfully. {:?}", header);
let pi = D::instance_hash(assemble_protocol_instance(&input, &header)?);
// Make sure the blockhash from the node matches the one from the builder
assert_eq!(header.hash().0, input.block_hash, "block hash unexpected");
let output = GuestOutput::Success((
WrappedHeader {
header: header.clone(),
},
pi,
));
memory::print_stats("Guest program peak memory used: ");
// Prove
memory::reset_stats();
let measurement = Measurement::start("Generating proof...", false);
let res = D::run(input.clone(), output, config)
.await
.map(|proof| (input, proof))
.map_err(|e| HostError::GuestError(e.to_string()));
measurement.stop_with("=> Proof generated");
memory::print_stats("Prover peak memory used: ");
total_proving_time.stop_with("====> Complete proof generated");
res
}
Err(e) => {
warn!("Proving bad block construction!");
Err(HostError::GuestError(e.to_string()))
}
}
}
/// Prepare input data for provers
async fn prepare_input(config: &Config) -> Result<GuestInput> {
let req = ProofRequest::try_from(config)?;
let block_number = req.block_number;
let rpc = req.rpc.clone();
let l1_rpc = req.l1_rpc.clone();
let beacon_rpc = req.beacon_rpc.clone();
let network = req.network.clone();
let graffiti = req.graffiti;
let prover = req.prover;
tokio::task::spawn_blocking(move || {
preflight(
Some(rpc),
block_number,
Network::from_str(&network).unwrap(),
TaikoProverData { graffiti, prover },
Some(l1_rpc),
Some(beacon_rpc),
)
.expect("Failed to fetch required data for block")
})
.await
.map_err(Into::<super::error::HostError>::into)
}
pub struct NativeDriver;
#[derive(Clone, Serialize, Deserialize)]
pub struct NativeResponse {
output: GuestOutput,
}
impl Prover for NativeDriver {
async fn run(
_input: GuestInput,
output: GuestOutput,
_request: &Config,
) -> ProverResult<Proof> {
to_proof(Ok(NativeResponse { output }))
}
fn instance_hash(_pi: ProtocolInstance) -> B256 {
B256::default()
}
}
use std::convert::TryFrom;
impl TryFrom<&serde_json::Value> for Config {
type Error = HostError;
fn try_from(value: &serde_json::Value) -> Result<Self, Self::Error> {
let config: Config = serde_json::from_value(value.clone())
.map_err(|e| HostError::DeserializeError(format!("Failed to deserialize config: {}", e)))?;
Ok(config)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_async_block() {
let result = async { Result::<(), &'static str>::Err("error") };
println!("must here");
assert!(result.await.is_err());
}
}