{"action":"opened","issue":{"url":"https://api.github.com/repos/neo-project/neo/issues/522","repository_url":"https://api.github.com/repos/neo-project/neo","labels_url":"https://api.github.com/repos/neo-project/neo/issues/522/labels{/name}","comments_url":"https://api.github.com/repos/neo-project/neo/issues/522/comments","events_url":"https://api.github.com/repos/neo-project/neo/issues/522/events","html_url":"https://github.com/neo-project/neo/issues/522","id":390774550,"node_id":"MDU6SXNzdWUzOTA3NzQ1NTA=","number":522,"title":"Network protocol suggestion: getfullblocks","user":{"login":"ixje","id":6625537,"node_id":"MDQ6VXNlcjY2MjU1Mzc=","avatar_url":"https://avatars0.githubusercontent.com/u/6625537?v=4","gravatar_id":"","url":"https://api.github.com/users/ixje","html_url":"https://github.com/ixje","followers_url":"https://api.github.com/users/ixje/followers","following_url":"https://api.github.com/users/ixje/following{/other_user}","gists_url":"https://api.github.com/users/ixje/gists{/gist_id}","starred_url":"https://api.github.com/users/ixje/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ixje/subscriptions","organizations_url":"https://api.github.com/users/ixje/orgs","repos_url":"https://api.github.com/users/ixje/repos","events_url":"https://api.github.com/users/ixje/events{/privacy}","received_events_url":"https://api.github.com/users/ixje/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-12-13T17:07:38Z","updated_at":"2018-12-13T17:07:38Z","closed_at":null,"author_association":"NONE","body":"There are some improvements proposed in https://github.com/neo-project/neo/issues/366\r\nI'd like to discuss one more that is also backwards compatible.\r\n\r\nThe current `getblocks` command is inefficient and also has a misleading name. The name suggests you will receive `blocks`. In reality you get hashes (via an `inv` message). You then basically repackage the same information of this `inv` message but now with the `getdata` command to finally receive the `blocks` messages. This is a 4-step process:\r\n1. -> `getblocks`\r\n2. <- `inv` with hash list\r\n3. -> `getdata` with the received hash list\r\n4. <- _n_ times `block` (for all requested hashes)\r\n\r\nWe can do the same process in just 2-steps.\r\n\r\n**Proposal**\r\nI'd like to propose a `getfullblocks` command (or something along those lines) that will do the above in 2 steps (specifically only step 1 & 4). This is nearly identical to the current `getblocks` but instead of sending an `inv` it will instantly return the requested blocks. \r\n\r\nUntested example, but should be close enough to explain the idea\r\n```C#\r\nprivate void OnGetFullBlocksMessageReceived(GetBlocksPayload payload)\r\n{\r\n    UInt256 hash = payload.HashStart[0];\r\n    if (hash == payload.HashStop) return;\r\n    BlockState state = Blockchain.Singleton.Store.GetBlocks().TryGet(hash);\r\n    if (state == null) return;\r\n\r\n    for (uint i = 1; i <= InvPayload.MaxHashesCount; i++)\r\n    {\r\n        uint index = state.TrimmedBlock.Index + i;\r\n        if (index > Blockchain.Singleton.Height)\r\n            break;\r\n        hash = Blockchain.Singleton.GetBlockHash(index);\r\n        if (hash == null) break;\r\n        if (hash == payload.HashStop) break;\r\n\r\n        // code extracted from OnGetDataMessageReceived()\r\n        Blockchain.Singleton.RelayCache.TryGet(hash, out IInventory inventory);\r\n        if (inventory == null)\r\n            inventory = Blockchain.Singleton.GetBlock(hash);\r\n        if (inventory is Block block)\r\n        {\r\n            if (bloom_filter == null)\r\n            {\r\n                Context.Parent.Tell(Message.Create(\"block\", inventory));\r\n            }\r\n            else\r\n            {\r\n                BitArray flags = new BitArray(block.Transactions.Select(p => bloom_filter.Test(p)).ToArray());\r\n                Context.Parent.Tell(Message.Create(\"merkleblock\", MerkleBlockPayload.Create(block, flags)));\r\n            }\r\n        }\r\n        // end code extracted from OnGetDataMessageReceived()\r\n    }\r\n}\r\n```\r\nThe above is basically a combination of `OnGetBlocksMessageReceived()` and `OnGetDataMessageReceived()` \r\n\r\n**Benefits**\r\n- less network traffic\r\n- self-explanatory command instead of misleading command\r\n- less business logic for retrieving blocks from the network.\r\n\r\n**Possible improvements**\r\nallow querying data using a `start_index` , `stop_index`. This would mean we cannot re-use the `GetBlocksPayload` but requires a new one. \r\n\r\nBenefits of these parameters are;\r\n- smaller `getfullblock` message, as you do not need any `UInt256` hashes to start requesting data, just an `int` for the index\r\n- does not require knowing any hashes to get started on block data syncing. Meaning; no need to know the genesis block hash to start from scratch, and no need to know the `inv` payload structure for deserialising a hash that was broadcasted on the network. You can skip all unnecessary data and just go straight to retrieving blocks."}}
{"actor":{"display_login":"ixje"}}