Merge pull request #1515 from bitcoinjs/addWeightBlock

Add weight and ability to get strippedsize
This commit is contained in:
d-yokoi 2019-12-09 10:57:44 +09:00 committed by GitHub
commit 456ba5a6d9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 74 additions and 62 deletions

View file

@ -127,12 +127,17 @@ class Block {
hasWitness() {
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;
return (
80 +
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() {

View file

@ -179,15 +179,31 @@ class Transaction {
});
}
weight() {
const base = this.__byteLength(false);
const total = this.__byteLength(true);
const base = this.byteLength(false);
const total = this.byteLength(true);
return base * 3 + total;
}
virtualSize() {
return Math.ceil(this.weight() / 4);
}
byteLength() {
return this.__byteLength(true);
byteLength(_ALLOW_WITNESS = 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() {
const newTx = new Transaction();
@ -269,7 +285,7 @@ class Transaction {
txTmp.ins[inIndex].script = ourScript;
}
// 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);
txTmp.__toBuffer(buffer, 0, false);
return bcrypto.hash256(buffer);
@ -386,27 +402,8 @@ class Transaction {
typeforce(types.tuple(types.Number, [types.Buffer]), arguments);
this.ins[index].witness = witness;
}
__byteLength(_ALLOW_WITNESS) {
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)
);
}
__toBuffer(buffer, initialOffset, _ALLOW_WITNESS) {
if (!buffer) buffer = Buffer.allocUnsafe(this.__byteLength(_ALLOW_WITNESS));
__toBuffer(buffer, initialOffset, _ALLOW_WITNESS = false) {
if (!buffer) buffer = Buffer.allocUnsafe(this.byteLength(_ALLOW_WITNESS));
let offset = initialOffset || 0;
function writeSlice(slice) {
offset += slice.copy(buffer, offset);

View file

@ -48,6 +48,11 @@ describe('Block', () => {
assert.strictEqual(block.bits, f.bits);
assert.strictEqual(block.nonce, f.nonce);
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);
}
});
});

View file

@ -133,7 +133,10 @@
"prevHash": "8980ebb11236bacc66c447d5ad961bc546c0f9cc385a08000000000000000000",
"timestamp": 1537429727,
"valid": true,
"version": 536870912
"version": 536870912,
"size": 2355,
"strippedSize": 2209,
"weight": 8982
}
],
"invalid": [

View file

@ -148,13 +148,19 @@ export class Block {
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;
return (
80 +
varuint.encodingLength(this.transactions.length) +
this.transactions.reduce((a, x) => a + x.byteLength(), 0)
this.transactions.reduce((a, x) => a + x.byteLength(allowWitness), 0)
);
}

View file

@ -237,8 +237,8 @@ export class Transaction {
}
weight(): number {
const base = this.__byteLength(false);
const total = this.__byteLength(true);
const base = this.byteLength(false);
const total = this.byteLength(true);
return base * 3 + total;
}
@ -246,8 +246,25 @@ export class Transaction {
return Math.ceil(this.weight() / 4);
}
byteLength(): number {
return this.__byteLength(true);
byteLength(_ALLOW_WITNESS: boolean = true): 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)
);
}
clone(): Transaction {
@ -352,7 +369,7 @@ export class Transaction {
}
// 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);
txTmp.__toBuffer(buffer, 0, false);
@ -506,34 +523,13 @@ export class Transaction {
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(
buffer?: Buffer,
initialOffset?: number,
_ALLOW_WITNESS?: boolean,
_ALLOW_WITNESS: boolean = false,
): 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;

3
types/block.d.ts vendored
View file

@ -15,7 +15,8 @@ export declare class Block {
getWitnessCommit(): Buffer | null;
hasWitnessCommit(): boolean;
hasWitness(): boolean;
byteLength(headersOnly?: boolean): number;
weight(): number;
byteLength(headersOnly?: boolean, allowWitness?: boolean): number;
getHash(): Buffer;
getId(): string;
getUTCDate(): Date;

View file

@ -30,7 +30,7 @@ export declare class Transaction {
hasWitnesses(): boolean;
weight(): number;
virtualSize(): number;
byteLength(): number;
byteLength(_ALLOW_WITNESS?: boolean): number;
clone(): Transaction;
/**
* Hash transaction for signing a specific input.
@ -48,6 +48,5 @@ export declare class Transaction {
toHex(): string;
setInputScript(index: number, scriptSig: Buffer): void;
setWitness(index: number, witness: Buffer[]): void;
private __byteLength;
private __toBuffer;
}