Search in sources :

Example 1 with RemoveVisitor

use of org.hyperledger.besu.ethereum.trie.RemoveVisitor 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

Ordering (com.google.common.collect.Ordering)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Map (java.util.Map)1 NavigableMap (java.util.NavigableMap)1 Optional (java.util.Optional)1 SortedMap (java.util.SortedMap)1 TreeMap (java.util.TreeMap)1 Function (java.util.function.Function)1 Bytes (org.apache.tuweni.bytes.Bytes)1 Bytes32 (org.apache.tuweni.bytes.Bytes32)1 UInt256 (org.apache.tuweni.units.bigints.UInt256)1 Address (org.hyperledger.besu.datatypes.Address)1 Hash (org.hyperledger.besu.datatypes.Hash)1 RLP (org.hyperledger.besu.ethereum.rlp.RLP)1 InnerNodeDiscoveryManager (org.hyperledger.besu.ethereum.trie.InnerNodeDiscoveryManager)1 InnerNode (org.hyperledger.besu.ethereum.trie.InnerNodeDiscoveryManager.InnerNode)1 MerklePatriciaTrie (org.hyperledger.besu.ethereum.trie.MerklePatriciaTrie)1 MerkleTrieException (org.hyperledger.besu.ethereum.trie.MerkleTrieException)1 Proof (org.hyperledger.besu.ethereum.trie.Proof)1