Skip to content

Commit

Permalink
modify the ivc accumulator code for smartcontract comaptible compute …
Browse files Browse the repository at this point in the history
…and add log proofing capabilities by multiple filters
  • Loading branch information
g11tech committed Oct 9, 2024
1 parent f768aef commit 841db33
Showing 1 changed file with 31 additions and 11 deletions.
42 changes: 31 additions & 11 deletions packages/vm/src/runTx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
} from '@ethereumjs/util'
import debugDefault from 'debug'
import { keccak256 } from 'ethereum-cryptography/keccak.js'
import { sha256 } from 'ethereum-cryptography/sha256.js'

import { Bloom } from './bloom/index.js'
import { emitEVMProfile } from './emitEVMProfile.js'
Expand Down Expand Up @@ -774,10 +775,22 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise<RunTxResult> {
}

async function accumulateIVCLogs(vm: VM, number: bigint, logs: Log[]) {
// keep all declarations here for ease of movement and diff
const LOG_ADDRESS_STORAGE_SLOT = setLengthLeft(new Uint8Array([0]), 32)
const LOG_TOPICS_STORAGE_SLOT = setLengthLeft(new Uint8Array([1]), 32)
const LOG_ADDRESS_TOPICS_STORAGE_SLOT = setLengthLeft(new Uint8Array([2]), 32)

const commonSHA256 = vm.common.customCrypto.sha256 ?? sha256
const ivcContractAddress = new Address(
bigIntToAddressBytes(vm.common.param('ivcPredeployAddress')),
)

async function accumulateLog(key: Uint8Array, logRoot: Uint8Array) {
const prevRoot = setLengthLeft(await vm.stateManager.getStorage(ivcContractAddress, key), 32)
const newRoot = commonSHA256(concatBytes(logRoot, prevRoot))
await vm.stateManager.putStorage(ivcContractAddress, key, newRoot)
}

if ((await vm.stateManager.getAccount(ivcContractAddress)) === undefined) {
// store with nonce of 1 to prevent 158 cleanup
const ivcContract = new Account()
Expand All @@ -791,20 +804,27 @@ async function accumulateIVCLogs(vm: VM, number: bigint, logs: Log[]) {
topics: log[1],
data: log[2],
}

const logRoot = ssz.Log.hashTreeRoot(sszLog)

// Allow eth_getLogs proof via `address` filter
// abi.encode(log.address, LOG_ADDRESS_STORAGE_SLOT)
const paddedAddress = setLengthLeft(sszLog.address, 32)
const addressKey = keccak256(concatBytes(paddedAddress, LOG_ADDRESS_STORAGE_SLOT))
await accumulateLog(addressKey, logRoot)

for (const topic of sszLog.topics) {
// should be 32 bytes but 0 bytes in case value doesn't exist so just left pad
const prevTopicRoot = setLengthLeft(
await vm.stateManager.getStorage(ivcContractAddress, topic),
32,
// Allow eth_getLogs proof via `topics` filter
// abi.encode(topic, LOG_TOPICS_STORAGE_SLOT)
const topicKey = keccak256(concatBytes(topic, LOG_TOPICS_STORAGE_SLOT))
await accumulateLog(topicKey, logRoot)

// Allow eth_getLogs proof via combined `address` + `topics` filter
// abi.encode(log.address, topic)
const addressAndTopic = keccak256(concatBytes(paddedAddress, topic))
const addressAndTopicKey = keccak256(
concatBytes(addressAndTopic, LOG_ADDRESS_TOPICS_STORAGE_SLOT),
)
const newTopicRoot = ssz.IVCEntry.hashTreeRoot({
prevTopicRoot,
number,
logRoot,
})
await vm.stateManager.putStorage(ivcContractAddress, topic, newTopicRoot)
await accumulateLog(addressAndTopicKey, logRoot)
}
}
}
Expand Down

0 comments on commit 841db33

Please sign in to comment.