2020-12-14 11:27:15 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Copyright 2020 The go-ethereum Authors  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This file is part of the go-ethereum library.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// The go-ethereum library is free software: you can redistribute it and/or modify  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// it under the terms of the GNU Lesser General Public License as published by  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the Free Software Foundation, either version 3 of the License, or  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// (at your option) any later version.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// The go-ethereum library is distributed in the hope that it will be useful,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// but WITHOUT ANY WARRANTY; without even the implied warranty of  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// GNU Lesser General Public License for more details.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// You should have received a copy of the GNU Lesser General Public License  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								package  snap  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/ethereum/go-ethereum/common" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/ethereum/go-ethereum/log" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/ethereum/go-ethereum/p2p" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Peer is a collection of relevant information we have about a `snap` peer.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  Peer  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									id  string  // Unique ID for the peer, cached 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									* p2p . Peer                    // The embedded P2P package peer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rw         p2p . MsgReadWriter  // Input/output streams for snap 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									version    uint               // Protocol version negotiated 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									logger  log . Logger  // Contextual logger with the peer id injected 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// newPeer create a wrapper for a network connection and negotiated  protocol  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// version.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  newPeer ( version  uint ,  p  * p2p . Peer ,  rw  p2p . MsgReadWriter )  * Peer  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									id  :=  p . ID ( ) . String ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  & Peer { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										id :       id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Peer :     p , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rw :       rw , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										version :  version , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										logger :   log . New ( "peer" ,  id [ : 8 ] ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// ID retrieves the peer's unique identifier.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( p  * Peer )  ID ( )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  p . id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Version retrieves the peer's negoatiated `snap` protocol version.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( p  * Peer )  Version ( )  uint  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  p . version 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-25 07:17:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Log overrides the P2P logget with the higher level one containing only the id.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( p  * Peer )  Log ( )  log . Logger  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  p . logger 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-14 11:27:15 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// RequestAccountRange fetches a batch of accounts rooted in a specific account  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// trie, starting with the origin.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( p  * Peer )  RequestAccountRange ( id  uint64 ,  root  common . Hash ,  origin ,  limit  common . Hash ,  bytes  uint64 )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p . logger . Trace ( "Fetching range of accounts" ,  "reqid" ,  id ,  "root" ,  root ,  "origin" ,  origin ,  "limit" ,  limit ,  "bytes" ,  common . StorageSize ( bytes ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-22 11:42:46 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									requestTracker . Track ( p . id ,  p . version ,  GetAccountRangeMsg ,  AccountRangeMsg ,  id ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-14 11:27:15 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  p2p . Send ( p . rw ,  GetAccountRangeMsg ,  & GetAccountRangePacket { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ID :      id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Root :    root , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Origin :  origin , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Limit :   limit , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Bytes :   bytes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// RequestStorageRange fetches a batch of storage slots belonging to one or more  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// accounts. If slots from only one accout is requested, an origin marker may also  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// be used to retrieve from there.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( p  * Peer )  RequestStorageRanges ( id  uint64 ,  root  common . Hash ,  accounts  [ ] common . Hash ,  origin ,  limit  [ ] byte ,  bytes  uint64 )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( accounts )  ==  1  &&  origin  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p . logger . Trace ( "Fetching range of large storage slots" ,  "reqid" ,  id ,  "root" ,  root ,  "account" ,  accounts [ 0 ] ,  "origin" ,  common . BytesToHash ( origin ) ,  "limit" ,  common . BytesToHash ( limit ) ,  "bytes" ,  common . StorageSize ( bytes ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p . logger . Trace ( "Fetching ranges of small storage slots" ,  "reqid" ,  id ,  "root" ,  root ,  "accounts" ,  len ( accounts ) ,  "first" ,  accounts [ 0 ] ,  "bytes" ,  common . StorageSize ( bytes ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-22 11:42:46 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									requestTracker . Track ( p . id ,  p . version ,  GetStorageRangesMsg ,  StorageRangesMsg ,  id ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-14 11:27:15 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  p2p . Send ( p . rw ,  GetStorageRangesMsg ,  & GetStorageRangesPacket { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ID :        id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Root :      root , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Accounts :  accounts , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Origin :    origin , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Limit :     limit , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Bytes :     bytes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// RequestByteCodes fetches a batch of bytecodes by hash.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( p  * Peer )  RequestByteCodes ( id  uint64 ,  hashes  [ ] common . Hash ,  bytes  uint64 )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p . logger . Trace ( "Fetching set of byte codes" ,  "reqid" ,  id ,  "hashes" ,  len ( hashes ) ,  "bytes" ,  common . StorageSize ( bytes ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-22 11:42:46 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									requestTracker . Track ( p . id ,  p . version ,  GetByteCodesMsg ,  ByteCodesMsg ,  id ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-14 11:27:15 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  p2p . Send ( p . rw ,  GetByteCodesMsg ,  & GetByteCodesPacket { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ID :      id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Hashes :  hashes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Bytes :   bytes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// RequestTrieNodes fetches a batch of account or storage trie nodes rooted in  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// a specificstate trie.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( p  * Peer )  RequestTrieNodes ( id  uint64 ,  root  common . Hash ,  paths  [ ] TrieNodePathSet ,  bytes  uint64 )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p . logger . Trace ( "Fetching set of trie nodes" ,  "reqid" ,  id ,  "root" ,  root ,  "pathsets" ,  len ( paths ) ,  "bytes" ,  common . StorageSize ( bytes ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-22 11:42:46 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									requestTracker . Track ( p . id ,  p . version ,  GetTrieNodesMsg ,  TrieNodesMsg ,  id ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-14 11:27:15 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  p2p . Send ( p . rw ,  GetTrieNodesMsg ,  & GetTrieNodesPacket { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ID :     id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Root :   root , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Paths :  paths , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Bytes :  bytes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}