MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / Open

Method Open

src/wallet/migrate.cpp:529–724  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

527}
528
529void BerkeleyRODatabase::Open()
530{
531 // Open the file
532 FILE* file = fsbridge::fopen(m_filepath, "rb");
533 AutoFile db_file(file);
534 if (db_file.IsNull()) {
535 throw std::runtime_error("BerkeleyRODatabase: Failed to open database file");
536 }
537
538 uint32_t page_size = 4096; // Default page size
539
540 // Read the outer metapage
541 // Expected page number is 0
542 MetaPage outer_meta(0);
543 db_file >> outer_meta;
544 page_size = outer_meta.pagesize;
545
546 // Verify the size of the file is a multiple of the page size
547 const int64_t size{db_file.size()};
548
549 // Since BDB stores everything in a page, the file size should be a multiple of the page size;
550 // However, BDB doesn't actually check that this is the case, and enforcing this check results
551 // in us rejecting a database that BDB would not, so this check needs to be excluded.
552 // This is left commented out as a reminder to not accidentally implement this in the future.
553 // if (size % page_size != 0) {
554 // throw std::runtime_error("File size is not a multiple of page size");
555 // }
556
557 // Check the last page number
558 uint32_t expected_last_page{uint32_t((size / page_size) - 1)};
559 if (outer_meta.last_page != expected_last_page) {
560 throw std::runtime_error("Last page number could not fit in file");
561 }
562
563 // Make sure encryption is disabled
564 if (outer_meta.encrypt_algo != 0) {
565 throw std::runtime_error("BDB builtin encryption is not supported");
566 }
567
568 // Check all Log Sequence Numbers (LSN) point to file 0 and offset 1 which indicates that the LSNs were
569 // reset and that the log files are not necessary to get all of the data in the database.
570 for (uint32_t i = 0; i <= outer_meta.last_page; ++i) {
571 // The LSN is composed of 2 32-bit ints, the first is a file id, the second an offset
572 // It will always be the first 8 bytes of a page, so we deserialize it directly for every page
573 uint32_t file;
574 uint32_t offset;
575 SeekToPage(db_file, i, page_size);
576 db_file >> file >> offset;
577 if (outer_meta.other_endian) {
578 file = internal_bswap_32(file);
579 offset = internal_bswap_32(offset);
580 }
581 if (file != 0 || offset != 1) {
582 throw std::runtime_error("LSNs are not reset, this database is not completely flushed. Please reopen then close the database with a version that has BDB support");
583 }
584 }
585
586 // Read the root page

Callers

nothing calls this directly

Calls 15

fopenFunction · 0.85
SeekToPageFunction · 0.85
internal_bswap_32Function · 0.85
ReadBE32Function · 0.85
emplaceMethod · 0.80
IsNullMethod · 0.45
sizeMethod · 0.45
atMethod · 0.45
dataMethod · 0.45
backMethod · 0.45
pop_backMethod · 0.45
emplace_backMethod · 0.45

Tested by

no test coverage detected