1use std::{fs::OpenOptions, io::Write, path::PathBuf, process::Command};
7
8use alloy::hex::ToHexExt;
9use clap::Parser;
10use hotshot_contract_adapter::sol_types::VerifyingKeySol;
11use hotshot_types::light_client::DEFAULT_STAKE_TABLE_CAPACITY;
12use jf_pcs::prelude::UnivariateUniversalParams;
13
14#[derive(Parser)]
15struct Cli {
16 #[arg(long, default_value_t = false)]
18 mock: bool,
19}
20
21fn main() {
22 let mock = Cli::parse().mock;
23
24 let srs = {
25 let srs = if mock {
27 ark_srs::kzg10::aztec20::setup(2u64.pow(16) as usize + 2)
28 .expect("Aztec SRS fail to load")
29 } else {
30 ark_srs::kzg10::aztec20::setup(2u64.pow(20) as usize + 2)
31 .expect("Aztec SRS fail to load")
32 };
33 UnivariateUniversalParams {
36 powers_of_g: srs.powers_of_g,
37 h: srs.h,
38 beta_h: srs.beta_h,
39 powers_of_h: vec![srs.h, srs.beta_h],
40 }
41 };
42 let (_, vk) = if mock {
43 hotshot_state_prover::preprocess(&srs, 10).expect("Circuit preprocess failed")
44 } else {
45 hotshot_state_prover::preprocess(&srs, DEFAULT_STAKE_TABLE_CAPACITY)
46 .expect("Circuit preprocess failed")
47 };
48 let vk: VerifyingKeySol = vk.into();
49
50 let contract_name = if mock {
52 "LightClientStateUpdateVKMock"
53 } else {
54 "LightClientStateUpdateVK"
55 };
56 let mut path = PathBuf::new();
57 path.push(env!("CARGO_MANIFEST_DIR"));
58 path.pop();
59 path.pop();
60 if mock {
61 path.push("test/mocks");
62 } else {
63 path.push("src/libraries");
64 }
65 path.push(contract_name);
66 path.set_extension("sol");
67 println!("Path:{:?}", path.to_str());
68
69 let mut file = OpenOptions::new()
71 .write(true)
72 .create(true)
73 .truncate(true)
74 .open(path)
75 .unwrap();
76
77 let import_path = if mock {
78 "import { IPlonkVerifier } from \"../../src/interfaces/IPlonkVerifier.sol\";"
79 } else {
80 "import { IPlonkVerifier } from \"../interfaces/IPlonkVerifier.sol\";"
81 };
82
83 let code = format!(
84 "// SPDX-License-Identifier: GPL-3.0-or-later
85 //
86 // Copyright (c) 2023 Espresso Systems (espressosys.com)
87 // This file is part of the Espresso Sequencer project.
88 //
89 // This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
90 // This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
91 // You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
92
93 // NOTE: DO NOT MODIFY! GENERATED BY SCRIPT VIA `cargo run --bin gen-vk-contract --release`.
94 pragma solidity ^0.8.0;
95
96 {}
97
98 /* solhint-disable no-inline-assembly */
99
100 library {} {{
101 function getVk() internal pure returns (IPlonkVerifier.VerifyingKey memory vk) {{
102 assembly {{
103 // domain size
104 mstore(vk, {})
105 // num of public inputs
106 mstore(add(vk, 0x20), {})
107
108 // sigma0
109 mstore(mload(add(vk, 0x40)), {})
110 mstore(add(mload(add(vk, 0x40)), 0x20), {})
111 // sigma1
112 mstore(mload(add(vk, 0x60)), {})
113 mstore(add(mload(add(vk, 0x60)), 0x20), {})
114 // sigma2
115 mstore(mload(add(vk, 0x80)), {})
116 mstore(add(mload(add(vk, 0x80)), 0x20), {})
117 // sigma3
118 mstore(mload(add(vk, 0xa0)), {})
119 mstore(add(mload(add(vk, 0xa0)), 0x20), {})
120 // sigma4
121 mstore(mload(add(vk, 0xc0)), {})
122 mstore(add(mload(add(vk, 0xc0)), 0x20), {})
123
124 // q1
125 mstore(mload(add(vk, 0xe0)), {})
126 mstore(add(mload(add(vk, 0xe0)), 0x20), {})
127 // q2
128 mstore(mload(add(vk, 0x100)), {})
129 mstore(add(mload(add(vk, 0x100)), 0x20), {})
130 // q3
131 mstore(mload(add(vk, 0x120)), {})
132 mstore(add(mload(add(vk, 0x120)), 0x20), {})
133 // q4
134 mstore(mload(add(vk, 0x140)), {})
135 mstore(add(mload(add(vk, 0x140)), 0x20), {})
136
137 // qM12
138 mstore(mload(add(vk, 0x160)), {})
139 mstore(add(mload(add(vk, 0x160)), 0x20), {})
140 // qM34
141 mstore(mload(add(vk, 0x180)), {})
142 mstore(add(mload(add(vk, 0x180)), 0x20), {})
143
144 // qO
145 mstore(mload(add(vk, 0x1a0)), {})
146 mstore(add(mload(add(vk, 0x1a0)), 0x20), {})
147 // qC
148 mstore(mload(add(vk, 0x1c0)), {})
149 mstore(add(mload(add(vk, 0x1c0)), 0x20), {})
150 // qH1
151 mstore(mload(add(vk, 0x1e0)), {})
152 mstore(add(mload(add(vk, 0x1e0)), 0x20), {})
153 // qH2
154 mstore(mload(add(vk, 0x200)), {})
155 mstore(add(mload(add(vk, 0x200)), 0x20), {})
156 // qH3
157 mstore(mload(add(vk, 0x220)), {})
158 mstore(add(mload(add(vk, 0x220)), 0x20), {})
159 // qH4
160 mstore(mload(add(vk, 0x240)), {})
161 mstore(add(mload(add(vk, 0x240)), 0x20), {})
162 // qEcc
163 mstore(mload(add(vk, 0x260)), {})
164 mstore(add(mload(add(vk, 0x260)), 0x20), {})
165 // g2LSB
166 mstore(add(vk, 0x280), {})
167 // g2MSB
168 mstore(add(vk, 0x2A0), {})
169 }}
170 }}
171 }}",
172 import_path,
173 contract_name,
174 vk.domainSize,
175 vk.numInputs,
176 vk.sigma0.x,
177 vk.sigma0.y,
178 vk.sigma1.x,
179 vk.sigma1.y,
180 vk.sigma2.x,
181 vk.sigma2.y,
182 vk.sigma3.x,
183 vk.sigma3.y,
184 vk.sigma4.x,
185 vk.sigma4.y,
186 vk.q1.x,
187 vk.q1.y,
188 vk.q2.x,
189 vk.q2.y,
190 vk.q3.x,
191 vk.q3.y,
192 vk.q4.x,
193 vk.q4.y,
194 vk.qM12.x,
195 vk.qM12.y,
196 vk.qM34.x,
197 vk.qM34.y,
198 vk.qO.x,
199 vk.qO.y,
200 vk.qC.x,
201 vk.qC.y,
202 vk.qH1.x,
203 vk.qH1.y,
204 vk.qH2.x,
205 vk.qH2.y,
206 vk.qH3.x,
207 vk.qH3.y,
208 vk.qH4.x,
209 vk.qH4.y,
210 vk.qEcc.x,
211 vk.qEcc.y,
212 vk.g2LSB.encode_hex(),
213 vk.g2MSB.encode_hex(),
214 )
215 .into_bytes();
216
217 file.write_all(&code).unwrap();
218
219 Command::new("just")
221 .arg("sol-lint")
222 .output()
223 .expect("Failed to lint the contract code");
224}