diff --git a/lib/blockchain/chain.js b/lib/blockchain/chain.js index 6ab9a9d8..287e011b 100644 --- a/lib/blockchain/chain.js +++ b/lib/blockchain/chain.js @@ -21,7 +21,6 @@ var assert = require('assert'); var errors = require('../btc/errors'); var VerifyError = errors.VerifyError; var VerifyResult = errors.VerifyResult; -var time = require('../net/time'); var co = require('../utils/co'); /** @@ -279,6 +278,7 @@ Chain.prototype.isGenesis = function isGenesis(block) { Chain.prototype.verify = co(function* verify(block, prev) { var ret = new VerifyResult(); + var now = this.network.now(); var i, err, height, ts, tx, medianTime; var commit, ancestors, state; @@ -286,7 +286,7 @@ Chain.prototype.verify = co(function* verify(block, prev) { if (this.isGenesis(block)) return this.state; - if (!block.verify(ret)) { + if (!block.verify(now, ret)) { err = new VerifyError(block, 'invalid', ret.reason, @@ -1199,6 +1199,7 @@ Chain.prototype.add = co(function* add(block) { Chain.prototype._add = co(function* add(block) { var ret = new VerifyResult(); + var now = this.network.now(); var initial = true; var hash, prevBlock, height, checkpoint; var orphan, entry, existing, prev; @@ -1248,7 +1249,7 @@ Chain.prototype._add = co(function* add(block) { // This is only necessary for new // blocks coming in, not the resolving // orphans. - if (initial && !block.verify(ret)) { + if (initial && !block.verify(now, ret)) { if (ret.reason === 'high-hash') this.invalid[hash] = true; this.emit('invalid', block, block.getCoinbaseHeight()); @@ -1840,7 +1841,7 @@ Chain.prototype.getTarget = function getTarget(block, prev, ancestors) { if ((prev.height + 1) % pow.retargetInterval !== 0) { if (pow.difficultyReset) { // Special behavior for testnet: - ts = block ? (block.ts || block) : time.now(); + ts = block ? (block.ts || block) : this.network.now(); if (ts > prev.ts + pow.targetSpacing * 2) return pow.bits; @@ -2123,7 +2124,7 @@ Chain.prototype.checkFinal = co(function* checkFinal(prev, tx, flags) { return tx.isFinal(height, ts); } - return tx.isFinal(height, time.now()); + return tx.isFinal(height, this.network.now()); }); /** diff --git a/lib/env.js b/lib/env.js index 57e3ef89..acffe9cc 100644 --- a/lib/env.js +++ b/lib/env.js @@ -165,7 +165,6 @@ function Environment() { this.require('peer', './net/peer'); this.require('pool', './net/pool'); this.require('tcp', './net/tcp'); - this.require('time', './net/time'); // Node this.require('node', './node'); @@ -195,6 +194,7 @@ function Environment() { this.require('constants', './protocol/constants'); this.require('network', './protocol/network'); this.require('networks', './protocol/networks'); + this.require('timedata', './protocol/timedata'); // Script this.require('scripting', './script'); // -> scripting? @@ -254,7 +254,7 @@ Environment.prototype.set = function set(options) { */ Environment.prototype.now = function now() { - return this.time.now(); + return this.network.primary.now(); }; /** diff --git a/lib/http/rpc.js b/lib/http/rpc.js index 43530114..3a65cba9 100644 --- a/lib/http/rpc.js +++ b/lib/http/rpc.js @@ -12,7 +12,6 @@ var crypto = require('../crypto/crypto'); var assert = require('assert'); var constants = require('../protocol/constants'); var ec = require('../crypto/ec'); -var time = require('../net/time'); var Amount = require('../btc/amount'); var NetworkAddress = require('../primitives/netaddress'); var Script = require('../script/script'); @@ -323,7 +322,7 @@ RPC.prototype.getinfo = co(function* getinfo(args) { walletversion: 0, balance: Amount.btc(balance.unconfirmed, true), blocks: this.chain.height, - timeoffset: time.offset, + timeoffset: this.network.time.offset, connections: this.pool.peers.all.length, proxy: '', difficulty: this._getDifficulty(), @@ -375,7 +374,7 @@ RPC.prototype.getnetworkinfo = function getnetworkinfo(args) { subversion: constants.USER_AGENT, protocolversion: constants.VERSION, localservices: this.pool.services, - timeoffset: time.offset, + timeoffset: this.network.time.offset, connections: this.pool.peers.all.length, networks: [], relayfee: Amount.btc(this.network.getMinRelay(), true), @@ -1242,6 +1241,7 @@ RPC.prototype.gettxoutproof = co(function* gettxoutproof(args) { }); RPC.prototype.verifytxoutproof = co(function* verifytxoutproof(args) { + var now = this.network.now(); var res = []; var i, block, hash, entry; @@ -1250,7 +1250,7 @@ RPC.prototype.verifytxoutproof = co(function* verifytxoutproof(args) { block = MerkleBlock.fromRaw(toString(args[0]), 'hex'); - if (!block.verify()) + if (!block.verify(now)) return res; entry = yield this.chain.db.getEntry(block.hash('hex')); @@ -1311,6 +1311,7 @@ RPC.prototype._submitwork = co(function* _submitwork(data) { }); RPC.prototype.__submitwork = co(function* _submitwork(data) { + var now = this.network.now(); var attempt = this.attempt; var block, header, cb, cur; @@ -1332,7 +1333,7 @@ RPC.prototype.__submitwork = co(function* _submitwork(data) { return false; } - if (!header.verify()) + if (!header.verify(now)) return false; cb = this.coinbase[header.merkleRoot]; @@ -1620,7 +1621,7 @@ RPC.prototype.__template = co(function* _template(version, coinbase, rules) { target: util.revHex(attempt.target.toString('hex')), submitold: false, mintime: block.ts, - maxtime: time.now() + 2 * 60 * 60, + maxtime: this.network.now() + 2 * 60 * 60, mutable: mutable, noncerange: '00000000ffffffff', sigoplimit: attempt.witness @@ -2637,8 +2638,9 @@ RPC.prototype.setmocktime = function setmocktime(args) { if (ts < 0) return Promise.reject(new RPCError('Invalid parameter.')); - delta = time.now() - ts; - time.offset = -delta; + delta = this.network.now() - ts; + + this.network.time.offset = -delta; return Promise.resolve(); }; @@ -4010,6 +4012,7 @@ RPC.prototype.walletpassphrase = co(function* walletpassphrase(args) { }); RPC.prototype.importprunedfunds = co(function* importprunedfunds(args) { + var now = this.network.now(); var tx, block, label, height; if (args.help || args.length < 2 || args.length > 3) { @@ -4029,7 +4032,7 @@ RPC.prototype.importprunedfunds = co(function* importprunedfunds(args) { if (args.length === 3) label = toString(args[2]); - if (!block.verify()) + if (!block.verify(now)) throw new RPCError('Invalid proof.'); if (!block.hasTX(tx)) diff --git a/lib/http/server.js b/lib/http/server.js index f7654d4f..7eb6dd4e 100644 --- a/lib/http/server.js +++ b/lib/http/server.js @@ -26,7 +26,6 @@ var Outpoint = require('../primitives/outpoint'); var HD = require('../hd/hd'); var Script = require('../script/script'); var crypto = require('../crypto/crypto'); -var time = require('../net/time'); var con = co.con; var RPC; @@ -588,8 +587,8 @@ HTTPServer.prototype._init = function _init() { mempoolSize: size, uptime: Math.floor(util.uptime()), systemTime: util.now(), - adjustedTime: time.now(), - timeOffset: time.offset, + adjustedTime: this.network.now(), + timeOffset: this.network.time.offset, memory: getMemory() }); }); diff --git a/lib/mining/miner.js b/lib/mining/miner.js index 3bc575c8..9c4bd6cc 100644 --- a/lib/mining/miner.js +++ b/lib/mining/miner.js @@ -14,7 +14,6 @@ var constants = require('../protocol/constants'); var AsyncObject = require('../utils/async'); var MinerBlock = require('./minerblock'); var Address = require('../primitives/address'); -var time = require('../net/time'); /** * A bitcoin miner (supports mining witness blocks). @@ -313,7 +312,7 @@ Miner.prototype.createBlock = co(function* createBlock(tip, address) { assert(tip); - ts = Math.max(time.now(), tip.ts + 1); + ts = Math.max(this.network.now(), tip.ts + 1); locktime = ts; target = yield this.chain.getTargetAsync(ts, tip); diff --git a/lib/mining/minerblock.js b/lib/mining/minerblock.js index 76128162..5d0add6c 100644 --- a/lib/mining/minerblock.js +++ b/lib/mining/minerblock.js @@ -11,7 +11,6 @@ var assert = require('assert'); var util = require('../utils/util'); var btcutils = require('../btc/utils'); var co = require('../utils/co'); -var crypto = require('../crypto/crypto'); var constants = require('../protocol/constants'); var Network = require('../protocol/network'); var BN = require('bn.js'); @@ -20,7 +19,6 @@ var TX = require('../primitives/tx'); var Block = require('../primitives/block'); var Input = require('../primitives/input'); var Output = require('../primitives/output'); -var time = require('../net/time'); var mine = require('./mine'); var workerPool = require('../workers/workerpool').pool; @@ -113,7 +111,7 @@ MinerBlock.prototype._init = function _init() { block.version = this.version; block.prevBlock = this.tip.hash; block.merkleRoot = constants.NULL_HASH; - block.ts = Math.max(time.now(), this.tip.ts + 1); + block.ts = Math.max(this.network.now(), this.tip.ts + 1); block.bits = this.bits; block.nonce = 0; block.height = this.height; @@ -223,7 +221,7 @@ MinerBlock.prototype.updateCoinbase = function updateCoinbase() { */ MinerBlock.prototype.updateNonce = function updateNonce() { - this.block.ts = Math.max(time.now(), this.tip.ts + 1); + this.block.ts = Math.max(this.network.now(), this.tip.ts + 1); // Overflow the nonce and increment the extraNonce. this.block.nonce = 0; @@ -249,7 +247,7 @@ MinerBlock.prototype.updateMerkle = function updateMerkle() { this.updateCommitment(); // Update timestamp. - this.block.ts = Math.max(time.now(), this.tip.ts + 1); + this.block.ts = Math.max(this.network.now(), this.tip.ts + 1); // Recalculate merkle root. this.block.merkleRoot = this.block.createMerkleRoot('hex'); @@ -430,7 +428,7 @@ MinerBlock.prototype.mineAsync = co(function* mineAsync() { MinerBlock.prototype.iterate = function iterate() { var block = this.block; var tip = this.tip; - var now = time.now(); + var now = this.network.now(); // Keep track of our iterations. this.iterations++; diff --git a/lib/net/bip152.js b/lib/net/bip152.js index d486c12c..ac174ae3 100644 --- a/lib/net/bip152.js +++ b/lib/net/bip152.js @@ -52,8 +52,8 @@ function CompactBlock(options) { util.inherits(CompactBlock, AbstractBlock); -CompactBlock.prototype._verify = function _verify(ret) { - return this.verifyHeaders(ret); +CompactBlock.prototype._verify = function _verify(now, ret) { + return this.verifyHeaders(now, ret); }; CompactBlock.prototype.fromOptions = function fromOptions(options) { diff --git a/lib/net/packets.js b/lib/net/packets.js index 31c0794a..c973568d 100644 --- a/lib/net/packets.js +++ b/lib/net/packets.js @@ -11,7 +11,6 @@ var constants = require('../protocol/constants'); var util = require('../utils/util'); var assert = require('assert'); var crypto = require('../crypto/crypto'); -var time = require('./time'); var ec = require('../crypto/ec'); var Bloom = require('../utils/bloom'); var bip152 = require('./bip152'); @@ -118,7 +117,7 @@ function VersionPacket(options) { this.version = constants.VERSION; this.services = constants.LOCAL_SERVICES; - this.ts = time.now(); + this.ts = util.now(); this.recv = new NetworkAddress(); this.from = new NetworkAddress(); this.nonce = constants.ZERO_U64; @@ -517,7 +516,7 @@ function AlertPacket(options) { Packet.call(this); - ts = time.now() + 7 * 86400; + ts = util.now() + 7 * 86400; this.version = 1; this.relayUntil = ts; diff --git a/lib/net/peer.js b/lib/net/peer.js index afa665d2..cc209e1c 100644 --- a/lib/net/peer.js +++ b/lib/net/peer.js @@ -26,7 +26,6 @@ var BIP150 = require('./bip150'); var BIP152 = require('./bip152'); var Block = require('../primitives/block'); var TX = require('../primitives/tx'); -var time = require('./time'); /** * Represents a remote peer. @@ -661,7 +660,7 @@ Peer.prototype.sendVersion = function sendVersion() { var packet = new packets.VersionPacket({ version: constants.VERSION, services: this.pool.services, - ts: time.now(), + ts: this.network.now(), recv: new NetworkAddress(), from: this.pool.address, nonce: this.pool.localNonce, @@ -1864,11 +1863,18 @@ Peer.prototype._handleNotFound = function _handleNotFound(packet) { */ Peer.prototype._handleAddr = function _handleAddr(packet) { + var now = this.network.now(); var addrs = packet.items; - var i; + var i, addr; - for (i = 0; i < addrs.length; i++) - this.addrFilter.add(addrs[i].host, 'ascii'); + for (i = 0; i < addrs.length; i++) { + addr = addrs[i]; + + if (addr.ts <= 100000000 || addr.ts > now + 10 * 60) + addr.ts = now - 5 * 24 * 60 * 60; + + this.addrFilter.add(addr.host, 'ascii'); + } this.logger.info( 'Received %d addrs (hosts=%d, peers=%d) (%s).', diff --git a/lib/net/pool.js b/lib/net/pool.js index 6010efb3..bbef75a1 100644 --- a/lib/net/pool.js +++ b/lib/net/pool.js @@ -25,7 +25,6 @@ var ec = require('../crypto/ec'); var InvItem = require('../primitives/invitem'); var Locker = require('../utils/locker'); var Network = require('../protocol/network'); -var time = require('./time'); var Peer = require('./peer'); var TX = require('../primitives/tx'); var tcp = require('./tcp'); @@ -462,7 +461,7 @@ Pool.prototype._handleLeech = function _handleLeech(socket) { return; } - addr = NetworkAddress.fromSocket(socket); + addr = NetworkAddress.fromSocket(socket, this.network); if (this.peers.leeches.length >= this.maxLeeches) { this.logger.debug('Ignoring leech: too many leeches (%s).', addr.hostname); @@ -733,11 +732,12 @@ Pool.prototype._handleHeaders = co(function* _handleHeaders(headers, peer) { */ Pool.prototype.__handleHeaders = co(function* _handleHeaders(headers, peer) { - var i, ret, header, hash, last; + var i, now, ret, header, hash, last; if (!this.options.headers) return; + now = this.network.now(); ret = new VerifyResult(); this.logger.debug( @@ -763,7 +763,7 @@ Pool.prototype.__handleHeaders = co(function* _handleHeaders(headers, peer) { throw new Error('Bad header chain.'); } - if (!header.verify(ret)) { + if (!header.verify(now, ret)) { peer.reject(header, 'invalid', ret.reason, 100); throw new Error('Invalid header.'); } @@ -1216,7 +1216,7 @@ Pool.prototype.createPeer = function createPeer(addr, socket) { version.services.toString(2), version.agent); - time.add(peer.hostname, version.ts); + self.network.time.add(peer.hostname, version.ts); self.emit('version', version, peer); }); @@ -1254,7 +1254,7 @@ Pool.prototype.createPeer = function createPeer(addr, socket) { */ Pool.prototype._handleAlert = function _handleAlert(alert, peer) { - var now = time.now(); + var now = this.network.now(); if (!alert.verify(this.network.alertKey)) { this.logger.warning('Peer sent a phony alert packet (%s).', peer.hostname); diff --git a/lib/node/node.js b/lib/node/node.js index b1489fb9..7dd8461f 100644 --- a/lib/node/node.js +++ b/lib/node/node.js @@ -14,7 +14,6 @@ var assert = require('assert'); var Network = require('../protocol/network'); var Logger = require('./logger'); var NodeClient = require('./nodeclient'); -var time = require('../net/time'); var workerPool = require('../workers/workerpool').pool; /** @@ -95,16 +94,16 @@ Node.prototype._onOpen = function _onOpen() { this.logger.open(); - this._bind(time, 'offset', function(offset) { + this._bind(this.network.time, 'offset', function(offset) { self.logger.info('Time offset: %d (%d minutes).', offset, offset / 60 | 0); }); - this._bind(time, 'sample', function(sample, total) { + this._bind(this.network.time, 'sample', function(sample, total) { self.logger.debug('Added time data: samples=%d, offset=%d (%d minutes).', total, sample, sample / 60 | 0); }); - this._bind(time, 'mismatch', function() { + this._bind(this.network.time, 'mismatch', function() { self.logger.warning('Please make sure your system clock is correct!'); }); diff --git a/lib/primitives/abstractblock.js b/lib/primitives/abstractblock.js index 39f574c7..5ad0855f 100644 --- a/lib/primitives/abstractblock.js +++ b/lib/primitives/abstractblock.js @@ -14,7 +14,6 @@ var crypto = require('../crypto/crypto'); var btcutils = require('../btc/utils'); var VerifyResult = require('../btc/errors').VerifyResult; var BufferWriter = require('../utils/writer'); -var time = require('../net/time'); var InvItem = require('./invitem'); /** @@ -188,11 +187,11 @@ AbstractBlock.prototype.abbr = function abbr(writer) { * @returns {Boolean} */ -AbstractBlock.prototype.verify = function verify(ret) { +AbstractBlock.prototype.verify = function verify(now, ret) { var valid = this._valid; if (valid == null) { - valid = this._verify(ret); + valid = this._verify(now, ret); if (!this.mutable) this._valid = valid; } @@ -203,12 +202,16 @@ AbstractBlock.prototype.verify = function verify(ret) { /** * Verify the block headers (called by `verify()` in * all objects which inherit from AbstractBlock). + * @param {Number|null} - Adjusted time. * @param {Object?} ret - Return object, may be * set with properties `reason` and `score`. * @returns {Boolean} */ -AbstractBlock.prototype.verifyHeaders = function verifyHeaders(ret) { +AbstractBlock.prototype.verifyHeaders = function verifyHeaders(now, ret) { + if (!now) + now = util.now(); + if (!ret) ret = new VerifyResult(); @@ -220,7 +223,7 @@ AbstractBlock.prototype.verifyHeaders = function verifyHeaders(ret) { } // Check timestamp against adjusted-time + 2 hours. - if (this.ts > time.now() + 2 * 60 * 60) { + if (this.ts > now + 2 * 60 * 60) { ret.reason = 'time-too-new'; ret.score = 0; return false; diff --git a/lib/primitives/block.js b/lib/primitives/block.js index c80e3776..ada5f533 100644 --- a/lib/primitives/block.js +++ b/lib/primitives/block.js @@ -427,12 +427,13 @@ Block.prototype.getCommitmentHash = function getCommitmentHash(enc) { * Do non-contextual verification on the block. Including checking the block * size, the coinbase and the merkle root. This is consensus-critical. * @alias Block#verify + * @param {Number|null} - Adjusted time. * @param {Object?} ret - Return object, may be * set with properties `reason` and `score`. * @returns {Boolean} */ -Block.prototype._verify = function _verify(ret) { +Block.prototype._verify = function _verify(now, ret) { var sigops = 0; var scale = constants.WITNESS_SCALE_FACTOR; var i, tx, merkle; @@ -440,7 +441,7 @@ Block.prototype._verify = function _verify(ret) { if (!ret) ret = new VerifyResult(); - if (!this.verifyHeaders(ret)) + if (!this.verifyHeaders(now, ret)) return false; // Size can't be bigger than MAX_BLOCK_SIZE diff --git a/lib/primitives/headers.js b/lib/primitives/headers.js index c09bd017..9ce9a850 100644 --- a/lib/primitives/headers.js +++ b/lib/primitives/headers.js @@ -32,13 +32,14 @@ util.inherits(Headers, AbstractBlock); /** * Do non-contextual verification on the headers. * @alias Headers#verify + * @param {Number|null} - Adjusted time. * @param {Object?} ret - Return object, may be * set with properties `reason` and `score`. * @returns {Boolean} */ -Headers.prototype._verify = function _verify(ret) { - return this.verifyHeaders(ret); +Headers.prototype._verify = function _verify(now, ret) { + return this.verifyHeaders(now, ret); }; /** diff --git a/lib/primitives/memblock.js b/lib/primitives/memblock.js index 3ca10296..4156d1ed 100644 --- a/lib/primitives/memblock.js +++ b/lib/primitives/memblock.js @@ -106,13 +106,14 @@ MemBlock.prototype.getSize = function getSize() { /** * Verify the block headers. * @alias MemBlock#verify + * @param {Number|null} - Adjusted time. * @param {Object?} ret - Return object, may be * set with properties `reason` and `score`. * @returns {Boolean} */ -MemBlock.prototype._verify = function _verify(ret) { - return this.verifyHeaders(ret); +MemBlock.prototype._verify = function _verify(now, ret) { + return this.verifyHeaders(now, ret); }; /** diff --git a/lib/primitives/merkleblock.js b/lib/primitives/merkleblock.js index d470b518..dcd9f43e 100644 --- a/lib/primitives/merkleblock.js +++ b/lib/primitives/merkleblock.js @@ -279,16 +279,17 @@ MerkleBlock.prototype.extractTree = function extractTree() { * Do non-contextual verification on the block. * Verify the headers and the partial merkle tree. * @alias MerkleBlock#verify + * @param {Number|null} - Adjusted time. * @param {Object?} ret - Return object, may be * set with properties `reason` and `score`. * @returns {Boolean} */ -MerkleBlock.prototype._verify = function _verify(ret) { +MerkleBlock.prototype._verify = function _verify(now, ret) { if (!ret) ret = new VerifyResult(); - if (!this.verifyHeaders(ret)) + if (!this.verifyHeaders(now, ret)) return false; if (!this.verifyPartial()) { diff --git a/lib/primitives/netaddress.js b/lib/primitives/netaddress.js index 8fdf3bbc..e52635a3 100644 --- a/lib/primitives/netaddress.js +++ b/lib/primitives/netaddress.js @@ -8,7 +8,6 @@ var constants = require('../protocol/constants'); var Network = require('../protocol/network'); -var time = require('../net/time'); var util = require('../utils/util'); var IP = require('../utils/ip'); var assert = require('assert'); @@ -193,7 +192,7 @@ NetworkAddress.prototype.fromHostname = function fromHostname(hostname, network) this.services = constants.services.NETWORK | constants.services.BLOOM | constants.services.WITNESS; - this.ts = time.now(); + this.ts = network.now(); this.hostname = IP.hostname(this.host, this.port); @@ -218,16 +217,18 @@ NetworkAddress.fromHostname = function fromHostname(hostname, network) { * @param {net.Socket} socket */ -NetworkAddress.prototype.fromSocket = function fromSocket(socket) { +NetworkAddress.prototype.fromSocket = function fromSocket(socket, network) { assert(typeof socket.remoteAddress === 'string'); assert(typeof socket.remotePort === 'number'); + network = Network.get(network); + this.host = IP.normalize(socket.remoteAddress); this.port = socket.remotePort; this.services = constants.services.NETWORK | constants.services.BLOOM | constants.services.WITNESS; - this.ts = time.now(); + this.ts = network.now(); this.hostname = IP.hostname(this.host, this.port); @@ -241,8 +242,8 @@ NetworkAddress.prototype.fromSocket = function fromSocket(socket) { * @returns {NetworkAddress} */ -NetworkAddress.fromSocket = function fromSocket(hostname) { - return new NetworkAddress().fromSocket(hostname); +NetworkAddress.fromSocket = function fromSocket(hostname, network) { + return new NetworkAddress().fromSocket(hostname, network); }; /** @@ -254,7 +255,6 @@ NetworkAddress.fromSocket = function fromSocket(hostname) { NetworkAddress.prototype.fromRaw = function fromRaw(data, full) { var br = BufferReader(data); - var now = time.now(); // only version >= 31402 this.ts = full ? br.readU32() : 0; @@ -262,9 +262,6 @@ NetworkAddress.prototype.fromRaw = function fromRaw(data, full) { this.host = IP.toString(br.readBytes(16)); this.port = br.readU16BE(); - if (this.ts <= 100000000 || this.ts > now + 10 * 60) - this.ts = now - 5 * 24 * 60 * 60; - this.hostname = IP.hostname(this.host, this.port); return this; diff --git a/lib/protocol/network.js b/lib/protocol/network.js index d291ed89..85fd3eab 100644 --- a/lib/protocol/network.js +++ b/lib/protocol/network.js @@ -11,6 +11,7 @@ var assert = require('assert'); var util = require('../utils/util'); var networks = require('./networks'); var constants = require('./constants'); +var TimeData = require('./timedata'); /** * Represents a network. @@ -53,6 +54,7 @@ function Network(options) { this.selfConnect = options.selfConnect; this.requestMempool = options.requestMempool; this.batchSize = options.batchSize; + this.time = new TimeData(); this._init(); } @@ -135,6 +137,15 @@ Network.prototype.getBatchSize = function getBatchSize(height) { return batch[last][0]; }; +/** + * Get network adjusted time. + * @returns {Number} + */ + +Network.prototype.now = function now() { + return this.time.now(); +}; + /** * Create a network. Get existing network if possible. * @param {NetworkType|Object} options diff --git a/lib/net/time.js b/lib/protocol/timedata.js similarity index 92% rename from lib/net/time.js rename to lib/protocol/timedata.js index 927daca0..2ebfc2ba 100644 --- a/lib/net/time.js +++ b/lib/protocol/timedata.js @@ -44,21 +44,21 @@ util.inherits(TimeData, EventEmitter); /** * Add time data. - * @param {String} host + * @param {String} id * @param {Number} time */ -TimeData.prototype.add = function add(host, time) { +TimeData.prototype.add = function add(id, time) { var sample = time - util.now(); var i, median, match, offset; if (this.samples.length >= this.limit) return; - if (this.known[host] != null) + if (this.known[id] != null) return; - this.known[host] = sample; + this.known[id] = sample; util.binaryInsert(this.samples, sample, compare); @@ -112,4 +112,4 @@ function compare(a, b) { * Expose */ -module.exports = new TimeData(); +module.exports = TimeData; diff --git a/test/block-test.js b/test/block-test.js index 25a57254..336f4adf 100644 --- a/test/block-test.js +++ b/test/block-test.js @@ -166,7 +166,7 @@ describe('Block', function() { block2.merkleRoot = constants.NULL_HASH; delete block2._valid; var ret = {}; - assert(!block2.verify(ret)); + assert(!block2.verify(0, ret)); assert.equal(ret.reason, 'bad-txnmrklroot'); delete block2._valid; delete block2._hash; @@ -179,7 +179,7 @@ describe('Block', function() { mblock2.hash(); mblock2.merkleRoot = constants.NULL_HASH; var ret = {}; - assert(!mblock2.verify(ret)); + assert(!mblock2.verify(0, ret)); assert.equal(ret.reason, 'bad-txnmrklroot'); delete mblock2._validPartial; delete mblock2._valid; @@ -193,7 +193,7 @@ describe('Block', function() { block2.hash(); block2.bits = 403014710; var ret = {}; - assert(!block2.verify(ret)); + assert(!block2.verify(0, ret)); assert.equal(ret.reason, 'high-hash'); delete block2._valid; delete block2._hash; @@ -205,7 +205,7 @@ describe('Block', function() { var block2 = new bcoin.block(block); block2.txs.push(block2.txs[block2.txs.length - 1]); var ret = {}; - assert(!block2.verify(ret)); + assert(!block2.verify(0, ret)); assert.equal(ret.reason, 'bad-txns-duplicate'); });