Commit 192357c0 authored by Andreas Bigger's avatar Andreas Bigger

Clean up PreimageOracle

parent 909554d0
This diff is collapsed.
This diff is collapsed.
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
/// @title PreimageOracle
/// @notice A contract for storing permissioned pre-images.
contract PreimageOracle {
/// @notice Mapping of pre-image keys to pre-image lengths.
mapping(bytes32 => uint256) public preimageLengths;
/// @notice Mapping of pre-image keys to pre-image parts.
mapping(bytes32 => mapping(uint256 => bytes32)) public preimageParts;
/// @notice Mapping of pre-image keys to pre-image part offsets.
mapping(bytes32 => mapping(uint256 => bool)) public preimagePartOk;
function readPreimage(bytes32 key, uint256 offset)
/// @notice Reads a pre-image from the oracle.
/// @param _key The key of the pre-image to read.
/// @param _offset The offset of the pre-image to read.
/// @return dat_ The pre-image data.
/// @return datLen_ The length of the pre-image data.
function readPreimage(bytes32 _key, uint256 _offset)
external
view
returns (bytes32 dat, uint256 datLen)
returns (bytes32 dat_, uint256 datLen_)
{
require(preimagePartOk[key][offset], "preimage must exist");
datLen = 32;
uint256 length = preimageLengths[key];
// add 8 for the length-prefix part
if (offset + 32 >= length + 8) {
datLen = length + 8 - offset;
require(preimagePartOk[_key][_offset], "pre-image must exist");
// Calculate the length of the pre-image data
// Add 8 for the length-prefix part
datLen_ = 32;
uint256 length = preimageLengths[_key];
if (_offset + 32 >= length + 8) {
datLen_ = length + 8 - _offset;
}
dat = preimageParts[key][offset];
// Retrieve the pre-image data
dat_ = preimageParts[_key][_offset];
}
// TODO(CLI-4104):
......@@ -37,17 +53,47 @@ contract PreimageOracle {
preimageLengths[key] = size;
}
// loadKeccak256PreimagePart prepares the pre-image to be read by keccak256 key,
// starting at the given offset, up to 32 bytes (clipped at preimage length, if out of data).
function loadKeccak256PreimagePart(uint256 partOffset, bytes calldata preimage) external {
/// @notice Computes and returns the key for a pre-image.
/// @param _preimage The pre-image.
/// @return key_ The pre-image key.
function computePreimageKey(bytes calldata _preimage) external pure returns (bytes32 key_) {
uint256 size;
assembly {
size := calldataload(0x24)
// Leave slots 0x40 and 0x60 untouched,
// and everything after as scratch-memory.
let ptr := 0x80
// Store size as a big-endian uint64 at the start of pre-image
mstore(ptr, shl(192, size))
ptr := add(ptr, 8)
// Copy preimage payload into memory so we can hash and read it.
calldatacopy(ptr, _preimage.offset, size)
// Compute the pre-image keccak256 hash (aka the pre-image key)
let h := keccak256(ptr, size)
// Mask out prefix byte, replace with type 2 byte
key_ := or(and(h, not(shl(248, 0xFF))), shl(248, 2))
}
}
/// @notice Prepares a pre-image to be read by keccak256 key, starting at
/// the given offset and up to 32 bytes (clipped at pre-image length, if out of data).
/// @param _partOffset The offset of the pre-image to read.
/// @param _preimage The preimage data.
function loadKeccak256PreimagePart(uint256 _partOffset, bytes calldata _preimage) external {
uint256 size;
bytes32 key;
bytes32 part;
assembly {
// len(sig) + len(partOffset) + len(preimage offset) = 4 + 32 + 32 = 0x44
size := calldataload(0x44)
// revert if part offset > size+8 (i.e. parts must be within bounds)
if gt(partOffset, add(size, 8)) {
if gt(_partOffset, add(size, 8)) {
revert(0, 0)
}
// we leave solidity slots 0x40 and 0x60 untouched,
......@@ -57,16 +103,16 @@ contract PreimageOracle {
mstore(ptr, shl(192, size))
ptr := add(ptr, 8)
// copy preimage payload into memory so we can hash and read it.
calldatacopy(ptr, preimage.offset, size)
calldatacopy(ptr, _preimage.offset, size)
// Note that it includes the 8-byte big-endian uint64 length prefix.
// this will be zero-padded at the end, since memory at end is clean.
part := mload(add(sub(ptr, 8), partOffset))
part := mload(add(sub(ptr, 8), _partOffset))
let h := keccak256(ptr, size) // compute preimage keccak256 hash
// mask out prefix byte, replace with type 2 byte
key := or(and(h, not(shl(248, 0xFF))), shl(248, 2))
}
preimagePartOk[key][partOffset] = true;
preimageParts[key][partOffset] = part;
preimagePartOk[key][_partOffset] = true;
preimageParts[key][_partOffset] = part;
preimageLengths[key] = size;
}
}
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