public TxReceipt[] Get(Block block)
        {
            var receipts = _innerFinder.Get(block);

            _receiptsRecovery.TryRecover(block, receipts);
            return(receipts);
        }
        public TxReceipt[] Get(Block block)
        {
            var receipts = _receiptStorage.Get(block);

            if (_receiptsRecovery.TryRecover(block, receipts) == ReceiptsRecoveryResult.Success)
            {
                _receiptStorage.Insert(block, receipts);
            }

            return(receipts);
        }
示例#3
0
        public void Insert(Block block, params TxReceipt[] txReceipts)
        {
            txReceipts ??= Array.Empty <TxReceipt>();

            if (block.Transactions.Length != txReceipts.Length)
            {
                throw new ArgumentException($"Block {block.ToString(Block.Format.FullHashAndNumber)} has different number of transactions than receipts.");
            }

            _receiptsRecovery.TryRecover(block, txReceipts);

            var          blockNumber = block.Number;
            var          spec        = _specProvider.GetSpec(blockNumber);
            RlpBehaviors behaviors   = spec.IsEip658Enabled ? RlpBehaviors.Eip658Receipts | RlpBehaviors.Storage : RlpBehaviors.Storage;

            _blocksDb.Set(block.Hash, StorageDecoder.Encode(txReceipts, behaviors).Bytes);

            for (int i = 0; i < txReceipts.Length; i++)
            {
                var txHash = block.Transactions[i].Hash;
                _transactionDb.Set(txHash, block.Hash.Bytes);
            }

            if (blockNumber < (LowestInsertedReceiptBlock ?? long.MaxValue))
            {
                LowestInsertedReceiptBlock = blockNumber;
            }

            if (blockNumber < MigratedBlockNumber)
            {
                MigratedBlockNumber = blockNumber;
            }
        }
示例#4
0
        public void SetReceipts(int index, TxReceipt[] receipts)
        {
            if (!_downloadReceipts)
            {
                throw new InvalidOperationException($"Unexpected call to {nameof(SetReceipts)} when not downloading receipts");
            }

            int   mappedIndex = _indexMapping[index];
            Block block       = Blocks[_indexMapping[index]];

            if (receipts == null)
            {
                receipts = Array.Empty <TxReceipt>();
            }

            if (_receiptsRecovery.TryRecover(block, receipts))
            {
                ValidateReceipts(block, receipts);
                ReceiptsForBlocks[mappedIndex] = receipts;
            }
            else
            {
                throw new EthSyncException($"Missing receipts for block {block.ToString(Block.Format.Short)}.");
            }
        }
示例#5
0
        private IEnumerable <FilterLog> FilterLogsInBlockHighMemoryAllocation(LogFilter filter, Keccak blockHash, long blockNumber)
        {
            TxReceipt[] GetReceipts(Keccak hash, long number)
            {
                var canUseHash = _receiptFinder.CanGetReceiptsByHash(number);

                if (canUseHash)
                {
                    return(_receiptFinder.Get(hash));
                }
                else
                {
                    var block = _blockFinder.FindBlock(blockHash, BlockTreeLookupOptions.TotalDifficultyNotNeeded);
                    return(block == null ? null : _receiptFinder.Get(block));
                }
            }

            void RecoverReceiptsData(Keccak hash, TxReceipt[] receipts)
            {
                if (_receiptsRecovery.NeedRecover(receipts))
                {
                    var block = _blockFinder.FindBlock(hash, BlockTreeLookupOptions.TotalDifficultyNotNeeded);
                    if (block != null)
                    {
                        _receiptsRecovery.TryRecover(block, receipts);
                    }
                }
            }

            var  receipts        = GetReceipts(blockHash, blockNumber);
            long logIndexInBlock = 0;

            if (receipts != null)
            {
                for (var i = 0; i < receipts.Length; i++)
                {
                    var receipt = receipts[i];

                    if (filter.Matches(receipt.Bloom))
                    {
                        for (var j = 0; j < receipt.Logs.Length; j++)
                        {
                            var log = receipt.Logs[j];
                            if (filter.Accepts(log))
                            {
                                RecoverReceiptsData(blockHash, receipts);
                                yield return(new FilterLog(logIndexInBlock, j, receipt, log));
                            }

                            logIndexInBlock++;
                        }
                    }
                    else
                    {
                        logIndexInBlock += receipt.Logs.Length;
                    }
                }
            }
        }
示例#6
0
        public static TxReceipt[] FindForBlock(this IReceiptStorage receiptStorage, Block block, IReceiptsRecovery receiptsRecovery)
        {
            TxReceipt[] result = new TxReceipt[block.Body.Transactions.Length];
            for (int i = 0; i < result.Length; i++)
            {
                result[i] = receiptStorage.Find(block.Body.Transactions[i].Hash);
            }

            receiptsRecovery.TryRecover(block, result);

            return(result);
        }
示例#7
0
        public void SetReceipts(int index, TxReceipt[] receipts)
        {
            if (!_downloadReceipts)
            {
                throw new InvalidOperationException($"Unexpected call to {nameof(SetReceipts)} when not downloading receipts");
            }

            int   mappedIndex = _indexMapping[index];
            Block block       = Blocks[_indexMapping[index]];

            receipts ??= Array.Empty <TxReceipt>();

            if (_receiptsRecovery.TryRecover(block, receipts))
            {
                ValidateReceipts(block, receipts);
                ReceiptsForBlocks ![mappedIndex] = receipts;
示例#8
0
        public bool TrySetReceipts(int index, TxReceipt[]?receipts, out Block block)
        {
            if (!_downloadReceipts)
            {
                throw new InvalidOperationException($"Unexpected call to {nameof(TrySetReceipts)} when not downloading receipts");
            }

            int mappedIndex = _indexMapping[index];

            block = Blocks[_indexMapping[index]];
            receipts ??= Array.Empty <TxReceipt>();

            bool result = _receiptsRecovery.TryRecover(block, receipts, false) != ReceiptsRecoveryResult.Fail;

            if (result)
            {
                ValidateReceipts(block, receipts);
                ReceiptsForBlocks ![mappedIndex] = receipts;
示例#9
0
    public void TryRecover_should_return_correct_receipts_recovery_result(int blockTxsLength, int receiptsLength, bool forceRecoverSender, ReceiptsRecoveryResult expected)
    {
        Transaction[] txs = new Transaction[blockTxsLength];
        for (int i = 0; i < blockTxsLength; i++)
        {
            txs[i] = Build.A.Transaction.SignedAndResolved().TestObject;
        }

        Block block = Build.A.Block.WithTransactions(txs).TestObject;

        TxReceipt[] receipts = new TxReceipt[receiptsLength];
        for (int i = 0; i < receiptsLength; i++)
        {
            receipts[i] = Build.A.Receipt.WithBlockHash(block.Hash).TestObject;
        }

        _receiptsRecovery.TryRecover(block, receipts, forceRecoverSender).Should().Be(expected);
    }