UNPKG

2.98 kBJavaScriptView Raw
1/*jshint bitwise: false*/
2
3/*
4 This file is part of web3.js.
5
6 web3.js is free software: you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 web3.js is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with web3.js. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20/**
21 * @file bloom.js
22 * @author Bas van Kervel <bas@ethereum.org>
23 * @date 2017
24 */
25
26/**
27 * Ethereum bloom filter support.
28 *
29 * TODO UNDOCUMENTED
30 *
31 * @module bloom
32 * @class [bloom] bloom
33 */
34
35var utils = require("./utils.js");
36
37function codePointToInt(codePoint) {
38 if (codePoint >= 48 && codePoint <= 57) { /*['0'..'9'] -> [0..9]*/
39 return codePoint-48;
40 }
41
42 if (codePoint >= 65 && codePoint <= 70) { /*['A'..'F'] -> [10..15]*/
43 return codePoint-55;
44 }
45
46 if (codePoint >= 97 && codePoint <= 102) { /*['a'..'f'] -> [10..15]*/
47 return codePoint-87;
48 }
49
50 throw "invalid bloom";
51}
52
53function testBytes(bloom, bytes) {
54 var hash = utils.sha3(bytes).replace('0x','');
55
56 for (var i = 0; i < 12; i += 4) {
57 // calculate bit position in bloom filter that must be active
58 var bitpos = ((parseInt(hash.substr(i, 2), 16) << 8) + parseInt(hash.substr((i+2), 2), 16)) & 2047;
59
60 // test if bitpos in bloom is active
61 var code = codePointToInt(bloom.charCodeAt(bloom.length - 1 - Math.floor(bitpos/4)));
62 var offset = 1 << (bitpos % 4);
63
64 if ((code&offset) !== offset) {
65 return false;
66 }
67 }
68
69 return true;
70}
71
72/**
73 * Returns true if address is part of the given bloom.
74 * note: false positives are possible.
75 *
76 * @method testAddress
77 * @param {String} hex encoded bloom
78 * @param {String} address in hex notation
79 * @returns {Boolean} topic is (probably) part of the block
80 */
81var testAddress = function(bloom, address) {
82 if (!utils.isBloom(bloom)) {
83 throw 'Invalid bloom given';
84 }
85 if (!utils.isAddress(address)) {
86 throw 'Invalid address given: "'+ address +'\"';
87 }
88
89 return testBytes(bloom, address);
90};
91
92/**
93 * Returns true if the topic is part of the given bloom.
94 * note: false positives are possible.
95 *
96 * @method hasTopic
97 * @param {String} hex encoded bloom
98 * @param {String} address in hex notation
99 * @returns {Boolean} topic is (probably) part of the block
100 */
101var testTopic = function(bloom, topic) {
102 if (!utils.isBloom(bloom)) throw "invalid bloom";
103 if (!utils.isTopic(topic)) throw "invalid topic";
104
105 return testBytes(bloom, topic);
106};
107
108module.exports = {
109 testAddress: testAddress,
110 testTopic: testTopic
111};