( st xi.Storage, irreHash hash.Hash)
| 471 | } |
| 472 | |
| 473 | func loadBlocks( |
| 474 | st xi.Storage, irreHash hash.Hash) (lastIrre *blockNode, heads []*blockNode, err error, |
| 475 | ) { |
| 476 | var ( |
| 477 | rows *sql.Rows |
| 478 | |
| 479 | index = make(map[hash.Hash]*blockNode) |
| 480 | headsIndex = make(map[hash.Hash]*blockNode) |
| 481 | |
| 482 | // Scan buffer |
| 483 | id uint32 |
| 484 | height uint32 |
| 485 | bnHex, pnHex string |
| 486 | enc []byte |
| 487 | |
| 488 | ok bool |
| 489 | bh, ph hash.Hash |
| 490 | bn, pn *blockNode |
| 491 | ) |
| 492 | |
| 493 | // Load blocks |
| 494 | if rows, err = st.Reader().Query( |
| 495 | `SELECT "rowid", "height", "hash", "parent", "encoded" FROM "blocks" ORDER BY "rowid"`, |
| 496 | ); err != nil { |
| 497 | return |
| 498 | } |
| 499 | defer rows.Close() |
| 500 | |
| 501 | for rows.Next() { |
| 502 | // Scan and decode block |
| 503 | if err = rows.Scan(&id, &height, &bnHex, &pnHex, &enc); err != nil { |
| 504 | return |
| 505 | } |
| 506 | if err = hash.Decode(&bh, bnHex); err != nil { |
| 507 | return |
| 508 | } |
| 509 | if err = hash.Decode(&ph, pnHex); err != nil { |
| 510 | return |
| 511 | } |
| 512 | var dec = &types.BPBlock{} |
| 513 | if err = utils.DecodeMsgPack(enc, dec); err != nil { |
| 514 | return |
| 515 | } |
| 516 | log.WithFields(log.Fields{ |
| 517 | "rowid": id, |
| 518 | "height": height, |
| 519 | "hash": bh.Short(4), |
| 520 | "parent": ph.Short(4), |
| 521 | }).Debug("loaded new block") |
| 522 | // Add genesis block |
| 523 | if height == 0 { |
| 524 | if len(index) != 0 { |
| 525 | err = ErrMultipleGenesis |
| 526 | return |
| 527 | } |
| 528 | bn = newNonCacheBlockNode(0, dec, nil) |
| 529 | index[bh] = bn |
| 530 | headsIndex[bh] = bn |
no test coverage detected