1use super::{state::Notarize, Prover, ProverError};
7use serio::{stream::IoStreamExt as _, SinkExt as _};
8use tlsn_common::encoding;
9use tlsn_core::{
10 attestation::Attestation,
11 request::{Request, RequestConfig},
12 transcript::{encoding::EncodingTree, Transcript, TranscriptCommitConfig},
13 Secrets,
14};
15use tracing::{debug, instrument};
16
17impl Prover<Notarize> {
18 pub fn transcript(&self) -> &Transcript {
20 &self.state.transcript
21 }
22
23 pub fn transcript_commit(&mut self, config: TranscriptCommitConfig) {
25 self.state.transcript_commit_config = Some(config);
26 }
27
28 #[instrument(parent = &self.span, level = "debug", skip_all, err)]
30 pub async fn finalize(
31 self,
32 config: &RequestConfig,
33 ) -> Result<(Attestation, Secrets), ProverError> {
34 let Notarize {
35 mux_ctrl,
36 mut mux_fut,
37 mut ctx,
38 vm,
39 connection_info,
40 server_cert_data,
41 transcript,
42 transcript_refs,
43 transcript_commit_config,
44 ..
45 } = self.state;
46
47 let sent_macs = transcript_refs
48 .sent()
49 .iter()
50 .flat_map(|plaintext| vm.get_macs(*plaintext).expect("reference is valid"))
51 .map(|mac| mac.as_block());
52 let recv_macs = transcript_refs
53 .recv()
54 .iter()
55 .flat_map(|plaintext| vm.get_macs(*plaintext).expect("reference is valid"))
56 .map(|mac| mac.as_block());
57
58 let encoding_provider = mux_fut
59 .poll_with(encoding::receive(&mut ctx, sent_macs, recv_macs))
60 .await?;
61
62 let provider = self.config.crypto_provider();
63
64 let hasher = provider
65 .hash
66 .get(config.hash_alg())
67 .map_err(ProverError::config)?;
68
69 let mut builder = Request::builder(config);
70
71 builder
72 .server_name(self.config.server_name().clone())
73 .server_cert_data(server_cert_data)
74 .transcript(transcript);
75
76 if let Some(config) = transcript_commit_config {
77 if config.has_encoding() {
78 builder.encoding_tree(
79 EncodingTree::new(
80 hasher,
81 config.iter_encoding(),
82 &encoding_provider,
83 &connection_info.transcript_length,
84 )
85 .map_err(ProverError::commit)?,
86 );
87 }
88 }
89
90 let (request, secrets) = builder.build(provider).map_err(ProverError::attestation)?;
91
92 let attestation = mux_fut
93 .poll_with(async {
94 debug!("sending attestation request");
95
96 ctx.io_mut().send(request.clone()).await?;
97
98 let attestation: Attestation = ctx.io_mut().expect_next().await?;
99
100 Ok::<_, ProverError>(attestation)
101 })
102 .await?;
103
104 if !mux_fut.is_complete() {
106 mux_ctrl.close();
107 mux_fut.await?;
108 }
109
110 request
112 .validate(&attestation)
113 .map_err(ProverError::attestation)?;
114
115 Ok((attestation, secrets))
116 }
117}