Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: dedup pc by codehash for unique pc metric #485

Merged
merged 3 commits into from
Jan 9, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions fuzzing/coverage/coverage_maps.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ package coverage
import (
"golang.org/x/exp/slices"

"sync"

compilationTypes "github.com/crytic/medusa/compilation/types"
"github.com/crytic/medusa/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"sync"
)

// CoverageMaps represents a data structure used to identify instruction execution coverage of various smart contracts
Expand Down Expand Up @@ -249,6 +250,10 @@ func (cm *CoverageMaps) UniquePCs() uint64 {
uniquePCs := uint64(0)
// Iterate across each contract deployment
for _, mapsByAddress := range cm.maps {
// Consider the coverage of all of the different deployments of this codehash as a set
// And mark a PC as hit if any of the instances has a hit for it
uniquePCsForHash := make(map[int]struct{})

for _, contractCoverageMap := range mapsByAddress {
// TODO: Note we are not checking for nil dereference here because we are guaranteed that the successful
// coverage and reverted coverage arrays have been instantiated if we are iterating over it
Expand All @@ -259,18 +264,20 @@ func (cm *CoverageMaps) UniquePCs() uint64 {
for i, hits := range contractCoverageMap.successfulCoverage.executedFlags {
// If we hit the PC at least once, we have a unique PC hit
if hits != 0 {
uniquePCs++
uniquePCsForHash[i] = struct{}{}

// Do not count both success and revert
continue
}

// This is only executed if the PC was not executed successfully
if contractCoverageMap.revertedCoverage.executedFlags != nil && contractCoverageMap.revertedCoverage.executedFlags[i] != 0 {
uniquePCs++
uniquePCsForHash[i] = struct{}{}
}
}
}

uniquePCs += uint64(len(uniquePCsForHash))
}
return uniquePCs
}
Expand Down
Loading