diff --git a/contrib/debian/examples/bitcoin.conf b/contrib/debian/examples/bitcoin.conf index 95fca26be..fd7983b88 100644 --- a/contrib/debian/examples/bitcoin.conf +++ b/contrib/debian/examples/bitcoin.conf @@ -11,12 +11,12 @@ # Use as many addnode= settings as you like to connect to specific peers #addnode=69.164.218.197 -#addnode=10.0.0.2:8333 +#addnode=10.0.0.2:22556 # ... or use as many connect= settings as you like to connect ONLY # to specific peers: #connect=69.164.218.197 -#connect=10.0.0.1:8333 +#connect=10.0.0.1:22556 # Maximum number of inbound+outbound connections. #maxconnections= diff --git a/contrib/debian/manpages/bitcoin-qt.1 b/contrib/debian/manpages/bitcoin-qt.1 index d0819fe4b..450a3faf5 100644 --- a/contrib/debian/manpages/bitcoin-qt.1 +++ b/contrib/debian/manpages/bitcoin-qt.1 @@ -44,7 +44,7 @@ Use proxy to reach tor hidden services (default: same as \fB\-proxy\fR) Allow DNS lookups for \fB\-addnode\fR, \fB\-seednode\fR and \fB\-connect\fR .TP \fB\-port=\fR -Listen for connections on (default: 8333 or testnet: 18333) +Listen for connections on (default: 22556 or testnet: 44556) .TP \fB\-maxconnections=\fR Maintain at most connections to peers (default: 125) @@ -125,7 +125,7 @@ Username for JSON\-RPC connections Password for JSON\-RPC connections .TP \fB\-rpcport=\fR -Listen for JSON\-RPC connections on (default: 8332 or testnet: 18332) +Listen for JSON\-RPC connections on (default: 22555 or testnet: 44555) .TP \fB\-rpcallowip=\fR Allow JSON\-RPC connections from specified IP address diff --git a/contrib/debian/manpages/bitcoin.conf.5 b/contrib/debian/manpages/bitcoin.conf.5 index cca88228c..638562245 100644 --- a/contrib/debian/manpages/bitcoin.conf.5 +++ b/contrib/debian/manpages/bitcoin.conf.5 @@ -18,10 +18,10 @@ Enable or disable run on the test network instead of the real *dogecoin* network \fBproxy=\fR\fI'127.0.0.1:9050'\fR Connect via a socks4 proxy. .TP -\fBaddnode=\fR\fI'10.0.0.2:8333'\fR +\fBaddnode=\fR\fI'10.0.0.2:22556'\fR Use as many *addnode=* settings as you like to connect to specific peers. .TP -\fBconnect=\fR\fI'10.0.0.1:8333'\fR +\fBconnect=\fR\fI'10.0.0.1:22556'\fR Use as many *connect=* settings as you like to connect ONLY to specific peers. .TP \fRmaxconnections=\fR\fI'value'\fR @@ -40,7 +40,7 @@ You must set *rpcpassword* to secure the JSON-RPC api. \fBrpcallowip=\fR\fI'192.168.1.*'\fR By default, only RPC connections from localhost are allowed. Specify as many *rpcallowip=* settings as you like to allow connections from other hosts (and you may use * as a wildcard character). .TP -\fBrpcport=\fR\fI'8332'\fR +\fBrpcport=\fR\fI'22555'\fR Listen for RPC connections on this TCP port. .TP \fBrpcconnect=\fR\fI'127.0.0.1'\fR diff --git a/contrib/gitian-descriptors/deps-linux.yml b/contrib/gitian-descriptors/deps-linux.yml index a23e06175..eb0e63c81 100644 --- a/contrib/gitian-descriptors/deps-linux.yml +++ b/contrib/gitian-descriptors/deps-linux.yml @@ -17,7 +17,7 @@ reference_datetime: "2013-06-01 00:00:00" remotes: [] files: - "openssl-1.0.1l.tar.gz" -- "miniupnpc-1.9.20140701.tar.gz" +- "miniupnpc-1.9.20151008.tar.gz" - "qrencode-3.4.3.tar.bz2" - "protobuf-2.5.0.tar.bz2" - "db-5.1.29.NC.tar.gz" @@ -31,7 +31,7 @@ script: | export LIBRARY_PATH="$STAGING/lib" # Integrity Check echo "b2cf4d48fe5d49f240c61c9e624193a6f232b5ed0baf010681e725963c40d1d4 openssl-1.0.1l.tar.gz" | sha256sum -c - echo "26f3985bad7768b8483b793448ae49414cdc4451d0ec83e7c1944367e15f9f07 miniupnpc-1.9.20140701.tar.gz" | sha256sum -c + echo "e444ac3b587ce82709c4d0cfca1fe71f44f9fc433e9f946b12b9e1bfe667a633 miniupnpc-1.9.20151008.tar.gz" | sha256sum -c echo "dfd71487513c871bad485806bfd1fdb304dedc84d2b01a8fb8e0940b50597a98 qrencode-3.4.3.tar.bz2" | sha256sum -c echo "13bfc5ae543cf3aa180ac2485c0bc89495e3ae711fc6fab4f8ffe90dfb4bb677 protobuf-2.5.0.tar.bz2" | sha256sum -c echo "08238e59736d1aacdd47cfb8e68684c695516c37f4fbe1b8267dde58dc3a576c db-5.1.29.NC.tar.gz" | sha256sum -c @@ -46,8 +46,8 @@ script: | make install_sw cd .. # - tar xzfm miniupnpc-1.9.20140701.tar.gz - cd miniupnpc-1.9.20140701 + tar xzfm miniupnpc-1.9.20151008.tar.gz + cd miniupnpc-1.9.20151008 # miniupnpc is always built with -fPIC INSTALLPREFIX=$STAGING make $MAKEOPTS install rm -f $STAGING/lib/libminiupnpc.so* # no way to skip shared lib build diff --git a/contrib/gitian-descriptors/deps-win.yml b/contrib/gitian-descriptors/deps-win.yml index 8dff8eb05..632d211f1 100644 --- a/contrib/gitian-descriptors/deps-win.yml +++ b/contrib/gitian-descriptors/deps-win.yml @@ -16,7 +16,7 @@ remotes: [] files: - "openssl-1.0.1l.tar.gz" - "db-5.1.29.NC.tar.gz" -- "miniupnpc-1.9.20140701.tar.gz" +- "miniupnpc-1.9.20151008.tar.gz" - "zlib-1.2.8.tar.gz" - "libpng-1.6.8.tar.gz" - "qrencode-3.4.3.tar.bz2" @@ -30,7 +30,7 @@ script: | # Input Integrity Check echo "b2cf4d48fe5d49f240c61c9e624193a6f232b5ed0baf010681e725963c40d1d4 openssl-1.0.1l.tar.gz" | sha256sum -c echo "08238e59736d1aacdd47cfb8e68684c695516c37f4fbe1b8267dde58dc3a576c db-5.1.29.NC.tar.gz" | sha256sum -c - echo "26f3985bad7768b8483b793448ae49414cdc4451d0ec83e7c1944367e15f9f07 miniupnpc-1.9.20140701.tar.gz" | sha256sum -c + echo "e444ac3b587ce82709c4d0cfca1fe71f44f9fc433e9f946b12b9e1bfe667a633 miniupnpc-1.9.20151008.tar.gz" | sha256sum -c echo "36658cb768a54c1d4dec43c3116c27ed893e88b02ecfcb44f2166f9c0b7f2a0d zlib-1.2.8.tar.gz" | sha256sum -c echo "32c7acf1608b9c8b71b743b9780adb7a7b347563dbfb4a5263761056da44cc96 libpng-1.6.8.tar.gz" | sha256sum -c echo "dfd71487513c871bad485806bfd1fdb304dedc84d2b01a8fb8e0940b50597a98 qrencode-3.4.3.tar.bz2" | sha256sum -c @@ -69,8 +69,8 @@ script: | make install_lib install_include cd ../.. # - tar xzf $INDIR/miniupnpc-1.9.20140701.tar.gz - cd miniupnpc-1.9.20140701 + tar xzf $INDIR/miniupnpc-1.9.20151008.tar.gz + cd miniupnpc-1.9.20151008 echo " --- miniupnpc-1.9/Makefile.mingw.orig 2013-09-29 18:52:51.014087958 -1000 +++ miniupnpc-1.9/Makefile.mingw 2013-09-29 19:09:29.663318691 -1000 diff --git a/doc/release-process.md b/doc/release-process.md index 85c1cb7b6..5c9d7e6ef 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -37,7 +37,7 @@ Release Process Fetch and build inputs: (first time, or when dependency versions change) mkdir -p inputs; cd inputs/ - wget 'http://miniupnp.free.fr/files/download.php?file=miniupnpc-1.9.20140701.tar.gz' -O miniupnpc-1.9.20140701.tar.gz + wget 'http://miniupnp.free.fr/files/download.php?file=miniupnpc-1.9.20151008.tar.gz' -O miniupnpc-1.9.20151008.tar.gz wget 'https://www.openssl.org/source/openssl-1.0.1l.tar.gz' wget 'http://download.oracle.com/berkeley-db/db-5.1.29.NC.tar.gz' wget 'http://zlib.net/zlib-1.2.8.tar.gz' diff --git a/src/core.h b/src/core.h index 6a0286f9d..ae1e463c7 100644 --- a/src/core.h +++ b/src/core.h @@ -33,6 +33,7 @@ static const int BLOCK_VERSION_DEFAULT = (1 << 0); static const int BLOCK_VERSION_AUXPOW = (1 << 8); static const int BLOCK_VERSION_CHAIN_START = (1 << 16); static const int BLOCK_VERSION_CHAIN_END = (1 << 30); +static const int BLOCK_VERSION_BASE_MASK = 0x000000ff; // DogeCoin aux chain ID = 0x0062 (98) static const int AUXPOW_CHAIN_ID = 0x0062; @@ -364,7 +365,7 @@ class CBlockHeader { public: // header - static const int CURRENT_VERSION=2; + static const int CURRENT_VERSION=3; int nVersion; uint256 hashPrevBlock; uint256 hashMerkleRoot; @@ -396,6 +397,12 @@ public: return nVersion / BLOCK_VERSION_CHAIN_START; } + // base block version without auxpow chain + int GetBaseVersion() const + { + return nVersion & BLOCK_VERSION_BASE_MASK; + } + void SetAuxPow(CAuxPow* pow); void SetNull() diff --git a/src/main.cpp b/src/main.cpp index 9d1eca948..5cf8d744c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1966,6 +1966,12 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C unsigned int flags = SCRIPT_VERIFY_NOCACHE | (fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE); + if (block.GetBaseVersion() >= 3 && + ((!TestNet() && CBlockIndex::IsSuperMajority(3, pindex->pprev, 1500, 2000)) || + (TestNet() && CBlockIndex::IsSuperMajority(3, pindex->pprev, 501, 1000)))) { + flags |= SCRIPT_VERIFY_DERSIG; + } + CBlockUndo blockundo; CCheckQueueControl control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL); @@ -2131,7 +2137,7 @@ void static UpdateTip(CBlockIndex *pindexNew) { const CBlockIndex* pindex = chainActive.Tip(); for (int i = 0; i < 100 && pindex != NULL; i++) { - if (pindex->nVersion > CBlock::CURRENT_VERSION && !IsAuxPowVersion(pindex->nVersion)) + if (pindex->GetBaseVersion() > CBlock::CURRENT_VERSION) ++nUpgraded; pindex = pindex->pprev; } @@ -2706,15 +2712,13 @@ bool AcceptBlockHeader(CBlockHeader& block, CValidationState& state, CBlockIndex if (pcheckpoint && nHeight < pcheckpoint->nHeight) return state.DoS(100, error("AcceptBlock() : forked chain older than last checkpoint (height %d)", nHeight)); - // Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded: - if (block.nVersion < 2) - { - if ((!TestNet() && CBlockIndex::IsSuperMajority(2, pindexPrev, 950, 1000)) || - (TestNet() && CBlockIndex::IsSuperMajority(2, pindexPrev, 75, 100))) - { - return state.Invalid(error("AcceptBlock() : rejected nVersion=1 block"), + // Reject block.nVersion<3 blocks when 95% (75% on testnet) of the network has upgraded + // Dogecoin: reject v2 and v1 blocks at the same time, only check once + if (block.GetBaseVersion() < 3) { + if ((!TestNet() && CBlockIndex::IsSuperMajority(3, pindexPrev, 1900, 2000)) || + (TestNet() && CBlockIndex::IsSuperMajority(3, pindexPrev, 750, 1000))) + return state.Invalid(error("AcceptBlock() : rejected nVersion<3 block"), REJECT_OBSOLETE, "bad-version"); - } } } @@ -2756,11 +2760,13 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, } // Enforce block.nVersion=2 rule that the coinbase starts with serialized block height - if (block.nVersion >= 2) + // Dogecoin: reject ONLY if block.nVersion=3 has a supermajority because CBlockIndex::IsSuperMajority + // was hard-disabled until now + if (block.GetBaseVersion() >= 2) { // if 750 of the last 1,000 blocks are version 2 or greater (51/100 if testnet): - if ((!TestNet() && CBlockIndex::IsSuperMajority(2, pindex->pprev, 750, 1000)) || - (TestNet() && CBlockIndex::IsSuperMajority(2, pindex->pprev, 51, 100))) + if ((!TestNet() && CBlockIndex::IsSuperMajority(3, pindex->pprev, 1500, 2000)) || + (TestNet() && CBlockIndex::IsSuperMajority(3, pindex->pprev, 501, 1000))) { CScript expect = CScript() << nHeight; if (block.vtx[0].vin[0].scriptSig.size() < expect.size() || @@ -2804,13 +2810,11 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, bool CBlockIndex::IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned int nRequired, unsigned int nToCheck) { - // Dogecoin: temporarily disable v2 block lockin until we are ready for v2 transition - return false; unsigned int nFound = 0; for (unsigned int i = 0; i < nToCheck && nFound < nRequired && pstart != NULL; i++) { - if (pstart->nVersion >= minVersion) + if (pstart->GetBaseVersion() >= minVersion) ++nFound; pstart = pstart->pprev; } diff --git a/src/main.h b/src/main.h index 211d1b32f..bf11cf361 100644 --- a/src/main.h +++ b/src/main.h @@ -928,6 +928,12 @@ public: } return false; } + + // base block version without auxpow chain + int GetBaseVersion() const + { + return nVersion & BLOCK_VERSION_BASE_MASK; + } }; diff --git a/src/net.cpp b/src/net.cpp index 279ee4d76..f7ea00051 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1109,10 +1109,14 @@ void ThreadMapPort() #ifndef UPNPDISCOVER_SUCCESS /* miniupnpc 1.5 */ devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0); -#else +#elif MINIUPNPC_API_VERSION < 14 /* miniupnpc 1.6 */ int error = 0; devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error); +#else + /* miniupnpc 1.9.20150730 */ + int error = 0; + devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error); #endif struct UPNPUrls urls; diff --git a/src/protocol.h b/src/protocol.h index 4ea0bcebb..7f8626681 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -66,6 +66,7 @@ enum { NODE_NETWORK = (1 << 0), NODE_BLOOM = (1 << 1), + NODE_GETUTXO = (1 << 2), // not implemented, added for reference }; /** A CService with information about it as peer */ diff --git a/src/script.cpp b/src/script.cpp index db0724b27..2cbdaefc9 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -297,6 +297,86 @@ bool IsCanonicalSignature(const valtype &vchSig, unsigned int flags) { 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 &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 >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, unsigned int flags, int nHashType) { CScript::const_iterator pc = script.begin(); @@ -849,6 +929,10 @@ bool EvalScript(vector >& 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 = IsCanonicalSignature(vchSig, flags) && IsCanonicalPubKey(vchPubKey, flags) && CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType, flags); @@ -909,6 +993,10 @@ bool EvalScript(vector >& stack, const CScript& script, co valtype& vchSig = stacktop(-isig); valtype& vchPubKey = stacktop(-ikey); + if (!CheckSignatureEncoding(vchSig, flags)) { + return false; + } + // Check signature bool fOk = IsCanonicalSignature(vchSig, flags) && IsCanonicalPubKey(vchPubKey, flags) && CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType, flags); diff --git a/src/script.h b/src/script.h index 0d8a8544b..0fd6634f4 100644 --- a/src/script.h +++ b/src/script.h @@ -190,7 +190,8 @@ enum SCRIPT_VERIFY_STRICTENC = (1U << 1), // enforce strict conformance to DER and SEC2 for signatures and pubkeys SCRIPT_VERIFY_LOW_S = (1U << 2), // enforce low S values ( 3 && ("," + test[2].get_str() + ",").find(",DERSIG,") != string::npos) { + flagsNow |= SCRIPT_VERIFY_DERSIG; + } + CTransaction tx; - BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, tx, 0, flags, SIGHASH_NONE), strTest); + BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, tx, 0, flagsNow, SIGHASH_NONE), strTest); } } @@ -168,8 +173,13 @@ BOOST_AUTO_TEST_CASE(script_invalid) string scriptPubKeyString = test[1].get_str(); CScript scriptPubKey = ParseScript(scriptPubKeyString); + int flagsNow = flags; + if (test.size() > 3 && ("," + test[2].get_str() + ",").find(",DERSIG,") != string::npos) { + flagsNow |= SCRIPT_VERIFY_DERSIG; + } + CTransaction tx; - BOOST_CHECK_MESSAGE(!VerifyScript(scriptSig, scriptPubKey, tx, 0, flags, SIGHASH_NONE), strTest); + BOOST_CHECK_MESSAGE(!VerifyScript(scriptSig, scriptPubKey, tx, 0, flagsNow, SIGHASH_NONE), strTest); } } diff --git a/src/version.h b/src/version.h index 04b68999a..ea4971415 100644 --- a/src/version.h +++ b/src/version.h @@ -27,7 +27,7 @@ extern const std::string CLIENT_DATE; // network protocol versioning // -static const int PROTOCOL_VERSION = 70003; +static const int PROTOCOL_VERSION = 70004; // intial proto version, to be increased after version/verack negotiation static const int INIT_PROTO_VERSION = 209;