Commit f419bd15 authored by mergify[bot]'s avatar mergify[bot] Committed by GitHub

Merge pull request #6159 from ethereum-optimism/inphi/oracle-test

cannon: Fix oracle tests for mipsevm
parents 73d6cfa9 4cc16840
......@@ -48,7 +48,7 @@ func LoadContractsFromFiles() (*Contracts, error) {
if err != nil {
return nil, err
}
oracle, err := LoadContract("Oracle")
oracle, err := LoadContract("PreimageOracle")
if err != nil {
return nil, err
}
......
......@@ -58,8 +58,9 @@ func TestEVM(t *testing.T) {
for _, f := range testFiles {
t.Run(f.Name(), func(t *testing.T) {
var oracle PreimageOracle
if f.Name() == "oracle.bin" {
t.Skip("oracle test needs to be updated to use syscall pre-image oracle")
oracle = staticOracle(t, []byte("hello world"))
}
env, evmState := NewEVMEnv(contracts, addrs)
......@@ -75,7 +76,7 @@ func TestEVM(t *testing.T) {
// set the return address ($ra) to jump into when test completes
state.Registers[31] = endAddr
us := NewInstrumentedState(state, nil, os.Stdout, os.Stderr)
us := NewInstrumentedState(state, oracle, os.Stdout, os.Stderr)
for i := 0; i < 1000; i++ {
if us.state.PC == endAddr {
......@@ -91,6 +92,16 @@ func TestEVM(t *testing.T) {
// we take a snapshot so we can clean up the state, and isolate the logs of this instruction run.
snap := env.StateDB.Snapshot()
// prepare pre-image oracle data, if any
if stepWitness.HasPreimage() {
t.Logf("reading preimage key %x at offset %d", stepWitness.PreimageKey, stepWitness.PreimageOffset)
poInput, err := stepWitness.EncodePreimageOracleInput()
require.NoError(t, err, "encode preimage oracle input")
_, leftOverGas, err := env.Call(vm.AccountRef(addrs.Sender), addrs.Oracle, poInput, startingGas, big.NewInt(0))
require.NoErrorf(t, err, "evm should not fail, took %d gas", startingGas-leftOverGas)
}
ret, leftOverGas, err := env.Call(vm.AccountRef(sender), addrs.MIPS, input, startingGas, big.NewInt(0))
require.NoError(t, err, "evm should not fail")
require.Len(t, ret, 32, "expecting 32-byte state hash")
......
.section .test, "x"
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
# load hash at 0x30001000
# 0x47173285 a8d7341e 5e972fc6 77286384 f802f8ef 42a5ec5f 03bbfa25 4cb01fad = "hello world"
# 0x47173285 a8d7341e 5e972fc6 77286384 f802f8ef 42a5ec5f 03bbfa25 4cb01fad = keccak("hello world")
# 0x02173285 a8d7341e 5e972fc6 77286384 f802f8ef 42a5ec5f 03bbfa25 4cb01fad = keccak("hello world").key
test:
lui $s0, 0x3000
ori $s0, 0x1000
lui $t0, 0x4717
lui $t0, 0x0217
ori $t0, 0x3285
sw $t0, 0($s0)
lui $t0, 0xa8d7
......@@ -35,20 +36,53 @@ test:
ori $t0, 0x1fad
sw $t0, 0x1c($s0)
# syscall 4020 to trigger
li $v0, 4020
# preimage request - write(fdPreimageWrite, preimageData, 32)
li $a0, 6
li $a1, 0x30001000
li $t0, 8
li $a2, 4
$writeloop:
li $v0, 4004
syscall
addiu $a1, $a1, 4
addiu $t0, $t0, -1
bnez $t0, $writeloop
nop
# preimage response to 0x30002000 - read(fdPreimageRead, addr, count)
# read preimage length
li $a0, 5
li $a1, 0x31000000
li $a2, 4
li $v0, 4003
syscall
li $a1, 0x31000004
li $v0, 4003
syscall
# read the preimage data
li $a1, 0x31000008
li $t0, 3
$readloop:
li $v0, 4003
syscall
addiu $a1, $a1, 4
addiu $t0, $t0, -1
bnez $t0, $readloop
nop
# length at 0x31000000
# length at 0x31000000. We also check that the lower 32 bits are zero
lui $s1, 0x3100
lw $t0, 0($s1)
sltiu $t6, $t0, 1
li $s1, 0x31000004
lw $t0, 0($s1)
# should be len("hello world") == 11
li $t4, 11
subu $t5, $t0, $t4
sltiu $v0, $t5, 1
sltiu $v0, $t5, 1
and $v0, $v0, $t6
# data at 0x31000004
# data at 0x31000008
lw $t0, 4($s1)
lui $t4, 0x6865
ori $t4, 0x6c6c
......
......@@ -31,8 +31,9 @@ func TestState(t *testing.T) {
for _, f := range testFiles {
t.Run(f.Name(), func(t *testing.T) {
var oracle PreimageOracle
if f.Name() == "oracle.bin" {
t.Skip("oracle test needs to be updated to use syscall pre-image oracle")
oracle = staticOracle(t, []byte("hello world"))
}
// TODO: currently tests are compiled as flat binary objects
// We can use more standard tooling to compile them to ELF files and get remove maketests.py
......@@ -50,7 +51,7 @@ func TestState(t *testing.T) {
// set the return address ($ra) to jump into when test completes
state.Registers[31] = endAddr
us := NewInstrumentedState(state, nil, os.Stdout, os.Stderr)
us := NewInstrumentedState(state, oracle, os.Stdout, os.Stderr)
for i := 0; i < 1000; i++ {
if us.state.PC == endAddr {
......@@ -196,3 +197,15 @@ func TestClaim(t *testing.T) {
require.Equal(t, expectedStdOut, stdOutBuf.String(), "stdout")
require.Equal(t, expectedStdErr, stdErrBuf.String(), "stderr")
}
func staticOracle(t *testing.T, preimageData []byte) *testOracle {
return &testOracle{
hint: func(v []byte) {},
getPreimage: func(k [32]byte) []byte {
if k != preimage.Keccak256Key(crypto.Keccak256Hash(preimageData)).PreimageKey() {
t.Fatalf("invalid preimage request for %x", k)
}
return preimageData
},
}
}
This diff is collapsed.
This diff is collapsed.
......@@ -95,6 +95,9 @@ func (s *SourceMap) Info(pc uint64) (source string, line uint32, col uint32) {
if s.PosData[instr.F] == nil { // when the source file is known to be unavailable
return
}
if int(instr.S) >= len(s.PosData[instr.F]) { // possibly invalid / truncated source mapping
return
}
lc := s.PosData[instr.F][instr.S]
line = lc.Line
col = lc.Col
......
......@@ -145,9 +145,9 @@ contract MIPS {
if lt(space, datLen) { datLen := space } // if less space than data, shorten data
if lt(a2, datLen) { datLen := a2 } // if requested to read less, read less
dat := shr(sub(256, mul(datLen, 8)), dat) // right-align data
dat := shl(mul(alignment, 8), dat) // position data to insert into memory word
dat := shl(mul(add(sub(4, datLen), alignment), 8), dat) // position data to insert into memory word
let mask := sub(shl(mul(sub(4, alignment), 8), 1), 1) // mask all bytes after start
let suffixMask := sub(shl(mul(add(sub(4, alignment), datLen), 8), 1), 1) // mask of all bytes starting from end, maybe none
let suffixMask := sub(shl(mul(sub(sub(4, alignment), datLen), 8), 1), 1) // mask of all bytes starting from end, maybe none
mask := and(mask, not(suffixMask)) // reduce mask to just cover the data we insert
mem := or(and(mem, not(mask)), dat) // clear masked part of original memory, and insert data
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment