Search in sources :

Example 6 with Block

use of org.aion.zero.impl.types.Block in project aion by aionnetwork.

the class BlockPropagationHandler method processIncomingBlock.

public PropStatus processIncomingBlock(final int nodeId, final String displayId, final Block block) {
    if (block == null)
        return PropStatus.DROPPED;
    ByteArrayWrapper hashWrapped = block.getHashWrapper();
    if (!this.blockHeaderValidator.validate(block.getHeader(), log))
        return PropStatus.DROPPED;
    // guarantees if multiple requests of same block appears, only one goes through
    synchronized (this.cacheMap) {
        if (this.cacheMap.get(hashWrapped) != null) {
            if (log.isTraceEnabled()) {
                log.trace("block {} already cached", block.getShortHash());
            }
            return PropStatus.DROPPED;
        }
        // regardless if block processing is successful, place into cache
        this.cacheMap.put(hashWrapped, true);
    }
    // process
    long t1 = System.currentTimeMillis();
    ImportResult result;
    if (this.blockchain.skipTryToConnect(block.getNumber())) {
        result = ImportResult.NO_PARENT;
        if (log.isInfoEnabled()) {
            log.info("<import-status: node = {}, hash = {}, number = {}, txs = {}, result = NOT_IN_RANGE>", displayId, block.getShortHash(), block.getNumber(), block.getTransactionsList().size(), result);
        } else if (log.isDebugEnabled()) {
            log.debug("<import-status: node = {}, hash = {}, number = {}, txs = {}, block time = {}, result = NOT_IN_RANGE>", displayId, block.getShortHash(), block.getNumber(), block.getTransactionsList().size(), block.getTimestamp(), result);
        }
    } else {
        result = this.blockchain.tryToConnect(new BlockWrapper(block));
        long t2 = System.currentTimeMillis();
        if (result.isStored()) {
            this.syncStats.updatePeerBlocks(displayId, 1, BlockType.IMPORTED);
        }
        if (log.isInfoEnabled()) {
            log.info("<import-status: node = {}, hash = {}, number = {}, txs = {}, result = {}, time elapsed = {} ms>", displayId, block.getShortHash(), block.getNumber(), block.getTransactionsList().size(), result, t2 - t1);
        } else if (log.isDebugEnabled()) {
            log.debug("<import-status: node = {}, hash = {}, number = {}, td = {}, txs = {}, block time = {}, result = {}, time elapsed = {} ms>", displayId, block.getShortHash(), block.getNumber(), blockchain.getTotalDifficulty(), block.getTransactionsList().size(), block.getTimestamp(), result, t2 - t1);
        }
    }
    // send
    boolean sent = result.isBest() && send(block, nodeId);
    // notify higher td peers in order to limit the rebroadcast on delay of res status updating
    if (result.isBest()) {
        Block bestBlock = blockchain.getBestBlock();
        BigInteger td = bestBlock.getTotalDifficulty();
        ResStatus rs = new ResStatus(bestBlock.getNumber(), td.toByteArray(), bestBlock.getHash(), genesis, apiVersion, (short) p2pManager.getActiveNodes().size(), BigInteger.valueOf(this.pendingState.getPendingTxSize()).toByteArray(), p2pManager.getAvgLatency());
        this.p2pManager.getActiveNodes().values().stream().filter(n -> n.getIdHash() != nodeId).filter(n -> n.getTotalDifficulty().compareTo(td) >= 0).forEach(n -> {
            log.debug("<push-status blk={} hash={} to-node={} dd={} import-result={}>", block.getNumber(), block.getShortHash(), n.getIdShort(), td.longValue() - n.getTotalDifficulty().longValue(), result.name());
            this.p2pManager.send(n.getIdHash(), n.getIdShort(), rs);
        });
    }
    // process resulting state
    if (sent && result.isSuccessful())
        return PropStatus.PROP_CONNECTED;
    if (result.isSuccessful())
        return PropStatus.CONNECTED;
    if (sent)
        return PropStatus.PROPAGATED;
    // gets dropped when the result is not valid
    return PropStatus.DROPPED;
}
Also used : BlockWrapper(org.aion.zero.impl.blockchain.BlockWrapper) AionLoggerFactory(org.aion.log.AionLoggerFactory) IP2pMgr(org.aion.p2p.IP2pMgr) BlockHeaderValidator(org.aion.zero.impl.valid.BlockHeaderValidator) Logger(org.slf4j.Logger) BlockWrapper(org.aion.zero.impl.blockchain.BlockWrapper) IAionBlockchain(org.aion.zero.impl.blockchain.IAionBlockchain) ImportResult(org.aion.zero.impl.core.ImportResult) BroadcastNewBlock(org.aion.zero.impl.sync.msg.BroadcastNewBlock) BlockType(org.aion.zero.impl.sync.statistics.BlockType) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) LRUMap(org.apache.commons.collections4.map.LRUMap) AionPendingStateImpl(org.aion.zero.impl.pendingState.AionPendingStateImpl) ByteArrayWrapper(org.aion.util.types.ByteArrayWrapper) LogEnum(org.aion.log.LogEnum) SyncStats(org.aion.zero.impl.sync.SyncStats) Map(java.util.Map) ResStatus(org.aion.zero.impl.sync.msg.ResStatus) BigInteger(java.math.BigInteger) Block(org.aion.zero.impl.types.Block) CfgAion(org.aion.zero.impl.config.CfgAion) ImportResult(org.aion.zero.impl.core.ImportResult) ResStatus(org.aion.zero.impl.sync.msg.ResStatus) ByteArrayWrapper(org.aion.util.types.ByteArrayWrapper) BroadcastNewBlock(org.aion.zero.impl.sync.msg.BroadcastNewBlock) Block(org.aion.zero.impl.types.Block) BigInteger(java.math.BigInteger)

Example 7 with Block

use of org.aion.zero.impl.types.Block in project aion by aionnetwork.

the class BlockPropagationHandler method send.

private boolean send(Block block, int nodeId) {
    if (isSyncOnlyNode)
        return true;
    // current proposal is to send to all peers with lower blockNumbers
    AtomicBoolean sent = new AtomicBoolean();
    this.p2pManager.getActiveNodes().values().stream().filter(n -> n.getIdHash() != nodeId).filter(n -> {
        long delta = block.getNumber() - n.getBestBlockNumber();
        return (delta >= 0 && delta <= 100) || (n.getBestBlockNumber() == 0);
    }).forEach(n -> {
        if (log.isDebugEnabled())
            log.debug("<sending-new-block hash=" + block.getShortHash() + " to-node=" + n.getIdShort() + ">");
        this.p2pManager.send(n.getIdHash(), n.getIdShort(), new BroadcastNewBlock(block));
        sent.getAndSet(true);
    });
    return sent.get();
}
Also used : AionLoggerFactory(org.aion.log.AionLoggerFactory) IP2pMgr(org.aion.p2p.IP2pMgr) BlockHeaderValidator(org.aion.zero.impl.valid.BlockHeaderValidator) Logger(org.slf4j.Logger) BlockWrapper(org.aion.zero.impl.blockchain.BlockWrapper) IAionBlockchain(org.aion.zero.impl.blockchain.IAionBlockchain) ImportResult(org.aion.zero.impl.core.ImportResult) BroadcastNewBlock(org.aion.zero.impl.sync.msg.BroadcastNewBlock) BlockType(org.aion.zero.impl.sync.statistics.BlockType) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) LRUMap(org.apache.commons.collections4.map.LRUMap) AionPendingStateImpl(org.aion.zero.impl.pendingState.AionPendingStateImpl) ByteArrayWrapper(org.aion.util.types.ByteArrayWrapper) LogEnum(org.aion.log.LogEnum) SyncStats(org.aion.zero.impl.sync.SyncStats) Map(java.util.Map) ResStatus(org.aion.zero.impl.sync.msg.ResStatus) BigInteger(java.math.BigInteger) Block(org.aion.zero.impl.types.Block) CfgAion(org.aion.zero.impl.config.CfgAion) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) BroadcastNewBlock(org.aion.zero.impl.sync.msg.BroadcastNewBlock)

Example 8 with Block

use of org.aion.zero.impl.types.Block in project aion by aionnetwork.

the class SyncMgr method requestBodies.

/**
 * Requests the bodies associated to the given block headers.
 */
void requestBodies(int nodeId, String displayId) {
    Thread.currentThread().setName("sync-gb-" + Thread.currentThread().getId());
    long startTime = System.nanoTime();
    List<List<BlockHeader>> forRequests = syncHeaderRequestManager.getHeadersForBodiesRequests(nodeId);
    for (List<BlockHeader> requestHeaders : forRequests) {
        // Filter headers again in case the blockchain has advanced while this task was waiting to be executed.
        List<BlockHeader> filtered = requestHeaders.stream().filter(h -> !importedBlockHashes.containsKey(ByteArrayWrapper.wrap(h.getHash()))).collect(Collectors.toList());
        // Check the peer state and discard blocks that are under the current best (in case the hashes already dropped from the above map).
        // This check is only applicable for SyncMode.NORMAL because the other sync modes deal with side chains.
        long currentBest = chain.getBestBlock() == null ? 0L : chain.getBestBlock().getNumber();
        long firstInBatch = requestHeaders.get(0).getNumber();
        if (syncHeaderRequestManager.getSyncMode(nodeId) == SyncMode.NORMAL && firstInBatch <= currentBest) {
            // remove all blocks in the batch that are under the current best
            for (Iterator<BlockHeader> it = filtered.iterator(); it.hasNext(); ) {
                if (it.next().getNumber() <= currentBest) {
                    it.remove();
                }
            }
        }
        if (filtered.size() == requestHeaders.size()) {
            // Log bodies request before sending the request.
            log.debug("<get-bodies from-num={} to-num={} node={}>", firstInBatch, requestHeaders.get(requestHeaders.size() - 1).getNumber(), displayId);
            p2pMgr.send(nodeId, displayId, new ReqBlocksBodies(requestHeaders.stream().map(k -> k.getHash()).collect(Collectors.toList())));
            stats.updateTotalRequestsToPeer(displayId, RequestType.BODIES);
            stats.updateRequestTime(displayId, System.nanoTime(), RequestType.BODIES);
        } else {
            // Drop the headers that are already known.
            syncHeaderRequestManager.dropHeaders(nodeId, requestHeaders);
            if (!filtered.isEmpty()) {
                // Store the subset that is still useful.
                syncHeaderRequestManager.storeHeaders(nodeId, filtered);
            }
        }
    }
    long duration = System.nanoTime() - startTime;
    survey_log.debug("TaskGetBodies: make request, duration = {} ns.", duration);
}
Also used : IP2pMgr(org.aion.p2p.IP2pMgr) ThreadPoolExecutor(java.util.concurrent.ThreadPoolExecutor) IEvent(org.aion.evtmgr.IEvent) LRUMap(org.apache.commons.collections4.map.LRUMap) ArrayList(java.util.ArrayList) BlockHeader(org.aion.zero.impl.types.BlockHeader) HashSet(java.util.HashSet) ByteArrayWrapper(org.aion.util.types.ByteArrayWrapper) IEventMgr(org.aion.evtmgr.IEventMgr) BlockUtil(org.aion.zero.impl.types.BlockUtil) Map(java.util.Map) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) INode(org.aion.p2p.INode) SharedRLPList(org.aion.rlp.SharedRLPList) SyncMode(org.aion.zero.impl.sync.SyncHeaderRequestManager.SyncMode) BigInteger(java.math.BigInteger) ReqBlocksBodies(org.aion.zero.impl.sync.msg.ReqBlocksBodies) RequestType(org.aion.zero.impl.sync.statistics.RequestType) Block(org.aion.zero.impl.types.Block) ExecutorService(java.util.concurrent.ExecutorService) AionLoggerFactory(org.aion.log.AionLoggerFactory) StringUtils.getNodeIdShort(org.aion.util.string.StringUtils.getNodeIdShort) BlockHeaderValidator(org.aion.zero.impl.valid.BlockHeaderValidator) Hex(org.aion.util.conversions.Hex) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) BlockType(org.aion.zero.impl.sync.statistics.BlockType) Set(java.util.Set) AionBlockchainImpl(org.aion.zero.impl.blockchain.AionBlockchainImpl) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) Collectors(java.util.stream.Collectors) ChainConfiguration(org.aion.zero.impl.blockchain.ChainConfiguration) Executors(java.util.concurrent.Executors) TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) LogEnum(org.aion.log.LogEnum) ReqStatus(org.aion.zero.impl.sync.msg.ReqStatus) StatsType(org.aion.zero.impl.config.StatsType) VisibleForTesting(com.google.common.annotations.VisibleForTesting) EventConsensus(org.aion.evtmgr.impl.evt.EventConsensus) Collections(java.util.Collections) ArrayList(java.util.ArrayList) SharedRLPList(org.aion.rlp.SharedRLPList) List(java.util.List) BlockHeader(org.aion.zero.impl.types.BlockHeader) ReqBlocksBodies(org.aion.zero.impl.sync.msg.ReqBlocksBodies)

Example 9 with Block

use of org.aion.zero.impl.types.Block in project aion by aionnetwork.

the class SyncMgr method getStatus.

private static String getStatus(AionBlockchainImpl chain, NetworkStatus networkStatus, SyncStats syncStats) {
    Block selfBest = chain.getBestBlock();
    String selfTd = selfBest.getTotalDifficulty().toString(10);
    return "sync-status avg-import=" + String.format("%.2f", syncStats.getAvgBlocksPerSec()) + " b/s" + " td=" + selfTd + "/" + networkStatus.getTargetTotalDiff().toString(10) + " b-num=" + selfBest.getNumber() + "/" + networkStatus.getTargetBestBlockNumber() + " b-hash=" + Hex.toHexString(chain.getBestBlockHash()) + "/" + networkStatus.getTargetBestBlockHash();
}
Also used : Block(org.aion.zero.impl.types.Block)

Example 10 with Block

use of org.aion.zero.impl.types.Block in project aion by aionnetwork.

the class AionPendingStateImpl method executeTx.

private AionTxExecSummary executeTx(AionTransaction tx) {
    Block bestBlk = currentBestBlock.get();
    LOGGER_TX.debug("executeTx: {}", Hex.toHexString(tx.getTransactionHash()));
    try {
        // Booleans moved out here so their meaning is explicit.
        boolean isLocalCall = false;
        boolean incrementSenderNonce = true;
        boolean checkBlockEnergyLimit = false;
        // this parameter should not be relevant to execution
        byte[] difficulty = bestBlk.getDifficulty();
        // the pending state is executed on top of the best block
        long currentBlockNumber = bestBlk.getNumber() + 1;
        // simulating future block
        long timestamp = bestBlk.getTimestamp() + 1;
        // the limit is not checked so making it unlimited
        long blockNrgLimit = Long.MAX_VALUE;
        // assuming same person will mine the future block
        AionAddress miner = bestBlk.getCoinbase();
        return BulkExecutor.executeTransactionWithNoPostExecutionWork(difficulty, currentBlockNumber, timestamp, blockNrgLimit, miner, tx, pendingState, isLocalCall, incrementSenderNonce, blockchain.forkUtility.is040ForkActive(currentBlockNumber), checkBlockEnergyLimit, LOGGER_VM, BlockCachingContext.PENDING, bestBlk.getNumber(), blockchain.forkUtility.isUnityForkActive(currentBlockNumber), blockchain.forkUtility.isSignatureSwapForkActive(currentBlockNumber));
    } catch (VmFatalException e) {
        LOGGER_VM.error("Shutdown due to a VM fatal error.", e);
        System.exit(SystemExitCodes.FATAL_VM_ERROR);
        return null;
    }
}
Also used : AionAddress(org.aion.types.AionAddress) Block(org.aion.zero.impl.types.Block) VmFatalException(org.aion.zero.impl.vm.common.VmFatalException)

Aggregations

Block (org.aion.zero.impl.types.Block)283 MiningBlock (org.aion.zero.impl.types.MiningBlock)155 Test (org.junit.Test)148 AionTransaction (org.aion.base.AionTransaction)106 ImportResult (org.aion.zero.impl.core.ImportResult)86 ArrayList (java.util.ArrayList)63 AionAddress (org.aion.types.AionAddress)61 StakingBlock (org.aion.zero.impl.types.StakingBlock)58 AionBlockSummary (org.aion.zero.impl.types.AionBlockSummary)57 BigInteger (java.math.BigInteger)55 AionRepositoryImpl (org.aion.zero.impl.db.AionRepositoryImpl)34 ByteArrayWrapper (org.aion.util.types.ByteArrayWrapper)30 AionTxReceipt (org.aion.base.AionTxReceipt)29 Hex.toHexString (org.aion.util.conversions.Hex.toHexString)28 AccountState (org.aion.base.AccountState)26 EventBlock (org.aion.evtmgr.impl.evt.EventBlock)26 JSONArray (org.json.JSONArray)26 JSONObject (org.json.JSONObject)26 MiningBlockHeader (org.aion.zero.impl.types.MiningBlockHeader)22 AionTxExecSummary (org.aion.base.AionTxExecSummary)20