diff --git a/src/loom-provider-2.ts b/src/loom-provider-2.ts index 886678f5..7be794bb 100644 --- a/src/loom-provider-2.ts +++ b/src/loom-provider-2.ts @@ -1,4 +1,5 @@ import debug from 'debug' +import retry from 'retry' import { Wallet } from 'ethers' import { Client as WSClient } from 'rpc-websockets' import { EthRPCMethod, IEthRPCPayload } from './loom-provider' @@ -19,6 +20,19 @@ export class LoomProvider2 { protected notificationCallbacks: Array = new Array() readonly wallets: Map = new Map() + /** + * The retry strategy that should be used to retry some web3 requests. + * By default failed requested won't be resent. + * To understand how to tweak the retry strategy see + * https://github.com/tim-kos/node-retry#retrytimeoutsoptions + */ + retryStrategy: retry.OperationOptions = { + retries: 0, + minTimeout: 1000, // 1s + maxTimeout: 30000, // 30s + randomize: true + } + /** * Constructs the LoomProvider2 to bridges communication between Web3 and Loom DappChains * @@ -94,21 +108,29 @@ export class LoomProvider2 { return } - let result - - try { - if (this._ethRPCMethods.has(payload.method)) { - const f: Function = this._ethRPCMethods.get(payload.method)! - result = await f(payload) - } else { - result = await this._wsRPC.call(payload.method, payload.params) + const op = retry.operation(this.retryStrategy) + op.attempt(async currAttempt => { + debugLog(`Current attempt ${currAttempt}`) + + let result + + try { + if (this._ethRPCMethods.has(payload.method)) { + const f: Function = this._ethRPCMethods.get(payload.method)! + result = await f(payload) + } else { + result = await this._wsRPC.call(payload.method, payload.params) + } + + callback(null, this._okResponse(payload.id, result, isArray)) + } catch (err) { + if (!op.retry(err)) { + callback(err, null) + } else { + errorLog(err) + } } - - callback(null, this._okResponse(payload.id, result, isArray)) - } catch (err) { - errorLog(err) - callback(err, null) - } + }) } // EVENT HANDLING METHODS diff --git a/src/tests/e2e/address-mapper-tests.ts b/src/tests/e2e/contracts/address-mapper-tests.ts similarity index 90% rename from src/tests/e2e/address-mapper-tests.ts rename to src/tests/e2e/contracts/address-mapper-tests.ts index 90585282..f1d4673f 100644 --- a/src/tests/e2e/address-mapper-tests.ts +++ b/src/tests/e2e/contracts/address-mapper-tests.ts @@ -7,10 +7,9 @@ import { CryptoUtils, createDefaultTxMiddleware, Contracts -} from '../../index' -import { createTestHttpClient } from '../helpers' -import { EthersSigner, getJsonRPCSignerAsync } from '../../solidity-helpers' -import { ethers, Signer } from 'ethers' +} from '../../../index' +import { createTestHttpClient } from '../../helpers' +import { EthersSigner, getJsonRPCSignerAsync } from '../../../solidity-helpers' async function getClientAndContract( createClient: () => Client diff --git a/src/tests/e2e/coin-tests.ts b/src/tests/e2e/contracts/coin-tests.ts similarity index 97% rename from src/tests/e2e/coin-tests.ts rename to src/tests/e2e/contracts/coin-tests.ts index bc90d96b..a9933520 100644 --- a/src/tests/e2e/coin-tests.ts +++ b/src/tests/e2e/contracts/coin-tests.ts @@ -7,9 +7,9 @@ import { createDefaultTxMiddleware, Client, LocalAddress -} from '../../index' -import { createTestHttpClient } from '../helpers' -import { B64ToUint8Array } from '../../crypto-utils' +} from '../../../index' +import { createTestHttpClient } from '../../helpers' +import { B64ToUint8Array } from '../../../crypto-utils' const toCoinE18 = (amount: number): BN => { return new BN(10).pow(new BN(18)).mul(new BN(amount)) diff --git a/src/tests/e2e/contract-tests.ts b/src/tests/e2e/contracts/contract-tests.ts similarity index 97% rename from src/tests/e2e/contract-tests.ts rename to src/tests/e2e/contracts/contract-tests.ts index 0697066c..9ca51061 100644 --- a/src/tests/e2e/contract-tests.ts +++ b/src/tests/e2e/contracts/contract-tests.ts @@ -8,14 +8,14 @@ import { IChainEventArgs, CryptoUtils, createDefaultTxMiddleware -} from '../../index' -import { MapEntry } from '../tests_pb' +} from '../../../index' +import { MapEntry } from '../../tests_pb' import { createTestClient, createTestHttpClient, createTestWSClient, createTestHttpWSClient -} from '../helpers' +} from '../../helpers' async function getClientAndContract( createClient: () => Client diff --git a/src/tests/e2e/dpos-tests.ts b/src/tests/e2e/contracts/dpos-tests.ts similarity index 96% rename from src/tests/e2e/dpos-tests.ts rename to src/tests/e2e/contracts/dpos-tests.ts index 9c8998fd..63d0a62c 100644 --- a/src/tests/e2e/dpos-tests.ts +++ b/src/tests/e2e/contracts/dpos-tests.ts @@ -1,5 +1,4 @@ import test from 'tape' -import BN from 'bn.js' import { Address, Contracts, @@ -7,9 +6,9 @@ import { createDefaultTxMiddleware, Client, LocalAddress -} from '../../index' -import { createTestHttpClient, waitForMillisecondsAsync } from '../helpers' -import { B64ToUint8Array } from '../../crypto-utils' +} from '../../../index' +import { createTestHttpClient, waitForMillisecondsAsync } from '../../helpers' +import { B64ToUint8Array } from '../../../crypto-utils' async function getClientAndContract( createClient: () => Client diff --git a/src/tests/e2e/client-evm-event-tests-2.ts b/src/tests/e2e/evm/client-evm-event-tests-2.ts similarity index 89% rename from src/tests/e2e/client-evm-event-tests-2.ts rename to src/tests/e2e/evm/client-evm-event-tests-2.ts index 0a4359f7..e5b86d1f 100644 --- a/src/tests/e2e/client-evm-event-tests-2.ts +++ b/src/tests/e2e/evm/client-evm-event-tests-2.ts @@ -1,13 +1,13 @@ import test from 'tape' -import { CryptoUtils, Client } from '../../index' -import { createTestClient, waitForMillisecondsAsync } from '../helpers' -import { CallTx, VMType, MessageTx, Transaction } from '../../proto/loom_pb' -import { LoomProvider } from '../../loom-provider' -import { deployContract } from '../evm-helpers' -import { bufferToProtobufBytes } from '../../crypto-utils' -import { Address, LocalAddress } from '../../address' -import { createDefaultTxMiddleware } from '../../helpers' +import { CryptoUtils, Client } from '../../../index' +import { createTestClient, waitForMillisecondsAsync } from '../../helpers' +import { CallTx, VMType, MessageTx, Transaction } from '../../../proto/loom_pb' +import { LoomProvider } from '../../../loom-provider' +import { deployContract } from '../../evm-helpers' +import { bufferToProtobufBytes } from '../../../crypto-utils' +import { Address, LocalAddress } from '../../../address' +import { createDefaultTxMiddleware } from '../../../helpers' /** * Requires the SimpleStore solidity contract deployed on a loomchain. diff --git a/src/tests/e2e/client-evm-event-tests.ts b/src/tests/e2e/evm/client-evm-event-tests.ts similarity index 90% rename from src/tests/e2e/client-evm-event-tests.ts rename to src/tests/e2e/evm/client-evm-event-tests.ts index 891f388f..8b956a16 100644 --- a/src/tests/e2e/client-evm-event-tests.ts +++ b/src/tests/e2e/evm/client-evm-event-tests.ts @@ -1,12 +1,12 @@ import test from 'tape' -import { NonceTxMiddleware, SignedTxMiddleware, CryptoUtils } from '../../index' -import { createTestClient } from '../helpers' -import { CallTx, VMType, MessageTx, Transaction } from '../../proto/loom_pb' -import { LoomProvider } from '../../loom-provider' -import { deployContract } from '../evm-helpers' -import { bufferToProtobufBytes } from '../../crypto-utils' -import { Address, LocalAddress } from '../../address' +import { NonceTxMiddleware, SignedTxMiddleware, CryptoUtils } from '../../../index' +import { createTestClient } from '../../helpers' +import { CallTx, VMType, MessageTx, Transaction } from '../../../proto/loom_pb' +import { LoomProvider } from '../../../loom-provider' +import { deployContract } from '../../evm-helpers' +import { bufferToProtobufBytes } from '../../../crypto-utils' +import { Address, LocalAddress } from '../../../address' /** * Requires the SimpleStore solidity contract deployed on a loomchain. diff --git a/src/tests/e2e/client-evm-tests.ts b/src/tests/e2e/evm/client-evm-tests.ts similarity index 89% rename from src/tests/e2e/client-evm-tests.ts rename to src/tests/e2e/evm/client-evm-tests.ts index f97da354..5327e738 100644 --- a/src/tests/e2e/client-evm-tests.ts +++ b/src/tests/e2e/evm/client-evm-tests.ts @@ -1,10 +1,10 @@ import test from 'tape' -import { CryptoUtils } from '../../index' -import { createTestClient, execAndWaitForMillisecondsAsync } from '../helpers' -import { EthBlockHashList, EthBlockInfo } from '../../proto/evm_pb' -import { bytesToHexAddr } from '../../crypto-utils' -import { createDefaultTxMiddleware } from '../../helpers' +import { CryptoUtils } from '../../../index' +import { createTestClient, execAndWaitForMillisecondsAsync } from '../../helpers' +import { EthBlockHashList, EthBlockInfo } from '../../../proto/evm_pb' +import { bytesToHexAddr } from '../../../crypto-utils' +import { createDefaultTxMiddleware } from '../../../helpers' test('Client EVM test (newBlockEvmFilterAsync)', async t => { let client diff --git a/src/tests/e2e/evm-contract-tests.ts b/src/tests/e2e/evm/evm-contract-tests.ts similarity index 97% rename from src/tests/e2e/evm-contract-tests.ts rename to src/tests/e2e/evm/evm-contract-tests.ts index 16b72dc9..19904d63 100644 --- a/src/tests/e2e/evm-contract-tests.ts +++ b/src/tests/e2e/evm/evm-contract-tests.ts @@ -6,8 +6,8 @@ import { LocalAddress, CryptoUtils, createDefaultTxMiddleware -} from '../../index' -import { createTestWSClient } from '../helpers' +} from '../../../index' +import { createTestWSClient } from '../../helpers' /** * Requires the SimpleStore solidity contract deployed on a loomchain. diff --git a/src/tests/e2e/loom-provider-2/loom-provider-eth-filters.ts b/src/tests/e2e/loom-provider-2/loom-provider-eth-filters.ts new file mode 100644 index 00000000..b179812c --- /dev/null +++ b/src/tests/e2e/loom-provider-2/loom-provider-eth-filters.ts @@ -0,0 +1,151 @@ +import test from 'tape' + +import { execAndWaitForMillisecondsAsync, getTestUrls } from '../../helpers' +import { deployContract2 } from '../../evm-helpers' +import { LoomProvider2 } from '../../../loom-provider-2' + +/** + * Requires the SimpleStore solidity contract deployed on a loomchain. + * go-loom/examples/plugins/evmexample/contract/SimpleStore.sol + * + * pragma solidity ^0.4.22; + * + * contract SimpleStore { + * uint value; + * + * constructor() { + * value = 10; + * } + * + * event NewValueSet(uint _value); + * + * function set(uint _value) public { + * value = _value; + * emit NewValueSet(value); + * } + * + * function get() public view returns (uint) { + * return value; + * } + * } + * + */ + +const contractData = + '0x608060405234801561001057600080fd5b50600a600081905550610114806100286000396000f3006080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c14606c575b600080fd5b606a600480360381019080803590602001909291905050506094565b005b348015607757600080fd5b50607e60df565b6040518082815260200191505060405180910390f35b806000819055507f2afa03c814297ffc234ff967b6f0863d3c358be243103f20217c8d3a4d39f9c060005434604051808381526020018281526020019250505060405180910390a150565b600080549050905600a165627a7a72305820deed812a797567167162d0af3ae5f0528c39bea0620e32b28e243628cd655dc40029' + +test('LoomProvider + Filters', async t => { + let loomProvider + + try { + const { wsEth } = getTestUrls() + loomProvider = new LoomProvider2(wsEth) + + await deployContract2(loomProvider, contractData) + + // Transaction receipt in order to obtain the topic of the event NewValueSet + const ethNewFilterResult = await execAndWaitForMillisecondsAsync( + loomProvider.sendAsync({ + id: 10, + method: 'eth_newFilter', + params: [{ toBlock: 'latest' }] + }) + ) + + t.assert(/0x.+/.test(ethNewFilterResult.result), 'New id should be created for new filter') + + const ethNewBlockFilter = await execAndWaitForMillisecondsAsync( + loomProvider.sendAsync({ + id: 11, + method: 'eth_newBlockFilter' + }) + ) + + t.assert( + /0x.+/.test(ethNewBlockFilter.result), + 'New id should be created for new block filter' + ) + + const ethGetFilterChanges = await execAndWaitForMillisecondsAsync( + loomProvider.sendAsync({ + id: 12, + method: 'eth_getFilterChanges', + params: [ethNewBlockFilter.result] + }) + ) + + t.assert( + ethGetFilterChanges.result.length > 0, + 'Get filter changes should return array with new blocks' + ) + + const ethUninstallFilterResult = await execAndWaitForMillisecondsAsync( + loomProvider.sendAsync({ + id: 13, + method: 'eth_uninstallFilter', + params: [ethNewBlockFilter.result] + }) + ) + + t.deepEqual(ethUninstallFilterResult.result, true, 'Should uninstall filter and return true') + } catch (err) { + t.error(err) + } + + if (loomProvider) { + loomProvider.disconnect() + } + + t.end() +}) + +test('LoomProvider + Filters 2', async t => { + let loomProvider + + try { + const { wsEth } = getTestUrls() + loomProvider = new LoomProvider2(wsEth) + + await deployContract2(loomProvider, contractData) + + const ethNewBlockFilter = await execAndWaitForMillisecondsAsync( + loomProvider.sendAsync({ + id: 11, + method: 'eth_newBlockFilter' + }) + ) + + t.assert( + /0x.+/.test(ethNewBlockFilter.result), + 'New id should be created for new block filter' + ) + + const ethGetFilterChanges = await execAndWaitForMillisecondsAsync( + loomProvider.sendAsync({ + id: 12, + method: 'eth_getFilterChanges', + params: [ethNewBlockFilter.result] + }) + ) + + t.assert(ethGetFilterChanges.result.length > 0, 'Should return filter changes') + + const ethGetBlockByHash = await execAndWaitForMillisecondsAsync( + loomProvider.sendAsync({ + id: 13, + method: 'eth_getBlockByHash', + params: [ethGetFilterChanges.result[0], true] + }) + ) + + t.assert(ethGetBlockByHash.result, 'Should return the block requested by hash') + } catch (err) { + t.error(err) + } + + if (loomProvider) { + loomProvider.disconnect() + } + + t.end() +}) diff --git a/src/tests/e2e/loom-provider-2/loom-provider-eth-get-logs.ts b/src/tests/e2e/loom-provider-2/loom-provider-eth-get-logs.ts new file mode 100644 index 00000000..19aeb343 --- /dev/null +++ b/src/tests/e2e/loom-provider-2/loom-provider-eth-get-logs.ts @@ -0,0 +1,181 @@ +import test from 'tape' + +import { + execAndWaitForMillisecondsAsync, + getTestUrls, + waitForMillisecondsAsync +} from '../../helpers' +import { deployContract2 } from '../../evm-helpers' +import { LoomProvider2 } from '../../../loom-provider-2' + +/** + * Requires the SimpleStore solidity contract deployed on a loomchain. + * go-loom/examples/plugins/evmexample/contract/SimpleStore.sol + * + * pragma solidity ^0.4.22; + * + * contract SimpleStore { + * uint value; + * + * constructor() { + * value = 10; + * } + * + * event NewValueSet(uint _value); + * + * function set(uint _value) public { + * value = _value; + * emit NewValueSet(value); + * } + * + * function get() public view returns (uint) { + * return value; + * } + * } + * + */ + +const contractData = + '0x608060405234801561001057600080fd5b50600a600081905550610114806100286000396000f3006080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c14606c575b600080fd5b606a600480360381019080803590602001909291905050506094565b005b348015607757600080fd5b50607e60df565b6040518082815260200191505060405180910390f35b806000819055507f2afa03c814297ffc234ff967b6f0863d3c358be243103f20217c8d3a4d39f9c060005434604051808381526020018281526020019250505060405180910390a150565b600080549050905600a165627a7a72305820deed812a797567167162d0af3ae5f0528c39bea0620e32b28e243628cd655dc40029' + +async function newTransactionToSetState(loomProvider: LoomProvider2, fromAddr: string) { + const contractDeployResult = await deployContract2(loomProvider, contractData) + const contractAddress = contractDeployResult.contractAddress + + // Send transaction to function set in order dispatch event NewValueSet + const ethSendTransactionResult = await loomProvider.sendAsync({ + id: 1, + method: 'eth_sendTransaction', + params: [ + { + to: contractAddress, + from: fromAddr, + data: '0x60fe47b10000000000000000000000000000000000000000000000000000000000000002', + gas: '0x0', + gasPrice: '0x0', + value: '0x0' + } + ] + }) + + await waitForMillisecondsAsync(1000) + + // Transaction receipt in order to obtain the topic of the event NewValueSet + const ethGetTransactionReceiptResult = await execAndWaitForMillisecondsAsync( + loomProvider.sendAsync({ + id: 2, + method: 'eth_getTransactionReceipt', + params: [ethSendTransactionResult.result] + }) + ) + + return { ethGetTransactionReceiptResult, contractAddress } +} + +async function testGetLogsPendingState( + t: test.Test, + loomProvider: LoomProvider2, + fromAddr: string +) { + const newSetTransaction = await newTransactionToSetState(loomProvider, fromAddr) + + // Filtering to get logs + let ethGetLogs = await loomProvider.sendAsync({ + id: 3, + method: 'eth_getLogs', + params: [ + { + address: newSetTransaction.contractAddress, + fromBlock: '0x1', + toBlock: 'pending', + topics: [newSetTransaction.ethGetTransactionReceiptResult.result.logs[0].topics[0]] + } + ] + }) + + t.equal(ethGetLogs.result.length, 1, 'Should return one log for the pending block') +} + +async function testGetLogsLatest(t: test.Test, loomProvider: LoomProvider2, fromAddr: string) { + const newSetTransaction = await newTransactionToSetState(loomProvider, fromAddr) + + // Filtering to get logs + let ethGetLogs = await loomProvider.sendAsync({ + id: 4, + method: 'eth_getLogs', + params: [ + { + address: newSetTransaction.contractAddress, + fromBlock: '0x1', + toBlock: 'latest', + topics: [newSetTransaction.ethGetTransactionReceiptResult.result.logs[0].topics[0]] + } + ] + }) + + t.equal(ethGetLogs.result.length, 1, 'Should return one log for the latest block') +} + +async function testGetLogsAny(t: test.Test, loomProvider: LoomProvider2, fromAddr: string) { + const curBlock = await loomProvider.sendAsync({ + id: 6, + method: 'eth_blockNumber', + params: [] + }) + + console.log(`current block: ${curBlock.result}`) + const fromBlock = curBlock.result + await newTransactionToSetState(loomProvider, fromAddr) + + // Filtering to get logs + let ethGetLogs = await loomProvider.sendAsync({ + id: 7, + method: 'eth_getLogs', + params: [{ fromBlock }] + }) + + t.equal(ethGetLogs.result.length, 1, 'Should return one log for anything filter') +} + +async function testGetLogsAnyPending(t: test.Test, loomProvider: LoomProvider2, fromAddr: string) { + const curBlock = await loomProvider.sendAsync({ + id: 8, + method: 'eth_blockNumber', + params: [] + }) + console.log(`current block: ${curBlock.result}`) + const fromBlock = curBlock.result + await newTransactionToSetState(loomProvider, fromAddr) + + // Filtering to get logs + let ethGetLogs = await loomProvider.sendAsync({ + id: 9, + method: 'eth_getLogs', + params: [{ fromBlock, toBlock: 'pending' }] + }) + + t.equal(ethGetLogs.result.length, 1, 'Should return one log for anything pending filter') +} + +test('LoomProvider.getEVMLogsAsync', async t => { + let loomProvider + try { + const { wsEth } = getTestUrls() + loomProvider = new LoomProvider2(wsEth) + + const fromAddr = await loomProvider.wallet.getAddress() + + await testGetLogsPendingState(t, loomProvider, fromAddr) + await testGetLogsLatest(t, loomProvider, fromAddr) + await testGetLogsAny(t, loomProvider, fromAddr) + await testGetLogsAnyPending(t, loomProvider, fromAddr) + } catch (err) { + t.error(err) + } + + if (loomProvider) { + loomProvider.disconnect() + } + + t.end() +}) diff --git a/src/tests/e2e/loom-provider-2/loom-provider-subscribe.ts b/src/tests/e2e/loom-provider-2/loom-provider-subscribe.ts new file mode 100644 index 00000000..24dc532c --- /dev/null +++ b/src/tests/e2e/loom-provider-2/loom-provider-subscribe.ts @@ -0,0 +1,104 @@ +import test from 'tape' + +import { execAndWaitForMillisecondsAsync, getTestUrls } from '../../helpers' +import { deployContract2 } from '../../evm-helpers' +import { LoomProvider2 } from '../../../loom-provider-2' + +/** + * Requires the SimpleStore solidity contract deployed on a loomchain. + * go-loom/examples/plugins/evmexample/contract/SimpleStore.sol + * + * pragma solidity ^0.4.22; + * + * contract SimpleStore { + * uint value; + * + * constructor() { + * value = 10; + * } + * + * event NewValueSet(uint _value); + * + * function set(uint _value) public { + * value = _value; + * emit NewValueSet(value); + * } + * + * function get() public view returns (uint) { + * return value; + * } + * } + * + */ + +const contractData = + '0x608060405234801561001057600080fd5b50600a600081905550610114806100286000396000f3006080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c14606c575b600080fd5b606a600480360381019080803590602001909291905050506094565b005b348015607757600080fd5b50607e60df565b6040518082815260200191505060405180910390f35b806000819055507f2afa03c814297ffc234ff967b6f0863d3c358be243103f20217c8d3a4d39f9c060005434604051808381526020018281526020019250505060405180910390a150565b600080549050905600a165627a7a72305820deed812a797567167162d0af3ae5f0528c39bea0620e32b28e243628cd655dc40029' + +test('LoomProvider + Subscribe', async t => { + let loomProvider + try { + const { wsEth } = getTestUrls() + loomProvider = new LoomProvider2(wsEth) + + await deployContract2(loomProvider, contractData) + const id = 1 + + const ethSubscribeNewHardsResult = await execAndWaitForMillisecondsAsync( + loomProvider.sendAsync({ + id, + method: 'eth_subscribe', + params: ['newHeads', {}] + }) + ) + + t.equal(ethSubscribeNewHardsResult.id, id, `Id for eth_subscribe should be equal ${id}`) + t.assert( + /0x.+/.test(ethSubscribeNewHardsResult.result), + 'Filter identification should be returned on eth_subscribe' + ) + + const ethUnsubscribeNewHeadsResult = await execAndWaitForMillisecondsAsync( + loomProvider.sendAsync({ + id, + method: 'eth_unsubscribe', + params: [ethSubscribeNewHardsResult.result] + }) + ) + + t.equal(ethUnsubscribeNewHeadsResult.id, id, `Id for eth_unsubscribe should be equal ${id}`) + t.assert(ethUnsubscribeNewHeadsResult.result, 'Unsubscribed for newHeads') + + const ethSubscribeLogsResult = await execAndWaitForMillisecondsAsync( + loomProvider.sendAsync({ + id, + method: 'eth_subscribe', + params: ['logs', {}] + }) + ) + + t.equal(ethSubscribeLogsResult.id, id, `Id for eth_subscribe should be equal ${id}`) + t.assert( + /0x.+/.test(ethSubscribeLogsResult.result), + 'Filter identification should be returned on eth_subscribe' + ) + + const ethUnsubscribeLogsResult = await execAndWaitForMillisecondsAsync( + loomProvider.sendAsync({ + id, + method: 'eth_unsubscribe', + params: [ethSubscribeLogsResult.result] + }) + ) + + t.equal(ethUnsubscribeLogsResult.id, id, `Id for eth_unsubscribe should be equal ${id}`) + t.assert(ethUnsubscribeLogsResult.result, 'Unsubscribed for Logs') + } catch (err) { + console.log(err) + } + + if (loomProvider) { + loomProvider.disconnect() + } + + t.end() +}) diff --git a/src/tests/e2e/loom-provider-2-tests.ts b/src/tests/e2e/loom-provider-2/loom-provider-tests.ts similarity index 98% rename from src/tests/e2e/loom-provider-2-tests.ts rename to src/tests/e2e/loom-provider-2/loom-provider-tests.ts index dd4589d6..04c22a00 100644 --- a/src/tests/e2e/loom-provider-2-tests.ts +++ b/src/tests/e2e/loom-provider-2/loom-provider-tests.ts @@ -1,10 +1,10 @@ import test from 'tape' -import { LocalAddress, CryptoUtils } from '../../index' -import { createTestClient, execAndWaitForMillisecondsAsync, getTestUrls } from '../helpers' -import { LoomProvider } from '../../loom-provider' -import { deployContract } from '../evm-helpers' -import { LoomProvider2 } from '../../loom-provider-2' +import { LocalAddress, CryptoUtils } from '../../../index' +import { createTestClient, execAndWaitForMillisecondsAsync, getTestUrls } from '../../helpers' +import { LoomProvider } from '../../../loom-provider' +import { deployContract } from '../../evm-helpers' +import { LoomProvider2 } from '../../../loom-provider-2' /** * Requires the SimpleStore solidity contract deployed on a loomchain. diff --git a/src/tests/e2e/loom-provider-web3-child-events.ts b/src/tests/e2e/loom-provider-2/loom-provider-web3-child-events.ts similarity index 100% rename from src/tests/e2e/loom-provider-web3-child-events.ts rename to src/tests/e2e/loom-provider-2/loom-provider-web3-child-events.ts diff --git a/src/tests/e2e/loom-provider-2-web3-tests.ts b/src/tests/e2e/loom-provider-2/loom-provider-web3-tests.ts similarity index 97% rename from src/tests/e2e/loom-provider-2-web3-tests.ts rename to src/tests/e2e/loom-provider-2/loom-provider-web3-tests.ts index 2bb5fc83..74211c16 100644 --- a/src/tests/e2e/loom-provider-2-web3-tests.ts +++ b/src/tests/e2e/loom-provider-2/loom-provider-web3-tests.ts @@ -1,9 +1,9 @@ import test from 'tape' -import { waitForMillisecondsAsync, getTestUrls } from '../helpers' +import { waitForMillisecondsAsync, getTestUrls } from '../../helpers' -import { deployContract2 } from '../evm-helpers' +import { deployContract2 } from '../../evm-helpers' import Web3 from 'web3' -import { LoomProvider2 } from '../../loom-provider-2' +import { LoomProvider2 } from '../../../loom-provider-2' /** * Requires the SimpleStore solidity contract deployed on a loomchain. diff --git a/src/tests/e2e/multiple-events-nd-tests.ts b/src/tests/e2e/loom-provider-2/multiple-events-nd-tests.ts similarity index 100% rename from src/tests/e2e/multiple-events-nd-tests.ts rename to src/tests/e2e/loom-provider-2/multiple-events-nd-tests.ts diff --git a/src/tests/e2e/loom-provider-eth-filters.ts b/src/tests/e2e/loom-provider/loom-provider-eth-filters.ts similarity index 96% rename from src/tests/e2e/loom-provider-eth-filters.ts rename to src/tests/e2e/loom-provider/loom-provider-eth-filters.ts index 34e633e7..ad735752 100644 --- a/src/tests/e2e/loom-provider-eth-filters.ts +++ b/src/tests/e2e/loom-provider/loom-provider-eth-filters.ts @@ -1,9 +1,9 @@ import test from 'tape' -import { CryptoUtils } from '../../index' -import { createTestClient, execAndWaitForMillisecondsAsync } from '../helpers' -import { LoomProvider } from '../../loom-provider' -import { deployContract } from '../evm-helpers' +import { CryptoUtils } from '../../../index' +import { createTestClient, execAndWaitForMillisecondsAsync } from '../../helpers' +import { LoomProvider } from '../../../loom-provider' +import { deployContract } from '../../evm-helpers' /** * Requires the SimpleStore solidity contract deployed on a loomchain. diff --git a/src/tests/e2e/loom-provider-eth-get-logs.ts b/src/tests/e2e/loom-provider/loom-provider-eth-get-logs.ts similarity index 95% rename from src/tests/e2e/loom-provider-eth-get-logs.ts rename to src/tests/e2e/loom-provider/loom-provider-eth-get-logs.ts index 57383a61..1af00b6c 100644 --- a/src/tests/e2e/loom-provider-eth-get-logs.ts +++ b/src/tests/e2e/loom-provider/loom-provider-eth-get-logs.ts @@ -1,10 +1,10 @@ import test from 'tape' -import { LocalAddress, CryptoUtils } from '../../index' -import { createTestClient, execAndWaitForMillisecondsAsync } from '../helpers' -import { LoomProvider } from '../../loom-provider' -import { deployContract } from '../evm-helpers' -import { numberToHex } from '../../crypto-utils' +import { LocalAddress, CryptoUtils } from '../../../index' +import { createTestClient, execAndWaitForMillisecondsAsync } from '../../helpers' +import { LoomProvider } from '../../../loom-provider' +import { deployContract } from '../../evm-helpers' +import { numberToHex } from '../../../crypto-utils' /** * Requires the SimpleStore solidity contract deployed on a loomchain. diff --git a/src/tests/e2e/loom-provider-subscribe.ts b/src/tests/e2e/loom-provider/loom-provider-subscribe.ts similarity index 95% rename from src/tests/e2e/loom-provider-subscribe.ts rename to src/tests/e2e/loom-provider/loom-provider-subscribe.ts index abb412ed..2c370aa1 100644 --- a/src/tests/e2e/loom-provider-subscribe.ts +++ b/src/tests/e2e/loom-provider/loom-provider-subscribe.ts @@ -1,9 +1,9 @@ import test from 'tape' -import { LocalAddress, CryptoUtils } from '../../index' -import { createTestClient, execAndWaitForMillisecondsAsync } from '../helpers' -import { LoomProvider } from '../../loom-provider' -import { deployContract } from '../evm-helpers' +import { LocalAddress, CryptoUtils } from '../../../index' +import { createTestClient, execAndWaitForMillisecondsAsync } from '../../helpers' +import { LoomProvider } from '../../../loom-provider' +import { deployContract } from '../../evm-helpers' /** * Requires the SimpleStore solidity contract deployed on a loomchain. diff --git a/src/tests/e2e/loom-provider-tests.ts b/src/tests/e2e/loom-provider/loom-provider-tests.ts similarity index 98% rename from src/tests/e2e/loom-provider-tests.ts rename to src/tests/e2e/loom-provider/loom-provider-tests.ts index 4ce1a3bf..c0a9640e 100644 --- a/src/tests/e2e/loom-provider-tests.ts +++ b/src/tests/e2e/loom-provider/loom-provider-tests.ts @@ -1,17 +1,17 @@ import test from 'tape' import BN from 'bn.js' -import { LocalAddress, CryptoUtils } from '../../index' +import { LocalAddress, CryptoUtils } from '../../../index' import { createTestClient, execAndWaitForMillisecondsAsync, waitForMillisecondsAsync -} from '../helpers' -import { LoomProvider } from '../../loom-provider' -import { deployContract } from '../evm-helpers' +} from '../../helpers' +import { LoomProvider } from '../../../loom-provider' +import { deployContract } from '../../evm-helpers' import { ecrecover, privateToPublic, fromRpcSig, toBuffer } from 'ethereumjs-util' -import { soliditySha3 } from '../../solidity-helpers' -import { bytesToHexAddr } from '../../crypto-utils' +import { soliditySha3 } from '../../../solidity-helpers' +import { bytesToHexAddr } from '../../../crypto-utils' /** * Requires the SimpleStore solidity contract deployed on a loomchain. diff --git a/src/tests/e2e/loom-provider/loom-provider-web3-child-events.ts b/src/tests/e2e/loom-provider/loom-provider-web3-child-events.ts new file mode 100644 index 00000000..8e94d5e1 --- /dev/null +++ b/src/tests/e2e/loom-provider/loom-provider-web3-child-events.ts @@ -0,0 +1,181 @@ +import test, { Test } from 'tape' + +import { LocalAddress, CryptoUtils } from '../../../index' +import { createTestClient, waitForMillisecondsAsync } from '../../helpers' + +import { LoomProvider } from '../../../loom-provider' +import { deployContract } from '../../evm-helpers' + +const Web3 = require('web3') + +/** + * Requires the SimpleStore solidity contract deployed on a loomchain. + * go-loom/examples/plugins/evmexample/contract/SimpleStore.sol + * + * pragma solidity 0.4.24; + * + * interface ContractB { + * function callEvent(uint256 v) external; + * } + * + * contract ContractA { + * event ContractAEvent(uint256 v); + * + * function doEmit(uint256 _v, address _contractBAddr) public { + * emit ContractAEvent(_v); + * ContractB(_contractBAddr).callEvent(_v); + * } + * } + * + * pragma solidity 0.4.24; + * + * contract ContractB { + * event ContractBEvent(uint256 v); + * + * function callEvent(uint256 _v) public { + * emit ContractBEvent(_v); + * } + * } + * + */ + +function contractABIAndBinary() { + const contractBData = + '6080604052348015600f57600080fd5b5060db8061001e6000396000f300608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063f88d0dfc146044575b600080fd5b348015604f57600080fd5b50606c60048036038101908080359060200190929190505050606e565b005b806000819055507f8611c0f1e10aa104c81817ff1befe6e3677acee7991f16f99a8c375ca0793120816040518082815260200191505060405180910390a1505600a165627a7a723058203819249ad266695de9c923df5f4b3d2b244d3f6ba4297db60b92c4955bec2c230029' + + const contractAData = + '608060405234801561001057600080fd5b50610181806100206000396000f300608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063a045846314610046575b600080fd5b34801561005257600080fd5b5061009160048036038101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610093565b005b7fbb6ecd3f0ef42d655786d77b262f49bee128d78f171832c1ea73b1383674c23a826040518082815260200191505060405180910390a18073ffffffffffffffffffffffffffffffffffffffff1663f88d0dfc836040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b15801561013957600080fd5b505af115801561014d573d6000803e3d6000fd5b5050505050505600a165627a7a72305820101762f1d82f0bc7e12cf1b12098f2dfda892ad477dfd98760c2efab436ae3600029' + + const ABIContractB = [ + { + constant: false, + inputs: [{ name: '_v', type: 'uint256' }], + name: 'callEvent', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + anonymous: false, + inputs: [{ indexed: false, name: 'v', type: 'uint256' }], + name: 'ContractBEvent', + type: 'event' + } + ] + + const ABIContractA = [ + { + constant: false, + inputs: [{ name: '_v', type: 'uint256' }, { name: '_contractBAddr', type: 'address' }], + name: 'doEmit', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + anonymous: false, + inputs: [{ indexed: false, name: 'v', type: 'uint256' }], + name: 'ContractAEvent', + type: 'event' + } + ] + + return { contractBData, contractAData, ABIContractB, ABIContractA } +} + +async function testContracts(t: Test, contractB: any, contractA: any) { + try { + const value = 5 + + contractA.events.ContractAEvent({}, (_err: Error, event: any) => { + t.equal(event.returnValues.v, '5', 'Value returned should be 5') + }) + + contractB.events.ContractBEvent({}, (_err: Error, event: any) => { + t.equal(event.returnValues.v, '5', 'Value returned should be 5') + }) + + let tx = await contractA.methods.doEmit(value, contractB.options.address).send() + t.equal( + tx.status === true ? true : tx.status, + true, + `doEmit should return correct status for ${value}` + ) + + await waitForMillisecondsAsync(1000) + } catch (err) { + console.log(err) + } +} + +async function deployContractGanache(web3Provider: any, contractData: string) { + const web3 = new Web3(web3Provider) + const fromAddr = '0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1' + + const ethSendTransactionDeployResult = await web3.eth.sendTransaction({ + from: fromAddr, + data: contractData, + gas: '300000', + gasPrice: '0x1' + }) + + if (!ethSendTransactionDeployResult.status) { + throw Error('Cant deploy contract on ganache') + } + + const ethGetTransactionReceiptResult = await web3.eth.getTransactionReceipt( + ethSendTransactionDeployResult.transactionHash + ) + + return ethGetTransactionReceiptResult +} + +async function testGanache(t: Test) { + const from = '0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1' + + const websocketProvider = new Web3.providers.WebsocketProvider('ws://127.0.0.1:8545') + const web3 = new Web3(websocketProvider) + + const { contractBData, contractAData, ABIContractB, ABIContractA } = contractABIAndBinary() + + const resultB = await deployContractGanache(websocketProvider, contractBData) + const resultA = await deployContractGanache(websocketProvider, contractAData) + + const contractB = new web3.eth.Contract(ABIContractB, resultB.contractAddress, { from }) + const contractA = new web3.eth.Contract(ABIContractA, resultA.contractAddress, { from }) + + t.comment('Testing Ganache') + await testContracts(t, contractB, contractA) + + web3.currentProvider.connection.close() +} + +async function testLoomProvider(t: Test) { + const privKey = CryptoUtils.generatePrivateKey() + const client = createTestClient() + const from = LocalAddress.fromPublicKey(CryptoUtils.publicKeyFromPrivateKey(privKey)).toString() + const loomProvider = new LoomProvider(client, privKey) + const web3 = new Web3(loomProvider) + + const { contractBData, contractAData, ABIContractB, ABIContractA } = contractABIAndBinary() + + const resultB = await deployContract(loomProvider, contractBData) + const resultA = await deployContract(loomProvider, contractAData) + + const contractB = new web3.eth.Contract(ABIContractB, resultB.contractAddress, { from }) + const contractA = new web3.eth.Contract(ABIContractA, resultA.contractAddress, { from }) + + t.comment('Testing Loom Provider') + await testContracts(t, contractB, contractA) + + client.disconnect() +} + +test('LoomProvider + Web3 + Child contracts events', async t => { + t.plan(6) + await testGanache(t) + await testLoomProvider(t) + t.end() +}) diff --git a/src/tests/e2e/loom-provider-web3-middlewares-tests.ts b/src/tests/e2e/loom-provider/loom-provider-web3-middlewares-tests.ts similarity index 90% rename from src/tests/e2e/loom-provider-web3-middlewares-tests.ts rename to src/tests/e2e/loom-provider/loom-provider-web3-middlewares-tests.ts index 4776cac1..b2cd82fe 100644 --- a/src/tests/e2e/loom-provider-web3-middlewares-tests.ts +++ b/src/tests/e2e/loom-provider/loom-provider-web3-middlewares-tests.ts @@ -1,13 +1,13 @@ import test from 'tape' -import { LocalAddress, CryptoUtils, Client } from '../../index' -import { createTestClient, waitForMillisecondsAsync } from '../helpers' - -import { LoomProvider } from '../../loom-provider' -import { deployContract } from '../evm-helpers' -import { SignedTxMiddleware } from '../../middleware' -import { ITxMiddlewareHandler } from '../../client' -import { NonceTx } from '../../proto/loom_pb' +import { LocalAddress, CryptoUtils, Client } from '../../../index' +import { createTestClient, waitForMillisecondsAsync } from '../../helpers' + +import { LoomProvider } from '../../../loom-provider' +import { deployContract } from '../../evm-helpers' +import { SignedTxMiddleware } from '../../../middleware' +import { ITxMiddlewareHandler } from '../../../client' +import { NonceTx } from '../../../proto/loom_pb' // import Web3 from 'web3' const Web3 = require('web3') diff --git a/src/tests/e2e/loom-provider-web3-tests.ts b/src/tests/e2e/loom-provider/loom-provider-web3-tests.ts similarity index 96% rename from src/tests/e2e/loom-provider-web3-tests.ts rename to src/tests/e2e/loom-provider/loom-provider-web3-tests.ts index c7d10953..99f19881 100644 --- a/src/tests/e2e/loom-provider-web3-tests.ts +++ b/src/tests/e2e/loom-provider/loom-provider-web3-tests.ts @@ -1,14 +1,14 @@ import test from 'tape' import BN from 'bn.js' -import { LocalAddress, CryptoUtils } from '../../index' -import { createTestClient, waitForMillisecondsAsync } from '../helpers' +import { LocalAddress, CryptoUtils } from '../../../index' +import { createTestClient, waitForMillisecondsAsync } from '../../helpers' -import { LoomProvider } from '../../loom-provider' -import { deployContract } from '../evm-helpers' +import { LoomProvider } from '../../../loom-provider' +import { deployContract } from '../../evm-helpers' import { ecrecover, privateToPublic, fromRpcSig } from 'ethereumjs-util' -import { soliditySha3 } from '../../solidity-helpers' -import { bytesToHexAddr } from '../../crypto-utils' +import { soliditySha3 } from '../../../solidity-helpers' +import { bytesToHexAddr } from '../../../crypto-utils' // import Web3 from 'web3' const Web3 = require('web3') diff --git a/src/tests/e2e/loom-provider/multiple-events-nd-tests.ts b/src/tests/e2e/loom-provider/multiple-events-nd-tests.ts new file mode 100644 index 00000000..ba81c5a3 --- /dev/null +++ b/src/tests/e2e/loom-provider/multiple-events-nd-tests.ts @@ -0,0 +1,293 @@ +import test from 'tape' + +import { LocalAddress, CryptoUtils } from '../../../index' +import { createTestClient, waitForMillisecondsAsync } from '../../helpers' + +import { LoomProvider } from '../../../loom-provider' +import { deployContract } from '../../evm-helpers' + +const Web3 = require('web3') + +/** + * pragma solidity ^0.4.24; + * + * import "openzeppelin-solidity/contracts/token/ERC721/ERC721Token.sol"; + * + * contract CryptoCardsDappChain is ERC721Token { + * event CreateCard(address _user, uint256 _tokenId); + * + * constructor() ERC721Token("CryptoCardsDappChain", "CRC") public { } + * + * // Parent contract ER721Token should emit Transfer + * function mint() public { + * uint256 tokenId = allTokens.length; + * + * // Event emitting + * emit CreateCard(msg.sender, tokenId); + * + * // Event Transfer isn't emitted + * super._mint(msg.sender, tokenId); + * } + * } + * + */ + +const newContractAndClient = async () => { + const privKey = CryptoUtils.generatePrivateKey() + const client = createTestClient() + const from = LocalAddress.fromPublicKey(CryptoUtils.publicKeyFromPrivateKey(privKey)).toString() + const loomProvider = new LoomProvider(client, privKey) + const web3 = new Web3(loomProvider) + + const contractData = + '0x60806040523480156200001157600080fd5b506040805190810160405280601481526020017f43727970746f436172647344617070436861696e0000000000000000000000008152506040805190810160405280600381526020017f4352430000000000000000000000000000000000000000000000000000000000815250816004908051906020019062000096929190620000b8565b508060059080519060200190620000af929190620000b8565b50505062000167565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620000fb57805160ff19168380011785556200012c565b828001600101855582156200012c579182015b828111156200012b5782518255916020019190600101906200010e565b5b5090506200013b91906200013f565b5090565b6200016491905b808211156200016057600081600090555060010162000146565b5090565b90565b611d0580620001776000396000f3006080604052600436106100f1576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100f6578063081812fc14610186578063095ea7b3146101f35780631249c58b1461024057806318160ddd1461025757806323b872dd146102825780632f745c59146102ef57806342842e0e146103505780634f558e79146103bd5780634f6ccce7146104025780636352211e1461044357806370a08231146104b057806395d89b4114610507578063a22cb46514610597578063b88d4fde146105e6578063c87b56dd14610699578063e985e9c51461073f575b600080fd5b34801561010257600080fd5b5061010b6107ba565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561014b578082015181840152602081019050610130565b50505050905090810190601f1680156101785780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561019257600080fd5b506101b16004803603810190808035906020019092919050505061085c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156101ff57600080fd5b5061023e600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610899565b005b34801561024c57600080fd5b50610255610a5f565b005b34801561026357600080fd5b5061026c610ae1565b6040518082815260200191505060405180910390f35b34801561028e57600080fd5b506102ed600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610aee565b005b3480156102fb57600080fd5b5061033a600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610c05565b6040518082815260200191505060405180910390f35b34801561035c57600080fd5b506103bb600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610c7c565b005b3480156103c957600080fd5b506103e860048036038101908080359060200190929190505050610cb4565b604051808215151515815260200191505060405180910390f35b34801561040e57600080fd5b5061042d60048036038101908080359060200190929190505050610d25565b6040518082815260200191505060405180910390f35b34801561044f57600080fd5b5061046e60048036038101908080359060200190929190505050610d5d565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156104bc57600080fd5b506104f1600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610dda565b6040518082815260200191505060405180910390f35b34801561051357600080fd5b5061051c610e5e565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561055c578082015181840152602081019050610541565b50505050905090810190601f1680156105895780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156105a357600080fd5b506105e4600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050610f00565b005b3480156105f257600080fd5b50610697600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929050505061103c565b005b3480156106a557600080fd5b506106c46004803603810190808035906020019092919050505061107b565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156107045780820151818401526020810190506106e9565b50505050905090810190601f1680156107315780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561074b57600080fd5b506107a0600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611144565b604051808215151515815260200191505060405180910390f35b606060048054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156108525780601f1061082757610100808354040283529160200191610852565b820191906000526020600020905b81548152906001019060200180831161083557829003601f168201915b5050505050905090565b60006001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006108a482610d5d565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141515156108e157600080fd5b8073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061092157506109208133611144565b5b151561092c57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff1661094d8361085c565b73ffffffffffffffffffffffffffffffffffffffff1614158061099d5750600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b15610a5a57826001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a35b505050565b600060088054905090507f12b2a00a98b1c020d242fccd2fac74dd465b5e601631abd612d151d7fe74dfea3382604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a1610ade33826111d8565b50565b6000600880549050905090565b80610af9338261122f565b1515610b0457600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614151515610b4057600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614151515610b7c57600080fd5b610b8684836112c4565b610b90848361142d565b610b9a8383611645565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a350505050565b6000610c1083610dda565b82101515610c1d57600080fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002082815481101515610c6957fe5b9060005260206000200154905092915050565b80610c87338261122f565b1515610c9257600080fd5b610cae848484602060405190810160405280600081525061103c565b50505050565b60008060008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415915050919050565b6000610d2f610ae1565b82101515610d3c57600080fd5b600882815481101515610d4b57fe5b90600052602060002001549050919050565b60008060008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515610dd157600080fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614151515610e1757600080fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b606060058054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610ef65780601f10610ecb57610100808354040283529160200191610ef6565b820191906000526020600020905b815481529060010190602001808311610ed957829003601f168201915b5050505050905090565b3373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614151515610f3b57600080fd5b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051808215151515815260200191505060405180910390a35050565b81611047338261122f565b151561105257600080fd5b61105d858585610aee565b6110698585858561171c565b151561107457600080fd5b5050505050565b606061108682610cb4565b151561109157600080fd5b600a60008381526020019081526020016000208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156111385780601f1061110d57610100808354040283529160200191611138565b820191906000526020600020905b81548152906001019060200180831161111b57829003601f168201915b50505050509050919050565b6000600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6111e2828261190a565b600880549050600960008381526020019081526020016000208190555060088190806001815401808255809150509060018203906000526020600020016000909192909190915055505050565b60008061123b83610d5d565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806112aa57508373ffffffffffffffffffffffffffffffffffffffff166112928461085c565b73ffffffffffffffffffffffffffffffffffffffff16145b806112bb57506112ba8185611144565b5b91505092915050565b8173ffffffffffffffffffffffffffffffffffffffff166112e482610d5d565b73ffffffffffffffffffffffffffffffffffffffff1614151561130657600080fd5b600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415156114295760006001600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a35b5050565b600080600061143c85856119ba565b600760008581526020019081526020016000205492506114a86001600660008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050611ae890919063ffffffff16565b9150600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020828154811015156114f657fe5b9060005260206000200154905080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208481548110151561155057fe5b90600052602060002001819055506000600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020838154811015156115ac57fe5b9060005260206000200181905550600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080548091906001900361160c9190611c88565b50600060076000868152602001908152602001600020819055508260076000838152602001908152602001600020819055505050505050565b60006116518383611b01565b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020829080600181540180825580915050906001820390600052602060002001600090919290919091505550806007600084815260200190815260200160002081905550505050565b60008061173e8573ffffffffffffffffffffffffffffffffffffffff16611c59565b151561174d5760019150611901565b8473ffffffffffffffffffffffffffffffffffffffff1663f0b9e5ba8786866040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561180f5780820151818401526020810190506117f4565b50505050905090810190601f16801561183c5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b15801561185d57600080fd5b505af1158015611871573d6000803e3d6000fd5b505050506040513d602081101561188757600080fd5b8101908080519060200190929190505050905063f0b9e5ba7c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505b50949350505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415151561194657600080fd5b6119508282611645565b8173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff166119da82610d5d565b73ffffffffffffffffffffffffffffffffffffffff161415156119fc57600080fd5b611a4f6001600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611ae890919063ffffffff16565b600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600080600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6000828211151515611af657fe5b818303905092915050565b600073ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515611b6e57600080fd5b8160008083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611c126001600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611c6c90919063ffffffff16565b600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505050565b600080823b905060008111915050919050565b60008183019050828110151515611c7f57fe5b80905092915050565b815481835581811115611caf57818360005260206000209182019101611cae9190611cb4565b5b505050565b611cd691905b80821115611cd2576000816000905550600101611cba565b5090565b905600a165627a7a72305820640a56be705b9ad59a60a1c07599ef587b2f04a503bc6d1318f90a2fb24c03220029' + + const ABI = [ + { + constant: true, + inputs: [], + name: 'name', + outputs: [{ name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [{ name: '_tokenId', type: 'uint256' }], + name: 'getApproved', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [{ name: '_to', type: 'address' }, { name: '_tokenId', type: 'uint256' }], + name: 'approve', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + { name: '_tokenId', type: 'uint256' } + ], + name: 'transferFrom', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [{ name: '_owner', type: 'address' }, { name: '_index', type: 'uint256' }], + name: 'tokenOfOwnerByIndex', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [ + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + { name: '_tokenId', type: 'uint256' } + ], + name: 'safeTransferFrom', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [{ name: '_tokenId', type: 'uint256' }], + name: 'exists', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [{ name: '_index', type: 'uint256' }], + name: 'tokenByIndex', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [{ name: '_tokenId', type: 'uint256' }], + name: 'ownerOf', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [{ name: '_owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [{ name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: false, + inputs: [{ name: '_to', type: 'address' }, { name: '_approved', type: 'bool' }], + name: 'setApprovalForAll', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: false, + inputs: [ + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + { name: '_tokenId', type: 'uint256' }, + { name: '_data', type: 'bytes' } + ], + name: 'safeTransferFrom', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + }, + { + constant: true, + inputs: [{ name: '_tokenId', type: 'uint256' }], + name: 'tokenURI', + outputs: [{ name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { + constant: true, + inputs: [{ name: '_owner', type: 'address' }, { name: '_operator', type: 'address' }], + name: 'isApprovedForAll', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function' + }, + { inputs: [], payable: false, stateMutability: 'nonpayable', type: 'constructor' }, + { + anonymous: false, + inputs: [ + { indexed: false, name: '_user', type: 'address' }, + { indexed: false, name: '_tokenId', type: 'uint256' } + ], + name: 'CreateCard', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { indexed: true, name: '_from', type: 'address' }, + { indexed: true, name: '_to', type: 'address' }, + { indexed: false, name: '_tokenId', type: 'uint256' } + ], + name: 'Transfer', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { indexed: true, name: '_owner', type: 'address' }, + { indexed: true, name: '_approved', type: 'address' }, + { indexed: false, name: '_tokenId', type: 'uint256' } + ], + name: 'Approval', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { indexed: true, name: '_owner', type: 'address' }, + { indexed: true, name: '_operator', type: 'address' }, + { indexed: false, name: '_approved', type: 'bool' } + ], + name: 'ApprovalForAll', + type: 'event' + }, + { + constant: false, + inputs: [], + name: 'mint', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + } + ] + + const result = await deployContract(loomProvider, contractData) + + const contract = new web3.eth.Contract(ABI, result.contractAddress, { from }) + + return { + contract, + client + } +} + +test('LoomProvider + Web3', async t => { + t.plan(3) // EXPECTS 3 ASSERTIONS + const { contract, client } = await newContractAndClient() + + try { + contract.events.Transfer({}, (err: any, event: any) => { + t.assert(!err) + }) + + contract.events.CreateCard({}, (err: any, event: any) => { + t.assert(!err) + }) + + await contract.methods.mint().send() + + const totalSupply = await contract.methods.totalSupply().call() + + t.assert(totalSupply === '1', 'Total Supply eq 1') + + await waitForMillisecondsAsync(3000) + } catch (err) { + console.log(err) + } + + if (client) { + client.disconnect() + } + + t.end() +}) diff --git a/src/tests/e2e/binance-test-tx-middleware.ts b/src/tests/e2e/middlewares/binance-test-tx-middleware.ts similarity index 100% rename from src/tests/e2e/binance-test-tx-middleware.ts rename to src/tests/e2e/middlewares/binance-test-tx-middleware.ts diff --git a/src/tests/e2e/client-test-tx-cache.ts b/src/tests/e2e/middlewares/client-test-tx-cache.ts similarity index 100% rename from src/tests/e2e/client-test-tx-cache.ts rename to src/tests/e2e/middlewares/client-test-tx-cache.ts diff --git a/src/tests/e2e/client-test-tx-middleware.ts b/src/tests/e2e/middlewares/client-test-tx-middleware.ts similarity index 100% rename from src/tests/e2e/client-test-tx-middleware.ts rename to src/tests/e2e/middlewares/client-test-tx-middleware.ts diff --git a/src/tests/e2e/tron-test-tx-middleware.ts b/src/tests/e2e/middlewares/tron-test-tx-middleware.ts similarity index 100% rename from src/tests/e2e/tron-test-tx-middleware.ts rename to src/tests/e2e/middlewares/tron-test-tx-middleware.ts diff --git a/src/tests/e2e_tests.ts b/src/tests/e2e_tests.ts index 2d9ccc5c..4ad0c7f1 100644 --- a/src/tests/e2e_tests.ts +++ b/src/tests/e2e_tests.ts @@ -2,41 +2,40 @@ // import './e2e/ws-rpc-client-tests' // // Loom Provider -// import './e2e/loom-provider-tests' -// import './e2e/loom-provider-eth-get-logs' -// import './e2e/loom-provider-eth-filters' -// import './e2e/loom-provider-eth-filters-2' -// import './e2e/loom-provider-subscribe' -// import './e2e/loom-provider-web3-tests' -// import './e2e/loom-provider-web3-middlewares-tests' -// import './e2e/loom-provider-web3-child-events' +// import './e2e/loom-provider/loom-provider-tests' +// import './e2e/loom-provider/loom-provider-web3-tests' +// import './e2e/loom-provider/loom-provider-eth-get-logs' +// import './e2e/loom-provider/loom-provider-eth-filters' +// import './e2e/loom-provider/loom-provider-subscribe' +// import './e2e/loom-provider/loom-provider-web3-middlewares-tests' +// import './e2e/loom-provider/loom-provider-web3-child-events' +// import './e2e/loom-provider/multiple-events-nd-tests' // Loom Provider 2 -import './e2e/loom-provider-2-tests' -import './e2e/loom-provider-2-web3-tests' +// import './e2e/loom-provider-2/loom-provider-eth-filters' +// import './e2e/loom-provider-2/loom-provider-eth-get-logs' +import './e2e/loom-provider-2/loom-provider-subscribe' +// import './e2e/loom-provider-2/loom-provider-tests' +// import './e2e/loom-provider-2/loom-provider-web3-child-events' +// import './e2e/loom-provider-2/loom-provider-web3-tests' +// import './e2e/loom-provider-2/multiple-events-nd-tests' // // EVM -// import './e2e/client-evm-tests' -// import './e2e/client-evm-event-tests' -// import './e2e/client-evm-event-tests-2' +// import './e2e/evm/client-evm-tests' +// import './e2e/evm/client-evm-event-tests' +// import './e2e/evm/client-evm-event-tests-2' +// import './e2e/evm/evm-contract-tests' // // Middlewares -// import './e2e/client-test-tx-cache' -// import './e2e/client-test-tx-middleware' -// import './e2e/tron-test-tx-middleware' -// import './e2e/binance-test-tx-middleware' - -// // Events -// import './e2e/multiple-events-nd-tests' +// import './e2e/middlewares/client-test-tx-cache' +// import './e2e/middlewares/client-test-tx-middleware' +// import './e2e/middlewares/tron-test-tx-middleware' +// import './e2e/middlewares/binance-test-tx-middleware' // // Contracts -// import './e2e/coin-tests' -// import './e2e/address-mapper-tests' -// // TODO: Re-enable once this is updated to DPOSv2 -// //import './e2e/dpos-tests' +// import './e2e/contracts/coin-tests' +// import './e2e/contracts/address-mapper-tests' +// import './e2e/contracts/contract-tests' -// // Weave Blueprint Contract -// import './e2e/contract-tests' - -// // Simple Store Contract -// import './e2e/evm-contract-tests' +// // TODO: Re-enable once this is updated to DPOSv2 +// //import './e2e/contracts/dpos-tests'