Search in sources :

Example 1 with PersistVisitor

use of org.hyperledger.besu.ethereum.trie.PersistVisitor 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");
}
Also used : RollingFileReader(org.hyperledger.besu.util.io.RollingFileReader) StateTrieAccountValue(org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue) Bytes32(org.apache.tuweni.bytes.Bytes32) Bytes(org.apache.tuweni.bytes.Bytes) PersistVisitor(org.hyperledger.besu.ethereum.trie.PersistVisitor) BytesValueRLPInput(org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput) RestoreVisitor(org.hyperledger.besu.ethereum.trie.RestoreVisitor)

Aggregations

Bytes (org.apache.tuweni.bytes.Bytes)1 Bytes32 (org.apache.tuweni.bytes.Bytes32)1 BytesValueRLPInput (org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput)1 PersistVisitor (org.hyperledger.besu.ethereum.trie.PersistVisitor)1 RestoreVisitor (org.hyperledger.besu.ethereum.trie.RestoreVisitor)1 StateTrieAccountValue (org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue)1 RollingFileReader (org.hyperledger.besu.util.io.RollingFileReader)1