Search in sources :

Example 1 with ContractDetailsCacheImpl

use of org.aion.mcf.db.ContractDetailsCacheImpl in project aion by aionnetwork.

the class AionRepositoryImpl method updateBatch.

@Override
public synchronized void updateBatch(Map<Address, AccountState> stateCache, Map<Address, IContractDetails<DataWord>> detailsCache) {
    for (Map.Entry<Address, AccountState> entry : stateCache.entrySet()) {
        Address address = entry.getKey();
        AccountState accountState = entry.getValue();
        IContractDetails<DataWord> contractDetails = detailsCache.get(address);
        if (accountState.isDeleted()) {
            // TODO-A: batch operations here
            rwLock.readLock().lock();
            try {
                worldState.delete(address.toBytes());
            } catch (Exception e) {
                LOG.error("key deleted exception [{}]", e.toString());
            } finally {
                rwLock.readLock().unlock();
            }
            LOG.debug("key deleted <key={}>", Hex.toHexString(address.toBytes()));
        } else {
            if (!contractDetails.isDirty()) {
                // ContractState class
                if (accountState.isDirty()) {
                    updateAccountState(address, accountState);
                    if (LOG.isTraceEnabled()) {
                        LOG.trace("update: [{}],nonce: [{}] balance: [{}] [{}]", Hex.toHexString(address.toBytes()), accountState.getNonce(), accountState.getBalance(), contractDetails.getStorage());
                    }
                }
                continue;
            }
            ContractDetailsCacheImpl contractDetailsCache = (ContractDetailsCacheImpl) contractDetails;
            if (contractDetailsCache.origContract == null) {
                contractDetailsCache.origContract = this.cfg.contractDetailsImpl();
                try {
                    contractDetailsCache.origContract.setAddress(address);
                } catch (Exception e) {
                    e.printStackTrace();
                    LOG.error("contractDetailsCache setAddress exception [{}]", e.toString());
                }
                contractDetailsCache.commit();
            }
            contractDetails = contractDetailsCache.origContract;
            updateContractDetails(address, contractDetails);
            if (!Arrays.equals(accountState.getCodeHash(), EMPTY_TRIE_HASH)) {
                accountState.setStateRoot(contractDetails.getStorageHash());
            }
            updateAccountState(address, accountState);
            if (LOG.isTraceEnabled()) {
                LOG.trace("update: [{}],nonce: [{}] balance: [{}] [{}]", Hex.toHexString(address.toBytes()), accountState.getNonce(), accountState.getBalance(), contractDetails.getStorage());
            }
        }
    }
    LOG.trace("updated: detailsCache.size: {}", detailsCache.size());
    stateCache.clear();
    detailsCache.clear();
}
Also used : Address(org.aion.base.type.Address) ContractDetailsCacheImpl(org.aion.mcf.db.ContractDetailsCacheImpl) DataWord(org.aion.mcf.vm.types.DataWord) AccountState(org.aion.mcf.core.AccountState)

Example 2 with ContractDetailsCacheImpl

use of org.aion.mcf.db.ContractDetailsCacheImpl in project aion by aionnetwork.

the class AionRepositoryImpl method loadAccountState.

/**
 * @implNote The loaded objects are fresh copies of the original account
 *           state and contract details.
 */
@Override
public synchronized void loadAccountState(Address address, Map<Address, AccountState> cacheAccounts, Map<Address, IContractDetails<DataWord>> cacheDetails) {
    AccountState account = getAccountState(address);
    IContractDetails<DataWord> details = getContractDetails(address);
    account = (account == null) ? new AccountState() : new AccountState(account);
    details = new ContractDetailsCacheImpl(details);
    // details.setAddress(addr);
    cacheAccounts.put(address, account);
    cacheDetails.put(address, details);
}
Also used : ContractDetailsCacheImpl(org.aion.mcf.db.ContractDetailsCacheImpl) DataWord(org.aion.mcf.vm.types.DataWord) AccountState(org.aion.mcf.core.AccountState)

Example 3 with ContractDetailsCacheImpl

use of org.aion.mcf.db.ContractDetailsCacheImpl in project aion by aionnetwork.

the class AionRepositoryCache method flush.

/**
 * @implNote To maintain intended functionality this method does not call
 *           the parent's {@code flush()} method. The changes are propagated
 *           to the parent through calling the parent's
 *           {@code updateBatch()} method.
 */
@Override
public synchronized void flush() {
    // determine which accounts should get stored
    HashMap<Address, AccountState> cleanedCacheAccounts = new HashMap<>();
    for (Map.Entry<Address, AccountState> entry : cachedAccounts.entrySet()) {
        AccountState account = entry.getValue();
        if (account != null && account.isDirty() && account.isEmpty()) {
            // ignore contract state for empty accounts at storage
            cachedDetails.remove(entry.getKey());
        } else {
            cleanedCacheAccounts.put(entry.getKey(), entry.getValue());
        }
    }
    // determine which contracts should get stored
    for (Map.Entry<Address, IContractDetails<DataWord>> entry : cachedDetails.entrySet()) {
        IContractDetails<DataWord> ctd = entry.getValue();
        // different ContractDetails implementation
        if (ctd != null && ctd instanceof ContractDetailsCacheImpl) {
            ContractDetailsCacheImpl contractDetailsCache = (ContractDetailsCacheImpl) ctd;
            contractDetailsCache.commit();
            if (contractDetailsCache.origContract == null && repository.hasContractDetails(entry.getKey())) {
                // in forked block the contract account might not exist thus
                // it is created without
                // origin, but on the main chain details can contain data
                // which should be merged
                // into a single storage trie so both branches with
                // different stateRoots are valid
                contractDetailsCache.origContract = repository.getContractDetails(entry.getKey());
                contractDetailsCache.commit();
            }
        }
    }
    repository.updateBatch(cleanedCacheAccounts, cachedDetails);
    cachedAccounts.clear();
    cachedDetails.clear();
}
Also used : IContractDetails(org.aion.base.db.IContractDetails) Address(org.aion.base.type.Address) HashMap(java.util.HashMap) ContractDetailsCacheImpl(org.aion.mcf.db.ContractDetailsCacheImpl) DataWord(org.aion.mcf.vm.types.DataWord) AccountState(org.aion.mcf.core.AccountState) Map(java.util.Map) HashMap(java.util.HashMap)

Aggregations

AccountState (org.aion.mcf.core.AccountState)3 ContractDetailsCacheImpl (org.aion.mcf.db.ContractDetailsCacheImpl)3 DataWord (org.aion.mcf.vm.types.DataWord)3 Address (org.aion.base.type.Address)2 HashMap (java.util.HashMap)1 Map (java.util.Map)1 IContractDetails (org.aion.base.db.IContractDetails)1