Skip to content

Commit 09a8806

Browse files
committed
Update scripts
1 parent 2091e9a commit 09a8806

File tree

4 files changed

+431
-202
lines changed

4 files changed

+431
-202
lines changed

src/contracts/Campaign.ts

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -273,38 +273,38 @@ export class CampaignContract extends SmartContract {
273273
// eslint-disable-next-line @typescript-eslint/no-empty-function
274274
@method updateCampaignInfo(input: UpdateCampaignInput) {}
275275

276-
@method rollup(proof: CampaignProof) {
277-
proof.verify();
278-
let ownerTreeRoot = this.ownerTreeRoot.getAndRequireEquals();
279-
let infoTreeRoot = this.infoTreeRoot.getAndRequireEquals();
280-
let statusTreeRoot = this.statusTreeRoot.getAndRequireEquals();
281-
let configTreeRoot = this.configTreeRoot.getAndRequireEquals();
282-
let nextCampaignId = this.nextCampaignId.getAndRequireEquals();
283-
let lastRolledUpActionState =
284-
this.lastRolledUpActionState.getAndRequireEquals();
285-
286-
ownerTreeRoot.assertEquals(proof.publicOutput.initialOwnerTreeRoot);
287-
infoTreeRoot.assertEquals(proof.publicOutput.initialInfoTreeRoot);
288-
statusTreeRoot.assertEquals(proof.publicOutput.initialStatusTreeRoot);
289-
configTreeRoot.assertEquals(proof.publicOutput.initialConfigTreeRoot);
290-
nextCampaignId.assertEquals(proof.publicOutput.initialNextCampaignId);
291-
lastRolledUpActionState.assertEquals(
292-
proof.publicOutput.initialLastRolledUpACtionState
293-
);
276+
@method rollup(proof: CampaignProof) {
277+
proof.verify();
278+
let ownerTreeRoot = this.ownerTreeRoot.getAndRequireEquals();
279+
let infoTreeRoot = this.infoTreeRoot.getAndRequireEquals();
280+
let statusTreeRoot = this.statusTreeRoot.getAndRequireEquals();
281+
let configTreeRoot = this.configTreeRoot.getAndRequireEquals();
282+
// let nextCampaignId = this.nextCampaignId.getAndRequireEquals();
283+
let lastRolledUpActionState =
284+
this.lastRolledUpActionState.getAndRequireEquals();
285+
286+
ownerTreeRoot.assertEquals(proof.publicOutput.initialOwnerTreeRoot);
287+
infoTreeRoot.assertEquals(proof.publicOutput.initialInfoTreeRoot);
288+
statusTreeRoot.assertEquals(proof.publicOutput.initialStatusTreeRoot);
289+
configTreeRoot.assertEquals(proof.publicOutput.initialConfigTreeRoot);
290+
// nextCampaignId.assertEquals(proof.publicOutput.initialNextCampaignId);
291+
lastRolledUpActionState.assertEquals(
292+
proof.publicOutput.initialLastRolledUpACtionState
293+
);
294294

295295
let lastActionState = this.account.actionState.getAndRequireEquals();
296296
lastActionState.assertEquals(
297297
proof.publicOutput.finalLastRolledUpActionState
298298
);
299299

300-
// update on-chain state
301-
this.ownerTreeRoot.set(proof.publicOutput.finalOwnerTreeRoot);
302-
this.infoTreeRoot.set(proof.publicOutput.finalInfoTreeRoot);
303-
this.statusTreeRoot.set(proof.publicOutput.finalStatusTreeRoot);
304-
this.configTreeRoot.set(proof.publicOutput.finalConfigTreeRoot);
305-
this.lastRolledUpActionState.set(
306-
proof.publicOutput.finalLastRolledUpActionState
307-
);
300+
// update on-chain state
301+
this.ownerTreeRoot.set(proof.publicOutput.finalOwnerTreeRoot);
302+
this.infoTreeRoot.set(proof.publicOutput.finalInfoTreeRoot);
303+
this.statusTreeRoot.set(proof.publicOutput.finalStatusTreeRoot);
304+
this.configTreeRoot.set(proof.publicOutput.finalConfigTreeRoot);
305+
this.lastRolledUpActionState.set(
306+
proof.publicOutput.finalLastRolledUpActionState
307+
);
308308

309309
this.emitEvent(
310310
EventEnum.CAMPAIGN_CREATED,

src/scripts/helper/deploy.ts

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
/* eslint-disable @typescript-eslint/no-explicit-any */
2+
import {
3+
AccountUpdate,
4+
Cache,
5+
Field,
6+
Mina,
7+
Provable,
8+
PublicKey,
9+
Reducer,
10+
SmartContract,
11+
UInt32,
12+
fetchAccount,
13+
fetchEvents as fetchEvent,
14+
} from 'o1js';
15+
import { Key } from './config.js';
16+
import { Profiler } from './profiler.js';
17+
18+
const DEFAULT_WAIT_TIME = 6 * 60 * 1000; // 6m
19+
20+
export async function wait(time?: number): Promise<void> {
21+
let waitTime = time || DEFAULT_WAIT_TIME;
22+
console.log(`Wait for ${waitTime / 1000}s ...`);
23+
return new Promise((resolve) => setTimeout(resolve, waitTime));
24+
}
25+
26+
export async function compile(
27+
prg: any,
28+
cache?: Cache,
29+
logMemory?: boolean,
30+
profiler?: Profiler
31+
): Promise<void> {
32+
if (logMemory) logMemUsage();
33+
console.log(`Compiling ${prg.name}...`);
34+
if (profiler) profiler.start(`${prg.name}.compile`);
35+
if (cache) await prg.compile({ cache });
36+
else await prg.compile();
37+
if (profiler) profiler.stop();
38+
console.log('Compiling done!');
39+
}
40+
41+
export type ContractList = {
42+
[key: string]: {
43+
name: string;
44+
key: Key;
45+
contract: SmartContract;
46+
actionStates: Field[];
47+
};
48+
};
49+
50+
export async function deploy(
51+
ct: { name: string; contract: any; key: Key },
52+
initArgs: [string, any][],
53+
feePayer: Key,
54+
fee?: number,
55+
nonce?: number
56+
): Promise<void> {
57+
console.log(`Deploying ${ct.name}...`);
58+
let sender;
59+
if (nonce) {
60+
sender = { sender: feePayer.publicKey, fee: fee, nonce: nonce };
61+
} else {
62+
sender = { sender: feePayer.publicKey, fee: fee };
63+
}
64+
let tx = await Mina.transaction(sender, () => {
65+
AccountUpdate.fundNewAccount(feePayer.publicKey, 1);
66+
ct.contract.deploy();
67+
for (let i = 0; i < initArgs.length; i++) {
68+
(ct as any)[initArgs[i][0]].set(initArgs[i][1]);
69+
}
70+
});
71+
await tx.sign([feePayer.privateKey, ct.key.privateKey]).send();
72+
console.log(`${ct.name} deployed!`);
73+
}
74+
75+
export async function proveAndSend(
76+
tx: Mina.Transaction,
77+
feePayer: Key,
78+
contractName: string,
79+
methodName: string,
80+
logMemory?: boolean,
81+
profiler?: Profiler
82+
) {
83+
if (logMemory) logMemUsage();
84+
console.log(
85+
`Generate proof and submit tx for ${contractName}.${methodName}()...`
86+
);
87+
let retries = 3; // Number of retries
88+
let res;
89+
while (retries > 0) {
90+
try {
91+
if (profiler) profiler.start(`${contractName}.${methodName}.prove`);
92+
await tx.prove();
93+
if (profiler) profiler.stop();
94+
res = await tx.sign([feePayer.privateKey]).send();
95+
console.log('DONE!');
96+
Provable.log('Transaction:', res);
97+
break; // Exit the loop if successful
98+
} catch (error) {
99+
console.error('Error:', error);
100+
retries--; // Decrement the number of retries
101+
if (retries === 0) {
102+
throw error; // Throw the error if no more retries left
103+
}
104+
console.log(`Retrying... (${retries} retries left)`);
105+
}
106+
}
107+
try {
108+
console.log('Waiting for tx to succeed...');
109+
if (res) await res.wait();
110+
console.log('Tx succeeded!');
111+
} catch (error) {
112+
console.error('Error:', error);
113+
}
114+
}
115+
116+
export async function fetchAllContract(
117+
contracts: ContractList,
118+
selected: string[],
119+
maxAttempts = 10
120+
): Promise<ContractList> {
121+
let attempts = 0;
122+
123+
while (attempts < maxAttempts) {
124+
try {
125+
const entries = Object.entries(contracts);
126+
for (const [key, { contract }] of entries) {
127+
if (selected.length > 0 && !selected.includes(key)) continue;
128+
const [fetchedActions, fetchedAccount] = await Promise.all([
129+
Mina.fetchActions(contract.address),
130+
fetchAccount({ publicKey: contract.address }),
131+
]);
132+
133+
if (Array.isArray(fetchedActions)) {
134+
contracts[key].actionStates = [
135+
Reducer.initialActionState,
136+
...fetchedActions.map((e) => Field(e.hash)),
137+
];
138+
}
139+
}
140+
console.log('Fetch all info success');
141+
142+
// If the code succeeds, break out of the loop
143+
break;
144+
} catch (error) {
145+
console.log('Error: ', error);
146+
attempts++;
147+
148+
// Wait for some time before retrying (e.g., 1 second)
149+
await new Promise((resolve) => setTimeout(resolve, 1000));
150+
}
151+
}
152+
153+
if (attempts === maxAttempts) {
154+
console.log('Maximum number of attempts reached. Code failed.');
155+
}
156+
157+
return contracts;
158+
}
159+
160+
export function logMemUsage() {
161+
console.log(
162+
'Current memory usage:',
163+
Math.floor(process.memoryUsage().rss / 1024 / 1024),
164+
'MB'
165+
);
166+
}
167+
168+
export interface FetchedActions {
169+
actions: string[][];
170+
hash: string;
171+
}
172+
173+
export async function fetchActions(
174+
publicKey: string,
175+
fromActionState?: Field,
176+
endActionState?: Field
177+
): Promise<FetchedActions[]> {
178+
return (await Mina.fetchActions(PublicKey.fromBase58(publicKey), {
179+
fromActionState: fromActionState,
180+
endActionState: endActionState,
181+
})) as FetchedActions[];
182+
}
183+
184+
export interface FetchedEvents {
185+
events: {
186+
data: string[];
187+
transactionInfo: {
188+
hash: string;
189+
memo: string;
190+
status: string;
191+
};
192+
}[];
193+
blockHeight: UInt32;
194+
blockHash: string;
195+
parentBlockHash: string;
196+
globalSlot: UInt32;
197+
chainStatus: string;
198+
}
199+
200+
export async function fetchEvents(
201+
publicKey: string,
202+
from?: number,
203+
to?: number
204+
): Promise<FetchedEvents[]> {
205+
const events = await fetchEvent(
206+
{
207+
publicKey: publicKey,
208+
},
209+
undefined,
210+
{
211+
from: from == undefined ? undefined : UInt32.from(from),
212+
to: to == undefined ? undefined : UInt32.from(to),
213+
}
214+
);
215+
return events;
216+
}
217+
218+
export async function fetchZkAppState(
219+
publicKey: string
220+
): Promise<Field[] | undefined> {
221+
const result = await fetchAccount({
222+
publicKey: publicKey,
223+
});
224+
const account = result.account;
225+
return account?.zkapp?.appState;
226+
}

0 commit comments

Comments
 (0)