bool WriteSyncCheckpoint(const uint256& hashCheckpoint) { if (!pblocktree->WriteSyncCheckpoint(hashCheckpoint)) { return error("WriteSyncCheckpoint(): failed to write to txdb sync checkpoint %s", hashCheckpoint.ToString().c_str()); } if (!pblocktree->Sync()) return error("WriteSyncCheckpoint(): failed to commit to txdb sync checkpoint %s", hashCheckpoint.ToString().c_str()); hashSyncCheckpoint = hashCheckpoint; return true; }
UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit( MergeToAddressJSInfo& info, std::vector<boost::optional<SproutWitness>> witnesses, uint256 anchor) { if (anchor.IsNull()) { throw std::runtime_error("anchor is null"); } if (witnesses.size() != info.notes.size()) { throw runtime_error("number of notes and witnesses do not match"); } if (info.notes.size() != info.zkeys.size()) { throw runtime_error("number of notes and spending keys do not match"); } for (size_t i = 0; i < witnesses.size(); i++) { if (!witnesses[i]) { throw runtime_error("joinsplit input could not be found in tree"); } info.vjsin.push_back(JSInput(*witnesses[i], info.notes[i], info.zkeys[i])); } // Make sure there are two inputs and two outputs while (info.vjsin.size() < ZC_NUM_JS_INPUTS) { info.vjsin.push_back(JSInput()); } while (info.vjsout.size() < ZC_NUM_JS_OUTPUTS) { info.vjsout.push_back(JSOutput()); } if (info.vjsout.size() != ZC_NUM_JS_INPUTS || info.vjsin.size() != ZC_NUM_JS_OUTPUTS) { throw runtime_error("unsupported joinsplit input/output counts"); } CMutableTransaction mtx(tx_); LogPrint("zrpcunsafe", "%s: creating joinsplit at index %d (vpub_old=%s, vpub_new=%s, in[0]=%s, in[1]=%s, out[0]=%s, out[1]=%s)\n", getId(), tx_.vjoinsplit.size(), FormatMoney(info.vpub_old), FormatMoney(info.vpub_new), FormatMoney(info.vjsin[0].note.value()), FormatMoney(info.vjsin[1].note.value()), FormatMoney(info.vjsout[0].value), FormatMoney(info.vjsout[1].value)); // Generate the proof, this can take over a minute. std::array<libzcash::JSInput, ZC_NUM_JS_INPUTS> inputs{info.vjsin[0], info.vjsin[1]}; std::array<libzcash::JSOutput, ZC_NUM_JS_OUTPUTS> outputs{info.vjsout[0], info.vjsout[1]}; std::array<size_t, ZC_NUM_JS_INPUTS> inputMap; std::array<size_t, ZC_NUM_JS_OUTPUTS> outputMap; uint256 esk; // payment disclosure - secret JSDescription jsdesc = JSDescription::Randomized( mtx.fOverwintered && (mtx.nVersion >= SAPLING_TX_VERSION), *pzcashParams, joinSplitPubKey_, anchor, inputs, outputs, inputMap, outputMap, info.vpub_old, info.vpub_new, !this->testmode, &esk); // parameter expects pointer to esk, so pass in address { auto verifier = libzcash::ProofVerifier::Strict(); if (!(jsdesc.Verify(*pzcashParams, verifier, joinSplitPubKey_))) { throw std::runtime_error("error verifying joinsplit"); } } mtx.vjoinsplit.push_back(jsdesc); // Empty output script. CScript scriptCode; CTransaction signTx(mtx); uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId_); // Add the signature if (!(crypto_sign_detached(&mtx.joinSplitSig[0], NULL, dataToBeSigned.begin(), 32, joinSplitPrivKey_) == 0)) { throw std::runtime_error("crypto_sign_detached failed"); } // Sanity check if (!(crypto_sign_verify_detached(&mtx.joinSplitSig[0], dataToBeSigned.begin(), 32, mtx.joinSplitPubKey.begin()) == 0)) { throw std::runtime_error("crypto_sign_verify_detached failed"); } CTransaction rawTx(mtx); tx_ = rawTx; CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss << rawTx; std::string encryptedNote1; std::string encryptedNote2; { CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION); ss2 << ((unsigned char)0x00); ss2 << jsdesc.ephemeralKey; ss2 << jsdesc.ciphertexts[0]; ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_); encryptedNote1 = HexStr(ss2.begin(), ss2.end()); } { CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION); ss2 << ((unsigned char)0x01); ss2 << jsdesc.ephemeralKey; ss2 << jsdesc.ciphertexts[1]; ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_); encryptedNote2 = HexStr(ss2.begin(), ss2.end()); } UniValue arrInputMap(UniValue::VARR); UniValue arrOutputMap(UniValue::VARR); for (size_t i = 0; i < ZC_NUM_JS_INPUTS; i++) { arrInputMap.push_back(static_cast<uint64_t>(inputMap[i])); } for (size_t i = 0; i < ZC_NUM_JS_OUTPUTS; i++) { arrOutputMap.push_back(static_cast<uint64_t>(outputMap[i])); } // !!! Payment disclosure START unsigned char buffer[32] = {0}; memcpy(&buffer[0], &joinSplitPrivKey_[0], 32); // private key in first half of 64 byte buffer std::vector<unsigned char> vch(&buffer[0], &buffer[0] + 32); uint256 joinSplitPrivKey = uint256(vch); size_t js_index = tx_.vjoinsplit.size() - 1; uint256 placeholder; for (int i = 0; i < ZC_NUM_JS_OUTPUTS; i++) { uint8_t mapped_index = outputMap[i]; // placeholder for txid will be filled in later when tx has been finalized and signed. PaymentDisclosureKey pdKey = {placeholder, js_index, mapped_index}; JSOutput output = outputs[mapped_index]; libzcash::SproutPaymentAddress zaddr = output.addr; // randomized output PaymentDisclosureInfo pdInfo = {PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL, esk, joinSplitPrivKey, zaddr}; paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo)); LogPrint("paymentdisclosure", "%s: Payment Disclosure: js=%d, n=%d, zaddr=%s\n", getId(), js_index, int(mapped_index), EncodePaymentAddress(zaddr)); } // !!! Payment disclosure END UniValue obj(UniValue::VOBJ); obj.push_back(Pair("encryptednote1", encryptedNote1)); obj.push_back(Pair("encryptednote2", encryptedNote2)); obj.push_back(Pair("rawtxn", HexStr(ss.begin(), ss.end()))); obj.push_back(Pair("inputmap", arrInputMap)); obj.push_back(Pair("outputmap", arrOutputMap)); return obj; }
UniValue name_pending (const UniValue& params, bool fHelp) { if (fHelp || params.size () > 1) throw std::runtime_error ( "name_pending (\"name\")\n" "\nList unconfirmed name operations in the mempool.\n" "\nIf a name is given, only check for operations on this name.\n" "\nArguments:\n" "1. \"name\" (string, optional) only look for this name\n" "\nResult:\n" "[\n" " {\n" " \"op\": xxxx (string) the operation being performed\n" " \"name\": xxxx (string) the name operated on\n" " \"value\": xxxx (string) the name's new value\n" " \"txid\": xxxx (string) the txid corresponding to the operation\n" " \"ismine\": xxxx (boolean) whether the name is owned by the wallet\n" " },\n" " ...\n" "]\n" + HelpExampleCli ("name_pending", "") + HelpExampleCli ("name_pending", "\"d/domob\"") + HelpExampleRpc ("name_pending", "") ); #ifdef ENABLE_WALLET LOCK2 (pwalletMain ? &pwalletMain->cs_wallet : NULL, mempool.cs); #else LOCK (mempool.cs); #endif std::vector<uint256> txHashes; if (params.size () == 0) mempool.queryHashes (txHashes); else { const std::string name = params[0].get_str (); const valtype vchName = ValtypeFromString (name); const uint256 txid = mempool.getTxForName (vchName); if (!txid.IsNull ()) txHashes.push_back (txid); } UniValue arr(UniValue::VARR); for (std::vector<uint256>::const_iterator i = txHashes.begin (); i != txHashes.end (); ++i) { CTransaction tx; if (!mempool.lookup (*i, tx) || !tx.IsNamecoin ()) continue; for (unsigned i = 0; i < tx.vout.size (); ++i) { const CNameScript op(tx.vout[i].scriptPubKey); if (!op.isNameOp () || !op.isAnyUpdate ()) continue; const valtype vchName = op.getOpName (); const valtype vchValue = op.getOpValue (); const std::string name = ValtypeToString (vchName); const std::string value = ValtypeToString (vchValue); std::string strOp; switch (op.getNameOp ()) { case OP_NAME_FIRSTUPDATE: strOp = "name_firstupdate"; break; case OP_NAME_UPDATE: strOp = "name_update"; break; default: assert (false); } UniValue obj(UniValue::VOBJ); obj.push_back (Pair ("op", strOp)); obj.push_back (Pair ("name", name)); obj.push_back (Pair ("value", value)); obj.push_back (Pair ("txid", tx.GetHash ().GetHex ())); #ifdef ENABLE_WALLET isminetype mine = ISMINE_NO; if (pwalletMain) mine = IsMine (*pwalletMain, op.getAddress ()); const bool isMine = (mine & ISMINE_SPENDABLE); obj.push_back (Pair ("ismine", isMine)); #endif arr.push_back (obj); } } return arr; }
static void json_line_uint256(FILE *f, int indent, const char *key, const uint256 &value) { do_indent(f, indent); fprintf(f, "%s: \"%s\",\n", key, value.to_string().raw()); }
bool WriteSyncCheckpoint(const uint256& hashCheckpoint) { CTxDB txdb; txdb.TxnBegin(); if (!txdb.WriteSyncCheckpoint(hashCheckpoint)) { txdb.TxnAbort(); return error("WriteSyncCheckpoint(): failed to write to db sync checkpoint %s", hashCheckpoint.ToString()); } if (!txdb.TxnCommit()) return error("WriteSyncCheckpoint(): failed to commit to db sync checkpoint %s", hashCheckpoint.ToString()); Checkpoints::hashSyncCheckpoint = hashCheckpoint; return true; }
~prevector_tester() { BOOST_CHECK_MESSAGE(passed, "insecure_rand: " + rand_seed.ToString()); }
void RippleAddress::setAccountPrivate (uint256 hash256) { mIsValid = true; SetData (VER_ACCOUNT_PRIVATE, hash256.begin (), 32); }
void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) { entry.push_back(Pair("txid", tx.GetHash().GetHex())); entry.push_back(Pair("version", tx.nVersion)); entry.push_back(Pair("time", (boost::int64_t)tx.nTime)); entry.push_back(Pair("locktime", (boost::int64_t)tx.nLockTime)); if (tx.nVersion >= 2) { entry.push_back(Pair("tx-comment", tx.strTxComment)); } Array vin; BOOST_FOREACH(const CTxIn& txin, tx.vin) { Object in; if (tx.IsCoinBase()) in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); else { in.push_back(Pair("txid", txin.prevout.hash.GetHex())); in.push_back(Pair("vout", (boost::int64_t)txin.prevout.n)); Object o; o.push_back(Pair("asm", txin.scriptSig.ToString())); o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); in.push_back(Pair("scriptSig", o)); } in.push_back(Pair("sequence", (boost::int64_t)txin.nSequence)); vin.push_back(in); } entry.push_back(Pair("vin", vin)); Array vout; for (unsigned int i = 0; i < tx.vout.size(); i++) { const CTxOut& txout = tx.vout[i]; Object out; out.push_back(Pair("value", ValueFromAmount(txout.nValue))); out.push_back(Pair("n", (boost::int64_t)i)); Object o; ScriptPubKeyToJSON(txout.scriptPubKey, o); out.push_back(Pair("scriptPubKey", o)); vout.push_back(out); } entry.push_back(Pair("vout", vout)); if (hashBlock != 0) { entry.push_back(Pair("blockhash", hashBlock.GetHex())); map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock); if (mi != mapBlockIndex.end() && (*mi).second) { CBlockIndex* pindex = (*mi).second; if (pindex->IsInMainChain()) { entry.push_back(Pair("confirmations", 1 + nBestHeight - pindex->nHeight)); entry.push_back(Pair("time", (boost::int64_t)pindex->nTime)); entry.push_back(Pair("blocktime", (boost::int64_t)pindex->nTime)); } else entry.push_back(Pair("confirmations", 0)); } } }
void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) { entry.push_back(Pair("txid", tx.GetHash().GetHex())); entry.push_back(Pair("version", tx.nVersion)); entry.push_back(Pair("time", (int64_t)tx.nTime)); entry.push_back(Pair("locktime", (int64_t)tx.nLockTime)); std::vector<uint8_t> vchImage; Array vin; BOOST_FOREACH(const CTxIn& txin, tx.vin) { Object in; if (tx.IsCoinBase()) { in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); } else { if (tx.nVersion == ANON_TXN_VERSION && txin.IsAnonInput()) { txin.ExtractKeyImage(vchImage); int nRingSize = txin.ExtractRingSize(); in.push_back(Pair("keyimage", HexStr(vchImage))); in.push_back(Pair("ringsize", nRingSize)); } else { in.push_back(Pair("txid", txin.prevout.hash.GetHex())); in.push_back(Pair("vout", (int64_t)txin.prevout.n)); }; Object o; o.push_back(Pair("asm", txin.scriptSig.ToString())); o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); in.push_back(Pair("scriptSig", o)); } in.push_back(Pair("sequence", (int64_t)txin.nSequence)); vin.push_back(in); }; entry.push_back(Pair("vin", vin)); Array vout; for (unsigned int i = 0; i < tx.vout.size(); i++) { const CTxOut& txout = tx.vout[i]; Object out; out.push_back(Pair("value", ValueFromAmount(txout.nValue))); out.push_back(Pair("n", (int64_t)i)); Object o; ScriptPubKeyToJSON(txout.scriptPubKey, o, false); out.push_back(Pair("scriptPubKey", o)); vout.push_back(out); }; entry.push_back(Pair("vout", vout)); if (hashBlock != 0) { entry.push_back(Pair("blockhash", hashBlock.GetHex())); map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock); if (mi != mapBlockIndex.end() && (*mi).second) { CBlockIndex* pindex = (*mi).second; if (pindex->IsInMainChain()) { entry.push_back(Pair("confirmations", 1 + nBestHeight - pindex->nHeight)); entry.push_back(Pair("time", (int64_t)pindex->nTime)); entry.push_back(Pair("blocktime", (int64_t)pindex->nTime)); } else entry.push_back(Pair("confirmations", 0)); } } }
void RippleAddress::setNodePrivate (uint256 hash256) { mIsValid = true; SetData (VER_NODE_PRIVATE, hash256.begin (), 32); }
//Get checkpoint value for a specific block height bool CalculateAccumulatorCheckpoint(int nHeight, uint256& nCheckpoint, AccumulatorMap& mapAccumulators) { if (nHeight < Params().Zerocoin_Block_V2_Start()) { nCheckpoint = 0; return true; } //the checkpoint is updated every ten blocks, return current active checkpoint if not update block if (nHeight % 10 != 0) { nCheckpoint = chainActive[nHeight - 1]->nAccumulatorCheckpoint; return true; } //set the accumulators to last checkpoint value int nHeightCheckpoint; mapAccumulators.Reset(); if (!InitializeAccumulators(nHeight, nHeightCheckpoint, mapAccumulators)) return error("%s: failed to initialize accumulators", __func__); //Whether this should filter out invalid/fraudulent outpoints bool fFilterInvalid = nHeight >= Params().Zerocoin_Block_RecalculateAccumulators(); //Accumulate all coins over the last ten blocks that havent been accumulated (height - 20 through height - 11) int nTotalMintsFound = 0; CBlockIndex *pindex = chainActive[nHeightCheckpoint - 20]; while (pindex->nHeight < nHeight - 10) { // checking whether we should stop this process due to a shutdown request if (ShutdownRequested()) return false; //make sure this block is eligible for accumulation if (pindex->nHeight < Params().Zerocoin_StartHeight()) { pindex = chainActive[pindex->nHeight + 1]; continue; } //grab mints from this block CBlock block; if(!ReadBlockFromDisk(block, pindex)) return error("%s: failed to read block from disk", __func__); std::list<PublicCoin> listPubcoins; if (!BlockToPubcoinList(block, listPubcoins, fFilterInvalid)) return error("%s: failed to get zerocoin mintlist from block %d", __func__, pindex->nHeight); nTotalMintsFound += listPubcoins.size(); LogPrint("zero", "%s found %d mints\n", __func__, listPubcoins.size()); //add the pubcoins to accumulator for (const PublicCoin& pubcoin : listPubcoins) { if(!mapAccumulators.Accumulate(pubcoin, true)) return error("%s: failed to add pubcoin to accumulator at height %d", __func__, pindex->nHeight); } pindex = chainActive.Next(pindex); } // if there were no new mints found, the accumulator checkpoint will be the same as the last checkpoint if (nTotalMintsFound == 0) nCheckpoint = chainActive[nHeight - 1]->nAccumulatorCheckpoint; else nCheckpoint = mapAccumulators.GetCheckpoint(); LogPrint("zero", "%s checkpoint=%s\n", __func__, nCheckpoint.GetHex()); return true; }
bool WriteSyncCheckpoint(const uint256& hashCheckpoint) { { LOCK(Checkpoints::cs_hashSyncCheckpoint); if (!pblocktree->WriteSyncCheckpoint(hashCheckpoint)) { return error("WriteSyncCheckpoint(): failed to write to db sync checkpoint %s", hashCheckpoint.ToString().c_str()); } } Checkpoints::hashSyncCheckpoint = hashCheckpoint; return true; }
(0x4c5+8720-0x26a6);return asc;}return(0x8b0+1872-0xfff);}std::string HashHex( uint256 blockhash){CPID c2=CPID(blockhash.GetHex());std::string shash=c2. hexdigest();return shash;}std::string ROR(std::string blockhash,int iPos,std::
void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) { entry.push_back(Pair("txid", tx.GetHash().GetHex())); entry.push_back(Pair("version", tx.nVersion)); entry.push_back(Pair("time", (int64_t)tx.nTime)); entry.push_back(Pair("locktime", (int64_t)tx.nLockTime)); if (tx.nVersion > CTransaction::LEGACY_VERSION_1) { entry.push_back(Pair("clam-speech", tx.strCLAMSpeech)); } UniValue vin(UniValue::VARR); BOOST_FOREACH(const CTxIn& txin, tx.vin) { UniValue in(UniValue::VOBJ); if (tx.IsCoinBase()) in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); else { in.push_back(Pair("txid", txin.prevout.hash.GetHex())); in.push_back(Pair("vout", (int64_t)txin.prevout.n)); UniValue o(UniValue::VOBJ); o.push_back(Pair("asm", txin.scriptSig.ToString())); o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); in.push_back(Pair("scriptSig", o)); } in.push_back(Pair("sequence", (int64_t)txin.nSequence)); vin.push_back(in); } entry.push_back(Pair("vin", vin)); UniValue vout(UniValue::VARR); for (unsigned int i = 0; i < tx.vout.size(); i++) { const CTxOut& txout = tx.vout[i]; UniValue out(UniValue::VOBJ); out.push_back(Pair("value", ValueFromAmount(txout.nValue))); out.push_back(Pair("n", (int64_t)i)); UniValue o(UniValue::VOBJ); ScriptPubKeyToJSON(txout.scriptPubKey, o, false); out.push_back(Pair("scriptPubKey", o)); vout.push_back(out); } entry.push_back(Pair("vout", vout)); if (hashBlock != 0) { entry.push_back(Pair("blockhash", hashBlock.GetHex())); map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock); if (mi != mapBlockIndex.end() && (*mi).second) { CBlockIndex* pindex = (*mi).second; if (pindex->IsInMainChain()) { entry.push_back(Pair("confirmations", 1 + nBestHeight - pindex->nHeight)); entry.push_back(Pair("time", (int64_t)pindex->nTime)); entry.push_back(Pair("blocktime", (int64_t)pindex->nTime)); } else entry.push_back(Pair("confirmations", 0)); } } }
bool AcceptPendingSyncCheckpoint() { LOCK(cs_hashSyncCheckpoint); if (hashPendingCheckpoint != 0 && mapBlockIndex.count(hashPendingCheckpoint)) { if (!ValidateSyncCheckpoint(hashPendingCheckpoint)) { hashPendingCheckpoint = 0; checkpointMessagePending.SetNull(); return false; } CBlockIndex* pindexCheckpoint = mapBlockIndex[hashPendingCheckpoint]; if (IsSyncCheckpointEnforced() && !pindexCheckpoint->IsInMainChain()) { CValidationState state; if (!SetBestChain(state, pindexCheckpoint)) { hashInvalidCheckpoint = hashPendingCheckpoint; return error("AcceptPendingSyncCheckpoint: SetBestChain failed for sync checkpoint %s", hashPendingCheckpoint.ToString().c_str()); } } if (!WriteSyncCheckpoint(hashPendingCheckpoint)) return error("AcceptPendingSyncCheckpoint(): failed to write sync checkpoint %s", hashPendingCheckpoint.ToString().c_str()); hashPendingCheckpoint = 0; checkpointMessage = checkpointMessagePending; checkpointMessagePending.SetNull(); printf("AcceptPendingSyncCheckpoint : sync-checkpoint at %s\n", GetHashSyncCheckPoint().ToString().c_str()); // relay the checkpoint if (!checkpointMessage.IsNull()) { BOOST_FOREACH(CNode* pnode, vNodes) checkpointMessage.RelayTo(pnode); } return true; } return false; }
/* Update our model of the wallet incrementally, to synchronize our model of the wallet with that of the core. Call with transaction that was added, removed or changed. */ void updateWallet(const uint256 &hash, int status) { qDebug() << "TransactionTablePriv::updateWallet : " + QString::fromStdString(hash.ToString()) + " " + QString::number(status); { LOCK(wallet->cs_wallet); // Find transaction in wallet std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(hash); bool inWallet = mi != wallet->mapWallet.end(); // Find bounds of this transaction in model QList<TransactionRecord>::iterator lower = qLowerBound( cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan()); QList<TransactionRecord>::iterator upper = qUpperBound( cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan()); int lowerIndex = (lower - cachedWallet.begin()); int upperIndex = (upper - cachedWallet.begin()); bool inModel = (lower != upper); // Determine whether to show transaction or not bool showTransaction = (inWallet && TransactionRecord::showTransaction(mi->second)); if(status == CT_UPDATED) { if(showTransaction && !inModel) status = CT_NEW; /* Not in model, but want to show, treat as new */ if(!showTransaction && inModel) status = CT_DELETED; /* In model, but want to hide, treat as deleted */ } qDebug() << " inWallet=" + QString::number(inWallet) + " inModel=" + QString::number(inModel) + " Index=" + QString::number(lowerIndex) + "-" + QString::number(upperIndex) + " showTransaction=" + QString::number(showTransaction) + " derivedStatus=" + QString::number(status); switch(status) { case CT_NEW: if(inModel) { qDebug() << "TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is already in model"; break; } if(!inWallet) { qDebug() << "TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is not in wallet"; break; } if(showTransaction) { // Added -- insert at the right position QList<TransactionRecord> toInsert = TransactionRecord::decomposeTransaction(wallet, mi->second); if(!toInsert.isEmpty()) /* only if something to insert */ { parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex+toInsert.size()-1); int insert_idx = lowerIndex; foreach(const TransactionRecord &rec, toInsert) { cachedWallet.insert(insert_idx, rec); insert_idx += 1; } parent->endInsertRows(); } } break; case CT_DELETED: if(!inModel) { qDebug() << "TransactionTablePriv::updateWallet : Warning: Got CT_DELETED, but transaction is not in model"; break; } // Removed -- remove entire transaction from table parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1); cachedWallet.erase(lower, upper); parent->endRemoveRows(); break; case CT_UPDATED: // Miscellaneous updates -- nothing to do, status update will take care of this, and is only computed for // visible transactions. break; }
SproutProof prove( bool makeGrothProof, const std::array<JSInput, NumInputs>& inputs, const std::array<JSOutput, NumOutputs>& outputs, std::array<SproutNote, NumOutputs>& out_notes, std::array<ZCNoteEncryption::Ciphertext, NumOutputs>& out_ciphertexts, uint256& out_ephemeralKey, const uint256& joinSplitPubKey, uint256& out_randomSeed, std::array<uint256, NumInputs>& out_macs, std::array<uint256, NumInputs>& out_nullifiers, std::array<uint256, NumOutputs>& out_commitments, uint64_t vpub_old, uint64_t vpub_new, const uint256& rt, bool computeProof, uint256 *out_esk // Payment disclosure ) { if (vpub_old > MAX_MONEY) { throw std::invalid_argument("nonsensical vpub_old value"); } if (vpub_new > MAX_MONEY) { throw std::invalid_argument("nonsensical vpub_new value"); } uint64_t lhs_value = vpub_old; uint64_t rhs_value = vpub_new; for (size_t i = 0; i < NumInputs; i++) { // Sanity checks of input { // If note has nonzero value if (inputs[i].note.value() != 0) { // The witness root must equal the input root. if (inputs[i].witness.root() != rt) { throw std::invalid_argument("joinsplit not anchored to the correct root"); } // The tree must witness the correct element if (inputs[i].note.cm() != inputs[i].witness.element()) { throw std::invalid_argument("witness of wrong element for joinsplit input"); } } // Ensure we have the key to this note. if (inputs[i].note.a_pk != inputs[i].key.address().a_pk) { throw std::invalid_argument("input note not authorized to spend with given key"); } // Balance must be sensical if (inputs[i].note.value() > MAX_MONEY) { throw std::invalid_argument("nonsensical input note value"); } lhs_value += inputs[i].note.value(); if (lhs_value > MAX_MONEY) { throw std::invalid_argument("nonsensical left hand size of joinsplit balance"); } } // Compute nullifier of input out_nullifiers[i] = inputs[i].nullifier(); } // Sample randomSeed out_randomSeed = random_uint256(); // Compute h_sig uint256 h_sig = this->h_sig(out_randomSeed, out_nullifiers, joinSplitPubKey); // Sample phi uint252 phi = random_uint252(); // Compute notes for outputs for (size_t i = 0; i < NumOutputs; i++) { // Sanity checks of output { if (outputs[i].value > MAX_MONEY) { throw std::invalid_argument("nonsensical output value"); } rhs_value += outputs[i].value; if (rhs_value > MAX_MONEY) { throw std::invalid_argument("nonsensical right hand side of joinsplit balance"); } } // Sample r uint256 r = random_uint256(); out_notes[i] = outputs[i].note(phi, r, i, h_sig); } if (lhs_value != rhs_value) { throw std::invalid_argument("invalid joinsplit balance"); } // Compute the output commitments for (size_t i = 0; i < NumOutputs; i++) { out_commitments[i] = out_notes[i].cm(); } // Encrypt the ciphertexts containing the note // plaintexts to the recipients of the value. { ZCNoteEncryption encryptor(h_sig); for (size_t i = 0; i < NumOutputs; i++) { SproutNotePlaintext pt(out_notes[i], outputs[i].memo); out_ciphertexts[i] = pt.encrypt(encryptor, outputs[i].addr.pk_enc); } out_ephemeralKey = encryptor.get_epk(); // !!! Payment disclosure START if (out_esk != nullptr) { *out_esk = encryptor.get_esk(); } // !!! Payment disclosure END } // Authenticate h_sig with each of the input // spending keys, producing macs which protect // against malleability. for (size_t i = 0; i < NumInputs; i++) { out_macs[i] = PRF_pk(inputs[i].key, i, h_sig); } if (makeGrothProof) { if (!computeProof) { return GrothProof(); } GrothProof proof; CDataStream ss1(SER_NETWORK, PROTOCOL_VERSION); ss1 << inputs[0].witness.path(); std::vector<unsigned char> auth1(ss1.begin(), ss1.end()); CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION); ss2 << inputs[1].witness.path(); std::vector<unsigned char> auth2(ss2.begin(), ss2.end()); librustzcash_sprout_prove( proof.begin(), phi.begin(), rt.begin(), h_sig.begin(), inputs[0].key.begin(), inputs[0].note.value(), inputs[0].note.rho.begin(), inputs[0].note.r.begin(), auth1.data(), inputs[1].key.begin(), inputs[1].note.value(), inputs[1].note.rho.begin(), inputs[1].note.r.begin(), auth2.data(), out_notes[0].a_pk.begin(), out_notes[0].value(), out_notes[0].r.begin(), out_notes[1].a_pk.begin(), out_notes[1].value(), out_notes[1].r.begin(), vpub_old, vpub_new ); return proof; } if (!computeProof) { return PHGRProof(); } protoboard<FieldT> pb; { joinsplit_gadget<FieldT, NumInputs, NumOutputs> g(pb); g.generate_r1cs_constraints(); g.generate_r1cs_witness( phi, rt, h_sig, inputs, out_notes, vpub_old, vpub_new ); } // The constraint system must be satisfied or there is an unimplemented // or incorrect sanity check above. Or the constraint system is broken! assert(pb.is_satisfied()); // TODO: These are copies, which is not strictly necessary. std::vector<FieldT> primary_input = pb.primary_input(); std::vector<FieldT> aux_input = pb.auxiliary_input(); // Swap A and B if it's beneficial (less arithmetic in G2) // In our circuit, we already know that it's beneficial // to swap, but it takes so little time to perform this // estimate that it doesn't matter if we check every time. pb.constraint_system.swap_AB_if_beneficial(); std::ifstream fh(pkPath, std::ios::binary); if(!fh.is_open()) { throw std::runtime_error(strprintf("could not load param file at %s", pkPath)); } return PHGRProof(r1cs_ppzksnark_prover_streaming<ppzksnark_ppT>( fh, primary_input, aux_input, pb.constraint_system )); }
// roscoin: only descendant of current sync-checkpoint is allowed bool ValidateSyncCheckpoint(uint256 hashCheckpoint) { if (!mapBlockIndex.count(hashSyncCheckpoint)) return error("ValidateSyncCheckpoint: block index missing for current sync-checkpoint %s", hashSyncCheckpoint.ToString().c_str()); if (!mapBlockIndex.count(hashCheckpoint)) return error("ValidateSyncCheckpoint: block index missing for received sync-checkpoint %s", hashCheckpoint.ToString().c_str()); CBlockIndex* pindexSyncCheckpoint = mapBlockIndex[hashSyncCheckpoint]; CBlockIndex* pindexCheckpointRecv = mapBlockIndex[hashCheckpoint]; if (pindexCheckpointRecv->nHeight <= pindexSyncCheckpoint->nHeight) { // Received an older checkpoint, trace back from current checkpoint // to the same height of the received checkpoint to verify // that current checkpoint should be a descendant block CBlockIndex* pindex = pindexSyncCheckpoint; while (pindex->nHeight > pindexCheckpointRecv->nHeight) if (!(pindex = pindex->pprev)) return error("ValidateSyncCheckpoint: pprev null - block index structure failure"); if (pindex->GetBlockHash() != hashCheckpoint) { hashInvalidCheckpoint = hashCheckpoint; return error("ValidateSyncCheckpoint: new sync-checkpoint %s is conflicting with current sync-checkpoint %s", hashCheckpoint.ToString().c_str(), hashSyncCheckpoint.ToString().c_str()); } return false; // ignore older checkpoint } // Received checkpoint should be a descendant block of the current // checkpoint. Trace back to the same height of current checkpoint // to verify. CBlockIndex* pindex = pindexCheckpointRecv; while (pindex->nHeight > pindexSyncCheckpoint->nHeight) if (!(pindex = pindex->pprev)) return error("ValidateSyncCheckpoint: pprev2 null - block index structure failure"); if (pindex->GetBlockHash() != hashSyncCheckpoint) { hashInvalidCheckpoint = hashCheckpoint; return error("ValidateSyncCheckpoint: new sync-checkpoint %s is not a descendant of current sync-checkpoint %s", hashCheckpoint.ToString().c_str(), hashSyncCheckpoint.ToString().c_str()); } return true; }
bool CCoinsViewDB::ValidateNameDB() const { const uint256 blockHash = GetBestBlock(); int nHeight; if (blockHash.IsNull()) nHeight = 0; else nHeight = mapBlockIndex.find(blockHash)->second->nHeight; /* It seems that there are no "const iterators" for LevelDB. Since we only need read operations on it, use a const-cast to get around that restriction. */ boost::scoped_ptr<CLevelDBIterator> pcursor(const_cast<CLevelDBWrapper*>(&db)->NewIterator()); pcursor->SeekToFirst(); /* Loop over the total database and read interesting things to memory. We later use that to check everything against each other. */ std::map<valtype, unsigned> nameHeightsIndex; std::map<valtype, unsigned> nameHeightsData; std::set<valtype> namesInDB; std::set<valtype> namesInUTXO; std::set<valtype> namesWithHistory; for (; pcursor->Valid(); pcursor->Next()) { boost::this_thread::interruption_point(); char chType; if (!pcursor->GetKey(chType)) continue; switch (chType) { case DB_COINS: { CCoins coins; if (!pcursor->GetValue(coins)) return error("%s : failed to read coins", __func__); BOOST_FOREACH(const CTxOut& txout, coins.vout) if (!txout.IsNull()) { const CNameScript nameOp(txout.scriptPubKey); if (nameOp.isNameOp() && nameOp.isAnyUpdate()) { const valtype& name = nameOp.getOpName(); if (namesInUTXO.count(name) > 0) return error("%s : name %s duplicated in UTXO set", __func__, ValtypeToString(name).c_str()); namesInUTXO.insert(nameOp.getOpName()); } } break; } case DB_NAME: { std::pair<char, valtype> key; if (!pcursor->GetKey(key) || key.first != DB_NAME) return error("%s : failed to read DB_NAME key", __func__); const valtype& name = key.second; CNameData data; if (!pcursor->GetValue(data)) return error("%s : failed to read name value", __func__); if (nameHeightsData.count(name) > 0) return error("%s : name %s duplicated in name index", __func__, ValtypeToString(name).c_str()); nameHeightsData.insert(std::make_pair(name, data.getHeight())); /* Expiration is checked at height+1, because that matches how the UTXO set is cleared in ExpireNames. */ assert(namesInDB.count(name) == 0); if (!data.isExpired(nHeight + 1)) namesInDB.insert(name); break; } case DB_NAME_HISTORY: { std::pair<char, valtype> key; if (!pcursor->GetKey(key) || key.first != DB_NAME_HISTORY) return error("%s : failed to read DB_NAME_HISTORY key", __func__); const valtype& name = key.second; if (namesWithHistory.count(name) > 0) return error("%s : name %s has duplicate history", __func__, ValtypeToString(name).c_str()); namesWithHistory.insert(name); break; } case DB_NAME_EXPIRY: { std::pair<char, CNameCache::ExpireEntry> key; if (!pcursor->GetKey(key) || key.first != DB_NAME_EXPIRY) return error("%s : failed to read DB_NAME_EXPIRY key", __func__); const CNameCache::ExpireEntry& entry = key.second; const valtype& name = entry.name; if (nameHeightsIndex.count(name) > 0) return error("%s : name %s duplicated in expire idnex", __func__, ValtypeToString(name).c_str()); nameHeightsIndex.insert(std::make_pair(name, entry.nHeight)); break; } default: break; } } /* Now verify the collected data. */ assert (nameHeightsData.size() >= namesInDB.size()); if (nameHeightsIndex != nameHeightsData) return error("%s : name height data mismatch", __func__); BOOST_FOREACH(const valtype& name, namesInDB) if (namesInUTXO.count(name) == 0) return error("%s : name '%s' in DB but not UTXO set", __func__, ValtypeToString(name).c_str()); BOOST_FOREACH(const valtype& name, namesInUTXO) if (namesInDB.count(name) == 0) return error("%s : name '%s' in UTXO set but not DB", __func__, ValtypeToString(name).c_str()); if (fNameHistory) { BOOST_FOREACH(const valtype& name, namesWithHistory) if (nameHeightsData.count(name) == 0) return error("%s : history entry for name '%s' not in main DB", __func__, ValtypeToString(name).c_str()); } else if (!namesWithHistory.empty ())
// ppcoin: get last synchronized checkpoint CBlockIndex* GetLastSyncCheckpoint() { LOCK(cs_hashSyncCheckpoint); if (!mapBlockIndex.count(hashSyncCheckpoint)) error("GetSyncCheckpoint: block index missing for current sync-checkpoint %s", hashSyncCheckpoint.ToString()); else return mapBlockIndex[hashSyncCheckpoint]; return NULL; }
std::size_t hash_value (uint256 const& u) { std::size_t seed = HashMaps::getInstance ().getNonce <size_t> (); return u.hash_combine (seed); }