Commit 60cd86a4 authored by George Hotz's avatar George Hotz

add compare test, change dead address

parent d63afff7
...@@ -27,7 +27,7 @@ PreimageOracle -- key value store ...@@ -27,7 +27,7 @@ PreimageOracle -- key value store
returns returns
$v0 = preimage[$t7...$t0] >> ($a0 * 32) $v0 = preimage[$t7...$t0] >> ($a0 * 32)
Program returns a hash in mem(0x30000800) and exits(jump to 0xDEAD0000) with the hash in the state Program returns a hash in mem(0x30000800) and exits(jump to 0x5EAD0000) with the hash in the state
Challenge Flow: Challenge Flow:
C is challenger, D is defender C is challenger, D is defender
...@@ -39,7 +39,7 @@ C: InitiateChallenge(uint blockNumberN, bytes blockHeaderN, bytes blockHeaderNp1 ...@@ -39,7 +39,7 @@ C: InitiateChallenge(uint blockNumberN, bytes blockHeaderN, bytes blockHeaderNp1
* saves inputs for input oracle * saves inputs for input oracle
* confirms assertionHash != blockHeaderNp1.Hash * confirms assertionHash != blockHeaderNp1.Hash
* confirm assertionProof[0..7] proves the final state of [$t7...$t0] in finalSystemHash is assertionHash * confirm assertionProof[0..7] proves the final state of [$t7...$t0] in finalSystemHash is assertionHash
* confirm assertionProof[8] proves the final state of $pc in finalSystemHash is 0xDEAD0000 * confirm assertionProof[8] proves the final state of $pc in finalSystemHash is 0x5EAD0000
* L = 0, R = stepCount # we agree at L=0, we disagree at R=stepCount * L = 0, R = stepCount # we agree at L=0, we disagree at R=stepCount
* return new challengeId * return new challengeId
* assertedState[0] = GlobalStartSystemHash + inputOracleMutations * assertedState[0] = GlobalStartSystemHash + inputOracleMutations
......
...@@ -111,7 +111,7 @@ contract Challenge { ...@@ -111,7 +111,7 @@ contract Challenge {
// you must load these proofs into MIPS before calling this // you must load these proofs into MIPS before calling this
// we disagree at the end // we disagree at the end
require(mem.ReadBytes32(finalSystemState, 0x30000800) == assertionRoot, "you are claiming a different state root in machine"); require(mem.ReadBytes32(finalSystemState, 0x30000800) == assertionRoot, "you are claiming a different state root in machine");
require(mem.ReadMemory(finalSystemState, 0xC0000080) == 0xDEAD0000, "machine is not stopped in final state (PC == 0xDEAD0000)"); require(mem.ReadMemory(finalSystemState, 0xC0000080) == 0x5EAD0000, "machine is not stopped in final state (PC == 0x5EAD0000)");
return newChallengeTrusted(startState, finalSystemState, stepCount); return newChallengeTrusted(startState, finalSystemState, stepCount);
} }
......
...@@ -94,6 +94,9 @@ contract MIPS { ...@@ -94,6 +94,9 @@ contract MIPS {
} else if (syscall_no == 4120) { } else if (syscall_no == 4120) {
// clone (not supported) // clone (not supported)
v0 = 1; v0 = 1;
} else if (syscall_no == 4246) {
// exit group
stateHash = WriteMemory(stateHash, REG_PC, 0x5ead0000);
} }
stateHash = WriteMemory(stateHash, REG_OFFSET+2*4, v0); stateHash = WriteMemory(stateHash, REG_OFFSET+2*4, v0);
...@@ -114,7 +117,7 @@ contract MIPS { ...@@ -114,7 +117,7 @@ contract MIPS {
function Step(bytes32 stateHash) public returns (bytes32) { function Step(bytes32 stateHash) public returns (bytes32) {
// instruction fetch // instruction fetch
uint32 pc = ReadMemory(stateHash, REG_PC); uint32 pc = ReadMemory(stateHash, REG_PC);
if (pc == 0xdead0000) { if (pc == 0x5ead0000) {
return stateHash; return stateHash;
} }
......
...@@ -51,7 +51,8 @@ func Input(index int) common.Hash { ...@@ -51,7 +51,8 @@ func Input(index int) common.Hash {
} }
func Halt() { func Halt() {
os.Stderr.WriteString("THIS SHOULD BE PATCHED OUT\n") //os.Stderr.WriteString("THIS SHOULD BE PATCHED OUT\n")
// the exit syscall is a jump to 0x5ead0000 now
os.Exit(0) os.Exit(0)
} }
......
...@@ -53,12 +53,12 @@ def load_minigeth(mu, fn="minigeth"): ...@@ -53,12 +53,12 @@ def load_minigeth(mu, fn="minigeth"):
# nop gcenable # nop gcenable
mu.mem_write(symbol['st_value'], b"\x03\xe0\x00\x08\x00\x00\x00\x00") mu.mem_write(symbol['st_value'], b"\x03\xe0\x00\x08\x00\x00\x00\x00")
found += 1 found += 1
if symbol.name == "github.com/ethereum/go-ethereum/oracle.Halt": #if symbol.name == "github.com/ethereum/go-ethereum/oracle.Halt":
#00400000: 2004dead ; <input:0> li $a0, 57005 #00400000: 2004dead ; <input:0> li $a0, 57005
# 00400004: 00042400 ; <input:1> sll $a0, $a0, 16 # 00400004: 00042400 ; <input:1> sll $a0, $a0, 16
# 00400008: 00800008 ; <input:2> jr $a0 # 00400008: 00800008 ; <input:2> jr $a0
mu.mem_write(symbol['st_value'], b"\x20\x04\xde\xad\x00\x04\x24\x00\x00\x80\x00\x08") #mu.mem_write(symbol['st_value'], b"\x20\x04\xde\xad\x00\x04\x24\x00\x00\x80\x00\x08")
found += 1 #found += 1
except Exception: except Exception:
#traceback.print_exc() #traceback.print_exc()
pass pass
......
...@@ -276,7 +276,7 @@ died_well = False ...@@ -276,7 +276,7 @@ died_well = False
def hook_mem_invalid(uc, access, address, size, value, user_data): def hook_mem_invalid(uc, access, address, size, value, user_data):
global died_well global died_well
pc = uc.reg_read(UC_MIPS_REG_PC) pc = uc.reg_read(UC_MIPS_REG_PC)
if pc == 0xDEAD0000: if pc == 0x5EAD0000:
died_well = True died_well = True
return False return False
print("UNMAPPED MEMORY:", access, hex(address), size, "at", hex(pc)) print("UNMAPPED MEMORY:", access, hex(address), size, "at", hex(pc))
......
...@@ -84,7 +84,7 @@ if len(sys.argv) > 1: ...@@ -84,7 +84,7 @@ if len(sys.argv) > 1:
def hook_mem_invalid(uc, access, address, size, value, user_data): def hook_mem_invalid(uc, access, address, size, value, user_data):
global has_input_oracle global has_input_oracle
pc = uc.reg_read(UC_MIPS_REG_PC) pc = uc.reg_read(UC_MIPS_REG_PC)
if pc == 0xdead0000: if pc == 0x5ead0000:
compare_hash = binascii.hexlify(mu.mem_read(0x30000800, 0x20)) compare_hash = binascii.hexlify(mu.mem_read(0x30000800, 0x20))
print("compare", compare_hash) print("compare", compare_hash)
os._exit(0) os._exit(0)
......
package main
import (
"fmt"
uc "github.com/unicorn-engine/unicorn/bindings/go/unicorn"
"testing"
)
func TestCompare(t *testing.T) {
fn := "../mipigeth/test.bin"
steps := 10000000
cevm := make(chan []uint32)
cuni := make(chan []uint32)
ram := make(map[uint32](uint32))
LoadMappedFile(fn, ram, 0)
go RunWithRam(ram, steps, 0, func(step int, ram map[uint32](uint32)) {
fmt.Printf("%d evm %x\n", step, ram[0xc0000080])
cevm <- []uint32{ram[0xc0000080] & 0x7FFFFFFF, ram[0xc0000008]}
})
go RunUnicorn(fn, steps, func(step int, mu uc.Unicorn) {
pc, _ := mu.RegRead(uc.MIPS_REG_PC)
v0, _ := mu.RegRead(uc.MIPS_REG_V0)
fmt.Printf("%d uni %x\n", step, pc)
cuni <- []uint32{uint32(pc), uint32(v0)}
})
for i := 0; i < steps; i++ {
x, y := <-cevm, <-cuni
if x[0] == 0x5ead0000 && y[0] == 0x5ead0000 {
fmt.Println("both processes exited")
break
}
if i%1000 == 0 {
fmt.Println(i, x, y)
}
for j := 0; j < len(x); j++ {
if x[j] != y[j] {
fmt.Println(i, x, y)
t.Fatal("value mismatch")
}
}
}
}
...@@ -25,16 +25,16 @@ func RunMinigeth(fn string, steps int, debug int) { ...@@ -25,16 +25,16 @@ func RunMinigeth(fn string, steps int, debug int) {
ram := make(map[uint32](uint32)) ram := make(map[uint32](uint32))
LoadMappedFile(fn, ram, 0) LoadMappedFile(fn, ram, 0)
LoadMappedFile(fmt.Sprintf("/tmp/eth/%d", 13284469), ram, 0x30000000) LoadMappedFile(fmt.Sprintf("/tmp/eth/%d", 13284469), ram, 0x30000000)
RunWithRam(ram, steps, debug) RunWithRam(ram, steps, debug, nil)
} }
func runTest(fn string, steps int, debug int) (uint32, uint64) { func runTest(fn string, steps int, debug int) (uint32, uint64) {
ram := make(map[uint32](uint32)) ram := make(map[uint32](uint32))
ram[0xC000007C] = 0xDEAD0000 ram[0xC000007C] = 0x5EAD0000
LoadMappedFile(fn, ram, 0) LoadMappedFile(fn, ram, 0)
start := time.Now() start := time.Now()
remainingGas, err := RunWithRam(ram, steps, debug) remainingGas, err := RunWithRam(ram, steps, debug, nil)
elapsed := time.Now().Sub(start) elapsed := time.Now().Sub(start)
fmt.Println(err, remainingGas, elapsed, fmt.Println(err, remainingGas, elapsed,
...@@ -55,7 +55,7 @@ func main() { ...@@ -55,7 +55,7 @@ func main() {
debug, _ := strconv.Atoi(os.Getenv("DEBUG")) debug, _ := strconv.Atoi(os.Getenv("DEBUG"))
RunMinigeth(os.Args[1], steps, debug) RunMinigeth(os.Args[1], steps, debug)
} else if os.Args[1] == "unicorn" { } else if os.Args[1] == "unicorn" {
RunUnicorn(os.Args[2], steps) RunUnicorn(os.Args[2], steps, nil)
} else { } else {
runTest(os.Args[1], 20, 2) runTest(os.Args[1], 20, 2)
} }
......
...@@ -24,6 +24,8 @@ var pcCount int = 0 ...@@ -24,6 +24,8 @@ var pcCount int = 0
var ram map[uint32](uint32) var ram map[uint32](uint32)
var ministart time.Time var ministart time.Time
var callback func(int, map[uint32](uint32))
func bytesTo32(a []byte) uint32 { func bytesTo32(a []byte) uint32 {
//return uint32(common.BytesToHash(a).Big().Uint64()) //return uint32(common.BytesToHash(a).Big().Uint64())
return binary.BigEndian.Uint32(a[28:]) return binary.BigEndian.Uint32(a[28:])
...@@ -115,6 +117,9 @@ func (s *StateDB) GetState(fakeaddr common.Address, hash common.Hash) common.Has ...@@ -115,6 +117,9 @@ func (s *StateDB) GetState(fakeaddr common.Address, hash common.Hash) common.Has
steps_per_sec := float64(pcCount) * 1e9 / float64(time.Now().Sub(ministart).Nanoseconds()) steps_per_sec := float64(pcCount) * 1e9 / float64(time.Now().Sub(ministart).Nanoseconds())
os.Stderr.WriteString(fmt.Sprintf("%10d pc: %x steps per s %f ram entries %d\n", pcCount, nret&0x7FFFFFFF, steps_per_sec, len(ram))) os.Stderr.WriteString(fmt.Sprintf("%10d pc: %x steps per s %f ram entries %d\n", pcCount, nret&0x7FFFFFFF, steps_per_sec, len(ram)))
} }
if callback != nil {
callback(pcCount, ram)
}
pcCount += 1 pcCount += 1
seenWrite = false seenWrite = false
} }
...@@ -210,7 +215,11 @@ func GetInterpreterAndBytecode(ldebug int) (*vm.EVMInterpreter, []byte) { ...@@ -210,7 +215,11 @@ func GetInterpreterAndBytecode(ldebug int) (*vm.EVMInterpreter, []byte) {
return interpreter, bytecode return interpreter, bytecode
} }
func runWithRamInternal(lram map[uint32](uint32), steps int, interpreter *vm.EVMInterpreter, bytecode []byte) (uint64, error) { func RunWithRam(lram map[uint32](uint32), steps int, debug int, lcallback func(int, map[uint32](uint32))) (uint64, error) {
interpreter, bytecode := GetInterpreterAndBytecode(debug)
callback = lcallback
ram = lram ram = lram
gas := 100000 * uint64(steps) gas := 100000 * uint64(steps)
...@@ -230,8 +239,3 @@ func runWithRamInternal(lram map[uint32](uint32), steps int, interpreter *vm.EVM ...@@ -230,8 +239,3 @@ func runWithRamInternal(lram map[uint32](uint32), steps int, interpreter *vm.EVM
return (gas - contract.Gas), err return (gas - contract.Gas), err
} }
func RunWithRam(lram map[uint32](uint32), steps int, debug int) (uint64, error) {
interpreter, bytecode := GetInterpreterAndBytecode(debug)
return runWithRamInternal(lram, steps, interpreter, bytecode)
}
...@@ -33,7 +33,7 @@ func WriteBytes(fd int, bytes []byte) { ...@@ -33,7 +33,7 @@ func WriteBytes(fd int, bytes []byte) {
} }
// reimplement simple.py in go // reimplement simple.py in go
func RunUnicorn(fn string, totalSteps int) { func RunUnicorn(fn string, totalSteps int, callback func(int, uc.Unicorn)) {
mu, err := uc.NewUnicorn(uc.ARCH_MIPS, uc.MODE_32|uc.MODE_BIG_ENDIAN) mu, err := uc.NewUnicorn(uc.ARCH_MIPS, uc.MODE_32|uc.MODE_BIG_ENDIAN)
check(err) check(err)
...@@ -71,6 +71,9 @@ func RunUnicorn(fn string, totalSteps int) { ...@@ -71,6 +71,9 @@ func RunUnicorn(fn string, totalSteps int) {
v0 = 0x40000000 v0 = 0x40000000
} else if syscall_no == 4120 { } else if syscall_no == 4120 {
v0 = 1 v0 = 1
} else if syscall_no == 4246 {
// exit group
mu.RegWrite(uc.MIPS_REG_PC, 0x5ead0000)
} else { } else {
//fmt.Println("syscall", syscall_no) //fmt.Println("syscall", syscall_no)
} }
...@@ -98,13 +101,21 @@ func RunUnicorn(fn string, totalSteps int) { ...@@ -98,13 +101,21 @@ func RunUnicorn(fn string, totalSteps int) {
steps_per_sec := float64(steps) * 1e9 / float64(time.Now().Sub(ministart).Nanoseconds()) steps_per_sec := float64(steps) * 1e9 / float64(time.Now().Sub(ministart).Nanoseconds())
fmt.Printf("%10d pc: %x steps per s %f ram entries %d\n", steps, addr, steps_per_sec, len(ram)) fmt.Printf("%10d pc: %x steps per s %f ram entries %d\n", steps, addr, steps_per_sec, len(ram))
} }
if callback != nil {
callback(steps, mu)
}
steps += 1 steps += 1
if totalSteps == steps { if totalSteps == steps {
os.Exit(0) //os.Exit(0)
mu.RegWrite(uc.MIPS_REG_PC, 0x5ead0000)
} }
}, 0, 0x80000000) }, 0, 0x80000000)
} }
// loop forever to match EVM
//mu.MemMap(0x5ead0000, 0x1000)
//mu.MemWrite(0xdead0000, []byte{0x08, 0x10, 0x00, 0x00})
check(mu.MemMap(0, 0x80000000)) check(mu.MemMap(0, 0x80000000))
// program // program
...@@ -119,6 +130,5 @@ func RunUnicorn(fn string, totalSteps int) { ...@@ -119,6 +130,5 @@ func RunUnicorn(fn string, totalSteps int) {
LoadMappedFile(fn, ram, 0) LoadMappedFile(fn, ram, 0)
LoadMappedFile(inputFile, ram, 0x30000000) LoadMappedFile(inputFile, ram, 0x30000000)
mu.Start(0, 0xdead0000) mu.Start(0, 0x5ead0004)
} }
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