Search in sources :

Example 61 with ByteArrayWrapper

use of org.aion.util.types.ByteArrayWrapper in project aion by aionnetwork.

the class ExternalStateForAvm method removeStorage.

@Override
public void removeStorage(AionAddress address, byte[] key) {
    ByteArrayWrapper storageKey = ByteArrayWrapper.wrap(key);
    this.repositoryCache.removeStorageRow(address, storageKey);
    setVmType(address);
}
Also used : ByteArrayWrapper(org.aion.util.types.ByteArrayWrapper)

Example 62 with ByteArrayWrapper

use of org.aion.util.types.ByteArrayWrapper in project aion by aionnetwork.

the class AionRepositoryImpl method updateBatch.

@Override
public void updateBatch(Map<AionAddress, AccountState> stateCache, Map<AionAddress, ContractDetail> detailsCache, Map<AionAddress, TransformedCodeInfoInterface> transformedCodeCache) {
    rwLock.writeLock().lock();
    try {
        for (Map.Entry<AionAddress, AccountState> entry : stateCache.entrySet()) {
            AionAddress address = entry.getKey();
            AccountState accountState = entry.getValue();
            ContractDetails contractDetails = (ContractDetails) detailsCache.get(address);
            if (accountState.isDeleted()) {
                // TODO-A: batch operations here
                try {
                    worldState.delete(address.toByteArray());
                } catch (Exception e) {
                    LOG.error("key deleted exception [{}]", e.toString());
                }
                if (LOG.isDebugEnabled()) {
                    LOG.debug("key deleted <key={}>", Hex.toHexString(address.toByteArray()));
                }
            } else {
                if (!contractDetails.isDirty() || (contractDetails.getVmType() == InternalVmType.EITHER && !ContractInfo.isPrecompiledContract(address))) {
                    // ContractState class
                    if (accountState.isDirty()) {
                        updateAccountState(address, accountState);
                        if (LOG.isTraceEnabled()) {
                            LOG.trace("update: [{}],nonce: [{}] balance: [{}] [{}]", Hex.toHexString(address.toByteArray()), accountState.getNonce(), accountState.getBalance(), Hex.toHexString(contractDetails.getStorageHash()));
                        }
                    }
                    continue;
                }
                InnerContractDetails contractDetailsCache = (InnerContractDetails) contractDetails;
                if (contractDetailsCache.origContract == null) {
                    contractDetailsCache.origContract = detailsDS.newContractDetails(address, contractDetailsCache.getVmType());
                    contractDetailsCache.commit();
                }
                StoredContractDetails parentDetails = (StoredContractDetails) contractDetailsCache.origContract;
                // this method requires the encoding functionality therefore can be applied only to StoredContractDetails
                detailsDS.update(address, parentDetails);
                accountState.setStateRoot(parentDetails.getStorageHash());
                updateAccountState(address, accountState);
                cachedContractIndex.put(address, Pair.of(ByteArrayWrapper.wrap(accountState.getCodeHash()), parentDetails.getVmType()));
                if (LOG.isTraceEnabled()) {
                    LOG.trace("update: [{}],nonce: [{}] balance: [{}] [{}]", Hex.toHexString(address.toByteArray()), accountState.getNonce(), accountState.getBalance(), Hex.toHexString(parentDetails.getStorageHash()));
                }
            }
        }
        for (Map.Entry<AionAddress, TransformedCodeInfoInterface> entry : transformedCodeCache.entrySet()) {
            for (Map.Entry<ByteArrayWrapper, Map<Integer, byte[]>> infoMap : ((TransformedCodeInfo) entry.getValue()).transformedCodeMap.entrySet()) {
                for (Map.Entry<Integer, byte[]> innerEntry : infoMap.getValue().entrySet()) {
                    setTransformedCode(entry.getKey(), infoMap.getKey().toBytes(), innerEntry.getKey(), innerEntry.getValue());
                }
            }
        }
        LOG.trace("updated: detailsCache.size: {}", detailsCache.size());
        stateCache.clear();
        detailsCache.clear();
        transformedCodeCache.clear();
    } finally {
        rwLock.writeLock().unlock();
    }
}
Also used : TransformedCodeInfoInterface(org.aion.base.db.TransformedCodeInfoInterface) AionAddress(org.aion.types.AionAddress) AccountState(org.aion.base.AccountState) IOException(java.io.IOException) BigInteger(java.math.BigInteger) ByteArrayWrapper(org.aion.util.types.ByteArrayWrapper) Map(java.util.Map) HashMap(java.util.HashMap)

Example 63 with ByteArrayWrapper

use of org.aion.util.types.ByteArrayWrapper in project aion by aionnetwork.

the class AionRepositoryImpl method commitCachedVMs.

/**
 * Indexes the contract information.
 */
public void commitCachedVMs(ByteArrayWrapper inceptionBlock) {
    for (Map.Entry<AionAddress, Pair<ByteArrayWrapper, InternalVmType>> entry : cachedContractIndex.entrySet()) {
        AionAddress contract = entry.getKey();
        ByteArrayWrapper codeHash = entry.getValue().getLeft();
        InternalVmType vm = entry.getValue().getRight();
        // write only if not already stored
        ContractInformation ci = getIndexedContractInformation(contract);
        if (ci == null || !ci.getVmUsed(codeHash.toBytes()).isContract()) {
            saveIndexedContractInformation(contract, codeHash, inceptionBlock, vm, true);
        } else {
            if (ci != null && ci.getVmUsed(codeHash.toBytes()) != vm) {
                // possibly same code hash for AVM and FVM
                LOG.error("The stored VM type does not match the cached VM type for the contract {} with code hash {}.", contract, codeHash);
            }
        }
    }
    cachedContractIndex.clear();
}
Also used : InternalVmType(org.aion.base.InternalVmType) AionAddress(org.aion.types.AionAddress) ByteArrayWrapper(org.aion.util.types.ByteArrayWrapper) Map(java.util.Map) HashMap(java.util.HashMap) Pair(org.apache.commons.lang3.tuple.Pair)

Example 64 with ByteArrayWrapper

use of org.aion.util.types.ByteArrayWrapper in project aion by aionnetwork.

the class AionRepositoryImpl method dumpImportableState.

@VisibleForTesting
public byte[] dumpImportableState(byte[] root, int limit, DatabaseType dbType) {
    Map<ByteArrayWrapper, byte[]> refs = getReferencedTrieNodes(root, limit, dbType);
    byte[][] elements = new byte[refs.size()][];
    int i = 0;
    for (ByteArrayWrapper ref : refs.keySet()) {
        elements[i] = RLP.encodeList(RLP.encodeElement(ref.toBytes()), RLP.encodeElement(getTrieNode(ref.toBytes(), dbType)));
        i++;
    }
    return RLP.encodeList(elements);
}
Also used : ByteArrayWrapper(org.aion.util.types.ByteArrayWrapper) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 65 with ByteArrayWrapper

use of org.aion.util.types.ByteArrayWrapper in project aion by aionnetwork.

the class PendingBlockStore method dropPendingQueues.

/**
 * Used to delete imported queues from storage.
 *
 * @param level the block height of the queue starting point
 * @param queues the identifiers for the queues to be deleted
 * @param blocks the queue to blocks mappings to be deleted (used to ensure that if the queues
 *     have been expanded, only the relevant blocks get deleted)
 * @param log the logger used for messages
 */
public void dropPendingQueues(long level, Collection<ByteArrayWrapper> queues, Map<ByteArrayWrapper, List<Block>> blocks, Logger log) {
    databaseLock.writeLock().lock();
    try {
        // delete imported queues & blocks
        for (ByteArrayWrapper q : queues) {
            // delete imported blocks
            for (Block b : blocks.get(q)) {
                // delete index
                indexSource.delete(b.getHash());
            }
            // delete queue
            queueSource.delete(q.toBytes());
        }
        // update level
        byte[] levelKey = ByteUtil.longToBytes(level);
        List<byte[]> levelData = levelSource.get(levelKey);
        if (levelData == null) {
            log.error("Corrupt data in PendingBlockStorage. Level (expected to exist) was not found.");
        // level already missing so nothing to do here
        } else {
            List<byte[]> updatedLevelData = new ArrayList<>();
            for (byte[] qHash : levelData) {
                if (!queues.contains(ByteArrayWrapper.wrap(qHash))) {
                    // this queue was not imported
                    updatedLevelData.add(qHash);
                }
            }
            if (updatedLevelData.isEmpty()) {
                // delete level
                levelSource.delete(levelKey);
            } else {
                // update level
                levelSource.put(levelKey, updatedLevelData);
            }
        }
        // push changed to disk
        indexSource.commit();
        queueSource.commit();
        levelSource.commit();
        // log operation
        log.debug("Dropped from storage level = {} with queues = {}.", level, Arrays.toString(queues.toArray()));
    } catch (Exception e) {
        log.error("Unable to delete used blocks due to: ", e);
    } finally {
        databaseLock.writeLock().unlock();
    }
}
Also used : ByteArrayWrapper(org.aion.util.types.ByteArrayWrapper) ArrayList(java.util.ArrayList) Block(org.aion.zero.impl.types.Block) IOException(java.io.IOException)

Aggregations

ByteArrayWrapper (org.aion.util.types.ByteArrayWrapper)130 Test (org.junit.Test)51 HashMap (java.util.HashMap)39 ArrayList (java.util.ArrayList)33 AionAddress (org.aion.types.AionAddress)26 Block (org.aion.zero.impl.types.Block)24 Map (java.util.Map)20 BigInteger (java.math.BigInteger)14 MiningBlock (org.aion.zero.impl.types.MiningBlock)14 IOException (java.io.IOException)13 MockDB (org.aion.db.impl.mockdb.MockDB)13 DataWord (org.aion.util.types.DataWord)13 PooledTransaction (org.aion.base.PooledTransaction)11 List (java.util.List)10 AionTransaction (org.aion.base.AionTransaction)10 Properties (java.util.Properties)8 HashSet (java.util.HashSet)5 Optional (java.util.Optional)5 ECKey (org.aion.crypto.ECKey)5 RLPElement (org.aion.rlp.RLPElement)5