embedded_mips.go 2.6 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

George Hotz's avatar
George Hotz committed
19 20
// only 6 here
var inputs [6]common.Hash
George Hotz's avatar
George Hotz committed
21 22
var inputsLoaded bool = false

23 24 25 26 27 28 29 30 31
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
}

George Hotz's avatar
George Hotz committed
32
func Input(index int) common.Hash {
33
	if index < 0 || index > 6 {
George Hotz's avatar
George Hotz committed
34 35 36
		panic("bad input index")
	}
	if !inputsLoaded {
37 38 39 40 41
		// before this isn't run on chain (confirm this isn't cached)
		// does this interact with the GC?
		ret := byteAt(0x30000000, len(inputs)*0x20)

		os.Stderr.WriteString("********* on chain starts here *********\n")
George Hotz's avatar
George Hotz committed
42 43 44

		for i := 0; i < len(inputs); i++ {
			inputs[i] = common.BytesToHash(ret[i*0x20 : i*0x20+0x20])
45
			//fmt.Println(i, inputs[i])
George Hotz's avatar
George Hotz committed
46 47 48 49 50 51 52
		}

		inputsLoaded = true
	}
	return inputs[index]
}

George Hotz's avatar
George Hotz committed
53 54 55 56 57
func Halt() {
	os.Stderr.WriteString("THIS SHOULD BE PATCHED OUT\n")
	os.Exit(0)
}

George Hotz's avatar
George Hotz committed
58
func Output(output common.Hash, receipts common.Hash) {
59 60
	ret := byteAt(0x30000800, 0x20)
	copy(ret, output.Bytes())
George Hotz's avatar
George Hotz committed
61 62
	rret := byteAt(0x30000820, 0x20)
	copy(rret, receipts.Bytes())
George Hotz's avatar
George Hotz committed
63
	Halt()
George Hotz's avatar
George Hotz committed
64
}
65

George Hotz's avatar
George Hotz committed
66 67 68
func Preimage(hash common.Hash) []byte {
	val, ok := preimages[hash]
	if !ok {
George Hotz's avatar
George Hotz committed
69 70 71 72 73 74 75 76 77 78 79 80
		// load in hash
		preImageHash := byteAt(0x30001000, 0x20)
		copy(preImageHash, hash.Bytes())

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

		// ready
		rawSize := common.CopyBytes(byteAt(0x31000000, 4))
		size := (int(rawSize[0]) << 24) | (int(rawSize[1]) << 16) | (int(rawSize[2]) << 8) | int(rawSize[3])
		ret := common.CopyBytes(byteAt(0x31000004, size))
George Hotz's avatar
George Hotz committed
81 82 83 84 85 86 87 88

		realhash := crypto.Keccak256Hash(ret)
		if realhash != hash {
			panic("preimage has wrong hash")
		}

		preimages[hash] = ret
		return ret
89
	}
George Hotz's avatar
George Hotz committed
90
	return val
91 92 93
}

// these are stubs in embedded world
94 95
func PrefetchStorage(*big.Int, common.Address, common.Hash, func(map[common.Hash][]byte)) {}
func PrefetchAccount(*big.Int, common.Address, func(map[common.Hash][]byte))              {}
96 97 98 99 100 101 102 103
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 }