From: Luke Dashjr Date: Fri, 3 Feb 2012 01:17:41 +0000 (-0500) Subject: Merge branch '0.4.x' into 0.5.0.x X-Git-Tag: v0.4.0-unstable~129^2~1^2~18^2~10^2~25^2 X-Git-Url: https://git.novaco.in/?a=commitdiff_plain;h=882e00e2159ce5e12170c7c1811236a039d8abfa;hp=c13d50d8617678c8696b1f33549ed9cc3a0b554e;p=novacoin.git Merge branch '0.4.x' into 0.5.0.x Conflicts: src/main.cpp --- diff --git a/src/db.cpp b/src/db.cpp index 9ac93b3..c2d1827 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -861,12 +861,16 @@ int CWalletDB::LoadWallet(CWallet* pwallet) CPrivKey pkey; ssValue >> pkey; key.SetPrivKey(pkey); + if (key.GetPubKey() != vchPubKey || !key.IsValid()) + return DB_CORRUPT; } else { CWalletKey wkey; ssValue >> wkey; key.SetPrivKey(wkey.vchPrivKey); + if (key.GetPubKey() != vchPubKey || !key.IsValid()) + return DB_CORRUPT; } if (!pwallet->LoadKey(key)) return DB_CORRUPT; diff --git a/src/init.cpp b/src/init.cpp index fc171cd..f8a63d2 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -484,16 +484,11 @@ bool AppInit2(int argc, char* argv[]) fAllowDNS = GetBoolArg("-dns"); fNoListen = GetBoolArg("-nolisten"); - if (fHaveUPnP) - { -#if USE_UPNP - if (GetBoolArg("-noupnp")) - fUseUPnP = false; -#else - if (GetBoolArg("-upnp")) - fUseUPnP = true; -#endif - } + // Command-line args override in-wallet settings: + if (mapArgs.count("-upnp")) + fUseUPnP = GetBoolArg("-upnp"); + else if (mapArgs.count("-noupnp")) + fUseUPnP = !GetBoolArg("-noupnp"); if (!fNoListen) { diff --git a/src/key.h b/src/key.h index df5cfeb..0105916 100644 --- a/src/key.h +++ b/src/key.h @@ -387,6 +387,17 @@ public: { return CBitcoinAddress(GetPubKey()); } + + bool IsValid() + { + if (!fSet) + return false; + + CSecret secret = GetSecret(); + CKey key2; + key2.SetSecret(secret); + return GetPubKey() == key2.GetPubKey(); + } }; #endif diff --git a/src/main.cpp b/src/main.cpp index 1f23844..07b0744 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -418,10 +418,11 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi // Check against previous transactions map mapUnused; int64 nFees = 0; - if (!ConnectInputs(txdb, mapUnused, CDiskTxPos(1,1,1), pindexBest, nFees, false, false)) + bool fInvalid = false; + if (!ConnectInputs(txdb, mapUnused, CDiskTxPos(1,1,1), pindexBest, nFees, false, false, 0, fInvalid)) { - if (pfMissingInputs) - *pfMissingInputs = true; + if (fInvalid) + return error("AcceptToMemoryPool() : FetchInputs found invalid tx %s", hash.ToString().substr(0,10).c_str()); return error("AcceptToMemoryPool() : ConnectInputs failed %s", hash.ToString().substr(0,10).c_str()); } @@ -668,6 +669,11 @@ static const int64 nInterval = nTargetTimespan / nTargetSpacing; // unsigned int ComputeMinWork(unsigned int nBase, int64 nTime) { + // Testnet has min-difficulty blocks + // after nTargetSpacing*2 time between blocks: + if (fTestNet && nTime > nTargetSpacing*2) + return bnProofOfWorkLimit.GetCompact(); + CBigNum bnResult; bnResult.SetCompact(nBase); while (nTime > 0 && bnResult < bnProofOfWorkLimit) @@ -682,16 +688,36 @@ unsigned int ComputeMinWork(unsigned int nBase, int64 nTime) return bnResult.GetCompact(); } -unsigned int static GetNextWorkRequired(const CBlockIndex* pindexLast) +unsigned int static GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlock *pblock) { + unsigned int nProofOfWorkLimit = bnProofOfWorkLimit.GetCompact(); // Genesis block if (pindexLast == NULL) - return bnProofOfWorkLimit.GetCompact(); + return nProofOfWorkLimit; // Only change once per interval if ((pindexLast->nHeight+1) % nInterval != 0) + { + // Special rules for testnet after 15 Feb 2012: + if (fTestNet && pblock->nTime > 1329264000) + { + // If the new block's timestamp is more than 2* 10 minutes + // then allow mining of a min-difficulty block. + if (pblock->nTime - pindexLast->nTime > nTargetSpacing*2) + return nProofOfWorkLimit; + else + { + // Return the last non-special-min-difficulty-rules-block + const CBlockIndex* pindex = pindexLast; + while (pindex->pprev && pindex->nHeight % nInterval != 0 && pindex->nBits == nProofOfWorkLimit) + pindex = pindex->pprev; + return pindex->nBits; + } + } + return pindexLast->nBits; + } // Go back by what we want to be 14 days worth of blocks const CBlockIndex* pindexFirst = pindexLast; @@ -821,8 +847,15 @@ bool CTransaction::DisconnectInputs(CTxDB& txdb) bool CTransaction::ConnectInputs(CTxDB& txdb, map& mapTestPool, CDiskTxPos posThisTx, - CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee) + CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee, + bool& fInvalid) { + // FetchInputs can return false either because we just haven't seen some inputs + // (in which case the transaction should be stored as an orphan) + // or because the transaction is malformed (in which case the transaction should + // be dropped). If tx is definitely invalid, fInvalid will be set to true. + fInvalid = false; + // Take over previous transactions' spent pointers // fBlock is true when this is called from AcceptBlock when a new best-block is added to the blockchain // fMiner is true when called from the internal bitcoin miner @@ -872,7 +905,12 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, map& mapTestPoo } if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size()) + { + // Revisit this if/when transaction replacement is implemented and allows + // adding inputs: + fInvalid = true; return DoS(100, error("ConnectInputs() : %s prevout.n out of range %d %d %d prev tx %s\n%s", GetHash().ToString().substr(0,10).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().substr(0,10).c_str(), txPrev.ToString().c_str())); + } // If prev is coinbase, check that it's matured if (txPrev.IsCoinBase()) @@ -1022,7 +1060,8 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex) CDiskTxPos posThisTx(pindex->nFile, pindex->nBlockPos, nTxPos); nTxPos += ::GetSerializeSize(tx, SER_DISK); - if (!tx.ConnectInputs(txdb, mapQueuedChanges, posThisTx, pindex, nFees, true, false)) + bool fInvalid; + if (!tx.ConnectInputs(txdb, mapQueuedChanges, posThisTx, pindex, nFees, true, false, 0, fInvalid)) return false; } // Write queued txindex changes @@ -1311,7 +1350,7 @@ bool CBlock::AcceptBlock() int nHeight = pindexPrev->nHeight+1; // Check proof of work - if (nBits != GetNextWorkRequired(pindexPrev)) + if (nBits != GetNextWorkRequired(pindexPrev, this)) return DoS(100, error("AcceptBlock() : incorrect proof of work")); // Check timestamp against prev @@ -2832,7 +2871,8 @@ CBlock* CreateNewBlock(CReserveKey& reservekey) // Connecting shouldn't fail due to dependency on other memory pool transactions // because we're already processing them in order of dependency map mapTestPoolTmp(mapTestPool); - if (!tx.ConnectInputs(txdb, mapTestPoolTmp, CDiskTxPos(1,1,1), pindexPrev, nFees, false, true, nMinFee)) + bool fInvalid; + if (!tx.ConnectInputs(txdb, mapTestPoolTmp, CDiskTxPos(1,1,1), pindexPrev, nFees, false, true, nMinFee, fInvalid)) continue; swap(mapTestPool, mapTestPoolTmp); @@ -2863,7 +2903,7 @@ CBlock* CreateNewBlock(CReserveKey& reservekey) pblock->hashPrevBlock = pindexPrev->GetBlockHash(); pblock->hashMerkleRoot = pblock->BuildMerkleTree(); pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); - pblock->nBits = GetNextWorkRequired(pindexPrev); + pblock->nBits = GetNextWorkRequired(pindexPrev, pblock.get()); pblock->nNonce = 0; return pblock.release(); diff --git a/src/main.h b/src/main.h index 3870cee..47394ff 100644 --- a/src/main.h +++ b/src/main.h @@ -637,7 +637,8 @@ public: bool ReadFromDisk(COutPoint prevout); bool DisconnectInputs(CTxDB& txdb); bool ConnectInputs(CTxDB& txdb, std::map& mapTestPool, CDiskTxPos posThisTx, - CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee=0); + CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee, + bool& fInvalid); bool ClientConnectInputs(); bool CheckTransaction() const; bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL); diff --git a/src/net.cpp b/src/net.cpp index 10f7c62..7b92e87 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1156,11 +1156,11 @@ void ThreadMapPort2(void* parg) { string strDesc = "Bitcoin " + FormatFullVersion(); #ifndef UPNPDISCOVER_SUCCESS - /* miniupnpc 1.5 */ + /* miniupnpc 1.5 */ r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, port, port, lanaddr, strDesc.c_str(), "TCP", 0); #else - /* miniupnpc 1.6 */ + /* miniupnpc 1.6 */ r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0"); #endif @@ -1170,6 +1170,7 @@ void ThreadMapPort2(void* parg) port, port, lanaddr, r, strupnperror(r)); else printf("UPnP Port Mapping successful.\n"); + int i = 1; loop { if (fShutdown || !fUseUPnP) { @@ -1179,7 +1180,26 @@ void ThreadMapPort2(void* parg) FreeUPNPUrls(&urls); return; } + if (i % 600 == 0) // Refresh every 20 minutes + { +#ifndef UPNPDISCOVER_SUCCESS + /* miniupnpc 1.5 */ + r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, + port, port, lanaddr, strDesc.c_str(), "TCP", 0); +#else + /* miniupnpc 1.6 */ + r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, + port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0"); +#endif + + if(r!=UPNPCOMMAND_SUCCESS) + printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", + port, port, lanaddr, r, strupnperror(r)); + else + printf("UPnP Port Mapping successful.\n");; + } Sleep(2000); + i++; } } else { printf("No valid UPnP IGDs found\n");