From b15a34227d5469ccbf613555d87cb123466264e9 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Mon, 19 Aug 2019 15:34:22 -0400 Subject: [PATCH 1/2] support tracking function calls --- src/eventSyncer.js | 34 ++++++++ test/test3.js | 188 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 222 insertions(+) create mode 100644 test/test3.js diff --git a/src/eventSyncer.js b/src/eventSyncer.js index 56b64a7..b55304b 100644 --- a/src/eventSyncer.js +++ b/src/eventSyncer.js @@ -133,6 +133,40 @@ class EventSyncer { return sub; } + trackProperty(contractInstance, propName, filterConditionsOrCb) { + // let eventKey = propName + "-from0x123"; + let eventKey = propName; + let namespace = randomString() + + let filterConditions, filterConditionsCb; + if (typeof filterConditionsOrCb === 'function') { + filterConditionsCb = filterConditionsOrCb + } else { + filterConditions = filterConditionsOrCb + } + + let tracked = this.db.getCollection('tracked') + + let sub = new ReplaySubject(); + + let children = this.db.getCollection('children') + + // TODO: use call args from user + let method = contractInstance.methods[propName].apply(contractInstance.methods[propName], []) + + method.call.apply(method.call, [(filterConditions || {}), (err, result) => { + sub.next(result) + }]) + + var subscription = this.web3.eth.subscribe('newBlockHeaders', function (error, result) { + method.call.apply(method.call, [(filterConditions || {}), (err, result) => { + sub.next(result) + }]) + }) + + return sub; + } + } // process.on('exit', function () { diff --git a/test/test3.js b/test/test3.js new file mode 100644 index 0000000..5ea6bb1 --- /dev/null +++ b/test/test3.js @@ -0,0 +1,188 @@ +const { map, scan, last, distinctUntilChanged } = require('rxjs/operators'); +const Web3 = require('web3'); + +let web3 = new Web3("ws://localhost:8545"); + +let myscan = scan((acc, curr) => { + acc.push(curr); + if (acc.length > 4) { + acc.shift(); + } + return acc; +}, []) + +let mymap = map(arr => arr.reduce((acc, current) => acc + current, 0) / arr.length) + +async function deployContract() { + let accounts = await web3.eth.getAccounts(); + + // pragma solidity ^0.5.0; + // contract SimpleStorage { + // uint public storedData; + // event Test(uint indexed value); + // constructor(uint initialValue) public { + // storedData = initialValue; + // } + // function set(uint x) public { + // storedData = x; + // } + // function set2(uint x) public { + // storedData = x; + // emit Test(x); + // } + // function get() public view returns (uint retVal) { + // return storedData; + // } + // } + + let abi = [ + { + "constant": true, + "inputs": [], + "name": "storedData", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "x", + "type": "uint256" + } + ], + "name": "set", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "get", + "outputs": [ + { + "name": "retVal", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "x", + "type": "uint256" + } + ], + "name": "set2", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "name": "initialValue", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "value", + "type": "uint256" + } + ], + "name": "Test", + "type": "event" + } + ] + + var contract = new web3.eth.Contract(abi) + let instance = await contract.deploy({ + data: '0x608060405234801561001057600080fd5b506040516020806102018339810180604052602081101561003057600080fd5b810190808051906020019092919050505080600081905550506101a9806100586000396000f3fe60806040526004361061005c576000357c0100000000000000000000000000000000000000000000000000000000900480632a1afcd91461006157806360fe47b11461008c5780636d4ce63c146100c7578063ce01e1ec146100f2575b600080fd5b34801561006d57600080fd5b5061007661012d565b6040518082815260200191505060405180910390f35b34801561009857600080fd5b506100c5600480360360208110156100af57600080fd5b8101908080359060200190929190505050610133565b005b3480156100d357600080fd5b506100dc61013d565b6040518082815260200191505060405180910390f35b3480156100fe57600080fd5b5061012b6004803603602081101561011557600080fd5b8101908080359060200190929190505050610146565b005b60005481565b8060008190555050565b60008054905090565b80600081905550807f63a242a632efe33c0e210e04e4173612a17efa4f16aa4890bc7e46caece80de060405160405180910390a25056fea165627a7a7230582063160eb16dc361092a85ced1a773eed0b63738b83bea1e1c51cf066fa90e135d0029', + arguments: [100] + }).send({ + from: accounts[0], + gas: '4700000' + }) + return instance +} + +async function run() { + let accounts = await web3.eth.getAccounts(); + var SimpleStorageContract = await deployContract() + console.dir(SimpleStorageContract) + console.dir(SimpleStorageContract.options.address) + + // var subscription = web3.eth.subscribe('logs', { + // address: SimpleStorageContract.options.address + // // topics: ['0x12345...'] + // }, function (error, result) { + // console.dir("----------") + // console.dir(error) + // console.dir(result) + // }); + + // subscription.on('data', console.log) + // subscription.on('changed', console.log) + + setTimeout(async () => { + console.dir("set 100") + await SimpleStorageContract.methods.set(100).send({ from: accounts[0], gas: 4700000 }) + console.dir("set 200") + await SimpleStorageContract.methods.set2(200).send({ from: accounts[0] }) + console.dir("set 300") + await SimpleStorageContract.methods.set(300).send({ from: accounts[0] }) + + let value = await SimpleStorageContract.methods.get().call() + console.dir(value) + }, 3000) + + // EscrowContract.events.getPastEvents('Rating', {fromBlock: 1}) + // EscrowContract.events.Created({fromBlock: 1}, (err, event) => { + // console.dir("new event") + // console.dir(event) + // }) + + const EventSyncer = require('../src/eventSyncer.js') + const eventSyncer = new EventSyncer(web3); + + eventSyncer.init(() => { + + // eventSyncer.trackEvent(EscrowContract, 'Created', ((x) => true)).pipe().subscribe((v) => { + // eventSyncer.trackEvent(EscrowContract, 'Created', {filter: {buyer: accounts[0]}, fromBlock: 1}).pipe().subscribe((v) => { + // eventSyncer.trackEvent(EscrowContract, 'Rating', ((x) => true)).pipe(map(x => x.rating)).subscribe((v) => { + // console.dir("value is ") + // console.dir(v) + // }); + + eventSyncer.trackProperty(SimpleStorageContract, 'get', ((x) => true)).pipe().subscribe((v) => { + console.dir("value is ") + console.dir(v) + }) + + }); + +} + +run() From 0e320d910217a8bbfeaab515d0ea5109e959a738 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Mon, 19 Aug 2019 15:36:49 -0400 Subject: [PATCH 2/2] add todo --- src/eventSyncer.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/eventSyncer.js b/src/eventSyncer.js index b55304b..e20d56d 100644 --- a/src/eventSyncer.js +++ b/src/eventSyncer.js @@ -164,6 +164,7 @@ class EventSyncer { }]) }) + // TODO: add distinctUntilChanged return sub; }