use of io.nuls.kernel.model.BlockHeader in project nuls by nuls-io.
the class TemporaryCacheManagerTest method cacheSmallBlock.
/**
* 测试小区快的缓存处理流程:
* 1. 先测试放入缓存,不出现异常视为成功
* 2. 测试获取刚放入的小区快,获取的结果不能为空且和刚仿佛的是相同内容
* 3. 测试删除之前放入的小区快,删除后再获取应该得到null
* 4. 重新把小区快放回缓存中,调用清理方法,清理后缓存中应该没有任何小区块或者交易
* test the cache processing process of the smallblock:
* 1. The first test is put into the cache, and no exceptions are deemed to be successful.
* 2. Test to get the newly inserted smallblock fast, the results can not be empty and the same content as if it is just as if.
* 3. Before the test is deleted, the cells should be put into the smallblock quickly. After deleting, it should be null.
* 4. Reattach the smallblock to the cache, call the cleaning method, and there should be no blocks or transactions in the cache.
*/
@Test
public void cacheSmallBlock() {
SmallBlock smallBlock = new SmallBlock();
BlockHeader header = new BlockHeader();
NulsDigestData hash = NulsDigestData.calcDigestData("abcdefg".getBytes());
header.setHash(hash);
manager.cacheSmallBlock(smallBlock);
assertTrue(true);
this.getSmallBlock(hash, smallBlock);
this.removeSmallBlock(hash);
manager.cacheSmallBlock(smallBlock);
this.clear();
}
use of io.nuls.kernel.model.BlockHeader in project nuls by nuls-io.
the class CallContractTxProcessor method onCommit.
@Override
public Result onCommit(CallContractTransaction tx, Object secondaryData) {
try {
ContractResult contractResult = tx.getContractResult();
// 保存调用合约交易的UTXO
Result utxoResult = contractUtxoService.saveUtxoForContractAddress(tx);
if (utxoResult.isFailed()) {
Log.error("save confirmed contract utxo error, reason is {}.", utxoResult.getMsg());
return utxoResult;
}
long blockHeight = tx.getBlockHeight();
/**
* 保存子交易到全网账本、合约账本、本地账本
*/
Collection<ContractTransferTransaction> contractTransferTxs = tx.getContractTransferTxs();
if (contractTransferTxs != null && contractTransferTxs.size() > 0) {
for (ContractTransferTransaction transferTx : contractTransferTxs) {
try {
transferTx.setBlockHeight(blockHeight);
Result result = ledgerService.saveTx(transferTx);
if (result.isFailed()) {
Log.error("save contract transfer tx to ledger error. msg: {}", result.getMsg());
return result;
}
result = contractService.saveContractTransferTx(transferTx);
if (result.isFailed()) {
Log.error("save contract transfer tx to contract ledger error. msg: {}", result.getMsg());
return result;
}
result = accountLedgerService.saveConfirmedTransaction(transferTx);
if (result.isFailed()) {
Log.error("save contract transfer tx to account ledger error. msg: {}", result.getMsg());
return result;
}
} catch (Exception e) {
e.printStackTrace();
Log.error("save contract transfer tx error. msg: {}", e.getMessage());
return Result.getFailed();
}
}
}
// 保存代币交易
CallContractData callContractData = tx.getTxData();
byte[] contractAddress = callContractData.getContractAddress();
Result<ContractAddressInfoPo> contractAddressInfoPoResult = contractAddressStorageService.getContractAddressInfo(contractAddress);
if (contractAddressInfoPoResult.isFailed()) {
return contractAddressInfoPoResult;
}
ContractAddressInfoPo contractAddressInfoPo = contractAddressInfoPoResult.getData();
if (contractAddressInfoPo == null) {
return Result.getFailed(ContractErrorCode.CONTRACT_ADDRESS_NOT_EXIST);
}
contractResult.setNrc20(contractAddressInfoPo.isNrc20());
BlockHeader blockHeader = tx.getBlockHeader();
byte[] newestStateRoot = blockHeader.getStateRoot();
// 获取合约当前状态
ProgramStatus status = vmHelper.getContractStatus(newestStateRoot, contractAddress);
boolean isTerminatedContract = ContractUtil.isTerminatedContract(status.ordinal());
// 处理合约执行失败 - 没有transferEvent的情况, 直接从数据库中获取, 若是本地创建的交易,获取到修改为失败交易
if (isTerminatedContract || !contractResult.isSuccess()) {
if (contractAddressInfoPo != null && contractAddressInfoPo.isNrc20() && ContractUtil.isTransferMethod(callContractData.getMethodName())) {
byte[] txHashBytes = tx.getHash().serialize();
byte[] infoKey = ArraysTool.concatenate(callContractData.getSender(), txHashBytes, new VarInt(0).encode());
Result<ContractTokenTransferInfoPo> infoResult = contractTokenTransferStorageService.getTokenTransferInfo(infoKey);
ContractTokenTransferInfoPo po = infoResult.getData();
if (po != null) {
po.setStatus((byte) 2);
contractTokenTransferStorageService.saveTokenTransferInfo(infoKey, po);
// 刷新token余额
if (isTerminatedContract) {
// 终止的合约,回滚token余额
this.rollbackContractToken(po);
contractResult.setError(true);
contractResult.setErrorMessage("this contract has been terminated");
} else {
if (po.getFrom() != null) {
vmHelper.refreshTokenBalance(newestStateRoot, contractAddressInfoPo, AddressTool.getStringAddressByBytes(po.getFrom()), po.getContractAddress());
}
if (po.getTo() != null) {
vmHelper.refreshTokenBalance(newestStateRoot, contractAddressInfoPo, AddressTool.getStringAddressByBytes(po.getTo()), po.getContractAddress());
}
}
}
}
}
if (!isTerminatedContract) {
// 处理合约事件
vmHelper.dealEvents(newestStateRoot, tx, contractResult, contractAddressInfoPo);
}
// 保存合约执行结果
contractService.saveContractExecuteResult(tx.getHash(), contractResult);
} catch (Exception e) {
Log.error("save call contract tx error.", e);
return Result.getFailed();
}
return Result.getSuccess();
}
use of io.nuls.kernel.model.BlockHeader in project nuls by nuls-io.
the class CacheManager method load.
public void load() throws NulsException {
// load storage data to memory
List<BlockHeader> blockHeaderList = cacheLoader.loadBlockHeaders(PocConsensusConstant.INIT_HEADERS_OF_ROUND_COUNT);
List<Block> blockList = cacheLoader.loadBlocks(PocConsensusConstant.INIT_BLOCKS_COUNT);
if (blockHeaderList == null || blockHeaderList.size() == 0 || blockList == null || blockList.size() == 0) {
Log.error("load cache error ,not find the block info!");
throw new NulsRuntimeException(KernelErrorCode.DATA_ERROR);
}
List<Agent> agentList = cacheLoader.loadAgents();
List<Deposit> depositList = cacheLoader.loadDepositList();
List<PunishLogPo> allPunishList = NulsContext.getServiceBean(PunishLogStorageService.class).getPunishList();
List<PunishLogPo> yellowPunishList = cacheLoader.loadYellowPunishList(allPunishList, PocConsensusConstant.INIT_HEADERS_OF_ROUND_COUNT);
List<PunishLogPo> redPunishList = cacheLoader.loadRedPunishList(allPunishList);
Chain masterChain = new Chain();
masterChain.initData(blockList.get(0).getHeader(), blockHeaderList, blockList);
masterChain.setAgentList(agentList);
masterChain.setDepositList(depositList);
masterChain.setYellowPunishList(yellowPunishList);
masterChain.setRedPunishList(redPunishList);
ChainContainer masterChainContainer = new ChainContainer(masterChain);
chainManager.setMasterChain(masterChainContainer);
chainManager.getMasterChain().initRound();
}
use of io.nuls.kernel.model.BlockHeader in project nuls by nuls-io.
the class RoundManager method initRound.
public MeetingRound initRound() {
MeetingRound currentRound = resetRound(false);
if (currentRound.getPreRound() == null) {
BlockExtendsData extendsData = null;
List<BlockHeader> blockHeaderList = chain.getAllBlockHeaderList();
for (int i = blockHeaderList.size() - 1; i >= 0; i--) {
BlockHeader blockHeader = blockHeaderList.get(i);
extendsData = new BlockExtendsData(blockHeader.getExtend());
if (extendsData.getRoundIndex() < currentRound.getIndex()) {
break;
}
}
MeetingRound preRound = getNextRound(extendsData, false);
currentRound.setPreRound(preRound);
}
return currentRound;
}
use of io.nuls.kernel.model.BlockHeader in project nuls by nuls-io.
the class RoundManager method getFirstBlockHeightOfPreRoundByRoundIndex.
private BlockHeader getFirstBlockHeightOfPreRoundByRoundIndex(long roundIndex) {
BlockHeader firstBlockHeader = null;
long startRoundIndex = 0L;
List<BlockHeader> blockHeaderList = chain.getAllBlockHeaderList();
for (int i = blockHeaderList.size() - 1; i >= 0; i--) {
BlockHeader blockHeader = blockHeaderList.get(i);
long currentRoundIndex = new BlockExtendsData(blockHeader.getExtend()).getRoundIndex();
if (roundIndex > currentRoundIndex) {
if (startRoundIndex == 0L) {
startRoundIndex = currentRoundIndex;
}
if (currentRoundIndex < startRoundIndex) {
firstBlockHeader = blockHeaderList.get(i + 1);
BlockExtendsData roundData = new BlockExtendsData(firstBlockHeader.getExtend());
if (roundData.getPackingIndexOfRound() > 1) {
firstBlockHeader = blockHeader;
}
break;
}
}
}
if (firstBlockHeader == null) {
firstBlockHeader = chain.getStartBlockHeader();
Log.warn("the first block of pre round not found");
}
return firstBlockHeader;
}
Aggregations