diff --git a/configure.ac b/configure.ac index 96690eb..5e7dc2f 100755 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 1) define(_CLIENT_VERSION_MINOR, 3) define(_CLIENT_VERSION_REVISION, 1) -define(_CLIENT_VERSION_BUILD, 19) +define(_CLIENT_VERSION_BUILD, 20) define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2018) AC_INIT([NewYorkCoin],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[https://github.com/NewYorkCoin-NYC/nycoin/issues],[newyorkcoin]) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 9de2556..18aaea7 100755 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -158,7 +158,8 @@ class CMainParams : public CChainParams { (3000000, uint256S("0x66e6dcb49370062537c1f6abf655ffbbc53ba4851ef00081aa2e4be1e2903ba7")) (3500000, uint256S("0x3f1a97f68ce8eaf38fc0c56868b3eb98ccb67d14bff4e78afb91d82cba853ddf")) (3938415, uint256S("0xe1fa41f6fe8d2785d89b0468e13e4c450493e5356c024a098c5b727ca89138ee")) - (4500000, uint256S("0xdd86fad58b3fa5d83a15a18df1cc20cdcdb1b2cf5d2d702e0c60bbb7d4602fb1")), + (4500000, uint256S("0xdd86fad58b3fa5d83a15a18df1cc20cdcdb1b2cf5d2d702e0c60bbb7d4602fb1")) + (4821195, uint256S("0x7cf9862123405a687626b27ecaea377698d23d68458bb9b2a16e0262ec32df84")), 1514765144, // * UNIX timestamp of last checkpoint block 5141422, // * total number of transactions between genesis and last checkpoint diff --git a/src/init.cpp b/src/init.cpp index 4230303..566f28e 100755 --- a/src/init.cpp +++ b/src/init.cpp @@ -322,6 +322,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-seednode=", _("Connect to a node to retrieve peer addresses, and disconnect")); strUsage += HelpMessageOpt("-timeout=", strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT)); strUsage += HelpMessageOpt("-bloomfilters", _("Allow peers to set bloom filters (default: 1)")); + strUsage += HelpMessageOpt("-fastsync", _("Increases maximum number of in-flight blocks and only perform minimal block validation")); #ifdef USE_UPNP #if USE_UPNP strUsage += HelpMessageOpt("-upnp", _("Use UPnP to map the listening port (default: 1 when listening)")); @@ -332,7 +333,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-whitebind=", _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6")); strUsage += HelpMessageOpt("-whitelist=", _("Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.") + " " + _("Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway")); - + #ifdef ENABLE_WALLET strUsage += HelpMessageGroup(_("Wallet options:")); @@ -451,7 +452,9 @@ std::string LicenseInfo() { return FormatParagraph(strprintf(_("Copyright (C) 2009-%i The Bitcoin Core Developers"), COPYRIGHT_YEAR)) + "\n" + "\n" + - FormatParagraph(strprintf(_("Copyright (C) 2013-%i The NewYorkCoin Developers"), COPYRIGHT_YEAR)) + "\n" + + FormatParagraph(strprintf(_("Copyright (C) 2013-%i The DogeCoin Developers"), COPYRIGHT_YEAR)) + "\n" + + "\n" + + FormatParagraph(strprintf(_("Copyright (C) 2017-%i The NewYorkCoin Developers"), COPYRIGHT_YEAR)) + "\n" + "\n" + FormatParagraph(_("This is experimental software.")) + "\n" + "\n" + @@ -734,6 +737,11 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) LogPrintf("%s: parameter interaction: -salvagewallet=1 -> setting -rescan=1\n", __func__); } + if (GetBoolArg("-fastsync", false)) + { + LogPrintf("%s: parameter interaction: -fastsync=1 increasing max blocks in flight and minimizing block checks\n", __func__); + } + // -zapwallettx implies a rescan if (GetBoolArg("-zapwallettxes", false)) { if (SoftSetBoolArg("-rescan", true)) @@ -975,15 +983,15 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) std::string warningString; std::string errorString; - + if (!CWallet::Verify(strWalletFile, warningString, errorString)) return false; - + if (!warningString.empty()) InitWarning(warningString); if (!errorString.empty()) return InitError(warningString); - + } // (!fDisableWallet) #endif // ENABLE_WALLET // ********************************************************* Step 6: network initialization diff --git a/src/leveldb/util/env_win.cc b/src/leveldb/util/env_win.cc index ef2ecae..d877d61 100755 --- a/src/leveldb/util/env_win.cc +++ b/src/leveldb/util/env_win.cc @@ -1,7 +1,7 @@ // This file contains source that originates from: // http://code.google.com/p/leveldbwin/source/browse/trunk/win32_impl_src/env_win32.h // http://code.google.com/p/leveldbwin/source/browse/trunk/win32_impl_src/port_win32.cc -// Those files dont' have any explict license headers but the +// Those files dont' have any explict license headers but the // project (http://code.google.com/p/leveldbwin/) lists the 'New BSD License' // as the license. #if defined(LEVELDB_PLATFORM_WINDOWS) @@ -103,39 +103,21 @@ class Win32RandomAccessFile : public RandomAccessFile DISALLOW_COPY_AND_ASSIGN(Win32RandomAccessFile); }; -class Win32MapFile : public WritableFile +class Win32WritableFile : public WritableFile { public: - Win32MapFile(const std::string& fname); + Win32WritableFile(const std::string& fname); - ~Win32MapFile(); + ~Win32WritableFile(); virtual Status Append(const Slice& data); virtual Status Close(); virtual Status Flush(); virtual Status Sync(); BOOL isEnable(); private: - std::string _filename; - HANDLE _hFile; - size_t _page_size; - size_t _map_size; // How much extra memory to map at a time - char* _base; // The mapped region - HANDLE _base_handle; - char* _limit; // Limit of the mapped region - char* _dst; // Where to write next (in range [base_,limit_]) - char* _last_sync; // Where have we synced up to - uint64_t _file_offset; // Offset of base_ in file - //LARGE_INTEGER file_offset_; - // Have we done an munmap of unsynced data? - bool _pending_sync; - - // Roundup x to a multiple of y - static size_t _Roundup(size_t x, size_t y); - size_t _TruncateToPageBoundary(size_t s); - bool _UnmapCurrentRegion(); - bool _MapNewRegion(); - DISALLOW_COPY_AND_ASSIGN(Win32MapFile); - BOOL _Init(LPCWSTR Path); + std::string filename_; + ::HANDLE _hFile; + }; class Win32FileLock : public FileLock @@ -155,7 +137,7 @@ class Win32FileLock : public FileLock class Win32Logger : public Logger { -public: +public: friend class Win32Env; virtual ~Win32Logger(); virtual void Logv(const char* format, va_list ap); @@ -265,19 +247,19 @@ std::wstring& ModifyPath(std::wstring& path) std::string GetLastErrSz() { LPWSTR lpMsgBuf; - FormatMessageW( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | + FormatMessageW( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), 0, // Default language (LPWSTR) &lpMsgBuf, 0, - NULL + NULL ); std::string Err; - ToNarrowPath(lpMsgBuf, Err); + ToNarrowPath(lpMsgBuf, Err); LocalFree( lpMsgBuf ); return Err; } @@ -285,16 +267,16 @@ std::string GetLastErrSz() std::wstring GetLastErrSzW() { LPVOID lpMsgBuf; - FormatMessageW( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | + FormatMessageW( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), 0, // Default language (LPWSTR) &lpMsgBuf, 0, - NULL + NULL ); std::wstring Err = (LPCWSTR)lpMsgBuf; LocalFree(lpMsgBuf); @@ -442,202 +424,67 @@ void Win32RandomAccessFile::_CleanUp() } } -size_t Win32MapFile::_Roundup( size_t x, size_t y ) -{ - return ((x + y - 1) / y) * y; -} - -size_t Win32MapFile::_TruncateToPageBoundary( size_t s ) +Win32WritableFile::Win32WritableFile(const std::string& fname) : filename_(fname) { - s -= (s & (_page_size - 1)); - assert((s % _page_size) == 0); - return s; + std::wstring path; + ToWidePath(fname, path); + DWORD Flag = PathFileExistsW(path.c_str()) ? OPEN_EXISTING : CREATE_ALWAYS; + _hFile = CreateFileW(path.c_str(), + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE, + NULL, + Flag, + FILE_ATTRIBUTE_NORMAL, + NULL); + // CreateFileW returns INVALID_HANDLE_VALUE in case of error, always check isEnable() before use } -bool Win32MapFile::_UnmapCurrentRegion() +Win32WritableFile::~Win32WritableFile() { - bool result = true; - if (_base != NULL) { - if (_last_sync < _limit) { - // Defer syncing this data until next Sync() call, if any - _pending_sync = true; - } - if (!UnmapViewOfFile(_base) || !CloseHandle(_base_handle)) - result = false; - _file_offset += _limit - _base; - _base = NULL; - _base_handle = NULL; - _limit = NULL; - _last_sync = NULL; - _dst = NULL; - // Increase the amount we map the next time, but capped at 1MB - if (_map_size < (1<<20)) { - _map_size *= 2; - } + if(_hFile != INVALID_HANDLE_VALUE) + { + Close(); } - return result; } -bool Win32MapFile::_MapNewRegion() +Status Win32WritableFile::Append(const Slice& data) { - assert(_base == NULL); - //LONG newSizeHigh = (LONG)((file_offset_ + map_size_) >> 32); - //LONG newSizeLow = (LONG)((file_offset_ + map_size_) & 0xFFFFFFFF); - DWORD off_hi = (DWORD)(_file_offset >> 32); - DWORD off_lo = (DWORD)(_file_offset & 0xFFFFFFFF); - LARGE_INTEGER newSize; - newSize.QuadPart = _file_offset + _map_size; - SetFilePointerEx(_hFile, newSize, NULL, FILE_BEGIN); - SetEndOfFile(_hFile); - - _base_handle = CreateFileMappingA( - _hFile, - NULL, - PAGE_READWRITE, - 0, - 0, - 0); - if (_base_handle != NULL) { - _base = (char*) MapViewOfFile(_base_handle, - FILE_MAP_ALL_ACCESS, - off_hi, - off_lo, - _map_size); - if (_base != NULL) { - _limit = _base + _map_size; - _dst = _base; - _last_sync = _base; - return true; - } + DWORD r = 0; + if(!WriteFile(_hFile, data.data(), data.size(), &r, NULL) || r != data.size()) + { + return Status::IOError("Win32WritableFile.Append::WriteFile:" +filename_, Win32::GetLastErrSz()); } - return false; + return Status::OK(); } -Win32MapFile::Win32MapFile( const std::string& fname) : - _filename(fname), - _hFile(NULL), - _page_size(Win32::g_PageSize), - _map_size(_Roundup(65536, Win32::g_PageSize)), - _base(NULL), - _base_handle(NULL), - _limit(NULL), - _dst(NULL), - _last_sync(NULL), - _file_offset(0), - _pending_sync(false) +Status Win32WritableFile::Close() { - std::wstring path; - ToWidePath(fname, path); - _Init(path.c_str()); - assert((Win32::g_PageSize & (Win32::g_PageSize - 1)) == 0); -} - -Status Win32MapFile::Append( const Slice& data ) -{ - const char* src = data.data(); - size_t left = data.size(); - Status s; - while (left > 0) { - assert(_base <= _dst); - assert(_dst <= _limit); - size_t avail = _limit - _dst; - if (avail == 0) { - if (!_UnmapCurrentRegion() || - !_MapNewRegion()) { - return Status::IOError("WinMmapFile.Append::UnmapCurrentRegion or MapNewRegion: ", Win32::GetLastErrSz()); - } - } - size_t n = (left <= avail) ? left : avail; - memcpy(_dst, src, n); - _dst += n; - src += n; - left -= n; - } - return s; -} - -Status Win32MapFile::Close() -{ - Status s; - size_t unused = _limit - _dst; - if (!_UnmapCurrentRegion()) { - s = Status::IOError("WinMmapFile.Close::UnmapCurrentRegion: ",Win32::GetLastErrSz()); - } else if (unused > 0) { - // Trim the extra space at the end of the file - LARGE_INTEGER newSize; - newSize.QuadPart = _file_offset - unused; - if (!SetFilePointerEx(_hFile, newSize, NULL, FILE_BEGIN)) { - s = Status::IOError("WinMmapFile.Close::SetFilePointer: ",Win32::GetLastErrSz()); - } else - SetEndOfFile(_hFile); - } - if (!CloseHandle(_hFile)) { - if (s.ok()) { - s = Status::IOError("WinMmapFile.Close::CloseHandle: ", Win32::GetLastErrSz()); - } + if(!CloseHandle(_hFile)) + { + return Status::IOError("Win32WritableFile.Close::CloseHandle:"+filename_, Win32::GetLastErrSz()); } _hFile = INVALID_HANDLE_VALUE; - _base = NULL; - _base_handle = NULL; - _limit = NULL; - - return s; + return Status::OK(); } -Status Win32MapFile::Sync() -{ - Status s; - if (_pending_sync) { - // Some unmapped data was not synced - _pending_sync = false; - if (!FlushFileBuffers(_hFile)) { - s = Status::IOError("WinMmapFile.Sync::FlushFileBuffers: ",Win32::GetLastErrSz()); - } - } - if (_dst > _last_sync) { - // Find the beginnings of the pages that contain the first and last - // bytes to be synced. - size_t p1 = _TruncateToPageBoundary(_last_sync - _base); - size_t p2 = _TruncateToPageBoundary(_dst - _base - 1); - _last_sync = _dst; - if (!FlushViewOfFile(_base + p1, p2 - p1 + _page_size)) { - s = Status::IOError("WinMmapFile.Sync::FlushViewOfFile: ",Win32::GetLastErrSz()); - } - } - return s; -} -Status Win32MapFile::Flush() +Status Win32WritableFile::Flush() { return Status::OK(); } -Win32MapFile::~Win32MapFile() +Status Win32WritableFile::Sync() { - if (_hFile != INVALID_HANDLE_VALUE) { - Win32MapFile::Close(); + if(!FlushFileBuffers(_hFile)) + { + return Status::IOError("Win32WritableFile.Sync::FlushFilebuffers:"+filename_, Win32::GetLastErrSz()); } + return Status::OK(); } -BOOL Win32MapFile::_Init( LPCWSTR Path ) -{ - DWORD Flag = PathFileExistsW(Path) ? OPEN_EXISTING : CREATE_ALWAYS; - _hFile = CreateFileW(Path, - GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE, - NULL, - Flag, - FILE_ATTRIBUTE_NORMAL, - NULL); - if(!_hFile || _hFile == INVALID_HANDLE_VALUE) - return FALSE; - else - return TRUE; -} - -BOOL Win32MapFile::isEnable() +BOOL Win32WritableFile::isEnable() { - return _hFile ? TRUE : FALSE; + return _hFile != INVALID_HANDLE_VALUE; } Win32FileLock::Win32FileLock( const std::string& fname ) : @@ -779,7 +626,7 @@ Status Win32Env::GetChildren(const std::string& dir, std::vector* r BOOL hasNext = TRUE; std::string child; while(hasNext){ - ToNarrowPath(wfd.cFileName, child); + ToNarrowPath(wfd.cFileName, child); if(child != ".." && child != ".") { result->push_back(child); } @@ -846,7 +693,7 @@ Status Win32Env::RenameFile( const std::string& src, const std::string& target ) sRet = Status::IOError(src, "Could not rename file."); else if(!::MoveFileW(wsrc_path.c_str(), wtarget_path.c_str() ) ) - sRet = Status::IOError(src, "Could not rename file."); + sRet = Status::IOError(src, "Could not rename file."); } } return sRet; @@ -981,7 +828,7 @@ Status Win32Env::NewLogger( const std::string& fname, Logger** result ) { Status sRet; std::string path = fname; - Win32MapFile* pMapFile = new Win32MapFile(ModifyPath(path)); + Win32WritableFile* pMapFile = new Win32WritableFile(ModifyPath(path)); if(!pMapFile->isEnable()){ delete pMapFile; *result = NULL; @@ -995,7 +842,7 @@ Status Win32Env::NewWritableFile( const std::string& fname, WritableFile** resul { Status sRet; std::string path = fname; - Win32MapFile* pFile = new Win32MapFile(ModifyPath(path)); + Win32WritableFile* pFile = new Win32WritableFile(ModifyPath(path)); if(!pFile->isEnable()){ *result = NULL; sRet = Status::IOError(fname,Win32::GetLastErrSz()); diff --git a/src/main.cpp b/src/main.cpp index e022347..5d04cd5 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -68,6 +68,8 @@ size_t nCoinCacheUsage = 5000 * 300; uint64_t nPruneTarget = 0; bool fAlerts = DEFAULT_ALERTS; +int nAllowedBlocksInTransit = DEFAULT_MAX_BLOCKS_IN_TRANSIT_PER_PEER; + /** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */ CFeeRate minRelayTxFee = CFeeRate(DEFAULT_FEE); @@ -2696,6 +2698,20 @@ bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool f bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bool fCheckMerkleRoot) { + // Shortcut checks for almost all early blocks + if(chainActive.Height() < SKIP_VALIDATION_HEIGHT && GetBoolArg("-fastsync", false)) + { + const CChainParams& chainParams = Params(); + // hit all the checkpoints but skip most of the rest + std::map::const_iterator cpItr = chainParams.Checkpoints().mapCheckpoints.find(chainActive.Height()); + + // if the current block is not found in the checkpoints list, skip it + if(cpItr == chainParams.Checkpoints().mapCheckpoints.end()) + { + return true; + } + } + // These are checks that are independent of context. // Check that the header is valid (particularly PoW). This is mostly @@ -2872,22 +2888,30 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc return true; } - if (!CheckBlockHeader(block, state)) - return false; + // Since we're close to chaintip, reenable checks to ensure state is correct when sync completes + // Also reenable checks if -fastsync is not set + if(chainActive.Height() >= SKIP_VALIDATION_HEIGHT || (GetBoolArg("-fastsync", false) == false)) + { + if (!CheckBlockHeader(block, state)) + return false; - // Get prev block index - CBlockIndex* pindexPrev = NULL; - if (hash != chainparams.GetConsensus(0).hashGenesisBlock) { - BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock); - if (mi == mapBlockIndex.end()) - return state.DoS(10, error("%s: prev block not found", __func__), 0, "bad-prevblk"); - pindexPrev = (*mi).second; - if (pindexPrev->nStatus & BLOCK_FAILED_MASK) - return state.DoS(100, error("%s: prev block invalid", __func__), REJECT_INVALID, "bad-prevblk"); + // Get prev block index + CBlockIndex* pindexPrev = NULL; + if (hash != chainparams.GetConsensus(0).hashGenesisBlock) { + BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock); + if (mi == mapBlockIndex.end()) + return state.DoS(10, error("%s: prev block not found", __func__), 0, "bad-prevblk"); + pindexPrev = (*mi).second; + if (pindexPrev->nStatus & BLOCK_FAILED_MASK) + return state.DoS(100, error("%s: prev block invalid", __func__), REJECT_INVALID, "bad-prevblk"); + } + + if (!ContextualCheckBlockHeader(block, state, pindexPrev)) + return false; } - if (!ContextualCheckBlockHeader(block, state, pindexPrev)) - return false; + + if (pindex == NULL) pindex = AddToBlockIndex(block); @@ -4226,6 +4250,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, return error("message inv size() = %u", vInv.size()); } + if(GetBoolArg("-fastsync", false)) + { + nAllowedBlocksInTransit = MAX_BLOCKS_IN_TRANSIT_PER_PEER; + LogPrint("net", "fastsync activated maximum number of blocks in transit increased"); + } + LOCK(cs_main); std::vector vToFetch; @@ -4257,7 +4287,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexBestHeader), inv.hash); CNodeState *nodestate = State(pfrom->GetId()); if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - chainparams.GetConsensus(chainActive.Height()).nPowTargetSpacing * 20 && - nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) { + nodestate->nBlocksInFlight < nAllowedBlocksInTransit) { vToFetch.push_back(inv); // Mark block as in flight already, even though the actual "getdata" message only goes out // later (within the same cs_main lock, though). @@ -5142,11 +5172,16 @@ bool SendMessages(CNode* pto, bool fSendTrickle) // // Message: getdata (blocks) // + if(GetBoolArg("-fastsync", false)) + { + nAllowedBlocksInTransit = MAX_BLOCKS_IN_TRANSIT_PER_PEER; + LogPrint("net", "fastsync activated maximum number of blocks in transit increased"); + } vector vGetData; - if (!pto->fDisconnect && !pto->fClient && (fFetch || !IsInitialBlockDownload()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) { + if (!pto->fDisconnect && !pto->fClient && (fFetch || !IsInitialBlockDownload()) && state.nBlocksInFlight < nAllowedBlocksInTransit) { vector vToDownload; NodeId staller = -1; - FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller); + FindNextBlocksToDownload(pto->GetId(), nAllowedBlocksInTransit - state.nBlocksInFlight, vToDownload, staller); BOOST_FOREACH(CBlockIndex *pindex, vToDownload) { vGetData.push_back(CInv(MSG_BLOCK, pindex->GetBlockHash())); MarkBlockAsInFlight(pto->GetId(), pindex->GetBlockHash(), consensusParams, pindex); diff --git a/src/main.h b/src/main.h index 58484b5..3090a3f 100755 --- a/src/main.h +++ b/src/main.h @@ -53,6 +53,9 @@ static const unsigned int DEFAULT_BLOCK_MIN_SIZE = 0; static const unsigned int DEFAULT_FEE = 0; + +/** Don't validate every block below this height **/ +static const int SKIP_VALIDATION_HEIGHT = 4500001; /** Default for -blockprioritysize, maximum space for zero/low-fee transactions **/ static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE = 27000; /** Default for accepting alerts from the P2P network. */ @@ -75,8 +78,10 @@ static const unsigned int UNDOFILE_CHUNK_SIZE = 0x100000; // 1 MiB static const int MAX_SCRIPTCHECK_THREADS = 16; /** -par default (number of script-checking threads, 0 = auto) */ static const int DEFAULT_SCRIPTCHECK_THREADS = 0; -/** Number of blocks that can be requested at any given time from a single peer. */ -static const int MAX_BLOCKS_IN_TRANSIT_PER_PEER = 16; +/** Default Number of Blocks that can be requested at any given time from a single peer **/ +static const int DEFAULT_MAX_BLOCKS_IN_TRANSIT_PER_PEER = 16; +/** Maximum Number of blocks that can be requested at any given time from a single peer. */ +static const int MAX_BLOCKS_IN_TRANSIT_PER_PEER = 256; /** Timeout in seconds during which a peer must stall block download progress before being disconnected. */ static const unsigned int BLOCK_STALLING_TIMEOUT = 2; /** Number of headers sent in one getheaders result. We rely on the assumption that if a peer sends @@ -119,6 +124,7 @@ extern bool fCheckpointsEnabled; extern size_t nCoinCacheUsage; extern CFeeRate minRelayTxFee; extern bool fAlerts; +extern int nAllowedBlocksInTransit; /** Best header we've seen so far (used for getheaders queries' starting points). */ extern CBlockIndex *pindexBestHeader; diff --git a/src/net.cpp b/src/net.cpp index c9103b6..00c57d9 100755 --- a/src/net.cpp +++ b/src/net.cpp @@ -549,6 +549,7 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes) if (msg.in_data && msg.hdr.nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH) { LogPrint("net", "Oversized message from peer=%i, disconnecting\n", GetId()); + LogPrint("net", "Oversized message type=%s, size=%i\n", msg.hdr.GetCommand(), msg.hdr.nMessageSize); return false; } diff --git a/src/net.h b/src/net.h index 17502b9..a8ce1b8 100755 --- a/src/net.h +++ b/src/net.h @@ -47,8 +47,8 @@ static const int TIMEOUT_INTERVAL = 20 * 60; static const unsigned int MAX_INV_SZ = 50000; /** The maximum number of new addresses to accumulate before announcing. */ static const unsigned int MAX_ADDR_TO_SEND = 1000; -/** Maximum length of incoming protocol messages (no message over 2 MiB is currently acceptable). */ -static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = 2 * 1024 * 1024; +/** Maximum length of incoming protocol messages (no message over 4 MiB is currently acceptable). */ +static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = 4 * 1000 * 1000; /** -listen default */ static const bool DEFAULT_LISTEN = true; /** -upnp default */ diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index c817d44..cb819fc 100755 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -215,6 +215,25 @@ Value addnode(const Array& params, bool fHelp) return Value::null; } +Value disconnectnode(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "disconnectnode \"node\" \n" + "\nImmediately disconnects from the specified node.\n" + "\nArguments:\n" + "1. \"node\" (string, required) The node (see getpeerinfo for nodes)\n" + "\nExamples:\n" + + HelpExampleCli("disconnectnode", "\"192.168.0.6:17020\"") + + HelpExampleRpc("disconnectnode", "\"192.168.0.6:17020\"") + ); + CNode* pNode = FindNode(params[0].get_str()); + if (pNode == NULL) + throw JSONRPCError(RPC_CLIENT_NODE_NOT_CONNECTED, "Node not found in connected nodes"); + pNode->CloseSocketDisconnect(); + return Value::null; +} + Value getaddednodeinfo(const Array& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) diff --git a/src/rpcprotocol.h b/src/rpcprotocol.h index 4f3f70f..f4f112c 100755 --- a/src/rpcprotocol.h +++ b/src/rpcprotocol.h @@ -65,6 +65,7 @@ enum RPCErrorCode RPC_CLIENT_IN_INITIAL_DOWNLOAD = -10, //! Still downloading initial blocks RPC_CLIENT_NODE_ALREADY_ADDED = -23, //! Node is already added RPC_CLIENT_NODE_NOT_ADDED = -24, //! Node has not been added before + RPC_CLIENT_NODE_NOT_CONNECTED = -29, //! Node to disconnect not found in connected nodes //! Wallet errors RPC_WALLET_ERROR = -4, //! Unspecified problem with wallet (key not found etc.) diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 27ce74f..5ac9234 100755 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -284,6 +284,7 @@ static const CRPCCommand vRPCCommands[] = /* P2P networking */ { "network", "getnetworkinfo", &getnetworkinfo, true }, { "network", "addnode", &addnode, true }, + { "network", "disconnectnode", &disconnectnode, true }, { "network", "getaddednodeinfo", &getaddednodeinfo, true }, { "network", "getconnectioncount", &getconnectioncount, true }, { "network", "getnettotals", &getnettotals, true }, diff --git a/src/rpcserver.h b/src/rpcserver.h index d1051c4..ff216ea 100755 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -56,7 +56,7 @@ void StopRPCThreads(); /** Query whether RPC is running */ bool IsRPCRunning(); -/** +/** * Set the RPC warmup status. When this is done, all RPC calls will error out * immediately with RPC_IN_WARMUP. */ @@ -148,6 +148,7 @@ extern std::string HelpExampleRpc(std::string methodname, std::string args); extern void EnsureWalletIsUnlocked(); +extern json_spirit::Value disconnectnode(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getconnectioncount(const json_spirit::Array& params, bool fHelp); // in rpcnet.cpp extern json_spirit::Value getpeerinfo(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value ping(const json_spirit::Array& params, bool fHelp); diff --git a/src/version.h b/src/version.h index 504262d..0465be4 100755 --- a/src/version.h +++ b/src/version.h @@ -9,7 +9,7 @@ * network protocol versioning */ -static const int PROTOCOL_VERSION = 70005; +static const int PROTOCOL_VERSION = 70012; //! initial proto version, to be increased after version/verack negotiation static const int INIT_PROTO_VERSION = 209;