Skip to content

Commit

Permalink
WIP cache codehash
Browse files Browse the repository at this point in the history
  • Loading branch information
samalws-tob committed Sep 4, 2024
1 parent 3a9b0fa commit c4d807a
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 5 deletions.
10 changes: 8 additions & 2 deletions fuzzing/coverage/coverage_maps.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ type CoverageMaps struct {
// maps represents a structure used to track every ContractCoverageMap by a given deployed address/lookup hash.
maps map[common.Hash]map[common.Address]*ContractCoverageMap

// TODO comment this
// The assumption here is that geth codehash matches if and only if codehash matches
cachedGethCodeHash common.Hash

// cachedCodeAddress represents the last code address which coverage was updated for. This is used to prevent an
// expensive lookup in maps. If cachedCodeHash does not match the current code address for which we are updating
// coverage for, it, along with other cache variables are updated.
Expand Down Expand Up @@ -46,6 +50,7 @@ func (cm *CoverageMaps) Reset() {
cm.maps = make(map[common.Hash]map[common.Address]*ContractCoverageMap)
cm.cachedCodeAddress = common.Address{}
cm.cachedCodeHash = common.Hash{}
cm.cachedGethCodeHash = common.Hash{}
cm.cachedMap = nil
}

Expand Down Expand Up @@ -170,7 +175,7 @@ func (cm *CoverageMaps) Update(coverageMaps *CoverageMaps) (bool, bool, error) {
}

// UpdateAt updates the hit count of a given program counter location within code coverage data.
func (cm *CoverageMaps) UpdateAt(codeAddress common.Address, codeLookupHash common.Hash, codeSize int, pc uint64) (bool, error) {
func (cm *CoverageMaps) UpdateAt(codeAddress common.Address, gethCodeHash common.Hash, codeLookupHash common.Hash, codeSize int, pc uint64) (bool, error) {
// If the code size is zero, do nothing
if codeSize == 0 {
return false, nil
Expand All @@ -185,7 +190,7 @@ func (cm *CoverageMaps) UpdateAt(codeAddress common.Address, codeLookupHash comm
)

// Try to obtain a coverage map from our cache
if cm.cachedMap != nil && cm.cachedCodeAddress == codeAddress && cm.cachedCodeHash == codeLookupHash {
if cm.cachedMap != nil && cm.cachedCodeAddress == codeAddress && cm.cachedCodeHash == codeLookupHash && cm.cachedGethCodeHash == gethCodeHash {
coverageMap = cm.cachedMap
} else {
// If a coverage map lookup for this code hash doesn't exist, create the mapping.
Expand All @@ -207,6 +212,7 @@ func (cm *CoverageMaps) UpdateAt(codeAddress common.Address, codeLookupHash comm
// Set our cached variables for faster coverage setting next time this method is called.
cm.cachedMap = coverageMap
cm.cachedCodeHash = codeLookupHash
cm.cachedGethCodeHash = gethCodeHash
cm.cachedCodeAddress = codeAddress
}

Expand Down
12 changes: 9 additions & 3 deletions fuzzing/coverage/coverage_tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,18 +157,24 @@ func (t *CoverageTracer) OnOpcode(pc uint64, op byte, gas, cost uint64, scope tr
address := scope.Address()
// We can cast OpContext to ScopeContext because that is the type passed to OnOpcode.
scopeContext := scope.(*vm.ScopeContext)
gethCodeHash := scopeContext.Contract.CodeHash
code := scopeContext.Contract.Code
codeSize := len(code)
if codeSize > 0 {

// Obtain our contract coverage map lookup hash.
if callFrameState.lookupHash == nil {
lookupHash := getContractCoverageMapHash(code, callFrameState.create)
callFrameState.lookupHash = &lookupHash
if callFrameState.pendingCoverageMap.cachedGethCodeHash == gethCodeHash {
lookupHash := callFrameState.pendingCoverageMap.cachedCodeHash
callFrameState.lookupHash = &lookupHash
} else {
lookupHash := getContractCoverageMapHash(code, callFrameState.create)
callFrameState.lookupHash = &lookupHash
}
}

// Record coverage for this location in our map.
_, coverageUpdateErr := callFrameState.pendingCoverageMap.UpdateAt(address, *callFrameState.lookupHash, codeSize, pc)
_, coverageUpdateErr := callFrameState.pendingCoverageMap.UpdateAt(address, gethCodeHash, *callFrameState.lookupHash, codeSize, pc)
if coverageUpdateErr != nil {
logging.GlobalLogger.Panic("Coverage tracer failed to update coverage map while tracing state", coverageUpdateErr)
}
Expand Down

0 comments on commit c4d807a

Please sign in to comment.