-
-
Published
Linked with GitHub
# EOF Testing Proposal
Currently the blockchain tests provided by the standard test fixture format only provides binary information around the validity of EOF byte code. It is of course important to test EOF in these contexts as it is full pipeline in which EOF will execute under consensus. However, the opaqueness of errors make it unclear if tests fail for the anticipated reason (or if clients all fail for the same reason).
Because of this, I propose an additional testing tool, similar to binary that `eofparse` runs, which exits with a standardized error code. This will allow testers to have higher confidence in the tests they write, as well as improve the granularity in which `eofparse` can fuzz implementations.
## Specification
### Binary
The binary should accept newline-delimited hex strings, potentially separated by spaces and/or dashes `-`, and output `err(X): error message`.
The message after the colon can be determined per implementation, but the error code `X` is standardized below.
#### Error Codes
(derived this by just going through the errors in geth implementation in order - can obviously debate each and add others)
| Number | Name | Reason |
|---|---|---|
| 1 | UnexpectedEOF | Container ends abruptly while trying to read fixed-sized value |
| 2 | InvalidMagic | Magic value is not `0xEF00` |
| 3 | InvaildVersion | Version number not `0x01` |
| 4 | MissingTypeHeader | Type section not first header section |
| 5 | InvalidTypeSize | Type size must be a multiple of 4 and size must not exceed 4 * 1024|
| 6 | MissingCodeHeader | Code section not second header section |
| 7 | InvalidCodeHeader | Number of code sections does not line up with type section size
| 8 | MissingDataHeader | Data section not third header section |
| 9 | MissingTerminator | Header not terminated after data section |
| 10 | TooManyInputs | Section has too many listed inputs |
| 11 | TooManyOutputs | Section has too many listed outputs |
| 12 | TooLargeMaxStackHeight | Section max stack height exceeds limit |
| 13 | InvalidSection0Type | Code section 0 has non-zero input/output |
| 14 | InvalidCodeSize | Code section size must not be 0 |
| 15 | InvalidContainerSize | Container size does not match computed size |
| 16 | UndefinedInstruction | Code references undefined instruction |
| 17 | TruncatedImmediate | Code segments with truncated immediate |
| 18 | InvalidSectionArgument | CALLF instruction points to non-existent section |
| 19 | InvalidJumpDest | Offset points to out-of-bounds destination (less than pos 0 or greater than len(code)) or immediate value |
| 20 | ConflictingStack | Instruction has multplie possible stack heights |
| 21 | InvalidBranchCount | RJUMPV can't have 0 case count |
| 22 | StackUnderflow | Instruction attempts to access more elements than are available |
| 23 | StackOverflow | Instruction attempts to push more elements than is allowed |
| 24 | InvalidOutputs | RETF attempts to return the wrong number of outputs for the section |
| 25 | InvalidMaxStackHeight | Compute max stack height for code section does not match type annotation |
| 26 | InvalidCodeTermination | Code section ends without terminal instruction or unconditional jump |
| 27 | UnreachableCode | Detected instructions which are never reachable in the control flow analysis |
### Test Fixture
The test fixture format will be a generic format that is easily processed by a wrapper around the above binary.
#### Example
Adapted from: https://github.com/ethereum/tests/issues/1130
```
{
"testname" : {
"code" : "0xefef",
"results" : {
"Cancun" : {
"result" : false,
"exception" : UnexpectedEOF
}
}
}
}
```