diff --git a/README.md b/README.md index 6c7198f3a06688d79cfb5110c07360df387c37b6..2d4aeb6439d1994ab6d6ce3cb51ca757c64b55bd 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ mipsevm -- A MIPS runtime in the EVM (see also contracts/) ## TODO * Support fast generation of a specific state from the checkpoints -** Load into Unicorn/evm from the trie + * Load into Unicorn/evm from the trie * Write binary search "responder" * Deploy to cheapETH! diff --git a/mipsevm/trie.go b/mipsevm/trie.go index 2e2635c287b6bad575629b9b69d94a97442af2ba..3e2ae4592e0d53215dcb6ebd48f54c729ddf57b5 100644 --- a/mipsevm/trie.go +++ b/mipsevm/trie.go @@ -29,6 +29,14 @@ func TrieToJson(root common.Hash, step int) []byte { return b } +func TrieFromJson(dat []byte) (common.Hash, int) { + var j Jtree + err := json.Unmarshal(dat, &j) + check(err) + Preimages = j.Preimages + return j.Root, j.Step +} + // TODO: this is copied from the oracle func (kw PreimageKeyValueWriter) Put(key []byte, value []byte) error { hash := crypto.Keccak256Hash(value) @@ -80,6 +88,12 @@ func ParseNode(node common.Hash, depth int, callback func(common.Hash) []byte) { ParseNodeInternal(elems, depth, callback) } +func RamFromTrie(root common.Hash) map[uint32](uint32) { + ram := make(map[uint32](uint32)) + // TODO: write this + return ram +} + func RamToTrie(ram map[uint32](uint32)) common.Hash { mt := trie.NewStackTrie(PreimageKeyValueWriter{}) diff --git a/mipsevm/trie_test.go b/mipsevm/trie_test.go index 8cb9428606fb6d44c782ba4461b2c6fe4b897734..df328d1349bacf1097fb389e54740b9be985e502 100644 --- a/mipsevm/trie_test.go +++ b/mipsevm/trie_test.go @@ -3,6 +3,7 @@ package main import ( "fmt" "io/ioutil" + "reflect" "testing" "github.com/ethereum/go-ethereum/common" @@ -20,6 +21,21 @@ func TestTrie(t *testing.T) { dat := TrieToJson(root, -1) fmt.Println("serialized length is", len(dat)) ioutil.WriteFile("/tmp/cannon/ramtrie.json", dat, 0644) + + // load the trie + oldPreLen := len(Preimages) + Preimages = make(map[common.Hash][]byte) + dat, err := ioutil.ReadFile("/tmp/cannon/ramtrie.json") + check(err) + newroot, _ := TrieFromJson(dat) + if root != newroot { + t.Fatal("loaded root mismatch") + } + if len(Preimages) != oldPreLen { + t.Fatal("preimage length mismatch") + } + + // TODO: load memory when ready } func printRoot(ram map[uint32](uint32)) { @@ -35,6 +51,19 @@ func printTrie(ram map[uint32](uint32)) { }) } +func TestToFromTrie(t *testing.T) { + ram := make(map[uint32](uint32)) + ram[0] = 1 + ram[4] = 2 + + trie := RamToTrie(ram) + newram := RamFromTrie(trie) + + if !reflect.DeepEqual(ram, newram) { + t.Fatal("ram to/from mismatch") + } +} + func TestBuggedTrie(t *testing.T) { ram := make(map[uint32](uint32)) diff --git a/test/mips_test_memory.js b/test/mips_test_memory.js index be3f19348a3ec8170ef831f5a70b36303134e636..a94f873e957c10b75601701e29d731ce2df76846 100644 --- a/test/mips_test_memory.js +++ b/test/mips_test_memory.js @@ -67,13 +67,20 @@ describe("MIPSMemory contract", function () { for (var i = 0; i < 100; i++) { const keys = Object.keys(kv) const choice = Math.random() - if (choice < 0.5 || keys.length == 0) { + if (choice < 0.3 || keys.length == 0) { // write new key const key = randint(0x100)*4 const value = randint(0x100000000) console.log("writing", key, value) root = await write(mm, root, key, value) kv[key] = value + } else if (choice < 0.5) { + // write new high key + const key = randint(0x100)*4 + 0x10000000 + const value = randint(0x100000000) + console.log("writing", key, value) + root = await write(mm, root, key, value) + kv[key] = value } else if (choice > 0.7) { // read old key const idx = randint(keys.length)