aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.cpp22
-rw-r--r--src/rpcwallet.cpp27
2 files changed, 21 insertions, 28 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 34b4c51d5f..b6a61f7da1 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -3355,19 +3355,17 @@ void static ProcessGetData(CNode* pfrom)
BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
if (mi != mapBlockIndex.end())
{
- // If the requested block is at a height below our last
- // checkpoint, only serve it if it's in the checkpointed chain
- int nHeight = mi->second->nHeight;
- CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint();
- if (pcheckpoint && nHeight < pcheckpoint->nHeight) {
- if (!chainActive.Contains(mi->second))
- {
- LogPrintf("ProcessGetData(): ignoring request for old block that isn't in the main chain\n");
- } else {
- send = true;
- }
- } else {
+ if (chainActive.Contains(mi->second)) {
send = true;
+ } else {
+ // To prevent fingerprinting attacks, only send blocks outside of the active
+ // chain if they are valid, and no more than a month older than the best header
+ // chain we know about.
+ send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) &&
+ (mi->second->GetBlockTime() > pindexBestHeader->GetBlockTime() - 30 * 24 * 60 * 60);
+ if (!send) {
+ LogPrintf("ProcessGetData(): ignoring request from peer=%i for old block that isn't in the main chain\n", pfrom->GetId());
+ }
}
}
if (send)
diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp
index 1afc3c910e..d097b6a0fa 100644
--- a/src/rpcwallet.cpp
+++ b/src/rpcwallet.cpp
@@ -19,6 +19,7 @@
#include <stdint.h>
#include <boost/assign/list_of.hpp>
+
#include "json/json_spirit_utils.h"
#include "json/json_spirit_value.h"
@@ -316,35 +317,29 @@ Value getaddressesbyaccount(const Array& params, bool fHelp)
return ret;
}
-void SendMoney(const CTxDestination &address, CAmount nValue, CWalletTx& wtxNew)
+static void SendMoney(const CTxDestination &address, CAmount nValue, CWalletTx& wtxNew)
{
+ CAmount curBalance = pwalletMain->GetBalance();
+
// Check amount
if (nValue <= 0)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount");
- if (nValue > pwalletMain->GetBalance())
+ if (nValue > curBalance)
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds");
- string strError;
- if (pwalletMain->IsLocked())
- {
- strError = "Error: Wallet locked, unable to create transaction!";
- LogPrintf("SendMoney(): %s", strError);
- throw JSONRPCError(RPC_WALLET_ERROR, strError);
- }
-
// Parse Bitcoin address
CScript scriptPubKey = GetScriptForDestination(address);
// Create and send the transaction
CReserveKey reservekey(pwalletMain);
CAmount nFeeRequired;
- if (!pwalletMain->CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired, strError))
- {
- if (nValue + nFeeRequired > pwalletMain->GetBalance())
- strError = strprintf("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!", FormatMoney(nFeeRequired));
- LogPrintf("SendMoney(): %s\n", strError);
- throw JSONRPCError(RPC_WALLET_ERROR, strError);
+ std::string strError;
+ if (!pwalletMain->CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired, strError)) {
+ if (nValue + nFeeRequired > curBalance)
+ throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!", FormatMoney(nFeeRequired)));
+ else
+ throw JSONRPCError(RPC_WALLET_ERROR, strError);
}
if (!pwalletMain->CommitTransaction(wtxNew, reservekey))
throw JSONRPCError(RPC_WALLET_ERROR, "Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.");