Merge pull request #297 from svost/patch
authorCryptoManiac <CryptoManiac@users.noreply.github.com>
Sat, 2 Apr 2016 14:50:17 +0000 (17:50 +0300)
committerCryptoManiac <CryptoManiac@users.noreply.github.com>
Sat, 2 Apr 2016 14:50:17 +0000 (17:50 +0300)
Minor fix

src/bitcoinrpc.cpp
src/bitcoinrpc.h
src/key.cpp
src/rpcwallet.cpp
src/wallet.cpp
src/wallet.h

index 56ac4ef..60baac0 100644 (file)
@@ -237,97 +237,97 @@ Value stop(const Array& params, bool fHelp)
 static const CRPCCommand vRPCCommands[] =
 { //  name                      function                 safemd  unlocked
   //  ------------------------  -----------------------  ------  --------
-    { "help",                   &help,                   true,   true },
-    { "stop",                   &stop,                   true,   true },
-    { "getbestblockhash",       &getbestblockhash,       true,   false },
-    { "getblockcount",          &getblockcount,          true,   false },
-    { "getconnectioncount",     &getconnectioncount,     true,   false },
-    { "getaddrmaninfo",         &getaddrmaninfo,         true,   false },
-    { "getpeerinfo",            &getpeerinfo,            true,   false },
-    { "addnode",                &addnode,                true,   true  },
-    { "getaddednodeinfo",       &getaddednodeinfo,       true,   true  },
-    { "getdifficulty",          &getdifficulty,          true,   false },
-    { "getinfo",                &getinfo,                true,   false },
-    { "getsubsidy",             &getsubsidy,             true,   false },
-    { "getmininginfo",          &getmininginfo,          true,   false },
-    { "scaninput",              &scaninput,              true,   true },
-    { "getnewaddress",          &getnewaddress,          true,   false },
-    { "getnettotals",           &getnettotals,           true,   true  },
-    { "ntptime",                &ntptime,                true,   true  },
-    { "getaccountaddress",      &getaccountaddress,      true,   false },
-    { "setaccount",             &setaccount,             true,   false },
-    { "getaccount",             &getaccount,             false,  false },
-    { "getaddressesbyaccount",  &getaddressesbyaccount,  true,   false },
-    { "sendtoaddress",          &sendtoaddress,          false,  false },
-    { "mergecoins",             &mergecoins,             false,  false },
-    { "getreceivedbyaddress",   &getreceivedbyaddress,   false,  false },
-    { "getreceivedbyaccount",   &getreceivedbyaccount,   false,  false },
-    { "listreceivedbyaddress",  &listreceivedbyaddress,  false,  false },
-    { "listreceivedbyaccount",  &listreceivedbyaccount,  false,  false },
-    { "backupwallet",           &backupwallet,           true,   false },
-    { "keypoolrefill",          &keypoolrefill,          true,   false },
-    { "keypoolreset",           &keypoolreset,           true,   false },
-    { "walletpassphrase",       &walletpassphrase,       true,   false },
-    { "walletpassphrasechange", &walletpassphrasechange, false,  false },
-    { "walletlock",             &walletlock,             true,   false },
-    { "encryptwallet",          &encryptwallet,          false,  false },
-    { "validateaddress",        &validateaddress,        true,   false },
-    { "getbalance",             &getbalance,             false,  false },
-    { "move",                   &movecmd,                false,  false },
-    { "sendfrom",               &sendfrom,               false,  false },
-    { "sendmany",               &sendmany,               false,  false },
-    { "addmultisigaddress",     &addmultisigaddress,     false,  false },
-    { "addredeemscript",        &addredeemscript,        false,  false },
-    { "getrawmempool",          &getrawmempool,          true,   false },
-    { "getblock",               &getblock,               false,  false },
-    { "getblockbynumber",       &getblockbynumber,       false,  false },
-    { "dumpblock",              &dumpblock,              false,  false },
-    { "dumpblockbynumber",      &dumpblockbynumber,      false,  false },
-    { "getblockhash",           &getblockhash,           false,  false },
-    { "gettransaction",         &gettransaction,         false,  false },
-    { "listtransactions",       &listtransactions,       false,  false },
-    { "listaddressgroupings",   &listaddressgroupings,   false,  false },
-    { "signmessage",            &signmessage,            false,  false },
-    { "verifymessage",          &verifymessage,          false,  false },
-    { "getwork",                &getwork,                true,   false },
-    { "getworkex",              &getworkex,              true,   false },
-    { "listaccounts",           &listaccounts,           false,  false },
-    { "settxfee",               &settxfee,               false,  false },
-    { "getblocktemplate",       &getblocktemplate,       true,   false },
-    { "submitblock",            &submitblock,            false,  false },
-    { "listsinceblock",         &listsinceblock,         false,  false },
-    { "dumpprivkey",            &dumpprivkey,            false,  false },
-    { "dumppem",                &dumppem,                true,   false },
-    { "dumpwallet",             &dumpwallet,             true,   false },
-    { "importwallet",           &importwallet,           false,  false },
-    { "importprivkey",          &importprivkey,          false,  false },
-    { "importaddress",          &importaddress,          false,  true  },
-    { "removeaddress",          &removeaddress,          false,  true  },
-    { "listunspent",            &listunspent,            false,  false },
-    { "getrawtransaction",      &getrawtransaction,      false,  false },
-    { "createrawtransaction",   &createrawtransaction,   false,  false },
-    { "decoderawtransaction",   &decoderawtransaction,   false,  false },
-    { "createmultisig",         &createmultisig,         false,  false },
-    { "decodescript",           &decodescript,           false,  false },
-    { "signrawtransaction",     &signrawtransaction,     false,  false },
-    { "sendrawtransaction",     &sendrawtransaction,     false,  false },
-    { "getcheckpoint",          &getcheckpoint,          true,   false },
-    { "reservebalance",         &reservebalance,         false,  true},
-    { "checkwallet",            &checkwallet,            false,  true},
-    { "repairwallet",           &repairwallet,           false,  true},
-    { "resendtx",               &resendtx,               false,  true},
-    { "makekeypair",            &makekeypair,            false,  true},
-    { "newmalleablekey",        &newmalleablekey,        false,  false},
-    { "adjustmalleablekey",     &adjustmalleablekey,     false,  false},
-    { "adjustmalleablepubkey",  &adjustmalleablepubkey,  false,  false},
-    { "listmalleableviews",     &listmalleableviews,     false,  false},
-    { "dumpmalleablekey",       &dumpmalleablekey,       false,  false},
-    { "importmalleablekey",     &importmalleablekey,     true,   false },
-    { "encryptdata",            &encryptdata,            false,  false },
-    { "decryptdata",            &decryptdata,            false,  false },
-    { "encryptmessage",         &encryptmessage,         false,  false },
-    { "decryptmessage",         &decryptmessage,         false,  false },
-    { "sendalert",              &sendalert,              false,  false},
+    { "help",                       &help,                        true,   true },
+    { "stop",                       &stop,                        true,   true },
+    { "getbestblockhash",           &getbestblockhash,            true,   false },
+    { "getblockcount",              &getblockcount,               true,   false },
+    { "getconnectioncount",         &getconnectioncount,          true,   false },
+    { "getaddrmaninfo",             &getaddrmaninfo,              true,   false },
+    { "getpeerinfo",                &getpeerinfo,                 true,   false },
+    { "addnode",                    &addnode,                     true,   true  },
+    { "getaddednodeinfo",           &getaddednodeinfo,            true,   true  },
+    { "getdifficulty",              &getdifficulty,               true,   false },
+    { "getinfo",                    &getinfo,                     true,   false },
+    { "getsubsidy",                 &getsubsidy,                  true,   false },
+    { "getmininginfo",              &getmininginfo,               true,   false },
+    { "scaninput",                  &scaninput,                   true,   true },
+    { "getnewaddress",              &getnewaddress,               true,   false },
+    { "getnettotals",               &getnettotals,                true,   true  },
+    { "ntptime",                    &ntptime,                     true,   true  },
+    { "getaccountaddress",          &getaccountaddress,           true,   false },
+    { "setaccount",                 &setaccount,                  true,   false },
+    { "getaccount",                 &getaccount,                  false,  false },
+    { "getaddressesbyaccount",      &getaddressesbyaccount,       true,   false },
+    { "sendtoaddress",              &sendtoaddress,               false,  false },
+    { "mergecoins",                 &mergecoins,                  false,  false },
+    { "getreceivedbyaddress",       &getreceivedbyaddress,        false,  false },
+    { "getreceivedbyaccount",       &getreceivedbyaccount,        false,  false },
+    { "listreceivedbyaddress",      &listreceivedbyaddress,       false,  false },
+    { "listreceivedbyaccount",      &listreceivedbyaccount,       false,  false },
+    { "backupwallet",               &backupwallet,                true,   false },
+    { "keypoolrefill",              &keypoolrefill,               true,   false },
+    { "keypoolreset",               &keypoolreset,                true,   false },
+    { "walletpassphrase",           &walletpassphrase,            true,   false },
+    { "walletpassphrasechange",     &walletpassphrasechange,      false,  false },
+    { "walletlock",                 &walletlock,                  true,   false },
+    { "encryptwallet",              &encryptwallet,               false,  false },
+    { "validateaddress",            &validateaddress,             true,   false },
+    { "getbalance",                 &getbalance,                  false,  false },
+    { "move",                       &movecmd,                     false,  false },
+    { "sendfrom",                   &sendfrom,                    false,  false },
+    { "sendmany",                   &sendmany,                    false,  false },
+    { "addmultisigaddress",         &addmultisigaddress,          false,  false },
+    { "addredeemscript",            &addredeemscript,             false,  false },
+    { "getrawmempool",              &getrawmempool,               true,   false },
+    { "getblock",                   &getblock,                    false,  false },
+    { "getblockbynumber",           &getblockbynumber,            false,  false },
+    { "dumpblock",                  &dumpblock,                   false,  false },
+    { "dumpblockbynumber",          &dumpblockbynumber,           false,  false },
+    { "getblockhash",               &getblockhash,                false,  false },
+    { "gettransaction",             &gettransaction,              false,  false },
+    { "listtransactions",           &listtransactions,            false,  false },
+    { "listaddressgroupings",       &listaddressgroupings,        false,  false },
+    { "signmessage",                &signmessage,                 false,  false },
+    { "verifymessage",              &verifymessage,               false,  false },
+    { "getwork",                    &getwork,                     true,   false },
+    { "getworkex",                  &getworkex,                   true,   false },
+    { "listaccounts",               &listaccounts,                false,  false },
+    { "settxfee",                   &settxfee,                    false,  false },
+    { "getblocktemplate",           &getblocktemplate,            true,   false },
+    { "submitblock",                &submitblock,                 false,  false },
+    { "listsinceblock",             &listsinceblock,              false,  false },
+    { "dumpprivkey",                &dumpprivkey,                 false,  false },
+    { "dumppem",                    &dumppem,                     true,   false },
+    { "dumpwallet",                 &dumpwallet,                  true,   false },
+    { "importwallet",               &importwallet,                false,  false },
+    { "importprivkey",              &importprivkey,               false,  false },
+    { "importaddress",              &importaddress,               false,  true  },
+    { "removeaddress",              &removeaddress,               false,  true  },
+    { "listunspent",                &listunspent,                 false,  false },
+    { "getrawtransaction",          &getrawtransaction,           false,  false },
+    { "createrawtransaction",       &createrawtransaction,        false,  false },
+    { "decoderawtransaction",       &decoderawtransaction,        false,  false },
+    { "createmultisig",             &createmultisig,              false,  false },
+    { "decodescript",               &decodescript,                false,  false },
+    { "signrawtransaction",         &signrawtransaction,          false,  false },
+    { "sendrawtransaction",         &sendrawtransaction,          false,  false },
+    { "getcheckpoint",              &getcheckpoint,               true,   false },
+    { "reservebalance",             &reservebalance,              false,  true},
+    { "checkwallet",                &checkwallet,                 false,  true},
+    { "repairwallet",               &repairwallet,                false,  true},
+    { "resendwallettransactions",   &resendwallettransactions,    false,  true},
+    { "makekeypair",                &makekeypair,                 false,  true},
+    { "newmalleablekey",            &newmalleablekey,             false,  false},
+    { "adjustmalleablekey",         &adjustmalleablekey,          false,  false},
+    { "adjustmalleablepubkey",      &adjustmalleablepubkey,       false,  false},
+    { "listmalleableviews",         &listmalleableviews,          false,  false},
+    { "dumpmalleablekey",           &dumpmalleablekey,            false,  false},
+    { "importmalleablekey",         &importmalleablekey,          true,   false },
+    { "encryptdata",                &encryptdata,                 false,  false },
+    { "decryptdata",                &decryptdata,                 false,  false },
+    { "encryptmessage",             &encryptmessage,              false,  false },
+    { "decryptmessage",             &decryptmessage,              false,  false },
+    { "sendalert",                  &sendalert,                   false,  false},
 };
 
 CRPCTable::CRPCTable()
index 3c9106b..6c707ea 100644 (file)
@@ -203,7 +203,7 @@ extern json_spirit::Value getinfo(const json_spirit::Array& params, bool fHelp);
 extern json_spirit::Value reservebalance(const json_spirit::Array& params, bool fHelp);
 extern json_spirit::Value checkwallet(const json_spirit::Array& params, bool fHelp);
 extern json_spirit::Value repairwallet(const json_spirit::Array& params, bool fHelp);
-extern json_spirit::Value resendtx(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value resendwallettransactions(const json_spirit::Array& params, bool fHelp);
 extern json_spirit::Value makekeypair(const json_spirit::Array& params, bool fHelp);
 extern json_spirit::Value mergecoins(const json_spirit::Array& params, bool fHelp);
 extern json_spirit::Value newmalleablekey(const json_spirit::Array& params, bool fHelp);
index 1c700d0..355d6dd 100644 (file)
@@ -761,6 +761,8 @@ bool CMalleablePubKey::SetString(const std::string& strMalleablePubKey)
     if (!DecodeBase58Check(strMalleablePubKey, vchTemp)) {
         throw key_error("CMalleablePubKey::SetString() : Provided key data seems corrupted.");
     }
+    if (vchTemp.size() != 68)
+        return false;
 
     CDataStream ssKey(vchTemp, SER_NETWORK, PROTOCOL_VERSION);
     ssKey >> *this;
@@ -1028,7 +1030,8 @@ bool CMalleableKey::SetString(const std::string& strMutableKey)
     if (!DecodeBase58Check(strMutableKey, vchTemp)) {
         throw key_error("CMalleableKey::SetString() : Provided key data seems corrupted.");
     }
-
+    if (vchTemp.size() != 66)
+        return false;
     CDataStream ssKey(vchTemp, SER_NETWORK, PROTOCOL_VERSION);
     ssKey >> *this;
 
@@ -1172,6 +1175,9 @@ bool CMalleableKeyView::SetString(const std::string& strMutableKey)
         throw key_error("CMalleableKeyView::SetString() : Provided key data seems corrupted.");
     }
 
+    if (vchTemp.size() != 67)
+        return false;
+
     CDataStream ssKey(vchTemp, SER_NETWORK, PROTOCOL_VERSION);
     ssKey >> *this;
 
index aa91f7f..757e7f4 100644 (file)
@@ -1744,6 +1744,7 @@ Value validateaddress(const Array& params, bool fHelp)
             CMalleableKeyView view;
             bool isMine = pwalletMain->GetMalleableView(mpk, view);
             ret.push_back(Pair("ismine", isMine));
+            ret.push_back(Pair("PubkeyPair", mpk.ToString()));
 
             if (isMine)
                 ret.push_back(Pair("KeyView", view.ToString()));
@@ -1867,6 +1868,29 @@ Value resendtx(const Array& params, bool fHelp)
     return Value::null;
 }
 
+Value resendwallettransactions(const Array& params, bool fHelp)
+{
+    if (fHelp || params.size() != 0)
+        throw runtime_error(
+            "resendwallettransactions\n"
+            "Immediately re-broadcast unconfirmed wallet transactions to all peers.\n"
+            "Intended only for testing; the wallet code periodically re-broadcasts\n"
+            "automatically.\n"
+            "Returns array of transaction ids that were re-broadcast.\n"
+            );
+
+    LOCK2(cs_main, pwalletMain->cs_wallet);
+
+    std::vector<uint256> txids = pwalletMain->ResendWalletTransactionsBefore(GetTime());
+    Array result;
+    BOOST_FOREACH(const uint256& txid, txids)
+    {
+        result.push_back(txid.ToString());
+    }
+    return result;
+}
+
+
 // Make a public-private key pair
 Value makekeypair(const Array& params, bool fHelp)
 {
@@ -1958,16 +1982,34 @@ Value adjustmalleablepubkey(const Array& params, bool fHelp)
 {
     if (fHelp || params.size() > 2 || params.size() == 0)
         throw runtime_error(
-            "adjustmalleablepubkey <Malleable public key data>\n"
-            "Calculate new public key using provided malleable public key data.\n");
+            "adjustmalleablepubkey <Malleable address, key view or public key pair>\n"
+            "Calculate new public key using provided data.\n");
 
-    string pubKeyPair = params[0].get_str();
+    string strData = params[0].get_str();
     CMalleablePubKey malleablePubKey;
 
-    if (pubKeyPair.size() == 136) {
-        malleablePubKey.setvch(ParseHex(pubKeyPair));
-    } else
-        malleablePubKey.SetString(pubKeyPair);
+    do
+    {
+        CBitcoinAddress addr(strData);
+        if (addr.IsValid() && addr.IsPair())
+        {
+            // Initialize malleable pubkey with address data
+            malleablePubKey = CMalleablePubKey(addr.GetData());
+            break;
+        }
+        CMalleableKeyView viewTmp(strData);
+        if (viewTmp.IsValid())
+        {
+            // Shazaam, we have a valid key view here.
+            malleablePubKey = viewTmp.GetMalleablePubKey();
+            break;
+        }
+        if (malleablePubKey.SetString(strData))
+            break; // A valid public key pair
+
+        throw runtime_error("Though your data seems a valid Base58 string, we were unable to recognize it.");
+    }
+    while(false);
 
     CPubKey R, vchPubKeyVariant;
     malleablePubKey.GetVariant(R, vchPubKeyVariant);
index 1d735d3..0d0cf99 100644 (file)
@@ -1485,83 +1485,83 @@ void CWallet::ReacceptWalletTransactions()
     }
 }
 
-void CWalletTx::RelayWalletTransaction(CTxDB& txdb)
+bool CWalletTx::RelayWalletTransaction(CTxDB& txdb)
 {
-    BOOST_FOREACH(const CMerkleTx& tx, vtxPrev)
-    {
-        if (!(tx.IsCoinBase() || tx.IsCoinStake()))
-        {
-            uint256 hash = tx.GetHash();
-            if (!txdb.ContainsTx(hash))
-                RelayTransaction((CTransaction)tx, hash);
-        }
-    }
-    if (!(IsCoinBase() || IsCoinStake()))
+    uint256 hash = GetHash();
+    if (IsCoinBase() || IsCoinStake() || txdb.ContainsTx(hash) || !InMempool())
+        return false;
+
+    for(std::vector<CMerkleTx>::const_iterator it = vtxPrev.begin(); it != vtxPrev.end(); it++)
     {
-        uint256 hash = GetHash();
+        const CMerkleTx& tx = *it;
+        uint256 hash = tx.GetHash();
+
+        if (tx.IsCoinBase() || tx.IsCoinStake())
+            continue;
+
         if (!txdb.ContainsTx(hash))
-        {
-            printf("Relaying wtx %s\n", hash.ToString().substr(0,10).c_str());
-            RelayTransaction((CTransaction)*this, hash);
-        }
+            RelayTransaction((CTransaction)tx, hash);
     }
+
+    printf("Relaying wtx %s\n", hash.ToString().substr(0,10).c_str());
+    RelayTransaction((CTransaction)*this, hash);
+    return true;
 }
 
-void CWalletTx::RelayWalletTransaction()
+bool CWalletTx::RelayWalletTransaction()
 {
    CTxDB txdb("r");
-   RelayWalletTransaction(txdb);
+   return RelayWalletTransaction(txdb);
 }
 
-void CWallet::ResendWalletTransactions(bool fForceResend)
+std::vector<uint256> CWallet::ResendWalletTransactionsBefore(int64_t nTime)
 {
-    if (!fForceResend) {
-        // Do this infrequently and randomly to avoid giving away
-        // that these are our transactions.
-        static int64_t nNextTime = GetRand(GetTime() + 30 * 60);
-        if (GetTime() < nNextTime)
-            return;
-        bool fFirst = (nNextTime == 0);
-        nNextTime = GetTime() + GetRand(30 * 60);
-        if (fFirst)
-            return;
+    std::vector<uint256> result;
 
-        // Only do it if there's been a new block since last time
-        static int64_t nLastTime = 0;
-        if (nTimeBestReceived < nLastTime)
-            return;
-        nLastTime = GetTime();
+    LOCK(cs_wallet);
+    // Sort them in chronological order
+    map<unsigned int, CWalletTx*> mapSorted;
+    BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
+    {
+        CWalletTx& wtx = item.second;
+        // Don't rebroadcast if newer than nTime:
+        if (wtx.nTimeReceived > nTime)
+            continue;
+        mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx));
     }
-
-    // Rebroadcast any of our txes that aren't in a block yet
-    printf("ResendWalletTransactions()\n");
-    CTxDB txdb("r");
+    BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted)
     {
-        LOCK(cs_wallet);
-        // Sort them in chronological order
-        multimap<unsigned int, CWalletTx*> mapSorted;
-        BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
-        {
-            CWalletTx& wtx = item.second;
-            // Don't rebroadcast until it's had plenty of time that
-            // it should have gotten in already by now.
-            if (fForceResend || nTimeBestReceived - (int64_t)wtx.nTimeReceived > 5 * 60)
-                mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx));
-        }
-        BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted)
-        {
-            CWalletTx& wtx = *item.second;
-            if (wtx.CheckTransaction())
-                wtx.RelayWalletTransaction(txdb);
-            else
-                printf("ResendWalletTransactions() : CheckTransaction failed for transaction %s\n", wtx.GetHash().ToString().c_str());
-        }
+        CWalletTx& wtx = *item.second;
+        if (wtx.RelayWalletTransaction())
+            result.push_back(wtx.GetHash());
     }
+    return result;
 }
 
+void CWallet::ResendWalletTransactions(int64_t nBestBlockTime)
+{
+    int64_t nNow = GetTime();
 
+    // Do this infrequently and randomly to avoid giving away
+    // that these are our transactions.
+    if (nNow < nNextResend)
+        return;
+    bool fFirst = (nNextResend == 0);
+    nNextResend = PoissonNextSend(nNow, 5*60);
+    if (fFirst)
+        return;
 
+    // Only do it if there's been a new block since last time
+    if (nBestBlockTime < nLastResend)
+        return;
+    nLastResend = nNow;
 
+    // Rebroadcast unconfirmed txes older than 5 minutes before the last
+    // block was found:
+    std::vector<uint256> relayed = ResendWalletTransactionsBefore(nBestBlockTime - 5*60);
+    if (!relayed.empty())
+        printf("CWallet::ResendWalletTransactions: rebroadcast %" PRIszu " unconfirmed transactions\n", relayed.size());
+}
 
 
 //////////////////////////////////////////////////////////////////////////////
index 2b1774a..26cf745 100644 (file)
@@ -85,6 +85,9 @@ private:
     // the maximum wallet format version: memory-only variable that specifies to what version this wallet may be upgraded
     int nWalletMaxVersion;
 
+    int64_t nNextResend;
+    int64_t nLastResend;
+
     // stake mining statistics
     uint64_t nKernelsTried;
     uint64_t nCoinDaysTried;
@@ -126,6 +129,8 @@ public:
         nMasterKeyMaxID = 0;
         pwalletdbEncryption = NULL;
         pwalletdbDecryption = NULL;
+        nNextResend = 0;
+        nLastResend = 0;
         nOrderPosNext = 0;
         nKernelsTried = 0;
         nCoinDaysTried = 0;
@@ -219,7 +224,8 @@ public:
     int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false);
     int ScanForWalletTransaction(const uint256& hashTx);
     void ReacceptWalletTransactions();
-    void ResendWalletTransactions(bool fForceResend=false);
+    void ResendWalletTransactions(int64_t nBestBlockTime);
+    std::vector<uint256> ResendWalletTransactionsBefore(int64_t nTime);
     int64_t GetBalance() const;
     int64_t GetWatchOnlyBalance() const;
     int64_t GetUnconfirmedBalance() const;
@@ -560,8 +566,8 @@ public:
     bool AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs=true);
     bool AcceptWalletTransaction();
 
-    void RelayWalletTransaction(CTxDB& txdb);
-    void RelayWalletTransaction();
+    bool RelayWalletTransaction(CTxDB& txdb);
+    bool RelayWalletTransaction();
 };