/// <summary> /// Update cross chain block info, side chain block and parent block info if needed /// </summary> /// <param name="block"></param> /// <param name="txnRes"></param> /// <returns></returns> private async Task UpdateCrossChainInfo(IBlock block, List <TransactionResult> txnRes) { await _binaryMerkleTreeManager.AddTransactionsMerkleTreeAsync(block.Body.BinaryMerkleTree, block.Header.ChainId, block.Header.Index); await _binaryMerkleTreeManager.AddSideChainTransactionRootsMerkleTreeAsync( block.Body.BinaryMerkleTreeForSideChainTransactionRoots, block.Header.ChainId, block.Header.Index); // update side chain block info if execution succeed foreach (var blockInfo in block.Body.IndexedInfo) { /*if (!await _clientManager.TryUpdateAndRemoveSideChainBlockInfo(blockInfo)) * // Todo: _clientManager would be chaos if this happened. * throw new InvalidCrossChainInfoException( * "Inconsistent side chain info. Something about side chain would be chaos if you see this. ", BlockExecutionResult.InvalidSideChainInfo);*/ await _chainManagerBasic.UpdateCurrentBlockHeightAsync(blockInfo.ChainId, blockInfo.Height); } // update parent chain info /*if (block.ParentChainBlockInfo != null) * { * * await _chainManagerBasic.UpdateCurrentBlockHeightAsync(block.ParentChainBlockInfo.ChainId, * block.ParentChainBlockInfo.Height); * }*/ }
public async Task <BlockExecutionResultCC> ExecuteBlock(IBlock block) { if (!await Prepare(block)) { return(BlockExecutionResultCC.Failed); } _logger?.Trace($"Executing block {block.GetHash()}"); var uncompressedPrivateKey = block.Header.P.ToByteArray(); var recipientKeyPair = ECKeyPair.FromPublicKey(uncompressedPrivateKey); var blockProducerAddress = recipientKeyPair.GetAddress(); _stateDictator.ChainId = block.Header.ChainId; _stateDictator.BlockHeight = block.Header.Index - 1; _stateDictator.BlockProducerAccountAddress = blockProducerAddress; var txs = new List <Transaction>(); try { txs = block.Body.TransactionList.ToList(); var txResults = await ExecuteTransactions(txs, Hash.LoadHex(NodeConfig.Instance.ChainId)); await InsertTxs(txs, txResults, block); var res = await UpdateState(block); var blockchain = _chainService.GetBlockChain(block.Header.ChainId); if (!res) { var txToRevert = await blockchain.RollbackOneBlock(); await _txPoolService.Revert(txToRevert); return(BlockExecutionResultCC.Failed); } await blockchain.AddBlocksAsync(new List <IBlock> { block }); await _binaryMerkleTreeManager.AddTransactionsMerkleTreeAsync(block.Body.BinaryMerkleTree, block.Header.ChainId, block.Header.Index); await _binaryMerkleTreeManager.AddSideChainTransactionRootsMerkleTreeAsync( block.Body.BinaryMerkleTreeForSideChainTransactionRoots, block.Header.ChainId, block.Header.Index); } catch (Exception e) { await Interrupt($"ExecuteBlock - Execution failed with exception {e}", txs, e); return(BlockExecutionResultCC.Failed); } return(BlockExecutionResultCC.Success); }
/// <summary> /// Update database /// </summary> /// <param name="txResults"></param> /// <param name="block"></param> private void Update(HashSet <TransactionResult> txResults, IBlock block) { var bn = block.Header.Index; var bh = block.Header.GetHash(); txResults.AsParallel().ForEach(async r => { r.BlockNumber = bn; r.BlockHash = bh; r.MerklePath = block.Body.BinaryMerkleTree.GenerateMerklePath(r.Index); await _transactionResultManager.AddTransactionResultAsync(r); }); // update merkle tree _binaryMerkleTreeManager.AddTransactionsMerkleTreeAsync(block.Body.BinaryMerkleTree, Config.ChainId, block.Header.Index); if (block.Body.IndexedInfo.Count > 0) { _binaryMerkleTreeManager.AddSideChainTransactionRootsMerkleTreeAsync( block.Body.BinaryMerkleTreeForSideChainTransactionRoots, Config.ChainId, block.Header.Index); } }