Skip to content

Commit

Permalink
Merge pull request bitcoin#1 from FeatherCoin/master-0.8
Browse files Browse the repository at this point in the history
Master 0.8
  • Loading branch information
wellenreiter01 committed Mar 25, 2016
2 parents 23e8526 + 5fce35c commit 43dc7e9
Show file tree
Hide file tree
Showing 24 changed files with 300 additions and 1,274 deletions.
2 changes: 1 addition & 1 deletion feathercoin-qt.pro
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
TEMPLATE = app
TARGET = feathercoin-qt
macx:TARGET = "Feathercoin-Qt"
VERSION = 0.8.7.2
VERSION = 0.8.7.3
INCLUDEPATH += src src/json src/qt
QT += core gui network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
Expand Down
3 changes: 1 addition & 2 deletions src/bitcoinrpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1031,8 +1031,7 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s

// Observe safe mode
string strWarning = GetWarnings("rpc");
if (strWarning != "" && !GetBoolArg("-disablesafemode") &&
!pcmd->okSafeMode)
if((strWarning != "") && !GetBoolArg("-disablesafemode", true) && !pcmd->okSafeMode)
throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, string("Safe mode: ") + strWarning);

try
Expand Down
1 change: 1 addition & 0 deletions src/checkpoints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ namespace Checkpoints
( 33918, uint256("0x023cf4acfd8bf0114090a7ce048e79ac28152de78bb41f1277742904494e6c49"))
( 34000, uint256("0x082f5d9023af3f068733ab68cf81b741f58e3c75ae28d2a9bd07f30b74c38356"))
( 41300, uint256("0x8c4e02f6c0d20e856fd7e952a147fee30ce145ca6932a284f354924362d2b408"))
( 1114311, uint256("0x93515f222f16a9ff3db6594e5ee7c12924cff9ba05b01dbe551d0a9e65dd141f"))
;
static const CCheckpointData data = {
&mapCheckpoints,
Expand Down
4 changes: 2 additions & 2 deletions src/clientversion.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@
#define CLIENT_VERSION_MAJOR 0
#define CLIENT_VERSION_MINOR 8
#define CLIENT_VERSION_REVISION 7
#define CLIENT_VERSION_BUILD 2
#define CLIENT_VERSION_BUILD 3

// Set to true for release, false for prerelease or test build
#define CLIENT_VERSION_IS_RELEASE true

// Copyright year (2009-this)
// Todo: update this when changing our copyright comments in the source
#define COPYRIGHT_YEAR 2014
#define COPYRIGHT_YEAR 2016

// Converts the parameter X to a string after macro replacement on X has been performed.
// Don't merge these into one macro!
Expand Down
22 changes: 19 additions & 3 deletions src/key.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,10 +202,26 @@ class CECKey {
}

bool Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) {

if(vchSig.empty()) return(false);

/* Decode and re-encode signatures to work around new OpenSSL versions */
unsigned char *norm_der = NULL;
ECDSA_SIG *norm_sig = ECDSA_SIG_new();
const unsigned char* sigptr = &vchSig[0];
if(d2i_ECDSA_SIG(&norm_sig, &sigptr, vchSig.size()) == NULL) {
ECDSA_SIG_free(norm_sig);
return(false);
}
int derlen = i2d_ECDSA_SIG(norm_sig, &norm_der);
ECDSA_SIG_free(norm_sig);
if(derlen <= 0) return(false);

// -1 = error, 0 = bad sig, 1 = good
if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1)
return false;
return true;
int ret = ECDSA_verify(0, (unsigned char *) &hash, sizeof(hash), norm_der, derlen, pkey);
OPENSSL_free(norm_der);
if(ret != 1) return(false);
return(true);
}

bool SignCompact(const uint256 &hash, unsigned char *p64, int &rec) {
Expand Down
17 changes: 9 additions & 8 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -792,8 +792,8 @@ bool CTxMemPool::accept(CValidationState &state, CTransaction &tx, bool fCheckIn

// Check against previous transactions
// This is done last to help prevent CPU exhaustion denial-of-service attacks.
if (!tx.CheckInputs(state, view, true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC))
{
if(!tx.CheckInputs(state, view, true,
SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC | SCRIPT_VERIFY_DERSIG)) {
return error("CTxMemPool::accept() : ConnectInputs failed %s", hash.ToString().c_str());
}
}
Expand Down Expand Up @@ -1305,8 +1305,8 @@ bool IsInitialBlockDownload()
pindexLastBest = pindexBest;
nLastUpdate = GetTime();
}
return (GetTime() - nLastUpdate < 10 &&
pindexBest->GetBlockTime() < GetTime() - 24 * 60 * 60);
return(((GetTime() - nLastUpdate) < 10) &&
(pindexBest->GetBlockTime() < (GetTime() - 4 * 60 * 60)));
}

void static InvalidChainFound(CBlockIndex* pindexNew)
Expand Down Expand Up @@ -2333,7 +2333,7 @@ bool CBlock::AcceptBlock(CValidationState &state, CDiskBlockPos *dbp)
}

// ppcoin: check pending sync-checkpoint
AcceptPendingSyncCheckpoint();
if(!IsInitialBlockDownload()) AcceptPendingSyncCheckpoint();

return true;
}
Expand Down Expand Up @@ -2381,7 +2381,7 @@ bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBl
}

// ppcoin: ask for pending sync-checkpoint if any
if (!IsInitialBlockDownload())
if(pfrom && !IsInitialBlockDownload())
AskForPendingSyncCheckpoint(pfrom);

// If we don't already have its previous block, shunt it off to holding area until we get it
Expand Down Expand Up @@ -3115,8 +3115,9 @@ string GetWarnings(string strFor)
}

// Longer invalid proof-of-work chain
if (pindexBest && nBestInvalidWork > nBestChainWork + (pindexBest->GetBlockWork() * 6).getuint256())
{
if(pindexBest && !IsInitialBlockDownload() && !fTestNet &&
IsSyncCheckpointTooOld(60 * 60 * 24 * 10) &&
(nBestInvalidWork > nBestChainWork + (pindexBest->GetBlockWork() * 6).getuint256())) {
nPriority = 2000;
strStatusBar = strRPC = _("Warning: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade.");
}
Expand Down
5 changes: 4 additions & 1 deletion src/qt/rpcconsole.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
#include "ui_rpcconsole.h"

#include "clientmodel.h"
#include "bitcoinrpc.h"
#include "guiutil.h"

#ifndef Q_MOC_RUN
#include "bitcoinrpc.h"
#endif

#include <QTime>
#include <QThread>
#include <QKeyEvent>
Expand Down
88 changes: 88 additions & 0 deletions src/script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,86 @@ bool IsCanonicalSignature(const valtype &vchSig) {
return true;
}

// BIP 66 defined signature encoding check. This largely overlaps with
// IsCanonicalSignature above, but lacks hashtype constraints, and uses the
// exact implementation code from BIP 66.
bool static IsValidSignatureEncoding(const std::vector<unsigned char> &sig) {
// Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S] [sighash]
// * total-length: 1-byte length descriptor of everything that follows,
// excluding the sighash byte.
// * R-length: 1-byte length descriptor of the R value that follows.
// * R: arbitrary-length big-endian encoded R value. It must use the shortest
// possible encoding for a positive integers (which means no null bytes at
// the start, except a single one when the next byte has its highest bit set).
// * S-length: 1-byte length descriptor of the S value that follows.
// * S: arbitrary-length big-endian encoded S value. The same rules apply.
// * sighash: 1-byte value indicating what data is hashed (not part of the DER
// signature)

// Minimum and maximum size constraints.
if (sig.size() < 9) return false;
if (sig.size() > 73) return false;

// A signature is of type 0x30 (compound).
if (sig[0] != 0x30) return false;

// Make sure the length covers the entire signature.
if (sig[1] != sig.size() - 3) return false;

// Extract the length of the R element.
unsigned int lenR = sig[3];

// Make sure the length of the S element is still inside the signature.
if (5 + lenR >= sig.size()) return false;

// Extract the length of the S element.
unsigned int lenS = sig[5 + lenR];

// Verify that the length of the signature matches the sum of the length
// of the elements.
if ((size_t)(lenR + lenS + 7) != sig.size()) return false;

// Check whether the R element is an integer.
if (sig[2] != 0x02) return false;

// Zero-length integers are not allowed for R.
if (lenR == 0) return false;

// Negative numbers are not allowed for R.
if (sig[4] & 0x80) return false;

// Null bytes at the start of R are not allowed, unless R would
// otherwise be interpreted as a negative number.
if (lenR > 1 && (sig[4] == 0x00) && !(sig[5] & 0x80)) return false;

// Check whether the S element is an integer.
if (sig[lenR + 4] != 0x02) return false;

// Zero-length integers are not allowed for S.
if (lenS == 0) return false;

// Negative numbers are not allowed for S.
if (sig[lenR + 6] & 0x80) return false;

// Null bytes at the start of S are not allowed, unless S would otherwise be
// interpreted as a negative number.
if (lenS > 1 && (sig[lenR + 6] == 0x00) && !(sig[lenR + 7] & 0x80)) return false;

return true;
}

bool static CheckSignatureEncoding(const valtype &vchSig, unsigned int flags) {
// Empty signature. Not strictly DER encoded, but allowed to provide a
// compact way to provide an invalid signature for use with CHECK(MULTI)SIG
if (vchSig.size() == 0) {
return true;
}
if ((flags & SCRIPT_VERIFY_DERSIG) != 0 && !IsValidSignatureEncoding(vchSig)) {
return false;
}
return true;
}

bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, unsigned int flags, int nHashType)
{
CAutoBN_CTX pctx;
Expand Down Expand Up @@ -841,6 +921,10 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
// Drop the signature, since there's no way for a signature to sign itself
scriptCode.FindAndDelete(CScript(vchSig));

if (!CheckSignatureEncoding(vchSig, flags)) {
return false;
}

bool fSuccess = (!fStrictEncodings || (IsCanonicalSignature(vchSig) && IsCanonicalPubKey(vchPubKey)));
if (fSuccess)
fSuccess = CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType, flags);
Expand Down Expand Up @@ -902,6 +986,10 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
valtype& vchSig = stacktop(-isig);
valtype& vchPubKey = stacktop(-ikey);

if (!CheckSignatureEncoding(vchSig, flags)) {
return false;
}

// Check signature
bool fOk = (!fStrictEncodings || (IsCanonicalSignature(vchSig) && IsCanonicalPubKey(vchPubKey)));
if (fOk)
Expand Down
1 change: 1 addition & 0 deletions src/script.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ enum
SCRIPT_VERIFY_P2SH = (1U << 0),
SCRIPT_VERIFY_STRICTENC = (1U << 1),
SCRIPT_VERIFY_NOCACHE = (1U << 2),
SCRIPT_VERIFY_DERSIG = (1U << 3),
};

enum txnouttype
Expand Down
18 changes: 9 additions & 9 deletions src/test/Checkpoints_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,21 @@ BOOST_AUTO_TEST_SUITE(Checkpoints_tests)

BOOST_AUTO_TEST_CASE(sanity)
{
uint256 p1500 = uint256("0x841a2965955dd288cfa707a755d05a54e45f8bd476835ec9af4402a2b59a2967");
uint256 p120000 = uint256("0xbd9d26924f05f6daa7f0155f32828ec89e8e29cee9e7121b026a7a3552ac6131");
BOOST_CHECK(Checkpoints::CheckBlock(1500, p1500));
BOOST_CHECK(Checkpoints::CheckBlock(120000, p120000));
uint256 p1 = uint256("0xfdbe99b90c90bae7505796461471d89ae8388ab953997aa06a355bbda8d915cb");
uint256 p41300 = uint256("0x8c4e02f6c0d20e856fd7e952a147fee30ce145ca6932a284f354924362d2b408");
BOOST_CHECK(Checkpoints::CheckBlock(1, p1));
BOOST_CHECK(Checkpoints::CheckBlock(41300, p41300));


// Wrong hashes at checkpoints should fail:
BOOST_CHECK(!Checkpoints::CheckBlock(1500, p120000));
BOOST_CHECK(!Checkpoints::CheckBlock(120000, p1500));
BOOST_CHECK(!Checkpoints::CheckBlock(1, p41300));
BOOST_CHECK(!Checkpoints::CheckBlock(41300, p1));

// ... but any hash not at a checkpoint should succeed:
BOOST_CHECK(Checkpoints::CheckBlock(1500+1, p120000));
BOOST_CHECK(Checkpoints::CheckBlock(120000+1, p1500));
BOOST_CHECK(Checkpoints::CheckBlock(1+1, p41300));
BOOST_CHECK(Checkpoints::CheckBlock(41300+1, p1));

BOOST_CHECK(Checkpoints::GetTotalBlocksEstimate() >= 120000);
BOOST_CHECK(Checkpoints::GetTotalBlocksEstimate() >= 40000);
}

BOOST_AUTO_TEST_SUITE_END()
49 changes: 0 additions & 49 deletions src/test/DoS_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,55 +82,6 @@ BOOST_AUTO_TEST_CASE(DoS_bantime)
BOOST_CHECK(!CNode::IsBanned(addr));
}

static bool CheckNBits(unsigned int nbits1, int64 time1, unsigned int nbits2, int64 time2)\
{
if (time1 > time2)
return CheckNBits(nbits2, time2, nbits1, time1);
int64 deltaTime = time2-time1;

CBigNum required;
required.SetCompact(ComputeMinWork(nbits1, deltaTime));
CBigNum have;
have.SetCompact(nbits2);
return (have <= required);
}

BOOST_AUTO_TEST_CASE(DoS_checknbits)
{
using namespace boost::assign; // for 'map_list_of()'

// Timestamps,nBits from the bitcoin block chain.
// These are the block-chain checkpoint blocks
typedef std::map<int64, unsigned int> BlockData;
BlockData chainData =
map_list_of(1239852051,486604799)(1262749024,486594666)
(1279305360,469854461)(1280200847,469830746)(1281678674,469809688)
(1296207707,453179945)(1302624061,453036989)(1309640330,437004818)
(1313172719,436789733);

// Make sure CheckNBits considers every combination of block-chain-lock-in-points
// "sane":
BOOST_FOREACH(const BlockData::value_type& i, chainData)
{
BOOST_FOREACH(const BlockData::value_type& j, chainData)
{
BOOST_CHECK(CheckNBits(i.second, i.first, j.second, j.first));
}
}

// Test a couple of insane combinations:
BlockData::value_type firstcheck = *(chainData.begin());
BlockData::value_type lastcheck = *(chainData.rbegin());

// First checkpoint difficulty at or a while after the last checkpoint time should fail when
// compared to last checkpoint
BOOST_CHECK(!CheckNBits(firstcheck.second, lastcheck.first+60*10, lastcheck.second, lastcheck.first));
BOOST_CHECK(!CheckNBits(firstcheck.second, lastcheck.first+60*60*24*14, lastcheck.second, lastcheck.first));

// ... but OK if enough time passed for difficulty to adjust downward:
BOOST_CHECK(CheckNBits(firstcheck.second, lastcheck.first+60*60*24*365*4, lastcheck.second, lastcheck.first));
}

CTransaction RandomOrphan()
{
std::map<uint256, CTransaction>::iterator it;
Expand Down

0 comments on commit 43dc7e9

Please sign in to comment.