github.com/codysnider/go-ethereum@v1.10.18-0.20220420071915-14f4ae99222a/cmd/devp2p/internal/ethtest/snap.go (about)

     1  // Copyright 2014 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package ethtest
    18  
    19  import (
    20  	"bytes"
    21  	"errors"
    22  	"fmt"
    23  	"math/rand"
    24  
    25  	"github.com/ethereum/go-ethereum/common"
    26  	"github.com/ethereum/go-ethereum/crypto"
    27  	"github.com/ethereum/go-ethereum/eth/protocols/snap"
    28  	"github.com/ethereum/go-ethereum/internal/utesting"
    29  	"github.com/ethereum/go-ethereum/light"
    30  	"github.com/ethereum/go-ethereum/trie"
    31  	"golang.org/x/crypto/sha3"
    32  )
    33  
    34  func (s *Suite) TestSnapStatus(t *utesting.T) {
    35  	conn, err := s.dialSnap()
    36  	if err != nil {
    37  		t.Fatalf("dial failed: %v", err)
    38  	}
    39  	defer conn.Close()
    40  	if err := conn.peer(s.chain, nil); err != nil {
    41  		t.Fatalf("peering failed: %v", err)
    42  	}
    43  }
    44  
    45  type accRangeTest struct {
    46  	nBytes uint64
    47  	root   common.Hash
    48  	origin common.Hash
    49  	limit  common.Hash
    50  
    51  	expAccounts int
    52  	expFirst    common.Hash
    53  	expLast     common.Hash
    54  }
    55  
    56  // TestSnapGetAccountRange various forms of GetAccountRange requests.
    57  func (s *Suite) TestSnapGetAccountRange(t *utesting.T) {
    58  	var (
    59  		root           = s.chain.RootAt(999)
    60  		ffHash         = common.HexToHash("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")
    61  		zero           = common.Hash{}
    62  		firstKeyMinus1 = common.HexToHash("0x00bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf29")
    63  		firstKey       = common.HexToHash("0x00bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a")
    64  		firstKeyPlus1  = common.HexToHash("0x00bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2b")
    65  		secondKey      = common.HexToHash("0x09e47cd5056a689e708f22fe1f932709a320518e444f5f7d8d46a3da523d6606")
    66  		storageRoot    = common.HexToHash("0xbe3d75a1729be157e79c3b77f00206db4d54e3ea14375a015451c88ec067c790")
    67  	)
    68  	for i, tc := range []accRangeTest{
    69  		// Tests decreasing the number of bytes
    70  		{4000, root, zero, ffHash, 76, firstKey, common.HexToHash("0xd2669dcf3858e7f1eecb8b5fedbf22fbea3e9433848a75035f79d68422c2dcda")},
    71  		{3000, root, zero, ffHash, 57, firstKey, common.HexToHash("0x9b63fa753ece5cb90657d02ecb15df4dc1508d8c1d187af1bf7f1a05e747d3c7")},
    72  		{2000, root, zero, ffHash, 38, firstKey, common.HexToHash("0x5e6140ecae4354a9e8f47559a8c6209c1e0e69cb077b067b528556c11698b91f")},
    73  		{1, root, zero, ffHash, 1, firstKey, firstKey},
    74  
    75  		// Tests variations of the range
    76  		//
    77  		// [00b to firstkey]: should return [firstkey, secondkey], where secondkey is out of bounds
    78  		{4000, root, common.HexToHash("0x00bf000000000000000000000000000000000000000000000000000000000000"), common.HexToHash("0x00bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2b"), 2, firstKey, secondKey},
    79  		// [00b0 to 0bf0]: where both are before firstkey. Should return firstKey (even though it's out of bounds)
    80  		{4000, root, common.HexToHash("0x00b0000000000000000000000000000000000000000000000000000000000000"), common.HexToHash("0x00bf100000000000000000000000000000000000000000000000000000000000"), 1, firstKey, firstKey},
    81  		{4000, root, zero, zero, 1, firstKey, firstKey},
    82  		{4000, root, firstKey, ffHash, 76, firstKey, common.HexToHash("0xd2669dcf3858e7f1eecb8b5fedbf22fbea3e9433848a75035f79d68422c2dcda")},
    83  		{4000, root, firstKeyPlus1, ffHash, 76, secondKey, common.HexToHash("0xd28f55d3b994f16389f36944ad685b48e0fc3f8fbe86c3ca92ebecadf16a783f")},
    84  
    85  		// Test different root hashes
    86  		//
    87  		// A stateroot that does not exist
    88  		{4000, common.Hash{0x13, 37}, zero, ffHash, 0, zero, zero},
    89  		// The genesis stateroot (we expect it to not be served)
    90  		{4000, s.chain.RootAt(0), zero, ffHash, 0, zero, zero},
    91  		// A 127 block old stateroot, expected to be served
    92  		{4000, s.chain.RootAt(999 - 127), zero, ffHash, 77, firstKey, common.HexToHash("0xe4c6fdef5dd4e789a2612390806ee840b8ec0fe52548f8b4efe41abb20c37aac")},
    93  		// A root which is not actually an account root, but a storage orot
    94  		{4000, storageRoot, zero, ffHash, 0, zero, zero},
    95  
    96  		// And some non-sensical requests
    97  		//
    98  		// range from [0xFF to 0x00], wrong order. Expect not to be serviced
    99  		{4000, root, ffHash, zero, 0, zero, zero},
   100  		// range from [firstkey, firstkey-1], wrong order. Expect to get first key.
   101  		{4000, root, firstKey, firstKeyMinus1, 1, firstKey, firstKey},
   102  		// range from [firstkey, 0], wrong order. Expect to get first key.
   103  		{4000, root, firstKey, zero, 1, firstKey, firstKey},
   104  		// Max bytes: 0. Expect to deliver one account.
   105  		{0, root, zero, ffHash, 1, firstKey, firstKey},
   106  	} {
   107  		if err := s.snapGetAccountRange(t, &tc); err != nil {
   108  			t.Errorf("test %d \n root: %x\n range: %#x - %#x\n bytes: %d\nfailed: %v", i, tc.root, tc.origin, tc.limit, tc.nBytes, err)
   109  		}
   110  	}
   111  }
   112  
   113  type stRangesTest struct {
   114  	root     common.Hash
   115  	accounts []common.Hash
   116  	origin   []byte
   117  	limit    []byte
   118  	nBytes   uint64
   119  
   120  	expSlots int
   121  }
   122  
   123  // TestSnapGetStorageRange various forms of GetStorageRanges requests.
   124  func (s *Suite) TestSnapGetStorageRanges(t *utesting.T) {
   125  	var (
   126  		ffHash    = common.HexToHash("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")
   127  		zero      = common.Hash{}
   128  		firstKey  = common.HexToHash("0x00bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a")
   129  		secondKey = common.HexToHash("0x09e47cd5056a689e708f22fe1f932709a320518e444f5f7d8d46a3da523d6606")
   130  	)
   131  	for i, tc := range []stRangesTest{
   132  		{
   133  			root:     s.chain.RootAt(999),
   134  			accounts: []common.Hash{secondKey, firstKey},
   135  			origin:   zero[:],
   136  			limit:    ffHash[:],
   137  			nBytes:   500,
   138  			expSlots: 0,
   139  		},
   140  
   141  		/*
   142  			Some tests against this account:
   143  			{
   144  			  "balance": "0",
   145  			  "nonce": 1,
   146  			  "root": "0xbe3d75a1729be157e79c3b77f00206db4d54e3ea14375a015451c88ec067c790",
   147  			  "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470",
   148  			  "storage": {
   149  			    "0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace": "02",
   150  			    "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6": "01",
   151  			    "0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b": "03"
   152  			  },
   153  			  "key": "0xf493f79c43bd747129a226ad42529885a4b108aba6046b2d12071695a6627844"
   154  			}
   155  		*/
   156  		{ // [:] -> [slot1, slot2, slot3]
   157  			root:     s.chain.RootAt(999),
   158  			accounts: []common.Hash{common.HexToHash("0xf493f79c43bd747129a226ad42529885a4b108aba6046b2d12071695a6627844")},
   159  			origin:   zero[:],
   160  			limit:    ffHash[:],
   161  			nBytes:   500,
   162  			expSlots: 3,
   163  		},
   164  		{ // [slot1:] -> [slot1, slot2, slot3]
   165  			root:     s.chain.RootAt(999),
   166  			accounts: []common.Hash{common.HexToHash("0xf493f79c43bd747129a226ad42529885a4b108aba6046b2d12071695a6627844")},
   167  			origin:   common.FromHex("0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace"),
   168  			limit:    ffHash[:],
   169  			nBytes:   500,
   170  			expSlots: 3,
   171  		},
   172  		{ // [slot1+ :] -> [slot2, slot3]
   173  			root:     s.chain.RootAt(999),
   174  			accounts: []common.Hash{common.HexToHash("0xf493f79c43bd747129a226ad42529885a4b108aba6046b2d12071695a6627844")},
   175  			origin:   common.FromHex("0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf"),
   176  			limit:    ffHash[:],
   177  			nBytes:   500,
   178  			expSlots: 2,
   179  		},
   180  		{ // [slot1:slot2] -> [slot1, slot2]
   181  			root:     s.chain.RootAt(999),
   182  			accounts: []common.Hash{common.HexToHash("0xf493f79c43bd747129a226ad42529885a4b108aba6046b2d12071695a6627844")},
   183  			origin:   common.FromHex("0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace"),
   184  			limit:    common.FromHex("0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6"),
   185  			nBytes:   500,
   186  			expSlots: 2,
   187  		},
   188  		{ // [slot1+:slot2+] -> [slot2, slot3]
   189  			root:     s.chain.RootAt(999),
   190  			accounts: []common.Hash{common.HexToHash("0xf493f79c43bd747129a226ad42529885a4b108aba6046b2d12071695a6627844")},
   191  			origin:   common.FromHex("0x4fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
   192  			limit:    common.FromHex("0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7"),
   193  			nBytes:   500,
   194  			expSlots: 2,
   195  		},
   196  	} {
   197  		if err := s.snapGetStorageRanges(t, &tc); err != nil {
   198  			t.Errorf("test %d \n root: %x\n range: %#x - %#x\n bytes: %d\n #accounts: %d\nfailed: %v",
   199  				i, tc.root, tc.origin, tc.limit, tc.nBytes, len(tc.accounts), err)
   200  		}
   201  	}
   202  }
   203  
   204  type byteCodesTest struct {
   205  	nBytes uint64
   206  	hashes []common.Hash
   207  
   208  	expHashes int
   209  }
   210  
   211  var (
   212  	// emptyRoot is the known root hash of an empty trie.
   213  	emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
   214  	// emptyCode is the known hash of the empty EVM bytecode.
   215  	emptyCode = common.HexToHash("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")
   216  )
   217  
   218  // TestSnapGetByteCodes various forms of GetByteCodes requests.
   219  func (s *Suite) TestSnapGetByteCodes(t *utesting.T) {
   220  	// The halfchain import should yield these bytecodes
   221  	var hcBytecodes []common.Hash
   222  	for _, s := range []string{
   223  		"0x200c90460d8b0063210d5f5b9918e053c8f2c024485e0f1b48be8b1fc71b1317",
   224  		"0x20ba67ed4ac6aff626e0d1d4db623e2fada9593daeefc4a6eb4b70e6cff986f3",
   225  		"0x24b5b4902cb3d897c1cee9f16be8e897d8fa277c04c6dc8214f18295fca5de44",
   226  		"0x320b9d0a2be39b8a1c858f9f8cb96b1df0983071681de07ded3a7c0d05db5fd6",
   227  		"0x48cb0d5275936a24632babc7408339f9f7b051274809de565b8b0db76e97e03c",
   228  		"0x67c7a6f5cdaa43b4baa0e15b2be63346d1b9ce9f2c3d7e5804e0cacd44ee3b04",
   229  		"0x6d8418059bdc8c3fabf445e6bfc662af3b6a4ae45999b953996e42c7ead2ab49",
   230  		"0x7043422e5795d03f17ee0463a37235258e609fdd542247754895d72695e3e142",
   231  		"0x727f9e6f0c4bac1ff8d72c2972122d9c8d37ccb37e04edde2339e8da193546f1",
   232  		"0x86ccd5e23c78568a8334e0cebaf3e9f48c998307b0bfb1c378cee83b4bfb29cb",
   233  		"0x8fc89b00d6deafd4c4279531e743365626dbfa28845ec697919d305c2674302d",
   234  		"0x92cfc353bcb9746bb6f9996b6b9df779c88af2e9e0eeac44879ca19887c9b732",
   235  		"0x941b4872104f0995a4898fcf0f615ea6bf46bfbdfcf63ea8f2fd45b3f3286b77",
   236  		"0xa02fe8f41159bb39d2b704c633c3d6389cf4bfcb61a2539a9155f60786cf815f",
   237  		"0xa4b94e0afdffcb0af599677709dac067d3145489ea7aede57672bee43e3b7373",
   238  		"0xaf4e64edd3234c1205b725e42963becd1085f013590bd7ed93f8d711c5eb65fb",
   239  		"0xb69a18fa855b742031420081999086f6fb56c3930ae8840944e8b8ae9931c51e",
   240  		"0xc246c217bc73ce6666c93a93a94faa5250564f50a3fdc27ea74c231c07fe2ca6",
   241  		"0xcd6e4ab2c3034df2a8a1dfaaeb1c4baecd162a93d22de35e854ee2945cbe0c35",
   242  		"0xe24b692d09d6fc2f3d1a6028c400a27c37d7cbb11511907c013946d6ce263d3b",
   243  		"0xe440c5f0e8603fd1ed25976eee261ccee8038cf79d6a4c0eb31b2bf883be737f",
   244  		"0xe6eacbc509203d21ac814b350e72934fde686b7f673c19be8cf956b0c70078ce",
   245  		"0xe8530de4371467b5be7ea0e69e675ab36832c426d6c1ce9513817c0f0ae1486b",
   246  		"0xe85d487abbbc83bf3423cf9731360cf4f5a37220e18e5add54e72ee20861196a",
   247  		"0xf195ea389a5eea28db0be93660014275b158963dec44af1dfa7d4743019a9a49",
   248  	} {
   249  		hcBytecodes = append(hcBytecodes, common.HexToHash(s))
   250  	}
   251  
   252  	for i, tc := range []byteCodesTest{
   253  		// A few stateroots
   254  		{
   255  			nBytes: 10000, hashes: []common.Hash{s.chain.RootAt(0), s.chain.RootAt(999)},
   256  			expHashes: 0,
   257  		},
   258  		{
   259  			nBytes: 10000, hashes: []common.Hash{s.chain.RootAt(0), s.chain.RootAt(0)},
   260  			expHashes: 0,
   261  		},
   262  		// Empties
   263  		{
   264  			nBytes: 10000, hashes: []common.Hash{emptyRoot},
   265  			expHashes: 0,
   266  		},
   267  		{
   268  			nBytes: 10000, hashes: []common.Hash{emptyCode},
   269  			expHashes: 1,
   270  		},
   271  		{
   272  			nBytes: 10000, hashes: []common.Hash{emptyCode, emptyCode, emptyCode},
   273  			expHashes: 3,
   274  		},
   275  		// The existing bytecodes
   276  		{
   277  			nBytes: 10000, hashes: hcBytecodes,
   278  			expHashes: len(hcBytecodes),
   279  		},
   280  		// The existing, with limited byte arg
   281  		{
   282  			nBytes: 1, hashes: hcBytecodes,
   283  			expHashes: 1,
   284  		},
   285  		{
   286  			nBytes: 0, hashes: hcBytecodes,
   287  			expHashes: 1,
   288  		},
   289  		{
   290  			nBytes: 1000, hashes: []common.Hash{hcBytecodes[0], hcBytecodes[0], hcBytecodes[0], hcBytecodes[0]},
   291  			expHashes: 4,
   292  		},
   293  	} {
   294  		if err := s.snapGetByteCodes(t, &tc); err != nil {
   295  			t.Errorf("test %d \n bytes: %d\n #hashes: %d\nfailed: %v", i, tc.nBytes, len(tc.hashes), err)
   296  		}
   297  	}
   298  }
   299  
   300  type trieNodesTest struct {
   301  	root   common.Hash
   302  	paths  []snap.TrieNodePathSet
   303  	nBytes uint64
   304  
   305  	expHashes []common.Hash
   306  	expReject bool
   307  }
   308  
   309  func decodeNibbles(nibbles []byte, bytes []byte) {
   310  	for bi, ni := 0, 0; ni < len(nibbles); bi, ni = bi+1, ni+2 {
   311  		bytes[bi] = nibbles[ni]<<4 | nibbles[ni+1]
   312  	}
   313  }
   314  
   315  // hasTerm returns whether a hex key has the terminator flag.
   316  func hasTerm(s []byte) bool {
   317  	return len(s) > 0 && s[len(s)-1] == 16
   318  }
   319  
   320  func keybytesToHex(str []byte) []byte {
   321  	l := len(str)*2 + 1
   322  	var nibbles = make([]byte, l)
   323  	for i, b := range str {
   324  		nibbles[i*2] = b / 16
   325  		nibbles[i*2+1] = b % 16
   326  	}
   327  	nibbles[l-1] = 16
   328  	return nibbles
   329  }
   330  
   331  func hexToCompact(hex []byte) []byte {
   332  	terminator := byte(0)
   333  	if hasTerm(hex) {
   334  		terminator = 1
   335  		hex = hex[:len(hex)-1]
   336  	}
   337  	buf := make([]byte, len(hex)/2+1)
   338  	buf[0] = terminator << 5 // the flag byte
   339  	if len(hex)&1 == 1 {
   340  		buf[0] |= 1 << 4 // odd flag
   341  		buf[0] |= hex[0] // first nibble is contained in the first byte
   342  		hex = hex[1:]
   343  	}
   344  	decodeNibbles(hex, buf[1:])
   345  	return buf
   346  }
   347  
   348  // TestSnapTrieNodes various forms of GetTrieNodes requests.
   349  func (s *Suite) TestSnapTrieNodes(t *utesting.T) {
   350  
   351  	key := common.FromHex("0x00bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a")
   352  	// helper function to iterate the key, and generate the compact-encoded
   353  	// trie paths along the way.
   354  	pathTo := func(length int) snap.TrieNodePathSet {
   355  		hex := keybytesToHex(key)[:length]
   356  		hex[len(hex)-1] = 0 // remove term flag
   357  		hKey := hexToCompact(hex)
   358  		return snap.TrieNodePathSet{hKey}
   359  	}
   360  	var accPaths []snap.TrieNodePathSet
   361  	for i := 1; i <= 65; i++ {
   362  		accPaths = append(accPaths, pathTo(i))
   363  	}
   364  	empty := emptyCode
   365  	for i, tc := range []trieNodesTest{
   366  		{
   367  			root:      s.chain.RootAt(999),
   368  			paths:     nil,
   369  			nBytes:    500,
   370  			expHashes: nil,
   371  		},
   372  		{
   373  			root: s.chain.RootAt(999),
   374  			paths: []snap.TrieNodePathSet{
   375  				snap.TrieNodePathSet{}, // zero-length pathset should 'abort' and kick us off
   376  				snap.TrieNodePathSet{[]byte{0}},
   377  			},
   378  			nBytes:    5000,
   379  			expHashes: []common.Hash{},
   380  			expReject: true,
   381  		},
   382  		{
   383  			root: s.chain.RootAt(999),
   384  			paths: []snap.TrieNodePathSet{
   385  				snap.TrieNodePathSet{[]byte{0}},
   386  				snap.TrieNodePathSet{[]byte{1}, []byte{0}},
   387  			},
   388  			nBytes: 5000,
   389  			//0x6b3724a41b8c38b46d4d02fba2bb2074c47a507eb16a9a4b978f91d32e406faf
   390  			expHashes: []common.Hash{s.chain.RootAt(999)},
   391  		},
   392  		{ // nonsensically long path
   393  			root: s.chain.RootAt(999),
   394  			paths: []snap.TrieNodePathSet{
   395  				snap.TrieNodePathSet{[]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8,
   396  					0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8}},
   397  			},
   398  			nBytes:    5000,
   399  			expHashes: []common.Hash{common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")},
   400  		},
   401  		{
   402  			root: s.chain.RootAt(0),
   403  			paths: []snap.TrieNodePathSet{
   404  				snap.TrieNodePathSet{[]byte{0}},
   405  				snap.TrieNodePathSet{[]byte{1}, []byte{0}},
   406  			},
   407  			nBytes:    5000,
   408  			expHashes: []common.Hash{},
   409  		},
   410  		{
   411  			// The leaf is only a couple of levels down, so the continued trie traversal causes lookup failures.
   412  			root:   s.chain.RootAt(999),
   413  			paths:  accPaths,
   414  			nBytes: 5000,
   415  			expHashes: []common.Hash{
   416  				common.HexToHash("0xbcefee69b37cca1f5bf3a48aebe08b35f2ea1864fa958bb0723d909a0e0d28d8"),
   417  				common.HexToHash("0x4fb1e4e2391e4b4da471d59641319b8fa25d76c973d4bec594d7b00a69ae5135"),
   418  				empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty,
   419  				empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty,
   420  				empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty,
   421  				empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty,
   422  				empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty,
   423  				empty, empty, empty},
   424  		},
   425  		{
   426  			// Basically the same as above, with different ordering
   427  			root: s.chain.RootAt(999),
   428  			paths: []snap.TrieNodePathSet{
   429  				accPaths[10], accPaths[1], accPaths[0],
   430  			},
   431  			nBytes: 5000,
   432  			expHashes: []common.Hash{
   433  				empty,
   434  				common.HexToHash("0x4fb1e4e2391e4b4da471d59641319b8fa25d76c973d4bec594d7b00a69ae5135"),
   435  				common.HexToHash("0xbcefee69b37cca1f5bf3a48aebe08b35f2ea1864fa958bb0723d909a0e0d28d8"),
   436  			},
   437  		},
   438  	} {
   439  		if err := s.snapGetTrieNodes(t, &tc); err != nil {
   440  			t.Errorf("test %d \n #hashes %x\n root: %#x\n bytes: %d\nfailed: %v", i, len(tc.expHashes), tc.root, tc.nBytes, err)
   441  		}
   442  	}
   443  }
   444  
   445  func (s *Suite) snapGetAccountRange(t *utesting.T, tc *accRangeTest) error {
   446  	conn, err := s.dialSnap()
   447  	if err != nil {
   448  		t.Fatalf("dial failed: %v", err)
   449  	}
   450  	defer conn.Close()
   451  	if err = conn.peer(s.chain, nil); err != nil {
   452  		t.Fatalf("peering failed: %v", err)
   453  	}
   454  	// write request
   455  	req := &GetAccountRange{
   456  		ID:     uint64(rand.Int63()),
   457  		Root:   tc.root,
   458  		Origin: tc.origin,
   459  		Limit:  tc.limit,
   460  		Bytes:  tc.nBytes,
   461  	}
   462  	resp, err := conn.snapRequest(req, req.ID, s.chain)
   463  	if err != nil {
   464  		return fmt.Errorf("account range request failed: %v", err)
   465  	}
   466  	var res *snap.AccountRangePacket
   467  	if r, ok := resp.(*AccountRange); !ok {
   468  		return fmt.Errorf("account range response wrong: %T %v", resp, resp)
   469  	} else {
   470  		res = (*snap.AccountRangePacket)(r)
   471  	}
   472  	if exp, got := tc.expAccounts, len(res.Accounts); exp != got {
   473  		return fmt.Errorf("expected %d accounts, got %d", exp, got)
   474  	}
   475  	// Check that the encoding order is correct
   476  	for i := 1; i < len(res.Accounts); i++ {
   477  		if bytes.Compare(res.Accounts[i-1].Hash[:], res.Accounts[i].Hash[:]) >= 0 {
   478  			return fmt.Errorf("accounts not monotonically increasing: #%d [%x] vs #%d [%x]", i-1, res.Accounts[i-1].Hash[:], i, res.Accounts[i].Hash[:])
   479  		}
   480  	}
   481  	var (
   482  		hashes   []common.Hash
   483  		accounts [][]byte
   484  		proof    = res.Proof
   485  	)
   486  	hashes, accounts, err = res.Unpack()
   487  	if err != nil {
   488  		return err
   489  	}
   490  	if len(hashes) == 0 && len(accounts) == 0 && len(proof) == 0 {
   491  		return nil
   492  	}
   493  	if len(hashes) > 0 {
   494  		if exp, got := tc.expFirst, res.Accounts[0].Hash; exp != got {
   495  			return fmt.Errorf("expected first account 0x%x, got 0x%x", exp, got)
   496  		}
   497  		if exp, got := tc.expLast, res.Accounts[len(res.Accounts)-1].Hash; exp != got {
   498  			return fmt.Errorf("expected last account 0x%x, got 0x%x", exp, got)
   499  		}
   500  	}
   501  	// Reconstruct a partial trie from the response and verify it
   502  	keys := make([][]byte, len(hashes))
   503  	for i, key := range hashes {
   504  		keys[i] = common.CopyBytes(key[:])
   505  	}
   506  	nodes := make(light.NodeList, len(proof))
   507  	for i, node := range proof {
   508  		nodes[i] = node
   509  	}
   510  	proofdb := nodes.NodeSet()
   511  
   512  	var end []byte
   513  	if len(keys) > 0 {
   514  		end = keys[len(keys)-1]
   515  	}
   516  	_, err = trie.VerifyRangeProof(tc.root, tc.origin[:], end, keys, accounts, proofdb)
   517  	return err
   518  }
   519  
   520  func (s *Suite) snapGetStorageRanges(t *utesting.T, tc *stRangesTest) error {
   521  	conn, err := s.dialSnap()
   522  	if err != nil {
   523  		t.Fatalf("dial failed: %v", err)
   524  	}
   525  	defer conn.Close()
   526  	if err = conn.peer(s.chain, nil); err != nil {
   527  		t.Fatalf("peering failed: %v", err)
   528  	}
   529  	// write request
   530  	req := &GetStorageRanges{
   531  		ID:       uint64(rand.Int63()),
   532  		Root:     tc.root,
   533  		Accounts: tc.accounts,
   534  		Origin:   tc.origin,
   535  		Limit:    tc.limit,
   536  		Bytes:    tc.nBytes,
   537  	}
   538  	resp, err := conn.snapRequest(req, req.ID, s.chain)
   539  	if err != nil {
   540  		return fmt.Errorf("account range request failed: %v", err)
   541  	}
   542  	var res *snap.StorageRangesPacket
   543  	if r, ok := resp.(*StorageRanges); !ok {
   544  		return fmt.Errorf("account range response wrong: %T %v", resp, resp)
   545  	} else {
   546  		res = (*snap.StorageRangesPacket)(r)
   547  	}
   548  	gotSlots := 0
   549  	// Ensure the ranges are monotonically increasing
   550  	for i, slots := range res.Slots {
   551  		gotSlots += len(slots)
   552  		for j := 1; j < len(slots); j++ {
   553  			if bytes.Compare(slots[j-1].Hash[:], slots[j].Hash[:]) >= 0 {
   554  				return fmt.Errorf("storage slots not monotonically increasing for account #%d: #%d [%x] vs #%d [%x]", i, j-1, slots[j-1].Hash[:], j, slots[j].Hash[:])
   555  			}
   556  		}
   557  	}
   558  	if exp, got := tc.expSlots, gotSlots; exp != got {
   559  		return fmt.Errorf("expected %d slots, got %d", exp, got)
   560  	}
   561  	return nil
   562  }
   563  
   564  func (s *Suite) snapGetByteCodes(t *utesting.T, tc *byteCodesTest) error {
   565  	conn, err := s.dialSnap()
   566  	if err != nil {
   567  		t.Fatalf("dial failed: %v", err)
   568  	}
   569  	defer conn.Close()
   570  	if err = conn.peer(s.chain, nil); err != nil {
   571  		t.Fatalf("peering failed: %v", err)
   572  	}
   573  	// write request
   574  	req := &GetByteCodes{
   575  		ID:     uint64(rand.Int63()),
   576  		Hashes: tc.hashes,
   577  		Bytes:  tc.nBytes,
   578  	}
   579  	resp, err := conn.snapRequest(req, req.ID, s.chain)
   580  	if err != nil {
   581  		return fmt.Errorf("getBytecodes request failed: %v", err)
   582  	}
   583  	var res *snap.ByteCodesPacket
   584  	if r, ok := resp.(*ByteCodes); !ok {
   585  		return fmt.Errorf("bytecodes response wrong: %T %v", resp, resp)
   586  	} else {
   587  		res = (*snap.ByteCodesPacket)(r)
   588  	}
   589  	if exp, got := tc.expHashes, len(res.Codes); exp != got {
   590  		for i, c := range res.Codes {
   591  			fmt.Printf("%d. %#x\n", i, c)
   592  		}
   593  		return fmt.Errorf("expected %d bytecodes, got %d", exp, got)
   594  	}
   595  	// Cross reference the requested bytecodes with the response to find gaps
   596  	// that the serving node is missing
   597  	var (
   598  		bytecodes = res.Codes
   599  		hasher    = sha3.NewLegacyKeccak256().(crypto.KeccakState)
   600  		hash      = make([]byte, 32)
   601  		codes     = make([][]byte, len(req.Hashes))
   602  	)
   603  
   604  	for i, j := 0, 0; i < len(bytecodes); i++ {
   605  		// Find the next hash that we've been served, leaving misses with nils
   606  		hasher.Reset()
   607  		hasher.Write(bytecodes[i])
   608  		hasher.Read(hash)
   609  
   610  		for j < len(req.Hashes) && !bytes.Equal(hash, req.Hashes[j][:]) {
   611  			j++
   612  		}
   613  		if j < len(req.Hashes) {
   614  			codes[j] = bytecodes[i]
   615  			j++
   616  			continue
   617  		}
   618  		// We've either ran out of hashes, or got unrequested data
   619  		return errors.New("unexpected bytecode")
   620  	}
   621  
   622  	return nil
   623  }
   624  
   625  func (s *Suite) snapGetTrieNodes(t *utesting.T, tc *trieNodesTest) error {
   626  	conn, err := s.dialSnap()
   627  	if err != nil {
   628  		t.Fatalf("dial failed: %v", err)
   629  	}
   630  	defer conn.Close()
   631  	if err = conn.peer(s.chain, nil); err != nil {
   632  		t.Fatalf("peering failed: %v", err)
   633  	}
   634  	// write request
   635  	req := &GetTrieNodes{
   636  		ID:    uint64(rand.Int63()),
   637  		Root:  tc.root,
   638  		Paths: tc.paths,
   639  		Bytes: tc.nBytes,
   640  	}
   641  	resp, err := conn.snapRequest(req, req.ID, s.chain)
   642  	if err != nil {
   643  		if tc.expReject {
   644  			return nil
   645  		}
   646  		return fmt.Errorf("trienodes  request failed: %v", err)
   647  	}
   648  	var res *snap.TrieNodesPacket
   649  	if r, ok := resp.(*TrieNodes); !ok {
   650  		return fmt.Errorf("trienodes response wrong: %T %v", resp, resp)
   651  	} else {
   652  		res = (*snap.TrieNodesPacket)(r)
   653  	}
   654  
   655  	// Check the correctness
   656  
   657  	// Cross reference the requested trienodes with the response to find gaps
   658  	// that the serving node is missing
   659  	hasher := sha3.NewLegacyKeccak256().(crypto.KeccakState)
   660  	hash := make([]byte, 32)
   661  	trienodes := res.Nodes
   662  	if got, want := len(trienodes), len(tc.expHashes); got != want {
   663  		return fmt.Errorf("wrong trienode count, got %d, want %d\n", got, want)
   664  	}
   665  	for i, trienode := range trienodes {
   666  		hasher.Reset()
   667  		hasher.Write(trienode)
   668  		hasher.Read(hash)
   669  		if got, want := hash, tc.expHashes[i]; !bytes.Equal(got, want[:]) {
   670  			fmt.Printf("hash %d wrong, got %#x, want %#x\n", i, got, want)
   671  			err = fmt.Errorf("hash %d wrong, got %#x, want %#x", i, got, want)
   672  		}
   673  	}
   674  	return err
   675  }