Skip to content

Instantly share code, notes, and snippets.

@Savio-Sou
Created March 28, 2022 08:34
Show Gist options
  • Select an option

  • Save Savio-Sou/acc9b311bec8952c58d08cc58b584223 to your computer and use it in GitHub Desktop.

Select an option

Save Savio-Sou/acc9b311bec8952c58d08cc58b584223 to your computer and use it in GitHub Desktop.
Review snarkyjs-workshop/src/bonus.ts
// Recursive proof system
@proofSystem
class RollupProof extends ProofWithInput<RollupStateTransition> {
// Process deposit from L1
@branch static processDeposit(
pending: MerkleStack<RollupDeposit>, // deposit queue
accountDb: AccountDb // L2 account database
): RollupProof {
let before = new RollupState(pending.commitment, accountDb.commitment()); // current L2 state
let deposit = pending.pop(); // get deposit from queue
let [{ isSome }, mem] = accountDb.get(deposit.publicKey); // get [if account already in database, account info]
isSome.assertEquals(false); // assure account does not already exist
// Create account on L2
let account = new RollupAccount(
UInt64.zero,
UInt32.zero,
deposit.publicKey
);
accountDb.set(mem, account);
let after = new RollupState(pending.commitment, accountDb.commitment()); // new L2 state
// Generate and return proof of L2 state update from deposit processed
return new RollupProof(new RollupStateTransition(before, after));
}
// Process L2 transaction
@branch static transaction(
t: RollupTransaction,
s: Signature,
pending: MerkleStack<RollupDeposit>,
accountDb: AccountDb
): RollupProof {
s.verify(t.sender, t.toFields()).assertEquals(true); // verify signature
let stateBefore = new RollupState(
pending.commitment,
accountDb.commitment()
);
// Get sender account from database
let [senderAccount, senderPos] = accountDb.get(t.sender);
senderAccount.isSome.assertEquals(true); // assure account exists
senderAccount.value.nonce.assertEquals(t.nonce); // assure transaction nonce is validity
// Process transaction send
senderAccount.value.balance = senderAccount.value.balance.sub(t.amount);
senderAccount.value.nonce = senderAccount.value.nonce.add(1);
// Update account's info in database
accountDb.set(senderPos, senderAccount.value);
// Process transaction receive
let [receiverAccount, receiverPos] = accountDb.get(t.receiver);
receiverAccount.value.balance = receiverAccount.value.balance.add(t.amount);
accountDb.set(receiverPos, receiverAccount.value);
let stateAfter = new RollupState(
pending.commitment,
accountDb.commitment()
);
// Generate and return proof of L2 state update from transaction processed
return new RollupProof(new RollupStateTransition(stateBefore, stateAfter));
}
// Merge two proofs into one
@branch static merge(p1: RollupProof, p2: RollupProof): RollupProof {
// Assure the first state update's state output is used as input of second
p1.publicInput.target.assertEquals(p2.publicInput.source);
// Generate and return proof of total state transition
// from before first update to after second update
return new RollupProof(
new RollupStateTransition(p1.publicInput.source, p2.publicInput.target)
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment