Commit ede82663 authored by George Hotz's avatar George Hotz

minigeth emulation is real

parent 628f5b90
......@@ -17,11 +17,22 @@ interface IMIPSMemory {
}
contract MIPS {
IMIPSMemory constant public m = IMIPSMemory(0x1338);
IMIPSMemory public immutable m;
uint32 constant public REG_OFFSET = 0xc0000000;
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
function Step(bytes32 stateHash) public view returns (bytes32) {
// instruction fetch
......
......@@ -2,5 +2,13 @@
* @type import('hardhat/config').HardhatUserConfig
*/
module.exports = {
solidity: "0.7.3",
solidity: {
version: "0.7.3",
settings: {
optimizer: {
enabled: true,
runs: 200
}
}
},
};
......@@ -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
// the return byte-slice and an error if one occurred.
//
......
......@@ -48,6 +48,10 @@ type operation struct {
returns bool // determines whether the operations sets the return data content
}
func (o *operation) SetExecute(f executionFunc) {
o.execute = f
}
var (
frontierInstructionSet = newFrontierInstructionSet()
homesteadInstructionSet = newHomesteadInstructionSet()
......
......@@ -50,6 +50,11 @@ func (st *Stack) Data() []uint256.Int {
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) {
// NOTE push limit (1024) is checked in baseCheck
st.data = append(st.data, *d)
......@@ -59,6 +64,12 @@ func (st *Stack) pushN(ds ...uint256.Int) {
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) {
ret = st.data[len(st.data)-1]
st.data = st.data[:len(st.data)-1]
......
......@@ -40,7 +40,7 @@ func (s *StateDB) GetCode(addr common.Address) []byte {
return s.Bytecode
}
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 100 }
func (s *StateDB) GetCommittedState(addr common.Address, hash common.Hash) common.Hash {
return common.Hash{}
}
......@@ -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.
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
......@@ -90,6 +90,33 @@ type jsoncontract struct {
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() {
fmt.Println("hello")
......@@ -125,13 +152,27 @@ func main() {
fmt.Println(ret, gas, err)*/
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.BigToHash(big.NewInt(int64(steps))).Bytes()...)
contract := vm.NewContract(vm.AccountRef(from), vm.AccountRef(to), common.Big0, 20000000)
//fmt.Println(bytecodehash, bytecode)
contract.SetCallCode(&to, bytecodehash, bytecode)
start := time.Now()
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 {
log.Fatal(err)
}
......
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