Beispiel #1
0
        private ResultWrapper <UInt256?> GetAccountNonce(Address address, BlockParameter blockParameter)
        {
            if (blockParameter.Type == BlockParameterType.Pending)
            {
                blockParameter.Type = BlockParameterType.Latest;
            }

            BlockHeader header;

            try
            {
                header = _blockchainBridge.GetHeader(blockParameter);
            }
            catch (JsonRpcException ex)
            {
                return(ResultWrapper <UInt256?> .Fail(ex.Message, ex.ErrorType, null));
            }

            if (header == null)
            {
                return(ResultWrapper <UInt256?> .Fail("Block not found", ErrorType.NotFound, null));
            }

            Account account = _blockchainBridge.GetAccount(address, header.StateRoot);

            return(ResultWrapper <UInt256?> .Success(account?.Nonce ?? 0));
        }
Beispiel #2
0
        private ResultWrapper <Quantity> GetAccountBalance(Address address, Keccak stateRoot)
        {
            var account = _blockchainBridge.GetAccount(address, stateRoot);

            if (account == null)
            {
                return(ResultWrapper <Quantity> .Fail("Cannot find account", ErrorType.NotFound));
            }
            return(ResultWrapper <Quantity> .Success(new Quantity(account.Balance)));
        }
Beispiel #3
0
        private ResultWrapper <byte[]> GetAccountStorage(Address address, BigInteger index, Keccak stateRoot)
        {
            var account = _blockchainBridge.GetAccount(address, stateRoot);

            if (account == null)
            {
                return(ResultWrapper <byte[]> .Success(Bytes.Empty));
            }

            return(ResultWrapper <byte[]> .Success(_blockchainBridge.GetStorage(address, index, stateRoot)));
        }
Beispiel #4
0
        public Task <ResultWrapper <UInt256?> > eth_getBalance(Address address, BlockParameter blockParameter = null)
        {
            SearchResult <BlockHeader> searchResult = _blockchainBridge.SearchForHeader(blockParameter);

            if (searchResult.IsError)
            {
                return(Task.FromResult(ResultWrapper <UInt256?> .Fail(searchResult)));
            }

            BlockHeader header  = searchResult.Object;
            Account     account = _blockchainBridge.GetAccount(address, header.StateRoot);

            return(Task.FromResult(ResultWrapper <UInt256?> .Success(account?.Balance ?? UInt256.Zero)));
        }
Beispiel #5
0
        public Task <ResultWrapper <UInt256?> > eth_getBalance(Address address, BlockParameter blockParameter = null)
        {
            SearchResult <BlockHeader> searchResult = _blockchainBridge.SearchForHeader(blockParameter);

            if (searchResult.IsError)
            {
                return(Task.FromResult(ResultWrapper <UInt256?> .Fail(searchResult)));
            }

            BlockHeader header = searchResult.Object;

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

            Account account = _blockchainBridge.GetAccount(address, header.StateRoot);

            return(Task.FromResult(ResultWrapper <UInt256?> .Success(account?.Balance ?? UInt256.Zero)));
        }
        public void Eth_get_balance()
        {
            IBlockchainBridge bridge = Substitute.For <IBlockchainBridge>();

            bridge.FindBlock(Arg.Any <long>()).Returns(Build.A.Block.TestObject);
            bridge.GetAccount(Arg.Any <Address>(), Arg.Any <Keccak>()).Returns(Build.A.Account.WithBalance(1.Ether()).TestObject);
            bridge.Head.Returns(Build.A.BlockHeader.TestObject);

            IEthModule module = new EthModule(NullLogManager.Instance, bridge);

            string serialized = RpcTest.TestSerializedRequest(module, "eth_getBalance", TestItem.AddressA.Bytes.ToHexString(true), "0x01");

            Assert.AreEqual("{\"id\":\"0x43\",\"jsonrpc\":\"2.0\",\"result\":\"0xde0b6b3a7640000\"}", serialized);
        }
Beispiel #7
0
 public void Setup()
 {
     _blockchainBridge = Substitute.For <IBlockchainBridge>();
     _repository       = Substitute.For <IEthRequestRepository>();
     _faucetAddress    = Address.FromNumber(1);
     _maxValue         = 1.GWei();
     _enabled          = true;
     _timestamp        = new Timestamp();
     _logManager       = NullLogManager.Instance;
     _host             = "127.0.0.1";
     _address          = Address.FromNumber(2);
     _value            = 1.GWei();
     _faucetAccount    = Account.TotallyEmpty;
     _transactionHash  = Keccak.Zero;
     _blockchainBridge.GetAccount(_faucetAddress).Returns(_faucetAccount);
     _blockchainBridge.SendTransaction(Arg.Any <Transaction>()).Returns(_transactionHash);
 }
Beispiel #8
0
 public void Setup()
 {
     _blockchainBridge = Substitute.For <IBlockchainBridge>();
     _repository       = Substitute.For <IEthRequestRepository>();
     _repository.SumDailyRequestsTotalValueAsync(Arg.Any <DateTime>()).ReturnsForAnyArgs(UInt256.Zero);
     _faucetAddress = Address.FromNumber(1);
     _maxValue      = 1.Ether();
     _dailyRequestsTotalValueEth = 500;
     _enabled         = true;
     _timestamper     = new Timestamper();
     _logManager      = LimboLogs.Instance;
     _host            = "127.0.0.1";
     _address         = Address.FromNumber(2);
     _value           = 1.Ether();
     _faucetAccount   = Account.TotallyEmpty;
     _transactionHash = Keccak.Zero;
     _blockchainBridge.GetAccount(_faucetAddress).Returns(_faucetAccount);
     _blockchainBridge.SendTransaction(Arg.Any <Transaction>(), true).Returns(_transactionHash);
 }
Beispiel #9
0
        public async Task <bool> TryRequestEthAsync(string host, Address address, UInt256 value)
        {
            if (!_enabled)
            {
                if (_logger.IsInfo)
                {
                    _logger.Info("NDM Faucet is disabled");
                }
                return(false);
            }

            if (_faucetAddress is null || _faucetAddress == Address.Zero)
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn("NDM Faucet address is not set");
                }
                return(false);
            }

            if (string.IsNullOrWhiteSpace(host) || address is null || address == Address.Zero ||
                _faucetAddress == address || value == 0)
            {
                if (_logger.IsInfo)
                {
                    _logger.Info("Invalid NDM Faucet ETH request");
                }
                return(false);
            }

            if (value > _maxValue)
            {
                if (_logger.IsInfo)
                {
                    _logger.Info($"ETH request from: {host} has too big value: {value} wei > {_maxValue} wei");
                }
                return(false);
            }

            if (_pendingRequests.TryGetValue(host, out _))
            {
                if (_logger.IsInfo)
                {
                    _logger.Info($"ETH request from: {host} is already being processed.");
                }
                return(false);
            }

            if (_logger.IsInfo)
            {
                _logger.Info($"Received ETH request from: {host}, address: {address}, value: {value} wei");
            }
            var latestRequest = await _requestRepository.GetLatestAsync(host);

            var requestedAt = _timestamp.UtcNow;

            if (!(latestRequest is null) && latestRequest.RequestedAt.Date >= requestedAt.Date)
            {
                if (_logger.IsInfo)
                {
                    _logger.Info($"ETH request from: {host} was already processed today at: {latestRequest.RequestedAt}");
                }
                return(false);
            }

            if (!_pendingRequests.TryAdd(host, true))
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn($"Couldn't start processing ETH request from: {host}");
                }
                return(false);
            }

            if (_logger.IsInfo)
            {
                _logger.Info($"Processing ETH request for: {host}, address: {address}, value: {value} wei");
            }
            try
            {
                var faucetAccount = _blockchainBridge.GetAccount(_faucetAddress);
                var transaction   = new Transaction
                {
                    Value         = value,
                    GasLimit      = 21000,
                    GasPrice      = 20.GWei(),
                    To            = address,
                    SenderAddress = _faucetAddress,
                    Nonce         = faucetAccount?.Nonce ?? 0
                };
                _blockchainBridge.Sign(transaction);
                var transactionHash = _blockchainBridge.SendTransaction(transaction);
                if (latestRequest is null)
                {
                    var requestId = Keccak.Compute(Rlp.Encode(Rlp.Encode(host)));
                    await _requestRepository.AddAsync(new EthRequest(requestId, host, address, value, requestedAt,
                                                                     transactionHash));
                }
                else
                {
                    latestRequest.UpdateRequestDate(requestedAt);
                    await _requestRepository.UpdateAsync(latestRequest);
                }

                if (_logger.IsInfo)
                {
                    _logger.Info($"ETH request was successfully processed for: {host}, address: {address}, value: {value} wei");
                }
                return(true);
            }
            catch (Exception e)
            {
                if (_logger.IsError)
                {
                    _logger.Error(e.Message, e);
                }
                return(false);
            }
            finally
            {
                _pendingRequests.TryRemove(host, out _);
            }
        }
Beispiel #10
0
        public async Task <FaucetResponse> TryRequestEthAsync(string node, Address address, UInt256 value)
        {
            if (!_enabled)
            {
                if (_logger.IsInfo)
                {
                    _logger.Info("NDM Faucet is disabled.");
                }
                return(FaucetResponse.FaucetDisabled);
            }

            if (!_initialized)
            {
                if (_logger.IsInfo)
                {
                    _logger.Info("NDM Faucet is not initialized.");
                }
                return(FaucetResponse.FaucetDisabled);
            }

            if (_today.Date != _timestamper.UtcNow.Date)
            {
                lock (_locker)
                {
                    _today = _timestamper.UtcNow;
                    _todayRequestsTotalValueWei = 0;
                }

                if (_logger.IsInfo)
                {
                    _logger.Info($"NDM Faucet has updated its today's date ({_today.Date:d}) and reset the total requests value.");
                }
            }

            if (_faucetAddress is null || _faucetAddress == Address.Zero)
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn("NDM Faucet address is not set.");
                }
                return(FaucetResponse.FaucetAddressNotSet);
            }

            if (string.IsNullOrWhiteSpace(node) || address is null || address == Address.Zero)
            {
                if (_logger.IsInfo)
                {
                    _logger.Info("Invalid NDM Faucet request.");
                }
                return(FaucetResponse.InvalidNodeAddress);
            }

            if (_faucetAddress == address)
            {
                if (_logger.IsInfo)
                {
                    _logger.Info("NDM Faucet request cannot be processed for the same address as NDM Faucet.");
                }
                return(FaucetResponse.SameAddressAsFaucet);
            }

            if (value == 0)
            {
                if (_logger.IsInfo)
                {
                    _logger.Info("NDM Faucet request cannot be processed for the zero value.");
                }
                return(FaucetResponse.ZeroValue);
            }

            if (value > _maxValue)
            {
                if (_logger.IsInfo)
                {
                    _logger.Info($"NDM Faucet request from: {node} has too big value: {value} wei > {_maxValue} wei.");
                }
                return(FaucetResponse.TooBigValue);
            }

            if (_logger.IsInfo)
            {
                _logger.Info($"Received NDM Faucet request from: {node}, address: {address}, value: {value} wei.");
            }
            if (_pendingRequests.TryGetValue(node, out _))
            {
                if (_logger.IsInfo)
                {
                    _logger.Info($"NDM Faucet request from: {node} is already being processed.");
                }
                return(FaucetResponse.RequestAlreadyProcessing);
            }

            var latestRequest = await _requestRepository.GetLatestAsync(node);

            var requestedAt = _timestamper.UtcNow;

            if (!(latestRequest is null) && latestRequest.RequestedAt.Date >= requestedAt.Date)
            {
                if (_logger.IsInfo)
                {
                    _logger.Info($"NDM Faucet request from: {node} was already processed today at: {latestRequest.RequestedAt}.");
                }
                return(FaucetResponse.RequestAlreadyProcessedToday(FaucetRequestDetails.From(latestRequest)));
            }

            if (!_pendingRequests.TryAdd(node, true))
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn($"Couldn't start processing NDM Faucet request from: {node}.");
                }
                return(FaucetResponse.RequestError);
            }

            lock (_locker)
            {
                _todayRequestsTotalValueWei += value;
                if (_logger.IsInfo)
                {
                    _logger.Info($"Increased NDM Faucet total value of today's ({_today.Date:d}) requests to {_todayRequestsTotalValueWei} wei.");
                }
            }

            if (_todayRequestsTotalValueWei > _dailyRequestsTotalValueWei)
            {
                if (_logger.IsInfo)
                {
                    _logger.Info($"Daily ({_today.Date:d}) requests value for NDM Faucet was reached ({_dailyRequestsTotalValueWei} wei).");
                }
                return(FaucetResponse.DailyRequestsTotalValueReached);
            }

            if (_logger.IsInfo)
            {
                _logger.Info($"NDM Faucet is processing request for: {node}, address: {address}, value: {value} wei.");
            }
            try
            {
                var faucetAccount = _blockchainBridge.GetAccount(_faucetAddress);
                var transaction   = new Transaction
                {
                    Value         = value,
                    GasLimit      = 21000,
                    GasPrice      = 20.GWei(),
                    To            = address,
                    SenderAddress = _faucetAddress,
                    Nonce         = faucetAccount?.Nonce ?? 0
                };
                _blockchainBridge.Sign(transaction);
                var transactionHash = _blockchainBridge.SendTransaction(transaction, true);
                if (latestRequest is null)
                {
                    var requestId = Keccak.Compute(Rlp.Encode(Rlp.Encode(node)));
                    latestRequest = new EthRequest(requestId, node, address, value, requestedAt, transactionHash);
                    await _requestRepository.AddAsync(latestRequest);
                }
                else
                {
                    latestRequest.UpdateRequestDetails(address, value, requestedAt, transactionHash);
                    await _requestRepository.UpdateAsync(latestRequest);
                }

                if (_logger.IsInfo)
                {
                    _logger.Info($"NDM Faucet has successfully processed request for: {node}, address: {address}, value: {value} wei.");
                }
                return(FaucetResponse.RequestCompleted(FaucetRequestDetails.From(latestRequest)));
            }
            catch (Exception ex)
            {
                if (_logger.IsError)
                {
                    _logger.Error(ex.Message, ex);
                }
                lock (_locker)
                {
                    _todayRequestsTotalValueWei -= value;
                    if (_logger.IsInfo)
                    {
                        _logger.Info($"Decreased NDM Faucet total value of today's ({_today.Date:d}) requests to {_todayRequestsTotalValueWei} wei.");
                    }
                }

                return(FaucetResponse.ProcessingRequestError);
            }
            finally
            {
                _pendingRequests.TryRemove(node, out _);
            }
        }