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 (
"github.com/ethereum/go-ethereum/crypto"
)
func deploy(interpreter *vm.EVMInterpreter, statedb *StateDB) {
func DeployChain(interpreter *vm.EVMInterpreter, statedb *StateDB) {
bytecode := GetBytecode(false)
from := common.Address{}
......@@ -47,7 +47,7 @@ func getTrieNode(str common.Hash, interpreter *vm.EVMInterpreter, statedb *State
return ret[64:]
}
func addTrieNode(str []byte, interpreter *vm.EVMInterpreter, statedb *StateDB) {
func AddTrieNode(str []byte, interpreter *vm.EVMInterpreter, statedb *StateDB) {
from := common.Address{}
to := common.HexToAddress("0xBd770416a3345F91E4B34576cb804a576fa48EB1")
gas := uint64(100000000)
......@@ -68,9 +68,19 @@ func addTrieNode(str []byte, interpreter *vm.EVMInterpreter, statedb *StateDB) {
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() {
interpreter, statedb := GetInterpreter(0, true)
deploy(interpreter, statedb)
DeployChain(interpreter, statedb)
ram := make(map[uint32](uint32))
LoadMappedFile("../mipigo/test/test.bin", ram, 0)
......@@ -88,7 +98,7 @@ func RunFull() {
for k, v := range Preimages {
fmt.Println("AddTrieNode", k)
addTrieNode(v, interpreter, statedb)
AddTrieNode(v, interpreter, statedb)
}
fmt.Println("trie is ready, let's run")
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 {
func (s *StateDB) AddAddressToAccessList(addr common.Address) {}
func (s *StateDB) AddBalance(addr common.Address, amount *big.Int) {}
func (s *StateDB) AddLog(log *types.Log) {
if log.Topics[0] == common.HexToHash("0x70c25ce54e55d181671946b6120c8147a91806a3620c981a355f3ae5b11deb13") {
fmt.Printf("R: %x\n", bytesTo32(log.Data[0:32]))
} else if log.Topics[0] == common.HexToHash("0x7b1a2ade00e6a076351ef8a0f302b160b7fd0c65c18234dfe8218c4fa4fa10ab") {
//fmt.Printf("R: %x -> %x\n", bytesTo32(log.Data[0:32]), bytesTo32(log.Data[32:]))
} else if log.Topics[0] == common.HexToHash("0x486ca368095cbbef9046ac7858bec943e866422cc388f49da1aa3aa77c10aa35") {
fmt.Printf("W: %x <- %x\n", bytesTo32(log.Data[0:32]), bytesTo32(log.Data[32:]))
} else {
fmt.Println("AddLog", log.Topics, log.Data)
if s.Debug >= 1 {
if log.Topics[0] == common.HexToHash("0x70c25ce54e55d181671946b6120c8147a91806a3620c981a355f3ae5b11deb13") {
fmt.Printf("R: %x\n", bytesTo32(log.Data[0:32]))
} else if log.Topics[0] == common.HexToHash("0x7b1a2ade00e6a076351ef8a0f302b160b7fd0c65c18234dfe8218c4fa4fa10ab") {
//fmt.Printf("R: %x -> %x\n", bytesTo32(log.Data[0:32]), bytesTo32(log.Data[32:]))
} else if log.Topics[0] == common.HexToHash("0x486ca368095cbbef9046ac7858bec943e866422cc388f49da1aa3aa77c10aa35") {
fmt.Printf("W: %x <- %x\n", bytesTo32(log.Data[0:32]), bytesTo32(log.Data[32:]))
} else {
fmt.Println("AddLog", log.Topics, log.Data)
}
}
}
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
ram[0xc0000008], ram[0xc000000c], ram[0xc0000010], ram[0xc0000014],
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())
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
ministart := time.Now()
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())
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