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);
}
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();
}
}
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();
}
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);
}
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();
}
}
Aggregations