From 577156fe5f63e581b101682d13b7e70e7a9336e5 Mon Sep 17 00:00:00 2001 From: Alex Browne Date: Mon, 21 May 2018 13:56:32 -0700 Subject: Use Geth for contract tests --- packages/web3-wrapper/src/web3_wrapper.ts | 37 ++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) (limited to 'packages/web3-wrapper/src') diff --git a/packages/web3-wrapper/src/web3_wrapper.ts b/packages/web3-wrapper/src/web3_wrapper.ts index 3de152df1..d922c80cd 100644 --- a/packages/web3-wrapper/src/web3_wrapper.ts +++ b/packages/web3-wrapper/src/web3_wrapper.ts @@ -281,7 +281,6 @@ export class Web3Wrapper { }; const payload = { jsonrpc: '2.0', - id: this._jsonRpcRequestId++, method: 'eth_getLogs', params: [serializedFilter], }; @@ -403,8 +402,44 @@ export class Web3Wrapper { } return receipt; } + /** + * Start the CPU mining process with the given number of threads and + * generate a new DAG if need be. + * @param threads The number of threads to mine on. + */ + public async minerStartAsync(threads: number = 1): Promise { + await this._sendRawPayloadAsync({ + method: 'miner_start', + params: [threads], + }); + } + /** + * Stop the CPU mining process. + * @param threads The number of threads to mine on. + */ + public async minerStopAsync(): Promise { + await this._sendRawPayloadAsync({ method: 'miner_stop', params: [] }); + } + /** + * Returns true if client is actively mining new blocks. + * @returns A boolean indicating whether the node is currently mining. + */ + public async isMiningAsync(): Promise { + const isMining = await promisify(this._web3.eth.getMining)(); + return isMining; + } + /** + * Sets the current head of the local chain by block number. Note, this is a + * destructive action and may severely damage your chain. Use with extreme + * caution. + * @param blockNumber The block number to reset to. + */ + public async setHeadAsync(blockNumber: number): Promise { + await this._sendRawPayloadAsync({ method: 'debug_setHead', params: [this._web3.toHex(blockNumber)] }); + } private async _sendRawPayloadAsync(payload: Partial): Promise { const sendAsync = this._web3.currentProvider.sendAsync.bind(this._web3.currentProvider); + payload.id = this._jsonRpcRequestId++; const response = await promisify(sendAsync)(payload); const result = response.result; return result; -- cgit v1.2.3 From 00bf957b53c22f3ccdd6c2e7ad75f0c9e15caa38 Mon Sep 17 00:00:00 2001 From: Alex Browne Date: Wed, 23 May 2018 18:13:18 -0700 Subject: Add more transactions to Geth on init. Skip tests that are failing. --- packages/web3-wrapper/src/web3_wrapper.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'packages/web3-wrapper/src') diff --git a/packages/web3-wrapper/src/web3_wrapper.ts b/packages/web3-wrapper/src/web3_wrapper.ts index d922c80cd..b9b0bdbb2 100644 --- a/packages/web3-wrapper/src/web3_wrapper.ts +++ b/packages/web3-wrapper/src/web3_wrapper.ts @@ -258,7 +258,8 @@ export class Web3Wrapper { * @param timeDelta Amount of time to add in seconds */ public async increaseTimeAsync(timeDelta: number): Promise { - await this._sendRawPayloadAsync({ method: 'evm_increaseTime', params: [timeDelta] }); + // TODO(albrow): Detect Geth vs. Ganache and use appropriate endpoint. + await this._sendRawPayloadAsync({ method: 'debug_increaseTime', params: [timeDelta] }); } /** * Retrieve smart contract logs for a given filter -- cgit v1.2.3 From 5900899c0195a851c8d20ca0d4ad85dbbf4c100f Mon Sep 17 00:00:00 2001 From: Alex Browne Date: Mon, 4 Jun 2018 17:47:18 -0700 Subject: Add support for TEST_PROVIDER env var --- packages/web3-wrapper/src/web3_wrapper.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'packages/web3-wrapper/src') diff --git a/packages/web3-wrapper/src/web3_wrapper.ts b/packages/web3-wrapper/src/web3_wrapper.ts index b9b0bdbb2..ace6a2d61 100644 --- a/packages/web3-wrapper/src/web3_wrapper.ts +++ b/packages/web3-wrapper/src/web3_wrapper.ts @@ -257,9 +257,9 @@ export class Web3Wrapper { * Increase the next blocks timestamp on TestRPC/Ganache local node * @param timeDelta Amount of time to add in seconds */ - public async increaseTimeAsync(timeDelta: number): Promise { + public async increaseTimeAsync(timeDelta: number): Promise { // TODO(albrow): Detect Geth vs. Ganache and use appropriate endpoint. - await this._sendRawPayloadAsync({ method: 'debug_increaseTime', params: [timeDelta] }); + return this._sendRawPayloadAsync({ method: 'debug_increaseTime', params: [timeDelta] }); } /** * Retrieve smart contract logs for a given filter -- cgit v1.2.3 From bca62c813d2e821c56968916615861366402435b Mon Sep 17 00:00:00 2001 From: Alex Browne Date: Mon, 4 Jun 2018 18:10:42 -0700 Subject: Throw in web3-wrapper when rawCallResult is '0x' --- packages/web3-wrapper/src/web3_wrapper.ts | 3 +++ 1 file changed, 3 insertions(+) (limited to 'packages/web3-wrapper/src') diff --git a/packages/web3-wrapper/src/web3_wrapper.ts b/packages/web3-wrapper/src/web3_wrapper.ts index ace6a2d61..ed2d0a119 100644 --- a/packages/web3-wrapper/src/web3_wrapper.ts +++ b/packages/web3-wrapper/src/web3_wrapper.ts @@ -315,6 +315,9 @@ export class Web3Wrapper { */ public async callAsync(callData: CallData, defaultBlock?: BlockParam): Promise { const rawCallResult = await promisify(this._web3.eth.call)(callData, defaultBlock); + if (rawCallResult === '0x') { + throw new Error('Contract call failed (returned null)'); + } return rawCallResult; } /** -- cgit v1.2.3 From 63caddea62453863de84a4b53e14fe3e61d3008f Mon Sep 17 00:00:00 2001 From: Alex Browne Date: Tue, 5 Jun 2018 15:12:09 -0700 Subject: Small fixes and cleanup --- packages/web3-wrapper/src/web3_wrapper.ts | 26 -------------------------- 1 file changed, 26 deletions(-) (limited to 'packages/web3-wrapper/src') diff --git a/packages/web3-wrapper/src/web3_wrapper.ts b/packages/web3-wrapper/src/web3_wrapper.ts index ed2d0a119..a19253449 100644 --- a/packages/web3-wrapper/src/web3_wrapper.ts +++ b/packages/web3-wrapper/src/web3_wrapper.ts @@ -406,32 +406,6 @@ export class Web3Wrapper { } return receipt; } - /** - * Start the CPU mining process with the given number of threads and - * generate a new DAG if need be. - * @param threads The number of threads to mine on. - */ - public async minerStartAsync(threads: number = 1): Promise { - await this._sendRawPayloadAsync({ - method: 'miner_start', - params: [threads], - }); - } - /** - * Stop the CPU mining process. - * @param threads The number of threads to mine on. - */ - public async minerStopAsync(): Promise { - await this._sendRawPayloadAsync({ method: 'miner_stop', params: [] }); - } - /** - * Returns true if client is actively mining new blocks. - * @returns A boolean indicating whether the node is currently mining. - */ - public async isMiningAsync(): Promise { - const isMining = await promisify(this._web3.eth.getMining)(); - return isMining; - } /** * Sets the current head of the local chain by block number. Note, this is a * destructive action and may severely damage your chain. Use with extreme -- cgit v1.2.3 From d6d7f4e875b161aa7284467a61f67989f76ec89e Mon Sep 17 00:00:00 2001 From: Alex Browne Date: Tue, 5 Jun 2018 16:20:38 -0700 Subject: Update more things to work with both Geth and Ganache --- packages/web3-wrapper/src/index.ts | 2 +- packages/web3-wrapper/src/web3_wrapper.ts | 21 ++++++++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) (limited to 'packages/web3-wrapper/src') diff --git a/packages/web3-wrapper/src/index.ts b/packages/web3-wrapper/src/index.ts index 7309e09a8..b14fa7406 100644 --- a/packages/web3-wrapper/src/index.ts +++ b/packages/web3-wrapper/src/index.ts @@ -1,2 +1,2 @@ -export { Web3Wrapper } from './web3_wrapper'; +export { Web3Wrapper, uniqueVersionIds } from './web3_wrapper'; export { Web3WrapperErrors } from './types'; diff --git a/packages/web3-wrapper/src/web3_wrapper.ts b/packages/web3-wrapper/src/web3_wrapper.ts index a19253449..6c9fa980e 100644 --- a/packages/web3-wrapper/src/web3_wrapper.ts +++ b/packages/web3-wrapper/src/web3_wrapper.ts @@ -21,6 +21,13 @@ import { Web3WrapperErrors } from './types'; const BASE_TEN = 10; +// These are unique identifiers contained in the response of the +// web3_clientVersion call. +export const uniqueVersionIds = { + geth: 'Geth', + ganache: 'EthereumJS TestRPC', +}; + /** * A wrapper around the Web3.js 0.x library that provides a consistent, clean promise-based interface. */ @@ -254,12 +261,20 @@ export class Web3Wrapper { await this._sendRawPayloadAsync({ method: 'evm_mine', params: [] }); } /** - * Increase the next blocks timestamp on TestRPC/Ganache local node + * Increase the next blocks timestamp on TestRPC/Ganache or Geth local node. + * Will throw if provider is neither TestRPC/Ganache or Geth. * @param timeDelta Amount of time to add in seconds */ public async increaseTimeAsync(timeDelta: number): Promise { - // TODO(albrow): Detect Geth vs. Ganache and use appropriate endpoint. - return this._sendRawPayloadAsync({ method: 'debug_increaseTime', params: [timeDelta] }); + // Detect Geth vs. Ganache and use appropriate endpoint. + const version = await this.getNodeVersionAsync(); + if (_.includes(version, uniqueVersionIds.geth)) { + return this._sendRawPayloadAsync({ method: 'debug_increaseTime', params: [timeDelta] }); + } else if (_.includes(version, uniqueVersionIds.ganache)) { + return this._sendRawPayloadAsync({ method: 'evm_increaseTime', params: [timeDelta] }); + } else { + throw new Error(`Unknown client version: ${version}`); + } } /** * Retrieve smart contract logs for a given filter -- cgit v1.2.3 From dd8727d3aebf1f4b552f8bad921b92107ad22936 Mon Sep 17 00:00:00 2001 From: Alex Browne Date: Wed, 6 Jun 2018 11:43:07 -0700 Subject: Apply various fixes based on PR feedback --- packages/web3-wrapper/src/web3_wrapper.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'packages/web3-wrapper/src') diff --git a/packages/web3-wrapper/src/web3_wrapper.ts b/packages/web3-wrapper/src/web3_wrapper.ts index 6c9fa980e..559bf3ea9 100644 --- a/packages/web3-wrapper/src/web3_wrapper.ts +++ b/packages/web3-wrapper/src/web3_wrapper.ts @@ -422,9 +422,11 @@ export class Web3Wrapper { return receipt; } /** - * Sets the current head of the local chain by block number. Note, this is a - * destructive action and may severely damage your chain. Use with extreme - * caution. + * Calls the 'debug_setHead' JSON RPC method, which sets the current head of + * the local chain by block number. Note, this is a destructive action and + * may severely damage your chain. Use with extreme caution. As of now, this + * is only supported by Geth. It sill throw if the 'debug_setHead' method is + * not supported. * @param blockNumber The block number to reset to. */ public async setHeadAsync(blockNumber: number): Promise { -- cgit v1.2.3 From 760bab8f866ec3d5fc7627ce9bbf5c2eaaef1f36 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Fri, 8 Jun 2018 11:18:32 -0700 Subject: Implement SolidityProfiler & adapt sol-cov to work with Geth --- packages/web3-wrapper/src/web3_wrapper.ts | 41 +++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 5 deletions(-) (limited to 'packages/web3-wrapper/src') diff --git a/packages/web3-wrapper/src/web3_wrapper.ts b/packages/web3-wrapper/src/web3_wrapper.ts index 559bf3ea9..ecb400656 100644 --- a/packages/web3-wrapper/src/web3_wrapper.ts +++ b/packages/web3-wrapper/src/web3_wrapper.ts @@ -2,6 +2,7 @@ import { AbiDecoder, addressUtils, BigNumber, intervalUtils, promisify } from '@ import { BlockParam, BlockWithoutTransactionData, + BlockWithTransactionData, CallData, ContractAbi, FilterObject, @@ -10,8 +11,10 @@ import { LogEntry, Provider, RawLogEntry, + TraceParams, TransactionReceipt, TransactionReceiptWithDecodedLogs, + TransactionTrace, TxData, } from 'ethereum-types'; import * as _ from 'lodash'; @@ -187,11 +190,22 @@ export class Web3Wrapper { * @returns Whether or not contract code was found at the supplied address */ public async doesContractExistAtAddressAsync(address: string): Promise { - const code = await promisify(this._web3.eth.getCode)(address); + const code = await this.getContractCodeAsync(address); // Regex matches 0x0, 0x00, 0x in order to accommodate poorly implemented clients const isCodeEmpty = /^0x0{0,40}$/i.test(code); return !isCodeEmpty; } + public async getContractCodeAsync(address: string): Promise { + const code = await promisify(this._web3.eth.getCode)(address); + return code; + } + public async getTransactionTraceAsync(txHash: string, traceParams: TraceParams): Promise { + const trace = await this._sendRawPayloadAsync({ + method: 'debug_traceTransaction', + params: [txHash, traceParams], + }); + return trace; + } /** * Sign a message with a specific address's private key (`eth_sign`) * @param address Address of signer @@ -211,13 +225,30 @@ export class Web3Wrapper { return blockNumber; } /** - * Fetch a specific Ethereum block + * Fetch a specific Ethereum block without transaction data * @param blockParam The block you wish to fetch (blockHash, blockNumber or blockLiteral) * @returns The requested block without transaction data */ public async getBlockAsync(blockParam: string | BlockParam): Promise { - const block = await promisify(this._web3.eth.getBlock)(blockParam); - return block; + const shouldIncludeTransactionData = false; + const blockWithoutTransactionData = await promisify(this._web3.eth.getBlock)( + blockParam, + shouldIncludeTransactionData, + ); + return blockWithoutTransactionData; + } + /** + * Fetch a specific Ethereum block with transaction data + * @param blockParam The block you wish to fetch (blockHash, blockNumber or blockLiteral) + * @returns The requested block with transaction data + */ + public async getBlockWithTransactionDataAsync(blockParam: string | BlockParam): Promise { + const shouldIncludeTransactionData = true; + const blockWithTransactionData = await promisify(this._web3.eth.getBlock)( + blockParam, + shouldIncludeTransactionData, + ); + return blockWithTransactionData; } /** * Fetch a block's timestamp @@ -469,4 +500,4 @@ export class Web3Wrapper { const decimal = this._web3.toDecimal(hex); return decimal; } -} +} // tslint:disable-line:max-file-line-count -- cgit v1.2.3 From 1c3dc757c3332dad39f47e25cbbbdc60ce2540da Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Fri, 8 Jun 2018 13:27:55 -0700 Subject: Fix typos --- packages/web3-wrapper/src/web3_wrapper.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'packages/web3-wrapper/src') diff --git a/packages/web3-wrapper/src/web3_wrapper.ts b/packages/web3-wrapper/src/web3_wrapper.ts index ecb400656..780695091 100644 --- a/packages/web3-wrapper/src/web3_wrapper.ts +++ b/packages/web3-wrapper/src/web3_wrapper.ts @@ -195,10 +195,21 @@ export class Web3Wrapper { const isCodeEmpty = /^0x0{0,40}$/i.test(code); return !isCodeEmpty; } + /** + * Gets the contract code by address + * @param address Address of the contract + * @return Code of the contract + */ public async getContractCodeAsync(address: string): Promise { const code = await promisify(this._web3.eth.getCode)(address); return code; } + /** + * Gets the debug trace of a transaction + * @param txHash Hash of the transactuon to get a trace for + * @param traceParams Config object allowing you to specify if you need memory/storage/stack traces. + * @return Transaction trace + */ public async getTransactionTraceAsync(txHash: string, traceParams: TraceParams): Promise { const trace = await this._sendRawPayloadAsync({ method: 'debug_traceTransaction', -- cgit v1.2.3 From 3cc30f91a99578b626d95811a26ee7b19f404455 Mon Sep 17 00:00:00 2001 From: Alex Browne Date: Mon, 11 Jun 2018 17:04:47 -0700 Subject: Speedup awaitTransactionMinedAsync and reduce polling interval in contracts tests --- packages/web3-wrapper/src/web3_wrapper.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'packages/web3-wrapper/src') diff --git a/packages/web3-wrapper/src/web3_wrapper.ts b/packages/web3-wrapper/src/web3_wrapper.ts index 780695091..5d2eedcb3 100644 --- a/packages/web3-wrapper/src/web3_wrapper.ts +++ b/packages/web3-wrapper/src/web3_wrapper.ts @@ -402,6 +402,21 @@ export class Web3Wrapper { pollingIntervalMs: number = 1000, timeoutMs?: number, ): Promise { + // Immediately check if the transaction has already been mined. + let transactionReceipt = await this.getTransactionReceiptAsync(txHash); + if (!_.isNull(transactionReceipt)) { + const logsWithDecodedArgs = _.map( + transactionReceipt.logs, + this.abiDecoder.tryToDecodeLogOrNoop.bind(this.abiDecoder), + ); + const transactionReceiptWithDecodedLogArgs: TransactionReceiptWithDecodedLogs = { + ...transactionReceipt, + logs: logsWithDecodedArgs, + }; + return transactionReceiptWithDecodedLogArgs; + } + + // Otherwise, check again every pollingIntervalMs. let wasTimeoutExceeded = false; if (timeoutMs) { setTimeout(() => (wasTimeoutExceeded = true), timeoutMs); @@ -416,7 +431,7 @@ export class Web3Wrapper { return reject(Web3WrapperErrors.TransactionMiningTimeout); } - const transactionReceipt = await this.getTransactionReceiptAsync(txHash); + transactionReceipt = await this.getTransactionReceiptAsync(txHash); if (!_.isNull(transactionReceipt)) { intervalUtils.clearAsyncExcludingInterval(intervalId); const logsWithDecodedArgs = _.map( -- cgit v1.2.3