Exemplo n.º 1
0
        private static async Task <HashSet <string> > GetAddressFromInput(Executor executor, ITransaction tx)
        {
            var ret = new HashSet <string>();

            if (tx.IsCoinbase)
            {
                return(ret);
            }

            foreach (Input input in tx.Inputs)
            {
                OutputPoint previousOutput = input.PreviousOutput;

                using (DisposableApiCallResult <GetTxDataResult> getTxResult = await executor.Chain.FetchTransactionAsync(previousOutput.Hash, false))
                {
                    Utils.CheckBitprimApiErrorCode(getTxResult.ErrorCode, "FetchTransactionAsync(" + Binary.ByteArrayToHexString(previousOutput.Hash) + ") failed, check errog log");

                    Output output = getTxResult.Result.Tx.Outputs[previousOutput.Index];

                    PaymentAddress outputAddress = output.PaymentAddress(executor.UseTestnetRules);
                    if (outputAddress.IsValid)
                    {
                        ret.Add(outputAddress.Encoded);
                    }
                }
            }

            return(ret);
        }
        public async Task <ActionResult> GetBlockByHash(string hash, int noTxList = 1)
        {
            if (!Validations.IsValidHash(hash))
            {
                return(BadRequest(hash + " is not a valid block hash"));
            }

            Utils.CheckIfChainIsFresh(chain_, config_.AcceptStaleRequests);

            string key = "block" + noTxList + hash;

            if (memoryCache_.TryGetValue(key, out JsonResult cachedBlockJson))
            {
                return(cachedBlockJson);
            }
            ;

            var binaryHash = Binary.HexStringToByteArray(hash);

            using (DisposableApiCallResult <GetBlockHeaderByHashTxSizeResult> getBlockResult = await chain_.FetchBlockHeaderByHashTxSizesAsync(binaryHash))
            {
                Utils.CheckBitprimApiErrorCode(getBlockResult.ErrorCode, "FetchBlockHeaderByHashTxSizesAsync(" + hash + ") failed, check error log");

                var getLastHeightResult = await chain_.FetchLastHeightAsync();

                Utils.CheckBitprimApiErrorCode(getLastHeightResult.ErrorCode, "FetchLastHeightAsync() failed, check error log");

                var blockHeight = getBlockResult.Result.Header.BlockHeight;

                ApiCallResult <GetBlockHashTimestampResult> getNextBlockResult = null;
                if (blockHeight != getLastHeightResult.Result)
                {
                    getNextBlockResult = await chain_.FetchBlockByHeightHashTimestampAsync(blockHeight + 1);

                    Utils.CheckBitprimApiErrorCode(getNextBlockResult.ErrorCode, "FetchBlockByHeightHashTimestampAsync(" + blockHeight + 1 + ") failed, check error log");
                }

                decimal  blockReward;
                PoolInfo poolInfo;
                using (DisposableApiCallResult <GetTxDataResult> coinbase = await chain_.FetchTransactionAsync(getBlockResult.Result.TransactionHashes[0], true))
                {
                    Utils.CheckBitprimApiErrorCode(coinbase.ErrorCode, "FetchTransactionAsync(" + getBlockResult.Result.TransactionHashes[0] + ") failed, check error log");
                    blockReward = Utils.SatoshisToCoinUnits(coinbase.Result.Tx.TotalOutputValue);
                    poolInfo    = poolsInfo_.GetPoolInfo(coinbase.Result.Tx);
                }

                JsonResult blockJson = Json(BlockToJSON
                                            (
                                                getBlockResult.Result.Header.BlockData, blockHeight, getBlockResult.Result.TransactionHashes,
                                                blockReward, getLastHeightResult.Result, getNextBlockResult?.Result.BlockHash,
                                                getBlockResult.Result.SerializedBlockSize, poolInfo, noTxList == 0)
                                            );

                memoryCache_.Set(key, blockJson, new MemoryCacheEntryOptions {
                    Size = Constants.Cache.BLOCK_CACHE_ENTRY_SIZE
                });
                return(blockJson);
            }
        }
        private async Task <BlockSummary> GetBlockSummary(IHeader header, UInt64 height, UInt64 topHeight)
        {
            var hashStr = Binary.ByteArrayToHexString(header.Hash);
            var key     = "blockSummary" + hashStr;

            if (memoryCache_.TryGetValue(key, out BlockSummary ret))
            {
                return(ret);
            }

            using (var blockHeaderResult = await chain_.FetchBlockHeaderByHashTxSizesAsync(header.Hash))
            {
                Utils.CheckBitprimApiErrorCode(blockHeaderResult.ErrorCode,
                                               "FetchBlockHeaderByHashTxSizesAsync(" + header.Hash + ") failed, check error log");

                PoolInfo poolInfo;
                using (DisposableApiCallResult <GetTxDataResult> coinbase = await chain_.FetchTransactionAsync(blockHeaderResult.Result.TransactionHashes[0], true))
                {
                    Utils.CheckBitprimApiErrorCode(coinbase.ErrorCode, "FetchTransactionAsync(" + blockHeaderResult.Result.TransactionHashes[0] + ") failed, check error log");
                    poolInfo = poolsInfo_.GetPoolInfo(coinbase.Result.Tx);
                }

                var blockSummary = new BlockSummary
                {
                    height   = height,
                    size     = blockHeaderResult.Result.SerializedBlockSize,
                    hash     = Binary.ByteArrayToHexString(header.Hash),
                    time     = header.Timestamp,
                    txlength = blockHeaderResult.Result.TransactionHashes.Count,
                    poolInfo = new DTOs.PoolInfo {
                        poolName = poolInfo.Name, url = poolInfo.Url
                    }
                };

                var confirmations = topHeight - height + 1;
                if (confirmations >= Constants.Cache.BLOCK_CACHE_CONFIRMATIONS)
                {
                    memoryCache_.Set(key, blockSummary, new MemoryCacheEntryOptions {
                        Size = Constants.Cache.BLOCK_CACHE_SUMMARY_SIZE
                    });
                }

                return(blockSummary);
            }
        }