use of com.hedera.mirror.common.domain.addressbook.AddressBook in project hedera-mirror-node by hashgraph.
the class AddressBookServiceImpl method migrate.
/**
* Migrates address book data by searching file_data table for applicable 101 and 102 files. These files are
* converted to AddressBook objects and used to populate address_book and address_book_entry tables. Migrate flow
* will populate initial addressBook where applicable and consider all file_data present
*
* @return Latest AddressBook from historical files
*/
@Override
public synchronized AddressBook migrate() {
long consensusTimestamp = DomainUtils.convertToNanosMax(Instant.now());
var currentAddressBook = addressBookRepository.findLatestAddressBook(consensusTimestamp, ADDRESS_BOOK_102_ENTITY_ID.getId()).orElse(null);
if (currentAddressBook != null) {
// verify no file_data 102 entries exists after current addressBook
List<FileData> fileDataList = fileDataRepository.findAddressBooksBetween(currentAddressBook.getStartConsensusTimestamp(), Long.MAX_VALUE, 1);
if (CollectionUtils.isEmpty(fileDataList)) {
log.trace("All valid address books exist in db, skipping migration");
return currentAddressBook;
}
log.warn("Valid address book file data entries exist in db after current address book");
}
log.info("Empty or incomplete list of address books found in db, proceeding with migration");
return transactionTemplate.execute(status -> {
log.info("Searching for address book on file system");
var initialAddressBook = currentAddressBook == null ? parse(getInitialAddressBookFileData()) : currentAddressBook;
// Parse all applicable addressBook file_data entries are processed
AddressBook latestAddressBook = parseHistoricAddressBooks(initialAddressBook.getStartConsensusTimestamp() - 1, consensusTimestamp);
// set latestAddressBook as newest addressBook from file_data entries or initial addressBook from filesystem
latestAddressBook = latestAddressBook == null ? initialAddressBook : latestAddressBook;
log.info("Migration complete. Current address book to db: {}", latestAddressBook);
return latestAddressBook;
});
}
use of com.hedera.mirror.common.domain.addressbook.AddressBook in project hedera-mirror-node by hashgraph.
the class AddressBookServiceImpl method parseHistoricAddressBooks.
/**
* Batch parse all 101 and 102 addressBook fileData objects and update the address_book table. Uses page size and
* timestamp counters to batch query file data entries within timestamp range
*/
private AddressBook parseHistoricAddressBooks(long startTimestamp, long endTimestamp) {
var fileDataEntries = 0;
long currentConsensusTimestamp = startTimestamp;
AddressBook lastAddressBook = null;
// retrieve pages of fileData entries for historic address books within range
var pageSize = 1000;
List<FileData> fileDataList = fileDataRepository.findAddressBooksBetween(currentConsensusTimestamp, endTimestamp, pageSize);
while (!CollectionUtils.isEmpty(fileDataList)) {
log.info("Retrieved {} file_data rows for address book processing", fileDataList.size());
for (FileData fileData : fileDataList) {
if (fileData.getFileData() != null && fileData.getFileData().length > 0) {
// convert and ingest address book fileData contents
lastAddressBook = parse(fileData);
fileDataEntries++;
}
// update timestamp counter to ensure next query doesn't reconsider files in this time range
currentConsensusTimestamp = fileData.getConsensusTimestamp();
}
fileDataList = fileDataRepository.findAddressBooksBetween(currentConsensusTimestamp, endTimestamp, pageSize);
}
log.info("Processed {} historic address books", fileDataEntries);
return lastAddressBook;
}
use of com.hedera.mirror.common.domain.addressbook.AddressBook in project hedera-mirror-node by hashgraph.
the class Downloader method downloadNextBatch.
protected void downloadNextBatch() {
if (!downloaderProperties.isEnabled()) {
return;
}
if (ShutdownHelper.isStopping()) {
return;
}
try {
AddressBook addressBook = addressBookService.getCurrent();
var sigFilesMap = downloadAndParseSigFiles(addressBook);
// Following is a cost optimization to not unnecessarily list the public demo bucket once complete
if (sigFilesMap.isEmpty() && mirrorProperties.getNetwork() == MirrorProperties.HederaNetwork.DEMO) {
downloaderProperties.setEnabled(false);
log.warn("Disabled polling after downloading all files in demo bucket");
}
// Verify signature files and download corresponding files of valid signature files
verifySigsAndDownloadDataFiles(sigFilesMap);
} catch (SignatureVerificationException e) {
log.warn(e.getMessage());
} catch (InterruptedException e) {
log.error("Error downloading files", e);
Thread.currentThread().interrupt();
} catch (Exception e) {
log.error("Error downloading files", e);
}
}
use of com.hedera.mirror.common.domain.addressbook.AddressBook in project hedera-mirror-node by hashgraph.
the class AddressBookServiceImplTest method startupWithOtherNetwork.
@Test
void startupWithOtherNetwork() {
// copy other addressbook to file system
FileCopier fileCopier = FileCopier.create(testPath, dataPath).from("").filterFiles("test-v1").to("");
fileCopier.copy();
MirrorProperties otherNetworkMirrorProperties = new MirrorProperties();
otherNetworkMirrorProperties.setDataPath(dataPath);
otherNetworkMirrorProperties.setInitialAddressBook(dataPath.resolve("test-v1"));
otherNetworkMirrorProperties.setNetwork(MirrorProperties.HederaNetwork.OTHER);
AddressBookService customAddressBookService = new AddressBookServiceImpl(addressBookRepository, fileDataRepository, otherNetworkMirrorProperties, transactionTemplate);
AddressBook addressBook = customAddressBookService.getCurrent();
assertThat(addressBook.getStartConsensusTimestamp()).isEqualTo(1L);
assertEquals(1, addressBookRepository.count());
}
use of com.hedera.mirror.common.domain.addressbook.AddressBook in project hedera-mirror-node by hashgraph.
the class AddressBookServiceImplTest method verifyAddressBookMigrationWithNewFileDataAfterCurrentAddressBook.
@Test
void verifyAddressBookMigrationWithNewFileDataAfterCurrentAddressBook() {
byte[] addressBookBytes1 = UPDATED.toByteArray();
store(addressBookBytes1, 2L, false);
byte[] addressBookBytes2 = UPDATED.toByteArray();
store(addressBookBytes2, 3L, true);
// initial migration
AddressBook addressBook = addressBookService.getCurrent();
assertThat(addressBook.getStartConsensusTimestamp()).isEqualTo(4L);
assertAddressBook(addressBook, UPDATED);
// valid file data added but no address book produced
// file 101 update contents to be split over 1 update and 1 append operation
byte[] addressBook101Bytes = FINAL.toByteArray();
int index101 = addressBook101Bytes.length / 2;
byte[] addressBook101Bytes1 = Arrays.copyOfRange(addressBook101Bytes, 0, index101);
byte[] addressBook101Bytes2 = Arrays.copyOfRange(addressBook101Bytes, index101, addressBook101Bytes.length);
fileDataRepository.save(createFileData(addressBook101Bytes1, 4L, false, TransactionType.FILEUPDATE));
fileDataRepository.save(createFileData(addressBook101Bytes2, 5L, false, TransactionType.FILEAPPEND));
// file 102 update contents to be split over 1 update and 1 append operation
byte[] addressBook102Bytes = FINAL.toByteArray();
int index = addressBook102Bytes.length / 2;
byte[] addressBook102Bytes1 = Arrays.copyOfRange(addressBook102Bytes, 0, index);
byte[] addressBook102Bytes2 = Arrays.copyOfRange(addressBook102Bytes, index, addressBook102Bytes.length);
fileDataRepository.save(createFileData(addressBook102Bytes1, 6L, true, TransactionType.FILEUPDATE));
fileDataRepository.save(createFileData(addressBook102Bytes2, 7L, true, TransactionType.FILEAPPEND));
// migration on startup
AddressBook newAddressBook = addressBookService.migrate();
assertThat(newAddressBook.getStartConsensusTimestamp()).isEqualTo(8L);
assertAddressBook(newAddressBook, FINAL);
assertEquals(6, fileDataRepository.count());
// initial plus 4 files
assertEquals(5, addressBookRepository.count());
assertEquals(TEST_INITIAL_ADDRESS_BOOK_NODE_COUNT + (UPDATED.getNodeAddressCount() * 2) + (FINAL.getNodeAddressCount() * 2), addressBookEntryRepository.count());
}
Aggregations