/// <summary> /// Generate a system tx for parent chain block info and broadcast it. /// </summary> /// <returns></returns> private async Task GenerateTransactionWithParentChainBlockInfo() { var parentChainBlockInfo = GetParentChainBlockInfo(); if (parentChainBlockInfo == null) { return; } try { var bn = await _blockChain.GetCurrentBlockHeightAsync(); bn = bn > 4 ? bn - 4 : 0; var bh = bn == 0 ? Hash.Genesis : (await _blockChain.GetHeaderByHeightAsync(bn)).GetHash(); var bhPref = bh.Value.Where((x, i) => i < 4).ToArray(); var tx = new Transaction { From = _keyPair.GetAddress(), To = AddressHelpers.GetSystemContractAddress(Config.ChainId, SmartContractType.SideChainContract.ToString()), RefBlockNumber = bn, RefBlockPrefix = ByteString.CopyFrom(bhPref), MethodName = "WriteParentChainBlockInfo", Sig = new Signature { P = ByteString.CopyFrom(_keyPair.GetEncodedPublicKey()) }, Type = TransactionType.CrossChainBlockInfoTransaction, Params = ByteString.CopyFrom(ParamsPacker.Pack(parentChainBlockInfo)), Time = Timestamp.FromDateTime(DateTime.UtcNow) }; // sign tx var signature = new ECSigner().Sign(_keyPair, tx.GetHash().DumpByteArray()); tx.Sig.R = ByteString.CopyFrom(signature.R); tx.Sig.S = ByteString.CopyFrom(signature.S); await InsertTransactionToPool(tx); _logger?.Trace($"Generated Cross chain info transaction {tx.GetHash()}"); } catch (Exception e) { _logger?.Error(e, "PCB transaction generation failed."); } }