aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--PULL_REQUEST_TEMPLATE.md10
-rw-r--r--packages/json-schemas/CHANGELOG.json4
-rw-r--r--packages/json-schemas/schemas/tx_data_schema.ts1
-rw-r--r--packages/json-schemas/test/schema_test.ts4
-rw-r--r--packages/sol-compiler/package.json1
-rw-r--r--packages/sol-compiler/src/cli.ts1
-rw-r--r--packages/sol-cov/CHANGELOG.json24
-rw-r--r--packages/sol-cov/src/artifact_adapters/truffle_artifact_adapter.ts58
-rw-r--r--packages/sol-cov/src/trace_collection_subprovider.ts16
-rw-r--r--packages/sol-resolver/CHANGELOG.json4
-rw-r--r--packages/sol-resolver/src/resolvers/npm_resolver.ts2
-rw-r--r--packages/subproviders/src/subproviders/signer.ts3
-rw-r--r--packages/web3-wrapper/CHANGELOG.json13
-rw-r--r--packages/web3-wrapper/src/index.ts13
-rw-r--r--packages/web3-wrapper/src/marshaller.ts48
15 files changed, 174 insertions, 28 deletions
diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md
index 63ef8db3d..9bacbcede 100644
--- a/PULL_REQUEST_TEMPLATE.md
+++ b/PULL_REQUEST_TEMPLATE.md
@@ -20,8 +20,8 @@
<!--- The following points should be used to indicate the progress of your PR. Put an `x` in all the boxes that apply right now, and come back over time and check them off as you make progress. If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
-* [ ] Prefixed the title of this PR with `[WIP]` if it is a work in progress.
-* [ ] Prefixed the title of this PR with bracketed package name(s) corresponding to the changed package(s). For example: `[sol-cov] Fixed bug`.
-* [ ] Added tests to cover my changes, or decided that tests would be too impractical.
-* [ ] Updated documentation, or decided that no doc change is needed.
-* [ ] Added new entries to the relevant CHANGELOG.jsons.
+* [ ] Prefix PR title with `[WIP]` if necessary.
+* [ ] Prefix PR title with bracketed package name(s) corresponding to the changed package(s). For example: `[sol-cov] Fixed bug`.
+* [ ] Add tests to cover changes as needed.
+* [ ] Update documentation as needed.
+* [ ] Add new entries to the relevant CHANGELOG.jsons.
diff --git a/packages/json-schemas/CHANGELOG.json b/packages/json-schemas/CHANGELOG.json
index 6017b2f2b..5af23dbe9 100644
--- a/packages/json-schemas/CHANGELOG.json
+++ b/packages/json-schemas/CHANGELOG.json
@@ -3,6 +3,10 @@
"version": "1.0.1-rc.4",
"changes": [
{
+ "note": "Allow for additional properties in txData schema",
+ "pr": 938
+ },
+ {
"note": "Change hexSchema to match `0x`",
"pr": 937
},
diff --git a/packages/json-schemas/schemas/tx_data_schema.ts b/packages/json-schemas/schemas/tx_data_schema.ts
index 41a5c708a..c57e18461 100644
--- a/packages/json-schemas/schemas/tx_data_schema.ts
+++ b/packages/json-schemas/schemas/tx_data_schema.ts
@@ -29,5 +29,4 @@ export const txDataSchema = {
},
required: ['from'],
type: 'object',
- additionalProperties: false,
};
diff --git a/packages/json-schemas/test/schema_test.ts b/packages/json-schemas/test/schema_test.ts
index 39cdec8a2..4e0f66ef5 100644
--- a/packages/json-schemas/test/schema_test.ts
+++ b/packages/json-schemas/test/schema_test.ts
@@ -849,10 +849,6 @@ describe('Schema', () => {
{
gas: new BigNumber(42),
},
- {
- from: NULL_ADDRESS,
- unknownProp: 'here',
- },
{},
[],
new BigNumber(1),
diff --git a/packages/sol-compiler/package.json b/packages/sol-compiler/package.json
index fcf9775c1..7eaff360f 100644
--- a/packages/sol-compiler/package.json
+++ b/packages/sol-compiler/package.json
@@ -92,6 +92,7 @@
"require-from-string": "^2.0.1",
"semver": "5.5.0",
"solc": "^0.4.23",
+ "source-map-support": "^0.5.0",
"web3-eth-abi": "^1.0.0-beta.24",
"yargs": "^10.0.3"
},
diff --git a/packages/sol-compiler/src/cli.ts b/packages/sol-compiler/src/cli.ts
index 8901c0a31..83dadc7ca 100644
--- a/packages/sol-compiler/src/cli.ts
+++ b/packages/sol-compiler/src/cli.ts
@@ -3,6 +3,7 @@
import { logUtils } from '@0xproject/utils';
import * as _ from 'lodash';
+import 'source-map-support/register';
import * as yargs from 'yargs';
import { Compiler } from './compiler';
diff --git a/packages/sol-cov/CHANGELOG.json b/packages/sol-cov/CHANGELOG.json
index 5a1fdc712..1a0fe43ca 100644
--- a/packages/sol-cov/CHANGELOG.json
+++ b/packages/sol-cov/CHANGELOG.json
@@ -1,5 +1,29 @@
[
{
+ "version": "2.0.0",
+ "changes": [
+ {
+ "note":
+ "Fix a bug when eth_call coverage was not computed because of silent schema validation failures",
+ "pr": 938
+ },
+ {
+ "note": "Make `TruffleArtifactAdapter` read the `truffle.js` config for `solc` settings",
+ "pr": 938
+ },
+ {
+ "note":
+ "Change the first param of `TruffleArtifactAdapter` to be the `projectRoot` instead of `sourcesDir`",
+ "pr": 938
+ },
+ {
+ "note":
+ "Throw a helpful error message if truffle artifacts were generated with a different solc version than the one passed in",
+ "pr": 938
+ }
+ ]
+ },
+ {
"version": "1.0.3",
"changes": [
{
diff --git a/packages/sol-cov/src/artifact_adapters/truffle_artifact_adapter.ts b/packages/sol-cov/src/artifact_adapters/truffle_artifact_adapter.ts
index 53b77aed5..2706435cc 100644
--- a/packages/sol-cov/src/artifact_adapters/truffle_artifact_adapter.ts
+++ b/packages/sol-cov/src/artifact_adapters/truffle_artifact_adapter.ts
@@ -1,25 +1,40 @@
import { Compiler, CompilerOptions } from '@0xproject/sol-compiler';
-import * as rimraf from 'rimraf';
+import * as fs from 'fs';
+import * as glob from 'glob';
+import * as path from 'path';
import { ContractData } from '../types';
import { AbstractArtifactAdapter } from './abstract_artifact_adapter';
import { SolCompilerArtifactAdapter } from './sol_compiler_artifact_adapter';
+const DEFAULT_TRUFFLE_ARTIFACTS_DIR = './build/contracts';
+
+interface TruffleConfig {
+ solc?: any;
+ contracts_build_directory?: string;
+}
+
export class TruffleArtifactAdapter extends AbstractArtifactAdapter {
private readonly _solcVersion: string;
- private readonly _sourcesPath: string;
- constructor(sourcesPath: string, solcVersion: string) {
+ private readonly _projectRoot: string;
+ constructor(projectRoot: string, solcVersion: string) {
super();
this._solcVersion = solcVersion;
- this._sourcesPath = sourcesPath;
+ this._projectRoot = projectRoot;
}
public async collectContractsDataAsync(): Promise<ContractData[]> {
const artifactsDir = '.0x-artifacts';
+ const contractsDir = path.join(this._projectRoot, 'contracts');
+ const truffleConfig = this._getTruffleConfig();
+ const solcConfig = truffleConfig.solc || {};
+ const truffleArtifactsDirectory = truffleConfig.contracts_build_directory || DEFAULT_TRUFFLE_ARTIFACTS_DIR;
+ this._assertSolidityVersionIsCorrect(truffleArtifactsDirectory);
const compilerOptions: CompilerOptions = {
- contractsDir: this._sourcesPath,
+ contractsDir,
artifactsDir,
compilerSettings: {
+ ...solcConfig,
outputSelection: {
['*']: {
['*']: ['abi', 'evm.bytecode.object', 'evm.deployedBytecode.object'],
@@ -31,9 +46,38 @@ export class TruffleArtifactAdapter extends AbstractArtifactAdapter {
};
const compiler = new Compiler(compilerOptions);
await compiler.compileAsync();
- const solCompilerArtifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, this._sourcesPath);
+ const solCompilerArtifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, contractsDir);
const contractsDataFrom0xArtifacts = await solCompilerArtifactAdapter.collectContractsDataAsync();
- rimraf.sync(artifactsDir);
return contractsDataFrom0xArtifacts;
}
+ private _getTruffleConfig(): TruffleConfig {
+ const truffleConfigFileShort = path.resolve(path.join(this._projectRoot, 'truffle.js'));
+ const truffleConfigFileLong = path.resolve(path.join(this._projectRoot, 'truffle-config.js'));
+ if (fs.existsSync(truffleConfigFileShort)) {
+ const truffleConfig = require(truffleConfigFileShort);
+ return truffleConfig;
+ } else if (fs.existsSync(truffleConfigFileLong)) {
+ const truffleConfig = require(truffleConfigFileLong);
+ return truffleConfig;
+ } else {
+ throw new Error(
+ `Neither ${truffleConfigFileShort} nor ${truffleConfigFileLong} exists. Make sure the project root is correct`,
+ );
+ }
+ }
+ private _assertSolidityVersionIsCorrect(truffleArtifactsDirectory: string): void {
+ const artifactsGlob = `${truffleArtifactsDirectory}/**/*.json`;
+ const artifactFileNames = glob.sync(artifactsGlob, { absolute: true });
+ for (const artifactFileName of artifactFileNames) {
+ const artifact = JSON.parse(fs.readFileSync(artifactFileName).toString());
+ const compilerVersion = artifact.compiler.version;
+ if (!compilerVersion.startsWith(this._solcVersion)) {
+ throw new Error(
+ `${artifact.contractName} was compiled with solidity ${compilerVersion} but specified version is ${
+ this._solcVersion
+ } making it impossible for sol-cov to process traces`,
+ );
+ }
+ }
+ }
}
diff --git a/packages/sol-cov/src/trace_collection_subprovider.ts b/packages/sol-cov/src/trace_collection_subprovider.ts
index b530b59db..b6486e6f7 100644
--- a/packages/sol-cov/src/trace_collection_subprovider.ts
+++ b/packages/sol-cov/src/trace_collection_subprovider.ts
@@ -1,7 +1,7 @@
import { BlockchainLifecycle } from '@0xproject/dev-utils';
import { Callback, ErrorCallback, NextCallback, Subprovider } from '@0xproject/subproviders';
-import { Web3Wrapper } from '@0xproject/web3-wrapper';
-import { CallData, JSONRPCRequestPayload, Provider, TxData } from 'ethereum-types';
+import { CallDataRPC, marshaller, Web3Wrapper } from '@0xproject/web3-wrapper';
+import { JSONRPCRequestPayload, Provider, TxData } from 'ethereum-types';
import * as _ from 'lodash';
import { Lock } from 'semaphore-async-await';
@@ -152,7 +152,7 @@ export abstract class TraceCollectionSubprovider extends Subprovider {
cb();
}
private async _onCallOrGasEstimateExecutedAsync(
- callData: Partial<CallData>,
+ callData: Partial<CallDataRPC>,
_err: Error | null,
_callResult: string,
cb: Callback,
@@ -160,22 +160,24 @@ export abstract class TraceCollectionSubprovider extends Subprovider {
await this._recordCallOrGasEstimateTraceAsync(callData);
cb();
}
- private async _recordCallOrGasEstimateTraceAsync(callData: Partial<CallData>): Promise<void> {
+ private async _recordCallOrGasEstimateTraceAsync(callData: Partial<CallDataRPC>): Promise<void> {
// We don't want other transactions to be exeucted during snashotting period, that's why we lock the
// transaction execution for all transactions except our fake ones.
await this._lock.acquire();
const blockchainLifecycle = new BlockchainLifecycle(this._web3Wrapper);
await blockchainLifecycle.startAsync();
- const fakeTxData: MaybeFakeTxData = {
- gas: BLOCK_GAS_LIMIT,
+ const fakeTxData = {
+ gas: BLOCK_GAS_LIMIT.toString(16), // tslint:disable-line:custom-no-magic-numbers
isFakeTransaction: true, // This transaction (and only it) is allowed to come through when the lock is locked
...callData,
from: callData.from || this._defaultFromAddress,
};
try {
- const txHash = await this._web3Wrapper.sendTransactionAsync(fakeTxData);
+ const txData = marshaller.unmarshalTxData(fakeTxData);
+ const txHash = await this._web3Wrapper.sendTransactionAsync(txData);
await this._web3Wrapper.awaitTransactionMinedAsync(txHash, 0);
} catch (err) {
+ // TODO(logvinov) Check that transaction failed and not some other exception
// Even if this transaction failed - we've already recorded it's trace.
_.noop();
}
diff --git a/packages/sol-resolver/CHANGELOG.json b/packages/sol-resolver/CHANGELOG.json
index abce53d09..dd9cb3f5d 100644
--- a/packages/sol-resolver/CHANGELOG.json
+++ b/packages/sol-resolver/CHANGELOG.json
@@ -5,6 +5,10 @@
{
"note": "Fix a bug where RelativeFSResolver would crash when trying to read a directory",
"pr": 909
+ },
+ {
+ "note": "Fix a bug where NpmResolver would crash when trying to read a directory",
+ "pr": 961
}
]
},
diff --git a/packages/sol-resolver/src/resolvers/npm_resolver.ts b/packages/sol-resolver/src/resolvers/npm_resolver.ts
index 9f8617145..a2df0dcad 100644
--- a/packages/sol-resolver/src/resolvers/npm_resolver.ts
+++ b/packages/sol-resolver/src/resolvers/npm_resolver.ts
@@ -19,7 +19,7 @@ export class NPMResolver extends Resolver {
const ROOT_PATH = '/';
while (currentPath !== ROOT_PATH) {
const lookupPath = path.join(currentPath, 'node_modules', packageName, pathWithinPackage);
- if (fs.existsSync(lookupPath)) {
+ if (fs.existsSync(lookupPath) && fs.lstatSync(lookupPath).isFile()) {
const fileContent = fs.readFileSync(lookupPath).toString();
return {
source: fileContent,
diff --git a/packages/subproviders/src/subproviders/signer.ts b/packages/subproviders/src/subproviders/signer.ts
index 8c4e89caf..d5fd86897 100644
--- a/packages/subproviders/src/subproviders/signer.ts
+++ b/packages/subproviders/src/subproviders/signer.ts
@@ -1,5 +1,4 @@
-import { Web3Wrapper } from '@0xproject/web3-wrapper';
-import { marshaller } from '@0xproject/web3-wrapper/lib/src/marshaller';
+import { marshaller, Web3Wrapper } from '@0xproject/web3-wrapper';
import { JSONRPCRequestPayload, Provider } from 'ethereum-types';
import { Callback, ErrorCallback } from '../types';
diff --git a/packages/web3-wrapper/CHANGELOG.json b/packages/web3-wrapper/CHANGELOG.json
index 7bf28dfa8..9224d89b0 100644
--- a/packages/web3-wrapper/CHANGELOG.json
+++ b/packages/web3-wrapper/CHANGELOG.json
@@ -1,5 +1,18 @@
[
{
+ "version": "1.2.0",
+ "changes": [
+ {
+ "note": "Export marshaller to convert between RPC and user-space data formats",
+ "pr": 938
+ },
+ {
+ "note": "Export RPC types",
+ "pr": 938
+ }
+ ]
+ },
+ {
"timestamp": 1532619515,
"version": "1.1.2",
"changes": [
diff --git a/packages/web3-wrapper/src/index.ts b/packages/web3-wrapper/src/index.ts
index 6787e0102..5d3d135e4 100644
--- a/packages/web3-wrapper/src/index.ts
+++ b/packages/web3-wrapper/src/index.ts
@@ -1,2 +1,13 @@
export { Web3Wrapper } from './web3_wrapper';
-export { Web3WrapperErrors, NodeType } from './types';
+export { marshaller } from './marshaller';
+export {
+ Web3WrapperErrors,
+ NodeType,
+ CallDataRPC,
+ CallTxDataBaseRPC,
+ AbstractBlockRPC,
+ BlockWithoutTransactionDataRPC,
+ BlockWithTransactionDataRPC,
+ TransactionRPC,
+ TxDataRPC,
+} from './types';
diff --git a/packages/web3-wrapper/src/marshaller.ts b/packages/web3-wrapper/src/marshaller.ts
index fed197822..572a322d6 100644
--- a/packages/web3-wrapper/src/marshaller.ts
+++ b/packages/web3-wrapper/src/marshaller.ts
@@ -25,7 +25,15 @@ import {
TxDataRPC,
} from './types';
+/**
+ * Utils to convert ethereum structures from user-space format to RPC format. (marshall/unmarshall)
+ */
export const marshaller = {
+ /**
+ * Unmarshall block without transaction data
+ * @param blockWithHexValues block to unmarshall
+ * @return unmarshalled block without transaction data
+ */
unmarshalIntoBlockWithoutTransactionData(
blockWithHexValues: BlockWithoutTransactionDataRPC,
): BlockWithoutTransactionData {
@@ -41,6 +49,11 @@ export const marshaller = {
};
return block;
},
+ /**
+ * Unmarshall block with transaction data
+ * @param blockWithHexValues block to unmarshall
+ * @return unmarshalled block with transaction data
+ */
unmarshalIntoBlockWithTransactionData(blockWithHexValues: BlockWithTransactionDataRPC): BlockWithTransactionData {
const block = {
...blockWithHexValues,
@@ -59,6 +72,11 @@ export const marshaller = {
});
return block;
},
+ /**
+ * Unmarshall transaction
+ * @param txRpc transaction to unmarshall
+ * @return unmarshalled transaction
+ */
unmarshalTransaction(txRpc: TransactionRPC): Transaction {
const tx = {
...txRpc,
@@ -73,6 +91,11 @@ export const marshaller = {
};
return tx;
},
+ /**
+ * Unmarshall transaction data
+ * @param txDataRpc transaction data to unmarshall
+ * @return unmarshalled transaction data
+ */
unmarshalTxData(txDataRpc: TxDataRPC): TxData {
if (_.isUndefined(txDataRpc.from)) {
throw new Error(`txData must include valid 'from' value.`);
@@ -86,6 +109,11 @@ export const marshaller = {
};
return txData;
},
+ /**
+ * Marshall transaction data
+ * @param txData transaction data to marshall
+ * @return marshalled transaction data
+ */
marshalTxData(txData: Partial<TxData>): Partial<TxDataRPC> {
if (_.isUndefined(txData.from)) {
throw new Error(`txData must include valid 'from' value.`);
@@ -107,6 +135,11 @@ export const marshaller = {
});
return txDataRPC;
},
+ /**
+ * Marshall call data
+ * @param callData call data to marshall
+ * @return marshalled call data
+ */
marshalCallData(callData: Partial<CallData>): Partial<CallDataRPC> {
const callTxDataBase = {
...callData,
@@ -119,12 +152,22 @@ export const marshaller = {
};
return callDataRPC;
},
+ /**
+ * Marshall address
+ * @param address address to marshall
+ * @return marshalled address
+ */
marshalAddress(address: string): string {
if (addressUtils.isAddress(address)) {
return ethUtil.addHexPrefix(address);
}
throw new Error(`Invalid address encountered: ${address}`);
},
+ /**
+ * Marshall block param
+ * @param blockParam block param to marshall
+ * @return marshalled block param
+ */
marshalBlockParam(blockParam: BlockParam | string | number | undefined): string | undefined {
if (_.isUndefined(blockParam)) {
return BlockParamLiteral.Latest;
@@ -132,6 +175,11 @@ export const marshaller = {
const encodedBlockParam = _.isNumber(blockParam) ? utils.numberToHex(blockParam) : blockParam;
return encodedBlockParam;
},
+ /**
+ * Unmarshall log
+ * @param rawLog log to unmarshall
+ * @return unmarshalled log
+ */
unmarshalLog(rawLog: RawLogEntry): LogEntry {
const formattedLog = {
...rawLog,