本文整理汇总了C++中LOCK2函数的典型用法代码示例。如果您正苦于以下问题:C++ LOCK2函数的具体用法?C++ LOCK2怎么用?C++ LOCK2使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了LOCK2函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: SignTransaction
bool SignTransaction(CWallet* wallet, CMutableTransaction& mtx) {
LOCK2(cs_main, wallet->cs_wallet);
return wallet->SignTransaction(mtx);
}
示例2: rest_getutxos
//.........这里部分代码省略.........
CDataStream oss(SER_NETWORK, PROTOCOL_VERSION);
oss << strRequestMutable;
oss >> fCheckMemPool;
oss >> vOutPoints;
}
} catch (const std::ios_base::failure& e) {
// abort in case of unreadable binary data
return RESTERR(req, HTTP_BAD_REQUEST, "Parse error");
}
break;
}
case RF_JSON: {
if (!fInputParsed)
return RESTERR(req, HTTP_BAD_REQUEST, "Error: empty request");
break;
}
default: {
return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
}
}
// limit max outpoints
if (vOutPoints.size() > MAX_GETUTXOS_OUTPOINTS)
return RESTERR(req, HTTP_BAD_REQUEST, strprintf("Error: max outpoints exceeded (max: %d, tried: %d)", MAX_GETUTXOS_OUTPOINTS, vOutPoints.size()));
// check spentness and form a bitmap (as well as a JSON capable human-readable string representation)
std::vector<unsigned char> bitmap;
std::vector<CCoin> outs;
std::string bitmapStringRepresentation;
std::vector<bool> hits;
bitmap.resize((vOutPoints.size() + 7) / 8);
{
LOCK2(cs_main, mempool.cs);
CCoinsView viewDummy;
CCoinsViewCache view(&viewDummy);
CCoinsViewCache& viewChain = *pcoinsTip;
CCoinsViewMemPool viewMempool(&viewChain, mempool);
if (fCheckMemPool)
view.SetBackend(viewMempool); // switch cache backend to db+mempool in case user likes to query mempool
for (size_t i = 0; i < vOutPoints.size(); i++) {
bool hit = false;
Coin coin;
if (view.GetCoin(vOutPoints[i], coin) && !mempool.isSpent(vOutPoints[i])) {
hit = true;
outs.emplace_back(std::move(coin));
}
hits.push_back(hit);
bitmapStringRepresentation.append(hit ? "1" : "0"); // form a binary string representation (human-readable for json output)
bitmap[i / 8] |= ((uint8_t)hit) << (i % 8);
}
}
switch (rf) {
case RF_BINARY: {
// serialize data
// use exact same output as mentioned in Bip64
CDataStream ssGetUTXOResponse(SER_NETWORK, PROTOCOL_VERSION);
ssGetUTXOResponse << chainActive.Height() << chainActive.Tip()->GetBlockHash() << bitmap << outs;
std::string ssGetUTXOResponseString = ssGetUTXOResponse.str();
示例3: LOCK2
bool CInstantSend::ResolveConflicts(const CTxLockCandidate& txLockCandidate)
{
LOCK2(cs_main, cs_instantsend);
uint256 txHash = txLockCandidate.GetHash();
// make sure the lock is ready
if(!txLockCandidate.IsAllOutPointsReady()) return false;
AssertLockHeld(mempool.cs); // protect mempool.mapNextTx
for (const auto& txin : txLockCandidate.txLockRequest.tx->vin) {
uint256 hashConflicting;
if(GetLockedOutPointTxHash(txin.prevout, hashConflicting) && txHash != hashConflicting) {
// completed lock which conflicts with another completed one?
// this means that majority of MNs in the quorum for this specific tx input are malicious!
std::map<uint256, CTxLockCandidate>::iterator itLockCandidate = mapTxLockCandidates.find(txHash);
std::map<uint256, CTxLockCandidate>::iterator itLockCandidateConflicting = mapTxLockCandidates.find(hashConflicting);
if(itLockCandidate == mapTxLockCandidates.end() || itLockCandidateConflicting == mapTxLockCandidates.end()) {
// safety check, should never really happen
LogPrintf("CInstantSend::ResolveConflicts -- ERROR: Found conflicting completed Transaction Lock, but one of txLockCandidate-s is missing, txid=%s, conflicting txid=%s\n",
txHash.ToString(), hashConflicting.ToString());
return false;
}
LogPrintf("CInstantSend::ResolveConflicts -- WARNING: Found conflicting completed Transaction Lock, dropping both, txid=%s, conflicting txid=%s\n",
txHash.ToString(), hashConflicting.ToString());
CTxLockRequest txLockRequest = itLockCandidate->second.txLockRequest;
CTxLockRequest txLockRequestConflicting = itLockCandidateConflicting->second.txLockRequest;
itLockCandidate->second.SetConfirmedHeight(0); // expired
itLockCandidateConflicting->second.SetConfirmedHeight(0); // expired
CheckAndRemove(); // clean up
// AlreadyHave should still return "true" for both of them
mapLockRequestRejected.insert(std::make_pair(txHash, txLockRequest));
mapLockRequestRejected.insert(std::make_pair(hashConflicting, txLockRequestConflicting));
// TODO: clean up mapLockRequestRejected later somehow
// (not a big issue since we already PoSe ban malicious masternodes
// and they won't be able to spam)
// TODO: ban all malicious masternodes permanently, do not accept anything from them, ever
// TODO: notify zmq+script about this double-spend attempt
// and let merchant cancel/hold the order if it's not too late...
// can't do anything else, fallback to regular txes
return false;
} else if (mempool.mapNextTx.count(txin.prevout)) {
// check if it's in mempool
hashConflicting = mempool.mapNextTx.find(txin.prevout)->second->GetHash();
if(txHash == hashConflicting) continue; // matches current, not a conflict, skip to next txin
// conflicts with tx in mempool
LogPrintf("CInstantSend::ResolveConflicts -- ERROR: Failed to complete Transaction Lock, conflicts with mempool, txid=%s\n", txHash.ToString());
return false;
}
} // FOREACH
// No conflicts were found so far, check to see if it was already included in block
CTransactionRef txTmp;
uint256 hashBlock;
if(GetTransaction(txHash, txTmp, Params().GetConsensus(), hashBlock, true) && hashBlock != uint256()) {
LogPrint("instantsend", "CInstantSend::ResolveConflicts -- Done, %s is included in block %s\n", txHash.ToString(), hashBlock.ToString());
return true;
}
// Not in block yet, make sure all its inputs are still unspent
for (const auto& txin : txLockCandidate.txLockRequest.tx->vin) {
Coin coin;
if(!GetUTXOCoin(txin.prevout, coin)) {
// Not in UTXO anymore? A conflicting tx was mined while we were waiting for votes.
LogPrintf("CInstantSend::ResolveConflicts -- ERROR: Failed to find UTXO %s, can't complete Transaction Lock\n", txin.prevout.ToStringShort());
return false;
}
}
LogPrint("instantsend", "CInstantSend::ResolveConflicts -- Done, txid=%s\n", txHash.ToString());
return true;
}
示例4: validateaddress
UniValue validateaddress(const JSONRPCRequest& request)
{
if (request.fHelp || request.params.size() != 1)
throw std::runtime_error(
"validateaddress \"address\"\n"
"\nReturn information about the given bitcoin address.\n"
"\nArguments:\n"
"1. \"address\" (string, required) The bitcoin address to validate\n"
"\nResult:\n"
"{\n"
" \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n"
" \"address\" : \"address\", (string) The bitcoin address validated\n"
" \"scriptPubKey\" : \"hex\", (string) The hex encoded scriptPubKey generated by the address\n"
" \"ismine\" : true|false, (boolean) If the address is yours or not\n"
" \"iswatchonly\" : true|false, (boolean) If the address is watchonly\n"
" \"isscript\" : true|false, (boolean) If the key is a script\n"
" \"script\" : \"type\" (string, optional) The output script type. Possible types: nonstandard, pubkey, pubkeyhash, scripthash, multisig, nulldata, witness_v0_keyhash, witness_v0_scripthash\n"
" \"hex\" : \"hex\", (string, optional) The redeemscript for the p2sh address\n"
" \"addresses\" (string, optional) Array of addresses associated with the known redeemscript\n"
" [\n"
" \"address\"\n"
" ,...\n"
" ]\n"
" \"sigsrequired\" : xxxxx (numeric, optional) Number of signatures required to spend multisig output\n"
" \"pubkey\" : \"publickeyhex\", (string) The hex value of the raw public key\n"
" \"iscompressed\" : true|false, (boolean) If the address is compressed\n"
" \"account\" : \"account\" (string) DEPRECATED. The account associated with the address, \"\" is the default account\n"
" \"timestamp\" : timestamp, (number, optional) The creation time of the key if available in seconds since epoch (Jan 1 1970 GMT)\n"
" \"hdkeypath\" : \"keypath\" (string, optional) The HD keypath if the key is HD and available\n"
" \"hdmasterkeyid\" : \"<hash160>\" (string, optional) The Hash160 of the HD master pubkey\n"
"}\n"
"\nExamples:\n"
+ HelpExampleCli("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
+ HelpExampleRpc("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
);
#ifdef ENABLE_WALLET
CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : NULL);
#else
LOCK(cs_main);
#endif
CBitcoinAddress address(request.params[0].get_str());
bool isValid = address.IsValid();
UniValue ret(UniValue::VOBJ);
ret.push_back(Pair("isvalid", isValid));
if (isValid)
{
CTxDestination dest = address.Get();
std::string currentAddress = address.ToString();
ret.push_back(Pair("address", currentAddress));
CScript scriptPubKey = GetScriptForDestination(dest);
ret.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
#ifdef ENABLE_WALLET
isminetype mine = pwallet ? IsMine(*pwallet, dest) : ISMINE_NO;
ret.push_back(Pair("ismine", bool(mine & ISMINE_SPENDABLE)));
ret.push_back(Pair("iswatchonly", bool(mine & ISMINE_WATCH_ONLY)));
UniValue detail = boost::apply_visitor(DescribeAddressVisitor(pwallet), dest);
ret.pushKVs(detail);
if (pwallet && pwallet->mapAddressBook.count(dest)) {
ret.push_back(Pair("account", pwallet->mapAddressBook[dest].name));
}
CKeyID keyID;
if (pwallet) {
const auto& meta = pwallet->mapKeyMetadata;
auto it = address.GetKeyID(keyID) ? meta.find(keyID) : meta.end();
if (it == meta.end()) {
it = meta.find(CScriptID(scriptPubKey));
}
if (it != meta.end()) {
ret.push_back(Pair("timestamp", it->second.nCreateTime));
if (!it->second.hdKeypath.empty()) {
ret.push_back(Pair("hdkeypath", it->second.hdKeypath));
ret.push_back(Pair("hdmasterkeyid", it->second.hdMasterKeyID.GetHex()));
}
}
}
#endif
}
return ret;
}
示例5: updateWallet
/* 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);
{
LOCK2(cs_main, 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;
}
示例6: Q_FOREACH
WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl)
{
CAmount total = 0;
bool fSubtractFeeFromAmount = false;
QList<SendCoinsRecipient> recipients = transaction.getRecipients();
std::vector<CRecipient> vecSend;
if(recipients.empty())
{
return OK;
}
QSet<QString> setAddress; // Used to detect duplicates
int nAddresses = 0;
// Pre-check input data for validity
Q_FOREACH(const SendCoinsRecipient &rcp, recipients)
{
if (rcp.fSubtractFeeFromAmount)
fSubtractFeeFromAmount = true;
if (rcp.paymentRequest.IsInitialized())
{ // PaymentRequest...
CAmount subtotal = 0;
const payments::PaymentDetails& details = rcp.paymentRequest.getDetails();
for (int i = 0; i < details.outputs_size(); i++)
{
const payments::Output& out = details.outputs(i);
if (out.amount() <= 0) continue;
subtotal += out.amount();
const unsigned char* scriptStr = (const unsigned char*)out.script().data();
CScript scriptPubKey(scriptStr, scriptStr+out.script().size());
CAmount nAmount = out.amount();
CRecipient recipient = {scriptPubKey, nAmount, rcp.fSubtractFeeFromAmount};
vecSend.push_back(recipient);
}
if (subtotal <= 0)
{
return InvalidAmount;
}
total += subtotal;
}
else
{ // User-entered bitcoin address / amount:
if(!validateAddress(rcp.address))
{
return InvalidAddress;
}
if(rcp.amount <= 0)
{
return InvalidAmount;
}
setAddress.insert(rcp.address);
++nAddresses;
CScript scriptPubKey = GetScriptForDestination(CBitcoinAddress(rcp.address.toStdString()).Get());
CRecipient recipient = {scriptPubKey, rcp.amount, rcp.fSubtractFeeFromAmount};
vecSend.push_back(recipient);
total += rcp.amount;
}
}
if(setAddress.size() != nAddresses)
{
return DuplicateAddress;
}
CAmount nBalance = getBalance(coinControl);
if(total > nBalance)
{
return AmountExceedsBalance;
}
{
LOCK2(cs_main, wallet->cs_wallet);
transaction.newPossibleKeyChange(wallet);
CAmount nFeeRequired = 0;
int nChangePosRet = -1;
std::string strFailReason;
CWalletTx *newTx = transaction.getTransaction();
CReserveKey *keyChange = transaction.getPossibleKeyChange();
bool fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, nFeeRequired, nChangePosRet, strFailReason, coinControl);
transaction.setTransactionFee(nFeeRequired);
if (fSubtractFeeFromAmount && fCreated)
transaction.reassignAmounts(nChangePosRet);
if(!fCreated)
{
if(!fSubtractFeeFromAmount && (total + nFeeRequired) > nBalance)
{
return SendCoinsReturn(AmountWithFeeExceedsBalance);
}
Q_EMIT message(tr("Send Coins"), QString::fromStdString(strFailReason),
CClientUIInterface::MSG_ERROR);
return TransactionCreationFailed;
}
//.........这里部分代码省略.........
示例7: name_pending
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)
{
std::shared_ptr<const CTransaction> tx = mempool.get (*i);
if (!tx || !tx->IsNamecoin ())
continue;
for (const auto& txOut : tx->vout)
{
const CNameScript op(txOut.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;
}
示例8: LOCK2
void CMasternodePayments::Clear()
{
LOCK2(cs_mapMasternodeBlocks, cs_mapMasternodePaymentVotes);
mapMasternodeBlocks.clear();
mapMasternodePaymentVotes.clear();
}
示例9: explorer
QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
{
QString strHTML;
QString explorer(fTestNet ? "http://explorer.butterflycoin.info/" : "http://explorer.butterflycoin.info/");
LOCK2(cs_main, wallet->cs_wallet);
strHTML.reserve(4000);
strHTML += "<html><font face='verdana, arial, helvetica, sans-serif'>";
int64_t nTime = wtx.GetTxTime();
int64_t nCredit = wtx.GetCredit();
int64_t nDebit = wtx.GetDebit();
int64_t nNet = nCredit - nDebit;
strHTML += "<b>" + tr("Status") + ":</b> " + FormatTxStatus(wtx);
int nRequests = wtx.GetRequestCount();
if (nRequests != -1)
{
if (nRequests == 0)
strHTML += tr(", has not been successfully broadcast yet");
else if (nRequests > 0)
strHTML += tr(", broadcast through %n node(s)", "", nRequests);
};
strHTML += "<br>";
strHTML += "<b>" + tr("Date") + ":</b> " + (nTime ? GUIUtil::dateTimeStr(nTime) : "") + "<br>";
//
// From
//
if (wtx.IsCoinBase() || wtx.IsCoinStake())
{
strHTML += "<b>" + tr("Source") + ":</b> " + tr("Generated") + "<br>";
} else
if (wtx.mapValue.count("from") && !wtx.mapValue["from"].empty())
{
// Online transaction
strHTML += "<b>" + tr("From") + ":</b> " + GUIUtil::HtmlEscape(wtx.mapValue["from"]) + "<br>";
} else
{
// Offline transaction
if (nNet > 0)
{
// Credit
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
{
if (wtx.nVersion == ANON_TXN_VERSION
&& txout.IsAnonOutput())
{
const CScript &s = txout.scriptPubKey;
CKeyID ckidD = CPubKey(&s[2+1], 33).GetID();
std::string sAnonPrefix("ao ");
if (wallet->HaveKey(ckidD) && (wallet->mapAddressBook[ckidD].empty() || !wallet->mapAddressBook[ckidD].compare(0, sAnonPrefix.length(), sAnonPrefix) == 0))
{
strHTML += "<b>" + tr("From") + ":</b> " + tr("unknown") + "<br>";
strHTML += "<b>" + tr("To") + ":</b> <a href='"+explorer+"address.asp?address=";
strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(ckidD).ToString())+"' target='_blank'>";
strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(ckidD).ToString());
if (!wallet->mapAddressBook[ckidD].empty())
strHTML += " (" + tr("own address") + ", " + tr("label") + ": " + GUIUtil::HtmlEscape(wallet->mapAddressBook[ckidD]) + ")";
else
strHTML += " (" + tr("own address") + ")";
strHTML += "</a><br>";
};
continue;
}
if (wallet->IsMine(txout))
{
CTxDestination address;
if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address))
{
if (wallet->mapAddressBook.count(address))
{
strHTML += "<b>" + tr("From") + ":</b> " + tr("unknown") + "<br>";
strHTML += "<b>" + tr("To") + ":</b> <a href='"+explorer+"address.asp?address=";
strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(address).ToString())+"' target='_blank'>";
strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(address).ToString());
if (!wallet->mapAddressBook[address].empty())
strHTML += " (" + tr("own address") + ", " + tr("label") + ": " + GUIUtil::HtmlEscape(wallet->mapAddressBook[address]) + ")";
else
strHTML += " (" + tr("own address") + ")";
strHTML += "</a><br>";
};
};
break;
};
};
};
};
示例10: LOCK2
WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &transaction)
{
QByteArray transaction_array; /* store serialized transaction */
if(isAnonymizeOnlyUnlocked())
{
return AnonymizeOnlyUnlocked;
}
{
LOCK2(cs_main, wallet->cs_wallet);
CWalletTx *newTx = transaction.getTransaction();
QList<SendCoinsRecipient> recipients = transaction.getRecipients();
// Store PaymentRequests in wtx.vOrderForm in wallet.
foreach(const SendCoinsRecipient &rcp, recipients)
{
if (rcp.paymentRequest.IsInitialized())
{
std::string key("PaymentRequest");
std::string value;
rcp.paymentRequest.SerializeToString(&value);
newTx->vOrderForm.push_back(make_pair(key, value));
}
else if (!rcp.message.isEmpty()) // Message from normal limecoinx:URI (limecoinx:XyZ...?message=example)
{
newTx->vOrderForm.push_back(make_pair("Message", rcp.message.toStdString()));
}
}
CReserveKey *keyChange = transaction.getPossibleKeyChange();
transaction.getRecipients();
if(!wallet->CommitTransaction(*newTx, *keyChange, (recipients[0].useInstantX) ? "txlreq" : "tx"))
return TransactionCommitFailed;
CTransaction* t = (CTransaction*)newTx;
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
ssTx << *t;
transaction_array.append(&(ssTx[0]), ssTx.size());
}
// Add addresses / update labels that we've sent to to the address book,
// and emit coinsSent signal for each recipient
foreach(const SendCoinsRecipient &rcp, transaction.getRecipients())
{
// Don't touch the address book when we have a payment request
if (!rcp.paymentRequest.IsInitialized())
{
std::string strAddress = rcp.address.toStdString();
CTxDestination dest = CBitcoinAddress(strAddress).Get();
std::string strLabel = rcp.label.toStdString();
{
LOCK(wallet->cs_wallet);
std::map<CTxDestination, CAddressBookData>::iterator mi = wallet->mapAddressBook.find(dest);
// Check if we have a new address or an updated label
if (mi == wallet->mapAddressBook.end())
{
wallet->SetAddressBook(dest, strLabel, "send");
}
else if (mi->second.name != strLabel)
{
wallet->SetAddressBook(dest, strLabel, ""); // "" means don't change purpose
}
}
}
emit coinsSent(wallet, rcp, transaction_array);
}
return SendCoinsReturn(OK);
}
示例11: foreach
WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipient> &recipients, const CCoinControl *coinControl)
{
qint64 total = 0;
QSet<QString> setAddress;
QString hex;
if(recipients.empty())
{
return OK;
}
// Pre-check input data for validity
foreach(const SendCoinsRecipient &rcp, recipients)
{
if(!validateAddress(rcp.address))
{
return InvalidAddress;
}
setAddress.insert(rcp.address);
if(rcp.amount <= 0)
{
return InvalidAmount;
}
total += rcp.amount;
}
if(recipients.size() > setAddress.size())
{
return DuplicateAddress;
}
int64_t nBalance = 0;
std::vector<COutput> vCoins;
wallet->AvailableCoins(vCoins, true, coinControl);
BOOST_FOREACH(const COutput& out, vCoins)
nBalance += out.tx->vout[out.i].nValue;
if(total > nBalance)
{
return AmountExceedsBalance;
}
if((total + nTransactionFee) > nBalance)
{
return SendCoinsReturn(AmountWithFeeExceedsBalance, nTransactionFee);
}
{
LOCK2(cs_main, wallet->cs_wallet);
// Sendmany
std::vector<std::pair<CScript, int64_t> > vecSend;
std::string sNarr;
foreach(const SendCoinsRecipient &rcp, recipients)
{
CScript scriptPubKey;
scriptPubKey.SetDestination(CBitcoinAddress(rcp.address.toStdString()).Get());
vecSend.push_back(make_pair(scriptPubKey, rcp.amount));
sNarr = rcp.reference.toStdString();
if (sNarr.length() > 0)
{
if (sNarr.length() > 50)
{
printf("Reference is too long.\n");
return ReferenceTooLong;
};
std::vector<uint8_t> vNarr(sNarr.c_str(), sNarr.c_str() + sNarr.length());
CScript scriptN = CScript() << OP_RETURN << vNarr;
vecSend.push_back(make_pair(scriptN, 0));
}
}
CWalletTx wtx;
if (sNarr.length() > 0) {
wtx.mapValue["reference"] = sNarr;
}
CReserveKey keyChange(wallet);
int64_t nFeeRequired = 0;
bool fCreated = wallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, coinControl);
if(!fCreated)
{
if((total + nFeeRequired) > nBalance) // FIXME: could cause collisions in the future
{
return SendCoinsReturn(AmountWithFeeExceedsBalance, nFeeRequired);
}
return TransactionCreationFailed;
}
if(!uiInterface.ThreadSafeAskFee(nFeeRequired, tr("Sending...").toStdString()))
{
return Aborted;
}
if(!wallet->CommitTransaction(wtx, keyChange))
//.........这里部分代码省略.........
示例12: LOCK2
QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
{
// individual tx do not affect any representation
static const bool fMultiSig = true;
QString strHTML;
LOCK2(cs_main, wallet->cs_wallet);
strHTML.reserve(4000);
strHTML += "<html><font face='verdana, arial, helvetica, sans-serif'>";
int64_t nTime = wtx.GetTxTime();
std::map<int, int64_t> mapDebit, mapCredit, mapChange, mapNet;
// debits
wallet->FillDebits(wtx, mapDebit, fMultiSig);
// credits (mature)
wallet->FillMatures(wtx, mapCredit, fMultiSig);
// nets (mature - debits)
FillNets(mapDebit, mapCredit, mapNet);
strHTML += "<b>" + tr("Status") + ":</b> " + FormatTxStatus(wtx);
int nRequests = wtx.GetRequestCount();
if (nRequests != -1)
{
if (nRequests == 0)
strHTML += tr(", has not been successfully broadcast yet");
else if (nRequests > 0)
strHTML += tr(", broadcast through %n node(s)", "", nRequests);
}
strHTML += "<br>";
strHTML += "<b>" + tr("Date") + ":</b> " + (nTime ? GUIUtil::dateTimeStr(nTime) : "") + "<br>";
//
// From
//
if (wtx.IsCoinBase() || wtx.IsCoinStake())
{
strHTML += "<b>" + tr("Source") + ":</b> " + tr("Generated") + "<br>";
}
else if (wtx.mapValue.count("from") && !wtx.mapValue["from"].empty())
{
// Online transaction
strHTML += "<b>" + tr("From") + ":</b> " + GUIUtil::HtmlEscape(wtx.mapValue["from"]) + "<br>";
}
else
{
// Offline transaction
if (ValueMapAllPositive(mapNet))
{
// Credit
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
{
if (wallet->IsMine(txout, fMultiSig) & ISMINE_ALL)
{
CTxDestination address;
if (ExtractDestination(txout.scriptPubKey, address) &&
(IsMine(*wallet, address, fMultiSig) & ISMINE_ALL))
{
if (wallet->mapAddressBook.count(address))
{
strHTML += "<b>" + tr("From") + ":</b> " + tr("unknown") + "<br>";
strHTML += "<b>" + tr("To") + ":</b> ";
CBitcoinAddress addr(address, txout.nColor);
strHTML += GUIUtil::HtmlEscape(addr.ToString());
// indicate distinction between own address and watch address
if (IsMine(*wallet, address, fMultiSig) & ISMINE_SPENDABLE)
{
if (!wallet->mapAddressBook[address].empty())
{
strHTML += " (" + tr("own address") + ", " + tr("label") + ": " +
GUIUtil::HtmlEscape(wallet->mapAddressBook[address]) + ")";
}
else
{
strHTML += " (" + tr("own address") + ")";
}
}
else
{
if (!wallet->mapAddressBook[address].empty())
{
strHTML += " (" + tr("watch address") + ", " + tr("label") + ": " +
GUIUtil::HtmlEscape(wallet->mapAddressBook[address]) + ")";
}
else
{
strHTML += " (" + tr("watch address") + ")";
}
}
strHTML += "<br>";
}
}
break;
}
}
}
//.........这里部分代码省略.........
示例13: CreateTransaction
Result CreateTransaction(const CWallet* wallet, const uint256& txid, const CCoinControl& coin_control, CAmount total_fee, std::vector<std::string>& errors,
CAmount& old_fee, CAmount& new_fee, CMutableTransaction& mtx)
{
LOCK2(cs_main, wallet->cs_wallet);
errors.clear();
auto it = wallet->mapWallet.find(txid);
if (it == wallet->mapWallet.end()) {
errors.push_back("Invalid or non-wallet transaction id");
return Result::INVALID_ADDRESS_OR_KEY;
}
const CWalletTx& wtx = it->second;
Result result = PreconditionChecks(wallet, wtx, errors);
if (result != Result::OK) {
return result;
}
if (!SignalsOptInRBF(*wtx.tx)) {
errors.push_back("Transaction is not BIP 125 replaceable");
return Result::WALLET_ERROR;
}
if (wtx.mapValue.count("replaced_by_txid")) {
errors.push_back(strprintf("Cannot bump transaction %s which was already bumped by transaction %s", txid.ToString(), wtx.mapValue.at("replaced_by_txid")));
return Result::WALLET_ERROR;
}
// check that original tx consists entirely of our inputs
// if not, we can't bump the fee, because the wallet has no way of knowing the value of the other inputs (thus the fee)
if (!wallet->IsAllFromMe(*wtx.tx, ISMINE_SPENDABLE)) {
errors.push_back("Transaction contains inputs that don't belong to this wallet");
return Result::WALLET_ERROR;
}
// figure out which output was change
// if there was no change output or multiple change outputs, fail
int nOutput = -1;
for (size_t i = 0; i < wtx.tx->vout.size(); ++i) {
if (wallet->IsChange(wtx.tx->vout[i])) {
if (nOutput != -1) {
errors.push_back("Transaction has multiple change outputs");
return Result::WALLET_ERROR;
}
nOutput = i;
}
}
if (nOutput == -1) {
errors.push_back("Transaction does not have a change output");
return Result::WALLET_ERROR;
}
// Calculate the expected size of the new transaction.
int64_t txSize = GetVirtualTransactionSize(*(wtx.tx));
const int64_t maxNewTxSize = CalculateMaximumSignedTxSize(*wtx.tx, wallet);
if (maxNewTxSize < 0) {
errors.push_back("Transaction contains inputs that cannot be signed");
return Result::INVALID_ADDRESS_OR_KEY;
}
// calculate the old fee and fee-rate
old_fee = wtx.GetDebit(ISMINE_SPENDABLE) - wtx.tx->GetValueOut();
CFeeRate nOldFeeRate(old_fee, txSize);
CFeeRate nNewFeeRate;
// The wallet uses a conservative WALLET_INCREMENTAL_RELAY_FEE value to
// future proof against changes to network wide policy for incremental relay
// fee that our node may not be aware of.
CFeeRate walletIncrementalRelayFee = CFeeRate(WALLET_INCREMENTAL_RELAY_FEE);
if (::incrementalRelayFee > walletIncrementalRelayFee) {
walletIncrementalRelayFee = ::incrementalRelayFee;
}
if (total_fee > 0) {
CAmount minTotalFee = nOldFeeRate.GetFee(maxNewTxSize) + ::incrementalRelayFee.GetFee(maxNewTxSize);
if (total_fee < minTotalFee) {
errors.push_back(strprintf("Insufficient totalFee, must be at least %s (oldFee %s + incrementalFee %s)",
FormatMoney(minTotalFee), FormatMoney(nOldFeeRate.GetFee(maxNewTxSize)), FormatMoney(::incrementalRelayFee.GetFee(maxNewTxSize))));
return Result::INVALID_PARAMETER;
}
CAmount requiredFee = GetRequiredFee(maxNewTxSize);
if (total_fee < requiredFee) {
errors.push_back(strprintf("Insufficient totalFee (cannot be less than required fee %s)",
FormatMoney(requiredFee)));
return Result::INVALID_PARAMETER;
}
new_fee = total_fee;
nNewFeeRate = CFeeRate(total_fee, maxNewTxSize);
} else {
new_fee = GetMinimumFee(maxNewTxSize, coin_control, mempool, ::feeEstimator, nullptr /* FeeCalculation */);
nNewFeeRate = CFeeRate(new_fee, maxNewTxSize);
// New fee rate must be at least old rate + minimum incremental relay rate
// walletIncrementalRelayFee.GetFeePerK() should be exact, because it's initialized
// in that unit (fee per kb).
// However, nOldFeeRate is a calculated value from the tx fee/size, so
// add 1 satoshi to the result, because it may have been rounded down.
if (nNewFeeRate.GetFeePerK() < nOldFeeRate.GetFeePerK() + 1 + walletIncrementalRelayFee.GetFeePerK()) {
nNewFeeRate = CFeeRate(nOldFeeRate.GetFeePerK() + 1 + walletIncrementalRelayFee.GetFeePerK());
new_fee = nNewFeeRate.GetFee(maxNewTxSize);
}
}
//.........这里部分代码省略.........
示例14: TransactionCanBeBumped
bool TransactionCanBeBumped(CWallet* wallet, const uint256& txid)
{
LOCK2(cs_main, wallet->cs_wallet);
const CWalletTx* wtx = wallet->GetWalletTx(txid);
return wtx && SignalsOptInRBF(*wtx->tx) && !wtx->mapValue.count("replaced_by_txid");
}
示例15: foreach
WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipient> &recipients, const CCoinControl *coinControl)
{
qint64 total = 0;
QSet<QString> setAddress;
QString hex;
if(recipients.empty())
{
return OK;
}
// Pre-check input data for validity
foreach(const SendCoinsRecipient &rcp, recipients)
{
if(!validateAddress(rcp.address))
{
return InvalidAddress;
}
setAddress.insert(rcp.address);
if(rcp.amount <= 0)
{
return InvalidAmount;
}
total += rcp.amount;
}
if(recipients.size() > setAddress.size())
{
return DuplicateAddress;
}
// we do not use getBalance() here, because some coins could be locked or coin control could be active
int64 nBalance = 0;
std::vector<COutput> vCoins;
wallet->AvailableCoins(vCoins, true, coinControl);
BOOST_FOREACH(const COutput& out, vCoins)
nBalance += out.tx->vout[out.i].nValue;
if(total > nBalance)
{
return AmountExceedsBalance;
}
if((total + nTransactionFee) > nBalance)
{
return SendCoinsReturn(AmountWithFeeExceedsBalance, nTransactionFee);
}
{
LOCK2(cs_main, wallet->cs_wallet);
// Sendmany
std::vector<std::pair<CScript, int64> > vecSend;
foreach(const SendCoinsRecipient &rcp, recipients)
{
CScript scriptPubKey;
scriptPubKey.SetDestination(CBitcoinAddress(rcp.address.toStdString()).Get());
vecSend.push_back(make_pair(scriptPubKey, rcp.amount));
}
CWalletTx wtx;
CReserveKey keyChange(wallet);
int64 nFeeRequired = 0;
bool fCreated = wallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, coinControl);
if(!fCreated)
{
if((total + nFeeRequired) > nBalance)
{
return SendCoinsReturn(AmountWithFeeExceedsBalance, nFeeRequired);
}
return TransactionCreationFailed;
}
if(!uiInterface.ThreadSafeAskFee(nFeeRequired, tr("Sending...").toStdString()))
{
return Aborted;
}
if(!wallet->CommitTransaction(wtx, keyChange))
{
return TransactionCommitFailed;
}
hex = QString::fromStdString(wtx.GetHash().GetHex());
}