Advertisement
Guest User

coinbaser as a whole

a guest
Oct 11th, 2011
259
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 9.44 KB | None | 0 0
  1. diff --git a/src/init.cpp b/src/init.cpp
  2. index dbc2c41..6bd3004 100644
  3. --- a/src/init.cpp
  4. +++ b/src/init.cpp
  5. @@ -199,6 +199,7 @@ bool AppInit2(int argc, char* argv[])
  6.              "  -rpcport=<port>  \t\t  " + _("Listen for JSON-RPC connections on <port> (default: 8332)\n") +
  7.              "  -rpcallowip=<ip> \t\t  " + _("Allow JSON-RPC connections from specified IP address\n") +
  8.              "  -rpcconnect=<ip> \t  "   + _("Send commands to node running on <ip> (default: 127.0.0.1)\n") +
  9. +            "  -coinbaser=<cmd> \t  "   + _("Execute <cmd> to calculate coinbase payees\n") +
  10.              "  -keypool=<n>     \t  "   + _("Set key pool size to <n> (default: 100)\n") +
  11.              "  -rescan          \t  "   + _("Rescan the block chain for missing wallet transactions\n");
  12.  
  13. diff --git a/src/main.cpp b/src/main.cpp
  14. index 6a3bacc..126a7d1 100644
  15. --- a/src/main.cpp
  16. +++ b/src/main.cpp
  17. @@ -7,6 +7,12 @@
  18.  #include "net.h"
  19.  #include "init.h"
  20.  #include "cryptopp/sha.h"
  21. +
  22. +#ifdef __WXMSW__
  23. +#include <fcntl.h>
  24. +#endif
  25. +#include <limits.h>
  26. +
  27.  #include <boost/filesystem.hpp>
  28.  #include <boost/filesystem/fstream.hpp>
  29.  
  30. @@ -2652,6 +2658,125 @@ public:
  31.  };
  32.  
  33.  
  34. +int DoCoinbaser_I(CBlock* pblock, uint64 nTotal, FILE* file)
  35. +{
  36. +    int nCount;
  37. +    if (fscanf(file, "%d\n", &nCount) != 1)
  38. +    {
  39. +        printf("DoCoinbaser(): failed to fscanf count\n");
  40. +        return -2;
  41. +    }
  42. +    pblock->vtx[0].vout.resize(nCount + 1);
  43. +    uint64 nDistributed = 0;
  44. +    for (int i = 1; i <= nCount; ++i)
  45. +    {
  46. +        uint64 nValue;
  47. +        if (fscanf(file, "%" PRI64u "\n", &nValue) != 1)
  48. +        {
  49. +            printf("DoCoinbaser(): failed to fscanf amount for transaction #%d\n", i);
  50. +            return -(0x1000 | i);
  51. +        }
  52. +        pblock->vtx[0].vout[i].nValue = nValue;
  53. +        nDistributed += nValue;
  54. +        char strAddr[35];
  55. +        if (fscanf(file, "%34s\n", strAddr) != 1)
  56. +        {
  57. +            printf("DoCoinbaser(): failed to fscanf address for transaction #%d\n", i);
  58. +            return -(0x2000 | i);
  59. +        }
  60. +        CBitcoinAddress address;
  61. +        if (!address.SetString(strAddr))
  62. +        {
  63. +            printf("DoCoinbaser(): invalid bitcoin address for transaction #%d\n", i);
  64. +            return -(0x3000 | i);
  65. +        }
  66. +        pblock->vtx[0].vout[i].scriptPubKey.SetBitcoinAddress(address);
  67. +    }
  68. +    if (nTotal < nDistributed)
  69. +    {
  70. +        printf("DoCoinbaser(): attempt to distribute %" PRI64u "/%" PRI64u "\n", nDistributed, nTotal);
  71. +        return -3;
  72. +    }
  73. +    uint64 nMine = nTotal - nDistributed;
  74. +    printf("DoCoinbaser(): total distributed: %" PRI64u "/%" PRI64u " = %" PRI64u " for me\n", nDistributed, nTotal, nMine);
  75. +    pblock->vtx[0].vout[0].nValue = nMine;
  76. +    return 0;
  77. +}
  78. +
  79. +int DoCoinbaser(CBlock* pblock, uint64 nTotal)
  80. +{
  81. +    string strCmd = mapArgs["-coinbaser"];
  82. +    FILE* file = NULL;
  83. +    if (!strCmd.compare(0, 4, "tcp:"))
  84. +    {
  85. +        CAddress addrCoinbaser(strCmd.substr(4), true, 0);
  86. +        SOCKET hSocket;
  87. +        if (!ConnectSocket(addrCoinbaser, hSocket))
  88. +        {
  89. +            perror("DoCoinbaser(): failed to connect");
  90. +            return -3;
  91. +        }
  92. +#ifdef __WXMSW__
  93. +        int nSocket = _open_osfhandle((intptr_t)hSocket, _O_RDONLY | _O_TEXT);
  94. +        if (-1 == nSocket)
  95. +        {
  96. +            printf("DoCoinbaser(): failed to _open_osfhandle\n");
  97. +            return -4;
  98. +        }
  99. +        file = fdopen(nSocket, "r");
  100. +#else
  101. +        file = fdopen(hSocket, "r");
  102. +#endif
  103. +        if (file)
  104. +            fprintf(file, "total: %" PRI64u "\n\n", nTotal);
  105. +    }
  106. +    else
  107. +    {
  108. +
  109. +    try
  110. +    {
  111. +        char strTotal[11];
  112. +        int nTotalLen = snprintf(strTotal, 11, "%" PRI64u, nTotal);
  113. +        if (nTotalLen < 1 || nTotalLen > 10)
  114. +        {
  115. +            strTotal[0] = '\0';
  116. +            nTotalLen = 0;
  117. +        }
  118. +        string::size_type nPos;
  119. +        while ((nPos = strCmd.find("%d")) != string::npos)
  120. +        {
  121. +            strCmd.replace(nPos, 2, strTotal, nTotalLen);
  122. +        }
  123. +    }
  124. +    catch (...)
  125. +    {
  126. +        return 1;
  127. +    }
  128. +    file = popen(strCmd.c_str(), "r");
  129. +
  130. +    }
  131. +
  132. +    if (!file)
  133. +    {
  134. +        printf("DoCoinbaser(): failed to popen: %s", strerror(errno));
  135. +        return -1;
  136. +    }
  137. +
  138. +    int rv;
  139. +    try
  140. +    {
  141. +        rv = DoCoinbaser_I(pblock, nTotal, file);
  142. +    }
  143. +    catch (...)
  144. +    {
  145. +        rv = 1;
  146. +    }
  147. +    pclose(file);
  148. +    if (rv)
  149. +        pblock->vtx[0].vout.resize(1);
  150. +    return rv;
  151. +}
  152. +
  153.  CBlock* CreateNewBlock(CReserveKey& reservekey)
  154.  {
  155.      CBlockIndex* pindexPrev = pindexBest;
  156. @@ -2787,7 +2912,10 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
  157.              }
  158.          }
  159.      }
  160. -    pblock->vtx[0].vout[0].nValue = GetBlockValue(pindexPrev->nHeight+1, nFees);
  161. +    int64 nBlkValue = GetBlockValue(pindexPrev->nHeight+1, nFees);
  162. +    pblock->vtx[0].vout[0].nValue = nBlkValue;
  163. +    if (mapArgs.count("-coinbaser"))
  164. +        DoCoinbaser(&*pblock, nBlkValue);
  165.  
  166.      // Fill in header
  167.      pblock->hashPrevBlock  = pindexPrev->GetBlockHash();
  168. @@ -2796,21 +2924,58 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
  169.      pblock->nBits          = GetNextWorkRequired(pindexPrev);
  170.      pblock->nNonce         = 0;
  171.  
  172. +    pblock->print();
  173.      return pblock.release();
  174.  }
  175.  
  176.  
  177. +std::map<std::string, CScript> mapAuxCoinbases;
  178. +
  179. +CScript BuildCoinbaseScriptSig(uint64 nTime, unsigned int nExtraNonce, bool *pfOverflow)
  180. +{
  181. +    CScript scriptSig = CScript() << nTime << CBigNum(nExtraNonce);
  182. +
  183. +    map<std::string, CScript>::iterator it;
  184. +    for (it = mapAuxCoinbases.begin() ; it != mapAuxCoinbases.end(); ++it)
  185. +        scriptSig += (*it).second;
  186. +
  187. +    if (scriptSig.size() > 100)
  188. +    {
  189. +        scriptSig.resize(100);
  190. +        if (pfOverflow)
  191. +            *pfOverflow = true;
  192. +    }
  193. +    else
  194. +        if (pfOverflow)
  195. +            *pfOverflow = false;
  196. +
  197. +    return scriptSig;
  198. +}
  199. +
  200.  void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce)
  201.  {
  202.      // Update nExtraNonce
  203. -    static uint256 hashPrevBlock;
  204. -    if (hashPrevBlock != pblock->hashPrevBlock)
  205. +    static uint64 nPrevTime = 0;
  206. +    static bool fBackward = false;
  207. +    uint64 nNow = GetTime();
  208. +    if (nNow > nPrevTime + 1)
  209.      {
  210.          nExtraNonce = 0;
  211. -        hashPrevBlock = pblock->hashPrevBlock;
  212. +        nPrevTime = nNow;
  213. +        fBackward = false;
  214. +    }
  215. +    else
  216. +    {
  217. +        if (nNow < nPrevTime && !fBackward)
  218. +        {
  219. +            printf("IncrementExtraNonce: WARNING: nNow moved backward: %d -> %d\n", nPrevTime, nNow);
  220. +            fBackward = true;
  221. +        }
  222. +        if (nExtraNonce == UINT_MAX)
  223. +            printf("IncrementExtraNonce: WARNING: nExtraNonce overflowing!\n");
  224. +        ++nExtraNonce;
  225.      }
  226. -    ++nExtraNonce;
  227. -    pblock->vtx[0].vin[0].scriptSig = CScript() << pblock->nTime << CBigNum(nExtraNonce);
  228. +    pblock->vtx[0].vin[0].scriptSig = BuildCoinbaseScriptSig(nNow, nExtraNonce);
  229.      pblock->hashMerkleRoot = pblock->BuildMerkleTree();
  230.  }
  231.  
  232. diff --git a/src/main.h b/src/main.h
  233. index c400145..791c52a 100644
  234. --- a/src/main.h
  235. +++ b/src/main.h
  236. @@ -94,6 +94,8 @@ bool ProcessMessages(CNode* pfrom);
  237.  bool SendMessages(CNode* pto, bool fSendTrickle);
  238.  void GenerateBitcoins(bool fGenerate, CWallet* pwallet);
  239.  CBlock* CreateNewBlock(CReserveKey& reservekey);
  240. +extern std::map<std::string, CScript> mapAuxCoinbases;
  241. +CScript BuildCoinbaseScriptSig(uint64 nTime, unsigned int nExtraNonce, bool *pfOverflow = NULL);
  242.  void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
  243.  void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1);
  244.  bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey);
  245. diff --git a/src/rpc.cpp b/src/rpc.cpp
  246. index 885ffd1..2bc63bf 100644
  247. --- a/src/rpc.cpp
  248. +++ b/src/rpc.cpp
  249. @@ -1480,6 +1480,35 @@ Value validateaddress(const Array& params, bool fHelp)
  250.  }
  251.  
  252.  
  253. +Value setworkaux(const Array& params, bool fHelp)
  254. +{
  255. +    if (fHelp || params.size() < 1 || params.size() > 2)
  256. +        throw runtime_error(
  257. +            "setworkaux <id> [data]\n"
  258. +            "If [data] is not specified, deletes aux.\n"
  259. +        );
  260. +
  261. +    std::string strId = params[0].get_str();
  262. +    if (params.size() > 1)
  263. +    {
  264. +        std::string strData = params[1].get_str();
  265. +        std::vector<unsigned char> vchData = ParseHex(strData);
  266. +        if (vchData.size() * 2 != strData.size())
  267. +            throw JSONRPCError(-8, "Failed to parse data as hexadecimal");
  268. +        CScript scriptBackup = mapAuxCoinbases[strId];
  269. +        mapAuxCoinbases[strId] = CScript(vchData);
  270. +        bool fOverflow;
  271. +        BuildCoinbaseScriptSig(0, UINT_MAX, &fOverflow);
  272. +        if (fOverflow)
  273. +            throw JSONRPCError(-7, "Change would overflow coinbase script");
  274. +    }
  275. +    else
  276. +        mapAuxCoinbases.erase(strId);
  277. +
  278. +    return true;
  279. +}
  280. +
  281. +
  282.  Value getwork(const Array& params, bool fHelp)
  283.  {
  284.      if (fHelp || params.size() > 1)
  285. @@ -1640,6 +1669,7 @@ pair<string, rpcfn_type> pCallTable[] =
  286.      make_pair("sendmany",               &sendmany),
  287.      make_pair("gettransaction",         &gettransaction),
  288.      make_pair("listtransactions",       &listtransactions),
  289. +    make_pair("setworkaux",             &setworkaux),
  290.      make_pair("getwork",                &getwork),
  291.      make_pair("listaccounts",           &listaccounts),
  292.      make_pair("settxfee",               &settxfee),
  293.  
  294.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement