本文整理汇总了C++中CValidationState::IsInvalid方法的典型用法代码示例。如果您正苦于以下问题:C++ CValidationState::IsInvalid方法的具体用法?C++ CValidationState::IsInvalid怎么用?C++ CValidationState::IsInvalid使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类CValidationState
的用法示例。
在下文中一共展示了CValidationState::IsInvalid方法的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: CommitTransaction
Result CommitTransaction(CWallet* wallet, const uint256& txid, CMutableTransaction&& mtx, std::vector<std::string>& errors, uint256& bumped_txid)
{
LOCK2(cs_main, wallet->cs_wallet);
if (!errors.empty()) {
return Result::MISC_ERROR;
}
auto it = txid.IsNull() ? wallet->mapWallet.end() : wallet->mapWallet.find(txid);
if (it == wallet->mapWallet.end()) {
errors.push_back("Invalid or non-wallet transaction id");
return Result::MISC_ERROR;
}
CWalletTx& oldWtx = it->second;
// make sure the transaction still has no descendants and hasn't been mined in the meantime
Result result = PreconditionChecks(wallet, oldWtx, errors);
if (result != Result::OK) {
return result;
}
CWalletTx wtxBumped(wallet, MakeTransactionRef(std::move(mtx)));
// commit/broadcast the tx
CReserveKey reservekey(wallet);
wtxBumped.mapValue = oldWtx.mapValue;
wtxBumped.mapValue["replaces_txid"] = oldWtx.GetHash().ToString();
wtxBumped.vOrderForm = oldWtx.vOrderForm;
wtxBumped.strFromAccount = oldWtx.strFromAccount;
wtxBumped.fTimeReceivedIsTxTime = true;
wtxBumped.fFromMe = true;
CValidationState state;
if (!wallet->CommitTransaction(wtxBumped, reservekey, g_connman.get(), state)) {
// NOTE: CommitTransaction never returns false, so this should never happen.
errors.push_back(strprintf("The transaction was rejected: %s", state.GetRejectReason()));
return Result::WALLET_ERROR;
}
bumped_txid = wtxBumped.GetHash();
if (state.IsInvalid()) {
// This can happen if the mempool rejected the transaction. Report
// what happened in the "errors" response.
errors.push_back(strprintf("Error: The transaction was rejected: %s", FormatStateMessage(state)));
}
// mark the original tx as bumped
if (!wallet->MarkReplaced(oldWtx.GetHash(), wtxBumped.GetHash())) {
// TODO: see if JSON-RPC has a standard way of returning a response
// along with an exception. It would be good to return information about
// wtxBumped to the caller even if marking the original transaction
// replaced does not succeed for some reason.
errors.push_back("Created new bumpfee transaction but could not mark the original transaction as replaced");
}
return Result::OK;
}
示例2: CScript
/**
* Ensure that the mempool won't accept coinbase transactions.
*/
BOOST_FIXTURE_TEST_CASE(tx_mempool_reject_coinbase, TestChain100Setup)
{
CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;
CMutableTransaction coinbaseTx;
coinbaseTx.nVersion = 1;
coinbaseTx.vin.resize(1);
coinbaseTx.vout.resize(1);
coinbaseTx.vin[0].scriptSig = CScript() << OP_11 << OP_EQUAL;
coinbaseTx.vout[0].nValue = 1 * CENT;
coinbaseTx.vout[0].scriptPubKey = scriptPubKey;
BOOST_CHECK(CTransaction(coinbaseTx).IsCoinBase());
CValidationState state;
LOCK(cs_main);
unsigned int initialPoolSize = mempool.size();
BOOST_CHECK_EQUAL(
false,
AcceptToMemoryPool(mempool, state, MakeTransactionRef(coinbaseTx),
nullptr /* pfMissingInputs */,
nullptr /* plTxnReplaced */,
true /* bypass_limits */,
0 /* nAbsurdFee */));
// Check that the transaction hasn't been added to mempool.
BOOST_CHECK_EQUAL(mempool.size(), initialPoolSize);
// Check that the validation state reflects the unsuccessful attempt.
BOOST_CHECK(state.IsInvalid());
BOOST_CHECK_EQUAL(state.GetRejectReason(), "coinbase");
int nDoS;
BOOST_CHECK_EQUAL(state.IsInvalid(nDoS), true);
BOOST_CHECK_EQUAL(nDoS, 100);
}
示例3: commit
bool CFeeBumper::commit(CWallet *pWallet)
{
AssertLockHeld(pWallet->cs_wallet);
if (!vErrors.empty() || currentResult != BumpFeeResult::OK) {
return false;
}
if (txid.IsNull() || !pWallet->mapWallet.count(txid)) {
vErrors.push_back("Invalid or non-wallet transaction id");
currentResult = BumpFeeResult::MISC_ERROR;
return false;
}
CWalletTx& oldWtx = pWallet->mapWallet[txid];
// make sure the transaction still has no descendants and hasen't been mined in the meantime
if (!preconditionChecks(pWallet, oldWtx)) {
return false;
}
CWalletTx wtxBumped(pWallet, MakeTransactionRef(std::move(mtx)));
// commit/broadcast the tx
CReserveKey reservekey(pWallet);
wtxBumped.mapValue = oldWtx.mapValue;
wtxBumped.mapValue["replaces_txid"] = oldWtx.GetHash().ToString();
wtxBumped.vOrderForm = oldWtx.vOrderForm;
wtxBumped.strFromAccount = oldWtx.strFromAccount;
wtxBumped.fTimeReceivedIsTxTime = true;
wtxBumped.fFromMe = true;
CValidationState state;
if (!pWallet->CommitTransaction(wtxBumped, reservekey, g_connman.get(), state)) {
// NOTE: CommitTransaction never returns false, so this should never happen.
vErrors.push_back(strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason()));
return false;
}
bumpedTxid = wtxBumped.GetHash();
if (state.IsInvalid()) {
// This can happen if the mempool rejected the transaction. Report
// what happened in the "errors" response.
vErrors.push_back(strprintf("Error: The transaction was rejected: %s", FormatStateMessage(state)));
}
// mark the original tx as bumped
if (!pWallet->MarkReplaced(oldWtx.GetHash(), wtxBumped.GetHash())) {
// TODO: see if JSON-RPC has a standard way of returning a response
// along with an exception. It would be good to return information about
// wtxBumped to the caller even if marking the original transaction
// replaced does not succeed for some reason.
vErrors.push_back("Error: Created new bumpfee transaction but could not mark the original transaction as replaced.");
}
return true;
}
示例4: CheckFalse
void CheckFalse(int ndos, const std::string &msg)
{
CValidationState state;
bool ret;
int v;
ret = handler->CheckValid(
CTransaction(transactions[member_hash]), state, NULL);
ret &= handler->CheckFormat(
CTransaction(transactions[member_hash]), state, NULL);
BOOST_CHECK_MESSAGE(
ret == false && state.IsInvalid(v) && v == ndos, msg);
}
示例5: JSONRPCError
// NOTE: Assumes a conclusive result; if result is inconclusive, it must be handled by caller
static UniValue BIP22ValidationResult(const CValidationState& state)
{
if (state.IsValid())
return NullUniValue;
if (state.IsError())
throw JSONRPCError(RPC_VERIFY_ERROR, FormatStateMessage(state));
if (state.IsInvalid())
{
std::string strRejectReason = state.GetRejectReason();
if (strRejectReason.empty())
return "rejected";
return strRejectReason;
}
// Should be impossible
return "valid?";
}
示例6: BlockChecked
void CZMQNotificationInterface::BlockChecked(const CBlock& block, const CValidationState& state)
{
if (state.IsInvalid()) {
return;
}
for (std::list<CZMQAbstractNotifier*>::iterator i = notifiers.begin(); i!=notifiers.end(); )
{
CZMQAbstractNotifier *notifier = *i;
if (notifier->NotifyBlock(block))
{
i++;
}
else
{
notifier->Shutdown();
i = notifiers.erase(i);
}
}
}
示例7: commitMultisigTx
void MultisigDialog::commitMultisigTx()
{
CMutableTransaction tx(multisigTx);
try{
#ifdef ENABLE_WALLET
CWalletTx wtx(pwalletMain, tx);
CReserveKey keyChange(pwalletMain);
if (!pwalletMain->CommitTransaction(wtx, keyChange))
throw runtime_error(string("Transaction rejected - Failed to commit"));
#else
uint256 hashTx = tx.GetHash();
CCoinsViewCache& view = *pcoinsTip;
const CCoins* existingCoins = view.AccessCoins(hashTx);
bool fOverrideFees = false;
bool fHaveMempool = mempool.exists(hashTx);
bool fHaveChain = existingCoins && existingCoins->nHeight < 1000000000;
if (!fHaveMempool && !fHaveChain) {
// push to local node and sync with wallets
CValidationState state;
if (!AcceptToMemoryPool(mempool, state, tx, false, NULL, !fOverrideFees)) {
if (state.IsInvalid())
throw runtime_error(strprintf("Transaction rejected - %i: %s", state.GetRejectCode(), state.GetRejectReason()));
else
throw runtime_error(string("Transaction rejected - ") + state.GetRejectReason());
}
} else if (fHaveChain) {
throw runtime_error("transaction already in block chain");
}
RelayTransaction(tx);
#endif
//disable commit if successfully committed
ui->commitButton->setEnabled(false);
ui->signButtonStatus->setText(strprintf("Transaction has been successfully published with transaction ID:\n %s", tx.GetHash().GetHex()).c_str());
}catch(const runtime_error& e){
ui->signButtonStatus->setText(e.what());
}
}
示例8: CheckInputsAndAdd
bool CMasternodeBroadcast::CheckInputsAndAdd(int& nDoS)
{
// we are a masternode with the same vin (i.e. already activated) and this mnb is ours (matches our Masternode privkey)
// so nothing to do here for us
if(fMasterNode && vin.prevout == activeMasternode.vin.prevout && pubkey2 == activeMasternode.pubKeyMasternode)
return true;
// search existing Masternode list
CMasternode* pmn = mnodeman.Find(vin);
if(pmn != NULL) {
// nothing to do here if we already know about this masternode and it's enabled
if(pmn->IsEnabled()) return true;
// if it's not enabled, remove old MN first and continue
else mnodeman.Remove(pmn->vin);
}
CValidationState state;
CMutableTransaction tx = CMutableTransaction();
CTxOut vout = CTxOut(999.99*COIN, darkSendPool.collateralPubKey);
tx.vin.push_back(vin);
tx.vout.push_back(vout);
{
TRY_LOCK(cs_main, lockMain);
if(!lockMain) {
// not mnb fault, let it to be checked again later
mnodeman.mapSeenMasternodeBroadcast.erase(GetHash());
masternodeSync.mapSeenSyncMNB.erase(GetHash());
return false;
}
if(!AcceptableInputs(mempool, state, CTransaction(tx), false, NULL)) {
//set nDos
state.IsInvalid(nDoS);
return false;
}
}
LogPrint("masternode", "mnb - Accepted Masternode entry\n");
if(GetInputAge(vin) < MASTERNODE_MIN_CONFIRMATIONS){
LogPrintf("mnb - Input must have at least %d confirmations\n", MASTERNODE_MIN_CONFIRMATIONS);
// maybe we miss few blocks, let this mnb to be checked again later
mnodeman.mapSeenMasternodeBroadcast.erase(GetHash());
masternodeSync.mapSeenSyncMNB.erase(GetHash());
return false;
}
// verify that sig time is legit in past
// should be at least not earlier than block when 1000 DASH tx got MASTERNODE_MIN_CONFIRMATIONS
uint256 hashBlock = 0;
CTransaction tx2;
GetTransaction(vin.prevout.hash, tx2, hashBlock, true);
BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
if (mi != mapBlockIndex.end() && (*mi).second)
{
CBlockIndex* pMNIndex = (*mi).second; // block for 1000 DASH tx -> 1 confirmation
CBlockIndex* pConfIndex = chainActive[pMNIndex->nHeight + MASTERNODE_MIN_CONFIRMATIONS - 1]; // block where tx got MASTERNODE_MIN_CONFIRMATIONS
if(pConfIndex->GetBlockTime() > sigTime)
{
LogPrintf("mnb - Bad sigTime %d for Masternode %20s %105s (%i conf block is at %d)\n",
sigTime, addr.ToString(), vin.ToString(), MASTERNODE_MIN_CONFIRMATIONS, pConfIndex->GetBlockTime());
return false;
}
}
LogPrintf("mnb - Got NEW Masternode entry - %s - %s - %s - %lli \n", GetHash().ToString(), addr.ToString(), vin.ToString(), sigTime);
CMasternode mn(*this);
mnodeman.Add(mn);
// if it matches our Masternode privkey, then we've been remotely activated
if(pubkey2 == activeMasternode.pubKeyMasternode && protocolVersion == PROTOCOL_VERSION){
activeMasternode.EnableHotColdMasterNode(vin, addr);
}
bool isLocal = addr.IsRFC1918() || addr.IsLocal();
if(Params().NetworkID() == CBaseChainParams::REGTEST) isLocal = false;
if(!isLocal) Relay();
return true;
}
示例9: ProcessMessageMasternode
//.........这里部分代码省略.........
std::string strMessage = addr.ToString() + boost::lexical_cast<std::string>(sigTime) + vchPubKey + vchPubKey2;
CScript pubkeyScript2;
pubkeyScript2.SetDestination(pubkey2.GetID());
if(pubkeyScript2.size() != 25) {
LogPrintf("dsee - pubkey the wrong size\n");
pfrom->Misbehaving(100);
return;
}
std::string errorMessage = "";
if(!darkSendSigner.VerifyMessage(pubkey, vchSig, strMessage, errorMessage)){
LogPrintf("dsee - Got bad masternode address signature\n");
pfrom->Misbehaving(100);
return;
}
if((fTestNet && addr.GetPort() != 19999) || (!fTestNet && addr.GetPort() != 9999)) return;
//LogPrintf("Searching existing masternodes : %s - %s\n", addr.ToString().c_str(), vin.ToString().c_str());
BOOST_FOREACH(CMasterNode& mn, darkSendMasterNodes) {
//LogPrintf(" -- %s\n", mn.vin.ToString().c_str());
if(mn.vin.prevout == vin.prevout) {
//count == -1 when it's a new entry
// e.g. We don't want the entry relayed/time updated when we're syncing the list
if(count == -1 && !mn.UpdatedWithin(MASTERNODE_MIN_SECONDS)){
mn.UpdateLastSeen();
if(mn.now < sigTime){ //take the newest entry
LogPrintf("dsee - Got updated entry for %s\n", addr.ToString().c_str());
mn.pubkey2 = pubkey2;
mn.now = sigTime;
mn.sig = vchSig;
if(pubkey2 == activeMasternode.pubkeyMasterNode2){
activeMasternode.EnableHotColdMasterNode(vin, sigTime, addr);
}
RelayDarkSendElectionEntry(vin, addr, vchSig, sigTime, pubkey, pubkey2, count, current, lastUpdated);
}
}
return;
}
}
if(!darkSendSigner.IsVinAssociatedWithPubkey(vin, pubkey)) {
LogPrintf("dsee - Got mismatched pubkey and vin\n");
pfrom->Misbehaving(100);
return;
}
LogPrintf("dsee - Got NEW masternode entry %s\n", addr.ToString().c_str());
CValidationState state;
CTransaction tx = CTransaction();
CTxOut vout = CTxOut(999.99*COIN, darkSendPool.collateralPubKey);
tx.vin.push_back(vin);
tx.vout.push_back(vout);
if(tx.AcceptableInputs(state, true)){
LogPrintf("dsee - Accepted masternode entry %i %i\n", count, current);
if(GetInputAge(vin) < MASTERNODE_MIN_CONFIRMATIONS){
LogPrintf("dsee - Input must have least %d confirmations\n", MASTERNODE_MIN_CONFIRMATIONS);
pfrom->Misbehaving(20);
return;
}
addrman.Add(CAddress(addr), pfrom->addr, 2*60*60);
CMasterNode mn(addr, vin, pubkey, vchSig, sigTime, pubkey2);
mn.UpdateLastSeen(lastUpdated);
darkSendMasterNodes.push_back(mn);
if(pubkey2 == activeMasternode.pubkeyMasterNode2){
activeMasternode.EnableHotColdMasterNode(vin, sigTime, addr);
}
if(count == -1 && !isLocal)
RelayDarkSendElectionEntry(vin, addr, vchSig, sigTime, pubkey, pubkey2, count, current, lastUpdated);
} else {
LogPrintf("dsee - Rejected masternode entry\n");
int nDoS = 0;
if (state.IsInvalid(nDoS))
{
LogPrintf("dsee - %s from %s %s was not accepted into the memory pool\n", tx.GetHash().ToString().c_str(),
pfrom->addr.ToString().c_str(), pfrom->cleanSubVer.c_str());
if (nDoS > 0)
pfrom->Misbehaving(nDoS);
}
}
}
else if (strCommand == "dseep") { //DarkSend Election Entry Ping
示例10: ProcessMessageMasternode
//.........这里部分代码省略.........
Misbehaving(pfrom->GetId(), 100);
return;
}
std::string errorMessage = "";
if(!darkSendSigner.VerifyMessage(pubkey, vchSig, strMessage, errorMessage)){
LogPrintf("dsee - Got bad masternode address signature\n");
Misbehaving(pfrom->GetId(), 100);
return;
}
//search existing masternode list, this is where we update existing masternodes with new dsee broadcasts
LOCK(cs_masternodes);
BOOST_FOREACH(CMasterNode& mn, vecMasternodes) {
if(mn.vin.prevout == vin.prevout) {
// count == -1 when it's a new entry
// e.g. We don't want the entry relayed/time updated when we're syncing the list
// mn.pubkey = pubkey, IsVinAssociatedWithPubkey is validated once below,
// after that they just need to match
if(count == -1 && mn.pubkey == pubkey && !mn.UpdatedWithin(MASTERNODE_MIN_DSEE_SECONDS)){
mn.UpdateLastSeen();
if(mn.now < sigTime){ //take the newest entry
LogPrintf("dsee - Got updated entry for %s\n", addr.ToString().c_str());
mn.pubkey2 = pubkey2;
mn.now = sigTime;
mn.sig = vchSig;
mn.protocolVersion = protocolVersion;
mn.addr = addr;
RelayDarkSendElectionEntry(vin, addr, vchSig, sigTime, pubkey, pubkey2, count, current, lastUpdated, protocolVersion);
}
}
return;
}
}
// make sure the vout that was signed is related to the transaction that spawned the masternode
// - this is expensive, so it's only done once per masternode
if(!darkSendSigner.IsVinAssociatedWithPubkey(vin, pubkey)) {
LogPrintf("dsee - Got mismatched pubkey and vin\n");
Misbehaving(pfrom->GetId(), 100);
return;
}
if(fDebug) LogPrintf("dsee - Got NEW masternode entry %s\n", addr.ToString().c_str());
// make sure it's still unspent
// - this is checked later by .check() in many places and by ThreadCheckDarkSendPool()
CValidationState state;
CTransaction tx = CTransaction();
CTxOut vout = CTxOut((GetMNCollateral(pindexBest->nHeight)-1)*COIN, darkSendPool.collateralPubKey);
tx.vin.push_back(vin);
tx.vout.push_back(vout);
//if(AcceptableInputs(mempool, state, tx)){
bool* pfMissingInputs = false;
if(AcceptableInputs(mempool, tx, false, pfMissingInputs)){
if(fDebug) LogPrintf("dsee - Accepted masternode entry %i %i\n", count, current);
if(GetInputAge(vin) < MASTERNODE_MIN_CONFIRMATIONS){
LogPrintf("dsee - Input must have least %d confirmations\n", MASTERNODE_MIN_CONFIRMATIONS);
Misbehaving(pfrom->GetId(), 20);
return;
}
// use this as a peer
addrman.Add(CAddress(addr), pfrom->addr, 2*60*60);
// add our masternode
CMasterNode mn(addr, vin, pubkey, vchSig, sigTime, pubkey2, protocolVersion);
mn.UpdateLastSeen(lastUpdated);
vecMasternodes.push_back(mn);
// if it matches our masternodeprivkey, then we've been remotely activated
if(pubkey2 == activeMasternode.pubKeyMasternode && protocolVersion == PROTOCOL_VERSION){
activeMasternode.EnableHotColdMasterNode(vin, addr);
}
if(count == -1 && !isLocal)
RelayDarkSendElectionEntry(vin, addr, vchSig, sigTime, pubkey, pubkey2, count, current, lastUpdated, protocolVersion);
} else {
LogPrintf("dsee - Rejected masternode entry %s\n", addr.ToString().c_str());
int nDoS = 0;
if (state.IsInvalid(nDoS))
{
LogPrintf("dsee - %s from %s %s was not accepted into the memory pool\n", tx.GetHash().ToString().c_str(),
pfrom->addr.ToString().c_str(), pfrom->cleanSubVer.c_str());
if (nDoS > 0)
Misbehaving(pfrom->GetId(), nDoS);
}
}
}
else if (strCommand == "dseep") { //DarkSend Election Entry Ping
示例11: sendrawtransaction
UniValue sendrawtransaction(const JSONRPCRequest& request)
{
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
throw std::runtime_error(
"sendrawtransaction \"hexstring\" ( allowhighfees )\n"
"\nSubmits raw transaction (serialized, hex-encoded) to local node and network.\n"
"\nAlso see createrawtransaction and signrawtransaction calls.\n"
"\nArguments:\n"
"1. \"hexstring\" (string, required) The hex string of the raw transaction)\n"
"2. allowhighfees (boolean, optional, default=false) Allow high fees\n"
"\nResult:\n"
"\"hex\" (string) The transaction hash in hex\n"
"\nExamples:\n"
"\nCreate a transaction\n"
+ HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" \"{\\\"myaddress\\\":0.01}\"") +
"Sign the transaction, and get back the hex\n"
+ HelpExampleCli("signrawtransaction", "\"myhex\"") +
"\nSend the transaction (signed hex)\n"
+ HelpExampleCli("sendrawtransaction", "\"signedhex\"") +
"\nAs a json rpc call\n"
+ HelpExampleRpc("sendrawtransaction", "\"signedhex\"")
);
ObserveSafeMode();
LOCK(cs_main);
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL});
// parse hex string from parameter
CMutableTransaction mtx;
if (!DecodeHexTx(mtx, request.params[0].get_str()))
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
CTransactionRef tx(MakeTransactionRef(std::move(mtx)));
const uint256& hashTx = tx->GetHash();
CAmount nMaxRawTxFee = maxTxFee;
if (!request.params[1].isNull() && request.params[1].get_bool())
nMaxRawTxFee = 0;
CCoinsViewCache &view = *pcoinsTip;
bool fHaveChain = false;
for (size_t o = 0; !fHaveChain && o < tx->vout.size(); o++) {
const Coin& existingCoin = view.AccessCoin(COutPoint(hashTx, o));
fHaveChain = !existingCoin.IsSpent();
}
bool fHaveMempool = mempool.exists(hashTx);
if (!fHaveMempool && !fHaveChain) {
// push to local node and sync with wallets
CValidationState state;
bool fMissingInputs;
bool fLimitFree = true;
if (!AcceptToMemoryPool(mempool, state, std::move(tx), fLimitFree, &fMissingInputs, nullptr, false, nMaxRawTxFee)) {
if (state.IsInvalid()) {
throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason()));
} else {
if (fMissingInputs) {
throw JSONRPCError(RPC_TRANSACTION_ERROR, "Missing inputs");
}
throw JSONRPCError(RPC_TRANSACTION_ERROR, state.GetRejectReason());
}
}
} else if (fHaveChain) {
throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN, "transaction already in block chain");
}
if(!g_connman)
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
CInv inv(MSG_TX, hashTx);
g_connman->ForEachNode([&inv](CNode* pnode)
{
pnode->PushInventory(inv);
});
return hashTx.GetHex();
}