Пример #1
0
        // https://github.com/ethereum/EIPs/issues/1186
        public ResultWrapper <AccountProof> eth_getProof(Address accountAddress, byte[][] storageKeys, BlockParameter blockParameter)
        {
            BlockHeader header;

            try
            {
                header = _blockchainBridge.FindHeader(blockParameter);
                if (header == null)
                {
                    return(ResultWrapper <AccountProof> .Fail($"{blockParameter} block not found", ErrorCodes.ResourceNotFound, null));
                }
            }
            catch (Exception ex)
            {
                return(ResultWrapper <AccountProof> .Fail(ex.Message, ErrorCodes.InternalError, null));
            }

            AccountProofCollector accountProofCollector = new AccountProofCollector(accountAddress, storageKeys);

            _blockchainBridge.RunTreeVisitor(accountProofCollector, header.StateRoot);

            return(ResultWrapper <AccountProof> .Success(accountProofCollector.BuildResult()));
        }
Пример #2
0
        private async Task <ResultWrapper <Keccak> > SendTx(Transaction tx,
                                                            TxHandlingOptions txHandlingOptions = TxHandlingOptions.None)
        {
            try
            {
                Keccak txHash =
                    await _txSender.SendTransaction(tx, txHandlingOptions | TxHandlingOptions.PersistentBroadcast);

                return(ResultWrapper <Keccak> .Success(txHash));
            }
            catch (SecurityException e)
            {
                return(ResultWrapper <Keccak> .Fail(e.Message, ErrorCodes.AccountLocked));
            }
            catch (Exception e)
            {
                if (_logger.IsError)
                {
                    _logger.Error("Failed to send transaction.", e);
                }
                return(ResultWrapper <Keccak> .Fail(e.Message, ErrorCodes.TransactionRejected));
            }
        }
Пример #3
0
        public Task <ResultWrapper <bool> > baseline_track(Address contractAddress)
        {
            ResultWrapper <bool> result;

            // can potentially warn user if tree is not deployed at the address
            if (contractAddress == null)
            {
                result = ResultWrapper <bool> .Fail("Contract address was NULL");
            }
            else if (TryAddTree(contractAddress))
            {
                UpdateMetadata(contractAddress);
                result = ResultWrapper <bool> .Success(true);
            }
            else
            {
                result = ResultWrapper <bool> .Fail(
                    $"{contractAddress} is already tracked or no contract at given address",
                    ErrorCodes.InvalidInput);
            }

            return(Task.FromResult(result));
        }
Пример #4
0
        public ResultWrapper <byte[]> eth_sign(Address addressData, byte[] message)
        {
            Signature sig;

            try
            {
                Address      address           = addressData;
                string       messageText       = _messageEncoding.GetString(message);
                const string signatureTemplate = "\x19Ethereum Signed Message:\n{0}{1}";
                string       signatureText     = string.Format(signatureTemplate, messageText.Length, messageText);
                sig = _blockchainBridge.Sign(address, Keccak.Compute(signatureText));
            }
            catch (Exception)
            {
                return(ResultWrapper <byte[]> .Fail($"Unable to sign as {addressData}"));
            }

            if (_logger.IsTrace)
            {
                _logger.Trace($"eth_sign request {addressData}, {message}, result: {sig}");
            }
            return(ResultWrapper <byte[]> .Success(sig.Bytes));
        }
Пример #5
0
        public ResultWrapper <TransactionForRpc> eth_getTransactionByHash(Keccak transactionHash)
        {
            try
            {
                _readerWriterLockSlim.EnterReadLock();
                (Core.TransactionReceipt receipt, Transaction transaction) = _blockchainBridge.GetTransaction(transactionHash);
                if (transaction == null)
                {
                    return(ResultWrapper <TransactionForRpc> .Fail($"Cannot find transaction for hash: {transactionHash}", ErrorType.NotFound));
                }

                var transactionModel = new TransactionForRpc(receipt.BlockHash, receipt.BlockNumber, receipt.Index, transaction);
                if (Logger.IsTrace)
                {
                    Logger.Trace($"eth_getTransactionByHash request {transactionHash}, result: {transactionModel.Hash}");
                }
                return(ResultWrapper <TransactionForRpc> .Success(transactionModel));
            }
            finally
            {
                _readerWriterLockSlim.ExitReadLock();
            }
        }
Пример #6
0
        public ValueTask <ResultWrapper <Keccak> > deposit_deploy(Address senderAddress)
        {
            ResultWrapper <Keccak> result;

            if (_depositContract == null)
            {
                result = ResultWrapper <Keccak> .Fail("Deposit contract address not specified.", ErrorCodes.InternalError);

                return(new ValueTask <ResultWrapper <Keccak> >(result));
            }

            Transaction tx     = _depositContract.Deploy(senderAddress);
            Keccak      txHash = _txPoolBridge.SendTransaction(tx, TxHandlingOptions.ManagedNonce);

            if (_logger.IsInfo)
            {
                _logger.Info($"Sent transaction at price {tx.GasPrice} to {tx.SenderAddress}");
            }

            result = ResultWrapper <Keccak> .Success(txHash);

            return(new ValueTask <ResultWrapper <Keccak> >(result));
        }
Пример #7
0
        public ResultWrapper <BlockForRpc> eth_getBlockByHash(Keccak blockHash, bool returnFullTransactionObjects)
        {
            try
            {
                _readerWriterLockSlim.EnterReadLock();
                var block = _blockchainBridge.FindBlock(blockHash, false);
                if (block == null)
                {
                    return(ResultWrapper <BlockForRpc> .Fail($"Cannot find block for hash: {blockHash}", ErrorType.NotFound));
                }


                if (Logger.IsDebug)
                {
                    Logger.Debug($"eth_getBlockByHash request {blockHash}, result: {block}");
                }
                return(ResultWrapper <BlockForRpc> .Success(new BlockForRpc(block, returnFullTransactionObjects)));
            }
            finally
            {
                _readerWriterLockSlim.ExitReadLock();
            }
        }
Пример #8
0
        private ResultWrapper <Core.Block> GetBlock(BlockParameter blockParameter)
        {
            switch (blockParameter.Type)
            {
            case BlockParameterType.Pending:
                var pending = _blockchainBridge.FindBlock(_blockchainBridge.BestSuggested.Hash, false);
                return(ResultWrapper <Core.Block> .Success(pending));  // TODO: a pending block for sealEngine, work in progress

            case BlockParameterType.Latest:
                return(ResultWrapper <Core.Block> .Success(_blockchainBridge.RetrieveHeadBlock()));

            case BlockParameterType.Earliest:
                var genesis = _blockchainBridge.RetrieveGenesisBlock();
                return(ResultWrapper <Core.Block> .Success(genesis));

            case BlockParameterType.BlockId:
                if (blockParameter.BlockId?.Value == null)
                {
                    return(ResultWrapper <Core.Block> .Fail($"Block id is required for {BlockParameterType.BlockId}", ErrorType.InvalidParams));
                }
                var value = blockParameter.BlockId.GetValue();
                if (!value.HasValue)
                {
                    return(ResultWrapper <Core.Block> .Fail("Invalid block id", ErrorType.InvalidParams));
                }
                throw new NotImplementedException();     // TODO: TKS - discuss with me later, there was a rebuilt of BlockStore / Blockchain, work in progress now, so just commenting it out

//                    var block = _blockTree.FindBlock(value.Value);
//                    if (block == null)
//                    {
//                        return ResultWrapper<Core.Block>.Fail($"Cannot find block for {value.Value}", ErrorType.NotFound);
//                    }
//                    return ResultWrapper<Core.Block>.Success(block);
            default:
                throw new Exception($"BlockParameterType not supported: {blockParameter.Type}");
            }
        }
Пример #9
0
        public ResultWrapper <Block> eth_getUncleByBlockNumberAndIndex(BlockParameter blockParameter, Quantity positionIndex)
        {
            if (_blockchainBridge.Head == null)
            {
                return(ResultWrapper <Block> .Fail($"Incorrect head block: {(_blockchainBridge.Head != null ? "HeadBlock is null" : "HeadBlock header is null")}"));
            }

            var result = GetBlock(blockParameter);

            if (result.Result.ResultType == ResultType.Failure)
            {
                return(ResultWrapper <Block> .Fail(result.Result.Error, result.ErrorType));
            }

            var index = positionIndex.GetValue();

            if (!index.HasValue)
            {
                return(ResultWrapper <Block> .Fail("Position Index is required", ErrorType.InvalidParams));
            }
            if (index.Value < 0 || index.Value > result.Data.Ommers.Length - 1)
            {
                return(ResultWrapper <Block> .Fail("Position Index is incorrect", ErrorType.InvalidParams));
            }

            var ommerHeader = result.Data.Ommers[(int)index.Value];
            var ommer       = _blockchainBridge.FindBlock(ommerHeader.Hash, false);

            if (ommer == null)
            {
                return(ResultWrapper <Block> .Fail($"Cannot find ommer for hash: {ommerHeader.Hash}", ErrorType.NotFound));
            }
            var blockModel = _modelMapper.MapBlock(ommer, false);

            Logger.Debug($"eth_getUncleByBlockNumberAndIndex request {blockParameter}, index: {positionIndex.ToJson()}, result: {GetJsonLog(blockModel.ToJson())}");
            return(ResultWrapper <Block> .Success(blockModel));
        }
Пример #10
0
        public Task <ResultWrapper <Keccak> > baseline_getRoot(
            Address contractAddress,
            BlockParameter?blockParameter = null)
        {
            bool isTracked = TryGetTracked(contractAddress, out BaselineTree? tree);

            ResultWrapper <Keccak> result;

            if (!isTracked || tree == null)
            {
                result = ResultWrapper <Keccak> .Fail(
                    $"{contractAddress} tree is not tracked",
                    ErrorCodes.InvalidInput);
            }
            else
            {
                if (blockParameter == null || blockParameter == BlockParameter.Latest)
                {
                    result = ResultWrapper <Keccak> .Success(tree.Root);
                }
                else
                {
                    SearchResult <BlockHeader> searchResult = _blockFinder.SearchForHeader(blockParameter);
                    if (searchResult.IsError)
                    {
                        result = ResultWrapper <Keccak> .Fail(searchResult);
                    }
                    else
                    {
                        var historicalTree = _baselineTreeHelper.CreateHistoricalTree(contractAddress, searchResult.Object.Number);
                        result = ResultWrapper <Keccak> .Success(historicalTree.Root);
                    }
                }
            }

            return(Task.FromResult(result));
        }
Пример #11
0
        private ResultWrapper <Core.Block> GetBlock(BlockParameter blockParameter)
        {
            switch (blockParameter.Type)
            {
            case BlockParameterType.Pending:
                var pending = _blockchainBridge.FindBlock(_blockchainBridge.BestSuggested.Hash, false);
                return(ResultWrapper <Core.Block> .Success(pending));  // TODO: a pending block for sealEngine, work in progress

            case BlockParameterType.Latest:
                return(ResultWrapper <Core.Block> .Success(_blockchainBridge.RetrieveHeadBlock()));

            case BlockParameterType.Earliest:
                var genesis = _blockchainBridge.RetrieveGenesisBlock();
                return(ResultWrapper <Core.Block> .Success(genesis));

            case BlockParameterType.BlockId:
                if (blockParameter.BlockId?.Value == null)
                {
                    return(ResultWrapper <Core.Block> .Fail($"Block id is required for {BlockParameterType.BlockId}", ErrorType.InvalidParams));
                }
                var value = blockParameter.BlockId.GetValue();
                if (!value.HasValue)
                {
                    return(ResultWrapper <Core.Block> .Fail("Invalid block id", ErrorType.InvalidParams));
                }

                var block = _blockchainBridge.FindBlock(new UInt256(value.Value));
                if (block == null)
                {
                    return(ResultWrapper <Core.Block> .Fail($"Cannot find block for {value.Value}", ErrorType.NotFound));
                }
                return(ResultWrapper <Core.Block> .Success(block));

            default:
                throw new Exception($"BlockParameterType not supported: {blockParameter.Type}");
            }
        }
Пример #12
0
        public ResultWrapper <TransactionForRpc> eth_getTransactionByBlockHashAndIndex(Keccak blockHash, UInt256 positionIndex)
        {
            SearchResult <Block> searchResult = _blockFinder.SearchForBlock(new BlockParameter(blockHash));

            if (searchResult.IsError)
            {
                return(ResultWrapper <TransactionForRpc> .Fail(searchResult));
            }

            Block block = searchResult.Object;

            if (positionIndex < 0 || positionIndex > block.Transactions.Length - 1)
            {
                return(ResultWrapper <TransactionForRpc> .Fail("Position Index is incorrect", ErrorCodes.InvalidParams));
            }

            Transaction transaction = block.Transactions[(int)positionIndex];

            RecoverTxSenderIfNeeded(transaction);

            TransactionForRpc transactionModel = new TransactionForRpc(block.Hash, block.Number, (int)positionIndex, transaction);

            return(ResultWrapper <TransactionForRpc> .Success(transactionModel));
        }
Пример #13
0
        public ResultWrapper <string> eth_call(TransactionForRpc transactionCall, BlockParameter blockParameter = null)
        {
            SearchResult <BlockHeader> searchResult = _blockFinder.SearchForHeader(blockParameter);

            if (searchResult.IsError)
            {
                return(ResultWrapper <string> .Fail(searchResult));
            }

            BlockHeader header = searchResult.Object;

            if (!HasStateForBlock(header))
            {
                return(ResultWrapper <string> .Fail($"No state available for block {header.Hash}", ErrorCodes.ResourceUnavailable));
            }

            FixCallTx(transactionCall, header);

            Transaction tx = transactionCall.ToTransaction();

            BlockchainBridge.CallOutput result = _blockchainBridge.Call(header, tx);

            return(result.Error != null ? ResultWrapper <string> .Fail("VM execution error.", ErrorCodes.ExecutionError, result.Error) : ResultWrapper <string> .Success(result.OutputData.ToHexString(true)));
        }
Пример #14
0
        public async Task <ResultWrapper <Keccak> > baseline_deploy(Address address, string contractType)
        {
            ResultWrapper <Keccak> result;

            try
            {
                var bytecode = await GetContractBytecode(contractType);

                try
                {
                    Keccak txHash = await DeployBytecode(address, contractType, bytecode);

                    result = ResultWrapper <Keccak> .Success(txHash);
                }
                catch (Exception e)
                {
                    result = ResultWrapper <Keccak> .Fail(
                        $"Provided bytecode could not be deployed. {e}",
                        ErrorCodes.InternalError);
                }
            }
            catch (IOException e)
            {
                result = ResultWrapper <Keccak> .Fail(
                    $"{contractType} bytecode could not be loaded. {e}",
                    ErrorCodes.ResourceNotFound);
            }
            catch (Exception e)
            {
                result = ResultWrapper <Keccak> .Fail(
                    $"{contractType} bytecode could not be loaded. {e}",
                    ErrorCodes.InternalError);
            }

            return(result);
        }
Пример #15
0
        public ResultWrapper <Transaction> eth_getTransactionByBlockNumberAndIndex(BlockParameter blockParameter, Quantity positionIndex)
        {
            if (_blockchainBridge.Head == null)
            {
                return(ResultWrapper <Transaction> .Fail($"Incorrect head block: {(_blockchainBridge.Head != null ? "HeadBlock is null" : "HeadBlock header is null")}"));
            }

            var result = GetBlock(blockParameter);

            if (result.Result.ResultType == ResultType.Failure)
            {
                return(ResultWrapper <Transaction> .Fail(result.Result.Error, result.ErrorType));
            }

            var index = positionIndex.AsNumber();

            if (!index.HasValue)
            {
                return(ResultWrapper <Transaction> .Fail("Position Index is required", ErrorType.InvalidParams));
            }

            if (index.Value < 0 || index.Value > result.Data.Transactions.Length - 1)
            {
                return(ResultWrapper <Transaction> .Fail("Position Index is incorrect", ErrorType.InvalidParams));
            }

            Core.Block block            = result.Data;
            var        transaction      = block.Transactions[(int)index.Value];
            var        transactionModel = _modelMapper.MapTransaction(block.Hash, block.Number, (int)index.Value, transaction);

            if (Logger.IsDebug)
            {
                Logger.Debug($"eth_getTransactionByBlockNumberAndIndex request {blockParameter}, index: {positionIndex.ToJson()}, result: {GetJsonLog(transactionModel.ToJson())}");
            }
            return(ResultWrapper <Transaction> .Success(transactionModel));
        }
Пример #16
0
        public ResultWrapper <TransactionTrace> debug_traceTransactionByBlockAndIndex(BlockParameter blockParameter, int index)
        {
            UInt256?blockNo = blockParameter.BlockId.AsNumber();

            if (!blockNo.HasValue)
            {
                throw new InvalidDataException("Block number value incorrect");
            }

            var transactionTrace = _debugBridge.GetTransactionTrace(blockNo.Value, index);

            if (transactionTrace == null)
            {
                return(ResultWrapper <TransactionTrace> .Fail($"Cannot find transactionTrace {blockNo}", ErrorType.NotFound));
            }

            var transactionModel = _modelMapper.MapTransactionTrace(transactionTrace);

            if (Logger.IsTrace)
            {
                Logger.Trace($"{nameof(debug_traceTransactionByBlockAndIndex)} request {blockNo}, result: {GetJsonLog(transactionModel.ToJson())}");
            }
            return(ResultWrapper <TransactionTrace> .Success(transactionModel));
        }
Пример #17
0
        public ResultWrapper <BlockTraceItem[]> debug_traceBlockByNumber(Quantity blockNumber)
        {
            UInt256?blockNo = blockNumber.AsNumber();

            if (!blockNo.HasValue)
            {
                throw new InvalidDataException("Expected block number value");
            }

            var blockTrace = _debugBridge.GetBlockTrace(blockNo.Value);

            if (blockTrace == null)
            {
                return(ResultWrapper <BlockTraceItem[]> .Fail($"Trace is null for block {blockNo}", ErrorType.NotFound));
            }

            var blockTraceModel = _modelMapper.MapBlockTrace(blockTrace);

            if (Logger.IsTrace)
            {
                Logger.Trace($"{nameof(debug_traceBlockByNumber)} request {blockNumber}, result: {GetJsonLog(blockTraceModel.Select(btm => btm.ToJson()))}");
            }
            return(ResultWrapper <BlockTraceItem[]> .Success(blockTraceModel));
        }
Пример #18
0
        public Task <ResultWrapper <long> > baseline_getCount(
            Address contractAddress,
            BlockParameter?blockParameter = null)
        {
            bool isTracked = TryGetTracked(contractAddress, out BaselineTree? tree);

            ResultWrapper <long> result;

            if (!isTracked || tree == null)
            {
                result = ResultWrapper <long> .Fail(
                    $"{contractAddress} tree is not tracked",
                    ErrorCodes.InvalidInput);
            }
            else
            {
                if (blockParameter == null)
                {
                    result = ResultWrapper <long> .Success(tree.Count);
                }
                else
                {
                    SearchResult <BlockHeader> searchResult = _blockFinder.SearchForHeader(blockParameter);
                    if (searchResult.IsError)
                    {
                        result = ResultWrapper <long> .Fail(searchResult);
                    }
                    else
                    {
                        result = ResultWrapper <long> .Success(tree.GetBlockCount(searchResult.Object.Number));
                    }
                }
            }

            return(Task.FromResult(result));
        }
Пример #19
0
    public ResultWrapper <IEnumerable <object> > eth_getFilterChanges(UInt256 filterId)
    {
        int        id         = (int)filterId;
        FilterType filterType = _blockchainBridge.GetFilterType(id);

        switch (filterType)
        {
        case FilterType.BlockFilter:
            {
                return(_blockchainBridge.FilterExists(id)
                    ? ResultWrapper <IEnumerable <object> > .Success(_blockchainBridge.GetBlockFilterChanges(id))
                    : ResultWrapper <IEnumerable <object> > .Fail($"Filter with id: '{filterId}' does not exist."));
            }

        case FilterType.PendingTransactionFilter:
        {
            return(_blockchainBridge.FilterExists(id)
                    ? ResultWrapper <IEnumerable <object> > .Success(_blockchainBridge
                                                                     .GetPendingTransactionFilterChanges(id))
                    : ResultWrapper <IEnumerable <object> > .Fail($"Filter with id: '{filterId}' does not exist."));
        }

        case FilterType.LogFilter:
        {
            return(_blockchainBridge.FilterExists(id)
                    ? ResultWrapper <IEnumerable <object> > .Success(
                       _blockchainBridge.GetLogFilterChanges(id).ToArray())
                    : ResultWrapper <IEnumerable <object> > .Fail($"Filter with id: '{filterId}' does not exist."));
        }

        default:
        {
            throw new NotSupportedException($"Filter type {filterType} is not supported");
        }
        }
    }
Пример #20
0
        public ResultWrapper <IEnumerable <FilterLog> > eth_getLogs(Filter filter)
        {
            IEnumerable <FilterLog> GetLogs(BlockParameter blockParameter, BlockParameter toBlockParameter,
                                            CancellationTokenSource cancellationTokenSource, CancellationToken token)
            {
                using (cancellationTokenSource)
                {
                    foreach (FilterLog log in _blockchainBridge.GetLogs(blockParameter, toBlockParameter,
                                                                        filter.Address, filter.Topics, token))
                    {
                        yield return(log);
                    }
                }
            }

            BlockParameter fromBlock = filter.FromBlock;
            BlockParameter toBlock   = filter.ToBlock;

            try
            {
                CancellationTokenSource cancellationTokenSource = new(_rpcConfig.Timeout);
                return(ResultWrapper <IEnumerable <FilterLog> > .Success(GetLogs(fromBlock, toBlock,
                                                                                 cancellationTokenSource, cancellationTokenSource.Token)));
            }
            catch (ArgumentException e)
            {
                switch (e.Message)
                {
                case ILogFinder.NotFoundError:
                    return(ResultWrapper <IEnumerable <FilterLog> > .Fail(e.Message, ErrorCodes.ResourceNotFound));

                default:
                    return(ResultWrapper <IEnumerable <FilterLog> > .Fail(e.Message, ErrorCodes.InvalidParams));
                }
            }
        }
Пример #21
0
        public ResultWrapper <TransactionForRpc> eth_getTransactionByBlockNumberAndIndex(BlockParameter blockParameter, BigInteger positionIndex)
        {
            try
            {
                _readerWriterLockSlim.EnterReadLock();
                if (_blockchainBridge.Head == null)
                {
                    return(ResultWrapper <TransactionForRpc> .Fail($"Incorrect head block"));
                }

                var result = GetBlock(blockParameter);
                if (result.Result.ResultType == ResultType.Failure)
                {
                    return(ResultWrapper <TransactionForRpc> .Fail(result.Result.Error, result.ErrorType));
                }

                if (positionIndex < 0 || positionIndex > result.Data.Transactions.Length - 1)
                {
                    return(ResultWrapper <TransactionForRpc> .Fail("Position Index is incorrect", ErrorType.InvalidParams));
                }

                Block block            = result.Data;
                var   transaction      = block.Transactions[(int)positionIndex];
                var   transactionModel = new TransactionForRpc(block.Hash, block.Number, (int)positionIndex, transaction);

                if (Logger.IsDebug)
                {
                    Logger.Debug($"eth_getTransactionByBlockNumberAndIndex request {blockParameter}, index: {positionIndex}, result: {transactionModel.Hash}");
                }
                return(ResultWrapper <TransactionForRpc> .Success(transactionModel));
            }
            finally
            {
                _readerWriterLockSlim.ExitReadLock();
            }
        }
Пример #22
0
        public ResultWrapper <Data> eth_sign(Data address, Data message)
        {
            //TODO check how to deal with password
            SecureString secureString = new SecureString();

            secureString.AppendChar('?');

            var privateKey = _blockchainBridge.GetKey(new Address(address.Value), secureString);

            if (privateKey.Item2.ResultType == ResultType.Failure)
            {
                return(ResultWrapper <Data> .Fail("Incorrect address"));
            }

            var messageText   = Encoding.GetEncoding(ConfigurationProvider.MessageEncoding).GetString(message.Value);
            var signatureText = string.Format(ConfigurationProvider.SignatureTemplate, messageText.Length, messageText);
            var signature     = _blockchainBridge.Sign(privateKey.Item1, Keccak.Compute(signatureText));

            if (Logger.IsTrace)
            {
                Logger.Trace($"eth_sign request {address.ToJson()}, {message.ToJson()}, result: {signature}");
            }
            return(ResultWrapper <Data> .Success(new Data(signature.Bytes)));
        }
Пример #23
0
 public ResultWrapper <byte[]> eth_snapshot()
 {
     return(ResultWrapper <byte[]> .Fail("eth_snapshot not supported"));
 }
Пример #24
0
 public ResultWrapper <bool?> eth_submitHashrate(string hashRate, string id)
 {
     return(ResultWrapper <bool?> .Fail("eth_submitHashrate not supported", ErrorType.MethodNotFound, null));
 }
Пример #25
0
 public ResultWrapper <bool?> eth_submitWork(byte[] nonce, Keccak headerPowHash, byte[] mixDigest)
 {
     return(ResultWrapper <bool?> .Fail("eth_submitWork not supported", ErrorType.MethodNotFound, null));
 }
Пример #26
0
 public ResultWrapper <IEnumerable <byte[]> > eth_getWork()
 {
     return(ResultWrapper <IEnumerable <byte[]> > .Fail("eth_getWork not supported"));
 }
Пример #27
0
 public ResultWrapper <bool> eth_submitHashrate(string hashRate, string id)
 {
     return(ResultWrapper <bool> .Fail("eth_submitHashrate not supported"));
 }
Пример #28
0
 protected ResultWrapper <TResult> GetInputError(BlockchainBridge.CallOutput result) =>
 ResultWrapper <TResult> .Fail(result.Error ?? string.Empty, ErrorCodes.InvalidInput);
Пример #29
0
 public ResultWrapper <IEnumerable <byte[]> > eth_getWork()
 {
     return(ResultWrapper <IEnumerable <byte[]> > .Fail("eth_getWork not supported", ErrorCodes.MethodNotFound));
 }
Пример #30
0
    public ResultWrapper <IEnumerable <FilterLog> > eth_getLogs(Filter filter)
    {
        IEnumerable <FilterLog> GetLogs(IEnumerable <FilterLog> logs, CancellationTokenSource cancellationTokenSource)
        {
            using (cancellationTokenSource)
            {
                foreach (FilterLog log in logs)
                {
                    yield return(log);
                }
            }
        }

        // because of lazy evaluation of enumerable, we need to do the validation here first
        CancellationTokenSource cancellationTokenSource = new(_rpcConfig.Timeout);
        CancellationToken       cancellationToken       = cancellationTokenSource.Token;

        SearchResult <BlockHeader> fromBlockResult;
        SearchResult <BlockHeader> toBlockResult;

        if (filter.FromBlock == filter.ToBlock)
        {
            fromBlockResult = toBlockResult = _blockFinder.SearchForHeader(filter.ToBlock);
        }
        else
        {
            toBlockResult = _blockFinder.SearchForHeader(filter.ToBlock);

            if (toBlockResult.IsError)
            {
                cancellationTokenSource.Dispose();

                return(ResultWrapper <IEnumerable <FilterLog> > .Fail(toBlockResult));
            }

            cancellationToken.ThrowIfCancellationRequested();

            fromBlockResult = _blockFinder.SearchForHeader(filter.FromBlock);
        }

        if (fromBlockResult.IsError)
        {
            cancellationTokenSource.Dispose();

            return(ResultWrapper <IEnumerable <FilterLog> > .Fail(fromBlockResult));
        }

        cancellationToken.ThrowIfCancellationRequested();

        long fromBlockNumber = fromBlockResult.Object !.Number;
        long toBlockNumber   = toBlockResult.Object !.Number;

        if (fromBlockNumber > toBlockNumber && toBlockNumber != 0)
        {
            cancellationTokenSource.Dispose();

            return(ResultWrapper <IEnumerable <FilterLog> > .Fail($"'From' block '{fromBlockNumber}' is later than 'to' block '{toBlockNumber}'.", ErrorCodes.InvalidParams));
        }

        try
        {
            IEnumerable <FilterLog> filterLogs = _blockchainBridge.GetLogs(filter.FromBlock, filter.ToBlock,
                                                                           filter.Address, filter.Topics, cancellationToken);

            return(ResultWrapper <IEnumerable <FilterLog> > .Success(GetLogs(filterLogs, cancellationTokenSource)));
        }
        catch (ResourceNotFoundException exception)
        {
            return(ResultWrapper <IEnumerable <FilterLog> > .Fail(exception.Message, ErrorCodes.ResourceNotFound));
        }
    }