From 2844988c94e101843c8daa7b97094e546dda56f4 Mon Sep 17 00:00:00 2001 From: Gabriel Coutinho de Paula Date: Sat, 3 Aug 2024 09:45:31 -0300 Subject: [PATCH] WIP --- src/AccessLogs.sol | 38 ++++++++++++++++++++-------- templates/AccessLogs.sol.template | 42 +++++++++++++++++++++++-------- 2 files changed, 60 insertions(+), 20 deletions(-) diff --git a/src/AccessLogs.sol b/src/AccessLogs.sol index 2abc625..b3380ee 100644 --- a/src/AccessLogs.sol +++ b/src/AccessLogs.sol @@ -143,24 +143,28 @@ library AccessLogs { Memory.PhysicalAddress writeAddress, uint64 newValue ) internal pure { - bytes32 writtenData = a.buffer.consumeBytes32(); - (Memory.PhysicalAddress leafAddress, uint64 offset) = writeAddress.truncateToLeaf(); - uint64 expectedNewValue = machineWordToSolidityUint64( - getBytes8FromBytes32AtOffset(writtenData, offset) + + Memory.Region memory region = Memory.regionFromStride( + Memory.strideFromLeafAddress(leafAddress), + Memory.alignedSizeFromLog2(0) ); + bytes32 oldLeaf = a.buffer.consumeBytes32(); + (bytes32 rootHash,) = + a.buffer.peekRoot(region, keccak256(abi.encodePacked(oldLeaf))); + require( - newValue == expectedNewValue, - "Access log value does not contain the expected written value" + a.currentRootHash == rootHash, "Write region root doesn't match" ); - writeLeaf( - a, - Memory.strideFromLeafAddress(leafAddress), - keccak256(abi.encodePacked(writtenData)) + bytes32 newLeaf = setBytes8ToBytes32AtOffset( + solidityUint64ToMachineWord(newValue), oldLeaf, offset ); + + bytes32 newRootHash = a.buffer.getRoot(region, newLeaf); + a.currentRootHash = newRootHash; } function getBytes8FromBytes32AtOffset(bytes32 source, uint64 offset) @@ -170,4 +174,18 @@ library AccessLogs { { return bytes8(source << (offset << Memory.LOG2_WORD)); } + + function setBytes8ToBytes32AtOffset( + bytes8 word, + bytes32 leaf, + uint64 offset + ) internal pure returns (bytes32) { + uint64 wordOffset = offset << Memory.LOG2_WORD; + bytes32 toWrite = bytes32(word) << wordOffset; + + bytes32 wordMask = bytes32((1 << Memory.LOG2_WORD) - 1); + bytes32 mask = ~(wordMask << wordOffset); + + return (leaf & mask) | toWrite; + } } diff --git a/templates/AccessLogs.sol.template b/templates/AccessLogs.sol.template index ba0265e..82ffcdc 100644 --- a/templates/AccessLogs.sol.template +++ b/templates/AccessLogs.sol.template @@ -155,20 +155,27 @@ library AccessLogs { Memory.PhysicalAddress writeAddress, uint64 newValue ) internal pure { - bytes32 writtenData = a.buffer.consumeBytes32(); + (Memory.PhysicalAddress leafAddress, uint64 offset) = + writeAddress.truncateToLeaf(); - (Memory.PhysicalAddress leafAddress, uint64 offset) = writeAddress.truncateToLeaf(); - uint64 expectedNewValue = - machineWordToSolidityUint64( - getBytes8FromBytes32AtOffset(writtenData, offset)); + Memory.Region memory region = Memory.regionFromStride( + Memory.strideFromLeafAddress(leafAddress), + Memory.alignedSizeFromLog2(0) + ); - require(newValue == expectedNewValue, "Access log value does not contain the expected written value"); + bytes32 oldLeaf = a.buffer.consumeBytes32(); + (bytes32 rootHash,) = a.buffer.peekRoot(region, keccak256(abi.encodePacked(oldLeaf))); - writeLeaf( - a, - Memory.strideFromLeafAddress(leafAddress), - keccak256(abi.encodePacked(writtenData)) + require( + a.currentRootHash == rootHash, "Write region root doesn't match" ); + + bytes32 newLeaf = setBytes8ToBytes32AtOffset( + solidityUint64ToMachineWord(newValue), oldLeaf, offset + ); + + bytes32 newRootHash = a.buffer.getRoot(region, newLeaf); + a.currentRootHash = newRootHash; } function getBytes8FromBytes32AtOffset(bytes32 source, uint64 offset) @@ -179,6 +186,21 @@ library AccessLogs { return bytes8(source << (offset << Memory.LOG2_WORD)); } + function setBytes8ToBytes32AtOffset(bytes8 word, bytes32 leaf, uint64 offset) + internal + pure + returns (bytes32) + { + uint64 wordOffset = offset << Memory.LOG2_WORD; + bytes32 toWrite = bytes32(word) << wordOffset; + + bytes32 wordMask = bytes32((1 << Memory.LOG2_WORD) - 1); + bytes32 mask = ~(wordMask << wordOffset); + + return (leaf & mask) | toWrite; + } + + //:#else /// @dev This library mocks the `templates/AccessLogs.sol` yet with a very different implementation.