public async Task <AccountPoolItem> SetInactive(string hash, string transactionHash, decimal addedValue) { AccountPoolItem item = null; try { item = await applicationDbContext.AccountPools.FirstOrDefaultAsync(x => x.Address == hash); if (item != null) { item.IsProcessed = false; item.LastTransactionHash = transactionHash; item.Balance += addedValue; await applicationDbContext.SaveChangesAsync(); } } catch (Exception ex) { logger.LogWarning(ex, $"Error set acc {hash} active incative."); throw; } return(null); }
public async Task <AccountPoolItem> GetPoolOrNewAddress(TimeSpan timeout, int tryCount = 2, int delayMS = 1000) { AccountPoolItem result = null; for (int i = 0; i < tryCount; i++) { try { var data = await addressPool.GetInactiveAccount(CurrencyCode); if (!data.Any()) { await Task.Delay(timeout); data = await addressPool.GetInactiveAccount(CurrencyCode); } if (!data.Any()) { var account = await CreateNewAccount(); result = new AccountPoolItem { Id = Guid.NewGuid().ToString(), Address = account, Balance = 0, CurrencyName = CurrencyCode, IsProcessed = true, LastTransactionHash = string.Empty }; await addressPool.WriteNewAccount(result); break; } else { result = data.First(); await addressPool.SetActive(result); break; } } catch (Exception ex) { logger.LogError(ex, "Failed to get Ethereum address"); } await Task.Delay(delayMS); } if (result.Address == null) { throw new ApiException(ErrorCode.CannotCreateEthAddress); } return(result); }
public async Task WriteNewAccount(AccountPoolItem accountPoolItem) { try { applicationDbContext.AccountPools.Add(accountPoolItem); await applicationDbContext.SaveChangesAsync(); } catch (Exception ex) { logger.LogWarning(ex, $"Error creating new acc."); throw; } }
private async Task DrainPoolItem(AccountPoolItem poolItem) { if (poolItem == null) { return; } if (poolItem.IsProcessed) { return; } if (string.IsNullOrEmpty(drainAddress)) { return; } if (!string.Equals(poolItem.CurrencyName, CurrencyCode, StringComparison.OrdinalIgnoreCase)) { return; } if (poolItem.Balance > drainValue && poolItem.Balance > drainLimit) { try { var web3 = new Nethereum.Web3.Web3(gethNodeAddress); var sendBalance = Converter.DecimalToAtomicUnit(poolItem.Balance - drainLimit); await web3.Personal.UnlockAccount.SendRequestAsync(poolItem.Address, defaultAccountPassword, AccountUnlockDurationInSeconds).ConfigureAwait(false); await web3.TransactionManager.SendTransactionAsync(poolItem.Address, drainAddress, sendBalance).ConfigureAwait(false); await addressPool.ClearBalance(poolItem.Address).ConfigureAwait(false); } catch (Exception ex) { logger.LogError(ex, "Failed to DrainPoolItem"); } } }
public async Task ReturnAddressToPool(AccountPoolItem accountPoolItem, string transactionHash) { var poolItem = await addressPool.SetInactive(accountPoolItem, transactionHash); await DrainPoolItem(poolItem); }
public Task <AccountPoolItem> SetInactive(AccountPoolItem accountPoolItem, string transactionHash) { return(SetInactive(accountPoolItem.Address, transactionHash, accountPoolItem.Balance)); }
public Task SetActive(AccountPoolItem accountPoolItem) { return(SetActive(accountPoolItem.Address)); }