diff --git a/lib/http/rpc.js b/lib/http/rpc.js index 5b0628ce..63307d91 100644 --- a/lib/http/rpc.js +++ b/lib/http/rpc.js @@ -993,7 +993,7 @@ RPC.prototype.getmempoolinfo = function getmempoolinfo(args) { bytes: this.mempool.getSize(), usage: this.mempool.getSize(), maxmempool: constants.mempool.MAX_MEMPOOL_SIZE, - mempoolminfee: +utils.btc(this.mempool.minFeeRate) + mempoolminfee: +utils.btc(this.mempool.minRelay) }); }; diff --git a/lib/mempool/mempool.js b/lib/mempool/mempool.js index 6fe70bde..b0939c4f 100644 --- a/lib/mempool/mempool.js +++ b/lib/mempool/mempool.js @@ -46,8 +46,8 @@ var flags = constants.flags; * @property {Number} maxSize * @property {Boolean} blockSinceBump * @property {Number} lastFeeUpdate - * @property {Rate} minFeeRate - * @property {Rate} minReasonableFee + * @property {Rate} minRate + * @property {Rate} minReasonable * @property {Rate} minRelayFee * @emits Mempool#open * @emits Mempool#error @@ -97,6 +97,7 @@ function Mempool(options) { this.limitFree = this.options.limitFree !== false; this.limitFreeRelay = this.options.limitFreeRelay || 15; this.relayPriority = this.options.relayPriority !== false; + this.rejectFee = this.options.rejectFee === true; this.requireStandard = this.options.requireStandard != null ? this.options.requireStandard : this.network.requireStandard; @@ -108,9 +109,9 @@ function Mempool(options) { this.expiryTime = options.expiryTime || constants.mempool.MEMPOOL_EXPIRY; this.blockSinceBump = false; this.lastFeeUpdate = utils.now(); - this.minFeeRate = 0; - this.minReasonableFee = constants.tx.MIN_RELAY; - this.minRelayFee = constants.tx.MIN_RELAY; + this.minRate = 0; + this.minReasonable = this.network.minRelay; + this.minRelay = this.network.minRelay; } utils.inherits(Mempool, AsyncObject); @@ -796,9 +797,9 @@ Mempool.prototype.removeUnchecked = function removeUnchecked(entry, limit) { if (limit) { this.logger.spam('Removed tx %s from mempool.', entry.tx.rhash); rate = bcoin.tx.getRate(entry.sizes, entry.fees); - rate += this.minReasonableFee; - if (rate > this.minFeeRate) { - this.minFeeRate = rate; + rate += this.minReasonable; + if (rate > this.minRate) { + this.minRate = rate; this.blockSinceBump = false; } } else { @@ -816,8 +817,8 @@ Mempool.prototype.removeUnchecked = function removeUnchecked(entry, limit) { Mempool.prototype.getMinRate = function getMinRate() { var now, halflife, size; - if (!this.blockSinceBump || this.minFeeRate === 0) - return this.minFeeRate; + if (!this.blockSinceBump || this.minRate === 0) + return this.minRate; now = utils.now(); @@ -830,17 +831,17 @@ Mempool.prototype.getMinRate = function getMinRate() { else if (size < this.maxSize / 2) halflife >>>= 1; - this.minFeeRate /= Math.pow(2.0, (now - this.lastFeeUpdate) / halflife | 0); - this.minFeeRate |= 0; + this.minRate /= Math.pow(2.0, (now - this.lastFeeUpdate) / halflife | 0); + this.minRate |= 0; this.lastFeeUpdate = now; - if (this.minFeeRate < this.minReasonableFee / 2) { - this.minFeeRate = 0; + if (this.minRate < this.minReasonable / 2) { + this.minRate = 0; return 0; } } - return Math.max(this.minFeeRate, this.minReasonableFee); + return Math.max(this.minRate, this.minReasonable); }; /** @@ -899,21 +900,20 @@ Mempool.prototype.verify = co(function* verify(entry) { fee = tx.getFee(); modFee = entry.fees; size = entry.size; - minRate = this.getMinRate(); - if (minRate > this.minRelayFee) - this.network.updateMinRelay(minRate); - - rejectFee = tx.getMinFee(size, minRate); - minRelayFee = tx.getMinFee(size, this.minRelayFee); - - if (rejectFee > 0 && modFee < rejectFee) { - throw new VerifyError(tx, - 'insufficientfee', - 'mempool min fee not met', - 0); + if (this.rejectFee) { + minRate = this.getMinRate(); + rejectFee = tx.getMinFee(size, minRate); + if (rejectFee > 0 && modFee < rejectFee) { + throw new VerifyError(tx, + 'insufficientfee', + 'mempool min fee not met', + 0); + } } + minRelayFee = tx.getMinFee(size, this.minRelay); + if (this.relayPriority && modFee < minRelayFee) { if (!entry.isFree(height)) { throw new VerifyError(tx, @@ -1219,8 +1219,10 @@ Mempool.prototype.storeOrphan = function storeOrphan(tx) { for (i = 0; i < tx.inputs.length; i++) { input = tx.inputs[i]; + if (input.coin) continue; + missing[input.prevout.hash] = true; } @@ -1888,69 +1890,6 @@ MempoolEntry.fromTX = function fromTX(tx, height) { return new MempoolEntry().fromTX(tx, height); }; -/** - * Serialize a mempool entry. Note that this - * can still be parsed as a regular tx since - * the mempool entry data comes after the - * serialized transaction. - * @param {BufferWriter?} writer - * @returns {Buffer} - */ - -MempoolEntry.prototype.toRaw = function toRaw(writer) { - var p = new BufferWriter(writer); - - this.tx.toRaw(p); - - p.writeU32(this.height); - p.writeU32(this.size); - p.writeDouble(this.priority); - p.writeVarint(this.fee); - p.writeVarint(this.chainValue); - p.writeU32(this.ts); - p.writeU32(this.count); - p.writeU32(this.sizes); - p.writeVarint(this.fees); - p.writeU8(this.dependencies ? 1 : 0); - - if (!writer) - p = p.render(); - - return p; -}; - -/** - * Inject properties from serialized data. - * @private - * @param {Buffer} data - */ - -MempoolEntry.prototype.fromRaw = function fromRaw(data) { - var p = new BufferReader(data); - this.tx = bcoin.tx.fromRaw(p); - this.height = p.readU32(); - this.size = p.readU32(); - this.priority = p.readDouble(); - this.fee = p.readVarint(); - this.chainValue = p.readVarint(); - this.ts = p.readU32(); - this.count = p.readU32(); - this.sizes = p.readU32(); - this.fees = p.readVarint(); - this.dependencies = p.readU8() === 1; - return this; -}; - -/** - * Create a mempool entry from serialized data. - * @param {Buffer|BufferReader} data - * @returns {MempoolEntry} - */ - -MempoolEntry.fromRaw = function fromRaw(data) { - return new MempoolEntry().fromRaw(data); -}; - /** * Calculate priority, taking into account * the entry height delta, modified size, diff --git a/lib/net/peer.js b/lib/net/peer.js index f6b84778..78b941ad 100644 --- a/lib/net/peer.js +++ b/lib/net/peer.js @@ -509,6 +509,17 @@ Peer.prototype.announce = co(function* announce(items) { if (!this.isWatched(item)) continue; + // Send them the block immediately if + // they're using compact block mode 1. + if (this.compactMode && this.compactMode.mode === 1) { + if (item instanceof bcoin.block) { + if (!this.invFilter.added(item.hash())) + continue; + yield this._sendCompactBlock(item, false); + continue; + } + } + // Convert item to block headers // for peers that request it. if (this.preferHeaders && item.toHeaders) { @@ -1514,7 +1525,7 @@ Peer.prototype._getItem = co(function* _getItem(item) { if (this.chain.db.options.prune) return; - return yield this.chain.db.getRawBlock(item.hash); + return yield this.chain.db.getBlock(item.hash); }); /** @@ -1559,6 +1570,27 @@ Peer.prototype._sendBlock = co(function* _sendBlock(item) { return true; }); +/** + * Send a compact block. + * @param {InvItem} item + * @returns {Boolean} + */ + +Peer.prototype._sendCompactBlock = function _sendCompactBlock(block, witness) { + // Try again with a new nonce + // if we get a siphash collision. + for (;;) { + try { + block = bcoin.bip152.CompactBlock.fromBlock(block); + } catch (e) { + continue; + } + break; + } + + return this.send(new packets.CmpctBlockPacket(block, witness)); +}; + /** * Handle `getdata` packet. * @private @@ -1650,18 +1682,7 @@ Peer.prototype._handleGetData = co(function* _handleGetData(packet) { continue; } - // Try again with a new nonce - // if we get a siphash collision. - for (;;) { - try { - block = bcoin.bip152.CompactBlock.fromBlock(block); - } catch (e) { - continue; - } - break; - } - - yield this.send(new packets.CmpctBlockPacket(block, false)); + yield this._sendCompactBlock(block, false); break; default: @@ -2076,8 +2097,7 @@ Peer.prototype._handleSendCmpct = function _handleSendCmpct(packet) { return; } - if (packet.mode !== 0) { - // Ignore (we can't do mode 1 yet). + if (packet.mode > 1) { this.logger.info('Peer request compact blocks mode %d (%s).', packet.mode, this.hostname); return; diff --git a/lib/protocol/network.js b/lib/protocol/network.js index 352b7ecf..291f2223 100644 --- a/lib/protocol/network.js +++ b/lib/protocol/network.js @@ -16,10 +16,6 @@ var networks = require('./networks'); * @exports Network * @constructor * @param {Object|NetworkType} options - See {@link module:network}. - * @property {Number} height - * @property {Rate} feeRate - * @property {Rate} minRelay - * @property {PolicyEstimator} fees */ function Network(options) { @@ -51,8 +47,6 @@ function Network(options) { this.rpcPort = options.rpcPort; this.minRelay = options.minRelay; this.feeRate = options.feeRate; - this.minRate = options.minRate; - this.maxRate = options.maxRate; this.selfConnect = options.selfConnect; this.requestMempool = options.requestMempool; this.batchSize = options.batchSize; @@ -85,50 +79,6 @@ Network.prototype.updateHeight = function updateHeight(height) { this.height = height; }; -/** - * Update the estimated fee rate of the network. - * @param {Rate} rate - */ - -Network.prototype.updateRate = function updateRate(rate) { - this.feeRate = rate; -}; - -/** - * Update the minimum relay rate (reject rate) of the network. - * @param {Rate} rate - */ - -Network.prototype.updateMinRelay = function updateMinRelay(rate) { - this.minRelay = rate; -}; - -/** - * Calculate the minimum relay rate. If the network is - * inactive (height=-1), return the default minimum relay. - * @return {Rate} Rate - */ - -Network.prototype.getMinRelay = function getMinRelay() { - if (this.height === -1) - return this.minRate; - - return Math.min(this.minRelay, this.maxRate); -}; - -/** - * Calculate the normal relay rate. If the network is - * inactive (height=-1), return the default rate. - * @return {Rate} Rate - */ - -Network.prototype.getRate = function getRate() { - if (this.height === -1) - return this.maxRate; - - return Math.min(this.feeRate, this.maxRate); -}; - /** * Determine how many blocks to request * based on current height of the chain. diff --git a/lib/protocol/networks.js b/lib/protocol/networks.js index 14a8d2cf..67660013 100644 --- a/lib/protocol/networks.js +++ b/lib/protocol/networks.js @@ -399,7 +399,7 @@ main.requireStandard = true; main.rpcPort = 8332; /** - * Default min relay rate (the rate for mempoolRejectFee). + * Default min relay rate. * @const {Rate} * @default */ @@ -414,22 +414,6 @@ main.minRelay = 10000; main.feeRate = 50000; -/** - * Default min rate. - * @const {Rate} - * @default - */ - -main.minRate = 10000; - -/** - * Default max rate. - * @const {Rate} - * @default - */ - -main.maxRate = 50000; - /** * Whether to allow self-connection. * @const {Boolean} @@ -597,10 +581,6 @@ testnet.minRelay = 10000; testnet.feeRate = 20000; -testnet.minRate = 10000; - -testnet.maxRate = 40000; - testnet.selfConnect = false; testnet.requestMempool = false; @@ -743,10 +723,6 @@ regtest.minRelay = 10000; regtest.feeRate = 20000; -regtest.minRate = 10000; - -regtest.maxRate = 40000; - regtest.selfConnect = true; regtest.requestMempool = true; @@ -863,10 +839,6 @@ segnet3.minRelay = 10000; segnet3.feeRate = 20000; -segnet3.minRate = 10000; - -segnet3.maxRate = 40000; - segnet3.selfConnect = false; segnet3.requestMempool = true; @@ -1002,10 +974,6 @@ segnet4.minRelay = 10000; segnet4.feeRate = 20000; -segnet4.minRate = 10000; - -segnet4.maxRate = 40000; - segnet4.selfConnect = false; segnet4.requestMempool = true; @@ -1149,10 +1117,6 @@ simnet.minRelay = 10000; simnet.feeRate = 20000; -simnet.minRate = 10000; - -simnet.maxRate = 40000; - simnet.selfConnect = true; simnet.requestMempool = false; diff --git a/lib/wallet/wallet.js b/lib/wallet/wallet.js index 3b2a0d26..68ab4c4b 100644 --- a/lib/wallet/wallet.js +++ b/lib/wallet/wallet.js @@ -938,7 +938,7 @@ Wallet.prototype._fund = co(function* fund(tx, options) { if (this.db.fees) rate = this.db.fees.estimateFee(); else - rate = this.network.getRate(); + rate = this.network.feeRate; } // Don't use any locked coins.