Commit 348b28c3 authored by George Hotz's avatar George Hotz

write the nice compare for unicorn and on chain

parent 340d254b
package main
import (
"fmt"
"log"
"math/big"
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
func LoadRam() map[uint32](uint32) {
ram := make(map[uint32](uint32))
fn := "../mipigo/test/test.bin"
//LoadMappedFile("test/bin/add.bin", ram, 0)
LoadMappedFile(fn, ram, 0)
ZeroRegisters(ram)
ram[0xC000007C] = 0x5EAD0000
return ram
}
/*func TestFullSlow(t *testing.T) {
RunFull()
}*/
// go test -run TestCompareUnicornChain
func TestCompareUnicornChain(t *testing.T) {
totalSteps := 20
cchain := make(chan common.Hash, 1)
cuni := make(chan common.Hash, 1)
// only need one ram
ram := LoadRam()
root := RamToTrie(ram)
fmt.Println("state root", root, "nodes", len(Preimages))
// deploy chain
interpreter, statedb := GetInterpreter(0, true)
DeployChain(interpreter, statedb)
// load chain trie node
for _, v := range Preimages {
//fmt.Println("AddTrieNode", k)
AddTrieNode(v, interpreter, statedb)
}
// run on chain
go func(root common.Hash) {
for step := 0; step < totalSteps; step++ {
steps := 1
input := crypto.Keccak256Hash([]byte("Steps(bytes32,uint256)")).Bytes()[:4]
input = append(input, root.Bytes()...)
input = append(input, common.BigToHash(big.NewInt(int64(steps))).Bytes()...)
dat, _, err := RunWithInputAndGas(interpreter, statedb, input, uint64(100000000))
if err != nil {
if len(dat) >= 0x24 {
fmt.Println(string(dat[0x24:]))
}
log.Fatal(err)
} else {
root = common.BytesToHash(dat)
//fmt.Println("new state root", step, root, "gas used", gasUsed)
cchain <- root
}
}
}(root)
// run in unicorn
go func() {
for step := 0; step < totalSteps; step++ {
RunWithRam(ram, 1, 0, nil)
root = RamToTrie(ram)
cuni <- root
}
}()
for i := 0; i < totalSteps; i++ {
x, y := <-cchain, <-cuni
if x != y {
log.Fatal("mismatch at step", i)
}
fmt.Println(i, x, y)
}
/*ParseNode(root, 0, func(t common.Hash) []byte {
return Preimages[t]
})*/
}
...@@ -11,7 +11,7 @@ import ( ...@@ -11,7 +11,7 @@ import (
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
) )
func deploy(interpreter *vm.EVMInterpreter, statedb *StateDB) { func DeployChain(interpreter *vm.EVMInterpreter, statedb *StateDB) {
bytecode := GetBytecode(false) bytecode := GetBytecode(false)
from := common.Address{} from := common.Address{}
...@@ -47,7 +47,7 @@ func getTrieNode(str common.Hash, interpreter *vm.EVMInterpreter, statedb *State ...@@ -47,7 +47,7 @@ func getTrieNode(str common.Hash, interpreter *vm.EVMInterpreter, statedb *State
return ret[64:] return ret[64:]
} }
func addTrieNode(str []byte, interpreter *vm.EVMInterpreter, statedb *StateDB) { func AddTrieNode(str []byte, interpreter *vm.EVMInterpreter, statedb *StateDB) {
from := common.Address{} from := common.Address{}
to := common.HexToAddress("0xBd770416a3345F91E4B34576cb804a576fa48EB1") to := common.HexToAddress("0xBd770416a3345F91E4B34576cb804a576fa48EB1")
gas := uint64(100000000) gas := uint64(100000000)
...@@ -68,9 +68,19 @@ func addTrieNode(str []byte, interpreter *vm.EVMInterpreter, statedb *StateDB) { ...@@ -68,9 +68,19 @@ func addTrieNode(str []byte, interpreter *vm.EVMInterpreter, statedb *StateDB) {
check(err) check(err)
} }
func RunWithInputAndGas(interpreter *vm.EVMInterpreter, statedb *StateDB, input []byte, gas uint64) ([]byte, uint64, error) {
from := common.Address{}
to := common.HexToAddress("0x1337")
bytecode := statedb.Bytecodes[to]
contract := vm.NewContract(vm.AccountRef(from), vm.AccountRef(to), common.Big0, gas)
contract.SetCallCode(&to, crypto.Keccak256Hash(bytecode), bytecode)
dat, err := interpreter.Run(contract, input, false)
return dat, (gas - contract.Gas), err
}
func RunFull() { func RunFull() {
interpreter, statedb := GetInterpreter(0, true) interpreter, statedb := GetInterpreter(0, true)
deploy(interpreter, statedb) DeployChain(interpreter, statedb)
ram := make(map[uint32](uint32)) ram := make(map[uint32](uint32))
LoadMappedFile("../mipigo/test/test.bin", ram, 0) LoadMappedFile("../mipigo/test/test.bin", ram, 0)
...@@ -88,7 +98,7 @@ func RunFull() { ...@@ -88,7 +98,7 @@ func RunFull() {
for k, v := range Preimages { for k, v := range Preimages {
fmt.Println("AddTrieNode", k) fmt.Println("AddTrieNode", k)
addTrieNode(v, interpreter, statedb) AddTrieNode(v, interpreter, statedb)
} }
fmt.Println("trie is ready, let's run") fmt.Println("trie is ready, let's run")
fmt.Println("state root", root, "nodes", len(Preimages)) fmt.Println("state root", root, "nodes", len(Preimages))
......
package main
import (
"fmt"
"testing"
"github.com/ethereum/go-ethereum/common"
)
func TestFullSlow(t *testing.T) {
RunFull()
}
func TestFullEvm(t *testing.T) {
ram := make(map[uint32](uint32))
LoadMappedFile("test/bin/add.bin", ram, 0)
ZeroRegisters(ram)
ram[0xC000007C] = 0x5EAD0000
root := RamToTrie(ram)
for step := 0; step < 12; step++ {
RunWithRam(ram, 1, 0, nil)
root = RamToTrie(ram)
fmt.Println(step, root)
}
ParseNode(root, 0, func(t common.Hash) []byte {
return Preimages[t]
})
}
...@@ -42,14 +42,16 @@ func NewStateDB(debug int, realState bool) *StateDB { ...@@ -42,14 +42,16 @@ func NewStateDB(debug int, realState bool) *StateDB {
func (s *StateDB) AddAddressToAccessList(addr common.Address) {} func (s *StateDB) AddAddressToAccessList(addr common.Address) {}
func (s *StateDB) AddBalance(addr common.Address, amount *big.Int) {} func (s *StateDB) AddBalance(addr common.Address, amount *big.Int) {}
func (s *StateDB) AddLog(log *types.Log) { func (s *StateDB) AddLog(log *types.Log) {
if log.Topics[0] == common.HexToHash("0x70c25ce54e55d181671946b6120c8147a91806a3620c981a355f3ae5b11deb13") { if s.Debug >= 1 {
fmt.Printf("R: %x\n", bytesTo32(log.Data[0:32])) if log.Topics[0] == common.HexToHash("0x70c25ce54e55d181671946b6120c8147a91806a3620c981a355f3ae5b11deb13") {
} else if log.Topics[0] == common.HexToHash("0x7b1a2ade00e6a076351ef8a0f302b160b7fd0c65c18234dfe8218c4fa4fa10ab") { fmt.Printf("R: %x\n", bytesTo32(log.Data[0:32]))
//fmt.Printf("R: %x -> %x\n", bytesTo32(log.Data[0:32]), bytesTo32(log.Data[32:])) } else if log.Topics[0] == common.HexToHash("0x7b1a2ade00e6a076351ef8a0f302b160b7fd0c65c18234dfe8218c4fa4fa10ab") {
} else if log.Topics[0] == common.HexToHash("0x486ca368095cbbef9046ac7858bec943e866422cc388f49da1aa3aa77c10aa35") { //fmt.Printf("R: %x -> %x\n", bytesTo32(log.Data[0:32]), bytesTo32(log.Data[32:]))
fmt.Printf("W: %x <- %x\n", bytesTo32(log.Data[0:32]), bytesTo32(log.Data[32:])) } else if log.Topics[0] == common.HexToHash("0x486ca368095cbbef9046ac7858bec943e866422cc388f49da1aa3aa77c10aa35") {
} else { fmt.Printf("W: %x <- %x\n", bytesTo32(log.Data[0:32]), bytesTo32(log.Data[32:]))
fmt.Println("AddLog", log.Topics, log.Data) } else {
fmt.Println("AddLog", log.Topics, log.Data)
}
} }
} }
func (s *StateDB) AddPreimage(hash common.Hash, preimage []byte) {} func (s *StateDB) AddPreimage(hash common.Hash, preimage []byte) {}
...@@ -105,7 +107,7 @@ func (s *StateDB) GetState(fakeaddr common.Address, hash common.Hash) common.Has ...@@ -105,7 +107,7 @@ func (s *StateDB) GetState(fakeaddr common.Address, hash common.Hash) common.Has
ram[0xc0000008], ram[0xc000000c], ram[0xc0000010], ram[0xc0000014], ram[0xc0000008], ram[0xc000000c], ram[0xc0000010], ram[0xc0000014],
ram[0xc0000018], ram[0xc000001c], ram[0xc0000020], ram[0xc0000024]) ram[0xc0000018], ram[0xc000001c], ram[0xc0000020], ram[0xc0000024])
} }
if (s.PcCount % 100000) == 0 { if (s.PcCount%100000) == 0 && false {
steps_per_sec := float64(s.PcCount) * 1e9 / float64(time.Now().Sub(ministart).Nanoseconds()) steps_per_sec := float64(s.PcCount) * 1e9 / float64(time.Now().Sub(ministart).Nanoseconds())
os.Stderr.WriteString(fmt.Sprintf("%10d pc: %x steps per s %f ram entries %d\n", s.PcCount, nret&0x7FFFFFFF, steps_per_sec, len(ram))) os.Stderr.WriteString(fmt.Sprintf("%10d pc: %x steps per s %f ram entries %d\n", s.PcCount, nret&0x7FFFFFFF, steps_per_sec, len(ram)))
} }
......
...@@ -153,7 +153,7 @@ func RunUnicorn(fn string, ram map[uint32](uint32), totalSteps int, callback fun ...@@ -153,7 +153,7 @@ func RunUnicorn(fn string, ram map[uint32](uint32), totalSteps int, callback fun
ministart := time.Now() ministart := time.Now()
mu.HookAdd(uc.HOOK_CODE, func(mu uc.Unicorn, addr uint64, size uint32) { mu.HookAdd(uc.HOOK_CODE, func(mu uc.Unicorn, addr uint64, size uint32) {
if steps%1000000 == 0 { if steps%1000000 == 0 && false {
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))
} }
......
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