Commit b1d71b87 authored by Kelvin Fichter's avatar Kelvin Fichter

Added trie libs

parent a1a499f1
......@@ -3,7 +3,7 @@ pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/* Library Imports */
import { Lib_OVMCodec } from "../../../libraries/codec/Lib_OVMCodec.sol";
import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol";
/* Interface Imports */
import { iOVM_FraudVerifier } from "../../iOVM/execution/iOVM_FraudVerifier.sol";
......
......@@ -3,7 +3,7 @@ pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/* Library Imports */
import { Lib_OVMCodec } from "../../../libraries/codec/Lib_OVMCodec.sol";
import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol";
/**
* @title iOVM_StateTransitioner
......
......@@ -77,7 +77,9 @@ library Lib_MerkleTrie {
)
internal
view
returns (bool)
returns (
bool
)
{
return verifyProof(_key, _value, _proof, _root, true);
}
......@@ -102,7 +104,9 @@ library Lib_MerkleTrie {
)
internal
view
returns (bool)
returns (
bool
)
{
return verifyProof(_key, _value, _proof, _root, false);
}
......@@ -126,7 +130,9 @@ library Lib_MerkleTrie {
)
internal
view
returns (bytes32)
returns (
bytes32
)
{
TrieNode[] memory proof = parseProof(_proof);
(uint256 pathLength, bytes memory keyRemainder, ) = walkNodePath(proof, _key, _root);
......@@ -150,7 +156,10 @@ library Lib_MerkleTrie {
)
internal
view
returns (bool, bytes memory)
returns (
bool,
bytes memory
)
{
TrieNode[] memory proof = parseProof(_proof);
(uint256 pathLength, bytes memory keyRemainder, ) = walkNodePath(proof, _key, _root);
......@@ -176,7 +185,9 @@ library Lib_MerkleTrie {
)
internal
view
returns (bytes32)
returns (
bytes32
)
{
return keccak256(makeLeafNode(
_key,
......@@ -212,7 +223,9 @@ library Lib_MerkleTrie {
)
private
view
returns (bool)
returns (
bool
)
{
TrieNode[] memory proof = parseProof(_proof);
(uint256 pathLength, bytes memory keyRemainder, bool isFinalNode) = walkNodePath(proof, _key, _root);
......@@ -370,7 +383,9 @@ library Lib_MerkleTrie {
)
private
view
returns (TrieNode[] memory)
returns (
TrieNode[] memory
)
{
bytes memory keyRemainder = _keyRemainder;
......@@ -494,7 +509,9 @@ library Lib_MerkleTrie {
)
private
view
returns (bytes32)
returns (
bytes32
)
{
bytes memory key = libByteUtils.toNibbles(_key);
......@@ -555,7 +572,9 @@ library Lib_MerkleTrie {
)
private
view
returns (TrieNode[] memory)
returns (
TrieNode[] memory
)
{
Lib_RLPReader.RLPItem[] memory nodes = libRLPReader.toList(libRLPReader.toRlpItem(_proof));
TrieNode[] memory proof = new TrieNode[](nodes.length);
......@@ -583,7 +602,9 @@ library Lib_MerkleTrie {
)
private
view
returns (bytes32)
returns (
bytes32
)
{
bytes memory nodeID;
......@@ -608,7 +629,9 @@ library Lib_MerkleTrie {
)
private
view
returns (bytes memory)
returns (
bytes memory
)
{
return libByteUtils.toNibbles(libRLPReader.toBytes(_node.decoded[0]));
}
......@@ -624,7 +647,9 @@ library Lib_MerkleTrie {
)
private
view
returns (bytes memory)
returns (
bytes memory
)
{
return removeHexPrefix(getNodePath(_node));
}
......@@ -639,7 +664,9 @@ library Lib_MerkleTrie {
)
private
view
returns (bytes memory)
returns (
bytes memory
)
{
return libRLPReader.toBytes(_node.decoded[_node.decoded.length - 1]);
}
......@@ -655,7 +682,9 @@ library Lib_MerkleTrie {
)
private
view
returns (bytes memory)
returns (
bytes memory
)
{
if (_encoded.length < 32) {
return _encoded;
......@@ -674,7 +703,9 @@ library Lib_MerkleTrie {
)
private
view
returns (NodeType)
returns (
NodeType
)
{
if (_node.decoded.length == BRANCH_NODE_LENGTH) {
return NodeType.BranchNode;
......@@ -705,7 +736,9 @@ library Lib_MerkleTrie {
)
private
view
returns (uint256)
returns (
uint256
)
{
uint256 i = 0;
while (_a.length > i && _b.length > i && _a[i] == _b[i]) {
......@@ -724,7 +757,9 @@ library Lib_MerkleTrie {
)
private
view
returns (TrieNode memory)
returns (
TrieNode memory
)
{
bytes memory encoded = libRLPWriter.encodeList(_raw);
......@@ -744,7 +779,9 @@ library Lib_MerkleTrie {
)
private
view
returns (TrieNode memory)
returns (
TrieNode memory
)
{
bytes[] memory raw = new bytes[](_items.length);
for (uint256 i = 0; i < _items.length; i++) {
......@@ -765,7 +802,9 @@ library Lib_MerkleTrie {
)
private
view
returns (TrieNode memory)
returns (
TrieNode memory
)
{
bytes[] memory raw = new bytes[](2);
bytes memory key = addHexPrefix(_key, false);
......@@ -789,7 +828,9 @@ library Lib_MerkleTrie {
)
private
view
returns (TrieNode memory)
returns (
TrieNode memory
)
{
bytes[] memory raw = new bytes[](2);
bytes memory key = addHexPrefix(_key, true);
......@@ -805,7 +846,9 @@ library Lib_MerkleTrie {
function makeEmptyBranchNode()
private
view
returns (TrieNode memory)
returns (
TrieNode memory
)
{
bytes[] memory raw = new bytes[](BRANCH_NODE_LENGTH);
for (uint256 i = 0; i < raw.length; i++) {
......@@ -826,7 +869,9 @@ library Lib_MerkleTrie {
)
private
view
returns (TrieNode memory)
returns (
TrieNode memory
)
{
bytes memory encoded = libRLPWriter.encodeBytes(_value);
_branch.decoded[_branch.decoded.length - 1] = libRLPReader.toRlpItem(encoded);
......@@ -847,7 +892,9 @@ library Lib_MerkleTrie {
)
private
view
returns (TrieNode memory)
returns (
TrieNode memory
)
{
bytes memory encoded = _value.length < 32 ? _value : libRLPWriter.encodeBytes(_value);
_branch.decoded[_index] = libRLPReader.toRlpItem(encoded);
......@@ -866,7 +913,9 @@ library Lib_MerkleTrie {
)
private
view
returns (bytes memory)
returns (
bytes memory
)
{
uint8 prefix = _isLeaf ? uint8(0x02) : uint8(0x00);
uint8 offset = uint8(_key.length % 2);
......@@ -885,7 +934,9 @@ library Lib_MerkleTrie {
)
private
view
returns (bytes memory)
returns (
bytes memory
)
{
if (uint8(_path[0]) % 2 == 0) {
return libByteUtils.slice(_path, 2);
......@@ -912,7 +963,9 @@ library Lib_MerkleTrie {
)
private
view
returns (TrieNode[] memory)
returns (
TrieNode[] memory
)
{
TrieNode[] memory ret = new TrieNode[](_aLength + _bLength);
......
......@@ -32,9 +32,11 @@ library Lib_SecureMerkleTrie {
bytes memory _proof,
bytes32 _root
)
public
internal
view
returns (bool)
returns (
bool
)
{
bytes memory key = _getSecureKey(_key);
return Lib_MerkleTrie.verifyInclusionProof(key, _value, _proof, _root);
......@@ -58,9 +60,11 @@ library Lib_SecureMerkleTrie {
bytes memory _proof,
bytes32 _root
)
public
internal
view
returns (bool)
returns (
bool
)
{
bytes memory key = _getSecureKey(_key);
return Lib_MerkleTrie.verifyExclusionProof(key, _value, _proof, _root);
......@@ -83,9 +87,11 @@ library Lib_SecureMerkleTrie {
bytes memory _proof,
bytes32 _root
)
public
internal
view
returns (bytes32)
returns (
bytes32
)
{
bytes memory key = _getSecureKey(_key);
return Lib_MerkleTrie.update(key, _value, _proof, _root);
......@@ -103,9 +109,12 @@ library Lib_SecureMerkleTrie {
bytes memory _proof,
bytes32 _root
)
public
internal
view
returns (bool, bytes memory)
returns (
bool,
bytes memory
)
{
bytes memory key = _getSecureKey(_key);
return Lib_MerkleTrie.get(key, _proof, _root);
......@@ -121,9 +130,11 @@ library Lib_SecureMerkleTrie {
bytes memory _key,
bytes memory _value
)
public
internal
view
returns (bytes32)
returns (
bytes32
)
{
bytes memory key = _getSecureKey(_key);
return Lib_MerkleTrie.getSingleNodeRootHash(key, _value);
......@@ -136,7 +147,13 @@ library Lib_SecureMerkleTrie {
function _getSecureKey(
bytes memory _key
) private pure returns (bytes memory) {
)
private
pure
returns (
bytes memory
)
{
return abi.encodePacked(keccak256(_key));
}
}
\ No newline at end of file
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
/*
* @title Lib_ByteUtils
*/
library Lib_ByteUtils {
/**********************
* Internal Functions *
**********************/
function concat(
bytes memory _preBytes,
bytes memory _postBytes
)
internal
pure
returns (bytes memory)
{
bytes memory tempBytes;
assembly {
// Get a location of some free memory and store it in tempBytes as
// Solidity does for memory variables.
tempBytes := mload(0x40)
// Store the length of the first bytes array at the beginning of
// the memory for tempBytes.
let length := mload(_preBytes)
mstore(tempBytes, length)
// Maintain a memory counter for the current write location in the
// temp bytes array by adding the 32 bytes for the array length to
// the starting location.
let mc := add(tempBytes, 0x20)
// Stop copying when the memory counter reaches the length of the
// first bytes array.
let end := add(mc, length)
for {
// Initialize a copy counter to the start of the _preBytes data,
// 32 bytes into its memory.
let cc := add(_preBytes, 0x20)
} lt(mc, end) {
// Increase both counters by 32 bytes each iteration.
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
// Write the _preBytes data into the tempBytes memory 32 bytes
// at a time.
mstore(mc, mload(cc))
}
// Add the length of _postBytes to the current length of tempBytes
// and store it as the new length in the first 32 bytes of the
// tempBytes memory.
length := mload(_postBytes)
mstore(tempBytes, add(length, mload(tempBytes)))
// Move the memory counter back from a multiple of 0x20 to the
// actual end of the _preBytes data.
mc := end
// Stop copying when the memory counter reaches the new combined
// length of the arrays.
end := add(mc, length)
for {
let cc := add(_postBytes, 0x20)
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
mstore(mc, mload(cc))
}
// Update the free-memory pointer by padding our last write location
// to 32 bytes: add 31 bytes to the end of tempBytes to move to the
// next 32 byte block, then round down to the nearest multiple of
// 32. If the sum of the length of the two arrays is zero then add
// one before rounding down to leave a blank 32 bytes (the length block with 0).
mstore(0x40, and(
add(add(end, iszero(add(length, mload(_preBytes)))), 31),
not(31) // Round down to the nearest 32 bytes.
))
}
return tempBytes;
}
function slice(
bytes memory _bytes,
uint256 _start,
uint256 _length
)
internal
pure
returns (bytes memory)
{
require(_bytes.length >= (_start + _length), "Read out of bounds");
bytes memory tempBytes;
assembly {
switch iszero(_length)
case 0 {
// Get a location of some free memory and store it in tempBytes as
// Solidity does for memory variables.
tempBytes := mload(0x40)
// The first word of the slice result is potentially a partial
// word read from the original array. To read it, we calculate
// the length of that partial word and start copying that many
// bytes into the array. The first word we copy will start with
// data we don't care about, but the last `lengthmod` bytes will
// land at the beginning of the contents of the new array. When
// we're done copying, we overwrite the full first word with
// the actual length of the slice.
let lengthmod := and(_length, 31)
// The multiplication in the next line is necessary
// because when slicing multiples of 32 bytes (lengthmod == 0)
// the following copy loop was copying the origin's length
// and then ending prematurely not copying everything it should.
let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
let end := add(mc, _length)
for {
// The multiplication in the next line has the same exact purpose
// as the one above.
let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
mstore(mc, mload(cc))
}
mstore(tempBytes, _length)
//update free-memory pointer
//allocating the array padded to 32 bytes like the compiler does now
mstore(0x40, and(add(mc, 31), not(31)))
}
//if we want a zero-length slice let's just return a zero-length array
default {
tempBytes := mload(0x40)
mstore(0x40, add(tempBytes, 0x20))
}
}
return tempBytes;
}
function slice(
bytes memory _bytes,
uint256 _start
)
internal
pure
returns (bytes memory)
{
if (_bytes.length - _start == 0) {
return bytes('');
}
return slice(_bytes, _start, _bytes.length - _start);
}
function toBytes32(
bytes memory _bytes
)
internal
pure
returns (bytes32)
{
bytes32 ret;
assembly {
ret := mload(add(_bytes, 32))
}
return ret;
}
function toUint256(
bytes memory _bytes
)
internal
pure
returns (uint256)
{
return uint256(toBytes32(_bytes));
}
function toNibbles(
bytes memory _bytes
)
internal
pure
returns (bytes memory)
{
bytes memory nibbles = new bytes(_bytes.length * 2);
for (uint256 i = 0; i < _bytes.length; i++) {
nibbles[i * 2] = _bytes[i] >> 4;
nibbles[i * 2 + 1] = bytes1(uint8(_bytes[i]) % 16);
}
return nibbles;
}
function fromNibbles(
bytes memory _bytes
)
internal
pure
returns (bytes memory)
{
bytes memory ret = new bytes(_bytes.length / 2);
for (uint256 i = 0; i < ret.length; i++) {
ret[i] = (_bytes[i * 2] << 4) | (_bytes[i * 2 + 1]);
}
return ret;
}
function equal(
bytes memory _bytes,
bytes memory _other
)
internal
pure
returns (bool)
{
return keccak256(_bytes) == keccak256(_other);
}
}
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