Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
3e4e0be0
Commit
3e4e0be0
authored
Jul 19, 2023
by
clabby
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Load data in oracle
parent
d6f80baf
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
144 additions
and
39 deletions
+144
-39
.gas-snapshot
packages/contracts-bedrock/.gas-snapshot
+0
-1
PreimageOracle.sol
packages/contracts-bedrock/src/cannon/PreimageOracle.sol
+113
-30
DisputeGameFactory.sol
...ages/contracts-bedrock/src/dispute/DisputeGameFactory.sol
+3
-1
FaultDisputeGame.sol
packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol
+3
-0
IBigStepper.sol
.../contracts-bedrock/src/dispute/interfaces/IBigStepper.sol
+11
-0
FaultDisputeGame.t.sol
packages/contracts-bedrock/test/FaultDisputeGame.t.sol
+12
-5
PreimageOracle.t.sol
packages/contracts-bedrock/test/PreimageOracle.t.sol
+2
-2
No files found.
packages/contracts-bedrock/.gas-snapshot
View file @
3e4e0be0
...
...
@@ -575,4 +575,3 @@ TransactorTest:test_constructor_succeeds() (gas: 9739)
TransactorTest:test_delegateCall_succeeds() (gas: 20909)
TransactorTest:test_delegateCall_unauthorized_reverts() (gas: 16550)
TransferOnionTest:test_constructor_succeeds() (gas: 564855)
TransferOnionTest:test_unwrap_succeeds() (gas: 724955)
\ No newline at end of file
packages/contracts-bedrock/src/cannon/PreimageOracle.sol
View file @
3e4e0be0
...
...
@@ -51,29 +51,87 @@ contract PreimageOracle {
preimageLengths[key] = size;
}
/// @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_) {
/// @notice Loads local data into the pre-image oracle in the context of the caller.
/// @param _bootInfo The boot info struct encoded as a tuple of .
function loadLocalData(bytes memory _bootInfo) external {
(
bytes32 l1head,
bytes32 l2head,
bytes32 l2claim,
uint64 l2ClaimBlockNumber,
bytes memory l2ChainConfig,
bytes memory rollupConfig
) = abi.decode(_bootInfo, (bytes32, bytes32, bytes32, uint64, bytes, bytes));
assembly {
let size := calldataload(0x24)
/// Store a value in a mapping
function storeInMapping(k, v, mappingSlot) {
// Value slot: `keccak256(k . mappingSlot)`
mstore(0x00, k)
mstore(0x20, mappingSlot)
sstore(keccak256(0x00, 0x40), v)
}
// Leave slots 0x40 and 0x60 untouched,
// and everything after as scratch-memory.
let ptr := 0x80
/// Store a value in a nested mapping
function storeInNestedMapping(ka, kb, v, mappingSlot) {
// Compute the slot of the nested mapping
mstore(0x00, ka)
mstore(0x20, mappingSlot)
let nestedSlot := keccak256(0x00, 0x40)
// Compute the slot of the value & store it
mstore(0x00, kb)
mstore(0x20, nestedSlot)
sstore(keccak256(0x00, 0x40), v)
}
// Store size as a big-endian uint64 at the start of pre-image
mstore(ptr, shl(192, size))
ptr := add(ptr, 8)
/// Compute the context-specifc key for a given local data identifier
function contextKey(ident) -> key {
// Store the global key (1 << 248 | ident)
mstore(0, or(shl(248, 1), ident))
// Store the caller to add context to the local data's global key
mstore(0x20, caller())
// Hash the data to get the context-specific key
// localize(k) = H(k .. sender) & ~(0xFF << 248) | (1 << 248)
key := or(and(keccak256(0, 0x40), not(shl(248, 0xFF))), shl(248, 1))
}
// Copy preimage payload into memory so we can hash and read it.
calldatacopy(ptr, _preimage.offset, size)
/// Store a fixed-size piece of local data
function storeFixed(ident, offset, size, data) {
// Grab the context key for the given `ident`
let k := contextKey(ident)
// Compute the pre-image keccak256 hash (aka the pre-image key)
let h := keccak256(ptr, size)
// Store the fixed data
storeInNestedMapping(k, offset, true, preimagePartOk.slot)
storeInNestedMapping(k, offset, data, preimageParts.slot)
storeInMapping(k, size, preimageLengths.slot)
}
// Mask out prefix byte, replace with type 2 byte
key_ := or(and(h, not(shl(248, 0xFF))), shl(248, 2))
/// Store a dynamic-size piece of local data
function storeDyn(ident, dataOffset) {
// Grab the length of the data
let size := mload(dataOffset)
// Grab the context key for the given `ident`
let k := contextKey(ident)
// Store each component of the preimage key.
let dataStart := add(dataOffset, 0x20)
for { let i := 0 } lt(i, size) { i := add(i, 0x20) } {
// Load the part at the given offset
// TODO(clabby): Verify size.
let part := mload(add(dataStart, i))
storeInNestedMapping(k, i, true, preimagePartOk.slot)
storeInNestedMapping(k, i, part, preimageParts.slot)
storeInMapping(k, size, preimageLengths.slot)
}
}
// Store all components of the boot info.
storeFixed(0, 0, 32, l1head)
storeFixed(1, 0, 32, l2head)
storeFixed(2, 0, 32, l2claim)
storeFixed(3, 0, 32, l2ClaimBlockNumber)
storeDyn(4, l2ChainConfig)
storeDyn(5, rollupConfig)
}
}
...
...
@@ -82,34 +140,59 @@ contract PreimageOracle {
/// @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) = loadPart(_partOffset, _preimage);
preimagePartOk[key][_partOffset] = true;
preimageParts[key][_partOffset] = part;
preimageLengths[key] = size;
}
function loadPart(uint256 _partOffset, bytes calldata _preimage) internal pure returns (uint256 size_, bytes32 key_, bytes32 part_) {
uint256 size;
bytes32 key;
bytes32 part;
assembly {
// len(sig) + len(partOffset) + len(preimage offset) = 4 + 32 + 32 = 0x44
size
_
:= calldataload(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,
// and everything after as scratch-memory.
let ptr := 0x80
// put size as big-endian uint64 at start of pre-image
mstore(ptr, shl(192, size
_
))
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))
let h := keccak256(ptr, size
_
) // compute preimage keccak256 hash
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;
preimageLengths[key] = size;
}
/// @notice Computes and returns the key for a global keccak pre-image.
/// @param _preimage The pre-image.
/// @return key_ The pre-image key.
function computeKeccak256PreimageKey(bytes calldata _preimage) external pure returns (bytes32 key_) {
assembly {
let 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))
}
}
...
...
packages/contracts-bedrock/src/dispute/DisputeGameFactory.sol
View file @
3e4e0be0
...
...
@@ -93,7 +93,9 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, Semver {
}
// Clone the implementation contract and initialize it with the given parameters.
proxy = IDisputeGame(address(impl).clone(abi.encodePacked(rootClaim, extraData.length, extraData)));
proxy = IDisputeGame(
address(impl).clone(abi.encodePacked(rootClaim, extraData.length, extraData))
);
proxy.initialize();
// Compute the unique identifier for the dispute game.
...
...
packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol
View file @
3e4e0be0
...
...
@@ -382,6 +382,9 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
countered: false
})
);
// Load the local data into the preimage oracle.
VM.oracle().loadLocalData(extraData());
}
/// @notice Returns the length of the `claimData` array.
...
...
packages/contracts-bedrock/src/dispute/interfaces/IBigStepper.sol
View file @
3e4e0be0
...
...
@@ -31,4 +31,15 @@ interface IBigStepper {
function step(bytes calldata _stateData, bytes calldata _proof)
external
returns (bytes32 postState_);
/// @notice Returns the preimage oracle used by the stepper.
function oracle() external view returns (IPreimageOracle oracle_);
}
/// @notice Temporary interface for the `IPreimageOracle`. Remove once we've upgraded
/// the cannon contracts to a newer version of solc.
interface IPreimageOracle {
/// @notice Loads local data into the pre-image oracle in the context of the caller.
/// @param _bootInfo The boot info struct encoded as a tuple of .
function loadLocalData(bytes memory _bootInfo) external;
}
packages/contracts-bedrock/test/FaultDisputeGame.t.sol
View file @
3e4e0be0
...
...
@@ -7,11 +7,11 @@ import { DisputeGameFactory_Init } from "./DisputeGameFactory.t.sol";
import { DisputeGameFactory } from "../src/dispute/DisputeGameFactory.sol";
import { FaultDisputeGame } from "../src/dispute/FaultDisputeGame.sol";
import "../
src/
libraries/DisputeTypes.sol";
import "../
src/
libraries/DisputeErrors.sol";
import { LibClock } from "../
src/
dispute/lib/LibClock.sol";
import { LibPosition } from "../
src/
dispute/lib/LibPosition.sol";
import { IBigStepper
} from "../src
/dispute/interfaces/IBigStepper.sol";
import "../libraries/DisputeTypes.sol";
import "../libraries/DisputeErrors.sol";
import { LibClock } from "../dispute/lib/LibClock.sol";
import { LibPosition } from "../dispute/lib/LibPosition.sol";
import { IBigStepper
, IPreimageOracle } from "..
/dispute/interfaces/IBigStepper.sol";
contract FaultDisputeGame_Init is DisputeGameFactory_Init {
/// @dev The extra data passed to the game for initialization.
...
...
@@ -889,9 +889,16 @@ contract VariableDivergentPlayer is GamePlayer {
contract AlphabetVM is IBigStepper {
Claim internal immutable ABSOLUTE_PRESTATE;
IPreimageOracle public oracle;
constructor(Claim _absolutePrestate) {
ABSOLUTE_PRESTATE = _absolutePrestate;
// Deploy a noop preimage oracle
assembly {
mstore(0x00, 0x60016000F3)
let size := 5
sstore(oracle.slot, create(0, sub(0x20, size), size))
}
}
/// @inheritdoc IBigStepper
...
...
packages/contracts-bedrock/test/PreimageOracle.t.sol
View file @
3e4e0be0
...
...
@@ -17,7 +17,7 @@ contract PreimageOracle_Test is Test {
/// @notice Test the pre-image key computation with a known pre-image.
function test_computePreimageKey_succeeds() public {
bytes memory preimage = hex"deadbeef";
bytes32 key = oracle.computePreimageKey(preimage);
bytes32 key = oracle.compute
Keccak256
PreimageKey(preimage);
bytes32 known = 0x02fd4e189132273036449fc9e11198c739161b4c0116a9a2dccdfa1c492006f1;
assertEq(key, known);
}
...
...
@@ -26,7 +26,7 @@ contract PreimageOracle_Test is Test {
function test_loadKeccak256PreimagePart_succeeds() public {
// Set the pre-image
bytes memory preimage = hex"deadbeef";
bytes32 key = oracle.computePreimageKey(preimage);
bytes32 key = oracle.compute
Keccak256
PreimageKey(preimage);
uint256 offset = 0;
oracle.loadKeccak256PreimagePart(offset, preimage);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment