X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fbitcoinrpc.cpp;h=60c5449080955cd272d893dfc8e76d3d15bbcd8d;hb=09f2a990950512cbe418526d91838887a0dded2a;hp=ecd35ac5ea42a751a9dae5388fc964a2b25368a6;hpb=c9d655232500a0b4e085fb6a9cc0ba1966db027a;p=novacoin.git diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index ecd35ac..60c5449 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -216,10 +216,11 @@ double GetDifficulty() if (pindexBest == NULL) return 1.0; - int nShift = (pindexBest->nBits >> 24) & 0xff; + const CBlockIndex* pindexLastProofOfWork = GetLastBlockIndex(pindexBest, false); + int nShift = (pindexLastProofOfWork->nBits >> 24) & 0xff; double dDiff = - (double)0x0000ffff / (double)(pindexBest->nBits & 0x00ffffff); + (double)0x0000ffff / (double)(pindexLastProofOfWork->nBits & 0x00ffffff); while (nShift < 29) { @@ -306,8 +307,9 @@ Value getinfo(const Array& params, bool fHelp) "Returns an object containing various state info."); Object obj; - obj.push_back(Pair("version", (int)VERSION)); + obj.push_back(Pair("version", FormatFullVersion())); obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance()))); + obj.push_back(Pair("newmint", ValueFromAmount(pwalletMain->GetNewMint()))); obj.push_back(Pair("stake", ValueFromAmount(pwalletMain->GetStake()))); obj.push_back(Pair("blocks", (int)nBestHeight)); obj.push_back(Pair("connections", (int)vNodes.size())); @@ -1655,14 +1657,14 @@ Value getwork(const Array& params, bool fHelp) nStart = GetTime(); // Create new block - pblock = CreateNewBlock(pwalletMain); + pblock = CreateNewBlock(pwalletMain, true); if (!pblock) throw JSONRPCError(-7, "Out of memory"); vNewBlock.push_back(pblock); } // Update nTime - pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); + pblock->nTime = max(pblock->GetBlockTime(), GetAdjustedTime()); pblock->nNonce = 0; // Update nExtraNonce @@ -1708,6 +1710,8 @@ Value getwork(const Array& params, bool fHelp) pblock->nNonce = pdata->nNonce; pblock->vtx[0].vin[0].scriptSig = mapNewBlock[pdata->hashMerkleRoot].second; pblock->hashMerkleRoot = pblock->BuildMerkleTree(); + if (!pblock->SignBlock(*pwalletMain)) + throw JSONRPCError(-100, "Unable to sign block"); return CheckWork(pblock, *pwalletMain, reservekey); } @@ -1801,47 +1805,22 @@ Value getmemorypool(const Array& params, bool fHelp) } -// ppcoin: reset auto checkpoint -Value resetcheckpoint(const Array& params, bool fHelp) -{ - if (fHelp || params.size() < 1 || params.size() > 1) - throw runtime_error( - "resetcheckpoint \n" - "Reset automatic checkpoint to specified height.\n" - " is the height of the new checkpoint block.\n"); - - int nCheckpoint = params[0].get_int(); - if (nCheckpoint <= 0 || nCheckpoint >= nBestHeight) - throw runtime_error( - "invalid checkpoint height.\n" - ); - if (nCheckpoint >= Checkpoints::nAutoCheckpoint) - throw runtime_error( - "new checkpoint must be earlier than current auto checkpoint.\n" - ); - if (!Checkpoints::ResetAutoCheckpoint(nCheckpoint)) - throw runtime_error( - "internal error - reset checkpoint failed.\n" - ); - - return Value::null; -} - - -// ppcoin: get branch point of alternative branch -Value getbranchpoint(const Array& params, bool fHelp) +// ppcoin: get information of sync-checkpoint +Value getcheckpoint(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( - "getbranchpoint\n" - "Returns height of branch point of alternative branch.\n"); + "getcheckpoint\n" + "Show info of synchronized checkpoint.\n"); Object result; - if (Checkpoints::nBranchPoint > 0) - result.push_back(Pair("branchpoint", Checkpoints::nBranchPoint)); - else - result.push_back(Pair("branchpoint", "none")); - result.push_back(Pair("checkpoint", Checkpoints::nAutoCheckpoint)); + CBlockIndex* pindexCheckpoint; + + result.push_back(Pair("synccheckpoint", Checkpoints::hashSyncCheckpoint.ToString().c_str())); + pindexCheckpoint = mapBlockIndex[Checkpoints::hashSyncCheckpoint]; + result.push_back(Pair("height", pindexCheckpoint->nHeight)); + result.push_back(Pair("timestamp", DateTimeStrFormat("%x %H:%M:%S", pindexCheckpoint->GetBlockTime()).c_str())); + return result; } @@ -1930,9 +1909,146 @@ Value repairwallet(const Array& params, bool fHelp) return result; } +// ppcoin: make a public-private key pair +Value makekeypair(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 1) + throw runtime_error( + "makekeypair [prefix]\n" + "Make a public/private key pair.\n" + "[prefix] is optional preferred prefix for the public key.\n"); + + string strPrefix = ""; + if (params.size() > 0) + strPrefix = params[0].get_str(); + + CKey key; + do + { + key.MakeNewKey(); + } while (strPrefix != HexStr(key.GetPubKey()).substr(0, strPrefix.size())); + + CPrivKey vchPrivKey = key.GetPrivKey(); + Object result; + result.push_back(Pair("PrivateKey", HexStr(vchPrivKey.begin(), vchPrivKey.end()))); + result.push_back(Pair("PublicKey", HexStr(key.GetPubKey()))); + return result; +} + +extern CCriticalSection cs_mapAlerts; +extern map mapAlerts; + +// ppcoin: send alert. +// There is a known deadlock situation with ThreadMessageHandler +// ThreadMessageHandler: holds cs_vSend and acquiring cs_main in SendMessages() +// ThreadRPCServer: holds cs_main and acquiring cs_vSend in alert.RelayTo()/PushMessage()/BeginMessage() +Value sendalert(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 5) + throw runtime_error( + "sendalert [cancelupto]\n" + " is the alert text message\n" + " is hex string of alert master private key\n" + " is the minimum applicable client version\n" + " is the maximum applicable client version\n" + " is the alert id\n" + "[cancelupto] cancels all alert id's up to this number\n" + "Returns true or false."); + + CAlert alert; + CKey key; + + alert.strStatusBar = params[0].get_str(); + alert.nMinVer = params[2].get_int(); + alert.nMaxVer = params[3].get_int(); + alert.nID = params[4].get_int(); + if (params.size() > 5) + alert.nCancel = params[5].get_int(); + alert.nVersion = VERSION; + alert.nRelayUntil = GetAdjustedTime() + 365*24*60*60; + alert.nExpiration = GetAdjustedTime() + 365*24*60*60; + alert.nPriority = 1; + + CDataStream sMsg; + sMsg << (CUnsignedAlert)alert; + alert.vchMsg = vector(sMsg.begin(), sMsg.end()); + + vector vchPrivKey = ParseHex(params[1].get_str()); + key.SetPrivKey(CPrivKey(vchPrivKey.begin(), vchPrivKey.end())); // if key is not correct openssl may crash + if (!key.Sign(Hash(alert.vchMsg.begin(), alert.vchMsg.end()), alert.vchSig)) + throw runtime_error( + "Unable to sign alert, check private key?\n"); + if(!alert.ProcessAlert()) + throw runtime_error( + "Failed to process alert.\n"); + // Relay alert + CRITICAL_BLOCK(cs_vNodes) + BOOST_FOREACH(CNode* pnode, vNodes) + alert.RelayTo(pnode); + + Object result; + result.push_back(Pair("strStatusBar", alert.strStatusBar)); + result.push_back(Pair("nVersion", alert.nVersion)); + result.push_back(Pair("nMinVer", alert.nMinVer)); + result.push_back(Pair("nMaxVer", alert.nMaxVer)); + result.push_back(Pair("nID", alert.nID)); + if (alert.nCancel > 0) + result.push_back(Pair("nCancel", alert.nCancel)); + return result; +} + +// ppcoin: send checkpoint +Value sendcheckpoint(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 2 || params.size() < 1 ) + throw runtime_error( + "sendcheckpoint [checkpointhash]\n" + " is hex string of checkpoint master private key\n" + " is the hash of checkpoint block\n"); + CSyncCheckpoint checkpoint; + CKey key; + // TODO: omit checkpointhash parameter + if (params.size() > 1) + { + checkpoint.hashCheckpoint = uint256(params[1].get_str()); + if (!mapBlockIndex.count(checkpoint.hashCheckpoint)) + throw runtime_error( + "Provided checkpoint block is not on main chain\n"); + } + else + { + checkpoint.hashCheckpoint = Checkpoints::AutoSelectSyncCheckpoint(); + if (checkpoint.hashCheckpoint == Checkpoints::hashSyncCheckpoint) + throw runtime_error( + "Unable to select a more recent sync-checkpoint"); + } + + CDataStream sMsg; + sMsg << (CUnsignedSyncCheckpoint)checkpoint; + checkpoint.vchMsg = vector(sMsg.begin(), sMsg.end()); + vector vchPrivKey = ParseHex(params[0].get_str()); + key.SetPrivKey(CPrivKey(vchPrivKey.begin(), vchPrivKey.end())); // if key is not correct openssl may crash + if (!key.Sign(Hash(checkpoint.vchMsg.begin(), checkpoint.vchMsg.end()), checkpoint.vchSig)) + throw runtime_error( + "Unable to sign checkpoint, check private key?\n"); + + if(!checkpoint.ProcessSyncCheckpoint(NULL)) + throw runtime_error( + "Failed to process checkpoint.\n"); + // Relay checkpoint + CRITICAL_BLOCK(cs_vNodes) + BOOST_FOREACH(CNode* pnode, vNodes) + checkpoint.RelayTo(pnode); + + Object result; + result.push_back(Pair("checkpoint", Checkpoints::hashSyncCheckpoint.ToString().c_str())); + result.push_back(Pair("height", mapBlockIndex[Checkpoints::hashSyncCheckpoint]->nHeight)); + result.push_back(Pair("timestamp", DateTimeStrFormat("%x %H:%M:%S", mapBlockIndex[Checkpoints::hashSyncCheckpoint]->GetBlockTime()).c_str())); + return result; +} // @@ -1981,11 +2097,13 @@ pair pCallTable[] = make_pair("settxfee", &settxfee), make_pair("getmemorypool", &getmemorypool), make_pair("listsinceblock", &listsinceblock), - make_pair("resetcheckpoint", &resetcheckpoint), - make_pair("getbranchpoint", &getbranchpoint), + make_pair("getcheckpoint", &getcheckpoint), make_pair("reservebalance", &reservebalance), make_pair("checkwallet", &checkwallet), make_pair("repairwallet", &repairwallet), + make_pair("makekeypair", &makekeypair), + make_pair("sendalert", &sendalert), + make_pair("sendcheckpoint", &sendcheckpoint), }; map mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0])); @@ -2012,8 +2130,7 @@ string pAllowInSafeMode[] = "validateaddress", "getwork", "getmemorypool", - "resetcheckpoint", - "getbranchpoint", + "getcheckpoint", }; set setAllowInSafeMode(pAllowInSafeMode, pAllowInSafeMode + sizeof(pAllowInSafeMode)/sizeof(pAllowInSafeMode[0])); @@ -2612,6 +2729,10 @@ int CommandLineRPC(int argc, char *argv[]) if (strMethod == "walletpassphrase" && n > 1) ConvertTo(params[1]); if (strMethod == "walletpassphrase" && n > 2) ConvertTo(params[2]); if (strMethod == "listsinceblock" && n > 1) ConvertTo(params[1]); + if (strMethod == "sendalert" && n > 2) ConvertTo(params[2]); + if (strMethod == "sendalert" && n > 3) ConvertTo(params[3]); + if (strMethod == "sendalert" && n > 4) ConvertTo(params[4]); + if (strMethod == "sendalert" && n > 5) ConvertTo(params[5]); if (strMethod == "sendmany" && n > 1) { string s = params[1].get_str(); @@ -2621,7 +2742,6 @@ int CommandLineRPC(int argc, char *argv[]) params[1] = v.get_obj(); } if (strMethod == "sendmany" && n > 2) ConvertTo(params[2]); - if (strMethod == "resetcheckpoint" && n > 0) ConvertTo(params[0]); if (strMethod == "reservebalance" && n > 0) ConvertTo(params[0]); if (strMethod == "reservebalance" && n > 1) ConvertTo(params[1]);