{"action":"created","issue":{"url":"https://api.github.com/repos/bitcoin/bitcoin/issues/5835","labels_url":"https://api.github.com/repos/bitcoin/bitcoin/issues/5835/labels{/name}","comments_url":"https://api.github.com/repos/bitcoin/bitcoin/issues/5835/comments","events_url":"https://api.github.com/repos/bitcoin/bitcoin/issues/5835/events","html_url":"https://github.com/bitcoin/bitcoin/pull/5835","id":59177993,"number":5835,"title":"Optimize block validation code and block propagation speed","user":{"login":"gavinandresen","id":331997,"avatar_url":"https://avatars.githubusercontent.com/u/331997?v=3","gravatar_id":"","url":"https://api.github.com/users/gavinandresen","html_url":"https://github.com/gavinandresen","followers_url":"https://api.github.com/users/gavinandresen/followers","following_url":"https://api.github.com/users/gavinandresen/following{/other_user}","gists_url":"https://api.github.com/users/gavinandresen/gists{/gist_id}","starred_url":"https://api.github.com/users/gavinandresen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gavinandresen/subscriptions","organizations_url":"https://api.github.com/users/gavinandresen/orgs","repos_url":"https://api.github.com/users/gavinandresen/repos","events_url":"https://api.github.com/users/gavinandresen/events{/privacy}","received_events_url":"https://api.github.com/users/gavinandresen/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2015-02-27T01:59:39Z","updated_at":"2015-02-27T02:25:01Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/bitcoin/bitcoin/pulls/5835","html_url":"https://github.com/bitcoin/bitcoin/pull/5835","diff_url":"https://github.com/bitcoin/bitcoin/pull/5835.diff","patch_url":"https://github.com/bitcoin/bitcoin/pull/5835.patch"},"body":"I was running some benchmarks on 20MB blocks, and was surprised at how long block validation took even when all transactions had already been seen and were in the signature cache.\r\n\r\nSo I moved caching up from being a low-level signature cache to a high-level \"have we already validated this txid.\"\r\n\r\nBenchmark results on a recent 365K block with all transactions already in the memory pool / signature cache:\r\n\r\nOld code: (results from running with -debug=bench and hacked code to make sure all txn pre-validated):\r\n      - Verify 1839 txins: 191.66ms (0.104ms/txin)\r\nNew code:\r\n    - Verify 1839 txins: 2.06ms (0.001ms/txin)\r\n\r\nExtrapolating to full (1MB) blocks, the old code would spend about 600ms CPU time per hop propagating blocks with already-seen transactions, this new code will spend under 10ms.\r\n\r\nMemory usage is about 10 times smaller, also:\r\nOld code:  (sizeof(scriptSig)+std::set overhead) * number of txins  (about 200K for the 365K block)\r\nNew code: an extra 32 bytes per transaction in the mempool  (about 22K for the 365K block)\r\n\r\nI first wrote this as a standalone CTxValidationCache class, but it is simpler and more efficient to extend the mempool. The second commit in this pull request fixes two bugs in limitedmap I stumbled across when testing that code.\r\n"},"comment":{"url":"https://api.github.com/repos/bitcoin/bitcoin/issues/comments/76319604","html_url":"https://github.com/bitcoin/bitcoin/pull/5835#issuecomment-76319604","issue_url":"https://api.github.com/repos/bitcoin/bitcoin/issues/5835","id":76319604,"user":{"login":"gmaxwell","id":858454,"avatar_url":"https://avatars.githubusercontent.com/u/858454?v=3","gravatar_id":"","url":"https://api.github.com/users/gmaxwell","html_url":"https://github.com/gmaxwell","followers_url":"https://api.github.com/users/gmaxwell/followers","following_url":"https://api.github.com/users/gmaxwell/following{/other_user}","gists_url":"https://api.github.com/users/gmaxwell/gists{/gist_id}","starred_url":"https://api.github.com/users/gmaxwell/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gmaxwell/subscriptions","organizations_url":"https://api.github.com/users/gmaxwell/orgs","repos_url":"https://api.github.com/users/gmaxwell/repos","events_url":"https://api.github.com/users/gmaxwell/events{/privacy}","received_events_url":"https://api.github.com/users/gmaxwell/received_events","type":"User","site_admin":false},"created_at":"2015-02-27T02:25:01Z","updated_at":"2015-02-27T02:25:01Z","body":"WRT POW, I was worrying about the lose transaction case, not attacks in blocks.   The attack is the attacker has 1000 valid signatures, 1 invalid signature; the time is wasted on the valid signatures; the invalid is just there to avoid paying fees.  I don't see a way to cheaply invalidate the cache on the valid signatures.\r\n\r\nThe P2SH limit is per signature, I'm pretty sure you can get1000 checksigs in an IsStandard transaction, you'd just use 66 inputs with 15 checksigs each. With unusual script pubkeys (op_dup-ing the signatures) such a transaction would only be under15kb I'd guess."}}