eth/protocols/snap: speed up hash checks (#22023)
* eth/protocols/snap: speed up hash checks * eth/protocols/snap: nit fix Co-authored-by: Péter Szilágyi <peterke@gmail.com>
This commit is contained in:
		
							parent
							
								
									38310f9022
								
							
						
					
					
						commit
						4bb5c6ca7a
					
				| @ -2112,14 +2112,15 @@ func (s *Syncer) onByteCodes(peer *Peer, id uint64, bytecodes [][]byte) error { | |||||||
| 
 | 
 | ||||||
| 	// Cross reference the requested bytecodes with the response to find gaps
 | 	// Cross reference the requested bytecodes with the response to find gaps
 | ||||||
| 	// that the serving node is missing
 | 	// that the serving node is missing
 | ||||||
| 	hasher := sha3.NewLegacyKeccak256() | 	hasher := sha3.NewLegacyKeccak256().(crypto.KeccakState) | ||||||
|  | 	hash := make([]byte, 32) | ||||||
| 
 | 
 | ||||||
| 	codes := make([][]byte, len(req.hashes)) | 	codes := make([][]byte, len(req.hashes)) | ||||||
| 	for i, j := 0, 0; i < len(bytecodes); i++ { | 	for i, j := 0, 0; i < len(bytecodes); i++ { | ||||||
| 		// Find the next hash that we've been served, leaving misses with nils
 | 		// Find the next hash that we've been served, leaving misses with nils
 | ||||||
| 		hasher.Reset() | 		hasher.Reset() | ||||||
| 		hasher.Write(bytecodes[i]) | 		hasher.Write(bytecodes[i]) | ||||||
| 		hash := hasher.Sum(nil) | 		hasher.Read(hash) | ||||||
| 
 | 
 | ||||||
| 		for j < len(req.hashes) && !bytes.Equal(hash, req.hashes[j][:]) { | 		for j < len(req.hashes) && !bytes.Equal(hash, req.hashes[j][:]) { | ||||||
| 			j++ | 			j++ | ||||||
| @ -2350,14 +2351,15 @@ func (s *Syncer) OnTrieNodes(peer *Peer, id uint64, trienodes [][]byte) error { | |||||||
| 
 | 
 | ||||||
| 	// Cross reference the requested trienodes with the response to find gaps
 | 	// Cross reference the requested trienodes with the response to find gaps
 | ||||||
| 	// that the serving node is missing
 | 	// that the serving node is missing
 | ||||||
| 	hasher := sha3.NewLegacyKeccak256() | 	hasher := sha3.NewLegacyKeccak256().(crypto.KeccakState) | ||||||
|  | 	hash := make([]byte, 32) | ||||||
| 
 | 
 | ||||||
| 	nodes := make([][]byte, len(req.hashes)) | 	nodes := make([][]byte, len(req.hashes)) | ||||||
| 	for i, j := 0, 0; i < len(trienodes); i++ { | 	for i, j := 0, 0; i < len(trienodes); i++ { | ||||||
| 		// Find the next hash that we've been served, leaving misses with nils
 | 		// Find the next hash that we've been served, leaving misses with nils
 | ||||||
| 		hasher.Reset() | 		hasher.Reset() | ||||||
| 		hasher.Write(trienodes[i]) | 		hasher.Write(trienodes[i]) | ||||||
| 		hash := hasher.Sum(nil) | 		hasher.Read(hash) | ||||||
| 
 | 
 | ||||||
| 		for j < len(req.hashes) && !bytes.Equal(hash, req.hashes[j][:]) { | 		for j < len(req.hashes) && !bytes.Equal(hash, req.hashes[j][:]) { | ||||||
| 			j++ | 			j++ | ||||||
| @ -2437,14 +2439,15 @@ func (s *Syncer) onHealByteCodes(peer *Peer, id uint64, bytecodes [][]byte) erro | |||||||
| 
 | 
 | ||||||
| 	// Cross reference the requested bytecodes with the response to find gaps
 | 	// Cross reference the requested bytecodes with the response to find gaps
 | ||||||
| 	// that the serving node is missing
 | 	// that the serving node is missing
 | ||||||
| 	hasher := sha3.NewLegacyKeccak256() | 	hasher := sha3.NewLegacyKeccak256().(crypto.KeccakState) | ||||||
|  | 	hash := make([]byte, 32) | ||||||
| 
 | 
 | ||||||
| 	codes := make([][]byte, len(req.hashes)) | 	codes := make([][]byte, len(req.hashes)) | ||||||
| 	for i, j := 0, 0; i < len(bytecodes); i++ { | 	for i, j := 0, 0; i < len(bytecodes); i++ { | ||||||
| 		// Find the next hash that we've been served, leaving misses with nils
 | 		// Find the next hash that we've been served, leaving misses with nils
 | ||||||
| 		hasher.Reset() | 		hasher.Reset() | ||||||
| 		hasher.Write(bytecodes[i]) | 		hasher.Write(bytecodes[i]) | ||||||
| 		hash := hasher.Sum(nil) | 		hasher.Read(hash) | ||||||
| 
 | 
 | ||||||
| 		for j < len(req.hashes) && !bytes.Equal(hash, req.hashes[j][:]) { | 		for j < len(req.hashes) && !bytes.Equal(hash, req.hashes[j][:]) { | ||||||
| 			j++ | 			j++ | ||||||
|  | |||||||
							
								
								
									
										98
									
								
								eth/protocols/snap/sync_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								eth/protocols/snap/sync_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,98 @@ | |||||||
|  | // 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 ( | ||||||
|  | 	"crypto/rand" | ||||||
|  | 	"fmt" | ||||||
|  | 	"testing" | ||||||
|  | 
 | ||||||
|  | 	"github.com/ethereum/go-ethereum/crypto" | ||||||
|  | 	"golang.org/x/crypto/sha3" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func TestHashing(t *testing.T) { | ||||||
|  | 	var bytecodes = make([][]byte, 10) | ||||||
|  | 	for i := 0; i < len(bytecodes); i++ { | ||||||
|  | 		buf := make([]byte, 100) | ||||||
|  | 		rand.Read(buf) | ||||||
|  | 		bytecodes[i] = buf | ||||||
|  | 	} | ||||||
|  | 	var want, got string | ||||||
|  | 	var old = func() { | ||||||
|  | 		hasher := sha3.NewLegacyKeccak256() | ||||||
|  | 		for i := 0; i < len(bytecodes); i++ { | ||||||
|  | 			hasher.Reset() | ||||||
|  | 			hasher.Write(bytecodes[i]) | ||||||
|  | 			hash := hasher.Sum(nil) | ||||||
|  | 			got = fmt.Sprintf("%v\n%v", got, hash) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	var new = func() { | ||||||
|  | 		hasher := sha3.NewLegacyKeccak256().(crypto.KeccakState) | ||||||
|  | 		var hash = make([]byte, 32) | ||||||
|  | 		for i := 0; i < len(bytecodes); i++ { | ||||||
|  | 			hasher.Reset() | ||||||
|  | 			hasher.Write(bytecodes[i]) | ||||||
|  | 			hasher.Read(hash) | ||||||
|  | 			want = fmt.Sprintf("%v\n%v", want, hash) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	old() | ||||||
|  | 	new() | ||||||
|  | 	if want != got { | ||||||
|  | 		t.Errorf("want\n%v\ngot\n%v\n", want, got) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func BenchmarkHashing(b *testing.B) { | ||||||
|  | 	var bytecodes = make([][]byte, 10000) | ||||||
|  | 	for i := 0; i < len(bytecodes); i++ { | ||||||
|  | 		buf := make([]byte, 100) | ||||||
|  | 		rand.Read(buf) | ||||||
|  | 		bytecodes[i] = buf | ||||||
|  | 	} | ||||||
|  | 	var old = func() { | ||||||
|  | 		hasher := sha3.NewLegacyKeccak256() | ||||||
|  | 		for i := 0; i < len(bytecodes); i++ { | ||||||
|  | 			hasher.Reset() | ||||||
|  | 			hasher.Write(bytecodes[i]) | ||||||
|  | 			hasher.Sum(nil) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	var new = func() { | ||||||
|  | 		hasher := sha3.NewLegacyKeccak256().(crypto.KeccakState) | ||||||
|  | 		var hash = make([]byte, 32) | ||||||
|  | 		for i := 0; i < len(bytecodes); i++ { | ||||||
|  | 			hasher.Reset() | ||||||
|  | 			hasher.Write(bytecodes[i]) | ||||||
|  | 			hasher.Read(hash) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	b.Run("old", func(b *testing.B) { | ||||||
|  | 		b.ReportAllocs() | ||||||
|  | 		for i := 0; i < b.N; i++ { | ||||||
|  | 			old() | ||||||
|  | 		} | ||||||
|  | 	}) | ||||||
|  | 	b.Run("new", func(b *testing.B) { | ||||||
|  | 		b.ReportAllocs() | ||||||
|  | 		for i := 0; i < b.N; i++ { | ||||||
|  | 			new() | ||||||
|  | 		} | ||||||
|  | 	}) | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user