Search in sources :

Example 1 with ResponseBlocks

use of org.aion.zero.impl.sync.msg.ResponseBlocks in project aion by aionnetwork.

the class ResponseBlocksHandler method receive.

@Override
public void receive(int peerId, String displayId, final byte[] message) {
    if (message == null || message.length == 0) {
        p2pMgr.errCheck(peerId, displayId);
        log.debug("<response-blocks empty message from peer={}>", displayId);
        return;
    }
    ResponseBlocks response = ResponseBlocks.decode(message);
    if (response != null) {
        if (log.isDebugEnabled()) {
            log.debug("<response-blocks response={} peer={}>", response, displayId);
        }
    // checks PoW and adds correct blocks to import list
    // TODO: reenable when used
    // fastSyncMgr.validateAndAddBlocks(peerId, displayId, response);
    } else {
        p2pMgr.errCheck(peerId, displayId);
        log.error("<response-blocks decode-error msg-bytes={} peer={}>", message.length, displayId);
        if (log.isTraceEnabled()) {
            log.trace("<response-blocks decode-error for msg={} peer={}>", Arrays.toString(message), displayId);
        }
    }
}
Also used : ResponseBlocks(org.aion.zero.impl.sync.msg.ResponseBlocks)

Example 2 with ResponseBlocks

use of org.aion.zero.impl.sync.msg.ResponseBlocks in project aion by aionnetwork.

the class RequestBlocksHandler method receive.

@Override
public void receive(int peerId, String displayId, final byte[] message) {
    if (message == null || message.length == 0) {
        this.log.debug("<request-blocks empty message from peer={}>", displayId);
        return;
    }
    RequestBlocks request = RequestBlocks.decode(message);
    if (request != null) {
        if (request.isNumber()) {
            // process block requests by number
            long start = request.getStartHeight();
            int count = Math.min(request.getCount(), V1Constants.BLOCKS_REQUEST_MAXIMUM_BATCH_SIZE);
            boolean descending = request.isDescending();
            if (log.isDebugEnabled()) {
                this.log.debug("<request-blocks from-block={} count={} order={}>", start, count, descending ? "DESC" : "ASC");
            }
            List<Block> blockList = null;
            try {
                // retrieve blocks from block store depending on requested order
                if (descending) {
                    blockList = chain.getBlocksByRange(start, start - count + 1);
                } else {
                    blockList = chain.getBlocksByRange(start, start + count - 1);
                }
            } catch (Exception e) {
                this.log.error("<request-blocks value retrieval failed>", e);
            }
            if (blockList != null) {
                // generate response with retrieved blocks
                // TODO: check the message size and ensure that it fits predefined limits
                ResponseBlocks response = new ResponseBlocks(blockList);
                // reply to request
                this.p2p.send(peerId, displayId, response);
            }
        } else {
            // process block requests by hash
            byte[] startHash = request.getStartHash();
            int count = Math.min(request.getCount(), V1Constants.BLOCKS_REQUEST_MAXIMUM_BATCH_SIZE);
            boolean descending = request.isDescending();
            if (log.isDebugEnabled()) {
                this.log.debug("<request-blocks from-block={} count={} order={}>", Hex.toHexString(startHash), count, descending ? "DESC" : "ASC");
            }
            // check if block exists
            Block block = chain.getBlockByHash(startHash);
            if (block != null) {
                long start = block.getNumber();
                List<Block> blockList = null;
                try {
                    // retrieve blocks from block store depending on requested order
                    if (descending) {
                        blockList = chain.getBlocksByRange(start, start - count + 1);
                    } else {
                        blockList = chain.getBlocksByRange(start, start + count - 1);
                    }
                } catch (Exception e) {
                    this.log.error("<request-blocks value retrieval failed>", e);
                }
                if (blockList != null && blockList.contains(block)) {
                    // generate response with retrieved blocks
                    // TODO: check the message size and ensure that it fits predefined limits
                    ResponseBlocks response = new ResponseBlocks(blockList);
                    // reply to request
                    this.p2p.send(peerId, displayId, response);
                } else {
                    // retrieving multiple blocks failed
                    // or the requested block was on a side chain
                    // generate response with single block
                    ResponseBlocks response = new ResponseBlocks(List.of(block));
                    // reply to request
                    this.p2p.send(peerId, displayId, response);
                }
            }
        }
    } else {
        this.log.error("<request-blocks decode-error msg-bytes={} peer={}>", message.length, displayId);
        if (log.isTraceEnabled()) {
            this.log.trace("<request-blocks decode-error for msg={} peer={}>", Arrays.toString(message), displayId);
        }
    }
}
Also used : RequestBlocks(org.aion.zero.impl.sync.msg.RequestBlocks) Block(org.aion.zero.impl.types.Block) ResponseBlocks(org.aion.zero.impl.sync.msg.ResponseBlocks)

Example 3 with ResponseBlocks

use of org.aion.zero.impl.sync.msg.ResponseBlocks in project aion by aionnetwork.

the class RequestBlocksHandlerTest method testReceive_correctMessage_ascending_withHash.

@Test
public void testReceive_correctMessage_ascending_withHash() {
    Block first = consecutiveBlocks.get(0);
    byte[] hash = first.getHash();
    Block last = consecutiveBlocks.get(3);
    Logger log = mock(Logger.class);
    when(log.isDebugEnabled()).thenReturn(true);
    IAionBlockchain chain = mock(AionBlockchainImpl.class);
    when(chain.getBlockByHash(hash)).thenReturn(first);
    when(chain.getBlocksByRange(first.getNumber(), last.getNumber())).thenReturn(consecutiveBlocks);
    IP2pMgr p2p = mock(P2pMgr.class);
    RequestBlocksHandler handler = new RequestBlocksHandler(log, chain, p2p);
    // receive correct message
    RequestBlocks request = new RequestBlocks(hash, 4, false);
    handler.receive(peerId, displayId, request.encode());
    verify(log, times(1)).debug("<request-blocks from-block={} count={} order={}>", Hex.toHexString(hash), 4, "ASC");
    verify(chain, times(1)).getBlockByHash(hash);
    verify(chain, times(1)).getBlocksByRange(first.getNumber(), last.getNumber());
    ResponseBlocks expectedResponse = new ResponseBlocks(consecutiveBlocks);
    verify(p2p, times(1)).send(peerId, displayId, expectedResponse);
}
Also used : RequestBlocks(org.aion.zero.impl.sync.msg.RequestBlocks) Block(org.aion.zero.impl.types.Block) IAionBlockchain(org.aion.zero.impl.blockchain.IAionBlockchain) Logger(org.slf4j.Logger) IP2pMgr(org.aion.p2p.IP2pMgr) ResponseBlocks(org.aion.zero.impl.sync.msg.ResponseBlocks) Test(org.junit.Test)

Example 4 with ResponseBlocks

use of org.aion.zero.impl.sync.msg.ResponseBlocks in project aion by aionnetwork.

the class RequestBlocksHandlerTest method testReceive_correctMessage_descending_withHeight.

@Test
public void testReceive_correctMessage_descending_withHeight() {
    Block first = consecutiveBlocks.get(3);
    Block last = consecutiveBlocks.get(0);
    // reverse the list order
    LinkedList<Block> reverse = new LinkedList<>();
    for (Block b : consecutiveBlocks) {
        reverse.addFirst(b);
    }
    Logger log = mock(Logger.class);
    when(log.isDebugEnabled()).thenReturn(true);
    IAionBlockchain chain = mock(AionBlockchainImpl.class);
    when(chain.getBlocksByRange(first.getNumber(), last.getNumber())).thenReturn(reverse);
    IP2pMgr p2p = mock(P2pMgr.class);
    RequestBlocksHandler handler = new RequestBlocksHandler(log, chain, p2p);
    // receive correct message
    RequestBlocks request = new RequestBlocks(first.getNumber(), 4, true);
    handler.receive(peerId, displayId, request.encode());
    verify(log, times(1)).debug("<request-blocks from-block={} count={} order={}>", first.getNumber(), 4, "DESC");
    verify(chain, times(1)).getBlocksByRange(first.getNumber(), last.getNumber());
    ResponseBlocks expectedResponse = new ResponseBlocks(reverse);
    verify(p2p, times(1)).send(peerId, displayId, expectedResponse);
}
Also used : RequestBlocks(org.aion.zero.impl.sync.msg.RequestBlocks) Block(org.aion.zero.impl.types.Block) IAionBlockchain(org.aion.zero.impl.blockchain.IAionBlockchain) Logger(org.slf4j.Logger) IP2pMgr(org.aion.p2p.IP2pMgr) LinkedList(java.util.LinkedList) ResponseBlocks(org.aion.zero.impl.sync.msg.ResponseBlocks) Test(org.junit.Test)

Example 5 with ResponseBlocks

use of org.aion.zero.impl.sync.msg.ResponseBlocks in project aion by aionnetwork.

the class RequestBlocksHandlerTest method testReceive_correctMessage_withException_withHash.

@Test
public void testReceive_correctMessage_withException_withHash() {
    Block first = consecutiveBlocks.get(0);
    byte[] hash = first.getHash();
    Block last = consecutiveBlocks.get(3);
    Logger log = mock(Logger.class);
    when(log.isDebugEnabled()).thenReturn(true);
    IAionBlockchain chain = mock(AionBlockchainImpl.class);
    when(chain.getBlockByHash(hash)).thenReturn(first);
    Exception e = new NullPointerException();
    when(chain.getBlocksByRange(first.getNumber(), last.getNumber())).thenThrow(e);
    IP2pMgr p2p = mock(P2pMgr.class);
    RequestBlocksHandler handler = new RequestBlocksHandler(log, chain, p2p);
    // receive correct message
    byte[] encoding = RLP.encodeList(RLP.encodeByte(isFalse), RLP.encode(hash), RLP.encodeInt(4), RLP.encodeByte(isFalse));
    handler.receive(peerId, displayId, encoding);
    verify(log, times(1)).debug("<request-blocks from-block={} count={} order={}>", Hex.toHexString(hash), 4, "ASC");
    verify(log).error("<request-blocks value retrieval failed>", e);
    verify(chain, times(1)).getBlockByHash(hash);
    verify(chain, times(1)).getBlocksByRange(first.getNumber(), last.getNumber());
    ResponseBlocks expectedResponse = new ResponseBlocks(List.of(first));
    verify(p2p, times(1)).send(peerId, displayId, expectedResponse);
}
Also used : Block(org.aion.zero.impl.types.Block) IAionBlockchain(org.aion.zero.impl.blockchain.IAionBlockchain) Logger(org.slf4j.Logger) IP2pMgr(org.aion.p2p.IP2pMgr) ResponseBlocks(org.aion.zero.impl.sync.msg.ResponseBlocks) Test(org.junit.Test)

Aggregations

ResponseBlocks (org.aion.zero.impl.sync.msg.ResponseBlocks)9 Block (org.aion.zero.impl.types.Block)8 IP2pMgr (org.aion.p2p.IP2pMgr)7 IAionBlockchain (org.aion.zero.impl.blockchain.IAionBlockchain)7 Test (org.junit.Test)7 Logger (org.slf4j.Logger)7 RequestBlocks (org.aion.zero.impl.sync.msg.RequestBlocks)6 LinkedList (java.util.LinkedList)2