8
8
9
9
/**
10
10
* @typedef Estimate
11
- * @prop {Uint53 } secondsPerBlock
12
11
* @prop {Uint53 } voteHeight
13
12
* @prop {Uint53 } voteDelta
14
13
* @prop {String } voteIso - date in ISO format
@@ -40,6 +39,13 @@ var DashGov = ("object" === typeof module && exports) || {};
40
39
// USAGE
41
40
// node ./gobject-hash-debugger.js
42
41
42
+ const LITTLE_ENDIAN = true ;
43
+ const VARINT_8_MAX = 252 ;
44
+ const UINT_16_MAX = 65535 ;
45
+ const UINT_32_MAX = 4294967295 ;
46
+
47
+ let textEncoder = new TextEncoder ( ) ;
48
+
43
49
GObj . _type = 0b0000010 ; // from SER_GETHASH (bitwise enum)
44
50
GObj . _typeBytes = Uint8Array . from ( [ 0b0000010 ] ) ;
45
51
GObj . _protocalVersion = 70231 ; // 0x00011257 (BE) => 0x57120100 (LE)
@@ -71,37 +77,47 @@ var DashGov = ("object" === typeof module && exports) || {};
71
77
* @param {number } nSize
72
78
*/
73
79
GObj . utils . toVarIntSize = function ( nSize ) {
74
- return nSize < 253
75
- ? 0
76
- : nSize <= 2 ** 16 - 1
77
- ? 2
78
- : nSize <= 2 ** 32 - 1
79
- ? 4
80
- : 8 ;
80
+ if ( nSize <= VARINT_8_MAX ) {
81
+ return 1 ;
82
+ }
83
+
84
+ if ( nSize <= UINT_16_MAX ) {
85
+ return 3 ;
86
+ }
87
+
88
+ if ( nSize <= UINT_32_MAX ) {
89
+ return 5 ;
90
+ }
91
+
92
+ return 9 ;
81
93
} ;
82
94
83
95
/**
84
- * Writes `nSize ` out to `dv` in a variable-length encoding.
96
+ * Writes `n ` out to `dv` in a variable-length encoding.
85
97
* Assumes you want to write out the data of `nSize` length to `dv` afterwards.
86
98
* @param {DataView } dv
87
- * @param {number } offset
88
- * @param {number } nSize
99
+ * @param {Number } offset
100
+ * @param {Number } n
89
101
*/
90
- function WriteCompactSize (
91
- dv ,
92
- offset ,
93
- nSize ,
94
- s = GObj . utils . toVarIntSize ( nSize ) ,
95
- ) {
96
- switch ( s ) {
97
- case 2 :
98
- case 4 :
99
- case 8 :
100
- dv . setBigUint64 ( offset + 1 , BigInt ( nSize ) , true ) ;
101
- nSize = 252 + Math . log2 ( s ) ;
102
- default :
103
- dv . setUint8 ( offset , nSize ) ;
102
+ function writeVarInt ( dv , offset , n ) {
103
+ if ( n <= VARINT_8_MAX ) {
104
+ dv . setUint8 ( offset , n ) ;
105
+ return ;
106
+ }
107
+
108
+ let size ;
109
+ if ( n <= UINT_16_MAX ) {
110
+ size = 253 ;
111
+ } else if ( n <= UINT_32_MAX ) {
112
+ size = 254 ;
113
+ } else {
114
+ size = 255 ;
104
115
}
116
+ dv . setUint8 ( offset , size ) ;
117
+
118
+ offset += 1 ;
119
+ let bigN = BigInt ( n ) ;
120
+ dv . setBigUint64 ( offset , bigN , LITTLE_ENDIAN ) ;
105
121
}
106
122
107
123
/**
@@ -131,7 +147,6 @@ var DashGov = ("object" === typeof module && exports) || {};
131
147
* @prop {BigInt|Uint53 } time - seconds since epoch (8 bytes)
132
148
* @prop {String } hexJson - variable
133
149
* @prop {null } [masternodeOutpoint] - ??
134
- * @prop {null } [collateralTxOutputIndex] - 4 bytes of 0xffs
135
150
* @prop {null } [collateralTxId] - 32 bytes of 0x00s
136
151
* @prop {null } [collateralTxOutputIndex] - 4 bytes of 0xffs
137
152
* @prop {null } [signature] - 0 bytes
@@ -147,14 +162,13 @@ var DashGov = ("object" === typeof module && exports) || {};
147
162
time,
148
163
hexJson,
149
164
} ) {
150
- const compactSizeExtraOffset = GObj . utils . toVarIntSize ( hexJson . length ) ;
165
+ const varIntSize = GObj . utils . toVarIntSize ( hexJson . length ) ;
151
166
152
167
const dataLen =
153
168
32 + // hashParent
154
169
4 + // revision
155
170
8 + // time
156
- 1 +
157
- compactSizeExtraOffset + // compacted length header for HexStr(vchData)
171
+ varIntSize + // compacted length header for HexStr(vchData)
158
172
hexJson . length + // HexStr(vchData)
159
173
32 +
160
174
4 + // masterNodeOutpoint (not used, so these bytes are the defaults)
@@ -172,39 +186,37 @@ var DashGov = ("object" === typeof module && exports) || {};
172
186
}
173
187
offset += 32 ;
174
188
175
- dv . setInt32 ( offset , revision , true ) ;
189
+ dv . setInt32 ( offset , revision , LITTLE_ENDIAN ) ;
176
190
offset += 4 ;
177
191
178
- dv . setBigInt64 ( offset , BigInt ( time ) , true ) ;
192
+ let bigTime = BigInt ( time ) ;
193
+ dv . setBigInt64 ( offset , bigTime , LITTLE_ENDIAN ) ;
179
194
offset += 8 ;
180
195
181
- // Write out hexJson, with a compacted size in front
182
- WriteCompactSize ( dv , offset , hexJson . length , compactSizeExtraOffset ) ;
183
- offset += 1 + compactSizeExtraOffset ;
184
- bytes . set ( new TextEncoder ( ) . encode ( hexJson ) , offset ) ;
196
+ void writeVarInt ( dv , offset , hexJson . length ) ;
197
+ offset += varIntSize ;
198
+ let hexJsonBytes = textEncoder . encode ( hexJson ) ;
199
+ bytes . set ( hexJsonBytes , offset ) ;
185
200
offset += hexJson . length ;
186
201
187
202
{
188
- // masternodeOutpoint exists in the C++ object and needs to be included,
189
- // however, it is not filled with data for our purposes.
190
-
191
- // Write out empty masternodeHash
203
+ // masternodeOutpointId (hash + index) is required for legacy reasons,
204
+ // but not used for collateral serialization
192
205
offset += 32 ;
193
206
194
207
// Write out default mastNode `n` (index)
195
208
let masternodeOutpointIndex = 0xffffffff ;
196
- dv . setUint32 ( offset , masternodeOutpointIndex , true ) ;
209
+ dv . setUint32 ( offset , masternodeOutpointIndex , LITTLE_ENDIAN ) ;
197
210
offset += 4 ;
198
211
199
212
// adding dummy values here to match old hashing
200
213
offset += 1 ;
201
- dv . setUint32 ( offset , 0xffffffff , true ) ;
214
+ dv . setUint32 ( offset , 0xffffffff , LITTLE_ENDIAN ) ;
202
215
offset += 4 ;
203
216
}
204
217
205
- // In the C++ version, `vchSig` must have its length written out in `WriteCompactSize` fashion.
206
- // Then, if the length is greater than 0, `vchSig` is written out too.
207
- // However, we never need a signature here, so we just write out a `0`.
218
+ // the trailing 0 byte represents the VarInt Size of the vchSig,
219
+ // which is always 0 for collateral serialization
208
220
offset += 1 ;
209
221
return bytes ;
210
222
} ;
@@ -403,6 +415,7 @@ if ("object" === typeof module) {
403
415
module . exports = DashGov ;
404
416
}
405
417
418
+ /** @typedef {bigint } BigInt */
406
419
/** @typedef {Number } Uint8 */
407
420
/** @typedef {Number } Uint32 */
408
421
/** @typedef {Number } Uint53 */
0 commit comments