Added documentation for p2p usage

This commit is contained in:
Matt 2014-04-16 11:50:58 -06:00
parent c72d5e01ae
commit 5d236c63fb
3 changed files with 60 additions and 38 deletions

View File

@ -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

View File

@ -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:

View File

@ -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();