forked from visoftsolutions/noir_rs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: accrued substate instructions (AztecProtocol#4197)
- Loading branch information
Showing
6 changed files
with
239 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
89 changes: 89 additions & 0 deletions
89
yarn-project/acir-simulator/src/avm/opcodes/accrued_substate.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import { mock } from 'jest-mock-extended'; | ||
|
||
import { AvmMachineState } from '../avm_machine_state.js'; | ||
import { Field } from '../avm_memory_types.js'; | ||
import { initExecutionEnvironment } from '../fixtures/index.js'; | ||
import { HostStorage } from '../journal/host_storage.js'; | ||
import { AvmJournal } from '../journal/journal.js'; | ||
import { EmitNoteHash, EmitNullifier, EmitUnencryptedLog, SendL2ToL1Message } from './accrued_substate.js'; | ||
import { StaticCallStorageAlterError } from './storage.js'; | ||
|
||
describe('Accrued Substate', () => { | ||
let journal: AvmJournal; | ||
let machineState: AvmMachineState; | ||
|
||
beforeEach(() => { | ||
const hostStorage = mock<HostStorage>(); | ||
journal = new AvmJournal(hostStorage); | ||
machineState = new AvmMachineState(initExecutionEnvironment()); | ||
}); | ||
|
||
it('Should append a new note hash correctly', async () => { | ||
const value = new Field(69n); | ||
machineState.memory.set(0, value); | ||
|
||
await new EmitNoteHash(0).execute(machineState, journal); | ||
|
||
const journalState = journal.flush(); | ||
const expected = [value.toFr()]; | ||
expect(journalState.newNoteHashes).toEqual(expected); | ||
}); | ||
|
||
it('Should append a new nullifier correctly', async () => { | ||
const value = new Field(69n); | ||
machineState.memory.set(0, value); | ||
|
||
await new EmitNullifier(0).execute(machineState, journal); | ||
|
||
const journalState = journal.flush(); | ||
const expected = [value.toFr()]; | ||
expect(journalState.newNullifiers).toEqual(expected); | ||
}); | ||
|
||
it('Should append unencrypted logs correctly', async () => { | ||
const startOffset = 0; | ||
|
||
const values = [new Field(69n), new Field(420n), new Field(Field.MODULUS - 1n)]; | ||
machineState.memory.setSlice(0, values); | ||
|
||
const length = values.length; | ||
|
||
await new EmitUnencryptedLog(startOffset, length).execute(machineState, journal); | ||
|
||
const journalState = journal.flush(); | ||
const expected = values.map(v => v.toFr()); | ||
expect(journalState.newLogs).toEqual([expected]); | ||
}); | ||
|
||
it('Should append l1 to l2 messages correctly', async () => { | ||
const startOffset = 0; | ||
|
||
const values = [new Field(69n), new Field(420n), new Field(Field.MODULUS - 1n)]; | ||
machineState.memory.setSlice(0, values); | ||
|
||
const length = values.length; | ||
|
||
await new SendL2ToL1Message(startOffset, length).execute(machineState, journal); | ||
|
||
const journalState = journal.flush(); | ||
const expected = values.map(v => v.toFr()); | ||
expect(journalState.newLogs).toEqual([expected]); | ||
}); | ||
|
||
it('All substate instructions should fail within a static call', async () => { | ||
const executionEnvironment = initExecutionEnvironment({ isStaticCall: true }); | ||
machineState = new AvmMachineState(executionEnvironment); | ||
|
||
const instructions = [ | ||
new EmitNoteHash(0), | ||
new EmitNullifier(0), | ||
new EmitUnencryptedLog(0, 1), | ||
new SendL2ToL1Message(0, 1), | ||
]; | ||
|
||
for (const instruction of instructions) { | ||
const inst = () => instruction.execute(machineState, journal); | ||
await expect(inst()).rejects.toThrowError(StaticCallStorageAlterError); | ||
} | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import { AvmMachineState } from '../avm_machine_state.js'; | ||
import { AvmJournal } from '../journal/journal.js'; | ||
import { Instruction } from './instruction.js'; | ||
import { StaticCallStorageAlterError } from './storage.js'; | ||
|
||
export class EmitNoteHash extends Instruction { | ||
static type: string = 'EMITNOTEHASH'; | ||
static numberOfOperands = 1; | ||
|
||
constructor(private noteHashOffset: number) { | ||
super(); | ||
} | ||
|
||
async execute(machineState: AvmMachineState, journal: AvmJournal): Promise<void> { | ||
if (machineState.executionEnvironment.isStaticCall) { | ||
throw new StaticCallStorageAlterError(); | ||
} | ||
|
||
const noteHash = machineState.memory.get(this.noteHashOffset).toFr(); | ||
journal.writeNoteHash(noteHash); | ||
|
||
this.incrementPc(machineState); | ||
} | ||
} | ||
|
||
export class EmitNullifier extends Instruction { | ||
static type: string = 'EMITNULLIFIER'; | ||
static numberOfOperands = 1; | ||
|
||
constructor(private nullifierOffset: number) { | ||
super(); | ||
} | ||
|
||
async execute(machineState: AvmMachineState, journal: AvmJournal): Promise<void> { | ||
if (machineState.executionEnvironment.isStaticCall) { | ||
throw new StaticCallStorageAlterError(); | ||
} | ||
|
||
const nullifier = machineState.memory.get(this.nullifierOffset).toFr(); | ||
journal.writeNullifier(nullifier); | ||
|
||
this.incrementPc(machineState); | ||
} | ||
} | ||
|
||
export class EmitUnencryptedLog extends Instruction { | ||
static type: string = 'EMITUNENCRYPTEDLOG'; | ||
static numberOfOperands = 2; | ||
|
||
constructor(private logOffset: number, private logSize: number) { | ||
super(); | ||
} | ||
|
||
async execute(machineState: AvmMachineState, journal: AvmJournal): Promise<void> { | ||
if (machineState.executionEnvironment.isStaticCall) { | ||
throw new StaticCallStorageAlterError(); | ||
} | ||
|
||
const log = machineState.memory.getSlice(this.logOffset, this.logSize).map(f => f.toFr()); | ||
journal.writeLog(log); | ||
|
||
this.incrementPc(machineState); | ||
} | ||
} | ||
|
||
export class SendL2ToL1Message extends Instruction { | ||
static type: string = 'EMITUNENCRYPTEDLOG'; | ||
static numberOfOperands = 2; | ||
|
||
constructor(private msgOffset: number, private msgSize: number) { | ||
super(); | ||
} | ||
|
||
async execute(machineState: AvmMachineState, journal: AvmJournal): Promise<void> { | ||
if (machineState.executionEnvironment.isStaticCall) { | ||
throw new StaticCallStorageAlterError(); | ||
} | ||
|
||
const msg = machineState.memory.getSlice(this.msgOffset, this.msgSize).map(f => f.toFr()); | ||
journal.writeLog(msg); | ||
|
||
this.incrementPc(machineState); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters