Skip to content

Commit

Permalink
Merge develop
Browse files Browse the repository at this point in the history
  • Loading branch information
ejMina226 committed Nov 29, 2024
2 parents 77441fb + 04124a9 commit 3c1385c
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 34 deletions.
2 changes: 2 additions & 0 deletions packages/common/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,5 @@ type NonMethodKeys<Type> = {
[Key in keyof Type]: Type[Key] extends Function ? never : Key;
}[keyof Type];
export type NonMethods<Type> = Pick<Type, NonMethodKeys<Type>>;

export const MAX_FIELD = Field(Field.ORDER - 1n);
8 changes: 2 additions & 6 deletions packages/protocol/src/prover/block/BlockProvable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export class BlockProverPublicInput extends Struct({
blockHashRoot: Field,
eternalTransactionsHash: Field,
incomingMessagesHash: Field,
blockNumber: Field,
}) {}

export class BlockProverPublicOutput extends Struct({
Expand All @@ -36,15 +37,10 @@ export class BlockProverPublicOutput extends Struct({
closed: Bool,
blockNumber: Field,
}) {
public equals(
input: BlockProverPublicInput,
closed: Bool,
blockNumber: Field
): Bool {
public equals(input: BlockProverPublicInput, closed: Bool): Bool {
const output2 = BlockProverPublicOutput.toFields({
...input,
closed,
blockNumber,
});
const output1 = BlockProverPublicOutput.toFields(this);
return output1
Expand Down
45 changes: 27 additions & 18 deletions packages/protocol/src/prover/block/BlockProver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
import { container, inject, injectable, injectAll } from "tsyringe";
import {
AreProofsEnabled,
MAX_FIELD,
PlainZkProgram,
provableMethod,
WithZkProgrammable,
Expand Down Expand Up @@ -124,10 +125,6 @@ export interface BlockProverState {
incomingMessagesHash: Field;
}

function maxField() {
return Field(Field.ORDER - 1n);
}

export type BlockProof = Proof<BlockProverPublicInput, BlockProverPublicOutput>;
export type RuntimeProof = Proof<void, MethodPublicOutput>;

Expand Down Expand Up @@ -416,6 +413,11 @@ export class BlockProverProgrammable extends ZkProgrammable<
"ExecutionData Networkstate doesn't equal public input hash"
);

publicInput.blockNumber.assertEquals(
MAX_FIELD,
"blockNumber has to be MAX for transaction proofs"
);

// Verify the [methodId, vk] tuple against the baked-in vk tree root
const { verificationKey, witness: verificationKeyTreeWitness } =
verificationKeyWitness;
Expand Down Expand Up @@ -445,7 +447,7 @@ export class BlockProverProgrammable extends ZkProgrammable<

return new BlockProverPublicOutput({
...stateTo,
blockNumber: maxField(),
blockNumber: publicInput.blockNumber,
closed: Bool(false),
});
}
Expand Down Expand Up @@ -525,16 +527,16 @@ export class BlockProverProgrammable extends ZkProgrammable<
.not();
stateTransitionProof.verifyIf(stsEmitted);

// Verify Transaction proof if it has at least 1 tx
// Verify Transaction proof if it has at least 1 tx - i.e. the
// input and output doesn't match fully
// We have to compare the whole input and output because we can make no
// assumptions about the values, since it can be an arbitrary dummy-proof
const txProofOutput = transactionProof.publicOutput;
const verifyTransactionProof = txProofOutput.equals(
transactionProof.publicInput,
txProofOutput.closed,
txProofOutput.blockNumber
txProofOutput.closed
);
transactionProof.verifyIf(verifyTransactionProof);
transactionProof.verifyIf(verifyTransactionProof.not());

// 2. Execute beforeBlock hooks
const beforeBlockResult = await this.executeBlockHooks(
Expand Down Expand Up @@ -616,6 +618,8 @@ export class BlockProverProgrammable extends ZkProgrammable<
// Calculate the new block index
const blockIndex = blockWitness.calculateIndex();

blockIndex.assertEquals(publicInput.blockNumber);

blockWitness
.calculateRoot(Field(0))
.assertEquals(
Expand All @@ -633,7 +637,7 @@ export class BlockProverProgrammable extends ZkProgrammable<

return new BlockProverPublicOutput({
...state,
blockNumber: blockIndex,
blockNumber: blockIndex.add(1),
closed: Bool(true),
});
}
Expand Down Expand Up @@ -740,19 +744,25 @@ export class BlockProverProgrammable extends ZkProgrammable<
// assert proof1.height == proof2.height
// }

const proof1Height = proof1.publicOutput.blockNumber;
const proof1Closed = proof1.publicOutput.closed;
const proof2Height = proof2.publicOutput.blockNumber;
const proof2Closed = proof2.publicOutput.closed;

const isValidTransactionMerge = proof1Height
.equals(maxField())
.and(proof2Height.equals(proof1Height))
const blockNumberProgressionValid = publicInput.blockNumber
.equals(proof1.publicInput.blockNumber)
.and(
proof1.publicOutput.blockNumber.equals(proof2.publicInput.blockNumber)
);

// For tx proofs, we check that the progression starts and end with MAX
// in addition to that both proofs are non-closed
const isValidTransactionMerge = publicInput.blockNumber
.equals(MAX_FIELD)
.and(blockNumberProgressionValid)
.and(proof1Closed.or(proof2Closed).not());

const isValidClosedMerge = proof1Closed
.and(proof2Closed)
.and(proof1Height.add(1).equals(proof2Height));
.and(blockNumberProgressionValid);

isValidTransactionMerge
.or(isValidClosedMerge)
Expand All @@ -765,9 +775,8 @@ export class BlockProverProgrammable extends ZkProgrammable<
blockHashRoot: proof2.publicOutput.blockHashRoot,
eternalTransactionsHash: proof2.publicOutput.eternalTransactionsHash,
incomingMessagesHash: proof2.publicOutput.incomingMessagesHash,
// Provable.if(isValidClosedMerge, Bool(true), Bool(false));
closed: isValidClosedMerge,
blockNumber: proof2Height,
blockNumber: proof2.publicOutput.blockNumber,
});
}

Expand Down
2 changes: 1 addition & 1 deletion packages/sequencer/src/mempool/PendingTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ export class PendingTransaction extends UnsignedTransaction {

public toJSON(): PendingTransactionJSONType {
return {
hash: this.hash.toString(),
hash: this.hash().toString(),
methodId: this.methodId.toJSON(),
nonce: this.nonce.toString(),
sender: this.sender.toBase58(),
Expand Down
31 changes: 26 additions & 5 deletions packages/sequencer/src/protocol/production/BlockTaskFlowService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
Protocol,
StateTransitionProof,
} from "@proto-kit/protocol";
import { log, MOCK_PROOF } from "@proto-kit/common";
import { log, MAX_FIELD, MOCK_PROOF } from "@proto-kit/common";

import { TaskQueue } from "../../worker/queue/TaskQueue";
import { Flow, FlowCreator } from "../../worker/flow/Flow";
Expand Down Expand Up @@ -171,9 +171,9 @@ export class BlockTaskFlowService {
mappingTask: this.blockProvingTask,
reductionTask: this.blockReductionTask,

mergableFunction: (a, b) =>
mergableFunction: (a, b) => {
// TODO Proper replication of merge logic
a.publicOutput.stateRoot
const part1 = a.publicOutput.stateRoot
.equals(b.publicInput.stateRoot)
.and(
a.publicOutput.blockHashRoot.equals(b.publicInput.blockHashRoot)
Expand All @@ -189,7 +189,28 @@ export class BlockTaskFlowService {
)
)
.and(a.publicOutput.closed.equals(b.publicOutput.closed))
.toBoolean(),
.toBoolean();

const proof1Closed = a.publicOutput.closed;
const proof2Closed = b.publicOutput.closed;

const blockNumberProgressionValid = a.publicOutput.blockNumber.equals(
b.publicInput.blockNumber
);

const isValidTransactionMerge = a.publicInput.blockNumber
.equals(MAX_FIELD)
.and(blockNumberProgressionValid)
.and(proof1Closed.or(proof2Closed).not());

const isValidClosedMerge = proof1Closed
.and(proof2Closed)
.and(blockNumberProgressionValid);

return (
part1 && isValidClosedMerge.or(isValidTransactionMerge).toBoolean()
);
},
},
this.flowCreator
);
Expand Down Expand Up @@ -286,13 +307,13 @@ export class BlockTaskFlowService {
blockTrace.block.publicInput.eternalTransactionsHash,
incomingMessagesHash:
blockTrace.block.publicInput.incomingMessagesHash,
blockNumber: MAX_FIELD,
};
const publicInput = new BlockProverPublicInput(piObject);

// TODO Set publicInput.stateRoot to result after block hooks!
const publicOutput = new BlockProverPublicOutput({
...piObject,
blockNumber: Field(Field.ORDER - 1n),
closed: Bool(true),
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
StateTransitionProverPublicInput,
StateTransitionType,
} from "@proto-kit/protocol";
import { MAX_FIELD } from "@proto-kit/common";
import { Bool, Field } from "o1js";
import chunk from "lodash/chunk";
import { LinkedMerkleTree } from "@proto-kit/common/dist/trees/LinkedMerkleTree";
Expand Down Expand Up @@ -133,6 +134,7 @@ export class TransactionTraceService {
blockHashRoot: block.block.fromBlockHashRoot,
eternalTransactionsHash: block.block.fromEternalTransactionsHash,
incomingMessagesHash: block.block.fromMessagesHash,
blockNumber: block.block.height,
});

return {
Expand Down Expand Up @@ -241,6 +243,7 @@ export class TransactionTraceService {
incomingMessagesHash,
networkStateHash: networkState.hash(),
blockHashRoot: Field(0),
blockNumber: MAX_FIELD,
},

executionData: {
Expand Down
16 changes: 13 additions & 3 deletions packages/sequencer/test/integration/BlockProduction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -473,10 +473,17 @@ describe("block production", () => {
[1, 2, 1],
[1, 1, 2],
[2, 2, 2],
[1, 14, 0],
])(
"should produce multiple blocks with multiple batches with multiple transactions",
async (batches, blocksPerBatch, txsPerBlock) => {
expect.assertions(2 * batches + 3 * batches * blocksPerBatch);
expect.assertions(
2 * batches +
1 * batches * blocksPerBatch +
2 * batches * blocksPerBatch * txsPerBlock
);

log.setLevel("DEBUG");

const sender = PrivateKey.random();

Expand Down Expand Up @@ -511,8 +518,11 @@ describe("block production", () => {
const block = await blockTrigger.produceBlock();

expect(block).toBeDefined();
expect(block!.transactions).toHaveLength(txsPerBlock);
expect(block!.transactions[0].status.toBoolean()).toBe(true);

for (let k = 0; k < txsPerBlock; k++) {
expect(block!.transactions).toHaveLength(txsPerBlock);
expect(block!.transactions[0].status.toBoolean()).toBe(true);
}
}

const batch = await blockTrigger.produceBatch();
Expand Down
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"strictFunctionTypes": true,
"strictBindCallApply": true,
"skipLibCheck": true,
"baseUrl": "."
"baseUrl": ".",
"sourceMap": true
},
"exclude": ["jest.config.cjs"]
}

0 comments on commit 3c1385c

Please sign in to comment.