embedded_mips.go 2.57 KB
Newer Older
1
//go:build mips
George Hotz's avatar
George Hotz committed
2
// +build mips
3 4 5 6 7 8

package oracle

import (
	"math/big"
	"os"
9 10
	"reflect"
	"unsafe"
11 12

	"github.com/ethereum/go-ethereum/common"
George Hotz's avatar
George Hotz committed
13
	"github.com/ethereum/go-ethereum/core/types"
14
	"github.com/ethereum/go-ethereum/crypto"
15 16
)

George Hotz's avatar
George Hotz committed
17
var preimages = make(map[common.Hash][]byte)
George Hotz's avatar
George Hotz committed
18

19 20 21 22 23 24 25 26 27
func byteAt(addr uint64, length int) []byte {
	var ret []byte
	bh := (*reflect.SliceHeader)(unsafe.Pointer(&ret))
	bh.Data = uintptr(addr)
	bh.Len = length
	bh.Cap = length
	return ret
}

28
func InputHash() common.Hash {
29
	ret := byteAt(0x30000000, 0x20)
30 31
	os.Stderr.WriteString("********* on chain starts here *********\n")
	return common.BytesToHash(ret)
George Hotz's avatar
George Hotz committed
32 33
}

George Hotz's avatar
George Hotz committed
34
func Halt() {
35 36
	//os.Stderr.WriteString("THIS SHOULD BE PATCHED OUT\n")
	// the exit syscall is a jump to 0x5ead0000 now
George Hotz's avatar
George Hotz committed
37 38 39
	os.Exit(0)
}

George Hotz's avatar
George Hotz committed
40
func Output(output common.Hash, receipts common.Hash) {
41
	ret := byteAt(0x30000804, 0x20)
42
	copy(ret, output.Bytes())
43
	rret := byteAt(0x30000824, 0x20)
George Hotz's avatar
George Hotz committed
44
	copy(rret, receipts.Bytes())
45
	magic := byteAt(0x30000800, 4)
46
	copy(magic, []byte{0x13, 0x37, 0xf0, 0x0d})
George Hotz's avatar
George Hotz committed
47
	Halt()
George Hotz's avatar
George Hotz committed
48
}
49

George Hotz's avatar
George Hotz committed
50 51 52
func Preimage(hash common.Hash) []byte {
	val, ok := preimages[hash]
	if !ok {
George Hotz's avatar
George Hotz committed
53
		// load in hash
54
		preImageHash := byteAt(0x30001000, 0x20)
George Hotz's avatar
George Hotz committed
55 56 57 58 59 60 61
		copy(preImageHash, hash.Bytes())

		// used in unicorn emulator to trigger the load
		// in onchain mips, it's instant
		os.Getpid()

		// ready
62
		rawSize := common.CopyBytes(byteAt(0x31000000, 4))
George Hotz's avatar
George Hotz committed
63
		size := (int(rawSize[0]) << 24) | (int(rawSize[1]) << 16) | (int(rawSize[2]) << 8) | int(rawSize[3])
64
		ret := common.CopyBytes(byteAt(0x31000004, size))
George Hotz's avatar
George Hotz committed
65

66 67
		// this is 20% of the exec instructions, this speedup is always an option
		realhash := crypto.Keccak256Hash(ret)
George Hotz's avatar
George Hotz committed
68 69
		if realhash != hash {
			panic("preimage has wrong hash")
70
		}
George Hotz's avatar
George Hotz committed
71 72 73

		preimages[hash] = ret
		return ret
74
	}
George Hotz's avatar
George Hotz committed
75
	return val
76 77 78
}

// these are stubs in embedded world
George Hotz's avatar
George Hotz committed
79
func SetNodeUrl(newNodeUrl string)                                                        {}
George Hotz's avatar
George Hotz committed
80
func SetRoot(newRoot string)                                                              {}
81 82
func PrefetchStorage(*big.Int, common.Address, common.Hash, func(map[common.Hash][]byte)) {}
func PrefetchAccount(*big.Int, common.Address, func(map[common.Hash][]byte))              {}
83 84 85 86 87 88 89 90
func PrefetchCode(blockNumber *big.Int, addrHash common.Hash)                             {}
func PrefetchBlock(blockNumber *big.Int, startBlock bool, hasher types.TrieHasher)        {}

// KeyValueWriter wraps the Put method of a backing data store.
type PreimageKeyValueWriter struct{}

func (kw PreimageKeyValueWriter) Put(key []byte, value []byte) error { return nil }
func (kw PreimageKeyValueWriter) Delete(key []byte) error            { return nil }