<commit_before>"use strict";

const u = require("./UtilFunctions.js"),
	ChordSignalChannel = require("./ChordSignalChannel.js"),
	BootstrapChannelClient = require("./BootstrapChannelClient.js"),
	BootstrapChannelServer = require("./BootstrapChannelServer.js"),
	ModuleRegistry = require("./ModuleRegistry.js"),
	RemoteCallModule = require("./RemoteCallModule.js"),
	Node = require("./Node.js"),
	RemoteNode = require("./RemoteNode.js"),
	ID = require("./ID.js"),
	sha3 = require("js-sha3"),
	pki = require("node-forge").pki,
	Conductor = require("webrtc-conductor");


class ConductorChord {
	static get defaultConfig(){
		return {
			idWidth: 224,

			keyWidth: 2048,

			serverConfig: {
				port: 7171
			},

			conductorConfig: {
				channel: null
			},

			isServer: false,

			allowUpgrade: true,

			allowDowngrade: false,

			debug: false
		}
	};

	constructor(config){
		this.config = u.mergeConfig(ConductorChord.defaultConfig, config);
		u.log(this, "Config merged.");
		u.log(this, this.config);

		//Generate a public-private key combination, and store the public key in PEM format.
		u.log(this, "Generating RSA keys...");
		this.key = pki.rsa.generateKeyPair({bits: this.config.keyWidth, e: 0x10001});
		this.pubKeyPem = pki.publicKeyToRSAPublicKeyPem(this.key.publicKey);
		u.log(this, "Generated.");

		//Generate an ID on the network from this public key.
		u.log(this, "Generating ID from public key.");
		let idBuf = sha3["sha3_"+this.config.idWidth].buffer(this.pubKeyPem);
		this.id = new ID(idBuf);
		u.log(this, "ID created:");
		u.log(this, this.id.idString);

		//Set up a Node object to represent the local state.
		u.log(this, "Creating local node.");
		this.node = new Node(this);
		u.log(this, "Created.");

		//Store the K,V pair <ID, pubKey> on the local view of the DHT.
		//This will be relocated once an actual network is joined.
		u.log(this, "Adding public key to local store.");
		this.addItem(this.id.idString, this.pubKeyPem);
		u.log(this, "Added.");

		//Create a module registry, register the RPC default module.
		this.registry = new ModuleRegistry();
		this.rcm = new RemoteCallModule(this);

		//Prepare the standard connection channel and an instance of Conductor:
		//(SignalChannel registers itself to the module registry)
		u.log(this, "Creating standard channel and conductor.");
		this.config.conductorConfig.channel = new ChordSignalChannel(this);
		this.conductor = Conductor.create(this.config.conductorConfig);
		u.log(this, "Channel and conductor created? "+this.conductor!=null);

		//Set onconnection event to handle connections made to us.
		this.conductor.onconnection = conn => {
			conn.ondatachannel = dChan => {
				dChan.onmessage = msg => {
					// console.log(a);
					// dChan.send(a.data);
					let parsy = JSON.parse(msg.data);
					this.message(parsy.id, parsy.data)
				};
				this.directNodes[conn.id] = new RemoteNode(this, new ID(conn.id), conn)
			}
		};

		//If this node is actually a server, load a background channel which will mediate requests to join the network.
		if(this.config.isServer){
			u.log(this, "Initialising server backing channel.");
			this.conductor.register(new BootstrapChannelServer(this));
			setInterval(this.node.stabilize.bind(this.node), 1000);
			setInterval(this.node.fixFingers.bind(this.node), 666);
		}

		//space to store, well, external nodes - if you're a server, for instance.
		//This is also used for resource management and ring bypass.
		this.directNodes = {};
		this.server = {
			connect: false,
			node: null,
			address: null
		};

		if(this.config.debug)
			window.chorddebug = this;
	}

	smartConnectToNode(id, optNode) {
		if (Object.getOwnPropertyNames(this.directNodes).length === 0) {
			return this.join(this.server.address)
				.then( () => {
					return this.nodeOverRing(id, optNode);
				} );
		} else if (this.directNodes[ID.coerceString(id)]) {
			return Promise.resolve(this.directNodes[ID.coerceString(id)]);<commit_msg>Made global scope debug node-compliant<commit_after>"use strict";

const u = require("./UtilFunctions.js"),
	ChordSignalChannel = require("./ChordSignalChannel.js"),
	BootstrapChannelClient = require("./BootstrapChannelClient.js"),
	BootstrapChannelServer = require("./BootstrapChannelServer.js"),
	ModuleRegistry = require("./ModuleRegistry.js"),
	RemoteCallModule = require("./RemoteCallModule.js"),
	Node = require("./Node.js"),
	RemoteNode = require("./RemoteNode.js"),
	ID = require("./ID.js"),
	sha3 = require("js-sha3"),
	pki = require("node-forge").pki,
	Conductor = require("webrtc-conductor");


class ConductorChord {
	static get defaultConfig(){
		return {
			idWidth: 224,

			keyWidth: 2048,

			serverConfig: {
				port: 7171
			},

			conductorConfig: {
				channel: null
			},

			isServer: false,

			allowUpgrade: true,

			allowDowngrade: false,

			debug: false
		}
	};

	constructor(config){
		this.config = u.mergeConfig(ConductorChord.defaultConfig, config);
		u.log(this, "Config merged.");
		u.log(this, this.config);

		//Generate a public-private key combination, and store the public key in PEM format.
		u.log(this, "Generating RSA keys...");
		this.key = pki.rsa.generateKeyPair({bits: this.config.keyWidth, e: 0x10001});
		this.pubKeyPem = pki.publicKeyToRSAPublicKeyPem(this.key.publicKey);
		u.log(this, "Generated.");

		//Generate an ID on the network from this public key.
		u.log(this, "Generating ID from public key.");
		let idBuf = sha3["sha3_"+this.config.idWidth].buffer(this.pubKeyPem);
		this.id = new ID(idBuf);
		u.log(this, "ID created:");
		u.log(this, this.id.idString);

		//Set up a Node object to represent the local state.
		u.log(this, "Creating local node.");
		this.node = new Node(this);
		u.log(this, "Created.");

		//Store the K,V pair <ID, pubKey> on the local view of the DHT.
		//This will be relocated once an actual network is joined.
		u.log(this, "Adding public key to local store.");
		this.addItem(this.id.idString, this.pubKeyPem);
		u.log(this, "Added.");

		//Create a module registry, register the RPC default module.
		this.registry = new ModuleRegistry();
		this.rcm = new RemoteCallModule(this);

		//Prepare the standard connection channel and an instance of Conductor:
		//(SignalChannel registers itself to the module registry)
		u.log(this, "Creating standard channel and conductor.");
		this.config.conductorConfig.channel = new ChordSignalChannel(this);
		this.conductor = Conductor.create(this.config.conductorConfig);
		u.log(this, "Channel and conductor created? "+this.conductor!=null);

		//Set onconnection event to handle connections made to us.
		this.conductor.onconnection = conn => {
			conn.ondatachannel = dChan => {
				dChan.onmessage = msg => {
					// console.log(a);
					// dChan.send(a.data);
					let parsy = JSON.parse(msg.data);
					this.message(parsy.id, parsy.data)
				};
				this.directNodes[conn.id] = new RemoteNode(this, new ID(conn.id), conn)
			}
		};

		//If this node is actually a server, load a background channel which will mediate requests to join the network.
		if(this.config.isServer){
			u.log(this, "Initialising server backing channel.");
			this.conductor.register(new BootstrapChannelServer(this));
			setInterval(this.node.stabilize.bind(this.node), 1000);
			setInterval(this.node.fixFingers.bind(this.node), 666);
		}

		//space to store, well, external nodes - if you're a server, for instance.
		//This is also used for resource management and ring bypass.
		this.directNodes = {};
		this.server = {
			connect: false,
			node: null,
			address: null
		};

		if(this.config.debug) {
			if(window)
				window.chorddebug = this;
			else
				global.chorddebug = this;
		}
	}

	smartConnectToNode(id, optNode) {
		if (Object.getOwnPropertyNames(this.directNodes).length === 0) {
			return this.join(this.server.address)
				.then( () => {
					return this.nodeOverRing(id, optNode);
				} );
		} else if (this.directNodes[ID.coerceString(id)]) {
			return Promise.resolve(this.directNodes[ID.coerceString(id)]);
{'fraction_non_alphanumeric': 0.14125, 'fraction_numerical': 0.00725, 'mean_word_length': 3.8169777242624923, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '50709', 'n_tokens_mistral': 2996, 'n_tokens_neox': 2558, 'n_words': 653}