github.com/klaytn/klaytn@v1.12.1/storage/statedb/stacktrie_test.go (about) 1 // Modifications Copyright 2021 The klaytn Authors 2 // Copyright 2021 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 // 18 // This file is derived from trie/stacktrie_test.go (2021/11/23). 19 // Modified and improved for the klaytn development. 20 21 package statedb 22 23 import ( 24 "bytes" 25 "math/big" 26 "testing" 27 28 "github.com/klaytn/klaytn/common" 29 "github.com/klaytn/klaytn/crypto" 30 "github.com/klaytn/klaytn/storage/database" 31 ) 32 33 func TestStackTrieInsertAndHash(t *testing.T) { 34 type KeyValueHash struct { 35 K string // Hex string for key. 36 V string // Value, directly converted to bytes. 37 H string // Expected root hash after insert of (K, V) to an existing trie. 38 } 39 tests := [][]KeyValueHash{ 40 { // {0:0, 7:0, f:0} 41 {"00", "v_______________________0___0", "5cb26357b95bb9af08475be00243ceb68ade0b66b5cd816b0c18a18c612d2d21"}, 42 {"70", "v_______________________0___1", "8ff64309574f7a437a7ad1628e690eb7663cfde10676f8a904a8c8291dbc1603"}, 43 {"f0", "v_______________________0___2", "9e3a01bd8d43efb8e9d4b5506648150b8e3ed1caea596f84ee28e01a72635470"}, 44 }, 45 { // {1:0cc, e:{1:fc, e:fc}} 46 {"10cc", "v_______________________1___0", "233e9b257843f3dfdb1cce6676cdaf9e595ac96ee1b55031434d852bc7ac9185"}, 47 {"e1fc", "v_______________________1___1", "39c5e908ae83d0c78520c7c7bda0b3782daf594700e44546e93def8f049cca95"}, 48 {"eefc", "v_______________________1___2", "d789567559fd76fe5b7d9cc42f3750f942502ac1c7f2a466e2f690ec4b6c2a7c"}, 49 }, 50 { // {b:{a:ac, b:ac}, d:acc} 51 {"baac", "v_______________________2___0", "8be1c86ba7ec4c61e14c1a9b75055e0464c2633ae66a055a24e75450156a5d42"}, 52 {"bbac", "v_______________________2___1", "8495159b9895a7d88d973171d737c0aace6fe6ac02a4769fff1bc43bcccce4cc"}, 53 {"dacc", "v_______________________2___2", "9bcfc5b220a27328deb9dc6ee2e3d46c9ebc9c69e78acda1fa2c7040602c63ca"}, 54 }, 55 { // {0:0cccc, 2:456{0:0, 2:2} 56 {"00cccc", "v_______________________3___0", "e57dc2785b99ce9205080cb41b32ebea7ac3e158952b44c87d186e6d190a6530"}, 57 {"245600", "v_______________________3___1", "0335354adbd360a45c1871a842452287721b64b4234dfe08760b243523c998db"}, 58 {"245622", "v_______________________3___2", "9e6832db0dca2b5cf81c0e0727bfde6afc39d5de33e5720bccacc183c162104e"}, 59 }, 60 { // {1:4567{1:1c, 3:3c}, 3:0cccccc} 61 {"1456711c", "v_______________________4___0", "f2389e78d98fed99f3e63d6d1623c1d4d9e8c91cb1d585de81fbc7c0e60d3529"}, 62 {"1456733c", "v_______________________4___1", "101189b3fab852be97a0120c03d95eefcf984d3ed639f2328527de6def55a9c0"}, 63 {"30cccccc", "v_______________________4___2", "3780ce111f98d15751dfde1eb21080efc7d3914b429e5c84c64db637c55405b3"}, 64 }, 65 { // 8800{1:f, 2:e, 3:d} 66 {"88001f", "v_______________________5___0", "e817db50d84f341d443c6f6593cafda093fc85e773a762421d47daa6ac993bd5"}, 67 {"88002e", "v_______________________5___1", "d6e3e6047bdc110edd296a4d63c030aec451bee9d8075bc5a198eee8cda34f68"}, 68 {"88003d", "v_______________________5___2", "b6bdf8298c703342188e5f7f84921a402042d0e5fb059969dd53a6b6b1fb989e"}, 69 }, 70 { // 0{1:fc, 2:ec, 4:dc} 71 {"01fc", "v_______________________6___0", "693268f2ca80d32b015f61cd2c4dba5a47a6b52a14c34f8e6945fad684e7a0d5"}, 72 {"02ec", "v_______________________6___1", "e24ddd44469310c2b785a2044618874bf486d2f7822603a9b8dce58d6524d5de"}, 73 {"04dc", "v_______________________6___2", "33fc259629187bbe54b92f82f0cd8083b91a12e41a9456b84fc155321e334db7"}, 74 }, 75 { // f{0:fccc, f:ff{0:f, f:f}} 76 {"f0fccc", "v_______________________7___0", "b0966b5aa469a3e292bc5fcfa6c396ae7a657255eef552ea7e12f996de795b90"}, 77 {"ffff0f", "v_______________________7___1", "3b1ca154ec2a3d96d8d77bddef0abfe40a53a64eb03cecf78da9ec43799fa3d0"}, 78 {"ffffff", "v_______________________7___2", "e75463041f1be8252781be0ace579a44ea4387bf5b2739f4607af676f7719678"}, 79 }, 80 { // ff{0:f{0:f, f:f}, f:fcc} 81 {"ff0f0f", "v_______________________8___0", "0928af9b14718ec8262ab89df430f1e5fbf66fac0fed037aff2b6767ae8c8684"}, 82 {"ff0fff", "v_______________________8___1", "d870f4d3ce26b0bf86912810a1960693630c20a48ba56be0ad04bc3e9ddb01e6"}, 83 {"ffffcc", "v_______________________8___2", "4239f10dd9d9915ecf2e047d6a576bdc1733ed77a30830f1bf29deaf7d8e966f"}, 84 }, 85 { 86 {"123d", "x___________________________0", "fc453d88b6f128a77c448669710497380fa4588abbea9f78f4c20c80daa797d0"}, 87 {"123e", "x___________________________1", "5af48f2d8a9a015c1ff7fa8b8c7f6b676233bd320e8fb57fd7933622badd2cec"}, 88 {"123f", "x___________________________2", "1164d7299964e74ac40d761f9189b2a3987fae959800d0f7e29d3aaf3eae9e15"}, 89 }, 90 { 91 {"123d", "x___________________________0", "fc453d88b6f128a77c448669710497380fa4588abbea9f78f4c20c80daa797d0"}, 92 {"123e", "x___________________________1", "5af48f2d8a9a015c1ff7fa8b8c7f6b676233bd320e8fb57fd7933622badd2cec"}, 93 {"124a", "x___________________________2", "661a96a669869d76b7231380da0649d013301425fbea9d5c5fae6405aa31cfce"}, 94 }, 95 { 96 {"123d", "x___________________________0", "fc453d88b6f128a77c448669710497380fa4588abbea9f78f4c20c80daa797d0"}, 97 {"123e", "x___________________________1", "5af48f2d8a9a015c1ff7fa8b8c7f6b676233bd320e8fb57fd7933622badd2cec"}, 98 {"13aa", "x___________________________2", "6590120e1fd3ffd1a90e8de5bb10750b61079bb0776cca4414dd79a24e4d4356"}, 99 }, 100 { 101 {"123d", "x___________________________0", "fc453d88b6f128a77c448669710497380fa4588abbea9f78f4c20c80daa797d0"}, 102 {"123e", "x___________________________1", "5af48f2d8a9a015c1ff7fa8b8c7f6b676233bd320e8fb57fd7933622badd2cec"}, 103 {"2aaa", "x___________________________2", "f869b40e0c55eace1918332ef91563616fbf0755e2b946119679f7ef8e44b514"}, 104 }, 105 { 106 {"1234da", "x___________________________0", "1c4b4462e9f56a80ca0f5d77c0d632c41b0102290930343cf1791e971a045a79"}, 107 {"1234ea", "x___________________________1", "2f502917f3ba7d328c21c8b45ee0f160652e68450332c166d4ad02d1afe31862"}, 108 {"1234fa", "x___________________________2", "4f4e368ab367090d5bc3dbf25f7729f8bd60df84de309b4633a6b69ab66142c0"}, 109 }, 110 { 111 {"1234da", "x___________________________0", "1c4b4462e9f56a80ca0f5d77c0d632c41b0102290930343cf1791e971a045a79"}, 112 {"1234ea", "x___________________________1", "2f502917f3ba7d328c21c8b45ee0f160652e68450332c166d4ad02d1afe31862"}, 113 {"1235aa", "x___________________________2", "21840121d11a91ac8bbad9a5d06af902a5c8d56a47b85600ba813814b7bfcb9b"}, 114 }, 115 { 116 {"1234da", "x___________________________0", "1c4b4462e9f56a80ca0f5d77c0d632c41b0102290930343cf1791e971a045a79"}, 117 {"1234ea", "x___________________________1", "2f502917f3ba7d328c21c8b45ee0f160652e68450332c166d4ad02d1afe31862"}, 118 {"124aaa", "x___________________________2", "ea4040ddf6ae3fbd1524bdec19c0ab1581015996262006632027fa5cf21e441e"}, 119 }, 120 { 121 {"1234da", "x___________________________0", "1c4b4462e9f56a80ca0f5d77c0d632c41b0102290930343cf1791e971a045a79"}, 122 {"1234ea", "x___________________________1", "2f502917f3ba7d328c21c8b45ee0f160652e68450332c166d4ad02d1afe31862"}, 123 {"13aaaa", "x___________________________2", "e4beb66c67e44f2dd8ba36036e45a44ff68f8d52942472b1911a45f886a34507"}, 124 }, 125 { 126 {"1234da", "x___________________________0", "1c4b4462e9f56a80ca0f5d77c0d632c41b0102290930343cf1791e971a045a79"}, 127 {"1234ea", "x___________________________1", "2f502917f3ba7d328c21c8b45ee0f160652e68450332c166d4ad02d1afe31862"}, 128 {"2aaaaa", "x___________________________2", "5f5989b820ff5d76b7d49e77bb64f26602294f6c42a1a3becc669cd9e0dc8ec9"}, 129 }, 130 { 131 {"000000", "x___________________________0", "3b32b7af0bddc7940e7364ee18b5a59702c1825e469452c8483b9c4e0218b55a"}, 132 {"1234da", "x___________________________1", "3ab152a1285dca31945566f872c1cc2f17a770440eda32aeee46a5e91033dde2"}, 133 {"1234ea", "x___________________________2", "0cccc87f96ddef55563c1b3be3c64fff6a644333c3d9cd99852cb53b6412b9b8"}, 134 {"1234fa", "x___________________________3", "65bb3aafea8121111d693ffe34881c14d27b128fd113fa120961f251fe28428d"}, 135 }, 136 { 137 {"000000", "x___________________________0", "3b32b7af0bddc7940e7364ee18b5a59702c1825e469452c8483b9c4e0218b55a"}, 138 {"1234da", "x___________________________1", "3ab152a1285dca31945566f872c1cc2f17a770440eda32aeee46a5e91033dde2"}, 139 {"1234ea", "x___________________________2", "0cccc87f96ddef55563c1b3be3c64fff6a644333c3d9cd99852cb53b6412b9b8"}, 140 {"1235aa", "x___________________________3", "f670e4d2547c533c5f21e0045442e2ecb733f347ad6d29ef36e0f5ba31bb11a8"}, 141 }, 142 { 143 {"000000", "x___________________________0", "3b32b7af0bddc7940e7364ee18b5a59702c1825e469452c8483b9c4e0218b55a"}, 144 {"1234da", "x___________________________1", "3ab152a1285dca31945566f872c1cc2f17a770440eda32aeee46a5e91033dde2"}, 145 {"1234ea", "x___________________________2", "0cccc87f96ddef55563c1b3be3c64fff6a644333c3d9cd99852cb53b6412b9b8"}, 146 {"124aaa", "x___________________________3", "c17464123050a9a6f29b5574bb2f92f6d305c1794976b475b7fb0316b6335598"}, 147 }, 148 { 149 {"000000", "x___________________________0", "3b32b7af0bddc7940e7364ee18b5a59702c1825e469452c8483b9c4e0218b55a"}, 150 {"1234da", "x___________________________1", "3ab152a1285dca31945566f872c1cc2f17a770440eda32aeee46a5e91033dde2"}, 151 {"1234ea", "x___________________________2", "0cccc87f96ddef55563c1b3be3c64fff6a644333c3d9cd99852cb53b6412b9b8"}, 152 {"13aaaa", "x___________________________3", "aa8301be8cb52ea5cd249f5feb79fb4315ee8de2140c604033f4b3fff78f0105"}, 153 }, 154 { 155 {"0000", "x___________________________0", "cb8c09ad07ae882136f602b3f21f8733a9f5a78f1d2525a8d24d1c13258000b2"}, 156 {"123d", "x___________________________1", "8f09663deb02f08958136410dc48565e077f76bb6c9d8c84d35fc8913a657d31"}, 157 {"123e", "x___________________________2", "0d230561e398c579e09a9f7b69ceaf7d3970f5a436fdb28b68b7a37c5bdd6b80"}, 158 {"123f", "x___________________________3", "80f7bad1893ca57e3443bb3305a517723a74d3ba831bcaca22a170645eb7aafb"}, 159 }, 160 { 161 {"0000", "x___________________________0", "cb8c09ad07ae882136f602b3f21f8733a9f5a78f1d2525a8d24d1c13258000b2"}, 162 {"123d", "x___________________________1", "8f09663deb02f08958136410dc48565e077f76bb6c9d8c84d35fc8913a657d31"}, 163 {"123e", "x___________________________2", "0d230561e398c579e09a9f7b69ceaf7d3970f5a436fdb28b68b7a37c5bdd6b80"}, 164 {"124a", "x___________________________3", "383bc1bb4f019e6bc4da3751509ea709b58dd1ac46081670834bae072f3e9557"}, 165 }, 166 { 167 {"0000", "x___________________________0", "cb8c09ad07ae882136f602b3f21f8733a9f5a78f1d2525a8d24d1c13258000b2"}, 168 {"123d", "x___________________________1", "8f09663deb02f08958136410dc48565e077f76bb6c9d8c84d35fc8913a657d31"}, 169 {"123e", "x___________________________2", "0d230561e398c579e09a9f7b69ceaf7d3970f5a436fdb28b68b7a37c5bdd6b80"}, 170 {"13aa", "x___________________________3", "ff0dc70ce2e5db90ee42a4c2ad12139596b890e90eb4e16526ab38fa465b35cf"}, 171 }, 172 } 173 st := NewStackTrie(nil) 174 for i, test := range tests { 175 // The StackTrie does not allow Insert(), Hash(), Insert(), ... 176 // so we will create new trie for every sequence length of inserts. 177 for l := 1; l <= len(test); l++ { 178 st.Reset() 179 for j := 0; j < l; j++ { 180 kv := &test[j] 181 if err := st.TryUpdate(common.FromHex(kv.K), []byte(kv.V)); err != nil { 182 t.Fatal(err) 183 } 184 } 185 expected := common.HexToHash(test[l-1].H) 186 if h := st.Hash(); h != expected { 187 t.Errorf("%d(%d): root hash mismatch: %x, expected %x", i, l, h, expected) 188 } 189 } 190 } 191 } 192 193 func TestSizeBug(t *testing.T) { 194 st := NewStackTrie(nil) 195 nt, _ := NewTrie(common.Hash{}, NewDatabase(database.NewMemoryDBManager()), nil) 196 197 leaf := common.FromHex("290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563") 198 value := common.FromHex("94cf40d0d2b44f2b66e07cace1372ca42b73cf21a3") 199 200 nt.TryUpdate(leaf, value) 201 st.TryUpdate(leaf, value) 202 203 if nt.Hash() != st.Hash() { 204 t.Fatalf("error %x != %x", st.Hash(), nt.Hash()) 205 } 206 } 207 208 func TestEmptyBug(t *testing.T) { 209 st := NewStackTrie(nil) 210 nt, _ := NewTrie(common.Hash{}, NewDatabase(database.NewMemoryDBManager()), nil) 211 212 // leaf := common.FromHex("290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563") 213 // value := common.FromHex("94cf40d0d2b44f2b66e07cace1372ca42b73cf21a3") 214 kvs := []struct { 215 K string 216 V string 217 }{ 218 {K: "405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace", V: "9496f4ec2bf9dab484cac6be589e8417d84781be08"}, 219 {K: "40edb63a35fcf86c08022722aa3287cdd36440d671b4918131b2514795fefa9c", V: "01"}, 220 {K: "b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6", V: "947a30f7736e48d6599356464ba4c150d8da0302ff"}, 221 {K: "c2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b", V: "02"}, 222 } 223 224 for _, kv := range kvs { 225 nt.TryUpdate(common.FromHex(kv.K), common.FromHex(kv.V)) 226 st.TryUpdate(common.FromHex(kv.K), common.FromHex(kv.V)) 227 } 228 229 if nt.Hash() != st.Hash() { 230 t.Fatalf("error %x != %x", st.Hash(), nt.Hash()) 231 } 232 } 233 234 func TestValLength56(t *testing.T) { 235 st := NewStackTrie(nil) 236 nt, _ := NewTrie(common.Hash{}, NewDatabase(database.NewMemoryDBManager()), nil) 237 238 // leaf := common.FromHex("290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563") 239 // value := common.FromHex("94cf40d0d2b44f2b66e07cace1372ca42b73cf21a3") 240 kvs := []struct { 241 K string 242 V string 243 }{ 244 {K: "405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace", V: "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"}, 245 } 246 247 for _, kv := range kvs { 248 nt.TryUpdate(common.FromHex(kv.K), common.FromHex(kv.V)) 249 st.TryUpdate(common.FromHex(kv.K), common.FromHex(kv.V)) 250 } 251 252 if nt.Hash() != st.Hash() { 253 t.Fatalf("error %x != %x", st.Hash(), nt.Hash()) 254 } 255 } 256 257 // TestUpdateSmallNodes tests a case where the leaves are small (both key and value), 258 // which causes a lot of node-within-node. This case was found via fuzzing. 259 func TestUpdateSmallNodes(t *testing.T) { 260 st := NewStackTrie(nil) 261 nt, _ := NewTrie(common.Hash{}, NewDatabase(database.NewMemoryDBManager()), nil) 262 kvs := []struct { 263 K string 264 V string 265 }{ 266 {"63303030", "3041"}, // stacktrie.Update 267 {"65", "3000"}, // stacktrie.Update 268 } 269 for _, kv := range kvs { 270 nt.TryUpdate(common.FromHex(kv.K), common.FromHex(kv.V)) 271 st.TryUpdate(common.FromHex(kv.K), common.FromHex(kv.V)) 272 } 273 if nt.Hash() != st.Hash() { 274 t.Fatalf("error %x != %x", st.Hash(), nt.Hash()) 275 } 276 } 277 278 // TestUpdateVariableKeys contains a case which stacktrie fails: when keys of different 279 // sizes are used, and the second one has the same prefix as the first, then the 280 // stacktrie fails, since it's unable to 'expand' on an already added leaf. 281 // For all practical purposes, this is fine, since keys are fixed-size length 282 // in account and storage tries. 283 // 284 // The test is marked as 'skipped', and exists just to have the behaviour documented. 285 // This case was found via fuzzing. 286 func TestUpdateVariableKeys(t *testing.T) { 287 t.SkipNow() 288 st := NewStackTrie(nil) 289 nt, _ := NewTrie(common.Hash{}, NewDatabase(database.NewMemoryDBManager()), nil) 290 kvs := []struct { 291 K string 292 V string 293 }{ 294 {"0x33303534636532393561313031676174", "303030"}, 295 {"0x3330353463653239356131303167617430", "313131"}, 296 } 297 for _, kv := range kvs { 298 nt.TryUpdate(common.FromHex(kv.K), common.FromHex(kv.V)) 299 st.TryUpdate(common.FromHex(kv.K), common.FromHex(kv.V)) 300 } 301 if nt.Hash() != st.Hash() { 302 t.Fatalf("error %x != %x", st.Hash(), nt.Hash()) 303 } 304 } 305 306 // TestStacktrieNotModifyValues checks that inserting blobs of data into the 307 // stacktrie does not mutate the blobs 308 func TestStacktrieNotModifyValues(t *testing.T) { 309 st := NewStackTrie(nil) 310 { // Test a very small trie 311 // Give it the value as a slice with large backing alloc, 312 // so if the stacktrie tries to append, it won't have to realloc 313 value := make([]byte, 1, 100) 314 value[0] = 0x2 315 want := common.CopyBytes(value) 316 st.TryUpdate([]byte{0x01}, value) 317 st.Hash() 318 if have := value; !bytes.Equal(have, want) { 319 t.Fatalf("tiny trie: have %#x want %#x", have, want) 320 } 321 st = NewStackTrie(nil) 322 } 323 // Test with a larger trie 324 keyB := big.NewInt(1) 325 keyDelta := big.NewInt(1) 326 var vals [][]byte 327 getValue := func(i int) []byte { 328 if i%2 == 0 { // large 329 return crypto.Keccak256(big.NewInt(int64(i)).Bytes()) 330 } else { // small 331 return big.NewInt(int64(i)).Bytes() 332 } 333 } 334 for i := 0; i < 1000; i++ { 335 key := common.BigToHash(keyB) 336 value := getValue(i) 337 st.TryUpdate(key.Bytes(), value) 338 vals = append(vals, value) 339 keyB = keyB.Add(keyB, keyDelta) 340 keyDelta.Add(keyDelta, common.Big1) 341 } 342 st.Hash() 343 for i := 0; i < 1000; i++ { 344 want := getValue(i) 345 346 have := vals[i] 347 if !bytes.Equal(have, want) { 348 t.Fatalf("item %d, have %#x want %#x", i, have, want) 349 } 350 351 } 352 } 353 354 // TestStacktrieSerialization tests that the stacktrie works well if we 355 // serialize/unserialize it a lot 356 func TestStacktrieSerialization(t *testing.T) { 357 var ( 358 st = NewStackTrie(nil) 359 nt, _ = NewTrie(common.Hash{}, NewDatabase(database.NewMemoryDBManager()), nil) 360 keyB = big.NewInt(1) 361 keyDelta = big.NewInt(1) 362 vals [][]byte 363 keys [][]byte 364 ) 365 getValue := func(i int) []byte { 366 if i%2 == 0 { // large 367 return crypto.Keccak256(big.NewInt(int64(i)).Bytes()) 368 } else { // small 369 return big.NewInt(int64(i)).Bytes() 370 } 371 } 372 for i := 0; i < 10; i++ { 373 vals = append(vals, getValue(i)) 374 keys = append(keys, common.BigToHash(keyB).Bytes()) 375 keyB = keyB.Add(keyB, keyDelta) 376 keyDelta.Add(keyDelta, common.Big1) 377 } 378 for i, k := range keys { 379 nt.TryUpdate(k, common.CopyBytes(vals[i])) 380 } 381 382 for i, k := range keys { 383 blob, err := st.MarshalBinary() 384 if err != nil { 385 t.Fatal(err) 386 } 387 newSt, err := NewFromBinary(blob, nil) 388 if err != nil { 389 t.Fatal(err) 390 } 391 st = newSt 392 st.TryUpdate(k, common.CopyBytes(vals[i])) 393 } 394 if have, want := st.Hash(), nt.Hash(); have != want { 395 t.Fatalf("have %#x want %#x", have, want) 396 } 397 }