github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/core/rawdb/accessors_chain_test.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:35</date> 10 //</624450079306027008> 11 12 13 package rawdb 14 15 import ( 16 "bytes" 17 "math/big" 18 "testing" 19 20 "github.com/ethereum/go-ethereum/common" 21 "github.com/ethereum/go-ethereum/core/types" 22 "github.com/ethereum/go-ethereum/ethdb" 23 "github.com/ethereum/go-ethereum/rlp" 24 "golang.org/x/crypto/sha3" 25 ) 26 27 //测试块头存储和检索操作。 28 func TestHeaderStorage(t *testing.T) { 29 db := ethdb.NewMemDatabase() 30 31 //创建一个测试头以在数据库中移动,并确保它确实是新的 32 header := &types.Header{Number: big.NewInt(42), Extra: []byte("test header")} 33 if entry := ReadHeader(db, header.Hash(), header.Number.Uint64()); entry != nil { 34 t.Fatalf("Non existent header returned: %v", entry) 35 } 36 //在数据库中写入并验证头 37 WriteHeader(db, header) 38 if entry := ReadHeader(db, header.Hash(), header.Number.Uint64()); entry == nil { 39 t.Fatalf("Stored header not found") 40 } else if entry.Hash() != header.Hash() { 41 t.Fatalf("Retrieved header mismatch: have %v, want %v", entry, header) 42 } 43 if entry := ReadHeaderRLP(db, header.Hash(), header.Number.Uint64()); entry == nil { 44 t.Fatalf("Stored header RLP not found") 45 } else { 46 hasher := sha3.NewLegacyKeccak256() 47 hasher.Write(entry) 48 49 if hash := common.BytesToHash(hasher.Sum(nil)); hash != header.Hash() { 50 t.Fatalf("Retrieved RLP header mismatch: have %v, want %v", entry, header) 51 } 52 } 53 //删除头并验证执行 54 DeleteHeader(db, header.Hash(), header.Number.Uint64()) 55 if entry := ReadHeader(db, header.Hash(), header.Number.Uint64()); entry != nil { 56 t.Fatalf("Deleted header returned: %v", entry) 57 } 58 } 59 60 //测试块体存储和检索操作。 61 func TestBodyStorage(t *testing.T) { 62 db := ethdb.NewMemDatabase() 63 64 //创建一个测试体以在数据库中移动,并确保它确实是新的 65 body := &types.Body{Uncles: []*types.Header{{Extra: []byte("test header")}}} 66 67 hasher := sha3.NewLegacyKeccak256() 68 rlp.Encode(hasher, body) 69 hash := common.BytesToHash(hasher.Sum(nil)) 70 71 if entry := ReadBody(db, hash, 0); entry != nil { 72 t.Fatalf("Non existent body returned: %v", entry) 73 } 74 //在数据库中写入并验证正文 75 WriteBody(db, hash, 0, body) 76 if entry := ReadBody(db, hash, 0); entry == nil { 77 t.Fatalf("Stored body not found") 78 } else if types.DeriveSha(types.Transactions(entry.Transactions)) != types.DeriveSha(types.Transactions(body.Transactions)) || types.CalcUncleHash(entry.Uncles) != types.CalcUncleHash(body.Uncles) { 79 t.Fatalf("Retrieved body mismatch: have %v, want %v", entry, body) 80 } 81 if entry := ReadBodyRLP(db, hash, 0); entry == nil { 82 t.Fatalf("Stored body RLP not found") 83 } else { 84 hasher := sha3.NewLegacyKeccak256() 85 hasher.Write(entry) 86 87 if calc := common.BytesToHash(hasher.Sum(nil)); calc != hash { 88 t.Fatalf("Retrieved RLP body mismatch: have %v, want %v", entry, body) 89 } 90 } 91 //删除主体并验证执行 92 DeleteBody(db, hash, 0) 93 if entry := ReadBody(db, hash, 0); entry != nil { 94 t.Fatalf("Deleted body returned: %v", entry) 95 } 96 } 97 98 //测试块存储和检索操作。 99 func TestBlockStorage(t *testing.T) { 100 db := ethdb.NewMemDatabase() 101 102 //创建一个测试块来移动数据库并确保它真的是新的 103 block := types.NewBlockWithHeader(&types.Header{ 104 Extra: []byte("test block"), 105 UncleHash: types.EmptyUncleHash, 106 TxHash: types.EmptyRootHash, 107 ReceiptHash: types.EmptyRootHash, 108 }) 109 if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry != nil { 110 t.Fatalf("Non existent block returned: %v", entry) 111 } 112 if entry := ReadHeader(db, block.Hash(), block.NumberU64()); entry != nil { 113 t.Fatalf("Non existent header returned: %v", entry) 114 } 115 if entry := ReadBody(db, block.Hash(), block.NumberU64()); entry != nil { 116 t.Fatalf("Non existent body returned: %v", entry) 117 } 118 //写入并验证数据库中的块 119 WriteBlock(db, block) 120 if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry == nil { 121 t.Fatalf("Stored block not found") 122 } else if entry.Hash() != block.Hash() { 123 t.Fatalf("Retrieved block mismatch: have %v, want %v", entry, block) 124 } 125 if entry := ReadHeader(db, block.Hash(), block.NumberU64()); entry == nil { 126 t.Fatalf("Stored header not found") 127 } else if entry.Hash() != block.Header().Hash() { 128 t.Fatalf("Retrieved header mismatch: have %v, want %v", entry, block.Header()) 129 } 130 if entry := ReadBody(db, block.Hash(), block.NumberU64()); entry == nil { 131 t.Fatalf("Stored body not found") 132 } else if types.DeriveSha(types.Transactions(entry.Transactions)) != types.DeriveSha(block.Transactions()) || types.CalcUncleHash(entry.Uncles) != types.CalcUncleHash(block.Uncles()) { 133 t.Fatalf("Retrieved body mismatch: have %v, want %v", entry, block.Body()) 134 } 135 //删除块并验证执行 136 DeleteBlock(db, block.Hash(), block.NumberU64()) 137 if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry != nil { 138 t.Fatalf("Deleted block returned: %v", entry) 139 } 140 if entry := ReadHeader(db, block.Hash(), block.NumberU64()); entry != nil { 141 t.Fatalf("Deleted header returned: %v", entry) 142 } 143 if entry := ReadBody(db, block.Hash(), block.NumberU64()); entry != nil { 144 t.Fatalf("Deleted body returned: %v", entry) 145 } 146 } 147 148 //测试部分块内容不能重新组装成完整块。 149 func TestPartialBlockStorage(t *testing.T) { 150 db := ethdb.NewMemDatabase() 151 block := types.NewBlockWithHeader(&types.Header{ 152 Extra: []byte("test block"), 153 UncleHash: types.EmptyUncleHash, 154 TxHash: types.EmptyRootHash, 155 ReceiptHash: types.EmptyRootHash, 156 }) 157 //存储一个头并检查它是否未被识别为块 158 WriteHeader(db, block.Header()) 159 if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry != nil { 160 t.Fatalf("Non existent block returned: %v", entry) 161 } 162 DeleteHeader(db, block.Hash(), block.NumberU64()) 163 164 //存储正文并检查它是否未被识别为块 165 WriteBody(db, block.Hash(), block.NumberU64(), block.Body()) 166 if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry != nil { 167 t.Fatalf("Non existent block returned: %v", entry) 168 } 169 DeleteBody(db, block.Hash(), block.NumberU64()) 170 171 //单独存放一个收割台和一个车斗,并检查重新组装情况。 172 WriteHeader(db, block.Header()) 173 WriteBody(db, block.Hash(), block.NumberU64(), block.Body()) 174 175 if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry == nil { 176 t.Fatalf("Stored block not found") 177 } else if entry.Hash() != block.Hash() { 178 t.Fatalf("Retrieved block mismatch: have %v, want %v", entry, block) 179 } 180 } 181 182 //测试块总难度存储和检索操作。 183 func TestTdStorage(t *testing.T) { 184 db := ethdb.NewMemDatabase() 185 186 //创建一个测试td来移动数据库,并确保它是新的 187 hash, td := common.Hash{}, big.NewInt(314) 188 if entry := ReadTd(db, hash, 0); entry != nil { 189 t.Fatalf("Non existent TD returned: %v", entry) 190 } 191 //在数据库中编写并验证TD 192 WriteTd(db, hash, 0, td) 193 if entry := ReadTd(db, hash, 0); entry == nil { 194 t.Fatalf("Stored TD not found") 195 } else if entry.Cmp(td) != 0 { 196 t.Fatalf("Retrieved TD mismatch: have %v, want %v", entry, td) 197 } 198 //删除TD并验证执行情况 199 DeleteTd(db, hash, 0) 200 if entry := ReadTd(db, hash, 0); entry != nil { 201 t.Fatalf("Deleted TD returned: %v", entry) 202 } 203 } 204 205 //Tests that canonical numbers can be mapped to hashes and retrieved. 206 func TestCanonicalMappingStorage(t *testing.T) { 207 db := ethdb.NewMemDatabase() 208 209 //创建一个测试规范编号和分配的哈希以四处移动 210 hash, number := common.Hash{0: 0xff}, uint64(314) 211 if entry := ReadCanonicalHash(db, number); entry != (common.Hash{}) { 212 t.Fatalf("Non existent canonical mapping returned: %v", entry) 213 } 214 //在数据库中编写并验证TD 215 WriteCanonicalHash(db, hash, number) 216 if entry := ReadCanonicalHash(db, number); entry == (common.Hash{}) { 217 t.Fatalf("Stored canonical mapping not found") 218 } else if entry != hash { 219 t.Fatalf("Retrieved canonical mapping mismatch: have %v, want %v", entry, hash) 220 } 221 //删除TD并验证执行情况 222 DeleteCanonicalHash(db, number) 223 if entry := ReadCanonicalHash(db, number); entry != (common.Hash{}) { 224 t.Fatalf("Deleted canonical mapping returned: %v", entry) 225 } 226 } 227 228 //测试头标题和头块可以单独分配。 229 func TestHeadStorage(t *testing.T) { 230 db := ethdb.NewMemDatabase() 231 232 blockHead := types.NewBlockWithHeader(&types.Header{Extra: []byte("test block header")}) 233 blockFull := types.NewBlockWithHeader(&types.Header{Extra: []byte("test block full")}) 234 blockFast := types.NewBlockWithHeader(&types.Header{Extra: []byte("test block fast")}) 235 236 //检查原始数据库中是否没有头条目 237 if entry := ReadHeadHeaderHash(db); entry != (common.Hash{}) { 238 t.Fatalf("Non head header entry returned: %v", entry) 239 } 240 if entry := ReadHeadBlockHash(db); entry != (common.Hash{}) { 241 t.Fatalf("Non head block entry returned: %v", entry) 242 } 243 if entry := ReadHeadFastBlockHash(db); entry != (common.Hash{}) { 244 t.Fatalf("Non fast head block entry returned: %v", entry) 245 } 246 //Assign separate entries for the head header and block 247 WriteHeadHeaderHash(db, blockHead.Hash()) 248 WriteHeadBlockHash(db, blockFull.Hash()) 249 WriteHeadFastBlockHash(db, blockFast.Hash()) 250 251 //检查两个磁头是否存在以及是否不同(即保持两个磁头) 252 if entry := ReadHeadHeaderHash(db); entry != blockHead.Hash() { 253 t.Fatalf("Head header hash mismatch: have %v, want %v", entry, blockHead.Hash()) 254 } 255 if entry := ReadHeadBlockHash(db); entry != blockFull.Hash() { 256 t.Fatalf("Head block hash mismatch: have %v, want %v", entry, blockFull.Hash()) 257 } 258 if entry := ReadHeadFastBlockHash(db); entry != blockFast.Hash() { 259 t.Fatalf("Fast head block hash mismatch: have %v, want %v", entry, blockFast.Hash()) 260 } 261 } 262 263 //测试与单个块关联的收据是否可以存储和检索。 264 func TestBlockReceiptStorage(t *testing.T) { 265 db := ethdb.NewMemDatabase() 266 267 receipt1 := &types.Receipt{ 268 Status: types.ReceiptStatusFailed, 269 CumulativeGasUsed: 1, 270 Logs: []*types.Log{ 271 {Address: common.BytesToAddress([]byte{0x11})}, 272 {Address: common.BytesToAddress([]byte{0x01, 0x11})}, 273 }, 274 TxHash: common.BytesToHash([]byte{0x11, 0x11}), 275 ContractAddress: common.BytesToAddress([]byte{0x01, 0x11, 0x11}), 276 GasUsed: 111111, 277 } 278 receipt2 := &types.Receipt{ 279 PostState: common.Hash{2}.Bytes(), 280 CumulativeGasUsed: 2, 281 Logs: []*types.Log{ 282 {Address: common.BytesToAddress([]byte{0x22})}, 283 {Address: common.BytesToAddress([]byte{0x02, 0x22})}, 284 }, 285 TxHash: common.BytesToHash([]byte{0x22, 0x22}), 286 ContractAddress: common.BytesToAddress([]byte{0x02, 0x22, 0x22}), 287 GasUsed: 222222, 288 } 289 receipts := []*types.Receipt{receipt1, receipt2} 290 291 //Check that no receipt entries are in a pristine database 292 hash := common.BytesToHash([]byte{0x03, 0x14}) 293 if rs := ReadReceipts(db, hash, 0); len(rs) != 0 { 294 t.Fatalf("non existent receipts returned: %v", rs) 295 } 296 //将收据切片插入数据库并检查是否存在 297 WriteReceipts(db, hash, 0, receipts) 298 if rs := ReadReceipts(db, hash, 0); len(rs) == 0 { 299 t.Fatalf("no receipts returned") 300 } else { 301 for i := 0; i < len(receipts); i++ { 302 rlpHave, _ := rlp.EncodeToBytes(rs[i]) 303 rlpWant, _ := rlp.EncodeToBytes(receipts[i]) 304 305 if !bytes.Equal(rlpHave, rlpWant) { 306 t.Fatalf("receipt #%d: receipt mismatch: have %v, want %v", i, rs[i], receipts[i]) 307 } 308 } 309 } 310 //删除收据切片并检查清除 311 DeleteReceipts(db, hash, 0) 312 if rs := ReadReceipts(db, hash, 0); len(rs) != 0 { 313 t.Fatalf("deleted receipts returned: %v", rs) 314 } 315 } 316