Skip to content

Commit

Permalink
Preparations for random done
Browse files Browse the repository at this point in the history
  • Loading branch information
aii23 committed Jul 16, 2024
1 parent 74db7f3 commit a8a32ab
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/Lottery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ export class Lottery extends SmartContract {
public checkRoundPass(round: UInt32) {
const startBlock = this.startBlock.getAndRequireEquals();
this.network.globalSlotSinceGenesis.requireBetween(
startBlock.add(round.mul(BLOCK_PER_ROUND)),
startBlock.add(round.add(1).mul(BLOCK_PER_ROUND)),
UInt32.MAXINT()
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/PLottery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ export class PLottery extends SmartContract {
public checkRoundPass(round: UInt32) {
const startBlock = this.startBlock.getAndRequireEquals();
this.network.globalSlotSinceGenesis.requireBetween(
startBlock.add(round.mul(BLOCK_PER_ROUND)),
startBlock.add(round.add(1).mul(BLOCK_PER_ROUND)),
UInt32.MAXINT()
);
}
Expand Down
142 changes: 142 additions & 0 deletions src/Random/RandomManager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import {
Field,
MerkleMap,
MerkleMapWitness,
Poseidon,
PublicKey,
SmartContract,
State,
UInt32,
method,
state,
} from 'o1js';
import { treasury } from '../private_constants';
import { BLOCK_PER_ROUND } from '../constants';

const emptyMapRoot = new MerkleMap().getRoot();

export class RandomManager extends SmartContract {
@state(Field) commitRoot = State<Field>();

@state(Field) hashCommitRoot = State<Field>();

@state(Field) resultRoot = State<Field>();

@state(UInt32) startSlot = State<UInt32>();

init() {
super.init();

this.commitRoot.set(emptyMapRoot);
this.hashCommitRoot.set(emptyMapRoot);
this.resultRoot.set(emptyMapRoot);

this.startSlot.set(
this.network.globalSlotSinceGenesis.getAndRequireEquals()
);
}

/*
* Can we update value
* What we will do if value is wrong?
*/
@method async commitValue(witness: MerkleMapWitness, value: Field) {
this.permissionCheck();

const [prevCommitRoot, round] = witness.computeRootAndKey(Field(0));

prevCommitRoot.assertEquals(
this.commitRoot.getAndRequireEquals(),
'Wrong commit witness'
);

this.checkRoundDoNotEnd(UInt32.fromFields([round]));

const [newCommitRoot] = witness.computeRootAndKey(value);

this.commitRoot.set(newCommitRoot);
}

@method async commitBlockHash(witness: MerkleMapWitness) {
const [prevBlockCommitRoot, key] = witness.computeRootAndKey(Field(0));

prevBlockCommitRoot.assertEquals(
this.hashCommitRoot.getAndRequireEquals(),
'Wrong witness for hashCommits'
);

this.checkRoundPass(UInt32.fromFields([key]));

const newValue = Poseidon.hash([
this.network.snarkedLedgerHash.get(),
this.network.globalSlotSinceGenesis.getAndRequireEquals().value,
]);
const [newBlockCommitRoot] = witness.computeRootAndKey(newValue);

this.hashCommitRoot.set(newBlockCommitRoot);
}

@method async produceValue(
commitWitness: MerkleMapWitness,
commitValue: Field,
revealValue: Field,
salt: Field,
blockHashCommitWitness: MerkleMapWitness,
blockHashValue: Field,
blockHashProof: BlockHashProof
) {
const [commitRoot, commitKey] =
commitWitness.computeRootAndKey(commitValue);

commitRoot.assertEquals(
this.commitRoot.getAndRequireEquals(),
'Wrong commit witness'
);

Poseidon.hash([revealValue, salt]).assertEquals(
commitValue,
'Wrong reveal'
);

const [blockHashCommitRoot, blockHashCommitKey] =
blockHashCommitWitness.computeRootAndKey(blockHashValue);

blockHashCommitRoot.assertEquals(
this.hashCommitRoot.getAndRequireEquals(),
'Wrong hash commit witness'
);

commitKey.assertEquals(
blockHashCommitKey,
'Different rounds for commit and hash commit'
);

blockHashProof.verify();

// Check blockHashProof initialHash to equal blockHashValue

// Check that blockHashProof final block is right slot

// Call lottery contract
}

private permissionCheck() {
this.sender.getAndRequireSignature().assertEquals(treasury);
}

public checkRoundPass(round: UInt32) {
const startBlock = this.startSlot.getAndRequireEquals();
this.network.globalSlotSinceGenesis.requireBetween(
startBlock.add(round.add(1).mul(BLOCK_PER_ROUND)),
UInt32.MAXINT()
);
}

public checkRoundDoNotEnd(round: UInt32) {
const startBlock = this.startSlot.getAndRequireEquals();
this.network.globalSlotSinceGenesis.requireBetween(
UInt32.from(0),
startBlock.add(round.add(1).mul(BLOCK_PER_ROUND))
);
}
}

0 comments on commit a8a32ab

Please sign in to comment.