From 7a1bd45a6ae4db752f3e4d39e1f57584abbec453 Mon Sep 17 00:00:00 2001 From: Vincent Durham Date: Sat, 1 Oct 2011 01:34:22 -0400 Subject: [PATCH 1/4] Add -R and getaux to merged-mine-proxy --- contrib/merged-mine-proxy | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/contrib/merged-mine-proxy b/contrib/merged-mine-proxy index d3d8dd82ac73..4ab5bf458e26 100755 --- a/contrib/merged-mine-proxy +++ b/contrib/merged-mine-proxy @@ -20,7 +20,7 @@ from twisted.internet.error import ConnectionRefusedError import twisted.internet.error from urlparse import urlsplit -__version__ = '0.2' +__version__ = '0.2.1' ''' merge-mine-proxy @@ -222,8 +222,10 @@ class Listener(Server): self.merkle_tree_queue = [] self.merkle_trees = {} self.rewrite_target = None - if rewrite_target: + if rewrite_target == 1: self.rewrite_target = reverse_chunks("00000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffe", 2) + elif rewrite_target == 100: + self.rewrite_target = reverse_chunks("00000000028f5c28000000000000000000000000000000000000000000000000", 2) if merkle_size > 255: raise ValueError('merkle size up to 255') self.putChild('', self) @@ -280,8 +282,36 @@ class Listener(Server): reactor.callLater(AUX_UPDATE_INTERVAL, self.update_aux_process) self.update_auxs() + def rpc_getaux(self, data=None): + ''' Use this rpc call to get the aux chain merkle root and aux target. Pool software + can then call getworkaux(aux) instead of going through this proxy. It is enough to call this + once a second. + ''' + try: + # Get aux based on the latest tree + merkle_root = self.merkle_tree_queue[-1] + # nonce = 0, one byte merkle size + aux = merkle_root + ("%02x000000" % self.merkle_size) + "00000000" + result = {'aux': aux} + + if self.rewrite_target: + result['aux_target'] = self.rewrite_target + else: + # Find highest target + targets = [] + targets.extend(self.aux_targets) + targets.sort() + result['aux_target'] = reverse_chunks(targets[-1], 2) # fix endian + return result + except Exception: + logger.error(traceback.format_exc()) + raise + @defer.inlineCallbacks def rpc_getwork(self, data=None): + ''' This rpc call generates bitcoin miner compatible work from data received + from the aux and parent chains. + ''' try: if data: # Submit work upstream @@ -400,7 +430,10 @@ def run(): dest='merkle_size') parser.add_argument('-r', '--rewrite-target', help='rewrite target difficulty to 1', - action='store_true', default=False, + action='store_const', const=1, default=False, + dest='rewrite_target') + parser.add_argument('-R', '--rewrite-target-100', help='rewrite target difficulty to 100', + action='store_const', const=100, default=False, dest='rewrite_target') parser.add_argument('-i', '--pidfile', metavar='PID', type=str, action='store', default=None, dest='pidfile') From ffcbfdc1bc3444bdf653f0b5ca7b92c53e24425a Mon Sep 17 00:00:00 2001 From: Vincent Durham Date: Sun, 2 Oct 2011 03:28:13 -0400 Subject: [PATCH 2/4] Use httplib in merged-mine-proxy for keepalive --- contrib/merged-mine-proxy | 62 ++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/contrib/merged-mine-proxy b/contrib/merged-mine-proxy index 4ab5bf458e26..4c382152fa17 100755 --- a/contrib/merged-mine-proxy +++ b/contrib/merged-mine-proxy @@ -12,15 +12,19 @@ import sys import traceback import json import base64 +import socket + from datetime import datetime -from twisted.internet import defer, reactor -from twisted.web import server, resource, client +from twisted.internet import defer, reactor, threads +from twisted.web import server, resource from twisted.internet.error import ConnectionRefusedError import twisted.internet.error from urlparse import urlsplit +import httplib +import thread -__version__ = '0.2.1' +__version__ = '0.2.2' ''' merge-mine-proxy @@ -50,6 +54,10 @@ logger.setLevel(logging.DEBUG) def reverse_chunks(s, l): return ''.join(reversed([s[x:x+l] for x in xrange(0, len(s), l)])) +def getresponse(http, path, postdata, headers): + http.request(path, 'POST', postdata, headers) + return http.getresponse().read() + class Error(Exception): def __init__(self, code, message, data=''): if not isinstance(code, int): @@ -72,12 +80,24 @@ class Proxy(object): auth = None if netloc.find('@') >= 0: (auth, netloc) = netloc.split("@") - self._url = "%s://%s/%s" % (schema, netloc, path) + if path == "": + path = "/" + self._url = "%s://%s%s" % (schema, netloc, path) + self._path = path self._auth = auth + self._netloc = netloc + self._http = None - @defer.inlineCallbacks def callRemote(self, method, *params): try: + if self._http is None: + (host, port) = self._netloc.split(":") + self._http = httplib.HTTPConnection(host, port) + try: + self._http.connect() + except socket.error: + raise httplib.HTTPException() + id_ = 0 headers = { @@ -86,29 +106,25 @@ class Proxy(object): if self._auth is not None: headers['Authorization'] = 'Basic ' + base64.b64encode(self._auth) resp = None - try: - resp = (yield client.getPage( - url=self._url, - method='POST', - headers=headers, - postdata=json.dumps({ - 'jsonrpc': '2.0', - 'method': method, - 'params': params, - 'id': id_, - }), - )) - except twisted.web.error.Error, e: - resp = e.response - - resp = json.loads(resp) + + postdata=json.dumps({ + 'jsonrpc': '2.0', + 'method': method, + 'params': params, + 'id': id_, + }) + + content = getresponse(self._http, self._path, postdata, headers) + + resp = json.loads(content) if resp['id'] != id_: raise ValueError('invalid id') if 'error' in resp and resp['error'] is not None: raise Error(resp['error']['code'], resp['error']['message']) - defer.returnValue(resp['result']) - except ConnectionRefusedError: + return resp['result'] + except httplib.HTTPException: + self._http = None logger.error("Could not connect to %s", self._url) raise Error(-32099, u'Could not connect to backend', self._url) From ddca550f5a94350ce60d40a88fde28d892fdc60e Mon Sep 17 00:00:00 2001 From: Vincent Durham Date: Sun, 16 Oct 2011 20:26:10 -0400 Subject: [PATCH 3/4] Fix hole in aux POW validation --- src/auxpow.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/auxpow.cpp b/src/auxpow.cpp index 2131b0c7ccb4..620504f05c14 100644 --- a/src/auxpow.cpp +++ b/src/auxpow.cpp @@ -20,6 +20,9 @@ void RemoveMergedMiningHeader(vector& vchAux) bool CAuxPow::Check(uint256 hashAuxBlock, int nChainID) { + if (nIndex != 0) + return error("AuxPow is not a generate"); + if (!fTestNet && parentBlock.GetChainID() == nChainID) return error("Aux POW parent has our chain ID"); From d2cd985c0b7af3fbc897c40cf41315145f3d449d Mon Sep 17 00:00:00 2001 From: Vincent Durham Date: Sun, 16 Oct 2011 20:27:47 -0400 Subject: [PATCH 4/4] Advance version --- src/serialize.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/serialize.h b/src/serialize.h index dcf6f548371c..d26ac771e810 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -33,7 +33,7 @@ class CDataStream; class CAutoFile; static const unsigned int MAX_SIZE = 0x02000000; -static const int VERSION = 32463; +static const int VERSION = 32464; static const char* pszSubVer = ""; static const bool VERSION_IS_BETA = true;