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

handshake-org / hsd / 15042451478

15 May 2025 10:16AM UTC coverage: 19.792% (-51.5%) from 71.269%
15042451478

Pull #928

github

web-flow
Merge fa1d30da4 into 5f11d622b
Pull Request #928: Wallet coinselection

1570 of 13236 branches covered (11.86%)

Branch coverage included in aggregate %.

217 of 388 new or added lines in 6 files covered. (55.93%)

17866 existing lines in 127 files now uncovered.

7855 of 34384 relevant lines covered (22.84%)

129.11 hits per line

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

3.25
/lib/workers/parser.js
1
/*!
2
 * parser.js - worker parser for hsd
3
 * Copyright (c) 2017-2018, 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 EventEmitter = require('events');
1✔
11
const packets = require('./packets');
1✔
12

13
/**
14
 * Parser
15
 * @alias module:workers.Parser
16
 * @extends EventEmitter
17
 */
18

19
class Parser extends EventEmitter {
20
  /**
21
   * Create a parser.
22
   * @constructor
23
   */
24

25
  constructor() {
UNCOV
26
    super();
×
27

UNCOV
28
    this.waiting = 9;
×
UNCOV
29
    this.header = null;
×
UNCOV
30
    this.pending = [];
×
UNCOV
31
    this.total = 0;
×
32
  }
33

34
  feed(data) {
UNCOV
35
    this.total += data.length;
×
UNCOV
36
    this.pending.push(data);
×
37

UNCOV
38
    while (this.total >= this.waiting) {
×
UNCOV
39
      const chunk = this.read(this.waiting);
×
UNCOV
40
      this.parse(chunk);
×
41
    }
42
  }
43

44
  read(size) {
UNCOV
45
    assert(this.total >= size, 'Reading too much.');
×
46

UNCOV
47
    if (size === 0)
×
48
      return Buffer.alloc(0);
×
49

UNCOV
50
    const pending = this.pending[0];
×
51

UNCOV
52
    if (pending.length > size) {
×
UNCOV
53
      const chunk = pending.slice(0, size);
×
UNCOV
54
      this.pending[0] = pending.slice(size);
×
UNCOV
55
      this.total -= chunk.length;
×
UNCOV
56
      return chunk;
×
57
    }
58

UNCOV
59
    if (pending.length === size) {
×
UNCOV
60
      const chunk = this.pending.shift();
×
UNCOV
61
      this.total -= chunk.length;
×
UNCOV
62
      return chunk;
×
63
    }
64

UNCOV
65
    const chunk = Buffer.allocUnsafe(size);
×
UNCOV
66
    let off = 0;
×
67

UNCOV
68
    while (off < chunk.length) {
×
UNCOV
69
      const pending = this.pending[0];
×
UNCOV
70
      const len = pending.copy(chunk, off);
×
UNCOV
71
      if (len === pending.length)
×
UNCOV
72
        this.pending.shift();
×
73
      else
UNCOV
74
        this.pending[0] = pending.slice(len);
×
UNCOV
75
      off += len;
×
76
    }
77

UNCOV
78
    assert.strictEqual(off, chunk.length);
×
79

UNCOV
80
    this.total -= chunk.length;
×
81

UNCOV
82
    return chunk;
×
83
  }
84

85
  parse(data) {
UNCOV
86
    let header = this.header;
×
87

UNCOV
88
    if (!header) {
×
UNCOV
89
      try {
×
UNCOV
90
        header = this.parseHeader(data);
×
91
      } catch (e) {
92
        this.emit('error', e);
×
93
        return;
×
94
      }
95

UNCOV
96
      this.header = header;
×
UNCOV
97
      this.waiting = header.size + 1;
×
98

UNCOV
99
      return;
×
100
    }
101

UNCOV
102
    this.waiting = 9;
×
UNCOV
103
    this.header = null;
×
104

105
    let packet;
UNCOV
106
    try {
×
UNCOV
107
      packet = this.parsePacket(header, data);
×
108
    } catch (e) {
109
      this.emit('error', e);
×
110
      return;
×
111
    }
112

UNCOV
113
    if (data[data.length - 1] !== 0x0a) {
×
114
      this.emit('error', new Error('No trailing newline.'));
×
115
      return;
×
116
    }
117

UNCOV
118
    packet.id = header.id;
×
119

UNCOV
120
    this.emit('packet', packet);
×
121
  }
122

123
  parseHeader(data) {
UNCOV
124
    const id = data.readUInt32LE(0, true);
×
UNCOV
125
    const cmd = data.readUInt8(4, true);
×
UNCOV
126
    const size = data.readUInt32LE(5, true);
×
UNCOV
127
    return new Header(id, cmd, size);
×
128
  }
129

130
  parsePacket(header, data) {
UNCOV
131
    switch (header.cmd) {
×
132
      case packets.types.ENV:
UNCOV
133
        return packets.EnvPacket.decode(data);
×
134
      case packets.types.EVENT:
135
        return packets.EventPacket.decode(data);
×
136
      case packets.types.LOG:
137
        return packets.LogPacket.decode(data);
×
138
      case packets.types.ERROR:
139
        return packets.ErrorPacket.decode(data);
×
140
      case packets.types.ERRORRESULT:
141
        return packets.ErrorResultPacket.decode(data);
×
142
      case packets.types.CHECK:
UNCOV
143
        return packets.CheckPacket.decode(data);
×
144
      case packets.types.CHECKRESULT:
UNCOV
145
        return packets.CheckResultPacket.decode(data);
×
146
      case packets.types.SIGN:
UNCOV
147
        return packets.SignPacket.decode(data);
×
148
      case packets.types.SIGNRESULT:
UNCOV
149
        return packets.SignResultPacket.decode(data);
×
150
      case packets.types.CHECKINPUT:
151
        return packets.CheckInputPacket.decode(data);
×
152
      case packets.types.CHECKINPUTRESULT:
153
        return packets.CheckInputResultPacket.decode(data);
×
154
      case packets.types.SIGNINPUT:
155
        return packets.SignInputPacket.decode(data);
×
156
      case packets.types.SIGNINPUTRESULT:
157
        return packets.SignInputResultPacket.decode(data);
×
158
      case packets.types.ECVERIFY:
159
        return packets.ECVerifyPacket.decode(data);
×
160
      case packets.types.ECVERIFYRESULT:
161
        return packets.ECVerifyResultPacket.decode(data);
×
162
      case packets.types.ECSIGN:
163
        return packets.ECSignPacket.decode(data);
×
164
      case packets.types.ECSIGNRESULT:
165
        return packets.ECSignResultPacket.decode(data);
×
166
      case packets.types.MINE:
UNCOV
167
        return packets.MinePacket.decode(data);
×
168
      case packets.types.MINERESULT:
UNCOV
169
        return packets.MineResultPacket.decode(data);
×
170
      case packets.types.SCRYPT:
171
        return packets.ScryptPacket.decode(data);
×
172
      case packets.types.SCRYPTRESULT:
173
        return packets.ScryptResultPacket.decode(data);
×
174
      default:
175
        throw new Error('Unknown packet.');
×
176
    }
177
  }
178
}
179

180
/**
181
 * Header
182
 * @ignore
183
 */
184

185
class Header {
186
  /**
187
   * Create a header.
188
   * @constructor
189
   */
190

191
  constructor(id, cmd, size) {
UNCOV
192
    this.id = id;
×
UNCOV
193
    this.cmd = cmd;
×
UNCOV
194
    this.size = size;
×
195
  }
196
}
197

198
/*
199
 * Expose
200
 */
201

202
module.exports = Parser;
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