Skip to content

Commit 191621c

Browse files
committed
WIP: CoinJoin has a lot of code, and a button now
1 parent d5a125c commit 191621c

File tree

3 files changed

+252
-77
lines changed

3 files changed

+252
-77
lines changed

public/dashjoin.js

Lines changed: 127 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ var DashJoin = ('object' === typeof module && exports) || {};
99

1010
const DENOM_LOWEST = 100001;
1111
const PREDENOM_MIN = DENOM_LOWEST + 193;
12-
const COLLATERAL = 10000; // DENOM_LOWEST / 10
12+
const MIN_COLLATERAL = 10000; // DENOM_LOWEST / 10
1313

1414
let STANDARD_DENOMINATIONS_MAP = {
1515
// 0.00100001
@@ -44,7 +44,7 @@ var DashJoin = ('object' === typeof module && exports) || {};
4444
// const COINJOIN_ENTRY_MAX_SIZE = 2; // just for testing right now
4545

4646
DashJoin.DENOM_LOWEST = DENOM_LOWEST;
47-
DashJoin.COLLATERAL = COLLATERAL;
47+
DashJoin.MIN_COLLATERAL = MIN_COLLATERAL;
4848
DashJoin.PREDENOM_MIN = PREDENOM_MIN;
4949
DashJoin.DENOMS = [
5050
100001, // 0.00100001
@@ -81,8 +81,15 @@ var DashJoin = ('object' === typeof module && exports) || {};
8181
Sizes.READY = 1; // 1-byte bool
8282
Sizes.SIG = 97;
8383

84-
// Sizes.DSSU = 16;
85-
// Sizes.SESSION_ID = 4;
84+
Sizes.DSSU = 16;
85+
Sizes.SESSION_ID = 4;
86+
Sizes.MESSAGE_ID = 4;
87+
88+
/////////////////////
89+
// //
90+
// Packers //
91+
// //
92+
/////////////////////
8693

8794
/**
8895
* Turns on or off DSQ messages (necessary for CoinJoin, but off by default)
@@ -223,8 +230,8 @@ var DashJoin = ('object' === typeof module && exports) || {};
223230
const command = 'dss';
224231

225232
if (!inputs?.length) {
226-
// TODO make better
227-
throw new Error('you must provide some inputs');
233+
let msg = `'dss' should receive signed inputs as requested in 'dsi' and accepted in 'dsf', but got 0 inputs`;
234+
throw new Error(msg);
228235
}
229236

230237
let txInputsHex = DashTx.serializeInputs(inputs);
@@ -238,6 +245,12 @@ var DashJoin = ('object' === typeof module && exports) || {};
238245
return bytes;
239246
};
240247

248+
/////////////////////
249+
// //
250+
// Parsers //
251+
// //
252+
/////////////////////
253+
241254
/**
242255
* @param {Uint8Array} bytes
243256
*/
@@ -256,25 +269,16 @@ var DashJoin = ('object' === typeof module && exports) || {};
256269
//@ts-ignore - correctness of denomination must be checked higher up
257270
let denomination = STANDARD_DENOMINATIONS_MAP[denomination_id];
258271

259-
/**
260-
* Grab the protxhash
261-
*/
262272
let protxhash_bytes = bytes.subarray(offset, offset + Sizes.PROTX);
263273
offset += Sizes.PROTX;
264274

265-
/**
266-
* Grab the time
267-
*/
268275
let timestamp64n = dv.getBigInt64(offset, DV_LITTLE_ENDIAN);
269276
offset += Sizes.TIME;
270277
let timestamp_unix = Number(timestamp64n);
271278
let timestampMs = timestamp_unix * 1000;
272279
let timestampDate = new Date(timestampMs);
273280
let timestamp = timestampDate.toISOString();
274281

275-
/**
276-
* Grab the fReady
277-
*/
278282
let ready = bytes[offset] > 0x00;
279283
offset += Sizes.READY;
280284

@@ -295,8 +299,114 @@ var DashJoin = ('object' === typeof module && exports) || {};
295299
return dsqMessage;
296300
};
297301

298-
// Utils.hexToBytes = DashTx.utils.hexToBytes;
299-
// Utils.bytesToHex = DashTx.utils.bytesToHex;
302+
Parsers._DSSU_MESSAGE_IDS = {
303+
0x00: 'ERR_ALREADY_HAVE',
304+
0x01: 'ERR_DENOM',
305+
0x02: 'ERR_ENTRIES_FULL',
306+
0x03: 'ERR_EXISTING_TX',
307+
0x04: 'ERR_FEES',
308+
0x05: 'ERR_INVALID_COLLATERAL',
309+
0x06: 'ERR_INVALID_INPUT',
310+
0x07: 'ERR_INVALID_SCRIPT',
311+
0x08: 'ERR_INVALID_TX',
312+
0x09: 'ERR_MAXIMUM',
313+
0x0a: 'ERR_MN_LIST', // <--
314+
0x0b: 'ERR_MODE',
315+
0x0c: 'ERR_NON_STANDARD_PUBKEY', // (Not used)
316+
0x0d: 'ERR_NOT_A_MN', //(Not used)
317+
0x0e: 'ERR_QUEUE_FULL',
318+
0x0f: 'ERR_RECENT',
319+
0x10: 'ERR_SESSION',
320+
0x11: 'ERR_MISSING_TX',
321+
0x12: 'ERR_VERSION',
322+
0x13: 'MSG_NOERR',
323+
0x14: 'MSG_SUCCESS',
324+
0x15: 'MSG_ENTRIES_ADDED',
325+
0x16: 'ERR_SIZE_MISMATCH',
326+
};
327+
328+
Parsers._DSSU_STATES = {
329+
0x00: 'IDLE',
330+
0x01: 'QUEUE',
331+
0x02: 'ACCEPTING_ENTRIES',
332+
0x03: 'SIGNING',
333+
0x04: 'ERROR',
334+
0x05: 'SUCCESS',
335+
};
336+
337+
Parsers._DSSU_STATUSES = {
338+
0x00: 'REJECTED',
339+
0x01: 'ACCEPTED',
340+
};
341+
342+
// TODO DSSU type
343+
/**
344+
* 4 nMsgSessionID - Required - Session ID
345+
* 4 nMsgState - Required - Current state of processing
346+
* 4 nMsgEntriesCount - Required - Number of entries in the pool (deprecated)
347+
* 4 nMsgStatusUpdate - Required - Update state and/or signal if entry was accepted or not
348+
* 4 nMsgMessageID - Required - ID of the typical masternode reply message
349+
*/
350+
351+
/**
352+
* @param {Uint8Array} bytes
353+
*/
354+
Parsers.dssu = function (bytes) {
355+
const STATE_SIZE = 4;
356+
const STATUS_UPDATE_SIZE = 4;
357+
358+
if (bytes.length !== Sizes.DSSU) {
359+
let msg = `developer error: a 'dssu' message is 16 bytes, but got ${bytes.length}`;
360+
throw new Error(msg);
361+
}
362+
let dv = new DataView(bytes.buffer);
363+
let offset = 0;
364+
365+
let session_id = dv.getUint32(offset, DV_LITTLE_ENDIAN);
366+
offset += Sizes.SESSION_ID;
367+
368+
let state_id = dv.getUint32(offset, DV_LITTLE_ENDIAN);
369+
offset += STATE_SIZE;
370+
371+
let status_id = dv.getUint32(offset, DV_LITTLE_ENDIAN);
372+
offset += STATUS_UPDATE_SIZE;
373+
374+
let message_id = dv.getUint32(offset, DV_LITTLE_ENDIAN);
375+
376+
let dssuMessage = {
377+
session_id: session_id,
378+
state_id: state_id,
379+
state: Parsers._DSSU_STATES[state_id],
380+
status_id: status_id,
381+
status: Parsers._DSSU_STATUSES[status_id],
382+
message_id: message_id,
383+
message: Parsers._DSSU_MESSAGE_IDS[message_id],
384+
};
385+
return dssuMessage;
386+
};
387+
388+
/**
389+
* @param {Uint8Array} bytes
390+
*/
391+
Parsers.dsf = function (bytes) {
392+
let offset = 0;
393+
let sessionId = bytes.subarray(offset, Sizes.SESSION_ID);
394+
let session_id = DashTx.utils.bytesToHex(sessionId);
395+
offset += Sizes.SESSION_ID;
396+
397+
let transactionUnsigned = bytes.subarray(offset);
398+
let transaction_unsigned = DashTx.utils.bytesToHex(transactionUnsigned);
399+
400+
let txRequest = DashTx.parseUnknown(transaction_unsigned);
401+
let dsfTxRequest = {
402+
session_id: session_id,
403+
version: txRequest.version,
404+
inputs: txRequest.inputs,
405+
outputs: txRequest.outputs,
406+
locktime: txRequest.locktime,
407+
};
408+
return dsfTxRequest;
409+
};
300410

301411
Utils._evonodeMapToList = function (evonodesMap) {
302412
console.log('[debug] get evonode list...');

public/index.html

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@
6060
margin: 0;
6161
padding: 0;
6262
}
63-
fieldset label {
63+
fieldset label,
64+
fieldset button {
6465
display: inline-block;
6566
}
6667
</style>
@@ -474,9 +475,14 @@ <h1>Digital Cash Wallet</h1>
474475
</tr>
475476
</tbody>
476477
</table>
477-
<button type="button" onclick="App.denominateCoins(event)">
478-
Denominate Coins
479-
</button>
478+
<fieldset>
479+
<button type="button" onclick="App.denominateCoins(event)">
480+
Denominate Coins
481+
</button>
482+
<button type="button" onclick="App.createCoinJoinSession(event)">
483+
Run CoinJoin
484+
</button>
485+
</fieldset>
480486
</form>
481487
</section>
482488
<br />

0 commit comments

Comments
 (0)