From 446c03de47ea6cdc02ac5b50cca41477362e69c8 Mon Sep 17 00:00:00 2001 From: Fabian Vogelsteller Date: Mon, 15 Aug 2016 14:54:10 +0200 Subject: [PATCH] finished pastEvents --- lib/web3/contract.js | 104 ++++++++++++++++++++++++--------------- lib/web3/method.js | 6 +-- lib/web3/subscription.js | 11 +++-- 3 files changed, 74 insertions(+), 47 deletions(-) diff --git a/lib/web3/contract.js b/lib/web3/contract.js index 59fdd4e1cfb..7a8536ad349 100644 --- a/lib/web3/contract.js +++ b/lib/web3/contract.js @@ -22,6 +22,7 @@ var utils = require('../utils/utils'); var eventifiedPromise = require('./eventifiedPromise.js'); +var Method = require('./method.js'); var coder = require('../solidity/coder'); var formatters = require('./formatters'); var sha3 = require('../utils/sha3'); @@ -191,43 +192,50 @@ Contract.prototype._encodeEventABI = function (event, options) { var filter = options.filter || {}, result = {}; - ['fromBlock', 'toBlock'].filter(function (f) { return options[f] !== undefined; }).forEach(function (f) { result[f] = formatters.inputBlockNumberFormatter(options[f]); }); - result.topics = []; + // use given topics + if(utils.isArray(options.topics)) { + result.topics = options.topics; - // add event signature - if (event && !event.anonymous && event.name !== 'ALLEVENTS') { - result.topics.push(event.signature); - } + // create topics based on filter + } else { - // add event topics (indexed arguments) - if (event.name !== 'ALLEVENTS') { - var indexedTopics = event.inputs.filter(function (i) { - return i.indexed === true; - }).map(function (i) { - var value = filter[i.name]; - if (!value) { - return null; - } + result.topics = []; - if (utils.isArray(value)) { - return value.map(function (v) { - return '0x' + coder.encodeParam(i.type, v); - }); - } - return '0x' + coder.encodeParam(i.type, value); - }); + // add event signature + if (event && !event.anonymous && event.name !== 'ALLEVENTS') { + result.topics.push(event.signature); + } - result.topics = result.topics.concat(indexedTopics); - } + // add event topics (indexed arguments) + if (event.name !== 'ALLEVENTS') { + var indexedTopics = event.inputs.filter(function (i) { + return i.indexed === true; + }).map(function (i) { + var value = filter[i.name]; + if (!value) { + return null; + } - if(!result.topics.length) - delete result.topics; + if (utils.isArray(value)) { + return value.map(function (v) { + return '0x' + coder.encodeParam(i.type, v); + }); + } + return '0x' + coder.encodeParam(i.type, value); + }); + + result.topics = result.topics.concat(indexedTopics); + } + + if(!result.topics.length) + delete result.topics; + } result.address = this.address; @@ -243,6 +251,7 @@ Contract.prototype._encodeEventABI = function (event, options) { */ Contract.prototype._decodeEventABI = function (data) { var event = this; + data.data = data.data || ''; data.topics = data.topics || []; var result = formatters.outputLogFormatter(data); @@ -527,24 +536,27 @@ Contract.prototype.encodeABI = function encodeABI(options){ * @param {String} _generateEventOptions * @param {Object} event * @param {Object} options + * @param {Function} callback * @return {Object} the event options object */ -Contract.prototype._generateEventOptions = function(event, options, func) { - var args = Array.prototype.slice.call(arguments), - event = (event.toLowerCase() === 'allevents') ? { - name: 'ALLEVENTS', - jsonInterface: this.jsonInterface - } : this.jsonInterface.find(function (json) { - return (json.type === 'event' && json.name === event); - }); +Contract.prototype._generateEventOptions = function(event, options, callback) { + var args = Array.prototype.slice.call(arguments); // get the callback if (utils.isFunction(args[args.length - 1])) { - callback = args[args.length - 1]; + callback = args.pop(); } // get the options - options = (utils.isObject(args[args.length - 1])) ? args[args.length - 1] : options; + options = (utils.isObject(args[args.length - 1])) ? args.pop() : {}; + + event = (utils.isString(args[0])) ? event : 'allevents'; + event = (event.toLowerCase() === 'allevents') ? { + name: 'ALLEVENTS', + jsonInterface: this.jsonInterface + } : this.jsonInterface.find(function (json) { + return (json.type === 'event' && json.name === event); + }); if (!event) { throw new Error('Event "' + event.name + '" doesn\'t exist in this contract.'); @@ -596,7 +608,7 @@ Contract.prototype.once = function(event, options, callback) { * @return {Object} the event subscription */ Contract.prototype.on = function(event, options, callback){ - var subOptions = this._generateEventOptions(event ,options, callback); + var subOptions = this._generateEventOptions.apply(this, arguments); // prevent the event "newListener" and "removeListener" from being overwritten @@ -631,11 +643,21 @@ Contract.prototype.on = function(event, options, callback){ * @return {Object} the promievent */ Contract.prototype.pastEvents = function(event, options, callback){ - var subOptions = this._generateEventOptions(event ,options, callback); + var subOptions = this._generateEventOptions.apply(this, arguments); + + var getPastLogs = new Method({ + name: 'getPastLogs', + call: 'eth_getLogs', + params: 1, + inputFormatter: [formatters.inputLogFormatter], + outputFormatter: this._decodeEventABI.bind(subOptions.event) + }); + getPastLogs.setRequestManager(this._web3._requestManager); + var call = getPastLogs.buildCall(); - console.log(subOptions.params, this._decodeEventABI.bind(subOptions.event)); + getPastLogs = null; - return this._web3.eth.getPastLogs(subOptions.params, subOptions.callback); + return call(subOptions.params, subOptions.callback); }; @@ -684,7 +706,7 @@ Contract.prototype._executeMethod = function _executeMethod(type){ options = (utils.isObject(args[args.length - 1])) ? args.pop() : {}; - + options.from = options.from || this._parent.options.from; options.data = this.encodeABI(); // TODO remove once we switched everywhere to gasLimit diff --git a/lib/web3/method.js b/lib/web3/method.js index 1e97f7b7dd2..d16c5c02e5c 100644 --- a/lib/web3/method.js +++ b/lib/web3/method.js @@ -62,7 +62,7 @@ Method.prototype.extractCallback = function (args) { /** * Should be called to check if the number of arguments is correct - * + * * @method validateArgs * @param {Array} arguments * @throws {Error} if it is not @@ -75,7 +75,7 @@ Method.prototype.validateArgs = function (args) { /** * Should be called to format input args of method - * + * * @method formatInput * @param {Array} * @return {Array} @@ -137,7 +137,7 @@ Method.prototype.attachToObject = function (obj) { obj[name[0]] = obj[name[0]] || {}; obj[name[0]][name[1]] = func; } else { - obj[name[0]] = func; + obj[name[0]] = func; } }; diff --git a/lib/web3/subscription.js b/lib/web3/subscription.js index e729050ffca..cce9912467d 100644 --- a/lib/web3/subscription.js +++ b/lib/web3/subscription.js @@ -189,11 +189,11 @@ Subscription.prototype.subscribe = function() { if(!err) { logs.forEach(function(log){ var output = _this._formatOutput(log); - _this.callback(null, output); + _this.callback(null, output, _this); _this.emit('data', output); }); } else { - _this.callback(err); + _this.callback(err, null, _this); _this.emit('error', err); } }); @@ -208,6 +208,11 @@ Subscription.prototype.subscribe = function() { // call callback on notifications _this.options.requestManager.addSubscription(_this.id, payload.params[0] ,'eth', function(err, result) { + + // TODO remove once its fixed in geth + if(utils.isArray(result)) + result = result[0]; + var output = _this._formatOutput(result); _this.callback(err, output, _this); @@ -238,7 +243,7 @@ Subscription.prototype.subscribe = function() { }); } else { - _this.callback(err); + _this.callback(err, null, _this); } });