Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
60cd86a4
Commit
60cd86a4
authored
Oct 07, 2021
by
George Hotz
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add compare test, change dead address
parent
d63afff7
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
90 additions
and
24 deletions
+90
-24
CHALLENGE
CHALLENGE
+2
-2
Challenge.sol
contracts/Challenge.sol
+1
-1
MIPS.sol
contracts/MIPS.sol
+4
-1
embedded_mips.go
minigeth/oracle/embedded_mips.go
+2
-1
compile.py
mipigeth/compile.py
+3
-3
run.py
mipigeth/run.py
+1
-1
simple.py
mipigeth/simple.py
+1
-1
compare_test.go
mipsevm/compare_test.go
+48
-0
main.go
mipsevm/main.go
+4
-4
mipsevm.go
mipsevm/mipsevm.go
+10
-6
unicorn.go
mipsevm/unicorn.go
+14
-4
No files found.
CHALLENGE
View file @
60cd86a4
...
@@ -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 0x
D
EAD0000) with the hash in the state
Program returns a hash in mem(0x30000800) and exits(jump to 0x
5
EAD0000) 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 0x
D
EAD0000
* confirm assertionProof[8] proves the final state of $pc in finalSystemHash is 0x
5
EAD0000
* 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
...
...
contracts/Challenge.sol
View file @
60cd86a4
...
@@ -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) == 0x
DEAD0000, "machine is not stopped in final state (PC == 0xD
EAD0000)");
require(mem.ReadMemory(finalSystemState, 0xC0000080) == 0x
5EAD0000, "machine is not stopped in final state (PC == 0x5
EAD0000)");
return newChallengeTrusted(startState, finalSystemState, stepCount);
return newChallengeTrusted(startState, finalSystemState, stepCount);
}
}
...
...
contracts/MIPS.sol
View file @
60cd86a4
...
@@ -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 == 0x
d
ead0000) {
if (pc == 0x
5
ead0000) {
return stateHash;
return stateHash;
}
}
...
...
minigeth/oracle/embedded_mips.go
View file @
60cd86a4
...
@@ -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
)
}
}
...
...
mipigeth/compile.py
View file @
60cd86a4
...
@@ -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
...
...
mipigeth/run.py
View file @
60cd86a4
...
@@ -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
==
0x
D
EAD0000
:
if
pc
==
0x
5
EAD0000
:
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
))
...
...
mipigeth/simple.py
View file @
60cd86a4
...
@@ -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
==
0x
d
ead0000
:
if
pc
==
0x
5
ead0000
:
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
)
...
...
mipsevm/compare_test.go
0 → 100644
View file @
60cd86a4
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"
)
}
}
}
}
mipsevm/main.go
View file @
60cd86a4
...
@@ -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
]
=
0x
D
EAD0000
ram
[
0xC000007C
]
=
0x
5
EAD0000
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
)
}
}
...
...
mipsevm/mipsevm.go
View file @
60cd86a4
...
@@ -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
)
}
mipsevm/unicorn.go
View file @
60cd86a4
...
@@ -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
)
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment