• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

handshake-org / hsd / 8452447998

27 Mar 2024 01:17PM UTC coverage: 16.226% (-52.4%) from 68.632%
8452447998

Pull #888

github

web-flow
Merge c40b9e40c into 0a4f24bdb
Pull Request #888: Wallet TX Count and time indexing

1001 of 12966 branches covered (7.72%)

Branch coverage included in aggregate %.

130 of 474 new or added lines in 11 files covered. (27.43%)

17522 existing lines in 124 files now uncovered.

6546 of 33547 relevant lines covered (19.51%)

37.41 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

36.57
/lib/script/scriptnum.js
1
/*!
2
 * scriptnum.js - script number object for hsd.
3
 * Copyright (c) 2017, Christopher Jeffrey (MIT License).
4
 * https://github.com/handshake-org/hsd
5
 */
6

7
'use strict';
8

9
const assert = require('bsert');
1✔
10
const {I64} = require('n64');
1✔
11
const ScriptError = require('./scripterror');
1✔
12

13
/*
14
 * Constants
15
 */
16

17
const EMPTY_ARRAY = Buffer.alloc(0);
1✔
18

19
/**
20
 * Script Number
21
 * @see https://github.com/chjj/n64
22
 * @alias module:script.ScriptNum
23
 * @property {Number} hi
24
 * @property {Number} lo
25
 * @property {Number} sign
26
 */
27

28
class ScriptNum extends I64 {
29
  /**
30
   * Create a script number.
31
   * @constructor
32
   * @param {(Number|String|Buffer|Object)?} num
33
   * @param {(String|Number)?} base
34
   */
35

36
  constructor(num, base) {
37
    super(num, base);
1,263✔
38
  }
39

40
  /**
41
   * Cast to int32.
42
   * @returns {Number}
43
   */
44

45
  getInt() {
UNCOV
46
    if (this.lt(I64.INT32_MIN))
×
47
      return I64.LONG_MIN;
×
48

UNCOV
49
    if (this.gt(I64.INT32_MAX))
×
50
      return I64.LONG_MAX;
×
51

UNCOV
52
    return this.toInt();
×
53
  }
54

55
  /**
56
   * Serialize script number.
57
   * @returns {Buffer}
58
   */
59

60
  encode() {
61
    let num = this;
1,254✔
62

63
    // Zeroes are always empty arrays.
64
    if (num.isZero())
1,254!
UNCOV
65
      return EMPTY_ARRAY;
×
66

67
    // Need to append sign bit.
68
    let neg = false;
1,254✔
69
    if (num.isNeg()) {
1,254✔
70
      num = num.neg();
9✔
71
      neg = true;
9✔
72
    }
73

74
    // Calculate size.
75
    const size = num.byteLength();
1,254✔
76

77
    let offset = 0;
1,254✔
78

79
    if (num.testn((size * 8) - 1))
1,254✔
80
      offset = 1;
7✔
81

82
    // Write number.
83
    const data = Buffer.allocUnsafe(size + offset);
1,254✔
84

85
    switch (size) {
1,254!
86
      case 8:
87
        data[7] = (num.hi >>> 24) & 0xff;
×
88
      case 7:
89
        data[6] = (num.hi >> 16) & 0xff;
×
90
      case 6:
91
        data[5] = (num.hi >> 8) & 0xff;
×
92
      case 5:
93
        data[4] = num.hi & 0xff;
×
94
      case 4:
95
        data[3] = (num.lo >>> 24) & 0xff;
4✔
96
      case 3:
97
        data[2] = (num.lo >> 16) & 0xff;
13✔
98
      case 2:
99
        data[1] = (num.lo >> 8) & 0xff;
21✔
100
      case 1:
101
        data[0] = num.lo & 0xff;
1,254✔
102
    }
103

104
    // Append sign bit.
105
    if (data[size - 1] & 0x80) {
1,254✔
106
      assert(offset === 1);
7✔
107
      assert(data.length === size + offset);
7✔
108
      data[size] = neg ? 0x80 : 0;
7✔
109
    } else if (neg) {
1,247✔
110
      assert(offset === 0);
6✔
111
      assert(data.length === size);
6✔
112
      data[size - 1] |= 0x80;
6✔
113
    } else {
114
      assert(offset === 0);
1,241✔
115
      assert(data.length === size);
1,241✔
116
    }
117

118
    return data;
1,254✔
119
  }
120

121
  /**
122
   * Instantiate script number from serialized data.
123
   * @private
124
   * @param {Buffer} data
125
   * @returns {ScriptNum}
126
   */
127

128
  _decode(data) {
UNCOV
129
    assert(Buffer.isBuffer(data));
×
130

131
    // Empty arrays are always zero.
UNCOV
132
    if (data.length === 0)
×
UNCOV
133
      return this;
×
134

135
    // Read number (9 bytes max).
UNCOV
136
    switch (data.length) {
×
137
      case 8:
138
        this.hi |= data[7] << 24;
×
139
      case 7:
140
        this.hi |= data[6] << 16;
×
141
      case 6:
142
        this.hi |= data[5] << 8;
×
143
      case 5:
UNCOV
144
        this.hi |= data[4];
×
145
      case 4:
UNCOV
146
        this.lo |= data[3] << 24;
×
147
      case 3:
UNCOV
148
        this.lo |= data[2] << 16;
×
149
      case 2:
UNCOV
150
        this.lo |= data[1] << 8;
×
151
      case 1:
UNCOV
152
        this.lo |= data[0];
×
UNCOV
153
        break;
×
154
      default:
155
        for (let i = 0; i < data.length; i++)
×
156
          this.orb(i, data[i]);
×
157
        break;
×
158
    }
159

160
    // Remove high bit and flip sign.
UNCOV
161
    if (data[data.length - 1] & 0x80) {
×
UNCOV
162
      this.setn((data.length * 8) - 1, 0);
×
UNCOV
163
      this.ineg();
×
164
    }
165

UNCOV
166
    return this;
×
167
  }
168

169
  /**
170
   * Decode and verify script number.
171
   * @private
172
   * @param {Buffer} data
173
   * @param {Boolean?} minimal - Require minimal encoding.
174
   * @param {Number?} limit - Size limit.
175
   * @returns {ScriptNum}
176
   */
177

178
  decode(data, minimal, limit) {
UNCOV
179
    assert(Buffer.isBuffer(data));
×
180

UNCOV
181
    if (limit != null && data.length > limit)
×
UNCOV
182
      throw new ScriptError('UNKNOWN_ERROR', 'Script number overflow.');
×
183

UNCOV
184
    if (minimal && !ScriptNum.isMinimal(data))
×
UNCOV
185
      throw new ScriptError('UNKNOWN_ERROR', 'Non-minimal script number.');
×
186

UNCOV
187
    return this._decode(data);
×
188
  }
189

190
  /**
191
   * Inspect script number.
192
   * @returns {String}
193
   */
194

195
  inspect() {
196
    return `<ScriptNum: ${this.toString(10)}>`;
×
197
  }
198

199
  /**
200
   * Test wether a serialized script
201
   * number is in its most minimal form.
202
   * @param {Buffer} data
203
   * @returns {Boolean}
204
   */
205

206
  static isMinimal(data) {
UNCOV
207
    assert(Buffer.isBuffer(data));
×
208

UNCOV
209
    if (data.length === 0)
×
UNCOV
210
      return true;
×
211

UNCOV
212
    if ((data[data.length - 1] & 0x7f) === 0) {
×
UNCOV
213
      if (data.length === 1)
×
UNCOV
214
        return false;
×
215

UNCOV
216
      if ((data[data.length - 2] & 0x80) === 0)
×
UNCOV
217
        return false;
×
218
    }
219

UNCOV
220
    return true;
×
221
  }
222

223
  /**
224
   * Decode and verify script number.
225
   * @param {Buffer} data
226
   * @param {Boolean?} minimal - Require minimal encoding.
227
   * @param {Number?} limit - Size limit.
228
   * @returns {ScriptNum}
229
   */
230

231
  static decode(data, minimal, limit) {
UNCOV
232
    return new this().decode(data, minimal, limit);
×
233
  }
234

235
  /**
236
   * Test whether object is a script number.
237
   * @param {Object} obj
238
   * @returns {Boolean}
239
   */
240

241
  static isScriptNum(obj) {
242
    return obj instanceof ScriptNum;
1,254✔
243
  }
244
}
245

246
/*
247
 * Expose
248
 */
249

250
module.exports = ScriptNum;
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc