Search in sources :

Example 1 with Block

use of com.jd.blockchain.consensus.raft.consensus.Block in project jdchain-core by blockchain-jd-com.

the class BlockCommitService method commitBlock.

public boolean commitBlock(Block block, BlockClosure done) throws BlockCommittedException {
    boolean result = true;
    long latestBlockHeight = ledgerRepository.retrieveLatestBlockHeight();
    if (latestBlockHeight >= block.getHeight()) {
        throw new BlockCommittedException(block.getHeight());
    }
    if (latestBlockHeight + 1 != block.getHeight()) {
        notifyCatchUp(block.getHeight());
        LOGGER.error("commit block ignore. expect height:{}, latest block: {}", block.getHeight(), latestBlockHeight);
        return false;
    }
    RaftConsensusMessageContext context = RaftConsensusMessageContext.createContext(realmName);
    context.setTimestamp(block.getProposalTimestamp());
    String batch = messageHandle.beginBatch(context);
    context.setBatchId(batch);
    LoggerUtils.debugIfEnabled(LOGGER, "commit block start, batchId: {}", batch);
    Status status = Status.OK();
    try {
        int msgId = 0;
        for (byte[] tx : block.getTxs()) {
            AsyncFuture<byte[]> asyncFuture = messageHandle.processOrdered(msgId++, tx, context);
            Optional.ofNullable(done).ifPresent(d -> d.addFuture(asyncFuture));
        }
        messageHandle.completeBatch(context);
        // todo ?
        messageHandle.commitBatch(context);
        LedgerBlock repositoryLatestBlock = ledgerRepository.getLatestBlock();
        assert repositoryLatestBlock.getHeight() == block.getHeight();
        block.setPreBlockHash(repositoryLatestBlock.getPreviousHash());
        block.setCurrentBlockHash(repositoryLatestBlock.getHash());
        blockCommitCallbackList.forEach(c -> c.commitCallBack(block, true));
    } catch (Exception e) {
        LOGGER.error("commitBlock error", e);
        result = false;
        messageHandle.rollbackBatch(TransactionState.CONSENSUS_ERROR.CODE, context);
        status = new Status(TransactionState.CONSENSUS_ERROR.CODE, e.getMessage());
        blockCommitCallbackList.forEach(c -> c.commitCallBack(block, false));
    }
    LoggerUtils.debugIfEnabled(LOGGER, "commit block end, batchId: {}, blockHeight: {}, status: {}", batch, block.getHeight(), status);
    if (done != null) {
        done.run(status);
    }
    return result;
}
Also used : Status(com.alipay.sofa.jraft.Status) Longs(com.google.common.primitives.Longs) Logger(org.slf4j.Logger) MessageHandle(com.jd.blockchain.consensus.service.MessageHandle) TransactionState(com.jd.blockchain.ledger.TransactionState) BlockCommitCallback(com.jd.blockchain.consensus.raft.consensus.BlockCommitCallback) MessageBus(com.jd.blockchain.consensus.raft.msgbus.MessageBus) BlockCommittedException(com.jd.blockchain.consensus.raft.consensus.BlockCommittedException) LoggerFactory(org.slf4j.LoggerFactory) LedgerBlock(com.jd.blockchain.ledger.LedgerBlock) LedgerRepository(com.jd.blockchain.ledger.core.LedgerRepository) Status(com.alipay.sofa.jraft.Status) LoggerUtils(com.jd.blockchain.consensus.raft.util.LoggerUtils) ArrayList(java.util.ArrayList) List(java.util.List) AsyncFuture(utils.concurrent.AsyncFuture) BLOCK_CATCH_UP_TOPIC(com.jd.blockchain.consensus.raft.msgbus.MessageBus.BLOCK_CATCH_UP_TOPIC) Block(com.jd.blockchain.consensus.raft.consensus.Block) Optional(java.util.Optional) BlockCommitter(com.jd.blockchain.consensus.raft.consensus.BlockCommitter) LedgerBlock(com.jd.blockchain.ledger.LedgerBlock) BlockCommittedException(com.jd.blockchain.consensus.raft.consensus.BlockCommittedException) BlockCommittedException(com.jd.blockchain.consensus.raft.consensus.BlockCommittedException)

Example 2 with Block

use of com.jd.blockchain.consensus.raft.consensus.Block in project jdchain-core by blockchain-jd-com.

the class RaftNodeServerServiceImpl method proposalBlock.

private void proposalBlock(List<SubmitTx> submitTxList) {
    if (!proposer.canPropose()) {
        LoggerUtils.debugIfEnabled(LOGGER, "node {} can't propose block", nodeServer.getNode().getNodeId());
        for (SubmitTx submitTx : submitTxList) {
            submitTx.getDone().run(new Status(RaftError.ENEWLEADER, "node {} can't propose block", nodeServer.getNode().getNodeId()));
        }
        return;
    }
    LoggerUtils.debugIfEnabled(LOGGER, "node: {} begin proposal block, proposal tx size: {}", nodeServer.getNode().getNodeId(), submitTxList.size());
    List<byte[]> txList = submitTxList.stream().map(SubmitTx::getValues).collect(Collectors.toList());
    List<Closure> doneList = submitTxList.stream().map(SubmitTx::getDone).collect(Collectors.toList());
    try {
        final Task task = new Task();
        Block block = proposer.proposeBlock(txList);
        task.setData(ByteBuffer.wrap(serializer.serialize(block)));
        task.setDone(new BlockClosure(block, doneList));
        nodeServer.getNode().apply(task);
    } catch (Exception e) {
        LOGGER.error("proposal block error", e);
        // todo retry ?
        for (Closure closure : doneList) {
            runSubmitTxClosure(closure, i -> RpcResponse.fail(RaftError.UNKNOWN.getNumber(), e.getMessage()), 0);
        }
    }
}
Also used : Status(com.alipay.sofa.jraft.Status) TransactionState(com.jd.blockchain.ledger.TransactionState) LoggerFactory(org.slf4j.LoggerFactory) Function(java.util.function.Function) ByteBuffer(java.nio.ByteBuffer) ArrayList(java.util.ArrayList) BlockProposer(com.jd.blockchain.consensus.raft.consensus.BlockProposer) com.lmax.disruptor(com.lmax.disruptor) Block(com.jd.blockchain.consensus.raft.consensus.Block) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Closure(com.alipay.sofa.jraft.Closure) BiConsumer(java.util.function.BiConsumer) RaftError(com.alipay.sofa.jraft.error.RaftError) BlockSerializer(com.jd.blockchain.consensus.raft.consensus.BlockSerializer) com.jd.blockchain.consensus.raft.rpc(com.jd.blockchain.consensus.raft.rpc) Logger(org.slf4j.Logger) PeerId(com.alipay.sofa.jraft.entity.PeerId) Configuration(com.alipay.sofa.jraft.conf.Configuration) com.alipay.sofa.jraft.util(com.alipay.sofa.jraft.util) ProducerType(com.lmax.disruptor.dsl.ProducerType) Status(com.alipay.sofa.jraft.Status) Collectors(java.util.stream.Collectors) JRaftUtils(com.alipay.sofa.jraft.JRaftUtils) LoggerUtils(com.jd.blockchain.consensus.raft.util.LoggerUtils) List(java.util.List) Task(com.alipay.sofa.jraft.entity.Task) Disruptor(com.lmax.disruptor.dsl.Disruptor) Task(com.alipay.sofa.jraft.entity.Task) Closure(com.alipay.sofa.jraft.Closure) Block(com.jd.blockchain.consensus.raft.consensus.Block)

Example 3 with Block

use of com.jd.blockchain.consensus.raft.consensus.Block in project jdchain-core by blockchain-jd-com.

the class BlockProposerService method commitCallBack.

@Override
public void commitCallBack(Block block, boolean isCommit) {
    lock.lock();
    try {
        proposalBlockMap.headMap(block.getHeight(), true).clear();
        long nextHeight = block.getHeight() + 1;
        Block blockCache = proposalBlockMap.get(nextHeight);
        if (isCommit) {
            Optional.ofNullable(blockCache).ifPresent(b -> b.setPreBlockHash(block.getCurrentBlockHash()));
        } else {
            Optional.ofNullable(blockCache).ifPresent(b -> b.setPreBlockHash(block.getPreBlockHash()));
            TreeMap<Long, Block> blockTreeMap = new TreeMap<>();
            proposalBlockMap.values().forEach(b -> {
                b.setHeight(b.getHeight() - 1);
                blockTreeMap.put(b.getHeight(), b);
            });
            proposalBlockMap.clear();
            proposalBlockMap = null;
            proposalBlockMap = blockTreeMap;
        }
    } finally {
        lock.unlock();
    }
}
Also used : LedgerBlock(com.jd.blockchain.ledger.LedgerBlock) Block(com.jd.blockchain.consensus.raft.consensus.Block) TreeMap(java.util.TreeMap)

Example 4 with Block

use of com.jd.blockchain.consensus.raft.consensus.Block in project jdchain-core by blockchain-jd-com.

the class BlockProposerService method proposeBlock.

@Override
public Block proposeBlock(List<byte[]> txs) {
    lock.lock();
    Block proposeBlock = new Block();
    try {
        proposeBlock.setProposalTimestamp(System.currentTimeMillis());
        proposeBlock.setTxs(txs);
        // todo: 使用latestProposalBlock减少账本查询
        if (proposalBlockMap.isEmpty()) {
            LedgerBlock latestBlock = ledgerRepository.retrieveLatestBlock();
            proposeBlock.setPreBlockHash(latestBlock.getHash());
            proposeBlock.setHeight(latestBlock.getHeight() + 1);
        } else {
            proposeBlock.setHeight(latestProposalBlock.getHeight() + +1);
        }
        proposalBlockMap.put(proposeBlock.getHeight(), proposeBlock);
        latestProposalBlock = proposeBlock;
        LoggerUtils.debugIfEnabled(LOGGER, "proposal cache size: {}, latest proposal height: {}", proposalBlockMap.size(), latestProposalBlock.getHeight());
    } finally {
        lock.unlock();
    }
    return proposeBlock;
}
Also used : LedgerBlock(com.jd.blockchain.ledger.LedgerBlock) LedgerBlock(com.jd.blockchain.ledger.LedgerBlock) Block(com.jd.blockchain.consensus.raft.consensus.Block)

Example 5 with Block

use of com.jd.blockchain.consensus.raft.consensus.Block in project jdchain-core by blockchain-jd-com.

the class SimpleBlockSerializerServiceTest method testSerialize.

public void testSerialize() {
    Block block = blockProposer.proposeBlock(Lists.newArrayList(new byte[] { 1, 2 }));
    byte[] serialize = blockSerializer.serialize(block);
    Block block1 = blockSerializer.deserialize(serialize);
    Assert.assertEquals(block.getPreBlockHash(), block1.getPreBlockHash());
}
Also used : Block(com.jd.blockchain.consensus.raft.consensus.Block)

Aggregations

Block (com.jd.blockchain.consensus.raft.consensus.Block)6 LedgerBlock (com.jd.blockchain.ledger.LedgerBlock)4 Status (com.alipay.sofa.jraft.Status)2 LoggerUtils (com.jd.blockchain.consensus.raft.util.LoggerUtils)2 TransactionState (com.jd.blockchain.ledger.TransactionState)2 ArrayList (java.util.ArrayList)2 List (java.util.List)2 Logger (org.slf4j.Logger)2 LoggerFactory (org.slf4j.LoggerFactory)2 Closure (com.alipay.sofa.jraft.Closure)1 JRaftUtils (com.alipay.sofa.jraft.JRaftUtils)1 Configuration (com.alipay.sofa.jraft.conf.Configuration)1 PeerId (com.alipay.sofa.jraft.entity.PeerId)1 Task (com.alipay.sofa.jraft.entity.Task)1 RaftError (com.alipay.sofa.jraft.error.RaftError)1 com.alipay.sofa.jraft.util (com.alipay.sofa.jraft.util)1 Longs (com.google.common.primitives.Longs)1 BlockCommitCallback (com.jd.blockchain.consensus.raft.consensus.BlockCommitCallback)1 BlockCommittedException (com.jd.blockchain.consensus.raft.consensus.BlockCommittedException)1 BlockCommitter (com.jd.blockchain.consensus.raft.consensus.BlockCommitter)1