Commit f176f263 authored by protolambda's avatar protolambda

mipsevm: remove old MPT-state focused tests

parent ebce83d1
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"
//fn := "test/bin/add.bin"
LoadMappedFile(fn, ram, 0)
ZeroRegisters(ram)
ram[0xC000007C] = 0x5EAD0000
return ram
}
// go test -run TestCompareEvmChain
func TestCompareEvmChain(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 (fake) 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 on evm
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
fmt.Println(i, x, y)
if x != y {
log.Fatal("mismatch at step", i)
}
}
/*ParseNode(root, 0, func(t common.Hash) []byte {
return Preimages[t]
})*/
}
package main
import (
"fmt"
"log"
"sync"
"testing"
"time"
uc "github.com/unicorn-engine/unicorn/bindings/go/unicorn"
)
func TestCompareUnicornEvm(t *testing.T) {
fn := "../mipigo/test/test.bin"
//fn := "../mipigo/minigeth.bin"
var done sync.Mutex
RegSerialize := func(ram map[uint32](uint32)) []uint32 {
ret := []uint32{ram[0xc0000080], uint32(len(ram))}
// 36 registers, 32 basic + pc + hi/lo + heap
for i := uint32(0xc0000000); i < 0xc0000000+36*4; i += 4 {
ret = append(ret, ram[i])
}
return ret
}
steps := 1000000000
//steps := 1165
//steps := 1180
//steps := 24
cevm := make(chan []uint32, 1)
cuni := make(chan []uint32, 1)
evmram := make(map[uint32](uint32))
LoadMappedFile(fn, evmram, 0)
// not for test.bin
/*inputFile := fmt.Sprintf("/tmp/cannon/%d_%d/input", 0, 13284469)
LoadMappedFile(inputFile, evmram, 0x30000000)*/
// init registers to 0 in evm
for i := uint32(0xC0000000); i < 0xC0000000+36*4; i += 4 {
WriteRam(evmram, i, 0)
}
go RunWithRam(evmram, steps, 0, "", func(step int, ram map[uint32](uint32)) {
//fmt.Printf("%d evm %x\n", step, ram[0xc0000080])
cevm <- RegSerialize(ram)
done.Lock()
done.Unlock()
})
uniram := make(map[uint32](uint32))
ministart := time.Now()
go RunUnicorn(fn, uniram, false, func(step int, mu uc.Unicorn, ram map[uint32](uint32)) {
SyncRegs(mu, ram)
cuni <- RegSerialize(ram)
done.Lock()
done.Unlock()
if step%1000000 == 0 {
steps_per_sec := float64(step) * 1e9 / float64(time.Now().Sub(ministart).Nanoseconds())
fmt.Printf("%10d pc: %x steps per s %f ram entries %d\n", step, ram[0xc0000080], steps_per_sec, len(ram))
}
// halt at steps
if step == steps {
mu.RegWrite(uc.MIPS_REG_PC, 0x5ead0004)
}
})
mismatch := false
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%100000 == 0 {
fmt.Println(i, x[0:9], y[0:9])
}
for j := 0; j < len(x); j++ {
if x[j] != y[j] {
fmt.Println(i, "mismatch at", j, "cevm", x, "cuni", y)
mismatch = true
}
}
if mismatch {
break
}
}
// final ram check
done.Lock()
time.Sleep(100 * time.Millisecond)
for k, v := range uniram {
if val, ok := evmram[k]; !ok || val != v {
fmt.Printf("ram mismatch at %x, evm %x != uni %x\n", k, evmram[k], uniram[k])
mismatch = true
}
}
if mismatch {
log.Fatal("RAM mismatch")
}
}
package main
import (
"fmt"
"log"
"math/big"
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
func TestMipsChain(t *testing.T) {
// only need one ram
ram := LoadRam()
root := RamToTrie(ram)
interpreter, statedb := GetInterpreter(1, true, "")
DeployChain(interpreter, statedb)
// load chain trie node
for _, v := range Preimages {
//fmt.Println("AddTrieNode", k)
AddTrieNode(v, interpreter, statedb)
}
steps := 50
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, gasUsed, err := RunWithInputAndGas(interpreter, statedb, input, uint64(steps*10000000))
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", root, "gas used", gasUsed)
}
}
package main
import (
"fmt"
"io/ioutil"
"log"
"testing"
"time"
)
func TestMinigethUnicorn(t *testing.T) {
uniram := make(map[uint32](uint32))
RunUnicorn("../mipigo/minigeth.bin", uniram, true, nil)
}
func TestSimpleEVM(t *testing.T) {
files, err := ioutil.ReadDir("test/bin")
if err != nil {
log.Fatal(err)
}
good := true
gas := uint64(0)
for _, f := range files {
ram := make(map[uint32](uint32))
ram[0xC000007C] = 0x5EAD0000
fn := "test/bin/" + f.Name()
LoadMappedFile(fn, ram, 0)
start := time.Now()
remainingGas, err := RunWithRam(ram, 100, 0, "testoracle/", nil)
elapsed := time.Now().Sub(start)
fmt.Println(err, remainingGas, elapsed,
ram[0xbffffff4], ram[0xbffffff8], fmt.Sprintf("%x", ram[0xc0000080]), fn)
if err != nil {
log.Fatal(err)
}
good = good && ((ram[0xbffffff4] & ram[0xbffffff8]) == 1)
gas += remainingGas
}
if !good {
panic("some tests failed")
}
fmt.Println("used", gas, "gas")
}
package main
import (
"encoding/binary"
"fmt"
"io/ioutil"
"log"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
)
func DeployChain(interpreter *vm.EVMInterpreter, statedb *StateDB) {
bytecode := GetBytecode(false)
from := common.Address{}
to := common.Address{}
gas := uint64(10000000)
input := make([]byte, 0)
contract := vm.NewContract(vm.AccountRef(from), vm.AccountRef(to), common.Big0, gas)
contract.SetCallCode(&to, crypto.Keccak256Hash(bytecode), bytecode)
ret, err := interpreter.Run(contract, input, false)
check(err)
fmt.Println("returned", len(ret))
statedb.Bytecodes[common.HexToAddress("0x1337")] = ret
}
func getTrieNode(str common.Hash, interpreter *vm.EVMInterpreter, statedb *StateDB) []byte {
from := common.Address{}
to := common.HexToAddress("0xBd770416a3345F91E4B34576cb804a576fa48EB1")
gas := uint64(100000000)
input := crypto.Keccak256Hash([]byte("trie(bytes32)")).Bytes()[:4]
input = append(input, str.Bytes()...)
bytecode := statedb.Bytecodes[to]
//fmt.Println("bytecode", len(bytecode))
contract := vm.NewContract(vm.AccountRef(from), vm.AccountRef(to), common.Big0, gas)
contract.SetCallCode(&to, crypto.Keccak256Hash(bytecode), bytecode)
ret, err := interpreter.Run(contract, input, false)
check(err)
//fmt.Println("getTrieNode", str, ret)
return ret[64:]
}
func AddTrieNode(str []byte, interpreter *vm.EVMInterpreter, statedb *StateDB) {
from := common.Address{}
to := common.HexToAddress("0xBd770416a3345F91E4B34576cb804a576fa48EB1")
gas := uint64(100000000)
input := crypto.Keccak256Hash([]byte("AddTrieNode(bytes)")).Bytes()[:4]
// offset
input = append(input, common.BigToHash(big.NewInt(int64(0x20))).Bytes()...)
// length
input = append(input, common.BigToHash(big.NewInt(int64(len(str)))).Bytes()...)
input = append(input, str...)
input = append(input, make([]byte, 0x20-(len(input)%0x20))...)
bytecode := statedb.Bytecodes[to]
//fmt.Println("bytecode", len(bytecode))
contract := vm.NewContract(vm.AccountRef(from), vm.AccountRef(to), common.Big0, gas)
contract.SetCallCode(&to, crypto.Keccak256Hash(bytecode), bytecode)
_, err := interpreter.Run(contract, input, false)
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 ZeroRegisters(ram map[uint32](uint32)) {
for i := uint32(0xC0000000); i < 0xC0000000+36*4; i += 4 {
WriteRam(ram, i, 0)
}
}
func LoadData(dat []byte, ram map[uint32](uint32), base uint32) {
for i := 0; i < len(dat); i += 4 {
value := binary.BigEndian.Uint32(dat[i : i+4])
if value != 0 {
ram[base+uint32(i)] = value
}
}
}
func LoadMappedFile(fn string, ram map[uint32](uint32), base uint32) {
dat, err := ioutil.ReadFile(fn)
check(err)
LoadData(dat, ram, base)
}
func RunFull() {
interpreter, statedb := GetInterpreter(0, true, "")
DeployChain(interpreter, statedb)
ram := make(map[uint32](uint32))
LoadMappedFile("../mipigo/test/test.bin", ram, 0)
totalSteps := 1000
//LoadMappedFile("test/bin/add.bin", ram, 0)
//totalSteps := 12
ZeroRegisters(ram)
ram[0xC000007C] = 0x5EAD0000
root := RamToTrie(ram)
//ParseNode(root, 0)
ioutil.WriteFile("/tmp/cannon/trie.json", TrieToJson(root, -1), 0644)
for k, v := range Preimages {
fmt.Println("AddTrieNode", k)
AddTrieNode(v, interpreter, statedb)
}
fmt.Println("trie is ready, let's run")
fmt.Println("state root", root, "nodes", len(Preimages))
for step := 0; step < totalSteps; step++ {
// it's run o clock
from := common.Address{}
to := common.HexToAddress("0x1337")
bytecode := statedb.Bytecodes[to]
gas := uint64(100000000)
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()...)
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)
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", (gas - contract.Gas))
}
}
/*ParseNode(root, 0, func(t common.Hash) []byte {
return getTrieNode(t, interpreter, statedb)
})*/
}
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