Commit 10cfbb05 authored by George Hotz's avatar George Hotz

trie work

parent 443a51bd
......@@ -5,6 +5,13 @@ import "./lib/Lib_Keccak256.sol";
import "./lib/Lib_MerkleTrie.sol";
contract MIPSMemory {
// TODO: the trie library should read and write from this as appropriate
mapping(bytes32 => bytes) public trie;
function AddTrieNode(bytes calldata anything) public {
trie[keccak256(anything)] = anything;
}
// TODO: replace with mapping(bytes32 => mapping(uint, bytes4))
// to only save the part we care about
mapping(bytes32 => bytes) public preimage;
......
package main
import (
"bytes"
"encoding/binary"
"encoding/gob"
"fmt"
"sort"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie"
)
......@@ -14,6 +17,14 @@ type PreimageKeyValueWriter struct{}
var preimages = make(map[common.Hash][]byte)
func SerializeTrie(root common.Hash) []byte {
b := new(bytes.Buffer)
e := gob.NewEncoder(b)
check(e.Encode(root))
check(e.Encode(preimages))
return b.Bytes()
}
// TODO: this is copied from the oracle
func (kw PreimageKeyValueWriter) Put(key []byte, value []byte) error {
hash := crypto.Keccak256Hash(value)
......@@ -25,10 +36,35 @@ func (kw PreimageKeyValueWriter) Put(key []byte, value []byte) error {
}
func (kw PreimageKeyValueWriter) Delete(key []byte) error {
delete(preimages, common.BytesToHash(key))
return nil
}
func RamToTrie(ram map[uint32](uint32)) {
// full nodes have 17 values, each a hash
func parseNode(node common.Hash, depth int) {
if depth > 2 {
return
}
buf := preimages[node]
elems, _, err := rlp.SplitList(buf)
check(err)
c, _ := rlp.CountValues(elems)
fmt.Println("parsing", node, depth, "elements", c)
rest := elems
for i := 0; i < c; i++ {
kind, val, lrest, err := rlp.Split(rest)
rest = lrest
check(err)
fmt.Println(kind, val, len(val))
if len(val) == 32 {
hh := common.BytesToHash(val)
fmt.Println("node found with len", len(preimages[hh]))
parseNode(hh, depth+1)
}
}
}
func RamToTrie(ram map[uint32](uint32)) common.Hash {
mt := trie.NewStackTrie(PreimageKeyValueWriter{})
tk := make([]byte, 4)
......@@ -50,7 +86,9 @@ func RamToTrie(ram map[uint32](uint32)) {
binary.BigEndian.PutUint32(tv, v)
mt.Update(tk, tv)
}
mt.Commit()
fmt.Println("ram hash", mt.Hash())
fmt.Println("hash count", len(preimages))
fmt.Println("root node", preimages[mt.Hash()])
parseNode(mt.Hash(), 0)
return mt.Hash()
}
package main
import (
"io/ioutil"
"testing"
)
// go test -run TestTrie
func TestTrie(t *testing.T) {
fn := "../mipigo/minigeth.bin"
fn := "../mipigo/test/test.bin"
ram := make(map[uint32](uint32))
// TODO: copied from compare_test.go
......@@ -18,5 +19,7 @@ func TestTrie(t *testing.T) {
WriteRam(ram, i, 0)
}
RamToTrie(ram)
root := RamToTrie(ram)
dat := SerializeTrie(root)
ioutil.WriteFile("/tmp/eth/ramtrie", dat, 0644)
}
......@@ -13,6 +13,7 @@ import (
uc "github.com/unicorn-engine/unicorn/bindings/go/unicorn"
)
// SHOULD BE GO BUILTIN
func check(err error) {
if err != nil {
log.Fatal(err)
......
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