void Run(KeepSpyContext db) { var network = db.Set <Network>() .SingleOrDefault(n => n.Kind == NetworkKind.Bitcoin && n.IsTestnet == _options.IsTestnet); if (network == null) { network = new Network { Kind = NetworkKind.Bitcoin, IsTestnet = _options.IsTestnet, LastBlock = _apiClient.GetBlocks()[0].height, LastBlockAt = DateTime.Now, Id = Guid.NewGuid(), Name = "Bitcoin" }; db.Add(network); db.SaveChanges(); } foreach (var deposit in db.Set <Deposit>().Where(o => o.BitcoinAddress != null && o.Status >= DepositStatus.WaitingForBtc && o.Contract.Network.IsTestnet == _options.IsTestnet).ToList()) { while (true) { try { ProcessDeposit(db, deposit); break; } catch (Exception e) { _logger.LogError(e, "Failed for deposit " + deposit.Id); } } } var currentBlock = _apiClient.GetBlocks()[0]; network.LastBlock = currentBlock.height; network.LastBlockAt = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(currentBlock.timestamp); _logger.LogInformation($"Last block processed: {network.LastBlock} ({network.LastBlockAt})"); db.SaveChanges(); }
void ProcessTx(KeepSpyContext db, Deposit deposit, Tx tx) { if (db.Find <Transaction>(tx.txid) == null) { var sender = tx.vin.Count == 1 ? tx.vin[0].prevout.scriptpubkey_address : null; var recipient = tx.vout.Count == 1 ? tx.vout[0].scriptpubkey_address : null; var redeem = db.Find <Redeem>(deposit.Id); if (sender == deposit.BitcoinAddress && redeem == null) { return; } var t = new Transaction { Id = tx.txid, Redeem = sender == deposit.BitcoinAddress ? redeem : null, Deposit = sender == deposit.BitcoinAddress ? null : deposit, Block = tx.status.block_height, Status = sender == deposit.BitcoinAddress ? DepositStatus.Closed : DepositStatus.BtcReceived, RedeemStatus = sender == deposit.BitcoinAddress ? RedeemStatus.BtcTransferred : (RedeemStatus?)null, IsError = false, Error = "", Timestamp = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(tx.status.block_time), Amount = (sender == deposit.BitcoinAddress ? tx.vout[0].value / 100000000M : tx.vout.Where(o => o.scriptpubkey_address == deposit.BitcoinAddress) .Sum(v => v.value / 100000000M)), Fee = tx.fee / 100000000M, Kind = NetworkKind.Bitcoin, Sender = sender, Recipient = recipient }; db.Add(t); _logger.LogInformation($"Saved tx {t.Id} ({t.Timestamp})"); if (redeem != null && sender == deposit.BitcoinAddress) { redeem.BitcoinAddress = recipient; redeem.BitcoinRedeemedBlock = tx.status.block_height; redeem.BtcRedeemed = t.Amount; redeem.BtcFee = t.Fee; if (redeem.Status != RedeemStatus.Liquidated && redeem.Status != RedeemStatus.Redeemed) { redeem.Status = RedeemStatus.BtcTransferred; redeem.UpdatedAt = t.Timestamp; } } db.SaveChanges(); } }
void LoadPriceFeed(KeepSpyContext db, uint startBlock) { const string LogMedianPriceEvent = "0xb78ebc573f1f889ca9e1e0fb62c843c836f3d3a2e1f43ef62940e9b894f4ea4c"; foreach (var log in db.Set <ContractLog>().Where(cl => cl.Address == ethBtcContract && cl.Topic0 == LogMedianPriceEvent && cl.BlockNumber >= startBlock).ToList()) { if (db.Find <CurrencyRate>(log.TimeStamp, TradePair.ETHBTC, CurrencyRateSource.MedianETHBTC) == null) { var value = (decimal)System.Numerics.BigInteger.Parse(log.Data.Substring(32, 32), System.Globalization.NumberStyles.HexNumber) / 1000000000000000000M; db.Add(new CurrencyRate { Timestamp = log.TimeStamp, TradePair = TradePair.ETHBTC, Source = CurrencyRateSource.MedianETHBTC, Value = value }); db.SaveChanges(); } } }
private void Run(KeepSpyContext db, ILogger <RefreshViewWorker> logger) { logger.LogInformation("Market data logging"); var timestamp = DateTime.UtcNow.Date.AddHours(DateTime.UtcNow.Hour); var prices = db.Set <CurrencyRate>().Where(r => r.Source == CurrencyRateSource.CryptoCompare && r.Timestamp == timestamp).ToList(); if (prices.Count == 0) { var wc = new WebClient(); var apiResult = wc.DownloadString(_apiUrl); var md = JsonSerializer.Deserialize <MarketData>(apiResult); db.Add(new CurrencyRate { Source = CurrencyRateSource.CryptoCompare, Timestamp = timestamp, TradePair = TradePair.KEEPBTC, Value = md.BTC }); db.Add(new CurrencyRate { Source = CurrencyRateSource.CryptoCompare, Timestamp = timestamp, TradePair = TradePair.KEEPETH, Value = md.ETH }); db.Add(new CurrencyRate { Source = CurrencyRateSource.CryptoCompare, Timestamp = timestamp, TradePair = TradePair.KEEPUSD, Value = md.USD }); db.SaveChanges(); logger.LogWarning($"Market data on {timestamp} - KEEP/USD:{md.USD}; KEEP/BTC:{md.BTC}, KEEP/ETH:{md.ETH}"); } }
public void AddLog(Log log) { if (_db.Find <ContractLog>(log.transactionHash, log.logIndex) == null) { _db.Add(new ContractLog { Address = log.address, BlockNumber = log.BlockNumber, CreatedAt = DateTime.Now, Data = log.data.Substring(2), Fee = log.Fee, LogIndex = log.logIndex, TimeStamp = log.TimeStamp, Topic0 = log.topics[0], Topic1 = log.topics.Count > 1 ? log.topics[1] : "", Topic2 = log.topics.Count > 2 ? log.topics[2] : "", Topic3 = log.topics.Count > 3 ? log.topics[3] : "", TransactionId = log.transactionHash, Amount = log.data.Length > 2 && log.topics[0] == "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" ? (decimal?)BigInteger.Parse(log.data.Substring(2), NumberStyles.HexNumber) / 1e18M : null }); _db.SaveChanges(); } }
void Run(KeepSpyContext db, KeychainService keychainService) { /* * foreach(var cl in db.Set<ContractLog>().Where(o => o.Amount == null && o.Topic0 == TransferEvent && o.Data != "")) * { * cl.Amount = (decimal)BigInteger.Parse(cl.Data, NumberStyles.HexNumber) / 1e18M; * } * db.SaveChanges(); * foreach (var t in db.Set<Transaction>().Where(o => o.IsError && o.Error.Length <= 1)) * { * t.Error = _apiClient.GetTxStatus(t.Id).result.errDescription; * _logger.LogInformation($"Tx {t.Id} error description: {t.Error}"); * }*/ //foreach (var d in db.Set<Deposit>().Where(o => o.TokenID.StartsWith("-"))) // d.TokenID = System.Numerics.BigInteger.Parse("0" + d.Id.Substring(2), System.Globalization.NumberStyles.HexNumber).ToString(); //db.SaveChanges(); var network = db.Set <Network>() .SingleOrDefault(n => n.Kind == NetworkKind.Ethereum && n.IsTestnet == _options.IsTestnet); if (network == null) { network = new Network { Kind = NetworkKind.Ethereum, IsTestnet = _options.IsTestnet, LastBlock = uint.Parse(_apiClient.GetBlockNumber().result.Substring(2), System.Globalization.NumberStyles.HexNumber), LastBlockAt = DateTime.Now, Id = Guid.NewGuid(), Name = "Ethereum" }; db.Add(network); db.SaveChanges(); } if (lastBlock == 0) { lastBlock = network.LastBlockProcessed ?? (_options.IsTestnet ? 8594983u : 10867766); //lastBlock = (db.Set<Transaction>().Where(t => t.Kind == NetworkKind.Ethereum).Max(t => (uint?)t.Block) - 2000) ?? 0; //if (lastBlock < 0) } var contract = db.Set <Contract>().FirstOrDefault(c => c.Active && c.Network == network); if (contract == null && !_options.IsTestnet) { contract = new Contract { Active = true, Network = network, Name = "Deposit Factory", Id = "0x87effef56c7ff13e2463b5d4dce81be2340faf8b" }; db.Add(contract); db.SaveChanges(); } if (contract == null) { _logger.LogCritical("No active contract at network {0}", network.Name); return; } var getBlockNumberResult = uint.Parse(_apiClient.GetBlockNumber().result.Substring(2), NumberStyles.HexNumber) - 20; var toBlock = getBlockNumberResult; if (toBlock < lastBlock) { lastBlock = toBlock; } if (toBlock - lastBlock > 1000) { toBlock = lastBlock + 1000; } LoadContractLogs(contract.Id, lastBlock, toBlock, db); LoadContractLogs(tdtcontract, lastBlock, toBlock, db); LoadContractLogs(vmcontract, lastBlock, toBlock, db); LoadContractLogs(tbtccontract, lastBlock, toBlock, db); LoadContractLogs(tbtcsystem, lastBlock, toBlock, db); LoadContractLogs(bondedECDSAKeepFactory, lastBlock, toBlock, db); LoadContractLogs(keepBondingContract, lastBlock, toBlock, db); LoadContractLogs(ethBtcContract, lastBlock, toBlock, db); LoadContractLogs(tbtctoken, lastBlock, toBlock, db); LoadContractLogs(keepStakingContract, _options.IsTestnet ? 8594983u : 10867766, toBlock, db); LoadContractLogs(tokenGrantContract, _options.IsTestnet ? 8594983u : 10867766, toBlock, db); LoadPriceFeed(db, lastBlock); var resultTx = _apiClient.GetAccountTxList(contract.Id, lastBlock, toBlock); foreach (var item in resultTx.result) { if (item.isError == "1") { continue; } if (item.input.StartsWith("0xb7947b40")) { var lotSize = uint.Parse(item.input.Substring(66), NumberStyles.HexNumber) / 100000000M; var eventLog = db.Set <ContractLog>().Single(cl => cl.Address == contract.Id && cl.TransactionId == item.hash && cl.Topic0 == DepositCloneCreatedEvent); if (eventLog != null) { var tdt_id = "0x" + eventLog.Data.Substring(24); var deposit = db.Find <Deposit>(tdt_id); if (deposit == null) { deposit = new Deposit { CreatedAt = item.TimeStamp, UpdatedAt = item.TimeStamp, Id = tdt_id, LotSize = lotSize, SenderAddress = item.from, Contract = contract, Status = DepositStatus.InitiatingDeposit, TokenID = System.Numerics.BigInteger.Parse("0" + tdt_id.Substring(2), System.Globalization.NumberStyles.HexNumber).ToString() }; db.Add(deposit); AddTx(item, deposit); db.SaveChanges(); _logger.LogInformation("TDT {0} created with TokenID: {1}", deposit.Id, deposit.TokenID); } } } } foreach (var log in db.Set <ContractLog>().Where(o => o.Address == tbtcsystem && o.BlockNumber >= lastBlock && o.Topic0 == RegisteredPubKeyEvent && o.BlockNumber <= toBlock).ToList()) { string id = "0x" + log.Topic1.Substring(26); var deposit = db.Find <Deposit>(id); if (deposit == null) { continue; } if (deposit.BitcoinAddress == null) { var pubkeyX = log.Data.Substring(0, 64); var pubkeyY = log.Data.Substring(64, 64); var address = keychainService.GetBtcAddress(pubkeyX, pubkeyY, network.IsTestnet); deposit.BitcoinAddress = address; deposit.Status = DepositStatus.WaitingForBtc; deposit.UpdatedAt = log.TimeStamp; _logger.LogInformation("TDT {0} BTC address generated: {1}", deposit.Id, deposit.BitcoinAddress); } AddLog(log, deposit, DepositStatus.WaitingForBtc); db.SaveChanges(); } foreach (var log in db.Set <ContractLog>().Where(o => o.Address == tbtcsystem && o.BlockNumber >= lastBlock && o.Topic0 == SetupFailedEvent && o.BlockNumber <= toBlock).ToList()) { string id = "0x" + log.Topic1.Substring(26); var deposit = db.Find <Deposit>(id); if (deposit == null) { continue; } if (deposit.Status != DepositStatus.SetupFailed) { deposit.Status = DepositStatus.SetupFailed; deposit.UpdatedAt = log.TimeStamp; _logger.LogInformation("TDT {0} setup failed", deposit.Id); } AddLog(log, deposit, DepositStatus.SetupFailed); db.SaveChanges(); } foreach (var log in db.Set <ContractLog>().Where(o => o.Address == tbtcsystem && o.BlockNumber >= lastBlock && o.Topic0 == FundedEvent && o.BlockNumber <= toBlock).ToList()) { string id = "0x" + log.Topic1.Substring(26); var deposit = db.Find <Deposit>(id); if (deposit != null) { deposit.EndOfTerm = log.TimeStamp.AddMonths(6); if (deposit.Status <= DepositStatus.BtcReceived) { deposit.Status = DepositStatus.SubmittingProof; deposit.UpdatedAt = log.TimeStamp; _logger.LogInformation("TDT {0} submitted proof", deposit.Id); } AddLog(log, deposit, DepositStatus.SubmittingProof); db.SaveChanges(); } } foreach (var log in db.Set <ContractLog>().Where(o => o.Address == tdtcontract && o.BlockNumber >= lastBlock && o.Topic0 == ApprovalEvent && o.BlockNumber <= toBlock).ToList()) { string id = "0x" + log.Topic3.Substring(26); if ("0x" + log.Topic2.Substring(26) != vmcontract) { continue; } var deposit = db.Find <Deposit>(id); if (deposit == null) { continue; } if (deposit.Status == DepositStatus.SubmittingProof) { deposit.Status = DepositStatus.ApprovingSpendLimit; deposit.UpdatedAt = log.TimeStamp; _logger.LogInformation("TDT {0} tdt spend approved", deposit.Id); } AddLog(log, deposit, DepositStatus.ApprovingSpendLimit); db.SaveChanges(); } foreach (var logFee in db.Set <ContractLog>().Where(o => o.Address == tbtctoken && o.BlockNumber >= lastBlock && o.Topic0 == TransferEvent && o.Topic1 == "0x0000000000000000000000000000000000000000000000000000000000000000" && o.BlockNumber <= toBlock).ToList()) { string id = "0x" + logFee.Topic2.Substring(26); var deposit = db.Find <Deposit>(id); if (deposit == null) { continue; } deposit.LotSizeFee = (decimal)(ulong.Parse(logFee.Data.Substring(44), NumberStyles.HexNumber) / 1E18); var logMinted = db.Set <ContractLog>().Single(o => o.Address == tbtctoken && o.Topic1 == "0x0000000000000000000000000000000000000000000000000000000000000000" && o.TransactionId == logFee.TransactionId && o.Topic2 != logFee.Topic2); deposit.LotSizeMinted = (decimal)(ulong.Parse(logMinted.Data.Substring(44), NumberStyles.HexNumber) / 1E18); deposit.CompletedAt = logMinted.TimeStamp; if (deposit.Status != DepositStatus.Closed) { deposit.Status = DepositStatus.Minted; deposit.UpdatedAt = logMinted.TimeStamp; _logger.LogInformation("Minted {0} for {1}, fee {2}, TDT ID {3}", deposit.LotSizeMinted, deposit.SenderAddress, deposit.LotSizeFee, deposit.Id); } AddLog(logMinted, deposit, DepositStatus.Minted); db.SaveChanges(); } foreach (var log in db.Set <ContractLog>().Where(o => o.Address == tbtcsystem && o.BlockNumber >= lastBlock && (o.Topic0 == RedemptionRequestedEvent || o.Topic0 == CourtesyCalledEvent) && o.BlockNumber <= toBlock).ToList()) { var tdt_id = "0x" + log.Topic1.Substring(26); var deposit = db.Find <Deposit>(tdt_id); if (deposit is null) { _logger.LogWarning($"Deposit for tdt id {tdt_id} doesn't exists in db"); continue; } var redeem = db.Find <Redeem>(tdt_id); if (redeem == null) { redeem = new Redeem { Id = tdt_id, CreatedAt = log.TimeStamp, SenderAddress = log.Topic0 == RedemptionRequestedEvent ? "0x" + log.Topic2.Substring(26) : "", Deposit = deposit, Status = log.Topic0 == RedemptionRequestedEvent ? RedeemStatus.Requested : RedeemStatus.CourtesyCalled, UpdatedAt = log.TimeStamp }; db.Add(redeem); } deposit.Status = DepositStatus.Closed; deposit.UpdatedAt = log.TimeStamp; AddLog2(log, redeem, RedeemStatus.Requested); _logger.LogInformation("Redeem requested TDT ID {0}", deposit.Id); db.SaveChanges(); } foreach (var log in db.Set <ContractLog>().Where(o => o.Address == tbtcsystem && o.BlockNumber >= lastBlock && o.Topic0 == GotRedemptionSignatureEvent && o.BlockNumber <= toBlock).ToList()) { string id = "0x" + log.Topic1.Substring(26); var redeem = db.Find <Redeem>(id); if (redeem == null) { continue; } if (redeem.Status == RedeemStatus.Requested) { redeem.Status = RedeemStatus.Signed; redeem.UpdatedAt = log.TimeStamp; _logger.LogInformation("Redeem {0} signed", redeem.Id); } AddLog2(log, redeem, RedeemStatus.Signed); db.SaveChanges(); } foreach (var log in db.Set <ContractLog>().Where(o => o.Address == tbtcsystem && o.BlockNumber >= lastBlock && o.Topic0 == RedeemedEvent && o.BlockNumber <= toBlock).ToList()) { string id = "0x" + log.Topic1.Substring(26); var redeem = db.Find <Redeem>(id); if (redeem == null) { continue; } if (redeem.Status != RedeemStatus.Redeemed) { redeem.Status = RedeemStatus.Redeemed; redeem.UpdatedAt = log.TimeStamp; redeem.CompletedAt = log.TimeStamp; _logger.LogInformation("Redeem {0} complete", redeem.Id); } AddLog2(log, redeem, RedeemStatus.Redeemed); db.SaveChanges(); } foreach (var log in db.Set <ContractLog>().Where(o => o.Address == bondedECDSAKeepFactory && o.BlockNumber >= lastBlock && o.Topic0 == BondedECDSAKeepCreatedEvent && o.BlockNumber <= toBlock).ToList()) { string id = "0x" + log.Topic2.Substring(26); var deposit = db.Find <Deposit>(id); if (deposit == null) { continue; } if (deposit.KeepAddress == null) { deposit.KeepAddress = "0x" + log.Topic1.Substring(26); var data = Regex.Match(log.Data, "([0-9A-Fa-f]{64})*"); deposit.HonestThreshold = (int)ulong.Parse(data.Groups[1].Captures[1].Value, NumberStyles.HexNumber); for (int i = 3; i < data.Groups[1].Captures.Count; i++) { var signerId = "0x" + data.Groups[1].Captures[i].Value.Substring(24); var signer = db.Find <Signer>(signerId); if (signer == null) { signer = new Signer { Id = signerId }; db.Add(signer); } db.Add(new DepositSigner { Deposit = deposit, Signer = signer }); _logger.LogInformation("Deposit {0} signer: {1}", deposit.Id, signerId); } } db.SaveChanges(); } foreach (var log in db.Set <ContractLog>().Where(o => o.Address == keepBondingContract && o.BlockNumber >= lastBlock && o.Topic0 == BondCreatedEvent && o.BlockNumber <= toBlock).ToList()) { var signer = "0x" + log.Topic1.Substring(26); var keepAddress = "0x" + log.Topic2.Substring(26); var amount = (decimal)System.Numerics.BigInteger.Parse(log.Data.Substring(96, 32), NumberStyles.HexNumber) / 1000000000000000000M; if (!db.Set <Bond>().Any(b => b.Deposit.KeepAddress == keepAddress && b.SignerId == signer)) { var deposit = db.Set <Deposit>().SingleOrDefault(d => d.KeepAddress == keepAddress); if (deposit == null) { continue; } db.Add(new Bond { Amount = amount, SignerId = signer, Deposit = deposit }); _logger.LogInformation("Deposit {0}, Bond {1} ETH, signer {2}", deposit.Id, amount, signer); } db.SaveChanges(); } foreach (var log in db.Set <ContractLog>().Where(o => o.Address == tbtcsystem && o.BlockNumber >= lastBlock && o.Topic0 == StartedLiquidationEvent && o.BlockNumber <= toBlock).ToList()) { string id = "0x" + log.Topic1.Substring(26); var redeem = db.Find <Redeem>(id); if (redeem == null) { continue; } if (redeem.Status != RedeemStatus.Liquidation) { redeem.Status = RedeemStatus.Liquidation; redeem.UpdatedAt = log.TimeStamp; _logger.LogInformation("Redeem {0} started liquidation", redeem.Id); } AddLog2(log, redeem, RedeemStatus.Liquidation); db.SaveChanges(); } foreach (var log in db.Set <ContractLog>().Where(o => o.Address == tbtcsystem && o.BlockNumber >= lastBlock && o.Topic0 == LiquidatedEvent && o.BlockNumber <= toBlock).ToList()) { string id = "0x" + log.Topic1.Substring(26); var redeem = db.Find <Redeem>(id); if (redeem == null) { continue; } if (redeem.Status != RedeemStatus.Liquidated) { redeem.Status = RedeemStatus.Liquidated; redeem.UpdatedAt = log.TimeStamp; redeem.CompletedAt = log.TimeStamp; _logger.LogInformation("Redeem {0} liquidated", redeem.Id); } AddLog2(log, redeem, RedeemStatus.Liquidated); db.SaveChanges(); } var keepBonding = new KeepBonding(db, lastBlock, toBlock); foreach (var deposited in keepBonding.GetUnbondedValueDeposited()) { AddLog(deposited.log); var signer = db.Find <Signer>(deposited.@operator); if (signer == null) { db.Add(new Signer { Id = deposited.@operator }); db.SaveChanges(); } var be = db.Find <BondEvent>(deposited.log.LogIndex, deposited.log.TransactionId); if (be == null) { db.Add(new BondEvent { Amount = deposited.amount, Beneficiary = deposited.beneficiary, TransactionId = deposited.log.TransactionId, LogIndex = deposited.log.LogIndex, SignerId = deposited.@operator, Type = BondEventType.UnbondedValueDeposited }); db.SaveChanges(); } } foreach (var withdrawn in keepBonding.GetUnbondedValueWithdrawn()) { AddLog(withdrawn.log); var signer = db.Find <Signer>(withdrawn.@operator); if (signer == null) { db.Add(new Signer { Id = withdrawn.@operator }); db.SaveChanges(); } var be = db.Find <BondEvent>(withdrawn.log.LogIndex, withdrawn.log.TransactionId); if (be == null) { db.Add(new BondEvent { Amount = -withdrawn.amount, Beneficiary = withdrawn.beneficiary, TransactionId = withdrawn.log.TransactionId, LogIndex = withdrawn.log.LogIndex, SignerId = withdrawn.@operator, Type = BondEventType.UnbondedValueWithdrawn }); db.SaveChanges(); } } foreach (var bondCreated in keepBonding.GetBondCreated()) { var deposit = db.Set <Deposit>().SingleOrDefault(d => d.KeepAddress == bondCreated.holder); if (deposit == null) { continue; } AddLog(bondCreated.log); var signer = db.Find <Signer>(bondCreated.@operator); if (signer == null) { db.Add(new Signer { Id = bondCreated.@operator }); db.SaveChanges(); } var be = db.Find <BondEvent>(bondCreated.log.LogIndex, bondCreated.log.TransactionId); if (be == null) { db.Add(new BondEvent { Amount = bondCreated.amount, ReferenceID = bondCreated.referenceID, DepositId = deposit.Id, TransactionId = bondCreated.log.TransactionId, LogIndex = bondCreated.log.LogIndex, SignerId = bondCreated.@operator, Type = BondEventType.BondCreated }); db.SaveChanges(); } } foreach (var bondReleased in keepBonding.GetBondReleased()) { var bondCreated = db.Set <BondEvent>().SingleOrDefault(b => b.ReferenceID == bondReleased.referenceID && b.Type == BondEventType.BondCreated && b.SignerId == bondReleased.@operator); if (bondCreated == null) { continue; } AddLog(bondReleased.log); if (!bondCreated.Released) { bondCreated.Released = true; db.SaveChanges(); } var be = db.Find <BondEvent>(bondReleased.log.LogIndex, bondReleased.log.TransactionId); if (be == null) { db.Add(new BondEvent { Amount = -bondCreated.Amount, ReferenceID = bondReleased.referenceID, DepositId = bondCreated.DepositId, TransactionId = bondReleased.log.TransactionId, LogIndex = bondReleased.log.LogIndex, SignerId = bondReleased.@operator, Type = BondEventType.BondReleased }); db.SaveChanges(); } } foreach (var bondSeized in keepBonding.GetBondSeized()) { var bondCreated = db.Set <BondEvent>().SingleOrDefault(b => b.ReferenceID == bondSeized.referenceID && b.Type == BondEventType.BondCreated && b.SignerId == bondSeized.@operator); if (bondCreated == null) { continue; } AddLog(bondSeized.log); if (!bondCreated.Released) { bondCreated.Released = true; db.SaveChanges(); } var be = db.Find <BondEvent>(bondSeized.log.LogIndex, bondSeized.log.TransactionId); if (be == null) { db.Add(new BondEvent { Amount = -bondCreated.Amount, ReferenceID = bondSeized.referenceID, DepositId = bondCreated.DepositId, TransactionId = bondSeized.log.TransactionId, LogIndex = bondSeized.log.LogIndex, SignerId = bondSeized.@operator, Type = BondEventType.BondSeized }); db.SaveChanges(); } } var tokenStaking = new TokenStaking(db, lastBlock, toBlock); foreach (var item in tokenStaking.GetTokenGrantStaked()) { AddLog(item.log); var signer = db.Find <Signer>(item.@operator); if (signer == null) { db.Add(new Signer { Id = item.@operator }); db.SaveChanges(); } var se = db.Find <StakeEvent>(item.log.LogIndex, item.log.TransactionId); if (se == null) { db.Add(new StakeEvent { TransactionId = item.log.TransactionId, LogIndex = item.log.LogIndex, SignerId = item.@operator, Type = StakeEventType.TokenGrantStaked }); db.SaveChanges(); } } foreach (var item in tokenStaking.GetStakeDelegated()) { AddLog(item.log); var signer = db.Find <Signer>(item.@operator); if (signer == null) { db.Add(new Signer { Id = item.@operator }); db.SaveChanges(); } var se = db.Find <StakeEvent>(item.log.LogIndex, item.log.TransactionId); if (se == null) { db.Add(new StakeEvent { TransactionId = item.log.TransactionId, LogIndex = item.log.LogIndex, SignerId = item.@operator, Type = StakeEventType.StakeDelegated }); db.SaveChanges(); } } foreach (var item in tokenStaking.GetOperatorStaked()) { AddLog(item.log); var signer = db.Find <Signer>(item.@operator); if (signer == null) { db.Add(new Signer { Id = item.@operator }); db.SaveChanges(); } var se = db.Find <StakeEvent>(item.log.LogIndex, item.log.TransactionId); if (se == null) { db.Add(new StakeEvent { TransactionId = item.log.TransactionId, LogIndex = item.log.LogIndex, SignerId = item.@operator, Type = StakeEventType.OperatorStaked, Amount = item.amount }); db.SaveChanges(); } } foreach (var item in tokenStaking.GetTopUpInitiated()) { AddLog(item.log); var signer = db.Find <Signer>(item.@operator); if (signer == null) { db.Add(new Signer { Id = item.@operator }); db.SaveChanges(); } var se = db.Find <StakeEvent>(item.log.LogIndex, item.log.TransactionId); if (se == null) { db.Add(new StakeEvent { TransactionId = item.log.TransactionId, LogIndex = item.log.LogIndex, SignerId = item.@operator, Type = StakeEventType.TopUpInitiated, Amount = item.amount }); db.SaveChanges(); } } foreach (var item in tokenStaking.GetTopUpCompleted()) { AddLog(item.log); var signer = db.Find <Signer>(item.@operator); if (signer == null) { db.Add(new Signer { Id = item.@operator }); db.SaveChanges(); } var se = db.Find <StakeEvent>(item.log.LogIndex, item.log.TransactionId); if (se == null) { db.Add(new StakeEvent { TransactionId = item.log.TransactionId, LogIndex = item.log.LogIndex, SignerId = item.@operator, Type = StakeEventType.TopUpCompleted, Amount = item.amount }); db.SaveChanges(); } } foreach (var item in tokenStaking.GetUndelegated()) { AddLog(item.log); var signer = db.Find <Signer>(item.@operator); if (signer == null) { db.Add(new Signer { Id = item.@operator }); db.SaveChanges(); } var se = db.Find <StakeEvent>(item.log.LogIndex, item.log.TransactionId); if (se == null) { db.Add(new StakeEvent { TransactionId = item.log.TransactionId, LogIndex = item.log.LogIndex, SignerId = item.@operator, Type = StakeEventType.Undelegated }); db.SaveChanges(); } } foreach (var item in tokenStaking.GetRecoveredStake()) { AddLog(item.log); var signer = db.Find <Signer>(item.@operator); if (signer == null) { db.Add(new Signer { Id = item.@operator }); db.SaveChanges(); } var se = db.Find <StakeEvent>(item.log.LogIndex, item.log.TransactionId); if (se == null) { db.Add(new StakeEvent { TransactionId = item.log.TransactionId, LogIndex = item.log.LogIndex, SignerId = item.@operator, Type = StakeEventType.RecoveredStake }); db.SaveChanges(); } } foreach (var item in tokenStaking.GetTokensSeized()) { AddLog(item.log); var signer = db.Find <Signer>(item.@operator); if (signer == null) { db.Add(new Signer { Id = item.@operator }); db.SaveChanges(); } var se = db.Find <StakeEvent>(item.log.LogIndex, item.log.TransactionId); if (se == null) { db.Add(new StakeEvent { TransactionId = item.log.TransactionId, LogIndex = item.log.LogIndex, SignerId = item.@operator, Type = StakeEventType.TokensSeized, Amount = -item.amount }); db.SaveChanges(); } } /*foreach (var item in tokenStaking.GetStakeLocked()) * { * AddLog(item.log); * * var signer = db.Find<Signer>(item.@operator); * if (signer == null) * { * db.Add(new Signer { Id = item.@operator }); * db.SaveChanges(); * } * var se = db.Find<StakeEvent>(item.log.LogIndex, item.log.TransactionId); * if (se == null) * { * db.Add(new StakeEvent * { * TransactionId = item.log.TransactionId, * LogIndex = item.log.LogIndex, * SignerId = item.@operator, * Type = StakeEventType.StakeLocked, * DepositId = db.Set<Deposit>().Where(d => d.KeepAddress == item.lockCreator).FirstOrDefault()?.Id * }); * db.SaveChanges(); * } * } * foreach (var item in tokenStaking.GetLockReleased()) * { * AddLog(item.log); * * var signer = db.Find<Signer>(item.@operator); * if (signer == null) * { * db.Add(new Signer { Id = item.@operator }); * db.SaveChanges(); * } * var se = db.Find<StakeEvent>(item.log.LogIndex, item.log.TransactionId); * if (se == null) * { * db.Add(new StakeEvent * { * TransactionId = item.log.TransactionId, * LogIndex = item.log.LogIndex, * SignerId = item.@operator, * Type = StakeEventType.LockReleased, * DepositId = db.Set<Deposit>().Where(d => d.KeepAddress == item.lockCreator).FirstOrDefault()?.Id * }); * db.SaveChanges(); * } * } */ var bn = uint.MaxValue; if (resultTx.result.Count > 100) { bn = Math.Min(bn, resultTx.result.Max(o => uint.Parse(o.blockNumber))); } if (bn < uint.MaxValue) { lastBlock = bn; } else { lastBlock = toBlock; } network.LastBlockProcessed = lastBlock; if (network.LastBlock != getBlockNumberResult) { network.LastBlock = getBlockNumberResult; network.LastBlockAt = DateTime.Now; } db.SaveChanges(); _logger.LogWarning($"Last block processed: {lastBlock}/{getBlockNumberResult}"); if (getBlockNumberResult == lastBlock) { Thread.Sleep(_options.Interval * 1000); } void AddTx(Etherscan.Tx tx, Deposit d) { if (db.Find <Transaction>(tx.hash) == null) { string tx_error = ""; if (tx.isError == "1") { tx_error = _apiClient.GetTxStatus(tx.hash).result.errDescription; } db.Add(new Transaction { Id = tx.hash, Deposit = d, Block = uint.Parse(tx.blockNumber), Status = d.Status, IsError = tx.isError == "1", Error = tx_error, Timestamp = tx.TimeStamp, Amount = decimal.Parse(tx.value) / 1000000000000000000, Fee = decimal.Parse(tx.gasPrice) / 1000000000000000000 * decimal.Parse(tx.gasUsed), Kind = network.Kind, Sender = tx.from, Recipient = tx.to }); db.SaveChanges(); _logger.LogInformation($"Saved tx {tx.hash} ({tx.TimeStamp})"); } } void AddLog(ContractLog log, Deposit?d = null, DepositStatus?s = null) { if (db.Find <Transaction>(log.TransactionId) == null) { db.Add(new Transaction { Id = log.TransactionId, Deposit = d, Block = log.BlockNumber, Status = s, Timestamp = log.TimeStamp, Error = "", Fee = log.Fee, Kind = network.Kind }); db.SaveChanges(); _logger.LogInformation($"Saved tx {log.TransactionId} ({log.TimeStamp})"); } } void AddLog2(ContractLog log, Redeem r, RedeemStatus s) { if (db.Find <Transaction>(log.TransactionId) == null) { db.Add(new Transaction { Id = log.TransactionId, Redeem = r, Block = log.BlockNumber, Status = DepositStatus.Closed, RedeemStatus = s, Timestamp = log.TimeStamp, Error = "", Fee = log.Fee, Kind = network.Kind }); db.SaveChanges(); _logger.LogInformation($"Saved tx {log.TransactionId} ({log.TimeStamp})"); } } }