-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #436 from Tenderly/filters-subscriptions
Filters subscriptions
- Loading branch information
Showing
9 changed files
with
1,400 additions
and
140 deletions.
There are no files selected for viewing
142 changes: 142 additions & 0 deletions
142
packages/buidler-core/src/internal/buidler-evm/provider/filter.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
import Bloom from "@nomiclabs/ethereumjs-vm/dist/bloom"; | ||
import { BN, bufferToHex, toBuffer } from "ethereumjs-util"; | ||
|
||
import { RpcLogOutput } from "./output"; | ||
|
||
export const LATEST_BLOCK = new BN(-1); | ||
|
||
export enum Type { | ||
LOGS_SUBSCRIPTION = 0, | ||
PENDING_TRANSACTION_SUBSCRIPTION = 1, | ||
BLOCK_SUBSCRIPTION = 2 | ||
} | ||
|
||
export interface FilterCriteria { | ||
fromBlock: BN; | ||
toBlock: BN; | ||
addresses: Buffer[]; | ||
normalizedTopics: Array<Array<Buffer | null> | null>; | ||
} | ||
|
||
export interface Filter { | ||
id: string; | ||
type: Type; | ||
criteria?: FilterCriteria; | ||
deadline: Date; | ||
hashes: string[]; | ||
logs: RpcLogOutput[]; | ||
subscription: boolean; | ||
} | ||
|
||
export function bloomFilter( | ||
bloom: Bloom, | ||
addresses: Buffer[], | ||
normalizedTopics: Array<Array<Buffer | null> | null> | ||
): boolean { | ||
if (addresses.length > 0) { | ||
let included = false; | ||
for (const address of addresses) { | ||
if (bloom.check(address)) { | ||
included = true; | ||
break; | ||
} | ||
} | ||
|
||
if (!included) { | ||
return false; | ||
} | ||
} | ||
|
||
for (const sub of normalizedTopics) { | ||
if (sub == null || sub.length === 0) { | ||
continue; | ||
} | ||
|
||
let included = false; | ||
for (const topic of sub) { | ||
if (topic != null && bloom.check(topic)) { | ||
included = true; | ||
break; | ||
} | ||
} | ||
|
||
if (!included) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
|
||
export function filterLogs( | ||
logs: RpcLogOutput[], | ||
criteria: FilterCriteria | ||
): RpcLogOutput[] { | ||
const filteredLogs: RpcLogOutput[] = []; | ||
for (const log of logs) { | ||
const blockNumber = new BN(toBuffer(log.blockNumber!)); | ||
if (blockNumber.lt(criteria.fromBlock)) { | ||
continue; | ||
} | ||
|
||
if ( | ||
!criteria.toBlock.eq(LATEST_BLOCK) && | ||
blockNumber.gt(criteria.toBlock) | ||
) { | ||
continue; | ||
} | ||
|
||
if ( | ||
criteria.addresses.length !== 0 && | ||
!includes(criteria.addresses, toBuffer(log.address)) | ||
) { | ||
continue; | ||
} | ||
|
||
if (!topicMatched(criteria.normalizedTopics, log.topics)) { | ||
continue; | ||
} | ||
|
||
filteredLogs.push(log); | ||
} | ||
|
||
return filteredLogs; | ||
} | ||
|
||
export function includes(addresses: Buffer[], a: Buffer): boolean { | ||
for (const address of addresses) { | ||
if (Buffer.compare(address, a) === 0) { | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
export function topicMatched( | ||
normalizedTopics: Array<Array<Buffer | null> | null>, | ||
logTopics: string[] | ||
): boolean { | ||
for (let i = 0; i < normalizedTopics.length; i++) { | ||
if (normalizedTopics.length > logTopics.length) { | ||
return false; | ||
} | ||
|
||
const sub = normalizedTopics[i]; | ||
if (sub == null || sub.length === 0) { | ||
continue; | ||
} | ||
|
||
let match: boolean = false; | ||
for (const topic of sub) { | ||
if (topic === null || logTopics[i] === bufferToHex(topic)) { | ||
match = true; | ||
break; | ||
} | ||
} | ||
if (!match) { | ||
return false; | ||
} | ||
} | ||
|
||
return true; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.