{"action":"created","comment":{"url":"https://api.github.com/repos/bitcoin/bitcoin/pulls/comments/42606302","id":42606302,"diff_hunk":"@@ -2071,6 +2077,96 @@ void CNode::RecordBytesSent(uint64_t bytes)\n {\n     LOCK(cs_totalBytesSent);\n     nTotalBytesSent += bytes;\n+\n+    uint64_t now = GetTime();\n+    if (nMaxOutboundCycleStartTime + nMaxOutboundTimeframe < now)\n+    {\n+        // timeframe expired, reset cycle\n+        nMaxOutboundCycleStartTime = now;\n+        nMaxOutboundTotalBytesSentInCycle = 0;\n+    }\n+\n+    // TODO, exclude whitebind peers\n+    nMaxOutboundTotalBytesSentInCycle += bytes;\n+}\n+\n+void CNode::SetMaxOutboundTarget(uint64_t limit)\n+{\n+    LOCK(cs_totalBytesSent);\n+    uint64_t recommendedMinimum = (nMaxOutboundTimeframe / 600) * MAX_BLOCK_SIZE;\n+    nMaxOutboundLimit = limit;\n+\n+    if (limit < recommendedMinimum)\n+        LogPrintf(\"Max outbound target very small (%s) and are very unlikely to be reached, recommended minimum is %s\\n\", nMaxOutboundLimit, recommendedMinimum);\n+}\n+\n+uint64_t CNode::GetMaxOutboundTarget()\n+{\n+    LOCK(cs_totalBytesSent);\n+    return nMaxOutboundLimit;\n+}\n+\n+uint64_t CNode::GetMaxOutboundTimeframe()\n+{\n+    LOCK(cs_totalBytesSent);\n+    return nMaxOutboundTimeframe;\n+}\n+\n+uint64_t CNode::GetMaxOutboundTimeLeftInCycle()\n+{\n+    LOCK(cs_totalBytesSent);\n+    if (nMaxOutboundLimit == 0)\n+        return 0;\n+\n+    if (nMaxOutboundCycleStartTime == 0)\n+        return nMaxOutboundTimeframe;\n+\n+    uint64_t cycleEndTime = nMaxOutboundCycleStartTime + nMaxOutboundTimeframe;\n+    uint64_t now = GetTime();\n+    return (cycleEndTime < now) ? 0 : cycleEndTime - GetTime();\n+}\n+\n+void CNode::SetMaxOutboundTimeframe(uint64_t timeframe)\n+{\n+    LOCK(cs_totalBytesSent);\n+    if (nMaxOutboundTimeframe != timeframe)\n+    {\n+        // reset measure-cycle in case of changing\n+        // the timeframe\n+        nMaxOutboundCycleStartTime = GetTime();\n+    }\n+    nMaxOutboundTimeframe = timeframe;\n+}\n+\n+bool CNode::OutboundTargetReached(bool historicalBlockServingLimit)\n+{\n+    LOCK(cs_totalBytesSent);\n+    if (nMaxOutboundLimit == 0)\n+        return false;\n+\n+    if (historicalBlockServingLimit)\n+    {\n+        // keep a large enought buffer to at least relay each block once\n+        uint64_t timeLeftInCycle = GetMaxOutboundTimeLeftInCycle();\n+        uint64_t buffer = timeLeftInCycle / 600 * MAX_BLOCK_SIZE;\n+        if (buffer >= nMaxOutboundLimit || nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit - buffer)\n+        {\n+            return true;\n+        }","path":"src/net.cpp","position":99,"original_position":99,"commit_id":"30922c33bfc04ce12ebb5b53363a5321fe906a17","original_commit_id":"30922c33bfc04ce12ebb5b53363a5321fe906a17","user":{"login":"btcdrak","id":7275704,"avatar_url":"https://avatars.githubusercontent.com/u/7275704?v=3","gravatar_id":"","url":"https://api.github.com/users/btcdrak","html_url":"https://github.com/btcdrak","followers_url":"https://api.github.com/users/btcdrak/followers","following_url":"https://api.github.com/users/btcdrak/following{/other_user}","gists_url":"https://api.github.com/users/btcdrak/gists{/gist_id}","starred_url":"https://api.github.com/users/btcdrak/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/btcdrak/subscriptions","organizations_url":"https://api.github.com/users/btcdrak/orgs","repos_url":"https://api.github.com/users/btcdrak/repos","events_url":"https://api.github.com/users/btcdrak/events{/privacy}","received_events_url":"https://api.github.com/users/btcdrak/received_events","type":"User","site_admin":false},"body":"Braces not required.","created_at":"2015-10-21T10:19:34Z","updated_at":"2015-10-21T10:19:34Z","html_url":"https://github.com/bitcoin/bitcoin/pull/6622#discussion_r42606302","pull_request_url":"https://api.github.com/repos/bitcoin/bitcoin/pulls/6622","_links":{"self":{"href":"https://api.github.com/repos/bitcoin/bitcoin/pulls/comments/42606302"},"html":{"href":"https://github.com/bitcoin/bitcoin/pull/6622#discussion_r42606302"},"pull_request":{"href":"https://api.github.com/repos/bitcoin/bitcoin/pulls/6622"}}},"pull_request":{"url":"https://api.github.com/repos/bitcoin/bitcoin/pulls/6622","id":44033197,"html_url":"https://github.com/bitcoin/bitcoin/pull/6622","diff_url":"https://github.com/bitcoin/bitcoin/pull/6622.diff","patch_url":"https://github.com/bitcoin/bitcoin/pull/6622.patch","issue_url":"https://api.github.com/repos/bitcoin/bitcoin/issues/6622","number":6622,"state":"open","locked":false,"title":"Introduce -maxuploadtarget","user":{"login":"jonasschnelli","id":178464,"avatar_url":"https://avatars.githubusercontent.com/u/178464?v=3","gravatar_id":"","url":"https://api.github.com/users/jonasschnelli","html_url":"https://github.com/jonasschnelli","followers_url":"https://api.github.com/users/jonasschnelli/followers","following_url":"https://api.github.com/users/jonasschnelli/following{/other_user}","gists_url":"https://api.github.com/users/jonasschnelli/gists{/gist_id}","starred_url":"https://api.github.com/users/jonasschnelli/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jonasschnelli/subscriptions","organizations_url":"https://api.github.com/users/jonasschnelli/orgs","repos_url":"https://api.github.com/users/jonasschnelli/repos","events_url":"https://api.github.com/users/jonasschnelli/events{/privacy}","received_events_url":"https://api.github.com/users/jonasschnelli/received_events","type":"User","site_admin":false},"body":"**This is the first PR in a planed series of bandwidth / DOS prevention PRs.**\r\n**Focus for now is a simple and not over-complex solution to start with.**\r\n\r\nThe `-maxuploadtarget` (**in MiB**) is a configuration value that make bitcoind try to limit the total **outbound** traffic. Currently there is no guarantee that the limit target will be fulfilled.\r\n\r\nIf the `target-in-bytes - (time-left-in-24-cycle) / 600 * MAX_BLOCK_SIZE` is reached, stop serve blocks older than one week, stop serve filtered blocks (SPV) immediately.\r\n\r\nThe timeframe for the measurement is currently fixed to 24h.\r\n\r\nThis is a effective method of reducing traffic and might prevent node operators from getting expensive \"traffic exceed\"-bills.\r\n\r\nCurrently the limit also take effect for whitebinded peers.\r\n\r\nOver `getnettotals` one can get some upload limit statistics:\r\n```\r\n./src/bitcoin-cli getnettotals\r\n{\r\n  \"totalbytesrecv\": 0,\r\n  \"totalbytessent\": 0,\r\n  \"timemillis\": 1441222000173,\r\n  \"uploadtarget\": {\r\n    \"timeframe\": 86400,\r\n    \"target\": 300000000,\r\n    \"target_reached\": false,\r\n    \"serve_historical_blocks\": true,\r\n    \"bytes_left_in_cycle\": 300000000,\r\n    \"time_left_in_cycle\": 86400\r\n  }\r\n}\r\n```\r\n\r\n**needs documentation**\r\n**needs unit/rpc tests**","created_at":"2015-09-02T19:39:08Z","updated_at":"2015-10-21T10:19:34Z","closed_at":null,"merged_at":null,"merge_commit_sha":"cbf97f9c7c6004d4cdc096f130cd9ee836c7ec02","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/bitcoin/bitcoin/pulls/6622/commits","review_comments_url":"https://api.github.com/repos/bitcoin/bitcoin/pulls/6622/comments","review_comment_url":"https://api.github.com/repos/bitcoin/bitcoin/pulls/comments{/number}","comments_url":"https://api.github.com/repos/bitcoin/bitcoin/issues/6622/comments","statuses_url":"https://api.github.com/repos/bitcoin/bitcoin/statuses/30922c33bfc04ce12ebb5b53363a5321fe906a17","head":{"label":"jonasschnelli:2015/09/maxuploadtarget","ref":"2015/09/maxuploadtarget","sha":"30922c33bfc04ce12ebb5b53363a5321fe906a17","user":{"login":"jonasschnelli","id":178464,"avatar_url":"https://avatars.githubusercontent.com/u/178464?v=3","gravatar_id":"","url":"https://api.github.com/users/jonasschnelli","html_url":"https://github.com/jonasschnelli","followers_url":"https://api.github.com/users/jonasschnelli/followers","following_url":"https://api.github.com/users/jonasschnelli/following{/other_user}","gists_url":"https://api.github.com/users/jonasschnelli/gists{/gist_id}","starred_url":"https://api.github.com/users/jonasschnelli/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jonasschnelli/subscriptions","organizations_url":"https://api.github.com/users/jonasschnelli/orgs","repos_url":"https://api.github.com/users/jonasschnelli/repos","events_url":"https://api.github.com/users/jonasschnelli/events{/privacy}","received_events_url":"https://api.github.com/users/jonasschnelli/received_events","type":"User","site_admin":false},"repo":{"id":9264454,"name":"bitcoin","full_name":"jonasschnelli/bitcoin","owner":{"login":"jonasschnelli","id":178464,"avatar_url":"https://avatars.githubusercontent.com/u/178464?v=3","gravatar_id":"","url":"https://api.github.com/users/jonasschnelli","html_url":"https://github.com/jonasschnelli","followers_url":"https://api.github.com/users/jonasschnelli/followers","following_url":"https://api.github.com/users/jonasschnelli/following{/other_user}","gists_url":"https://api.github.com/users/jonasschnelli/gists{/gist_id}","starred_url":"https://api.github.com/users/jonasschnelli/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jonasschnelli/subscriptions","organizations_url":"https://api.github.com/users/jonasschnelli/orgs","repos_url":"https://api.github.com/users/jonasschnelli/repos","events_url":"https://api.github.com/users/jonasschnelli/events{/privacy}","received_events_url":"https://api.github.com/users/jonasschnelli/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jonasschnelli/bitcoin","description":"CoreWallet development branch - A better full node wallet for bitcoin-core","fork":true,"url":"https://api.github.com/repos/jonasschnelli/bitcoin","forks_url":"https://api.github.com/repos/jonasschnelli/bitcoin/forks","keys_url":"https://api.github.com/repos/jonasschnelli/bitcoin/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jonasschnelli/bitcoin/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jonasschnelli/bitcoin/teams","hooks_url":"https://api.github.com/repos/jonasschnelli/bitcoin/hooks","issue_events_url":"https://api.github.com/repos/jonasschnelli/bitcoin/issues/events{/number}","events_url":"https://api.github.com/repos/jonasschnelli/bitcoin/events","assignees_url":"https://api.github.com/repos/jonasschnelli/bitcoin/assignees{/user}","branches_url":"https://api.github.com/repos/jonasschnelli/bitcoin/branches{/branch}","tags_url":"https://api.github.com/repos/jonasschnelli/bitcoin/tags","blobs_url":"https://api.github.com/repos/jonasschnelli/bitcoin/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jonasschnelli/bitcoin/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jonasschnelli/bitcoin/git/refs{/sha}","trees_url":"https://api.github.com/repos/jonasschnelli/bitcoin/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jonasschnelli/bitcoin/statuses/{sha}","languages_url":"https://api.github.com/repos/jonasschnelli/bitcoin/languages","stargazers_url":"https://api.github.com/repos/jonasschnelli/bitcoin/stargazers","contributors_url":"https://api.github.com/repos/jonasschnelli/bitcoin/contributors","subscribers_url":"https://api.github.com/repos/jonasschnelli/bitcoin/subscribers","subscription_url":"https://api.github.com/repos/jonasschnelli/bitcoin/subscription","commits_url":"https://api.github.com/repos/jonasschnelli/bitcoin/commits{/sha}","git_commits_url":"https://api.github.com/repos/jonasschnelli/bitcoin/git/commits{/sha}","comments_url":"https://api.github.com/repos/jonasschnelli/bitcoin/comments{/number}","issue_comment_url":"https://api.github.com/repos/jonasschnelli/bitcoin/issues/comments{/number}","contents_url":"https://api.github.com/repos/jonasschnelli/bitcoin/contents/{+path}","compare_url":"https://api.github.com/repos/jonasschnelli/bitcoin/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jonasschnelli/bitcoin/merges","archive_url":"https://api.github.com/repos/jonasschnelli/bitcoin/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jonasschnelli/bitcoin/downloads","issues_url":"https://api.github.com/repos/jonasschnelli/bitcoin/issues{/number}","pulls_url":"https://api.github.com/repos/jonasschnelli/bitcoin/pulls{/number}","milestones_url":"https://api.github.com/repos/jonasschnelli/bitcoin/milestones{/number}","notifications_url":"https://api.github.com/repos/jonasschnelli/bitcoin/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jonasschnelli/bitcoin/labels{/name}","releases_url":"https://api.github.com/repos/jonasschnelli/bitcoin/releases{/id}","created_at":"2013-04-06T18:21:51Z","updated_at":"2015-08-23T12:33:26Z","pushed_at":"2015-10-08T09:00:22Z","git_url":"git://github.com/jonasschnelli/bitcoin.git","ssh_url":"git@github.com:jonasschnelli/bitcoin.git","clone_url":"https://github.com/jonasschnelli/bitcoin.git","svn_url":"https://github.com/jonasschnelli/bitcoin","homepage":"http://www.bitcoin.org","size":61562,"stargazers_count":2,"watchers_count":2,"language":"C++","has_issues":true,"has_downloads":false,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":2,"default_branch":"2015/05/corewallet"}},"base":{"label":"bitcoin:master","ref":"master","sha":"d5d1d2e65a1c3b91452d2428410f701bca1e53cc","user":{"login":"bitcoin","id":528860,"avatar_url":"https://avatars.githubusercontent.com/u/528860?v=3","gravatar_id":"","url":"https://api.github.com/users/bitcoin","html_url":"https://github.com/bitcoin","followers_url":"https://api.github.com/users/bitcoin/followers","following_url":"https://api.github.com/users/bitcoin/following{/other_user}","gists_url":"https://api.github.com/users/bitcoin/gists{/gist_id}","starred_url":"https://api.github.com/users/bitcoin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bitcoin/subscriptions","organizations_url":"https://api.github.com/users/bitcoin/orgs","repos_url":"https://api.github.com/users/bitcoin/repos","events_url":"https://api.github.com/users/bitcoin/events{/privacy}","received_events_url":"https://api.github.com/users/bitcoin/received_events","type":"Organization","site_admin":false},"repo":{"id":1181927,"name":"bitcoin","full_name":"bitcoin/bitcoin","owner":{"login":"bitcoin","id":528860,"avatar_url":"https://avatars.githubusercontent.com/u/528860?v=3","gravatar_id":"","url":"https://api.github.com/users/bitcoin","html_url":"https://github.com/bitcoin","followers_url":"https://api.github.com/users/bitcoin/followers","following_url":"https://api.github.com/users/bitcoin/following{/other_user}","gists_url":"https://api.github.com/users/bitcoin/gists{/gist_id}","starred_url":"https://api.github.com/users/bitcoin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bitcoin/subscriptions","organizations_url":"https://api.github.com/users/bitcoin/orgs","repos_url":"https://api.github.com/users/bitcoin/repos","events_url":"https://api.github.com/users/bitcoin/events{/privacy}","received_events_url":"https://api.github.com/users/bitcoin/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/bitcoin/bitcoin","description":"Bitcoin Core integration/staging tree","fork":false,"url":"https://api.github.com/repos/bitcoin/bitcoin","forks_url":"https://api.github.com/repos/bitcoin/bitcoin/forks","keys_url":"https://api.github.com/repos/bitcoin/bitcoin/keys{/key_id}","collaborators_url":"https://api.github.com/repos/bitcoin/bitcoin/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/bitcoin/bitcoin/teams","hooks_url":"https://api.github.com/repos/bitcoin/bitcoin/hooks","issue_events_url":"https://api.github.com/repos/bitcoin/bitcoin/issues/events{/number}","events_url":"https://api.github.com/repos/bitcoin/bitcoin/events","assignees_url":"https://api.github.com/repos/bitcoin/bitcoin/assignees{/user}","branches_url":"https://api.github.com/repos/bitcoin/bitcoin/branches{/branch}","tags_url":"https://api.github.com/repos/bitcoin/bitcoin/tags","blobs_url":"https://api.github.com/repos/bitcoin/bitcoin/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/bitcoin/bitcoin/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/bitcoin/bitcoin/git/refs{/sha}","trees_url":"https://api.github.com/repos/bitcoin/bitcoin/git/trees{/sha}","statuses_url":"https://api.github.com/repos/bitcoin/bitcoin/statuses/{sha}","languages_url":"https://api.github.com/repos/bitcoin/bitcoin/languages","stargazers_url":"https://api.github.com/repos/bitcoin/bitcoin/stargazers","contributors_url":"https://api.github.com/repos/bitcoin/bitcoin/contributors","subscribers_url":"https://api.github.com/repos/bitcoin/bitcoin/subscribers","subscription_url":"https://api.github.com/repos/bitcoin/bitcoin/subscription","commits_url":"https://api.github.com/repos/bitcoin/bitcoin/commits{/sha}","git_commits_url":"https://api.github.com/repos/bitcoin/bitcoin/git/commits{/sha}","comments_url":"https://api.github.com/repos/bitcoin/bitcoin/comments{/number}","issue_comment_url":"https://api.github.com/repos/bitcoin/bitcoin/issues/comments{/number}","contents_url":"https://api.github.com/repos/bitcoin/bitcoin/contents/{+path}","compare_url":"https://api.github.com/repos/bitcoin/bitcoin/compare/{base}...{head}","merges_url":"https://api.github.com/repos/bitcoin/bitcoin/merges","archive_url":"https://api.github.com/repos/bitcoin/bitcoin/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/bitcoin/bitcoin/downloads","issues_url":"https://api.github.com/repos/bitcoin/bitcoin/issues{/number}","pulls_url":"https://api.github.com/repos/bitcoin/bitcoin/pulls{/number}","milestones_url":"https://api.github.com/repos/bitcoin/bitcoin/milestones{/number}","notifications_url":"https://api.github.com/repos/bitcoin/bitcoin/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/bitcoin/bitcoin/labels{/name}","releases_url":"https://api.github.com/repos/bitcoin/bitcoin/releases{/id}","created_at":"2010-12-19T15:16:43Z","updated_at":"2015-10-21T06:36:00Z","pushed_at":"2015-10-21T09:58:29Z","git_url":"git://github.com/bitcoin/bitcoin.git","ssh_url":"git@github.com:bitcoin/bitcoin.git","clone_url":"https://github.com/bitcoin/bitcoin.git","svn_url":"https://github.com/bitcoin/bitcoin","homepage":"https://bitcoin.org/en/download","size":138020,"stargazers_count":7656,"watchers_count":7656,"language":"C++","has_issues":true,"has_downloads":false,"has_wiki":false,"has_pages":false,"forks_count":5286,"mirror_url":null,"open_issues_count":448,"forks":5286,"open_issues":448,"watchers":7656,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/bitcoin/bitcoin/pulls/6622"},"html":{"href":"https://github.com/bitcoin/bitcoin/pull/6622"},"issue":{"href":"https://api.github.com/repos/bitcoin/bitcoin/issues/6622"},"comments":{"href":"https://api.github.com/repos/bitcoin/bitcoin/issues/6622/comments"},"review_comments":{"href":"https://api.github.com/repos/bitcoin/bitcoin/pulls/6622/comments"},"review_comment":{"href":"https://api.github.com/repos/bitcoin/bitcoin/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/bitcoin/bitcoin/pulls/6622/commits"},"statuses":{"href":"https://api.github.com/repos/bitcoin/bitcoin/statuses/30922c33bfc04ce12ebb5b53363a5321fe906a17"}}}}