block: rename some more methods. refactor bip152 ptx vector.
This commit is contained in:
parent
7ed36ec2ba
commit
8c212d797f
@ -1334,7 +1334,7 @@ Chain.prototype.connect = async function connect(prev, block, flags) {
|
|||||||
// validated, and connected. Hopefully the
|
// validated, and connected. Hopefully the
|
||||||
// deserialized blocks get cleaned up by the
|
// deserialized blocks get cleaned up by the
|
||||||
// GC quickly.
|
// GC quickly.
|
||||||
if (block.memory) {
|
if (block.isMemory()) {
|
||||||
try {
|
try {
|
||||||
block = block.toBlock();
|
block = block.toBlock();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -1342,7 +1342,8 @@ Chain.prototype.connect = async function connect(prev, block, flags) {
|
|||||||
throw new VerifyError(block,
|
throw new VerifyError(block,
|
||||||
'malformed',
|
'malformed',
|
||||||
'error parsing message',
|
'error parsing message',
|
||||||
10);
|
10,
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -921,7 +921,7 @@ RPC.prototype.verifyTXOutProof = async function verifyTXOutProof(args, help) {
|
|||||||
let valid = new Validator([args]);
|
let valid = new Validator([args]);
|
||||||
let data = valid.buf(0);
|
let data = valid.buf(0);
|
||||||
let out = [];
|
let out = [];
|
||||||
let block, entry;
|
let block, entry, tree;
|
||||||
|
|
||||||
if (help || args.length !== 1)
|
if (help || args.length !== 1)
|
||||||
throw new RPCError(errs.MISC_ERROR, 'verifytxoutproof "proof"');
|
throw new RPCError(errs.MISC_ERROR, 'verifytxoutproof "proof"');
|
||||||
@ -939,7 +939,9 @@ RPC.prototype.verifyTXOutProof = async function verifyTXOutProof(args, help) {
|
|||||||
if (!entry)
|
if (!entry)
|
||||||
throw new RPCError(errs.MISC_ERROR, 'Block not found in chain.');
|
throw new RPCError(errs.MISC_ERROR, 'Block not found in chain.');
|
||||||
|
|
||||||
for (let hash of block.tree.matches)
|
tree = block.getTree();
|
||||||
|
|
||||||
|
for (let hash of tree.matches)
|
||||||
out.push(util.revHex(hash));
|
out.push(util.revHex(hash));
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
|
|||||||
@ -124,12 +124,7 @@ CompactBlock.prototype.fromRaw = function fromRaw(data) {
|
|||||||
let br = new BufferReader(data);
|
let br = new BufferReader(data);
|
||||||
let count;
|
let count;
|
||||||
|
|
||||||
this.version = br.readU32();
|
this.readHead(br);
|
||||||
this.prevBlock = br.readHash('hex');
|
|
||||||
this.merkleRoot = br.readHash('hex');
|
|
||||||
this.ts = br.readU32();
|
|
||||||
this.bits = br.readU32();
|
|
||||||
this.nonce = br.readU32();
|
|
||||||
|
|
||||||
this.keyNonce = br.readBytes(8);
|
this.keyNonce = br.readBytes(8);
|
||||||
this.sipKey = this.getKey();
|
this.sipKey = this.getKey();
|
||||||
@ -154,7 +149,7 @@ CompactBlock.prototype.fromRaw = function fromRaw(data) {
|
|||||||
|
|
||||||
tx = TX.fromReader(br);
|
tx = TX.fromReader(br);
|
||||||
|
|
||||||
this.ptx.push(new PrefilledTX(index, tx));
|
this.ptx.push([index, tx]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
@ -238,12 +233,13 @@ CompactBlock.prototype.getSize = function getSize(witness) {
|
|||||||
size += this.ids.length * 6;
|
size += this.ids.length * 6;
|
||||||
size += encoding.sizeVarint(this.ptx.length);
|
size += encoding.sizeVarint(this.ptx.length);
|
||||||
|
|
||||||
for (let ptx of this.ptx) {
|
for (let [index, tx] of this.ptx) {
|
||||||
size += encoding.sizeVarint(ptx.index);
|
size += encoding.sizeVarint(index);
|
||||||
|
|
||||||
if (witness)
|
if (witness)
|
||||||
size += ptx.tx.getSize();
|
size += tx.getSize();
|
||||||
else
|
else
|
||||||
size += ptx.tx.getBaseSize();
|
size += tx.getBaseSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
@ -273,12 +269,13 @@ CompactBlock.prototype.writeRaw = function writeRaw(bw, witness) {
|
|||||||
|
|
||||||
bw.writeVarint(this.ptx.length);
|
bw.writeVarint(this.ptx.length);
|
||||||
|
|
||||||
for (let ptx of this.ptx) {
|
for (let [index, tx] of this.ptx) {
|
||||||
bw.writeVarint(ptx.index);
|
bw.writeVarint(index);
|
||||||
|
|
||||||
if (witness)
|
if (witness)
|
||||||
ptx.tx.toWriter(bw);
|
tx.toWriter(bw);
|
||||||
else
|
else
|
||||||
ptx.tx.toNormalWriter(bw);
|
tx.toNormalWriter(bw);
|
||||||
}
|
}
|
||||||
|
|
||||||
return bw;
|
return bw;
|
||||||
@ -302,13 +299,14 @@ CompactBlock.prototype.toRequest = function toRequest() {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
CompactBlock.prototype.fillMempool = function fillMempool(witness, mempool) {
|
CompactBlock.prototype.fillMempool = function fillMempool(witness, mempool) {
|
||||||
let have = {};
|
let have;
|
||||||
|
|
||||||
if (this.count === this.totalTX)
|
if (this.count === this.totalTX)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
for (let entry of mempool.map.values()) {
|
have = new Set();
|
||||||
let tx = entry.tx;
|
|
||||||
|
for (let {tx} of mempool.map.values()) {
|
||||||
let hash = tx.hash();
|
let hash = tx.hash();
|
||||||
let id, index;
|
let id, index;
|
||||||
|
|
||||||
@ -321,7 +319,7 @@ CompactBlock.prototype.fillMempool = function fillMempool(witness, mempool) {
|
|||||||
if (index == null)
|
if (index == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (have[index]) {
|
if (have.has(index)) {
|
||||||
// Siphash collision, just request it.
|
// Siphash collision, just request it.
|
||||||
this.available[index] = null;
|
this.available[index] = null;
|
||||||
this.count--;
|
this.count--;
|
||||||
@ -329,7 +327,7 @@ CompactBlock.prototype.fillMempool = function fillMempool(witness, mempool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.available[index] = tx;
|
this.available[index] = tx;
|
||||||
have[index] = true;
|
have.add(index);
|
||||||
this.count++;
|
this.count++;
|
||||||
|
|
||||||
// We actually may have a siphash collision
|
// We actually may have a siphash collision
|
||||||
@ -417,7 +415,7 @@ CompactBlock.prototype.init = function init() {
|
|||||||
if (this.totalTX > consensus.MAX_BLOCK_SIZE / 10)
|
if (this.totalTX > consensus.MAX_BLOCK_SIZE / 10)
|
||||||
throw new Error('Compact block too big.');
|
throw new Error('Compact block too big.');
|
||||||
|
|
||||||
// Custom limit to avoid hashdos:
|
// Custom limit to avoid a hashdos.
|
||||||
// Min valid tx size: (4 + 1 + 41 + 1 + 9 + 4) = 60
|
// Min valid tx size: (4 + 1 + 41 + 1 + 9 + 4) = 60
|
||||||
// Min block header size: 81
|
// Min block header size: 81
|
||||||
// Max number of transactions: (1000000 - 81) / 60 = 16665
|
// Max number of transactions: (1000000 - 81) / 60 = 16665
|
||||||
@ -429,33 +427,25 @@ CompactBlock.prototype.init = function init() {
|
|||||||
this.available.push(null);
|
this.available.push(null);
|
||||||
|
|
||||||
for (let i = 0; i < this.ptx.length; i++) {
|
for (let i = 0; i < this.ptx.length; i++) {
|
||||||
let ptx = this.ptx[i];
|
let [index, tx] = this.ptx[i];
|
||||||
assert(ptx);
|
last += index + 1;
|
||||||
last += ptx.index + 1;
|
|
||||||
assert(last <= 0xffff);
|
assert(last <= 0xffff);
|
||||||
assert(last <= this.ids.length + i);
|
assert(last <= this.ids.length + i);
|
||||||
this.available[last] = ptx.tx;
|
this.available[last] = tx;
|
||||||
this.count++;
|
this.count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < this.ids.length; i++) {
|
for (let i = 0; i < this.ids.length; i++) {
|
||||||
let id;
|
let id = this.ids[i];
|
||||||
|
|
||||||
while (this.available[i + offset])
|
while (this.available[i + offset])
|
||||||
offset++;
|
offset++;
|
||||||
|
|
||||||
id = this.ids[i];
|
// Fails on siphash collision.
|
||||||
|
|
||||||
// Fails on siphash collision
|
|
||||||
if (this.idMap.has(id))
|
if (this.idMap.has(id))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
this.idMap.set(id, i + offset);
|
this.idMap.set(id, i + offset);
|
||||||
|
|
||||||
// We're supposed to fail here if there's
|
|
||||||
// more than 12 hash collisions, but we
|
|
||||||
// don't have lowlevel access to our hash
|
|
||||||
// table. Hopefully we don't get hashdos'd.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -526,7 +516,7 @@ CompactBlock.prototype.fromBlock = function fromBlock(block, witness, nonce) {
|
|||||||
this.ids.push(id);
|
this.ids.push(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.ptx.push(new PrefilledTX(0, block.txs[0]));
|
this.ptx.push([0, block.txs[0]]);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
@ -964,20 +954,6 @@ TXResponse.prototype.frameRaw = function frameRaw(witness) {
|
|||||||
return this.writeRaw(new StaticWriter(size), witness).render();
|
return this.writeRaw(new StaticWriter(size), witness).render();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a prefilled TX.
|
|
||||||
* @constructor
|
|
||||||
* @param {Number} index
|
|
||||||
* @param {TX} tx
|
|
||||||
* @property {Number} index
|
|
||||||
* @property {TX} tx
|
|
||||||
*/
|
|
||||||
|
|
||||||
function PrefilledTX(index, tx) {
|
|
||||||
this.index = index;
|
|
||||||
this.tx = tx;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Expose
|
* Expose
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -2687,6 +2687,7 @@ Pool.prototype._handleMerkleBlock = async function handleMerkleBlock(peer, packe
|
|||||||
let block = packet.block;
|
let block = packet.block;
|
||||||
let hash = block.hash('hex');
|
let hash = block.hash('hex');
|
||||||
let flags = chainCommon.flags.VERIFY_NONE;
|
let flags = chainCommon.flags.VERIFY_NONE;
|
||||||
|
let tree;
|
||||||
|
|
||||||
if (!this.syncing)
|
if (!this.syncing)
|
||||||
return;
|
return;
|
||||||
@ -2724,14 +2725,16 @@ Pool.prototype._handleMerkleBlock = async function handleMerkleBlock(peer, packe
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (block.tree.matches.length === 0) {
|
tree = block.getTree();
|
||||||
|
|
||||||
|
if (tree.matches.length === 0) {
|
||||||
await this._addBlock(peer, block, flags);
|
await this._addBlock(peer, block, flags);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
peer.merkleBlock = block;
|
peer.merkleBlock = block;
|
||||||
peer.merkleTime = util.ms();
|
peer.merkleTime = util.ms();
|
||||||
peer.merkleMatches = block.tree.matches.length;
|
peer.merkleMatches = tree.matches.length;
|
||||||
peer.merkleMap = new Set();
|
peer.merkleMap = new Set();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -29,8 +29,6 @@ const consensus = require('../protocol/consensus');
|
|||||||
* @property {Number} ts - Timestamp.
|
* @property {Number} ts - Timestamp.
|
||||||
* @property {Number} bits
|
* @property {Number} bits
|
||||||
* @property {Number} nonce
|
* @property {Number} nonce
|
||||||
* @property {TX[]} txs - Transaction vector.
|
|
||||||
* @property {ReversedHash} rhash - Reversed block hash (uint256le).
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function AbstractBlock() {
|
function AbstractBlock() {
|
||||||
@ -44,24 +42,12 @@ function AbstractBlock() {
|
|||||||
this.bits = 0;
|
this.bits = 0;
|
||||||
this.nonce = 0;
|
this.nonce = 0;
|
||||||
|
|
||||||
this.txs = null;
|
|
||||||
this.mutable = false;
|
this.mutable = false;
|
||||||
|
|
||||||
this._hash = null;
|
this._hash = null;
|
||||||
this._hhash = null;
|
this._hhash = null;
|
||||||
this._size = -1;
|
|
||||||
this._witness = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Memory flag.
|
|
||||||
* @const {Boolean}
|
|
||||||
* @default
|
|
||||||
* @memberof AbstractBlock#
|
|
||||||
*/
|
|
||||||
|
|
||||||
AbstractBlock.prototype.memory = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inject properties from options object.
|
* Inject properties from options object.
|
||||||
* @private
|
* @private
|
||||||
@ -116,33 +102,29 @@ AbstractBlock.prototype.parseJSON = function parseJSON(json) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear any cached values (abstract).
|
* Test whether the block is a memblock.
|
||||||
* @param {Boolean?} all - Clear transactions.
|
* @returns {Boolean}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
AbstractBlock.prototype._refresh = function refresh(all) {
|
AbstractBlock.prototype.isMemory = function isMemory() {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear any cached values (abstract).
|
||||||
|
*/
|
||||||
|
|
||||||
|
AbstractBlock.prototype._refresh = function refresh() {
|
||||||
this._hash = null;
|
this._hash = null;
|
||||||
this._hhash = null;
|
this._hhash = null;
|
||||||
this._size = -1;
|
|
||||||
this._witness = -1;
|
|
||||||
|
|
||||||
if (!all)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!this.txs)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (let tx of this.txs)
|
|
||||||
tx.refresh();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear any cached values.
|
* Clear any cached values.
|
||||||
* @param {Boolean?} all - Clear transactions.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
AbstractBlock.prototype.refresh = function refresh(all) {
|
AbstractBlock.prototype.refresh = function refresh() {
|
||||||
return this._refresh(all);
|
return this._refresh();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -182,6 +164,16 @@ AbstractBlock.prototype.toHead = function toHead() {
|
|||||||
return this.writeHead(new StaticWriter(80)).render();
|
return this.writeHead(new StaticWriter(80)).render();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inject properties from serialized data.
|
||||||
|
* @private
|
||||||
|
* @param {Buffer} data
|
||||||
|
*/
|
||||||
|
|
||||||
|
AbstractBlock.prototype.fromHead = function fromHead(data) {
|
||||||
|
return this.readHead(new BufferReader(data));
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serialize the block headers.
|
* Serialize the block headers.
|
||||||
* @param {BufferWriter} bw
|
* @param {BufferWriter} bw
|
||||||
@ -202,7 +194,7 @@ AbstractBlock.prototype.writeHead = function writeHead(bw) {
|
|||||||
* @param {BufferReader} br
|
* @param {BufferReader} br
|
||||||
*/
|
*/
|
||||||
|
|
||||||
AbstractBlock.prototype.parseHead = function parseHead(br) {
|
AbstractBlock.prototype.readHead = function readHead(br) {
|
||||||
this.version = br.readU32();
|
this.version = br.readU32();
|
||||||
this.prevBlock = br.readHash('hex');
|
this.prevBlock = br.readHash('hex');
|
||||||
this.merkleRoot = br.readHash('hex');
|
this.merkleRoot = br.readHash('hex');
|
||||||
|
|||||||
@ -79,8 +79,17 @@ Block.fromOptions = function fromOptions(options) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Block.prototype.refresh = function refresh(all) {
|
Block.prototype.refresh = function refresh(all) {
|
||||||
|
this._refresh();
|
||||||
|
|
||||||
this._raw = null;
|
this._raw = null;
|
||||||
this._refresh(all);
|
this._size = -1;
|
||||||
|
this._witness = -1;
|
||||||
|
|
||||||
|
if (!all)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (let tx of this.txs)
|
||||||
|
tx.refresh();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -644,7 +653,7 @@ Block.prototype.fromReader = function fromReader(br) {
|
|||||||
|
|
||||||
br.start();
|
br.start();
|
||||||
|
|
||||||
this.parseHead(br);
|
this.readHead(br);
|
||||||
|
|
||||||
count = br.readVarint();
|
count = br.readVarint();
|
||||||
|
|
||||||
|
|||||||
@ -80,7 +80,7 @@ Headers.prototype.toRaw = function toRaw() {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Headers.prototype.fromReader = function fromReader(br) {
|
Headers.prototype.fromReader = function fromReader(br) {
|
||||||
this.parseHead(br);
|
this.readHead(br);
|
||||||
br.readVarint();
|
br.readVarint();
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
@ -118,17 +118,6 @@ Headers.fromRaw = function fromRaw(data, enc) {
|
|||||||
return new Headers().fromRaw(data);
|
return new Headers().fromRaw(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Inject properties from serialized data.
|
|
||||||
* TODO: MOVE.
|
|
||||||
* @private
|
|
||||||
* @param {Buffer} data
|
|
||||||
*/
|
|
||||||
|
|
||||||
Headers.prototype.fromHead = function fromHead(data) {
|
|
||||||
return this.parseHead(new BufferReader(data));
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiate headers from serialized data.
|
* Instantiate headers from serialized data.
|
||||||
* @param {Buffer} data
|
* @param {Buffer} data
|
||||||
@ -149,8 +138,15 @@ Headers.fromHead = function fromHead(data, enc) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Headers.fromEntry = function fromEntry(entry) {
|
Headers.fromEntry = function fromEntry(entry) {
|
||||||
let headers = new Headers(entry);
|
let headers = new Headers();
|
||||||
|
headers.version = entry.version;
|
||||||
|
headers.prevBlock = entry.prevBlock;
|
||||||
|
headers.merkleRoot = entry.merkleRoot;
|
||||||
|
headers.ts = entry.ts;
|
||||||
|
headers.bits = entry.bits;
|
||||||
|
headers.nonce = entry.nonce;
|
||||||
headers._hash = Buffer.from(entry.hash, 'hex');
|
headers._hash = Buffer.from(entry.hash, 'hex');
|
||||||
|
headers._hhash = entry.hash;
|
||||||
return headers;
|
return headers;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -40,19 +40,21 @@ function MemBlock() {
|
|||||||
if (!(this instanceof MemBlock))
|
if (!(this instanceof MemBlock))
|
||||||
return new MemBlock();
|
return new MemBlock();
|
||||||
|
|
||||||
|
AbstractBlock.call(this);
|
||||||
|
|
||||||
this._raw = DUMMY;
|
this._raw = DUMMY;
|
||||||
}
|
}
|
||||||
|
|
||||||
util.inherits(MemBlock, AbstractBlock);
|
util.inherits(MemBlock, AbstractBlock);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Memory flag.
|
* Test whether the block is a memblock.
|
||||||
* @const {Boolean}
|
* @returns {Boolean}
|
||||||
* @default
|
|
||||||
* @memberof MemBlock#
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
MemBlock.prototype.memory = true;
|
MemBlock.prototype.isMemory = function isMemory() {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serialize the block headers.
|
* Serialize the block headers.
|
||||||
@ -144,7 +146,7 @@ MemBlock.prototype.parseCoinbaseHeight = function parseCoinbaseHeight() {
|
|||||||
MemBlock.prototype.fromRaw = function fromRaw(data) {
|
MemBlock.prototype.fromRaw = function fromRaw(data) {
|
||||||
let br = new BufferReader(data, true);
|
let br = new BufferReader(data, true);
|
||||||
|
|
||||||
this.parseHead(br);
|
this.readHead(br);
|
||||||
|
|
||||||
this._raw = br.data;
|
this._raw = br.data;
|
||||||
|
|
||||||
|
|||||||
@ -32,12 +32,12 @@ function MerkleBlock(options) {
|
|||||||
|
|
||||||
AbstractBlock.call(this);
|
AbstractBlock.call(this);
|
||||||
|
|
||||||
|
this.txs = [];
|
||||||
this.hashes = [];
|
this.hashes = [];
|
||||||
this.flags = DUMMY;
|
this.flags = DUMMY;
|
||||||
|
|
||||||
this.totalTX = 0;
|
this.totalTX = 0;
|
||||||
this.tree = null;
|
this._tree = null;
|
||||||
this.txs = [];
|
|
||||||
|
|
||||||
if (options)
|
if (options)
|
||||||
this.fromOptions(options);
|
this.fromOptions(options);
|
||||||
@ -63,15 +63,20 @@ MerkleBlock.prototype.fromOptions = function fromOptions(options) {
|
|||||||
for (let hash of options.hashes) {
|
for (let hash of options.hashes) {
|
||||||
if (typeof hash === 'string')
|
if (typeof hash === 'string')
|
||||||
hash = Buffer.from(hash, 'hex');
|
hash = Buffer.from(hash, 'hex');
|
||||||
|
assert(Buffer.isBuffer(hash));
|
||||||
this.hashes.push(hash);
|
this.hashes.push(hash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.flags)
|
if (options.flags) {
|
||||||
|
assert(Buffer.isBuffer(options.flags));
|
||||||
this.flags = options.flags;
|
this.flags = options.flags;
|
||||||
|
}
|
||||||
|
|
||||||
if (options.totalTX != null)
|
if (options.totalTX != null) {
|
||||||
|
assert(util.isUInt32(options.totalTX));
|
||||||
this.totalTX = options.totalTX;
|
this.totalTX = options.totalTX;
|
||||||
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
@ -92,8 +97,14 @@ MerkleBlock.fromOptions = function fromOptions(data) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
MerkleBlock.prototype.refresh = function refresh(all) {
|
MerkleBlock.prototype.refresh = function refresh(all) {
|
||||||
this.tree = null;
|
this._refresh();
|
||||||
this._refresh(all);
|
this._tree = null;
|
||||||
|
|
||||||
|
if (!all)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (let tx of this.txs)
|
||||||
|
tx.refresh();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -161,7 +172,7 @@ MerkleBlock.prototype.checkBody = function checkBody() {
|
|||||||
if (tree.root !== this.merkleRoot)
|
if (tree.root !== this.merkleRoot)
|
||||||
return [false, 'bad-txnmrklroot', 100];
|
return [false, 'bad-txnmrklroot', 100];
|
||||||
|
|
||||||
return [true, 'valid', 100];
|
return [true, 'valid', 0];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -171,14 +182,14 @@ MerkleBlock.prototype.checkBody = function checkBody() {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
MerkleBlock.prototype.getTree = function getTree() {
|
MerkleBlock.prototype.getTree = function getTree() {
|
||||||
if (!this.tree) {
|
if (!this._tree) {
|
||||||
try {
|
try {
|
||||||
this.tree = this.extractTree();
|
this._tree = this.extractTree();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.tree = new PartialTree();
|
this._tree = new PartialTree();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this.tree;
|
return this._tree;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -380,7 +391,7 @@ MerkleBlock.prototype.toRaw = function toRaw() {
|
|||||||
MerkleBlock.prototype.fromReader = function fromReader(br) {
|
MerkleBlock.prototype.fromReader = function fromReader(br) {
|
||||||
let count;
|
let count;
|
||||||
|
|
||||||
this.parseHead(br);
|
this.readHead(br);
|
||||||
|
|
||||||
this.totalTX = br.readU32();
|
this.totalTX = br.readU32();
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user