Search in sources :

Example 1 with ByteArrayWrapper

use of org.ethereum.db.ByteArrayWrapper in project rskj by rsksmart.

the class MutableTrieCache method getStorageKeys.

public Iterator<DataWord> getStorageKeys(RskAddress addr) {
    byte[] accountStoragePrefixKey = trieKeyMapper.getAccountStoragePrefixKey(addr);
    ByteArrayWrapper accountWrapper = getAccountWrapper(new ByteArrayWrapper(accountStoragePrefixKey));
    boolean isDeletedAccount = deleteRecursiveLog.contains(accountWrapper);
    Map<ByteArrayWrapper, byte[]> accountItems = cache.get(accountWrapper);
    if (accountItems == null && isDeletedAccount) {
        return Collections.emptyIterator();
    }
    if (isDeletedAccount) {
        // lower level is deleted, return cached items
        return new StorageKeysIterator(Collections.emptyIterator(), accountItems, addr, trieKeyMapper);
    }
    Iterator<DataWord> storageKeys = trie.getStorageKeys(addr);
    if (accountItems == null) {
        // uncached account
        return storageKeys;
    }
    return new StorageKeysIterator(storageKeys, accountItems, addr, trieKeyMapper);
}
Also used : ByteArrayWrapper(org.ethereum.db.ByteArrayWrapper) DataWord(org.ethereum.vm.DataWord)

Example 2 with ByteArrayWrapper

use of org.ethereum.db.ByteArrayWrapper in project rskj by rsksmart.

the class MutableTrieCache method deleteRecursive.

// //////////////////////////////////////////////////////////////////////////////////
// The semantic of implementations is special, and not the same of the MutableTrie
// It is DELETE ON COMMIT, which means that changes are not applies until commit()
// is called, and changes are applied last.
// //////////////////////////////////////////////////////////////////////////////////
@Override
public void deleteRecursive(byte[] key) {
    // Can there be wrongly unhandled interactions interactions between put() and deleteRecurse()
    // In theory, yes. In practice, never.
    // Suppose that a contract X calls a contract S.
    // Contract S calls itself with CALL.
    // Contract S suicides with SUICIDE opcode.
    // This causes a return to prev contract.
    // But the SUICIDE DOES NOT cause the storage keys to be removed YET.
    // Now parent contract S is still running, and it then can create a new storage cell
    // with SSTORE. This will be stored in the cache as a put(). The cache later receives a
    // deleteRecursive, BUT NEVER IN THE OTHER order.
    // See TransactionExecutor.finalization(), when it iterates the list with getDeleteAccounts().forEach()
    ByteArrayWrapper wrap = new ByteArrayWrapper(key);
    deleteRecursiveLog.add(wrap);
    cache.remove(wrap);
}
Also used : ByteArrayWrapper(org.ethereum.db.ByteArrayWrapper)

Example 3 with ByteArrayWrapper

use of org.ethereum.db.ByteArrayWrapper in project rskj by rsksmart.

the class MutableTrieCache method put.

// This method optimizes cache-to-cache transfers
@Override
public void put(ByteArrayWrapper wrapper, byte[] value) {
    // If value==null, do we have the choice to either store it
    // in cache with null or in deleteCache. Here we have the choice to
    // to add it to cache with null value or to deleteCache.
    ByteArrayWrapper accountWrapper = getAccountWrapper(wrapper);
    Map<ByteArrayWrapper, byte[]> accountMap = cache.computeIfAbsent(accountWrapper, k -> new HashMap<>());
    accountMap.put(wrapper, value);
}
Also used : ByteArrayWrapper(org.ethereum.db.ByteArrayWrapper)

Example 4 with ByteArrayWrapper

use of org.ethereum.db.ByteArrayWrapper in project rskj by rsksmart.

the class RLP method encodeSet.

public static byte[] encodeSet(Set<ByteArrayWrapper> data) {
    int dataLength = 0;
    Set<byte[]> encodedElements = new HashSet<>();
    for (ByteArrayWrapper element : data) {
        byte[] encodedElement = RLP.encodeElement(element.getData());
        dataLength += encodedElement.length;
        encodedElements.add(encodedElement);
    }
    byte[] listHeader = encodeListHeader(dataLength);
    byte[] output = new byte[listHeader.length + dataLength];
    System.arraycopy(listHeader, 0, output, 0, listHeader.length);
    int cummStart = listHeader.length;
    for (byte[] element : encodedElements) {
        System.arraycopy(element, 0, output, cummStart, element.length);
        cummStart += element.length;
    }
    return output;
}
Also used : ByteArrayWrapper(org.ethereum.db.ByteArrayWrapper)

Example 5 with ByteArrayWrapper

use of org.ethereum.db.ByteArrayWrapper in project rskj by rsksmart.

the class HashMapDB method updateBatch.

@Override
public synchronized void updateBatch(Map<ByteArrayWrapper, byte[]> rows, Set<ByteArrayWrapper> keysToRemove) {
    if (rows.containsKey(null) || rows.containsValue(null)) {
        throw new IllegalArgumentException("Cannot update null values");
    }
    rows.keySet().removeAll(keysToRemove);
    for (Map.Entry<ByteArrayWrapper, byte[]> entry : rows.entrySet()) {
        ByteArrayWrapper wrappedKey = entry.getKey();
        byte[] key = wrappedKey.getData();
        byte[] value = entry.getValue();
        put(key, value);
    }
    for (ByteArrayWrapper keyToRemove : keysToRemove) {
        delete(keyToRemove.getData());
    }
}
Also used : ByteArrayWrapper(org.ethereum.db.ByteArrayWrapper) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Aggregations

ByteArrayWrapper (org.ethereum.db.ByteArrayWrapper)21 Test (org.junit.Test)5 Metric (co.rsk.metrics.profilers.Metric)2 IOException (java.io.IOException)2 HashMap (java.util.HashMap)2 DataWord (org.ethereum.vm.DataWord)2 File (java.io.File)1 Path (java.nio.file.Path)1 DigestOutputStream (java.security.DigestOutputStream)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 MapSnapshot (org.ethereum.util.MapSnapshot)1