aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabio Berger <me@fabioberger.com>2018-08-14 04:40:46 +0800
committerGitHub <noreply@github.com>2018-08-14 04:40:46 +0800
commit7340338626ea11bccd44eef1da277196b78a6a7d (patch)
tree1a99424e80ece948af73995378a5737c8985dd0e
parent083319786fad31dfde16cb9e06e893bfeb23785d (diff)
parent9d3c287918389d07f884245bd1bc968955768b6f (diff)
downloaddexon-sol-tools-7340338626ea11bccd44eef1da277196b78a6a7d.tar
dexon-sol-tools-7340338626ea11bccd44eef1da277196b78a6a7d.tar.gz
dexon-sol-tools-7340338626ea11bccd44eef1da277196b78a6a7d.tar.bz2
dexon-sol-tools-7340338626ea11bccd44eef1da277196b78a6a7d.tar.lz
dexon-sol-tools-7340338626ea11bccd44eef1da277196b78a6a7d.tar.xz
dexon-sol-tools-7340338626ea11bccd44eef1da277196b78a6a7d.tar.zst
dexon-sol-tools-7340338626ea11bccd44eef1da277196b78a6a7d.zip
Merge pull request #938 from 0xProject/sol-cov-fixes
Sol cov fixes
-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-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/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
10 files changed, 162 insertions, 22 deletions
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-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/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,