no more dynamic heights.
This commit is contained in:
parent
1761266ba9
commit
2ec7989b6a
@ -31,6 +31,7 @@ function Block(data, subtype) {
|
||||
this.bits = data.bits;
|
||||
this.nonce = data.nonce;
|
||||
this.totalTX = data.totalTX;
|
||||
this.height = data.height != null ? data.height : -1;
|
||||
this.hashes = (data.hashes || []).map(function(hash) {
|
||||
return utils.toHex(hash);
|
||||
});
|
||||
@ -81,6 +82,7 @@ function Block(data, subtype) {
|
||||
tx.block = null;
|
||||
if (tx.ts === self.ts)
|
||||
tx.ts = 0;
|
||||
tx.height = -1;
|
||||
return tx;
|
||||
});
|
||||
}
|
||||
@ -200,6 +202,8 @@ Block.prototype.getMerkleRoot = function getMerkleRoot() {
|
||||
var merkleTree = [];
|
||||
var i, j, size, i2, hash;
|
||||
|
||||
assert(this.subtype === 'block');
|
||||
|
||||
for (i = 0; i < this.txs.length; i++) {
|
||||
merkleTree.push(this.txs[i].hash('hex'));
|
||||
}
|
||||
@ -485,8 +489,12 @@ Block.prototype.isGenesis = function isGenesis() {
|
||||
};
|
||||
|
||||
Block.prototype.getHeight = function getHeight() {
|
||||
if (this.height !== -1)
|
||||
return this.height;
|
||||
|
||||
if (!this.chain)
|
||||
return -1;
|
||||
|
||||
return this.chain.getHeight(this.hash('hex'));
|
||||
};
|
||||
|
||||
@ -526,9 +534,11 @@ Block.prototype._getReward = function _getReward() {
|
||||
if (this._reward)
|
||||
return this._reward;
|
||||
|
||||
base = Block.reward(this.getHeight());
|
||||
base = Block.reward(this.height);
|
||||
|
||||
if (this.txs.length === 0 || !this.txs[0].isCoinbase()) {
|
||||
if (this.subtype !== 'block'
|
||||
|| this.txs.length === 0
|
||||
|| !this.txs[0].isCoinbase()) {
|
||||
return this._reward = {
|
||||
fee: new bn(0),
|
||||
reward: base,
|
||||
@ -583,9 +593,15 @@ Block.prototype.isOrphan = function isOrphan() {
|
||||
};
|
||||
|
||||
Block.prototype.getCoinbase = function getCoinbase() {
|
||||
var tx = this.txs[0];
|
||||
var tx;
|
||||
|
||||
if (this.subtype !== 'block')
|
||||
return;
|
||||
|
||||
tx = this.txs[0];
|
||||
if (!tx || !tx.isCoinbase())
|
||||
return;
|
||||
|
||||
return tx;
|
||||
};
|
||||
|
||||
@ -597,10 +613,6 @@ Block.prototype.__defineGetter__('rhash', function() {
|
||||
return utils.revHex(this.hash('hex'));
|
||||
});
|
||||
|
||||
Block.prototype.__defineGetter__('height', function() {
|
||||
return this.getHeight();
|
||||
});
|
||||
|
||||
Block.prototype.__defineGetter__('nextBlock', function() {
|
||||
return this.getNextBlock();
|
||||
});
|
||||
@ -632,7 +644,6 @@ Block.prototype.inspect = function inspect() {
|
||||
delete copy._chain;
|
||||
copy.hash = this.hash('hex');
|
||||
copy.rhash = this.rhash;
|
||||
copy.height = this.getHeight();
|
||||
copy.nextBlock = this.getNextBlock();
|
||||
copy.reward = utils.btc(this.getReward());
|
||||
copy.fee = utils.btc(this.getFee());
|
||||
@ -648,6 +659,7 @@ Block.prototype.toJSON = function toJSON() {
|
||||
hash: this.hash('hex'),
|
||||
prevBlock: this.prevBlock,
|
||||
ts: this.ts,
|
||||
height: this.height,
|
||||
network: this.network,
|
||||
relayedBy: this.relayedBy,
|
||||
block: utils.toHex(this.render())
|
||||
@ -669,6 +681,7 @@ Block.fromJSON = function fromJSON(json) {
|
||||
else if (json.subtype === 'block' || json.subtype === 'header')
|
||||
data = parser.parseBlock(raw);
|
||||
|
||||
data.height = json.height;
|
||||
data.network = json.network;
|
||||
data.relayedBy = json.relayedBy;
|
||||
|
||||
|
||||
@ -367,6 +367,12 @@ Chain.prototype.add = function add(block, peer) {
|
||||
if (code !== Chain.codes.okay)
|
||||
break;
|
||||
|
||||
// Update the block height
|
||||
block.height = entry.height;
|
||||
block.txs.forEach(function(tx) {
|
||||
tx.height = entry.height;
|
||||
}, this);
|
||||
|
||||
// Keep track of the number of blocks we
|
||||
// added and the number of orphans resolved.
|
||||
total++;
|
||||
@ -376,11 +382,11 @@ Chain.prototype.add = function add(block, peer) {
|
||||
this.emit('block', block, peer);
|
||||
this.emit('entry', entry);
|
||||
if (block !== initial)
|
||||
this.emit('resolved', entry);
|
||||
}
|
||||
this.emit('resolved', entry.hash);
|
||||
|
||||
// Fullfill request
|
||||
this.request.fullfill(hash, block);
|
||||
// Fullfill request
|
||||
this.request.fullfill(hash, block);
|
||||
}
|
||||
|
||||
if (!this.orphan.map[hash])
|
||||
break;
|
||||
@ -396,6 +402,9 @@ Chain.prototype.add = function add(block, peer) {
|
||||
// Failsafe for large orphan chains. Do not
|
||||
// allow more than 20mb stored in memory.
|
||||
if (this.orphan.size > 20971520) {
|
||||
Object.keys(this.orphan.bmap).forEach(function(hash) {
|
||||
this.emit('unresolved', hash);
|
||||
}, this);
|
||||
this.orphan.map = {};
|
||||
this.orphan.bmap = {};
|
||||
this.orphan.count = 0;
|
||||
|
||||
@ -34,7 +34,7 @@ function Coin(tx, index) {
|
||||
this.index = index;
|
||||
this.value = tx.outputs[index].value;
|
||||
this.script = tx.outputs[index].script;
|
||||
this.height = tx.getHeight();
|
||||
this.height = tx.height;
|
||||
} else {
|
||||
options = tx;
|
||||
this.hash = options.hash;
|
||||
@ -64,13 +64,17 @@ Coin.prototype.__defineGetter__('chain', function() {
|
||||
return this._chain || bcoin.chain.global;
|
||||
});
|
||||
|
||||
Coin.prototype.getConfirmations = function getConfirmations() {
|
||||
Coin.prototype.getConfirmations = function getConfirmations(height) {
|
||||
var top;
|
||||
|
||||
if (!this.chain)
|
||||
return 0;
|
||||
if (height == null) {
|
||||
if (!this.chain)
|
||||
return 0;
|
||||
|
||||
top = this.chain.height();
|
||||
top = this.chain.height();
|
||||
} else {
|
||||
top = height;
|
||||
}
|
||||
|
||||
if (this.height === -1)
|
||||
return 0;
|
||||
@ -85,8 +89,8 @@ Coin.prototype.__defineGetter__('confirmations', function() {
|
||||
return this.getConfirmations();
|
||||
});
|
||||
|
||||
Coin.prototype.getAge = function getAge() {
|
||||
var age = this.getConfirmations();
|
||||
Coin.prototype.getAge = function getAge(height) {
|
||||
var age = this.getConfirmations(height);
|
||||
|
||||
if (age === -1)
|
||||
age = 0;
|
||||
|
||||
@ -35,7 +35,7 @@ function Input(options) {
|
||||
this.prevout.hash = utils.toHex(this.prevout.hash);
|
||||
|
||||
if (!this.prevout.rhash)
|
||||
this.prevout.rhash = utils.toHex(this.prevout.hash);
|
||||
this.prevout.rhash = utils.revHex(this.prevout.hash);
|
||||
|
||||
this.script = options.script ? options.script.slice() : [];
|
||||
this.sequence = options.sequence == null ? 0xffffffff : options.sequence;
|
||||
|
||||
@ -341,6 +341,9 @@ Peer.prototype._onPacket = function onPacket(packet) {
|
||||
var cmd = packet.cmd;
|
||||
var payload = packet.payload;
|
||||
|
||||
if (this.lastBlock && cmd !== 'tx')
|
||||
this._emitMerkle(this.lastBlock);
|
||||
|
||||
if (cmd === 'version')
|
||||
return this._handleVersion(payload);
|
||||
|
||||
@ -368,15 +371,28 @@ Peer.prototype._onPacket = function onPacket(packet) {
|
||||
if (cmd === 'reject')
|
||||
return this._handleReject(payload);
|
||||
|
||||
if (cmd === 'merkleblock' || cmd === 'block') {
|
||||
if (cmd === 'block') {
|
||||
payload.network = true;
|
||||
payload.relayedBy = this.host || '0.0.0.0';
|
||||
payload = bcoin.block(payload, cmd);
|
||||
payload = bcoin.block(payload, 'block');
|
||||
} else if (cmd === 'merkleblock') {
|
||||
payload.network = true;
|
||||
payload.relayedBy = this.host || '0.0.0.0';
|
||||
payload = bcoin.block(payload, 'merkleblock');
|
||||
this.lastBlock = payload;
|
||||
return;
|
||||
} else if (cmd === 'tx') {
|
||||
payload.network = true;
|
||||
payload.relayedBy = this.host || '0.0.0.0';
|
||||
payload = bcoin.tx(payload, this.lastBlock);
|
||||
if (this.lastBlock) {
|
||||
if (payload.block) {
|
||||
this.lastBlock.txs.push(payload);
|
||||
return;
|
||||
} else {
|
||||
this._emitMerkle(this.lastBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this._res(cmd, payload))
|
||||
@ -385,6 +401,12 @@ Peer.prototype._onPacket = function onPacket(packet) {
|
||||
this.emit(cmd, payload);
|
||||
};
|
||||
|
||||
Peer.prototype._emitMerkle = function _emitMerkle(payload) {
|
||||
if (!this._res('merkleblock', payload))
|
||||
this.emit('merkleblock', payload);
|
||||
this.lastBlock = null;
|
||||
};
|
||||
|
||||
Peer.prototype._handleVersion = function handleVersion(payload) {
|
||||
if (payload.v < constants.minVersion)
|
||||
return this._error('peer doesn\'t support required protocol version');
|
||||
|
||||
@ -175,6 +175,12 @@ Pool.prototype._init = function _init() {
|
||||
|
||||
this.chain.on('block', function(block, peer) {
|
||||
self.emit('block', block, peer);
|
||||
// Emit merkle txs after the fact
|
||||
if (block.subtype === 'merkleblock') {
|
||||
block.txs.forEach(function(tx) {
|
||||
self._handleTX(tx, peer);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.chain.on('fork', function(data, peer) {
|
||||
@ -748,14 +754,7 @@ Pool.prototype._createPeer = function _createPeer(priority) {
|
||||
});
|
||||
|
||||
peer.on('tx', function(tx) {
|
||||
var requested = self._response(tx);
|
||||
var added = self._addTX(tx, 1);
|
||||
|
||||
if (added || tx.block)
|
||||
self.emit('tx', tx, peer);
|
||||
|
||||
if (!self.options.fullNode && tx.block)
|
||||
self.emit('watched', tx, peer);
|
||||
self._handleTX(tx);
|
||||
});
|
||||
|
||||
peer.on('addr', function(data) {
|
||||
@ -791,6 +790,17 @@ Pool.prototype._createPeer = function _createPeer(priority) {
|
||||
return peer;
|
||||
};
|
||||
|
||||
Pool.prototype._handleTX = function _handleTX(tx, peer) {
|
||||
var requested = this._response(tx);
|
||||
var added = this._addTX(tx, 1);
|
||||
|
||||
if (added || tx.block)
|
||||
this.emit('tx', tx, peer);
|
||||
|
||||
if (!this.options.fullNode && tx.block)
|
||||
this.emit('watched', tx, peer);
|
||||
};
|
||||
|
||||
Pool.prototype._addPeer = function _addPeer() {
|
||||
var self = this;
|
||||
var peer;
|
||||
@ -1171,11 +1181,12 @@ Pool.prototype.searchWallet = function(w, h) {
|
||||
return;
|
||||
|
||||
if (w == null) {
|
||||
height = this.wallets.reduce(function(ts, w) {
|
||||
height = this.wallets.reduce(function(height, w) {
|
||||
if (w.lastHeight < height)
|
||||
return w.lastHeight;
|
||||
return ts;
|
||||
return height;
|
||||
}, Infinity);
|
||||
assert(height !== Infinity);
|
||||
ts = this.wallets.reduce(function(ts, w) {
|
||||
if (w.lastTs < ts)
|
||||
return w.lastTs;
|
||||
|
||||
@ -282,7 +282,7 @@ script.concat = function concat(scripts) {
|
||||
var s = [];
|
||||
var i;
|
||||
|
||||
s.push(scripts[0]);
|
||||
s = s.concat(scripts[0]);
|
||||
|
||||
for (i = 1; i < scripts.length; i++) {
|
||||
s.push('codeseparator');
|
||||
@ -2129,20 +2129,16 @@ script.format = function format(s) {
|
||||
scripts.push(s.script);
|
||||
}
|
||||
|
||||
scripts = scripts.map(function(script) {
|
||||
return script.map(function(chunk) {
|
||||
if (Array.isArray(chunk)) {
|
||||
if (chunk.length === 0)
|
||||
return 0 + '';
|
||||
return '[' + utils.toHex(chunk) + ']';
|
||||
}
|
||||
if (typeof chunk === 'number')
|
||||
return chunk + '';
|
||||
return chunk;
|
||||
}).join(' ');
|
||||
});
|
||||
|
||||
return script.concat(scripts);
|
||||
return script.concat(scripts).map(function(chunk) {
|
||||
if (Array.isArray(chunk)) {
|
||||
if (chunk.length === 0)
|
||||
return 0 + '';
|
||||
return '[' + utils.toHex(chunk) + ']';
|
||||
}
|
||||
if (typeof chunk === 'number')
|
||||
return chunk + '';
|
||||
return chunk;
|
||||
}).join(' ');
|
||||
};
|
||||
|
||||
script.isPushOnly = function isPushOnly(s) {
|
||||
|
||||
@ -84,7 +84,7 @@ TXPool.prototype._init = function init() {
|
||||
TXPool.prototype.add = function add(tx, noWrite, strict) {
|
||||
var hash = tx.hash('hex');
|
||||
var updated = false;
|
||||
var i, input, output, unspent, index, orphan;
|
||||
var i, input, output, coin, unspent, index, orphan;
|
||||
var key, orphans, some;
|
||||
|
||||
this._wallet.fillPrevout(tx);
|
||||
@ -105,9 +105,15 @@ TXPool.prototype.add = function add(tx, noWrite, strict) {
|
||||
this._all[hash].ps = 0;
|
||||
this._all[hash].ts = tx.ts;
|
||||
this._all[hash].block = tx.block;
|
||||
this._all[hash].height = tx.height;
|
||||
this._all[hash].outputs.forEach(function(output, i) {
|
||||
var key = hash + '/' + i;
|
||||
if (this._unspent[key])
|
||||
this._unspent[key].height = tx.height;
|
||||
});
|
||||
this._storeTX(hash, tx, noWrite);
|
||||
this._lastTs = Math.max(tx.ts, this._lastTs);
|
||||
this._lastHeight = Math.max(tx.getHeight(), this._lastHeight);
|
||||
this._lastHeight = Math.max(tx.height, this._lastHeight);
|
||||
this.emit('update', this._lastTs, this._lastHeight, tx);
|
||||
this.emit('confirmed', tx);
|
||||
}
|
||||
@ -159,7 +165,7 @@ TXPool.prototype.add = function add(tx, noWrite, strict) {
|
||||
assert(index !== -1);
|
||||
assert(orphan.tx.inputs[index].prevout.hash === tx.hash('hex'));
|
||||
assert(orphan.tx.inputs[index].prevout.index === i);
|
||||
orphan.tx.inputs[index].output = bcoin.coin(tx, i);
|
||||
orphan.tx.inputs[index].output = coin;
|
||||
|
||||
// Verify that input script is correct, if not - add output to unspent
|
||||
// and remove orphan from storage
|
||||
@ -180,6 +186,8 @@ TXPool.prototype.add = function add(tx, noWrite, strict) {
|
||||
if (!this._wallet.ownOutput(tx, i))
|
||||
continue;
|
||||
|
||||
coin = bcoin.coin(tx, i);
|
||||
|
||||
this._addOutput(tx, i);
|
||||
|
||||
key = hash + '/' + i;
|
||||
@ -194,13 +202,13 @@ TXPool.prototype.add = function add(tx, noWrite, strict) {
|
||||
|
||||
delete this._orphans[key];
|
||||
if (!orphans) {
|
||||
this._unspent[key] = bcoin.coin(tx, i);
|
||||
this._unspent[key] = coin;
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
|
||||
this._lastTs = Math.max(tx.ts, this._lastTs);
|
||||
this._lastHeight = Math.max(tx.getHeight(), this._lastHeight);
|
||||
this._lastHeight = Math.max(tx.height, this._lastHeight);
|
||||
if (updated)
|
||||
this.emit('update', this._lastTs, this._lastHeight, tx);
|
||||
|
||||
|
||||
119
lib/bcoin/tx.js
119
lib/bcoin/tx.js
@ -38,6 +38,7 @@ function TX(data, block) {
|
||||
this._raw = data._raw || null;
|
||||
this._size = data._size || 0;
|
||||
|
||||
this.height = data.height != null ? data.height : -1;
|
||||
this.network = data.network || false;
|
||||
this.relayedBy = data.relayedBy || '0.0.0.0';
|
||||
|
||||
@ -64,10 +65,12 @@ function TX(data, block) {
|
||||
if (block.hasTX(this.hash('hex'))) {
|
||||
this.ts = block.ts;
|
||||
this.block = block.hash('hex');
|
||||
this.height = block.height;
|
||||
}
|
||||
} else {
|
||||
this.ts = block.ts;
|
||||
this.block = block.hash('hex');
|
||||
this.height = block.height;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1392,11 +1395,18 @@ TX.prototype.testOutputs = function testOutputs(addressTable, index, collect) {
|
||||
return outputs;
|
||||
};
|
||||
|
||||
TX.prototype.avoidFeeSnipping = function avoidFeeSnipping() {
|
||||
if (!this.chain)
|
||||
return;
|
||||
TX.prototype.avoidFeeSnipping = function avoidFeeSnipping(height) {
|
||||
if (height == null) {
|
||||
if (!this.chain)
|
||||
return;
|
||||
|
||||
this.setLocktime(this.chain.height());
|
||||
height = this.chain.height();
|
||||
}
|
||||
|
||||
if (height === -1)
|
||||
height = 0;
|
||||
|
||||
this.setLocktime(height);
|
||||
|
||||
if ((Math.random() * 10 | 0) === 0)
|
||||
this.setLocktime(Math.max(0, this.locktime - (Math.random() * 100 | 0)));
|
||||
@ -1477,50 +1487,10 @@ TX.prototype.fillPrevout = function fillPrevout(txs, unspent) {
|
||||
return inputs.length === this.inputs.length;
|
||||
};
|
||||
|
||||
// Used for verifyContext/ContextualBlockCheck and miner isFinalTx call.
|
||||
// BIP113 will require that time-locked transactions have nLockTime set to
|
||||
// less than the median time of the previous block they're contained in.
|
||||
TX.prototype.isFinalBlock = function isFinalBlock(block, prev, useMedian) {
|
||||
var height = prev.height + 1;
|
||||
var ts = useMedian ? prev.getMedianTime() : block.ts;
|
||||
return this.isFinal(height, ts);
|
||||
};
|
||||
|
||||
// Used in AcceptToMemoryPool
|
||||
TX.prototype.isFinalMempool = function isFinalMempool(useMedian) {
|
||||
var height, ts;
|
||||
|
||||
if (!this.chain)
|
||||
return true;
|
||||
|
||||
height = this.chain.height() + 1;
|
||||
ts = useMedian
|
||||
? this.chain.getTip().getMedianTime()
|
||||
: utils.now();
|
||||
|
||||
return this.isFinal(height, ts);
|
||||
};
|
||||
|
||||
// Used in the original bitcoind code for AcceptBlock
|
||||
TX.prototype.isFinalLegacy = function isFinalLegacy(block) {
|
||||
var ts, height;
|
||||
|
||||
if (!this.chain)
|
||||
return true;
|
||||
|
||||
ts = block ? block.ts : utils.now();
|
||||
height = this.chain.height();
|
||||
|
||||
return this.isFinal(height, ts);
|
||||
};
|
||||
|
||||
TX.prototype.isFinal = function isFinal(height, ts) {
|
||||
var threshold = constants.locktimeThreshold;
|
||||
var i;
|
||||
|
||||
if (!this.chain)
|
||||
return true;
|
||||
|
||||
if (this.locktime === 0)
|
||||
return true;
|
||||
|
||||
@ -1649,18 +1619,26 @@ TX.prototype.isStandardInputs = function isStandardInputs(flags) {
|
||||
};
|
||||
|
||||
TX.prototype.getPriority = function getPriority() {
|
||||
var size, value, i, input, age;
|
||||
var size, sum, i, input, age, height;
|
||||
|
||||
height = this.height;
|
||||
|
||||
if (height === -1)
|
||||
height = null;
|
||||
|
||||
if (!this.hasPrevout())
|
||||
return new bn(0);
|
||||
|
||||
size = this.maxSize();
|
||||
value = new bn(0);
|
||||
sum = new bn(0);
|
||||
|
||||
for (i = 0; i < this.inputs.length; i++) {
|
||||
input = this.inputs[i];
|
||||
|
||||
if (!input.output)
|
||||
return constants.tx.freeThreshold.clone();
|
||||
return new bn(0);
|
||||
|
||||
age = input.output.getConfirmations();
|
||||
age = input.output.getConfirmations(height);
|
||||
|
||||
if (age === -1)
|
||||
age = 0;
|
||||
@ -1668,15 +1646,19 @@ TX.prototype.getPriority = function getPriority() {
|
||||
if (age !== 0)
|
||||
age += 1;
|
||||
|
||||
value.iadd(input.output.value.muln(age));
|
||||
sum.iadd(input.output.value.muln(age));
|
||||
}
|
||||
|
||||
return value.divn(size);
|
||||
return sum.divn(size);
|
||||
};
|
||||
|
||||
TX.prototype.isFree = function isFree() {
|
||||
var size = this.maxSize();
|
||||
var priority;
|
||||
var size, priority;
|
||||
|
||||
if (!this.hasPrevout())
|
||||
return false;
|
||||
|
||||
size = this.maxSize();
|
||||
|
||||
if (size >= constants.tx.maxFreeSize)
|
||||
return false;
|
||||
@ -1687,19 +1669,28 @@ TX.prototype.isFree = function isFree() {
|
||||
};
|
||||
|
||||
TX.prototype.getHeight = function getHeight() {
|
||||
if (this.height !== -1)
|
||||
return this.height;
|
||||
|
||||
if (!this.chain)
|
||||
return -1;
|
||||
|
||||
return this.block ? this.chain.getHeight(this.block) : -1;
|
||||
};
|
||||
|
||||
TX.prototype.getConfirmations = function getConfirmations() {
|
||||
TX.prototype.getConfirmations = function getConfirmations(height) {
|
||||
var top, height;
|
||||
|
||||
if (!this.chain)
|
||||
return 0;
|
||||
if (height == null) {
|
||||
if (!this.chain)
|
||||
return 0;
|
||||
|
||||
top = this.chain.height();
|
||||
height = this.getHeight();
|
||||
top = this.chain.height();
|
||||
} else {
|
||||
top = height;
|
||||
}
|
||||
|
||||
height = this.height;
|
||||
|
||||
if (height === -1)
|
||||
return 0;
|
||||
@ -1748,10 +1739,6 @@ TX.prototype.__defineGetter__('value', function() {
|
||||
return this.getValue();
|
||||
});
|
||||
|
||||
TX.prototype.__defineGetter__('height', function() {
|
||||
return this.getHeight();
|
||||
});
|
||||
|
||||
TX.prototype.__defineGetter__('confirmations', function() {
|
||||
return this.getConfirmations();
|
||||
});
|
||||
@ -1773,10 +1760,8 @@ TX.prototype.inspect = function inspect() {
|
||||
copy.rblock = this.rblock;
|
||||
copy.value = utils.btc(this.getValue());
|
||||
copy.fee = utils.btc(this.getFee());
|
||||
copy.height = this.getHeight();
|
||||
copy.confirmations = this.getConfirmations();
|
||||
if (this.hasPrevout())
|
||||
copy.priority = this.getPriority().toString(10);
|
||||
copy.priority = this.getPriority().toString(10);
|
||||
copy.date = new Date((copy.ts || 0) * 1000).toISOString();
|
||||
if (copy.hardFee)
|
||||
copy.hardFee = utils.btc(copy.hardFee);
|
||||
@ -1791,12 +1776,13 @@ TX.prototype.toJSON = function toJSON() {
|
||||
ts: this.ts,
|
||||
ps: this.ps,
|
||||
block: this.block,
|
||||
height: this.height,
|
||||
network: this.network,
|
||||
relayedBy: this.relayedBy,
|
||||
changeAddress: this.changeAddress,
|
||||
changeIndex: this.changeIndex,
|
||||
hardFee: this.hardFee ? utils.btc(this.hardFee) : null,
|
||||
outputs: this.inputs.map(function(input) {
|
||||
coins: this.inputs.map(function(input) {
|
||||
return input.output ? input.output.toJSON() : null;
|
||||
}),
|
||||
tx: utils.toHex(this.render())
|
||||
@ -1825,11 +1811,12 @@ TX.fromJSON = function fromJSON(json) {
|
||||
data._size = raw.length;
|
||||
|
||||
tx = new TX(data);
|
||||
tx.height = json.height;
|
||||
tx.ts = json.ts;
|
||||
tx.block = json.block || null;
|
||||
tx.ps = json.ps;
|
||||
|
||||
json.outputs.forEach(function(output, i) {
|
||||
json.coins.forEach(function(output, i) {
|
||||
if (!output)
|
||||
return;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user