private async Task <TransactionSummary> TxToJSON(ITransaction tx, UInt64 blockHeight, bool confirmed, bool returnLegacyAddresses, bool noAsm, bool noScriptSig, bool noSpend) { UInt32 blockTimestamp = 0; string blockHash = ""; if (confirmed) { using (var getBlockHeaderResult = await chain_.FetchBlockHeaderByHeightAsync(blockHeight)) { Utils.CheckBitprimApiErrorCode(getBlockHeaderResult.ErrorCode, "FetchBlockHeaderByHeightAsync(" + blockHeight + ") failed, check error log"); IHeader blockHeader = getBlockHeaderResult.Result.BlockData; blockTimestamp = blockHeader.Timestamp; blockHash = Binary.ByteArrayToHexString(blockHeader.Hash); } } ApiCallResult <UInt64> getLastHeightResult = await chain_.FetchLastHeightAsync(); Utils.CheckBitprimApiErrorCode(getLastHeightResult.ErrorCode, "FetchLastHeightAsync failed, check error log"); var txJson = new TransactionSummary(); txJson.txid = Binary.ByteArrayToHexString(tx.Hash); txJson.version = tx.Version; txJson.locktime = tx.Locktime; txJson.vin = await TxInputsToJSON(tx, returnLegacyAddresses, noAsm, noScriptSig); txJson.vout = await TxOutputsToJSON(tx, returnLegacyAddresses, noAsm, noSpend); txJson.confirmations = confirmed? getLastHeightResult.Result - blockHeight + 1 : 0; txJson.isCoinBase = tx.IsCoinbase; txJson.valueOut = Utils.SatoshisToCoinUnits(tx.TotalOutputValue); txJson.size = tx.GetSerializedSize(); UInt64 inputsTotal = await ManuallyCalculateInputsTotal(tx); //TODO Solve at native layer txJson.valueIn = Utils.SatoshisToCoinUnits(inputsTotal); if (confirmed) { txJson.blockhash = blockHash; txJson.time = blockTimestamp; txJson.blocktime = blockTimestamp; txJson.blockheight = (Int64)blockHeight; } else { txJson.blockheight = -1; txJson.time = (UInt32)DateTimeOffset.UtcNow.ToUnixTimeSeconds(); } if (!tx.IsCoinbase) { txJson.fees = Utils.SatoshisToCoinUnits(inputsTotal - tx.TotalOutputValue); //TODO Solve at native layer } return(txJson); }
private async Task <GetLastBlock> GetLastBlock() { if (!memoryCache_.TryGetValue(Constants.Cache.LAST_BLOCK_HEIGHT_CACHE_KEY, out ulong currentHeight)) { var getLastHeightResult = await chain_.FetchLastHeightAsync(); Utils.CheckBitprimApiErrorCode(getLastHeightResult.ErrorCode, "FetchLastHeightAsync() failed"); currentHeight = getLastHeightResult.Result; memoryCache_.Set(Constants.Cache.LAST_BLOCK_HEIGHT_CACHE_KEY, currentHeight, new MemoryCacheEntryOptions { AbsoluteExpirationRelativeToNow = Constants.Cache.LAST_BLOCK_HEIGHT_MAX_AGE, Size = Constants.Cache.LAST_BLOCK_HEIGHT_ENTRY_SIZE }); } if (!memoryCache_.TryGetValue(Constants.Cache.LAST_BLOCK_CACHE_KEY, out GetLastBlock ret)) { using (var getBlockDataResult = await chain_.FetchBlockHeaderByHeightAsync(currentHeight)) { Utils.CheckBitprimApiErrorCode(getBlockDataResult.ErrorCode, "FetchBlockHeaderByHeightAsync(" + currentHeight + ") failed"); ret = new GetLastBlock { BlockHeight = getBlockDataResult.Result.BlockHeight , Bits = getBlockDataResult.Result.BlockData.Bits , Hash = getBlockDataResult.Result.BlockData.Hash }; memoryCache_.Set(Constants.Cache.LAST_BLOCK_CACHE_KEY, ret, new MemoryCacheEntryOptions { AbsoluteExpirationRelativeToNow = Constants.Cache.LAST_BLOCK_MAX_AGE, Size = Constants.Cache.LAST_BLOCK_ENTRY_SIZE }); } } return(ret); }
private async Task <List <BlockSummary> > GetPreviousBlocks(UInt64 startingHeight, UInt64 blockCount, long initialTimeStamp, long lastTimeStamp, UInt64 topHeight) { //Prerequisite: blockDateToSearch doesn't include Time. Only date. Kind UTC. var blocks = new List <BlockSummary>(); var blockWithinDate = true; for (UInt64 i = 0; i < blockCount && startingHeight >= i && blockWithinDate; i++) { using (var getHeaderResult = await chain_.FetchBlockHeaderByHeightAsync(startingHeight - i)) { Utils.CheckBitprimApiErrorCode(getHeaderResult.ErrorCode, "FetchBlockHeaderByHeightAsync(" + (startingHeight - i) + ") failed, check error log"); blockWithinDate = getHeaderResult.Result.BlockData.Timestamp >= initialTimeStamp && getHeaderResult.Result.BlockData.Timestamp <= lastTimeStamp; if (blockWithinDate) { blocks.Add(await GetBlockSummary(getHeaderResult.Result.BlockData, getHeaderResult.Result.BlockHeight, topHeight)); } } } return(blocks); }