Search in sources :

Example 1 with InnerNodeDiscoveryManager

use of org.hyperledger.besu.ethereum.trie.InnerNodeDiscoveryManager in project besu by hyperledger.

the class StackTrie method commit.

public void commit(final NodeUpdater nodeUpdater) {
    if (nbSegments.decrementAndGet() <= 0 && !elements.isEmpty()) {
        final List<Bytes> proofs = new ArrayList<>();
        final TreeMap<Bytes32, Bytes> keys = new TreeMap<>();
        elements.values().forEach(taskElement -> {
            proofs.addAll(taskElement.proofs());
            keys.putAll(taskElement.keys());
        });
        final Map<Bytes32, Bytes> proofsEntries = new HashMap<>();
        for (Bytes proof : proofs) {
            proofsEntries.put(Hash.hash(proof), proof);
        }
        final InnerNodeDiscoveryManager<Bytes> snapStoredNodeFactory = new InnerNodeDiscoveryManager<>((location, hash) -> Optional.ofNullable(proofsEntries.get(hash)), Function.identity(), Function.identity(), startKeyHash, keys.lastKey(), true);
        final MerklePatriciaTrie<Bytes, Bytes> trie = new StoredMerklePatriciaTrie<>(snapStoredNodeFactory, proofs.isEmpty() ? MerklePatriciaTrie.EMPTY_TRIE_NODE_HASH : rootHash);
        for (Map.Entry<Bytes32, Bytes> account : keys.entrySet()) {
            trie.put(account.getKey(), new SnapPutVisitor<>(snapStoredNodeFactory, account.getValue()));
        }
        trie.commit(nodeUpdater, (new CommitVisitor<>(nodeUpdater) {

            @Override
            public void maybeStoreNode(final Bytes location, final Node<Bytes> node) {
                if (!node.isHealNeeded()) {
                    super.maybeStoreNode(location, node);
                }
            }
        }));
    }
}
Also used : StoredMerklePatriciaTrie(org.hyperledger.besu.ethereum.trie.StoredMerklePatriciaTrie) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) InnerNodeDiscoveryManager(org.hyperledger.besu.ethereum.trie.InnerNodeDiscoveryManager) Node(org.hyperledger.besu.ethereum.trie.Node) ArrayList(java.util.ArrayList) TreeMap(java.util.TreeMap) CommitVisitor(org.hyperledger.besu.ethereum.trie.CommitVisitor) Bytes32(org.apache.tuweni.bytes.Bytes32) Bytes(org.apache.tuweni.bytes.Bytes) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) TreeMap(java.util.TreeMap) Map(java.util.Map)

Example 2 with InnerNodeDiscoveryManager

use of org.hyperledger.besu.ethereum.trie.InnerNodeDiscoveryManager in project besu by hyperledger.

the class RangeManager method findNewBeginElementInRange.

/**
 * Helps to create a new range according to the last data obtained. This happens when a peer
 * doesn't return all of the data in a range.
 *
 * @param worldstateRootHash the root hash
 * @param proofs proof received
 * @param endKeyHash the end of the range initially wanted
 * @param receivedKeys the last key received
 * @return begin of the new range
 */
public static Optional<Bytes32> findNewBeginElementInRange(final Bytes32 worldstateRootHash, final List<Bytes> proofs, final TreeMap<Bytes32, Bytes> receivedKeys, final Bytes32 endKeyHash) {
    if (receivedKeys.isEmpty() || receivedKeys.lastKey().compareTo(endKeyHash) >= 0) {
        return Optional.empty();
    } else {
        final Map<Bytes32, Bytes> proofsEntries = new HashMap<>();
        for (Bytes proof : proofs) {
            proofsEntries.put(Hash.hash(proof), proof);
        }
        final StoredMerklePatriciaTrie<Bytes, Bytes> storageTrie = new StoredMerklePatriciaTrie<>(new InnerNodeDiscoveryManager<>((location, key) -> Optional.ofNullable(proofsEntries.get(key)), Function.identity(), Function.identity(), receivedKeys.lastKey(), endKeyHash, false), worldstateRootHash);
        try {
            storageTrie.visitAll(bytesNode -> {
            });
        } catch (MerkleTrieException e) {
            return Optional.of(InnerNodeDiscoveryManager.decodePath(e.getLocation()));
        }
        return Optional.empty();
    }
}
Also used : StoredMerklePatriciaTrie(org.hyperledger.besu.ethereum.trie.StoredMerklePatriciaTrie) InnerNodeDiscoveryManager(org.hyperledger.besu.ethereum.trie.InnerNodeDiscoveryManager) HashMap(java.util.HashMap) Bytes(org.apache.tuweni.bytes.Bytes) Function(java.util.function.Function) List(java.util.List) MerkleTrieException(org.hyperledger.besu.ethereum.trie.MerkleTrieException) TreeMap(java.util.TreeMap) Map(java.util.Map) Optional(java.util.Optional) BigInteger(java.math.BigInteger) Bytes32(org.apache.tuweni.bytes.Bytes32) Hash(org.hyperledger.besu.datatypes.Hash) Bytes(org.apache.tuweni.bytes.Bytes) StoredMerklePatriciaTrie(org.hyperledger.besu.ethereum.trie.StoredMerklePatriciaTrie) HashMap(java.util.HashMap) MerkleTrieException(org.hyperledger.besu.ethereum.trie.MerkleTrieException) Bytes32(org.apache.tuweni.bytes.Bytes32)

Example 3 with InnerNodeDiscoveryManager

use of org.hyperledger.besu.ethereum.trie.InnerNodeDiscoveryManager in project besu by hyperledger.

the class WorldStateProofProvider method isValidRangeProof.

public boolean isValidRangeProof(final Bytes32 startKeyHash, final Bytes32 endKeyHash, final Bytes32 rootHash, final List<Bytes> proofs, final TreeMap<Bytes32, Bytes> keys) {
    // check if it's monotonic increasing
    if (!Ordering.natural().isOrdered(keys.keySet())) {
        return false;
    }
    // when proof is empty we need to have all the keys to reconstruct the trie
    if (proofs.isEmpty()) {
        final MerklePatriciaTrie<Bytes, Bytes> trie = new SimpleMerklePatriciaTrie<>(Function.identity());
        // add the received keys in the trie
        for (Map.Entry<Bytes32, Bytes> key : keys.entrySet()) {
            trie.put(key.getKey(), key.getValue());
        }
        return rootHash.equals(trie.getRootHash());
    }
    // reconstruct a part of the trie with the proof
    final Map<Bytes32, Bytes> proofsEntries = new HashMap<>();
    for (Bytes proof : proofs) {
        proofsEntries.put(Hash.hash(proof), proof);
    }
    if (keys.isEmpty()) {
        final MerklePatriciaTrie<Bytes, Bytes> trie = new StoredMerklePatriciaTrie<>(new InnerNodeDiscoveryManager<>((location, hash) -> Optional.ofNullable(proofsEntries.get(hash)), Function.identity(), Function.identity(), startKeyHash, endKeyHash, false), rootHash);
        try {
            // check if there is not missing element
            // a missing node will throw an exception while it is loading
            // @see org.hyperledger.besu.ethereum.trie.StoredNode#load()
            trie.entriesFrom(startKeyHash, Integer.MAX_VALUE);
        } catch (MerkleTrieException e) {
            return false;
        }
        return true;
    }
    // search inner nodes in the range created by the proofs and remove
    final InnerNodeDiscoveryManager<Bytes> snapStoredNodeFactory = new InnerNodeDiscoveryManager<>((location, hash) -> Optional.ofNullable(proofsEntries.get(hash)), Function.identity(), Function.identity(), startKeyHash, keys.lastKey(), true);
    final MerklePatriciaTrie<Bytes, Bytes> trie = new StoredMerklePatriciaTrie<>(snapStoredNodeFactory, rootHash);
    // filling out innerNodes of the InnerNodeDiscoveryManager by walking through the trie
    trie.visitAll(node -> {
    });
    final List<InnerNode> innerNodes = snapStoredNodeFactory.getInnerNodes();
    for (InnerNode innerNode : innerNodes) {
        trie.removePath(Bytes.concatenate(innerNode.location(), innerNode.path()), new RemoveVisitor<>(false));
    }
    // add the received keys in the trie to reconstruct the trie
    for (Map.Entry<Bytes32, Bytes> account : keys.entrySet()) {
        trie.put(account.getKey(), account.getValue());
    }
    // check if the generated root hash is valid
    return rootHash.equals(trie.getRootHash());
}
Also used : StoredMerklePatriciaTrie(org.hyperledger.besu.ethereum.trie.StoredMerklePatriciaTrie) HashMap(java.util.HashMap) Bytes(org.apache.tuweni.bytes.Bytes) Address(org.hyperledger.besu.datatypes.Address) Function(java.util.function.Function) InnerNode(org.hyperledger.besu.ethereum.trie.InnerNodeDiscoveryManager.InnerNode) Map(java.util.Map) SimpleMerklePatriciaTrie(org.hyperledger.besu.ethereum.trie.SimpleMerklePatriciaTrie) WorldStateStorage(org.hyperledger.besu.ethereum.worldstate.WorldStateStorage) UInt256(org.apache.tuweni.units.bigints.UInt256) Bytes32(org.apache.tuweni.bytes.Bytes32) Proof(org.hyperledger.besu.ethereum.trie.Proof) InnerNodeDiscoveryManager(org.hyperledger.besu.ethereum.trie.InnerNodeDiscoveryManager) RLP(org.hyperledger.besu.ethereum.rlp.RLP) RemoveVisitor(org.hyperledger.besu.ethereum.trie.RemoveVisitor) MerklePatriciaTrie(org.hyperledger.besu.ethereum.trie.MerklePatriciaTrie) NavigableMap(java.util.NavigableMap) List(java.util.List) MerkleTrieException(org.hyperledger.besu.ethereum.trie.MerkleTrieException) StateTrieAccountValue(org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue) TreeMap(java.util.TreeMap) Ordering(com.google.common.collect.Ordering) Optional(java.util.Optional) SortedMap(java.util.SortedMap) Hash(org.hyperledger.besu.datatypes.Hash) StoredMerklePatriciaTrie(org.hyperledger.besu.ethereum.trie.StoredMerklePatriciaTrie) HashMap(java.util.HashMap) InnerNodeDiscoveryManager(org.hyperledger.besu.ethereum.trie.InnerNodeDiscoveryManager) Bytes32(org.apache.tuweni.bytes.Bytes32) InnerNode(org.hyperledger.besu.ethereum.trie.InnerNodeDiscoveryManager.InnerNode) Bytes(org.apache.tuweni.bytes.Bytes) SimpleMerklePatriciaTrie(org.hyperledger.besu.ethereum.trie.SimpleMerklePatriciaTrie) MerkleTrieException(org.hyperledger.besu.ethereum.trie.MerkleTrieException) HashMap(java.util.HashMap) Map(java.util.Map) NavigableMap(java.util.NavigableMap) TreeMap(java.util.TreeMap) SortedMap(java.util.SortedMap)

Aggregations

HashMap (java.util.HashMap)3 Map (java.util.Map)3 TreeMap (java.util.TreeMap)3 Bytes (org.apache.tuweni.bytes.Bytes)3 Bytes32 (org.apache.tuweni.bytes.Bytes32)3 InnerNodeDiscoveryManager (org.hyperledger.besu.ethereum.trie.InnerNodeDiscoveryManager)3 StoredMerklePatriciaTrie (org.hyperledger.besu.ethereum.trie.StoredMerklePatriciaTrie)3 List (java.util.List)2 Optional (java.util.Optional)2 Function (java.util.function.Function)2 Hash (org.hyperledger.besu.datatypes.Hash)2 MerkleTrieException (org.hyperledger.besu.ethereum.trie.MerkleTrieException)2 Ordering (com.google.common.collect.Ordering)1 BigInteger (java.math.BigInteger)1 ArrayList (java.util.ArrayList)1 LinkedHashMap (java.util.LinkedHashMap)1 NavigableMap (java.util.NavigableMap)1 SortedMap (java.util.SortedMap)1 UInt256 (org.apache.tuweni.units.bigints.UInt256)1 Address (org.hyperledger.besu.datatypes.Address)1