@@ -23,6 +23,7 @@ import {
2323} from '@ethereumjs/util'
2424import debugDefault from 'debug'
2525import { keccak256 } from 'ethereum-cryptography/keccak.js'
26+ import { sha256 } from 'ethereum-cryptography/sha256.js'
2627
2728import { Bloom } from './bloom/index.js'
2829import { emitEVMProfile } from './emitEVMProfile.js'
@@ -774,10 +775,22 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise<RunTxResult> {
774775}
775776
776777async function accumulateIVCLogs ( vm : VM , number : bigint , logs : Log [ ] ) {
778+ // keep all declarations here for ease of movement and diff
779+ const LOG_ADDRESS_STORAGE_SLOT = setLengthLeft ( new Uint8Array ( [ 0 ] ) , 32 )
780+ const LOG_TOPICS_STORAGE_SLOT = setLengthLeft ( new Uint8Array ( [ 1 ] ) , 32 )
781+ const LOG_ADDRESS_TOPICS_STORAGE_SLOT = setLengthLeft ( new Uint8Array ( [ 2 ] ) , 32 )
782+
783+ const commonSHA256 = vm . common . customCrypto . sha256 ?? sha256
777784 const ivcContractAddress = new Address (
778785 bigIntToAddressBytes ( vm . common . param ( 'ivcPredeployAddress' ) ) ,
779786 )
780787
788+ async function accumulateLog ( key : Uint8Array , logRoot : Uint8Array ) {
789+ const prevRoot = setLengthLeft ( await vm . stateManager . getStorage ( ivcContractAddress , key ) , 32 )
790+ const newRoot = commonSHA256 ( concatBytes ( logRoot , prevRoot ) )
791+ await vm . stateManager . putStorage ( ivcContractAddress , key , newRoot )
792+ }
793+
781794 if ( ( await vm . stateManager . getAccount ( ivcContractAddress ) ) === undefined ) {
782795 // store with nonce of 1 to prevent 158 cleanup
783796 const ivcContract = new Account ( )
@@ -791,20 +804,27 @@ async function accumulateIVCLogs(vm: VM, number: bigint, logs: Log[]) {
791804 topics : log [ 1 ] ,
792805 data : log [ 2 ] ,
793806 }
794-
795807 const logRoot = ssz . Log . hashTreeRoot ( sszLog )
808+
809+ // Allow eth_getLogs proof via `address` filter
810+ // abi.encode(log.address, LOG_ADDRESS_STORAGE_SLOT)
811+ const paddedAddress = setLengthLeft ( sszLog . address , 32 )
812+ const addressKey = keccak256 ( concatBytes ( paddedAddress , LOG_ADDRESS_STORAGE_SLOT ) )
813+ await accumulateLog ( addressKey , logRoot )
814+
796815 for ( const topic of sszLog . topics ) {
797- // should be 32 bytes but 0 bytes in case value doesn't exist so just left pad
798- const prevTopicRoot = setLengthLeft (
799- await vm . stateManager . getStorage ( ivcContractAddress , topic ) ,
800- 32 ,
816+ // Allow eth_getLogs proof via `topics` filter
817+ // abi.encode(topic, LOG_TOPICS_STORAGE_SLOT)
818+ const topicKey = keccak256 ( concatBytes ( topic , LOG_TOPICS_STORAGE_SLOT ) )
819+ await accumulateLog ( topicKey , logRoot )
820+
821+ // Allow eth_getLogs proof via combined `address` + `topics` filter
822+ // abi.encode(log.address, topic)
823+ const addressAndTopic = keccak256 ( concatBytes ( paddedAddress , topic ) )
824+ const addressAndTopicKey = keccak256 (
825+ concatBytes ( addressAndTopic , LOG_ADDRESS_TOPICS_STORAGE_SLOT ) ,
801826 )
802- const newTopicRoot = ssz . IVCEntry . hashTreeRoot ( {
803- prevTopicRoot,
804- number,
805- logRoot,
806- } )
807- await vm . stateManager . putStorage ( ivcContractAddress , topic , newTopicRoot )
827+ await accumulateLog ( addressAndTopicKey , logRoot )
808828 }
809829 }
810830}
0 commit comments