bloom filter. network.

This commit is contained in:
Christopher Jeffrey 2016-04-17 13:30:32 -07:00
parent f3c2134dfa
commit d5bfb124cf
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
6 changed files with 141 additions and 91 deletions

View File

@ -31,13 +31,12 @@ function Bloom(size, n, tweak, update) {
} else { } else {
this.filter = new Buffer(Math.ceil(size / 8)); this.filter = new Buffer(Math.ceil(size / 8));
this.size = size; this.size = size;
this.reset();
} }
this.n = n; this.n = n;
this.tweak = tweak; this.tweak = tweak;
this.update = update; this.update = update;
this.reset();
} }
/** /**
@ -84,6 +83,7 @@ Bloom.prototype.add = function add(val, enc) {
* Test whether data is present in the filter. * Test whether data is present in the filter.
* @param {Buffer|String} val * @param {Buffer|String} val
* @param {String?} enc - Can be any of the Buffer object's encodings. * @param {String?} enc - Can be any of the Buffer object's encodings.
* @returns {Boolean}
*/ */
Bloom.prototype.test = function test(val, enc) { Bloom.prototype.test = function test(val, enc) {
@ -114,6 +114,25 @@ Bloom.prototype.toBuffer = function toBuffer() {
return this.filter; 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) { function mul32(a, b) {
var alo = a & 0xffff; var alo = a & 0xffff;
var blo = b & 0xffff; var blo = b & 0xffff;
@ -202,6 +221,15 @@ function murmur(data, seed) {
return hash; return hash;
} }
/**
* Murmur3 hash.
* @static
* @function
* @param {Buffer} data
* @param {Number} seed
* @returns {Number}
*/
Bloom.hash = murmur; Bloom.hash = murmur;
module.exports = Bloom; module.exports = Bloom;

View File

@ -457,7 +457,7 @@ Peer.prototype._error = function error(err) {
if (typeof err === 'string') if (typeof err === 'string')
err = new Error(err); err = new Error(err);
err.message += ' (' + this.host + ')'; err.message += ' (' + this.host + ':' + this.port + ')';
this.destroy(); this.destroy();
this.emit('error', err); this.emit('error', err);
@ -651,6 +651,13 @@ Peer.prototype._handleFilterLoad = function _handleFilterLoad(payload) {
payload.tweak, payload.tweak,
payload.update payload.update
); );
if (!this.filter.isWithinConstraints()) {
delete this.filter;
this.setMisbehavior(100);
return;
}
this.relay = true; this.relay = true;
}; };

View File

@ -106,6 +106,17 @@ exports.filterFlags = {
PUBKEY_ONLY: 2 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. * Bloom filter update flags by value.
* @const {RevMap} * @const {RevMap}

View File

@ -1100,6 +1100,10 @@ Framer.addr = function addr(peers, writer) {
Framer.alert = function alert(data, writer) { Framer.alert = function alert(data, writer) {
var p, i, payload; var p, i, payload;
var key = data.key;
if (!key && network.alertPrivateKey)
key = network.alertPrivateKey;
if (!data.payload) { if (!data.payload) {
p = new BufferWriter(); p = new BufferWriter();
@ -1130,8 +1134,8 @@ Framer.alert = function alert(data, writer) {
if (data.signature) if (data.signature)
p.writeVarBytes(data.signature); p.writeVarBytes(data.signature);
else if (data.key) else if (key)
p.writeVarBytes(bcoin.ec.sign(utils.dsha256(payload), data.key)); p.writeVarBytes(bcoin.ec.sign(utils.dsha256(payload), key));
else else
assert(false, 'No key or signature.'); assert(false, 'No key or signature.');

View File

@ -110,26 +110,21 @@ main.alertKey = new Buffer(''
* @const {Object} * @const {Object}
*/ */
main.checkpoints = [ main.checkpoints = {
{ height: 11111, hash: '0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d' }, 11111: '1d7c6eb2fd42f55925e92efad68b61edd22fba29fde8783df744e26900000000',
{ height: 33333, hash: '000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6' }, 33333: 'a6d0b5df7d0df069ceb1e736a216ad187a50b07aaa4e78748a58d52d00000000',
{ height: 74000, hash: '0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20' }, 74000: '201a66b853f9e7814a820e2af5f5dc79c07144e31ce4c9a39339570000000000',
{ height: 105000, hash: '00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97' }, 105000: '97dc6b1d15fbeef373a744fee0b254b0d2c820a3ae7f0228ce91020000000000',
{ height: 134444, hash: '00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe' }, 134444: 'feb0d2420d4a18914c81ac30f494a5d4ff34cd15d34cfd2fb105000000000000',
{ height: 168000, hash: '000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763' }, 168000: '63b703835cb735cb9a89d733cbe66f212f63795e0172ea619e09000000000000',
{ height: 193000, hash: '000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317' }, 193000: '17138bca83bdc3e6f60f01177c3877a98266de40735f2a459f05000000000000',
{ height: 210000, hash: '000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e' }, 210000: '2e3471a19b8e22b7f939c63663076603cf692f19837e34958b04000000000000',
{ height: 216116, hash: '00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e' }, 216116: '4edf231bf170234e6a811460f95c94af9464e41ee833b4f4b401000000000000',
{ height: 225430, hash: '00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932' }, 225430: '32595730b165f097e7b806a679cf7f3e439040f750433808c101000000000000',
{ height: 250000, hash: '000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214' }, 250000: '14d2f24d29bed75354f3f88a5fb50022fc064b02291fdf873800000000000000',
{ height: 279000, hash: '0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40' }, 279000: '407ebde958e44190fa9e810ea1fc3a7ef601c3b0a0728cae0100000000000000',
{ height: 295000, hash: '00000000000000004d9b4ef50f0f9d686fd69db2e03af35a100370c64632a983' } 295000: '83a93246c67003105af33ae0b29dd66f689d0f0ff54e9b4d0000000000000000'
]; };
main.checkpoints = main.checkpoints.reduce(function(out, block) {
out[block.height] = utils.revHex(block.hash);
return block;
}, {});
main.checkpoints.tsLastCheckpoint = 1397080064; main.checkpoints.tsLastCheckpoint = 1397080064;
main.checkpoints.txsLastCheckpoint = 36544669; main.checkpoints.txsLastCheckpoint = 36544669;
@ -150,15 +145,11 @@ main.halvingInterval = 210000;
main.genesis = { main.genesis = {
version: 1, version: 1,
hash: utils.revHex( hash: '6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000',
'000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f'
),
prevBlock: '0000000000000000000000000000000000000000000000000000000000000000', prevBlock: '0000000000000000000000000000000000000000000000000000000000000000',
merkleRoot: utils.revHex( merkleRoot: '3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a',
'4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b'
),
ts: 1231006505, ts: 1231006505,
bits: 0x1d00ffff, bits: 486604799,
nonce: 2083236893 nonce: 2083236893
}; };
@ -167,7 +158,16 @@ main.genesis = {
* @const {String} * @const {String}
*/ */
main.genesisBlock = '0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000'; main.genesisBlock =
'0100000000000000000000000000000000000000000000000000000000000000000000'
+ '003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab'
+ '5f49ffff001d1dac2b7c01010000000100000000000000000000000000000000000000'
+ '00000000000000000000000000ffffffff4d04ffff001d0104455468652054696d6573'
+ '2030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66'
+ '207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01'
+ '000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f'
+ '61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f'
+ 'ac00000000';
main.pow = {}; main.pow = {};
@ -370,14 +370,9 @@ testnet.alertKey = new Buffer(''
+ 'db45200ca2b0a', + 'db45200ca2b0a',
'hex'); 'hex');
testnet.checkpoints = [ testnet.checkpoints = {
{ height: 546, hash: '000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70' } 546: '70cb6af7ebbcb1315d3414029c556c55f3e2fc353c4c9063a76c932a00000000'
]; };
testnet.checkpoints = testnet.checkpoints.reduce(function(out, block) {
out[block.height] = utils.revHex(block.hash);
return block;
}, {});
testnet.checkpoints.tsLastCheckpoint = 1338180505; testnet.checkpoints.tsLastCheckpoint = 1338180505;
testnet.checkpoints.txsLastCheckpoint = 16341; testnet.checkpoints.txsLastCheckpoint = 16341;
@ -386,21 +381,26 @@ testnet.checkpoints.lastHeight = 546;
testnet.halvingInterval = 210000; testnet.halvingInterval = 210000;
testnet.genesis = { testnet.genesis = {
version: 1, version: 1,
hash: utils.revHex( hash: '43497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea330900000000',
'000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943'
),
prevBlock: '0000000000000000000000000000000000000000000000000000000000000000', prevBlock: '0000000000000000000000000000000000000000000000000000000000000000',
merkleRoot: utils.revHex( merkleRoot: '3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a',
'4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b'
),
ts: 1296688602, ts: 1296688602,
bits: 0x1d00ffff, bits: 486604799,
nonce: 414098458 nonce: 414098458
}; };
testnet.genesisBlock = '0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff001d1aa4ae180101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000'; testnet.genesisBlock =
'0100000000000000000000000000000000000000000000000000000000000000000000'
+ '003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5'
+ '494dffff001d1aa4ae1801010000000100000000000000000000000000000000000000'
+ '00000000000000000000000000ffffffff4d04ffff001d0104455468652054696d6573'
+ '2030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66'
+ '207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01'
+ '000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f'
+ '61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f'
+ 'ac00000000';
testnet.pow = {}; testnet.pow = {};
@ -492,21 +492,26 @@ regtest.checkpoints.lastHeight = 0;
regtest.halvingInterval = 150; regtest.halvingInterval = 150;
regtest.genesis = { regtest.genesis = {
version: 1, version: 1,
hash: utils.revHex( hash: '06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f',
'0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206'
),
prevBlock: '0000000000000000000000000000000000000000000000000000000000000000', prevBlock: '0000000000000000000000000000000000000000000000000000000000000000',
merkleRoot: utils.revHex( merkleRoot: '3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a',
'4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b'
),
ts: 1296688602, ts: 1296688602,
bits: 0x207fffff, bits: 545259519,
nonce: 2 nonce: 2
}; };
regtest.genesisBlock = '0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff7f20020000000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000'; regtest.genesisBlock =
'0100000000000000000000000000000000000000000000000000000000000000000000'
+ '003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5'
+ '494dffff7f200200000001010000000100000000000000000000000000000000000000'
+ '00000000000000000000000000ffffffff4d04ffff001d0104455468652054696d6573'
+ '2030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66'
+ '207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01'
+ '000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f'
+ '61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f'
+ 'ac00000000';
regtest.pow = {}; regtest.pow = {};
@ -593,13 +598,7 @@ segnet3.alertKey = new Buffer(''
+ 'db45200ca2b0a', + 'db45200ca2b0a',
'hex'); 'hex');
segnet3.checkpoints = []; segnet3.checkpoints = {};
segnet3.checkpoints = segnet3.checkpoints.reduce(function(out, block) {
out[block.height] = utils.revHex(block.hash);
return block;
}, {});
segnet3.checkpoints.tsLastCheckpoint = 0; segnet3.checkpoints.tsLastCheckpoint = 0;
segnet3.checkpoints.txsLastCheckpoint = 0; segnet3.checkpoints.txsLastCheckpoint = 0;
segnet3.checkpoints.txsPerDay = 300; segnet3.checkpoints.txsPerDay = 300;
@ -609,19 +608,24 @@ segnet3.halvingInterval = 210000;
segnet3.genesis = { segnet3.genesis = {
version: 1, version: 1,
hash: utils.revHex( hash: 'aa022fd26404d3a1f6ac348fc049996a52f40d833017c7ca3f05df8d519c5b0d',
'0d5b9c518ddf053fcac71730830df4526a9949c08f34acf6a1d30464d22f02aa'
),
prevBlock: '0000000000000000000000000000000000000000000000000000000000000000', prevBlock: '0000000000000000000000000000000000000000000000000000000000000000',
merkleRoot: utils.revHex( merkleRoot: '3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a',
'4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b'
),
ts: 1452831101, ts: 1452831101,
bits: 0x1d00ffff, bits: 486604799,
nonce: 0 nonce: 0
}; };
segnet3.genesisBlock = '0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a7d719856ffff001d000000000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000'; segnet3.genesisBlock =
'0100000000000000000000000000000000000000000000000000000000000000000000'
+ '003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a7d71'
+ '9856ffff001d0000000001010000000100000000000000000000000000000000000000'
+ '00000000000000000000000000ffffffff4d04ffff001d0104455468652054696d6573'
+ '2030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66'
+ '207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01'
+ '000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f'
+ '61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f'
+ 'ac00000000';
segnet3.pow = {}; segnet3.pow = {};
@ -699,13 +703,7 @@ segnet4.alertKey = new Buffer(''
+ 'db45200ca2b0a', + 'db45200ca2b0a',
'hex'); 'hex');
segnet4.checkpoints = []; segnet4.checkpoints = {};
segnet4.checkpoints = segnet4.checkpoints.reduce(function(out, block) {
out[block.height] = utils.revHex(block.hash);
return block;
}, {});
segnet4.checkpoints.tsLastCheckpoint = 0; segnet4.checkpoints.tsLastCheckpoint = 0;
segnet4.checkpoints.txsLastCheckpoint = 0; segnet4.checkpoints.txsLastCheckpoint = 0;
segnet4.checkpoints.txsPerDay = 300; segnet4.checkpoints.txsPerDay = 300;
@ -717,15 +715,22 @@ segnet4.genesis = {
version: 1, version: 1,
hash: 'b291211d4bb2b7e1b7a4758225e69e50104091a637213d033295c010f55ffb18', hash: 'b291211d4bb2b7e1b7a4758225e69e50104091a637213d033295c010f55ffb18',
prevBlock: '0000000000000000000000000000000000000000000000000000000000000000', prevBlock: '0000000000000000000000000000000000000000000000000000000000000000',
merkleRoot: utils.revHex( merkleRoot: '3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a',
'4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b'
),
ts: 1452831101, ts: 1452831101,
bits: 503447551, bits: 503447551,
nonce: 0 nonce: 0
}; };
segnet4.genesisBlock = '0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a7d719856ffff011e000000000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000'; segnet4.genesisBlock =
'0100000000000000000000000000000000000000000000000000000000000000000000'
+ '003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a7d71'
+ '9856ffff011e0000000001010000000100000000000000000000000000000000000000'
+ '00000000000000000000000000ffffffff4d04ffff001d0104455468652054696d6573'
+ '2030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66'
+ '207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01'
+ '000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f'
+ '61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f'
+ 'ac00000000';
segnet4.pow = {}; segnet4.pow = {};
@ -764,11 +769,6 @@ segnet4.deployments = {
startTime: 0, startTime: 0,
timeout: 999999999999 timeout: 999999999999
} }
// bip109: {
// bit: 4,
// startTime: 1453939200, // Jan 28th, 2016
// timeout: 1514764800 // Jan 1st, 2018
// }
}; };
segnet4.prefixes = { segnet4.prefixes = {

View File

@ -1533,7 +1533,7 @@ Script.prototype.interpret = function interpret(stack, flags, tx, index, version
v2 = Script.num(stack.pop(), flags).toNumber(); // begin v2 = Script.num(stack.pop(), flags).toNumber(); // begin
v1 = stack.pop(); // string v1 = stack.pop(); // string
if (v2 < 0 || v3 < v2) 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) if (v2 > v1.length)
v2 = v1.length; v2 = v1.length;
if (v3 > v1.length) if (v3 > v1.length)