Add pending effective amount to rpc methods #232
15 changed files with 227 additions and 65 deletions
|
@ -82,13 +82,15 @@ function cleanup() {
|
|||
}
|
||||
|
||||
# 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 ""
|
||||
git log --no-merges --topo-order --pretty='format:%h %s (%an)' pull/"$PULL"/base..pull/"$PULL"/head
|
||||
)>"$TMPDIR/message"
|
||||
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
|
||||
cleanup
|
||||
exit 4
|
||||
|
|
BIN
contrib/gitian-downloader/jonasschnelli-key.pgp
Normal file
BIN
contrib/gitian-downloader/jonasschnelli-key.pgp
Normal file
Binary file not shown.
Binary file not shown.
|
@ -33,7 +33,7 @@
|
|||
|
||||
static bool fDaemon;
|
||||
|
||||
void DetectShutdownThread(boost::thread_group* threadGroup)
|
||||
void WaitForShutdown(boost::thread_group* threadGroup)
|
||||
{
|
||||
bool fShutdown = ShutdownRequested();
|
||||
// Tell the main threads to shutdown.
|
||||
|
@ -56,7 +56,6 @@ void DetectShutdownThread(boost::thread_group* threadGroup)
|
|||
bool AppInit(int argc, char* argv[])
|
||||
{
|
||||
boost::thread_group threadGroup;
|
||||
boost::thread* detectShutdownThread = NULL;
|
||||
|
||||
bool fRet = false;
|
||||
|
||||
|
@ -144,7 +143,6 @@ bool AppInit(int argc, char* argv[])
|
|||
#endif
|
||||
SoftSetBoolArg("-server", true);
|
||||
|
||||
detectShutdownThread = new boost::thread(boost::bind(&DetectShutdownThread, &threadGroup));
|
||||
fRet = AppInit2(threadGroup);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
|
@ -155,20 +153,12 @@ bool AppInit(int argc, char* argv[])
|
|||
|
||||
if (!fRet)
|
||||
{
|
||||
if (detectShutdownThread)
|
||||
detectShutdownThread->interrupt();
|
||||
|
||||
threadGroup.interrupt_all();
|
||||
// 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
|
||||
// thread-blocking-waiting-for-another-thread-during-startup case
|
||||
}
|
||||
|
||||
if (detectShutdownThread)
|
||||
{
|
||||
detectShutdownThread->join();
|
||||
delete detectShutdownThread;
|
||||
detectShutdownThread = NULL;
|
||||
} else {
|
||||
WaitForShutdown(&threadGroup);
|
||||
}
|
||||
Shutdown();
|
||||
|
||||
|
|
|
@ -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
|
||||
if (pqueue != NULL) {
|
||||
assert(pqueue->nTotal == pqueue->nIdle);
|
||||
assert(pqueue->nTodo == 0);
|
||||
assert(pqueue->fAllOk == true);
|
||||
bool isIdle = pqueue->IsIdle();
|
||||
assert(isIdle);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
100
src/main.cpp
100
src/main.cpp
|
@ -1592,6 +1592,51 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uin
|
|||
|
||||
} // 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)
|
||||
{
|
||||
assert(pindex->GetBlockHash() == view.GetBestBlock());
|
||||
|
@ -1617,11 +1662,8 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
|
|||
uint256 hash = tx.GetHash();
|
||||
|
||||
// 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
|
||||
// have outputs available even in the block itself, so we handle that case
|
||||
// specially with outsEmpty.
|
||||
// exactly.
|
||||
{
|
||||
CCoins outsEmpty;
|
||||
CCoinsModifier outs = view.ModifyCoins(hash);
|
||||
outs->ClearUnspendable();
|
||||
|
||||
|
@ -1662,36 +1704,8 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
|
|||
for (unsigned int j = tx.vin.size(); j-- > 0;) {
|
||||
const COutPoint &out = tx.vin[j].prevout;
|
||||
const CTxInUndo &undo = txundo.vprevout[j];
|
||||
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("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;
|
||||
if (!ApplyTxInUndo(undo, view, trieCache, out))
|
||||
fClean = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1702,9 +1716,9 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
|
|||
if (pfClean) {
|
||||
*pfClean = fClean;
|
||||
return true;
|
||||
} else {
|
||||
return fClean;
|
||||
}
|
||||
|
||||
return fClean;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n");
|
||||
|
@ -4374,7 +4388,7 @@ bool ProcessMessages(CNode* pfrom)
|
|||
|
||||
// Scan for message start
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
@ -4383,7 +4397,7 @@ bool ProcessMessages(CNode* pfrom)
|
|||
CMessageHeader& hdr = msg.hdr;
|
||||
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;
|
||||
}
|
||||
string strCommand = hdr.GetCommand();
|
||||
|
@ -4399,7 +4413,7 @@ bool ProcessMessages(CNode* pfrom)
|
|||
if (nChecksum != hdr.nChecksum)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -4416,12 +4430,12 @@ bool ProcessMessages(CNode* pfrom)
|
|||
if (strstr(e.what(), "end of data"))
|
||||
{
|
||||
// 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"))
|
||||
{
|
||||
// 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
|
||||
{
|
||||
|
@ -4438,7 +4452,7 @@ bool ProcessMessages(CNode* pfrom)
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -1971,7 +1971,7 @@ void CNode::BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSen
|
|||
ENTER_CRITICAL_SECTION(cs_vSend);
|
||||
assert(ssSend.size() == 0);
|
||||
ssSend << CMessageHeader(pszCommand, 0);
|
||||
LogPrint("net", "sending: %s ", pszCommand);
|
||||
LogPrint("net", "sending: %s ", SanitizeString(pszCommand));
|
||||
}
|
||||
|
||||
void CNode::AbortMessage() UNLOCK_FUNCTION(cs_vSend)
|
||||
|
|
|
@ -14,6 +14,69 @@
|
|||
<string notr="true">Bitcoin Core - Command-line options</string>
|
||||
</property>
|
||||
<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>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
|
@ -25,6 +88,9 @@
|
|||
</item>
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||
</property>
|
||||
|
@ -56,6 +122,22 @@
|
|||
</widget>
|
||||
</widget>
|
||||
</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>
|
||||
<widget class="QDialogButtonBox" name="okButton">
|
||||
<property name="orientation">
|
||||
|
|
|
@ -569,6 +569,14 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins
|
|||
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
|
||||
CTxOut txOut(sendingTo.second, sendingTo.first);
|
||||
if (txOut.IsDust(::minRelayTxFee)) {
|
||||
|
@ -580,6 +588,11 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins
|
|||
}
|
||||
|
||||
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
|
||||
recipient.address = addresses.join("<br />");
|
||||
|
@ -768,3 +781,15 @@ bool PaymentServer::verifyExpired(const payments::PaymentDetails& requestDetails
|
|||
}
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -95,6 +95,8 @@ public:
|
|||
static bool verifyNetwork(const payments::PaymentDetails& requestDetails);
|
||||
// Verify if the payment request is expired
|
||||
static bool verifyExpired(const payments::PaymentDetails& requestDetails);
|
||||
// Verify the payment request amount is valid
|
||||
static bool verifyAmount(const CAmount& requestAmount);
|
||||
|
||||
signals:
|
||||
// Fired when a valid payment request is received
|
||||
|
|
|
@ -433,3 +433,28 @@ dGluZyB0ZXN0bmV0ISqAAXSQG8+GFA18VaKarlYrOz293rNMIub0swKGcQm8jAGX\
|
|||
HSLaRgHfUDeEPr4hydy4dtfu59KNwe2xsHOHu/SpO4L8SrA4Dm9A7SlNBVWdcLbw\
|
||||
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==\
|
||||
";
|
||||
|
|
|
@ -7,7 +7,10 @@
|
|||
#include "optionsmodel.h"
|
||||
#include "paymentrequestdata.h"
|
||||
|
||||
#include "amount.h"
|
||||
#include "random.h"
|
||||
#include "script/script.h"
|
||||
#include "script/standard.h"
|
||||
#include "util.h"
|
||||
#include "utilstrencodings.h"
|
||||
|
||||
|
@ -184,6 +187,20 @@ void PaymentServerTests::paymentServerTests()
|
|||
tempFile.close();
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -137,6 +137,7 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) :
|
|||
|
||||
ui->helpMessage->moveCursor(QTextCursor::Start);
|
||||
ui->scrollArea->setVisible(false);
|
||||
ui->aboutLogo->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ Value GetNetworkHashPS(int lookup, int height) {
|
|||
|
||||
// If lookup is -1, then use blocks since last difficulty change.
|
||||
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 > pb->nHeight)
|
||||
|
|
|
@ -857,7 +857,7 @@ void JSONRequest::parse(const Value& valRequest)
|
|||
throw JSONRPCError(RPC_INVALID_REQUEST, "Method must be a string");
|
||||
strMethod = valMethod.get_str();
|
||||
if (strMethod != "getblocktemplate")
|
||||
LogPrint("rpc", "ThreadRPCServer method=%s\n", strMethod);
|
||||
LogPrint("rpc", "ThreadRPCServer method=%s\n", SanitizeString(strMethod));
|
||||
|
||||
// Parse params
|
||||
Value valParams = find_value(request, "params");
|
||||
|
|
Loading…
Reference in a new issue