Claim name returned is strange #172

Closed
mirgee wants to merge 286 commits from issue-119 into master
15 changed files with 227 additions and 65 deletions
Showing only changes of commit df59145787 - Show all commits

View file

@ -82,13 +82,15 @@ function cleanup() {
} }
# Create unsigned merge commit. # Create unsigned merge commit.
PRTITLE=`curl -s https://api.github.com/repos/$REPO/pulls/$PULL | grep -e ' "title": ".*",'| awk -F'"' '{print $4}'`
MERGEMESSAGE="Merge #$PULL: $PRTITLE"
( (
echo "Merge pull request #$PULL" echo $MERGEMESSAGE
echo "" echo ""
git log --no-merges --topo-order --pretty='format:%h %s (%an)' pull/"$PULL"/base..pull/"$PULL"/head git log --no-merges --topo-order --pretty='format:%h %s (%an)' pull/"$PULL"/base..pull/"$PULL"/head
)>"$TMPDIR/message" )>"$TMPDIR/message"
if git merge -q --commit --no-edit --no-ff -m "$(<"$TMPDIR/message")" pull/"$PULL"/head; then if git merge -q --commit --no-edit --no-ff -m "$(<"$TMPDIR/message")" pull/"$PULL"/head; then
if [ "d$(git log --pretty='format:%s' -n 1)" != "dMerge pull request #$PULL" ]; then if [ "d$(git log --pretty='format:%s' -n 1)" != "d$MERGEMESSAGE" ]; then
echo "ERROR: Creating merge failed (already merged?)." >&2 echo "ERROR: Creating merge failed (already merged?)." >&2
cleanup cleanup
exit 4 exit 4

Binary file not shown.

View file

@ -33,7 +33,7 @@
static bool fDaemon; static bool fDaemon;
void DetectShutdownThread(boost::thread_group* threadGroup) void WaitForShutdown(boost::thread_group* threadGroup)
{ {
bool fShutdown = ShutdownRequested(); bool fShutdown = ShutdownRequested();
// Tell the main threads to shutdown. // Tell the main threads to shutdown.
@ -56,7 +56,6 @@ void DetectShutdownThread(boost::thread_group* threadGroup)
bool AppInit(int argc, char* argv[]) bool AppInit(int argc, char* argv[])
{ {
boost::thread_group threadGroup; boost::thread_group threadGroup;
boost::thread* detectShutdownThread = NULL;
bool fRet = false; bool fRet = false;
@ -144,7 +143,6 @@ bool AppInit(int argc, char* argv[])
#endif #endif
SoftSetBoolArg("-server", true); SoftSetBoolArg("-server", true);
detectShutdownThread = new boost::thread(boost::bind(&DetectShutdownThread, &threadGroup));
fRet = AppInit2(threadGroup); fRet = AppInit2(threadGroup);
} }
catch (const std::exception& e) { catch (const std::exception& e) {
@ -155,20 +153,12 @@ bool AppInit(int argc, char* argv[])
if (!fRet) if (!fRet)
{ {
if (detectShutdownThread)
detectShutdownThread->interrupt();
threadGroup.interrupt_all(); threadGroup.interrupt_all();
// threadGroup.join_all(); was left out intentionally here, because we didn't re-test all of // threadGroup.join_all(); was left out intentionally here, because we didn't re-test all of
// the startup-failure cases to make sure they don't result in a hang due to some // the startup-failure cases to make sure they don't result in a hang due to some
// thread-blocking-waiting-for-another-thread-during-startup case // thread-blocking-waiting-for-another-thread-during-startup case
} } else {
WaitForShutdown(&threadGroup);
if (detectShutdownThread)
{
detectShutdownThread->join();
delete detectShutdownThread;
detectShutdownThread = NULL;
} }
Shutdown(); Shutdown();

View file

@ -161,7 +161,12 @@ public:
{ {
} }
friend class CCheckQueueControl<T>; bool IsIdle()
{
boost::unique_lock<boost::mutex> lock(mutex);
return (nTotal == nIdle && nTodo == 0 && fAllOk == true);
}
}; };
/** /**
@ -180,9 +185,8 @@ public:
{ {
// passed queue is supposed to be unused, or NULL // passed queue is supposed to be unused, or NULL
if (pqueue != NULL) { if (pqueue != NULL) {
assert(pqueue->nTotal == pqueue->nIdle); bool isIdle = pqueue->IsIdle();
assert(pqueue->nTodo == 0); assert(isIdle);
assert(pqueue->fAllOk == true);
} }
} }

View file

@ -1592,6 +1592,51 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uin
} // anon namespace } // anon namespace
/**
* Apply the undo operation of a CTxInUndo to the given chain state.
* @param undo The undo object.
* @param view The coins view to which to apply the changes.
* @param out The out point that corresponds to the tx input.
* @return True on success.
*/
static bool ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, CNCCTrieCache& trieCache, const COutPoint& out)
{
bool fClean = true;
CCoinsModifier coins = view.ModifyCoins(out.hash);
if (undo.nHeight != 0) {
// undo data contains height: this is the last output of the prevout tx being spent
if (!coins->IsPruned())
fClean = fClean && error("%s: undo data overwriting existing transaction", __func__);
coins->Clear();
coins->fCoinBase = undo.fCoinBase;
coins->nHeight = undo.nHeight;
coins->nVersion = undo.nVersion;
} else {
if (coins->IsPruned())
fClean = fClean && error("%s: undo data adding output to missing transaction", __func__);
}
if (coins->IsAvailable(out.n))
fClean = fClean && error("%s: undo data overwriting existing output", __func__);
if (coins->vout.size() < out.n+1)
coins->vout.resize(out.n+1);
// restore NCC claim if applicable
int op;
std::vector<std::vector<unsigned char> > vvchParams;
if (DecodeNCCScript(undo.txout.scriptPubKey, op, vvchParams))
{
assert(vvchParams.size() == 2);
std::string name(vvchParams[0].begin(), vvchParams[0].end());
if (!trieCache.insertName(name, out.hash, out.n, undo.txout.nValue, undo.nHeight))
LogPrintf("Something went wrong inserting the name");
}
coins->vout[out.n] = undo.txout;
return fClean;
}
bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, CNCCTrieCache& trieCache, bool* pfClean) bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, CNCCTrieCache& trieCache, bool* pfClean)
{ {
assert(pindex->GetBlockHash() == view.GetBestBlock()); assert(pindex->GetBlockHash() == view.GetBestBlock());
@ -1617,11 +1662,8 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
uint256 hash = tx.GetHash(); uint256 hash = tx.GetHash();
// Check that all outputs are available and match the outputs in the block itself // Check that all outputs are available and match the outputs in the block itself
// exactly. Note that transactions with only provably unspendable outputs won't // exactly.
// have outputs available even in the block itself, so we handle that case
// specially with outsEmpty.
{ {
CCoins outsEmpty;
CCoinsModifier outs = view.ModifyCoins(hash); CCoinsModifier outs = view.ModifyCoins(hash);
outs->ClearUnspendable(); outs->ClearUnspendable();
@ -1662,36 +1704,8 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
for (unsigned int j = tx.vin.size(); j-- > 0;) { for (unsigned int j = tx.vin.size(); j-- > 0;) {
const COutPoint &out = tx.vin[j].prevout; const COutPoint &out = tx.vin[j].prevout;
const CTxInUndo &undo = txundo.vprevout[j]; const CTxInUndo &undo = txundo.vprevout[j];
CCoinsModifier coins = view.ModifyCoins(out.hash); if (!ApplyTxInUndo(undo, view, trieCache, out))
if (undo.nHeight != 0) { fClean = false;
// undo data contains height: this is the last output of the prevout tx being spent
if (!coins->IsPruned())
fClean = fClean && error("DisconnectBlock(): undo data overwriting existing transaction");
coins->Clear();
coins->fCoinBase = undo.fCoinBase;
coins->nHeight = undo.nHeight;
coins->nVersion = undo.nVersion;
} else {
if (coins->IsPruned())
fClean = fClean && error("DisconnectBlock(): undo data adding output to missing transaction");
}
if (coins->IsAvailable(out.n))
fClean = fClean && error("DisconnectBlock(): undo data overwriting existing output");
if (coins->vout.size() < out.n+1)
coins->vout.resize(out.n+1);
// restore NCC claim if applicable
int op;
std::vector<std::vector<unsigned char> > vvchParams;
if (DecodeNCCScript(undo.txout.scriptPubKey, op, vvchParams))
{
assert(vvchParams.size() == 2);
std::string name(vvchParams[0].begin(), vvchParams[0].end());
if (!trieCache.insertName(name, out.hash, out.n, undo.txout.nValue, undo.nHeight))
LogPrintf("Something went wrong inserting the name");
}
coins->vout[out.n] = undo.txout;
} }
} }
} }
@ -1702,9 +1716,9 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
if (pfClean) { if (pfClean) {
*pfClean = fClean; *pfClean = fClean;
return true; return true;
} else {
return fClean;
} }
return fClean;
} }
void static FlushBlockFile(bool fFinalize = false) void static FlushBlockFile(bool fFinalize = false)
@ -3539,7 +3553,7 @@ void static ProcessGetData(CNode* pfrom)
bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived) bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived)
{ {
RandAddSeedPerfmon(); RandAddSeedPerfmon();
LogPrint("net", "received: %s (%u bytes) peer=%d\n", strCommand, vRecv.size(), pfrom->id); LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id);
if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0) if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
{ {
LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n"); LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n");
@ -4374,7 +4388,7 @@ bool ProcessMessages(CNode* pfrom)
// Scan for message start // Scan for message start
if (memcmp(msg.hdr.pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0) { if (memcmp(msg.hdr.pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0) {
LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", msg.hdr.GetCommand(), pfrom->id); LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", SanitizeString(msg.hdr.GetCommand()), pfrom->id);
fOk = false; fOk = false;
break; break;
} }
@ -4383,7 +4397,7 @@ bool ProcessMessages(CNode* pfrom)
CMessageHeader& hdr = msg.hdr; CMessageHeader& hdr = msg.hdr;
if (!hdr.IsValid()) if (!hdr.IsValid())
{ {
LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", hdr.GetCommand(), pfrom->id); LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", SanitizeString(hdr.GetCommand()), pfrom->id);
continue; continue;
} }
string strCommand = hdr.GetCommand(); string strCommand = hdr.GetCommand();
@ -4399,7 +4413,7 @@ bool ProcessMessages(CNode* pfrom)
if (nChecksum != hdr.nChecksum) if (nChecksum != hdr.nChecksum)
{ {
LogPrintf("ProcessMessages(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n", LogPrintf("ProcessMessages(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
strCommand, nMessageSize, nChecksum, hdr.nChecksum); SanitizeString(strCommand), nMessageSize, nChecksum, hdr.nChecksum);
continue; continue;
} }
@ -4416,12 +4430,12 @@ bool ProcessMessages(CNode* pfrom)
if (strstr(e.what(), "end of data")) if (strstr(e.what(), "end of data"))
{ {
// Allow exceptions from under-length message on vRecv // Allow exceptions from under-length message on vRecv
LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand, nMessageSize, e.what()); LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught, normally caused by a message being shorter than its stated length\n", SanitizeString(strCommand), nMessageSize, e.what());
} }
else if (strstr(e.what(), "size too large")) else if (strstr(e.what(), "size too large"))
{ {
// Allow exceptions from over-long size // Allow exceptions from over-long size
LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught\n", strCommand, nMessageSize, e.what()); LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught\n", SanitizeString(strCommand), nMessageSize, e.what());
} }
else else
{ {
@ -4438,7 +4452,7 @@ bool ProcessMessages(CNode* pfrom)
} }
if (!fRet) if (!fRet)
LogPrintf("ProcessMessage(%s, %u bytes) FAILED peer=%d\n", strCommand, nMessageSize, pfrom->id); LogPrintf("ProcessMessage(%s, %u bytes) FAILED peer=%d\n", SanitizeString(strCommand), nMessageSize, pfrom->id);
break; break;
} }

View file

@ -1971,7 +1971,7 @@ void CNode::BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSen
ENTER_CRITICAL_SECTION(cs_vSend); ENTER_CRITICAL_SECTION(cs_vSend);
assert(ssSend.size() == 0); assert(ssSend.size() == 0);
ssSend << CMessageHeader(pszCommand, 0); ssSend << CMessageHeader(pszCommand, 0);
LogPrint("net", "sending: %s ", pszCommand); LogPrint("net", "sending: %s ", SanitizeString(pszCommand));
} }
void CNode::AbortMessage() UNLOCK_FUNCTION(cs_vSend) void CNode::AbortMessage() UNLOCK_FUNCTION(cs_vSend)

View file

@ -14,6 +14,69 @@
<string notr="true">Bitcoin Core - Command-line options</string> <string notr="true">Bitcoin Core - Command-line options</string>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>12</number>
</property>
<property name="topMargin">
<number>12</number>
</property>
<property name="rightMargin">
<number>12</number>
</property>
<property name="bottomMargin">
<number>12</number>
</property>
<item>
<layout class="QVBoxLayout" name="verticalLayoutLogo" stretch="0,0">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>4</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="aboutLogo">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Ignored">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="pixmap">
<pixmap resource="../bitcoin.qrc">:/icons/bitcoin</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
</widget>
</item>
</layout>
</item>
<item> <item>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
@ -25,6 +88,9 @@
</item> </item>
<item> <item>
<widget class="QScrollArea" name="scrollArea"> <widget class="QScrollArea" name="scrollArea">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="verticalScrollBarPolicy"> <property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOn</enum> <enum>Qt::ScrollBarAlwaysOn</enum>
</property> </property>
@ -56,6 +122,22 @@
</widget> </widget>
</widget> </widget>
</item> </item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>4</width>
<height>4</height>
</size>
</property>
</spacer>
</item>
<item> <item>
<widget class="QDialogButtonBox" name="okButton"> <widget class="QDialogButtonBox" name="okButton">
<property name="orientation"> <property name="orientation">

View file

@ -569,6 +569,14 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins
return false; return false;
} }
// Bitcoin amounts are stored as (optional) uint64 in the protobuf messages (see paymentrequest.proto),
// but CAmount is defined as int64_t. Because of that we need to verify that amounts are in a valid range
// and no overflow has happened.
if (!verifyAmount(sendingTo.second)) {
emit message(tr("Payment request rejected"), tr("Invalid payment request."), CClientUIInterface::MSG_ERROR);
return false;
}
// Extract and check amounts // Extract and check amounts
CTxOut txOut(sendingTo.second, sendingTo.first); CTxOut txOut(sendingTo.second, sendingTo.first);
if (txOut.IsDust(::minRelayTxFee)) { if (txOut.IsDust(::minRelayTxFee)) {
@ -580,6 +588,11 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins
} }
recipient.amount += sendingTo.second; recipient.amount += sendingTo.second;
// Also verify that the final amount is still in a valid range after adding additional amounts.
if (!verifyAmount(recipient.amount)) {
emit message(tr("Payment request rejected"), tr("Invalid payment request."), CClientUIInterface::MSG_ERROR);
return false;
}
} }
// Store addresses and format them to fit nicely into the GUI // Store addresses and format them to fit nicely into the GUI
recipient.address = addresses.join("<br />"); recipient.address = addresses.join("<br />");
@ -768,3 +781,15 @@ bool PaymentServer::verifyExpired(const payments::PaymentDetails& requestDetails
} }
return fVerified; return fVerified;
} }
bool PaymentServer::verifyAmount(const CAmount& requestAmount)
{
bool fVerified = MoneyRange(requestAmount);
if (!fVerified) {
qWarning() << QString("PaymentServer::%1: Payment request amount out of allowed range (%2, allowed 0 - %3).")
.arg(__func__)
.arg(requestAmount)
.arg(MAX_MONEY);
}
return fVerified;
}

View file

@ -95,6 +95,8 @@ public:
static bool verifyNetwork(const payments::PaymentDetails& requestDetails); static bool verifyNetwork(const payments::PaymentDetails& requestDetails);
// Verify if the payment request is expired // Verify if the payment request is expired
static bool verifyExpired(const payments::PaymentDetails& requestDetails); static bool verifyExpired(const payments::PaymentDetails& requestDetails);
// Verify the payment request amount is valid
static bool verifyAmount(const CAmount& requestAmount);
signals: signals:
// Fired when a valid payment request is received // Fired when a valid payment request is received

View file

@ -433,3 +433,28 @@ dGluZyB0ZXN0bmV0ISqAAXSQG8+GFA18VaKarlYrOz293rNMIub0swKGcQm8jAGX\
HSLaRgHfUDeEPr4hydy4dtfu59KNwe2xsHOHu/SpO4L8SrA4Dm9A7SlNBVWdcLbw\ HSLaRgHfUDeEPr4hydy4dtfu59KNwe2xsHOHu/SpO4L8SrA4Dm9A7SlNBVWdcLbw\
d2hj739GDLz0b5KuJ2SG6VknMRQM976w/m2qlq0ccVGaaZ2zMIGfpzL3p6adwx/5\ d2hj739GDLz0b5KuJ2SG6VknMRQM976w/m2qlq0ccVGaaZ2zMIGfpzL3p6adwx/5\
"; ";
//
// Payment request with amount overflow (amount is set to 21000001 BTC)
//
const char* paymentrequest5_cert2_BASE64 =
"\
Egt4NTA5K3NoYTI1NhrQBArNBDCCAkkwggExoAMCAQICAQEwDQYJKoZIhvcNAQEL\
BQAwITEfMB0GA1UEAwwWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xNTAxMTEx\
ODIxMDhaFw0yNTAxMDgxODIxMDhaMCExHzAdBgNVBAMMFlBheW1lbnRSZXF1ZXN0\
IFRlc3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMsZqzkzeBGo+i2N\
mUak3Ciodr1V7S062VOy7N0OQYNDQHYkgDFAUET7cEb5VJaHPv5m3ppTBpU9xBcf\
wbHHUt4VjA+mhRmYrl1khjvZM+X8kEqvWn20BtcM9R6r0yIYec8UERDDHBleL/P8\
RkxEnVLjYTV9zigCXfMsgYb3EQShAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJ\
KoZIhvcNAQELBQADggEBABUJpl3QCqsoDSxAsQdV6zKT4VGV76AzoGj7etQsQY+r\
+S26VfWh/fMobEzuxFChr0USgLJ6FoK78hAtoZvt1lrye9yqFv/ig3WLWsJKWHHb\
3RT6oR03CIwZXFSUasi08QDVLxafwsU5OMcPLucF3a1lRL1ccYrNgVCCx1+X7Bos\
tIgDGRQQ4AyoHTcfVd2hEGeUv7k14mOxFsAp6851yosHq9Q2kwmdH+rHEJbjof87\
yyKLagc4owyXBZYkQmkeHWCNqnuRmO5vUsfVb0UUrkD64o7Th/NjwooA7SCiUXl6\
dfygT1b7ggpx7GC+sP2DsIM47IAZ55drjqX5u2f+Ba0iTAoEdGVzdBIkCIDC9P+F\
vt0DEhl2qRQErGqUUwSsaMpDvWIaGnJGNQqi8oisGLzcrKYFKhhUZXN0aW5nIGFt\
b3VudCBvdmVyZmxvdyEqgAG8S7WEDUC6tCL6q2CTBjop/AitgEy31RL9IqYruytR\
iEBFUrBDJZU+UEezGwr7/zoECjo5ZY3PmtZcM2sILNjyweJF6XVzGqTxUw6pN6sW\
XR2T3Gy2LzRvhVA25QgGqpz0/juS2BtmNbsZPkN9gMMwKimgzc+PuCzmEKwPK9cQ\
YQ==\
";

View file

@ -7,7 +7,10 @@
#include "optionsmodel.h" #include "optionsmodel.h"
#include "paymentrequestdata.h" #include "paymentrequestdata.h"
#include "amount.h"
#include "random.h" #include "random.h"
#include "script/script.h"
#include "script/standard.h"
#include "util.h" #include "util.h"
#include "utilstrencodings.h" #include "utilstrencodings.h"
@ -184,6 +187,20 @@ void PaymentServerTests::paymentServerTests()
tempFile.close(); tempFile.close();
QCOMPARE(PaymentServer::readPaymentRequestFromFile(tempFile.fileName(), r.paymentRequest), false); QCOMPARE(PaymentServer::readPaymentRequestFromFile(tempFile.fileName(), r.paymentRequest), false);
// Payment request with amount overflow (amount is set to 21000001 BTC):
data = DecodeBase64(paymentrequest5_cert2_BASE64);
byteArray = QByteArray((const char*)&data[0], data.size());
r.paymentRequest.parse(byteArray);
// Ensure the request is initialized
QVERIFY(r.paymentRequest.IsInitialized());
// Extract address and amount from the request
QList<std::pair<CScript, CAmount> > sendingTos = r.paymentRequest.getPayTo();
foreach (const PAIRTYPE(CScript, CAmount)& sendingTo, sendingTos) {
CTxDestination dest;
if (ExtractDestination(sendingTo.first, dest))
QCOMPARE(PaymentServer::verifyAmount(sendingTo.second), false);
}
delete server; delete server;
} }

View file

@ -137,6 +137,7 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) :
ui->helpMessage->moveCursor(QTextCursor::Start); ui->helpMessage->moveCursor(QTextCursor::Start);
ui->scrollArea->setVisible(false); ui->scrollArea->setVisible(false);
ui->aboutLogo->setVisible(false);
} }
} }

View file

@ -44,7 +44,7 @@ Value GetNetworkHashPS(int lookup, int height) {
// If lookup is -1, then use blocks since last difficulty change. // If lookup is -1, then use blocks since last difficulty change.
if (lookup <= 0) if (lookup <= 0)
lookup = pb->nHeight % 2016 + 1; lookup = pb->nHeight % Params().Interval() + 1;
// If lookup is larger than chain, then set it to chain length. // If lookup is larger than chain, then set it to chain length.
if (lookup > pb->nHeight) if (lookup > pb->nHeight)

View file

@ -857,7 +857,7 @@ void JSONRequest::parse(const Value& valRequest)
throw JSONRPCError(RPC_INVALID_REQUEST, "Method must be a string"); throw JSONRPCError(RPC_INVALID_REQUEST, "Method must be a string");
strMethod = valMethod.get_str(); strMethod = valMethod.get_str();
if (strMethod != "getblocktemplate") if (strMethod != "getblocktemplate")
LogPrint("rpc", "ThreadRPCServer method=%s\n", strMethod); LogPrint("rpc", "ThreadRPCServer method=%s\n", SanitizeString(strMethod));
// Parse params // Parse params
Value valParams = find_value(request, "params"); Value valParams = find_value(request, "params");