Skip to content

Test for fix "Do not emitting same event twice on same function call" #194

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis_e2e_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ set -euxo pipefail

eval "$(GIMME_GO_VERSION=1.10.2 gimme)"

export BUILD_ID=build-1283
export BUILD_ID=build-1309

bash e2e_tests.sh

Expand Down
220 changes: 200 additions & 20 deletions src/tests/e2e/loom-provider-web3-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,31 @@ const Web3 = require('web3')
*
* contract SimpleStore {
* uint value;
*
* constructor() public {
* value = 10;
* }
*
* event NewValueSet(uint indexed _value);
* event NewValueSetAgain(uint indexed _value);
*
* function set(uint _value) public {
* value = _value;
* emit NewValueSet(value);
* }
*
* function setTwiceEvent(uint _value) public {
* value = _value;
* emit NewValueSet(_value);
* emit NewValueSet(_value + 1);
* }
*
* function setTwiceEvent2(uint _value) public {
* value = _value;
* emit NewValueSet(_value);
* emit NewValueSetAgain(_value);
* }
*
* function get() public view returns (uint) {
* return value;
* }
Expand All @@ -47,15 +61,32 @@ const newContractAndClient = async (useEthEndpoint: boolean) => {
const loomProvider = new LoomProvider(client, privKey)
const web3 = new Web3(loomProvider)

client.on('error', console.log)

const contractData =
'0x608060405234801561001057600080fd5b50600a60008190555061010e806100286000396000f3006080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c146078575b600080fd5b348015605957600080fd5b5060766004803603810190808035906020019092919050505060a0565b005b348015608357600080fd5b50608a60d9565b6040518082815260200191505060405180910390f35b806000819055506000547fb922f092a64f1a076de6f21e4d7c6400b6e55791cc935e7bb8e7e90f7652f15b60405160405180910390a250565b600080549050905600a165627a7a72305820b76f6c855a1f95260fc70490b16774074225da52ea165a58e95eb7a72a59d1700029'
'608060405234801561001057600080fd5b50600a600081905550610252806100286000396000f300608060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063076a66cc1461006757806360fe47b1146100945780636d4ce63c146100c1578063bd6c8f7e146100ec575b600080fd5b34801561007357600080fd5b5061009260048036038101908080359060200190929190505050610119565b005b3480156100a057600080fd5b506100bf60048036038101908080359060200190929190505050610180565b005b3480156100cd57600080fd5b506100d66101b9565b6040518082815260200191505060405180910390f35b3480156100f857600080fd5b50610117600480360381019080803590602001909291905050506101c2565b005b80600081905550807fb922f092a64f1a076de6f21e4d7c6400b6e55791cc935e7bb8e7e90f7652f15b60405160405180910390a2600181017fb922f092a64f1a076de6f21e4d7c6400b6e55791cc935e7bb8e7e90f7652f15b60405160405180910390a250565b806000819055506000547fb922f092a64f1a076de6f21e4d7c6400b6e55791cc935e7bb8e7e90f7652f15b60405160405180910390a250565b60008054905090565b80600081905550807fb922f092a64f1a076de6f21e4d7c6400b6e55791cc935e7bb8e7e90f7652f15b60405160405180910390a2807fc151b22f26f815d64ae384647d49bc5655149c4b273318d8c3846086dae3835e60405160405180910390a2505600a165627a7a72305820a3a8ef0c6359500fe8c7b5fdc5b7e94c9cd31b38de83955ddff22304320b97340029'

const ABI = [
{
constant: false,
inputs: [{ name: '_value', type: 'uint256' }],
inputs: [
{
name: '_value',
type: 'uint256'
}
],
name: 'setTwiceEvent',
outputs: [],
payable: false,
stateMutability: 'nonpayable',
type: 'function'
},
{
constant: false,
inputs: [
{
name: '_value',
type: 'uint256'
}
],
name: 'set',
outputs: [],
payable: false,
Expand All @@ -66,17 +97,59 @@ const newContractAndClient = async (useEthEndpoint: boolean) => {
constant: true,
inputs: [],
name: 'get',
outputs: [{ name: '', type: 'uint256' }],
outputs: [
{
name: '',
type: 'uint256'
}
],
payable: false,
stateMutability: 'view',
type: 'function'
},
{ inputs: [], payable: false, stateMutability: 'nonpayable', type: 'constructor' },
{
constant: false,
inputs: [
{
name: '_value',
type: 'uint256'
}
],
name: 'setTwiceEvent2',
outputs: [],
payable: false,
stateMutability: 'nonpayable',
type: 'function'
},
{
inputs: [],
payable: false,
stateMutability: 'nonpayable',
type: 'constructor'
},
{
anonymous: false,
inputs: [{ indexed: true, name: '_value', type: 'uint256' }],
inputs: [
{
indexed: true,
name: '_value',
type: 'uint256'
}
],
name: 'NewValueSet',
type: 'event'
},
{
anonymous: false,
inputs: [
{
indexed: true,
name: '_value',
type: 'uint256'
}
],
name: 'NewValueSetAgain',
type: 'event'
}
]

Expand All @@ -95,7 +168,6 @@ async function testWeb3MismatchedTopic(t: any, useEthEndpoint: boolean) {
const newValue = 1

contract.events.NewValueSet({ filter: { _value: [4, 5] } }, (err: Error, event: any) => {
console.log(err, event)
if (err) t.error(err)
else {
t.fail('should not been dispatched')
Expand All @@ -110,7 +182,7 @@ async function testWeb3MismatchedTopic(t: any, useEthEndpoint: boolean) {

await waitForMillisecondsAsync(1000)
} catch (err) {
console.log(err)
t.fail(err)
}

if (client) {
Expand Down Expand Up @@ -138,7 +210,7 @@ async function testWeb3MultipleTopics(t: any, useEthEndpoint: boolean) {
const resultOfGet = await contract.methods.get().call()
t.equal(+resultOfGet, newValue, `SimpleStore.get should return correct value`)
} catch (err) {
console.log(err)
t.fail(err)
}

if (client) {
Expand Down Expand Up @@ -169,7 +241,7 @@ async function testWeb3Sign(t: any, useEthEndpoint: boolean) {
'Should pubKey from ecrecover be valid'
)
} catch (err) {
console.log(err)
t.fail(err)
}

if (client) {
Expand All @@ -190,7 +262,7 @@ async function testWeb3NetId(t: any, useEthEndpoint: boolean) {
const result = await web3.eth.net.getId()
t.equal(`${netVersionFromChainId}`, `${result}`, 'Should version match')
} catch (err) {
console.log(err)
t.fail(err)
}

if (client) {
Expand All @@ -206,7 +278,7 @@ async function testWeb3BlockNumber(t: any, useEthEndpoint: boolean) {
const blockNumber = await web3.eth.getBlockNumber()
t.assert(typeof blockNumber === 'number', 'Block number should be a number')
} catch (err) {
console.log(err)
t.fail(err)
}

if (client) {
Expand All @@ -223,7 +295,7 @@ async function testWeb3BlockByNumber(t: any, useEthEndpoint: boolean) {
const blockInfo = await web3.eth.getBlock(blockNumber, false)
t.equal(blockInfo.number, blockNumber, 'Block number should be equal')
} catch (err) {
console.log(err)
t.fail(err)
}

if (client) {
Expand Down Expand Up @@ -257,7 +329,7 @@ async function testWeb3GasPrice(t: any, useEthEndpoint: boolean) {
const gasPrice = await web3.eth.getGasPrice()
t.equal(gasPrice, null, "Gas price isn't used on Loomchain")
} catch (err) {
console.log(err)
t.fail(err)
}

if (client) {
Expand All @@ -273,7 +345,7 @@ async function testWeb3Balance(t: any, useEthEndpoint: boolean) {
const balance = await web3.eth.getBalance(from)
t.equal(balance, '0', 'Default balance is 0')
} catch (err) {
console.log(err)
t.fail(err)
}

if (client) {
Expand All @@ -289,7 +361,6 @@ async function testWeb3TransactionReceipt(t: any, useEthEndpoint: boolean) {
const newValue = 1

const tx = await contract.methods.set(newValue).send()
console.log('tx', tx)
// TODO: there is no blockTime property in tx.events.NewValueSet, it's a Loom extension that's
// not implemented on the /eth endpoint yet, re-enable this when we implement it again
if (!useEthEndpoint) {
Expand All @@ -300,7 +371,7 @@ async function testWeb3TransactionReceipt(t: any, useEthEndpoint: boolean) {

await waitForMillisecondsAsync(1000)
} catch (err) {
console.log(err)
t.fail(err)
}

if (client) {
Expand All @@ -322,7 +393,7 @@ async function testWeb3PastEvents(t: any, useEthEndpoint: boolean) {
const events = await contract.getPastEvents('NewValueSet', {
fromBlock: blockNum
})
console.log('events', events)

t.assert(events.length > 0, 'Should have more than 0 events')
// TODO: there is no blockTime property on Ethereum events, it's a Loom extension that's
// not implemented on the /eth endpoint yet, re-enable this when we implement it again
Expand All @@ -331,7 +402,107 @@ async function testWeb3PastEvents(t: any, useEthEndpoint: boolean) {
}
await waitForMillisecondsAsync(1000)
} catch (err) {
console.log(err)
t.fail(err)
}

if (client) {
client.disconnect()
}

t.end()
}

async function testWebEventsTwiceSameFunction(t: any, useEthEndpoint: boolean) {
// We're planning to execute 4 asserts
t.plan(4)

const { contract, client } = await newContractAndClient(useEthEndpoint)
try {
const newValue = 1
const eventValues = new Array<number>()
contract.events.NewValueSet({}, (err: Error, event: any) => {
if (err) t.error(err)
else {
// Assert 1
t.assert(
+event.returnValues._value >= 1,
`Value should be returned ${event.returnValues._value}`
)

eventValues.push(+event.returnValues._value)
}
})

const receipt = await contract.methods.setTwiceEvent(newValue).send()

// Assert 3
t.equal(receipt.status, true, 'SimpleStore.set should return correct status')

await waitForMillisecondsAsync(2000)

const eventSum = eventValues.reduce((acc, currValue) => acc + currValue)

// Assert 4
t.equal(eventSum, 3, `Sum of two events should be 3`)
} catch (err) {
t.fail(err)
}

if (client) {
client.disconnect()
}

t.end()
}

async function testWebTwoEventsSameFunction(t: any, useEthEndpoint: boolean) {
// We're planning to execute 4 asserts
t.plan(4)

const { contract, client } = await newContractAndClient(useEthEndpoint)
try {
const newValue = 1
const eventValues = new Array<number>()

contract.events.NewValueSet({}, (err: Error, event: any) => {
if (err) t.error(err)
else {
// Assert 1
t.assert(
+event.returnValues._value >= 1,
`Value should be returned ${event.returnValues._value}`
)

eventValues.push(+event.returnValues._value)
}
})

contract.events.NewValueSetAgain({}, (err: Error, event: any) => {
if (err) t.error(err)
else {
// Assert 1
t.assert(
+event.returnValues._value >= 1,
`Value should be returned ${event.returnValues._value}`
)

eventValues.push(+event.returnValues._value)
}
})

const receipt = await contract.methods.setTwiceEvent(newValue).send()

// Assert 3
t.equal(receipt.status, true, 'SimpleStore.set should return correct status')

await waitForMillisecondsAsync(2000)

const eventSum = eventValues.reduce((acc, currValue) => acc + currValue)

// Assert 4
t.equal(eventSum, 3, `Sum of two events should be 3`)
} catch (err) {
t.fail(err)
}

if (client) {
Expand Down Expand Up @@ -370,3 +541,12 @@ test('LoomProvider + Web3 + getTransactionReceipt (/eth)', (t: any) =>
testWeb3TransactionReceipt(t, true))
test('LoomProvider + Web3 + Logs (/query)', (t: any) => testWeb3PastEvents(t, false))
test('LoomProvider + Web3 + Logs (/eth)', (t: any) => testWeb3PastEvents(t, true))
test('LoomProvider + Web3 + Dispatch event twice same contract and function (/query)', (t: any) =>
testWebEventsTwiceSameFunction(t, false))
test('LoomProvider + Web3 + Dispatch event twice same contract and function (/eth)', (t: any) =>
testWebEventsTwiceSameFunction(t, true))

test('LoomProvider + Web3 + Dispatch two events on same function call (/query)', (t: any) =>
testWebTwoEventsSameFunction(t, false))
test('LoomProvider + Web3 + Dispatch two events on same function call (/eth)', (t: any) =>
testWebTwoEventsSameFunction(t, true))