Added documentation for p2p usage
This commit is contained in:
parent
c72d5e01ae
commit
5d236c63fb
31
README.md
31
README.md
@ -46,15 +46,15 @@ Features
|
||||
|
||||
|
||||
Under development:
|
||||
* ✗ *Keccak* (CopperLark [CLR])
|
||||
* ✗ *Max* (Maxcoin [MAX], HelixCoin [HXC])
|
||||
* ✗ *Keccak* (Maxcoin [MAX], HelixCoin, CryptoMeth, eCoin, CopperLark)
|
||||
* ✗ *Skein* (Skeincoin [SKC])
|
||||
* ✗ *Bcrypt* (Taojingcoin [TJC])
|
||||
* ✗ *Groestl* (MyriadCoin [MYR]
|
||||
* ✗ *Qubit* (QubitCoin [Q2C], MyriadCoin [MYR])
|
||||
* ✗ *Hefty1* (Heavycoin [HVC])
|
||||
* ✗ *Blake* (Blakecoin [BLC])
|
||||
* ✗ *Fugue* (Fuguecoin [FC])
|
||||
* ✗ *SHAvite-3* (INKcoin [INK])
|
||||
|
||||
* ✗ *Bcrypt* (Taojingcoin [TJC])
|
||||
|
||||
#### Under development
|
||||
|
||||
@ -223,23 +223,29 @@ var pool = Stratum.createPool({
|
||||
],
|
||||
|
||||
|
||||
/* This allows the pool to connect to the daemon as a node peer to recieve block updates.
|
||||
/* This allows the pool to connect to the daemon as a node peer to receive block updates.
|
||||
It may be the most efficient way to get block updates (faster than polling, less
|
||||
intensive than blocknotify script). However its still under development (not yet working). */
|
||||
intensive than blocknotify script). It requires additional setup: the 'magic' field must
|
||||
be exact (extracted from the coin source code). */
|
||||
"p2p": {
|
||||
"enabled": false,
|
||||
|
||||
/* Host for daemon */
|
||||
"host": "127.0.0.1",
|
||||
|
||||
/* Port configured for daemon (this is the actual peer port not RPC port) */
|
||||
"port": 19333,
|
||||
|
||||
/* If your coin daemon is new enough (i.e. not a shitcoin) then it will support a p2p feature
|
||||
that prevents the daemon from spamming our peer node with unnecessary transaction data.
|
||||
Assume its supported but if you have problems try disabling it. */
|
||||
"disableTransactions": true,
|
||||
|
||||
/* Magic value is different for main/testnet and for each coin. It is found in the daemon
|
||||
source code as the pchMessageStart variable.
|
||||
For example, litecoin mainnet magic: http://git.io/Bi8YFw
|
||||
And for litecoin testnet magic: http://git.io/NXBYJA
|
||||
*/
|
||||
"magic": "fcc1b7dc",
|
||||
|
||||
//Found in src as the PROTOCOL_VERSION variable, for example: http://git.io/KjuCrw
|
||||
"protocolVersion": 70002,
|
||||
And for litecoin testnet magic: http://git.io/NXBYJA */
|
||||
"magic": "fcc1b7dc"
|
||||
}
|
||||
|
||||
}, function(ip, workerName, password, callback){ //stratum authorization function
|
||||
@ -311,6 +317,7 @@ pool.start();
|
||||
Credits
|
||||
-------
|
||||
* [vekexasia](https://github.com/vekexasia) - co-developer & great tester
|
||||
* [LucasJones(//github.com/LucasJones) - getting p2p block notify script working
|
||||
* [TheSeven](https://github.com/TheSeven) - answering an absurd amount of my questions, found the block 1-16 problem, provided example code for peer node functionality
|
||||
* [pronooob](https://dogehouse.org) - knowledgeable & helpful
|
||||
* [Slush0](https://github.com/slush0/stratum-mining) - stratum protocol, documentation and original python code
|
||||
|
||||
32
lib/peer.js
32
lib/peer.js
@ -46,9 +46,10 @@ var Peer = module.exports = function (options) {
|
||||
|
||||
var _this = this;
|
||||
var client;
|
||||
var magic = new Buffer(options.magic, 'hex');
|
||||
var magic = new Buffer(options.p2p.magic, 'hex');
|
||||
var magicInt = magic.readUInt32LE(0);
|
||||
var verack = false;
|
||||
var validConnectionConfig = true;
|
||||
|
||||
//https://en.bitcoin.it/wiki/Protocol_specification#Inventory_Vectors
|
||||
var invCodes = {
|
||||
@ -64,7 +65,7 @@ var Peer = module.exports = function (options) {
|
||||
|
||||
//If protocol version is new enough, add do not relay transactions flag byte, outlined in BIP37
|
||||
//https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki#extensions-to-existing-messages
|
||||
var relayTransactions = options.protocolVersion >= 70001 ? new Buffer([false]) : new Buffer([]);
|
||||
var relayTransactions = options.p2p.disableTransactions === true ? new Buffer([false]) : new Buffer([]);
|
||||
|
||||
var commands = {
|
||||
version: commandStringBuffer('version'),
|
||||
@ -83,19 +84,28 @@ var Peer = module.exports = function (options) {
|
||||
function Connect() {
|
||||
|
||||
client = net.connect({
|
||||
host: options.host,
|
||||
port: options.port
|
||||
host: options.p2p.host,
|
||||
port: options.p2p.port
|
||||
}, function () {
|
||||
_this.emit('connected');
|
||||
SendVersion();
|
||||
});
|
||||
client.on('end', function () {
|
||||
_this.emit('disconnected');
|
||||
verack = false;
|
||||
Connect();
|
||||
client.on('close', function () {
|
||||
if (verack) {
|
||||
_this.emit('disconnected');
|
||||
verack = false;
|
||||
Connect();
|
||||
}
|
||||
else if (validConnectionConfig)
|
||||
_this.emit('connectionRejected');
|
||||
|
||||
});
|
||||
client.on('error', function (e) {
|
||||
_this.emit('connectionFailed', e);
|
||||
if (e.code === 'ECONNREFUSED') {
|
||||
validConnectionConfig = false;
|
||||
_this.emit('connectionFailed');
|
||||
}
|
||||
else
|
||||
_this.emit('socketError', e);
|
||||
});
|
||||
|
||||
|
||||
@ -175,7 +185,7 @@ var Peer = module.exports = function (options) {
|
||||
case commands.verack.toString():
|
||||
if(!verack) {
|
||||
verack = true;
|
||||
_this.emit('verack');
|
||||
_this.emit('connected');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
35
lib/pool.js
35
lib/pool.js
@ -195,17 +195,21 @@ var pool = module.exports = function pool(options, authorizeFn){
|
||||
function SetupPeer(){
|
||||
if (!options.p2p || !options.p2p.enabled)
|
||||
return;
|
||||
_this.peer = new peer(options.p2p);
|
||||
_this.peer.on('connected', function(){
|
||||
emitLog('connected to daemon as a peer node');
|
||||
_this.peer = new peer(options);
|
||||
_this.peer.on('connected', function() {
|
||||
emitLog('p2p connection successful');
|
||||
}).on('connectionRejected', function(){
|
||||
emitErrorLog('p2p connection failed - likely incorrect p2p magic value');
|
||||
}).on('disconnected', function(){
|
||||
emitWarningLog('peer node disconnected - attempting reconnection...');
|
||||
}).on('connectionFailed', function(){
|
||||
emitErrorLog('failed to connect to daemon as a peer node');
|
||||
emitWarningLog('p2p peer node disconnected - attempting reconnection...');
|
||||
}).on('connectionFailed', function(e){
|
||||
emitErrorLog('p2p connection failed - likely incorrect host or port');
|
||||
}).on('socketError', function(e){
|
||||
emitErrorLog('p2p had a socket error ' + JSON.stringify(e));
|
||||
}).on('error', function(msg){
|
||||
emitWarningLog(msg);
|
||||
emitWarningLog('p2p had an error ' + msg);
|
||||
}).on('blockFound', function(hash){
|
||||
_this.processBlockNotify(hash);
|
||||
_this.processBlockNotify(hash, 'p2p');
|
||||
});
|
||||
}
|
||||
|
||||
@ -334,7 +338,6 @@ var pool = module.exports = function pool(options, authorizeFn){
|
||||
|
||||
//TODO: Convert this all into a batch RPC call for better performance
|
||||
|
||||
|
||||
async.waterfall([
|
||||
|
||||
function(callback){
|
||||
@ -457,6 +460,7 @@ var pool = module.exports = function pool(options, authorizeFn){
|
||||
})[0].response;
|
||||
|
||||
options.testnet = infoResult.testnet;
|
||||
options.protocolVersion = infoResult.protocolversion;
|
||||
|
||||
options.initStats = { connections: infoResult.connections, difficulty: infoResult.difficulty };
|
||||
|
||||
@ -626,7 +630,10 @@ var pool = module.exports = function pool(options, authorizeFn){
|
||||
var pollingInterval = options.blockRefreshInterval;
|
||||
|
||||
blockPollingIntervalId = setInterval(function () {
|
||||
GetBlockTemplate(function(error, result){});
|
||||
GetBlockTemplate(function(error, result, foundNewBlock){
|
||||
if (foundNewBlock)
|
||||
emitLog('Block notification via RPC polling');
|
||||
});
|
||||
}, pollingInterval);
|
||||
}
|
||||
|
||||
@ -651,7 +658,7 @@ var pool = module.exports = function pool(options, authorizeFn){
|
||||
}
|
||||
|
||||
|
||||
callback(null, result.response);
|
||||
callback(null, result.response, processedNewBlock);
|
||||
callback = function(){};
|
||||
}
|
||||
}, true
|
||||
@ -682,13 +689,12 @@ var pool = module.exports = function pool(options, authorizeFn){
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This method is being called from the blockNotify so that when a new block is discovered by the daemon
|
||||
* We can inform our miners about the newly found block
|
||||
**/
|
||||
this.processBlockNotify = function(blockHash) {
|
||||
|
||||
this.processBlockNotify = function(blockHash, sourceTrigger) {
|
||||
emitLog('Block notification via ' + sourceTrigger);
|
||||
if (typeof(_this.jobManager.currentJob) !== 'undefined' && blockHash !== _this.jobManager.currentJob.rpcData.previousblockhash){
|
||||
GetBlockTemplate(function(error, result){
|
||||
if (error)
|
||||
@ -698,7 +704,6 @@ var pool = module.exports = function pool(options, authorizeFn){
|
||||
};
|
||||
|
||||
|
||||
|
||||
this.relinquishMiners = function(filterFn, resultCback) {
|
||||
var origStratumClients = this.stratumServer.getStratumClients();
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user