From ad4d0b34be6b8b73b0fd382106227afaa8a527a4 Mon Sep 17 00:00:00 2001 From: Eduardo Pereira Date: Thu, 17 Jan 2019 09:51:21 -0200 Subject: [PATCH 1/5] Evm functions removed from client --- src/client.ts | 273 +-------------------- src/evm-queries.ts | 277 ++++++++++++++++++++++ src/loom-provider.ts | 29 ++- src/tests/e2e/client-evm-event-tests-2.ts | 4 +- src/tests/e2e/client-evm-event-tests.ts | 2 +- src/tests/e2e/client-evm-tests.ts | 10 +- src/tests/e2e/evm-contract-tests.ts | 2 +- 7 files changed, 311 insertions(+), 286 deletions(-) create mode 100644 src/evm-queries.ts diff --git a/src/client.ts b/src/client.ts index 6b4f8db5..504e1029 100644 --- a/src/client.ts +++ b/src/client.ts @@ -4,16 +4,8 @@ import EventEmitter from 'events' import retry from 'retry' import { VMType } from './proto/loom_pb' -import { - EvmTxReceipt, - EvmTxObject, - EthBlockInfo, - EthFilterEnvelope, - EthBlockHashList, - EthFilterLogList, - EthTxHashList -} from './proto/evm_pb' -import { Uint8ArrayToB64, B64ToUint8Array, bufferToProtobufBytes } from './crypto-utils' +import { EvmQueries } from './evm-queries' +import { Uint8ArrayToB64, B64ToUint8Array } from './crypto-utils' import { Address, LocalAddress } from './address' import { WSRPCClient, IJSONRPCEvent } from './internal/ws-rpc-client' import { RPCClientEvent, IJSONRPCClient } from './internal/json-rpc-client' @@ -230,6 +222,7 @@ export class Client extends EventEmitter { private _writeClient: IJSONRPCClient private _readClient!: IJSONRPCClient + private _evmClient: EvmQueries /** Broadcaster to use to send txs & receive results. */ txBroadcaster: ITxBroadcaster @@ -245,6 +238,10 @@ export class Client extends EventEmitter { return this._writeClient.url } + get evm(): EvmQueries { + return this._evmClient + } + /** * Constructs a new client to read & write data from/to a Loom DAppChain via web sockets. * @param chainId DAppChain identifier. @@ -298,6 +295,8 @@ export class Client extends EventEmitter { ) } + this._evmClient = new EvmQueries(this._readClient) + const emitContractEvent = (url: string, event: IJSONRPCEvent) => this._emitContractEvent(url, event) @@ -421,260 +420,6 @@ export class Client extends EventEmitter { } } - /** - * Queries the receipt corresponding to a transaction hash - * - * @param txHash Transaction hash returned by call transaction. - * @return EvmTxReceipt The corresponding transaction receipt. - */ - async getEvmTxReceiptAsync(txHash: Uint8Array): Promise { - const result = await this._readClient.sendAsync('evmtxreceipt', { - txHash: Uint8ArrayToB64(txHash) - }) - if (result) { - return EvmTxReceipt.deserializeBinary(bufferToProtobufBytes(B64ToUint8Array(result))) - } else { - return null - } - } - - /** - * Returns the information about a transaction requested by transaction hash - * - * @param txHash Transaction hash returned by call transaction. - * @return EvmTxObject The corresponding transaction object data. - */ - async getEvmTxByHashAsync(txHash: Uint8Array): Promise { - const result = await this._readClient.sendAsync('getevmtransactionbyhash', { - txHash: Uint8ArrayToB64(txHash) - }) - if (result) { - return EvmTxObject.deserializeBinary(bufferToProtobufBytes(B64ToUint8Array(result))) - } else { - return null - } - } - - /** - * Queries the code corresponding to a contract - * - * @param contractAddress Contract address returned by deploy. - * @return Uint8Array The corresponding contract code - */ - async getEvmCodeAsync(contractAddress: Address): Promise { - const result = await this._readClient.sendAsync('getevmcode', { - contract: contractAddress.toString() - }) - if (result) { - return B64ToUint8Array(result) - } else { - return null - } - } - - /** - * Queries logs with filter terms - * - * @param filter Filter terms - * @return Uint8Array The corresponding result of the filter - */ - async getEvmLogsAsync(filterObject: Object): Promise { - const filter = JSON.stringify(filterObject) - debugLog(`Send filter ${filter} to getlogs`) - const result = await this._readClient.sendAsync('getevmlogs', { - filter - }) - if (result) { - return B64ToUint8Array(result) - } else { - return null - } - } - - /** - * Creates a new filter based on filter terms, to notify when the state changes - * - * The function getEVMNewFilterAsync works in the similar way of the RPC call eth_newFilter, for more - * - * Also for understand how filters works check https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_newfilter - * - * @param filter Filter terms - * @return Uint8Array The corresponding result of the filter - */ - async newEvmFilterAsync(filterObject: Object): Promise { - const filter = JSON.stringify(filterObject) - debugLog(`Send filter ${filter} to newfilter`) - const result = await this._readClient.sendAsync('newevmfilter', { - filter - }) - if (result) { - return result - } else { - return null - } - } - - /** - * Polling method for a filter, which returns an array of logs which occurred since last poll - * - * The ID used was requested from getEVMNewFilterChanges or getEVMNewBlockFilter - * - * @param id Id of filter previously created - * @return Uint8Array The corresponding result of the request for given id - */ - async getEvmFilterChangesAsync( - id: string - ): Promise { - debugLog(`Get filter changes for ${JSON.stringify({ id }, null, 2)}`) - const result = await this._readClient.sendAsync('getevmfilterchanges', { - id - }) - - if (result) { - const envelope: EthFilterEnvelope = EthFilterEnvelope.deserializeBinary( - bufferToProtobufBytes(result) - ) - - switch (envelope.getMessageCase()) { - case EthFilterEnvelope.MessageCase.ETH_BLOCK_HASH_LIST: - return envelope.getEthBlockHashList() as EthBlockHashList - case EthFilterEnvelope.MessageCase.ETH_FILTER_LOG_LIST: - return envelope.getEthFilterLogList() as EthFilterLogList - case EthFilterEnvelope.MessageCase.ETH_TX_HASH_LIST: - return envelope.getEthTxHashList() as EthTxHashList - case EthFilterEnvelope.MessageCase.MESSAGE_NOT_SET: - default: - return null - } - } else { - return null - } - } - - /** - * Creates a filter in the node, to notify when a new block arrives - * - * In order to check if the state has changed, call getEVMFilterChangesAsync - * - * @return String Filter ID in hex format to be used later with getEVMFilterChangesAsync - */ - async newBlockEvmFilterAsync(): Promise { - const result = await this._readClient.sendAsync('newblockevmfilter', {}) - if (result) { - return result.toString() - } else { - return null - } - } - - /** - * Creates a filter in the node, to notify when new pending transactions arrive. - * - * In order to check if the state has changed, call getEVMFilterChangesAsync - * - * @return String Filter ID in hex format to be used later with getEVMFilterChangesAsync - */ - async newPendingTransactionEvmFilterAsync(): Promise { - const result = await this._readClient.sendAsync('newpendingtransactionevmfilter', {}) - if (result) { - return result.toString() - } else { - return null - } - } - - /** - * Uninstall/delete previously created filters - * - * The ID used was requested from getEVMNewFilterChanges or getEVMNewBlockFilter - * - * @param id Id of filter previously created - * @return boolean If true the filter is removed with success - */ - uninstallEvmFilterAsync(id: string): Promise { - return this._readClient.sendAsync('uninstallevmfilter', { - id - }) - } - - /** - * Returns information about a block by block number. - * - * @param num Integer of a block number - * @param full If true it returns the full transaction objects, if false only the hashes of the transactions - */ - async getEvmBlockByNumberAsync(num: string, full: boolean = true): Promise { - const result = await this._readClient.sendAsync('getevmblockbynumber', { - number: num, - full - }) - if (result) { - return EthBlockInfo.deserializeBinary(bufferToProtobufBytes(B64ToUint8Array(result))) - } else { - return null - } - } - - /** - * Returns the information about a transaction requested by transaction hash. - * - * @param hash String with the hash of the transaction - * @param full If true it returns the full transaction objects, if false only the hashes of the transactions - */ - async getEvmBlockByHashAsync( - hashHexStr: string, - full: boolean = true - ): Promise { - const result = await this._readClient.sendAsync('getevmblockbyhash', { - hash: Buffer.from(hashHexStr.slice(2), 'hex').toString('base64'), - full - }) - if (result) { - return EthBlockInfo.deserializeBinary(bufferToProtobufBytes(B64ToUint8Array(result))) - } else { - return null - } - } - - /** - * It works by subscribing to particular events. The node will return a subscription id. - * For each event that matches the subscription a notification with relevant data is send - * together with the subscription id. - * - * Possible methods: - * * "NewHeads": Fires a notification each time a new header is appended to the chain - * * "Logs": Returns logs that are included in new imported blocks and match the given filter criteria - * - * Example of a "filter" (JSON String) with method "logs": - * { - * "address": "0xa520fe7702b96808f7bbc0d4a233ed1468216cfd", - * "topics": ["0x238a0cb8bb633d06981248b822e7bd33c2a35a6089241d099fa519e361cab902"] - * } - * - * @param method Method selected to the filter, can be "newHeads" or "logs" - * @param filter JSON string of the filter - */ - evmSubscribeAsync(method: string, filterObject: Object): Promise { - const filter = JSON.stringify(filterObject) - return this._readClient.sendAsync('evmsubscribe', { - method, - filter - }) - } - - /** - * Subscriptions are cancelled method and the subscription id as first parameter. - * It returns a bool indicating if the subscription was cancelled successful. - * - * @param id Id of subscription previously created - * @return boolean If true the subscription is removed with success - */ - evmUnsubscribeAsync(id: string): Promise { - return this._readClient.sendAsync('evmunsubscribe', { - id - }) - } - /** * Gets the number of the latest block * diff --git a/src/evm-queries.ts b/src/evm-queries.ts new file mode 100644 index 00000000..24aba0bc --- /dev/null +++ b/src/evm-queries.ts @@ -0,0 +1,277 @@ +import debug from 'debug' +import { + EvmTxReceipt, + EvmTxObject, + EthBlockInfo, + EthFilterEnvelope, + EthBlockHashList, + EthFilterLogList, + EthTxHashList +} from './proto/evm_pb' +import { Uint8ArrayToB64, B64ToUint8Array, bufferToProtobufBytes } from './crypto-utils' +import { IJSONRPCClient } from './internal/json-rpc-client' +import { Address } from './address' + +const debugLog = debug('evm-client') + +export class EvmQueries { + private _readClient: IJSONRPCClient + + constructor(readClient: IJSONRPCClient) { + this._readClient = readClient + } + + /** + * Queries the receipt corresponding to a transaction hash + * + * @param txHash Transaction hash returned by call transaction. + * @return EvmTxReceipt The corresponding transaction receipt. + */ + async getEvmTxReceiptAsync(txHash: Uint8Array): Promise { + const result = await this._readClient.sendAsync('evmtxreceipt', { + txHash: Uint8ArrayToB64(txHash) + }) + if (result) { + return EvmTxReceipt.deserializeBinary(bufferToProtobufBytes(B64ToUint8Array(result))) + } else { + return null + } + } + + /** + * Returns the information about a transaction requested by transaction hash + * + * @param txHash Transaction hash returned by call transaction. + * @return EvmTxObject The corresponding transaction object data. + */ + async getEvmTxByHashAsync(txHash: Uint8Array): Promise { + const result = await this._readClient.sendAsync('getevmtransactionbyhash', { + txHash: Uint8ArrayToB64(txHash) + }) + if (result) { + return EvmTxObject.deserializeBinary(bufferToProtobufBytes(B64ToUint8Array(result))) + } else { + return null + } + } + + /** + * Queries the code corresponding to a contract + * + * @param contractAddress Contract address returned by deploy. + * @return Uint8Array The corresponding contract code + */ + async getEvmCodeAsync(contractAddress: Address): Promise { + const result = await this._readClient.sendAsync('getevmcode', { + contract: contractAddress.toString() + }) + if (result) { + return B64ToUint8Array(result) + } else { + return null + } + } + + /** + * Queries logs with filter terms + * + * @param filter Filter terms + * @return Uint8Array The corresponding result of the filter + */ + async getEvmLogsAsync(filterObject: Object): Promise { + const filter = JSON.stringify(filterObject) + debugLog(`Send filter ${filter} to getlogs`) + const result = await this._readClient.sendAsync('getevmlogs', { + filter + }) + if (result) { + return B64ToUint8Array(result) + } else { + return null + } + } + + /** + * Creates a new filter based on filter terms, to notify when the state changes + * + * The function getEVMNewFilterAsync works in the similar way of the RPC call eth_newFilter, for more + * + * Also for understand how filters works check https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_newfilter + * + * @param filter Filter terms + * @return Uint8Array The corresponding result of the filter + */ + async newEvmFilterAsync(filterObject: Object): Promise { + const filter = JSON.stringify(filterObject) + debugLog(`Send filter ${filter} to newfilter`) + const result = await this._readClient.sendAsync('newevmfilter', { + filter + }) + if (result) { + return result + } else { + return null + } + } + + /** + * Polling method for a filter, which returns an array of logs which occurred since last poll + * + * The ID used was requested from getEVMNewFilterChanges or getEVMNewBlockFilter + * + * @param id Id of filter previously created + * @return Uint8Array The corresponding result of the request for given id + */ + async getEvmFilterChangesAsync( + id: string + ): Promise { + debugLog(`Get filter changes for ${JSON.stringify({ id }, null, 2)}`) + const result = await this._readClient.sendAsync('getevmfilterchanges', { + id + }) + + if (result) { + const envelope: EthFilterEnvelope = EthFilterEnvelope.deserializeBinary( + bufferToProtobufBytes(result) + ) + + switch (envelope.getMessageCase()) { + case EthFilterEnvelope.MessageCase.ETH_BLOCK_HASH_LIST: + return envelope.getEthBlockHashList() as EthBlockHashList + case EthFilterEnvelope.MessageCase.ETH_FILTER_LOG_LIST: + return envelope.getEthFilterLogList() as EthFilterLogList + case EthFilterEnvelope.MessageCase.ETH_TX_HASH_LIST: + return envelope.getEthTxHashList() as EthTxHashList + case EthFilterEnvelope.MessageCase.MESSAGE_NOT_SET: + default: + return null + } + } else { + return null + } + } + + /** + * Creates a filter in the node, to notify when a new block arrives + * + * In order to check if the state has changed, call getEVMFilterChangesAsync + * + * @return String Filter ID in hex format to be used later with getEVMFilterChangesAsync + */ + async newBlockEvmFilterAsync(): Promise { + const result = await this._readClient.sendAsync('newblockevmfilter', {}) + if (result) { + return result.toString() + } else { + return null + } + } + + /** + * Creates a filter in the node, to notify when new pending transactions arrive. + * + * In order to check if the state has changed, call getEVMFilterChangesAsync + * + * @return String Filter ID in hex format to be used later with getEVMFilterChangesAsync + */ + async newEvmPendingTransactionEvmFilterAsync(): Promise { + const result = await this._readClient.sendAsync('newpendingtransactionevmfilter', {}) + if (result) { + return result.toString() + } else { + return null + } + } + + /** + * Uninstall/delete previously created filters + * + * The ID used was requested from getEVMNewFilterChanges or getEVMNewBlockFilter + * + * @param id Id of filter previously created + * @return boolean If true the filter is removed with success + */ + uninstallEvmFilterAsync(id: string): Promise { + return this._readClient.sendAsync('uninstallevmfilter', { + id + }) + } + + /** + * Returns information about a block by block number. + * + * @param num Integer of a block number + * @param full If true it returns the full transaction objects, if false only the hashes of the transactions + */ + async getEvmBlockByNumberAsync(num: string, full: boolean = true): Promise { + const result = await this._readClient.sendAsync('getevmblockbynumber', { + number: num, + full + }) + if (result) { + return EthBlockInfo.deserializeBinary(bufferToProtobufBytes(B64ToUint8Array(result))) + } else { + return null + } + } + + /** + * Returns the information about a transaction requested by transaction hash. + * + * @param hash String with the hash of the transaction + * @param full If true it returns the full transaction objects, if false only the hashes of the transactions + */ + async getEvmBlockByHashAsync( + hashHexStr: string, + full: boolean = true + ): Promise { + const result = await this._readClient.sendAsync('getevmblockbyhash', { + hash: Buffer.from(hashHexStr.slice(2), 'hex').toString('base64'), + full + }) + if (result) { + return EthBlockInfo.deserializeBinary(bufferToProtobufBytes(B64ToUint8Array(result))) + } else { + return null + } + } + + /** + * It works by subscribing to particular events. The node will return a subscription id. + * For each event that matches the subscription a notification with relevant data is send + * together with the subscription id. + * + * Possible methods: + * * "NewHeads": Fires a notification each time a new header is appended to the chain + * * "Logs": Returns logs that are included in new imported blocks and match the given filter criteria + * + * Example of a "filter" (JSON String) with method "logs": + * { + * "address": "0xa520fe7702b96808f7bbc0d4a233ed1468216cfd", + * "topics": ["0x238a0cb8bb633d06981248b822e7bd33c2a35a6089241d099fa519e361cab902"] + * } + * + * @param method Method selected to the filter, can be "newHeads" or "logs" + * @param filter JSON string of the filter + */ + evmSubscribeAsync(method: string, filterObject: Object): Promise { + const filter = JSON.stringify(filterObject) + return this._readClient.sendAsync('evmsubscribe', { + method, + filter + }) + } + + /** + * Subscriptions are cancelled method and the subscription id as first parameter. + * It returns a bool indicating if the subscription was cancelled successful. + * + * @param id Id of subscription previously created + * @return boolean If true the subscription is removed with success + */ + evmUnsubscribeAsync(id: string): Promise { + return this._readClient.sendAsync('evmunsubscribe', { + id + }) + } +} diff --git a/src/loom-provider.ts b/src/loom-provider.ts index b1c05c7b..41de112e 100644 --- a/src/loom-provider.ts +++ b/src/loom-provider.ts @@ -405,7 +405,7 @@ export class LoomProvider { const blockHash = payload.params[0] const isFull = payload.params[1] || true - const result = await this._client.getEvmBlockByHashAsync(blockHash, isFull) + const result = await this._client.evm.getEvmBlockByHashAsync(blockHash, isFull) if (!result) { return null @@ -418,7 +418,10 @@ export class LoomProvider { const blockNumberToSearch = payload.params[0] === 'latest' ? payload.params[0] : hexToNumber(payload.params[0]) const isFull = payload.params[1] || true - const result = await this._client.getEvmBlockByNumberAsync(`${blockNumberToSearch}`, isFull) + const result = await this._client.evm.getEvmBlockByNumberAsync( + `${blockNumberToSearch}`, + isFull + ) if (!result) { return null @@ -432,7 +435,7 @@ export class LoomProvider { this._client.chainId, LocalAddress.fromHexString(payload.params[0]) ) - const result = await this._client.getEvmCodeAsync(address) + const result = await this._client.evm.getEvmCodeAsync(address) if (!result) { throw Error('No code returned on eth_getCode') @@ -442,7 +445,7 @@ export class LoomProvider { } private async _ethGetFilterChanges(payload: IEthRPCPayload) { - const result = await this._client.getEvmFilterChangesAsync(payload.params[0]) + const result = await this._client.evm.getEvmFilterChangesAsync(payload.params[0]) if (!result) { return [] @@ -478,7 +481,7 @@ export class LoomProvider { const receipt = await new Promise((resolve, reject) => { op.attempt(currentAttempt => { log(`Current attempt ${currentAttempt}`) - this._client + this._client.evm .getEvmTxReceiptAsync(bufferToProtobufBytes(data)) .then(receipt => { if (receipt) { @@ -504,7 +507,7 @@ export class LoomProvider { } private async _ethNewBlockFilter() { - const result = await this._client.newBlockEvmFilterAsync() + const result = await this._client.evm.newBlockEvmFilterAsync() if (!result) { throw Error('New block filter unexpected result') @@ -514,7 +517,7 @@ export class LoomProvider { } private async _ethNewFilter(payload: IEthRPCPayload) { - const result = await this._client.newEvmFilterAsync(payload.params[0]) + const result = await this._client.evm.newEvmFilterAsync(payload.params[0]) if (!result) { throw Error('Cannot create new filter on eth_newFilter') @@ -524,7 +527,7 @@ export class LoomProvider { } private async _ethNewPendingTransactionFilter() { - const result = await this._client.newPendingTransactionEvmFilterAsync() + const result = await this._client.evm.newEvmPendingTransactionEvmFilterAsync() if (!result) { throw Error('New pending transaction filter unexpected result') @@ -570,7 +573,7 @@ export class LoomProvider { const method = payload.params[0] const filterObject = payload.params[1] || {} - const result = await this._client.evmSubscribeAsync(method, filterObject) + const result = await this._client.evm.evmSubscribeAsync(method, filterObject) if (!result) { throw Error('Subscribe filter failed') } @@ -579,11 +582,11 @@ export class LoomProvider { } private _ethUninstallFilter(payload: IEthRPCPayload) { - return this._client.uninstallEvmFilterAsync(payload.params[0]) + return this._client.evm.uninstallEvmFilterAsync(payload.params[0]) } private _ethUnsubscribe(payload: IEthRPCPayload) { - return this._client.evmUnsubscribeAsync(payload.params[0]) + return this._client.evm.evmUnsubscribeAsync(payload.params[0]) } private _chainIdToNetVersion() { @@ -768,7 +771,7 @@ export class LoomProvider { private async _getTransaction(txHash: string): Promise { const data = Buffer.from(txHash.slice(2), 'hex') - const transaction = await this._client.getEvmTxByHashAsync(bufferToProtobufBytes(data)) + const transaction = await this._client.evm.getEvmTxByHashAsync(bufferToProtobufBytes(data)) if (!transaction) { throw Error('Transaction cannot be empty') } @@ -815,7 +818,7 @@ export class LoomProvider { } private async _getLogs(filterObject: Object): Promise> { - const logsListAsyncResult = await this._client.getEvmLogsAsync(filterObject) + const logsListAsyncResult = await this._client.evm.getEvmLogsAsync(filterObject) if (!logsListAsyncResult) { return [] diff --git a/src/tests/e2e/client-evm-event-tests-2.ts b/src/tests/e2e/client-evm-event-tests-2.ts index dcc5499d..f6a5d647 100644 --- a/src/tests/e2e/client-evm-event-tests-2.ts +++ b/src/tests/e2e/client-evm-event-tests-2.ts @@ -102,8 +102,8 @@ test('Client EVM Event test (two filters)', async t => { address: result.contractAddress } - const filterCreated1 = await client.evmSubscribeAsync('logs', filter1) - const filterCreated2 = await client.evmSubscribeAsync('logs', filter2) + const filterCreated1 = await client.evm.evmSubscribeAsync('logs', filter1) + const filterCreated2 = await client.evm.evmSubscribeAsync('logs', filter2) console.log('Filter 1 created', filterCreated1) console.log('Filter 2 created', filterCreated2) diff --git a/src/tests/e2e/client-evm-event-tests.ts b/src/tests/e2e/client-evm-event-tests.ts index 891f388f..84251f03 100644 --- a/src/tests/e2e/client-evm-event-tests.ts +++ b/src/tests/e2e/client-evm-event-tests.ts @@ -76,7 +76,7 @@ test('Client EVM Event test', async t => { address: result.contractAddress } - const filterCreated = await client.evmSubscribeAsync('logs', filter) + const filterCreated = await client.evm.evmSubscribeAsync('logs', filter) console.log('Filter created', filterCreated) diff --git a/src/tests/e2e/client-evm-tests.ts b/src/tests/e2e/client-evm-tests.ts index 0e97a626..42d45500 100644 --- a/src/tests/e2e/client-evm-tests.ts +++ b/src/tests/e2e/client-evm-tests.ts @@ -21,7 +21,7 @@ test('Client EVM test (newBlockEvmFilterAsync)', async t => { ] // calls newblockevmfilter - const filterId = await execAndWaitForMillisecondsAsync(client.newBlockEvmFilterAsync()) + const filterId = await execAndWaitForMillisecondsAsync(client.evm.newBlockEvmFilterAsync()) if (!filterId) { t.fail('Filter Id cannot be null') @@ -29,7 +29,7 @@ test('Client EVM test (newBlockEvmFilterAsync)', async t => { // calls getevmfilterchanges const hash = await execAndWaitForMillisecondsAsync( - client.getEvmFilterChangesAsync(filterId as string) + client.evm.getEvmFilterChangesAsync(filterId as string) ) if (!hash) { @@ -40,7 +40,7 @@ test('Client EVM test (newBlockEvmFilterAsync)', async t => { // calls getevmblockbyhash const block: EthBlockInfo = (await execAndWaitForMillisecondsAsync( - client.getEvmBlockByHashAsync(bytesToHexAddr(blockList[0] as Uint8Array)) + client.evm.getEvmBlockByHashAsync(bytesToHexAddr(blockList[0] as Uint8Array)) )) as EthBlockInfo if (!block) { @@ -76,7 +76,7 @@ test('Client EVM test (newPendingTransactionEvmFilterAsync)', async t => { // calls newblockevmfilter const filterId = await execAndWaitForMillisecondsAsync( - client.newPendingTransactionEvmFilterAsync() + client.evm.newEvmPendingTransactionEvmFilterAsync() ) if (!filterId) { @@ -84,7 +84,7 @@ test('Client EVM test (newPendingTransactionEvmFilterAsync)', async t => { } // calls getevmfilterchanges - const hash = await client.getEvmFilterChangesAsync(filterId as string) + const hash = await client.evm.getEvmFilterChangesAsync(filterId as string) if (!hash) { t.fail('Transaction cannot be null') diff --git a/src/tests/e2e/evm-contract-tests.ts b/src/tests/e2e/evm-contract-tests.ts index 4c9d132e..cf5d8681 100644 --- a/src/tests/e2e/evm-contract-tests.ts +++ b/src/tests/e2e/evm-contract-tests.ts @@ -104,7 +104,7 @@ test('EVM Contract Calls', async t => { } if (rtv) { - let receipt = await client.getEvmTxReceiptAsync(rtv) + let receipt = await client.evm.getEvmTxReceiptAsync(rtv) if (receipt) { t.deepEqual( receipt.getContractAddress_asU8().slice(), From 3bbda372d1b64e53b0af3da46053edfe4c1fae4b Mon Sep 17 00:00:00 2001 From: Eduardo Pereira Date: Thu, 17 Jan 2019 09:51:21 -0200 Subject: [PATCH 2/5] Evm functions removed from client * Added deprecation warnings --- src/client.ts | 212 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) diff --git a/src/client.ts b/src/client.ts index 504e1029..9e8294dd 100644 --- a/src/client.ts +++ b/src/client.ts @@ -6,10 +6,20 @@ import retry from 'retry' import { VMType } from './proto/loom_pb' import { EvmQueries } from './evm-queries' import { Uint8ArrayToB64, B64ToUint8Array } from './crypto-utils' +import { + EvmTxReceipt, + EvmTxObject, + EthBlockInfo, + EthFilterEnvelope, + EthBlockHashList, + EthFilterLogList, + EthTxHashList +} from './proto/evm_pb' import { Address, LocalAddress } from './address' import { WSRPCClient, IJSONRPCEvent } from './internal/ws-rpc-client' import { RPCClientEvent, IJSONRPCClient } from './internal/json-rpc-client' import { sleep } from './helpers' +import { deprecate } from 'util' export interface ITxHandlerResult { code?: number @@ -204,6 +214,11 @@ export class TxSyncBroadcaster implements ITxBroadcaster { } } +const deprecatedEvmWarn = () => + console.warn( + 'Deprecated: use evm property in order to call evm functions, i.e: client.evm.getEvmTxByHashAsync' + ) + /** * Writes to & reads from a Loom DAppChain. * @@ -420,6 +435,203 @@ export class Client extends EventEmitter { } } + /** + * Queries the receipt corresponding to a transaction hash + * + * @deprecated Use use `evm` property in order to call evm functions, i.e: client.evm.getEvmTxByHashAsync' + * + * @param txHash Transaction hash returned by call transaction. + * @return EvmTxReceipt The corresponding transaction receipt. + */ + async getEvmTxReceiptAsync(txHash: Uint8Array): Promise { + deprecatedEvmWarn() + return this.evm.getEvmTxReceiptAsync(txHash) + } + + /** + * Returns the information about a transaction requested by transaction hash + * + * @deprecated Use use `evm` property in order to call evm functions, i.e: client.evm.getEvmTxByHashAsync' + * + * @param txHash Transaction hash returned by call transaction. + * @return EvmTxObject The corresponding transaction object data. + */ + async getEvmTxByHashAsync(txHash: Uint8Array): Promise { + deprecatedEvmWarn() + return this.evm.getEvmTxByHashAsync(txHash) + } + + /** + * Queries the code corresponding to a contract + * + * @deprecated Use use `evm` property in order to call evm functions, i.e: client.evm.getEvmTxByHashAsync' + * + * @param contractAddress Contract address returned by deploy. + * @return Uint8Array The corresponding contract code + */ + async getEvmCodeAsync(contractAddress: Address): Promise { + deprecatedEvmWarn() + return this.evm.getEvmCodeAsync(contractAddress) + } + + /** + * Queries logs with filter terms + * + * @deprecated Use use `evm` property in order to call evm functions, i.e: client.evm.getEvmTxByHashAsync' + * + * @param filter Filter terms + * @return Uint8Array The corresponding result of the filter + */ + async getEvmLogsAsync(filterObject: Object): Promise { + deprecatedEvmWarn() + return this.evm.getEvmLogsAsync(filterObject) + } + + /** + * Creates a new filter based on filter terms, to notify when the state changes + * + * The function getEVMNewFilterAsync works in the similar way of the RPC call eth_newFilter, for more + * + * Also for understand how filters works check https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_newfilter + * + * @deprecated Use use `evm` property in order to call evm functions, i.e: client.evm.getEvmTxByHashAsync' + * + * @param filter Filter terms + * @return Uint8Array The corresponding result of the filter + */ + async newEvmFilterAsync(filterObject: Object): Promise { + deprecatedEvmWarn() + return this.evm.newEvmFilterAsync(filterObject) + } + + /** + * Polling method for a filter, which returns an array of logs which occurred since last poll + * + * The ID used was requested from getEVMNewFilterChanges or getEVMNewBlockFilter + * + * @deprecated Use use `evm` property in order to call evm functions, i.e: client.evm.getEvmTxByHashAsync' + * + * @param id Id of filter previously created + * @return Uint8Array The corresponding result of the request for given id + */ + async getEvmFilterChangesAsync( + id: string + ): Promise { + deprecatedEvmWarn() + return this.evm.getEvmFilterChangesAsync(id) + } + + /** + * Creates a filter in the node, to notify when a new block arrives + * + * In order to check if the state has changed, call getEVMFilterChangesAsync + * + * @deprecated Use use `evm` property in order to call evm functions, i.e: client.evm.getEvmTxByHashAsync' + * + * @return String Filter ID in hex format to be used later with getEVMFilterChangesAsync + */ + async newBlockEvmFilterAsync(): Promise { + deprecatedEvmWarn() + return this.evm.newBlockEvmFilterAsync() + } + + /** + * Creates a filter in the node, to notify when new pending transactions arrive. + * + * In order to check if the state has changed, call getEVMFilterChangesAsync + * + * @deprecated Use use `evm` property in order to call evm functions, i.e: client.evm.getEvmTxByHashAsync' + * + * @return String Filter ID in hex format to be used later with getEVMFilterChangesAsync + */ + async newPendingTransactionEvmFilterAsync(): Promise { + deprecatedEvmWarn() + return this.evm.newEvmPendingTransactionEvmFilterAsync() + } + + /** + * Uninstall/delete previously created filters + * + * The ID used was requested from getEVMNewFilterChanges or getEVMNewBlockFilter + * + * @deprecated Use use `evm` property in order to call evm functions, i.e: client.evm.getEvmTxByHashAsync' + * + * @param id Id of filter previously created + * @return boolean If true the filter is removed with success + */ + uninstallEvmFilterAsync(id: string): Promise { + deprecatedEvmWarn() + return this.evm.uninstallEvmFilterAsync(id) + } + + /** + * Returns information about a block by block number. + * + * @deprecated Use use `evm` property in order to call evm functions, i.e: client.evm.getEvmTxByHashAsync' + * + * @param num Integer of a block number + * @param full If true it returns the full transaction objects, if false only the hashes of the transactions + */ + async getEvmBlockByNumberAsync(num: string, full: boolean = true): Promise { + deprecatedEvmWarn() + return this.evm.getEvmBlockByNumberAsync(num, full) + } + + /** + * Returns the information about a transaction requested by transaction hash. + * + * @deprecated Use use `evm` property in order to call evm functions, i.e: client.evm.getEvmTxByHashAsync' + * + * @param hash String with the hash of the transaction + * @param full If true it returns the full transaction objects, if false only the hashes of the transactions + */ + async getEvmBlockByHashAsync( + hashHexStr: string, + full: boolean = true + ): Promise { + deprecatedEvmWarn() + return this.evm.getEvmBlockByHashAsync(hashHexStr) + } + + /** + * It works by subscribing to particular events. The node will return a subscription id. + * For each event that matches the subscription a notification with relevant data is send + * together with the subscription id. + * + * Possible methods: + * * "NewHeads": Fires a notification each time a new header is appended to the chain + * * "Logs": Returns logs that are included in new imported blocks and match the given filter criteria + * + * Example of a "filter" (JSON String) with method "logs": + * { + * "address": "0xa520fe7702b96808f7bbc0d4a233ed1468216cfd", + * "topics": ["0x238a0cb8bb633d06981248b822e7bd33c2a35a6089241d099fa519e361cab902"] + * } + * + * @deprecated Use use `evm` property in order to call evm functions, i.e: client.evm.getEvmTxByHashAsync' + * + * @param method Method selected to the filter, can be "newHeads" or "logs" + * @param filter JSON string of the filter + */ + evmSubscribeAsync(method: string, filterObject: Object): Promise { + deprecatedEvmWarn() + return this.evm.evmSubscribeAsync(method, filterObject) + } + + /** + * Subscriptions are cancelled method and the subscription id as first parameter. + * It returns a bool indicating if the subscription was cancelled successful. + * + * @deprecated Use use `evm` property in order to call evm functions, i.e: client.evm.getEvmTxByHashAsync' + * + * @param id Id of subscription previously created + * @return boolean If true the subscription is removed with success + */ + evmUnsubscribeAsync(id: string): Promise { + deprecatedEvmWarn() + return this.evm.evmUnsubscribeAsync(id) + } + /** * Gets the number of the latest block * From e1cedf2503dab560fb9028e7cadfcfe5db75bdfa Mon Sep 17 00:00:00 2001 From: Eduardo Pereira Date: Thu, 17 Jan 2019 10:25:08 -0200 Subject: [PATCH 3/5] Renamed evmClient to evmQueries --- src/client.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/client.ts b/src/client.ts index 9e8294dd..6d76c9d2 100644 --- a/src/client.ts +++ b/src/client.ts @@ -237,7 +237,7 @@ export class Client extends EventEmitter { private _writeClient: IJSONRPCClient private _readClient!: IJSONRPCClient - private _evmClient: EvmQueries + private _evmQueries: EvmQueries /** Broadcaster to use to send txs & receive results. */ txBroadcaster: ITxBroadcaster @@ -254,7 +254,7 @@ export class Client extends EventEmitter { } get evm(): EvmQueries { - return this._evmClient + return this._evmQueries } /** @@ -310,7 +310,7 @@ export class Client extends EventEmitter { ) } - this._evmClient = new EvmQueries(this._readClient) + this._evmQueries = new EvmQueries(this._readClient) const emitContractEvent = (url: string, event: IJSONRPCEvent) => this._emitContractEvent(url, event) From 5f1144a63d7ecaeb7fde1cae52e8537f90408328 Mon Sep 17 00:00:00 2001 From: Eduardo Pereira Date: Thu, 17 Jan 2019 10:27:31 -0200 Subject: [PATCH 4/5] Fixed func name --- src/client.ts | 2 +- src/evm-queries.ts | 2 +- src/loom-provider.ts | 2 +- src/tests/e2e/client-evm-tests.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/client.ts b/src/client.ts index 6d76c9d2..df77f801 100644 --- a/src/client.ts +++ b/src/client.ts @@ -546,7 +546,7 @@ export class Client extends EventEmitter { */ async newPendingTransactionEvmFilterAsync(): Promise { deprecatedEvmWarn() - return this.evm.newEvmPendingTransactionEvmFilterAsync() + return this.evm.newPendingTransactionEvmFilterAsync() } /** diff --git a/src/evm-queries.ts b/src/evm-queries.ts index 24aba0bc..5421dc83 100644 --- a/src/evm-queries.ts +++ b/src/evm-queries.ts @@ -174,7 +174,7 @@ export class EvmQueries { * * @return String Filter ID in hex format to be used later with getEVMFilterChangesAsync */ - async newEvmPendingTransactionEvmFilterAsync(): Promise { + async newPendingTransactionEvmFilterAsync(): Promise { const result = await this._readClient.sendAsync('newpendingtransactionevmfilter', {}) if (result) { return result.toString() diff --git a/src/loom-provider.ts b/src/loom-provider.ts index 41de112e..da3f1440 100644 --- a/src/loom-provider.ts +++ b/src/loom-provider.ts @@ -527,7 +527,7 @@ export class LoomProvider { } private async _ethNewPendingTransactionFilter() { - const result = await this._client.evm.newEvmPendingTransactionEvmFilterAsync() + const result = await this._client.evm.newPendingTransactionEvmFilterAsync() if (!result) { throw Error('New pending transaction filter unexpected result') diff --git a/src/tests/e2e/client-evm-tests.ts b/src/tests/e2e/client-evm-tests.ts index 42d45500..ec70ec8d 100644 --- a/src/tests/e2e/client-evm-tests.ts +++ b/src/tests/e2e/client-evm-tests.ts @@ -76,7 +76,7 @@ test('Client EVM test (newPendingTransactionEvmFilterAsync)', async t => { // calls newblockevmfilter const filterId = await execAndWaitForMillisecondsAsync( - client.evm.newEvmPendingTransactionEvmFilterAsync() + client.evm.newPendingTransactionEvmFilterAsync() ) if (!filterId) { From d23118f15bb81106697536fdf12949bbbcdd2c01 Mon Sep 17 00:00:00 2001 From: Eduardo Pereira Date: Thu, 17 Jan 2019 10:30:17 -0200 Subject: [PATCH 5/5] Removed unused import --- src/client.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/client.ts b/src/client.ts index df77f801..3671f4d6 100644 --- a/src/client.ts +++ b/src/client.ts @@ -10,7 +10,6 @@ import { EvmTxReceipt, EvmTxObject, EthBlockInfo, - EthFilterEnvelope, EthBlockHashList, EthFilterLogList, EthTxHashList @@ -19,7 +18,6 @@ import { Address, LocalAddress } from './address' import { WSRPCClient, IJSONRPCEvent } from './internal/ws-rpc-client' import { RPCClientEvent, IJSONRPCClient } from './internal/json-rpc-client' import { sleep } from './helpers' -import { deprecate } from 'util' export interface ITxHandlerResult { code?: number