Search in sources :

Example 56 with Address

use of org.aion.base.type.Address in project aion by aionnetwork.

the class AionRepositoryImplTest method testAccountStateUpdate.

@Test
public void testAccountStateUpdate() {
    AionRepositoryImpl repository = AionRepositoryImpl.createForTesting(repoConfig);
    byte[] originalRoot = repository.getRoot();
    Address defaultAccount = Address.wrap(ByteUtil.hexStringToBytes("CAF3CAF3CAF3CAF3CAF3CAF3CAF3CAF3CAF3CAF3CAF3CAF3CAF3CAF3CAF3CAF3"));
    IRepositoryCache track = repository.startTracking();
    track.addBalance(defaultAccount, BigInteger.valueOf(1));
    track.flush();
    byte[] newRoot = repository.getRoot();
    System.out.println(String.format("original root: %s", ByteUtil.toHexString(originalRoot)));
    System.out.println(String.format("new root: %s", ByteUtil.toHexString(newRoot)));
    assertThat(newRoot).isNotEqualTo(originalRoot);
}
Also used : Address(org.aion.base.type.Address) IRepositoryCache(org.aion.base.db.IRepositoryCache) AionRepositoryImpl(org.aion.zero.impl.db.AionRepositoryImpl) Test(org.junit.Test)

Example 57 with Address

use of org.aion.base.type.Address in project aion by aionnetwork.

the class ApiAion method sendTransaction.

public byte[] sendTransaction(ArgTxCall _params) {
    Address from = _params.getFrom();
    if (from == null || from.equals(Address.EMPTY_ADDRESS())) {
        LOG.error("<send-transaction msg=invalid-from-address>");
        return null;
    }
    ECKey key = this.getAccountKey(from.toString());
    if (key == null) {
        LOG.error("<send-transaction msg=account-not-found>");
        return null;
    }
    try {
        synchronized (pendingState) {
            // TODO : temp set nrg & price to 1
            byte[] nonce = (!_params.getNonce().equals(BigInteger.ZERO)) ? _params.getNonce().toByteArray() : pendingState.bestNonce(Address.wrap(key.getAddress())).toByteArray();
            AionTransaction tx = new AionTransaction(nonce, _params.getTo(), _params.getValue().toByteArray(), _params.getData(), _params.getNrg(), _params.getNrgPrice());
            tx.sign(key);
            pendingState.addPendingTransaction(tx);
            return tx.getHash();
        }
    } catch (Exception ex) {
        return null;
    }
}
Also used : Address(org.aion.base.type.Address) ECKey(org.aion.crypto.ECKey) AionTransaction(org.aion.zero.types.AionTransaction)

Example 58 with Address

use of org.aion.base.type.Address in project aion by aionnetwork.

the class AionBlockchainImpl method isValid.

/**
 * This mechanism enforces a homeostasis in terms of the time between
 * blocks; a smaller period between the last two blocks results in an
 * increase in the difficulty level and thus additional computation
 * required, lengthening the likely next period. Conversely, if the period
 * is too large, the difficulty, and expected time to the next block, is
 * reduced.
 */
private boolean isValid(AionBlock block) {
    if (block == null) {
        return false;
    }
    boolean isValid = true;
    if (!block.isGenesis()) {
        isValid = isValid(block.getHeader());
        // Sanity checks
        String trieHash = Hex.toHexString(block.getTxTrieRoot());
        String trieListHash = Hex.toHexString(calcTxTrie(block.getTransactionsList()));
        if (!trieHash.equals(trieListHash)) {
            LOG.warn("Block's given Trie Hash doesn't match: {} != {}", trieHash, trieListHash);
            return false;
        }
        List<AionTransaction> txs = block.getTransactionsList();
        if (txs != null && !txs.isEmpty()) {
            IRepository parentRepo = repository;
            if (!Arrays.equals(getBlockStore().getBestBlock().getHash(), block.getParentHash())) {
                parentRepo = repository.getSnapshotTo(getBlockByHash(block.getParentHash()).getStateRoot());
            }
            Map<Address, BigInteger> nonceCache = new HashMap<>();
            if (txs.parallelStream().anyMatch(tx -> !TXValidator.isValid(tx))) {
                LOG.error("Some transactions in the block are invalid");
                return false;
            }
            for (AionTransaction tx : txs) {
                Address txSender = tx.getFrom();
                BigInteger expectedNonce = nonceCache.get(txSender);
                if (expectedNonce == null) {
                    expectedNonce = parentRepo.getNonce(txSender);
                }
                BigInteger txNonce = new BigInteger(1, tx.getNonce());
                if (!expectedNonce.equals(txNonce)) {
                    LOG.warn("Invalid transaction: Tx nonce {} != expected nonce {} (parent nonce: {}): {}", txNonce.toString(), expectedNonce.toString(), parentRepo.getNonce(txSender), tx);
                    return false;
                }
                // update cache
                nonceCache.put(txSender, expectedNonce.add(BigInteger.ONE));
            }
        }
    }
    return isValid;
}
Also used : Address(org.aion.base.type.Address) BigInteger(java.math.BigInteger) IRepository(org.aion.base.db.IRepository)

Example 59 with Address

use of org.aion.base.type.Address in project aion by aionnetwork.

the class PendingTxCache method flush.

public List<AionTransaction> flush(Map<Address, BigInteger> nonceMap) {
    if (nonceMap == null) {
        throw new NullPointerException();
    }
    List<AionTransaction> processableTx = new ArrayList<>();
    for (Address addr : nonceMap.keySet()) {
        BigInteger bn = nonceMap.get(addr);
        if (LOG.isDebugEnabled()) {
            LOG.debug("cacheTx.flush addr[{}] bn[{}] size[{}], cache_size[{}]", addr.toString(), bn.toString(), cacheTxMap.get(addr).size(), currentSize.get());
        }
        if (cacheTxMap.get(addr) != null) {
            currentSize.addAndGet(-getAccountSize(cacheTxMap.get(addr)));
            cacheTxMap.get(addr).headMap(bn).clear();
            currentSize.addAndGet(getAccountSize(cacheTxMap.get(addr)));
            if (LOG.isDebugEnabled()) {
                LOG.debug("cacheTx.flush after addr[{}] size[{}], cache_size[{}]", addr.toString(), cacheTxMap.get(addr).size(), currentSize.get());
            }
            if (cacheTxMap.get(addr).get(bn) != null) {
                processableTx.add(cacheTxMap.get(addr).get(bn));
            }
        }
    }
    return processableTx;
}
Also used : Address(org.aion.base.type.Address) BigInteger(java.math.BigInteger) AionTransaction(org.aion.zero.types.AionTransaction)

Example 60 with Address

use of org.aion.base.type.Address 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

Address (org.aion.base.type.Address)61 Test (org.junit.Test)34 BigInteger (java.math.BigInteger)29 AionTransaction (org.aion.zero.types.AionTransaction)23 ITransaction (org.aion.base.type.ITransaction)14 ECKey (org.aion.crypto.ECKey)13 DataWord (org.aion.mcf.vm.types.DataWord)11 AionRepositoryImpl (org.aion.zero.impl.db.AionRepositoryImpl)10 TxPoolA0 (org.aion.txpool.zero.TxPoolA0)9 IRepositoryCache (org.aion.base.db.IRepositoryCache)8 HashMap (java.util.HashMap)6 ByteArrayWrapper (org.aion.base.util.ByteArrayWrapper)5 ByteUtil.toHexString (org.aion.base.util.ByteUtil.toHexString)5 AccountState (org.aion.mcf.core.AccountState)5 AionBlock (org.aion.zero.impl.types.AionBlock)5 ArrayList (java.util.ArrayList)4 ImportResult (org.aion.mcf.core.ImportResult)4 IByteArrayKeyValueDatabase (org.aion.base.db.IByteArrayKeyValueDatabase)3 IRepository (org.aion.base.db.IRepository)3 AionContractDetailsImpl (org.aion.zero.db.AionContractDetailsImpl)3