@tokamak-zk-evm/synthesizer
Version:
Tokamak zk-EVM Synthesizer - Processes Ethereum transactions into wire maps for Tokamak zk-SNARK proof generation
255 lines (238 loc) • 9.72 kB
text/typescript
export enum EOFError {
// Stream Reader
OutOfBounds = 'Trying to read out of bounds',
VerifyUint = 'Uint does not match expected value ',
VerifyBytes = 'Bytes do not match expected value',
// Section Markers
FORMAT = 'err: invalid format',
MAGIC = 'err: invalid magic',
VERSION = `err: invalid eof version`,
KIND_TYPE = `err: expected kind types`,
KIND_CODE = `err: expected kind code`,
KIND_DATA = `err: expected kind data`,
TERMINATOR = `err: expected terminator`,
// Section Sizes
TypeSize = `missing type size`,
InvalidTypeSize = `err: type section size invalid`,
CodeSize = `missing code size`,
CodeSectionSize = `code section should be at least one byte`,
InvalidCodeSize = `code size does not match type size`,
DataSize = `missing data size`,
ContainerSize = 'missing container size',
ContainerSectionSize = 'container section should at least contain one section and at most 255 sections',
// Type Section
TypeSections = `err: mismatch of code sections count and type signatures`,
Inputs = 'expected inputs',
Outputs = 'expected outputs',
MaxInputs = 'inputs exceeds 127, the maximum, got: ',
MaxOutputs = 'outputs exceeds 127, the maximum, got: ',
Code0Inputs = 'first code section should have 0 inputs',
Code0Outputs = 'first code section should have 0x80 (terminating section) outputs',
MaxStackHeight = `expected maxStackHeight`,
MaxStackHeightLimit = `stack height limit of 1024 exceeded: `,
// Code/Data Section
MinCodeSections = `should have at least 1 code section`,
MaxCodeSections = `can have at most 1024 code sections`,
CodeSection = `expected a code section`,
DataSection = `Expected data section`,
// Container section
ContainerSection = 'expected a container section',
ContainerSectionMin = 'container section should be at least 1 byte',
InvalidEOFCreateTarget = 'EOFCREATE targets an undefined container',
InvalidRETURNContractTarget = 'RETURNCONTRACT targets an undefined container',
ContainerDoubleType = 'Container is targeted by both EOFCREATE and RETURNCONTRACT',
UnreachableContainerSections = 'Unreachable containers (by both EOFCREATE and RETURNCONTRACT)',
ContainerTypeError = 'Container contains opcodes which this mode (deployment mode / init code / runtime mode) cannot have',
// Dangling Bytes
DanglingBytes = 'got dangling bytes in body',
// Code verification
InvalidOpcode = 'invalid opcode',
InvalidTerminator = 'invalid terminating opcode',
OpcodeIntermediatesOOB = 'invalid opcode: intermediates out-of-bounds',
InvalidRJUMP = 'invalid rjump* target',
InvalidCallTarget = 'invalid callf/jumpf target',
InvalidCALLFReturning = 'invalid callf: calls to non-returning function',
InvalidStackHeight = 'invalid stack height',
InvalidJUMPF = 'invalid jumpf target (output count)',
InvalidReturningSection = 'invalid returning code section: section is not returning',
RJUMPVTableSize0 = 'invalid RJUMPV: table size 0',
UnreachableCodeSections = 'unreachable code sections',
UnreachableCode = 'unreachable code (by forward jumps)',
DataLoadNOutOfBounds = 'DATALOADN reading out of bounds',
MaxStackHeightViolation = 'Max stack height does not match the reported max stack height',
StackUnderflow = 'Stack underflow',
StackOverflow = 'Stack overflow',
UnstableStack = 'Unstable stack (can reach stack under/overflow by jumps)',
RetfNoReturn = 'Trying to return to undefined function', // This should never happen (this is a return stack underflow)
ReturnStackOverflow = 'Return stack overflow',
InvalidExtcallTarget = 'invalid extcall target: address > 20 bytes',
InvalidReturnContractDataSize = 'invalid RETURNCONTRACT: data size lower than expected',
InvalidEofFormat = 'invalid EOF format',
}
export enum SimpleErrors {
minContainerSize = 'err: container size less than minimum valid size',
invalidContainerSize = 'err: invalid container size',
typeSize = 'err: type section size invalid',
code0msh = 'err: computed max stack height for code section 0 does not match expect',
underflow = 'err: stack underflow',
code0IO = 'err: input and output of first code section must be 0',
// Stream Reader
// OutOfBounds = 'err: relative offset out-of-bounds: ',
VerifyUint = 'Uint does not match expected value ',
VerifyBytes = 'Bytes do not match expected value',
// Section Sizes
TypeSize = `missing type size`,
InvalidTypeSize = `err: type section invalid`,
CodeSize = `missing code size`,
CodeSectionSize = `code section should be at least one byte`,
InvalidCodeSize = `code size does not match type size`,
DataSize = `missing data size`,
// Type Section
TypeSections = `need to have a type section for each code section`,
Inputs = 'expected inputs',
Outputs = 'expected outputs',
MaxInputs = 'inputs exceeds 127, the maximum, got: ',
MaxOutputs = 'outputs exceeds 127, the maximum, got: ',
Code0Inputs = 'first code section should have 0 inputs',
Code0Outputs = 'first code section should have 0 outputs',
MaxStackHeight = `expected maxStackHeight`,
MaxStackHeightLimit = `stack height limit of 1024 exceeded: `,
// Code/Data Section
MinCodeSections = `should have at least 1 code section`,
MaxCodeSections = `can have at most 1024 code sections`,
CodeSection = `expected a code section`,
DataSection = `Expected data section`,
// Dangling Bytes
DanglingBytes = 'got dangling bytes in body',
}
export function validationErrorMsg(type: EOFError, ...args: any) {
switch (type) {
case EOFError.OutOfBounds: {
return EOFError.OutOfBounds + ` at pos: ${args[0]}: ${args[1]}`
}
case EOFError.VerifyBytes: {
return EOFError.VerifyBytes + ` at pos: ${args[0]}: ${args[1]}`
}
case EOFError.VerifyUint: {
return EOFError.VerifyUint + `at pos: ${args[0]}: ${args[1]}`
}
case EOFError.TypeSize: {
return EOFError.TypeSize + args[0]
}
case EOFError.InvalidTypeSize: {
return EOFError.InvalidTypeSize + args[0]
}
case EOFError.InvalidCodeSize: {
return EOFError.InvalidCodeSize + args[0]
}
case EOFError.Inputs: {
return `${EOFError.Inputs} - typeSection ${args[0]}`
}
case EOFError.Outputs: {
return `${EOFError.Outputs} - typeSection ${args[0]}`
}
case EOFError.Code0Inputs: {
return `first code section should have 0 inputs`
}
case EOFError.Code0Outputs: {
return `first code section should have 0 outputs`
}
case EOFError.MaxInputs: {
return EOFError.MaxInputs + `${args[1]} - code section ${args[0]}`
}
case EOFError.MaxOutputs: {
return EOFError.MaxOutputs + `${args[1]} - code section ${args[0]}`
}
case EOFError.CodeSection: {
return `expected code: codeSection ${args[0]}: `
}
case EOFError.DataSection: {
return EOFError.DataSection
}
case EOFError.MaxStackHeight: {
return `${EOFError.MaxStackHeight} - typeSection ${args[0]}: `
}
case EOFError.MaxStackHeightLimit: {
return `${EOFError.MaxStackHeightLimit}, got: ${args[1]} - typeSection ${args[0]}`
}
case EOFError.DanglingBytes: {
return EOFError.DanglingBytes
}
default: {
return type
}
}
}
export function validationError(type: EOFError, ...args: any): never {
switch (type) {
case EOFError.OutOfBounds: {
const pos = args[0]
if (pos === 0 || pos === 2 || pos === 3 || pos === 6) {
throw new Error(args[1])
}
throw new Error(EOFError.OutOfBounds + ` `)
}
case EOFError.VerifyBytes: {
const pos = args[0]
if (pos === 0 || pos === 2 || pos === 3 || pos === 6) {
throw new Error(args[1])
}
throw new Error(EOFError.VerifyBytes + ` at pos: ${args[0]}: ${args[1]}`)
}
case EOFError.VerifyUint: {
const pos = args[0]
if (pos === 0 || pos === 2 || pos === 3 || pos === 6 || pos === 18) {
throw new Error(args[1])
}
throw new Error(EOFError.VerifyUint + `at pos: ${args[0]}: ${args[1]}`)
}
case EOFError.TypeSize: {
throw new Error(EOFError.TypeSize + args[0])
}
case EOFError.TypeSections: {
throw new Error(`${EOFError.TypeSections} (types ${args[0]} code ${args[1]})`)
}
case EOFError.InvalidTypeSize: {
throw new Error(EOFError.InvalidTypeSize)
}
case EOFError.InvalidCodeSize: {
throw new Error(EOFError.InvalidCodeSize + args[0])
}
case EOFError.Inputs: {
throw new Error(`${EOFError.Inputs} - typeSection ${args[0]}`)
}
case EOFError.Outputs: {
throw new Error(`${EOFError.Outputs} - typeSection ${args[0]}`)
}
case EOFError.Code0Inputs: {
throw new Error(`first code section should have 0 inputs`)
}
case EOFError.Code0Outputs: {
throw new Error(`first code section should have 0 outputs`)
}
case EOFError.MaxInputs: {
throw new Error(EOFError.MaxInputs + `${args[1]} - code section ${args[0]}`)
}
case EOFError.MaxOutputs: {
throw new Error(EOFError.MaxOutputs + `${args[1]} - code section ${args[0]}`)
}
case EOFError.CodeSection: {
throw new Error(`expected code: codeSection ${args[0]}: `)
}
case EOFError.DataSection: {
throw new Error(EOFError.DataSection)
}
case EOFError.MaxStackHeight: {
throw new Error(`${EOFError.MaxStackHeight} - typeSection ${args[0]}: `)
}
case EOFError.MaxStackHeightLimit: {
throw new Error(`${EOFError.MaxStackHeightLimit}, got: ${args[1]} - typeSection ${args[0]}`)
}
case EOFError.DanglingBytes: {
throw new Error(EOFError.DanglingBytes)
}
default: {
throw new Error(type)
}
}
}