Skip to content

Commit

Permalink
feat: ping, pong, senddsq, and various options
Browse files Browse the repository at this point in the history
  • Loading branch information
coolaj86 committed Aug 15, 2024
1 parent 7904138 commit e54d3f8
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 28 deletions.
54 changes: 47 additions & 7 deletions public/dashjoin.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ var DashJoin = ('object' === typeof module && exports) || {};
(function (window, DashJoin) {
'use strict';

// let DashTx = window.DashTx || require('dashtx');
let DashP2P = window.DashP2P || require('dashp2p');

const DENOM_LOWEST = 100001;
const PREDENOM_MIN = DENOM_LOWEST + 193;
const COLLATERAL = 10000; // DENOM_LOWEST / 10
const PAYLOAD_SIZE_MAX = 4 * 1024 * 1024;

const DSQ_SIZE = 1; // 1-byte bool

// https://github.com/dashpay/dash/blob/v19.x/src/coinjoin/coinjoin.h#L39
// const COINJOIN_ENTRY_MAX_SIZE = 9; // real
// const COINJOIN_ENTRY_MAX_SIZE = 2; // just for testing right now
Expand All @@ -27,6 +29,10 @@ var DashJoin = ('object' === typeof module && exports) || {};
let reverseDenoms = DashJoin.DENOMS.slice(0);
reverseDenoms.reverse();

let Packers = {};
let Parsers = {};
let Utils = {};

// Ask Niles if there's an layman-ish obvious way to do this
DashJoin.getDenom = function (sats) {
for (let denom of reverseDenoms) {
Expand All @@ -39,9 +45,39 @@ var DashJoin = ('object' === typeof module && exports) || {};
return 0;
};

DashJoin.utils = {};
/**
* Turns on or off DSQ messages (necessary for CoinJoin, but off by default)
* @param {Object} opts
* @param {NetworkName} opts.network - "mainnet", "testnet", etc
* @param {Uint8Array?} [opts.message]
* @param {Boolean?} [opts.send]
*/
Packers.senddsq = function ({ network, message = null, send = true }) {
// const command = 'senddsq';
// if (!message) {
// let dsqSize = DashP2P.sizes.HEADER_SIZE + DSQ_SIZE;
// message = new Uint8Array(dsqSize);
// }

let payload = new Uint8Array(1);
if (send) {
payload.set([0x01], 0);
} else {
payload.set([0x00], 0);
}

DashJoin.utils.hexToBytes = function (hex) {
// let payload = message.subarray(DashP2P.sizes.HEADER_SIZE);
// payload.set(sendByte, 0);
// void DashP2P.packers.message({ network, command, bytes: message });
// return {
// message,
// payload,
// };

return payload;
};

Utils.hexToBytes = function (hex) {
let bufLen = hex.length / 2;
let u8 = new Uint8Array(bufLen);

Expand All @@ -64,7 +100,7 @@ var DashJoin = ('object' === typeof module && exports) || {};
return u8;
};

DashJoin.utils.bytesToHex = function (u8) {
Utils.bytesToHex = function (u8) {
/** @type {Array<String>} */
let hex = [];

Expand All @@ -76,7 +112,7 @@ var DashJoin = ('object' === typeof module && exports) || {};
return hex.join('');
};

DashJoin.utils._evonodeMapToList = function (evonodesMap) {
Utils._evonodeMapToList = function (evonodesMap) {
console.log('[debug] get evonode list...');
let evonodes = [];
{
Expand Down Expand Up @@ -104,7 +140,7 @@ var DashJoin = ('object' === typeof module && exports) || {};
}

// void shuffle(evonodes);
evonodes.sort(DashJoin.utils.sortMnListById);
evonodes.sort(Utils.sortMnListById);
return evonodes;
};

Expand All @@ -114,7 +150,7 @@ var DashJoin = ('object' === typeof module && exports) || {};
* @param {Object} b
* @param {String} b.id
*/
DashJoin.utils.sortMnListById = function (a, b) {
Utils.sortMnListById = function (a, b) {
if (a.id > b.id) {
return 1;
}
Expand All @@ -124,6 +160,10 @@ var DashJoin = ('object' === typeof module && exports) || {};
return 0;
};

DashJoin.packers = Packers;
DashJoin.parsers = Parsers;
DashJoin.utils = Utils;

//@ts-ignore
window.DashJoin = DashJoin;
})(globalThis.window || {}, DashJoin);
Expand Down
42 changes: 39 additions & 3 deletions public/dashp2p.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,9 @@ var DashP2P = ('object' === typeof module && exports) || {};
p2p.header = Parsers.header(chunk);
} catch (e) {
p2p.state = 'error';
p2p.error = new Error('header parse error');
p2p.error = new Error(`header parse error: ${e.message}`);
console.error(e);
console.error(chunk);
return;
}

Expand Down Expand Up @@ -209,8 +211,7 @@ var DashP2P = ('object' === typeof module && exports) || {};
SIZES.PAYLOAD_SIZE + // 4
SIZES.CHECKSUM; // 4
Sizes.HEADER_SIZE = TOTAL_HEADER_SIZE; // 24

Parsers.PING_SIZE = SIZES.NONCE;
Sizes.PING_SIZE = SIZES.NONCE; // same as pong

Packers.PROTOCOL_VERSION = 70227;
Packers.NETWORKS = {};
Expand Down Expand Up @@ -372,6 +373,41 @@ var DashP2P = ('object' === typeof module && exports) || {};
return message;
};

Packers.verack = function ({ network }) {
let verackBytes = Packers.message({
network: network,
command: 'verack',
payload: null,
});
return verackBytes;
};

/**
* In this case the only bytes are the nonce
* Use a .subarray(offset) to define an offset.
* (a manual offset will not work consistently, and .byteOffset is context-sensitive)
* @param {Object} opts
* @param {NetworkName} opts.network - "mainnet", "testnet", etc
* @param {Uint8Array?} [opts.message]
* @param {Uint8Array} opts.nonce
*/
Packers.pong = function ({ network, message = null, nonce }) {
// const command = 'pong';

if (!message) {
let pongSize = Sizes.HEADER_SIZE + Sizes.PING_SIZE;
message = new Uint8Array(pongSize);
}

let payload = message.subarray(Sizes.HEADER_SIZE);
payload.set(nonce, 0);

// void CJPacker.packMessage({ network, command, bytes: message });
// return message;

return payload;
};

/**
* First 4 bytes of SHA256(SHA256(payload)) in internal byte order.
* @param {Uint8Array} payload
Expand Down
85 changes: 67 additions & 18 deletions public/wallet-app.js
Original file line number Diff line number Diff line change
Expand Up @@ -1056,28 +1056,77 @@
});
wsc.addEventListener('open', async function () {
// p2p.initWebSocket(wsc);
{
let payload = DashP2P.packers.version({
addr_recv_ip: App._evonode.hostname,
addr_recv_port: App._evonode.port,
start_height: App._chaininfo.blocks,
});
let command = 'version';
let versionBytes = DashP2P.packers.message({
network,
command,
payload,
});
wsc.send(versionBytes);
}

let payload = DashP2P.packers.version({
addr_recv_ip: App._evonode.hostname,
addr_recv_port: App._evonode.port,
start_height: App._chaininfo.blocks,
});
let command = 'version';
let messageBytes = DashP2P.packers.message({ network, command, payload });
wsc.send(messageBytes);
{
let verackBytes = DashP2P.packers.verack({ network: network });
console.log('wsc.send(verackBytes)');
wsc.send(verackBytes);
}
});

// initialize connection
// {
// let versionReq = DashP2P.packers.version({
// addr_recv_ip: App._evonode.hostname,
// addr_recv_port: App._evonode.port,
// start_height: App._chaininfo.blocks,
// });
// wsc.send(versionReq);
// void (await p2p.accept(['version']));
// }
// {
// }
// let msg = await p2p.accept(['verack']);
// for (;;) {
// let msg = await p2p.accept(['ping', 'inv']);
// if (msg.header.command === 'ping') {
// let pongBytes = DashP2P.packers.pong({
// network: network,
// nonce: msg.payload,
// });
// wsc.send(pongBytes);
// }
// }

for (;;) {
let msg = await p2p.accept([
'*',
'inv',
'ping',
'pong',
'version',
'verack',
]);
console.log('p2p.accept():');
console.log(msg);
let subs = ['*', 'inv', 'ping', 'pong', 'version', 'verack'];
let msg = await p2p.accept(subs);
let command = msg.header.command;
console.log('p2p.accept():', command);
let isSub = subs.includes(command);
if (isSub) {
console.log(msg);
}

// if (command === 'verack') {
// let verackBytes = DashP2P.packers.verack({ network: network });
// console.log('wsc.send(verackBytes)');
// wsc.send(verackBytes);
// } else
if (command === 'ping') {
let pongBytes = DashP2P.packers.pong({
network: network,
nonce: msg.payload,
});
console.log('wsc.send(pongBytes)');
wsc.send(pongBytes);
} else if (command === 'inv') {
console.log('(ignore inv)');
}
}
}

Expand Down

0 comments on commit e54d3f8

Please sign in to comment.