From d5bfb124cf93703a13070da8847deb72ba6b3958 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Sun, 17 Apr 2016 13:30:32 -0700 Subject: [PATCH] bloom filter. network. --- lib/bcoin/bloom.js | 32 +++++- lib/bcoin/peer.js | 9 +- lib/bcoin/protocol/constants.js | 11 +++ lib/bcoin/protocol/framer.js | 8 +- lib/bcoin/protocol/network.js | 170 ++++++++++++++++---------------- lib/bcoin/script.js | 2 +- 6 files changed, 141 insertions(+), 91 deletions(-) diff --git a/lib/bcoin/bloom.js b/lib/bcoin/bloom.js index e00b655a..e4e8efa0 100644 --- a/lib/bcoin/bloom.js +++ b/lib/bcoin/bloom.js @@ -31,13 +31,12 @@ function Bloom(size, n, tweak, update) { } else { this.filter = new Buffer(Math.ceil(size / 8)); this.size = size; + this.reset(); } this.n = n; this.tweak = tweak; this.update = update; - - this.reset(); } /** @@ -84,6 +83,7 @@ Bloom.prototype.add = function add(val, enc) { * Test whether data is present in the filter. * @param {Buffer|String} val * @param {String?} enc - Can be any of the Buffer object's encodings. + * @returns {Boolean} */ Bloom.prototype.test = function test(val, enc) { @@ -114,6 +114,25 @@ Bloom.prototype.toBuffer = function toBuffer() { return this.filter; }; +/** + * Ensure the filter is within the size limits. + * @returns {Boolean} + */ + +Bloom.prototype.isWithinConstraints = function isWithinConstraints() { + if (this.filter.length > constants.bloom.MAX_BLOOM_FILTER_SIZE) + return false; + + if (this.n > constants.bloom.MAX_HASH_FUNCS) + return false; + + return true; +}; + +/* + * Murmur + */ + function mul32(a, b) { var alo = a & 0xffff; var blo = b & 0xffff; @@ -202,6 +221,15 @@ function murmur(data, seed) { return hash; } +/** + * Murmur3 hash. + * @static + * @function + * @param {Buffer} data + * @param {Number} seed + * @returns {Number} + */ + Bloom.hash = murmur; module.exports = Bloom; diff --git a/lib/bcoin/peer.js b/lib/bcoin/peer.js index d36da4e3..0dc6a3cd 100644 --- a/lib/bcoin/peer.js +++ b/lib/bcoin/peer.js @@ -457,7 +457,7 @@ Peer.prototype._error = function error(err) { if (typeof err === 'string') err = new Error(err); - err.message += ' (' + this.host + ')'; + err.message += ' (' + this.host + ':' + this.port + ')'; this.destroy(); this.emit('error', err); @@ -651,6 +651,13 @@ Peer.prototype._handleFilterLoad = function _handleFilterLoad(payload) { payload.tweak, payload.update ); + + if (!this.filter.isWithinConstraints()) { + delete this.filter; + this.setMisbehavior(100); + return; + } + this.relay = true; }; diff --git a/lib/bcoin/protocol/constants.js b/lib/bcoin/protocol/constants.js index 922b40b3..a9dc50d5 100644 --- a/lib/bcoin/protocol/constants.js +++ b/lib/bcoin/protocol/constants.js @@ -106,6 +106,17 @@ exports.filterFlags = { PUBKEY_ONLY: 2 }; +/** + * Bloom filter limits. + * @enum {Number} + * @default + */ + +exports.bloom = { + MAX_BLOOM_FILTER_SIZE: 36000, + MAX_HASH_FUNCS: 50 +}; + /** * Bloom filter update flags by value. * @const {RevMap} diff --git a/lib/bcoin/protocol/framer.js b/lib/bcoin/protocol/framer.js index 28489a9e..3a69d163 100644 --- a/lib/bcoin/protocol/framer.js +++ b/lib/bcoin/protocol/framer.js @@ -1100,6 +1100,10 @@ Framer.addr = function addr(peers, writer) { Framer.alert = function alert(data, writer) { var p, i, payload; + var key = data.key; + + if (!key && network.alertPrivateKey) + key = network.alertPrivateKey; if (!data.payload) { p = new BufferWriter(); @@ -1130,8 +1134,8 @@ Framer.alert = function alert(data, writer) { if (data.signature) p.writeVarBytes(data.signature); - else if (data.key) - p.writeVarBytes(bcoin.ec.sign(utils.dsha256(payload), data.key)); + else if (key) + p.writeVarBytes(bcoin.ec.sign(utils.dsha256(payload), key)); else assert(false, 'No key or signature.'); diff --git a/lib/bcoin/protocol/network.js b/lib/bcoin/protocol/network.js index 676697ae..4814b798 100644 --- a/lib/bcoin/protocol/network.js +++ b/lib/bcoin/protocol/network.js @@ -110,26 +110,21 @@ main.alertKey = new Buffer('' * @const {Object} */ -main.checkpoints = [ - { height: 11111, hash: '0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d' }, - { height: 33333, hash: '000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6' }, - { height: 74000, hash: '0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20' }, - { height: 105000, hash: '00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97' }, - { height: 134444, hash: '00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe' }, - { height: 168000, hash: '000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763' }, - { height: 193000, hash: '000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317' }, - { height: 210000, hash: '000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e' }, - { height: 216116, hash: '00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e' }, - { height: 225430, hash: '00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932' }, - { height: 250000, hash: '000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214' }, - { height: 279000, hash: '0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40' }, - { height: 295000, hash: '00000000000000004d9b4ef50f0f9d686fd69db2e03af35a100370c64632a983' } -]; - -main.checkpoints = main.checkpoints.reduce(function(out, block) { - out[block.height] = utils.revHex(block.hash); - return block; -}, {}); +main.checkpoints = { + 11111: '1d7c6eb2fd42f55925e92efad68b61edd22fba29fde8783df744e26900000000', + 33333: 'a6d0b5df7d0df069ceb1e736a216ad187a50b07aaa4e78748a58d52d00000000', + 74000: '201a66b853f9e7814a820e2af5f5dc79c07144e31ce4c9a39339570000000000', + 105000: '97dc6b1d15fbeef373a744fee0b254b0d2c820a3ae7f0228ce91020000000000', + 134444: 'feb0d2420d4a18914c81ac30f494a5d4ff34cd15d34cfd2fb105000000000000', + 168000: '63b703835cb735cb9a89d733cbe66f212f63795e0172ea619e09000000000000', + 193000: '17138bca83bdc3e6f60f01177c3877a98266de40735f2a459f05000000000000', + 210000: '2e3471a19b8e22b7f939c63663076603cf692f19837e34958b04000000000000', + 216116: '4edf231bf170234e6a811460f95c94af9464e41ee833b4f4b401000000000000', + 225430: '32595730b165f097e7b806a679cf7f3e439040f750433808c101000000000000', + 250000: '14d2f24d29bed75354f3f88a5fb50022fc064b02291fdf873800000000000000', + 279000: '407ebde958e44190fa9e810ea1fc3a7ef601c3b0a0728cae0100000000000000', + 295000: '83a93246c67003105af33ae0b29dd66f689d0f0ff54e9b4d0000000000000000' +}; main.checkpoints.tsLastCheckpoint = 1397080064; main.checkpoints.txsLastCheckpoint = 36544669; @@ -150,15 +145,11 @@ main.halvingInterval = 210000; main.genesis = { version: 1, - hash: utils.revHex( - '000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f' - ), + hash: '6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000', prevBlock: '0000000000000000000000000000000000000000000000000000000000000000', - merkleRoot: utils.revHex( - '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b' - ), + merkleRoot: '3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a', ts: 1231006505, - bits: 0x1d00ffff, + bits: 486604799, nonce: 2083236893 }; @@ -167,7 +158,16 @@ main.genesis = { * @const {String} */ -main.genesisBlock = '0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000'; +main.genesisBlock = + '0100000000000000000000000000000000000000000000000000000000000000000000' + + '003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab' + + '5f49ffff001d1dac2b7c01010000000100000000000000000000000000000000000000' + + '00000000000000000000000000ffffffff4d04ffff001d0104455468652054696d6573' + + '2030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66' + + '207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01' + + '000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f' + + '61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f' + + 'ac00000000'; main.pow = {}; @@ -370,14 +370,9 @@ testnet.alertKey = new Buffer('' + 'db45200ca2b0a', 'hex'); -testnet.checkpoints = [ - { height: 546, hash: '000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70' } -]; - -testnet.checkpoints = testnet.checkpoints.reduce(function(out, block) { - out[block.height] = utils.revHex(block.hash); - return block; -}, {}); +testnet.checkpoints = { + 546: '70cb6af7ebbcb1315d3414029c556c55f3e2fc353c4c9063a76c932a00000000' +}; testnet.checkpoints.tsLastCheckpoint = 1338180505; testnet.checkpoints.txsLastCheckpoint = 16341; @@ -386,21 +381,26 @@ testnet.checkpoints.lastHeight = 546; testnet.halvingInterval = 210000; -testnet.genesis = { +testnet.genesis = { version: 1, - hash: utils.revHex( - '000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943' - ), + hash: '43497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea330900000000', prevBlock: '0000000000000000000000000000000000000000000000000000000000000000', - merkleRoot: utils.revHex( - '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b' - ), + merkleRoot: '3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a', ts: 1296688602, - bits: 0x1d00ffff, + bits: 486604799, nonce: 414098458 }; -testnet.genesisBlock = '0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff001d1aa4ae180101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000'; +testnet.genesisBlock = + '0100000000000000000000000000000000000000000000000000000000000000000000' + + '003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5' + + '494dffff001d1aa4ae1801010000000100000000000000000000000000000000000000' + + '00000000000000000000000000ffffffff4d04ffff001d0104455468652054696d6573' + + '2030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66' + + '207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01' + + '000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f' + + '61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f' + + 'ac00000000'; testnet.pow = {}; @@ -492,21 +492,26 @@ regtest.checkpoints.lastHeight = 0; regtest.halvingInterval = 150; -regtest.genesis = { +regtest.genesis = { version: 1, - hash: utils.revHex( - '0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206' - ), + hash: '06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f', prevBlock: '0000000000000000000000000000000000000000000000000000000000000000', - merkleRoot: utils.revHex( - '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b' - ), + merkleRoot: '3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a', ts: 1296688602, - bits: 0x207fffff, + bits: 545259519, nonce: 2 }; -regtest.genesisBlock = '0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff7f20020000000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000'; +regtest.genesisBlock = + '0100000000000000000000000000000000000000000000000000000000000000000000' + + '003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5' + + '494dffff7f200200000001010000000100000000000000000000000000000000000000' + + '00000000000000000000000000ffffffff4d04ffff001d0104455468652054696d6573' + + '2030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66' + + '207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01' + + '000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f' + + '61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f' + + 'ac00000000'; regtest.pow = {}; @@ -593,13 +598,7 @@ segnet3.alertKey = new Buffer('' + 'db45200ca2b0a', 'hex'); -segnet3.checkpoints = []; - -segnet3.checkpoints = segnet3.checkpoints.reduce(function(out, block) { - out[block.height] = utils.revHex(block.hash); - return block; -}, {}); - +segnet3.checkpoints = {}; segnet3.checkpoints.tsLastCheckpoint = 0; segnet3.checkpoints.txsLastCheckpoint = 0; segnet3.checkpoints.txsPerDay = 300; @@ -609,19 +608,24 @@ segnet3.halvingInterval = 210000; segnet3.genesis = { version: 1, - hash: utils.revHex( - '0d5b9c518ddf053fcac71730830df4526a9949c08f34acf6a1d30464d22f02aa' - ), + hash: 'aa022fd26404d3a1f6ac348fc049996a52f40d833017c7ca3f05df8d519c5b0d', prevBlock: '0000000000000000000000000000000000000000000000000000000000000000', - merkleRoot: utils.revHex( - '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b' - ), + merkleRoot: '3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a', ts: 1452831101, - bits: 0x1d00ffff, + bits: 486604799, nonce: 0 }; -segnet3.genesisBlock = '0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a7d719856ffff001d000000000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000'; +segnet3.genesisBlock = + '0100000000000000000000000000000000000000000000000000000000000000000000' + + '003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a7d71' + + '9856ffff001d0000000001010000000100000000000000000000000000000000000000' + + '00000000000000000000000000ffffffff4d04ffff001d0104455468652054696d6573' + + '2030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66' + + '207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01' + + '000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f' + + '61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f' + + 'ac00000000'; segnet3.pow = {}; @@ -699,13 +703,7 @@ segnet4.alertKey = new Buffer('' + 'db45200ca2b0a', 'hex'); -segnet4.checkpoints = []; - -segnet4.checkpoints = segnet4.checkpoints.reduce(function(out, block) { - out[block.height] = utils.revHex(block.hash); - return block; -}, {}); - +segnet4.checkpoints = {}; segnet4.checkpoints.tsLastCheckpoint = 0; segnet4.checkpoints.txsLastCheckpoint = 0; segnet4.checkpoints.txsPerDay = 300; @@ -717,15 +715,22 @@ segnet4.genesis = { version: 1, hash: 'b291211d4bb2b7e1b7a4758225e69e50104091a637213d033295c010f55ffb18', prevBlock: '0000000000000000000000000000000000000000000000000000000000000000', - merkleRoot: utils.revHex( - '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b' - ), + merkleRoot: '3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a', ts: 1452831101, bits: 503447551, nonce: 0 }; -segnet4.genesisBlock = '0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a7d719856ffff011e000000000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000'; +segnet4.genesisBlock = + '0100000000000000000000000000000000000000000000000000000000000000000000' + + '003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a7d71' + + '9856ffff011e0000000001010000000100000000000000000000000000000000000000' + + '00000000000000000000000000ffffffff4d04ffff001d0104455468652054696d6573' + + '2030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66' + + '207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01' + + '000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f' + + '61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f' + + 'ac00000000'; segnet4.pow = {}; @@ -764,11 +769,6 @@ segnet4.deployments = { startTime: 0, timeout: 999999999999 } - // bip109: { - // bit: 4, - // startTime: 1453939200, // Jan 28th, 2016 - // timeout: 1514764800 // Jan 1st, 2018 - // } }; segnet4.prefixes = { diff --git a/lib/bcoin/script.js b/lib/bcoin/script.js index 1211b2bb..35fcfed4 100644 --- a/lib/bcoin/script.js +++ b/lib/bcoin/script.js @@ -1533,7 +1533,7 @@ Script.prototype.interpret = function interpret(stack, flags, tx, index, version v2 = Script.num(stack.pop(), flags).toNumber(); // begin v1 = stack.pop(); // string if (v2 < 0 || v3 < v2) - throw new ScriptError('String begin and end out of range.', op, ip); + throw new ScriptError('String begin or end out of range.', op, ip); if (v2 > v1.length) v2 = v1.length; if (v3 > v1.length)