Commit 4020dc1e authored by George Hotz's avatar George Hotz

trie refactor

parent 10bbb65a
...@@ -9,7 +9,7 @@ contract MIPSMemory { ...@@ -9,7 +9,7 @@ contract MIPSMemory {
mapping(bytes32 => bytes) public trie; mapping(bytes32 => bytes) public trie;
function AddTrieNode(bytes calldata anything) public { function AddTrieNode(bytes calldata anything) public {
trie[keccak256(anything)] = anything; Lib_MerkleTrie.GetTrie()[keccak256(anything)] = anything;
} }
// TODO: replace with mapping(bytes32 => mapping(uint, bytes4)) // TODO: replace with mapping(bytes32 => mapping(uint, bytes4))
...@@ -72,7 +72,7 @@ contract MIPSMemory { ...@@ -72,7 +72,7 @@ contract MIPSMemory {
function WriteMemory(bytes32 stateHash, uint32 addr, uint32 value) public returns (bytes32) { function WriteMemory(bytes32 stateHash, uint32 addr, uint32 value) public returns (bytes32) {
require(addr & 3 == 0, "write memory must be 32-bit aligned"); require(addr & 3 == 0, "write memory must be 32-bit aligned");
return Lib_MerkleTrie.update(tb(addr>>2), tb(value), trie, stateHash); return Lib_MerkleTrie.update(tb(addr>>2), tb(value), stateHash);
} }
event DidStep(bytes32 stateHash); event DidStep(bytes32 stateHash);
...@@ -126,7 +126,7 @@ contract MIPSMemory { ...@@ -126,7 +126,7 @@ contract MIPSMemory {
bool exists; bool exists;
bytes memory value; bytes memory value;
(exists, value) = Lib_MerkleTrie.get(tb(addr>>2), trie, stateHash); (exists, value) = Lib_MerkleTrie.get(tb(addr>>2), stateHash);
if (!exists) { if (!exists) {
// this is uninitialized memory // this is uninitialized memory
......
...@@ -6,7 +6,7 @@ import { Lib_BytesUtils } from "./Lib_BytesUtils.sol"; ...@@ -6,7 +6,7 @@ import { Lib_BytesUtils } from "./Lib_BytesUtils.sol";
import { Lib_RLPReader } from "./Lib_RLPReader.sol"; import { Lib_RLPReader } from "./Lib_RLPReader.sol";
import { Lib_RLPWriter } from "./Lib_RLPWriter.sol"; import { Lib_RLPWriter } from "./Lib_RLPWriter.sol";
//import "hardhat/console.sol"; import "hardhat/console.sol";
/** /**
* @title Lib_MerkleTrie * @title Lib_MerkleTrie
...@@ -28,6 +28,10 @@ library Lib_MerkleTrie { ...@@ -28,6 +28,10 @@ library Lib_MerkleTrie {
Lib_RLPReader.RLPItem[] decoded; Lib_RLPReader.RLPItem[] decoded;
} }
function GetTrie() internal pure returns (mapping(bytes32 => bytes) storage trie) {
bytes32 position = keccak256("trie.trie.trie.trie");
assembly { trie.slot := position }
}
/********************** /**********************
* Contract Constants * * Contract Constants *
...@@ -64,7 +68,6 @@ library Lib_MerkleTrie { ...@@ -64,7 +68,6 @@ library Lib_MerkleTrie {
* @notice Updates a Merkle trie and returns a new root hash. * @notice Updates a Merkle trie and returns a new root hash.
* @param _key Key of the node to update, as a hex string. * @param _key Key of the node to update, as a hex string.
* @param _value Value of the node to update, as a hex string. * @param _value Value of the node to update, as a hex string.
* @param trie Merkle trie
* @param _root Known root of the Merkle trie. Used to verify that the * @param _root Known root of the Merkle trie. Used to verify that the
* included proof is correctly constructed. * included proof is correctly constructed.
* @return _updatedRoot Root hash of the newly constructed trie. * @return _updatedRoot Root hash of the newly constructed trie.
...@@ -72,7 +75,6 @@ library Lib_MerkleTrie { ...@@ -72,7 +75,6 @@ library Lib_MerkleTrie {
function update( function update(
bytes memory _key, bytes memory _key,
bytes memory _value, bytes memory _value,
mapping(bytes32 => bytes) storage trie,
bytes32 _root bytes32 _root
) )
internal internal
...@@ -82,13 +84,17 @@ library Lib_MerkleTrie { ...@@ -82,13 +84,17 @@ library Lib_MerkleTrie {
{ {
// Special case when inserting the very first node. // Special case when inserting the very first node.
if (_root == KECCAK256_RLP_NULL_BYTES) { if (_root == KECCAK256_RLP_NULL_BYTES) {
return getSingleNodeRootHash(_key, _value, trie); return getSingleNodeRootHash(_key, _value);
} }
(TrieNode[] memory proof, uint256 pathLength, bytes memory keyRemainder, ) = _walkNodePath(trie, _key, _root); (TrieNode[] memory proof, uint256 pathLength, bytes memory keyRemainder, ) = _walkNodePath(_key, _root);
TrieNode[] memory newPath = _getNewPath(proof, pathLength, _key, keyRemainder, _value); TrieNode[] memory newPath = _getNewPath(proof, pathLength, _key, keyRemainder, _value);
return _getUpdatedTrieRoot(newPath, _key, trie); _updatedRoot = _getUpdatedTrieRoot(newPath, _key);
for (uint i = 0; i < newPath.length; i++) {
console.log(i, newPath[i].decoded.length);
}
} }
function getRawNode(bytes memory encoded) private pure returns (TrieNode memory) { function getRawNode(bytes memory encoded) private pure returns (TrieNode memory) {
...@@ -98,8 +104,8 @@ library Lib_MerkleTrie { ...@@ -98,8 +104,8 @@ library Lib_MerkleTrie {
}); });
} }
function getTrieNode(mapping(bytes32 => bytes) storage trie, bytes32 nodeId) private view returns (TrieNode memory) { function getTrieNode(bytes32 nodeId) private view returns (TrieNode memory) {
bytes memory encoded = trie[nodeId]; bytes memory encoded = GetTrie()[nodeId];
require(keccak256(encoded) == nodeId, "bad hash in trie lookup"); require(keccak256(encoded) == nodeId, "bad hash in trie lookup");
return getRawNode(encoded); return getRawNode(encoded);
} }
...@@ -107,14 +113,12 @@ library Lib_MerkleTrie { ...@@ -107,14 +113,12 @@ library Lib_MerkleTrie {
/** /**
* @notice Retrieves the value associated with a given key. * @notice Retrieves the value associated with a given key.
* @param _key Key to search for, as hex bytes. * @param _key Key to search for, as hex bytes.
* @param trie Merkle trie
* @param _root Known root of the Merkle trie. * @param _root Known root of the Merkle trie.
* @return _exists Whether or not the key exists. * @return _exists Whether or not the key exists.
* @return _value Value of the key if it exists. * @return _value Value of the key if it exists.
*/ */
function get( function get(
bytes memory _key, bytes memory _key,
mapping(bytes32 => bytes) storage trie,
bytes32 _root bytes32 _root
) )
internal internal
...@@ -124,7 +128,7 @@ library Lib_MerkleTrie { ...@@ -124,7 +128,7 @@ library Lib_MerkleTrie {
bytes memory _value bytes memory _value
) )
{ {
(TrieNode[] memory proof, uint256 pathLength, bytes memory keyRemainder, bool isFinalNode) = _walkNodePath(trie, _key, _root); (TrieNode[] memory proof, uint256 pathLength, bytes memory keyRemainder, bool isFinalNode) = _walkNodePath(_key, _root);
bool exists = keyRemainder.length == 0; bool exists = keyRemainder.length == 0;
...@@ -149,8 +153,7 @@ library Lib_MerkleTrie { ...@@ -149,8 +153,7 @@ library Lib_MerkleTrie {
*/ */
function getSingleNodeRootHash( function getSingleNodeRootHash(
bytes memory _key, bytes memory _key,
bytes memory _value, bytes memory _value
mapping(bytes32 => bytes) storage trie
) )
internal internal
returns ( returns (
...@@ -161,7 +164,7 @@ library Lib_MerkleTrie { ...@@ -161,7 +164,7 @@ library Lib_MerkleTrie {
Lib_BytesUtils.toNibbles(_key), Lib_BytesUtils.toNibbles(_key),
_value).encoded; _value).encoded;
bytes32 ret = keccak256(dat); bytes32 ret = keccak256(dat);
trie[ret] = dat; GetTrie()[ret] = dat;
return ret; return ret;
} }
...@@ -172,7 +175,6 @@ library Lib_MerkleTrie { ...@@ -172,7 +175,6 @@ library Lib_MerkleTrie {
/** /**
* @notice Walks through a proof using a provided key. * @notice Walks through a proof using a provided key.
* @param trie Merkle trie
* @param _key Key to use for the walk. * @param _key Key to use for the walk.
* @param _root Known root of the trie. * @param _root Known root of the trie.
* @return _proof The proof * @return _proof The proof
...@@ -181,7 +183,6 @@ library Lib_MerkleTrie { ...@@ -181,7 +183,6 @@ library Lib_MerkleTrie {
* @return _isFinalNode Whether or not we've hit a dead end. * @return _isFinalNode Whether or not we've hit a dead end.
*/ */
function _walkNodePath( function _walkNodePath(
mapping(bytes32 => bytes) storage trie,
bytes memory _key, bytes memory _key,
bytes32 _root bytes32 _root
) )
...@@ -212,7 +213,7 @@ library Lib_MerkleTrie { ...@@ -212,7 +213,7 @@ library Lib_MerkleTrie {
break; break;
} }
if (currentNodeLength >= 32) { if (currentNodeLength >= 32) {
currentNode = getTrieNode(trie, currentNodeID); currentNode = getTrieNode(currentNodeID);
} else { } else {
currentNode = getRawNode(Lib_BytesUtils.slice(abi.encodePacked(currentNodeID), 0, currentNodeLength)); currentNode = getRawNode(Lib_BytesUtils.slice(abi.encodePacked(currentNodeID), 0, currentNodeLength));
} }
...@@ -483,8 +484,7 @@ library Lib_MerkleTrie { ...@@ -483,8 +484,7 @@ library Lib_MerkleTrie {
*/ */
function _getUpdatedTrieRoot( function _getUpdatedTrieRoot(
TrieNode[] memory _nodes, TrieNode[] memory _nodes,
bytes memory _key, bytes memory _key
mapping(bytes32 => bytes) storage trie
) )
private private
returns ( returns (
...@@ -530,12 +530,8 @@ library Lib_MerkleTrie { ...@@ -530,12 +530,8 @@ library Lib_MerkleTrie {
currentNode = _editBranchIndex(currentNode, branchKey, previousNodeHash); currentNode = _editBranchIndex(currentNode, branchKey, previousNodeHash);
} }
} }
// Compute the node hash for the next iteration. // Compute the node hash for the next iteration.
previousNodeHash = _getNodeHash(currentNode.encoded); previousNodeHash = _getNodeHash(currentNode.encoded);
if (currentNode.encoded.length >= 32) {
trie[keccak256(currentNode.encoded)] = currentNode.encoded;
}
} }
// Current node should be the root at this point. // Current node should be the root at this point.
...@@ -660,10 +656,11 @@ library Lib_MerkleTrie { ...@@ -660,10 +656,11 @@ library Lib_MerkleTrie {
if (itemType == Lib_RLPReader.RLPItemType.DATA_ITEM) { if (itemType == Lib_RLPReader.RLPItemType.DATA_ITEM) {
return Lib_RLPReader._copy(_in.ptr, itemOffset, itemLength); return Lib_RLPReader._copy(_in.ptr, itemOffset, itemLength);
} else { } else if (itemType == Lib_RLPReader.RLPItemType.LIST_ITEM) {
require(_in.length < 32, "bad _getNodeValue other"); require(_in.length < 32, "bad _getNodeValue list");
return Lib_RLPReader._copy(_in.ptr, 0, _in.length); return Lib_RLPReader._copy(_in.ptr, 0, _in.length);
} }
revert("bad _getNodeValue");
} }
/** /**
...@@ -676,14 +673,16 @@ library Lib_MerkleTrie { ...@@ -676,14 +673,16 @@ library Lib_MerkleTrie {
bytes memory _encoded bytes memory _encoded
) )
private private
pure
returns ( returns (
bytes memory _hash bytes memory _hash
) )
{ {
console.logBytes(_encoded);
if (_encoded.length < 32) { if (_encoded.length < 32) {
return _encoded; return _encoded;
} else { } else {
console.logBytes32(keccak256(_encoded));
GetTrie()[keccak256(_encoded)] = _encoded;
return abi.encodePacked(keccak256(_encoded)); return abi.encodePacked(keccak256(_encoded));
} }
} }
......
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