mirror of
https://github.com/zkitter/eth-json-rpc-filters.git
synced 2026-01-08 23:08:10 -05:00
filters - only keep history for log-filters + various log-filter fixes
This commit is contained in:
31
base-filter-history.js
Normal file
31
base-filter-history.js
Normal file
@@ -0,0 +1,31 @@
|
||||
const BaseFilter = require('./base-filter')
|
||||
|
||||
// tracks all results ever recorded
|
||||
class BaseFilterWithHistory extends BaseFilter {
|
||||
|
||||
constructor () {
|
||||
super()
|
||||
this.allResults = []
|
||||
}
|
||||
|
||||
async update () {
|
||||
throw new Error('BaseFilterWithHistory - no update method specified')
|
||||
}
|
||||
|
||||
addResults (newResults) {
|
||||
this.allResults = this.allResults.concat(newResults)
|
||||
super.addResults(newResults)
|
||||
}
|
||||
|
||||
addInitialResults (newResults) {
|
||||
this.allResults = this.allResults.concat(newResults)
|
||||
super.addInitialResults(newResults)
|
||||
}
|
||||
|
||||
getAllResults () {
|
||||
return this.allResults
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = BaseFilterWithHistory
|
||||
@@ -5,7 +5,6 @@ class BaseFilter extends SafeEventEmitter {
|
||||
constructor () {
|
||||
super()
|
||||
this.updates = []
|
||||
this.allResults = []
|
||||
}
|
||||
|
||||
async initialize () {}
|
||||
@@ -16,24 +15,17 @@ class BaseFilter extends SafeEventEmitter {
|
||||
|
||||
addResults (newResults) {
|
||||
this.updates = this.updates.concat(newResults)
|
||||
this.allResults = this.allResults.concat(newResults)
|
||||
newResults.forEach(result => this.emit('update', result))
|
||||
}
|
||||
|
||||
addInitialResults (newResults) {
|
||||
this.allResults = this.allResults.concat(newResults)
|
||||
}
|
||||
addInitialResults (newResults) {}
|
||||
|
||||
getChangesAndClear () {
|
||||
const updates = this.updates
|
||||
this.updates = []
|
||||
return updates
|
||||
}
|
||||
|
||||
getAllResults () {
|
||||
return this.allResults
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
module.exports = BaseFilter
|
||||
|
||||
16
index.js
16
index.js
@@ -1,5 +1,4 @@
|
||||
const Mutex = require('await-semaphore').Mutex
|
||||
const EthQuery = require('ethjs-query')
|
||||
const createAsyncMiddleware = require('json-rpc-engine/src/createAsyncMiddleware')
|
||||
const createJsonRpcMiddleware = require('eth-json-rpc-middleware/scaffold')
|
||||
const LogFilter = require('./log-filter.js')
|
||||
@@ -11,8 +10,6 @@ module.exports = createEthFilterMiddleware
|
||||
|
||||
function createEthFilterMiddleware({ blockTracker, provider }) {
|
||||
|
||||
// ethQuery for log lookups
|
||||
const ethQuery = new EthQuery(provider)
|
||||
// create filter collection
|
||||
let filterIndex = 0
|
||||
let filters = {}
|
||||
@@ -75,19 +72,19 @@ function createEthFilterMiddleware({ blockTracker, provider }) {
|
||||
//
|
||||
|
||||
async function newLogFilter(params) {
|
||||
const filter = new LogFilter({ provider, ethQuery, params })
|
||||
const filter = new LogFilter({ provider, params })
|
||||
const filterIndex = await installFilter(filter)
|
||||
return filter
|
||||
}
|
||||
|
||||
async function newBlockFilter() {
|
||||
const filter = new BlockFilter({ provider, ethQuery })
|
||||
const filter = new BlockFilter({ provider })
|
||||
const filterIndex = await installFilter(filter)
|
||||
return filter
|
||||
}
|
||||
|
||||
async function newPendingTransactionFilter() {
|
||||
const filter = new TxFilter({ provider, ethQuery })
|
||||
const filter = new TxFilter({ provider })
|
||||
const filterIndex = await installFilter(filter)
|
||||
return filter
|
||||
}
|
||||
@@ -112,7 +109,12 @@ function createEthFilterMiddleware({ blockTracker, provider }) {
|
||||
if (!filter) {
|
||||
throw new Error(`No filter for index "${filterIndex}"`)
|
||||
}
|
||||
const results = filter.getAllResults()
|
||||
// only return results for log filters
|
||||
if (filter.type === 'log') {
|
||||
results = filter.getAllResults()
|
||||
} else {
|
||||
results = []
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +1,29 @@
|
||||
const BaseFilter = require('./base-filter')
|
||||
const EthQuery = require('eth-query')
|
||||
const pify = require('pify')
|
||||
const BaseFilterWithHistory = require('./base-filter-history')
|
||||
const { bnToHex, hexToInt, incrementHexInt, minBlockRef, blockRefIsNumber } = require('./hexUtils')
|
||||
|
||||
class LogFilter extends BaseFilter {
|
||||
class LogFilter extends BaseFilterWithHistory {
|
||||
|
||||
constructor ({ ethQuery, params }) {
|
||||
constructor ({ provider, params }) {
|
||||
super()
|
||||
this.type = 'log'
|
||||
this.ethQuery = ethQuery
|
||||
this.ethQuery = new EthQuery(provider)
|
||||
this.params = Object.assign({
|
||||
fromBlock: 'latest',
|
||||
toBlock: 'latest',
|
||||
address: undefined,
|
||||
topics: [],
|
||||
}, params)
|
||||
// normalize address
|
||||
if (this.params.address) this.params.address = this.params.address.toLowerCase()
|
||||
// normalize address parameter
|
||||
if (this.params.address) {
|
||||
// ensure array
|
||||
if (!Array.isArray(this.params.address)) {
|
||||
this.params.address = [this.params.address]
|
||||
}
|
||||
// ensure lowercase
|
||||
this.params.address = this.params.address.map(address => address.toLowerCase())
|
||||
}
|
||||
}
|
||||
|
||||
async initialize({ currentBlock }) {
|
||||
@@ -51,13 +60,7 @@ class LogFilter extends BaseFilter {
|
||||
}
|
||||
|
||||
async _fetchLogs (params) {
|
||||
const newLogs = await this.ethQuery.getLogs(params)
|
||||
// de-BN ethQuery results
|
||||
newLogs.forEach((log) => {
|
||||
log.blockNumber = bnToHex(log.blockNumber)
|
||||
log.logIndex = bnToHex(log.logIndex)
|
||||
log.transactionIndex = bnToHex(log.transactionIndex)
|
||||
})
|
||||
const newLogs = await pify(cb => this.ethQuery.getLogs(params, cb))()
|
||||
// add to results
|
||||
return newLogs
|
||||
}
|
||||
@@ -68,7 +71,8 @@ class LogFilter extends BaseFilter {
|
||||
if (blockRefIsNumber(this.params.toBlock) && hexToInt(this.params.toBlock) <= hexToInt(log.blockNumber)) return false
|
||||
|
||||
// address is correct:
|
||||
if (this.params.address && this.params.address !== log.address) return false
|
||||
const normalizedLogAddress = log.address && log.address.toLowerCase()
|
||||
if (this.params.address && normalizedLogAddress && !this.params.address.includes(normalizedLogAddress)) return false
|
||||
|
||||
// topics match:
|
||||
// topics are position-dependant
|
||||
@@ -76,12 +80,15 @@ class LogFilter extends BaseFilter {
|
||||
// topics can be null, representing a wild card for that position
|
||||
const topicsMatch = this.params.topics.every((topicPattern, index) => {
|
||||
// pattern is longer than actual topics
|
||||
const logTopic = log.topics[index]
|
||||
let logTopic = log.topics[index]
|
||||
if (!logTopic) return false
|
||||
// wild card
|
||||
const subtopicsToMatch = Array.isArray(topicPattern) ? topicPattern : [topicPattern]
|
||||
logTopic = logTopic.toLowerCase()
|
||||
// normalize subTopics
|
||||
let subtopicsToMatch = Array.isArray(topicPattern) ? topicPattern : [topicPattern]
|
||||
// check for wild card
|
||||
const subtopicsIncludeWildcard = subtopicsToMatch.includes(null)
|
||||
if (subtopicsIncludeWildcard) return true
|
||||
subtopicsToMatch = subtopicsToMatch.map(topic => topic.toLowerCase())
|
||||
// check each possible matching topic
|
||||
const topicDoesMatch = subtopicsToMatch.includes(logTopic)
|
||||
return topicDoesMatch
|
||||
|
||||
Reference in New Issue
Block a user