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
ede82663
Commit
ede82663
authored
Sep 26, 2021
by
George Hotz
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
minigeth emulation is real
parent
628f5b90
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
85 additions
and
6 deletions
+85
-6
MIPS.sol
contracts/MIPS.sol
+12
-1
hardhat.config.js
hardhat.config.js
+9
-1
interpreter.go
minigeth/core/vm/interpreter.go
+4
-0
jump_table.go
minigeth/core/vm/jump_table.go
+4
-0
stack.go
minigeth/core/vm/stack.go
+11
-0
main.go
mipsevm/main.go
+45
-4
No files found.
contracts/MIPS.sol
View file @
ede82663
...
@@ -17,11 +17,22 @@ interface IMIPSMemory {
...
@@ -17,11 +17,22 @@ interface IMIPSMemory {
}
}
contract MIPS {
contract MIPS {
IMIPSMemory
constant public m = IMIPSMemory(0x1338)
;
IMIPSMemory
public immutable m
;
uint32 constant public REG_OFFSET = 0xc0000000;
uint32 constant public REG_OFFSET = 0xc0000000;
uint32 constant public REG_PC = REG_OFFSET + 0x20*4;
uint32 constant public REG_PC = REG_OFFSET + 0x20*4;
constructor(IMIPSMemory _m) {
m = _m;
}
function Steps(bytes32 stateHash, uint count) public view returns (bytes32) {
for (uint i = 0; i < count; i++) {
stateHash = Step(stateHash);
}
return stateHash;
}
// will revert if any required input state is missing
// will revert if any required input state is missing
function Step(bytes32 stateHash) public view returns (bytes32) {
function Step(bytes32 stateHash) public view returns (bytes32) {
// instruction fetch
// instruction fetch
...
...
hardhat.config.js
View file @
ede82663
...
@@ -2,5 +2,13 @@
...
@@ -2,5 +2,13 @@
* @type import('hardhat/config').HardhatUserConfig
* @type import('hardhat/config').HardhatUserConfig
*/
*/
module
.
exports
=
{
module
.
exports
=
{
solidity
:
"
0.7.3
"
,
solidity
:
{
version
:
"
0.7.3
"
,
settings
:
{
optimizer
:
{
enabled
:
true
,
runs
:
200
}
}
},
};
};
minigeth/core/vm/interpreter.go
View file @
ede82663
...
@@ -137,6 +137,10 @@ func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter {
...
@@ -137,6 +137,10 @@ func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter {
}
}
}
}
func
(
in
*
EVMInterpreter
)
GetCfg
()
*
Config
{
return
&
in
.
cfg
}
// Run loops and evaluates the contract's code with the given input data and returns
// Run loops and evaluates the contract's code with the given input data and returns
// the return byte-slice and an error if one occurred.
// the return byte-slice and an error if one occurred.
//
//
...
...
minigeth/core/vm/jump_table.go
View file @
ede82663
...
@@ -48,6 +48,10 @@ type operation struct {
...
@@ -48,6 +48,10 @@ type operation struct {
returns
bool
// determines whether the operations sets the return data content
returns
bool
// determines whether the operations sets the return data content
}
}
func
(
o
*
operation
)
SetExecute
(
f
executionFunc
)
{
o
.
execute
=
f
}
var
(
var
(
frontierInstructionSet
=
newFrontierInstructionSet
()
frontierInstructionSet
=
newFrontierInstructionSet
()
homesteadInstructionSet
=
newHomesteadInstructionSet
()
homesteadInstructionSet
=
newHomesteadInstructionSet
()
...
...
minigeth/core/vm/stack.go
View file @
ede82663
...
@@ -50,6 +50,11 @@ func (st *Stack) Data() []uint256.Int {
...
@@ -50,6 +50,11 @@ func (st *Stack) Data() []uint256.Int {
return
st
.
data
return
st
.
data
}
}
func
(
st
*
Stack
)
Push
(
d
*
uint256
.
Int
)
{
// NOTE push limit (1024) is checked in baseCheck
st
.
data
=
append
(
st
.
data
,
*
d
)
}
func
(
st
*
Stack
)
push
(
d
*
uint256
.
Int
)
{
func
(
st
*
Stack
)
push
(
d
*
uint256
.
Int
)
{
// NOTE push limit (1024) is checked in baseCheck
// NOTE push limit (1024) is checked in baseCheck
st
.
data
=
append
(
st
.
data
,
*
d
)
st
.
data
=
append
(
st
.
data
,
*
d
)
...
@@ -59,6 +64,12 @@ func (st *Stack) pushN(ds ...uint256.Int) {
...
@@ -59,6 +64,12 @@ func (st *Stack) pushN(ds ...uint256.Int) {
st
.
data
=
append
(
st
.
data
,
ds
...
)
st
.
data
=
append
(
st
.
data
,
ds
...
)
}
}
func
(
st
*
Stack
)
Pop
()
(
ret
uint256
.
Int
)
{
ret
=
st
.
data
[
len
(
st
.
data
)
-
1
]
st
.
data
=
st
.
data
[
:
len
(
st
.
data
)
-
1
]
return
}
func
(
st
*
Stack
)
pop
()
(
ret
uint256
.
Int
)
{
func
(
st
*
Stack
)
pop
()
(
ret
uint256
.
Int
)
{
ret
=
st
.
data
[
len
(
st
.
data
)
-
1
]
ret
=
st
.
data
[
len
(
st
.
data
)
-
1
]
st
.
data
=
st
.
data
[
:
len
(
st
.
data
)
-
1
]
st
.
data
=
st
.
data
[
:
len
(
st
.
data
)
-
1
]
...
...
mipsevm/main.go
View file @
ede82663
...
@@ -40,7 +40,7 @@ func (s *StateDB) GetCode(addr common.Address) []byte {
...
@@ -40,7 +40,7 @@ func (s *StateDB) GetCode(addr common.Address) []byte {
return
s
.
Bytecode
return
s
.
Bytecode
}
}
func
(
s
*
StateDB
)
GetCodeHash
(
addr
common
.
Address
)
common
.
Hash
{
return
common
.
Hash
{}
}
func
(
s
*
StateDB
)
GetCodeHash
(
addr
common
.
Address
)
common
.
Hash
{
return
common
.
Hash
{}
}
func
(
s
*
StateDB
)
GetCodeSize
(
addr
common
.
Address
)
int
{
return
0
}
func
(
s
*
StateDB
)
GetCodeSize
(
addr
common
.
Address
)
int
{
return
10
0
}
func
(
s
*
StateDB
)
GetCommittedState
(
addr
common
.
Address
,
hash
common
.
Hash
)
common
.
Hash
{
func
(
s
*
StateDB
)
GetCommittedState
(
addr
common
.
Address
,
hash
common
.
Hash
)
common
.
Hash
{
return
common
.
Hash
{}
return
common
.
Hash
{}
}
}
...
@@ -74,7 +74,7 @@ func (jst *Tracer) CaptureStart(env *vm.EVM, from common.Address, to common.Addr
...
@@ -74,7 +74,7 @@ func (jst *Tracer) CaptureStart(env *vm.EVM, from common.Address, to common.Addr
// CaptureState implements the Tracer interface to trace a single step of VM execution.
// CaptureState implements the Tracer interface to trace a single step of VM execution.
func
(
jst
*
Tracer
)
CaptureState
(
env
*
vm
.
EVM
,
pc
uint64
,
op
vm
.
OpCode
,
gas
,
cost
uint64
,
scope
*
vm
.
ScopeContext
,
rData
[]
byte
,
depth
int
,
err
error
)
{
func
(
jst
*
Tracer
)
CaptureState
(
env
*
vm
.
EVM
,
pc
uint64
,
op
vm
.
OpCode
,
gas
,
cost
uint64
,
scope
*
vm
.
ScopeContext
,
rData
[]
byte
,
depth
int
,
err
error
)
{
fmt
.
Println
(
pc
,
op
,
gas
)
//
fmt.Println(pc, op, gas)
}
}
// CaptureFault implements the Tracer interface to trace an execution fault
// CaptureFault implements the Tracer interface to trace an execution fault
...
@@ -90,6 +90,33 @@ type jsoncontract struct {
...
@@ -90,6 +90,33 @@ type jsoncontract struct {
DeployedBytecode
string
`json:"deployedBytecode"`
DeployedBytecode
string
`json:"deployedBytecode"`
}
}
func
opStaticCall
(
pc
*
uint64
,
interpreter
*
vm
.
EVMInterpreter
,
scope
*
vm
.
ScopeContext
)
([]
byte
,
error
)
{
// Pop gas. The actual gas is in interpreter.evm.callGasTemp.
stack
:=
scope
.
Stack
temp
:=
stack
.
Pop
()
returnGas
:=
temp
.
Uint64
()
_
,
inOffset
,
inSize
,
retOffset
,
retSize
:=
stack
.
Pop
(),
stack
.
Pop
(),
stack
.
Pop
(),
stack
.
Pop
(),
stack
.
Pop
()
//fmt.Println(temp, addr, inOffset, inSize, retOffset, retSize)
temp
.
SetOne
()
stack
.
Push
(
&
temp
)
ret
:=
common
.
Hash
{}
.
Bytes
()
// Get arguments from the memory.
args
:=
scope
.
Memory
.
GetPtr
(
int64
(
inOffset
.
Uint64
()),
int64
(
inSize
.
Uint64
()))
//scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
fmt
.
Println
(
"HOOKED!"
,
returnGas
,
args
)
scope
.
Memory
.
Set
(
retOffset
.
Uint64
(),
retSize
.
Uint64
(),
ret
)
//scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
//return ret
scope
.
Contract
.
Gas
+=
returnGas
return
ret
,
nil
}
func
main
()
{
func
main
()
{
fmt
.
Println
(
"hello"
)
fmt
.
Println
(
"hello"
)
...
@@ -125,13 +152,27 @@ func main() {
...
@@ -125,13 +152,27 @@ func main() {
fmt.Println(ret, gas, err)*/
fmt.Println(ret, gas, err)*/
interpreter
:=
vm
.
NewEVMInterpreter
(
evm
,
config
)
interpreter
:=
vm
.
NewEVMInterpreter
(
evm
,
config
)
input
:=
[]
byte
{
0x69
,
0x37
,
0x33
,
0x72
}
// Step(bytes32)
interpreter
.
GetCfg
()
.
JumpTable
[
vm
.
STATICCALL
]
.
SetExecute
(
opStaticCall
)
/*input := []byte{0x69, 0x37, 0x33, 0x72} // Step(bytes32)
input = append(input, common.Hash{}.Bytes()...)*/
// 1.26s for 100000 steps
steps
:=
10
// 0xdb7df598
input
:=
[]
byte
{
0xdb
,
0x7d
,
0xf5
,
0x98
}
// Steps(bytes32, uint256)
input
=
append
(
input
,
common
.
Hash
{}
.
Bytes
()
...
)
input
=
append
(
input
,
common
.
Hash
{}
.
Bytes
()
...
)
input
=
append
(
input
,
common
.
BigToHash
(
big
.
NewInt
(
int64
(
steps
)))
.
Bytes
()
...
)
contract
:=
vm
.
NewContract
(
vm
.
AccountRef
(
from
),
vm
.
AccountRef
(
to
),
common
.
Big0
,
20000000
)
contract
:=
vm
.
NewContract
(
vm
.
AccountRef
(
from
),
vm
.
AccountRef
(
to
),
common
.
Big0
,
20000000
)
//fmt.Println(bytecodehash, bytecode)
//fmt.Println(bytecodehash, bytecode)
contract
.
SetCallCode
(
&
to
,
bytecodehash
,
bytecode
)
contract
.
SetCallCode
(
&
to
,
bytecodehash
,
bytecode
)
start
:=
time
.
Now
()
ret
,
err
:=
interpreter
.
Run
(
contract
,
input
,
false
)
ret
,
err
:=
interpreter
.
Run
(
contract
,
input
,
false
)
fmt
.
Println
(
ret
,
err
,
contract
.
Gas
)
elapsed
:=
time
.
Now
()
.
Sub
(
start
)
fmt
.
Println
(
ret
,
err
,
contract
.
Gas
,
elapsed
)
if
err
!=
nil
{
if
err
!=
nil
{
log
.
Fatal
(
err
)
log
.
Fatal
(
err
)
}
}
...
...
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