aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmir Bandeali <abandeali1@gmail.com>2019-01-24 02:49:10 +0800
committerAmir Bandeali <abandeali1@gmail.com>2019-01-24 02:49:10 +0800
commit09cb3b7d5060bc8821cdbcab9639bb0a3b27d651 (patch)
tree63821d6126f9e8ca9ea866fa3ba36169d1b0f0e2
parent8566bb551b2399f5b966b2ac81c89ba96f272aaf (diff)
parentef928aff31f09b368307548bd5a512b4212a0c95 (diff)
downloaddexon-0x-contracts-09cb3b7d5060bc8821cdbcab9639bb0a3b27d651.tar
dexon-0x-contracts-09cb3b7d5060bc8821cdbcab9639bb0a3b27d651.tar.gz
dexon-0x-contracts-09cb3b7d5060bc8821cdbcab9639bb0a3b27d651.tar.bz2
dexon-0x-contracts-09cb3b7d5060bc8821cdbcab9639bb0a3b27d651.tar.lz
dexon-0x-contracts-09cb3b7d5060bc8821cdbcab9639bb0a3b27d651.tar.xz
dexon-0x-contracts-09cb3b7d5060bc8821cdbcab9639bb0a3b27d651.tar.zst
dexon-0x-contracts-09cb3b7d5060bc8821cdbcab9639bb0a3b27d651.zip
Merge branch 'development' into feat/contracts/split-packages
-rw-r--r--contracts/utils/CHANGELOG.json9
-rw-r--r--packages/devnet/docker-compose.yml8
-rwxr-xr-xpackages/devnet/run.sh1
-rw-r--r--packages/sol-coverage/src/coverage_subprovider.ts4
-rw-r--r--packages/sol-profiler/CHANGELOG.json9
-rw-r--r--packages/sol-tracing-utils/CHANGELOG.json21
-rw-r--r--packages/sol-tracing-utils/package.json1
-rw-r--r--packages/sol-tracing-utils/src/artifact_adapters/sol_compiler_artifact_adapter.ts19
-rw-r--r--packages/sol-tracing-utils/src/collect_coverage_entries.ts14
-rw-r--r--packages/sol-tracing-utils/src/utils.ts34
-rw-r--r--packages/sol-tracing-utils/test/collect_coverage_entries_test.ts3
-rw-r--r--yarn.lock4
12 files changed, 98 insertions, 29 deletions
diff --git a/contracts/utils/CHANGELOG.json b/contracts/utils/CHANGELOG.json
index e33c3c7fc..94434b803 100644
--- a/contracts/utils/CHANGELOG.json
+++ b/contracts/utils/CHANGELOG.json
@@ -17,6 +17,15 @@
]
},
{
+ "version": "2.0.1",
+ "changes": [
+ {
+ "note": "Fix imports in `TestConstants` and `TestLibBytes` to be relative. This way they show up correctly in coverage reports",
+ "pr": 1535
+ }
+ ]
+ },
+ {
"version": "2.0.0",
"changes": [
{
diff --git a/packages/devnet/docker-compose.yml b/packages/devnet/docker-compose.yml
new file mode 100644
index 000000000..1c1e7ca75
--- /dev/null
+++ b/packages/devnet/docker-compose.yml
@@ -0,0 +1,8 @@
+version: '3'
+services:
+ devnet:
+ image: 0x-devnet:latest
+ build:
+ context: .
+ ports:
+ - 8501:8501
diff --git a/packages/devnet/run.sh b/packages/devnet/run.sh
index dea243396..6000813f0 100755
--- a/packages/devnet/run.sh
+++ b/packages/devnet/run.sh
@@ -15,6 +15,7 @@ mkdir -p /var/log
--rpc \
--rpcaddr '0.0.0.0' \
--rpcport 8501 \
+ --rpcvhosts '*' \
--rpcapi 'personal,db,eth,net,web3,txpool,miner,debug' \
--networkid 50 \
--gasprice '2000000000' \
diff --git a/packages/sol-coverage/src/coverage_subprovider.ts b/packages/sol-coverage/src/coverage_subprovider.ts
index d03963ed6..2d92b25ca 100644
--- a/packages/sol-coverage/src/coverage_subprovider.ts
+++ b/packages/sol-coverage/src/coverage_subprovider.ts
@@ -50,6 +50,8 @@ export class CoverageSubprovider extends TraceInfoSubprovider {
}
}
+const IGNORE_REGEXP = /\/\*\s*solcov\s+ignore\s+next\s*\*\/\s*/gm;
+
/**
* Computed partial coverage for a single file & subtrace.
* @param contractData Contract metadata (source, srcMap, bytecode)
@@ -65,7 +67,7 @@ export const coverageHandler: SingleFileSubtraceHandler = (
fileIndex: number,
): Coverage => {
const absoluteFileName = contractData.sources[fileIndex];
- const coverageEntriesDescription = collectCoverageEntries(contractData.sourceCodes[fileIndex]);
+ const coverageEntriesDescription = collectCoverageEntries(contractData.sourceCodes[fileIndex], IGNORE_REGEXP);
// if the source wasn't provided for the fileIndex, we can't cover the file
if (_.isUndefined(coverageEntriesDescription)) {
diff --git a/packages/sol-profiler/CHANGELOG.json b/packages/sol-profiler/CHANGELOG.json
index 550ca2feb..fc928b516 100644
--- a/packages/sol-profiler/CHANGELOG.json
+++ b/packages/sol-profiler/CHANGELOG.json
@@ -1,5 +1,14 @@
[
{
+ "version": "2.0.1",
+ "changes": [
+ {
+ "note": "Fix a bug when some parts of the profiling report were missing because of the coverage ignore lines",
+ "pr": 1535
+ }
+ ]
+ },
+ {
"version": "2.0.0",
"changes": [
{
diff --git a/packages/sol-tracing-utils/CHANGELOG.json b/packages/sol-tracing-utils/CHANGELOG.json
index ef96dc69b..16a12ca63 100644
--- a/packages/sol-tracing-utils/CHANGELOG.json
+++ b/packages/sol-tracing-utils/CHANGELOG.json
@@ -1,5 +1,26 @@
[
{
+ "version": "6.0.0",
+ "changes": [
+ {
+ "note": "`SolCompilerArtifactAdapter` now uses `SolResolver` under the hood which allows to resolve `NPM` dependencies properly",
+ "pr": 1535
+ },
+ {
+ "note": "Cache the `utils.getContractDataIfExists` leading to faster execution",
+ "pr": 1535
+ },
+ {
+ "note": "`SolCompilerArtifactAdapter` now doesn't return the `ContractData` for interfaces",
+ "pr": 1535
+ },
+ {
+ "note": "Print resasonable error message on bytecode collision",
+ "pr": 1535
+ }
+ ]
+ },
+ {
"version": "5.0.0",
"changes": [
{
diff --git a/packages/sol-tracing-utils/package.json b/packages/sol-tracing-utils/package.json
index cabb752d2..4b0fff222 100644
--- a/packages/sol-tracing-utils/package.json
+++ b/packages/sol-tracing-utils/package.json
@@ -44,6 +44,7 @@
"dependencies": {
"@0x/dev-utils": "^1.0.24",
"@0x/sol-compiler": "^2.0.2",
+ "@0x/sol-resolver": "^1.2.3",
"@0x/subproviders": "^2.1.11",
"@0x/typescript-typings": "^3.0.8",
"@0x/utils": "^3.0.1",
diff --git a/packages/sol-tracing-utils/src/artifact_adapters/sol_compiler_artifact_adapter.ts b/packages/sol-tracing-utils/src/artifact_adapters/sol_compiler_artifact_adapter.ts
index d52587f2c..bfd3a504a 100644
--- a/packages/sol-tracing-utils/src/artifact_adapters/sol_compiler_artifact_adapter.ts
+++ b/packages/sol-tracing-utils/src/artifact_adapters/sol_compiler_artifact_adapter.ts
@@ -1,3 +1,4 @@
+import { FallthroughResolver, FSResolver, NPMResolver, RelativeFSResolver, URLResolver } from '@0x/sol-resolver';
import { logUtils } from '@0x/utils';
import { CompilerOptions, ContractArtifact } from 'ethereum-types';
import * as fs from 'fs';
@@ -14,6 +15,7 @@ const CONFIG_FILE = 'compiler.json';
export class SolCompilerArtifactAdapter extends AbstractArtifactAdapter {
private readonly _artifactsPath: string;
private readonly _sourcesPath: string;
+ private readonly _resolver: FallthroughResolver;
/**
* Instantiates a SolCompilerArtifactAdapter
* @param artifactsPath Path to your artifacts directory
@@ -32,6 +34,12 @@ export class SolCompilerArtifactAdapter extends AbstractArtifactAdapter {
throw new Error(`contractsDir not found in ${CONFIG_FILE}`);
}
this._sourcesPath = (sourcesPath || config.contractsDir) as string;
+ this._resolver = new FallthroughResolver();
+ this._resolver.appendResolver(new URLResolver());
+ const packagePath = path.resolve('');
+ this._resolver.appendResolver(new NPMResolver(packagePath));
+ this._resolver.appendResolver(new RelativeFSResolver(this._sourcesPath));
+ this._resolver.appendResolver(new FSResolver());
}
public async collectContractsDataAsync(): Promise<ContractData[]> {
const artifactsGlob = `${this._artifactsPath}/**/*.json`;
@@ -46,10 +54,9 @@ export class SolCompilerArtifactAdapter extends AbstractArtifactAdapter {
const sources: Sources = {};
const sourceCodes: SourceCodes = {};
_.map(artifact.sources, (value: { id: number }, relativeFilePath: string) => {
- const filePath = path.resolve(this._sourcesPath, relativeFilePath);
- const fileContent = fs.readFileSync(filePath).toString();
- sources[value.id] = filePath;
- sourceCodes[value.id] = fileContent;
+ const source = this._resolver.resolve(relativeFilePath);
+ sources[value.id] = source.absolutePath;
+ sourceCodes[value.id] = source.source;
});
const contractData = {
sourceCodes,
@@ -59,6 +66,10 @@ export class SolCompilerArtifactAdapter extends AbstractArtifactAdapter {
runtimeBytecode: artifact.compilerOutput.evm.deployedBytecode.object,
sourceMapRuntime: artifact.compilerOutput.evm.deployedBytecode.sourceMap,
};
+ const isInterfaceContract = contractData.bytecode === '0x' && contractData.runtimeBytecode === '0x';
+ if (isInterfaceContract) {
+ continue;
+ }
contractsData.push(contractData);
}
return contractsData;
diff --git a/packages/sol-tracing-utils/src/collect_coverage_entries.ts b/packages/sol-tracing-utils/src/collect_coverage_entries.ts
index 9e3591d74..d5045b106 100644
--- a/packages/sol-tracing-utils/src/collect_coverage_entries.ts
+++ b/packages/sol-tracing-utils/src/collect_coverage_entries.ts
@@ -5,18 +5,18 @@ import * as parser from 'solidity-parser-antlr';
import { ASTVisitor, CoverageEntriesDescription } from './ast_visitor';
import { getOffsetToLocation } from './source_maps';
-const IGNORE_RE = /\/\*\s*solcov\s+ignore\s+next\s*\*\/\s*/gm;
-
// Parsing source code for each transaction/code is slow and therefore we cache it
const sourceHashToCoverageEntries: { [sourceHash: string]: CoverageEntriesDescription } = {};
-export const collectCoverageEntries = (contractSource: string) => {
+export const collectCoverageEntries = (contractSource: string, ignoreRegexp?: RegExp) => {
const sourceHash = ethUtil.sha3(contractSource).toString('hex');
if (_.isUndefined(sourceHashToCoverageEntries[sourceHash]) && !_.isUndefined(contractSource)) {
const ast = parser.parse(contractSource, { range: true });
const offsetToLocation = getOffsetToLocation(contractSource);
- const ignoreRangesBegingingAt = gatherRangesToIgnore(contractSource);
- const visitor = new ASTVisitor(offsetToLocation, ignoreRangesBegingingAt);
+ const ignoreRangesBeginningAt = _.isUndefined(ignoreRegexp)
+ ? []
+ : gatherRangesToIgnore(contractSource, ignoreRegexp);
+ const visitor = new ASTVisitor(offsetToLocation, ignoreRangesBeginningAt);
parser.visit(ast, visitor);
sourceHashToCoverageEntries[sourceHash] = visitor.getCollectedCoverageEntries();
}
@@ -25,12 +25,12 @@ export const collectCoverageEntries = (contractSource: string) => {
};
// Gather the start index of all code blocks preceeded by "/* solcov ignore next */"
-function gatherRangesToIgnore(contractSource: string): number[] {
+function gatherRangesToIgnore(contractSource: string, ignoreRegexp: RegExp): number[] {
const ignoreRangesStart = [];
let match;
do {
- match = IGNORE_RE.exec(contractSource);
+ match = ignoreRegexp.exec(contractSource);
if (match) {
const matchLen = match[0].length;
ignoreRangesStart.push(match.index + matchLen);
diff --git a/packages/sol-tracing-utils/src/utils.ts b/packages/sol-tracing-utils/src/utils.ts
index 89c158ee7..7dc1844a5 100644
--- a/packages/sol-tracing-utils/src/utils.ts
+++ b/packages/sol-tracing-utils/src/utils.ts
@@ -1,15 +1,14 @@
-import { addressUtils, BigNumber } from '@0x/utils';
+import { addressUtils, BigNumber, logUtils } from '@0x/utils';
import { OpCode, StructLog } from 'ethereum-types';
import { addHexPrefix } from 'ethereumjs-util';
import * as _ from 'lodash';
import { ContractData, LineColumn, SingleFileSourceRange } from './types';
-// This is the minimum length of valid contract bytecode. The Solidity compiler
-// metadata is 86 bytes. If you add the '0x' prefix, we get 88.
-const MIN_CONTRACT_BYTECODE_LENGTH = 88;
const STATICCALL_GAS_COST = 40;
+const bytecodeToContractDataIfExists: { [bytecode: string]: ContractData | undefined } = {};
+
export const utils = {
compareLineColumn(lhs: LineColumn, rhs: LineColumn): number {
return lhs.line !== rhs.line ? lhs.line - rhs.line : lhs.column - rhs.column;
@@ -47,22 +46,29 @@ export const utils = {
if (!bytecode.startsWith('0x')) {
throw new Error(`0x hex prefix missing: ${bytecode}`);
}
- const contractData = _.find(contractsData, contractDataCandidate => {
+ // HACK(leo): We want to cache the values that are possibly undefined.
+ // That's why we can't check for undefined as we usually do, but need to use `hasOwnProperty`.
+ if (bytecodeToContractDataIfExists.hasOwnProperty(bytecode)) {
+ return bytecodeToContractDataIfExists[bytecode];
+ }
+ const contractDataCandidates = _.filter(contractsData, contractDataCandidate => {
const bytecodeRegex = utils.bytecodeToBytecodeRegex(contractDataCandidate.bytecode);
- // If the bytecode is less than the minimum length, we are probably
- // dealing with an interface. This isn't what we're looking for.
- if (bytecodeRegex.length < MIN_CONTRACT_BYTECODE_LENGTH) {
- return false;
- }
const runtimeBytecodeRegex = utils.bytecodeToBytecodeRegex(contractDataCandidate.runtimeBytecode);
- if (runtimeBytecodeRegex.length < MIN_CONTRACT_BYTECODE_LENGTH) {
- return false;
- }
// We use that function to find by bytecode or runtimeBytecode. Those are quasi-random strings so
// collisions are practically impossible and it allows us to reuse that code
return !_.isNull(bytecode.match(bytecodeRegex)) || !_.isNull(bytecode.match(runtimeBytecodeRegex));
});
- return contractData;
+ if (contractDataCandidates.length > 1) {
+ const candidates = contractDataCandidates.map(
+ contractDataCandidate => _.values(contractDataCandidate.sources)[0],
+ );
+ const errMsg =
+ "We've found more than one artifact that contains the exact same bytecode and therefore are unable to detect which contract was executed. " +
+ "We'll be assigning all traces to the first one.";
+ logUtils.warn(errMsg);
+ logUtils.warn(candidates);
+ }
+ return (bytecodeToContractDataIfExists[bytecode] = contractDataCandidates[0]);
},
isCallLike(op: OpCode): boolean {
return _.includes([OpCode.CallCode, OpCode.StaticCall, OpCode.Call, OpCode.DelegateCall], op);
diff --git a/packages/sol-tracing-utils/test/collect_coverage_entries_test.ts b/packages/sol-tracing-utils/test/collect_coverage_entries_test.ts
index 7832ec316..d3ca8930c 100644
--- a/packages/sol-tracing-utils/test/collect_coverage_entries_test.ts
+++ b/packages/sol-tracing-utils/test/collect_coverage_entries_test.ts
@@ -130,7 +130,8 @@ describe('Collect coverage entries', () => {
solcovIgnoreContractBaseName,
);
const solcovIgnoreContract = fs.readFileSync(solcovIgnoreContractFileName).toString();
- const coverageEntries = collectCoverageEntries(solcovIgnoreContract);
+ const IGNORE_REGEXP = /\/\*\s*solcov\s+ignore\s+next\s*\*\/\s*/gm;
+ const coverageEntries = collectCoverageEntries(solcovIgnoreContract, IGNORE_REGEXP);
const fnIds = _.keys(coverageEntries.fnMap);
expect(fnIds.length).to.be.equal(1);
diff --git a/yarn.lock b/yarn.lock
index 621bc69da..543ec9d5c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -13462,8 +13462,8 @@ react-highlight@0xproject/react-highlight#fix/react-version:
dependencies:
highlight.js "^9.11.0"
highlightjs-solidity "^1.0.5"
- react "^16.4.2"
- react-dom "^16.4.2"
+ react "^16.5.2"
+ react-dom "^16.5.2"
react-hot-loader@^4.3.3:
version "4.3.4"