Skip to content

Commit

Permalink
Implement LoadLocalData and Apply
Browse files Browse the repository at this point in the history
  • Loading branch information
pcw109550 committed Feb 5, 2024
1 parent c1289c1 commit bf31f2a
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 9 deletions.
1 change: 1 addition & 0 deletions rvgo/fast/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ var (
CheatBytes4 = crypto.Keccak256([]byte("cheat(uint256,bytes32,bytes32,uint256)"))[:4]
CheatLocalKeyBytes4 = crypto.Keccak256([]byte("cheatLocalKey(uint256,bytes32,bytes32,uint256,bytes32)"))[:4]
LoadKeccak256PreimagePartBytes4 = crypto.Keccak256([]byte("loadKeccak256PreimagePart(uint256,bytes)"))[:4]
LoadLocalDataBytes4 = crypto.Keccak256([]byte("loadLocalData(uint256,bytes32,bytes32,uint256,uint256)"))[:4]
)
19 changes: 10 additions & 9 deletions rvgo/fast/witness.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,19 +63,20 @@ func (wit *StepWitness) EncodePreimageOracleInput(localContext LocalContext) ([]

switch preimage.KeyType(wit.PreimageKey[0]) {
case preimage.LocalKeyType:
// We have no on-chain form of preparing the bootstrap pre-images onchain yet.
// So instead we cheat them in.
// In production usage there should be an on-chain contract that exposes this,
// rather than going through the global keccak256 oracle.
if len(wit.PreimageValue) > 32+8 {
return nil, fmt.Errorf("local pre-image exceeds maximum size of 32 bytes with key 0x%x", wit.PreimageKey)
}
var input []byte
input = append(input, CheatLocalKeyBytes4...)
input = append(input, uint64ToBytes32(wit.PreimageOffset)...)
input = append(input, LoadLocalDataBytes4...)
input = append(input, wit.PreimageKey[:]...)
input = append(input, common.Hash(localContext).Bytes()...)

preimagePart := wit.PreimageValue[8:]
var tmp [32]byte
copy(tmp[:], wit.PreimageValue[wit.PreimageOffset:])
copy(tmp[:], preimagePart)
input = append(input, tmp[:]...)
input = append(input, uint64ToBytes32(uint64(len(wit.PreimageValue))-8)...)
input = append(input, common.Hash(localContext).Bytes()...)
input = append(input, uint64ToBytes32(uint64(len(wit.PreimageValue)-8))...)
input = append(input, uint64ToBytes32(wit.PreimageOffset)...)
// Note: we can pad calldata to 32 byte multiple, but don't strictly have to
return input, nil
case preimage.Keccak256KeyType:
Expand Down
33 changes: 33 additions & 0 deletions rvsol/src/PreimageOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,40 @@ contract PreimageOracle is IPreimageOracle {
uint256 _size,
uint256 _partOffset
) external returns (bytes32 key_) {
// Compute the localized key from the given local identifier.
key_ = PreimageKeyLib.localizeIdent(_ident, _localContext);

// Revert if the given part offset is not within bounds.
if (_partOffset > _size + 8 || _size > 32) {
// Revert with "PartOffsetOOB()"
assembly {
// Store "PartOffsetOOB()"
mstore(0, 0xfe254987)
// Revert with "PartOffsetOOB()"
revert(0x1c, 4)
}
// TODO: remove with revert PartOffsetOOB();
}

// Prepare the local data part at the given offset
bytes32 part;
assembly {
// Clean the memory in [0x20, 0x40)
mstore(0x20, 0x00)

// Store the full local data in scratch space.
mstore(0x00, shl(192, _size))
mstore(0x08, _word)

// Prepare the local data part at the requested offset.
part := mload(_partOffset)
}

// Store the first part with `_partOffset`.
preimagePartOk[key_][_partOffset] = true;
preimageParts[key_][_partOffset] = part;
// Assign the length of the preimage at the localized key.
preimageLengths[key_] = _size;
}

// loadKeccak256PreimagePart prepares the pre-image to be read by keccak256 key,
Expand Down

0 comments on commit bf31f2a

Please sign in to comment.