1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 | 'use strict'
|
14 |
|
15 | import { Br } from './br'
|
16 | import { Bw } from './bw'
|
17 | import { BlockHeader } from './block-header'
|
18 | import { Hash } from './hash'
|
19 | import { Merkle } from './merkle'
|
20 | import { Struct } from './struct'
|
21 | import { Tx } from './tx'
|
22 | import { VarInt } from './var-int'
|
23 | import { Workers } from './workers'
|
24 |
|
25 | class Block extends Struct {
|
26 | constructor (blockHeader, txsVi, txs) {
|
27 | super({ blockHeader, txsVi, txs })
|
28 | }
|
29 |
|
30 | fromJSON (json) {
|
31 | const txs = []
|
32 | json.txs.forEach(function (tx) {
|
33 | txs.push(new Tx().fromJSON(tx))
|
34 | })
|
35 | this.fromObject({
|
36 | blockHeader: new BlockHeader().fromJSON(json.blockHeader),
|
37 | txsVi: new VarInt().fromJSON(json.txsVi),
|
38 | txs: txs
|
39 | })
|
40 | return this
|
41 | }
|
42 |
|
43 | toJSON () {
|
44 | const txs = []
|
45 | this.txs.forEach(function (tx) {
|
46 | txs.push(tx.toJSON())
|
47 | })
|
48 | return {
|
49 | blockHeader: this.blockHeader.toJSON(),
|
50 | txsVi: this.txsVi.toJSON(),
|
51 | txs: txs
|
52 | }
|
53 | }
|
54 |
|
55 | fromBr (br) {
|
56 | this.blockHeader = new BlockHeader().fromBr(br)
|
57 | this.txsVi = new VarInt(br.readVarIntBuf())
|
58 | const txsNum = this.txsVi.toNumber()
|
59 | this.txs = []
|
60 | for (let i = 0; i < txsNum; i++) {
|
61 | this.txs.push(new Tx().fromBr(br))
|
62 | }
|
63 | return this
|
64 | }
|
65 |
|
66 | toBw (bw) {
|
67 | if (!bw) {
|
68 | bw = new Bw()
|
69 | }
|
70 | bw.write(this.blockHeader.toBuffer())
|
71 | bw.write(this.txsVi.buf)
|
72 | const txsNum = this.txsVi.toNumber()
|
73 | for (let i = 0; i < txsNum; i++) {
|
74 | this.txs[i].toBw(bw)
|
75 | }
|
76 | return bw
|
77 | }
|
78 |
|
79 | hash () {
|
80 | return Hash.sha256Sha256(this.blockHeader.toBuffer())
|
81 | }
|
82 |
|
83 | async asyncHash () {
|
84 | const workersResult = await Workers.asyncObjectMethod(this, 'hash', [])
|
85 | return workersResult.resbuf
|
86 | }
|
87 |
|
88 | id () {
|
89 | return new Br(this.hash()).readReverse().toString('hex')
|
90 | }
|
91 |
|
92 | async asyncId () {
|
93 | const workersResult = await Workers.asyncObjectMethod(this, 'id', [])
|
94 | return JSON.parse(workersResult.resbuf.toString())
|
95 | }
|
96 |
|
97 | verifyMerkleRoot () {
|
98 | const txsbufs = this.txs.map(tx => tx.toBuffer())
|
99 | const merkleRootBuf = Merkle.fromBuffers(txsbufs).hash()
|
100 | return Buffer.compare(merkleRootBuf, this.blockHeader.merkleRootBuf)
|
101 | }
|
102 |
|
103 | |
104 |
|
105 |
|
106 |
|
107 |
|
108 |
|
109 |
|
110 |
|
111 |
|
112 | static iterateTxs (blockBuf) {
|
113 | const br = new Br(blockBuf)
|
114 | const blockHeader = new BlockHeader().fromBr(br)
|
115 | const txsVi = new VarInt(br.readVarIntBuf())
|
116 | const txsNum = txsVi.toNumber()
|
117 | return {
|
118 | blockHeader,
|
119 | txsVi,
|
120 | txsNum,
|
121 | * [Symbol.iterator] () {
|
122 | for (let i = 0; i < txsNum; i++) {
|
123 | yield new Tx().fromBr(br)
|
124 | }
|
125 | }
|
126 | }
|
127 | }
|
128 | }
|
129 |
|
130 | Block.MAX_BLOCK_SIZE = 1000000
|
131 |
|
132 | export { Block }
|