Merge pull request #1515 from bitcoinjs/addWeightBlock
Add weight and ability to get strippedsize
This commit is contained in:
commit
456ba5a6d9
8 changed files with 74 additions and 62 deletions
|
@ -127,12 +127,17 @@ class Block {
|
||||||
hasWitness() {
|
hasWitness() {
|
||||||
return anyTxHasWitness(this.transactions);
|
return anyTxHasWitness(this.transactions);
|
||||||
}
|
}
|
||||||
byteLength(headersOnly) {
|
weight() {
|
||||||
|
const base = this.byteLength(false, false);
|
||||||
|
const total = this.byteLength(false, true);
|
||||||
|
return base * 3 + total;
|
||||||
|
}
|
||||||
|
byteLength(headersOnly, allowWitness = true) {
|
||||||
if (headersOnly || !this.transactions) return 80;
|
if (headersOnly || !this.transactions) return 80;
|
||||||
return (
|
return (
|
||||||
80 +
|
80 +
|
||||||
varuint.encodingLength(this.transactions.length) +
|
varuint.encodingLength(this.transactions.length) +
|
||||||
this.transactions.reduce((a, x) => a + x.byteLength(), 0)
|
this.transactions.reduce((a, x) => a + x.byteLength(allowWitness), 0)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
getHash() {
|
getHash() {
|
||||||
|
|
|
@ -179,15 +179,31 @@ class Transaction {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
weight() {
|
weight() {
|
||||||
const base = this.__byteLength(false);
|
const base = this.byteLength(false);
|
||||||
const total = this.__byteLength(true);
|
const total = this.byteLength(true);
|
||||||
return base * 3 + total;
|
return base * 3 + total;
|
||||||
}
|
}
|
||||||
virtualSize() {
|
virtualSize() {
|
||||||
return Math.ceil(this.weight() / 4);
|
return Math.ceil(this.weight() / 4);
|
||||||
}
|
}
|
||||||
byteLength() {
|
byteLength(_ALLOW_WITNESS = true) {
|
||||||
return this.__byteLength(true);
|
const hasWitnesses = _ALLOW_WITNESS && this.hasWitnesses();
|
||||||
|
return (
|
||||||
|
(hasWitnesses ? 10 : 8) +
|
||||||
|
varuint.encodingLength(this.ins.length) +
|
||||||
|
varuint.encodingLength(this.outs.length) +
|
||||||
|
this.ins.reduce((sum, input) => {
|
||||||
|
return sum + 40 + varSliceSize(input.script);
|
||||||
|
}, 0) +
|
||||||
|
this.outs.reduce((sum, output) => {
|
||||||
|
return sum + 8 + varSliceSize(output.script);
|
||||||
|
}, 0) +
|
||||||
|
(hasWitnesses
|
||||||
|
? this.ins.reduce((sum, input) => {
|
||||||
|
return sum + vectorSize(input.witness);
|
||||||
|
}, 0)
|
||||||
|
: 0)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
clone() {
|
clone() {
|
||||||
const newTx = new Transaction();
|
const newTx = new Transaction();
|
||||||
|
@ -269,7 +285,7 @@ class Transaction {
|
||||||
txTmp.ins[inIndex].script = ourScript;
|
txTmp.ins[inIndex].script = ourScript;
|
||||||
}
|
}
|
||||||
// serialize and hash
|
// serialize and hash
|
||||||
const buffer = Buffer.allocUnsafe(txTmp.__byteLength(false) + 4);
|
const buffer = Buffer.allocUnsafe(txTmp.byteLength(false) + 4);
|
||||||
buffer.writeInt32LE(hashType, buffer.length - 4);
|
buffer.writeInt32LE(hashType, buffer.length - 4);
|
||||||
txTmp.__toBuffer(buffer, 0, false);
|
txTmp.__toBuffer(buffer, 0, false);
|
||||||
return bcrypto.hash256(buffer);
|
return bcrypto.hash256(buffer);
|
||||||
|
@ -386,27 +402,8 @@ class Transaction {
|
||||||
typeforce(types.tuple(types.Number, [types.Buffer]), arguments);
|
typeforce(types.tuple(types.Number, [types.Buffer]), arguments);
|
||||||
this.ins[index].witness = witness;
|
this.ins[index].witness = witness;
|
||||||
}
|
}
|
||||||
__byteLength(_ALLOW_WITNESS) {
|
__toBuffer(buffer, initialOffset, _ALLOW_WITNESS = false) {
|
||||||
const hasWitnesses = _ALLOW_WITNESS && this.hasWitnesses();
|
if (!buffer) buffer = Buffer.allocUnsafe(this.byteLength(_ALLOW_WITNESS));
|
||||||
return (
|
|
||||||
(hasWitnesses ? 10 : 8) +
|
|
||||||
varuint.encodingLength(this.ins.length) +
|
|
||||||
varuint.encodingLength(this.outs.length) +
|
|
||||||
this.ins.reduce((sum, input) => {
|
|
||||||
return sum + 40 + varSliceSize(input.script);
|
|
||||||
}, 0) +
|
|
||||||
this.outs.reduce((sum, output) => {
|
|
||||||
return sum + 8 + varSliceSize(output.script);
|
|
||||||
}, 0) +
|
|
||||||
(hasWitnesses
|
|
||||||
? this.ins.reduce((sum, input) => {
|
|
||||||
return sum + vectorSize(input.witness);
|
|
||||||
}, 0)
|
|
||||||
: 0)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
__toBuffer(buffer, initialOffset, _ALLOW_WITNESS) {
|
|
||||||
if (!buffer) buffer = Buffer.allocUnsafe(this.__byteLength(_ALLOW_WITNESS));
|
|
||||||
let offset = initialOffset || 0;
|
let offset = initialOffset || 0;
|
||||||
function writeSlice(slice) {
|
function writeSlice(slice) {
|
||||||
offset += slice.copy(buffer, offset);
|
offset += slice.copy(buffer, offset);
|
||||||
|
|
|
@ -48,6 +48,11 @@ describe('Block', () => {
|
||||||
assert.strictEqual(block.bits, f.bits);
|
assert.strictEqual(block.bits, f.bits);
|
||||||
assert.strictEqual(block.nonce, f.nonce);
|
assert.strictEqual(block.nonce, f.nonce);
|
||||||
assert.strictEqual(!block.transactions, f.hex.length === 160);
|
assert.strictEqual(!block.transactions, f.hex.length === 160);
|
||||||
|
if (f.size && f.strippedSize && f.weight) {
|
||||||
|
assert.strictEqual(block.byteLength(false, true), f.size);
|
||||||
|
assert.strictEqual(block.byteLength(false, false), f.strippedSize);
|
||||||
|
assert.strictEqual(block.weight(), f.weight);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
5
test/fixtures/block.json
vendored
5
test/fixtures/block.json
vendored
|
@ -133,7 +133,10 @@
|
||||||
"prevHash": "8980ebb11236bacc66c447d5ad961bc546c0f9cc385a08000000000000000000",
|
"prevHash": "8980ebb11236bacc66c447d5ad961bc546c0f9cc385a08000000000000000000",
|
||||||
"timestamp": 1537429727,
|
"timestamp": 1537429727,
|
||||||
"valid": true,
|
"valid": true,
|
||||||
"version": 536870912
|
"version": 536870912,
|
||||||
|
"size": 2355,
|
||||||
|
"strippedSize": 2209,
|
||||||
|
"weight": 8982
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"invalid": [
|
"invalid": [
|
||||||
|
|
|
@ -148,13 +148,19 @@ export class Block {
|
||||||
return anyTxHasWitness(this.transactions!);
|
return anyTxHasWitness(this.transactions!);
|
||||||
}
|
}
|
||||||
|
|
||||||
byteLength(headersOnly?: boolean): number {
|
weight(): number {
|
||||||
|
const base = this.byteLength(false, false);
|
||||||
|
const total = this.byteLength(false, true);
|
||||||
|
return base * 3 + total;
|
||||||
|
}
|
||||||
|
|
||||||
|
byteLength(headersOnly?: boolean, allowWitness: boolean = true): number {
|
||||||
if (headersOnly || !this.transactions) return 80;
|
if (headersOnly || !this.transactions) return 80;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
80 +
|
80 +
|
||||||
varuint.encodingLength(this.transactions.length) +
|
varuint.encodingLength(this.transactions.length) +
|
||||||
this.transactions.reduce((a, x) => a + x.byteLength(), 0)
|
this.transactions.reduce((a, x) => a + x.byteLength(allowWitness), 0)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -237,8 +237,8 @@ export class Transaction {
|
||||||
}
|
}
|
||||||
|
|
||||||
weight(): number {
|
weight(): number {
|
||||||
const base = this.__byteLength(false);
|
const base = this.byteLength(false);
|
||||||
const total = this.__byteLength(true);
|
const total = this.byteLength(true);
|
||||||
return base * 3 + total;
|
return base * 3 + total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,8 +246,25 @@ export class Transaction {
|
||||||
return Math.ceil(this.weight() / 4);
|
return Math.ceil(this.weight() / 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
byteLength(): number {
|
byteLength(_ALLOW_WITNESS: boolean = true): number {
|
||||||
return this.__byteLength(true);
|
const hasWitnesses = _ALLOW_WITNESS && this.hasWitnesses();
|
||||||
|
|
||||||
|
return (
|
||||||
|
(hasWitnesses ? 10 : 8) +
|
||||||
|
varuint.encodingLength(this.ins.length) +
|
||||||
|
varuint.encodingLength(this.outs.length) +
|
||||||
|
this.ins.reduce((sum, input) => {
|
||||||
|
return sum + 40 + varSliceSize(input.script);
|
||||||
|
}, 0) +
|
||||||
|
this.outs.reduce((sum, output) => {
|
||||||
|
return sum + 8 + varSliceSize(output.script);
|
||||||
|
}, 0) +
|
||||||
|
(hasWitnesses
|
||||||
|
? this.ins.reduce((sum, input) => {
|
||||||
|
return sum + vectorSize(input.witness);
|
||||||
|
}, 0)
|
||||||
|
: 0)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
clone(): Transaction {
|
clone(): Transaction {
|
||||||
|
@ -352,7 +369,7 @@ export class Transaction {
|
||||||
}
|
}
|
||||||
|
|
||||||
// serialize and hash
|
// serialize and hash
|
||||||
const buffer: Buffer = Buffer.allocUnsafe(txTmp.__byteLength(false) + 4);
|
const buffer: Buffer = Buffer.allocUnsafe(txTmp.byteLength(false) + 4);
|
||||||
buffer.writeInt32LE(hashType, buffer.length - 4);
|
buffer.writeInt32LE(hashType, buffer.length - 4);
|
||||||
txTmp.__toBuffer(buffer, 0, false);
|
txTmp.__toBuffer(buffer, 0, false);
|
||||||
|
|
||||||
|
@ -506,34 +523,13 @@ export class Transaction {
|
||||||
this.ins[index].witness = witness;
|
this.ins[index].witness = witness;
|
||||||
}
|
}
|
||||||
|
|
||||||
private __byteLength(_ALLOW_WITNESS: boolean): number {
|
|
||||||
const hasWitnesses = _ALLOW_WITNESS && this.hasWitnesses();
|
|
||||||
|
|
||||||
return (
|
|
||||||
(hasWitnesses ? 10 : 8) +
|
|
||||||
varuint.encodingLength(this.ins.length) +
|
|
||||||
varuint.encodingLength(this.outs.length) +
|
|
||||||
this.ins.reduce((sum, input) => {
|
|
||||||
return sum + 40 + varSliceSize(input.script);
|
|
||||||
}, 0) +
|
|
||||||
this.outs.reduce((sum, output) => {
|
|
||||||
return sum + 8 + varSliceSize(output.script);
|
|
||||||
}, 0) +
|
|
||||||
(hasWitnesses
|
|
||||||
? this.ins.reduce((sum, input) => {
|
|
||||||
return sum + vectorSize(input.witness);
|
|
||||||
}, 0)
|
|
||||||
: 0)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private __toBuffer(
|
private __toBuffer(
|
||||||
buffer?: Buffer,
|
buffer?: Buffer,
|
||||||
initialOffset?: number,
|
initialOffset?: number,
|
||||||
_ALLOW_WITNESS?: boolean,
|
_ALLOW_WITNESS: boolean = false,
|
||||||
): Buffer {
|
): Buffer {
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
buffer = Buffer.allocUnsafe(this.__byteLength(_ALLOW_WITNESS!)) as Buffer;
|
buffer = Buffer.allocUnsafe(this.byteLength(_ALLOW_WITNESS)) as Buffer;
|
||||||
|
|
||||||
let offset = initialOffset || 0;
|
let offset = initialOffset || 0;
|
||||||
|
|
||||||
|
|
3
types/block.d.ts
vendored
3
types/block.d.ts
vendored
|
@ -15,7 +15,8 @@ export declare class Block {
|
||||||
getWitnessCommit(): Buffer | null;
|
getWitnessCommit(): Buffer | null;
|
||||||
hasWitnessCommit(): boolean;
|
hasWitnessCommit(): boolean;
|
||||||
hasWitness(): boolean;
|
hasWitness(): boolean;
|
||||||
byteLength(headersOnly?: boolean): number;
|
weight(): number;
|
||||||
|
byteLength(headersOnly?: boolean, allowWitness?: boolean): number;
|
||||||
getHash(): Buffer;
|
getHash(): Buffer;
|
||||||
getId(): string;
|
getId(): string;
|
||||||
getUTCDate(): Date;
|
getUTCDate(): Date;
|
||||||
|
|
3
types/transaction.d.ts
vendored
3
types/transaction.d.ts
vendored
|
@ -30,7 +30,7 @@ export declare class Transaction {
|
||||||
hasWitnesses(): boolean;
|
hasWitnesses(): boolean;
|
||||||
weight(): number;
|
weight(): number;
|
||||||
virtualSize(): number;
|
virtualSize(): number;
|
||||||
byteLength(): number;
|
byteLength(_ALLOW_WITNESS?: boolean): number;
|
||||||
clone(): Transaction;
|
clone(): Transaction;
|
||||||
/**
|
/**
|
||||||
* Hash transaction for signing a specific input.
|
* Hash transaction for signing a specific input.
|
||||||
|
@ -48,6 +48,5 @@ export declare class Transaction {
|
||||||
toHex(): string;
|
toHex(): string;
|
||||||
setInputScript(index: number, scriptSig: Buffer): void;
|
setInputScript(index: number, scriptSig: Buffer): void;
|
||||||
setWitness(index: number, witness: Buffer[]): void;
|
setWitness(index: number, witness: Buffer[]): void;
|
||||||
private __byteLength;
|
|
||||||
private __toBuffer;
|
private __toBuffer;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue