Commit c63d2d8c authored by George Hotz's avatar George Hotz

running loads in trie

parent 121e9448
......@@ -33,8 +33,16 @@ contract MIPS {
m = new MIPSMemory();
}
bool constant public debug = true;
function WriteMemory(bytes32 stateHash, uint32 addr, uint32 value) internal returns (bytes32) {
if (address(m) != address(0)) {
if (debug) {
assembly {
// TODO: this is actually doing an SLOAD first
sstore(addr, value)
}
}
return m.WriteMemory(stateHash, addr, value);
} else {
assembly {
......@@ -45,9 +53,21 @@ contract MIPS {
}
}
function DebugEmit(uint32 val) internal view {
if (debug) {
uint256 junk;
assembly {
junk := sload(val)
}
require(junk != 0x133713371337, "huh");
}
}
function ReadMemory(bytes32 stateHash, uint32 addr) internal view returns (uint32 ret) {
if (address(m) != address(0)) {
DebugEmit(addr);
ret = m.ReadMemory(stateHash, addr);
DebugEmit(ret);
} else {
assembly {
ret := sload(addr)
......
......@@ -2,12 +2,25 @@
pragma solidity ^0.7.3;
import "./lib/Lib_Keccak256.sol";
import "./lib/Lib_MerkleTrie.sol";
import "hardhat/console.sol";
//import "./lib/Lib_MerkleTrie.sol";
import { Lib_RLPReader } from "./lib/Lib_RLPReader.sol";
import { Lib_BytesUtils } from "./lib/Lib_BytesUtils.sol";
contract MIPSMemory {
// TODO: the trie library should read and write from this as appropriate
mapping(bytes32 => bytes) public trie;
uint256 constant TREE_RADIX = 16;
uint256 constant BRANCH_NODE_LENGTH = TREE_RADIX + 1;
uint256 constant LEAF_OR_EXTENSION_NODE_LENGTH = 2;
uint8 constant PREFIX_EXTENSION_EVEN = 0;
uint8 constant PREFIX_EXTENSION_ODD = 1;
uint8 constant PREFIX_LEAF_EVEN = 2;
uint8 constant PREFIX_LEAF_ODD = 3;
function AddTrieNode(bytes calldata anything) public {
trie[keccak256(anything)] = anything;
}
......@@ -61,7 +74,7 @@ contract MIPSMemory {
return ret;
}
function fb(bytes memory dat) internal pure returns (uint32) {
function fb(bytes memory dat) internal view returns (uint32) {
require(dat.length == 4, "wrong length value");
uint32 ret = uint32(uint8(dat[0])) << 24 |
uint32(uint8(dat[1])) << 16 |
......@@ -70,19 +83,20 @@ contract MIPSMemory {
return ret;
}
mapping(bytes32 => mapping(uint32 => bytes)) proofs;
/*mapping(bytes32 => mapping(uint32 => bytes)) proofs;
function AddMerkleProof(bytes32 stateHash, uint32 addr, bytes calldata proof) public {
// validate proof
Lib_MerkleTrie.get(tb(addr), proof, stateHash);
proofs[stateHash][addr] = proof;
}
}*/
function WriteMemory(bytes32 stateHash, uint32 addr, uint32 value) public view returns (bytes32) {
require(addr & 3 == 0, "write memory must be 32-bit aligned");
// TODO: this can't delete nodes. modify the client to never delete
return Lib_MerkleTrie.update(tb(addr), tb(value), proofs[stateHash][addr], stateHash);
//return Lib_MerkleTrie.update(tb(addr), tb(value), proofs[stateHash][addr], stateHash);
return stateHash;
}
function WriteBytes32(bytes32 stateHash, uint32 addr, bytes32 val) public view returns (bytes32) {
......@@ -128,7 +142,7 @@ contract MIPSMemory {
(uint32(a3) << 0);
}
bool exists;
/*bool exists;
bytes memory value;
(exists, value) = Lib_MerkleTrie.get(tb(addr), proofs[stateHash][addr], stateHash);
......@@ -137,6 +151,46 @@ contract MIPSMemory {
return 0;
} else {
return fb(value);
}*/
bytes memory key = Lib_BytesUtils.toNibbles(tb(addr>>2));
bytes32 cnode = stateHash;
uint256 idx = 0;
while (true) {
Lib_RLPReader.RLPItem[] memory node = Lib_RLPReader.readList(trie[cnode]);
if (node.length == BRANCH_NODE_LENGTH) {
//revert("node length bnl");
uint8 branchKey = uint8(key[idx]);
if (idx == key.length-1) {
//if (addr != 0xc0000080) revert("here");
Lib_RLPReader.RLPItem[] memory lp = Lib_RLPReader.readList(node[branchKey]);
require(lp.length == 2, "wrong RLP list length");
return fb(Lib_RLPReader.readBytes(lp[1]));
} else {
cnode = Lib_RLPReader.readBytes32(node[branchKey]);
idx += 1;
}
} else if (node.length == LEAF_OR_EXTENSION_NODE_LENGTH) {
bytes memory path = Lib_BytesUtils.toNibbles(Lib_RLPReader.readBytes(node[0]));
uint8 prefix = uint8(path[0]);
if (prefix == PREFIX_LEAF_EVEN || prefix == PREFIX_LEAF_ODD) {
// TODO: check match
//return fb(Lib_RLPReader.readList(node[1]));
// broken
} else if (prefix == PREFIX_EXTENSION_EVEN || prefix == PREFIX_EXTENSION_ODD) {
// TODO: check match
if (prefix == PREFIX_EXTENSION_EVEN) {
idx += path.length - 2;
} else {
idx += path.length - 1;
}
cnode = Lib_RLPReader.readBytes32(node[1]);
}
} else {
revert("node in trie broken");
}
}
}
}
\ No newline at end of file
......@@ -2,6 +2,7 @@ package main
import (
"fmt"
"log"
"math/big"
"github.com/ethereum/go-ethereum/common"
......@@ -57,9 +58,34 @@ func RunFull() {
ram[0xC000007C] = 0x5EAD0000
root := RamToTrie(ram)
fmt.Println("state root", root, "nodes", len(Preimages))
//ParseNode(root, 0)
ParseNode(root, 0)
for _, v := range Preimages {
for k, v := range Preimages {
fmt.Println("AddTrieNode", k)
addTrieNode(v, interpreter, statedb)
}
fmt.Println("trie is ready, let's run")
// 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 {
fmt.Println("exited", common.BytesToHash(dat))
}
}
......@@ -39,9 +39,11 @@ func NewStateDB(debug int, realState bool) *StateDB {
return statedb
}
func (s *StateDB) AddAddressToAccessList(addr common.Address) {}
func (s *StateDB) AddBalance(addr common.Address, amount *big.Int) {}
func (s *StateDB) AddLog(log *types.Log) {}
func (s *StateDB) AddAddressToAccessList(addr common.Address) {}
func (s *StateDB) AddBalance(addr common.Address, amount *big.Int) {}
func (s *StateDB) AddLog(log *types.Log) {
fmt.Println("AddLog", log)
}
func (s *StateDB) AddPreimage(hash common.Hash, preimage []byte) {}
func (s *StateDB) AddRefund(gas uint64) {}
func (s *StateDB) AddSlotToAccessList(addr common.Address, slot common.Hash) {}
......@@ -68,6 +70,7 @@ func (s *StateDB) GetRefund() uint64 { return 0 }
func (s *StateDB) GetState(fakeaddr common.Address, hash common.Hash) common.Hash {
if s.useRealState {
// TODO: fakeaddr?
fmt.Println("GetState", fakeaddr, hash)
return s.RealState[hash]
}
ram := s.Ram
......
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