use of org.hyperledger.besu.ethereum.trie.RestoreVisitor in project besu by hyperledger.
the class RestoreState method restoreAccounts.
@SuppressWarnings("UnusedVariable")
private void restoreAccounts() throws IOException {
newWorldStateUpdater();
int storageBranchCount = 0;
int storageExtensionCount = 0;
int storageLeafCount = 0;
final PersistVisitor<Bytes> accountPersistVisitor = new PersistVisitor<>(this::updateAccountState);
Node<Bytes> root = accountPersistVisitor.initialRoot();
try (final RollingFileReader reader = new RollingFileReader(this::accountFileName, compressed)) {
for (long i = 0; i < accountCount; i++) {
if (i % 100000 == 0) {
LOG.info("Loading account data {} / {}", i, accountCount);
}
final byte[] accountEntry = reader.readBytes();
final BytesValueRLPInput accountInput = new BytesValueRLPInput(Bytes.of(accountEntry), false, true);
final int length = accountInput.enterList();
if (length != 3) {
throw new RuntimeException("Unexpected account length " + length);
}
final Bytes32 trieKey = accountInput.readBytes32();
final Bytes accountRlp = accountInput.readBytes();
final Bytes code = accountInput.readBytes();
final StateTrieAccountValue trieAccount = StateTrieAccountValue.readFrom(new BytesValueRLPInput(accountRlp, false, true));
if (!trieAccount.getCodeHash().equals(Hash.hash(code))) {
throw new RuntimeException("Code hash doesn't match");
}
if (code.size() > 0) {
updateCode(code);
}
final RestoreVisitor<Bytes> accountTrieWriteVisitor = new RestoreVisitor<>(t -> t, accountRlp, accountPersistVisitor);
root = root.accept(accountTrieWriteVisitor, bytesToPath(trieKey));
final PersistVisitor<Bytes> storagePersistVisitor = new PersistVisitor<>(this::updateAccountStorage);
Node<Bytes> storageRoot = storagePersistVisitor.initialRoot();
while (true) {
final byte[] trieEntry = reader.readBytes();
final BytesValueRLPInput trieInput = new BytesValueRLPInput(Bytes.of(trieEntry), false, true);
final int len = trieInput.enterList();
if (len == 0) {
break;
}
if (len != 2) {
throw new RuntimeException("Unexpected storage trie entry length " + len);
}
final Bytes32 storageTrieKey = Bytes32.wrap(trieInput.readBytes());
final Bytes storageTrieValue = Bytes.wrap(trieInput.readBytes());
final RestoreVisitor<Bytes> storageTrieWriteVisitor = new RestoreVisitor<>(t -> t, storageTrieValue, storagePersistVisitor);
storageRoot = storageRoot.accept(storageTrieWriteVisitor, bytesToPath(storageTrieKey));
trieInput.leaveList();
}
storagePersistVisitor.persist(storageRoot);
storageBranchCount += storagePersistVisitor.getBranchNodeCount();
storageExtensionCount += storagePersistVisitor.getExtensionNodeCount();
storageLeafCount += storagePersistVisitor.getLeafNodeCount();
accountInput.leaveList();
}
}
accountPersistVisitor.persist(root);
updater.commit();
LOG.info("Account BranchNodes: {} ", accountPersistVisitor.getBranchNodeCount());
LOG.info("Account ExtensionNodes: {} ", accountPersistVisitor.getExtensionNodeCount());
LOG.info("Account LeafNodes: {} ", accountPersistVisitor.getLeafNodeCount());
LOG.info("Storage BranchNodes: {} ", storageBranchCount);
LOG.info("Storage LeafNodes: {} ", storageExtensionCount);
LOG.info("Storage ExtensionNodes: {} ", storageLeafCount);
LOG.info("Account data loaded");
}
Aggregations