From 91e6c8abc3517571eca08fefe13adc433394d2bb Mon Sep 17 00:00:00 2001 From: junderw Date: Wed, 15 Jan 2020 10:44:29 +0900 Subject: [PATCH] Move to bufferutils and add BufferReader --- src/buffer_writer.js | 44 ----------------- src/bufferutils.js | 90 +++++++++++++++++++++++++++++++++ src/transaction.js | 13 +++-- ts_src/buffer_writer.ts | 54 -------------------- ts_src/bufferutils.ts | 104 +++++++++++++++++++++++++++++++++++++++ ts_src/transaction.ts | 3 +- types/buffer_writer.d.ts | 16 ------ types/bufferutils.d.ts | 32 ++++++++++++ 8 files changed, 233 insertions(+), 123 deletions(-) delete mode 100644 src/buffer_writer.js delete mode 100644 ts_src/buffer_writer.ts delete mode 100644 types/buffer_writer.d.ts diff --git a/src/buffer_writer.js b/src/buffer_writer.js deleted file mode 100644 index 19a2332..0000000 --- a/src/buffer_writer.js +++ /dev/null @@ -1,44 +0,0 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const bufferutils = require('./bufferutils'); -const types = require('./types'); -const typeforce = require('typeforce'); -const varuint = require('varuint-bitcoin'); -/** - * Helper class for serialization of bitcoin data types into a pre-allocated buffer. - */ -class BufferWriter { - constructor(buffer, offset = 0) { - typeforce(types.tuple(types.Buffer, types.UInt32), [buffer, offset]); - this.buffer = buffer; - this.offset = offset; - } - writeUInt8(i) { - this.offset = this.buffer.writeUInt8(i, this.offset); - } - writeInt32(i) { - this.offset = this.buffer.writeInt32LE(i, this.offset); - } - writeUInt32(i) { - this.offset = this.buffer.writeUInt32LE(i, this.offset); - } - writeUInt64(i) { - this.offset = bufferutils.writeUInt64LE(this.buffer, i, this.offset); - } - writeVarInt(i) { - varuint.encode(i, this.buffer, this.offset); - this.offset += varuint.encode.bytes; - } - writeSlice(slice) { - this.offset += slice.copy(this.buffer, this.offset); - } - writeVarSlice(slice) { - this.writeVarInt(slice.length); - this.writeSlice(slice); - } - writeVector(vector) { - this.writeVarInt(vector.length); - vector.forEach(buf => this.writeVarSlice(buf)); - } -} -exports.BufferWriter = BufferWriter; diff --git a/src/bufferutils.js b/src/bufferutils.js index 54ce1c9..19e8763 100644 --- a/src/bufferutils.js +++ b/src/bufferutils.js @@ -1,5 +1,8 @@ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); +const types = require('./types'); +const typeforce = require('typeforce'); +const varuint = require('varuint-bitcoin'); // https://github.com/feross/buffer/blob/master/index.js#L1127 function verifuint(value, max) { if (typeof value !== 'number') @@ -38,3 +41,90 @@ function reverseBuffer(buffer) { return buffer; } exports.reverseBuffer = reverseBuffer; +/** + * Helper class for serialization of bitcoin data types into a pre-allocated buffer. + */ +class BufferWriter { + constructor(buffer, offset = 0) { + this.buffer = buffer; + this.offset = offset; + typeforce(types.tuple(types.Buffer, types.UInt32), [buffer, offset]); + } + writeUInt8(i) { + this.offset = this.buffer.writeUInt8(i, this.offset); + } + writeInt32(i) { + this.offset = this.buffer.writeInt32LE(i, this.offset); + } + writeUInt32(i) { + this.offset = this.buffer.writeUInt32LE(i, this.offset); + } + writeUInt64(i) { + this.offset = writeUInt64LE(this.buffer, i, this.offset); + } + writeVarInt(i) { + varuint.encode(i, this.buffer, this.offset); + this.offset += varuint.encode.bytes; + } + writeSlice(slice) { + this.offset += slice.copy(this.buffer, this.offset); + } + writeVarSlice(slice) { + this.writeVarInt(slice.length); + this.writeSlice(slice); + } + writeVector(vector) { + this.writeVarInt(vector.length); + vector.forEach(buf => this.writeVarSlice(buf)); + } +} +exports.BufferWriter = BufferWriter; +/** + * Helper class for serialization of bitcoin data types into a pre-allocated buffer. + */ +class BufferReader { + constructor(buffer, offset = 0) { + this.buffer = buffer; + this.offset = offset; + typeforce(types.tuple(types.Buffer, types.UInt32), [buffer, offset]); + } + readUInt8() { + const result = this.buffer.readUInt8(this.offset); + this.offset++; + return result; + } + readInt32() { + const result = this.buffer.readInt32LE(this.offset); + this.offset += 4; + return result; + } + readUInt32() { + const result = this.buffer.readUInt32LE(this.offset); + this.offset += 4; + return result; + } + readUInt64() { + const result = readUInt64LE(this.buffer, this.offset); + this.offset += 8; + return result; + } + readVarInt() { + const vi = varuint.decode(this.buffer, this.offset); + this.offset += varuint.decode.bytes; + return vi; + } + readSlice(n) { + this.offset += n; + return this.buffer.slice(this.offset - n, this.offset); + } + readVarSlice() { + return this.readSlice(this.readVarInt()); + } + readVector() { + const count = this.readVarInt(); + const vector = []; + for (let i = 0; i < count; i++) vector.push(this.readVarSlice()); + return vector; + } +} +exports.BufferReader = BufferReader; diff --git a/src/transaction.js b/src/transaction.js index fc36a63..ef97900 100644 --- a/src/transaction.js +++ b/src/transaction.js @@ -1,6 +1,5 @@ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); -const buffer_writer_1 = require('./buffer_writer'); const bufferutils = require('./bufferutils'); const bufferutils_1 = require('./bufferutils'); const bcrypto = require('./crypto'); @@ -303,7 +302,7 @@ class Transaction { let hashSequence = ZERO; if (!(hashType & Transaction.SIGHASH_ANYONECANPAY)) { tbuffer = Buffer.allocUnsafe(36 * this.ins.length); - bufferWriter = new buffer_writer_1.BufferWriter(tbuffer, 0); + bufferWriter = new bufferutils_1.BufferWriter(tbuffer, 0); this.ins.forEach(txIn => { bufferWriter.writeSlice(txIn.hash); bufferWriter.writeUInt32(txIn.index); @@ -316,7 +315,7 @@ class Transaction { (hashType & 0x1f) !== Transaction.SIGHASH_NONE ) { tbuffer = Buffer.allocUnsafe(4 * this.ins.length); - bufferWriter = new buffer_writer_1.BufferWriter(tbuffer, 0); + bufferWriter = new bufferutils_1.BufferWriter(tbuffer, 0); this.ins.forEach(txIn => { bufferWriter.writeUInt32(txIn.sequence); }); @@ -330,7 +329,7 @@ class Transaction { return sum + 8 + varSliceSize(output.script); }, 0); tbuffer = Buffer.allocUnsafe(txOutsSize); - bufferWriter = new buffer_writer_1.BufferWriter(tbuffer, 0); + bufferWriter = new bufferutils_1.BufferWriter(tbuffer, 0); this.outs.forEach(out => { bufferWriter.writeUInt64(out.value); bufferWriter.writeVarSlice(out.script); @@ -342,13 +341,13 @@ class Transaction { ) { const output = this.outs[inIndex]; tbuffer = Buffer.allocUnsafe(8 + varSliceSize(output.script)); - bufferWriter = new buffer_writer_1.BufferWriter(tbuffer, 0); + bufferWriter = new bufferutils_1.BufferWriter(tbuffer, 0); bufferWriter.writeUInt64(output.value); bufferWriter.writeVarSlice(output.script); hashOutputs = bcrypto.hash256(tbuffer); } tbuffer = Buffer.allocUnsafe(156 + varSliceSize(prevOutScript)); - bufferWriter = new buffer_writer_1.BufferWriter(tbuffer, 0); + bufferWriter = new bufferutils_1.BufferWriter(tbuffer, 0); const input = this.ins[inIndex]; bufferWriter.writeUInt32(this.version); bufferWriter.writeSlice(hashPrevouts); @@ -388,7 +387,7 @@ class Transaction { } __toBuffer(buffer, initialOffset, _ALLOW_WITNESS = false) { if (!buffer) buffer = Buffer.allocUnsafe(this.byteLength(_ALLOW_WITNESS)); - const bufferWriter = new buffer_writer_1.BufferWriter( + const bufferWriter = new bufferutils_1.BufferWriter( buffer, initialOffset || 0, ); diff --git a/ts_src/buffer_writer.ts b/ts_src/buffer_writer.ts deleted file mode 100644 index 541457d..0000000 --- a/ts_src/buffer_writer.ts +++ /dev/null @@ -1,54 +0,0 @@ -import * as bufferutils from './bufferutils'; -import * as types from './types'; - -const typeforce = require('typeforce'); -const varuint = require('varuint-bitcoin'); - -/** - * Helper class for serialization of bitcoin data types into a pre-allocated buffer. - */ -export class BufferWriter { - buffer: Buffer; - offset: number; - - constructor(buffer: Buffer, offset: number = 0) { - typeforce(types.tuple(types.Buffer, types.UInt32), [buffer, offset]); - this.buffer = buffer; - this.offset = offset; - } - - writeUInt8(i: number): void { - this.offset = this.buffer.writeUInt8(i, this.offset); - } - - writeInt32(i: number): void { - this.offset = this.buffer.writeInt32LE(i, this.offset); - } - - writeUInt32(i: number): void { - this.offset = this.buffer.writeUInt32LE(i, this.offset); - } - - writeUInt64(i: number): void { - this.offset = bufferutils.writeUInt64LE(this.buffer, i, this.offset); - } - - writeVarInt(i: number): void { - varuint.encode(i, this.buffer, this.offset); - this.offset += varuint.encode.bytes; - } - - writeSlice(slice: Buffer): void { - this.offset += slice.copy(this.buffer, this.offset); - } - - writeVarSlice(slice: Buffer): void { - this.writeVarInt(slice.length); - this.writeSlice(slice); - } - - writeVector(vector: Buffer[]): void { - this.writeVarInt(vector.length); - vector.forEach((buf: Buffer) => this.writeVarSlice(buf)); - } -} diff --git a/ts_src/bufferutils.ts b/ts_src/bufferutils.ts index adb6060..6904b73 100644 --- a/ts_src/bufferutils.ts +++ b/ts_src/bufferutils.ts @@ -1,3 +1,8 @@ +import * as types from './types'; + +const typeforce = require('typeforce'); +const varuint = require('varuint-bitcoin'); + // https://github.com/feross/buffer/blob/master/index.js#L1127 function verifuint(value: number, max: number): void { if (typeof value !== 'number') @@ -42,3 +47,102 @@ export function reverseBuffer(buffer: Buffer): Buffer { } return buffer; } + +/** + * Helper class for serialization of bitcoin data types into a pre-allocated buffer. + */ +export class BufferWriter { + constructor(private buffer: Buffer, public offset: number = 0) { + typeforce(types.tuple(types.Buffer, types.UInt32), [buffer, offset]); + } + + writeUInt8(i: number): void { + this.offset = this.buffer.writeUInt8(i, this.offset); + } + + writeInt32(i: number): void { + this.offset = this.buffer.writeInt32LE(i, this.offset); + } + + writeUInt32(i: number): void { + this.offset = this.buffer.writeUInt32LE(i, this.offset); + } + + writeUInt64(i: number): void { + this.offset = writeUInt64LE(this.buffer, i, this.offset); + } + + writeVarInt(i: number): void { + varuint.encode(i, this.buffer, this.offset); + this.offset += varuint.encode.bytes; + } + + writeSlice(slice: Buffer): void { + this.offset += slice.copy(this.buffer, this.offset); + } + + writeVarSlice(slice: Buffer): void { + this.writeVarInt(slice.length); + this.writeSlice(slice); + } + + writeVector(vector: Buffer[]): void { + this.writeVarInt(vector.length); + vector.forEach((buf: Buffer) => this.writeVarSlice(buf)); + } +} + +/** + * Helper class for serialization of bitcoin data types into a pre-allocated buffer. + */ +export class BufferReader { + constructor(private buffer: Buffer, public offset: number = 0) { + typeforce(types.tuple(types.Buffer, types.UInt32), [buffer, offset]); + } + + readUInt8(): number { + const result = this.buffer.readUInt8(this.offset); + this.offset++; + return result; + } + + readInt32(): number { + const result = this.buffer.readInt32LE(this.offset); + this.offset += 4; + return result; + } + + readUInt32(): number { + const result = this.buffer.readUInt32LE(this.offset); + this.offset += 4; + return result; + } + + readUInt64(): number { + const result = readUInt64LE(this.buffer, this.offset); + this.offset += 8; + return result; + } + + readVarInt(): number { + const vi = varuint.decode(this.buffer, this.offset); + this.offset += varuint.decode.bytes; + return vi; + } + + readSlice(n: number): Buffer { + this.offset += n; + return this.buffer.slice(this.offset - n, this.offset); + } + + readVarSlice(): Buffer { + return this.readSlice(this.readVarInt()); + } + + readVector(): Buffer[] { + const count = this.readVarInt(); + const vector: Buffer[] = []; + for (let i = 0; i < count; i++) vector.push(this.readVarSlice()); + return vector; + } +} diff --git a/ts_src/transaction.ts b/ts_src/transaction.ts index ac5aea4..3b792ec 100644 --- a/ts_src/transaction.ts +++ b/ts_src/transaction.ts @@ -1,6 +1,5 @@ -import { BufferWriter } from './buffer_writer'; import * as bufferutils from './bufferutils'; -import { reverseBuffer } from './bufferutils'; +import { BufferWriter, reverseBuffer } from './bufferutils'; import * as bcrypto from './crypto'; import * as bscript from './script'; import { OPS as opcodes } from './script'; diff --git a/types/buffer_writer.d.ts b/types/buffer_writer.d.ts deleted file mode 100644 index 5ff07f9..0000000 --- a/types/buffer_writer.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Helper class for serialization of bitcoin data types into a pre-allocated buffer. - */ -export declare class BufferWriter { - buffer: Buffer; - offset: number; - constructor(buffer: Buffer, offset?: number); - writeUInt8(i: number): void; - writeInt32(i: number): void; - writeUInt32(i: number): void; - writeUInt64(i: number): void; - writeVarInt(i: number): void; - writeSlice(slice: Buffer): void; - writeVarSlice(slice: Buffer): void; - writeVector(vector: Buffer[]): void; -} diff --git a/types/bufferutils.d.ts b/types/bufferutils.d.ts index 1eff78d..d9e6dc0 100644 --- a/types/bufferutils.d.ts +++ b/types/bufferutils.d.ts @@ -1,3 +1,35 @@ export declare function readUInt64LE(buffer: Buffer, offset: number): number; export declare function writeUInt64LE(buffer: Buffer, value: number, offset: number): number; export declare function reverseBuffer(buffer: Buffer): Buffer; +/** + * Helper class for serialization of bitcoin data types into a pre-allocated buffer. + */ +export declare class BufferWriter { + private buffer; + offset: number; + constructor(buffer: Buffer, offset?: number); + writeUInt8(i: number): void; + writeInt32(i: number): void; + writeUInt32(i: number): void; + writeUInt64(i: number): void; + writeVarInt(i: number): void; + writeSlice(slice: Buffer): void; + writeVarSlice(slice: Buffer): void; + writeVector(vector: Buffer[]): void; +} +/** + * Helper class for serialization of bitcoin data types into a pre-allocated buffer. + */ +export declare class BufferReader { + private buffer; + offset: number; + constructor(buffer: Buffer, offset?: number); + readUInt8(): number; + readInt32(): number; + readUInt32(): number; + readUInt64(): number; + readVarInt(): number; + readSlice(n: number): Buffer; + readVarSlice(): Buffer; + readVector(): Buffer[]; +}