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